mirror of
https://github.com/pdf2htmlEX/pdf2htmlEX.git
synced 2024-12-22 13:00:08 +00:00
Improve DrawingTracer::stroke() by break path into steps.
This commit is contained in:
parent
a57b61731d
commit
f705a98581
@ -10,6 +10,9 @@
|
|||||||
#include "util/math.h"
|
#include "util/math.h"
|
||||||
#include "DrawingTracer.h"
|
#include "DrawingTracer.h"
|
||||||
|
|
||||||
|
//#define DT_DEBUG(x) (x)
|
||||||
|
#define DT_DEBUG(x)
|
||||||
|
|
||||||
namespace pdf2htmlEX
|
namespace pdf2htmlEX
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -128,14 +131,63 @@ void DrawingTracer::stroke(GfxState * state)
|
|||||||
{
|
{
|
||||||
if (!param.process_covered_text)
|
if (!param.process_covered_text)
|
||||||
return;
|
return;
|
||||||
// TODO
|
|
||||||
// 1. if stroke extents is large, break the path into pieces and handle each of them;
|
DT_DEBUG(printf("DrawingTracer::stroke\n"));
|
||||||
// 2. if the line width is small, could just ignore the path?
|
|
||||||
do_path(state, state->getPath());
|
|
||||||
cairo_set_line_width(cairo, state->getLineWidth());
|
cairo_set_line_width(cairo, state->getLineWidth());
|
||||||
double sbox[4];
|
|
||||||
cairo_stroke_extents(cairo, sbox, sbox + 1, sbox + 2, sbox + 3);
|
// GfxPath is broken into steps, each step makes up a cairo path and its bbox is used for covering test.
|
||||||
draw_non_char_bbox(state, sbox);
|
// TODO
|
||||||
|
// 1. path steps that are not vertical or horizontal lines may still falsely "cover" many chars,
|
||||||
|
// can we slice those steps further?
|
||||||
|
// 2. if the line width is small, can we just ignore the path?
|
||||||
|
GfxPath * path = state->getPath();
|
||||||
|
for (int i = 0; i < path->getNumSubpaths(); ++i) {
|
||||||
|
GfxSubpath * subpath = path->getSubpath(i);
|
||||||
|
if (subpath->getNumPoints() <= 0)
|
||||||
|
continue;
|
||||||
|
double x = subpath->getX(0);
|
||||||
|
double y = subpath->getY(0);
|
||||||
|
//p: loop cursor; j: next point index
|
||||||
|
int p =1, j = 1;
|
||||||
|
int n = subpath->getNumPoints();
|
||||||
|
while (p <= n) {
|
||||||
|
cairo_new_path(cairo);
|
||||||
|
cairo_move_to(cairo, x, y);
|
||||||
|
if (subpath->getCurve(j)) {
|
||||||
|
x = subpath->getX(j+2);
|
||||||
|
y = subpath->getY(j+2);
|
||||||
|
cairo_curve_to(cairo,
|
||||||
|
subpath->getX(j), subpath->getY(j),
|
||||||
|
subpath->getX(j+1), subpath->getY(j+1),
|
||||||
|
x, y);
|
||||||
|
p += 3;
|
||||||
|
} else {
|
||||||
|
x = subpath->getX(j);
|
||||||
|
y = subpath->getY(j);
|
||||||
|
cairo_line_to(cairo, x, y);
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
|
||||||
|
DT_DEBUG(printf("DrawingTracer::stroke:new box:\n"));
|
||||||
|
double sbox[4];
|
||||||
|
cairo_stroke_extents(cairo, sbox, sbox + 1, sbox + 2, sbox + 3);
|
||||||
|
if (sbox[0] != sbox[2] && sbox[1] != sbox[3])
|
||||||
|
draw_non_char_bbox(state, sbox);
|
||||||
|
else
|
||||||
|
DT_DEBUG(printf("DrawingTracer::stroke:zero box!\n"));
|
||||||
|
|
||||||
|
if (p == n)
|
||||||
|
{
|
||||||
|
if (subpath->isClosed())
|
||||||
|
j = 0; // if sub path is closed, go back to starting point
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
j = p;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawingTracer::fill(GfxState * state, bool even_odd)
|
void DrawingTracer::fill(GfxState * state, bool even_odd)
|
||||||
@ -157,6 +209,7 @@ void DrawingTracer::draw_non_char_bbox(GfxState * state, double * bbox)
|
|||||||
if(bbox_intersect(cbox, bbox, bbox))
|
if(bbox_intersect(cbox, bbox, bbox))
|
||||||
{
|
{
|
||||||
transform_bbox_by_ctm(bbox);
|
transform_bbox_by_ctm(bbox);
|
||||||
|
DT_DEBUG(printf("DrawingTracer::draw_non_char_bbox:[%f,%f,%f,%f]\n", bbox[0],bbox[1],bbox[2],bbox[3]));
|
||||||
if (on_non_char_drawn)
|
if (on_non_char_drawn)
|
||||||
on_non_char_drawn(bbox);
|
on_non_char_drawn(bbox);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user