1
0
mirror of https://github.com/pdf2htmlEX/pdf2htmlEX.git synced 2024-07-07 18:30:34 +00:00

Allow covered text handling (--process-covered-text) to work without cairo.

This commit is contained in:
Duan Yao 2014-06-25 18:49:40 +08:00
parent e69e9a8be8
commit 65e82028bb
3 changed files with 61 additions and 4 deletions

View File

@ -13,10 +13,17 @@
//#define DT_DEBUG(x) (x) //#define DT_DEBUG(x) (x)
#define DT_DEBUG(x) #define DT_DEBUG(x)
#if !ENABLE_SVG
#warning "Cairo is disabled because ENABLE_SVG is off, --process-covered-text has limited functionality."
#endif
namespace pdf2htmlEX namespace pdf2htmlEX
{ {
DrawingTracer::DrawingTracer(const Param & param): param(param), cairo(nullptr) DrawingTracer::DrawingTracer(const Param & param): param(param)
#if ENABLE_SVG
, cairo(nullptr)
#endif
{ {
} }
@ -30,18 +37,23 @@ void DrawingTracer::reset(GfxState *state)
if (!param.process_covered_text) if (!param.process_covered_text)
return; return;
finish(); finish();
#if ENABLE_SVG
cairo_rectangle_t page_box {0, 0, width:state->getPageWidth(), height:state->getPageHeight()}; cairo_rectangle_t page_box {0, 0, width:state->getPageWidth(), height:state->getPageHeight()};
cairo_surface_t * surface = cairo_recording_surface_create(CAIRO_CONTENT_COLOR_ALPHA, &page_box); cairo_surface_t * surface = cairo_recording_surface_create(CAIRO_CONTENT_COLOR_ALPHA, &page_box);
cairo = cairo_create(surface); cairo = cairo_create(surface);
#endif
} }
void DrawingTracer::finish() void DrawingTracer::finish()
{ {
#if ENABLE_SVG
if (cairo) if (cairo)
{ {
cairo_destroy(cairo); cairo_destroy(cairo);
cairo = nullptr; cairo = nullptr;
} }
#endif
} }
// Poppler won't inform us its initial CTM, and the initial CTM is affected by zoom level. // Poppler won't inform us its initial CTM, and the initial CTM is affected by zoom level.
@ -51,6 +63,8 @@ void DrawingTracer::update_ctm(GfxState *state, double m11, double m12, double m
{ {
if (!param.process_covered_text) if (!param.process_covered_text)
return; return;
#if ENABLE_SVG
cairo_matrix_t matrix; cairo_matrix_t matrix;
matrix.xx = m11; matrix.xx = m11;
matrix.yx = m12; matrix.yx = m12;
@ -59,15 +73,18 @@ void DrawingTracer::update_ctm(GfxState *state, double m11, double m12, double m
matrix.x0 = m31; matrix.x0 = m31;
matrix.y0 = m32; matrix.y0 = m32;
cairo_transform(cairo, &matrix); cairo_transform(cairo, &matrix);
#endif
} }
void DrawingTracer::clip(GfxState * state, bool even_odd) void DrawingTracer::clip(GfxState * state, bool even_odd)
{ {
if (!param.process_covered_text) if (!param.process_covered_text)
return; return;
#if ENABLE_SVG
do_path(state, state->getPath()); do_path(state, state->getPath());
cairo_set_fill_rule(cairo, even_odd? CAIRO_FILL_RULE_EVEN_ODD : CAIRO_FILL_RULE_WINDING); cairo_set_fill_rule(cairo, even_odd? CAIRO_FILL_RULE_EVEN_ODD : CAIRO_FILL_RULE_WINDING);
cairo_clip (cairo); cairo_clip (cairo);
#endif
} }
void DrawingTracer::clip_to_stroke_path(GfxState * state) void DrawingTracer::clip_to_stroke_path(GfxState * state)
@ -81,17 +98,22 @@ void DrawingTracer::save()
{ {
if (!param.process_covered_text) if (!param.process_covered_text)
return; return;
#if ENABLE_SVG
cairo_save(cairo); cairo_save(cairo);
#endif
} }
void DrawingTracer::restore() void DrawingTracer::restore()
{ {
if (!param.process_covered_text) if (!param.process_covered_text)
return; return;
#if ENABLE_SVG
cairo_restore(cairo); cairo_restore(cairo);
#endif
} }
void DrawingTracer::do_path(GfxState * state, GfxPath * path) void DrawingTracer::do_path(GfxState * state, GfxPath * path)
{ {
#if ENABLE_SVG
//copy from CairoOutputDev::doPath //copy from CairoOutputDev::doPath
GfxSubpath *subpath; GfxSubpath *subpath;
int i, j; int i, j;
@ -125,10 +147,12 @@ void DrawingTracer::do_path(GfxState * state, GfxPath * path)
} }
} }
} }
#endif
} }
void DrawingTracer::stroke(GfxState * state) void DrawingTracer::stroke(GfxState * state)
{ {
#if ENABLE_SVG
if (!param.process_covered_text) if (!param.process_covered_text)
return; return;
@ -192,27 +216,33 @@ void DrawingTracer::stroke(GfxState * state)
j = p; j = p;
} }
} }
#endif
} }
void DrawingTracer::fill(GfxState * state, bool even_odd) void DrawingTracer::fill(GfxState * state, bool even_odd)
{ {
if (!param.process_covered_text) if (!param.process_covered_text)
return; return;
#if ENABLE_SVG
do_path(state, state->getPath()); do_path(state, state->getPath());
//cairo_fill_extents don't take fill rule into account. //cairo_fill_extents don't take fill rule into account.
//cairo_set_fill_rule (cairo, even_odd? CAIRO_FILL_RULE_EVEN_ODD : CAIRO_FILL_RULE_WINDING); //cairo_set_fill_rule (cairo, even_odd? CAIRO_FILL_RULE_EVEN_ODD : CAIRO_FILL_RULE_WINDING);
double fbox[4]; double fbox[4];
cairo_fill_extents(cairo, fbox, fbox + 1, fbox + 2, fbox + 3); cairo_fill_extents(cairo, fbox, fbox + 1, fbox + 2, fbox + 3);
draw_non_char_bbox(state, fbox); draw_non_char_bbox(state, fbox);
#endif
} }
void DrawingTracer::draw_non_char_bbox(GfxState * state, double * bbox) void DrawingTracer::draw_non_char_bbox(GfxState * state, double * bbox)
{ {
#if ENABLE_SVG
double cbox[4]; double cbox[4];
cairo_clip_extents(cairo, cbox, cbox + 1, cbox + 2, cbox + 3); cairo_clip_extents(cairo, cbox, cbox + 1, cbox + 2, cbox + 3);
if(bbox_intersect(cbox, bbox, bbox)) if(bbox_intersect(cbox, bbox, bbox))
#endif
{ {
transform_bbox_by_ctm(bbox); transform_bbox_by_ctm(bbox, state);
DT_DEBUG(printf("DrawingTracer::draw_non_char_bbox:[%f,%f,%f,%f]\n", bbox[0],bbox[1],bbox[2],bbox[3])); 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);
@ -221,6 +251,7 @@ void DrawingTracer::draw_non_char_bbox(GfxState * state, double * bbox)
void DrawingTracer::draw_char_bbox(GfxState * state, double * bbox) void DrawingTracer::draw_char_bbox(GfxState * state, double * bbox)
{ {
#if ENABLE_SVG
// Note: even if 4 corners of the char are all in or all out of the clip area, // Note: even if 4 corners of the char are all in or all out of the clip area,
// it could still be partially clipped. // it could still be partially clipped.
// TODO better solution? // TODO better solution?
@ -260,6 +291,11 @@ void DrawingTracer::draw_char_bbox(GfxState * state, double * bbox)
on_char_drawn(bbox); on_char_drawn(bbox);
} }
} }
#else
transform_bbox_by_ctm(bbox, state);
if (on_char_drawn)
on_char_drawn(bbox);
#endif
DT_DEBUG(printf("DrawingTracer::draw_char_bbox:[%f,%f,%f,%f]\n",bbox[0],bbox[1],bbox[2],bbox[3])); DT_DEBUG(printf("DrawingTracer::draw_char_bbox:[%f,%f,%f,%f]\n",bbox[0],bbox[1],bbox[2],bbox[3]));
} }
@ -308,12 +344,17 @@ void DrawingTracer::draw_char(GfxState *state, double x, double y, double ax, do
draw_char_bbox(state, bbox); draw_char_bbox(state, bbox);
} }
void DrawingTracer::transform_bbox_by_ctm(double * bbox)
void DrawingTracer::transform_bbox_by_ctm(double * bbox, GfxState * state)
{ {
#if ENABLE_SVG
cairo_matrix_t mat; cairo_matrix_t mat;
cairo_get_matrix(cairo, &mat); cairo_get_matrix(cairo, &mat);
double mat_a[6] {mat.xx, mat.yx, mat.xy, mat.yy, mat.x0, mat.y0}; double mat_a[6] {mat.xx, mat.yx, mat.xy, mat.yy, mat.x0, mat.y0};
tm_transform_bbox(mat_a, bbox); tm_transform_bbox(mat_a, bbox);
#else
tm_transform_bbox(state->getCTM(), bbox);
#endif
} }
} /* namespace pdf2htmlEX */ } /* namespace pdf2htmlEX */

