X-Git-Url: http://git.asbjorn.biz/?p=swftools.git;a=blobdiff_plain;f=lib%2Fpdf%2FBitmapOutputDev.cc;h=6eaea6bcb461ff4c9b68c82464c85a37a25f7113;hp=4f88282814f7aea8dda008e7af373b9b8f14ec43;hb=b43d07ef45012438211d2ed4b588e77b73a1994c;hpb=79722aa76968646601b00a472f5c715ae4287f29 diff --git a/lib/pdf/BitmapOutputDev.cc b/lib/pdf/BitmapOutputDev.cc index 4f88282..6eaea6b 100644 --- a/lib/pdf/BitmapOutputDev.cc +++ b/lib/pdf/BitmapOutputDev.cc @@ -30,6 +30,7 @@ #include "../png.h" #include "../devices/record.h" #include "../types.h" +#include "bbox.h" #define UNKNOWN_BOUNDING_BOX 0,0,0,0 @@ -158,131 +159,116 @@ void BitmapOutputDev::setPageMap(int*page2page, int num_pages) this->gfxdev->setPageMap(page2page, num_pages); } -static void getBitmapBBox(Guchar*alpha, int width, int height, int*xmin, int*ymin, int*xmax, int*ymax) -{ - *ymin = -1; - *xmin = width; - *xmax = 0; - int x,y; - for(y=0;y*xmax) *xmax = right; - } - } - if(*xmin>=*xmax || *ymin>=*ymax) { - *xmin = 0; - *ymin = 0; - *xmax = 0; - *ymax = 0; - } -} +void writeBitmap(SplashBitmap*bitmap, char*filename); void BitmapOutputDev::flushBitmap() { int width = rgbdev->getBitmapWidth(); int height = rgbdev->getBitmapHeight(); + + if(sizeof(SplashColor)!=3) { + msg(" sizeof(SplashColor)!=3"); + return; + } + + /*static int counter=0; + if(!counter) { + writeBitmap(rgbdev->getBitmap(), "test.png"); + } counter++;*/ SplashColorPtr rgb = rgbbitmap->getDataPtr(); Guchar*alpha = rgbbitmap->getAlphaPtr(); - Guchar*alpha2 = boolpolybitmap->getAlphaPtr(); + + Guchar*alpha2 = boolpolybitmap->getDataPtr(); + int width8 = (boolpolybitmap->getWidth()+7)/8; - int xmin,ymin,xmax,ymax; - getBitmapBBox(alpha, width, height, &xmin,&ymin,&xmax,&ymax); + ibbox_t* boxes = get_bitmap_bboxes((unsigned char*)alpha, width, height); + ibbox_t*b; - /* clip against (-movex, -movey, -movex+width, -movey+height) */ - if(xmin < -this->movex) xmin = -this->movex; - if(ymin < -this->movey) ymin = -this->movey; - if(xmax > -this->movex + width) xmax = -this->movex+this->width; - if(ymax > -this->movey + height) ymax = -this->movey+this->height; - msg(" Flushing bitmap (bbox: %d,%d,%d,%d)", xmin,ymin,xmax,ymax); - - if((xmax-xmin)<=0 || (ymax-ymin)<=0) // no bitmap, nothing to do - return; + for(b=boxes;b;b=b->next) { + int xmin = b->xmin; + int ymin = b->ymin; + int xmax = b->xmax; + int ymax = b->ymax; - if(sizeof(SplashColor)!=3) { - msg(" sizeof(SplashColor)!=3"); - return; - } - //xmin = ymin = 0; - //xmax = width; - //ymax = height; - - int rangex = xmax-xmin; - int rangey = ymax-ymin; - gfximage_t*img = (gfximage_t*)malloc(sizeof(gfximage_t)); - img->data = (gfxcolor_t*)malloc(rangex * rangey * 4); - img->width = rangex; - img->height = rangey; - int x,y; - for(y=0;ydata[y*rangex]; - Guchar*ain = &alpha[(y+ymin)*width+xmin]; - Guchar*ain2 = &alpha2[(y+ymin)*width+xmin]; - if(this->emptypage) { - for(x=0;xmovex) xmin = -this->movex; + if(ymin < -this->movey) ymin = -this->movey; + if(xmax > -this->movex + width) xmax = -this->movex+this->width; + if(ymax > -this->movey + height) ymax = -this->movey+this->height; + + msg(" Flushing bitmap (bbox: %d,%d,%d,%d)", xmin,ymin,xmax,ymax); + + if((xmax-xmin)<=0 || (ymax-ymin)<=0) // no bitmap, nothing to do + continue; + + int rangex = xmax-xmin; + int rangey = ymax-ymin; + gfximage_t*img = (gfximage_t*)malloc(sizeof(gfximage_t)); + img->data = (gfxcolor_t*)malloc(rangex * rangey * 4); + img->width = rangex; + img->height = rangey; + int x,y; + for(y=0;ydata[y*rangex]; + Guchar*ain = &alpha[(y+ymin)*width+xmin]; + Guchar*ain2 = &alpha2[(y+ymin)*width8]; + if(this->emptypage) { + for(x=0;x>(x&7)))) { + /* cut away pixels that we don't remember drawing (i.e., that are + not in the monochrome bitmap. Prevents some "hairlines" showing + up to the left and right of bitmaps */ + out[x].r = 0;out[x].g = 0;out[x].b = 0;out[x].a = 0; + } else { + /* according to endPage()/compositeBackground() in xpdf/SplashOutputDev.cc, we + have to premultiply alpha (mix background and pixel according to the alpha channel). + */ + out[x].r = (in[x*3+0]*ain[x])/255; + out[x].g = (in[x*3+1]*ain[x])/255; + out[x].b = (in[x*3+2]*ain[x])/255; + out[x].a = ain[x]; + } + } } } + + /* transform bitmap rectangle to "device space" */ + xmin += movex; + ymin += movey; + xmax += movex; + ymax += movey; + + gfxmatrix_t m; + m.tx = xmin; + m.ty = ymin; + m.m00 = m.m11 = 1; + m.m10 = m.m01 = 0; + m.tx -= 0.5; + m.ty -= 0.5; + + gfxline_t* line = gfxline_makerectangle(xmin, ymin, xmax, ymax); + dev->fillbitmap(dev, line, img, &m, 0); + gfxline_free(line); + + free(img->data);img->data=0;free(img);img=0; } - /* transform bitmap rectangle to "device space" */ - xmin += movex; - ymin += movey; - xmax += movex; - ymax += movey; - - gfxmatrix_t m; - m.tx = xmin; - m.ty = ymin; - m.m00 = m.m11 = 1; - m.m10 = m.m01 = 0; - m.tx -= 0.5; - m.ty -= 0.5; - - gfxline_t* line = gfxline_makerectangle(xmin, ymin, xmax, ymax); - dev->fillbitmap(dev, line, img, &m, 0); - gfxline_free(line); + ibbox_destroy(boxes); memset(rgbbitmap->getAlphaPtr(), 0, rgbbitmap->getWidth()*rgbbitmap->getHeight()); memset(rgbbitmap->getDataPtr(), 0, rgbbitmap->getRowSize()*rgbbitmap->getHeight()); - free(img->data);img->data=0;free(img);img=0; - this->emptypage = 0; }