summaryrefslogtreecommitdiff
path: root/source/pdf
diff options
context:
space:
mode:
Diffstat (limited to 'source/pdf')
-rw-r--r--source/pdf/pdf-appearance.c58
-rw-r--r--source/pdf/pdf-device.c122
-rw-r--r--source/pdf/pdf-op-run.c24
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;
}