X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=lib%2Fpdf%2FGFXOutputDev.cc;h=f2074b810fe68ed9e0709581ab3217d75c78f640;hb=56a7509ae89bc94b5291a51e441cc839db2fedc4;hp=8377c5f6fe95389ff4cf7932361c81dd96324a27;hpb=b8d4219b572bec7285469f34897dae57c0fc6141;p=swftools.git diff --git a/lib/pdf/GFXOutputDev.cc b/lib/pdf/GFXOutputDev.cc index 8377c5f..f2074b8 100644 --- a/lib/pdf/GFXOutputDev.cc +++ b/lib/pdf/GFXOutputDev.cc @@ -38,9 +38,13 @@ #endif //xpdf header files #include "config.h" +#ifdef HAVE_POPPLER +#include +#include +#else #include "gfile.h" #include "GString.h" -#include "gmem.h" +#endif #include "Object.h" #include "Stream.h" #include "Array.h" @@ -54,12 +58,8 @@ #include "OutputDev.h" #include "GfxFont.h" #include "GfxState.h" -#include "CharCodeToUnicode.h" #include "NameToUnicodeTable.h" #include "GlobalParams.h" -#include "FoFiType1C.h" -#include "FoFiTrueType.h" -#include "GHash.h" #include "GFXOutputDev.h" // swftools header files @@ -125,7 +125,7 @@ struct fontentry { static int verbose = 0; -static int dbgindent = 0; +static int dbgindent = 1; static void dbg(const char*format, ...) { char buf[1024]; @@ -596,13 +596,6 @@ void GFXOutputDev::setParameter(const char*key, const char*value) this->config_fontquality = atof(value); if(this->config_fontquality<=1) this->config_fontquality=1; - } else if(!strcmp(key,"help")) { - printf("\nPDF layer options:\n"); - printf("breakonwarning=0/1 Abort conversion if graphic objects are found which\n"); - printf(" are not 100%% supported\n"); - printf("transparent=0/1 Make PDF transparent (alpha background)\n"); - printf("extrafontdata=0/1 Store Type3 characters and capture characters\n"); - printf("fontquality=1..100 Curve approximation quality of the fonts\n"); } } @@ -1363,7 +1356,8 @@ void GFXOutputDev::drawChar(GfxState *state, double x, double y, msg(" drawChar(%f,%f,c='%c' (%d), u=%d <%d>) CID=%d render=%d glyphid=%d font=%08x",x,y,(charid&127)>=32?charid:'?', charid, u, uLen, font->isCIDFont(), render, glyphid, current_gfxfont); gfxmatrix_t m = this->current_font_matrix; - this->transformXY(state, x, y, &m.tx, &m.ty); + this->transformXY(state, x-originX, y-originY, &m.tx, &m.ty); + m.tx += originX; m.ty += originY; if(render == RENDER_FILL || render == RENDER_INVISIBLE) { device->drawchar(device, current_gfxfont, glyphid, &col, &m); @@ -1738,38 +1732,47 @@ void GFXOutputDev::processLink(Link *link, Catalog *catalog) } void GFXOutputDev::saveState(GfxState *state) { - dbg("saveState"); dbgindent+=2; + dbg("saveState %08x", state); dbgindent+=2; - msg(" saveState"); + msg(" saveState %08x", state); updateAll(state); if(statepos>=64) { - msg(" Too many nested states in pdf."); - return; + msg(" Too many nested states in pdf."); + exit(1); } statepos ++; + states[statepos].state = state; states[statepos].createsoftmask = states[statepos-1].createsoftmask; states[statepos].transparencygroup = states[statepos-1].transparencygroup; states[statepos].clipping = 0; + states[statepos].olddevice = 0; states[statepos].clipbbox = states[statepos-1].clipbbox; }; void GFXOutputDev::restoreState(GfxState *state) { - dbgindent-=2; dbg("restoreState"); + dbgindent-=2; dbg("restoreState %08x", state); if(statepos==0) { - msg(" Invalid restoreState"); - return; + msg(" Invalid restoreState"); + exit(1); } - msg(" restoreState%s%s", states[statepos].softmask?" (end softmask)":"", + msg(" restoreState %08x%s%s", state, + states[statepos].softmask?" (end softmask)":"", states[statepos].clipping?" (end clipping)":""); if(states[statepos].softmask) { clearSoftMask(state); } updateAll(state); + while(states[statepos].clipping) { device->endclip(device); states[statepos].clipping--; } + if(states[statepos].state!=state) { + msg(" bad state nesting"); + exit(1); + } + states[statepos].state=0; statepos--; } @@ -1957,7 +1960,7 @@ void GFXOutputDev::updateFont(GfxState *state) unsigned char* antialize(unsigned char*data, int width, int height, int newwidth, int newheight, int palettesize) { - if((newwidth<2 || newheight<2) || + if((newwidth<1 || newheight<1) || (width<=newwidth || height<=newheight)) return 0; unsigned char*newdata; @@ -2076,6 +2079,8 @@ void GFXOutputDev::drawGeneralImage(GfxState *state, Object *ref, Stream *str, GBool inlineImg, int mask, int*maskColors, Stream *maskStr, int maskWidth, int maskHeight, GBool maskInvert, GfxImageColorMap*maskColorMap) { + /* the code in this function is *old*. It's not pretty, but it works. */ + double x1,y1,x2,y2,x3,y3,x4,y4; ImageStream *imgStr; Guchar pixBuf[4]; @@ -2199,10 +2204,6 @@ void GFXOutputDev::drawGeneralImage(GfxState *state, Object *ref, Stream *str, pic[width*y+x] = buf[0]; } - /* the size of the drawn image is added to the identifier - as the same image may require different bitmaps if displayed - at different sizes (due to antialiasing): */ - int found = -1; if(type3active) { unsigned char*pic2 = 0; numpalette = 16; @@ -2260,7 +2261,23 @@ void GFXOutputDev::drawGeneralImage(GfxState *state, Object *ref, Stream *str, pic[width*y+x].b = (unsigned char)(colToByte(rgb.b)); pic[width*y+x].a = 255;//(U8)(rgb.a * 255 + 0.5); if(maskbitmap) { - pic[width*y+x].a = maskbitmap[(y*maskHeight/height)*maskWidth+(x*maskWidth/width)]; + int x1 = x*maskWidth/width; + int y1 = y*maskHeight/height; + int x2 = (x+1)*maskWidth/width; + int y2 = (y+1)*maskHeight/height; + int xx,yy; + unsigned int alpha=0; + unsigned int count=0; + for(xx=x1;xxdevice; this->device = (gfxdevice_t*)rfx_calloc(sizeof(gfxdevice_t)); + dbg("this->device now %08x (old: %08x)", this->device, states[statepos].olddevice); gfxdevice_record_init(this->device); @@ -2604,11 +2622,21 @@ void GFXOutputDev::endTransparencyGroup(GfxState *state) dbgindent-=2; gfxdevice_t*r = this->device; + dbg("endTransparencyGroup this->device now back to %08x (destroying %08x)", states[statepos].olddevice, this->device); + this->device = states[statepos].olddevice; + if(!this->device) { + msg(" bad state nesting in transparency group- PDF file broken?"); + /* if these errors occur more often, we should build a seperate + transparency group stack, like xpdf/SplashOutputDev.cc does */ + restoreState(state); + this->device = states[statepos].olddevice; + } + states[statepos].olddevice = 0; gfxresult_t*recording = r->finish(r); - dbg("endTransparencyGroup forsoftmask=%d recording=%08x/%08x", states[statepos].createsoftmask, r, recording); + dbg(" forsoftmask=%d recording=%08x/%08x", states[statepos].createsoftmask, r, recording); msg(" endTransparencyGroup forsoftmask=%d recording=%08x/%08x", states[statepos].createsoftmask, r, recording); if(states[statepos].createsoftmask) { @@ -2628,9 +2656,9 @@ void GFXOutputDev::paintTransparencyGroup(GfxState *state, double *bbox) "colordodge","colorburn","hardlight","softlight","difference", "exclusion","hue","saturation","color","luminosity"}; - dbg("paintTransparencyGroup blend=%s softmaskon=%d", blendmodes[state->getBlendMode()], states[statepos].softmask); + dbg("paintTransparencyGroup blend=%s softmaskon=%d recording=%08x", blendmodes[state->getBlendMode()], states[statepos].softmask, states[statepos].grouprecording); msg(" paintTransparencyGroup blend=%s softmaskon=%d", blendmodes[state->getBlendMode()], states[statepos].softmask); - + if(state->getBlendMode() == gfxBlendNormal) infofeature("transparency groups"); else { @@ -2647,6 +2675,7 @@ void GFXOutputDev::paintTransparencyGroup(GfxState *state, double *bbox) if(blendmode == gfxBlendMultiply && alpha>200) alpha = 128; gfxdevice_t ops; + dbg("this->device=%08x, this->device->name=%s\n", this->device, this->device->name); gfxdevice_ops_init(&ops, this->device, alpha); gfxresult_record_replay(grouprecording, &ops); ops.finish(&ops); @@ -2674,7 +2703,11 @@ void GFXOutputDev::setSoftMask(GfxState *state, double *bbox, GBool alpha, Funct infofeature("soft masks"); else warnfeature("soft masks from alpha channel",0); - + + if(states[statepos].olddevice) { + msg(" Internal error: badly balanced softmasks/transparency groups"); + exit(1); + } states[statepos].olddevice = this->device; this->device = (gfxdevice_t*)rfx_calloc(sizeof(gfxdevice_t)); gfxdevice_record_init(this->device);