From fb243494490fa578dce28a88f1194a3f7a4a247d Mon Sep 17 00:00:00 2001 From: Lu Wang Date: Tue, 7 Aug 2012 00:48:33 +0800 Subject: [PATCH] color support --- bin/pdf2htmlEX | 2 +- src/HTMLRenderer.cc | 84 ++++++++++++++++++++++++++++++--------------- src/HTMLRenderer.h | 48 ++++++++++++++++++++++---- 3 files changed, 99 insertions(+), 35 deletions(-) diff --git a/bin/pdf2htmlEX b/bin/pdf2htmlEX index b6bb525..7261b0e 100755 --- a/bin/pdf2htmlEX +++ b/bin/pdf2htmlEX @@ -12,5 +12,5 @@ done for f in *.pfa; do fontforge -script "${SCRIPT_DIR}/convert.pe" $f 2>/dev/null - rm $f +# rm $f done diff --git a/src/HTMLRenderer.cc b/src/HTMLRenderer.cc index b52fe3a..c053c47 100644 --- a/src/HTMLRenderer.cc +++ b/src/HTMLRenderer.cc @@ -8,13 +8,7 @@ /* * TODO * color - * transformation - * remove line break for divs in the same line - * - * updatetextmat, position etc. - * * font base64 embedding - * custom css */ #include @@ -47,6 +41,7 @@ * s - font Size * w - White space * t - Transform matrix + * c - Color */ const char * HTML_HEAD = "\n\ @@ -136,7 +131,7 @@ void TextString::addChars(GfxState *state, double x, double y, { if(nbytes > 0) { - CharCode mask = 0xff << (8*(nbytes-1)); + CharCode mask = (0xffLL) << (8*(nbytes-1)); while(nbytes > 0) { unicodes.push_back((Unicode)((code & mask) >> (8 * (nbytes-1)))); @@ -179,6 +174,10 @@ HTMLRenderer::HTMLRenderer(const Param * param) install_font_size(0); install_transform_matrix(id_matrix); + + GfxRGB black; + black.r = black.g = black.b = 0; + install_color(&black); html_fout << HTML_HEAD; if(param->readable) html_fout << endl; @@ -255,11 +254,10 @@ void HTMLRenderer::startPage(int pageNum, GfxState *state) memcpy(draw_ctm, id_matrix, sizeof(draw_ctm)); draw_font_size = 0; draw_scale = 1.0; + + cur_color.r = cur_color.g = cur_color.b = 0; - pos_changed = false; - ctm_changed = false; - text_mat_changed = false; - font_changed = false; + reset_state_track(); } void HTMLRenderer::endPage() { @@ -338,6 +336,7 @@ void HTMLRenderer::updateAll(GfxState *state) text_mat_changed = true; ctm_changed = true; pos_changed = true; + color_changed = true; } void HTMLRenderer::updateFont(GfxState *state) @@ -360,14 +359,9 @@ void HTMLRenderer::updateTextPos(GfxState * state) pos_changed = true; } -void HTMLRenderer::saveTextPos(GfxState * state) +void HTMLRenderer::updateFillColor(GfxState * state) { - cout << "save" << endl; -} - -void HTMLRenderer::restoreTextPos(GfxState * state) -{ - cout << "restore" << endl; + color_changed = true; } void HTMLRenderer::beginString(GfxState *state, GooString *s) { @@ -425,7 +419,7 @@ void HTMLRenderer::endString(GfxState *state) { // open a new line // classes html_fout << "
first)) - { + if((iter != transform_matrix_map.end()) && (m == (iter->first))) return iter->second; - } long long new_tm_id = transform_matrix_map.size(); transform_matrix_map.insert(std::make_pair(m, new_tm_id)); @@ -874,6 +867,19 @@ long long HTMLRenderer::install_transform_matrix(const double * tm){ return new_tm_id; } +long long HTMLRenderer::install_color(const GfxRGB * rgb) +{ + Color c(rgb); + auto iter = color_map.lower_bound(c); + if((iter != color_map.end()) && (c == (iter->first))) + return iter->second; + + long long new_color_id = color_map.size(); + color_map.insert(std::make_pair(c, new_color_id)); + export_color(new_color_id, rgb); + return new_color_id; +} + void HTMLRenderer::export_remote_font(long long fn_id, const string & suffix, GfxFont * font) { @@ -957,7 +963,6 @@ void HTMLRenderer::export_transform_matrix (long long tm_id, const double * tm) { allcss_fout << boost::format(".t%|1$x|{") % tm_id; - // TODO: recognize common matices if(_tm_equal(tm, id_matrix)) { @@ -982,7 +987,13 @@ void HTMLRenderer::export_transform_matrix (long long tm_id, const double * tm) } allcss_fout << "}"; if(param->readable) allcss_fout << endl; +} +void HTMLRenderer::export_color(long long color_id, const GfxRGB * rgb) +{ + allcss_fout << boost::format(".c%|1$x|{color:rgb(%2%,%3%,%4%);}") + % color_id % rgb->r % rgb->g % rgb->b; + if(param->readable) allcss_fout << endl; } void HTMLRenderer::check_state_change(GfxState * state) @@ -994,6 +1005,19 @@ void HTMLRenderer::check_state_change(GfxState * state) close_cur_line(); cur_line_y = state->getLineY(); } + + } + + if(color_changed) + { + GfxRGB new_color; + state->getFillRGB(&new_color); + if(!((new_color.r == cur_color.r) && (new_color.g == cur_color.g) && (new_color.b == cur_color.b))) + { + close_cur_line(); + cur_color = new_color; + cur_color_id = install_color(&new_color); + } } bool need_rescale_font = true; @@ -1065,8 +1089,14 @@ void HTMLRenderer::check_state_change(GfxState * state) close_cur_line(); } - text_mat_changed = false; - pos_changed = false; - font_changed = false; + reset_state_track(); } +void HTMLRenderer::reset_state_track() +{ + pos_changed = false; + ctm_changed = false; + text_mat_changed = false; + font_changed = false; + color_changed = false; +} diff --git a/src/HTMLRenderer.h b/src/HTMLRenderer.h index b4d7792..f39aedc 100644 --- a/src/HTMLRenderer.h +++ b/src/HTMLRenderer.h @@ -128,8 +128,8 @@ class HTMLRenderer : public OutputDev virtual void updateTextMat(GfxState * state); virtual void updateCTM(GfxState * state, double m11, double m12, double m21, double m22, double m31, double m32); virtual void updateTextPos(GfxState * state); - virtual void saveTextPos(GfxState * state); - virtual void restoreTextPos(GfxState * state); + + virtual void updateFillColor(GfxState * state); //----- text drawing virtual void beginString(GfxState *state, GooString *s); @@ -160,6 +160,7 @@ class HTMLRenderer : public OutputDev long long install_font_size(double font_size); long long install_whitespace(double ws_width, double & actual_width); long long install_transform_matrix(const double * tm); + long long install_color(const GfxRGB * rgb); /* * remote font: to be retrieved from the web server @@ -173,7 +174,9 @@ class HTMLRenderer : public OutputDev void export_font_size(long long fs_id, double font_size); void export_whitespace(long long ws_id, double ws_width); void export_transform_matrix(long long tm_id, const double * tm); + void export_color(long long color_id, const GfxRGB * rgb); + XRef * xref; Catalog *catalog; Page *docPage; @@ -186,10 +189,8 @@ class HTMLRenderer : public OutputDev // state maintained when processing pdf void check_state_change(GfxState * state); + void reset_state_track(); - // current position - double cur_line_y; - bool pos_changed; // the string being processed TextString * cur_string; @@ -199,10 +200,12 @@ class HTMLRenderer : public OutputDev // (actual x) - (supposed x) double cur_line_x_offset; + // current position + double cur_line_y; + bool pos_changed; long long cur_fn_id; double cur_font_size; - long long cur_fs_id; bool font_changed; @@ -210,6 +213,9 @@ class HTMLRenderer : public OutputDev bool ctm_changed; bool text_mat_changed; + long long cur_color_id; + GfxRGB cur_color; + bool color_changed; // optmize for web // we try to render the final font size directly @@ -227,7 +233,6 @@ class HTMLRenderer : public OutputDev unordered_map font_name_map; map font_size_map; map whitespace_map; - XRef * xref; // transform matrix class TM{ @@ -252,6 +257,35 @@ class HTMLRenderer : public OutputDev map transform_matrix_map; + class Color{ + public: + Color() {} + Color(const GfxRGB * rgb) { + _[0] = rgb->r; + _[1] = rgb->g; + _[2] = rgb->b; + } + bool operator < (const Color & c) const { + for(int i = 0; i < 3; ++i) + { + if(_[i] < c._[i]) + return true; + if(_[i] > c._[i]) + return false; + } + return false; + } + bool operator == (const Color & c) const { + for(int i = 0; i < 3; ++i) + if(_[i] != c._[i]) + return false; + return true; + } + + int _[3]; + }; + map color_map; + const Param * param; };