diff --git a/src/HTMLRenderer/state.cc b/src/HTMLRenderer/state.cc index 1bc1131..0d361d1 100644 --- a/src/HTMLRenderer/state.cc +++ b/src/HTMLRenderer/state.cc @@ -181,22 +181,34 @@ void HTMLRenderer::check_state_change(GfxState * state) double old_tm[6]; memcpy(old_tm, cur_text_tm, sizeof(old_tm)); - // ctm & text ctm & hori scale - if(all_changed || ctm_changed || text_mat_changed || hori_scale_changed) + // rise + // depends draw_text_scale + if(all_changed || rise_changed || draw_text_scale_changed) + { + double new_rise = state->getRise() * draw_text_scale; + if(!equal(new_rise, cur_html_state.rise)) + { + cur_html_state.rise = new_rise; + new_line_state = max(new_line_state, NLS_SPAN); + } + } + + // ctm & text ctm & hori scale & rise + if(all_changed || ctm_changed || text_mat_changed || hori_scale_changed || rise_changed) { double new_text_tm[6]; - const double * m1 = state->getCTM(); - const double * m2 = state->getTextMat(); - double hori_scale = state->getHorizScaling(); + double m1[6]; + double m2[6]; - new_text_tm[0] = (m1[0] * m2[0] + m1[2] * m2[1]) * hori_scale; - new_text_tm[1] = (m1[1] * m2[0] + m1[3] * m2[1]) * hori_scale; - new_text_tm[2] = m1[0] * m2[2] + m1[2] * m2[3]; - new_text_tm[3] = m1[1] * m2[2] + m1[3] * m2[3]; - new_text_tm[4] = m1[0] * m2[4] + m1[2] * m2[5] + m1[4]; - new_text_tm[5] = m1[1] * m2[4] + m1[3] * m2[5] + m1[5]; - //new_text_tm[4] = new_text_tm[5] = 0; + //the matrix with horizontal_scale and rise + m1[0] = state->getHorizScaling(); + m1[3] = 1; + m1[5] = state->getRise(); + m1[1] = m1[2] = m1[4] = 0; + + tm_multiply(m2, state->getCTM(), state->getTextMat()); + tm_multiply(new_text_tm, m2, m1); if(!tm_equal(new_text_tm, cur_text_tm)) { @@ -265,7 +277,7 @@ void HTMLRenderer::check_state_change(GfxState * state) // see if the new line is compatible with the current line with proper position shift // don't bother doing the heavy job when (new_line_state == NLS_DIV) - // depends: rise & text position & transformation + // depends: text position & transformation if(need_recheck_position && (new_line_state < NLS_DIV)) { // try to transform the old origin under the new TM @@ -278,10 +290,6 @@ void HTMLRenderer::check_state_change(GfxState * state) * CurTM[4] - OldTM[4] = OldTM[0] * (draw_tx + dx - cur_tx) + OldTM[2] * (draw_ty + dy - cur_ty) * CurTM[5] - OldTM[5] = OldTM[1] * (draw_tx + dx - cur_tx) + OldTM[3] * (draw_ty + dy - cur_ty) * - * For horizontal text, set dy = 0, and try to solve dx - * If dx can be solved, we can simply append a x-offset without creating a new line - * - * TODO, writing mode, set dx = 0 and solve dy * TODO, try to merge when cur_tm and old_tm are proportional */ @@ -406,18 +414,6 @@ void HTMLRenderer::check_state_change(GfxState * state) } } - // rise - // depends draw_text_scale - if(all_changed || rise_changed || draw_text_scale_changed) - { - double new_rise = state->getRise() * draw_text_scale; - if(!equal(new_rise, cur_html_state.rise)) - { - cur_html_state.rise = new_rise; - new_line_state = max(new_line_state, NLS_SPAN); - } - } - reset_state_change(); } diff --git a/src/HTMLRenderer/text.cc b/src/HTMLRenderer/text.cc index 5572fb2..0e0f64a 100644 --- a/src/HTMLRenderer/text.cc +++ b/src/HTMLRenderer/text.cc @@ -97,19 +97,27 @@ void HTMLRenderer::drawString(GfxState * state, GooString * s) if((param->decompose_ligature) && (uLen > 1) && all_of(u, u+uLen, isLegalUnicode)) { text_line_buf->append_unicodes(u, uLen); + // TODO: decomposed characters may be not with the same width as the original ligature, need to fix it. } else { + Unicode uu; if(cur_html_state.font_info->use_tounicode) { - Unicode uu = check_unicode(u, uLen, code, font); - text_line_buf->append_unicodes(&uu, 1); + uu = check_unicode(u, uLen, code, font); } else { - Unicode uu = unicode_from_font(code, font); - text_line_buf->append_unicodes(&uu, 1); + uu = unicode_from_font(code, font); } + text_line_buf->append_unicodes(&uu, 1); + /* + * In PDF, word_space is appended if (n == 1 and *p = ' ') + * but in HTML, word_space is appended if (uu == ' ') + */ + int space_count = (is_space ? 1 : 0) - (uu == ' ' ? 1 : 0); + if(space_count != 0) + text_line_buf->append_offset(cur_word_space * draw_text_scale * space_count); } } diff --git a/src/util/math.h b/src/util/math.h index 2966090..7db46d7 100644 --- a/src/util/math.h +++ b/src/util/math.h @@ -24,6 +24,16 @@ static inline bool tm_equal(const double * tm1, const double * tm2, int size = 6 return false; return true; } +static inline void tm_multiply(double * result, const double * m1, const double * m2) +{ + result[0] = m1[0] * m2[0] + m1[2] * m2[1]; + result[1] = m1[1] * m2[0] + m1[3] * m2[1]; + result[2] = m1[0] * m2[2] + m1[2] * m2[3]; + result[3] = m1[1] * m2[2] + m1[3] * m2[3]; + result[4] = m1[0] * m2[4] + m1[2] * m2[5] + m1[4]; + result[5] = m1[1] * m2[4] + m1[3] * m2[5] + m1[5]; +} + static inline double hypot(double x, double y) { return std::sqrt(x*x+y*y); } void tm_transform(const double * tm, double & x, double & y, bool is_delta = false);