diff --git a/src/HTMLRenderer.h b/src/HTMLRenderer.h index f0f31e1..ba0f6f0 100644 --- a/src/HTMLRenderer.h +++ b/src/HTMLRenderer.h @@ -8,7 +8,6 @@ #ifndef HTMLRENDERER_H_ #define HTMLRENDERER_H_ -#include #include #include #include @@ -164,7 +163,8 @@ class HTMLRenderer : public OutputDev //////////////////////////////////////////////////// void check_state_change(GfxState * state); void reset_state_track(); - void close_cur_line(); + void prepare_line(); // close current span or div if necessary, according to new_line_status + void close_line(); //////////////////////////////////////////////////// @@ -182,13 +182,15 @@ class HTMLRenderer : public OutputDev //////////////////////////////////////////////////// // states //////////////////////////////////////////////////// - // if we have a pending opened line + //line status + //indicating the status for current line & next line + //see comments: meaning for current line || meaning for next line enum class LineStatus { - CLOSED, - SPAN, - DIV - } line_status; + NONE, // no line is opened (last
is closed) || stay with the same style + SPAN, // there's a pending opening (within a pending opening
) || open a new if possible, otherwise a new
+ DIV // there's a pending opening
(but no ) || has to open a new
+ } line_status, new_line_status; // The order is according to the appearance in check_state_change // any state changed diff --git a/src/HTMLRenderer/general.cc b/src/HTMLRenderer/general.cc index 7dc823a..074e588 100644 --- a/src/HTMLRenderer/general.cc +++ b/src/HTMLRenderer/general.cc @@ -19,7 +19,7 @@ using boost::filesystem::remove; using boost::filesystem::filesystem_error; HTMLRenderer::HTMLRenderer(const Param * param) - :line_status(LineStatus::CLOSED) + :line_status(LineStatus::NONE) ,image_count(0) ,param(param) ,dest_dir(param->dest_dir) @@ -142,7 +142,7 @@ void HTMLRenderer::startPage(int pageNum, GfxState *state) this->pageWidth = state->getPageWidth(); this->pageHeight = state->getPageHeight(); - assert(line_status == LineStatus::CLOSED); + assert(line_status == LineStatus::NONE); html_fout << format("
" << endl; } diff --git a/src/HTMLRenderer/image.cc b/src/HTMLRenderer/image.cc index 5a16528..6174ddb 100644 --- a/src/HTMLRenderer/image.cc +++ b/src/HTMLRenderer/image.cc @@ -53,7 +53,7 @@ void HTMLRenderer::drawImage(GfxState * state, Object * ref, Stream * str, int w img_stream->close(); delete img_stream; - close_cur_line(); + close_line(); double * ctm = state->getCTM(); ctm[4] = ctm[5] = 0.0; diff --git a/src/HTMLRenderer/state.cc b/src/HTMLRenderer/state.cc index ebd617f..f7a31e8 100644 --- a/src/HTMLRenderer/state.cc +++ b/src/HTMLRenderer/state.cc @@ -7,10 +7,13 @@ * 2012.08.14 */ +#include #include "HTMLRenderer.h" #include "namespace.h" +using std::max; + void HTMLRenderer::updateAll(GfxState * state) { all_changed = true; @@ -63,10 +66,13 @@ void HTMLRenderer::updateFillColor(GfxState * state) } void HTMLRenderer::check_state_change(GfxState * state) { + //TODO: + // close but not
, to use the first style of the line + // DEPENDENCY WARNING // don't adjust the order of state checking - bool close_line = false; + new_line_status = LineStatus::NONE; bool need_recheck_position = false; bool need_rescale_font = false; @@ -97,7 +103,7 @@ void HTMLRenderer::check_state_change(GfxState * state) // should draw_scale be updated, we'll close the line anyway if(!(abs((cur_ty + cur_rise) - draw_ty) * draw_scale < param->v_eps)) { - close_line = true; + new_line_status = max(new_line_status, LineStatus::DIV); } } @@ -108,7 +114,7 @@ void HTMLRenderer::check_state_change(GfxState * state) if(!(new_fn_id == cur_fn_id)) { - close_line = true; + new_line_status = max(new_line_status, LineStatus::SPAN); cur_fn_id = new_fn_id; } @@ -167,13 +173,13 @@ void HTMLRenderer::check_state_change(GfxState * state) if(!(_equal(new_draw_font_size, draw_font_size))) { - close_line = true; + new_line_status = max(new_line_status, LineStatus::SPAN); draw_font_size = new_draw_font_size; cur_fs_id = install_font_size(draw_font_size); } if(!(_tm_equal(new_draw_ctm, draw_ctm))) { - close_line = true; + new_line_status = max(new_line_status, LineStatus::DIV); memcpy(draw_ctm, new_draw_ctm, sizeof(draw_ctm)); cur_tm_id = install_transform_matrix(draw_ctm); } @@ -186,7 +192,7 @@ void HTMLRenderer::check_state_change(GfxState * state) double new_letter_space = state->getCharSpace(); if(!_equal(cur_letter_space, new_letter_space)) { - close_line = true; + new_line_status = max(new_line_status, LineStatus::SPAN); cur_letter_space = new_letter_space; cur_ls_id = install_letter_space(cur_letter_space * draw_scale); } @@ -199,14 +205,12 @@ void HTMLRenderer::check_state_change(GfxState * state) double new_word_space = state->getWordSpace(); if(!_equal(cur_word_space, new_word_space)) { - close_line = true; + new_line_status = max(new_line_status, LineStatus::SPAN); cur_word_space = new_word_space; cur_ws_id = install_word_space(cur_word_space * draw_scale); } } - // TODO, we may use nested span if only color is changed - // color if(all_changed || color_changed) { @@ -214,17 +218,103 @@ void HTMLRenderer::check_state_change(GfxState * state) state->getFillRGB(&new_color); if(!((new_color.r == cur_color.r) && (new_color.g == cur_color.g) && (new_color.b == cur_color.b))) { - close_line = true; + new_line_status = max(new_line_status, LineStatus::SPAN); cur_color = new_color; cur_color_id = install_color(&new_color); } } + prepare_line(); + + // TODO: move the following to prepare_line ?? + if(line_status == LineStatus::NONE) + { + new_line_status = LineStatus::DIV; + + //resync position + draw_ty = cur_ty + cur_rise; + draw_tx = cur_tx; + } + else + { + assert(new_line_status != LineStatus::DIV); + + // horizontal position + // try to merge with the last line if possible + double target = (cur_tx - draw_tx) * draw_scale; + if(abs(target) < param->h_eps) + { + // ignore it + } + else + { + // don't close a pending span here, keep the styling + + if(target > param->h_eps) + { + double w; + auto wid = install_whitespace(target, w); + html_fout << format(" ") % wid; + draw_tx += w / draw_scale; + } + else + { + // shift left + // TODO, create a class for this + html_fout << format("") % target; + draw_tx += target / draw_scale; + } + } + } + + if(new_line_status != LineStatus::NONE) + { + // have to open a new tag + + if(new_line_status == LineStatus::SPAN) + { + html_fout << "transform(state->getCurX(), state->getCurY(), &x, &y); + + html_fout << format("
getFont()->getDescent() * draw_font_size) + % (pageHeight - y - state->getFont()->getAscent() * draw_font_size) + % x; + + // "t0" is the id_matrix + if(cur_tm_id != 0) + html_fout << format("t%|1$x| ") % cur_tm_id; + } + else + { + assert(false && "Bad value of new_line_status"); + } + + + // TODO: only show changed styles for + html_fout << format("f%|1$x| s%|2$x| c%|3$x|") % cur_fn_id % cur_fs_id % cur_color_id; + + + if(cur_ls_id != 0) + html_fout << format(" l%|1$x|") % cur_ls_id; + + if(cur_ws_id != 0) + html_fout << format(" w%|1$x|") % cur_ws_id; + + html_fout << "\">"; + + line_status = new_line_status; + } + reset_state_track(); - if(close_line) - close_cur_line(); } + void HTMLRenderer::reset_state_track() { all_changed = false; @@ -242,24 +332,32 @@ void HTMLRenderer::reset_state_track() color_changed = false; } -void HTMLRenderer::close_cur_line() +void HTMLRenderer::prepare_line() { - switch(line_status) + if((line_status == LineStatus::NONE) || (new_line_status == LineStatus::NONE)) + return; + + if(new_line_status == LineStatus::DIV) { - case LineStatus::SPAN: - html_fout << ""; - // fall through - case LineStatus::DIV: - html_fout << "
" << endl; - line_status = LineStatus::CLOSED; - break; - - case LineStatus::CLOSED: - default: - break; + close_line(); + } + else + { + assert(new_line_status == LineStatus::SPAN); + if(line_status == LineStatus::SPAN) + html_fout << "
"; + else + assert(line_status == LineStatus::DIV); + // don't change line_status } - - draw_ty = cur_ty + cur_rise; - draw_tx = cur_tx; } +void HTMLRenderer::close_line() +{ + if(line_status == LineStatus::SPAN) + html_fout << ""; + else + assert(line_status == LineStatus::DIV); + html_fout << "
"; + line_status = LineStatus::NONE; +} diff --git a/src/HTMLRenderer/text.cc b/src/HTMLRenderer/text.cc index 5506a96..bcbf84a 100644 --- a/src/HTMLRenderer/text.cc +++ b/src/HTMLRenderer/text.cc @@ -155,80 +155,6 @@ void HTMLRenderer::drawString(GfxState * state, GooString * s) // see if the line has to be closed due to state change check_state_change(state); - - // if the line is still open, try to merge with it - if(line_status != LineStatus::CLOSED) - { - double target = (cur_tx - draw_tx) * draw_scale; - if(abs(target) < param->h_eps) - { - // ignore it - } - else - { - // don't close a pending span here, keep the styling - - if(target > param->h_eps) - { - double w; - auto wid = install_whitespace(target, w); - html_fout << format(" ") % wid; - draw_tx += w / draw_scale; - } - else - { - // shift left - // TODO, create a class for this - html_fout << format("") % target; - draw_tx += target / draw_scale; - } - } - } - else - { - // have to open a new line - - // classes - html_fout << "
transform(state->getCurX(), state->getCurY(), &x, &y); - // TODO: recheck descent/ascent - html_fout << "\" style=\"" - << "bottom:" << (y + state->getFont()->getDescent() * draw_font_size) << "px;" - << "top:" << (pageHeight - y - state->getFont()->getAscent() * draw_font_size) << "px;" - << "left:" << x << "px;" - ; - } - - //debug - { -#if 0 - html_fout << "\""; - double x,y; - state->transform(state->getCurX(), state->getCurY(), &x, &y); - html_fout << format("data-lx=\"%5%\" data-ly=\"%6%\" data-draw-x=\"%7%\" data-draw-y=\"%8%\" data-drawscale=\"%4%\" data-x=\"%1%\" data-y=\"%2%\" data-hs=\"%3%") - %x%y%(state->getHorizScaling())%draw_scale%state->getLineX()%state->getLineY()%draw_tx%draw_ty; -#endif - } - - html_fout << "\">"; - - line_status = LineStatus::DIV; - } // Now ready to output // get the unicodes