summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor.andersson@artifex.com>2012-07-17 18:05:05 +0200
committerTor Andersson <tor.andersson@artifex.com>2012-07-17 18:05:05 +0200
commit4091b7a357728aed033216baafed540b795bcf9e (patch)
treead0cd73cc428bc8922d1eaa94663479c04192edb
parent2b857ab9878d5ca8acd862ae58dafa8d269bc502 (diff)
downloadmupdf-4091b7a357728aed033216baafed540b795bcf9e.tar.xz
Handle glyphs that are too large to render as pixmaps.
-rw-r--r--draw/draw_device.c36
-rw-r--r--draw/draw_glyph.c44
-rw-r--r--fitz/fitz-internal.h9
-rw-r--r--fitz/res_font.c154
-rw-r--r--fitz/res_path.c34
-rw-r--r--xps/xps_path.c62
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,