summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor.andersson@artifex.com>2013-10-31 16:27:12 +0100
committerTor Andersson <tor.andersson@artifex.com>2013-11-05 16:26:01 +0100
commit1dd2a1ae1f1cb7d93ec2edcc5a6c7e7fd4f0e2ec (patch)
treeef65a1856625d83ac529b874a35d54a59f840c90
parent35f1679b8b0b5dff3021c642c014c2f564393465 (diff)
downloadmupdf-1dd2a1ae1f1cb7d93ec2edcc5a6c7e7fd4f0e2ec.tar.xz
Allow stroke states to be kept on the stack.
Add a function to clone stroke states, a magic number to keep in the reference count to signal that a stroke state is stack-stored, and automatically clone stack stored stroke states in the keep function. Use fz_default_stroke_state to initialise stack stored stroke states.
-rw-r--r--include/mupdf/fitz/path.h3
-rw-r--r--source/fitz/path.c23
2 files changed, 26 insertions, 0 deletions
diff --git a/include/mupdf/fitz/path.h b/include/mupdf/fitz/path.h
index a4a74aea..9b32b8d3 100644
--- a/include/mupdf/fitz/path.h
+++ b/include/mupdf/fitz/path.h
@@ -81,12 +81,15 @@ 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);
+extern const fz_stroke_state fz_default_stroke_state;
+
fz_stroke_state *fz_new_stroke_state(fz_context *ctx);
fz_stroke_state *fz_new_stroke_state_with_dash_len(fz_context *ctx, int len);
fz_stroke_state *fz_keep_stroke_state(fz_context *ctx, fz_stroke_state *stroke);
void fz_drop_stroke_state(fz_context *ctx, fz_stroke_state *stroke);
fz_stroke_state *fz_unshare_stroke_state(fz_context *ctx, fz_stroke_state *shared);
fz_stroke_state *fz_unshare_stroke_state_with_dash_len(fz_context *ctx, fz_stroke_state *shared, int len);
+fz_stroke_state *fz_clone_stroke_state(fz_context *ctx, fz_stroke_state *stroke);
#ifndef NDEBUG
void fz_print_path(fz_context *ctx, FILE *out, fz_path *, int indent);
diff --git a/source/fitz/path.c b/source/fitz/path.c
index 811db282..04a3a7bc 100644
--- a/source/fitz/path.c
+++ b/source/fitz/path.c
@@ -364,12 +364,24 @@ fz_print_path(fz_context *ctx, FILE *out, fz_path *path, int indent)
}
#endif
+const fz_stroke_state fz_default_stroke_state = {
+ -2, /* -2 is the magic number we use when we have stroke states stored on the stack */
+ FZ_LINECAP_BUTT, FZ_LINECAP_BUTT, FZ_LINECAP_BUTT,
+ FZ_LINEJOIN_MITER,
+ 1, 10,
+ 0, 0, { 0 }
+};
+
fz_stroke_state *
fz_keep_stroke_state(fz_context *ctx, fz_stroke_state *stroke)
{
if (!stroke)
return NULL;
+ /* -2 is the magic number we use when we have stroke states stored on the stack */
+ if (stroke->refs == -2)
+ return fz_clone_stroke_state(ctx, stroke);
+
fz_lock(ctx, FZ_LOCK_ALLOC);
if (stroke->refs > 0)
stroke->refs++;
@@ -423,6 +435,17 @@ fz_new_stroke_state(fz_context *ctx)
}
fz_stroke_state *
+fz_clone_stroke_state(fz_context *ctx, fz_stroke_state *stroke)
+{
+ fz_stroke_state *clone = fz_new_stroke_state_with_dash_len(ctx, stroke->dash_len);
+ int extra = stroke->dash_len - nelem(stroke->dash_list);
+ int size = sizeof(*stroke) + sizeof(stroke->dash_list[0]) * extra;
+ memcpy(clone, stroke, size);
+ clone->refs = 1;
+ return clone;
+}
+
+fz_stroke_state *
fz_unshare_stroke_state_with_dash_len(fz_context *ctx, fz_stroke_state *shared, int len)
{
int single, unsize, shsize, shlen, drop;