X-Git-Url: http://git.asbjorn.it/?a=blobdiff_plain;f=pdf2swf%2FSWFOutputDev.cc;h=fd753d5515bc490eb406ce07cf3bdbe4b4da4040;hb=4d69b67e4c0234d1be6e84acb68f00ff0a9f869f;hp=f92e95c00f6b9c1907fb1a1a1f898a65804a1d39;hpb=425116762bb167de8d1d391228fcac5e5dfa19ad;p=swftools.git diff --git a/pdf2swf/SWFOutputDev.cc b/pdf2swf/SWFOutputDev.cc index f92e95c..fd753d5 100644 --- a/pdf2swf/SWFOutputDev.cc +++ b/pdf2swf/SWFOutputDev.cc @@ -90,7 +90,7 @@ static int pagepos = 0; /* config */ static double caplinewidth = 3.0; static int zoom = 72; /* xpdf: 86 */ -static int forceType0Fonts = 0; +static int forceType0Fonts = 1; static void printInfoString(Dict *infoDict, char *key, char *fmt); static void printInfoDate(Dict *infoDict, char *key, char *fmt); @@ -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, @@ -216,8 +227,8 @@ public: 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; @@ -292,7 +303,7 @@ class InfoOutputDev: public OutputDev GfxFont*font = state->getFont(); if(!font) return; - char*id = getFontID(font); + /*char*id = getFontID(font);*/ /* FIXME*/ num_fonts++; } @@ -317,8 +328,7 @@ SWFOutputDev::SWFOutputDev() linkinfo = 0; pbminfo = 0; type3active = 0; - clippos = 0; - clipping[clippos] = 0; + statepos = 0; outputstarted = 0; xref = 0; substitutepos = 0; @@ -517,13 +527,14 @@ static void showFontError(GfxFont*font, int nr) static void dumpFontInfo(char*loglevel, GfxFont*font) { - char* name = getFontID(font); + char* id = getFontID(font); + char* name = getFontName(font); Ref* r=font->getID(); - msg("%s=========== %s (ID:%d,%d) ==========\n", loglevel, getFontName(font), r->num,r->gen); + msg("%s=========== %s (ID:%d,%d) ==========\n", loglevel, name, r->num,r->gen); GString*gstr = font->getTag(); - msg("%s| Tag: %s\n", loglevel, name); + msg("%s| Tag: %s\n", loglevel, id); if(font->isCIDFont()) msg("%s| is CID font\n", loglevel); @@ -557,10 +568,12 @@ static void dumpFontInfo(char*loglevel, GfxFont*font) Ref embRef; GBool embedded = font->getEmbeddedFontID(&embRef); - if(font->getEmbeddedFontName()) - name = font->getEmbeddedFontName()->getCString(); + char*embeddedName=0; + if(font->getEmbeddedFontName()) { + embeddedName = font->getEmbeddedFontName()->getCString(); + } if(embedded) - msg("%s| Embedded name: %s id: %d\n",loglevel, FIXNULL(name), embRef.num); + msg("%s| Embedded id: %s id: %d\n",loglevel, FIXNULL(embeddedName), embRef.num); gstr = font->getExtFontFile(); if(gstr) @@ -572,6 +585,9 @@ static void dumpFontInfo(char*loglevel, GfxFont*font) if(font->isSymbolic()) msg("%s| is symbolic\n", loglevel); if(font->isItalic()) msg("%s| is italic\n", loglevel); if(font->isBold()) msg("%s| is bold\n", loglevel); + + free(id); + free(name); } //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");} @@ -787,7 +803,7 @@ void SWFOutputDev::clip(GfxState *state) } swfoutput_startclip(&output, line); - clipping[clippos] ++; + states[statepos].clipping++; gfxline_free(line); } void SWFOutputDev::eoClip(GfxState *state) @@ -801,7 +817,7 @@ void SWFOutputDev::eoClip(GfxState *state) } swfoutput_startclip(&output, line); - clipping[clippos] ++; + states[statepos].clipping++; gfxline_free(line); } @@ -843,24 +859,67 @@ GBool SWFOutputDev::useGradients() return gTrue; } +char*renderModeDesc[]= {"fill", "stroke", "fill+stroke", "invisible", + "clip+fill", "stroke+clip", "fill+stroke+clip", "clip"}; + +static char tmp_printstr[4096]; +char* makeStringPrintable(char*str) +{ + int len = strlen(str); + int dots = 0; + if(len>=80) { + len = 80; + dots = 1; + } + int t; + for(t=0;t124) { + c = '.'; + } + tmp_printstr[t] = c; + } + if(dots) { + tmp_printstr[len++] = '.'; + tmp_printstr[len++] = '.'; + tmp_printstr[len++] = '.'; + } + tmp_printstr[len] = 0; + return tmp_printstr; +} + 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], makeStringPrintable(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); @@ -875,6 +934,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; @@ -904,9 +964,8 @@ void SWFOutputDev::drawChar(GfxState *state, double x, double y, if(font->isCIDFont()) { GfxCIDFont*cfont = (GfxCIDFont*)font; - if(font->getType() == fontCIDType2) { + if(font->getType() == fontCIDType2) CIDToGIDMap = cfont->getCIDToGID(); - } } else { Gfx8BitFont*font8; font8 = (Gfx8BitFont*)font; @@ -916,17 +975,24 @@ 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()"); } +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. @@ -1154,23 +1220,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) @@ -1375,7 +1443,7 @@ char* searchForSuitableFont(GfxFont*gfxFont) if (!fcinitcalled) { msg(" Initializing FontConfig..."); fcinitcalled = true; - if(FcInit()) { + if(!FcInit()) { msg(" FontConfig Initialization failed. Disabling."); config_use_fontconfig = 0; return 0; @@ -1403,7 +1471,7 @@ char* searchForSuitableFont(GfxFont*gfxFont) // if we get an exact match if (strcmp((char *)v, name) == 0) { if (FcPatternGetString(match, "file", 0, &v) == FcResultMatch) { - filename = strdup((char*)v); + filename = strdup((char*)v); // mem leak char *nfn = strrchr(filename, '/'); if(nfn) fontname = strdup(nfn+1); else fontname = filename; @@ -1444,7 +1512,7 @@ char* searchForSuitableFont(GfxFont*gfxFont) match = FcFontMatch (0, pattern, &result); if (FcPatternGetString(match, "file", 0, &v) == FcResultMatch) { - filename = strdup((char*)v); + filename = strdup((char*)v); // mem leak char *nfn = strrchr(filename, '/'); if(nfn) fontname = strdup(nfn+1); else fontname = filename; @@ -1478,7 +1546,7 @@ char* SWFOutputDev::substituteFont(GfxFont*gfxFont, char* oldname) } filename = searchFont(fontname); if(!filename) { - msg(" Couldn't find font %s- did you install the default fonts?"); + msg(" Couldn't find font %s- did you install the default fonts?", fontname); return 0; } @@ -1487,12 +1555,12 @@ char* SWFOutputDev::substituteFont(GfxFont*gfxFont, char* oldname) exit(1); } if(oldname) { - substitutesource[substitutepos] = oldname; + substitutesource[substitutepos] = strdup(oldname); //mem leak substitutetarget[substitutepos] = fontname; msg(" substituting %s -> %s", FIXNULL(oldname), FIXNULL(fontname)); substitutepos ++; } - return strdup(filename); + return strdup(filename); //mem leak } void unlinkfont(char* filename) @@ -1546,7 +1614,8 @@ void SWFOutputDev::updateFont(GfxState *state) too often */ for(t=0;t updateFont(%s) [cached]", fontid); + free(fontid); return; } @@ -1567,6 +1637,7 @@ void SWFOutputDev::updateFont(GfxState *state) type3Warning = gTrue; showFontError(gfxFont, 2); } + free(fontid); return; } @@ -1598,12 +1669,13 @@ void SWFOutputDev::updateFont(GfxState *state) msg(" Font %s %scould not be loaded.", fontname, embedded?"":"(not embedded) "); msg(" Try putting a TTF version of that font (named \"%s.ttf\") into /swftools/fonts", fontname); fileName = substituteFont(gfxFont, fontid); - if(fontid) { fontid = substitutetarget[substitutepos-1]; /*ugly hack*/}; + if(fontid) { free(fontid);fontid = strdup(substitutetarget[substitutepos-1]); /*ugly hack*/}; msg(" Font is now %s (%s)", fontid, fileName); } if(!fileName) { msg(" Couldn't set font %s\n", fontid); + free(fontid); return; } @@ -1616,6 +1688,7 @@ void SWFOutputDev::updateFont(GfxState *state) unlinkfont(fileName); if(fileName) free(fileName); + free(fontid); } #define SQR(x) ((x)*(x)) @@ -1869,6 +1942,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); } @@ -1877,6 +1952,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",