diff options
author | Tor Andersson <tor.andersson@artifex.com> | 2012-07-17 18:05:05 +0200 |
---|---|---|
committer | Tor Andersson <tor.andersson@artifex.com> | 2012-07-17 18:05:05 +0200 |
commit | 4091b7a357728aed033216baafed540b795bcf9e (patch) | |
tree | ad0cd73cc428bc8922d1eaa94663479c04192edb | |
parent | 2b857ab9878d5ca8acd862ae58dafa8d269bc502 (diff) | |
download | mupdf-4091b7a357728aed033216baafed540b795bcf9e.tar.xz |
Handle glyphs that are too large to render as pixmaps.
-rw-r--r-- | draw/draw_device.c | 36 | ||||
-rw-r--r-- | draw/draw_glyph.c | 44 | ||||
-rw-r--r-- | fitz/fitz-internal.h | 9 | ||||
-rw-r--r-- | fitz/res_font.c | 154 | ||||
-rw-r--r-- | fitz/res_path.c | 34 | ||||
-rw-r--r-- | xps/xps_path.c | 62 |
6 files changed, 262 insertions, 77 deletions
diff --git a/draw/draw_device.c b/draw/draw_device.c index 6f74eabf..2eaf1d49 100644 --- a/draw/draw_device.c +++ b/draw/draw_device.c @@ -463,11 +463,12 @@ fz_draw_fill_text(fz_device *devp, fz_text *text, fz_matrix ctm, unsigned char colorbv[FZ_MAX_COLORS + 1]; unsigned char shapebv; float colorfv[FZ_MAX_COLORS]; - fz_matrix tm, trm; + fz_matrix tm, trm, trunc_trm; fz_pixmap *glyph; int i, x, y, gid; fz_draw_state *state = &dev->stack[dev->top]; fz_colorspace *model = state->dest->colorspace; + fz_bbox scissor = state->scissor; if (state->blendmode & FZ_BLEND_KNOCKOUT) state = fz_knockout_begin(dev); @@ -491,10 +492,15 @@ fz_draw_fill_text(fz_device *devp, fz_text *text, fz_matrix ctm, trm = fz_concat(tm, ctm); x = floorf(trm.e); y = floorf(trm.f); - trm.e = QUANT(trm.e - floorf(trm.e), HSUBPIX); - trm.f = QUANT(trm.f - floorf(trm.f), VSUBPIX); - glyph = fz_render_glyph(dev->ctx, text->font, gid, trm, model); + trunc_trm = trm; + trunc_trm.e = QUANT(trm.e - floorf(trm.e), HSUBPIX); + trunc_trm.f = QUANT(trm.f - floorf(trm.f), VSUBPIX); + + scissor.x0 -= x; scissor.x1 -= x; + scissor.y0 -= y; scissor.y1 -= y; + + glyph = fz_render_glyph(dev->ctx, text->font, gid, trunc_trm, model, scissor); if (glyph) { if (glyph->n == 1) @@ -510,6 +516,20 @@ fz_draw_fill_text(fz_device *devp, fz_text *text, fz_matrix ctm, } fz_drop_pixmap(dev->ctx, glyph); } + else + { + fz_path *path = fz_outline_glyph(dev->ctx, text->font, gid, trm); + if (path) + { + fz_draw_fill_path(devp, path, 0, fz_identity, colorspace, color, alpha); + fz_free_path(dev->ctx, path); + } + + else + { + fz_warn(dev->ctx, "cannot render glyph"); + } + } } if (state->blendmode & FZ_BLEND_KNOCKOUT) @@ -553,7 +573,9 @@ fz_draw_stroke_text(fz_device *devp, fz_text *text, fz_stroke_state *stroke, fz_ trm.e = QUANT(trm.e - floorf(trm.e), HSUBPIX); trm.f = QUANT(trm.f - floorf(trm.f), VSUBPIX); - glyph = fz_render_stroked_glyph(dev->ctx, text->font, gid, trm, ctm, stroke); + // TODO: dash state + + glyph = fz_render_stroked_glyph(dev->ctx, text->font, gid, trm, ctm, stroke, state->scissor); if (glyph) { draw_glyph(colorbv, state->dest, glyph, x, y, state->scissor); @@ -645,7 +667,7 @@ fz_draw_clip_text(fz_device *devp, fz_text *text, fz_matrix ctm, int accumulate) trm.e = QUANT(trm.e - floorf(trm.e), HSUBPIX); trm.f = QUANT(trm.f - floorf(trm.f), VSUBPIX); - glyph = fz_render_glyph(dev->ctx, text->font, gid, trm, model); + glyph = fz_render_glyph(dev->ctx, text->font, gid, trm, model, bbox); if (glyph) { draw_glyph(NULL, mask, glyph, x, y, bbox); @@ -712,7 +734,7 @@ fz_draw_clip_stroke_text(fz_device *devp, fz_text *text, fz_stroke_state *stroke trm.e = QUANT(trm.e - floorf(trm.e), HSUBPIX); trm.f = QUANT(trm.f - floorf(trm.f), VSUBPIX); - glyph = fz_render_stroked_glyph(dev->ctx, text->font, gid, trm, ctm, stroke); + glyph = fz_render_stroked_glyph(dev->ctx, text->font, gid, trm, ctm, stroke, bbox); if (glyph) { draw_glyph(NULL, mask, glyph, x, y, bbox); diff --git a/draw/draw_glyph.c b/draw/draw_glyph.c index cef9d7fa..e7e7f03a 100644 --- a/draw/draw_glyph.c +++ b/draw/draw_glyph.c @@ -1,6 +1,5 @@ #include "fitz-internal.h" -#define MAX_FONT_SIZE 1000 #define MAX_GLYPH_SIZE 256 #define MAX_CACHE_SIZE (1024*1024) @@ -96,29 +95,44 @@ fz_keep_glyph_cache(fz_context *ctx) } fz_pixmap * -fz_render_stroked_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm, fz_matrix ctm, fz_stroke_state *stroke) +fz_render_stroked_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm, fz_matrix ctm, fz_stroke_state *stroke, fz_bbox scissor) { if (font->ft_face) return fz_render_ft_stroked_glyph(ctx, font, gid, trm, ctm, stroke); - return fz_render_glyph(ctx, font, gid, trm, NULL); + return fz_render_glyph(ctx, font, gid, trm, NULL, scissor); } +/* + Render a glyph and return a bitmap. + If the glyph is too large to fit the cache we have two choices: + 1) Return NULL so the caller can draw the glyph using an outline. + Only supported for freetype fonts. + 2) Render a clipped glyph by using the scissor rectangle. + Only supported for type 3 fonts. + This must not be inserted into the cache. + */ fz_pixmap * -fz_render_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix ctm, fz_colorspace *model) +fz_render_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix ctm, fz_colorspace *model, fz_bbox scissor) { fz_glyph_cache *cache; fz_glyph_key key; fz_pixmap *val; float size = fz_matrix_expansion(ctm); + int do_cache; - cache = ctx->glyph_cache; - - if (size > MAX_FONT_SIZE) + if (size <= MAX_GLYPH_SIZE) { - /* TODO: this case should be handled by rendering glyph as a path fill */ - fz_warn(ctx, "font size too large (%g), not rendering glyph", size); - return NULL; + scissor = fz_infinite_bbox; + do_cache = 1; } + else + { + if (font->ft_face) + return NULL; + do_cache = 0; + } + + cache = ctx->glyph_cache; memset(&key, 0, sizeof key); key.font = font; @@ -131,6 +145,9 @@ fz_render_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix ctm, fz_color key.f = (ctm.f - floorf(ctm.f)) * 256; key.aa = fz_aa_level(ctx); + ctm.e = floorf(ctm.e) + key.e / 256.0f; + ctm.f = floorf(ctm.f) + key.f / 256.0f; + fz_lock(ctx, FZ_LOCK_GLYPHCACHE); val = fz_hash_find(ctx, cache->hash, &key); if (val) @@ -140,9 +157,6 @@ fz_render_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix ctm, fz_color return val; } - ctm.e = floorf(ctm.e) + key.e / 256.0f; - ctm.f = floorf(ctm.f) + key.f / 256.0f; - fz_try(ctx) { if (font->ft_face) @@ -161,7 +175,7 @@ fz_render_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix ctm, fz_color * abandon ours, and use the one there already. */ fz_unlock(ctx, FZ_LOCK_GLYPHCACHE); - val = fz_render_t3_glyph(ctx, font, gid, ctm, model); + val = fz_render_t3_glyph(ctx, font, gid, ctm, model, scissor); fz_lock(ctx, FZ_LOCK_GLYPHCACHE); } else @@ -176,7 +190,7 @@ fz_render_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix ctm, fz_color fz_rethrow(ctx); } - if (val) + if (val && do_cache) { if (val->w < MAX_GLYPH_SIZE && val->h < MAX_GLYPH_SIZE) { diff --git a/fitz/fitz-internal.h b/fitz/fitz-internal.h index d352a94b..2670a335 100644 --- a/fitz/fitz-internal.h +++ b/fitz/fitz-internal.h @@ -810,6 +810,7 @@ struct fz_stroke_state_s }; fz_path *fz_new_path(fz_context *ctx); +fz_point fz_currentpoint(fz_context *ctx, fz_path *path); void fz_moveto(fz_context*, fz_path*, float x, float y); void fz_lineto(fz_context*, fz_path*, float x, float y); void fz_curveto(fz_context*,fz_path*, float, float, float, float, float, float); @@ -845,11 +846,13 @@ fz_glyph_cache *fz_keep_glyph_cache(fz_context *ctx); void fz_drop_glyph_cache_context(fz_context *ctx); void fz_purge_glyph_cache(fz_context *ctx); +fz_path *fz_outline_ft_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm); +fz_path *fz_outline_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix ctm); fz_pixmap *fz_render_ft_glyph(fz_context *ctx, fz_font *font, int cid, fz_matrix trm, int aa); -fz_pixmap *fz_render_t3_glyph(fz_context *ctx, fz_font *font, int cid, fz_matrix trm, fz_colorspace *model); +fz_pixmap *fz_render_t3_glyph(fz_context *ctx, fz_font *font, int cid, fz_matrix trm, fz_colorspace *model, fz_bbox scissor); fz_pixmap *fz_render_ft_stroked_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm, fz_matrix ctm, fz_stroke_state *state); -fz_pixmap *fz_render_glyph(fz_context *ctx, fz_font*, int, fz_matrix, fz_colorspace *model); -fz_pixmap *fz_render_stroked_glyph(fz_context *ctx, fz_font*, int, fz_matrix, fz_matrix, fz_stroke_state *stroke); +fz_pixmap *fz_render_glyph(fz_context *ctx, fz_font*, int, fz_matrix, fz_colorspace *model, fz_bbox scissor); +fz_pixmap *fz_render_stroked_glyph(fz_context *ctx, fz_font*, int, fz_matrix, fz_matrix, fz_stroke_state *stroke, fz_bbox scissor); void fz_render_t3_glyph_direct(fz_context *ctx, fz_device *dev, fz_font *font, int gid, fz_matrix trm, void *gstate); /* diff --git a/fitz/res_font.c b/fitz/res_font.c index e8af6643..568308be 100644 --- a/fitz/res_font.c +++ b/fitz/res_font.c @@ -380,7 +380,7 @@ fz_copy_ft_bitmap(fz_context *ctx, int left, int top, FT_Bitmap *bitmap) for (y = 0; y < pixmap->h; y++) { memcpy(pixmap->samples + (unsigned int)(y * pixmap->w), - bitmap->buffer + (unsigned int)((pixmap->h - y - 1) * bitmap->pitch), + bitmap->buffer + (unsigned int)((pixmap->h - y - 1) * bitmap->pitch), pixmap->w); } } @@ -398,6 +398,8 @@ fz_render_ft_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm, int a FT_Error fterr; fz_pixmap *result; + float strength = fz_matrix_expansion(trm) * 0.02f; + trm = fz_adjust_ft_glyph_width(ctx, font, gid, trm); if (font->ft_italic) @@ -474,7 +476,6 @@ retry_unhinted: if (font->ft_bold) { - float strength = fz_matrix_expansion(trm) * 0.02f; FT_Outline_Embolden(&face->glyph->outline, strength * 64); FT_Outline_Translate(&face->glyph->outline, -strength * 32, -strength * 32); } @@ -614,6 +615,8 @@ fz_bound_ft_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm) // TODO: refactor loading into fz_load_ft_glyph // TODO: cache results + float strength = fz_matrix_expansion(trm) * 0.02f; + trm = fz_adjust_ft_glyph_width(ctx, font, gid, trm); if (font->ft_italic) @@ -644,7 +647,6 @@ fz_bound_ft_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm) if (font->ft_bold) { - float strength = fz_matrix_expansion(trm) * 0.04f; FT_Outline_Embolden(&face->glyph->outline, strength * 64); FT_Outline_Translate(&face->glyph->outline, -strength * 32, -strength * 32); } @@ -665,6 +667,136 @@ fz_bound_ft_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm) return bounds; } +/* Turn FT_Outline into a fz_path */ + +struct closure { + fz_context *ctx; + fz_path *path; + float x, y; +}; + +static int move_to(const FT_Vector *p, void *cc) +{ + fz_context *ctx = ((struct closure *)cc)->ctx; + fz_path *path = ((struct closure *)cc)->path; + float tx = ((struct closure *)cc)->x; + float ty = ((struct closure *)cc)->y; + fz_moveto(ctx, path, tx + p->x / 64.0f, ty + p->y / 64.0f); + return 0; +} + +static int line_to(const FT_Vector *p, void *cc) +{ + fz_context *ctx = ((struct closure *)cc)->ctx; + fz_path *path = ((struct closure *)cc)->path; + float tx = ((struct closure *)cc)->x; + float ty = ((struct closure *)cc)->y; + fz_lineto(ctx, path, tx + p->x / 64.0f, ty + p->y / 64.0f); + return 0; +} + +static int conic_to(const FT_Vector *c, const FT_Vector *p, void *cc) +{ + fz_context *ctx = ((struct closure *)cc)->ctx; + fz_path *path = ((struct closure *)cc)->path; + float tx = ((struct closure *)cc)->x; + float ty = ((struct closure *)cc)->y; + fz_point s, c1, c2; + float cx = tx + c->x / 64.0f, cy = ty + c->y / 64.0f; + float px = tx + p->x / 64.0f, py = ty + p->y / 64.0f; + s = fz_currentpoint(ctx, path); + c1.x = (s.x + cx * 2) / 3; + c1.y = (s.y + cy * 2) / 3; + c2.x = (px + cx * 2) / 3; + c2.y = (py + cy * 2) / 3; + fz_curveto(ctx, path, c1.x, c1.y, c2.x, c2.y, px, py); + return 0; +} + +static int cubic_to(const FT_Vector *c1, const FT_Vector *c2, const FT_Vector *p, void *cc) +{ + fz_context *ctx = ((struct closure *)cc)->ctx; + fz_path *path = ((struct closure *)cc)->path; + float tx = ((struct closure *)cc)->x; + float ty = ((struct closure *)cc)->y; + fz_curveto(ctx, path, + tx + c1->x/64.0f, ty + c1->y/64.0f, + tx + c2->x/64.0f, ty + c2->y/64.0f, + tx + p->x/64.0f, ty + p->y/64.0f); + return 0; +} + +static const FT_Outline_Funcs outline_funcs = { + move_to, line_to, conic_to, cubic_to, 0, 0 +}; + +fz_path * +fz_outline_ft_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm) +{ + struct closure cc; + FT_Face face = font->ft_face; + FT_Matrix m; + FT_Vector v; + int fterr; + + float strength = fz_matrix_expansion(trm) * 0.02f; + + trm = fz_adjust_ft_glyph_width(ctx, font, gid, trm); + + if (font->ft_italic) + trm = fz_concat(fz_shear(SHEAR, 0), trm); + + m.xx = trm.a * 64; /* should be 65536 */ + m.yx = trm.b * 64; + m.xy = trm.c * 64; + m.yy = trm.d * 64; + v.x = 0; + v.y = 0; + + fz_lock(ctx, FZ_LOCK_FREETYPE); + + fterr = FT_Set_Char_Size(face, 65536, 65536, 72, 72); /* should be 64, 64 */ + if (fterr) + fz_warn(ctx, "freetype setting character size: %s", ft_error_string(fterr)); + FT_Set_Transform(face, &m, &v); + + fterr = FT_Load_Glyph(face, gid, FT_LOAD_NO_BITMAP | FT_LOAD_NO_HINTING); + if (fterr) + { + fz_warn(ctx, "freetype load glyph (gid %d): %s", gid, ft_error_string(fterr)); + fz_unlock(ctx, FZ_LOCK_FREETYPE); + return NULL; + } + + if (font->ft_bold) + { + FT_Outline_Embolden(&face->glyph->outline, strength * 64); + FT_Outline_Translate(&face->glyph->outline, -strength * 32, -strength * 32); + } + + fz_try(ctx) + { + cc.ctx = ctx; + cc.path = fz_new_path(ctx); + cc.x = trm.e; + cc.y = trm.f; + fz_moveto(ctx, cc.path, cc.x, cc.y); + FT_Outline_Decompose(&face->glyph->outline, &outline_funcs, &cc); + fz_closepath(ctx, cc.path); + } + fz_catch(ctx) + { + fz_warn(ctx, "freetype cannot decompose outline"); + fz_free(ctx, cc.path); + fz_unlock(ctx, FZ_LOCK_FREETYPE); + return NULL; + } + + fz_unlock(ctx, FZ_LOCK_FREETYPE); + + return cc.path; +} + /* * Type 3 fonts... */ @@ -726,7 +858,7 @@ fz_bound_t3_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm) } fz_pixmap * -fz_render_t3_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm, fz_colorspace *model) +fz_render_t3_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm, fz_colorspace *model, fz_bbox scissor) { fz_matrix ctm; void *contents; @@ -765,6 +897,8 @@ fz_render_t3_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm, fz_co bbox.x1++; bbox.y1++; + bbox = fz_intersect_bbox(bbox, scissor); + glyph = fz_new_pixmap_with_bbox(ctx, model ? model : fz_device_gray, bbox); fz_clear_pixmap(ctx, glyph); @@ -865,6 +999,18 @@ fz_bound_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm) return fz_transform_rect(trm, font->bbox); } +fz_path * +fz_outline_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix ctm) +{ + if (!font->ft_face) + { + fz_warn(ctx, "cannot convert type3 glyph to path"); + return NULL; + } + + return fz_outline_ft_glyph(ctx, font, gid, ctm); +} + int fz_glyph_cacheable(fz_context *ctx, fz_font *font, int gid) { if (!font->t3procs || !font->t3flags || gid < 0 || gid >= font->bbox_count) diff --git a/fitz/res_path.c b/fitz/res_path.c index 7b429c43..d02ea560 100644 --- a/fitz/res_path.c +++ b/fitz/res_path.c @@ -63,6 +63,40 @@ grow_path(fz_context *ctx, fz_path *path, int n) path->last = path->len; } +fz_point +fz_currentpoint(fz_context *ctx, fz_path *path) +{ + fz_point c, m; + int i; + + c.x = c.y = m.x = m.y = 0; + i = 0; + + while (i < path->len) + { + switch (path->items[i++].k) + { + case FZ_MOVETO: + m.x = c.x = path->items[i++].v; + m.y = c.y = path->items[i++].v; + break; + case FZ_LINETO: + c.x = path->items[i++].v; + c.y = path->items[i++].v; + break; + case FZ_CURVETO: + i += 4; + c.x = path->items[i++].v; + c.y = path->items[i++].v; + break; + case FZ_CLOSE_PATH: + c = m; + } + } + + return c; +} + void fz_moveto(fz_context *ctx, fz_path *path, float x, float y) { diff --git a/xps/xps_path.c b/xps/xps_path.c index 696a78b9..8650fbb8 100644 --- a/xps/xps_path.c +++ b/xps/xps_path.c @@ -35,40 +35,6 @@ xps_parse_point(char *s_in, float *x, float *y) return s_out; } -static fz_point -fz_currentpoint(fz_path *path) -{ - fz_point c, m; - int i; - - c.x = c.y = m.x = m.y = 0; - i = 0; - - while (i < path->len) - { - switch (path->items[i++].k) - { - case FZ_MOVETO: - m.x = c.x = path->items[i++].v; - m.y = c.y = path->items[i++].v; - break; - case FZ_LINETO: - c.x = path->items[i++].v; - c.y = path->items[i++].v; - break; - case FZ_CURVETO: - i += 4; - c.x = path->items[i++].v; - c.y = path->items[i++].v; - break; - case FZ_CLOSE_PATH: - c = m; - } - } - - return c; -} - /* Draw an arc segment transformed by the matrix, we approximate with straight * line segments. We cannot use the fz_arc function because they only draw * circular arcs, we need to transform the line to make them elliptical but @@ -160,7 +126,7 @@ xps_draw_arc(fz_context *doc, fz_path *path, float sign; float th1, dth; - pt = fz_currentpoint(path); + pt = fz_currentpoint(doc, path); x1 = pt.x; y1 = pt.y; x2 = point_x; @@ -334,7 +300,7 @@ xps_parse_abbreviated_geometry(xps_document *doc, char *geom, int *fill_rule) break; case 'm': if (i + 1 >= n) break; - pt = fz_currentpoint(path); + pt = fz_currentpoint(doc->ctx, path); fz_moveto(doc->ctx, path, pt.x + fz_atof(args[i]), pt.y + fz_atof(args[i+1])); i += 2; break; @@ -346,33 +312,33 @@ xps_parse_abbreviated_geometry(xps_document *doc, char *geom, int *fill_rule) break; case 'l': if (i + 1 >= n) break; - pt = fz_currentpoint(path); + pt = fz_currentpoint(doc->ctx, path); fz_lineto(doc->ctx, path, pt.x + fz_atof(args[i]), pt.y + fz_atof(args[i+1])); i += 2; break; case 'H': if (i >= n) break; - pt = fz_currentpoint(path); + pt = fz_currentpoint(doc->ctx, path); fz_lineto(doc->ctx, path, fz_atof(args[i]), pt.y); i += 1; break; case 'h': if (i >= n) break; - pt = fz_currentpoint(path); + pt = fz_currentpoint(doc->ctx, path); fz_lineto(doc->ctx, path, pt.x + fz_atof(args[i]), pt.y); i += 1; break; case 'V': if (i >= n) break; - pt = fz_currentpoint(path); + pt = fz_currentpoint(doc->ctx, path); fz_lineto(doc->ctx, path, pt.x, fz_atof(args[i])); i += 1; break; case 'v': if (i >= n) break; - pt = fz_currentpoint(path); + pt = fz_currentpoint(doc->ctx, path); fz_lineto(doc->ctx, path, pt.x, pt.y + fz_atof(args[i])); i += 1; break; @@ -394,7 +360,7 @@ xps_parse_abbreviated_geometry(xps_document *doc, char *geom, int *fill_rule) case 'c': if (i + 5 >= n) break; - pt = fz_currentpoint(path); + pt = fz_currentpoint(doc->ctx, path); x1 = fz_atof(args[i+0]) + pt.x; y1 = fz_atof(args[i+1]) + pt.y; x2 = fz_atof(args[i+2]) + pt.x; @@ -410,7 +376,7 @@ xps_parse_abbreviated_geometry(xps_document *doc, char *geom, int *fill_rule) case 'S': if (i + 3 >= n) break; - pt = fz_currentpoint(path); + pt = fz_currentpoint(doc->ctx, path); x1 = fz_atof(args[i+0]); y1 = fz_atof(args[i+1]); x2 = fz_atof(args[i+2]); @@ -424,7 +390,7 @@ xps_parse_abbreviated_geometry(xps_document *doc, char *geom, int *fill_rule) case 's': if (i + 3 >= n) break; - pt = fz_currentpoint(path); + pt = fz_currentpoint(doc->ctx, path); x1 = fz_atof(args[i+0]) + pt.x; y1 = fz_atof(args[i+1]) + pt.y; x2 = fz_atof(args[i+2]) + pt.x; @@ -438,7 +404,7 @@ xps_parse_abbreviated_geometry(xps_document *doc, char *geom, int *fill_rule) case 'Q': if (i + 3 >= n) break; - pt = fz_currentpoint(path); + pt = fz_currentpoint(doc->ctx, path); x1 = fz_atof(args[i+0]); y1 = fz_atof(args[i+1]); x2 = fz_atof(args[i+2]); @@ -451,7 +417,7 @@ xps_parse_abbreviated_geometry(xps_document *doc, char *geom, int *fill_rule) break; case 'q': if (i + 3 >= n) break; - pt = fz_currentpoint(path); + pt = fz_currentpoint(doc->ctx, path); x1 = fz_atof(args[i+0]) + pt.x; y1 = fz_atof(args[i+1]) + pt.y; x2 = fz_atof(args[i+2]) + pt.x; @@ -473,7 +439,7 @@ xps_parse_abbreviated_geometry(xps_document *doc, char *geom, int *fill_rule) break; case 'a': if (i + 6 >= n) break; - pt = fz_currentpoint(path); + pt = fz_currentpoint(doc->ctx, path); xps_draw_arc(doc->ctx, path, fz_atof(args[i+0]), fz_atof(args[i+1]), fz_atof(args[i+2]), atoi(args[i+3]), atoi(args[i+4]), @@ -587,7 +553,7 @@ xps_parse_poly_quadratic_bezier_segment(fz_context *doc, fz_path *path, xml_elem } else { - pt = fz_currentpoint(path); + pt = fz_currentpoint(doc, path); fz_curveto(doc, path, (pt.x + 2 * x[0]) / 3, (pt.y + 2 * y[0]) / 3, (x[1] + 2 * x[0]) / 3, (y[1] + 2 * y[0]) / 3, |