diff options
Diffstat (limited to 'source/pdf')
-rw-r--r-- | source/pdf/pdf-appearance.c | 58 | ||||
-rw-r--r-- | source/pdf/pdf-device.c | 122 | ||||
-rw-r--r-- | source/pdf/pdf-op-run.c | 24 |
3 files changed, 111 insertions, 93 deletions
diff --git a/source/pdf/pdf-appearance.c b/source/pdf/pdf-appearance.c index 9bd3754b..6132f97f 100644 --- a/source/pdf/pdf-appearance.c +++ b/source/pdf/pdf-appearance.c @@ -1898,36 +1898,37 @@ void pdf_update_ink_appearance(fz_context *ctx, pdf_document *doc, pdf_annot *an } } -static void add_text(fz_context *ctx, font_info *font_rec, fz_text *text, char *str, int str_len, float x, float y) +static void add_text(fz_context *ctx, font_info *font_rec, fz_text *text, char *str, int str_len, const fz_matrix *tm_) { fz_font *font = font_rec->font->font; - int mask = FT_LOAD_NO_SCALE | FT_LOAD_IGNORE_TRANSFORM; + fz_matrix tm = *tm_; + int ucs, gid, n; - while (str_len--) + while (str_len > 0) { - FT_Fixed adv; - - /* FIXME: convert str from utf8 to WinAnsi */ - int gid = FT_Get_Char_Index(font->ft_face, *str); - fz_add_text(ctx, text, gid, *str++, x, y); - - FT_Get_Advance(font->ft_face, gid, mask, &adv); - x += ((float)adv) * font_rec->da_rec.font_size / ((FT_Face)font->ft_face)->units_per_EM; + n = fz_chartorune(&ucs, str); + str += n; + str_len -= n; + gid = fz_encode_character(ctx, font, ucs); + fz_add_text(ctx, text, font, 0, &tm, gid, ucs); + tm.e += fz_advance_glyph(ctx, font, gid) * font_rec->da_rec.font_size; } } static fz_text *layout_text(fz_context *ctx, font_info *font_rec, char *str, float x, float y) { - fz_matrix tm; - fz_font *font = font_rec->font->font; fz_text *text; + fz_matrix tm; fz_scale(&tm, font_rec->da_rec.font_size, font_rec->da_rec.font_size); - text = fz_new_text(ctx, font, &tm, 0); + tm.e = x; + tm.f = y; + + text = fz_new_text(ctx); fz_try(ctx) { - add_text(ctx, font_rec, text, str, strlen(str), x, y); + add_text(ctx, font_rec, text, str, strlen(str), &tm); } fz_catch(ctx) { @@ -1944,6 +1945,7 @@ static fz_text *fit_text(fz_context *ctx, font_info *font_rec, char *str, fz_rec float height = bounds->y1 - bounds->y0; fz_matrix tm; fz_text *text = NULL; + fz_text_span *span; text_splitter splitter; float ascender; @@ -1961,14 +1963,15 @@ static fz_text *fit_text(fz_context *ctx, font_info *font_rec, char *str, fz_rec /* Try a layout pass */ int line = 0; float font_size; - float x = 0.0; - float y = 0.0; fz_drop_text(ctx, text); text = NULL; font_size = font_rec->da_rec.font_size; fz_scale(&tm, font_size, font_size); - text = fz_new_text(ctx, font_rec->font->font, &tm, 0); + tm.e = 0; + tm.f = 0; + + text = fz_new_text(ctx); text_splitter_start_pass(&splitter); @@ -1989,9 +1992,9 @@ static fz_text *fit_text(fz_context *ctx, font_info *font_rec, char *str, fz_rec int wordlen = splitter.text_end-splitter.text_start; text_splitter_move(&splitter, -line, &dx, &dy); - x += dx; - y += dy; - add_text(ctx, font_rec, text, word, wordlen, x, y); + tm.e += dx; + tm.f += dy; + add_text(ctx, font_rec, text, word, wordlen, &tm); } } @@ -2004,12 +2007,15 @@ static fz_text *fit_text(fz_context *ctx, font_info *font_rec, char *str, fz_rec /* Post process text with the scale determined by the splitter * and with the required offst */ - fz_pre_scale(&text->trm, splitter.scale, splitter.scale); - ascender = font_rec->font->ascent * font_rec->da_rec.font_size * splitter.scale / 1000.0f; - for (i = 0; i < text->len; i++) + for (span = text->head; span; span = span->next) { - text->items[i].x = text->items[i].x * splitter.scale + bounds->x0; - text->items[i].y = text->items[i].y * splitter.scale + bounds->y1 - ascender; + fz_pre_scale(&span->trm, splitter.scale, splitter.scale); + ascender = font_rec->font->ascent * font_rec->da_rec.font_size * splitter.scale / 1000.0f; + for (i = 0; i < span->len; i++) + { + span->items[i].x = span->items[i].x * splitter.scale + bounds->x0; + span->items[i].y = span->items[i].y * splitter.scale + bounds->y1 - ascender; + } } } fz_catch(ctx) diff --git a/source/pdf/pdf-device.c b/source/pdf/pdf-device.c index 51c5ee9e..a2ee1295 100644 --- a/source/pdf/pdf-device.c +++ b/source/pdf/pdf-device.c @@ -667,7 +667,7 @@ pdf_dev_pop(fz_context *ctx, pdf_device *pdev) } static void -pdf_dev_text(fz_context *ctx, pdf_device *pdev, fz_text *text, float size) +pdf_dev_text_span(fz_context *ctx, pdf_device *pdev, fz_text_span *span, float size) { int mask = FT_LOAD_NO_SCALE | FT_LOAD_IGNORE_TRANSFORM; int i; @@ -686,9 +686,9 @@ pdf_dev_text(fz_context *ctx, pdf_device *pdev, fz_text *text, float size) fz_invert_matrix(&inverse, &trunc_trm); i = 0; - while (i < text->len) + while (i < span->len) { - fz_text_item *it = &text->items[i]; + fz_text_item *it = &span->items[i]; fz_point delta; float x; int j; @@ -704,17 +704,17 @@ pdf_dev_text(fz_context *ctx, pdf_device *pdev, fz_text *text, float size) } j = i+1; - if (text->font->ft_face) + if (span->font->ft_face) { /* Find prefix of text for which the advance of each character accounts * for the position offset */ x = it->x; - while (j < text->len) + while (j < span->len) { FT_Fixed adv; - FT_Get_Advance(text->font->ft_face, text->items[j-1].gid, mask, &adv); - x += (float)adv * size /((FT_Face)text->font->ft_face)->units_per_EM; - if (fabs(x - text->items[j].x) > ALLOWED_TEXT_POS_ERROR || fabs(it->y - text->items[j].y) > ALLOWED_TEXT_POS_ERROR) + FT_Get_Advance(span->font->ft_face, span->items[j-1].gid, mask, &adv); + x += (float)adv * size /((FT_Face)span->font->ft_face)->units_per_EM; + if (fabs(x - span->items[j].x) > ALLOWED_TEXT_POS_ERROR || fabs(it->y - span->items[j].y) > ALLOWED_TEXT_POS_ERROR) break; j++; } @@ -725,7 +725,7 @@ pdf_dev_text(fz_context *ctx, pdf_device *pdev, fz_text *text, float size) { /* FIXME: should use it->gid, rather than it->ucs, and convert * to the correct encoding */ - fz_buffer_printf(ctx, gs->buf, "%02x", text->items[i].ucs); + fz_buffer_printf(ctx, gs->buf, "%02x", span->items[i].ucs); } fz_buffer_printf(ctx, gs->buf, "> Tj\n"); } @@ -935,83 +935,105 @@ pdf_dev_clip_stroke_path(fz_context *ctx, fz_device *dev, fz_path *path, const f static void pdf_dev_fill_text(fz_context *ctx, fz_device *dev, fz_text *text, const fz_matrix *ctm, - fz_colorspace *colorspace, float *color, float alpha) + fz_colorspace *colorspace, float *color, float alpha) { pdf_device *pdev = (pdf_device*)dev; - fz_matrix trm = text->trm; - float size = fz_matrix_expansion(&trm); + fz_text_span *span; - fz_pre_scale(&trm, 1/size, 1/size); + for (span = text->head; span; span = span->next) + { + fz_matrix trm = span->trm; + float size = fz_matrix_expansion(&trm); - pdf_dev_begin_text(ctx, pdev, &trm, 0); - pdf_dev_font(ctx, pdev, text->font, size); - pdf_dev_ctm(ctx, pdev, ctm); - pdf_dev_alpha(ctx, pdev, alpha, 0); - pdf_dev_color(ctx, pdev, colorspace, color, 0); - pdf_dev_text(ctx, pdev, text, size); + fz_pre_scale(&trm, 1/size, 1/size); + + pdf_dev_begin_text(ctx, pdev, &trm, 0); + pdf_dev_font(ctx, pdev, span->font, size); + pdf_dev_ctm(ctx, pdev, ctm); + pdf_dev_alpha(ctx, pdev, alpha, 0); + pdf_dev_color(ctx, pdev, colorspace, color, 0); + pdf_dev_text_span(ctx, pdev, span, size); + } } static void pdf_dev_stroke_text(fz_context *ctx, fz_device *dev, fz_text *text, fz_stroke_state *stroke, const fz_matrix *ctm, - fz_colorspace *colorspace, float *color, float alpha) + fz_colorspace *colorspace, float *color, float alpha) { pdf_device *pdev = (pdf_device*)dev; - fz_matrix trm = text->trm; - float size = fz_matrix_expansion(&trm); + fz_text_span *span; - fz_pre_scale(&trm, 1/size, 1/size); + for (span = text->head; span; span = span->next) + { + fz_matrix trm = span->trm; + float size = fz_matrix_expansion(&trm); - pdf_dev_begin_text(ctx, pdev, &text->trm, 1); - pdf_dev_font(ctx, pdev, text->font, 1); - pdf_dev_ctm(ctx, pdev, ctm); - pdf_dev_alpha(ctx, pdev, alpha, 1); - pdf_dev_color(ctx, pdev, colorspace, color, 1); - pdf_dev_text(ctx, pdev, text, size); + fz_pre_scale(&trm, 1/size, 1/size); + + pdf_dev_begin_text(ctx, pdev, &span->trm, 1); + pdf_dev_font(ctx, pdev, span->font, 1); + pdf_dev_ctm(ctx, pdev, ctm); + pdf_dev_alpha(ctx, pdev, alpha, 1); + pdf_dev_color(ctx, pdev, colorspace, color, 1); + pdf_dev_text_span(ctx, pdev, span, size); + } } static void pdf_dev_clip_text(fz_context *ctx, fz_device *dev, fz_text *text, const fz_matrix *ctm, int accumulate) { pdf_device *pdev = (pdf_device*)dev; - fz_matrix trm = text->trm; - float size = fz_matrix_expansion(&trm); + fz_text_span *span; + for (span = text->head; span; span = span->next) + { + fz_matrix trm = span->trm; + float size = fz_matrix_expansion(&trm); - fz_pre_scale(&trm, 1/size, 1/size); + fz_pre_scale(&trm, 1/size, 1/size); - pdf_dev_begin_text(ctx, pdev, &text->trm, 0); - pdf_dev_ctm(ctx, pdev, ctm); - pdf_dev_font(ctx, pdev, text->font, 7); - pdf_dev_text(ctx, pdev, text, size); + pdf_dev_begin_text(ctx, pdev, &span->trm, 0); + pdf_dev_ctm(ctx, pdev, ctm); + pdf_dev_font(ctx, pdev, span->font, 7); + pdf_dev_text_span(ctx, pdev, span, size); + } } static void pdf_dev_clip_stroke_text(fz_context *ctx, fz_device *dev, fz_text *text, fz_stroke_state *stroke, const fz_matrix *ctm) { pdf_device *pdev = (pdf_device*)dev; - fz_matrix trm = text->trm; - float size = fz_matrix_expansion(&trm); + fz_text_span *span; + for (span = text->head; span; span = span->next) + { + fz_matrix trm = span->trm; + float size = fz_matrix_expansion(&trm); - fz_pre_scale(&trm, 1/size, 1/size); + fz_pre_scale(&trm, 1/size, 1/size); - pdf_dev_begin_text(ctx, pdev, &text->trm, 0); - pdf_dev_font(ctx, pdev, text->font, 5); - pdf_dev_ctm(ctx, pdev, ctm); - pdf_dev_text(ctx, pdev, text, size); + pdf_dev_begin_text(ctx, pdev, &span->trm, 0); + pdf_dev_font(ctx, pdev, span->font, 5); + pdf_dev_ctm(ctx, pdev, ctm); + pdf_dev_text_span(ctx, pdev, span, size); + } } static void pdf_dev_ignore_text(fz_context *ctx, fz_device *dev, fz_text *text, const fz_matrix *ctm) { pdf_device *pdev = (pdf_device*)dev; - fz_matrix trm = text->trm; - float size = fz_matrix_expansion(&trm); + fz_text_span *span; + for (span = text->head; span; span = span->next) + { + fz_matrix trm = span->trm; + float size = fz_matrix_expansion(&trm); - fz_pre_scale(&trm, 1/size, 1/size); + fz_pre_scale(&trm, 1/size, 1/size); - pdf_dev_begin_text(ctx, pdev, &text->trm, 0); - pdf_dev_ctm(ctx, pdev, ctm); - pdf_dev_font(ctx, pdev, text->font, 3); - pdf_dev_text(ctx, pdev, text, size); + pdf_dev_begin_text(ctx, pdev, &span->trm, 0); + pdf_dev_ctm(ctx, pdev, ctm); + pdf_dev_font(ctx, pdev, span->font, 3); + pdf_dev_text_span(ctx, pdev, span, size); + } } static void diff --git a/source/pdf/pdf-op-run.c b/source/pdf/pdf-op-run.c index dbd9386d..ea2384be 100644 --- a/source/pdf/pdf-op-run.c +++ b/source/pdf/pdf-op-run.c @@ -754,7 +754,7 @@ pdf_flush_text(fz_context *ctx, pdf_run_processor *pr) fz_adjust_rect_for_stroke(ctx, &tb, gstate->stroke_state, &gstate->ctm); /* Don't bother sending a text group with nothing in it */ - if (text->len == 0) + if (!text->head) break; if (dofill || dostroke) @@ -921,22 +921,12 @@ pdf_show_char(fz_context *ctx, pdf_run_processor *pr, int cid) * uncachable, then render direct. */ render_direct = (!fontdesc->font->ft_face && pr->nested_depth > 0) || !fz_glyph_cacheable(ctx, fontdesc->font, gid); - /* flush buffered text if face or matrix or rendermode has changed */ - if (!pr->text || - fontdesc->font != pr->text->font || - fontdesc->wmode != pr->text->wmode || - fabsf(trm.a - pr->text->trm.a) > FLT_EPSILON || - fabsf(trm.b - pr->text->trm.b) > FLT_EPSILON || - fabsf(trm.c - pr->text->trm.c) > FLT_EPSILON || - fabsf(trm.d - pr->text->trm.d) > FLT_EPSILON || - gstate->render != pr->text_mode || - render_direct) + /* flush buffered text if rendermode has changed */ + if (!pr->text || gstate->render != pr->text_mode || render_direct) { gstate = pdf_flush_text(ctx, pr); - pr->text = fz_new_text(ctx, fontdesc->font, &trm, fontdesc->wmode); - pr->text->trm.e = 0; - pr->text->trm.f = 0; + pr->text = fz_new_text(ctx); pr->text_mode = gstate->render; pr->text_bbox = fz_empty_rect; } @@ -956,11 +946,11 @@ pdf_show_char(fz_context *ctx, pdf_run_processor *pr, int cid) fz_union_rect(&pr->text_bbox, &bbox); /* add glyph to textobject */ - fz_add_text(ctx, pr->text, gid, ucsbuf[0], trm.e, trm.f); + fz_add_text(ctx, pr->text, fontdesc->font, fontdesc->wmode, &trm, gid, ucsbuf[0]); /* add filler glyphs for one-to-many unicode mapping */ for (i = 1; i < ucslen; i++) - fz_add_text(ctx, pr->text, -1, ucsbuf[i], trm.e, trm.f); + fz_add_text(ctx, pr->text, fontdesc->font, fontdesc->wmode, &trm, -1, ucsbuf[i]); if (fontdesc->wmode == 0) { @@ -1658,7 +1648,7 @@ static void pdf_run_Tw(fz_context *ctx, pdf_processor *proc, float wordspace) static void pdf_run_Tz(fz_context *ctx, pdf_processor *proc, float scale) { pdf_run_processor *pr = (pdf_run_processor *)proc; - pdf_gstate *gstate = pdf_flush_text(ctx, pr); + pdf_gstate *gstate = pr->gstate + pr->gtop; gstate->scale = scale / 100; } |