+ GBool ret = false;
+ if(intersection(boolpolybitmap, staletextbitmap, x1,y1,x2,y2)) {
+ if(layerstate==STATE_PARALLEL) {
+ msg("<verbose> Bitmap is above current text data");
+ layerstate=STATE_BITMAP_IS_ABOVE;
+ update_bitmap(stalepolybitmap, boolpolybitmap, x1, y1, x2, y2, 0);
+ } else if(layerstate==STATE_TEXT_IS_ABOVE) {
+ msg("<verbose> Bitmap is above current text data (which is above some bitmap)");
+ flushBitmap();
+ layerstate=STATE_BITMAP_IS_ABOVE;
+ clearBoolPolyDev();
+ update_bitmap(stalepolybitmap, boolpolybitmap, x1, y1, x2, y2, 1);
+ ret = true;
+ } else {
+ msg("<verbose> Bitmap is still above current text data");
+ update_bitmap(stalepolybitmap, boolpolybitmap, x1, y1, x2, y2, 0);
+ }
+ } else {
+ update_bitmap(stalepolybitmap, boolpolybitmap, x1, y1, x2, y2, 0);
+ }
+
+ /* clear the thing we just drew from our temporary drawing bitmap */
+ clearBooleanBitmap(boolpolybitmap, x1, y1, x2, y2);
+
+ return ret;
+}
+
+//void checkNewText() {
+// Guchar*alpha = rgbbitmap->getAlphaPtr();
+// Guchar*charpixels = clip1bitmap->getDataPtr();
+// int xx,yy;
+// for(yy=0;yy<height;yy++) {
+// Guchar*aline = &alpha[yy*width];
+// Guchar*cline = &charpixels[yy*width8];
+// for(xx=0;xx<width;xx++) {
+// int bit = xx&7;
+// int bytepos = xx>>3;
+// /* TODO: is the bit order correct? */
+// if(aline[xx] && (cline[bytepos]&(1<<bit)))
+// break;
+// }
+// if(xx!=width)
+// break;
+//}
+
+GBool BitmapOutputDev::clip0and1differ(int x1,int y1,int x2,int y2)
+{
+ if(clip0bitmap->getMode()==splashModeMono1) {
+ int width = clip0bitmap->getWidth();
+ int width8 = (width+7)/8;
+ int height = clip0bitmap->getHeight();
+
+ if(!fixBBox(&x1,&y1,&x2,&y2,width,height)) {
+ /* area is outside or null */
+ return gFalse;
+ }
+
+ SplashBitmap*clip0 = clip0bitmap;
+ SplashBitmap*clip1 = clip1bitmap;
+ int x18 = x1/8;
+ int x28 = (x2+7)/8;
+ int y;
+
+ for(y=y1;y<y2;y++) {
+ unsigned char*row1 = &clip0bitmap->getDataPtr()[width8*y+x18];
+ unsigned char*row2 = &clip1bitmap->getDataPtr()[width8*y+x18];
+ if(memcmp(row1, row2, x28-x18)) {
+ return gTrue;
+ }
+ }
+ return gFalse;
+ } else {
+ SplashBitmap*clip0 = clip0bitmap;
+ SplashBitmap*clip1 = clip1bitmap;
+ int width = clip0->getAlphaRowSize();
+ int height = clip0->getHeight();
+
+ if(!fixBBox(&x1, &y1, &x2, &y2, width, height)) {
+ x1=y1=0;x2=y2=1;
+ }
+
+ Guchar*a0 = clip0->getAlphaPtr();
+ Guchar*a1 = clip1->getAlphaPtr();
+ int x,y;
+ char differs=0;
+ for(y=y1;y<y2;y++) {
+ for(x=x1;x<x2;x++) {
+ if(a0[y*width+x]!=a1[y*width+x]) {
+ differs=1;
+ break;
+ }
+ }
+ if(differs)
+ break;
+ }
+ char differs2 = memcmp(a0, a1, width*height);
+ if(differs && !differs2)
+ msg("<warning> Strange internal error (2)");
+ else if(!differs && differs2) {
+ msg("<warning> Bad Bounding Box: Difference in clip0 and clip1 outside bbox");
+ msg("<warning> %d %d %d %d", x1, y1, x2, y2);
+ }
+ return differs2;
+ }
+}
+
+GBool compare8(unsigned char*data1, unsigned char*data2, int len)
+{
+ if(!len)
+ return 0;
+ if(((ptroff_t)data1&7)==((ptroff_t)data2&7)) {
+ // oh good, we can align both to 8 byte
+ while((ptroff_t)data1&7) {
+ if(*data1&*data2)
+ return 1;
+ data1++;
+ data2++;
+ if(!--len)
+ return 0;
+ }
+ }
+ /* use 64 bit for the (hopefully aligned) middle section */
+ int l8 = len/8;
+ long long unsigned int*d1 = (long long unsigned int*)data1;
+ long long unsigned int*d2 = (long long unsigned int*)data2;
+ long long unsigned int x = 0;
+ int t;
+ for(t=0;t<l8;t++) {
+ x |= d1[t]&d2[t];
+ }
+ if(x)
+ return 1;
+
+ data1+=l8*8;
+ data2+=l8*8;
+ len -= l8*8;
+ for(t=0;t<len;t++) {
+ if(data1[t]&data2[t]) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+GBool BitmapOutputDev::intersection(SplashBitmap*boolpoly, SplashBitmap*booltext, int x1, int y1, int x2, int y2)
+{
+ if(boolpoly->getMode()==splashModeMono1) {
+ /* alternative implementation, using one bit per pixel-
+ needs the no-dither patch in xpdf */
+
+ int width = boolpoly->getWidth();
+ int height = boolpoly->getHeight();