diff --git a/src/HTMLRenderer/HTMLRenderer.h b/src/HTMLRenderer/HTMLRenderer.h index d873786..b70f6db 100644 --- a/src/HTMLRenderer/HTMLRenderer.h +++ b/src/HTMLRenderer/HTMLRenderer.h @@ -29,6 +29,7 @@ #include "util/const.h" #include "util/StringFormatter.h" #include "util/TmpFiles.h" +#include "util/misc.h" /* * Naming Convention @@ -75,44 +76,6 @@ public: bool is_type3; }; -class GfxRGB_hash -{ -public: - size_t operator () (const GfxRGB & rgb) const - { - return ( (((size_t)colToByte(rgb.r)) << 16) - | (((size_t)colToByte(rgb.g)) << 8) - | ((size_t)colToByte(rgb.b)) - ); - } -}; - -class GfxRGB_equal -{ -public: - bool operator ()(const GfxRGB & rgb1, const GfxRGB & rgb2) const - { - return ((rgb1.r == rgb2.r) && (rgb1.g == rgb2.g) && (rgb1.b == rgb2.b)); - } -}; - -class Matrix_less -{ -public: - bool operator () (const Matrix & m1, const Matrix & m2) const - { - // Note that we only care about the first 4 elements - for(int i = 0; i < 4; ++i) - { - if(m1.m[i] < m2.m[i] - EPS) - return true; - if(m1.m[i] > m2.m[i] + EPS) - return false; - } - return false; - } -}; - class HTMLRenderer : public OutputDev { public: @@ -380,11 +343,17 @@ class HTMLRenderer : public OutputDev double cur_word_space; bool word_space_changed; - // text color - long long cur_fill_color_id, cur_stroke_color_id; - GfxRGB cur_fill_color, cur_stroke_color; - bool cur_has_fill, cur_has_stroke; - bool fill_color_changed, stroke_color_changed; + // fill color + long long cur_fill_color_id; + GfxRGB cur_fill_color; + bool cur_has_fill; + bool fill_color_changed; + + // stroke color + long long cur_stroke_color_id; + GfxRGB cur_stroke_color; + bool cur_has_stroke; + bool stroke_color_changed; // rise long long cur_rise_id; diff --git a/src/HTMLRenderer/state.cc b/src/HTMLRenderer/state.cc index 3d9ec61..de3c61b 100644 --- a/src/HTMLRenderer/state.cc +++ b/src/HTMLRenderer/state.cc @@ -110,11 +110,12 @@ void HTMLRenderer::reset_state() cur_ws_id = install_word_space(cur_word_space); cur_fill_color.r = cur_fill_color.g = cur_fill_color.b = 0; - cur_stroke_color.r = cur_stroke_color.g = cur_stroke_color.b = 0; - cur_fill_color_id = install_fill_color(&cur_fill_color); - cur_stroke_color_id = install_stroke_color(&cur_stroke_color); - cur_has_stroke = false; - cur_has_fill = true; + cur_fill_color_id = install_fill_color(&cur_fill_color); + cur_has_fill = true; + + cur_stroke_color.r = cur_stroke_color.g = cur_stroke_color.b = 0; + cur_stroke_color_id = install_stroke_color(&cur_stroke_color); + cur_has_stroke = false; cur_rise = 0; cur_rise_id = install_rise(cur_rise); @@ -359,61 +360,58 @@ void HTMLRenderer::check_state_change(GfxState * state) if(all_changed || fill_color_changed || stroke_color_changed) { /* - * Render modes 0 2 4 6 fill text (stroke or not) - * Render modes 1 5 stroke only - * Render modes 3 7 hidden (but ok, we won't even draw text) + * PDF Spec. Table 106 – Text rendering modes */ + + static const char FILL[8] = { true, false, true, false, true, false, true, false }; + static const char STROKE[8] = { false, true, true, false, false, true, true, false }; - // PDF Spec. Table 106 – Text rendering modes - bool is_filled, is_stroked; - switch (state->getRender()) { - case 0: is_filled = true; is_stroked = false; break; - case 1: is_filled = false; is_stroked = true; break; - case 2: is_filled = true; is_stroked = true; break; - case 3: is_filled = false; is_stroked = false; break; - case 4: is_filled = true; is_stroked = false; break; - case 5: is_filled = false; is_stroked = true; break; - case 6: is_filled = true; is_stroked = true; break; - case 7: is_filled = false; is_stroked = false; break; - } + int idx = state->getRender(); + assert((idx >= 0) && (idx < 8)); + bool is_filled = FILL[idx]; + bool is_stroked = STROKE[idx]; - GfxRGB new_color; // fill - state->getFillRGB(&new_color); - - if(cur_has_fill != is_filled || - !((new_color.r == cur_fill_color.r) && - (new_color.g == cur_fill_color.g) && - (new_color.b == cur_fill_color.b))) + if(is_filled) { - new_line_state = max(new_line_state, NLS_SPAN); - cur_fill_color = new_color; - cur_fill_color_id = install_fill_color(&new_color); - } + GfxRGB new_color; + state->getFillRGB(&new_color); - if (!is_filled) { + if(!cur_has_fill + || (!GfxRGB_equal()(new_color, cur_fill_color)) + ) + { + new_line_state = max(new_line_state, NLS_SPAN); + cur_fill_color = new_color; + cur_fill_color_id = install_fill_color(&new_color); + } + } + else + { cur_fill_color_id = install_fill_color(nullptr); } + cur_has_fill = is_filled; // stroke - state->getStrokeRGB(&new_color); - - if(cur_has_stroke != is_stroked || - !((new_color.r == cur_stroke_color.r) && - (new_color.g == cur_stroke_color.g) && - (new_color.b == cur_stroke_color.b))) + if(is_stroked) { - new_line_state = max(new_line_state, NLS_SPAN); - cur_stroke_color = new_color; - cur_stroke_color_id = install_stroke_color(&new_color); + GfxRGB new_color; + state->getStrokeRGB(&new_color); + + if(!cur_has_stroke + || (!GfxRGB_equal()(new_color, cur_stroke_color)) + ) + { + new_line_state = max(new_line_state, NLS_SPAN); + cur_stroke_color = new_color; + cur_stroke_color_id = install_stroke_color(&new_color); + } } - - if (!is_stroked) { + else + { cur_stroke_color_id = install_stroke_color(nullptr); } - - cur_has_fill = is_filled; cur_has_stroke = is_stroked; } diff --git a/src/util/misc.h b/src/util/misc.h index 11ae739..3500bf7 100644 --- a/src/util/misc.h +++ b/src/util/misc.h @@ -13,6 +13,8 @@ #include +#include "util/const.h" + namespace pdf2htmlEX { static inline long long hash_ref(const Ref * id) @@ -32,6 +34,45 @@ void css_fix_rectangle_border_width(double x1, double y1, double x2, double y2, std::ostream & operator << (std::ostream & out, const GfxRGB & rgb); +class GfxRGB_hash +{ +public: + size_t operator () (const GfxRGB & rgb) const + { + return ( (((size_t)colToByte(rgb.r)) << 16) + | (((size_t)colToByte(rgb.g)) << 8) + | ((size_t)colToByte(rgb.b)) + ); + } +}; + +class GfxRGB_equal +{ +public: + bool operator ()(const GfxRGB & rgb1, const GfxRGB & rgb2) const + { + return ((rgb1.r == rgb2.r) && (rgb1.g == rgb2.g) && (rgb1.b == rgb2.b)); + } +}; + +class Matrix_less +{ +public: + bool operator () (const Matrix & m1, const Matrix & m2) const + { + // Note that we only care about the first 4 elements + for(int i = 0; i < 4; ++i) + { + if(m1.m[i] < m2.m[i] - EPS) + return true; + if(m1.m[i] > m2.m[i] + EPS) + return false; + } + return false; + } +}; + + } // namespace pdf2htmlEX #endif //UTIL_H__