+ 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();
+
+ if(!fixBBox(&x1,&y1,&x2,&y2, width, height)) {
+ return gFalse;
+ }
+
+ Guchar*polypixels = boolpoly->getDataPtr();
+ Guchar*textpixels = booltext->getDataPtr();
+
+ int width8 = (width+7)/8;
+ int runx = width8;
+ int runy = height;
+
+ if(x1|y1|x2|y2) {
+ polypixels+=y1*width8+x1/8;
+ textpixels+=y1*width8+x1/8;
+ runx=(x2+7)/8 - x1/8;
+ runy=y2-y1;
+ }
+
+ int t;
+ unsigned char c=0;
+
+ /*assert(sizeof(unsigned long long int)==8);
+ if(((ptroff_t)polypixels&7) || ((ptroff_t)textpixels&7)) {
+ //msg("<warning> Non-optimal alignment");
+ }*/
+
+ int x,y;
+ unsigned char*data1 = (unsigned char*)polypixels;
+ unsigned char*data2 = (unsigned char*)textpixels;
+ msg("<verbose> Testing area (%d,%d,%d,%d), runx=%d,runy=%d", x1,y1,x2,y2, runx, runy);
+ for(y=0;y<runy;y++) {
+ if(compare8(data1,data2,runx))
+ return gTrue;
+ data1+=width8;
+ data2+=width8;
+ }
+ return gFalse;
+ } else {
+ int width = boolpoly->getAlphaRowSize();
+ int height = boolpoly->getHeight();
+
+ if(!fixBBox(&x1, &y1, &x2, &y2, width, height)) {
+ x1=y1=0;x2=y2=1;
+ }
+ Guchar*polypixels = boolpoly->getAlphaPtr();
+ Guchar*textpixels = booltext->getAlphaPtr();
+
+ int x,y;
+ char overlap1 = 0;
+ char overlap2 = 0;
+ for(x=x1;x<x2;x++) {
+ for(y=y1;y<y2;y++) {
+ if(polypixels[width*y+x]&&textpixels[width*y+x])
+ overlap1 = 1;
+ }
+ }
+ int ax1=0,ay1=0,ax2=0,ay2=0;
+ for(y=0;y<height;y++) {
+ for(x=0;x<width;x++) {
+ if(polypixels[width*y+x]&&textpixels[width*y+x]) {
+ overlap2 = 1;
+ if(!(ax1|ay1|ax2|ay2)) {
+ ax1 = ax2 = x;
+ ay1 = ay2 = y;
+ } else {
+ ax1 = ax1<x?ax1:x;
+ ay1 = ay1<y?ay1:y;
+ ax2 = ax2>x?ax2:x;
+ ay2 = ay2>y?ay2:y;
+ }
+ }
+ }
+ }
+ if(overlap1 && !overlap2)
+ msg("<warning> strange internal error");
+ if(!overlap1 && overlap2) {
+ msg("<warning> Bad bounding box: intersection outside bbox");
+ msg("<warning> given bbox: %d %d %d %d", x1, y1, x2, y2);
+ msg("<warning> changed area: %d %d %d %d", ax1, ay1, ax2, ay2);
+ }
+ return overlap2;
+ }
+}
+
+GBool BitmapOutputDev::checkPageSlice(Page *page, double hDPI, double vDPI,
+ int rotate, GBool useMediaBox, GBool crop,
+ int sliceX, int sliceY, int sliceW, int sliceH,
+ GBool printing, Catalog *catalog,
+ GBool (*abortCheckCbk)(void *data),
+ void *abortCheckCbkData)
+{
+ this->setPage(page);
+ gfxdev->setPage(page);
+ return gTrue;
+}
+
+void BitmapOutputDev::startPage(int pageNum, GfxState *state)
+{
+ PDFRectangle *r = this->page->getCropBox();
+ double x1,y1,x2,y2;
+ state->transform(r->x1,r->y1,&x1,&y1);
+ state->transform(r->x2,r->y2,&x2,&y2);
+ if(x2<x1) {double x3=x1;x1=x2;x2=x3;}
+ if(y2<y1) {double y3=y1;y1=y2;y2=y3;}
+
+ this->movex = -(int)x1 - user_movex;
+ this->movey = -(int)y1 - user_movey;
+
+ if(user_clipx1|user_clipy1|user_clipx2|user_clipy2) {
+ x1 = user_clipx1;
+ x2 = user_clipx2;
+ y1 = user_clipy1;
+ y2 = user_clipy2;
+ }
+ this->width = (int)(x2-x1);
+ this->height = (int)(y2-y1);
+
+ rgbdev->startPage(pageNum, state);
+ boolpolydev->startPage(pageNum, state);
+ booltextdev->startPage(pageNum, state);
+ clip0dev->startPage(pageNum, state);
+ clip1dev->startPage(pageNum, state);
+ gfxdev->startPage(pageNum, state);
+
+ boolpolybitmap = boolpolydev->getBitmap();
+ stalepolybitmap = new SplashBitmap(boolpolybitmap->getWidth(), boolpolybitmap->getHeight(), 1, boolpolybitmap->getMode(), 0);
+ assert(stalepolybitmap->getRowSize() == boolpolybitmap->getRowSize());
+
+ booltextbitmap = booltextdev->getBitmap();
+ staletextbitmap = new SplashBitmap(booltextbitmap->getWidth(), booltextbitmap->getHeight(), 1, booltextbitmap->getMode(), 0);
+ assert(staletextbitmap->getRowSize() == booltextbitmap->getRowSize());
+
+ msg("<debug> startPage %dx%d (%dx%d)", this->width, this->height, booltextbitmap->getWidth(), booltextbitmap->getHeight());
+
+ clip0bitmap = clip0dev->getBitmap();
+ clip1bitmap = clip1dev->getBitmap();
+ rgbbitmap = rgbdev->getBitmap();
+
+ flushText(); // write out the initial clipping rectangle
+
+ /* just in case any device did draw a white background rectangle
+ into the device */
+ clearBoolTextDev();
+ clearBoolPolyDev();
+
+ this->layerstate = STATE_PARALLEL;
+ this->emptypage = 1;
+ msg("<debug> startPage done");