From 9aa850fb4c4b28c64d53e144b4a107d982917b2e Mon Sep 17 00:00:00 2001 From: kramm Date: Sat, 24 Jul 2004 18:21:20 +0000 Subject: [PATCH] * removed t1lib and ttf2pt1 references * changed code to use only SWFFONT * simplified font handling --- pdf2swf/SWFOutputDev.cc | 554 +++++++++++++++---------------------------- pdf2swf/SWFOutputDev.h | 1 + pdf2swf/pdf2swf.cc | 113 ++------- pdf2swf/swfoutput.cc | 606 +++++++++++------------------------------------ pdf2swf/swfoutput.h | 94 ++++---- 5 files changed, 400 insertions(+), 968 deletions(-) diff --git a/pdf2swf/SWFOutputDev.cc b/pdf2swf/SWFOutputDev.cc index defd24e..6dafd03 100644 --- a/pdf2swf/SWFOutputDev.cc +++ b/pdf2swf/SWFOutputDev.cc @@ -48,25 +48,27 @@ #include "swfoutput.h" #include "../lib/log.h" -#include "ttf2pt1.h" #include static PDFDoc*doc = 0; static char* swffilename = 0; -int numpages; -int currentpage; +static int numpages; +static int currentpage; + +static char*fonts[2048]; +static int fontnum = 0; // swf <-> pdf pages -int*pages = 0; -int pagebuflen = 0; -int pagepos = 0; +static int*pages = 0; +static int pagebuflen = 0; +static int pagepos = 0; -double caplinewidth = 3.0; +static double caplinewidth = 3.0; static void printInfoString(Dict *infoDict, char *key, char *fmt); static void printInfoDate(Dict *infoDict, char *key, char *fmt); -double fontsizes[] = +static double fontsizes[] = { 0.833,0.833,0.889,0.889, 0.788,0.722,0.833,0.778, @@ -74,7 +76,7 @@ double fontsizes[] = 0.576,0.576,0.576,0.576, 0.733 //? }; -char*fontnames[]={ +static char*fontnames[]={ "Helvetica", "Helvetica-Bold", "Helvetica-BoldOblique", @@ -99,20 +101,20 @@ struct mapping { char*filename; int id; } pdf2t1map[] ={ -{"Times-Roman", "n021003l.pfb"}, -{"Times-Italic", "n021023l.pfb"}, -{"Times-Bold", "n021004l.pfb"}, -{"Times-BoldItalic", "n021024l.pfb"}, -{"Helvetica", "n019003l.pfb"}, -{"Helvetica-Oblique", "n019023l.pfb"}, -{"Helvetica-Bold", "n019004l.pfb"}, -{"Helvetica-BoldOblique", "n019024l.pfb"}, -{"Courier", "n022003l.pfb"}, -{"Courier-Oblique", "n022023l.pfb"}, -{"Courier-Bold", "n022004l.pfb"}, -{"Courier-BoldOblique", "n022024l.pfb"}, -{"Symbol", "s050000l.pfb"}, -{"ZapfDingbats", "d050000l.pfb"}}; +{"Times-Roman", "n021003l"}, +{"Times-Italic", "n021023l"}, +{"Times-Bold", "n021004l"}, +{"Times-BoldItalic", "n021024l"}, +{"Helvetica", "n019003l"}, +{"Helvetica-Oblique", "n019023l"}, +{"Helvetica-Bold", "n019004l"}, +{"Helvetica-BoldOblique", "n019024l"}, +{"Courier", "n022003l"}, +{"Courier-Oblique", "n022023l"}, +{"Courier-Bold", "n022004l"}, +{"Courier-BoldOblique", "n022024l"}, +{"Symbol", "s050000l"}, +{"ZapfDingbats", "d050000l"}}; class GfxState; class GfxImageColorMap; @@ -210,7 +212,7 @@ public: XRef*xref; - int searchT1Font(char*name); + char* searchFont(char*name); char* substituteFont(GfxFont*gfxFont, char*oldname); char* writeEmbeddedFontToFile(XRef*ref, GfxFont*font); int t1id; @@ -452,7 +454,7 @@ SWFOutputDev::SWFOutputDev() // printf("SWFOutputDev::SWFOutputDev() \n"); }; -T1_OUTLINE* gfxPath_to_T1_OUTLINE(GfxState*state, GfxPath*path) +SWF_OUTLINE* gfxPath_to_SWF_OUTLINE(GfxState*state, GfxPath*path) { int num = path->getNumSubpaths(); int s,t; @@ -462,11 +464,11 @@ T1_OUTLINE* gfxPath_to_T1_OUTLINE(GfxState*state, GfxPath*path) double lastx=0,lasty=0; if(!num) { msg(" empty path"); - outline->type = T1_PATHTYPE_MOVE; + outline->type = SWF_PATHTYPE_MOVE; outline->dest.x = 0; outline->dest.y = 0; outline->link = 0; - return (T1_OUTLINE*)outline; + return (SWF_OUTLINE*)outline; } for(t = 0; t < num; t++) { GfxSubpath *subpath = path->getSubpath(t); @@ -480,10 +482,10 @@ T1_OUTLINE* gfxPath_to_T1_OUTLINE(GfxState*state, GfxPath*path) if(s==0) { last = outline; - outline->type = T1_PATHTYPE_MOVE; + outline->type = SWF_PATHTYPE_MOVE; outline->dest.x = x; outline->dest.y = y; - outline->link = (T1_OUTLINE*)new bezierpathsegment(); + outline->link = (SWF_OUTLINE*)new bezierpathsegment(); outline = (bezierpathsegment*)outline->link; cpos = 0; lastx = nx; @@ -506,9 +508,9 @@ T1_OUTLINE* gfxPath_to_T1_OUTLINE(GfxState*state, GfxPath*path) last = outline; outline->dest.x = x; outline->dest.y = y; - outline->type = cpos?T1_PATHTYPE_BEZIER:T1_PATHTYPE_LINE; + outline->type = cpos?SWF_PATHTYPE_BEZIER:SWF_PATHTYPE_LINE; outline->link = 0; - outline->link = (T1_OUTLINE*)new bezierpathsegment(); + outline->link = (SWF_OUTLINE*)new bezierpathsegment(); outline = (bezierpathsegment*)outline->link; cpos = 0; lastx = nx; @@ -517,7 +519,7 @@ T1_OUTLINE* gfxPath_to_T1_OUTLINE(GfxState*state, GfxPath*path) } } last->link = 0; - return (T1_OUTLINE*)start; + return (SWF_OUTLINE*)start; } /*---------------------------------------------------------------------------- * Primitive Graphic routines @@ -538,7 +540,7 @@ void SWFOutputDev::stroke(GfxState *state) m.m11 = 1; m.m21 = 0; m.m22 = 1; m.m12 = 0; m.m13 = 0; m.m23 = 0; - T1_OUTLINE*outline = gfxPath_to_T1_OUTLINE(state, path); + SWF_OUTLINE*outline = gfxPath_to_SWF_OUTLINE(state, path); lineJoin = 1; // other line joins are not yet supported by the swf encoder // TODO: support bevel joints @@ -569,7 +571,7 @@ void SWFOutputDev::fill(GfxState *state) struct swfmatrix m; m.m11 = 1; m.m21 = 0; m.m22 = 1; m.m12 = 0; m.m13 = 0; m.m23 = 0; - T1_OUTLINE*outline = gfxPath_to_T1_OUTLINE(state, path); + SWF_OUTLINE*outline = gfxPath_to_SWF_OUTLINE(state, path); swfoutput_setdrawmode(&output, DRAWMODE_FILL); swfoutput_drawpath(&output, outline, &m); } @@ -580,7 +582,7 @@ void SWFOutputDev::eoFill(GfxState *state) struct swfmatrix m; m.m11 = 1; m.m21 = 0; m.m22 = 1; m.m12 = 0; m.m13 = 0; m.m23 = 0; - T1_OUTLINE*outline = gfxPath_to_T1_OUTLINE(state, path); + SWF_OUTLINE*outline = gfxPath_to_SWF_OUTLINE(state, path); swfoutput_setdrawmode(&output, DRAWMODE_EOFILL); swfoutput_drawpath(&output, outline, &m); } @@ -592,7 +594,7 @@ void SWFOutputDev::clip(GfxState *state) m.m11 = 1; m.m22 = 1; m.m12 = 0; m.m21 = 0; m.m13 = 0; m.m23 = 0; - T1_OUTLINE*outline = gfxPath_to_T1_OUTLINE(state, path); + SWF_OUTLINE*outline = gfxPath_to_SWF_OUTLINE(state, path); swfoutput_startclip(&output, outline, &m); clipping[clippos] ++; } @@ -603,7 +605,7 @@ void SWFOutputDev::eoClip(GfxState *state) struct swfmatrix m; m.m11 = 1; m.m21 = 0; m.m22 = 1; m.m12 = 0; m.m13 = 0; m.m23 = 0; - T1_OUTLINE*outline = gfxPath_to_T1_OUTLINE(state, path); + SWF_OUTLINE*outline = gfxPath_to_SWF_OUTLINE(state, path); swfoutput_startclip(&output, outline, &m); clipping[clippos] ++; } @@ -659,7 +661,7 @@ void SWFOutputDev::drawChar(GfxState *state, double x, double y, if(_u) u = *_u; - msg(" drawChar(%f,%f,%f,%f,'%c',%d) CID=%d\n",x,y,dx,dy,c,u, font->isCIDFont()); + msg(" drawChar(%f,%f,%f,%f,c='%c' (%d),u=%d) CID=%d\n",x,y,dx,dy,c,c,u, font->isCIDFont()); if(font->isCIDFont()) { GfxCIDFont*cfont = (GfxCIDFont*)font; @@ -677,8 +679,7 @@ void SWFOutputDev::drawChar(GfxState *state, double x, double y, if(name) swfoutput_drawchar(&output, x1, y1, name, c, u); else { - msg(" couldn't get name for CID character %02x from Encoding", c); - swfoutput_drawchar(&output, x1, y1, "", c, u); + swfoutput_drawchar(&output, x1, y1, 0, c, u); } } else { Gfx8BitFont*font8; @@ -688,8 +689,7 @@ void SWFOutputDev::drawChar(GfxState *state, double x, double y, if(enc && enc[c]) swfoutput_drawchar(&output, x1, y1, enc[c], c, u); else { - msg(" couldn't get name for character %02x from Encoding", c); - swfoutput_drawchar(&output, x1, y1, "", c, u); + swfoutput_drawchar(&output, x1, y1, 0, c, u); } } } @@ -912,58 +912,31 @@ void SWFOutputDev::restoreState(GfxState *state) { char type3Warning=0; -int SWFOutputDev::searchT1Font(char*name) +char* SWFOutputDev::searchFont(char*name) { int i; - int mapid=-1; char*filename=0; msg(" SearchT1Font(%s)", name); + /* see if it is a pdf standard font */ for(i=0;i Loading extra font %s from %s\n", FIXNULL(fontname), - FIXNULL(T1_GetFontFileName(i))); - } - - if(fontname && !strcmp(name, fontname)) { - msg(" Extra font %d, \"%s\" is being used.\n", i, fontname); - return i; - } - fontname = T1_GetFontFileName(i); - if(strrchr(fontname,'/')) - fontname = strrchr(fontname,'/')+1; - - if(strstr(fontname, name)) { - msg(" Extra font %d, \"%s\" is being used.\n", i, fontname); - return i; - } + return fonts[i]; } } - return -1; + return 0; } void SWFOutputDev::updateLineWidth(GfxState *state) @@ -1004,112 +977,87 @@ void SWFOutputDev::updateStrokeColor(GfxState *state) char*SWFOutputDev::writeEmbeddedFontToFile(XRef*ref, GfxFont*font) { - char*tmpFileName = NULL; - FILE *f; - int c; - char *fontBuf; - int fontLen; - Ref embRef; - Object refObj, strObj; - char namebuf[512]; - tmpFileName = mktmpname(namebuf); - int ret; - - ret = font->getEmbeddedFontID(&embRef); - if(!ret) { - msg(" Didn't get embedded font id"); - /* not embedded- the caller should now search the font - directories for this font */ - return 0; - } + char*tmpFileName = NULL; + FILE *f; + int c; + char *fontBuf; + int fontLen; + Ref embRef; + Object refObj, strObj; + char namebuf[512]; + tmpFileName = mktmpname(namebuf); + int ret; + + ret = font->getEmbeddedFontID(&embRef); + if(!ret) { + msg(" Didn't get embedded font id"); + /* not embedded- the caller should now search the font + directories for this font */ + return 0; + } - f = fopen(tmpFileName, "wb"); - if (!f) { - msg(" Couldn't create temporary Type 1 font file"); - return 0; + f = fopen(tmpFileName, "wb"); + if (!f) { + msg(" Couldn't create temporary Type 1 font file"); + return 0; + } + if (font->getType() == fontType1C || + font->getType() == fontCIDType0C) { + if (!(fontBuf = font->readEmbFontFile(xref, &fontLen))) { + fclose(f); + msg(" Couldn't read embedded font file"); + return 0; } - if (font->getType() == fontType1C || - font->getType() == fontCIDType0C) { - if (!(fontBuf = font->readEmbFontFile(xref, &fontLen))) { - fclose(f); - msg(" Couldn't read embedded font file"); - return 0; - } - Type1CFontFile *cvt = new Type1CFontFile(fontBuf, fontLen); - cvt->convertToType1(f); - delete cvt; - gfree(fontBuf); - } else if(font->getType() == fontTrueType) { - msg(" writing font using TrueTypeFontFile::writeTTF"); - if (!(fontBuf = font->readEmbFontFile(xref, &fontLen))) { - fclose(f); - msg(" Couldn't read embedded font file"); - return 0; - } - TrueTypeFontFile *cvt = new TrueTypeFontFile(fontBuf, fontLen); - cvt->writeTTF(f); - delete cvt; - gfree(fontBuf); - } else { - font->getEmbeddedFontID(&embRef); - refObj.initRef(embRef.num, embRef.gen); - refObj.fetch(ref, &strObj); - refObj.free(); - strObj.streamReset(); - int f4[4]; - char f4c[4]; - int t; - for(t=0;t<4;t++) { - f4[t] = strObj.streamGetChar(); - f4c[t] = (char)f4[t]; - if(f4[t] == EOF) - break; - } - if(t==4) { - if(!strncmp(f4c, "true", 4)) { - /* some weird TTF fonts don't start with 0,1,0,0 but with "true". - Change this on the fly */ - f4[0] = f4[2] = f4[3] = 0; - f4[1] = 1; - } - fputc(f4[0], f); - fputc(f4[1], f); - fputc(f4[2], f); - fputc(f4[3], f); - - while ((c = strObj.streamGetChar()) != EOF) { - fputc(c, f); - } - } - strObj.streamClose(); - strObj.free(); + Type1CFontFile *cvt = new Type1CFontFile(fontBuf, fontLen); + cvt->convertToType1(f); + delete cvt; + gfree(fontBuf); + } else if(font->getType() == fontTrueType) { + msg(" writing font using TrueTypeFontFile::writeTTF"); + if (!(fontBuf = font->readEmbFontFile(xref, &fontLen))) { + fclose(f); + msg(" Couldn't read embedded font file"); + return 0; } - fclose(f); + TrueTypeFontFile *cvt = new TrueTypeFontFile(fontBuf, fontLen); + cvt->writeTTF(f); + delete cvt; + gfree(fontBuf); + } else { + font->getEmbeddedFontID(&embRef); + refObj.initRef(embRef.num, embRef.gen); + refObj.fetch(ref, &strObj); + refObj.free(); + strObj.streamReset(); + int f4[4]; + char f4c[4]; + int t; + for(t=0;t<4;t++) { + f4[t] = strObj.streamGetChar(); + f4c[t] = (char)f4[t]; + if(f4[t] == EOF) + break; + } + if(t==4) { + if(!strncmp(f4c, "true", 4)) { + /* some weird TTF fonts don't start with 0,1,0,0 but with "true". + Change this on the fly */ + f4[0] = f4[2] = f4[3] = 0; + f4[1] = 1; + } + fputc(f4[0], f); + fputc(f4[1], f); + fputc(f4[2], f); + fputc(f4[3], f); - if(font->getType() == fontTrueType || - font->getType() == fontCIDType2) - { - if(!ttfinfo) { - msg(" File contains TrueType fonts"); - ttfinfo = 1; + while ((c = strObj.streamGetChar()) != EOF) { + fputc(c, f); } - char name2[512]; - char*tmp; - tmp = strdup(mktmpname((char*)name2)); - sprintf(name2, "%s", tmp); - char*a[] = {"./ttf2pt1", "-W", "0", -#ifndef USE_FREETYPE - "-p", "ttf", -#else - "-p", "ft", -#endif - "-b", tmpFileName, name2}; - msg(" Invoking %s %s %s %s %s %s %s %s",a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7]); - ttf2pt1_main(8,a); - unlink(tmpFileName); - sprintf(name2,"%s.pfb",tmp); - tmpFileName = strdup(name2); } + strObj.streamClose(); + strObj.free(); + } + fclose(f); return strdup(tmpFileName); } @@ -1121,11 +1069,9 @@ int substitutepos = 0; char* SWFOutputDev::substituteFont(GfxFont*gfxFont, char* oldname) { -/* ------------------------------ V1 */ - char*fontname = "Times-Roman"; msg(" substituteFont(,%s)", FIXNULL(oldname)); - this->t1id = searchT1Font(fontname); + char*filename = searchFont(fontname); if(substitutepos>=sizeof(substitutesource)/sizeof(char*)) { msg(" Too many fonts in file."); exit(1); @@ -1136,95 +1082,7 @@ char* SWFOutputDev::substituteFont(GfxFont*gfxFont, char* oldname) msg(" substituting %s -> %s", FIXNULL(oldname), FIXNULL(fontname)); substitutepos ++; } - return fontname; - -/* ------------------------------ V2 */ - -/* //substitute font - char* fontname = 0; - double m11, m12, m21, m22; - int index; - int code; - double w,w1,w2; - double*fm; - double v; - if(gfxFont->getName()) { - fontname = gfxFont->getName()->getCString(); - } - -// printf("%d %s\n", t, gfxFont->getCharName(t)); - showFontError(gfxFont, 1); - if(1) { //if (!gfxFont->isCIDFont()) { FIXME: xpdf 1.01 does not have is16Bit() - if(gfxFont->isSymbolic()) { - if(fontname && (strstr(fontname,"ing"))) //Dingbats, Wingdings etc. - index = 16; - else - index = 12; - } else if (gfxFont->isFixedWidth()) { - index = 8; - } else if (gfxFont->isSerif()) { - index = 4; - } else { - index = 0; - } - if (gfxFont->isBold() && index!=16) - index += 2; - if (gfxFont->isItalic() && index!=16) - index += 1; - fontname = fontnames[index]; - // get width of 'm' in real font and substituted font - if ((code = gfxFont->getCharCode("m")) >= 0) - w1 = gfxFont->getWidth(code); - else - w1 = 0; - w2 = fontsizes[index]; - if (gfxFont->getType() == fontType3) { - // This is a hack which makes it possible to substitute for some - // Type 3 fonts. The problem is that it's impossible to know what - // the base coordinate system used in the font is without actually - // rendering the font. This code tries to guess by looking at the - // width of the character 'm' (which breaks if the font is a - // subset that doesn't contain 'm'). - if (w1 > 0 && (w1 > 1.1 * w2 || w1 < 0.9 * w2)) { - w1 /= w2; - m11 *= w1; - m12 *= w1; - m21 *= w1; - m22 *= w1; - } - fm = gfxFont->getFontMatrix(); - v = (fm[0] == 0) ? 1 : (fm[3] / fm[0]); - m21 *= v; - m22 *= v; - } else if (!gfxFont->isSymbolic()) { - // if real font is substantially narrower than substituted - // font, reduce the font size accordingly - if (w1 > 0.01 && w1 < 0.9 * w2) { - w1 /= w2; - if (w1 < 0.8) { - w1 = 0.8; - } - m11 *= w1; - m12 *= w1; - m21 *= w1; - m22 *= w1; - } - } - } - if(fontname) { - this->t1id = searchT1Font(fontname); - } - if(substitutepos>=sizeof(substitutesource)/sizeof(char*)) { - msg(" Too many fonts in file."); - exit(1); - } - if(oldname) { - substitutesource[substitutepos] = oldname; - substitutetarget[substitutepos] = fontname; - msg(" substituting %s -> %s", FIXNULL(oldname), FIXNULL(fontname)); - substitutepos ++; - } - return fontname;*/ + return filename; } void unlinkfont(char* filename) @@ -1258,117 +1116,82 @@ void unlinkfont(char* filename) void SWFOutputDev::startDoc(XRef *xref) { - this->xref = xref; + this->xref = xref; } void SWFOutputDev::updateFont(GfxState *state) { - GfxFont*gfxFont = state->getFont(); - char * fileName = 0; + GfxFont*gfxFont = state->getFont(); + + if (!gfxFont) { + return; + } + char * fontname = getFontName(gfxFont); - if (!gfxFont) { - return; - } - char * fontname = getFontName(gfxFont); - - int t; - /* first, look if we substituted this font before- - this way, we don't initialize the T1 Fonts - too often */ - for(t=0;t updateFont(%s) [cached]", fontname); + return; + } - if(swfoutput_queryfont(&output, fontname)) - { - swfoutput_setfont(&output, fontname, -1, 0); - return; - } + // look for Type 3 font + if (!type3Warning && gfxFont->getType() == fontType3) { + type3Warning = gTrue; + showFontError(gfxFont, 2); + } - // look for Type 3 font - if (!type3Warning && gfxFont->getType() == fontType3) { - type3Warning = gTrue; - showFontError(gfxFont, 2); - } + /* now either load the font, or find a substitution */ - /* now either load the font, or find a substitution */ + Ref embRef; + GBool embedded = gfxFont->getEmbeddedFontID(&embRef); - Ref embRef; - GBool embedded = gfxFont->getEmbeddedFontID(&embRef); - if(embedded) { - if (gfxFont->getType() == fontType1 || + char*fileName = 0; + int del = 0; + if(embedded && + (gfxFont->getType() == fontType1 || gfxFont->getType() == fontCIDType0C || gfxFont->getType() == fontType1C || gfxFont->getType() == fontTrueType || gfxFont->getType() == fontCIDType2 - ) + )) { - fileName = writeEmbeddedFontToFile(xref, gfxFont); - if(!fileName) { - msg(" Couldn't write font to file"); - showFontError(gfxFont,0); - return ; - } - this->t1id = T1_AddFont(fileName); - if(this->t1id<0) { - msg(" Couldn't load font from file %s", fileName); - showFontError(gfxFont,0); - unlinkfont(fileName); - return ; - } - } - else { - /* in case the font is embedded, but has an - unsupported format, we just look through the - font directories */ - int newt1id = searchT1Font(fontname); - if(newt1id<0) { - msg(" Couldn't find any suitable replacement for %s",fontname); - showFontError(gfxFont,0); - fontname = substituteFont(gfxFont, fontname); - } else - this->t1id = newt1id; - } - } else { - if(fontname) { - int newt1id = searchT1Font(fontname); - if(newt1id<0) { - showFontError(gfxFont,1); - fontname = substituteFont(gfxFont, fontname); - } else - this->t1id = newt1id; - } - else { - showFontError(gfxFont,1); - fontname = substituteFont(gfxFont, fontname); + fileName = writeEmbeddedFontToFile(xref, gfxFont); + if(!fileName) showFontError(gfxFont,0); + else del = 1; + } else { + fileName = searchFont(fontname); + if(!fileName) showFontError(gfxFont,0); } - } + if(!fileName) + fileName = substituteFont(gfxFont, fontname); - if(t1id<0) { - msg(" Current font's t1id is %d", t1id); - //showFontError(gfxFont,0); - return; - } - - /* we may have done some substitutions here, so check - again if this font is cached. */ - if(swfoutput_queryfont(&output, fontname)) - { - swfoutput_setfont(&output, fontname, -1, 0); - return; - } + if(!fileName) { + msg(" Couldn't set font %s\n", fontname); + return; + } + + msg(" updateFont(%s) -> %s", fontname, fileName); - msg(" Creating new SWF font: t1id: %d, filename: %s name:%s", this->t1id, FIXNULL(fileName), FIXNULL(fontname)); - swfoutput_setfont(&output, fontname, this->t1id, fileName); - if(fileName) - unlinkfont(fileName); + swfoutput_setfont(&output, fontname, fileName); + + if(fileName && del) + unlinkfont(fileName); } int pic_xids[1024]; @@ -1856,6 +1679,11 @@ void pdfswf_setparameter(char*name, char*value) } } +void pdfswf_addfont(char*filename) +{ + fonts[fontnum++] = filename; +} + void pdfswf_drawonlyshapes() { drawonlyshapes = 1; diff --git a/pdf2swf/SWFOutputDev.h b/pdf2swf/SWFOutputDev.h index c090bc4..2348da2 100644 --- a/pdf2swf/SWFOutputDev.h +++ b/pdf2swf/SWFOutputDev.h @@ -24,6 +24,7 @@ void pdfswf_init(char*filename, char*userPassword) ; void pdfswf_setparameter(char*name, char*value); +void pdfswf_addfont(char*filename); void pdfswf_setoutputfilename(char*filename); void pdfswf_drawonlyshapes(); diff --git a/pdf2swf/pdf2swf.cc b/pdf2swf/pdf2swf.cc index 9e49a08..affbdb9 100644 --- a/pdf2swf/pdf2swf.cc +++ b/pdf2swf/pdf2swf.cc @@ -33,7 +33,6 @@ #endif #include "../lib/args.h" #include "SWFOutputDev.h" -#include "t1lib.h" extern "C" { #include "log.h" } @@ -342,13 +341,8 @@ void args_callback_usage(char*name) } #ifdef HAVE_DIRENT_H -void addfontdir(FILE*database, char* dirname, int*numfonts, char*searchpath) +void addfontdir(char* dirname, int*numfonts) { - if(searchpath) { - if(searchpath[0]) - strcat(searchpath, ":"); - strcat(searchpath, dirname); - } if(!numfonts) msg(" Adding %s to search path\n", dirname); @@ -369,36 +363,25 @@ void addfontdir(FILE*database, char* dirname, int*numfonts, char*searchpath) l=strlen(name); if(l<4) continue; - if(!strncasecmp(&name[l-4], ".afm", 4)) + if(!strncasecmp(&name[l-4], ".pfa", 4)) type=1; + if(!strncasecmp(&name[l-4], ".pfb", 4)) + type=3; if(!strncasecmp(&name[l-4], ".ttf", 4)) type=2; if(type) { - if(database && type==1) { - char buf[256],a; - FILE*fi; + char*fontname = (char*)malloc(strlen(dirname)+strlen(name)+2); + strcpy(fontname, dirname); #ifdef WIN32 - sprintf(buf, "%s\\%s", dirname,name); + strcat(fontname, "\\"); #else - sprintf(buf, "%s/%s", dirname,name); -#endif - fi = fopen(buf, "rb"); - if(!fi || !fread(&a,1,1,fi)) { - msg(" Couldn't read from %s", buf); - } - -#ifdef WIN32 -/* might also work for all other systems, but we *need* it for win32 */ - if(!strncmp(buf, FONTDIR, strlen(FONTDIR))) - fprintf(database, "%s\n", buf+strlen(FONTDIR)); - else + strcat(fontname, "/"); #endif - fprintf(database, "%s\n", buf); - - msg(" Found font %s\n", buf); - fclose(fi); - } + strcat(fontname, name); + if(!numfonts) + msg(" Adding %s to fonts", fontname); + pdfswf_addfont(fontname); if(numfonts) (*numfonts)++; } @@ -482,81 +465,20 @@ int main(int argn, char *argv[]) exit(0); } - msg(" reading font files from %s\n", FONTDIR); - //TODO: use tempnam here. Check if environment already contains a - //T1LIB_CONFIG. - char buf1[256],buf2[256],buf3[256]; - char* t1lib_config = mktmpname(buf1); - char* fontdatabase = mktmpname(buf2); - - sprintf(buf3, "T1LIB_CONFIG=%s", t1lib_config); - putenv(buf3); - - FILE*db = fopen(fontdatabase, "wb"); - FILE*fi = fopen(t1lib_config, "wb"); - if(!db || !fi) { - if(!db) fprintf(stderr, "Couldn't create temporary file %s\n",fontdatabase); - if(!fi) fprintf(stderr, "Couldn't create temporary file %s\n",t1lib_config); - exit(1); - } - t1searchpath[0] = 0; #ifdef HAVE_DIRENT_H // pass 1 - addfontdir(0, FONTDIR, &numfonts, 0); + addfontdir(FONTDIR, &numfonts); for(t=0;t Couldn't find any fonts!"); #endif - fclose(fi); - fclose(db); - /* initialize t1lib */ - T1_SetBitmapPad( 16); - if ((T1_InitLib(LOGFILE)==NULL)){ - fprintf(stderr, "Initialization of t1lib failed\n"); - exit(1); - } - unlink(t1lib_config); pdfswf_init(filename, password); pdfswf_setoutputfilename(outputname); @@ -601,7 +523,6 @@ int main(int argn, char *argv[]) systemf("rm __tmp__.swf"); } - unlink(fontdatabase); return 0; } diff --git a/pdf2swf/swfoutput.cc b/pdf2swf/swfoutput.cc index c918b1f..9c66317 100644 --- a/pdf2swf/swfoutput.cc +++ b/pdf2swf/swfoutput.cc @@ -36,8 +36,6 @@ extern "C" { #include "../lib/log.h" #include "../lib/rfxswf.h" } -#define standardEncodingSize 335 -extern char *standardEncodingNames[standardEncodingSize]; int opennewwindow=0; int ignoredraworder=0; @@ -49,6 +47,8 @@ int insertstoptag=0; int flashversion=4; int splinemaxerror=1; int fontsplinemaxerror=1; + +static char storefont = 0; static int flag_protected = 0; typedef unsigned char u8; @@ -68,12 +68,12 @@ static int shapeid = -1; static int textid = -1; static int drawmode = -1; -static char storefont = 0; static int fillstyleid; static int linestyleid; static int swflastx=0; static int swflasty=0; static int lastwasfill = 0; +static int shapeisempty = 1; static char fill = 0; static int sizex; static int sizey; @@ -125,6 +125,7 @@ static void lineto(TAG*tag, plotxy p0) /* we can't skip this for rx=0,ry=0, those are plots */ swf_ShapeSetLine (tag, shape, rx,ry); + shapeisempty = 0; swflastx+=rx; swflasty+=ry; } @@ -142,6 +143,7 @@ static void splineto(TAG*tag, plotxy control,plotxy end) swflasty += ey; if(cx || cy || ex || ey) swf_ShapeSetCurve(tag, shape, cx,cy,ex,ey); + shapeisempty = 0; } /* write a line, given two points and the transformation @@ -211,9 +213,9 @@ static void startFill() } } -/* draw a T1 outline. These are generated by pdf2swf and by t1lib +/* draw an outline. These are generated by pdf2swf and by t1lib (representing characters). */ -void drawpath(TAG*tag, T1_OUTLINE*outline, struct swfmatrix*m, int log) +void drawpath(TAG*tag, SWF_OUTLINE*outline, struct swfmatrix*m, int log) { if(tag->id != ST_DEFINEFONT && tag->id != ST_DEFINESHAPE && @@ -232,7 +234,7 @@ void drawpath(TAG*tag, T1_OUTLINE*outline, struct swfmatrix*m, int log) { x += (outline->dest.x/(float)0xffff); y += (outline->dest.y/(float)0xffff); - if(outline->type == T1_PATHTYPE_MOVE) + if(outline->type == SWF_PATHTYPE_MOVE) { if(((int)(lastx*20) != (int)(firstx*20) || (int)(lasty*20) != (int)(firsty*20)) && @@ -251,7 +253,7 @@ void drawpath(TAG*tag, T1_OUTLINE*outline, struct swfmatrix*m, int log) firsty=y; init = 0; } - else if(outline->type == T1_PATHTYPE_LINE) + else if(outline->type == SWF_PATHTYPE_LINE) { plotxy p0; plotxy p1; @@ -262,13 +264,13 @@ void drawpath(TAG*tag, T1_OUTLINE*outline, struct swfmatrix*m, int log) if(log) printf("line: %f,%f -> %f,%f\n",p0.x,p0.y,p1.x,p1.y); line(tag, p0,p1,m); } - else if(outline->type == T1_PATHTYPE_BEZIER) + else if(outline->type == SWF_PATHTYPE_BEZIER) { plotxy p0; plotxy p1; plotxy p2; plotxy p3; - T1_BEZIERSEGMENT*o2 = (T1_BEZIERSEGMENT*)outline; + SWF_BEZIERSEGMENT*o2 = (SWF_BEZIERSEGMENT*)outline; p0.x=x; p0.y=y; p1.x=o2->C.x/(float)0xffff+lastx; @@ -302,32 +304,32 @@ void drawpath(TAG*tag, T1_OUTLINE*outline, struct swfmatrix*m, int log) } } -plotxy getPivot(T1_OUTLINE*outline, int dir, double line_width, int end, int trytwo) +plotxy getPivot(SWF_OUTLINE*outline, int dir, double line_width, int end, int trytwo) { - T1_PATHPOINT next, next2; + SWF_PATHPOINT next, next2; double xv=0,yv=0, xv2=0, yv2=0; plotxy p; int two = 0; if(!end) { - if(outline->type == T1_PATHTYPE_LINE) { + if(outline->type == SWF_PATHTYPE_LINE) { next = outline->dest; } else { - next = ((T1_BEZIERSEGMENT*)outline)->B; + next = ((SWF_BEZIERSEGMENT*)outline)->B; if(next.x==0 && next.y==0) { - next = ((T1_BEZIERSEGMENT*)outline)->C; + next = ((SWF_BEZIERSEGMENT*)outline)->C; } if(next.x==0 && next.y==0) { - next = ((T1_BEZIERSEGMENT*)outline)->dest; + next = ((SWF_BEZIERSEGMENT*)outline)->dest; } } next2 = next; - if(trytwo && outline->last && outline->last->type != T1_PATHTYPE_MOVE) { - if(outline->type == T1_PATHTYPE_LINE) { + if(trytwo && outline->last && outline->last->type != SWF_PATHTYPE_MOVE) { + if(outline->type == SWF_PATHTYPE_LINE) { next2 = outline->last->dest; } else { - T1_PATHPOINT c = ((T1_BEZIERSEGMENT*)(outline->last))->C; - T1_PATHPOINT b = ((T1_BEZIERSEGMENT*)(outline->last))->B; + SWF_PATHPOINT c = ((SWF_BEZIERSEGMENT*)(outline->last))->C; + SWF_PATHPOINT b = ((SWF_BEZIERSEGMENT*)(outline->last))->B; next2.x = outline->last->dest.x - c.x; next2.y = outline->last->dest.y - c.y; if(next2.x==0 && next2.y==0) { @@ -342,11 +344,11 @@ plotxy getPivot(T1_OUTLINE*outline, int dir, double line_width, int end, int try two = 1; } } else { - if(outline->type == T1_PATHTYPE_LINE) { + if(outline->type == SWF_PATHTYPE_LINE) { next = outline->dest; } else { - T1_PATHPOINT c = ((T1_BEZIERSEGMENT*)outline)->C; - T1_PATHPOINT b = ((T1_BEZIERSEGMENT*)outline)->B; + SWF_PATHPOINT c = ((SWF_BEZIERSEGMENT*)outline)->C; + SWF_PATHPOINT b = ((SWF_BEZIERSEGMENT*)outline)->B; next.x = outline->dest.x - c.x; next.y = outline->dest.y - c.y; if(next.x==0 && next.y==0) { @@ -359,16 +361,16 @@ plotxy getPivot(T1_OUTLINE*outline, int dir, double line_width, int end, int try } } next2 = next; - if(trytwo && outline->link && outline->link->type != T1_PATHTYPE_MOVE) { - if(outline->type == T1_PATHTYPE_LINE) { + if(trytwo && outline->link && outline->link->type != SWF_PATHTYPE_MOVE) { + if(outline->type == SWF_PATHTYPE_LINE) { next2 = outline->link->dest; } else { - next2 = ((T1_BEZIERSEGMENT*)(outline->link))->B; + next2 = ((SWF_BEZIERSEGMENT*)(outline->link))->B; if(next2.x==0 && next2.y==0) { - next2 = ((T1_BEZIERSEGMENT*)outline->link)->C; + next2 = ((SWF_BEZIERSEGMENT*)outline->link)->C; } if(next2.x==0 && next2.y==0) { - next2 = ((T1_BEZIERSEGMENT*)outline->link)->dest; + next2 = ((SWF_BEZIERSEGMENT*)outline->link)->dest; } } two = 1; @@ -411,15 +413,15 @@ plotxy getPivot(T1_OUTLINE*outline, int dir, double line_width, int end, int try return p; } -void drawShortPath(struct swfoutput*output, double x, double y, struct swfmatrix* m, T1_OUTLINE*outline) +void drawShortPath(struct swfoutput*output, double x, double y, struct swfmatrix* m, SWF_OUTLINE*outline) { double lastx=x, lasty=y; - while (outline && outline->type != T1_PATHTYPE_MOVE) + while (outline && outline->type != SWF_PATHTYPE_MOVE) { x += (outline->dest.x/(float)0xffff); y += (outline->dest.y/(float)0xffff); - if(outline->type == T1_PATHTYPE_LINE) + if(outline->type == SWF_PATHTYPE_LINE) { plotxy p0, p1; p0.x=lastx; @@ -428,10 +430,10 @@ void drawShortPath(struct swfoutput*output, double x, double y, struct swfmatrix p1.y= y; line(tag, p0, p1, m); } - else if(outline->type == T1_PATHTYPE_BEZIER) + else if(outline->type == SWF_PATHTYPE_BEZIER) { plotxy p0,p1,p2,p3; - T1_BEZIERSEGMENT*o2 = (T1_BEZIERSEGMENT*)outline; + SWF_BEZIERSEGMENT*o2 = (SWF_BEZIERSEGMENT*)outline; p3.x=lastx; p3.y=lasty; p1.x=o2->C.x/(float)0xffff+lastx; @@ -448,7 +450,7 @@ void drawShortPath(struct swfoutput*output, double x, double y, struct swfmatrix } } -void drawShortPathWithEnds(struct swfoutput*output, double x, double y, struct swfmatrix* m, T1_OUTLINE*outline, int num, int line_cap, int line_join, double line_width) +void drawShortPathWithEnds(struct swfoutput*output, double x, double y, struct swfmatrix* m, SWF_OUTLINE*outline, int num, int line_cap, int line_join, double line_width) { plotxy d,d2; int back = 0; @@ -456,14 +458,14 @@ void drawShortPathWithEnds(struct swfoutput*output, double x, double y, struct s if(line_cap == LINE_CAP_BUTT || line_cap == LINE_CAP_SQUARE) { endshape(); startshape(output); - T1_OUTLINE *last, *tmp=outline; + SWF_OUTLINE *last, *tmp=outline; plotxy s,e,p0,p1,p2,p3,m0,m1,m2,m3; double x2 = x; double y2 = y; double lx=x,ly=y; double ee = 1.0; int nr; - while(tmp && tmp->type != T1_PATHTYPE_MOVE) { + while(tmp && tmp->type != SWF_PATHTYPE_MOVE) { last = tmp; lx += (tmp->dest.x/(float)0xffff); ly += (tmp->dest.y/(float)0xffff); @@ -556,7 +558,7 @@ void drawShortPathWithEnds(struct swfoutput*output, double x, double y, struct s } } -void drawT1toRect(struct swfoutput*output, double x, double y, struct swfmatrix* m, T1_OUTLINE*outline, int num, int line_cap, int line_join, double line_width) +void drawT1toRect(struct swfoutput*output, double x, double y, struct swfmatrix* m, SWF_OUTLINE*outline, int num, int line_cap, int line_join, double line_width) { plotxy d1,d2,p1,p2,p3,p4; @@ -587,9 +589,9 @@ void drawT1toRect(struct swfoutput*output, double x, double y, struct swfmatrix* line(tag, p4,p1, m); } -void drawShortPathWithStraightEnds(struct swfoutput*output, double x, double y, struct swfmatrix* m, T1_OUTLINE*outline, int num, int line_cap, int line_join, double line_width) +void drawShortPathWithStraightEnds(struct swfoutput*output, double x, double y, struct swfmatrix* m, SWF_OUTLINE*outline, int num, int line_cap, int line_join, double line_width) { - T1_OUTLINE*tmp=outline; + SWF_OUTLINE*tmp=outline; double xx=x,yy=y; int stop=0; assert(shapeid>=0); @@ -597,14 +599,14 @@ void drawShortPathWithStraightEnds(struct swfoutput*output, double x, double y, startFill(); drawT1toRect(output, x, y, m,outline, num, line_cap, line_join, line_width); - while(tmp->link && tmp->link->type!=T1_PATHTYPE_MOVE) { + while(tmp->link && tmp->link->type!=SWF_PATHTYPE_MOVE) { xx += (tmp->dest.x/(float)0xffff); yy += (tmp->dest.y/(float)0xffff); tmp = tmp->link; } - assert(tmp->type == T1_PATHTYPE_LINE); - assert(outline->type == T1_PATHTYPE_LINE); + assert(tmp->type == SWF_PATHTYPE_LINE); + assert(outline->type == SWF_PATHTYPE_LINE); if(tmp!=outline) { @@ -623,7 +625,7 @@ void drawShortPathWithStraightEnds(struct swfoutput*output, double x, double y, { stopFill();stop=1; int save= tmp->type; - tmp->type = T1_PATHTYPE_MOVE; + tmp->type = SWF_PATHTYPE_MOVE; x += (outline->dest.x/(float)0xffff); y += (outline->dest.y/(float)0xffff); outline = outline->link; @@ -635,17 +637,17 @@ void drawShortPathWithStraightEnds(struct swfoutput*output, double x, double y, stopFill(); } -static int t1len(T1_OUTLINE*line) +static int t1len(SWF_OUTLINE*line) { int num=0; - while(line && line->type != T1_PATHTYPE_MOVE) { + while(line && line->type != SWF_PATHTYPE_MOVE) { num++; line = line->link; } return num; } -static float t1linelen(T1_OUTLINE*line) +static float t1linelen(SWF_OUTLINE*line) { float x,y; x = (line->dest.x/(float)0xffff); @@ -653,7 +655,7 @@ static float t1linelen(T1_OUTLINE*line) return sqrt(x*x+y*y); } -void drawpath2poly(struct swfoutput *output, T1_OUTLINE*outline, struct swfmatrix*m, int log, int line_join, int line_cap, double line_width, double miter_limit) +void drawpath2poly(struct swfoutput *output, SWF_OUTLINE*outline, struct swfmatrix*m, int log, int line_join, int line_cap, double line_width, double miter_limit) { if(tag->id != ST_DEFINEFONT && tag->id != ST_DEFINESHAPE && @@ -667,7 +669,7 @@ void drawpath2poly(struct swfoutput *output, T1_OUTLINE*outline, struct swfmatri double lastx=0,lasty=0; int valid = 0; int lastwasline = 0; - T1_OUTLINE*tmp = outline, *last = 0; + SWF_OUTLINE*tmp = outline, *last = 0; tmp->last = 0; while(1) { @@ -675,9 +677,9 @@ void drawpath2poly(struct swfoutput *output, T1_OUTLINE*outline, struct swfmatri x += (tmp->dest.x/(float)0xffff); y += (tmp->dest.y/(float)0xffff); } - if(!tmp || tmp->type == T1_PATHTYPE_MOVE) { + if(!tmp || tmp->type == SWF_PATHTYPE_MOVE) { if(valid && last) { - if(last->type == T1_PATHTYPE_LINE && t1linelen(last)>line_width*2 && + if(last->type == SWF_PATHTYPE_LINE && t1linelen(last)>line_width*2 && lastwasline && line_cap != LINE_CAP_ROUND) drawShortPathWithStraightEnds(output, lastx, lasty, m, last, valid, line_cap, line_join, line_width); else @@ -695,7 +697,7 @@ void drawpath2poly(struct swfoutput *output, T1_OUTLINE*outline, struct swfmatri valid++; } - if(tmp && tmp->type == T1_PATHTYPE_LINE && t1linelen(tmp)>line_width*2) + if(tmp && tmp->type == SWF_PATHTYPE_LINE && t1linelen(tmp)>line_width*2) lastwasline = 1; else lastwasline = 0; @@ -718,7 +720,7 @@ static inline int colorcompare(RGBA*a,RGBA*b) return 1; } -static const int CHARDATAMAX = 1024; +static const int CHARDATAMAX = 8192; struct chardata { int charid; int fontid; @@ -870,6 +872,7 @@ static void putcharacter(struct swfoutput*obj, int fontid, int charid, { if(chardatapos == CHARDATAMAX) { + msg(" Character buffer too small. SWF will be slightly bigger"); endtext(); starttext(obj); } @@ -884,7 +887,7 @@ static void putcharacter(struct swfoutput*obj, int fontid, int charid, /* process a character. */ -static void drawchar(struct swfoutput*obj, SWFFont*font, SWFFONT *swffont, char*character, int charnr, swfmatrix*m, Unicode u) +static void drawchar(struct swfoutput*obj, SWFFONT *swffont, char*character, int charnr, int u, swfmatrix*m) { int usefonts=1; if(m->m12!=0 || m->m21!=0) @@ -892,23 +895,18 @@ static void drawchar(struct swfoutput*obj, SWFFont*font, SWFFONT *swffont, char* if(m->m11 != m->m22) usefonts=0; - if(!font) { + if(!swffont) { msg(" Font is NULL"); } //if(usefonts && ! drawonlyshapes) if (1) { - int charid = font->getSWFCharID(character, charnr); - printf("charID %d, character %s\n", charid, character); - if (charid == -1) { - charid = 0; - charid = getCharID(swffont, charnr, character, u); - } + int charid = getCharID(swffont, charnr, character, u); if(charid<0) { - msg(" Didn't find character '%s' (%d) in current charset (%s)", - FIXNULL(character),charnr, FIXNULL(font->getName())); + msg(" Didn't find character '%s' (%d) in current charset (%s, %d characters)", + FIXNULL(character),charnr, FIXNULL((char*)swffont->name), swffont->numchars); return; } if(shapeid>=0) @@ -916,12 +914,12 @@ static void drawchar(struct swfoutput*obj, SWFFont*font, SWFFONT *swffont, char* if(textid<0) starttext(obj); - putcharacter(obj, font->swfid, charid,(int)(m->m13*20),(int)(m->m23*20), - (int)(m->m11*20/2+0.5)); //where does the /2 come from? + putcharacter(obj, swffont->id, charid,(int)(m->m13*20),(int)(m->m23*20), + (int)(m->m11+0.5)); } - else + /*else { - T1_OUTLINE*outline = font->getOutline(character, charnr); + SWF_OUTLINE*outline = font->getOutline(character, charnr); char* charname = character; if(!outline) { @@ -947,11 +945,11 @@ static void drawchar(struct swfoutput*obj, SWFFont*font, SWFFONT *swffont, char* fill = 1; drawpath(tag, outline, &m2, 0); fill = lf; - } + }*/ } /* draw a curved polygon. */ -void swfoutput_drawpath(swfoutput*output, T1_OUTLINE*outline, +void swfoutput_drawpath(swfoutput*output, SWF_OUTLINE*outline, struct swfmatrix*m) { if(textid>=0) @@ -975,7 +973,7 @@ void swfoutput_drawpath(swfoutput*output, T1_OUTLINE*outline, drawpath(tag, outline,m, 0); } -void swfoutput_drawpath2poly(struct swfoutput*output, T1_OUTLINE*outline, struct swfmatrix*m, int line_join, int line_cap, double line_width, double miter_limit) +void swfoutput_drawpath2poly(struct swfoutput*output, SWF_OUTLINE*outline, struct swfmatrix*m, int line_join, int line_cap, double line_width, double miter_limit) { if(textid>=0) endtext(); @@ -988,413 +986,100 @@ void swfoutput_drawpath2poly(struct swfoutput*output, T1_OUTLINE*outline, struct drawpath2poly(output, outline, m, 0, line_join, line_cap, line_width, miter_limit); } -/* SWFFont: copy all t1 font outlines to a local - array. */ -SWFFont::SWFFont(char*name, int id, char*filename) +int getCharID(SWFFONT *font, int charnr, char *charname, int u) { - if(!T1_GetFontName(id)) - T1_LoadFont(id); - - this->name = strdup(T1_GetFontFileName(id)); - this->fontid = strdup(name); - this->t1id = id; - - char**charnamebase= T1_GetAllCharNames(id); - char**a= charnamebase; - int t, outlinepos=0; - char*map[256]; - - char*null = 0; - if(!a) - a=&null; - - t=0; - while(a[t]) - t++; - this->charnum = t; - - if(!charnum) { - this->standardtablesize = 0; - } - msg(" Font %s(%d): Storing %d outlines.\n", FIXNULL(name), id, charnum); - - this->standardtablesize = 256; - if(this->charnum < this->standardtablesize) - this->standardtablesize = this->charnum; - this->standardtable = (char**)malloc(standardtablesize*sizeof(char*)); - - for(t = 0; t < this->standardtablesize; t++) { - char*name = T1_GetCharName(id,t); - char chh[2] = ""; - chh[0] = t; - if(!name || !strstr(name, "notdef")) { - if(t + int t; + if(charname) { + for(t=0;tnumchars;t++) { + if(font->glyphnames[t] && !strcmp(font->glyphnames[t],charname)) { + return t; } } - standardtable[t] = strdup(name); - msg(" Char %d is named %s\n", t, name); - } - - outline = (T1_OUTLINE**)malloc(charnum*sizeof(T1_OUTLINE*)); - charname = (char**)malloc(charnum*sizeof(char*)); - width = (int*)malloc(charnum*sizeof(int)); - memset(width, 0, charnum*sizeof(int)); - memset(charname, 0, charnum*sizeof(char*)); - used = (char*)malloc(charnum*sizeof(char)); - char2swfcharid = (U16*)malloc(charnum*2); - swfcharid2char = (U16*)malloc(charnum*2); - swfcharpos = 0; - - memset(used,0,charnum*sizeof(char)); - - this->swfid = ++currentswfid; - - t=0; - while(*a) - { - map[t] = strdup(*a); - a++; - t++; - if(t==256 || !*a) { - int s; - for(s=t;s<256;s++) - map[s] = ".notdef"; - - int ret = T1_ReencodeFont(id, map); - if(ret) { - T1_DeleteFont(id); - T1_LoadFont(id); - int ret = T1_ReencodeFont(id, map); - if(ret) - fprintf(stderr,"Can't reencode font: (%s) ret:%d\n",filename, ret); - /* Deleting the font invalidates the charname array, - so we have to ask for it again now. - We continue at the position we were, hoping the font - didn't shrink in the meantime or something. - */ - a = T1_GetAllCharNames(id) + (a - charnamebase); - } - - // parsecharacters - for(s=0;soutline[outlinepos] = T1_CopyOutline(T1_GetCharOutline(id, s, 100.0, 0)); - this->width[outlinepos] = T1_GetCharWidth(id, s); - this->charname[outlinepos] = strdup(name); - outlinepos++; - } - - for(s=0;scharnum;t++) - { - if(this->charname[t]) - getSWFCharID(this->charname[t], -1); - } - } - - ptr = (int*)malloc(swfcharpos*sizeof(int)); - - for(t=0;t Font %s has %d used characters",FIXNULL(fontid), usednum); - TAG*ftag = swf_InsertTag(swf.firstTag,ST_DEFINEFONT); - swf_SetU16(ftag, this->swfid); - int initpos = swf_GetTagLen(ftag); - swfmatrix m; - m.m11 = m.m22 = 1; - m.m21 = m.m12 = 0; - m.m13 = CHARMIDX; - m.m23 = CHARMIDY; - - for(t=0;tdata[ptr[t]] = - SWAP16(swf_GetTagLen(ftag)-initpos); - - swflastx=0; - swflasty=0; - swf_SetU8(ftag,0x10); //1 fill bits, 0 linestyle bits - SHAPE s; - s.bits.fill = 1; - s.bits.line = 0; - swf_ShapeSetStyle(ftag,&s,0,1,0); - fillstylechanged = 1; - int lastfill = fill; - fill = 1; - storefont = 1; - drawpath(ftag, outline[swfcharid2char[t]],&m, 0); - storefont = 0; - fill = lastfill; - swf_ShapeSetEnd(ftag); - } - ftag = swf_InsertTag(ftag,ST_DEFINEFONTINFO); - swf_SetU16(ftag, this->swfid); - if(this->fontid) { - swf_SetU8(ftag, strlen(this->fontid)); - swf_SetBlock(ftag, (U8*)this->fontid, strlen(this->fontid)); - } else { - swf_SetU8(ftag, 0); - } - swf_SetU8(ftag, 0); //flags - for(t=0;tcharname[this->swfcharid2char[t]]; - for(s=0;s<256;s++) { - if(standardEncodingNames[s] && - !strcmp(name,standardEncodingNames[s])) - break; + /* if we didn't find the character, maybe + we can find the capitalized version */ + for(t=0;tnumchars;t++) { + if(font->glyphnames[t] && !strcasecmp(font->glyphnames[t],charname)) { + return t; } - swf_SetU8(ftag, (U8)s); } } - free(ptr); - if(outline) - free(outline); - for(t=0;tcharnum;t++) { - if(!strcmp(this->charname[t],name)) { - return outline[t]; - } - } - - /* if we didn't find the character, maybe - we can find the capitalized version */ - for(t=0;tcharnum;t++) { - if(!strcasecmp(this->charname[t],name)) - return outline[t]; - } - - /* if we didn't find it by name, use the names of the first 256 characters - of the font to try a new name based on charnr */ - if(this->standardtable && charnr>=0 && charnr < this->standardtablesize) { - T1_OUTLINE*ret = getOutline(this->standardtable[charnr], -1); - if(ret) return ret; - } - - return 0; -} - -int SWFFont::getSWFCharID(char*name, int charnr) -{ - int t; - for(t=0;tcharnum;t++) { - if(!strcmp(this->charname[t],name)) { - if(!used[t]) - { - swfcharid2char[swfcharpos] = t; - char2swfcharid[t] = swfcharpos++; - used[t] = 1; - } - return char2swfcharid[t]; - } - } - - /* if we didn't find the character, maybe - we can find the capitalized version */ - for(t=0;tcharnum;t++) { - if(!strcasecmp(this->charname[t],name)) { - if(!used[t]) - { - swfcharid2char[swfcharpos] = t; - char2swfcharid[t] = swfcharpos++; - used[t] = 1; - } - return char2swfcharid[t]; - } - } - - /* if we didn't find it by name, use the names of the first 256 (or so) characters - of the font to try a new name based on charnr */ - if(this->standardtable && charnr>=0 && charnr < this->standardtablesize) { - int ret = getSWFCharID(this->standardtable[charnr], -1); - if(ret) return ret; - } - return -1; -} - -int getCharID(SWFFONT *font, int charnr, char *charname, Unicode u) -{ - int t; - for(t=0;tnumchars;t++) { - if(!strcmp(font->glyphnames[t],charname)) { - return t; - } - } + if(u>0) { + if(u>=font->maxascii) + msg(" u=%d, font->maxascii=%d",u,font->maxascii); + else + msg(" u=%d, font->maxascii=%d ascci2glyph[%d]=%d",u,font->maxascii,u,font->ascii2glyph[u]); - /* if we didn't find the character, maybe - we can find the capitalized version */ - for(t=0;tnumchars;t++) { - if(!strcasecmp(font->glyphnames[t],charname)) { - return t; - } + /* try to use the unicode id */ + if(u>=0 && umaxascii && font->ascii2glyph[u]>=0) + return font->ascii2glyph[u]; } - /* try to use the unicode id */ - for(t=0;tnumchars;t++) { - if(font->ascii2glyph[t] == u) { - return t; - } - } - + if(charnr>=0 && charnrnumchars) + return charnr; return -1; } -int SWFFont::getWidth(char*name) -{ - int t; - for(t=0;tcharnum;t++) { - if(!strcmp(this->charname[t],name)) { - return this->width[t]; - } - } - return 0; -} - -char*SWFFont::getName() -{ - return this->name; -} - struct fontlist_t { - SWFFont *font; SWFFONT *swffont; fontlist_t*next; } *fontlist = 0; /* set's the t1 font index of the font to use for swfoutput_drawchar(). */ -void swfoutput_setfont(struct swfoutput*obj, char*fontid, int t1id, char*filename) +void swfoutput_setfont(struct swfoutput*obj, char*fontid, char*filename) { - static int currentswfid = 0; - - if (0) - { - fontlist_t*last=0,*iterator; - if(obj->swffont && (obj->swffont->id == atoi(fontid))) - return; - - iterator = fontlist; - while(iterator) { - if(iterator->swffont->id == atoi(fontid)) - break; - last = iterator; - iterator = iterator->next; - } - if(iterator) - { - obj->swffont = iterator->swffont; - return ; - } - - if(t1id<0) { - msg(" internal error: t1id:%d, fontid:%s\n", t1id,FIXNULL(fontid)); - } - - SWFFONT *swffont = swf_LoadFont(filename); - swf_FontSetID(swffont, atoi(fontid)); - iterator = new fontlist_t; - iterator->swffont = swffont; - iterator->next = 0; - - if(last) - last->next = iterator; - else - fontlist = iterator; - obj->swffont = swffont; - } else - { fontlist_t*last=0,*iterator; - if(obj->font && !strcmp(obj->font->fontid,fontid)) + if(!fontid) { + msg(" No fontid"); + return; + } + + if(obj->swffont && obj->swffont->name && !strcmp((char*)obj->swffont->name,fontid)) return; iterator = fontlist; while(iterator) { - if(!strcmp(iterator->font->fontid,fontid)) - break; + if(!strcmp((char*)iterator->swffont->name,fontid)) { + obj->swffont = iterator->swffont; + return; + } last = iterator; iterator = iterator->next; } - if(iterator) - { - obj->font = iterator->font; - obj->swffont = iterator->swffont; - return ; - } - if(t1id<0) { - msg(" internal error: t1id:%d, fontid:%s\n", t1id,FIXNULL(fontid)); + if(!filename) { + msg(" No filename given for font- internal error?"); + return; } - - SWFFont*font = new SWFFont(fontid, t1id, filename); - //load swffont and print font information + /* TODO: sometimes, scale has to be 64, and sometimes 32. + It's probably font format related */ + swf_SetLoadFontParameters(32, 0); + SWFFONT *swffont = swf_LoadFont(filename); swf_FontSetID(swffont, ++currentswfid); - // print font information - /* - printf("\n----------------------SWF Font Information:\n"); - printf("ID:%d\n", swffont->id); - printf("Version:%d\n", swffont->version); - printf("Name:%s\n", swffont->name); - printf("Numchars:%d\n", swffont->numchars); - printf("Maxascii:%d\n", swffont->maxascii); - printf("Style:%d\n", swffont->style); - printf("Encoding:%d\n", swffont->encoding); - for(int iii=0; iiinumchars;iii++) - { - printf("Glyphname, glyph2ascii, ascii2glyph %d:%s, %d, %d\n", iii, swffont->glyphnames[iii], swffont->glyph2ascii[iii], swffont->ascii2glyph[iii]); + + if(screenloglevel >= LOGLEVEL_DEBUG) { + // print font information + msg(" Font %s (%s)",swffont->name, filename); + msg(" | ID: %d", swffont->id); + msg(" | Version: %d", swffont->version); + msg(" | Name: %s", fontid); + msg(" | Numchars: %d", swffont->numchars); + msg(" | Maxascii: %d", swffont->maxascii); + msg(" | Style: %d", swffont->style); + msg(" | Encoding: %d", swffont->encoding); + for(int iii=0; iiinumchars;iii++) { + msg(" | Glyph %d) name=%s, unicode=%d\n", iii, swffont->glyphnames[iii], swffont->glyph2ascii[iii]); + } } - printf("\n----------------------SWF Font Information End.\n"); - */ + + /* set the font name to the ID we use here */ + if(swffont->name) free(swffont->name); + swffont->name = (U8*)strdup(fontid); + iterator = new fontlist_t; - iterator->font = font; iterator->swffont = swffont; iterator->next = 0; @@ -1402,32 +1087,19 @@ void swfoutput_setfont(struct swfoutput*obj, char*fontid, int t1id, char*filenam last->next = iterator; else fontlist = iterator; - obj->font = font; + obj->swffont = swffont; - } } int swfoutput_queryfont(struct swfoutput*obj, char*fontid) { - if (0) - { - fontlist_t *iterator = fontlist; - while(iterator) { - if(iterator->swffont->id == atoi(fontid)) - return 1; - iterator = iterator->next; - } - return 0; - } else - { fontlist_t *iterator = fontlist; while(iterator) { - if(!strcmp(iterator->font->fontid,fontid)) + if(!strcmp((char*)iterator->swffont->name,fontid)) return 1; iterator = iterator->next; } return 0; - } } /* set's the matrix which is to be applied to characters drawn by @@ -1449,7 +1121,7 @@ void swfoutput_setfontmatrix(struct swfoutput*obj,double m11,double m12, } /* draws a character at x,y. */ -void swfoutput_drawchar(struct swfoutput* obj,double x,double y,char*character, int charnr, Unicode u) +void swfoutput_drawchar(struct swfoutput* obj,double x,double y,char*character, int charnr, int u) { swfmatrix m; m.m11 = obj->fontm11; @@ -1458,13 +1130,12 @@ void swfoutput_drawchar(struct swfoutput* obj,double x,double y,char*character, m.m22 = obj->fontm22; m.m13 = x; m.m23 = y; - drawchar(obj, obj->font, obj->swffont, character, charnr, &m, u); + drawchar(obj, obj->swffont, character, charnr, u, &m); } /* initialize the swf writer */ void swfoutput_init(struct swfoutput* obj, char*_filename, int x1, int y1, int x2, int y2) { - GLYPH *glyph; RGBA rgb; SRECT r; memset(obj, 0, sizeof(struct swfoutput)); @@ -1474,7 +1145,7 @@ void swfoutput_init(struct swfoutput* obj, char*_filename, int x1, int y1, int x msg(" initializing swf output for size %d*%d\n", sizex,sizey); - obj->font = 0; + obj->swffont = 0; memset(&swf,0x00,sizeof(SWF)); @@ -1566,6 +1237,7 @@ static void startshape(struct swfoutput*obj) swf_ShapeSetAll(tag,shape,/*x*/0,/*y*/0,linestyleid,0,0); swflastx=swflasty=0; lastwasfill = 0; + shapeisempty = 1; } static void starttext(struct swfoutput*obj) @@ -1601,6 +1273,12 @@ static void endshape() if(shapeid<0) return; swf_ShapeSetEnd(tag); + + if(shapeisempty) { + msg(" empty shape"); + // TODO: delete tag + } + tag = swf_InsertTag(tag,ST_PLACEOBJECT2); swf_ObjectPlace(tag,shapeid,/*depth*/depth++,NULL,NULL,NULL); shapeid = -1; @@ -1655,14 +1333,18 @@ void swfoutput_destroy(struct swfoutput* obj) endpage(obj); fontlist_t *tmp,*iterator = fontlist; while(iterator) { - delete iterator->font; - iterator->font = 0; + TAG*mtag = swf.firstTag; + if(iterator->swffont) { + mtag = swf_InsertTag(mtag, ST_DEFINEFONT2); + swf_FontSetDefine2(mtag, iterator->swffont); + swf_FontFree(iterator->swffont); + } + tmp = iterator; iterator = iterator->next; delete tmp; } - T1_CloseLib(); if(!filename) return; if(filename) @@ -1746,7 +1428,7 @@ void swfoutput_setlinewidth(struct swfoutput*obj, double linewidth) } -void swfoutput_startclip(swfoutput*obj, T1_OUTLINE*outline, struct swfmatrix*m) +void swfoutput_startclip(swfoutput*obj, SWF_OUTLINE*outline, struct swfmatrix*m) { if(textid>=0) endtext(); diff --git a/pdf2swf/swfoutput.h b/pdf2swf/swfoutput.h index 015fb39..0b4ceed 100644 --- a/pdf2swf/swfoutput.h +++ b/pdf2swf/swfoutput.h @@ -22,12 +22,6 @@ #ifndef __swfoutput_h__ #define __swfoutput_h__ -#include -#include "CharTypes.h" -#ifdef T1ERR_SCAN_ENCODING //t1lib 5.0.0 -#define T1_Get_no_fonts T1_GetNoFonts -#endif - extern "C" { #include "../lib/rfxswf.h" } @@ -54,50 +48,56 @@ struct swfcoord { twip y; }; -class SWFFont -{ - T1_OUTLINE**outline; - char**charname; - int*width; - char*used; - - char*name; - int charnum; - - U16*char2swfcharid; - U16*swfcharid2char; - int swfcharpos; - - char**standardtable; - int standardtablesize; - - public: - - int t1id; - char*fontid; - unsigned int swfid; - - SWFFont(char*name, int t1id, char*filename); - SWFFont::~SWFFont(); - T1_OUTLINE*getOutline(char*charname, int charnr); - int getSWFCharID(char*name, int charnr); - int getWidth(char*name); - char*getName(); - char*getCharName(int t); - int getCharWidth(int t) {return width[t];} -}; - struct swfoutput { - //int t1font; double fontm11,fontm12,fontm21,fontm22; unsigned short int linewidth; - SWFFont *font; SWFFONT *swffont; RGBA strokergb; RGBA fillrgb; }; +/* outline definition, adapted from t1lib.h */ + +/* A fractional point */ +typedef struct { + long x; + long y; +} SWF_PATHPOINT; + +/* A straight outline segment, stroked or not stroked */ +typedef struct pathsegment { + char type; /* type of segment (line or move) */ + unsigned char flag; /* type1 rasterizer internal stuff */ + short references; /* type1 rasterizer internal stuff */ + unsigned char size; /* size of the structure */ + unsigned char context; /* index to device context */ + struct pathsegment *link; /* pointer to next structure in linked list */ + struct pathsegment *last; /* pointer to last structure in list */ + SWF_PATHPOINT dest; /* relative ending location of path segment */ +} SWF_PATHSEGMENT; + +/* A third order bezier segment */ +typedef struct bezierpathsegment { + char type; /* type of segment (bezier) */ + unsigned char flag; /* type1 rasterizer internal stuff */ + short references; /* type1 rasterizer internal stuff */ + unsigned char size; /* as with any 'segment' type */ + unsigned char context; /* as with any 'segment' type */ + SWF_PATHSEGMENT *link; /* as with any 'segment' type */ + SWF_PATHSEGMENT *last; /* as with any 'segment' type */ + SWF_PATHPOINT dest; /* ending point (D) */ + SWF_PATHPOINT B; /* control point B */ + SWF_PATHPOINT C; /* control point C */ +} SWF_BEZIERSEGMENT; + +typedef SWF_PATHSEGMENT SWF_OUTLINE; + +#define SWF_PATHTYPE_LINE 0x10 +#define SWF_PATHTYPE_BEZIER 0x12 +#define SWF_PATHTYPE_MOVE 0x15 + + #define DRAWMODE_STROKE 1 #define DRAWMODE_FILL 2 #define DRAWMODE_EOFILL 3 @@ -109,9 +109,9 @@ void swfoutput_setprotected(); //write PROTECT tag void swfoutput_newpage(struct swfoutput*); -void swfoutput_setfont(struct swfoutput*, char*fontid, int t1font, char*filename); +void swfoutput_setfont(struct swfoutput*, char*fontid, char*filename); int swfoutput_queryfont(struct swfoutput*, char*fontid); -int getCharID(SWFFONT *font, int charnr, char *charname, Unicode u); +int getCharID(SWFFONT *font, int charnr, char *charname, int u); void swfoutput_setdrawmode(struct swfoutput*, int drawmode); void swfoutput_setfillcolor(struct swfoutput*, unsigned char r, unsigned char g, unsigned char b, unsigned char a); @@ -119,16 +119,16 @@ void swfoutput_setstrokecolor(struct swfoutput*, unsigned char r, unsigned char void swfoutput_setfontmatrix(struct swfoutput*,double,double,double,double); void swfoutput_setlinewidth(struct swfoutput*, double linewidth); -void swfoutput_drawchar(struct swfoutput*,double x,double y,char*a, int charnr, Unicode u); -void swfoutput_drawpath(struct swfoutput*, T1_OUTLINE*outline, struct swfmatrix*m); +void swfoutput_drawchar(struct swfoutput*,double x,double y,char*a, int charnr, int u); +void swfoutput_drawpath(struct swfoutput*, SWF_OUTLINE*outline, struct swfmatrix*m); #define LINE_CAP_BUTT 0 #define LINE_CAP_ROUND 1 #define LINE_CAP_SQUARE 2 #define LINE_JOIN_MITER 0 #define LINE_JOIN_ROUND 1 #define LINE_JOIN_BEVEL 2 -void swfoutput_drawpath2poly(struct swfoutput*, T1_OUTLINE*outline, struct swfmatrix*m, int line_join, int line_cap, double line_width, double miter_limit); -void swfoutput_startclip(struct swfoutput*, T1_OUTLINE*outline, struct swfmatrix*m); +void swfoutput_drawpath2poly(struct swfoutput*, SWF_OUTLINE*outline, struct swfmatrix*m, int line_join, int line_cap, double line_width, double miter_limit); +void swfoutput_startclip(struct swfoutput*, SWF_OUTLINE*outline, struct swfmatrix*m); void swfoutput_endclip(struct swfoutput*); int swfoutput_drawimagejpeg(struct swfoutput*, RGBA*pic, int sizex,int sizey, double x1,double y1, -- 1.7.10.4