#include "../log.h"
#include "../png.h"
#include "../devices/record.h"
+#include "../gfxtools.h"
#include "../types.h"
#include "bbox.h"
this->gfxdev->setDevice(this->gfxoutput);
this->config_extrafontdata = 0;
+ this->config_optimizeplaincolorfills = 0;
this->bboxpath = 0;
//this->clipdev = 0;
//this->clipstates = 0;
int ymax = b->ymax;
/* 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 + this->width) xmax = -this->movex+this->width;
- if(ymax > -this->movey + this->height) ymax = -this->movey+this->height;
- msg("<verbose> Flushing bitmap (bbox: %d,%d,%d,%d)", xmin,ymin,xmax,ymax);
+ msg("<verbose> Flushing bitmap (bbox: %d,%d,%d,%d %dx%d) (clipped against %d,%d,%d,%d)", xmin,ymin,xmax,ymax, xmax-xmin, ymax-ymin,
+ -this->movex, -this->movey, -this->movex+this->width, -this->movey+this->height);
+
+ if(xmin < -this->movex) {
+ xmin = -this->movex;
+ if(xmax < -this->movex) continue;
+ }
+ if(ymin < -this->movey) {
+ ymin = -this->movey;
+ if(ymax < -this->movey) continue;
+ }
+ if(xmax >= -this->movex + this->width) {
+ xmax = -this->movex+this->width;
+ if(xmin >= -this->movex + this->width) continue;
+ }
+ if(ymax >= -this->movey + this->height) {
+ ymax = -this->movey+this->height;
+ if(ymin >= -this->movey + this->height) continue;
+ }
if((xmax-xmin)<=0 || (ymax-ymin)<=0) // no bitmap, nothing to do
continue;
void BitmapOutputDev::flushText()
{
msg("<verbose> Flushing text");
- gfxdevice_record_flush(this->gfxoutput, this->dev);
+
+ static gfxfontlist_t*output_font_list = 0;
+ static gfxdevice_t*last = 0;
+ if(last != this->dev) {
+ if(output_font_list)
+ gfxfontlist_free(output_font_list, 0);
+ output_font_list = gfxfontlist_create();
+ }
+ gfxdevice_record_flush(this->gfxoutput, this->dev, &output_font_list);
+ last = this->dev;
this->emptypage = 0;
}
msg("<verbose> finishPage (BitmapOutputDev)");
gfxdev->endPage();
- if(layerstate == STATE_BITMAP_IS_ABOVE) {
- this->flushText();
- this->flushBitmap();
- } else {
- this->flushBitmap();
- this->flushText();
- }
+ flushEverything();
/* splash will now destroy alpha, and paint the
background color into the "holes" in the bitmap */
rgbdev->stroke(state);
dbg_newdata("stroke");
}
+
+extern gfxcolor_t getFillColor(GfxState * state);
+
+char area_is_plain_colored(GfxState*state, SplashBitmap*boolpoly, SplashBitmap*rgbbitmap, int x1, int y1, int x2, int y2)
+{
+ int width = boolpoly->getWidth();
+ int height = boolpoly->getHeight();
+ if(!fixBBox(&x1, &y1, &x2, &y2, width, height)) {
+ return 0;
+ }
+ gfxcolor_t color = getFillColor(state);
+ SplashColorPtr rgb = rgbbitmap->getDataPtr()
+ + (y1*width+x1)*sizeof(SplashColor);
+ int width8 = (width+7)/8;
+ unsigned char*bits = (unsigned char*)boolpoly->getDataPtr()
+ + (y1*width8+x1);
+ int x,y;
+ int w = x2-x1;
+ int h = y2-y1;
+ for(y=0;y<h;y++) {
+ for(x=0;x<w;x++) {
+ if(rgb[x*3+0] != color.r ||
+ rgb[x*3+1] != color.g ||
+ rgb[x*3+2] != color.b)
+ return 0;
+ }
+ rgb += width*sizeof(SplashColor);
+ }
+ return 1;
+}
+
void BitmapOutputDev::fill(GfxState *state)
{
msg("<debug> fill");
boolpolydev->fill(state);
gfxbbox_t bbox = getBBox(state);
+ if(config_optimizeplaincolorfills) {
+ if(area_is_plain_colored(state, boolpolybitmap, rgbbitmap, bbox.xmin, bbox.ymin, bbox.xmax, bbox.ymax)) {
+ return;
+ }
+ }
checkNewBitmap(bbox.xmin, bbox.ymin, ceil(bbox.xmax), ceil(bbox.ymax));
rgbdev->fill(state);
dbg_newdata("fill");
boolpolydev->drawChar(state, x, y, dx, dy, originX, originY, code, nBytes, u, uLen);
booltextdev->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);
+ } else if(state->getRender()&RENDER_STROKE) {
+ // we're drawing as stroke
+ boolpolydev->drawChar(state, x, y, dx, dy, originX, originY, code, nBytes, u, uLen);
+ rgbdev->drawChar(state, x, y, dx, dy, originX, originY, code, nBytes, u, uLen);
} else if(rgbbitmap != rgbdev->getBitmap()) {
// we're doing softmasking or transparency grouping
boolpolydev->drawChar(state, x, y, dx, dy, originX, originY, code, nBytes, u, uLen);
void BitmapOutputDev::processLink(Link *link, Catalog *catalog)
{
msg("<debug> processLink");
+ flushEverything();
gfxdev->processLink(link, catalog);
}
+void BitmapOutputDev::flushEverything()
+{
+ if(layerstate == STATE_BITMAP_IS_ABOVE) {
+ this->flushText();
+ this->flushBitmap();
+ } else {
+ this->flushBitmap();
+ this->flushText();
+ }
+}
void BitmapOutputDev::beginTransparencyGroup(GfxState *state, double *bbox,
GfxColorSpace *blendingColorSpace,