X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=pdf2swf%2FSWFOutputDev.cc;h=020dc8fd94172928220392b82fb71f81682e42ee;hb=3517626b913b0543bce4f9644005c1faba8d0580;hp=b14e633ba457aad24b5a8fc256cb8212044cddfc;hpb=07801fe922a2fee0a7f12cedf3941cdb22a7a798;p=swftools.git diff --git a/pdf2swf/SWFOutputDev.cc b/pdf2swf/SWFOutputDev.cc index b14e633..020dc8f 100644 --- a/pdf2swf/SWFOutputDev.cc +++ b/pdf2swf/SWFOutputDev.cc @@ -114,6 +114,16 @@ struct mapping { {"Symbol", "s050000l"}, {"ZapfDingbats", "d050000l"}}; +class SWFOutputState { + public: + int clipping; + int textRender; + SWFOutputState() { + this->clipping = 0; + this->textRender = 0; + } +}; + class SWFOutputDev: public OutputDev { int outputstarted; struct swfoutput output; @@ -193,6 +203,7 @@ public: //----- text drawing virtual void beginString(GfxState *state, GString *s) ; virtual void endString(GfxState *state) ; + virtual void endTextObject(GfxState *state); virtual void drawChar(GfxState *state, double x, double y, double dx, double dy, double originX, double originY, @@ -206,16 +217,18 @@ public: int width, int height, GfxImageColorMap *colorMap, int *maskColors, GBool inlineImg); - virtual GBool beginType3Char(GfxState *state, - CharCode code, Unicode *u, int uLen); + virtual GBool beginType3Char(GfxState *state, double x, double y, double dx, double dy, CharCode code, Unicode *u, int uLen); virtual void endType3Char(GfxState *state); + virtual void type3D0(GfxState *state, double wx, double wy); + virtual void type3D1(GfxState *state, double wx, double wy, double llx, double lly, double urx, double ury); + private: void drawGeneralImage(GfxState *state, Object *ref, Stream *str, int width, int height, GfxImageColorMap*colorMap, GBool invert, GBool inlineImg, int mask, int *maskColors); - int clipping[64]; - int clippos; + SWFOutputState states[64]; + int statepos; int currentpage; @@ -315,8 +328,7 @@ SWFOutputDev::SWFOutputDev() linkinfo = 0; pbminfo = 0; type3active = 0; - clippos = 0; - clipping[clippos] = 0; + statepos = 0; outputstarted = 0; xref = 0; substitutepos = 0; @@ -575,6 +587,21 @@ static void dumpFontInfo(char*loglevel, GfxFont*font) //void SWFOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str, int width, int height, GBool invert, GBool inlineImg) {printf("void SWFOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str, int width, int height, GBool invert, GBool inlineImg) \n");} //void SWFOutputDev::drawImage(GfxState *state, Object *ref, Stream *str, int width, int height, GfxImageColorMap *colorMap, GBool inlineImg) {printf("void SWFOutputDev::drawImage(GfxState *state, Object *ref, Stream *str, int width, int height, GfxImageColorMap *colorMap, GBool inlineImg) \n");} + +void dump_outline(gfxline_t*line) +{ + while(line) { + if(line->type == gfx_moveTo) { + msg(" | moveTo %.2f %.2f", line->x,line->y); + } else if(line->type == gfx_lineTo) { + msg(" | lineTo %.2f %.2f", line->x,line->y); + } else if(line->type == gfx_splineTo) { + msg(" | splineTo (%.2f %.2f) %.2f %.2f", line->sx,line->sy, line->x, line->y); + } + line = line->next; + } +} + gfxline_t* gfxPath_to_gfxline(GfxState*state, GfxPath*path, int closed) { int num = path->getNumSubpaths(); @@ -631,22 +658,8 @@ gfxline_t* gfxPath_to_gfxline(GfxState*state, GfxPath*path, int closed) if(closed && needsfix && (fabs(posx-lastx)+fabs(posy-lasty))>0.001) { draw.lineTo(&draw, lastx, lasty); } - return (gfxline_t*)draw.result(&draw); -} - - -void dump_outline(gfxline_t*line) -{ - while(line) { - if(line->type == gfx_moveTo) { - msg(" | moveTo %.2f %.2f", line->x,line->y); - } else if(line->type == gfx_lineTo) { - msg(" | lineTo %.2f %.2f", line->x,line->y); - } else if(line->type == gfx_splineTo) { - msg(" | splineTo (%.2f %.2f) %.2f %.2f", line->sx,line->sy, line->x, line->y); - } - line = line->next; - } + gfxline_t*result = (gfxline_t*)draw.result(&draw); + return result; } /*---------------------------------------------------------------------------- @@ -663,13 +676,16 @@ void SWFOutputDev::stroke(GfxState *state) GfxRGB rgb; double opaq = state->getStrokeOpacity(); - state->getStrokeRGB(&rgb); + if(type3active) + state->getFillRGB(&rgb); + else + state->getStrokeRGB(&rgb); gfxcolor_t col; col.r = (unsigned char)(rgb.r*255); col.g = (unsigned char)(rgb.g*255); col.b = (unsigned char)(rgb.b*255); col.a = (unsigned char)(opaq*255); - + gfx_capType capType = gfx_capRound; if(lineCap == 0) capType = gfx_capButt; else if(lineCap == 1) capType = gfx_capRound; @@ -710,11 +726,15 @@ void SWFOutputDev::stroke(GfxState *state) } if(getLogLevel() >= LOGLEVEL_TRACE) { - msg(" stroke width=%f join=%s cap=%s dashes=%d\n", + double gray; + state->getStrokeGray(&gray); + msg(" stroke width=%f join=%s cap=%s dashes=%d color=%02x%02x%02x%02x gray=%f\n", width, lineJoin==0?"miter": (lineJoin==1?"round":"bevel"), lineCap==0?"butt": (lineJoin==1?"round":"square"), - dashnum + dashnum, + col.r,col.g,col.b,col.a, + gray ); dump_outline(line); } @@ -777,7 +797,7 @@ void SWFOutputDev::clip(GfxState *state) } swfoutput_startclip(&output, line); - clipping[clippos] ++; + states[statepos].clipping++; gfxline_free(line); } void SWFOutputDev::eoClip(GfxState *state) @@ -791,7 +811,7 @@ void SWFOutputDev::eoClip(GfxState *state) } swfoutput_startclip(&output, line); - clipping[clippos] ++; + states[statepos].clipping++; gfxline_free(line); } @@ -833,24 +853,41 @@ GBool SWFOutputDev::useGradients() return gTrue; } +char*renderModeDesc[]= {"fill", "stroke", "fill+stroke", "invisible", + "clip+fill", "stroke+clip", "fill+stroke+clip", "clip"}; + void SWFOutputDev::beginString(GfxState *state, GString *s) { + int render = state->getRender(); + msg(" beginString(%s) render=%d", s->getCString(), render); double m11,m21,m12,m22; // msg(" %s beginstring \"%s\"\n", gfxstate2str(state), s->getCString()); state->getFontTransMat(&m11, &m12, &m21, &m22); m11 *= state->getHorizScaling(); m21 *= state->getHorizScaling(); swfoutput_setfontmatrix(&output, m11, -m21, m12, -m22); + if(render != 3 && render != 0) + msg(" Text rendering mode %d (%s) not fully supported yet (for text \"%s\")", render, renderModeDesc[render&7], s->getCString()); + states[statepos].textRender = render; } +static int textCount = 0; + void SWFOutputDev::drawChar(GfxState *state, double x, double y, double dx, double dy, double originX, double originY, CharCode c, Unicode *_u, int uLen) { + textCount++; + + int render = state->getRender(); // check for invisible text -- this is used by Acrobat Capture - if ((state->getRender() & 3) == 3) + if (render == 3) return; + + if(states[statepos].textRender != render) + msg(" Internal error: drawChar.render!=beginString.render"); + GfxRGB rgb; double opaq = state->getFillOpacity(); state->getFillRGB(&rgb); @@ -865,6 +902,7 @@ void SWFOutputDev::drawChar(GfxState *state, double x, double y, if(font->getType() == fontType3) { /* type 3 chars are passed as graphics */ + msg(" type3 char at %f/%f", x, y); return; } double x1,y1; @@ -906,28 +944,51 @@ void SWFOutputDev::drawChar(GfxState *state, double x, double y, } if (CIDToGIDMap) { - msg(" drawChar(%f, %f, c='%c' (%d), GID=%d, u=%d <%d>) CID=%d name=\"%s\"\n", x, y, (c&127)>=32?c:'?', c, CIDToGIDMap[c], u, uLen, font->isCIDFont(), FIXNULL(name)); + msg(" drawChar(%f, %f, c='%c' (%d), GID=%d, u=%d <%d>) CID=%d name=\"%s\" render=%d\n", x, y, (c&127)>=32?c:'?', c, CIDToGIDMap[c], u, uLen, font->isCIDFont(), FIXNULL(name), render); swfoutput_drawchar(&output, x1, y1, name, CIDToGIDMap[c], u, &col); } else { - msg(" drawChar(%f,%f,c='%c' (%d), u=%d <%d>) CID=%d name=\"%s\"\n",x,y,(c&127)>=32?c:'?',c,u, uLen, font->isCIDFont(), FIXNULL(name)); + msg(" drawChar(%f,%f,c='%c' (%d), u=%d <%d>) CID=%d name=\"%s\" render=%d\n",x,y,(c&127)>=32?c:'?',c,u, uLen, font->isCIDFont(), FIXNULL(name), render); swfoutput_drawchar(&output, x1, y1, name, c, u, &col); } } -void SWFOutputDev::endString(GfxState *state) { +void SWFOutputDev::endString(GfxState *state) +{ + msg(" endString()"); } - -GBool SWFOutputDev::beginType3Char(GfxState *state, - CharCode code, Unicode *u, int uLen) +void SWFOutputDev::endTextObject(GfxState *state) +{ + msg(" endTextObject()"); +} + +/* the logic seems to be as following: + first, beginType3Char is called, with the charcode and the coordinates. + if this function returns true, it already knew about the char and has now drawn it. + if the function returns false, it's a new char, and type3D1 is called with some parameters- + the all draw operations until endType3Char are part of the char (which in this moment is + at the position first passed to beginType3Char). the char ends with endType3Char. + + The drawing operations between beginType3Char and endType3Char are somewhat different to + the normal ones. For example, the fillcolor equals the stroke color. +*/ + +GBool SWFOutputDev::beginType3Char(GfxState *state, double x, double y, double dx, double dy, CharCode code, Unicode *u, int uLen) { msg(" beginType3Char %d, %08x, %d", code, *u, uLen); type3active = 1; - /* the character itself is going to be passed using - drawImageMask() */ + /* the character itself is going to be passed using the draw functions */ return gFalse; /* gTrue= is_in_cache? */ } +void SWFOutputDev::type3D0(GfxState *state, double wx, double wy) { + msg(" type3D0 width=%f height=%f", wx, wy); +} +void SWFOutputDev::type3D1(GfxState *state, double wx, double wy, double llx, double lly, double urx, double ury) { + msg(" type3D1 width=%f height=%f bbox=(%f,%f,%f,%f)", wx, wy, + llx,lly,urx,ury); +} + void SWFOutputDev::endType3Char(GfxState *state) { type3active = 0; @@ -1128,23 +1189,25 @@ void SWFOutputDev::drawLink(Link *link, Catalog *catalog) } void SWFOutputDev::saveState(GfxState *state) { - msg(" saveState\n"); + msg(" saveState\n"); updateAll(state); - if(clippos<64) - clippos ++; - else + if(statepos>=64) { msg(" Too many nested states in pdf."); - clipping[clippos] = 0; + return; + } + statepos ++; + states[statepos].clipping = 0; //? shouldn't this be the current value? + states[statepos].textRender = states[statepos-1].textRender; }; void SWFOutputDev::restoreState(GfxState *state) { - msg(" restoreState\n"); + msg(" restoreState\n"); updateAll(state); - while(clipping[clippos]) { + while(states[statepos].clipping) { swfoutput_endclip(&output); - clipping[clippos]--; + states[statepos].clipping--; } - clippos--; + statepos--; } char* SWFOutputDev::searchFont(char*name) @@ -1212,7 +1275,6 @@ void SWFOutputDev::updateStrokeColor(GfxState *state) GfxRGB rgb; double opaq = state->getStrokeOpacity(); state->getStrokeRGB(&rgb); - //swfoutput_setstrokecolor(&output, (char)(rgb.r*255), (char)(rgb.g*255), (char)(rgb.b*255), (char)(opaq*255)); } @@ -1254,8 +1316,7 @@ char*SWFOutputDev::writeEmbeddedFontToFile(XRef*ref, GfxFont*font) msg(" Collection: %s", c.getCString()); }*/ - if (font->getType() == fontType1C || - font->getType() == fontCIDType0C) { + if (font->getType() == fontType1C) { if (!(fontBuf = font->readEmbFontFile(xref, &fontLen))) { fclose(f); msg(" Couldn't read embedded font file"); @@ -1845,6 +1906,8 @@ void SWFOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str, int width, int height, GBool invert, GBool inlineImg) { + if(states[statepos].textRender & 4) //clipped + return; msg(" drawImageMask %dx%d, invert=%d inline=%d", width, height, invert, inlineImg); drawGeneralImage(state,ref,str,width,height,0,invert,inlineImg,1, 0); } @@ -1853,6 +1916,9 @@ void SWFOutputDev::drawImage(GfxState *state, Object *ref, Stream *str, int width, int height, GfxImageColorMap *colorMap, int *maskColors, GBool inlineImg) { + if(states[statepos].textRender & 4) //clipped + return; + msg(" drawImage %dx%d, %s %s, inline=%d", width, height, colorMap?"colorMap":"no colorMap", maskColors?"maskColors":"no maskColors",