diff options
Diffstat (limited to 'source/fitz/path.c')
-rw-r--r-- | source/fitz/path.c | 79 |
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); |