summaryrefslogtreecommitdiff
path: root/tree/optimize.c
diff options
context:
space:
mode:
Diffstat (limited to 'tree/optimize.c')
-rw-r--r--tree/optimize.c310
1 files changed, 0 insertions, 310 deletions
diff --git a/tree/optimize.c b/tree/optimize.c
deleted file mode 100644
index d92aa812..00000000
--- a/tree/optimize.c
+++ /dev/null
@@ -1,310 +0,0 @@
-#include <fitz.h>
-
-/*
- * Remove (mask ... white) until we get something not white
- */
-
-static int iswhitenode(fz_colornode *node)
-{
- if (!strcmp(node->cs->name, "DeviceGray"))
- return fabs(node->samples[0] - 1.0) < FLT_EPSILON;
- if (!strcmp(node->cs->name, "DeviceRGB"))
- return fabs(node->samples[0] - 1.0) < FLT_EPSILON &&
- fabs(node->samples[1] - 1.0) < FLT_EPSILON &&
- fabs(node->samples[2] - 1.0) < FLT_EPSILON;
- if (!strcmp(node->cs->name, "DeviceCMYK"))
- return fabs(node->samples[0]) < FLT_EPSILON &&
- fabs(node->samples[1]) < FLT_EPSILON &&
- fabs(node->samples[2]) < FLT_EPSILON &&
- fabs(node->samples[3]) < FLT_EPSILON;
- return 0;
-}
-
-static int cleanwhite(fz_node *node)
-{
- fz_node *current;
- fz_node *next;
- fz_node *shape;
- fz_node *color;
-
- for (current = node->first; current; current = next)
- {
- next = current->next;
-
- if (fz_islinknode(current))
- return 1;
- else if (fz_isimagenode(current))
- return 1;
- else if (fz_isshadenode(current))
- return 1;
- else if (fz_iscolornode(current))
- {
- if (!iswhitenode((fz_colornode*)current))
- return 1;
- }
-
- else if (fz_ismasknode(current))
- {
- shape = current->first;
- color = shape->next;
- if (fz_iscolornode(color))
- {
- if (iswhitenode((fz_colornode*)color))
- fz_removenode(current);
- else
- return 1;
- }
- else
- {
- if (cleanwhite(current))
- return 1;
- }
- }
-
- else
- {
- if (cleanwhite(current))
- return 1;
- }
- }
-
- return 0;
-}
-
-/*
- * Remove useless overs that only have one child.
- */
-
-static void cleanovers(fz_node *node)
-{
- fz_node *prev;
- fz_node *next;
- fz_node *current;
- fz_node *child;
-
- prev = nil;
- for (current = node->first; current; current = next)
- {
- next = current->next;
-
- if (fz_isovernode(current))
- {
- if (current->first == current->last)
- {
- child = current->first;
- fz_removenode(current);
- if (child)
- {
- if (prev)
- fz_insertnodeafter(prev, child);
- else
- fz_insertnodefirst(node, child);
- }
- current = child;
- }
- }
-
- if (current)
- prev = current;
- }
-
- for (current = node->first; current; current = current->next)
- cleanovers(current);
-}
-
-/*
- * Remove rectangular clip-masks whose contents fit...
- */
-
-static int getrect(fz_pathnode *path, fz_rect *bboxp)
-{
- float x, y, w, h;
-
- /* move x y, line x+w y, line x+w y+h, line x y+h, close */
-
- if (path->len != 13)
- return 0;
-
- if (path->els[0].k != FZ_MOVETO) return 0;
- x = path->els[1].v;
- y = path->els[2].v;
-
- if (path->els[3].k != FZ_LINETO) return 0;
- w = path->els[4].v - x;
- if (path->els[5].v != y) return 0;
-
- if (path->els[6].k != FZ_LINETO) return 0;
- if (path->els[7].v != x + w) return 0;
- h = path->els[8].v - y;
-
- if (path->els[9].k != FZ_LINETO) return 0;
- if (path->els[10].v != x) return 0;
- if (path->els[11].v != y + h) return 0;
-
- if (path->els[12].k != FZ_CLOSEPATH) return 0;
-
- bboxp->min.x = MIN(x, x + w);
- bboxp->min.y = MIN(y, y + h);
- bboxp->max.x = MAX(x, x + w);
- bboxp->max.y = MAX(y, y + h);
-
- return 1;
-}
-
-static int fitsinside(fz_node *node, fz_rect clip)
-{
- fz_rect bbox;
- bbox = fz_boundnode(node, fz_identity());
- if (fz_isinfiniterect(bbox)) return 0;
- if (fz_isemptyrect(bbox)) return 1;
- if (bbox.min.x < clip.min.x) return 0;
- if (bbox.max.x > clip.max.x) return 0;
- if (bbox.min.y < clip.min.y) return 0;
- if (bbox.max.y > clip.max.y) return 0;
- return 1;
-}
-
-static void cleanmasks(fz_node *node)
-{
- fz_node *prev;
- fz_node *current;
- fz_node *shape;
- fz_node *color;
- fz_rect bbox;
-
- for (current = node->first; current; current = current->next)
- cleanmasks(current);
-
- prev = nil;
- for (current = node->first; current; current = current->next)
- {
-retry:
- if (fz_ismasknode(current))
- {
- shape = current->first;
- color = shape->next;
-
- if (color == nil)
- {
- fz_removenode(current);
- prev = nil;
- current = node->first;
- goto retry;
- }
-
- if (fz_ispathnode(shape))
- {
- if (getrect((fz_pathnode*)shape, &bbox))
- {
- if (fitsinside(color, bbox))
- {
- fz_removenode(current);
- if (prev)
- fz_insertnodeafter(prev, color);
- else
- fz_insertnodefirst(node, color);
- current = color;
- goto retry;
- }
- }
- }
- }
-
- prev = current;
- }
-}
-
-/*
- * Turn 1x1 images into rectangle fills
- */
-
-static fz_error *clean1x1(fz_node *node)
-{
- fz_error *error;
- fz_node *current;
- fz_node *color;
- fz_pathnode *rect;
- fz_node *mask;
- fz_image *image;
- fz_pixmap *pix;
- float v[FZ_MAXCOLORS];
- int i;
-
- for (current = node->first; current; current = current->next)
- {
- if (fz_isimagenode(current))
- {
- image = ((fz_imagenode*)current)->image;
- if (image->w == 1 && image->h == 1)
- {
- error = fz_newpathnode(&rect);
- fz_moveto(rect, 0, 0);
- fz_lineto(rect, 1, 0);
- fz_lineto(rect, 1, 1);
- fz_lineto(rect, 0, 1);
- fz_closepath(rect);
- fz_endpath(rect, FZ_FILL, nil, nil);
-
- if (image->cs)
- {
- error = fz_newpixmap(&pix, 0, 0, 1, 1, image->n + 1);
- if (error)
- return error;
-
- error = image->loadtile(image, pix);
- if (error)
- return error;
-
- for (i = 0; i < image->n; i++)
- v[i] = pix->samples[i + 1] / 255.0;
-
- fz_droppixmap(pix);
-
- error = fz_newcolornode(&color, image->cs, image->n, v);
- if (error)
- return error;
- error = fz_newmasknode(&mask);
- if (error)
- return error;
-
- fz_insertnodeafter(current, mask);
- fz_insertnodelast(mask, (fz_node*)rect);
- fz_insertnodelast(mask, color);
- fz_removenode(current);
- current = mask;
- }
-
- else
- {
- /* pray that the 1x1 image mask is all opaque */
- fz_insertnodeafter(current, (fz_node*)rect);
- fz_removenode(current);
- current = (fz_node*)rect;
- }
- }
- }
-
- error = clean1x1(current);
- if (error)
- return error;
- }
-
- return nil;
-}
-
-/*
- *
- */
-
-fz_error *
-fz_optimizetree(fz_tree *tree)
-{
- if (getenv("DONTOPT"))
- return nil;
- cleanwhite(tree->root);
- cleanovers(tree->root);
- cleanmasks(tree->root);
- clean1x1(tree->root);
- return nil;
-}
-