#include "gfxtools.h"
#include "gfxpoly.h"
#include "mem.h"
-#ifdef INTERNAL_LIBART
#include "art/libart.h"
#include "art/art_svp_intersect.h"
#include "art/art_svp_ops.h"
-#else
-#include <libart_lgpl/libart.h>
-#include <libart_lgpl/art_svp_intersect.h>
-#include <libart_lgpl/art_svp_ops.h>
-#endif
#include "log.h"
#include <assert.h>
#include <memory.h>
if(x1 < b.xmin) b.xmin = x1;
if(y1 < b.ymin) b.ymin = y1;
if(x2 > b.xmax) b.xmax = x2;
- if(y2 > b.xmax) b.ymax = y2;
+ if(y2 > b.ymax) b.ymax = y2;
}
}
if(b.xmax > (int)(MAX_WIDTH*zoom))
#define B00000010 0x02
#define B00000001 0x01
-int compare_bitmaps(intbbox_t*bbox, unsigned char*data1, unsigned char*data2)
+static int compare_bitmaps(intbbox_t*bbox, unsigned char*data1, unsigned char*data2)
{
- int similar = 0;
+ if(!data1 || !data2)
+ return 0;
int x,y;
int height = bbox->height;
int width = bbox->width;
int width8 = (width+7) >> 3;
unsigned char*l1 = &data1[width8];
unsigned char*l2 = &data2[width8];
- int fail = 0;
for(y=1;y<height-1;y++) {
for(x=0;x<width8;x++) {
unsigned a = l1[x-width8] & l1[x] & l1[x+width8];
unsigned b = l2[x-width8] & l2[x] & l2[x+width8];
-
- if((a&B11100000) && !(l2[x]&B01000000))
- fail == 1;
- if((a&B01110000) && !(l2[x]&B00100000))
- fail == 1;
- if((a&B00111000) && !(l2[x]&B00010000))
- fail == 1;
- if((a&B00011100) && !(l2[x]&B00001000))
- fail == 1;
- if((a&B00001110) && !(l2[x]&B00000100))
- fail == 1;
- if((a&B00000111) && !(l2[x]&B00000010))
- fail == 1;
-
- if((b&B11100000) && !(l1[x]&B01000000))
- fail == 1;
- if((b&B01110000) && !(l1[x]&B00100000))
- fail == 1;
- if((b&B00111000) && !(l1[x]&B00010000))
- fail == 1;
- if((b&B00011100) && !(l1[x]&B00001000))
- fail == 1;
- if((b&B00001110) && !(l1[x]&B00000100))
- fail == 1;
- if((b&B00000111) && !(l1[x]&B00000010))
- fail == 1;
+
+ if((a&B11100000) && !(l2[x]&B01000000)) return 0;
+ if((a&B01110000) && !(l2[x]&B00100000)) return 0;
+ if((a&B00111000) && !(l2[x]&B00010000)) return 0;
+ if((a&B00011100) && !(l2[x]&B00001000)) return 0;
+ if((a&B00001110) && !(l2[x]&B00000100)) return 0;
+ if((a&B00000111) && !(l2[x]&B00000010)) return 0;
+
+ if((b&B11100000) && !(l1[x]&B01000000)) return 0;
+ if((b&B01110000) && !(l1[x]&B00100000)) return 0;
+ if((b&B00111000) && !(l1[x]&B00010000)) return 0;
+ if((b&B00011100) && !(l1[x]&B00001000)) return 0;
+ if((b&B00001110) && !(l1[x]&B00000100)) return 0;
+ if((b&B00000111) && !(l1[x]&B00000010)) return 0;
}
l1 += width8;
l2 += width8;
}
- return !fail;
+ return 1;
}
pos = 0;
l2 = line;
+ int lastmove=-1;
while(l2) {
if(l2->type == gfx_moveTo) {
vec[pos].code = ART_MOVETO_OPEN;
vec[pos].x = l2->x;
vec[pos].y = l2->y;
+ lastmove=pos;
pos++;
assert(pos<=len);
} else if(l2->type == gfx_lineTo) {
}
x = l2->x;
y = l2->y;
+
+ /* let closed line segments start w/ MOVETO instead of MOVETO_OPEN */
+ if(lastmove>=0 && l2->type!=gfx_moveTo && (!l2->next || l2->next->type == gfx_moveTo)) {
+ if(vec[lastmove].x == l2->x &&
+ vec[lastmove].y == l2->y) {
+ assert(vec[lastmove].code == ART_MOVETO_OPEN);
+ vec[lastmove].code = ART_MOVETO;
+ }
+ }
+
l2 = l2->next;
}
vec[pos++].code = ART_END;
}
/* Find adjacent identical points. If an ajdacent pair of identical
- points is found, the second is removed.
+ points is found, the second one is removed.
So moveto x,y lineto x,y becomes moveto x,y
lineto x,y lineto x,y becomes lineto x,y
lineto x,y moveto x,y becomes lineto x,y
//#ifdef SHEAR
// double shear = find_shear_value(svp);
-// gfxline_t*line = gfxpoly_to_gfxline((gfxpoly_t*)svp);
+// gfxline_t*line = gfxline_from_gfxpoly((gfxpoly_t*)svp);
// gfxline_t*l = line;
// while(l) {
// l->y += l->x*shear;
return result;
}
-gfxline_t* gfxpoly_to_gfxline(gfxpoly_t*poly)
+gfxline_t* gfxline_from_gfxpoly(gfxpoly_t*poly)
{
ArtSVP*svp = (ArtSVP*)poly;
int size = 0;
}
}
-gfxpoly_t* gfxpoly_fillToPoly(gfxline_t*line)
+gfxpoly_t* gfxpoly_from_fill(gfxline_t*line, double gridsize)
{
/* I'm not sure whether doing perturbation here is actually
a good idea- if that line has been run through the machinery
return (gfxpoly_t*)svp;
}
-gfxpoly_t* gfxpoly_strokeToPoly(gfxline_t*line, gfxcoord_t width, gfx_capType cap_style, gfx_joinType joint_style, double miterLimit)
+gfxpoly_t* gfxpoly_from_stroke(gfxline_t*line, gfxcoord_t width, gfx_capType cap_style, gfx_joinType joint_style, double miterLimit, double gridsize)
{
ArtVpath* vec = gfxline_to_ArtVpath(line, 0);
msg("<verbose> Casting gfxline of %d segments to a stroke-polygon", gfxline_len(line));
return (gfxpoly_t*)svp;
}
-gfxline_t* gfxline_circularToEvenOdd(gfxline_t*line)
+gfxline_t* gfxpoly_circular_to_evenodd(gfxline_t*line, double gridsize)
{
msg("<verbose> Converting circular-filled gfxline of %d segments to even-odd filled gfxline", gfxline_len(line));
ArtSVP* svp = gfxfillToSVP(line, 1);
- /* TODO: ART_WIND_RULE_POSITIVE means that a shape is visible if
- positive and negative line segments add up to something positive.
- I *think* that clockwise fill in PDF is defined in a way, however,
- that the *last* shape's direction will determine whether something
- is filled */
ArtSVP* svp_rewinded;
- svp_rewinded = run_intersector(svp, ART_WIND_RULE_POSITIVE);
+ svp_rewinded = run_intersector(svp, ART_WIND_RULE_NONZERO);
if(!svp_rewinded) {
art_svp_free(svp);
return 0;
}
- gfxline_t* result = gfxpoly_to_gfxline((gfxpoly_t*)svp_rewinded);
+ gfxline_t* result = gfxline_from_gfxpoly((gfxpoly_t*)svp_rewinded);
art_svp_free(svp);
art_svp_free(svp_rewinded);
return result;
}
-gfxpoly_t* gfxpoly_createbox(double x1, double y1,double x2, double y2)
+gfxpoly_t* gfxpoly_createbox(double x1, double y1,double x2, double y2, double gridsize)
{
ArtVpath *vec = art_new (ArtVpath, 5+1);
vec[0].code = ART_MOVETO;
return (gfxpoly_t*)svp;
}
-void gfxpoly_free(gfxpoly_t*poly)
+void gfxpoly_destroy(gfxpoly_t*poly)
{
ArtSVP*svp = (ArtSVP*)poly;
art_svp_free(svp);