summaryrefslogtreecommitdiff
path: root/source/fitz
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/fitz
parente3275837d5738c5092b2e452829919e31ad553e5 (diff)
downloadmupdf-fa0bffa57e7e2164f0201b0f2fdc984d475674ae.tar.xz
Keep spans of multiple fonts and sizes in one fz_text object.
Diffstat (limited to 'source/fitz')
-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
5 files changed, 477 insertions, 392 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");