summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor.andersson@artifex.com>2015-01-20 15:27:34 +0100
committerTor Andersson <tor.andersson@artifex.com>2015-02-17 16:31:34 +0100
commitb9d11456411907e9add8d91b02d67842990c2952 (patch)
treeca29439a35e83948645481cf0d0dfca445bf8b03
parent4fe9caafead64704a16c7093b72115893be3087f (diff)
downloadmupdf-b9d11456411907e9add8d91b02d67842990c2952.tar.xz
Reference count fz_path and fz_text.
Disallow modification of shared fz_path and fz_text objects. They should follow a create once, consume often pattern, and as such should be immutable once created.
-rw-r--r--include/mupdf/fitz/path.h7
-rw-r--r--include/mupdf/fitz/text.h6
-rw-r--r--source/fitz/draw-device.c8
-rw-r--r--source/fitz/list-device.c22
-rw-r--r--source/fitz/path.c42
-rw-r--r--source/fitz/text.c42
-rw-r--r--source/pdf/pdf-appearance.c25
-rw-r--r--source/pdf/pdf-op-run.c10
-rw-r--r--source/xps/xps-glyphs.c2
-rw-r--r--source/xps/xps-path.c6
-rw-r--r--source/xps/xps-tile.c2
11 files changed, 73 insertions, 99 deletions
diff --git a/include/mupdf/fitz/path.h b/include/mupdf/fitz/path.h
index 9b32b8d3..b621591f 100644
--- a/include/mupdf/fitz/path.h
+++ b/include/mupdf/fitz/path.h
@@ -43,6 +43,7 @@ typedef enum fz_linejoin_e
struct fz_path_s
{
+ int refs;
int cmd_len, cmd_cap;
unsigned char *cmds;
int coord_len, coord_cap;
@@ -65,6 +66,9 @@ struct fz_stroke_state_s
};
fz_path *fz_new_path(fz_context *ctx);
+fz_path *fz_keep_path(fz_context *ctx, fz_path *path);
+void fz_drop_path(fz_context *ctx, fz_path *path);
+
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);
@@ -72,12 +76,9 @@ void fz_curveto(fz_context*,fz_path*, float, float, float, float, float, float);
void fz_curvetov(fz_context*,fz_path*, float, float, float, float);
void fz_curvetoy(fz_context*,fz_path*, float, float, float, float);
void fz_closepath(fz_context*,fz_path*);
-void fz_free_path(fz_context *ctx, fz_path *path);
void fz_transform_path(fz_context *ctx, fz_path *path, const fz_matrix *transform);
-fz_path *fz_clone_path(fz_context *ctx, fz_path *old);
-
fz_rect *fz_bound_path(fz_context *ctx, fz_path *path, const fz_stroke_state *stroke, const fz_matrix *ctm, fz_rect *r);
fz_rect *fz_adjust_rect_for_stroke(fz_rect *r, const fz_stroke_state *stroke, const fz_matrix *ctm);
diff --git a/include/mupdf/fitz/text.h b/include/mupdf/fitz/text.h
index 13cc02ab..eb2ad12e 100644
--- a/include/mupdf/fitz/text.h
+++ b/include/mupdf/fitz/text.h
@@ -30,6 +30,7 @@ struct fz_text_item_s
struct fz_text_s
{
+ int refs;
fz_font *font;
fz_matrix trm;
int wmode;
@@ -38,10 +39,11 @@ struct fz_text_s
};
fz_text *fz_new_text(fz_context *ctx, fz_font *face, const fz_matrix *trm, int wmode);
+fz_text *fz_keep_text(fz_context *ctx, fz_text *text);
+void fz_drop_text(fz_context *ctx, fz_text *text);
+
void fz_add_text(fz_context *ctx, fz_text *text, int gid, int ucs, float x, float y);
-void fz_free_text(fz_context *ctx, fz_text *text);
fz_rect *fz_bound_text(fz_context *ctx, fz_text *text, const fz_stroke_state *stroke, const fz_matrix *ctm, fz_rect *r);
-fz_text *fz_clone_text(fz_context *ctx, fz_text *old);
void fz_print_text(fz_context *ctx, FILE *out, fz_text*);
#endif
diff --git a/source/fitz/draw-device.c b/source/fitz/draw-device.c
index f927e1b5..a8d745af 100644
--- a/source/fitz/draw-device.c
+++ b/source/fitz/draw-device.c
@@ -619,7 +619,7 @@ fz_draw_fill_text(fz_device *devp, fz_text *text, const fz_matrix *ctm,
if (path)
{
fz_draw_fill_path(devp, path, 0, ctm, colorspace, color, alpha);
- fz_free_path(dev->ctx, path);
+ fz_drop_path(dev->ctx, path);
}
else
{
@@ -682,7 +682,7 @@ fz_draw_stroke_text(fz_device *devp, fz_text *text, fz_stroke_state *stroke,
if (path)
{
fz_draw_stroke_path(devp, path, stroke, ctm, colorspace, color, alpha);
- fz_free_path(dev->ctx, path);
+ fz_drop_path(dev->ctx, path);
}
else
{
@@ -805,7 +805,7 @@ fz_draw_clip_text(fz_device *devp, fz_text *text, const fz_matrix *ctm, int accu
{
state[1].mask = state[1].dest;
state[1].dest = old_dest;
- fz_free_path(dev->ctx, path);
+ fz_drop_path(dev->ctx, path);
}
fz_catch(ctx)
{
@@ -911,7 +911,7 @@ fz_draw_clip_stroke_text(fz_device *devp, fz_text *text, fz_stroke_state *stroke
{
state[0].mask = state[0].dest;
state[0].dest = old_dest;
- fz_free_path(dev->ctx, path);
+ fz_drop_path(dev->ctx, path);
}
fz_catch(ctx)
{
diff --git a/source/fitz/list-device.c b/source/fitz/list-device.c
index 2bac3034..42590bab 100644
--- a/source/fitz/list-device.c
+++ b/source/fitz/list-device.c
@@ -193,14 +193,14 @@ fz_free_display_node(fz_context *ctx, fz_display_node *node)
case FZ_CMD_STROKE_PATH:
case FZ_CMD_CLIP_PATH:
case FZ_CMD_CLIP_STROKE_PATH:
- fz_free_path(ctx, node->item.path);
+ fz_drop_path(ctx, node->item.path);
break;
case FZ_CMD_FILL_TEXT:
case FZ_CMD_STROKE_TEXT:
case FZ_CMD_CLIP_TEXT:
case FZ_CMD_CLIP_STROKE_TEXT:
case FZ_CMD_IGNORE_TEXT:
- fz_free_text(ctx, node->item.text);
+ fz_drop_text(ctx, node->item.text);
break;
case FZ_CMD_FILL_SHADE:
fz_drop_shade(ctx, node->item.shade);
@@ -256,7 +256,7 @@ fz_list_fill_path(fz_device *dev, fz_path *path, int even_odd, const fz_matrix *
fz_try(ctx)
{
fz_bound_path(dev->ctx, path, NULL, ctm, &node->rect);
- node->item.path = fz_clone_path(dev->ctx, path);
+ node->item.path = fz_keep_path(dev->ctx, path);
node->flag = even_odd;
}
fz_catch(ctx)
@@ -277,7 +277,7 @@ fz_list_stroke_path(fz_device *dev, fz_path *path, fz_stroke_state *stroke,
fz_try(ctx)
{
fz_bound_path(dev->ctx, path, stroke, ctm, &node->rect);
- node->item.path = fz_clone_path(dev->ctx, path);
+ node->item.path = fz_keep_path(dev->ctx, path);
node->stroke = fz_keep_stroke_state(dev->ctx, stroke);
}
fz_catch(ctx)
@@ -299,7 +299,7 @@ fz_list_clip_path(fz_device *dev, fz_path *path, const fz_rect *rect, int even_o
fz_bound_path(dev->ctx, path, NULL, ctm, &node->rect);
if (rect)
fz_intersect_rect(&node->rect, rect);
- node->item.path = fz_clone_path(dev->ctx, path);
+ node->item.path = fz_keep_path(dev->ctx, path);
node->flag = even_odd;
}
fz_catch(ctx)
@@ -321,7 +321,7 @@ fz_list_clip_stroke_path(fz_device *dev, fz_path *path, const fz_rect *rect, fz_
fz_bound_path(dev->ctx, path, stroke, ctm, &node->rect);
if (rect)
fz_intersect_rect(&node->rect, rect);
- node->item.path = fz_clone_path(dev->ctx, path);
+ node->item.path = fz_keep_path(dev->ctx, path);
node->stroke = fz_keep_stroke_state(dev->ctx, stroke);
}
fz_catch(ctx)
@@ -342,7 +342,7 @@ fz_list_fill_text(fz_device *dev, fz_text *text, const fz_matrix *ctm,
fz_try(ctx)
{
fz_bound_text(dev->ctx, text, NULL, ctm, &node->rect);
- node->item.text = fz_clone_text(dev->ctx, text);
+ node->item.text = fz_keep_text(dev->ctx, text);
}
fz_catch(ctx)
{
@@ -363,7 +363,7 @@ fz_list_stroke_text(fz_device *dev, fz_text *text, fz_stroke_state *stroke, cons
fz_try(ctx)
{
fz_bound_text(dev->ctx, text, stroke, ctm, &node->rect);
- node->item.text = fz_clone_text(dev->ctx, text);
+ node->item.text = fz_keep_text(dev->ctx, text);
node->stroke = fz_keep_stroke_state(dev->ctx, stroke);
}
fz_catch(ctx)
@@ -383,7 +383,7 @@ fz_list_clip_text(fz_device *dev, fz_text *text, const fz_matrix *ctm, int accum
fz_try(ctx)
{
fz_bound_text(dev->ctx, text, NULL, ctm, &node->rect);
- node->item.text = fz_clone_text(dev->ctx, text);
+ node->item.text = fz_keep_text(dev->ctx, text);
node->flag = accumulate;
/* when accumulating, be conservative about culling */
if (accumulate)
@@ -406,7 +406,7 @@ fz_list_clip_stroke_text(fz_device *dev, fz_text *text, fz_stroke_state *stroke,
fz_try(ctx)
{
fz_bound_text(dev->ctx, text, stroke, ctm, &node->rect);
- node->item.text = fz_clone_text(dev->ctx, text);
+ node->item.text = fz_keep_text(dev->ctx, text);
node->stroke = fz_keep_stroke_state(dev->ctx, stroke);
}
fz_catch(ctx)
@@ -426,7 +426,7 @@ fz_list_ignore_text(fz_device *dev, fz_text *text, const fz_matrix *ctm)
fz_try(ctx)
{
fz_bound_text(dev->ctx, text, NULL, ctm, &node->rect);
- node->item.text = fz_clone_text(dev->ctx, text);
+ node->item.text = fz_keep_text(dev->ctx, text);
}
fz_catch(ctx)
{
diff --git a/source/fitz/path.c b/source/fitz/path.c
index 04a3a7bc..6c7991b9 100644
--- a/source/fitz/path.c
+++ b/source/fitz/path.c
@@ -7,6 +7,7 @@ fz_new_path(fz_context *ctx)
fz_path *path;
path = fz_malloc_struct(ctx, fz_path);
+ path->refs = 1;
path->last_cmd = 0;
path->current.x = 0;
path->current.y = 0;
@@ -17,48 +18,31 @@ fz_new_path(fz_context *ctx)
}
fz_path *
-fz_clone_path(fz_context *ctx, fz_path *old)
+fz_keep_path(fz_context *ctx, fz_path *path)
{
- fz_path *path;
-
- assert(old);
- path = fz_malloc_struct(ctx, fz_path);
- fz_try(ctx)
- {
- path->cmd_len = old->cmd_len;
- path->cmd_cap = old->cmd_len;
- path->cmds = fz_malloc_array(ctx, path->cmd_cap, sizeof(unsigned char));
- memcpy(path->cmds, old->cmds, sizeof(unsigned char) * path->cmd_len);
-
- path->coord_len = old->coord_len;
- path->coord_cap = old->coord_len;
- path->coords = fz_malloc_array(ctx, path->coord_cap, sizeof(float));
- memcpy(path->coords, old->coords, sizeof(float) * path->coord_len);
- }
- fz_catch(ctx)
- {
- fz_free(ctx, path->cmds);
- fz_free(ctx, path->coords);
- fz_free(ctx, path);
- fz_rethrow(ctx);
- }
-
+ ++path->refs;
return path;
}
void
-fz_free_path(fz_context *ctx, fz_path *path)
+fz_drop_path(fz_context *ctx, fz_path *path)
{
if (path == NULL)
return;
- fz_free(ctx, path->cmds);
- fz_free(ctx, path->coords);
- fz_free(ctx, path);
+ if (--path->refs == 0)
+ {
+ fz_free(ctx, path->cmds);
+ fz_free(ctx, path->coords);
+ fz_free(ctx, path);
+ }
}
static void
push_cmd(fz_context *ctx, fz_path *path, int cmd)
{
+ if (path->refs != 1)
+ fz_throw(ctx, FZ_ERROR_GENERIC, "cannot modify shared paths");
+
if (path->cmd_len + 1 >= path->cmd_cap)
{
int new_cmd_cap = fz_maxi(16, path->cmd_cap * 2);
diff --git a/source/fitz/text.c b/source/fitz/text.c
index 81e2e1d0..f184e11d 100644
--- a/source/fitz/text.c
+++ b/source/fitz/text.c
@@ -6,6 +6,7 @@ fz_new_text(fz_context *ctx, fz_font *font, const fz_matrix *trm, int wmode)
fz_text *text;
text = fz_malloc_struct(ctx, fz_text);
+ text->refs = 1;
text->font = fz_keep_font(ctx, font);
text->trm = *trm;
text->wmode = wmode;
@@ -16,40 +17,24 @@ fz_new_text(fz_context *ctx, fz_font *font, const fz_matrix *trm, int wmode)
return text;
}
-void
-fz_free_text(fz_context *ctx, fz_text *text)
+fz_text *
+fz_keep_text(fz_context *ctx, fz_text *text)
{
- if (text != NULL)
- {
- fz_drop_font(ctx, text->font);
- fz_free(ctx, text->items);
- }
- fz_free(ctx, text);
+ ++text->refs;
+ return text;
}
-fz_text *
-fz_clone_text(fz_context *ctx, fz_text *old)
+void
+fz_drop_text(fz_context *ctx, fz_text *text)
{
- fz_text *text;
-
- text = fz_malloc_struct(ctx, fz_text);
- text->len = old->len;
- fz_try(ctx)
- {
- text->items = fz_malloc_array(ctx, text->len, sizeof(fz_text_item));
- }
- fz_catch(ctx)
+ if (text == NULL)
+ return;
+ if (--text->refs == 0)
{
+ fz_drop_font(ctx, text->font);
+ fz_free(ctx, text->items);
fz_free(ctx, text);
- fz_rethrow(ctx);
}
- memcpy(text->items, old->items, text->len * sizeof(fz_text_item));
- text->font = fz_keep_font(ctx, old->font);
- text->trm = old->trm;
- text->wmode = old->wmode;
- text->cap = text->len;
-
- return text;
}
fz_rect *
@@ -117,6 +102,9 @@ fz_grow_text(fz_context *ctx, fz_text *text, int n)
void
fz_add_text(fz_context *ctx, fz_text *text, int gid, int ucs, float x, float y)
{
+ 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;
diff --git a/source/pdf/pdf-appearance.c b/source/pdf/pdf-appearance.c
index db11c32a..8ff3993e 100644
--- a/source/pdf/pdf-appearance.c
+++ b/source/pdf/pdf-appearance.c
@@ -1504,7 +1504,7 @@ void pdf_set_markup_appearance(pdf_document *doc, pdf_annot *annot, float color[
fz_stroke_path(dev, path, stroke, page_ctm, fz_device_rgb(ctx), color, alpha);
fz_drop_stroke_state(ctx, stroke);
stroke = NULL;
- fz_free_path(ctx, path);
+ fz_drop_path(ctx, path);
path = NULL;
}
@@ -1530,7 +1530,7 @@ void pdf_set_markup_appearance(pdf_document *doc, pdf_annot *annot, float color[
fz_free(ctx, qp);
fz_free_device(dev);
fz_drop_stroke_state(ctx, stroke);
- fz_free_path(ctx, path);
+ fz_drop_path(ctx, path);
fz_drop_display_list(ctx, strike_list);
}
fz_catch(ctx)
@@ -1664,7 +1664,7 @@ void pdf_update_ink_appearance(pdf_document *doc, pdf_annot *annot)
fz_drop_colorspace(ctx, cs);
fz_free_device(dev);
fz_drop_stroke_state(ctx, stroke);
- fz_free_path(ctx, path);
+ fz_drop_path(ctx, path);
fz_drop_display_list(ctx, strike_list);
}
fz_catch(ctx)
@@ -1706,7 +1706,7 @@ static fz_text *layout_text(fz_context *ctx, font_info *font_rec, char *str, flo
}
fz_catch(ctx)
{
- fz_free_text(ctx, text);
+ fz_drop_text(ctx, text);
fz_rethrow(ctx);
}
@@ -1739,8 +1739,7 @@ static fz_text *fit_text(fz_context *ctx, font_info *font_rec, char *str, fz_rec
float x = 0.0;
float y = 0.0;
-
- fz_free_text(ctx, text);
+ fz_drop_text(ctx, text);
text = NULL;
font_size = font_rec->da_rec.font_size;
fz_scale(&tm, font_size, font_size);
@@ -1790,7 +1789,7 @@ static fz_text *fit_text(fz_context *ctx, font_info *font_rec, char *str, fz_rec
}
fz_catch(ctx)
{
- fz_free_text(ctx, text);
+ fz_drop_text(ctx, text);
fz_rethrow(ctx);
}
@@ -1888,7 +1887,7 @@ void pdf_update_text_annot_appearance(pdf_document *doc, pdf_annot *annot)
cs = fz_device_rgb(ctx);
fz_fill_path(dev, path, 0, &tm, cs, yellow, 1.0f);
fz_stroke_path(dev, path, stroke, &tm, cs, black, 1.0f);
- fz_free_path(ctx, path);
+ fz_drop_path(ctx, path);
path = NULL;
path = fz_new_path(ctx);
@@ -1909,7 +1908,7 @@ void pdf_update_text_annot_appearance(pdf_document *doc, pdf_annot *annot)
fz_free_device(dev);
fz_drop_display_list(ctx, dlist);
fz_drop_stroke_state(ctx, stroke);
- fz_free_path(ctx, path);
+ fz_drop_path(ctx, path);
fz_drop_colorspace(ctx, cs);
}
fz_catch(ctx)
@@ -1974,7 +1973,7 @@ void pdf_update_free_text_annot_appearance(pdf_document *doc, pdf_annot *annot)
fz_free_device(dev);
fz_drop_display_list(ctx, dlist);
font_info_fin(ctx, &font_rec);
- fz_free_text(ctx, text);
+ fz_drop_text(ctx, text);
fz_drop_colorspace(ctx, cs);
}
fz_catch(ctx)
@@ -2166,7 +2165,7 @@ void pdf_set_signature_appearance(pdf_document *doc, pdf_annot *annot, char *nam
rect.x1 = (rect.x0 + rect.x1)/2.0f;
text = fit_text(ctx, &font_rec, name, &rect);
fz_fill_text(dev, text, page_ctm, cs, font_rec.da_rec.col, 1.0f);
- fz_free_text(ctx, text);
+ fz_drop_text(ctx, text);
text = NULL;
/* Display the distinguished name in the right-hand half */
@@ -2197,8 +2196,8 @@ void pdf_set_signature_appearance(pdf_document *doc, pdf_annot *annot, char *nam
fz_free_device(dev);
fz_drop_display_list(ctx, dlist);
font_info_fin(ctx, &font_rec);
- fz_free_path(ctx, path);
- fz_free_text(ctx, text);
+ fz_drop_path(ctx, path);
+ fz_drop_text(ctx, text);
fz_drop_colorspace(ctx, cs);
fz_drop_buffer(ctx, fzbuf);
}
diff --git a/source/pdf/pdf-op-run.c b/source/pdf/pdf-op-run.c
index 73f89fd3..52000b40 100644
--- a/source/pdf/pdf-op-run.c
+++ b/source/pdf/pdf-op-run.c
@@ -920,7 +920,7 @@ pdf_show_path(pdf_csi *csi, pdf_run_state *pr, int doclose, int dofill, int dost
}
fz_always(ctx)
{
- fz_free_path(ctx, path);
+ fz_drop_path(ctx, path);
}
fz_catch(ctx)
{
@@ -1051,7 +1051,7 @@ pdf_flush_text(pdf_csi *csi, pdf_run_state *pr)
}
fz_always(ctx)
{
- fz_free_text(ctx, text);
+ fz_drop_text(ctx, text);
}
fz_catch(ctx)
{
@@ -2642,8 +2642,8 @@ static void free_processor_normal(pdf_csi *csi, void *state)
while (pr->gstate[0].clip_depth--)
fz_pop_clip(pr->dev);
- if (pr->path) fz_free_path(ctx, pr->path);
- if (pr->text) fz_free_text(ctx, pr->text);
+ if (pr->path) fz_drop_path(ctx, pr->path);
+ if (pr->text) fz_drop_text(ctx, pr->text);
fz_free(ctx, pr->gstate);
fz_free(ctx, pr);
@@ -2849,7 +2849,7 @@ pdf_process *pdf_process_run(pdf_process *process, fz_device *dev, const fz_matr
}
fz_catch(ctx)
{
- fz_free_path(ctx, pr->path);
+ fz_drop_path(ctx, pr->path);
fz_free(ctx, pr);
fz_rethrow(ctx);
}
diff --git a/source/xps/xps-glyphs.c b/source/xps/xps-glyphs.c
index ee16fb6f..d2a786fe 100644
--- a/source/xps/xps-glyphs.c
+++ b/source/xps/xps-glyphs.c
@@ -622,7 +622,7 @@ xps_parse_glyphs(xps_document *doc, const fz_matrix *ctm,
xps_end_opacity(doc, opacity_mask_uri, dict, opacity_att, opacity_mask_tag);
- fz_free_text(doc->ctx, text);
+ fz_drop_text(doc->ctx, text);
if (clip_att || clip_tag)
fz_pop_clip(doc->dev);
diff --git a/source/xps/xps-path.c b/source/xps/xps-path.c
index 49240ee4..ee412d64 100644
--- a/source/xps/xps-path.c
+++ b/source/xps/xps-path.c
@@ -775,7 +775,7 @@ xps_clip(xps_document *doc, const fz_matrix *ctm, xps_resource *dict, char *clip
else
path = fz_new_path(doc->ctx);
fz_clip_path(doc->dev, path, NULL, fill_rule == 0, ctm);
- fz_free_path(doc->ctx, path);
+ fz_drop_path(doc->ctx, path);
}
/*
@@ -1049,8 +1049,8 @@ xps_parse_path(xps_document *doc, const fz_matrix *ctm, char *base_uri, xps_reso
xps_end_opacity(doc, opacity_mask_uri, dict, opacity_att, opacity_mask_tag);
if (stroke_path != path)
- fz_free_path(doc->ctx, stroke_path);
- fz_free_path(doc->ctx, path);
+ fz_drop_path(doc->ctx, stroke_path);
+ fz_drop_path(doc->ctx, path);
path = NULL;
fz_drop_stroke_state(doc->ctx, stroke);
diff --git a/source/xps/xps-tile.c b/source/xps/xps-tile.c
index b65981a2..5f966619 100644
--- a/source/xps/xps-tile.c
+++ b/source/xps/xps-tile.c
@@ -28,7 +28,7 @@ xps_paint_tiling_brush_clipped(xps_document *doc, const fz_matrix *ctm, const fz
fz_lineto(doc->ctx, path, viewbox->x1, viewbox->y0);
fz_closepath(doc->ctx, path);
fz_clip_path(doc->dev, path, NULL, 0, ctm);
- fz_free_path(doc->ctx, path);
+ fz_drop_path(doc->ctx, path);
c->func(doc, ctm, viewbox, c->base_uri, c->dict, c->root, c->user);
fz_pop_clip(doc->dev);
}