X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=pdf2swf%2FSWFOutputDev.cc;h=cef673326eca478cc0c8ea0b205090a648f50992;hb=5ede6209244433ea174111a9079fa6d0cf84d227;hp=7563762abf3e8d5d8a33c1f98eab780c73c3ce23;hpb=bd77e840e2e8bffee0b4cfdb7b006219e823af99;p=swftools.git diff --git a/pdf2swf/SWFOutputDev.cc b/pdf2swf/SWFOutputDev.cc index 7563762..cef6733 100644 --- a/pdf2swf/SWFOutputDev.cc +++ b/pdf2swf/SWFOutputDev.cc @@ -21,7 +21,11 @@ #include #include #include +#include +#include "../config.h" //xpdf header files +#include "config.h" +#include "gfile.h" #include "GString.h" #include "gmem.h" #include "Object.h" @@ -32,31 +36,46 @@ #include "Catalog.h" #include "Page.h" #include "PDFDoc.h" -#include "Params.h" #include "Error.h" -#include "config.h" #include "OutputDev.h" #include "GfxState.h" #include "GfxFont.h" +#include "CharCodeToUnicode.h" +#include "NameToUnicodeTable.h" #include "FontFile.h" +#include "GlobalParams.h" //swftools header files #include "swfoutput.h" -extern "C" { #include "../lib/log.h" -} -static char* filename = 0; +#include "ttf2pt1.h" + +#define logf logarithmf // logf is also used by ../lib/log.h +#include +#undef logf + +static PDFDoc*doc = 0; +static char* swffilename = 0; +int numpages; +int currentpage; + +// swf <-> pdf pages +int*pages = 0; +int pagebuflen = 0; +int pagepos = 0; + +double caplinewidth = 3.0; static void printInfoString(Dict *infoDict, char *key, char *fmt); static void printInfoDate(Dict *infoDict, char *key, char *fmt); -static char userPassword[33] = ""; -static GBool printVersion = gFalse; -static GBool printHelp = gFalse; - double fontsizes[] = { - 0.833,0.833,0.889,0.889,0.788,0.722,0.833,0.778,0.600,0.600,0.600,0.600,0.576,0.576,0.576,0.576 + 0.833,0.833,0.889,0.889, + 0.788,0.722,0.833,0.778, + 0.600,0.600,0.600,0.600, + 0.576,0.576,0.576,0.576, + 0.733 //? }; char*fontnames[]={ "Helvetica", @@ -98,48 +117,6 @@ struct mapping { {"Symbol", "s050000l.pfb"}, {"ZapfDingbats", "d050000l.pfb"}}; -static void printInfoString(Dict *infoDict, char *key, char *fmt) { - Object obj; - GString *s1, *s2; - int i; - - if (infoDict->lookup(key, &obj)->isString()) { - s1 = obj.getString(); - if ((s1->getChar(0) & 0xff) == 0xfe && - (s1->getChar(1) & 0xff) == 0xff) { - s2 = new GString(); - for (i = 2; i < obj.getString()->getLength(); i += 2) { - if (s1->getChar(i) == '\0') { - s2->append(s1->getChar(i+1)); - } else { - delete s2; - s2 = new GString(""); - break; - } - } - printf(fmt, s2->getCString()); - delete s2; - } else { - printf(fmt, s1->getCString()); - } - } - obj.free(); -} - -static void printInfoDate(Dict *infoDict, char *key, char *fmt) { - Object obj; - char *s; - - if (infoDict->lookup(key, &obj)->isString()) { - s = obj.getString()->getCString(); - if (s[0] == 'D' && s[1] == ':') { - s += 2; - } - printf(fmt, s); - } - obj.free(); -} - class GfxState; class GfxImageColorMap; @@ -162,9 +139,13 @@ public: // Does this device use drawChar() or drawString()? virtual GBool useDrawChar(); + + virtual GBool interpretType3Chars() {return gTrue;} //----- initialization and control + void startDoc(XRef *xref); + // Start a page. virtual void startPage(int pageNum, GfxState *state) ; @@ -181,6 +162,8 @@ public: virtual void updateFillColor(GfxState *state); virtual void updateStrokeColor(GfxState *state); virtual void updateLineWidth(GfxState *state); + virtual void updateLineJoin(GfxState *state); + virtual void updateLineCap(GfxState *state); virtual void updateAll(GfxState *state) { @@ -188,6 +171,8 @@ public: updateFillColor(state); updateStrokeColor(state); updateLineWidth(state); + updateLineJoin(state); + updateLineCap(state); }; //----- path painting @@ -203,9 +188,9 @@ public: virtual void beginString(GfxState *state, GString *s) ; virtual void endString(GfxState *state) ; virtual void drawChar(GfxState *state, double x, double y, - double dx, double dy, Guchar c) ; - virtual void drawChar16(GfxState *state, double x, double y, - double dx, double dy, int c) ; + double dx, double dy, + double originX, double originY, + CharCode code, Unicode *u, int uLen); //----- image drawing virtual void drawImageMask(GfxState *state, Object *ref, Stream *str, @@ -213,15 +198,33 @@ public: GBool inlineImg); virtual void drawImage(GfxState *state, Object *ref, Stream *str, int width, int height, GfxImageColorMap *colorMap, - GBool inlineImg); + int *maskColors, GBool inlineImg); + + virtual GBool beginType3Char(GfxState *state, + CharCode code, Unicode *u, int uLen); + virtual void endType3Char(GfxState *state); private: - int clipping[32]; + void drawGeneralImage(GfxState *state, Object *ref, Stream *str, + int width, int height, GfxImageColorMap*colorMap, GBool invert, + GBool inlineImg, int mask); + int clipping[64]; int clippos; - int setT1Font(char*name,FontEncoding*enc); - int initT1Font(int id, FontEncoding*encoding); + XRef*xref; + + int searchT1Font(char*name); + char* substituteFont(GfxFont*gfxFont, char*oldname); + char* writeEmbeddedFontToFile(XRef*ref, GfxFont*font); int t1id; + int jpeginfo; // did we write "File contains jpegs" yet? + int pbminfo; // did we write "File contains jpegs" yet? + int linkinfo; // did we write "File contains links" yet? + int ttfinfo; // did we write "File contains TrueType Fonts" yet? + + int type3active; // are we between beginType3()/endType3()? + + GfxState *laststate; }; char mybuf[1024]; @@ -340,46 +343,43 @@ int lastdumppos = 0; */ void showFontError(GfxFont*font, int nr) { - Ref r=font->getID(); + Ref*r=font->getID(); int t; for(t=0;tnum) break; if(t < lastdumppos) return; if(lastdumpposnum; if(nr == 0) - logf(" The following font caused problems:"); + logf(" The following font caused problems:"); else if(nr == 1) - logf(" The following font caused problems (substituting):"); + logf(" The following font caused problems (substituting):"); else if(nr == 2) - logf(" This document contains Type 3 Fonts: (some text may be incorrectly displayed)"); - - dumpFontInfo("", font); + logf(" The following Type 3 Font will be rendered as bitmap:"); + dumpFontInfo("", font); } void dumpFontInfo(char*loglevel, GfxFont*font) { GString *gstr; - char*name; + char*name = 0; gstr = font->getName(); - Ref r=font->getID(); - logf("%s=========== %s (ID:%d) ==========\n", loglevel, gstr?gstr->getCString():"(unknown font)", r.num); + Ref* r=font->getID(); + logf("%s=========== %s (ID:%d,%d) ==========\n", loglevel, gstr?FIXNULL(gstr->getCString()):"(unknown font)", r->num,r->gen); gstr = font->getTag(); if(gstr) - logf("%sTag: %s\n", loglevel, gstr->getCString()); - if(font->is16Bit()) logf("%sis 16 bit\n", loglevel); + logf("%sTag: %s\n", loglevel, FIXNULL(gstr->getCString())); + + if(font->isCIDFont()) logf("%sis CID font\n", loglevel); GfxFontType type=font->getType(); switch(type) { case fontUnknownType: logf("%sType: unknown\n",loglevel); break; - case fontType0: - logf("%sType: 0\n",loglevel); - break; case fontType1: logf("%sType: 1\n",loglevel); break; @@ -392,14 +392,27 @@ void dumpFontInfo(char*loglevel, GfxFont*font) case fontTrueType: logf("%sType: TrueType\n",loglevel); break; + case fontCIDType0: + logf("%sType: CIDType0\n",loglevel); + break; + case fontCIDType0C: + logf("%sType: CIDType0C\n",loglevel); + break; + case fontCIDType2: + logf("%sType: CIDType2\n",loglevel); + break; } - name = font->getEmbeddedFontName(); - if(name) - logf("%sEmbedded name: %s\n",loglevel, name); + + Ref embRef; + GBool embedded = font->getEmbeddedFontID(&embRef); + if(font->getEmbeddedFontName()) + name = font->getEmbeddedFontName()->getCString(); + if(embedded) + logf("%sEmbedded name: %s id: %d\n",loglevel, FIXNULL(name), embRef.num); gstr = font->getExtFontFile(); if(gstr) - logf("%sExternal Font file: %s\n", loglevel, gstr->getCString()); + logf("%sExternal Font file: %s\n", loglevel, FIXNULL(gstr->getCString())); // Get font descriptor flags. if(font->isFixedWidth()) logf("%sis fixed width\n", loglevel); @@ -414,9 +427,15 @@ void dumpFontInfo(char*loglevel, GfxFont*font) SWFOutputDev::SWFOutputDev() { + jpeginfo = 0; + ttfinfo = 0; + linkinfo = 0; + pbminfo = 0; + type3active = 0; clippos = 0; clipping[clippos] = 0; outputstarted = 0; + xref = 0; // printf("SWFOutputDev::SWFOutputDev() \n"); }; @@ -424,10 +443,18 @@ T1_OUTLINE* gfxPath_to_T1_OUTLINE(GfxState*state, GfxPath*path) { int num = path->getNumSubpaths(); int s,t; - bezierpathsegment*start,*last; + bezierpathsegment*start,*last=0; bezierpathsegment*outline = start = new bezierpathsegment(); int cpos = 0; double lastx=0,lasty=0; + if(!num) { + logf(" empty path"); + outline->type = T1_PATHTYPE_MOVE; + outline->dest.x = 0; + outline->dest.y = 0; + outline->link = 0; + return (T1_OUTLINE*)outline; + } for(t = 0; t < num; t++) { GfxSubpath *subpath = path->getSubpath(t); int subnum = subpath->getNumPoints(); @@ -485,58 +512,87 @@ T1_OUTLINE* gfxPath_to_T1_OUTLINE(GfxState*state, GfxPath*path) void SWFOutputDev::stroke(GfxState *state) { - logf(" %s stroke\n",gfxstate2str(state)); + logf(" stroke\n"); GfxPath * path = state->getPath(); + int lineCap = state->getLineCap(); // 0=butt, 1=round 2=square + int lineJoin = state->getLineJoin(); // 0=miter, 1=round 2=bevel + double miterLimit = state->getMiterLimit(); + double width = state->getTransformedLineWidth(); struct swfmatrix m; + GfxRGB rgb; + double opaq = state->getStrokeOpacity(); + state->getStrokeRGB(&rgb); + m.m11 = 1; m.m21 = 0; m.m22 = 1; - m.m21 = 0; m.m13 = 0; m.m23 = 0; + m.m12 = 0; m.m13 = 0; m.m23 = 0; T1_OUTLINE*outline = gfxPath_to_T1_OUTLINE(state, path); - swfoutput_setdrawmode(&output, DRAWMODE_STROKE); - swfoutput_drawpath(&output, outline, &m); + + lineJoin = 1; // other line joins are not yet supported by the swf encoder + // TODO: support bevel joints + + if(((lineCap==1) && (lineJoin==1)) || width<=caplinewidth) { + /* FIXME- if the path is smaller than 2 segments, we could ignore + lineJoin */ + swfoutput_setdrawmode(&output, DRAWMODE_STROKE); + swfoutput_drawpath(&output, outline, &m); + } else { + swfoutput_setfillcolor(&output, (char)(rgb.r*255), (char)(rgb.g*255), + (char)(rgb.b*255), (char)(opaq*255)); + + //swfoutput_setlinewidth(&output, 1.0); //only for debugging + //swfoutput_setstrokecolor(&output, 0, 255, 0, 255); //likewise, see below + //swfoutput_setfillcolor(&output, 255, 0, 0, 255); //likewise, see below + + swfoutput_drawpath2poly(&output, outline, &m, lineJoin, lineCap, width, miterLimit); + updateLineWidth(state); //reset + updateStrokeColor(state); //reset + updateFillColor(state); //reset + } } void SWFOutputDev::fill(GfxState *state) { - logf(" %s fill\n",gfxstate2str(state)); + logf(" fill\n"); GfxPath * path = state->getPath(); struct swfmatrix m; m.m11 = 1; m.m21 = 0; m.m22 = 1; - m.m21 = 0; m.m13 = 0; m.m23 = 0; + m.m12 = 0; m.m13 = 0; m.m23 = 0; T1_OUTLINE*outline = gfxPath_to_T1_OUTLINE(state, path); swfoutput_setdrawmode(&output, DRAWMODE_FILL); swfoutput_drawpath(&output, outline, &m); } void SWFOutputDev::eoFill(GfxState *state) { - logf(" %s eofill\n",gfxstate2str(state)); + logf(" eofill\n"); GfxPath * path = state->getPath(); struct swfmatrix m; m.m11 = 1; m.m21 = 0; m.m22 = 1; - m.m21 = 0; m.m13 = 0; m.m23 = 0; + m.m12 = 0; m.m13 = 0; m.m23 = 0; T1_OUTLINE*outline = gfxPath_to_T1_OUTLINE(state, path); swfoutput_setdrawmode(&output, DRAWMODE_EOFILL); swfoutput_drawpath(&output, outline, &m); } void SWFOutputDev::clip(GfxState *state) { - logf(" %s clip\n",gfxstate2str(state)); + logf(" clip\n"); GfxPath * path = state->getPath(); struct swfmatrix m; - m.m11 = 1; m.m21 = 0; m.m22 = 1; - m.m21 = 0; m.m13 = 0; m.m23 = 0; + 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); swfoutput_startclip(&output, outline, &m); - clipping[clippos] = 1; + clipping[clippos] ++; } void SWFOutputDev::eoClip(GfxState *state) { - logf(" %s eoclip\n",gfxstate2str(state)); + logf(" eoclip\n"); GfxPath * path = state->getPath(); struct swfmatrix m; m.m11 = 1; m.m21 = 0; m.m22 = 1; - m.m21 = 0; m.m13 = 0; m.m23 = 0; + m.m12 = 0; m.m13 = 0; m.m23 = 0; T1_OUTLINE*outline = gfxPath_to_T1_OUTLINE(state, path); swfoutput_startclip(&output, outline, &m); - clipping[clippos] = 1; + clipping[clippos] ++; } SWFOutputDev::~SWFOutputDev() @@ -558,52 +614,104 @@ GBool SWFOutputDev::useDrawChar() void SWFOutputDev::beginString(GfxState *state, GString *s) { double m11,m21,m12,m22; - logf(" %s beginstring \"%s\"\n", gfxstate2str(state), s->getCString()); +// logf(" %s beginstring \"%s\"\n", gfxstate2str(state), s->getCString()); state->getFontTransMat(&m11, &m12, &m21, &m22); m11 *= state->getHorizScaling(); m21 *= state->getHorizScaling(); - swfoutput_setfontmatrix(&output, m11, -m12, m21, -m22); + swfoutput_setfontmatrix(&output, m11, -m21, m12, -m22); } int charcounter = 0; -void SWFOutputDev::drawChar(GfxState *state, double x, double y, double dx, double dy, Guchar c) +void SWFOutputDev::drawChar(GfxState *state, double x, double y, + double dx, double dy, + double originX, double originY, + CharCode c, Unicode *_u, int uLen) { - logf(" %s drawChar(%f,%f,%f,%f,'%c')\n",gfxstate2str(state), x,y,dx,dy,c); + logf(" drawChar(%f,%f,%f,%f,'%c')\n",x,y,dx,dy,c); + // check for invisible text -- this is used by Acrobat Capture - if ((state->getRender() & 3) != 3) - { - FontEncoding*enc=state->getFont()->getEncoding(); + if ((state->getRender() & 3) == 3) + return; - double x1,y1; - x1 = x; - y1 = y; - state->transform(x, y, &x1, &y1); + GfxFont*font = state->getFont(); - swfoutput_drawchar(&output, x1, y1, c); + if(font->getType() == fontType3) { + /* type 3 chars are passed primarily as graphics */ + return; } -} + double x1,y1; + x1 = x; + y1 = y; + state->transform(x, y, &x1, &y1); + + if(font->isCIDFont()) { + GfxCIDFont*cfont = (GfxCIDFont*)font; + Unicode u=0; + char*name=0; + if(_u) + u = *_u; + if(u) { + int t; + for(t=0;tgetName()->getCString(), + cfont->getType());*/ -void SWFOutputDev::drawChar16(GfxState *state, double x, double y, double dx, double dy, int c) -{ - printf(" %s drawChar16(%f,%f,%f,%f,%08x)\n",gfxstate2str(state), x,y,dx,dy,c); - exit(1); + if(name) + swfoutput_drawchar(&output, x1, y1, name, c); + else + logf(" couldn't get name for CID character %02x from Encoding", c); + } else { + Gfx8BitFont*font8; + font8 = (Gfx8BitFont*)font; + char**enc=font8->getEncoding(); + + if(enc && enc[c]) + swfoutput_drawchar(&output, x1, y1, enc[c], c); + else { + logf(" couldn't get name for character %02x from Encoding", c); + } + } } void SWFOutputDev::endString(GfxState *state) { - logf(" %s endstring\n", gfxstate2str(state)); + logf(" endstring\n"); } + +GBool SWFOutputDev::beginType3Char(GfxState *state, + CharCode code, Unicode *u, int uLen) +{ + logf(" beginType3Char %d, %08x, %d", code, *u, uLen); + type3active = 1; + /* the character itself is going to be passed using + drawImageMask() */ + return gFalse; /* gTrue= is_in_cache? */ +} + +void SWFOutputDev::endType3Char(GfxState *state) +{ + type3active = 0; + logf(" endType3Char"); +} + void SWFOutputDev::startPage(int pageNum, GfxState *state) { double x1,y1,x2,y2; - logf(" %s, startPage %d\n", gfxstate2str(state), pageNum); + laststate = state; + logf(" startPage %d\n", pageNum); logf(" processing page %d", pageNum); state->transform(state->getX1(),state->getY1(),&x1,&y1); state->transform(state->getX2(),state->getY2(),&x2,&y2); if(!outputstarted) { - swfoutput_init(&output, filename, abs((int)(x2-x1)),abs((int)(y2-y1))); + swfoutput_init(&output, swffilename, abs((int)(x2-x1)),abs((int)(y2-y1))); outputstarted = 1; } else @@ -619,38 +727,90 @@ void SWFOutputDev::drawLink(Link *link, Catalog *catalog) int x, y; link->getBorder(&x1, &y1, &x2, &y2, &w); - if (w > 0) { +// if (w > 0) + { rgb.r = 0; rgb.g = 0; rgb.b = 1; cvtUserToDev(x1, y1, &x, &y); - points[0].x = points[4].x = x; - points[0].y = points[4].y = y; + points[0].x = points[4].x = (int)x; + points[0].y = points[4].y = (int)y; cvtUserToDev(x2, y1, &x, &y); - points[1].x = x; - points[1].y = y; + points[1].x = (int)x; + points[1].y = (int)y; cvtUserToDev(x2, y2, &x, &y); - points[2].x = x; - points[2].y = y; + points[2].x = (int)x; + points[2].y = (int)y; cvtUserToDev(x1, y2, &x, &y); - points[3].x = x; - points[3].y = y; - //PDF: draw rect + points[3].x = (int)x; + points[3].y = (int)y; + LinkAction*action=link->getAction(); - char*s; + char buf[128]; + char*s = "-?-"; + char*type = "-?-"; + char*url = 0; + char*named = 0; + int page = -1; switch(action->getKind()) { case actionGoTo: { - LinkGoTo*l = (LinkGoTo*)action; - s = l->getNamedDest()->getCString(); + type = "GoTo"; + LinkGoTo *ha=(LinkGoTo *)link->getAction(); + LinkDest *dest=NULL; + if (ha->getDest()==NULL) + dest=catalog->findDest(ha->getNamedDest()); + else dest=ha->getDest(); + if (dest){ + if (dest->isPageRef()){ + Ref pageref=dest->getPageRef(); + page=catalog->findPage(pageref.num,pageref.gen); + } + else page=dest->getPageNum(); + sprintf(buf, "%d", page); + s = buf; + } } break; case actionGoToR: { + type = "GoToR"; LinkGoToR*l = (LinkGoToR*)action; - s = l->getNamedDest()->getCString(); + GString*g = l->getNamedDest(); + if(g) + s = g->getCString(); + } + break; + case actionNamed: { + type = "Named"; + LinkNamed*l = (LinkNamed*)action; + GString*name = l->getName(); + if(name) { + s = name->lowerCase()->getCString(); + named = name->getCString(); + if(!strchr(s,':')) + { + if(strstr(s, "next") || strstr(s, "forward")) + { + page = currentpage + 1; + } + else if(strstr(s, "prev") || strstr(s, "back")) + { + page = currentpage - 1; + } + else if(strstr(s, "last") || strstr(s, "end")) + { + page = pages[pagepos-1]; //:) + } + else if(strstr(s, "first") || strstr(s, "top")) + { + page = 1; + } + } + } } break; case actionLaunch: { + type = "Launch"; LinkLaunch*l = (LinkLaunch*)action; GString * str = new GString(l->getFileName()); str->append(l->getParams()); @@ -658,49 +818,80 @@ void SWFOutputDev::drawLink(Link *link, Catalog *catalog) } break; case actionURI: { + type = "URI"; LinkURI*l = (LinkURI*)action; - s = l->getURI()->getCString(); - } - break; - case actionNamed: { - LinkNamed*l = (LinkNamed*)action; - s = l->getName()->getCString(); + GString*g = l->getURI(); + if(g) { + url = g->getCString(); + s = url; + } } break; case actionUnknown: { + type = "Unknown"; LinkUnknown*l = (LinkUnknown*)action; s = ""; } break; + default: { + logf(" Unknown link type!\n"); + break; + } + } + if(!linkinfo && (page || url)) + { + logf(" File contains links"); + linkinfo = 1; + } + if(page>0) + { + int t; + for(t=0;t link to \"%s\"\n", s); + else if(named) + { + swfoutput_namedlink(&output, named, points); + } + logf(" \"%s\" link to \"%s\" (%d)\n", type, FIXNULL(s), page); } } void SWFOutputDev::saveState(GfxState *state) { - logf(" %s saveState\n", gfxstate2str(state)); + logf(" saveState\n"); updateAll(state); - clippos ++; + if(clippos<64) + clippos ++; + else + logf(" Too many nested states in pdf."); clipping[clippos] = 0; }; void SWFOutputDev::restoreState(GfxState *state) { - logf(" %s restoreState\n", gfxstate2str(state)); + logf(" restoreState\n"); updateAll(state); - if(clipping[clippos]) + while(clipping[clippos]) { swfoutput_endclip(&output); + clipping[clippos]--; + } clippos--; } char type3Warning=0; -int SWFOutputDev::setT1Font(char*name, FontEncoding*encoding) +int SWFOutputDev::searchT1Font(char*name) { int i; - - int id=-1; int mapid=-1; char*filename=0; + for(i=0;i Loading extra font %s from %s\n", FIXNULL(fontname), + FIXNULL(T1_GetFontFileName(i))); + } + + if(fontname && !strcmp(name, fontname)) { + logf(" 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)) { + logf(" Extra font %d, \"%s\" is being used.\n", i, fontname); + return i; + } } } - if(id<0) - return 0; + return -1; +} - initT1Font(id, encoding); +void SWFOutputDev::updateLineWidth(GfxState *state) +{ + double width = state->getTransformedLineWidth(); + swfoutput_setlinewidth(&output, width); } -int SWFOutputDev::initT1Font(int id, FontEncoding*encoding) +void SWFOutputDev::updateLineCap(GfxState *state) { - int encStrSize; - char *encPtr; - int i; - T1_DeleteFont(id); - T1_LoadFont(id); - /* reencode the font: - * This is the only way to get the unmapped characters - * from t1lib - */ - encStrSize = 0; - for (i = 0; i < 256 && i < encoding->getSize(); ++i) { - if (encoding->getCharName(i)) { - encStrSize += strlen(encoding->getCharName(i)) + 1; - } - } - char**enc = (char **)gmalloc(257 * sizeof(char *)); - char*encStr = (char *)gmalloc(encStrSize * sizeof(char)); - encPtr = encStr; - for (i = 0; i < 256 && i < encoding->getSize(); ++i) { - if (encoding->getCharName(i)) { - strcpy(encPtr, encoding->getCharName(i)); - enc[i] = encPtr; - encPtr += strlen(encPtr) + 1; - } else { - enc[i] = ".notdef"; - } - } - for (; i < 256; ++i) { - enc[i] = ".notdef"; - } - enc[256] = "custom"; - int ret=T1_ReencodeFont(id, enc); - t1id = id; - return 1; + int c = state->getLineCap(); } -void SWFOutputDev::updateLineWidth(GfxState *state) +void SWFOutputDev::updateLineJoin(GfxState *state) { - double width = state->getLineWidth(); - swfoutput_setlinewidth(&output, width); + int j = state->getLineJoin(); } void SWFOutputDev::updateFillColor(GfxState *state) @@ -789,106 +974,176 @@ void SWFOutputDev::updateStrokeColor(GfxState *state) (char)(rgb.b*255), (char)(opaq*255)); } -void SWFOutputDev::updateFont(GfxState *state) +char*SWFOutputDev::writeEmbeddedFontToFile(XRef*ref, GfxFont*font) { - double m11, m12, m21, m22; - char * fontname = 0; - GfxFont*gfxFont = state->getFont(); - char * filename; - - if (!gfxFont) { - return; - } - // look for Type 3 font - if (!type3Warning && gfxFont->getType() == fontType3) { - type3Warning = gTrue; - showFontError(gfxFont, 2); - } - //dumpFontInfo (gfxFont); - + char*tmpFileName = NULL; + FILE *f; + int c; + char *fontBuf; + int fontLen; + Type1CFontFile *cvt; + Ref embRef; + Object refObj, strObj; + tmpFileName = "/tmp/tmpfont"; + int ret; + + ret = font->getEmbeddedFontID(&embRef); + if(!ret) { + logf(" Didn't get embedded font id"); + /* not embedded- the caller should now search the font + directories for this font */ + return 0; + } - Ref embRef; - GBool embedded = gfxFont->getEmbeddedFontID(&embRef); - if(embedded) { - char*tmpFileName = NULL; - char*fileName = NULL; - FILE *f; - char *fontBuf; - int fontLen; - Type1CFontConverter *cvt; - Ref embRef; - Object refObj, strObj; - int c; - if (!gfxFont->is16Bit() && - (gfxFont->getType() == fontType1 || - gfxFont->getType() == fontType1C) && - gfxFont->getEmbeddedFontID(&embRef)) { - tmpFileName = "tmpfont"; f = fopen(tmpFileName, "wb"); if (!f) { logf(" Couldn't create temporary Type 1 font file"); - return; + return 0; } - if (gfxFont->getType() == fontType1C) { - if (!(fontBuf = gfxFont->readEmbFontFile(&fontLen))) { + if (font->getType() == fontType1C) { + if (!(fontBuf = font->readEmbFontFile(xref, &fontLen))) { fclose(f); logf(" Couldn't read embedded font file"); - return ; + return 0; } - cvt = new Type1CFontConverter(fontBuf, fontLen, f); - cvt->convert(); + cvt = new Type1CFontFile(fontBuf, fontLen); + cvt->convertToType1(f); delete cvt; gfree(fontBuf); } else { - gfxFont->getEmbeddedFontID(&embRef); + font->getEmbeddedFontID(&embRef); refObj.initRef(embRef.num, embRef.gen); - refObj.fetch(&strObj); + refObj.fetch(ref, &strObj); refObj.free(); strObj.streamReset(); - while ((c = strObj.streamGetChar()) != EOF) { - fputc(c, f); + 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(); } fclose(f); - fileName = tmpFileName; - if(!fileName) { - logf(" Embedded font writer didn't create a file"); - return ; + + if(font->getType() == fontTrueType || + font->getType() == fontCIDType2) + { + if(!ttfinfo) { + logf(" File contains TrueType fonts"); + ttfinfo = 1; + } + char name2[80]; + char*tmp; + tmp = strdup(mktmpname((char*)name2)); + sprintf(name2, "%s", tmp); + char*a[] = {"./ttf2pt1", +#ifndef USE_FREETYPE + "-pttf", +#else + "-pft", +#endif + "-b", tmpFileName, name2}; + logf(" Invoking ttf2pt1..."); + ttf2pt1_main(5,a); + unlink(tmpFileName); + sprintf(name2,"%s.pfb",tmp); + tmpFileName = strdup(name2); } + + return tmpFileName; +} + +char* gfxFontName(GfxFont* gfxFont) +{ + GString *gstr; + gstr = gfxFont->getName(); + if(gstr) { + return gstr->getCString(); + } + else { + char buf[32]; + Ref*r=gfxFont->getID(); + sprintf(buf, "UFONT%d", r->num); + return strdup(buf); + } +} + +char* substitutetarget[256]; +char* substitutesource[256]; +int substitutepos = 0; + +char* SWFOutputDev::substituteFont(GfxFont*gfxFont, char* oldname) +{ +/* ------------------------------ V1 */ + + char*fontname = "Times-Roman"; + logf(" substituteFont(,%s)", FIXNULL(oldname)); + this->t1id = searchT1Font(fontname); + if(substitutepos>=sizeof(substitutesource)/sizeof(char*)) { + logf(" Too many fonts in file."); + exit(1); } - else { - showFontError(gfxFont,0); - return ; - } - t1id = T1_AddFont(fileName); - initT1Font(t1id, gfxFont->getEncoding()); - } else { - fontname = NULL; - if(gfxFont->getName()) { - fontname = gfxFont->getName()->getCString(); - //logf(" Processing font %s", fontname); + if(oldname) { + substitutesource[substitutepos] = oldname; + substitutetarget[substitutepos] = fontname; + logf(" substituting %s -> %s", FIXNULL(oldname), FIXNULL(fontname)); + substitutepos ++; } - if(!fontname || !setT1Font(state->getFont()->getName()->getCString(), gfxFont->getEncoding())) - { //substitute font + 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 (!gfxFont->is16Bit()) { - if (gfxFont->isFixedWidth()) { + 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()) + if (gfxFont->isBold() && index!=16) index += 2; - if (gfxFont->isItalic()) + if (gfxFont->isItalic() && index!=16) index += 1; fontname = fontnames[index]; // get width of 'm' in real font and substituted font @@ -930,91 +1185,547 @@ void SWFOutputDev::updateFont(GfxState *state) } } } - if(fontname) - setT1Font(fontname, gfxFont->getEncoding()); + if(fontname) { + this->t1id = searchT1Font(fontname); + } + if(substitutepos>=sizeof(substitutesource)/sizeof(char*)) { + logf(" Too many fonts in file."); + exit(1); + } + if(oldname) { + substitutesource[substitutepos] = oldname; + substitutetarget[substitutepos] = fontname; + logf(" substituting %s -> %s", FIXNULL(oldname), FIXNULL(fontname)); + substitutepos ++; + } + return fontname;*/ +} + +void unlinkfont(char* filename) +{ + int l; + if(!filename) + return; + l=strlen(filename); + unlink(filename); + if(!strncmp(&filename[l-4],".afm",4)) { + memcpy(&filename[l-4],".pfb",4); + unlink(filename); + memcpy(&filename[l-4],".pfa",4); + unlink(filename); + memcpy(&filename[l-4],".afm",4); + return; + } else + if(!strncmp(&filename[l-4],".pfa",4)) { + memcpy(&filename[l-4],".afm",4); + unlink(filename); + memcpy(&filename[l-4],".pfa",4); + return; + } else + if(!strncmp(&filename[l-4],".pfb",4)) { + memcpy(&filename[l-4],".afm",4); + unlink(filename); + memcpy(&filename[l-4],".pfb",4); + return; } - } +} - swfoutput_setfont(&output,gfxFont->getID().num,t1id); +void SWFOutputDev::startDoc(XRef *xref) +{ + this->xref = xref; } -void SWFOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str, - int width, int height, GBool invert, - GBool inlineImg) { - FILE *fi; - int c; - char fileName[128]; - double x1,y1,x2,y2,x3,y3,x4,y4; - state->transform(0, 1, &x1, &y1); - state->transform(0, 0, &x2, &y2); - state->transform(1, 0, &x3, &y3); - state->transform(1, 1, &x4, &y4); - if (str->getKind() == strDCT) { - sprintf(fileName, "/tmp/tmp%08x.jpg",lrand48()); - logf(" Found picture. Temporary storage is %s", fileName); - if (!(fi = fopen(fileName, "wb"))) { - logf(" Couldn't open temporary image file '%s'", fileName); +void SWFOutputDev::updateFont(GfxState *state) +{ + GfxFont*gfxFont = state->getFont(); + char * fileName = 0; + + if (!gfxFont) { + return; + } + char * fontname = gfxFontName(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;tgetType() == fontType3) { + type3Warning = gTrue; + showFontError(gfxFont, 2); + } + + /* now either load the font, or find a substitution */ + + Ref embRef; + GBool embedded = gfxFont->getEmbeddedFontID(&embRef); + if(embedded) { + if (gfxFont->getType() == fontType1 || + gfxFont->getType() == fontType1C || + gfxFont->getType() == fontTrueType || + gfxFont->getType() == fontCIDType2) + { + fileName = writeEmbeddedFontToFile(xref, gfxFont); + if(!fileName) { + logf(" Couldn't write font to file"); + showFontError(gfxFont,0); + return ; + } + this->t1id = T1_AddFont(fileName); + if(this->t1id<0) { + logf(" Couldn't load font from file"); + 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) { + showFontError(gfxFont,0); + fontname = substituteFont(gfxFont, fontname); + } else + this->t1id = newt1id; } - str = ((DCTStream *)str)->getRawStream(); - str->reset(); - while ((c = str->getChar()) != EOF) - fputc(c, fi); - fclose(fi); - swfoutput_drawimagefile(&output, fileName, width, height, x1,y1,x2,y2,x3,y3,x4,y4); } else { - logf(" File contains pbm pictures."); + 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); + } } + + if(t1id<0) { + 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; + } + + logf(" 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); } -void SWFOutputDev::drawImage(GfxState *state, Object *ref, Stream *str, - int width, int height, - GfxImageColorMap *colorMap, GBool inlineImg) { +int pic_xids[1024]; +int pic_yids[1024]; +int pic_ids[1024]; +int pic_width[1024]; +int pic_height[1024]; +int picpos = 0; +int pic_id = 0; + +#define SQR(x) ((x)*(x)) + +unsigned char* antialize(unsigned char*data, int width, int height, int newwidth, int newheight, int palettesize) +{ + if((newwidth<2 || newheight<2) || + (width<=newwidth || height<=newheight)) + return 0; + unsigned char*newdata; + int x,y; + newdata= (unsigned char*)malloc(newwidth*newheight); + int t; + double fx = (double)(width)/newwidth; + double fy = (double)(height)/newheight; + double px = 0; + int blocksize = (int)(8192/(fx*fy)); + int r = 8192*256/palettesize; + for(x=0;xgetNumPixelComps(); + bits = colorMap->getBits(); + } + imgStr = new ImageStream(str, width, ncomps,bits); + imgStr->reset(); + + if(!width || !height || (height<=1 && width<=1)) + { + logf(" Ignoring %d by %d image", width, height); + unsigned char buf[8]; + int x,y; + for (y = 0; y < height; ++y) + for (x = 0; x < width; ++x) { + imgStr->getPixel(buf); + } + delete imgStr; + return; + } + state->transform(0, 1, &x1, &y1); state->transform(0, 0, &x2, &y2); state->transform(1, 0, &x3, &y3); state->transform(1, 1, &x4, &y4); - if (str->getKind() == strDCT && - colorMap->getNumPixelComps() == 3) { - sprintf(fileName, "/tmp/tmp%08x.jpg", lrand48()); - logf(" Found picture. Temporary storage is %s", fileName); - if (!(fi = fopen(fileName, "wb"))) { - error(-1, "Couldn't open temporary image file '%s'", fileName); + if(!pbminfo && !(str->getKind()==strDCT)) { + if(!type3active) { + logf(" file contains pbm pictures %s",mask?"(masked)":""); + pbminfo = 1; + } + if(mask) + logf(" drawing %d by %d masked picture\n", width, height); + } + if(!jpeginfo && (str->getKind()==strDCT)) { + logf(" file contains jpeg pictures"); + jpeginfo = 1; + } + + if(mask) { + int yes=0,i,j; + unsigned char buf[8]; + int xid = 0; + int yid = 0; + int x,y; + unsigned char*pic = new unsigned char[width*height]; + RGBA pal[256]; + GfxRGB rgb; + state->getFillRGB(&rgb); + memset(pal,255,sizeof(pal)); + pal[0].r = (int)(rgb.r*255); pal[0].g = (int)(rgb.g*255); + pal[0].b = (int)(rgb.b*255); pal[0].a = 255; + pal[1].r = 0; pal[1].g = 0; pal[1].b = 0; pal[1].a = 0; + int numpalette = 2; + xid += pal[1].r*3 + pal[1].g*11 + pal[1].b*17; + yid += pal[1].r*7 + pal[1].g*5 + pal[1].b*23; + int realwidth = (int)sqrt(SQR(x2-x3) + SQR(y2-y3)); + int realheight = (int)sqrt(SQR(x1-x2) + SQR(y1-y2)); + for (y = 0; y < height; ++y) + for (x = 0; x < width; ++x) + { + imgStr->getPixel(buf); + if(invert) + buf[0]=1-buf[0]; + pic[width*y+x] = buf[0]; + xid+=x*buf[0]+1; + yid+=y*buf[0]*3+1; + } + + /* 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): */ + if(type3active) { + xid += realwidth; + yid += realheight; + } + int t,found = -1; + for(t=0;tgetNumPixelComps()!=1 || str->getKind()==strDCT) + { + RGBA*pic=new RGBA[width*height]; + int xid = 0; + int yid = 0; + for (y = 0; y < height; ++y) { + for (x = 0; x < width; ++x) { + int r,g,b,a; + imgStr->getPixel(pixBuf); + colorMap->getRGB(pixBuf, &rgb); + pic[width*y+x].r = r = (U8)(rgb.r * 255 + 0.5); + pic[width*y+x].g = g = (U8)(rgb.g * 255 + 0.5); + pic[width*y+x].b = b = (U8)(rgb.b * 255 + 0.5); + pic[width*y+x].a = a = 255;//(U8)(rgb.a * 255 + 0.5); + xid += x*r+x*b*3+x*g*7+x*a*11; + yid += y*r*3+y*b*17+y*g*19+y*a*11; + } + } + int t,found = -1; + for(t=0;tgetKind()==strDCT) + pic_ids[picpos] = swfoutput_drawimagejpeg(&output, pic, width, height, + x1,y1,x2,y2,x3,y3,x4,y4); + else + pic_ids[picpos] = swfoutput_drawimagelossless(&output, pic, width, height, + x1,y1,x2,y2,x3,y3,x4,y4); + pic_xids[picpos] = xid; + pic_yids[picpos] = yid; + pic_width[picpos] = width; + pic_height[picpos] = height; + if(picpos<1024) + picpos++; + } else { + swfoutput_drawimageagain(&output, pic_ids[found], width, height, + x1,y1,x2,y2,x3,y3,x4,y4); + } + delete pic; + delete imgStr; return; - } - str = ((DCTStream *)str)->getRawStream(); - str->reset(); - while ((c = str->getChar()) != EOF) - fputc(c, fi); - fclose(fi); - swfoutput_drawimagefile(&output, fileName, width, height, x1,y1,x2,y2,x3,y3,x4,y4); - } else { - logf(" File contains pbm pictures."); } + else + { + U8*pic = new U8[width*height]; + RGBA pal[256]; + int t; + int xid=0,yid=0; + for(t=0;t<256;t++) + { + int r,g,b,a; + pixBuf[0] = t; + colorMap->getRGB(pixBuf, &rgb); + pal[t].r = r = (U8)(rgb.r * 255 + 0.5); + pal[t].g = g = (U8)(rgb.g * 255 + 0.5); + pal[t].b = b = (U8)(rgb.b * 255 + 0.5); + pal[t].a = a = 255;//(U8)(rgb.b * 255 + 0.5); + xid += t*r+t*b*3+t*g*7+t*a*11; + xid += (~t)*r+t*b*3+t*g*7+t*a*11; + } + for (y = 0; y < height; ++y) { + for (x = 0; x < width; ++x) { + imgStr->getPixel(pixBuf); + pic[width*y+x] = pixBuf[0]; + xid += x*pixBuf[0]*7; + yid += y*pixBuf[0]*3; + } + } + int found = -1; + for(t=0;t drawImageMask %dx%d, invert=%d inline=%d", width, height, invert, inlineImg); + drawGeneralImage(state,ref,str,width,height,0,invert,inlineImg,1); +} + +void SWFOutputDev::drawImage(GfxState *state, Object *ref, Stream *str, + int width, int height, GfxImageColorMap *colorMap, + int *maskColors, GBool inlineImg) +{ + logf(" drawImage %dx%d, %s %s, inline=%d", width, height, + colorMap?"colorMap":"no colorMap", + maskColors?"maskColors":"no maskColors", + inlineImg); + if(colorMap) + logf(" colorMap pixcomps:%d bits:%d mode:%d\n", colorMap->getNumPixelComps(), + colorMap->getBits(),colorMap->getColorSpace()->getMode()); + drawGeneralImage(state,ref,str,width,height,colorMap,0,inlineImg,0); } -PDFDoc*doc = 0; SWFOutputDev*output = 0; +static void printInfoString(Dict *infoDict, char *key, char *fmt) { + Object obj; + GString *s1, *s2; + int i; + + if (infoDict->lookup(key, &obj)->isString()) { + s1 = obj.getString(); + if ((s1->getChar(0) & 0xff) == 0xfe && + (s1->getChar(1) & 0xff) == 0xff) { + s2 = new GString(); + for (i = 2; i < obj.getString()->getLength(); i += 2) { + if (s1->getChar(i) == '\0') { + s2->append(s1->getChar(i+1)); + } else { + delete s2; + s2 = new GString(""); + break; + } + } + printf(fmt, s2->getCString()); + delete s2; + } else { + printf(fmt, s1->getCString()); + } + } + obj.free(); +} + +static void printInfoDate(Dict *infoDict, char *key, char *fmt) { + Object obj; + char *s; + + if (infoDict->lookup(key, &obj)->isString()) { + s = obj.getString()->getCString(); + if (s[0] == 'D' && s[1] == ':') { + s += 2; + } + printf(fmt, s); + } + obj.free(); +} + void pdfswf_init(char*filename, char*userPassword) { GString *fileName = new GString(filename); GString *userPW; Object info; - // init error file - errorInit(); // read config file - initParams(xpdfConfigFile); + globalParams = new GlobalParams(""); // open PDF file - xref = NULL; if (userPassword && userPassword[0]) { userPW = new GString(userPassword); } else { @@ -1030,7 +1741,8 @@ void pdfswf_init(char*filename, char*userPassword) // print doc info doc->getDocInfo(&info); - if (info.isDict()) { + if (info.isDict() && + (screenloglevel>=LOGLEVEL_NOTICE)) { printInfoString(info.getDict(), "Title", "Title: %s\n"); printInfoString(info.getDict(), "Subject", "Subject: %s\n"); printInfoString(info.getDict(), "Keywords", "Keywords: %s\n"); @@ -1039,23 +1751,23 @@ void pdfswf_init(char*filename, char*userPassword) printInfoString(info.getDict(), "Producer", "Producer: %s\n"); printInfoDate(info.getDict(), "CreationDate", "CreationDate: %s\n"); printInfoDate(info.getDict(), "ModDate", "ModDate: %s\n"); + printf("Pages: %d\n", doc->getNumPages()); + printf("Linearized: %s\n", doc->isLinearized() ? "yes" : "no"); + printf("Encrypted: "); + if (doc->isEncrypted()) { + printf("yes (print:%s copy:%s change:%s addNotes:%s)\n", + doc->okToPrint() ? "yes" : "no", + doc->okToCopy() ? "yes" : "no", + doc->okToChange() ? "yes" : "no", + doc->okToAddNotes() ? "yes" : "no"); + } else { + printf("no\n"); + } } info.free(); - // print page count - printf("Pages: %d\n", doc->getNumPages()); - - // print linearization info - printf("Linearized: %s\n", doc->isLinearized() ? "yes" : "no"); - - // print encryption info - printf("Encrypted: "); + numpages = doc->getNumPages(); if (doc->isEncrypted()) { - printf("yes (print:%s copy:%s change:%s addNotes:%s)\n", - doc->okToPrint() ? "yes" : "no", - doc->okToCopy() ? "yes" : "no", - doc->okToChange() ? "yes" : "no", - doc->okToAddNotes() ? "yes" : "no"); /*ERROR: This pdf is encrypted, and disallows copying. Due to the DMCA, paragraph 1201, (2) A-C, circumventing a technological measure that efficively controls access to @@ -1068,38 +1780,140 @@ void pdfswf_init(char*filename, char*userPassword) } if(!doc->okToChange() || !doc->okToAddNotes()) swfoutput_setprotected(); - } - else { - printf("no\n"); } - output = new SWFOutputDev(); + output->startDoc(doc->getXRef()); +} + +void pdfswf_setparameter(char*name, char*value) +{ + if(!strcmp(name, "drawonlyshapes")) { + drawonlyshapes = atoi(value); + } else if(!strcmp(name, "ignoredraworder")) { + ignoredraworder = atoi(value); + } else if(!strcmp(name, "linksopennewwindow")) { + opennewwindow = atoi(value); + } else if(!strcmp(name, "storeallcharacters")) { + storeallcharacters = atoi(value); + } else if(!strcmp(name, "enablezlib")) { + enablezlib = atoi(value); + } else if(!strcmp(name, "insertstop")) { + insertstoptag = atoi(value); + } else if(!strcmp(name, "flashversion")) { + flashversion = atoi(value); + } else if(!strcmp(name, "jpegquality")) { + int val = atoi(value); + if(val<0) val=0; + if(val>100) val=100; + jpegquality = val; + } else if(!strcmp(name, "outputfilename")) { + swffilename = value; + } else if(!strcmp(name, "caplinewidth")) { + caplinewidth = atof(value); + } else if(!strcmp(name, "splinequality")) { + int v = atoi(value); + v = 500-(v*5); // 100% = 0.25 pixel, 0% = 25 pixel + if(v<1) v = 1; + splinemaxerror = v; + } else if(!strcmp(name, "fontquality")) { + int v = atoi(value); + v = 500-(v*5); // 100% = 0.25 pixel, 0% = 25 pixel + if(v<1) v = 1; + fontsplinemaxerror = v; + } else { + fprintf(stderr, "unknown parameter: %s (=%s)\n", name, value); + } +} + +void pdfswf_drawonlyshapes() +{ + drawonlyshapes = 1; +} + +void pdfswf_ignoredraworder() +{ + ignoredraworder = 1; +} + +void pdfswf_linksopennewwindow() +{ + opennewwindow = 1; +} + +void pdfswf_storeallcharacters() +{ + storeallcharacters = 1; +} + +void pdfswf_enablezlib() +{ + enablezlib = 1; +} + +void pdfswf_jpegquality(int val) +{ + if(val<0) val=0; + if(val>100) val=100; + jpegquality = val; } void pdfswf_setoutputfilename(char*_filename) { - filename = _filename; + swffilename = _filename; } +void pdfswf_insertstop() +{ + insertstoptag = 1; +} + +void pdfswf_setversion(int n) +{ + flashversion = n; +} + + void pdfswf_convertpage(int page) { - doc->displayPage((OutputDev*)output, page, /*zoom*/100, /*rotate*/0, /*doLinks*/(int)1); + if(!pages) + { + pages = (int*)malloc(1024*sizeof(int)); + pagebuflen = 1024; + } else { + if(pagepos == pagebuflen) + { + pagebuflen+=1024; + pages = (int*)realloc(pages, pagebuflen); + } + } + pages[pagepos++] = page; +} + +void pdfswf_performconversion() +{ + int t; + for(t=0;tdisplayPage((OutputDev*)output, currentpage, /*dpi*/72, /*rotate*/0, /*doLinks*/(int)1); + } } int pdfswf_numpages() { return doc->getNumPages(); } - +int closed=0; void pdfswf_close() { - delete doc; + logf(" pdfswf.cc: pdfswf_close()"); delete output; - - freeParams(); + delete doc; + //freeParams(); // check for memory leaks Object::memCheck(stderr); gMemReport(stderr); } +