summaryrefslogtreecommitdiff
path: root/source/pdf
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2015-03-05 17:31:05 -0700
committerRobin Watts <robin.watts@artifex.com>2015-03-24 19:50:00 +0000
commit5f161e45d5daacb696d02b8fad23d0c23f5bc8bc (patch)
tree6e8d84a383d580ee38b23dfb345bc96d0ba1e63e /source/pdf
parent563c482145d65c4006f5842c8860ab1b09f5a229 (diff)
downloadmupdf-5f161e45d5daacb696d02b8fad23d0c23f5bc8bc.tar.xz
Path rework for improved memory usage.
Firstly, we make the definition of the path structures local to path.c. This is achieved by using an fz_path_processor function to step through paths enumerating each section using callback functions. Next, we extend the internal path representation to include other section types, including quads, beziers with common control points rectangles, horizontal, vertical and degenerate lines. We also roll close path sections up into the previous sections commands. The hairiest part of this is that fz_transform_path has to cope with changing the path commands depending on the matrix. This is a relatively rare operation though.
Diffstat (limited to 'source/pdf')
-rw-r--r--source/pdf/pdf-device.c80
-rw-r--r--source/pdf/pdf-op-run.c6
2 files changed, 49 insertions, 37 deletions
diff --git a/source/pdf/pdf-device.c b/source/pdf/pdf-device.c
index 553810f6..e3b63dc5 100644
--- a/source/pdf/pdf-device.c
+++ b/source/pdf/pdf-device.c
@@ -360,42 +360,58 @@ pdf_dev_stroke_state(fz_context *ctx, pdf_device *pdev, fz_stroke_state *stroke_
gs->stroke_state = fz_keep_stroke_state(ctx, stroke_state);
}
+typedef struct
+{
+ fz_context *ctx;
+ fz_buffer *buf;
+} pdf_dev_path_arg;
+
+static void
+pdf_dev_path_moveto(fz_context *ctx, void *arg, float x, float y)
+{
+ fz_buffer *buf = (fz_buffer *)arg;
+
+ fz_buffer_printf(ctx, buf, "%f %f m\n", x, y);
+}
+
+static void
+pdf_dev_path_lineto(fz_context *ctx, void *arg, float x, float y)
+{
+ fz_buffer *buf = (fz_buffer *)arg;
+
+ fz_buffer_printf(ctx, buf, "%f %f l\n", x, y);
+}
+
+static void
+pdf_dev_path_curveto(fz_context *ctx, void *arg, float x1, float y1, float x2, float y2, float x3, float y3)
+{
+ fz_buffer *buf = (fz_buffer *)arg;
+
+ fz_buffer_printf(ctx, buf, "%f %f %f %f %f %f c\n", x1, y1, x2, y2, x3, y3);
+}
+
+static void
+pdf_dev_path_close(fz_context *ctx, void *arg)
+{
+ fz_buffer *buf = (fz_buffer *)arg;
+
+ fz_buffer_printf(ctx, buf, "h\n");
+}
+
+static const fz_path_processor pdf_dev_path_proc =
+{
+ pdf_dev_path_moveto,
+ pdf_dev_path_lineto,
+ pdf_dev_path_curveto,
+ pdf_dev_path_close
+};
+
static void
pdf_dev_path(fz_context *ctx, pdf_device *pdev, fz_path *path)
{
gstate *gs = CURRENT_GSTATE(pdev);
- float x, y;
- int i = 0, k = 0;
- while (i < path->cmd_len)
- {
- switch (path->cmds[i++])
- {
- case FZ_MOVETO:
- x = path->coords[k++];
- y = path->coords[k++];
- fz_buffer_printf(ctx, gs->buf, "%f %f m\n", x, y);
- break;
- case FZ_LINETO:
- x = path->coords[k++];
- y = path->coords[k++];
- fz_buffer_printf(ctx, gs->buf, "%f %f l\n", x, y);
- break;
- case FZ_CURVETO:
- x = path->coords[k++];
- y = path->coords[k++];
- fz_buffer_printf(ctx, gs->buf, "%f %f ", x, y);
- x = path->coords[k++];
- y = path->coords[k++];
- fz_buffer_printf(ctx, gs->buf, "%f %f ", x, y);
- x = path->coords[k++];
- y = path->coords[k++];
- fz_buffer_printf(ctx, gs->buf, "%f %f c\n", x, y);
- break;
- case FZ_CLOSE_PATH:
- fz_buffer_printf(ctx, gs->buf, "h\n");
- break;
- }
- }
+
+ fz_process_path(ctx, &pdf_dev_path_proc, (void *)gs->buf, path);
}
static void
diff --git a/source/pdf/pdf-op-run.c b/source/pdf/pdf-op-run.c
index 2bdd3b55..e153dbd1 100644
--- a/source/pdf/pdf-op-run.c
+++ b/source/pdf/pdf-op-run.c
@@ -1516,11 +1516,7 @@ static void pdf_run_h(fz_context *ctx, pdf_processor *proc)
static void pdf_run_re(fz_context *ctx, pdf_processor *proc, float x, float y, float w, float h)
{
pdf_run_processor *pr = (pdf_run_processor *)proc;
- fz_moveto(ctx, pr->path, x, y);
- fz_lineto(ctx, pr->path, x + w, y);
- fz_lineto(ctx, pr->path, x + w, y + h);
- fz_lineto(ctx, pr->path, x, y + h);
- fz_closepath(ctx, pr->path);
+ fz_rectto(ctx, pr->path, x, y, x+w, y+h);
}
/* path painting */