summaryrefslogtreecommitdiff
path: root/source/fitz/path.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/fitz/path.c')
-rw-r--r--source/fitz/path.c79
1 files changed, 33 insertions, 46 deletions
diff --git a/source/fitz/path.c b/source/fitz/path.c
index 04a3a7bc..8deb85b8 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,30 @@ 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;
+ if (path->refs == 1)
+ fz_trim_path(ctx, path);
+ return fz_keep_imp(ctx, path, &path->refs);
+}
- 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)
+void
+fz_drop_path(fz_context *ctx, fz_path *path)
+{
+ if (fz_drop_imp(ctx, path, &path->refs))
{
fz_free(ctx, path->cmds);
fz_free(ctx, path->coords);
fz_free(ctx, path);
- fz_rethrow(ctx);
}
-
- return path;
-}
-
-void
-fz_free_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);
}
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);
@@ -286,14 +269,14 @@ fz_bound_path(fz_context *ctx, fz_path *path, const fz_stroke_state *stroke, con
if (stroke)
{
- fz_adjust_rect_for_stroke(r, stroke, ctm);
+ fz_adjust_rect_for_stroke(ctx, r, stroke, ctm);
}
return r;
}
fz_rect *
-fz_adjust_rect_for_stroke(fz_rect *r, const fz_stroke_state *stroke, const fz_matrix *ctm)
+fz_adjust_rect_for_stroke(fz_context *ctx, fz_rect *r, const fz_stroke_state *stroke, const fz_matrix *ctm)
{
float expand;
@@ -322,6 +305,20 @@ fz_transform_path(fz_context *ctx, fz_path *path, const fz_matrix *ctm)
fz_transform_point((fz_point *)&path->coords[i], ctm);
}
+void fz_trim_path(fz_context *ctx, fz_path *path)
+{
+ if (path->cmd_cap > path->cmd_len)
+ {
+ path->cmds = fz_resize_array(ctx, path->cmds, path->cmd_len, sizeof(unsigned char));
+ path->cmd_cap = path->cmd_len;
+ }
+ if (path->coord_cap > path->coord_len)
+ {
+ path->coords = fz_resize_array(ctx, path->coords, path->coord_len, sizeof(float));
+ path->coord_cap = path->coord_len;
+ }
+}
+
#ifndef NDEBUG
void
fz_print_path(fz_context *ctx, FILE *out, fz_path *path, int indent)
@@ -382,25 +379,13 @@ fz_keep_stroke_state(fz_context *ctx, fz_stroke_state *stroke)
if (stroke->refs == -2)
return fz_clone_stroke_state(ctx, stroke);
- fz_lock(ctx, FZ_LOCK_ALLOC);
- if (stroke->refs > 0)
- stroke->refs++;
- fz_unlock(ctx, FZ_LOCK_ALLOC);
- return stroke;
+ return fz_keep_imp(ctx, stroke, &stroke->refs);
}
void
fz_drop_stroke_state(fz_context *ctx, fz_stroke_state *stroke)
{
- int drop;
-
- if (!stroke)
- return;
-
- fz_lock(ctx, FZ_LOCK_ALLOC);
- drop = (stroke->refs > 0 ? --stroke->refs == 0 : 0);
- fz_unlock(ctx, FZ_LOCK_ALLOC);
- if (drop)
+ if (fz_drop_imp(ctx, stroke, &stroke->refs))
fz_free(ctx, stroke);
}
@@ -464,10 +449,12 @@ fz_unshare_stroke_state_with_dash_len(fz_context *ctx, fz_stroke_state *shared,
len = 0;
if (single && shlen >= len)
return shared;
+
unsize = sizeof(*unshared) + sizeof(unshared->dash_list[0]) * len;
unshared = Memento_label(fz_malloc(ctx, unsize), "fz_stroke_state");
memcpy(unshared, shared, (shsize > unsize ? unsize : shsize));
unshared->refs = 1;
+
fz_lock(ctx, FZ_LOCK_ALLOC);
drop = (shared->refs > 0 ? --shared->refs == 0 : 0);
fz_unlock(ctx, FZ_LOCK_ALLOC);