#include <stdio.h>
#include <memory.h>
#include <assert.h>
-#include "config.h"
#include "BitmapOutputDev.h"
#include "GFXOutputDev.h"
-#include "SplashBitmap.h"
-#include "SplashPattern.h"
-#include "Splash.h"
+
+#ifdef HAVE_POPPLER
+ #include "splash/SplashBitmap.h"
+ #include "splash/SplashPattern.h"
+ #include "splash/Splash.h"
+#else
+ #include "xpdf/config.h"
+ #include "SplashBitmap.h"
+ #include "SplashPattern.h"
+ #include "Splash.h"
+#endif
+
#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;
void BitmapOutputDev::flushBitmap()
{
- int width = rgbdev->getBitmapWidth();
- int height = rgbdev->getBitmapHeight();
+ int bitmap_width = rgbdev->getBitmapWidth();
+ int bitmap_height = rgbdev->getBitmapHeight();
if(sizeof(SplashColor)!=3) {
msg("<error> sizeof(SplashColor)!=3");
Guchar*alpha = rgbbitmap->getAlphaPtr();
Guchar*alpha2 = stalepolybitmap->getDataPtr();
- int width8 = (stalepolybitmap->getWidth()+7)/8;
+ int bitmap_width8 = (stalepolybitmap->getWidth()+7)/8;
/*char filename[80];
sprintf(filename, "flush%d_mask.png", dbg_btm_counter);
sprintf(filename, "flush%d_bitmap.png", dbg_btm_counter);
writeBitmap(rgbbitmap, filename);*/
- ibbox_t* boxes = get_bitmap_bboxes((unsigned char*)alpha, width, height);
- ibbox_t*b;
+ ibbox_t pagebox = {-movex, -movey, -movex + this->width, -movey + this->height, 0};
+ ibbox_t bitmapbox = {0, 0, bitmap_width, bitmap_height, 0};
+ ibbox_t c = ibbox_clip(&bitmapbox, &pagebox);
+ ibbox_t* boxes = get_bitmap_bboxes((unsigned char*)(alpha+c.ymin*bitmap_width+c.xmin), c.xmax - c.xmin, c.ymax - c.ymin, bitmap_width);
+ ibbox_t*b;
for(b=boxes;b;b=b->next) {
- int xmin = b->xmin;
- int ymin = b->ymin;
- int xmax = b->xmax;
- int ymax = b->ymax;
+ int xmin = b->xmin - this->movex;
+ int ymin = b->ymin - this->movey;
+ int xmax = b->xmax - this->movex;
+ int ymax = b->ymax - this->movey;
/* 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("<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;
img->height = rangey;
int x,y;
for(y=0;y<rangey;y++) {
- SplashColorPtr in=&rgb[((y+ymin)*width+xmin)*sizeof(SplashColor)];
+ SplashColorPtr in=&rgb[((y+ymin)*bitmap_width+xmin)*sizeof(SplashColor)];
gfxcolor_t*out = &img->data[y*rangex];
- Guchar*ain = &alpha[(y+ymin)*width+xmin];
- Guchar*ain2 = &alpha2[(y+ymin)*width8];
+ Guchar*ain = &alpha[(y+ymin)*bitmap_width+xmin];
+ Guchar*ain2 = &alpha2[(y+ymin)*bitmap_width8];
if(this->emptypage) {
for(x=0;x<rangex;x++) {
/* the first bitmap on the page doesn't need to have an alpha channel-
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).
+ /* according to endPage()/compositeBackground() in xpdf/SplashOutputDev.cc, this
+ data has non-premultiplied alpha, which is exactly what the output device
+ expects, so don't premultiply it here, either.
*/
- 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].r = in[x*3+0];
+ out[x].g = in[x*3+1];
+ out[x].b = in[x*3+2];
out[x].a = ain[x];
}
}
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;
}
}
}
}
- writePNG(filename, (unsigned char*)b, width, height);
+ png_write(filename, (unsigned char*)b, width, height);
free(b);
}
line[x].a = bitmap->getAlpha(x,y);
}
}
- writePNG(filename, (unsigned char*)data, width, height);
+ png_write(filename, (unsigned char*)data, width, height);
free(data);
}
line[x].a = a;
}
}
- writePNG(filename, (unsigned char*)data, width, height);
+ png_write(filename, (unsigned char*)data, width, height);
free(data);
}
if(!fixBBox(&x1, &y1, &x2, &y2, bitmap->getWidth(), bitmap->getHeight()))
return;
- Guchar*b = bitmap->getDataPtr() + y1*width8;
- Guchar*u = update->getDataPtr() + y1*width8;
+ Guchar*b = bitmap->getDataPtr() + y1*width8 + x1/8;
+ Guchar*u = update->getDataPtr() + y1*width8 + x1/8;
+ int yspan = y2-y1;
+ int xspan = (x2+7)/8 - x1/8;
int size = (y2-y1)*width8;
if(overwrite) {
- memcpy(b, u, size);
+ int y;
+ for(y=0;y<yspan;y++) {
+ memcpy(b, u, xspan);
+ b += width8;
+ u += width8;
+ }
} else {
- int t;
- for(t=0;t<size;t++) {
- b[t] |= u[t];
+ if(((ptroff_t)b&7)==((ptroff_t)u&7)) {
+ int x,y;
+ for(y=0;y<yspan;y++) {
+ Guchar*e1 = b+xspan-8;
+ Guchar*e2 = b+xspan;
+ while(((ptroff_t)b&7) && b<e1) {
+ *b |= *u;
+ b++;u++;
+ }
+ while(b<e1) {
+ *(long long*)b |= *(long long*)u;
+ b+=8;u+=8;
+ }
+ while(b<e2) {
+ *b |= *u;
+ b++;u++;
+ }
+ b += width8-xspan;
+ u += width8-xspan;
+ }
+ } else {
+ int x,y;
+ for(y=0;y<yspan;y++) {
+ for(x=0;x<xspan;x++) {
+ b[x] |= u[x];
+ }
+ b += width8;
+ u += width8;
+ }
}
}
}
}
}
-GBool BitmapOutputDev::checkNewText(int x1, int y1, int x2, int y2)
+void BitmapOutputDev::dbg_newdata(char*newdata)
{
- /* called once some new text was drawn on booltextdev, and
- before the same thing is drawn on gfxdev */
-
- msg("<trace> Testing new text data against current bitmap data, state=%s, counter=%d\n", STATE_NAME[layerstate], dbg_btm_counter);
-
if(0) {
char filename1[80];
char filename2[80];
char filename3[80];
- sprintf(filename1, "state%dboolbitmap_afternewtext.png", dbg_btm_counter);
- sprintf(filename2, "state%dbooltext_afternewtext.png", dbg_btm_counter);
- sprintf(filename3, "state%dbitmap_afternewtext.png", dbg_btm_counter);
+ sprintf(filename1, "state%03dboolbitmap_after%s.png", dbg_btm_counter, newdata);
+ sprintf(filename2, "state%03dbooltext_after%s.png", dbg_btm_counter, newdata);
+ sprintf(filename3, "state%03dbitmap_after%s.png", dbg_btm_counter, newdata);
msg("<verbose> %s %s %s", filename1, filename2, filename3);
writeAlpha(stalepolybitmap, filename1);
writeAlpha(booltextbitmap, filename2);
writeBitmap(rgbdev->getBitmap(), filename3);
}
dbg_btm_counter++;
+}
+
+GBool 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 */
+
+ msg("<trace> Testing new text data against current bitmap data, state=%s, counter=%d\n", STATE_NAME[layerstate], dbg_btm_counter);
GBool ret = false;
if(intersection(booltextbitmap, stalepolybitmap, x1,y1,x2,y2)) {
/* similar to checkNewText() above, only in reverse */
msg("<trace> Testing new graphics data against current text data, state=%s, counter=%d\n", STATE_NAME[layerstate], dbg_btm_counter);
- if(0) {
- char filename1[80];
- char filename2[80];
- char filename3[80];
- sprintf(filename1, "state%dboolbitmap_afternewgfx.png", dbg_btm_counter);
- sprintf(filename2, "state%dbooltext_afternewgfx.png", dbg_btm_counter);
- sprintf(filename3, "state%dbitmap_afternewgfx.png", dbg_btm_counter);
- msg("<verbose> %s %s %s", filename1, filename2, filename3);
- writeAlpha(stalepolybitmap, filename1);
- writeAlpha(booltextbitmap, filename2);
- writeBitmap(rgbdev->getBitmap(), filename3);
- }
- dbg_btm_counter++;
-
GBool ret = false;
if(intersection(boolpolybitmap, staletextbitmap, x1,y1,x2,y2)) {
if(layerstate==STATE_PARALLEL) {
} 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);
if(!len)
return 0;
if(((ptroff_t)data1&7)==((ptroff_t)data2&7)) {
- // oh good, we can do aligning
+ // oh good, we can align both to 8 byte
while((ptroff_t)data1&7) {
if(*data1&*data2)
return 1;
}
}
+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, double crop_x1, double crop_y1, double crop_x2, double crop_y2)
+void BitmapOutputDev::startPage(int pageNum, GfxState *state)
{
+ PDFRectangle *r = this->page->getCropBox();
double x1,y1,x2,y2;
- state->transform(crop_x1,crop_y1,&x1,&y1);
- state->transform(crop_x2,crop_y2,&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->width = (int)(x2-x1);
this->height = (int)(y2-y1);
- msg("<debug> startPage");
- rgbdev->startPage(pageNum, state, crop_x1, crop_y1, crop_x2, crop_y2);
- boolpolydev->startPage(pageNum, state, crop_x1, crop_y1, crop_x2, crop_y2);
- booltextdev->startPage(pageNum, state, crop_x1, crop_y1, crop_x2, crop_y2);
- clip0dev->startPage(pageNum, state, crop_x1, crop_y1, crop_x2, crop_y2);
- clip1dev->startPage(pageNum, state, crop_x1, crop_y1, crop_x2, crop_y2);
- gfxdev->startPage(pageNum, state, crop_x1, crop_y1, crop_x2, crop_y2);
+ 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);
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();
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 */
clip1dev->needNonText();
return rgbdev->needNonText();
}
-/*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)
-{
- return gTrue;
-}*/
void BitmapOutputDev::setDefaultCTM(double *ctm)
{
boolpolydev->setDefaultCTM(ctm);
bbox.xmax += width; bbox.ymax += width;
checkNewBitmap(bbox.xmin, bbox.ymin, ceil(bbox.xmax), ceil(bbox.ymax));
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");
}
void BitmapOutputDev::eoFill(GfxState *state)
{
gfxbbox_t bbox = getBBox(state);
checkNewBitmap(bbox.xmin, bbox.ymin, ceil(bbox.xmax), ceil(bbox.ymax));
rgbdev->eoFill(state);
+ dbg_newdata("eofill");
}
-#if (xpdfMajorVersion*10000 + xpdfMinorVersion*100 + xpdfUpdateVersion) < 30207
-void BitmapOutputDev::tilingPatternFill(GfxState *state, Object *str,
- int paintType, Dict *resDict,
- double *mat, double *bbox,
- int x0, int y0, int x1, int y1,
- double xStep, double yStep)
-{
- msg("<debug> tilingPatternFill");
- boolpolydev->tilingPatternFill(state, str, paintType, resDict, mat, bbox, x0, y0, x1, y1, xStep, yStep);
- checkNewBitmap(UNKNOWN_BOUNDING_BOX);
- rgbdev->tilingPatternFill(state, str, paintType, resDict, mat, bbox, x0, y0, x1, y1, xStep, yStep);
-}
-#else
-void BitmapOutputDev::tilingPatternFill(GfxState *state, Gfx *gfx, Object *str,
+
+POPPLER_TILING_PATERN_RETURN BitmapOutputDev::tilingPatternFill(GfxState *state, POPPLER_TILING_PATERN_GFX Object *str,
int paintType, Dict *resDict,
double *mat, double *bbox,
int x0, int y0, int x1, int y1,
double xStep, double yStep)
{
msg("<debug> tilingPatternFill");
- boolpolydev->tilingPatternFill(state, gfx, str, paintType, resDict, mat, bbox, x0, y0, x1, y1, xStep, yStep);
+ boolpolydev->tilingPatternFill(state, POPPLER_TILING_PATERN_GFX_ARG str, paintType, resDict, mat,
+ bbox, x0, y0, x1, y1, xStep, yStep);
checkNewBitmap(UNKNOWN_BOUNDING_BOX);
- rgbdev->tilingPatternFill(state, gfx, str, paintType, resDict, mat, bbox, x0, y0, x1, y1, xStep, yStep);
-}
+ rgbdev->tilingPatternFill(state, POPPLER_TILING_PATERN_GFX_ARG str, paintType, resDict, mat,
+ bbox, x0, y0, x1, y1, xStep, yStep);
+ dbg_newdata("tilingpatternfill");
+#ifdef HAVE_POPPLER
+ return gTrue;
#endif
+}
GBool BitmapOutputDev::functionShadedFill(GfxState *state, GfxFunctionShading *shading)
{
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);
gfxdev->drawChar(state, x, y, dx, dy, originX, originY, code, nBytes, u, uLen);
}
}
+ dbg_newdata("text");
}
void BitmapOutputDev::drawString(GfxState *state, GString *s)
{
/* the only thing "drawn" here is clipping */
//checkNewText(UNKNOWN_BOUNDING_BOX);
gfxdev->endTextObject(state);
+ dbg_newdata("endtextobject");
}
void BitmapOutputDev::endString(GfxState *state)
{
checkNewText(UNKNOWN_BOUNDING_BOX);
}
gfxdev->endString(state);
+ dbg_newdata("endstring");
}
void BitmapOutputDev::endStringOp(GfxState *state)
{
clip1dev->endStringOp(state);
booltextdev->endStringOp(state);
gfxdev->endStringOp(state);
+ dbg_newdata("endstringop");
}
/* TODO: these four operations below *should* do nothing, as type3
double x,y;
state->transform(0, 1, &x, &y);
bbox.xmin=bbox.xmax = x;
- bbox.ymin=bbox.ymax = x;
+ bbox.ymin=bbox.ymax = y;
state->transform(0, 0, &x, &y);
bbox.xmin=min(bbox.xmin,x);
bbox.ymin=min(bbox.ymin,y);
- bbox.xmax=max(bbox.xmin,x);
- bbox.ymax=max(bbox.ymin,y);
+ bbox.xmax=max(bbox.xmax,x);
+ bbox.ymax=max(bbox.ymax,y);
state->transform(1, 0, &x, &y);
bbox.xmin=min(bbox.xmin,x);
bbox.ymin=min(bbox.ymin,y);
- bbox.xmax=max(bbox.xmin,x);
- bbox.ymax=max(bbox.ymin,y);
+ bbox.xmax=max(bbox.xmax,x);
+ bbox.ymax=max(bbox.ymax,y);
state->transform(1, 1, &x, &y);
bbox.xmin=min(bbox.xmin,x);
bbox.ymin=min(bbox.ymin,y);
- bbox.xmax=max(bbox.xmin,x);
- bbox.ymax=max(bbox.ymin,y);
+ bbox.xmax=max(bbox.xmax,x);
+ bbox.ymax=max(bbox.ymax,y);
return bbox;
}
+
+GBool invalid_size(int width, int height)
+{
+ if((U64)width*(U64)height > 0x7fffffffll)
+ return 1;
+ return 0;
+}
+
void BitmapOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str,
int width, int height, GBool invert,
GBool inlineImg)
{
msg("<debug> drawImageMask streamkind=%d", str->getKind());
- CopyStream*cpystr = 0;
- if(inlineImg) {
- cpystr = new CopyStream(str, height * ((width + 7) / 8));
- str = cpystr->getStream();
- }
+ if(invalid_size(width,height)) return;
+
+ CopyStream*cpystr = new CopyStream(str, height * ((width + 7) / 8));
+ str = cpystr->getStream();
+
boolpolydev->drawImageMask(state, ref, str, width, height, invert, inlineImg);
gfxbbox_t bbox = getImageBBox(state);
checkNewBitmap(bbox.xmin, bbox.ymin, ceil(bbox.xmax), ceil(bbox.ymax));
rgbdev->drawImageMask(state, ref, str, width, height, invert, inlineImg);
- if(cpystr)
- delete cpystr;
+ delete cpystr;
+ dbg_newdata("imagemask");
}
void BitmapOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
int width, int height, GfxImageColorMap *colorMap,
int *maskColors, GBool inlineImg)
{
msg("<debug> drawImage streamkind=%d", str->getKind());
- CopyStream*cpystr = 0;
- if(inlineImg) {
- cpystr = new CopyStream(str, height * ((width * colorMap->getNumPixelComps() * colorMap->getBits() + 7) / 8));
- str = cpystr->getStream();
- }
+ if(invalid_size(width,height)) return;
+
+ CopyStream*cpystr = new CopyStream(str, height * ((width * colorMap->getNumPixelComps() * colorMap->getBits() + 7) / 8));
+ str = cpystr->getStream();
+
boolpolydev->drawImage(state, ref, str, width, height, colorMap, maskColors, inlineImg);
gfxbbox_t bbox=getImageBBox(state);
checkNewBitmap(bbox.xmin, bbox.ymin, ceil(bbox.xmax), ceil(bbox.ymax));
rgbdev->drawImage(state, ref, str, width, height, colorMap, maskColors, inlineImg);
- if(cpystr)
- delete cpystr;
+ delete cpystr;
+ dbg_newdata("image");
}
void BitmapOutputDev::drawMaskedImage(GfxState *state, Object *ref, Stream *str,
int width, int height,
GBool maskInvert)
{
msg("<debug> drawMaskedImage streamkind=%d", str->getKind());
+ if(invalid_size(width,height)) return;
+
+ CopyStream*cpystr = new CopyStream(str, height * ((width * colorMap->getNumPixelComps() * colorMap->getBits() + 7) / 8));
+ str = cpystr->getStream();
+
boolpolydev->drawMaskedImage(state, ref, str, width, height, colorMap, maskStr, maskWidth, maskHeight, maskInvert);
gfxbbox_t bbox=getImageBBox(state);
checkNewBitmap(bbox.xmin, bbox.ymin, ceil(bbox.xmax), ceil(bbox.ymax));
rgbdev->drawMaskedImage(state, ref, str, width, height, colorMap, maskStr, maskWidth, maskHeight, maskInvert);
+ delete cpystr;
+ dbg_newdata("maskedimage");
}
void BitmapOutputDev::drawSoftMaskedImage(GfxState *state, Object *ref, Stream *str,
int width, int height,
GfxImageColorMap *maskColorMap)
{
msg("<debug> drawSoftMaskedImage %dx%d (%dx%d) streamkind=%d", width, height, maskWidth, maskHeight, str->getKind());
+ if(invalid_size(width,height)) return;
+
+ CopyStream*cpystr = new CopyStream(str, height * ((width * colorMap->getNumPixelComps() * colorMap->getBits() + 7) / 8));
+ str = cpystr->getStream();
+
boolpolydev->drawSoftMaskedImage(state, ref, str, width, height, colorMap, maskStr, maskWidth, maskHeight, maskColorMap);
gfxbbox_t bbox=getImageBBox(state);
checkNewBitmap(bbox.xmin, bbox.ymin, ceil(bbox.xmax), ceil(bbox.ymax));
rgbdev->drawSoftMaskedImage(state, ref, str, width, height, colorMap, maskStr, maskWidth, maskHeight, maskColorMap);
+ delete cpystr;
+ dbg_newdata("softmaskimage");
}
void BitmapOutputDev::drawForm(Ref id)
{
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,
clip1dev->beginTransparencyGroup(state, bbox, blendingColorSpace, isolated, knockout, forSoftMask);
delete state1;
delete state2;
+ dbg_newdata("endtransparencygroup");
}
void BitmapOutputDev::endTransparencyGroup(GfxState *state)
{
delete state1;
delete state2;
clip1dev->endTransparencyGroup(state);
+ dbg_newdata("endtransparencygroup");
}
void BitmapOutputDev::paintTransparencyGroup(GfxState *state, double *bbox)
{
checkNewBitmap(UNKNOWN_BOUNDING_BOX);
rgbdev->paintTransparencyGroup(state,bbox);
clip1dev->paintTransparencyGroup(state,bbox);
+ dbg_newdata("painttransparencygroup");
}
void BitmapOutputDev::setSoftMask(GfxState *state, double *bbox, GBool alpha, Function *transferFunc, GfxColor *backdropColor)
{
checkNewBitmap(UNKNOWN_BOUNDING_BOX);
rgbdev->setSoftMask(state, bbox, alpha, transferFunc, backdropColor);
clip1dev->setSoftMask(state, bbox, alpha, transferFunc, backdropColor);
+ dbg_newdata("setsoftmask");
}
void BitmapOutputDev::clearSoftMask(GfxState *state)
{
checkNewBitmap(UNKNOWN_BOUNDING_BOX);
rgbdev->clearSoftMask(state);
clip1dev->clearSoftMask(state);
+ dbg_newdata("clearsoftmask");
}