View File

@ -11,7 +11,12 @@
#include <functional> #include <functional>
#include <GfxState.h> #include <GfxState.h>
#include "pdf2htmlEX-config.h"
#if ENABLE_SVG
#include <cairo.h> #include <cairo.h>
#endif
#include "Param.h" #include "Param.h"
@ -60,10 +65,14 @@ private:
void do_path(GfxState * state, GfxPath * path); void do_path(GfxState * state, GfxPath * path);
void draw_non_char_bbox(GfxState * state, double * bbox); void draw_non_char_bbox(GfxState * state, double * bbox);
void draw_char_bbox(GfxState * state, double * bbox); void draw_char_bbox(GfxState * state, double * bbox);
void transform_bbox_by_ctm(double * bbox); // If cairo is available, parameter state is ignored
void transform_bbox_by_ctm(double * bbox, GfxState * state = nullptr);
const Param & param; const Param & param;
#if ENABLE_SVG
cairo_t * cairo; cairo_t * cairo;
#endif
}; };
} /* namespace pdf2htmlEX */ } /* namespace pdf2htmlEX */

View File

@ -24,6 +24,13 @@ static inline bool tm_equal(const double * tm1, const double * tm2, int size = 6
return false; return false;
return true; return true;
} }
static inline void tm_init(double * tm)
{
tm[0] = tm[3] = 1;
tm[1] = tm[2] = tm[4] = tm[5] = 0;
}
static inline void tm_multiply(double * result, const double * m1, const double * m2) static inline void tm_multiply(double * result, const double * m1, const double * m2)
{ {
result[0] = m1[0] * m2[0] + m1[2] * m2[1]; result[0] = m1[0] * m2[0] + m1[2] * m2[1];