#include <stdlib.h>
#include <stdio.h>
#include <memory.h>
+#include <assert.h>
#include "config.h"
#include "BitmapOutputDev.h"
#include "GFXOutputDev.h"
this->gfxdev->setDevice(this->gfxoutput);
- this->config_bitmapfonts = 0;
this->config_extrafontdata = 0;
this->bboxpath = 0;
//this->clipdev = 0;
if(this->rgbdev) {
delete this->rgbdev;this->rgbdev = 0;
}
+ if(this->gfxdev) {
+ delete this->gfxdev;this->gfxdev= 0;
+ }
if(this->boolpolydev) {
delete this->boolpolydev;this->boolpolydev = 0;
}
+ if(this->booltextdev) {
+ delete this->booltextdev;this->booltextdev = 0;
+ }
if(this->clip0dev) {
delete this->clip0dev;this->clip0dev = 0;
}
{
if(!strcmp(key, "extrafontdata")) {
this->config_extrafontdata = atoi(value);
- } else if(!strcmp(key, "bitmapfonts")) {
- this->config_bitmapfonts = atoi(value);
}
this->gfxdev->setParameter(key, value);
}
{
}
-void getBitmapBBox(Guchar*alpha, int width, int height, int*xmin, int*ymin, int*xmax, int*ymax)
+static void getBitmapBBox(Guchar*alpha, int width, int height, int*xmin, int*ymin, int*xmax, int*ymax)
{
*ymin = -1;
*xmin = width;
int width = rgbdev->getBitmapWidth();
int height = rgbdev->getBitmapHeight();
- SplashColorPtr rgb = rgbdev->getBitmap()->getDataPtr();
- Guchar*alpha = rgbdev->getBitmap()->getAlphaPtr();
+ SplashColorPtr rgb = rgbbitmap->getDataPtr();
+ Guchar*alpha = rgbbitmap->getAlphaPtr();
int xmin,ymin,xmax,ymax;
getBitmapBBox(alpha, width, height, &xmin,&ymin,&xmax,&ymax);
SplashColorPtr in=&rgb[((y+ymin)*width+xmin)*sizeof(SplashColor)];
gfxcolor_t*out = &img->data[y*rangex];
Guchar*ain = &alpha[(y+ymin)*width+xmin];
- for(x=0;x<rangex;x++) {
- /* 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];
+ if(this->emptypage) {
+ for(x=0;x<rangex;x++) {
+ /* the first bitmap on the page doesn't need to have an alpha channel-
+ blend against a white background*/
+ out[x].r = (in[x*3+0]*ain[x])/255 + 255-ain[x];
+ out[x].g = (in[x*3+1]*ain[x])/255 + 255-ain[x];
+ out[x].b = (in[x*3+2]*ain[x])/255 + 255-ain[x];
+ out[x].a = 255;
+ }
+ } else {
+ for(x=0;x<rangex;x++) {
+ /* 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" */
dev->fillbitmap(dev, line, img, &m, 0);
gfxline_free(line);
- memset(rgbdev->getBitmap()->getAlphaPtr(), 0, rgbdev->getBitmap()->getWidth()*rgbdev->getBitmap()->getHeight());
- memset(rgbdev->getBitmap()->getDataPtr(), 0, rgbdev->getBitmap()->getRowSize()*rgbdev->getBitmap()->getHeight());
+ 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;
}
void BitmapOutputDev::flushText()
{
msg("<verbose> Flushing text/polygons");
gfxdevice_record_flush(this->gfxoutput, this->dev);
+
+ this->emptypage = 0;
}
void writeAlpha(SplashBitmap*bitmap, char*filename)
{
- return;
int y,x;
int width = bitmap->getWidth();
}
static int dbg_btm_counter=1;
+static const char*STATE_NAME[] = {"parallel", "textabovebitmap", "bitmapabovetext"};
+
void BitmapOutputDev::checkNewText()
{
/* called once some new text was drawn on booltextdev, and
before the same thing is drawn on gfxdev */
-
- msg("<debug> Testing new text data against current bitmap data, state=%d, counter=%d\n", layerstate, dbg_btm_counter);
+
+ msg("<trace> Testing new text data against current bitmap data, state=%s, counter=%d\n", STATE_NAME[layerstate], dbg_btm_counter);
char filename1[80];
char filename2[80];
- sprintf(filename1, "state%dbitmap_newtext.png", dbg_btm_counter);
- sprintf(filename2, "state%dtext_newtext.png", dbg_btm_counter);
- writeAlpha(boolpolydev->getBitmap(), filename1);
- writeAlpha(booltextdev->getBitmap(), filename2);
+ sprintf(filename1, "state%dbitmap_afternewtext.png", dbg_btm_counter);
+ sprintf(filename2, "state%dtext_afternewtext.png", dbg_btm_counter);
+ if(0) {
+ writeAlpha(boolpolybitmap, filename1);
+ writeAlpha(booltextbitmap, filename2);
+ }
dbg_btm_counter++;
if(intersection()) {
- msg("<verbose> Text is above current bitmap/polygon data");
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
new intersections */
+ msg("<verbose> Text is above current bitmap/polygon data");
layerstate=STATE_TEXT_IS_ABOVE;
clearBoolPolyDev();
} else if(layerstate==STATE_BITMAP_IS_ABOVE) {
to flush out that text, and record that the *new*
text is now *above* the bitmap
*/
+ msg("<verbose> Text is above current bitmap/polygon data (which is above some other text)");
flushText();
layerstate=STATE_TEXT_IS_ABOVE;
/* clear both bool devices- the text device because
*again* it's above the current bitmap- so clear
the polygon bitmap again, so we can check for
new intersections */
+ msg("<verbose> Text is still above current bitmap/polygon data");
clearBoolPolyDev();
}
}
void BitmapOutputDev::checkNewBitmap()
{
/* similar to checkNewText() above, only in reverse */
- msg("<debug> Testing new graphics data against current text data, state=%d, counter=%d\n", layerstate, dbg_btm_counter);
+ msg("<trace> Testing new graphics data against current text data, state=%s, counter=%d\n", STATE_NAME[layerstate], dbg_btm_counter);
char filename1[80];
char filename2[80];
- sprintf(filename1, "state%dbitmap_newbitmap.png", dbg_btm_counter);
- sprintf(filename2, "state%dtext_newbitmap.png", dbg_btm_counter);
- writeAlpha(boolpolydev->getBitmap(), filename1);
- writeAlpha(booltextdev->getBitmap(), filename2);
+ sprintf(filename1, "state%dbitmap_afternewgfx.png", dbg_btm_counter);
+ sprintf(filename2, "state%dtext_afternewgfx.png", dbg_btm_counter);
+ if(0) {
+ writeAlpha(boolpolybitmap, filename1);
+ writeAlpha(booltextbitmap, filename2);
+ }
dbg_btm_counter++;
if(intersection()) {
- msg("<verbose> Bitmap is above current text data");
if(layerstate==STATE_PARALLEL) {
+ msg("<verbose> Bitmap is above current text data");
layerstate=STATE_BITMAP_IS_ABOVE;
clearBoolTextDev();
} else if(layerstate==STATE_TEXT_IS_ABOVE) {
+ msg("<verbose> Bitmap is above current text data (which is above some bitmap)");
flushBitmap();
layerstate=STATE_BITMAP_IS_ABOVE;
clearBoolTextDev();
clearBoolPolyDev();
} else {
+ msg("<verbose> Bitmap is still above current text data");
clearBoolTextDev();
}
}
}
//void checkNewText() {
-// Guchar*alpha = rgbdev->getBitmap()->getAlphaPtr();
-// Guchar*charpixels = clip1dev->getBitmap()->getDataPtr();
+// Guchar*alpha = rgbbitmap->getAlphaPtr();
+// Guchar*charpixels = clip1bitmap->getDataPtr();
// int xx,yy;
// for(yy=0;yy<height;yy++) {
// Guchar*aline = &alpha[yy*width];
GBool BitmapOutputDev::clip0and1differ()
{
- if(clip0dev->getBitmap()->getMode()==splashModeMono1) {
- SplashBitmap*clip0 = clip0dev->getBitmap();
- SplashBitmap*clip1 = clip1dev->getBitmap();
+ if(clip0bitmap->getMode()==splashModeMono1) {
+ SplashBitmap*clip0 = clip0bitmap;
+ SplashBitmap*clip1 = clip1bitmap;
int width8 = (clip0->getWidth()+7)/8;
int height = clip0->getHeight();
return memcmp(clip0->getDataPtr(), clip1->getDataPtr(), width8*height);
} else {
- SplashBitmap*clip0 = clip0dev->getBitmap();
- SplashBitmap*clip1 = clip1dev->getBitmap();
+ SplashBitmap*clip0 = clip0bitmap;
+ SplashBitmap*clip1 = clip1bitmap;
int width = clip0->getAlphaRowSize();
int height = clip0->getHeight();
return memcmp(clip0->getAlphaPtr(), clip1->getAlphaPtr(), width*height);
}
}
-static void clearBooleanDev(SplashOutputDev*dev)
+static void clearBooleanBitmap(SplashBitmap*btm)
{
- SplashBitmap*btm = dev->getBitmap();
if(btm->getMode()==splashModeMono1) {
int width8 = (btm->getWidth()+7)/8;
int width = btm->getWidth();
GBool BitmapOutputDev::intersection()
{
- SplashBitmap*boolpoly = boolpolydev->getBitmap();
- SplashBitmap*booltext = booltextdev->getBitmap();
+ SplashBitmap*boolpoly = boolpolybitmap;
+ SplashBitmap*booltext = booltextbitmap;
if(boolpoly->getMode()==splashModeMono1) {
/* alternative implementation, using one bit per pixel-
this->width = (int)(x2-x1);
this->height = (int)(y2-y1);
- msg("<verbose> startPage");
+ 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);
clip1dev->startPage(pageNum, state, crop_x1, crop_y1, crop_x2, crop_y2);
gfxdev->startPage(pageNum, state, crop_x1, crop_y1, crop_x2, crop_y2);
+ boolpolybitmap = boolpolydev->getBitmap();
+ booltextbitmap = booltextdev->getBitmap();
+ 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
clearBoolPolyDev();
this->layerstate = STATE_PARALLEL;
+ this->emptypage = 1;
+ msg("<debug> startPage done");
}
void BitmapOutputDev::endPage()
{
msg("<verbose> 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("<verbose> finishPage (BitmapOutputDev)");
+ gfxdev->endPage();
if(layerstate == STATE_BITMAP_IS_ABOVE) {
this->flushText();
rgbdev->endPage();
clip0dev->endPage();
clip1dev->endPage();
- gfxdev->endPage();
}
GBool BitmapOutputDev::upsideDown()
GBool BitmapOutputDev::interpretType3Chars()
{
- if(!config_bitmapfonts) {
- boolpolydev->interpretType3Chars();
- booltextdev->interpretType3Chars();
- clip0dev->interpretType3Chars();
- clip1dev->interpretType3Chars();
- return rgbdev->interpretType3Chars();
- } else {
- return gfxdev->interpretType3Chars();
- }
+ boolpolydev->interpretType3Chars();
+ booltextdev->interpretType3Chars();
+ clip0dev->interpretType3Chars();
+ clip1dev->interpretType3Chars();
+ return rgbdev->interpretType3Chars();
}
GBool BitmapOutputDev::needNonText()
rgbdev->setDefaultCTM(ctm);
clip0dev->setDefaultCTM(ctm);
clip1dev->setDefaultCTM(ctm);
- //gfxdev->setDefaultCTM(ctm);//?
+ gfxdev->setDefaultCTM(ctm);
}
void BitmapOutputDev::saveState(GfxState *state)
{
rgbdev->updateAll(state);
clip0dev->updateAll(state);
clip1dev->updateAll(state);
- if(!config_bitmapfonts)
- gfxdev->updateAll(state);
+ gfxdev->updateAll(state);
}
void BitmapOutputDev::updateCTM(GfxState *state, double m11, double m12, double m21, double m22, double m31, double m32)
{
rgbdev->updateCTM(state,m11,m12,m21,m22,m31,m32);
clip0dev->updateCTM(state,m11,m12,m21,m22,m31,m32);
clip1dev->updateCTM(state,m11,m12,m21,m22,m31,m32);
- if(!config_bitmapfonts)
- gfxdev->updateCTM(state,m11,m12,m21,m22,m31,m32);
+ gfxdev->updateCTM(state,m11,m12,m21,m22,m31,m32);
}
void BitmapOutputDev::updateLineDash(GfxState *state)
{
rgbdev->updateLineDash(state);
clip0dev->updateLineDash(state);
clip1dev->updateLineDash(state);
- if(!config_bitmapfonts)
- gfxdev->updateLineDash(state);
+ gfxdev->updateLineDash(state);
}
void BitmapOutputDev::updateFlatness(GfxState *state)
{
rgbdev->updateFlatness(state);
clip0dev->updateFlatness(state);
clip1dev->updateFlatness(state);
- if(!config_bitmapfonts)
- gfxdev->updateFlatness(state);
+ gfxdev->updateFlatness(state);
}
void BitmapOutputDev::updateLineJoin(GfxState *state)
{
rgbdev->updateLineJoin(state);
clip0dev->updateLineJoin(state);
clip1dev->updateLineJoin(state);
- if(!config_bitmapfonts)
- gfxdev->updateLineJoin(state);
+ gfxdev->updateLineJoin(state);
}
void BitmapOutputDev::updateLineCap(GfxState *state)
{
rgbdev->updateLineCap(state);
clip0dev->updateLineCap(state);
clip1dev->updateLineCap(state);
- if(!config_bitmapfonts)
- gfxdev->updateLineCap(state);
+ gfxdev->updateLineCap(state);
}
void BitmapOutputDev::updateMiterLimit(GfxState *state)
{
rgbdev->updateMiterLimit(state);
clip0dev->updateMiterLimit(state);
clip1dev->updateMiterLimit(state);
- if(!config_bitmapfonts)
- gfxdev->updateMiterLimit(state);
+ gfxdev->updateMiterLimit(state);
}
void BitmapOutputDev::updateLineWidth(GfxState *state)
{
rgbdev->updateLineWidth(state);
clip0dev->updateLineWidth(state);
clip1dev->updateLineWidth(state);
- if(!config_bitmapfonts)
- gfxdev->updateLineWidth(state);
+ gfxdev->updateLineWidth(state);
}
void BitmapOutputDev::updateStrokeAdjust(GfxState *state)
{
rgbdev->updateStrokeAdjust(state);
clip0dev->updateStrokeAdjust(state);
clip1dev->updateStrokeAdjust(state);
- if(!config_bitmapfonts)
- gfxdev->updateStrokeAdjust(state);
+ gfxdev->updateStrokeAdjust(state);
}
void BitmapOutputDev::updateFillColorSpace(GfxState *state)
{
rgbdev->updateFillColorSpace(state);
clip0dev->updateFillColorSpace(state);
clip1dev->updateFillColorSpace(state);
- if(!config_bitmapfonts)
- gfxdev->updateFillColorSpace(state);
+ gfxdev->updateFillColorSpace(state);
}
void BitmapOutputDev::updateStrokeColorSpace(GfxState *state)
{
rgbdev->updateStrokeColorSpace(state);
clip0dev->updateStrokeColorSpace(state);
clip1dev->updateStrokeColorSpace(state);
- if(!config_bitmapfonts)
- gfxdev->updateStrokeColorSpace(state);
+ gfxdev->updateStrokeColorSpace(state);
}
void BitmapOutputDev::updateFillColor(GfxState *state)
{
rgbdev->updateFillColor(state);
clip0dev->updateFillColor(state);
clip1dev->updateFillColor(state);
- if(!config_bitmapfonts)
- gfxdev->updateFillColor(state);
+ gfxdev->updateFillColor(state);
}
void BitmapOutputDev::updateStrokeColor(GfxState *state)
{
rgbdev->updateStrokeColor(state);
clip0dev->updateStrokeColor(state);
clip1dev->updateStrokeColor(state);
- if(!config_bitmapfonts)
- gfxdev->updateStrokeColor(state);
+ gfxdev->updateStrokeColor(state);
}
void BitmapOutputDev::updateBlendMode(GfxState *state)
{
rgbdev->updateBlendMode(state);
clip0dev->updateBlendMode(state);
clip1dev->updateBlendMode(state);
- if(!config_bitmapfonts)
- gfxdev->updateBlendMode(state);
+ gfxdev->updateBlendMode(state);
}
void BitmapOutputDev::updateFillOpacity(GfxState *state)
{
rgbdev->updateFillOpacity(state);
clip0dev->updateFillOpacity(state);
clip1dev->updateFillOpacity(state);
- if(!config_bitmapfonts)
- gfxdev->updateFillOpacity(state);
+ gfxdev->updateFillOpacity(state);
}
void BitmapOutputDev::updateStrokeOpacity(GfxState *state)
{
rgbdev->updateStrokeOpacity(state);
clip0dev->updateStrokeOpacity(state);
clip1dev->updateStrokeOpacity(state);
- if(!config_bitmapfonts)
- gfxdev->updateStrokeOpacity(state);
+ gfxdev->updateStrokeOpacity(state);
}
void BitmapOutputDev::updateFillOverprint(GfxState *state)
{
rgbdev->updateFillOverprint(state);
clip0dev->updateFillOverprint(state);
clip1dev->updateFillOverprint(state);
- if(!config_bitmapfonts)
- gfxdev->updateFillOverprint(state);
+ gfxdev->updateFillOverprint(state);
}
void BitmapOutputDev::updateStrokeOverprint(GfxState *state)
{
rgbdev->updateStrokeOverprint(state);
clip0dev->updateStrokeOverprint(state);
clip1dev->updateStrokeOverprint(state);
- if(!config_bitmapfonts)
- gfxdev->updateStrokeOverprint(state);
+ gfxdev->updateStrokeOverprint(state);
}
void BitmapOutputDev::updateTransfer(GfxState *state)
{
rgbdev->updateTransfer(state);
clip0dev->updateTransfer(state);
clip1dev->updateTransfer(state);
- if(!config_bitmapfonts)
- gfxdev->updateTransfer(state);
+ gfxdev->updateTransfer(state);
}
void BitmapOutputDev::updateFont(GfxState *state)
{
rgbdev->updateFont(state);
clip0dev->updateFont(state);
clip1dev->updateFont(state);
- if(!config_bitmapfonts)
- gfxdev->updateFont(state);
+ gfxdev->updateFont(state);
}
void BitmapOutputDev::updateTextMat(GfxState *state)
{
rgbdev->updateTextMat(state);
clip0dev->updateTextMat(state);
clip1dev->updateTextMat(state);
- if(!config_bitmapfonts)
- gfxdev->updateTextMat(state);
+ gfxdev->updateTextMat(state);
}
void BitmapOutputDev::updateCharSpace(GfxState *state)
{
rgbdev->updateCharSpace(state);
clip0dev->updateCharSpace(state);
clip1dev->updateCharSpace(state);
- if(!config_bitmapfonts)
- gfxdev->updateCharSpace(state);
+ gfxdev->updateCharSpace(state);
}
void BitmapOutputDev::updateRender(GfxState *state)
{
rgbdev->updateRender(state);
clip0dev->updateRender(state);
clip1dev->updateRender(state);
- if(!config_bitmapfonts)
- gfxdev->updateRender(state);
+ gfxdev->updateRender(state);
}
void BitmapOutputDev::updateRise(GfxState *state)
{
rgbdev->updateRise(state);
clip0dev->updateRise(state);
clip1dev->updateRise(state);
- if(!config_bitmapfonts)
- gfxdev->updateRise(state);
+ gfxdev->updateRise(state);
}
void BitmapOutputDev::updateWordSpace(GfxState *state)
{
rgbdev->updateWordSpace(state);
clip0dev->updateWordSpace(state);
clip1dev->updateWordSpace(state);
- if(!config_bitmapfonts)
- gfxdev->updateWordSpace(state);
+ gfxdev->updateWordSpace(state);
}
void BitmapOutputDev::updateHorizScaling(GfxState *state)
{
rgbdev->updateHorizScaling(state);
clip0dev->updateHorizScaling(state);
clip1dev->updateHorizScaling(state);
- if(!config_bitmapfonts)
- gfxdev->updateHorizScaling(state);
+ gfxdev->updateHorizScaling(state);
}
void BitmapOutputDev::updateTextPos(GfxState *state)
{
rgbdev->updateTextPos(state);
clip0dev->updateTextPos(state);
clip1dev->updateTextPos(state);
- if(!config_bitmapfonts)
- gfxdev->updateTextPos(state);
+ gfxdev->updateTextPos(state);
}
void BitmapOutputDev::updateTextShift(GfxState *state, double shift)
{
rgbdev->updateTextShift(state, shift);
clip0dev->updateTextShift(state, shift);
clip1dev->updateTextShift(state, shift);
- if(!config_bitmapfonts)
- gfxdev->updateTextShift(state, shift);
+ gfxdev->updateTextShift(state, shift);
}
void BitmapOutputDev::stroke(GfxState *state)
{
- msg("<verbose> stroke");
+ msg("<debug> stroke");
boolpolydev->stroke(state);
checkNewBitmap();
rgbdev->stroke(state);
}
void BitmapOutputDev::fill(GfxState *state)
{
- msg("<verbose> fill");
+ msg("<debug> fill");
boolpolydev->fill(state);
checkNewBitmap();
rgbdev->fill(state);
}
void BitmapOutputDev::eoFill(GfxState *state)
{
- msg("<verbose> eoFill");
+ msg("<debug> eoFill");
boolpolydev->eoFill(state);
checkNewBitmap();
rgbdev->eoFill(state);
int x0, int y0, int x1, int y1,
double xStep, double yStep)
{
- msg("<verbose> tilingPatternFill");
+ msg("<debug> tilingPatternFill");
boolpolydev->tilingPatternFill(state, str, paintType, resDict, mat, bbox, x0, y0, x1, y1, xStep, yStep);
checkNewBitmap();
rgbdev->tilingPatternFill(state, str, paintType, resDict, mat, bbox, x0, y0, x1, y1, xStep, yStep);
int x0, int y0, int x1, int y1,
double xStep, double yStep)
{
- msg("<verbose> tilingPatternFill");
+ msg("<debug> tilingPatternFill");
boolpolydev->tilingPatternFill(state, gfx, str, paintType, resDict, mat, bbox, x0, y0, x1, y1, xStep, yStep);
checkNewBitmap();
rgbdev->tilingPatternFill(state, gfx, str, paintType, resDict, mat, bbox, x0, y0, x1, y1, xStep, yStep);
GBool BitmapOutputDev::functionShadedFill(GfxState *state, GfxFunctionShading *shading)
{
- msg("<verbose> functionShadedFill");
+ msg("<debug> functionShadedFill");
boolpolydev->functionShadedFill(state, shading);
checkNewBitmap();
return rgbdev->functionShadedFill(state, shading);
}
GBool BitmapOutputDev::axialShadedFill(GfxState *state, GfxAxialShading *shading)
{
- msg("<verbose> axialShadedFill");
+ msg("<debug> axialShadedFill");
boolpolydev->axialShadedFill(state, shading);
checkNewBitmap();
return rgbdev->axialShadedFill(state, shading);
}
GBool BitmapOutputDev::radialShadedFill(GfxState *state, GfxRadialShading *shading)
{
- msg("<verbose> radialShadedFill");
+ msg("<debug> radialShadedFill");
boolpolydev->radialShadedFill(state, shading);
checkNewBitmap();
return rgbdev->radialShadedFill(state, shading);
void BitmapOutputDev::clip(GfxState *state)
{
- msg("<verbose> clip");
+ msg("<debug> clip");
boolpolydev->clip(state);
booltextdev->clip(state);
rgbdev->clip(state);
}
void BitmapOutputDev::eoClip(GfxState *state)
{
- msg("<verbose> eoClip");
+ msg("<debug> eoClip");
boolpolydev->eoClip(state);
booltextdev->eoClip(state);
rgbdev->eoClip(state);
}
void BitmapOutputDev::clipToStrokePath(GfxState *state)
{
- msg("<verbose> clipToStrokePath");
+ msg("<debug> clipToStrokePath");
boolpolydev->clipToStrokePath(state);
booltextdev->clipToStrokePath(state);
rgbdev->clipToStrokePath(state);
void BitmapOutputDev::beginStringOp(GfxState *state)
{
- msg("<verbose> beginStringOp");
- if(this->config_bitmapfonts) {
- rgbdev->beginStringOp(state);
- clip0dev->beginStringOp(state);
- clip1dev->beginStringOp(state);
- } else {
- booltextdev->beginStringOp(state);
- gfxdev->beginStringOp(state);
- }
+ msg("<debug> beginStringOp");
+ clip0dev->beginStringOp(state);
+ clip1dev->beginStringOp(state);
+ booltextdev->beginStringOp(state);
+ gfxdev->beginStringOp(state);
}
void BitmapOutputDev::endStringOp(GfxState *state)
{
- msg("<verbose> endStringOp");
- if(this->config_bitmapfonts) {
- rgbdev->endStringOp(state);
- clip0dev->endStringOp(state);
- clip1dev->endStringOp(state);
- } else {
- booltextdev->endStringOp(state);
- checkNewText();
- gfxdev->endStringOp(state);
- }
+ msg("<debug> endStringOp");
+ clip0dev->endStringOp(state);
+ clip1dev->endStringOp(state);
+ booltextdev->endStringOp(state);
+ checkNewText();
+ gfxdev->endStringOp(state);
}
void BitmapOutputDev::beginString(GfxState *state, GString *s)
{
- msg("<verbose> beginString");
- if(this->config_bitmapfonts) {
- rgbdev->beginString(state, s);
- clip0dev->beginString(state, s);
- clip1dev->beginString(state, s);
- } else {
- booltextdev->beginString(state, s);
- gfxdev->beginString(state, s);
- }
+ msg("<debug> beginString");
+ clip0dev->beginString(state, s);
+ clip1dev->beginString(state, s);
+ booltextdev->beginString(state, s);
+ gfxdev->beginString(state, s);
}
void BitmapOutputDev::endString(GfxState *state)
{
- msg("<verbose> endString");
- if(this->config_bitmapfonts) {
- rgbdev->endString(state);
- clip0dev->endString(state);
- clip1dev->endString(state);
- } else {
- booltextdev->endString(state);
- checkNewText();
- gfxdev->endString(state);
- }
+ msg("<debug> endString");
+ clip0dev->endString(state);
+ clip1dev->endString(state);
+ booltextdev->endString(state);
+ checkNewText();
+ gfxdev->endString(state);
}
void BitmapOutputDev::clearClips()
{
- clearBooleanDev(clip0dev);
- clearBooleanDev(clip1dev);
+ clearBooleanBitmap(clip0bitmap);
+ clearBooleanBitmap(clip1bitmap);
}
void BitmapOutputDev::clearBoolPolyDev()
{
- clearBooleanDev(boolpolydev);
+ clearBooleanBitmap(boolpolybitmap);
}
void BitmapOutputDev::clearBoolTextDev()
{
- clearBooleanDev(booltextdev);
+ clearBooleanBitmap(booltextbitmap);
}
void BitmapOutputDev::drawChar(GfxState *state, double x, double y,
double dx, double dy,
double originX, double originY,
CharCode code, int nBytes, Unicode *u, int uLen)
{
- msg("<verbose> drawChar");
- if(this->config_bitmapfonts || (state->getRender()&4) /*clip*/ ) {
+ msg("<debug> drawChar");
+ if(state->getRender()&RENDER_CLIP) {
rgbdev->drawChar(state, x, y, dx, dy, originX, originY, code, nBytes, u, uLen);
} else {
clearClips();
{
msg("<error> internal error: drawString not implemented");
return;
- if(this->config_bitmapfonts) {
- rgbdev->drawString(state, s);
- clip0dev->drawString(state, s);
- clip1dev->drawString(state, s);
- } else {
- booltextdev->drawString(state, s);
- gfxdev->drawString(state, s);
- }
+ clip0dev->drawString(state, s);
+ clip1dev->drawString(state, s);
+ booltextdev->drawString(state, s);
+ gfxdev->drawString(state, s);
}
void BitmapOutputDev::endTextObject(GfxState *state)
{
- /* FIXME: the below might render things (stroke outlines etc.) to gfxdev which
- might end up unflushed- should be handled similarily as
- drawChar() above
- */
- msg("<verbose> endTextObject");
- if(this->config_bitmapfonts) {
- rgbdev->endTextObject(state);
- clip0dev->endTextObject(state);
- clip1dev->endTextObject(state);
- } else {
- gfxdev->endType3Char(state);
- }
+ msg("<debug> endTextObject");
+ rgbdev->endTextObject(state);
+ clip0dev->endTextObject(state);
+ clip1dev->endTextObject(state);
+ booltextdev->endTextObject(state);
+ checkNewText();
+ gfxdev->endTextObject(state);
}
/* TODO: these four operations below *should* do nothing, as type3
double dx, double dy,
CharCode code, Unicode *u, int uLen)
{
- msg("<verbose> beginType3Char");
- if(this->config_bitmapfonts) {
- return rgbdev->beginType3Char(state, x, y, dx, dy, code, u, uLen);
- } else {
- /* call gfxdev so that it can generate "invisible" characters
- on top of the actual graphic content, for text extraction */
- return gfxdev->beginType3Char(state, x, y, dx, dy, code, u, uLen);
- }
+ msg("<debug> beginType3Char");
+ /* call gfxdev so that it can generate "invisible" characters
+ on top of the actual graphic content, for text extraction */
+ return gfxdev->beginType3Char(state, x, y, dx, dy, code, u, uLen);
}
void BitmapOutputDev::type3D0(GfxState *state, double wx, double wy)
{
- msg("<verbose> type3D0");
- if(this->config_bitmapfonts) {
- rgbdev->type3D0(state, wx, wy);
- } else {
- return gfxdev->type3D0(state, wx, wy);
- }
+ msg("<debug> type3D0");
+ return gfxdev->type3D0(state, wx, wy);
}
void BitmapOutputDev::type3D1(GfxState *state, double wx, double wy, double llx, double lly, double urx, double ury)
{
- msg("<verbose> type3D1");
- if(this->config_bitmapfonts) {
- rgbdev->type3D1(state, wx, wy, llx, lly, urx, ury);
- } else {
- return gfxdev->type3D1(state, wx, wy, llx, lly, urx, ury);
- }
+ msg("<debug> type3D1");
+ return gfxdev->type3D1(state, wx, wy, llx, lly, urx, ury);
}
void BitmapOutputDev::endType3Char(GfxState *state)
{
- msg("<verbose> endType3Char");
- if(this->config_bitmapfonts) {
- rgbdev->endType3Char(state);
- } else {
- gfxdev->endType3Char(state);
+ msg("<debug> endType3Char");
+ gfxdev->endType3Char(state);
+}
+
+class CopyStream: public Object
+{
+ Dict*dict;
+ char*buf;
+ MemStream*memstream;
+ public:
+ CopyStream(Stream*str, int len)
+ {
+ buf = 0;
+ str->reset();
+ if(len) {
+ buf = (char*)malloc(len);
+ int t;
+ for (t=0; t<len; t++)
+ buf[t] = str->getChar();
+ }
+ str->close();
+ this->dict = str->getDict();
+ this->memstream = new MemStream(buf, 0, len, this);
}
-}
+ ~CopyStream()
+ {
+ ::free(this->buf);this->buf = 0;
+ delete this->memstream;
+ }
+ Dict* getDict() {return dict;}
+ Stream* getStream() {return this->memstream;};
+};
+
void BitmapOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str,
int width, int height, GBool invert,
GBool inlineImg)
{
- msg("<verbose> drawImageMask");
+ msg("<debug> drawImageMask streamkind=%d", str->getKind());
+ CopyStream*cpystr = 0;
+ if(inlineImg) {
+ cpystr = new CopyStream(str, height * ((width + 7) / 8));
+ str = cpystr->getStream();
+ }
boolpolydev->drawImageMask(state, ref, str, width, height, invert, inlineImg);
checkNewBitmap();
rgbdev->drawImageMask(state, ref, str, width, height, invert, inlineImg);
+ if(cpystr)
+ delete cpystr;
}
void BitmapOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
int width, int height, GfxImageColorMap *colorMap,
int *maskColors, GBool inlineImg)
{
- msg("<verbose> drawImage");
+ 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();
+ }
boolpolydev->drawImage(state, ref, str, width, height, colorMap, maskColors, inlineImg);
checkNewBitmap();
rgbdev->drawImage(state, ref, str, width, height, colorMap, maskColors, inlineImg);
+ if(cpystr)
+ delete cpystr;
}
void BitmapOutputDev::drawMaskedImage(GfxState *state, Object *ref, Stream *str,
int width, int height,
Stream *maskStr, int maskWidth, int maskHeight,
GBool maskInvert)
{
- msg("<verbose> drawMaskedImage");
+ msg("<debug> drawMaskedImage streamkind=%d", str->getKind());
boolpolydev->drawMaskedImage(state, ref, str, width, height, colorMap, maskStr, maskWidth, maskHeight, maskInvert);
checkNewBitmap();
rgbdev->drawMaskedImage(state, ref, str, width, height, colorMap, maskStr, maskWidth, maskHeight, maskInvert);
int maskWidth, int maskHeight,
GfxImageColorMap *maskColorMap)
{
- msg("<verbose> drawSoftMaskedImage");
+ msg("<debug> drawSoftMaskedImage %dx%d (%dx%d) streamkind=%d", width, height, maskWidth, maskHeight, str->getKind());
boolpolydev->drawSoftMaskedImage(state, ref, str, width, height, colorMap, maskStr, maskWidth, maskHeight, maskColorMap);
checkNewBitmap();
rgbdev->drawSoftMaskedImage(state, ref, str, width, height, colorMap, maskStr, maskWidth, maskHeight, maskColorMap);
}
void BitmapOutputDev::drawForm(Ref id)
{
- msg("<verbose> drawForm");
+ msg("<debug> drawForm");
boolpolydev->drawForm(id);
checkNewBitmap();
rgbdev->drawForm(id);
void BitmapOutputDev::processLink(Link *link, Catalog *catalog)
{
- msg("<verbose> processLink");
+ msg("<debug> processLink");
gfxdev->processLink(link, catalog);
}
GBool isolated, GBool knockout,
GBool forSoftMask)
{
- msg("<verbose> beginTransparencyGroup");
- rgbdev->beginTransparencyGroup(state, bbox, blendingColorSpace, isolated, knockout, forSoftMask);
+ msg("<debug> beginTransparencyGroup");
+#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);
+ GfxState*state2 = state->copy(gTrue);
+#endif
+ boolpolydev->beginTransparencyGroup(state1, bbox, blendingColorSpace, isolated, knockout, forSoftMask);
+ rgbdev->beginTransparencyGroup(state2, bbox, blendingColorSpace, isolated, knockout, forSoftMask);
clip1dev->beginTransparencyGroup(state, bbox, blendingColorSpace, isolated, knockout, forSoftMask);
+ delete state1;
+ delete state2;
}
void BitmapOutputDev::endTransparencyGroup(GfxState *state)
{
- msg("<verbose> endTransparencyGroup");
- boolpolydev->endTransparencyGroup(state);
+ msg("<debug> endTransparencyGroup");
+#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);
+ GfxState*state2 = state->copy(gTrue);
+#endif
+ boolpolydev->endTransparencyGroup(state1);
checkNewBitmap();
- rgbdev->endTransparencyGroup(state);
+ rgbdev->endTransparencyGroup(state2);
+ delete state1;
+ delete state2;
clip1dev->endTransparencyGroup(state);
}
void BitmapOutputDev::paintTransparencyGroup(GfxState *state, double *bbox)
{
- msg("<verbose> paintTransparencyGroup");
+ msg("<debug> paintTransparencyGroup");
boolpolydev->paintTransparencyGroup(state,bbox);
checkNewBitmap();
rgbdev->paintTransparencyGroup(state,bbox);
+ clip1dev->paintTransparencyGroup(state,bbox);
}
void BitmapOutputDev::setSoftMask(GfxState *state, double *bbox, GBool alpha, Function *transferFunc, GfxColor *backdropColor)
{
- msg("<verbose> setSoftMask");
+ msg("<debug> setSoftMask");
boolpolydev->setSoftMask(state, bbox, alpha, transferFunc, backdropColor);
checkNewBitmap();
rgbdev->setSoftMask(state, bbox, alpha, transferFunc, backdropColor);
}
void BitmapOutputDev::clearSoftMask(GfxState *state)
{
- msg("<verbose> clearSoftMask");
+ msg("<debug> clearSoftMask");
boolpolydev->clearSoftMask(state);
checkNewBitmap();
rgbdev->clearSoftMask(state);