From e468f0349402a9cd72d51cb9c2a90f4329b94946 Mon Sep 17 00:00:00 2001 From: Duan Yao Date: Tue, 17 Jun 2014 23:37:25 +0800 Subject: [PATCH] Fix covered text processing issue (in DrawingTracer::set_ctm) when zoom != 1 --- src/DrawingTracer.cc | 32 +++++++++++++++++++++----------- src/DrawingTracer.h | 3 ++- src/HTMLRenderer/state.cc | 2 +- 3 files changed, 24 insertions(+), 13 deletions(-) diff --git a/src/DrawingTracer.cc b/src/DrawingTracer.cc index cb16c21..24fa6e2 100644 --- a/src/DrawingTracer.cc +++ b/src/DrawingTracer.cc @@ -41,19 +41,21 @@ void DrawingTracer::finish() } } -void DrawingTracer::set_ctm(GfxState *state) +// Poppler won't inform us its initial CTM, and the initial CTM is affected by zoom level. +// OutputDev::clip() may be called before OutputDev::updateCTM(), so we can't rely on GfxState::getCTM(), +// and should trace ctm changes ourself (via cairo). +void DrawingTracer::update_ctm(GfxState *state, double m11, double m12, double m21, double m22, double m31, double m32) { if (!param.process_covered_text) return; - double * ctm = state->getCTM(); cairo_matrix_t matrix; - matrix.xx = ctm[0]; - matrix.yx = ctm[1]; - matrix.xy = ctm[2]; - matrix.yy = ctm[3]; - matrix.x0 = ctm[4]; - matrix.y0 = ctm[5]; - cairo_set_matrix(cairo, &matrix); + matrix.xx = m11; + matrix.yx = m12; + matrix.xy = m21; + matrix.yy = m22; + matrix.x0 = m31; + matrix.y0 = m32; + cairo_transform(cairo, &matrix); } void DrawingTracer::clip(GfxState * state, bool even_odd) @@ -154,7 +156,7 @@ void DrawingTracer::draw_non_char_bbox(GfxState * state, double * bbox) cairo_clip_extents(cairo, cbox, cbox + 1, cbox + 2, cbox + 3); if(bbox_intersect(cbox, bbox, bbox)) { - tm_transform_bbox(state->getCTM(), bbox); + transform_bbox_by_ctm(bbox); if (on_non_char_drawn) on_non_char_drawn(bbox); } @@ -188,7 +190,7 @@ void DrawingTracer::draw_char_bbox(GfxState * state, double * bbox) cairo_clip_extents(cairo, cbox, cbox + 1, cbox + 2, cbox + 3); bbox_intersect(cbox, bbox, bbox); } - tm_transform_bbox(state->getCTM(), bbox); + transform_bbox_by_ctm(bbox); if (pt_in < 4) { if(on_char_clipped) @@ -247,4 +249,12 @@ void DrawingTracer::draw_char(GfxState *state, double x, double y, double ax, do draw_char_bbox(state, bbox); } +void DrawingTracer::transform_bbox_by_ctm(double * bbox) +{ + cairo_matrix_t mat; + cairo_get_matrix(cairo, &mat); + double mat_a[6] {mat.xx, mat.yx, mat.xy, mat.yy, mat.x0, mat.y0}; + tm_transform_bbox(mat_a, bbox); +} + } /* namespace pdf2htmlEX */ diff --git a/src/DrawingTracer.h b/src/DrawingTracer.h index 032c511..d8cee1c 100644 --- a/src/DrawingTracer.h +++ b/src/DrawingTracer.h @@ -46,7 +46,7 @@ public: * An image is drawing */ void draw_image(GfxState * state); - void set_ctm(GfxState * state); + void update_ctm(GfxState * state, double m11, double m12, double m21, double m22, double m31, double m32); void clip(GfxState * state, bool even_odd = false); void clip_to_stroke_path(GfxState * state); void fill(GfxState * state, bool even_odd = false); @@ -60,6 +60,7 @@ private: void do_path(GfxState * state, GfxPath * path); void draw_non_char_bbox(GfxState * state, double * bbox); void draw_char_bbox(GfxState * state, double * bbox); + void transform_bbox_by_ctm(double * bbox); const Param & param; cairo_t * cairo = nullptr; diff --git a/src/HTMLRenderer/state.cc b/src/HTMLRenderer/state.cc index 498655a..9278e4e 100644 --- a/src/HTMLRenderer/state.cc +++ b/src/HTMLRenderer/state.cc @@ -46,7 +46,7 @@ void HTMLRenderer::updateFont(GfxState * state) void HTMLRenderer::updateCTM(GfxState * state, double m11, double m12, double m21, double m22, double m31, double m32) { ctm_changed = true; - tracer.set_ctm(state); + tracer.update_ctm(state, m11, m12, m21, m22, m31, m32); } void HTMLRenderer::updateTextMat(GfxState * state) {