X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=lib%2Fpdf%2FBitmapOutputDev.cc;h=c27f87f4933f2dbb15c7a0978d8119e075fff25b;hb=1f80a93dce1414db2d9b237b6af51527bd3d14bf;hp=cedf06a80ec09b7f17ac4ef11c7a0ba066a741e7;hpb=d82ea1e1a48c88241e2d01c4b9ad935ebcb3b9ba;p=swftools.git diff --git a/lib/pdf/BitmapOutputDev.cc b/lib/pdf/BitmapOutputDev.cc index cedf06a..c27f87f 100644 --- a/lib/pdf/BitmapOutputDev.cc +++ b/lib/pdf/BitmapOutputDev.cc @@ -307,7 +307,7 @@ static int dbg_btm_counter=1; static const char*STATE_NAME[] = {"parallel", "textabovebitmap", "bitmapabovetext"}; -void BitmapOutputDev::checkNewText() +void BitmapOutputDev::checkNewText(int x1, int y1, int x2, int y2) { /* called once some new text was drawn on booltextdev, and before the same thing is drawn on gfxdev */ @@ -324,7 +324,7 @@ void BitmapOutputDev::checkNewText() } dbg_btm_counter++; - if(intersection()) { + if(intersection(x1,y1,x2,y2)) { if(layerstate==STATE_PARALLEL) { /* the new text is above the bitmap. So record that fact, and also clear the bitmap buffer, so we can check for @@ -373,7 +373,7 @@ void BitmapOutputDev::checkNewBitmap() } dbg_btm_counter++; - if(intersection()) { + if(intersection(0,0,0,0)) { if(layerstate==STATE_PARALLEL) { msg(" Bitmap is above current text data"); layerstate=STATE_BITMAP_IS_ABOVE; @@ -409,14 +409,46 @@ void BitmapOutputDev::checkNewBitmap() // break; //} -GBool BitmapOutputDev::clip0and1differ() +GBool BitmapOutputDev::clip0and1differ(int x1,int y1,int x2,int y2) { if(clip0bitmap->getMode()==splashModeMono1) { + if(x2<=x1) + return gFalse; + if(x2<0) + return gFalse; + if(x1<0) + x1 = 0; + if(x1>=clip0bitmap->getWidth()) + return gFalse; + if(x2>clip0bitmap->getWidth()) + x2=clip0bitmap->getWidth(); + + if(y2<=y1) + return gFalse; + if(y2<0) + return gFalse; + if(y1<0) + y1 = 0; + if(y1>=clip0bitmap->getHeight()) + return gFalse; + if(y2>clip0bitmap->getHeight()) + y2=clip0bitmap->getHeight(); + SplashBitmap*clip0 = clip0bitmap; SplashBitmap*clip1 = clip1bitmap; - int width8 = (clip0->getWidth()+7)/8; - int height = clip0->getHeight(); - return memcmp(clip0->getDataPtr(), clip1->getDataPtr(), width8*height); + int width8 = (clip0bitmap->getWidth()+7)/8; + int height = clip0bitmap->getHeight(); + int x18 = x1/8; + int x28 = (x2+7)/8; + int y; + + for(y=y1;ygetDataPtr()[width8*y+x18]; + unsigned char*row2 = &clip1bitmap->getDataPtr()[width8*y+x28]; + if(memcmp(row1, row2, x28-x18)) + return gTrue; + } + return gFalse; } else { SplashBitmap*clip0 = clip0bitmap; SplashBitmap*clip1 = clip1bitmap; @@ -440,7 +472,17 @@ static void clearBooleanBitmap(SplashBitmap*btm) } } -GBool BitmapOutputDev::intersection() +long long unsigned int compare64(long long unsigned int*data1, long long unsigned int*data2, int len) +{ + long long unsigned int c; + int t; + for(t=0;tgetDataPtr(); Guchar*textpixels = booltext->getDataPtr(); - + int width8 = (width+7)/8; int height = boolpoly->getHeight(); + if(x1|y1|x2|y2) { + if(y1>=0 && y1<=y2 && y2<=height) { + polypixels+=y1*width8; + textpixels+=y1*width8; + height=y2-y1; + } + } + int t; int len = height*width8; - unsigned int c=0; - if(len & (sizeof(unsigned int)-1)) { - Guchar c2=0; - for(t=0;t Non-optimal alignment"); + } + int l2 = len; + len /= sizeof(unsigned long long int); + c = compare64((unsigned long long int*)polypixels, (unsigned long long int*)textpixels, len); + int l1 = len*sizeof(unsigned long long int); + for(t=l1;t endPage (BitmapOutputDev)"); + + /* notice: we're not fully done yet with this page- there might still be + a few calls to drawLink() yet to come */ +} +void BitmapOutputDev::finishPage() +{ + msg(" finishPage (BitmapOutputDev)"); gfxdev->endPage(); if(layerstate == STATE_BITMAP_IS_ABOVE) { @@ -569,9 +627,6 @@ void BitmapOutputDev::endPage() rgbdev->endPage(); clip0dev->endPage(); clip1dev->endPage(); - - /* notice: we're not fully done yet with this page- there might still be - a few calls to drawLink() yet to come */ } GBool BitmapOutputDev::upsideDown() @@ -1049,7 +1104,7 @@ void BitmapOutputDev::endStringOp(GfxState *state) clip0dev->endStringOp(state); clip1dev->endStringOp(state); booltextdev->endStringOp(state); - checkNewText(); + checkNewText(0,0,0,0); gfxdev->endStringOp(state); } void BitmapOutputDev::beginString(GfxState *state, GString *s) @@ -1066,7 +1121,7 @@ void BitmapOutputDev::endString(GfxState *state) clip0dev->endString(state); clip1dev->endString(state); booltextdev->endString(state); - checkNewText(); + checkNewText(0,0,0,0); gfxdev->endString(state); } @@ -1095,11 +1150,27 @@ void BitmapOutputDev::drawChar(GfxState *state, double x, double y, clearClips(); clip0dev->drawChar(state, x, y, dx, dy, originX, originY, code, nBytes, u, uLen); clip1dev->drawChar(state, x, y, dx, dy, originX, originY, code, nBytes, u, uLen); + + /* calculate the bbox of this character */ + int x1 = (int)x, x2 = (int)x+1, y1 = (int)y, y2 = (int)y+1; + SplashPath*path = clip0dev->getCurrentFont()->getGlyphPath(code); + int t; + for(t=0;tgetLength();t++) { + double xx,yy; + Guchar f; + path->getPoint(t,&xx,&yy,&f); + xx+=x; + yy+=y; + if(xxx2) x2=(int)xx+1; + if(yy>y2) y2=(int)yy+1; + } /* if this character is affected somehow by the various clippings (i.e., it looks different on a device without clipping), then draw it on the bitmap, not as text */ - if(clip0and1differ()) { + if(clip0and1differ(x1,y1,x2,y2)) { msg(" Char %d is affected by clipping", code); boolpolydev->drawChar(state, x, y, dx, dy, originX, originY, code, nBytes, u, uLen); checkNewBitmap(); @@ -1114,7 +1185,7 @@ void BitmapOutputDev::drawChar(GfxState *state, double x, double y, /* this char is not at all affected by clipping. Now just dump out the bitmap we're currently working on, if necessary. */ booltextdev->drawChar(state, x, y, dx, dy, originX, originY, code, nBytes, u, uLen); - checkNewText(); + checkNewText(x1,y1,x2,y2); /* use polygonal output device to do the actual text handling */ gfxdev->drawChar(state, x, y, dx, dy, originX, originY, code, nBytes, u, uLen); } @@ -1136,7 +1207,8 @@ void BitmapOutputDev::endTextObject(GfxState *state) clip0dev->endTextObject(state); clip1dev->endTextObject(state); booltextdev->endTextObject(state); - checkNewText(); + /* TODO: do this only if rendermode!=0 */ + checkNewText(0,0,0,0); gfxdev->endTextObject(state); } @@ -1274,7 +1346,9 @@ void BitmapOutputDev::beginTransparencyGroup(GfxState *state, double *bbox, #if (xpdfMajorVersion*10000 + xpdfMinorVersion*100 + xpdfUpdateVersion) < 30207 GfxState*state1 = state->copy(); GfxState*state2 = state->copy(); + state1->setPath(0); state1->setPath(state->getPath()->copy()); + state2->setPath(0); state2->setPath(state->getPath()->copy()); #else GfxState*state1 = state->copy(gTrue); @@ -1292,7 +1366,9 @@ void BitmapOutputDev::endTransparencyGroup(GfxState *state) #if (xpdfMajorVersion*10000 + xpdfMinorVersion*100 + xpdfUpdateVersion) < 30207 GfxState*state1 = state->copy(); GfxState*state2 = state->copy(); + state1->setPath(0); state1->setPath(state->getPath()->copy()); + state2->setPath(0); state2->setPath(state->getPath()->copy()); #else GfxState*state1 = state->copy(gTrue);