From 863d6a2088be6b60ae9171befc50bce023cb4dc0 Mon Sep 17 00:00:00 2001 From: kramm Date: Mon, 19 Nov 2007 16:31:12 +0000 Subject: [PATCH] refined character handling --- lib/pdf/BitmapOutputDev.cc | 439 +++++++++++++++++++++++++++++++++----------- lib/pdf/BitmapOutputDev.h | 26 ++- 2 files changed, 357 insertions(+), 108 deletions(-) diff --git a/lib/pdf/BitmapOutputDev.cc b/lib/pdf/BitmapOutputDev.cc index fc0a158..6849eee 100644 --- a/lib/pdf/BitmapOutputDev.cc +++ b/lib/pdf/BitmapOutputDev.cc @@ -22,10 +22,19 @@ #include "BitmapOutputDev.h" #include "GFXOutputDev.h" #include "SplashBitmap.h" +#include "SplashPattern.h" +#include "Splash.h" #include "../log.h" static SplashColor splash_white = {255,255,255}; static SplashColor splash_black = {255,255,255}; + +ClipState::ClipState() +{ + this->next = 0; + this->clipbitmap = 0; + this->written = 0; +} BitmapOutputDev::BitmapOutputDev(InfoOutputDev*info, PDFDoc*doc) { @@ -33,16 +42,40 @@ BitmapOutputDev::BitmapOutputDev(InfoOutputDev*info, PDFDoc*doc) this->doc = doc; this->xref = doc->getXRef(); this->rgbdev = new SplashOutputDev(splashModeRGB8, 1, gFalse, splash_white, gTrue, gTrue); - this->alphadev = new SplashOutputDev(splashModeMono1, 1, gFalse, splash_black, gTrue, gTrue); + this->clip0dev = new SplashOutputDev(splashModeMono1, 1, gFalse, splash_black, gTrue, gFalse); + this->clip1dev = new SplashOutputDev(splashModeMono1, 1, gFalse, splash_black, gTrue, gFalse); this->gfxdev = new GFXOutputDev(info, this->doc); this->rgbdev->startDoc(this->xref); - this->alphadev->startDoc(this->xref); - memset(rgbdev->getBitmap()->getAlphaPtr(), 0, rgbdev->getBitmap()->getWidth()*rgbdev->getBitmap()->getHeight()); - + this->clip0dev->startDoc(this->xref); + this->clip1dev->startDoc(this->xref); + this->config_bitmapfonts = 0; + this->config_extrafontdata = 0; + this->bboxpath = 0; + //this->clipdev = 0; + //this->clipstates = 0; } BitmapOutputDev::~BitmapOutputDev() { + if(this->bboxpath) { + delete this->bboxpath;this->bboxpath = 0; + } + if(this->rgbdev) { + delete this->rgbdev;this->rgbdev= 0; + } + if(this->clip0dev) { + delete this->clip0dev;this->clip0dev= 0; + } + if(this->clip1dev) { + delete this->clip1dev;this->clip1dev= 0; + } + //if(this->clipbitmap) { + // delete this->clipbitmap;this->clipbitmap = 0; + //} + //if(this->clipdev) { + // delete this->clipdev;this->clipdev = 0; + //} + } void BitmapOutputDev::setDevice(gfxdevice_t*dev) @@ -52,12 +85,26 @@ void BitmapOutputDev::setDevice(gfxdevice_t*dev) } void BitmapOutputDev::setMove(int x,int y) { + this->gfxdev->setMove(x,y); + this->user_movex = x; + this->user_movey = y; } void BitmapOutputDev::setClip(int x1,int y1,int x2,int y2) { + this->gfxdev->setClip(x1,y1,x2,y2); + this->user_clipx1 = x1; + this->user_clipy1 = y1; + this->user_clipx2 = x2; + this->user_clipy2 = y2; } void BitmapOutputDev::setParameter(const char*key, const char*value) { + 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 BitmapOutputDev::preparePage(int pdfpage, int outputpage) { @@ -106,6 +153,12 @@ void BitmapOutputDev::flush() int xmin,ymin,xmax,ymax; getBitmapBBox(alpha, width, height, &xmin,&ymin,&xmax,&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 + width) xmax = -this->movex+this->width; + if(ymax > -this->movey + height) ymax = -this->movey+this->height; + msg(" Flushing graphics (bbox: %d,%d,%d,%d)", xmin,ymin,xmax,ymax); if((xmax-xmin)<=0 || (ymax-ymin)<=0) // no bitmap, nothing to do @@ -129,7 +182,7 @@ void BitmapOutputDev::flush() for(y=0;ydata[y*rangex]; - Guchar*ain = &alpha[(y+ymin)*width+xmax]; + Guchar*ain = &alpha[(y+ymin)*width+xmin]; for(x=0;xdata);img->data=0;free(img);img=0; } -void BitmapOutputDev::startPage(int pageNum, GfxState *state, double x1, double y1, double x2, double y2) +void BitmapOutputDev::startPage(int pageNum, GfxState *state, double crop_x1, double crop_y1, double crop_x2, double crop_y2) { + double x1,y1,x2,y2; + state->transform(crop_x1,crop_y1,&x1,&y1); + state->transform(crop_x2,crop_y2,&x2,&y2); + if(x2movex = -(int)x1 - user_movex; + this->movey = -(int)y1 - user_movey; + + if(user_clipx1|user_clipy1|user_clipx2|user_clipy2) { + x1 = user_clipx1; + x2 = user_clipx2; + y1 = user_clipy1; + y2 = user_clipy2; + } + this->width = (int)(x2-x1); + this->height = (int)(y2-y1); + msg(" startPage"); - this->width = (int)x2 - (int)x1; //not used yet - this->height = (int)y2 - (int)y1; - rgbdev->startPage(pageNum, state, x1, y1, x2, y2); - alphadev->startPage(pageNum, state, x1, y1, x2, y2); + rgbdev->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); + + /*int width = this->rgbdev->getBitmap()->getWidth(); + int height = this->rgbdev->getBitmap()->getHeight(); + this->bboxpath = new SplashPath(); + this->bboxpath->moveTo(0,0); + this->bboxpath->lineTo(width,0); + this->bboxpath->lineTo(width,height); + this->bboxpath->lineTo(0,height); + this->bboxpath->lineTo(0,0); + + if(this->clipbitmap) { + delete this->clipbitmap;this->clipbitmap = 0; + } + this->clipbitmap = new SplashBitmap(width, height, 1, splashModeMono1, gFalse, gTrue); + if(this->clipdev) { + delete this->clipdev;this->clipdev = 0; + } + SplashScreenParams params; + params.type = splashScreenDispersed; + params.size = 0; + params.dotRadius = 0; + this->clipdev = new Splash(this->clipbitmap, 0, (SplashScreenParams*)0);*/ } void BitmapOutputDev::endPage() @@ -171,44 +269,51 @@ void BitmapOutputDev::endPage() /* splash will now destroy alpha, and paint the background color into the "holes" in the bitmap */ rgbdev->endPage(); - alphadev->endPage(); + clip0dev->endPage(); + clip1dev->endPage(); } GBool BitmapOutputDev::upsideDown() { - rgbdev->upsideDown(); - return alphadev->upsideDown(); + clip0dev->upsideDown(); + clip1dev->upsideDown(); + return rgbdev->upsideDown(); } GBool BitmapOutputDev::useDrawChar() { - rgbdev->useDrawChar(); - return alphadev->useDrawChar(); + clip0dev->useDrawChar(); + clip1dev->useDrawChar(); + return rgbdev->useDrawChar(); } GBool BitmapOutputDev::useTilingPatternFill() { - rgbdev->useTilingPatternFill(); - return alphadev->useTilingPatternFill(); + clip0dev->useTilingPatternFill(); + clip1dev->useTilingPatternFill(); + return rgbdev->useTilingPatternFill(); } GBool BitmapOutputDev::useShadedFills() { - rgbdev->useTilingPatternFill(); - return alphadev->useTilingPatternFill(); + clip0dev->useTilingPatternFill(); + clip1dev->useTilingPatternFill(); + return rgbdev->useTilingPatternFill(); } GBool BitmapOutputDev::useDrawForm() { - rgbdev->useDrawForm(); - return alphadev->useDrawForm(); + clip0dev->useDrawForm(); + clip1dev->useDrawForm(); + return rgbdev->useDrawForm(); } GBool BitmapOutputDev::interpretType3Chars() { - if(config_bitmapfonts) { - rgbdev->interpretType3Chars(); - return alphadev->interpretType3Chars(); + if(!config_bitmapfonts) { + clip0dev->interpretType3Chars(); + clip1dev->interpretType3Chars(); + return rgbdev->interpretType3Chars(); } else { return gfxdev->interpretType3Chars(); } @@ -216,8 +321,9 @@ GBool BitmapOutputDev::interpretType3Chars() GBool BitmapOutputDev::needNonText() { - rgbdev->needNonText(); - return alphadev->needNonText(); + clip0dev->needNonText(); + clip1dev->needNonText(); + return rgbdev->needNonText(); } /*GBool BitmapOutputDev::checkPageSlice(Page *page, double hDPI, double vDPI, int rotate, GBool useMediaBox, GBool crop, @@ -231,185 +337,236 @@ GBool BitmapOutputDev::needNonText() void BitmapOutputDev::setDefaultCTM(double *ctm) { rgbdev->setDefaultCTM(ctm); - alphadev->setDefaultCTM(ctm); + clip0dev->setDefaultCTM(ctm); + clip1dev->setDefaultCTM(ctm); } void BitmapOutputDev::saveState(GfxState *state) { rgbdev->saveState(state); - alphadev->saveState(state); + clip0dev->saveState(state); + clip1dev->saveState(state); + + /*ClipState*cstate = new ClipState(); + cstate->next = this->clipstates; + this->clipstates = cstate;*/ } void BitmapOutputDev::restoreState(GfxState *state) { rgbdev->restoreState(state); - alphadev->restoreState(state); + clip0dev->restoreState(state); + clip1dev->restoreState(state); + + /*if(this->clipstates) { + ClipState*old = this->clipstates; + if(old->written) { + gfxdev->restoreState(state); + } + this->clipstates = this->clipstates->next; + delete(old); + } else { + msg(" invalid restoreState()"); + }*/ } void BitmapOutputDev::updateAll(GfxState *state) { rgbdev->updateAll(state); - alphadev->updateAll(state); + clip0dev->updateAll(state); + clip1dev->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); - alphadev->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); } void BitmapOutputDev::updateLineDash(GfxState *state) { rgbdev->updateLineDash(state); - alphadev->updateLineDash(state); + clip0dev->updateLineDash(state); + clip1dev->updateLineDash(state); } void BitmapOutputDev::updateFlatness(GfxState *state) { rgbdev->updateFlatness(state); - alphadev->updateFlatness(state); + clip0dev->updateFlatness(state); + clip1dev->updateFlatness(state); } void BitmapOutputDev::updateLineJoin(GfxState *state) { rgbdev->updateLineJoin(state); - alphadev->updateLineJoin(state); + clip0dev->updateLineJoin(state); + clip1dev->updateLineJoin(state); } void BitmapOutputDev::updateLineCap(GfxState *state) { rgbdev->updateLineCap(state); - alphadev->updateLineCap(state); + clip0dev->updateLineCap(state); + clip1dev->updateLineCap(state); } void BitmapOutputDev::updateMiterLimit(GfxState *state) { rgbdev->updateMiterLimit(state); - alphadev->updateMiterLimit(state); + clip0dev->updateMiterLimit(state); + clip1dev->updateMiterLimit(state); } void BitmapOutputDev::updateLineWidth(GfxState *state) { rgbdev->updateLineWidth(state); - alphadev->updateLineWidth(state); + clip0dev->updateLineWidth(state); + clip1dev->updateLineWidth(state); } void BitmapOutputDev::updateStrokeAdjust(GfxState *state) { rgbdev->updateStrokeAdjust(state); - alphadev->updateStrokeAdjust(state); + clip0dev->updateStrokeAdjust(state); + clip1dev->updateStrokeAdjust(state); } void BitmapOutputDev::updateFillColorSpace(GfxState *state) { rgbdev->updateFillColorSpace(state); - alphadev->updateFillColorSpace(state); + clip0dev->updateFillColorSpace(state); + clip1dev->updateFillColorSpace(state); } void BitmapOutputDev::updateStrokeColorSpace(GfxState *state) { rgbdev->updateStrokeColorSpace(state); - alphadev->updateStrokeColorSpace(state); + clip0dev->updateStrokeColorSpace(state); + clip1dev->updateStrokeColorSpace(state); } void BitmapOutputDev::updateFillColor(GfxState *state) { rgbdev->updateFillColor(state); - alphadev->updateFillColor(state); + clip0dev->updateFillColor(state); + clip0dev->updateFillColor(state); + clip1dev->updateFillColor(state); } void BitmapOutputDev::updateStrokeColor(GfxState *state) { rgbdev->updateStrokeColor(state); - alphadev->updateStrokeColor(state); + clip0dev->updateStrokeColor(state); + clip1dev->updateStrokeColor(state); } void BitmapOutputDev::updateBlendMode(GfxState *state) { rgbdev->updateBlendMode(state); - alphadev->updateBlendMode(state); + clip0dev->updateBlendMode(state); + clip1dev->updateBlendMode(state); } void BitmapOutputDev::updateFillOpacity(GfxState *state) { rgbdev->updateFillOpacity(state); - alphadev->updateFillOpacity(state); + clip0dev->updateFillOpacity(state); + clip1dev->updateFillOpacity(state); } void BitmapOutputDev::updateStrokeOpacity(GfxState *state) { rgbdev->updateStrokeOpacity(state); - alphadev->updateStrokeOpacity(state); + clip0dev->updateStrokeOpacity(state); + clip1dev->updateStrokeOpacity(state); } void BitmapOutputDev::updateFillOverprint(GfxState *state) { rgbdev->updateFillOverprint(state); - alphadev->updateFillOverprint(state); + clip0dev->updateFillOverprint(state); + clip1dev->updateFillOverprint(state); } void BitmapOutputDev::updateStrokeOverprint(GfxState *state) { rgbdev->updateStrokeOverprint(state); - alphadev->updateStrokeOverprint(state); + clip0dev->updateStrokeOverprint(state); + clip1dev->updateStrokeOverprint(state); } void BitmapOutputDev::updateTransfer(GfxState *state) { rgbdev->updateTransfer(state); - alphadev->updateTransfer(state); + clip0dev->updateTransfer(state); + clip1dev->updateTransfer(state); } void BitmapOutputDev::updateFont(GfxState *state) { rgbdev->updateFont(state); - alphadev->updateFont(state); - gfxdev->updateFont(state); + clip0dev->updateFont(state); + clip1dev->updateFont(state); + if(!config_bitmapfonts) + gfxdev->updateFont(state); } void BitmapOutputDev::updateTextMat(GfxState *state) { rgbdev->updateTextMat(state); - alphadev->updateTextMat(state); - gfxdev->updateTextMat(state); + clip0dev->updateTextMat(state); + clip1dev->updateTextMat(state); + if(!config_bitmapfonts) + gfxdev->updateTextMat(state); } void BitmapOutputDev::updateCharSpace(GfxState *state) { rgbdev->updateCharSpace(state); - alphadev->updateCharSpace(state); - gfxdev->updateTextMat(state); + clip0dev->updateCharSpace(state); + clip1dev->updateCharSpace(state); + if(!config_bitmapfonts) + gfxdev->updateCharSpace(state); } void BitmapOutputDev::updateRender(GfxState *state) { rgbdev->updateRender(state); - alphadev->updateRender(state); - gfxdev->updateTextMat(state); + clip0dev->updateRender(state); + clip1dev->updateRender(state); + if(!config_bitmapfonts) + gfxdev->updateRender(state); } void BitmapOutputDev::updateRise(GfxState *state) { rgbdev->updateRise(state); - alphadev->updateRise(state); - gfxdev->updateTextMat(state); + clip0dev->updateRise(state); + clip1dev->updateRise(state); + if(!config_bitmapfonts) + gfxdev->updateRise(state); } void BitmapOutputDev::updateWordSpace(GfxState *state) { rgbdev->updateWordSpace(state); - alphadev->updateWordSpace(state); - gfxdev->updateTextMat(state); + clip0dev->updateWordSpace(state); + clip1dev->updateWordSpace(state); + if(!config_bitmapfonts) + gfxdev->updateWordSpace(state); } void BitmapOutputDev::updateHorizScaling(GfxState *state) { rgbdev->updateHorizScaling(state); - alphadev->updateHorizScaling(state); - gfxdev->updateTextMat(state); + clip0dev->updateHorizScaling(state); + clip1dev->updateHorizScaling(state); + if(!config_bitmapfonts) + gfxdev->updateHorizScaling(state); } void BitmapOutputDev::updateTextPos(GfxState *state) { rgbdev->updateTextPos(state); - alphadev->updateTextPos(state); - gfxdev->updateTextMat(state); + clip0dev->updateTextPos(state); + clip1dev->updateTextPos(state); + if(!config_bitmapfonts) + gfxdev->updateTextPos(state); } void BitmapOutputDev::updateTextShift(GfxState *state, double shift) { rgbdev->updateTextShift(state, shift); - alphadev->updateTextShift(state, shift); - gfxdev->updateTextMat(state); + clip0dev->updateTextShift(state, shift); + clip1dev->updateTextShift(state, shift); } void BitmapOutputDev::stroke(GfxState *state) { msg(" stroke"); rgbdev->stroke(state); - alphadev->stroke(state); } void BitmapOutputDev::fill(GfxState *state) { msg(" fill"); rgbdev->fill(state); - alphadev->fill(state); } void BitmapOutputDev::eoFill(GfxState *state) { msg(" eoFill"); rgbdev->eoFill(state); - alphadev->eoFill(state); } void BitmapOutputDev::tilingPatternFill(GfxState *state, Object *str, int paintType, Dict *resDict, @@ -419,43 +576,61 @@ void BitmapOutputDev::tilingPatternFill(GfxState *state, Object *str, { msg(" tilingPatternFill"); rgbdev->tilingPatternFill(state, str, paintType, resDict, mat, bbox, x0, y0, x1, y1, xStep, yStep); - alphadev->tilingPatternFill(state, str, paintType, resDict, mat, bbox, x0, y0, x1, y1, xStep, yStep); } GBool BitmapOutputDev::functionShadedFill(GfxState *state, GfxFunctionShading *shading) { msg(" functionShadedFill"); - rgbdev->functionShadedFill(state, shading); - return alphadev->functionShadedFill(state, shading); + return rgbdev->functionShadedFill(state, shading); } GBool BitmapOutputDev::axialShadedFill(GfxState *state, GfxAxialShading *shading) { msg(" axialShadedFill"); - rgbdev->axialShadedFill(state, shading); - return alphadev->axialShadedFill(state, shading); + return rgbdev->axialShadedFill(state, shading); } GBool BitmapOutputDev::radialShadedFill(GfxState *state, GfxRadialShading *shading) { msg(" radialShadedFill"); - rgbdev->radialShadedFill(state, shading); - return alphadev->radialShadedFill(state, shading); + return rgbdev->radialShadedFill(state, shading); } + +SplashColor black = {0,0,0}; +SplashColor white = {255,255,255}; + +void BitmapOutputDev::doClip(GfxState *state, GBool eo) +{ + if(!eo) { + rgbdev->clip(state); + clip1dev->clip(state); + } else { + rgbdev->eoClip(state); + clip1dev->eoClip(state); + } + + //SplashPattern *pblack = new SplashSolidColor(black); + //SplashPattern *pwhite = new SplashSolidColor(white); + //SplashPath* path = rgbdev->convertPath(state, state->getPath()); + //clipdev->clear(black, 0); + //clipdev->clipToPath(path, eo); + //clipdev->setFillPattern(pwhite); + //clipdev->fill(bboxpath,gFalse); + //delete path; +} + void BitmapOutputDev::clip(GfxState *state) { msg(" clip"); - rgbdev->clip(state); - alphadev->clip(state); + doClip(state, gFalse); } void BitmapOutputDev::eoClip(GfxState *state) { msg(" eoClip"); - rgbdev->eoClip(state); - alphadev->eoClip(state); + doClip(state, gTrue); } void BitmapOutputDev::clipToStrokePath(GfxState *state) { msg(" clipToStrokePath"); rgbdev->clipToStrokePath(state); - alphadev->clipToStrokePath(state); + clip1dev->clipToStrokePath(state); } void BitmapOutputDev::beginStringOp(GfxState *state) @@ -463,7 +638,8 @@ void BitmapOutputDev::beginStringOp(GfxState *state) msg(" beginStringOp"); if(this->config_bitmapfonts) { rgbdev->beginStringOp(state); - alphadev->beginStringOp(state); + clip0dev->beginStringOp(state); + clip1dev->beginStringOp(state); } else { gfxdev->beginStringOp(state); } @@ -473,7 +649,8 @@ void BitmapOutputDev::endStringOp(GfxState *state) msg(" endStringOp"); if(this->config_bitmapfonts) { rgbdev->endStringOp(state); - alphadev->endStringOp(state); + clip0dev->endStringOp(state); + clip1dev->endStringOp(state); } else { gfxdev->endStringOp(state); } @@ -483,7 +660,8 @@ void BitmapOutputDev::beginString(GfxState *state, GString *s) msg(" beginString"); if(this->config_bitmapfonts) { rgbdev->beginString(state, s); - alphadev->beginString(state, s); + clip0dev->beginString(state, s); + clip1dev->beginString(state, s); } else { gfxdev->beginString(state, s); } @@ -493,7 +671,8 @@ void BitmapOutputDev::endString(GfxState *state) msg(" endString"); if(this->config_bitmapfonts) { rgbdev->endString(state); - alphadev->endString(state); + clip0dev->endString(state); + clip1dev->endString(state); } else { gfxdev->endString(state); } @@ -504,12 +683,61 @@ void BitmapOutputDev::drawChar(GfxState *state, double x, double y, CharCode code, int nBytes, Unicode *u, int uLen) { msg(" drawChar"); - flush(); - if(this->config_bitmapfonts) { + if(this->config_bitmapfonts || (state->getRender()&4) /*clip*/ ) { rgbdev->drawChar(state, x, y, dx, dy, originX, originY, code, nBytes, u, uLen); - alphadev->drawChar(state, x, y, dx, dy, originX, originY, code, nBytes, u, uLen); } else { - gfxdev->drawChar(state, x, y, dx, dy, originX, originY, code, nBytes, u, uLen); + SplashBitmap*clip0 = clip0dev->getBitmap(); + SplashBitmap*clip1 = clip1dev->getBitmap(); + int width8 = (clip0->getWidth()+7)/8; + int width = clip0->getWidth(); + int height = clip0->getHeight(); + memset(clip0->getDataPtr(), 0, width8*height); + memset(clip1->getDataPtr(), 0, width8*height); + 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); + + /* 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(memcmp(clip0->getDataPtr(), clip1->getDataPtr(), width8*height)) { + msg(" Char %d is affected by clipping", code); + + rgbdev->drawChar(state, x, y, dx, dy, originX, originY, code, nBytes, u, uLen); + if(config_extrafontdata) { + int oldrender = state->getRender(); + state->setRender(3); //invisible + gfxdev->drawChar(state, x, y, dx, dy, originX, originY, code, nBytes, u, uLen); + state->setRender(oldrender); + } + } else { + /* this char is not at all affected by clipping. Now just find out whether the + bitmap we're currently working on needs to be dumped out first */ + + Guchar*alpha = rgbdev->getBitmap()->getAlphaPtr(); + Guchar*charpixels = clip1dev->getBitmap()->getDataPtr(); + int xx,yy; + for(yy=0;yy>3; + /* TODO: is the bit order correct? */ + if(aline[xx] && (cline[bytepos]&(1< Char %d is above current bitmap data", code); + flush(); + } + gfxdev->drawChar(state, x, y, dx, dy, originX, originY, code, nBytes, u, uLen); + } } } void BitmapOutputDev::drawString(GfxState *state, GString *s) @@ -517,7 +745,8 @@ void BitmapOutputDev::drawString(GfxState *state, GString *s) msg(" drawString"); if(this->config_bitmapfonts) { rgbdev->drawString(state, s); - alphadev->drawString(state, s); + clip0dev->drawString(state, s); + clip1dev->drawString(state, s); } else { gfxdev->drawString(state, s); } @@ -527,7 +756,8 @@ void BitmapOutputDev::endTextObject(GfxState *state) msg(" endTextObject"); if(this->config_bitmapfonts) { rgbdev->endTextObject(state); - alphadev->endTextObject(state); + clip0dev->endTextObject(state); + clip1dev->endTextObject(state); } else { gfxdev->endType3Char(state); } @@ -538,8 +768,7 @@ GBool BitmapOutputDev::beginType3Char(GfxState *state, double x, double y, { msg(" beginType3Char"); if(this->config_bitmapfonts) { - rgbdev->beginType3Char(state, x, y, dx, dy, code, u, uLen); - return alphadev->beginType3Char(state, x, y, dx, dy, code, u, uLen); + return rgbdev->beginType3Char(state, x, y, dx, dy, code, u, uLen); } else { return gfxdev->beginType3Char(state, x, y, dx, dy, code, u, uLen); } @@ -549,7 +778,6 @@ void BitmapOutputDev::type3D0(GfxState *state, double wx, double wy) msg(" type3D0"); if(this->config_bitmapfonts) { rgbdev->type3D0(state, wx, wy); - alphadev->type3D0(state, wx, wy); } else { return gfxdev->type3D0(state, wx, wy); } @@ -559,7 +787,6 @@ void BitmapOutputDev::type3D1(GfxState *state, double wx, double wy, double llx, msg(" type3D1"); if(this->config_bitmapfonts) { rgbdev->type3D1(state, wx, wy, llx, lly, urx, ury); - alphadev->type3D1(state, wx, wy, llx, lly, urx, ury); } else { return gfxdev->type3D1(state, wx, wy, llx, lly, urx, ury); } @@ -569,7 +796,6 @@ void BitmapOutputDev::endType3Char(GfxState *state) msg(" endType3Char"); if(this->config_bitmapfonts) { rgbdev->endType3Char(state); - alphadev->endType3Char(state); } else { gfxdev->endType3Char(state); } @@ -580,7 +806,6 @@ void BitmapOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str, { msg(" drawImageMask"); rgbdev->drawImageMask(state, ref, str, width, height, invert, inlineImg); - alphadev->drawImageMask(state, ref, str, width, height, invert, inlineImg); } void BitmapOutputDev::drawImage(GfxState *state, Object *ref, Stream *str, int width, int height, GfxImageColorMap *colorMap, @@ -588,7 +813,6 @@ void BitmapOutputDev::drawImage(GfxState *state, Object *ref, Stream *str, { msg(" drawImage"); rgbdev->drawImage(state, ref, str, width, height, colorMap, maskColors, inlineImg); - alphadev->drawImage(state, ref, str, width, height, colorMap, maskColors, inlineImg); } void BitmapOutputDev::drawMaskedImage(GfxState *state, Object *ref, Stream *str, int width, int height, @@ -598,7 +822,6 @@ void BitmapOutputDev::drawMaskedImage(GfxState *state, Object *ref, Stream *str, { msg(" drawMaskedImage"); rgbdev->drawMaskedImage(state, ref, str, width, height, colorMap, maskStr, maskWidth, maskHeight, maskInvert); - alphadev->drawMaskedImage(state, ref, str, width, height, colorMap, maskStr, maskWidth, maskHeight, maskInvert); } void BitmapOutputDev::drawSoftMaskedImage(GfxState *state, Object *ref, Stream *str, int width, int height, @@ -609,14 +832,19 @@ void BitmapOutputDev::drawSoftMaskedImage(GfxState *state, Object *ref, Stream * { msg(" drawSoftMaskedImage"); rgbdev->drawSoftMaskedImage(state, ref, str, width, height, colorMap, maskStr, maskWidth, maskHeight, maskColorMap); - alphadev->drawSoftMaskedImage(state, ref, str, width, height, colorMap, maskStr, maskWidth, maskHeight, maskColorMap); } void BitmapOutputDev::drawForm(Ref id) { msg(" drawForm"); rgbdev->drawForm(id); - alphadev->drawForm(id); } + +void BitmapOutputDev::processLink(Link *link, Catalog *catalog) +{ + msg(" processLink"); + gfxdev->processLink(link, catalog); +} + void BitmapOutputDev::beginTransparencyGroup(GfxState *state, double *bbox, GfxColorSpace *blendingColorSpace, GBool isolated, GBool knockout, @@ -624,29 +852,28 @@ void BitmapOutputDev::beginTransparencyGroup(GfxState *state, double *bbox, { msg(" beginTransparencyGroup"); rgbdev->beginTransparencyGroup(state, bbox, blendingColorSpace, isolated, knockout, forSoftMask); - alphadev->beginTransparencyGroup(state, bbox, blendingColorSpace, isolated, knockout, forSoftMask); + clip1dev->beginTransparencyGroup(state, bbox, blendingColorSpace, isolated, knockout, forSoftMask); } void BitmapOutputDev::endTransparencyGroup(GfxState *state) { msg(" endTransparencyGroup"); rgbdev->endTransparencyGroup(state); - alphadev->endTransparencyGroup(state); + clip1dev->endTransparencyGroup(state); } void BitmapOutputDev::paintTransparencyGroup(GfxState *state, double *bbox) { msg(" paintTransparencyGroup"); rgbdev->paintTransparencyGroup(state,bbox); - alphadev->paintTransparencyGroup(state,bbox); } void BitmapOutputDev::setSoftMask(GfxState *state, double *bbox, GBool alpha, Function *transferFunc, GfxColor *backdropColor) { msg(" setSoftMask"); rgbdev->setSoftMask(state, bbox, alpha, transferFunc, backdropColor); - alphadev->setSoftMask(state, bbox, alpha, transferFunc, backdropColor); + clip1dev->setSoftMask(state, bbox, alpha, transferFunc, backdropColor); } void BitmapOutputDev::clearSoftMask(GfxState *state) { msg(" clearSoftMask"); rgbdev->clearSoftMask(state); - alphadev->clearSoftMask(state); + clip1dev->clearSoftMask(state); } diff --git a/lib/pdf/BitmapOutputDev.h b/lib/pdf/BitmapOutputDev.h index 3e821c7..071c64a 100644 --- a/lib/pdf/BitmapOutputDev.h +++ b/lib/pdf/BitmapOutputDev.h @@ -30,6 +30,14 @@ #include "PDFDoc.h" #include "CommonOutputDev.h" +struct ClipState +{ + ClipState*next; + SplashBitmap*clipbitmap; + char written; + ClipState(); +}; + class BitmapOutputDev: public CommonOutputDev { public: BitmapOutputDev(InfoOutputDev*info, PDFDoc*doc); @@ -106,6 +114,7 @@ public: virtual GBool axialShadedFill(GfxState *state, GfxAxialShading *shading); virtual GBool radialShadedFill(GfxState *state, GfxRadialShading *shading); + void doClip(GfxState *state, GBool eo); virtual void clip(GfxState *state); virtual void eoClip(GfxState *state); virtual void clipToStrokePath(GfxState *state); @@ -157,19 +166,32 @@ public: virtual void setSoftMask(GfxState *state, double *bbox, GBool alpha, Function *transferFunc, GfxColor *backdropColor); virtual void clearSoftMask(GfxState *state); + virtual void processLink(Link *link, Catalog *catalog); private: void flush(); char config_bitmapfonts; + char config_extrafontdata; + + SplashPath*bboxpath; - int width, height; PDFDoc*doc; XRef*xref; SplashOutputDev*rgbdev; - SplashOutputDev*alphadev; + SplashOutputDev*clip0dev; + SplashOutputDev*clip1dev; GFXOutputDev*gfxdev; InfoOutputDev*info; gfxdevice_t*dev; + + int movex, movey; + int width, height; + + int user_movex, user_movey; + int user_clipx1, user_clipy1; + int user_clipx2, user_clipy2; + + //ClipState*clipstates; }; #endif -- 1.7.10.4