summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorTor Andersson <tor.andersson@artifex.com>2015-10-09 11:07:42 +0200
committerTor Andersson <tor.andersson@artifex.com>2015-12-11 13:02:33 +0100
commitfa0bffa57e7e2164f0201b0f2fdc984d475674ae (patch)
treead6a7d7bc8641e390552ba8c49fdba351de00f82 /source
parente3275837d5738c5092b2e452829919e31ad553e5 (diff)
downloadmupdf-fa0bffa57e7e2164f0201b0f2fdc984d475674ae.tar.xz
Keep spans of multiple fonts and sizes in one fz_text object.
Diffstat (limited to 'source')
-rw-r--r--source/fitz/draw-device.c338
-rw-r--r--source/fitz/stext-device.c76
-rw-r--r--source/fitz/svg-device.c214
-rw-r--r--source/fitz/text.c165
-rw-r--r--source/fitz/trace-device.c76
-rw-r--r--source/html/html-layout.c50
-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
-rw-r--r--source/xps/xps-glyphs.c13
10 files changed, 616 insertions, 520 deletions
diff --git a/source/fitz/draw-device.c b/source/fitz/draw-device.c
index b109e6b7..ab6ebbe7 100644
--- a/source/fitz/draw-device.c
+++ b/source/fitz/draw-device.c
@@ -562,15 +562,13 @@ fz_draw_fill_text(fz_context *ctx, fz_device *devp, fz_text *text, const fz_matr
fz_colorspace *colorspace, float *color, float alpha)
{
fz_draw_device *dev = (fz_draw_device*)devp;
-
+ fz_draw_state *state = &dev->stack[dev->top];
+ fz_colorspace *model = state->dest->colorspace;
unsigned char colorbv[FZ_MAX_COLORS + 1];
unsigned char shapebv;
float colorfv[FZ_MAX_COLORS];
- fz_matrix tm, trm;
- fz_glyph *glyph;
- int i, gid;
- fz_draw_state *state = &dev->stack[dev->top];
- fz_colorspace *model = state->dest->colorspace;
+ fz_text_span *span;
+ int i;
if (state->blendmode & FZ_BLEND_KNOCKOUT)
state = fz_knockout_begin(ctx, dev);
@@ -581,50 +579,57 @@ fz_draw_fill_text(fz_context *ctx, fz_device *devp, fz_text *text, const fz_matr
colorbv[i] = alpha * 255;
shapebv = 255;
- tm = text->trm;
-
- for (i = 0; i < text->len; i++)
+ for (span = text->head; span; span = span->next)
{
- gid = text->items[i].gid;
- if (gid < 0)
- continue;
+ fz_matrix tm, trm;
+ fz_glyph *glyph;
+ int gid;
- tm.e = text->items[i].x;
- tm.f = text->items[i].y;
- fz_concat(&trm, &tm, ctm);
+ tm = span->trm;
- glyph = fz_render_glyph(ctx, text->font, gid, &trm, model, &state->scissor);
- if (glyph)
- {
- fz_pixmap *pixmap = glyph->pixmap;
- int x = floorf(trm.e);
- int y = floorf(trm.f);
- if (pixmap == NULL || pixmap->n == 1)
- {
- draw_glyph(colorbv, state->dest, glyph, x, y, &state->scissor);
- if (state->shape)
- draw_glyph(&shapebv, state->shape, glyph, x, y, &state->scissor);
- }
- else
- {
- fz_matrix mat;
- mat.a = pixmap->w; mat.b = mat.c = 0; mat.d = pixmap->h;
- mat.e = x + pixmap->x; mat.f = y + pixmap->y;
- fz_paint_image(state->dest, &state->scissor, state->shape, pixmap, &mat, alpha * 255, !(devp->hints & FZ_DONT_INTERPOLATE_IMAGES), devp->flags & FZ_DEVFLAG_GRIDFIT_AS_TILED);
- }
- fz_drop_glyph(ctx, glyph);
- }
- else
+ for (i = 0; i < span->len; i++)
{
- fz_path *path = fz_outline_glyph(ctx, text->font, gid, &tm);
- if (path)
+ gid = span->items[i].gid;
+ if (gid < 0)
+ continue;
+
+ tm.e = span->items[i].x;
+ tm.f = span->items[i].y;
+ fz_concat(&trm, &tm, ctm);
+
+ glyph = fz_render_glyph(ctx, span->font, gid, &trm, model, &state->scissor);
+ if (glyph)
{
- fz_draw_fill_path(ctx, devp, path, 0, ctm, colorspace, color, alpha);
- fz_drop_path(ctx, path);
+ fz_pixmap *pixmap = glyph->pixmap;
+ int x = floorf(trm.e);
+ int y = floorf(trm.f);
+ if (pixmap == NULL || pixmap->n == 1)
+ {
+ draw_glyph(colorbv, state->dest, glyph, x, y, &state->scissor);
+ if (state->shape)
+ draw_glyph(&shapebv, state->shape, glyph, x, y, &state->scissor);
+ }
+ else
+ {
+ fz_matrix mat;
+ mat.a = pixmap->w; mat.b = mat.c = 0; mat.d = pixmap->h;
+ mat.e = x + pixmap->x; mat.f = y + pixmap->y;
+ fz_paint_image(state->dest, &state->scissor, state->shape, pixmap, &mat, alpha * 255, !(devp->hints & FZ_DONT_INTERPOLATE_IMAGES), devp->flags & FZ_DEVFLAG_GRIDFIT_AS_TILED);
+ }
+ fz_drop_glyph(ctx, glyph);
}
else
{
- fz_warn(ctx, "cannot render glyph");
+ fz_path *path = fz_outline_glyph(ctx, span->font, gid, &tm);
+ if (path)
+ {
+ fz_draw_fill_path(ctx, devp, path, 0, ctm, colorspace, color, alpha);
+ fz_drop_path(ctx, path);
+ }
+ else
+ {
+ fz_warn(ctx, "cannot render glyph");
+ }
}
}
}
@@ -639,14 +644,12 @@ fz_draw_stroke_text(fz_context *ctx, fz_device *devp, fz_text *text, fz_stroke_s
float *color, float alpha)
{
fz_draw_device *dev = (fz_draw_device*)devp;
-
- unsigned char colorbv[FZ_MAX_COLORS + 1];
- float colorfv[FZ_MAX_COLORS];
- fz_matrix tm, trm;
- fz_glyph *glyph;
- int i, gid;
fz_draw_state *state = &dev->stack[dev->top];
fz_colorspace *model = state->dest->colorspace;
+ unsigned char colorbv[FZ_MAX_COLORS + 1];
+ float colorfv[FZ_MAX_COLORS];
+ fz_text_span *span;
+ int i;
if (state->blendmode & FZ_BLEND_KNOCKOUT)
state = fz_knockout_begin(ctx, dev);
@@ -656,39 +659,46 @@ fz_draw_stroke_text(fz_context *ctx, fz_device *devp, fz_text *text, fz_stroke_s
colorbv[i] = colorfv[i] * 255;
colorbv[i] = alpha * 255;
- tm = text->trm;
-
- for (i = 0; i < text->len; i++)
+ for (span = text->head; span; span = span->next)
{
- gid = text->items[i].gid;
- if (gid < 0)
- continue;
+ fz_matrix tm, trm;
+ fz_glyph *glyph;
+ int gid;
- tm.e = text->items[i].x;
- tm.f = text->items[i].y;
- fz_concat(&trm, &tm, ctm);
+ tm = span->trm;
- glyph = fz_render_stroked_glyph(ctx, text->font, gid, &trm, ctm, stroke, &state->scissor);
- if (glyph)
- {
- int x = (int)trm.e;
- int y = (int)trm.f;
- draw_glyph(colorbv, state->dest, glyph, x, y, &state->scissor);
- if (state->shape)
- draw_glyph(colorbv, state->shape, glyph, x, y, &state->scissor);
- fz_drop_glyph(ctx, glyph);
- }
- else
+ for (i = 0; i < span->len; i++)
{
- fz_path *path = fz_outline_glyph(ctx, text->font, gid, &tm);
- if (path)
+ gid = span->items[i].gid;
+ if (gid < 0)
+ continue;
+
+ tm.e = span->items[i].x;
+ tm.f = span->items[i].y;
+ fz_concat(&trm, &tm, ctm);
+
+ glyph = fz_render_stroked_glyph(ctx, span->font, gid, &trm, ctm, stroke, &state->scissor);
+ if (glyph)
{
- fz_draw_stroke_path(ctx, devp, path, stroke, ctm, colorspace, color, alpha);
- fz_drop_path(ctx, path);
+ int x = (int)trm.e;
+ int y = (int)trm.f;
+ draw_glyph(colorbv, state->dest, glyph, x, y, &state->scissor);
+ if (state->shape)
+ draw_glyph(colorbv, state->shape, glyph, x, y, &state->scissor);
+ fz_drop_glyph(ctx, glyph);
}
else
{
- fz_warn(ctx, "cannot render glyph");
+ fz_path *path = fz_outline_glyph(ctx, span->font, gid, &tm);
+ if (path)
+ {
+ fz_draw_stroke_path(ctx, devp, path, stroke, ctm, colorspace, color, alpha);
+ fz_drop_path(ctx, path);
+ }
+ else
+ {
+ fz_warn(ctx, "cannot render glyph");
+ }
}
}
}
@@ -708,6 +718,7 @@ fz_draw_clip_text(fz_context *ctx, fz_device *devp, fz_text *text, const fz_matr
int i, gid;
fz_draw_state *state;
fz_colorspace *model;
+ fz_text_span *span;
/* If accumulate == 0 then this text object is guaranteed complete */
/* If accumulate == 1 then this text object is the first (or only) in a sequence */
@@ -765,58 +776,61 @@ fz_draw_clip_text(fz_context *ctx, fz_device *devp, fz_text *text, const fz_matr
if (!fz_is_empty_irect(&bbox) && mask)
{
- tm = text->trm;
-
- for (i = 0; i < text->len; i++)
+ for (span = text->head; span; span = span->next)
{
- gid = text->items[i].gid;
- if (gid < 0)
- continue;
+ tm = span->trm;
- tm.e = text->items[i].x;
- tm.f = text->items[i].y;
- fz_concat(&trm, &tm, ctm);
-
- glyph = fz_render_glyph(ctx, text->font, gid, &trm, model, &state->scissor);
- if (glyph)
+ for (i = 0; i < span->len; i++)
{
- int x = (int)trm.e;
- int y = (int)trm.f;
- draw_glyph(NULL, mask, glyph, x, y, &bbox);
- if (state[1].shape)
- draw_glyph(NULL, state[1].shape, glyph, x, y, &bbox);
- fz_drop_glyph(ctx, glyph);
- }
- else
- {
- fz_path *path = fz_outline_glyph(ctx, text->font, gid, &tm);
- if (path)
- {
- fz_pixmap *old_dest;
- float white = 1;
+ gid = span->items[i].gid;
+ if (gid < 0)
+ continue;
- old_dest = state[1].dest;
- state[1].dest = state[1].mask;
- state[1].mask = NULL;
- fz_try(ctx)
- {
- fz_draw_fill_path(ctx, devp, path, 0, ctm, fz_device_gray(ctx), &white, 1);
- }
- fz_always(ctx)
+ tm.e = span->items[i].x;
+ tm.f = span->items[i].y;
+ fz_concat(&trm, &tm, ctm);
+
+ glyph = fz_render_glyph(ctx, span->font, gid, &trm, model, &state->scissor);
+ if (glyph)
+ {
+ int x = (int)trm.e;
+ int y = (int)trm.f;
+ draw_glyph(NULL, mask, glyph, x, y, &bbox);
+ if (state[1].shape)
+ draw_glyph(NULL, state[1].shape, glyph, x, y, &bbox);
+ fz_drop_glyph(ctx, glyph);
+ }
+ else
+ {
+ fz_path *path = fz_outline_glyph(ctx, span->font, gid, &tm);
+ if (path)
{
- state[1].mask = state[1].dest;
- state[1].dest = old_dest;
- fz_drop_path(ctx, path);
+ fz_pixmap *old_dest;
+ float white = 1;
+
+ old_dest = state[1].dest;
+ state[1].dest = state[1].mask;
+ state[1].mask = NULL;
+ fz_try(ctx)
+ {
+ fz_draw_fill_path(ctx, devp, path, 0, ctm, fz_device_gray(ctx), &white, 1);
+ }
+ fz_always(ctx)
+ {
+ state[1].mask = state[1].dest;
+ state[1].dest = old_dest;
+ fz_drop_path(ctx, path);
+ }
+ fz_catch(ctx)
+ {
+ fz_rethrow(ctx);
+ }
}
- fz_catch(ctx)
+ else
{
- fz_rethrow(ctx);
+ fz_warn(ctx, "cannot render glyph for clipping");
}
}
- else
- {
- fz_warn(ctx, "cannot render glyph for clipping");
- }
}
}
}
@@ -840,6 +854,7 @@ fz_draw_clip_stroke_text(fz_context *ctx, fz_device *devp, fz_text *text, fz_str
int i, gid;
fz_draw_state *state = push_stack(ctx, dev);
fz_colorspace *model = state->dest->colorspace;
+ fz_text_span *span;
fz_rect rect;
STACK_PUSHED("clip stroke text");
@@ -869,59 +884,62 @@ fz_draw_clip_stroke_text(fz_context *ctx, fz_device *devp, fz_text *text, fz_str
if (!fz_is_empty_irect(&bbox))
{
- tm = text->trm;
-
- for (i = 0; i < text->len; i++)
+ for (span = text->head; span; span = span->next)
{
- gid = text->items[i].gid;
- if (gid < 0)
- continue;
-
- tm.e = text->items[i].x;
- tm.f = text->items[i].y;
- fz_concat(&trm, &tm, ctm);
+ tm = span->trm;
- glyph = fz_render_stroked_glyph(ctx, text->font, gid, &trm, ctm, stroke, &state->scissor);
- if (glyph)
- {
- int x = (int)trm.e;
- int y = (int)trm.f;
- draw_glyph(NULL, mask, glyph, x, y, &bbox);
- if (shape)
- draw_glyph(NULL, shape, glyph, x, y, &bbox);
- fz_drop_glyph(ctx, glyph);
- }
- else
+ for (i = 0; i < span->len; i++)
{
- fz_path *path = fz_outline_glyph(ctx, text->font, gid, &tm);
- if (path)
+ gid = span->items[i].gid;
+ if (gid < 0)
+ continue;
+
+ tm.e = span->items[i].x;
+ tm.f = span->items[i].y;
+ fz_concat(&trm, &tm, ctm);
+
+ glyph = fz_render_stroked_glyph(ctx, span->font, gid, &trm, ctm, stroke, &state->scissor);
+ if (glyph)
{
- fz_pixmap *old_dest;
- float white = 1;
-
- state = &dev->stack[dev->top];
- old_dest = state[0].dest;
- state[0].dest = state[0].mask;
- state[0].mask = NULL;
- fz_try(ctx)
- {
- fz_draw_stroke_path(ctx, devp, path, stroke, ctm, fz_device_gray(ctx), &white, 1);
- }
- fz_always(ctx)
+ int x = (int)trm.e;
+ int y = (int)trm.f;
+ draw_glyph(NULL, mask, glyph, x, y, &bbox);
+ if (shape)
+ draw_glyph(NULL, shape, glyph, x, y, &bbox);
+ fz_drop_glyph(ctx, glyph);
+ }
+ else
+ {
+ fz_path *path = fz_outline_glyph(ctx, span->font, gid, &tm);
+ if (path)
{
- state[0].mask = state[0].dest;
- state[0].dest = old_dest;
- fz_drop_path(ctx, path);
+ fz_pixmap *old_dest;
+ float white = 1;
+
+ state = &dev->stack[dev->top];
+ old_dest = state[0].dest;
+ state[0].dest = state[0].mask;
+ state[0].mask = NULL;
+ fz_try(ctx)
+ {
+ fz_draw_stroke_path(ctx, devp, path, stroke, ctm, fz_device_gray(ctx), &white, 1);
+ }
+ fz_always(ctx)
+ {
+ state[0].mask = state[0].dest;
+ state[0].dest = old_dest;
+ fz_drop_path(ctx, path);
+ }
+ fz_catch(ctx)
+ {
+ fz_rethrow(ctx);
+ }
}
- fz_catch(ctx)
+ else
{
- fz_rethrow(ctx);
+ fz_warn(ctx, "cannot render glyph for stroked clipping");
}
}
- else
- {
- fz_warn(ctx, "cannot render glyph for stroked clipping");
- }
}
}
}
diff --git a/source/fitz/stext-device.c b/source/fitz/stext-device.c
index 4e14b298..060311d3 100644
--- a/source/fitz/stext-device.c
+++ b/source/fitz/stext-device.c
@@ -437,15 +437,15 @@ fz_lookup_stext_style_imp(fz_context *ctx, fz_stext_sheet *sheet,
}
static fz_stext_style *
-fz_lookup_stext_style(fz_context *ctx, fz_stext_sheet *sheet, fz_text *text, const fz_matrix *ctm,
+fz_lookup_stext_style(fz_context *ctx, fz_stext_sheet *sheet, fz_text_span *span, const fz_matrix *ctm,
fz_colorspace *colorspace, float *color, float alpha, fz_stroke_state *stroke)
{
float size = 1.0f;
- fz_font *font = text ? text->font : NULL;
- int wmode = text ? text->wmode : 0;
- if (ctm && text)
+ fz_font *font = span ? span->font : NULL;
+ int wmode = span ? span->wmode : 0;
+ if (ctm && span)
{
- fz_matrix tm = text->trm;
+ fz_matrix tm = span->trm;
fz_matrix trm;
tm.e = 0;
tm.f = 0;
@@ -744,11 +744,11 @@ fz_add_stext_char(fz_context *ctx, fz_stext_device *dev, fz_stext_style *style,
}
static void
-fz_stext_extract(fz_context *ctx, fz_stext_device *dev, fz_text *text, const fz_matrix *ctm, fz_stext_style *style)
+fz_stext_extract(fz_context *ctx, fz_stext_device *dev, fz_text_span *span, const fz_matrix *ctm, fz_stext_style *style)
{
- fz_font *font = text->font;
+ fz_font *font = span->font;
FT_Face face = font->ft_face;
- fz_matrix tm = text->trm;
+ fz_matrix tm = span->trm;
fz_matrix trm;
float adv;
float ascender = 1;
@@ -756,7 +756,7 @@ fz_stext_extract(fz_context *ctx, fz_stext_device *dev, fz_text *text, const fz_
int multi;
int i, j, err;
- if (text->len == 0)
+ if (span->len == 0)
return;
if (dev->spans == NULL)
@@ -792,36 +792,36 @@ fz_stext_extract(fz_context *ctx, fz_stext_device *dev, fz_text *text, const fz_
tm.f = 0;
fz_concat(&trm, &tm, ctm);
- for (i = 0; i < text->len; i++)
+ for (i = 0; i < span->len; i++)
{
/* Calculate new pen location and delta */
- tm.e = text->items[i].x;
- tm.f = text->items[i].y;
+ tm.e = span->items[i].x;
+ tm.f = span->items[i].y;
fz_concat(&trm, &tm, ctm);
/* Calculate bounding box and new pen position based on font metrics */
- adv = fz_advance_glyph(ctx, font, text->items[i].gid);
+ adv = fz_advance_glyph(ctx, font, span->items[i].gid);
/* Check for one glyph to many char mapping */
- for (j = i + 1; j < text->len; j++)
- if (text->items[j].gid >= 0)
+ for (j = i + 1; j < span->len; j++)
+ if (span->items[j].gid >= 0)
break;
multi = j - i;
if (multi == 1)
{
- fz_add_stext_char(ctx, dev, style, text->items[i].ucs, &trm, adv, text->wmode);
+ fz_add_stext_char(ctx, dev, style, span->items[i].ucs, &trm, adv, span->wmode);
}
else
{
for (j = 0; j < multi; j++)
{
- fz_add_stext_char(ctx, dev, style, text->items[i + j].ucs, &trm, adv/multi, text->wmode);
+ fz_add_stext_char(ctx, dev, style, span->items[i + j].ucs, &trm, adv/multi, span->wmode);
}
i += j - 1;
}
- dev->lastchar = text->items[i].ucs;
+ dev->lastchar = span->items[i].ucs;
}
}
@@ -831,8 +831,12 @@ fz_stext_fill_text(fz_context *ctx, fz_device *dev, fz_text *text, const fz_matr
{
fz_stext_device *tdev = (fz_stext_device*)dev;
fz_stext_style *style;
- style = fz_lookup_stext_style(ctx, tdev->sheet, text, ctm, colorspace, color, alpha, NULL);
- fz_stext_extract(ctx, tdev, text, ctm, style);
+ fz_text_span *span;
+ for (span = text->head; span; span = span->next)
+ {
+ style = fz_lookup_stext_style(ctx, tdev->sheet, span, ctm, colorspace, color, alpha, NULL);
+ fz_stext_extract(ctx, tdev, span, ctm, style);
+ }
}
static void
@@ -841,8 +845,12 @@ fz_stext_stroke_text(fz_context *ctx, fz_device *dev, fz_text *text, fz_stroke_s
{
fz_stext_device *tdev = (fz_stext_device*)dev;
fz_stext_style *style;
- style = fz_lookup_stext_style(ctx, tdev->sheet, text, ctm, colorspace, color, alpha, stroke);
- fz_stext_extract(ctx, tdev, text, ctm, style);
+ fz_text_span *span;
+ for (span = text->head; span; span = span->next)
+ {
+ style = fz_lookup_stext_style(ctx, tdev->sheet, span, ctm, colorspace, color, alpha, stroke);
+ fz_stext_extract(ctx, tdev, span, ctm, style);
+ }
}
static void
@@ -850,8 +858,12 @@ fz_stext_clip_text(fz_context *ctx, fz_device *dev, fz_text *text, const fz_matr
{
fz_stext_device *tdev = (fz_stext_device*)dev;
fz_stext_style *style;
- style = fz_lookup_stext_style(ctx, tdev->sheet, text, ctm, NULL, NULL, 0, NULL);
- fz_stext_extract(ctx, tdev, text, ctm, style);
+ fz_text_span *span;
+ for (span = text->head; span; span = span->next)
+ {
+ style = fz_lookup_stext_style(ctx, tdev->sheet, span, ctm, NULL, NULL, 0, NULL);
+ fz_stext_extract(ctx, tdev, span, ctm, style);
+ }
}
static void
@@ -859,8 +871,12 @@ fz_stext_clip_stroke_text(fz_context *ctx, fz_device *dev, fz_text *text, fz_str
{
fz_stext_device *tdev = (fz_stext_device*)dev;
fz_stext_style *style;
- style = fz_lookup_stext_style(ctx, tdev->sheet, text, ctm, NULL, NULL, 0, stroke);
- fz_stext_extract(ctx, tdev, text, ctm, style);
+ fz_text_span *span;
+ for (span = text->head; span; span = span->next)
+ {
+ style = fz_lookup_stext_style(ctx, tdev->sheet, span, ctm, NULL, NULL, 0, stroke);
+ fz_stext_extract(ctx, tdev, span, ctm, style);
+ }
}
static void
@@ -868,8 +884,12 @@ fz_stext_ignore_text(fz_context *ctx, fz_device *dev, fz_text *text, const fz_ma
{
fz_stext_device *tdev = (fz_stext_device*)dev;
fz_stext_style *style;
- style = fz_lookup_stext_style(ctx, tdev->sheet, text, ctm, NULL, NULL, 0, NULL);
- fz_stext_extract(ctx, tdev, text, ctm, style);
+ fz_text_span *span;
+ for (span = text->head; span; span = span->next)
+ {
+ style = fz_lookup_stext_style(ctx, tdev->sheet, span, ctm, NULL, NULL, 0, NULL);
+ fz_stext_extract(ctx, tdev, span, ctm, style);
+ }
}
static void
diff --git a/source/fitz/svg-device.c b/source/fitz/svg-device.c
index 4461f79e..a2cc5ed1 100644
--- a/source/fitz/svg-device.c
+++ b/source/fitz/svg-device.c
@@ -238,82 +238,86 @@ svg_dev_text(fz_context *ctx, svg_device *sdev, const fz_matrix *ctm, fz_text *t
fz_matrix local_trm;
float size;
int start, is_wspace, was_wspace;
+ fz_text_span *span;
- /* Rely on the fact that trm.{e,f} == 0 */
- size = fz_matrix_expansion(&text->trm);
- local_trm.a = text->trm.a / size;
- local_trm.b = text->trm.b / size;
- local_trm.c = -text->trm.c / size;
- local_trm.d = -text->trm.d / size;
- local_trm.e = 0;
- local_trm.f = 0;
- fz_invert_matrix(&inverse, &local_trm);
- fz_concat(&local_trm, &local_trm, ctm);
+ for (span = text->head; text; span = span->next)
+ {
+ /* Rely on the fact that trm.{e,f} == 0 */
+ size = fz_matrix_expansion(&span->trm);
+ local_trm.a = span->trm.a / size;
+ local_trm.b = span->trm.b / size;
+ local_trm.c = -span->trm.c / size;
+ local_trm.d = -span->trm.d / size;
+ local_trm.e = 0;
+ local_trm.f = 0;
+ fz_invert_matrix(&inverse, &local_trm);
+ fz_concat(&local_trm, &local_trm, ctm);
- fz_printf(ctx, out, " transform=\"matrix(%g,%g,%g,%g,%g,%g)\"",
- local_trm.a, local_trm.b, local_trm.c, local_trm.d, local_trm.e, local_trm.f);
- fz_printf(ctx, out, " font-size=\"%g\"", size);
- fz_printf(ctx, out, " font-family=\"%s\"", text->font->name);
+ fz_printf(ctx, out, " transform=\"matrix(%g,%g,%g,%g,%g,%g)\"",
+ local_trm.a, local_trm.b, local_trm.c, local_trm.d, local_trm.e, local_trm.f);
+ fz_printf(ctx, out, " font-size=\"%g\"", size);
+ fz_printf(ctx, out, " font-family=\"%s\"", span->font->name);
- /* Leading (and repeated) whitespace presents a problem for SVG
- * text, so elide it here. */
- for (start=0; start < text->len; start++)
- {
- fz_text_item *it = &text->items[start];
- if (!is_xml_wspace(it->ucs))
- break;
- }
+ /* Leading (and repeated) whitespace presents a problem for SVG
+ * text, so elide it here. */
+ for (start=0; start < span->len; start++)
+ {
+ fz_text_item *it = &span->items[start];
+ if (!is_xml_wspace(it->ucs))
+ break;
+ }
- fz_printf(ctx, out, " x=");
- was_wspace = 0;
- for (i=start; i < text->len; i++)
- {
- fz_text_item *it = &text->items[i];
- fz_point p;
- is_wspace = is_xml_wspace(it->ucs);
- if (is_wspace && was_wspace)
- continue;
- was_wspace = is_wspace;
- p.x = it->x;
- p.y = it->y;
- fz_transform_point(&p, &inverse);
- fz_printf(ctx, out, "%c%g", i == start ? '\"' : ' ', p.x);
- }
- fz_printf(ctx, out, "\" y=");
- was_wspace = 0;
- for (i=start; i < text->len; i++)
- {
- fz_text_item *it = &text->items[i];
- fz_point p;
- is_wspace = is_xml_wspace(it->ucs);
- if (is_wspace && was_wspace)
- continue;
- was_wspace = is_wspace;
- p.x = it->x;
- p.y = it->y;
- fz_transform_point(&p, &inverse);
- fz_printf(ctx, out, "%c%g", i == start ? '\"' : ' ', p.y);
- }
- fz_printf(ctx, out, "\">\n");
- was_wspace = 0;
- for (i=start; i < text->len; i++)
- {
- fz_text_item *it = &text->items[i];
- int c = it->ucs;
- is_wspace = is_xml_wspace(c);
- if (is_wspace && was_wspace)
- continue;
- was_wspace = is_wspace;
- if (c >= 32 && c <= 127 && c != '<' && c != '&')
- fz_printf(ctx, out, "%c", c);
- else
- fz_printf(ctx, out, "&#x%04x;", c);
+ fz_printf(ctx, out, " x=");
+ was_wspace = 0;
+ for (i=start; i < span->len; i++)
+ {
+ fz_text_item *it = &span->items[i];
+ fz_point p;
+ is_wspace = is_xml_wspace(it->ucs);
+ if (is_wspace && was_wspace)
+ continue;
+ was_wspace = is_wspace;
+ p.x = it->x;
+ p.y = it->y;
+ fz_transform_point(&p, &inverse);
+ fz_printf(ctx, out, "%c%g", i == start ? '\"' : ' ', p.x);
+ }
+ fz_printf(ctx, out, "\" y=");
+ was_wspace = 0;
+ for (i=start; i < span->len; i++)
+ {
+ fz_text_item *it = &span->items[i];
+ fz_point p;
+ is_wspace = is_xml_wspace(it->ucs);
+ if (is_wspace && was_wspace)
+ continue;
+ was_wspace = is_wspace;
+ p.x = it->x;
+ p.y = it->y;
+ fz_transform_point(&p, &inverse);
+ fz_printf(ctx, out, "%c%g", i == start ? '\"' : ' ', p.y);
+ }
+ fz_printf(ctx, out, "\">\n");
+ was_wspace = 0;
+ for (i=start; i < span->len; i++)
+ {
+ fz_text_item *it = &span->items[i];
+ int c = it->ucs;
+ is_wspace = is_xml_wspace(c);
+ if (is_wspace && was_wspace)
+ continue;
+ was_wspace = is_wspace;
+ if (c >= 32 && c <= 127 && c != '<' && c != '&')
+ fz_printf(ctx, out, "%c", c);
+ else
+ fz_printf(ctx, out, "&#x%04x;", c);
+ }
+ fz_printf(ctx, out, "\n</text>\n");
}
- fz_printf(ctx, out, "\n</text>\n");
}
static font *
-svg_dev_text_as_paths_defs(fz_context *ctx, fz_device *dev, fz_text *text, const fz_matrix *ctm)
+svg_dev_text_span_as_paths_defs(fz_context *ctx, fz_device *dev, fz_text_span *span, const fz_matrix *ctm)
{
svg_device *sdev = (svg_device*)dev;
fz_output *out = sdev->out;
@@ -323,7 +327,7 @@ svg_dev_text_as_paths_defs(fz_context *ctx, fz_device *dev, fz_text *text, const
for (font_idx = 0; font_idx < sdev->num_fonts; font_idx++)
{
- if (sdev->fonts[font_idx].font == text->font)
+ if (sdev->fonts[font_idx].font == span->font)
break;
}
if (font_idx == sdev->num_fonts)
@@ -339,14 +343,14 @@ svg_dev_text_as_paths_defs(fz_context *ctx, fz_device *dev, fz_text *text, const
sdev->max_fonts = newmax;
}
sdev->fonts[font_idx].id = sdev->id++;
- sdev->fonts[font_idx].font = fz_keep_font(ctx, text->font);
+ sdev->fonts[font_idx].font = fz_keep_font(ctx, span->font);
sdev->num_fonts++;
}
fnt = &sdev->fonts[font_idx];
- for (i=0; i < text->len; i++)
+ for (i=0; i < span->len; i++)
{
- fz_text_item *it = &text->items[i];
+ fz_text_item *it = &span->items[i];
int gid = it->gid;
if (gid < 0)
@@ -367,7 +371,7 @@ svg_dev_text_as_paths_defs(fz_context *ctx, fz_device *dev, fz_text *text, const
/* Need to send this one */
fz_rect rect;
fz_path *path;
- path = fz_outline_glyph(ctx, text->font, gid, &fz_identity);
+ path = fz_outline_glyph(ctx, span->font, gid, &fz_identity);
if (path)
{
fz_bound_path(ctx, path, NULL, &fz_identity, &rect);
@@ -382,12 +386,12 @@ svg_dev_text_as_paths_defs(fz_context *ctx, fz_device *dev, fz_text *text, const
}
else
{
- fz_bound_glyph(ctx, text->font, gid, &fz_identity, &rect);
+ fz_bound_glyph(ctx, span->font, gid, &fz_identity, &rect);
shift.e = -rect.x0;
shift.f = -rect.y0;
out = start_def(ctx, sdev);
fz_printf(ctx, out, "<symbol id=\"font_%x_%x\">", fnt->id, gid);
- fz_run_t3_glyph(ctx, text->font, gid, &shift, dev);
+ fz_run_t3_glyph(ctx, span->font, gid, &shift, dev);
}
fz_printf(ctx, out, "</symbol>");
out = end_def(ctx, sdev);
@@ -399,7 +403,7 @@ svg_dev_text_as_paths_defs(fz_context *ctx, fz_device *dev, fz_text *text, const
}
static void
-svg_dev_text_as_paths_fill(fz_context *ctx, fz_device *dev, fz_text *text, const fz_matrix *ctm,
+svg_dev_text_span_as_paths_fill(fz_context *ctx, fz_device *dev, fz_text_span *span, const fz_matrix *ctm,
fz_colorspace *colorspace, float *color, float alpha, font *fnt)
{
svg_device *sdev = (svg_device*)dev;
@@ -410,16 +414,16 @@ svg_dev_text_as_paths_fill(fz_context *ctx, fz_device *dev, fz_text *text, const
fz_matrix shift = { 1, 0, 0, 1, 0, 0};
/* Rely on the fact that trm.{e,f} == 0 */
- local_trm.a = text->trm.a;
- local_trm.b = text->trm.b;
- local_trm.c = text->trm.c;
- local_trm.d = text->trm.d;
+ local_trm.a = span->trm.a;
+ local_trm.b = span->trm.b;
+ local_trm.c = span->trm.c;
+ local_trm.d = span->trm.d;
local_trm.e = 0;
local_trm.f = 0;
- for (i=0; i < text->len; i++)
+ for (i=0; i < span->len; i++)
{
- fz_text_item *it = &text->items[i];
+ fz_text_item *it = &span->items[i];
int gid = it->gid;
if (gid < 0)
@@ -439,7 +443,7 @@ svg_dev_text_as_paths_fill(fz_context *ctx, fz_device *dev, fz_text *text, const
}
static void
-svg_dev_text_as_paths_stroke(fz_context *ctx, fz_device *dev, fz_text *text,
+svg_dev_text_span_as_paths_stroke(fz_context *ctx, fz_device *dev, fz_text_span *span,
fz_stroke_state *stroke, const fz_matrix *ctm,
fz_colorspace *colorspace, float *color, float alpha, font *fnt)
{
@@ -451,16 +455,16 @@ svg_dev_text_as_paths_stroke(fz_context *ctx, fz_device *dev, fz_text *text,
fz_matrix shift = { 1, 0, 0, 1, 0, 0};
/* Rely on the fact that trm.{e,f} == 0 */
- local_trm.a = text->trm.a;
- local_trm.b = text->trm.b;
- local_trm.c = text->trm.c;
- local_trm.d = text->trm.d;
+ local_trm.a = span->trm.a;
+ local_trm.b = span->trm.b;
+ local_trm.c = span->trm.c;
+ local_trm.d = span->trm.d;
local_trm.e = 0;
local_trm.f = 0;
- for (i=0; i < text->len; i++)
+ for (i=0; i < span->len; i++)
{
- fz_text_item *it = &text->items[i];
+ fz_text_item *it = &span->items[i];
int gid = it->gid;
if (gid < 0)
@@ -566,12 +570,16 @@ svg_dev_fill_text(fz_context *ctx, fz_device *dev, fz_text *text, const fz_matri
fz_output *out = sdev->out;
font *fnt;
+ fz_text_span *span;
fz_printf(ctx, out, "<text");
svg_dev_fill_color(ctx, sdev, colorspace, color, 0.0f);
svg_dev_text(ctx, sdev, ctm, text);
- fnt = svg_dev_text_as_paths_defs(ctx, dev, text, ctm);
- svg_dev_text_as_paths_fill(ctx, dev, text, ctm, colorspace, color, alpha, fnt);
+ for (span = text->head; span; span = span->next)
+ {
+ fnt = svg_dev_text_span_as_paths_defs(ctx, dev, span, ctm);
+ svg_dev_text_span_as_paths_fill(ctx, dev, span, ctm, colorspace, color, alpha, fnt);
+ }
}
static void
@@ -582,12 +590,16 @@ svg_dev_stroke_text(fz_context *ctx, fz_device *dev, fz_text *text, fz_stroke_st
fz_output *out = sdev->out;
font *fnt;
+ fz_text_span *span;
fz_printf(ctx, out, "<text");
svg_dev_fill_color(ctx, sdev, colorspace, color, 0.0f);
svg_dev_text(ctx, sdev, ctm, text);
- fnt = svg_dev_text_as_paths_defs(ctx, dev, text, ctm);
- svg_dev_text_as_paths_stroke(ctx, dev, text, stroke, ctm, colorspace, color, alpha, fnt);
+ for (span = text->head; span; span = span->next)
+ {
+ fnt = svg_dev_text_span_as_paths_defs(ctx, dev, span, ctm);
+ svg_dev_text_span_as_paths_stroke(ctx, dev, span, stroke, ctm, colorspace, color, alpha, fnt);
+ }
}
static void
@@ -600,6 +612,7 @@ svg_dev_clip_text(fz_context *ctx, fz_device *dev, fz_text *text, const fz_matri
int num = sdev->id++;
float white[3] = { 1, 1, 1 };
font *fnt;
+ fz_text_span *span;
fz_bound_text(ctx, text, NULL, ctm, &bounds);
@@ -609,8 +622,11 @@ svg_dev_clip_text(fz_context *ctx, fz_device *dev, fz_text *text, const fz_matri
fz_printf(ctx, out, "<text");
svg_dev_fill_color(ctx, sdev, fz_device_rgb(ctx), white, 0.0f);
svg_dev_text(ctx, sdev, ctm, text);
- fnt = svg_dev_text_as_paths_defs(ctx, dev, text, ctm);
- svg_dev_text_as_paths_fill(ctx, dev, text, ctm, fz_device_rgb(ctx), white, 1.0f, fnt);
+ for (span = text->head; span; span = span->next)
+ {
+ fnt = svg_dev_text_span_as_paths_defs(ctx, dev, span, ctm);
+ svg_dev_text_span_as_paths_fill(ctx, dev, span, ctm, fz_device_rgb(ctx), white, 1.0f, fnt);
+ }
fz_printf(ctx, out, "</mask>\n");
out = end_def(ctx, sdev);
fz_printf(ctx, out, "<g mask=\"url(#ma%d)\">\n", num);
@@ -626,6 +642,7 @@ svg_dev_clip_stroke_text(fz_context *ctx, fz_device *dev, fz_text *text, fz_stro
int num = sdev->id++;
float white[3] = { 255, 255, 255 };
font *fnt;
+ fz_text_span *span;
fz_bound_text(ctx, text, NULL, ctm, &bounds);
@@ -636,8 +653,11 @@ svg_dev_clip_stroke_text(fz_context *ctx, fz_device *dev, fz_text *text, fz_stro
svg_dev_stroke_state(ctx, sdev, stroke, &fz_identity);
svg_dev_stroke_color(ctx, sdev, fz_device_rgb(ctx), white, 0.0f);
svg_dev_text(ctx, sdev, ctm, text);
- fnt = svg_dev_text_as_paths_defs(ctx, dev, text, ctm);
- svg_dev_text_as_paths_stroke(ctx, dev, text, stroke, ctm, fz_device_rgb(ctx), white, 1.0f, fnt);
+ for (span = text->head; span; span = span->next)
+ {
+ fnt = svg_dev_text_span_as_paths_defs(ctx, dev, span, ctm);
+ svg_dev_text_span_as_paths_stroke(ctx, dev, span, stroke, ctm, fz_device_rgb(ctx), white, 1.0f, fnt);
+ }
fz_printf(ctx, out, "</mask>\n");
out = end_def(ctx, sdev);
fz_printf(ctx, out, "<g mask=\"url(#ma%d)\">\n", num);
diff --git a/source/fitz/text.c b/source/fitz/text.c
index 0616d6a9..f90fee53 100644
--- a/source/fitz/text.c
+++ b/source/fitz/text.c
@@ -1,19 +1,10 @@
#include "mupdf/fitz.h"
fz_text *
-fz_new_text(fz_context *ctx, fz_font *font, const fz_matrix *trm, int wmode)
+fz_new_text(fz_context *ctx)
{
- fz_text *text;
-
- text = fz_malloc_struct(ctx, fz_text);
+ fz_text *text = fz_malloc_struct(ctx, fz_text);
text->refs = 1;
- text->font = fz_keep_font(ctx, font);
- text->trm = *trm;
- text->wmode = wmode;
- text->len = 0;
- text->cap = 0;
- text->items = NULL;
-
return text;
}
@@ -28,84 +19,122 @@ fz_drop_text(fz_context *ctx, fz_text *text)
{
if (fz_drop_imp(ctx, text, &text->refs))
{
- fz_drop_font(ctx, text->font);
- fz_free(ctx, text->items);
+ fz_text_span *span = text->head;
+ while (span)
+ {
+ fz_text_span *next = span->next;
+ fz_drop_font(ctx, span->font);
+ fz_free(ctx, span->items);
+ fz_free(ctx, span);
+ span = next;
+ }
fz_free(ctx, text);
}
}
-fz_rect *
-fz_bound_text(fz_context *ctx, fz_text *text, const fz_stroke_state *stroke, const fz_matrix *ctm, fz_rect *bbox)
+static fz_text_span *
+fz_new_text_span(fz_context *ctx, fz_font *font, int wmode, const fz_matrix *trm)
{
- fz_matrix tm, trm;
- fz_rect gbox;
- int i;
+ fz_text_span *span = fz_malloc_struct(ctx, fz_text_span);
+ span->font = fz_keep_font(ctx, font);
+ span->wmode = wmode;
+ span->trm = *trm;
+ span->trm.e = 0;
+ span->trm.f = 0;
+ return span;
+}
- if (text->len == 0)
+static fz_text_span *
+fz_add_text_span(fz_context *ctx, fz_text *text, fz_font *font, int wmode, const fz_matrix *trm)
+{
+ if (!text->tail)
{
- *bbox = fz_empty_rect;
- return bbox;
+ text->head = text->tail = fz_new_text_span(ctx, font, wmode, trm);
}
-
- // TODO: stroke state
-
- tm = text->trm;
-
- tm.e = text->items[0].x;
- tm.f = text->items[0].y;
- fz_concat(&trm, &tm, ctm);
- fz_bound_glyph(ctx, text->font, text->items[0].gid, &trm, bbox);
-
- for (i = 1; i < text->len; i++)
+ else if (text->tail->font != font ||
+ text->tail->wmode != wmode ||
+ text->tail->trm.a != trm->a ||
+ text->tail->trm.b != trm->b ||
+ text->tail->trm.c != trm->c ||
+ text->tail->trm.d != trm->d)
{
- if (text->items[i].gid >= 0)
- {
- tm.e = text->items[i].x;
- tm.f = text->items[i].y;
- fz_concat(&trm, &tm, ctm);
- fz_bound_glyph(ctx, text->font, text->items[i].gid, &trm, &gbox);
-
- bbox->x0 = fz_min(bbox->x0, gbox.x0);
- bbox->y0 = fz_min(bbox->y0, gbox.y0);
- bbox->x1 = fz_max(bbox->x1, gbox.x1);
- bbox->y1 = fz_max(bbox->y1, gbox.y1);
- }
+ text->tail = text->tail->next = fz_new_text_span(ctx, font, wmode, trm);
}
-
- if (stroke)
- fz_adjust_rect_for_stroke(ctx, bbox, stroke, ctm);
-
- /* Compensate for the glyph cache limited positioning precision */
- bbox->x0 -= 1;
- bbox->y0 -= 1;
- bbox->x1 += 1;
- bbox->y1 += 1;
-
- return bbox;
+ return text->tail;
}
static void
-fz_grow_text(fz_context *ctx, fz_text *text, int n)
+fz_grow_text_span(fz_context *ctx, fz_text_span *span, int n)
{
- int new_cap = text->cap;
- if (text->len + n < new_cap)
+ int new_cap = span->cap;
+ if (span->len + n < new_cap)
return;
- while (text->len + n > new_cap)
+ while (span->len + n > new_cap)
new_cap = new_cap + 36;
- text->items = fz_resize_array(ctx, text->items, new_cap, sizeof(fz_text_item));
- text->cap = new_cap;
+ span->items = fz_resize_array(ctx, span->items, new_cap, sizeof(fz_text_item));
+ span->cap = new_cap;
}
void
-fz_add_text(fz_context *ctx, fz_text *text, int gid, int ucs, float x, float y)
+fz_add_text(fz_context *ctx, fz_text *text, fz_font *font, int wmode, const fz_matrix *trm, int gid, int ucs)
{
+ fz_text_span *span;
+
if (text->refs != 1)
fz_throw(ctx, FZ_ERROR_GENERIC, "cannot modify shared text objects");
- fz_grow_text(ctx, text, 1);
- text->items[text->len].ucs = ucs;
- text->items[text->len].gid = gid;
- text->items[text->len].x = x;
- text->items[text->len].y = y;
- text->len++;
+ span = fz_add_text_span(ctx, text, font, wmode, trm);
+
+ fz_grow_text_span(ctx, span, 1);
+
+ span->items[span->len].ucs = ucs;
+ span->items[span->len].gid = gid;
+ span->items[span->len].x = trm->e;
+ span->items[span->len].y = trm->f;
+ span->len++;
+}
+
+fz_rect *
+fz_bound_text(fz_context *ctx, fz_text *text, const fz_stroke_state *stroke, const fz_matrix *ctm, fz_rect *bbox)
+{
+ fz_text_span *span;
+ fz_matrix tm, trm;
+ fz_rect gbox;
+ int i;
+
+ *bbox = fz_empty_rect;
+
+ for (span = text->head; span; span = span->next)
+ {
+ if (span->len > 0)
+ {
+ tm = span->trm;
+ for (i = 0; i < span->len; i++)
+ {
+ if (span->items[i].gid >= 0)
+ {
+ tm.e = span->items[i].x;
+ tm.f = span->items[i].y;
+ fz_concat(&trm, &tm, ctm);
+ fz_bound_glyph(ctx, span->font, span->items[i].gid, &trm, &gbox);
+ fz_union_rect(bbox, &gbox);
+ }
+ }
+
+ }
+ }
+
+ if (!fz_is_empty_rect(bbox))
+ {
+ if (stroke)
+ fz_adjust_rect_for_stroke(ctx, bbox, stroke, ctm);
+
+ /* Compensate for the glyph cache limited positioning precision */
+ bbox->x0 -= 1;
+ bbox->y0 -= 1;
+ bbox->x1 += 1;
+ bbox->y1 += 1;
+ }
+
+ return bbox;
}
diff --git a/source/fitz/trace-device.c b/source/fitz/trace-device.c
index 59ea8ad8..df2f6455 100644
--- a/source/fitz/trace-device.c
+++ b/source/fitz/trace-device.c
@@ -14,13 +14,6 @@ fz_trace_matrix(fz_context *ctx, fz_output *out, const fz_matrix *ctm)
}
static void
-fz_trace_trm(fz_context *ctx, fz_output *out, const fz_matrix *trm)
-{
- fz_printf(ctx, out, " trm=\"%g %g %g %g\"",
- trm->a, trm->b, trm->c, trm->d);
-}
-
-static void
fz_trace_color(fz_context *ctx, fz_output *out, fz_colorspace *colorspace, float *color, float alpha)
{
int i;
@@ -32,6 +25,38 @@ fz_trace_color(fz_context *ctx, fz_output *out, fz_colorspace *colorspace, float
fz_printf(ctx, out, " alpha=\"%g\"", alpha);
}
+static int
+isxmlmeta(int c)
+{
+ return c < 32 || c >= 128 || c == '&' || c == '<' || c == '>' || c == '\'' || c == '"';
+}
+
+static void
+fz_trace_text_span(fz_context *ctx, fz_output *out, fz_text_span *span)
+{
+ int i;
+ fz_printf(ctx, out, "<span font=\"%s\" wmode=\"%d\"", span->font->name, span->wmode);
+ fz_printf(ctx, out, " trm=\"%g %g %g %g\">\n", span->trm.a, span->trm.b, span->trm.c, span->trm.d);
+ for (i = 0; i < span->len; i++)
+ {
+ if (!isxmlmeta(span->items[i].ucs))
+ fz_printf(ctx, out, "<g ucs=\"%c\" gid=\"%d\" x=\"%g\" y=\"%g\" />\n",
+ span->items[i].ucs, span->items[i].gid, span->items[i].x, span->items[i].y);
+ else
+ fz_printf(ctx, out, "<g ucs=\"U+%04X\" gid=\"%d\" x=\"%g\" y=\"%g\" />\n",
+ span->items[i].ucs, span->items[i].gid, span->items[i].x, span->items[i].y);
+ }
+ fz_printf(ctx, out, "</span>\n");
+}
+
+static void
+fz_trace_text(fz_context *ctx, fz_output *out, fz_text *text)
+{
+ fz_text_span *span;
+ for (span = text->head; span; span = span->next)
+ fz_trace_text_span(ctx, out, span);
+}
+
static void
trace_moveto(fz_context *ctx, void *arg, float x, float y)
{
@@ -166,36 +191,14 @@ fz_trace_clip_stroke_path(fz_context *ctx, fz_device *dev, fz_path *path, const
fz_printf(ctx, out, "</clip_stroke_path>\n");
}
-static int
-isxmlmeta(int c)
-{
- return c < 32 || c >= 128 || c == '&' || c == '<' || c == '>' || c == '\'' || c == '"';
-}
-
-static void
-fz_trace_text(fz_context *ctx, fz_output *out, fz_text *text)
-{
- int i;
- for (i = 0; i < text->len; i++)
- {
- if (!isxmlmeta(text->items[i].ucs))
- fz_printf(ctx, out, "<g ucs=\"%c\" gid=\"%d\" x=\"%g\" y=\"%g\" />\n",
- text->items[i].ucs, text->items[i].gid, text->items[i].x, text->items[i].y);
- else
- fz_printf(ctx, out, "<g ucs=\"U+%04X\" gid=\"%d\" x=\"%g\" y=\"%g\" />\n",
- text->items[i].ucs, text->items[i].gid, text->items[i].x, text->items[i].y);
- }
-}
-
static void
fz_trace_fill_text(fz_context *ctx, fz_device *dev, fz_text *text, const fz_matrix *ctm,
fz_colorspace *colorspace, float *color, float alpha)
{
fz_output *out = ((fz_trace_device*)dev)->out;
- fz_printf(ctx, out, "<fill_text font=\"%s\" wmode=\"%d\"", text->font->name, text->wmode);
+ fz_printf(ctx, out, "<fill_text");
fz_trace_color(ctx, out, colorspace, color, alpha);
fz_trace_matrix(ctx, out, ctm);
- fz_trace_trm(ctx, out, &text->trm);
fz_printf(ctx, out, ">\n");
fz_trace_text(ctx, out, text);
fz_printf(ctx, out, "</fill_text>\n");
@@ -206,10 +209,9 @@ fz_trace_stroke_text(fz_context *ctx, fz_device *dev, fz_text *text, fz_stroke_s
fz_colorspace *colorspace, float *color, float alpha)
{
fz_output *out = ((fz_trace_device*)dev)->out;
- fz_printf(ctx, out, "<stroke_text font=\"%s\" wmode=\"%d\"", text->font->name, text->wmode);
+ fz_printf(ctx, out, "<stroke_text");
fz_trace_color(ctx, out, colorspace, color, alpha);
fz_trace_matrix(ctx, out, ctm);
- fz_trace_trm(ctx, out, &text->trm);
fz_printf(ctx, out, ">\n");
fz_trace_text(ctx, out, text);
fz_printf(ctx, out, "</stroke_text>\n");
@@ -219,10 +221,8 @@ static void
fz_trace_clip_text(fz_context *ctx, fz_device *dev, fz_text *text, const fz_matrix *ctm, int accumulate)
{
fz_output *out = ((fz_trace_device*)dev)->out;
- fz_printf(ctx, out, "<clip_text font=\"%s\" wmode=\"%d\"", text->font->name, text->wmode);
- fz_printf(ctx, out, " accumulate=\"%d\"", accumulate);
+ fz_printf(ctx, out, "<clip_text");
fz_trace_matrix(ctx, out, ctm);
- fz_trace_trm(ctx, out, &text->trm);
fz_printf(ctx, out, ">\n");
fz_trace_text(ctx, out, text);
fz_printf(ctx, out, "</clip_text>\n");
@@ -232,9 +232,8 @@ static void
fz_trace_clip_stroke_text(fz_context *ctx, fz_device *dev, fz_text *text, fz_stroke_state *stroke, const fz_matrix *ctm)
{
fz_output *out = ((fz_trace_device*)dev)->out;
- fz_printf(ctx, out, "<clip_stroke_text font=\"%s\" wmode=\"%d\"", text->font->name, text->wmode);
+ fz_printf(ctx, out, "<clip_stroke_text");
fz_trace_matrix(ctx, out, ctm);
- fz_trace_trm(ctx, out, &text->trm);
fz_printf(ctx, out, ">\n");
fz_trace_text(ctx, out, text);
fz_printf(ctx, out, "</clip_stroke_text>\n");
@@ -244,9 +243,8 @@ static void
fz_trace_ignore_text(fz_context *ctx, fz_device *dev, fz_text *text, const fz_matrix *ctm)
{
fz_output *out = ((fz_trace_device*)dev)->out;
- fz_printf(ctx, out, "<ignore_text font=\"%s\" wmode=\"%d\"", text->font->name, text->wmode);
+ fz_printf(ctx, out, "<ignore_text");
fz_trace_matrix(ctx, out, ctm);
- fz_trace_trm(ctx, out, &text->trm);
fz_printf(ctx, out, ">\n");
fz_trace_text(ctx, out, text);
fz_printf(ctx, out, "</ignore_text>\n");
diff --git a/source/html/html-layout.c b/source/html/html-layout.c
index f742969c..b7e2b779 100644
--- a/source/html/html-layout.c
+++ b/source/html/html-layout.c
@@ -825,11 +825,9 @@ static void draw_flow_box(fz_context *ctx, fz_html *box, float page_top, float p
{
fz_html_flow *node;
fz_text *text;
- fz_text *falltext;
fz_matrix trm;
const char *s;
float color[3];
- float x, y;
int c, g;
for (node = box->flow_head; node; node = node->next)
@@ -853,11 +851,11 @@ static void draw_flow_box(fz_context *ctx, fz_html *box, float page_top, float p
color[1] = node->style->color.g / 255.0f;
color[2] = node->style->color.b / 255.0f;
- text = NULL;
- falltext = NULL;
+ /* TODO: reuse text object if color is unchanged */
+ text = fz_new_text(ctx);
- x = node->x;
- y = node->y;
+ trm.e = node->x;
+ trm.f = node->y;
s = node->text;
while (*s)
{
@@ -866,12 +864,8 @@ static void draw_flow_box(fz_context *ctx, fz_html *box, float page_top, float p
if (g)
{
if (node->style->visibility == V_VISIBLE)
- {
- if (!text)
- text = fz_new_text(ctx, node->style->font, &trm, 0);
- fz_add_text(ctx, text, g, c, x, y);
- }
- x += fz_advance_glyph(ctx, node->style->font, g) * node->em;
+ fz_add_text(ctx, text, node->style->font, 0, &trm, g, c);
+ trm.e += fz_advance_glyph(ctx, node->style->font, g) * node->em;
}
else
{
@@ -879,13 +873,16 @@ static void draw_flow_box(fz_context *ctx, fz_html *box, float page_top, float p
if (g)
{
if (node->style->visibility == V_VISIBLE)
- {
- if (!falltext)
- falltext = fz_new_text(ctx, node->style->fallback, &trm, 0);
- fz_add_text(ctx, falltext, g, c, x, y);
- }
+ fz_add_text(ctx, text, node->style->fallback, 0, &trm, g, c);
+ trm.e += fz_advance_glyph(ctx, node->style->fallback, g) * node->em;
+ }
+ else
+ {
+ g = fz_encode_character(ctx, node->style->font, 0x25CF); /* bullet */
+ if (node->style->visibility == V_VISIBLE)
+ fz_add_text(ctx, text, node->style->font, 0, &trm, g, c);
+ trm.e += fz_advance_glyph(ctx, node->style->font, g) * node->em;
}
- x += fz_advance_glyph(ctx, node->style->fallback, g) * node->em;
}
}
@@ -894,11 +891,6 @@ static void draw_flow_box(fz_context *ctx, fz_html *box, float page_top, float p
fz_fill_text(ctx, dev, text, ctm, fz_device_rgb(ctx), color, 1);
fz_drop_text(ctx, text);
}
- if (falltext)
- {
- fz_fill_text(ctx, dev, falltext, ctm, fz_device_rgb(ctx), color, 1);
- fz_drop_text(ctx, falltext);
- }
}
else if (node->type == FLOW_IMAGE)
{
@@ -1039,14 +1031,15 @@ static void draw_list_mark(fz_context *ctx, fz_html *box, float page_top, float
fz_text *text;
fz_matrix trm;
fz_html_flow *line;
- float x, y, w;
+ float y, w;
float color[3];
const char *s;
char buf[40];
int c, g;
fz_scale(&trm, box->em, -box->em);
- text = fz_new_text(ctx, box->style.font, &trm, 0);
+
+ text = fz_new_text(ctx);
line = find_list_mark_anchor(ctx, box);
if (line)
@@ -1078,13 +1071,14 @@ static void draw_list_mark(fz_context *ctx, fz_html *box, float page_top, float
}
s = buf;
- x = box->x - w;
+ trm.e = box->x - w;
+ trm.f = y;
while (*s)
{
s += fz_chartorune(&c, s);
g = fz_encode_character(ctx, box->style.font, c);
- fz_add_text(ctx, text, g, c, x, y);
- x += fz_advance_glyph(ctx, box->style.font, g) * box->em;
+ fz_add_text(ctx, text, box->style.font, 0, &trm, g, c);
+ trm.e += fz_advance_glyph(ctx, box->style.font, g) * box->em;
}
color[0] = box->style.color.r / 255.0f;
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;
}
diff --git a/source/xps/xps-glyphs.c b/source/xps/xps-glyphs.c
index 06d2820d..4434c4ed 100644
--- a/source/xps/xps-glyphs.c
+++ b/source/xps/xps-glyphs.c
@@ -348,7 +348,6 @@ xps_parse_glyphs_imp(fz_context *ctx, xps_document *doc, const fz_matrix *ctm,
xps_glyph_metrics mtx;
fz_text *text;
fz_matrix tm;
- float e, f;
float x = originx;
float y = originy;
char *us = unicode;
@@ -372,7 +371,7 @@ xps_parse_glyphs_imp(fz_context *ctx, xps_document *doc, const fz_matrix *ctm,
else
fz_scale(&tm, size, -size);
- text = fz_new_text(ctx, font, &tm, is_sideways);
+ text = fz_new_text(ctx);
while ((us && un > 0) || (is && *is))
{
@@ -440,16 +439,16 @@ xps_parse_glyphs_imp(fz_context *ctx, xps_document *doc, const fz_matrix *ctm,
if (is_sideways)
{
- e = x + u_offset + (mtx.vorg * size);
- f = y - v_offset + (mtx.hadv * 0.5f * size);
+ tm.e = x + u_offset + (mtx.vorg * size);
+ tm.f = y - v_offset + (mtx.hadv * 0.5f * size);
}
else
{
- e = x + u_offset;
- f = y - v_offset;
+ tm.e = x + u_offset;
+ tm.f = y - v_offset;
}
- fz_add_text(ctx, text, glyph_index, char_code, e, f);
+ fz_add_text(ctx, text, font, is_sideways, &tm, glyph_index, char_code);
x += advance * 0.01f * size;
}