X-Git-Url: http://git.asbjorn.it/?a=blobdiff_plain;ds=sidebyside;f=pdf2swf%2FSWFOutputDev.cc;h=0992ed96c39bc379e125e17ad0b07a2e87a978ff;hb=5fa2ba8aaca9efa62430b2866ddee66705f3349d;hp=ad411a934d0d39f9d8ada82d5dfa3685f1345500;hpb=864398ba4b887122ae6fa04f8eb2e9d630b990a5;p=swftools.git diff --git a/pdf2swf/SWFOutputDev.cc b/pdf2swf/SWFOutputDev.cc index ad411a9..0992ed9 100644 --- a/pdf2swf/SWFOutputDev.cc +++ b/pdf2swf/SWFOutputDev.cc @@ -45,11 +45,18 @@ #include "GfxFont.h" #include "CharCodeToUnicode.h" #include "NameToUnicodeTable.h" -#include "FontFile.h" #include "GlobalParams.h" +//#define XPDF_101 +#ifdef XPDF_101 +#include "FontFile.h" +#else +#include "FoFiType1C.h" +#include "FoFiTrueType.h" +#endif +#include "SWFOutputDev.h" + //swftools header files #include "swfoutput.h" -#include "SWFOutputDev.h" #include "../lib/log.h" #include @@ -79,38 +86,9 @@ static int zoom = 72; /* xpdf: 86 */ static void printInfoString(Dict *infoDict, char *key, char *fmt); static void printInfoDate(Dict *infoDict, char *key, char *fmt); -static 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.733 //? -}; -static char*fontnames[]={ -"Helvetica", -"Helvetica-Bold", -"Helvetica-BoldOblique", -"Helvetica-Oblique", -"Times-Roman", -"Times-Bold", -"Times-BoldItalic", -"Times-Italic", -"Courier", -"Courier-Bold", -"Courier-BoldOblique", -"Courier-Oblique", -"Symbol", -"Symbol", -"Symbol", -"Symbol", -"ZapfDingBats" -}; - struct mapping { char*pdffont; char*filename; - int id; } pdf2t1map[] ={ {"Times-Roman", "n021003l"}, {"Times-Italic", "n021023l"}, @@ -127,9 +105,6 @@ struct mapping { {"Symbol", "s050000l"}, {"ZapfDingbats", "d050000l"}}; -class GfxState; -class GfxImageColorMap; - class SWFOutputDev: public OutputDev { struct swfoutput output; int outputstarted; @@ -150,6 +125,9 @@ public: // Does this device use drawChar() or drawString()? virtual GBool useDrawChar(); + // Can this device draw gradients? + virtual GBool useGradients(); + virtual GBool interpretType3Chars() {return gTrue;} //----- initialization and control @@ -231,10 +209,42 @@ public: 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 gradientinfo; // did we write "File contains Gradients yet? int type3active; // are we between beginType3()/endType3()? GfxState *laststate; + + int pic_xids[1024]; + int pic_yids[1024]; + int pic_ids[1024]; + int pic_width[1024]; + int pic_height[1024]; + int picpos; + int pic_id; + char type3Warning; + + char* substitutetarget[256]; + char* substitutesource[256]; + int substitutepos; +}; + +SWFOutputDev::SWFOutputDev() +{ + jpeginfo = 0; + ttfinfo = 0; + linkinfo = 0; + pbminfo = 0; + type3active = 0; + clippos = 0; + clipping[clippos] = 0; + outputstarted = 0; + xref = 0; + picpos = 0; + pic_id = 0; + substitutepos = 0; + type3Warning = 0; +// printf("SWFOutputDev::SWFOutputDev() \n"); }; static char*getFontID(GfxFont*font) @@ -259,8 +269,8 @@ static char*getFontName(GfxFont*font) return fontname; } -char mybuf[1024]; -char* gfxstate2str(GfxState *state) +static char mybuf[1024]; +static char* gfxstate2str(GfxState *state) { char*bufpos = mybuf; GfxRGB rgb; @@ -366,16 +376,14 @@ char* gfxstate2str(GfxState *state) return mybuf; } - - -void dumpFontInfo(char*loglevel, GfxFont*font); -int lastdumps[1024]; -int lastdumppos = 0; +static void dumpFontInfo(char*loglevel, GfxFont*font); +static int lastdumps[1024]; +static int lastdumppos = 0; /* nr = 0 unknown nr = 1 substituting nr = 2 type 3 */ -void showFontError(GfxFont*font, int nr) +static void showFontError(GfxFont*font, int nr) { Ref*r=font->getID(); int t; @@ -395,7 +403,7 @@ void showFontError(GfxFont*font, int nr) dumpFontInfo("", font); } -void dumpFontInfo(char*loglevel, GfxFont*font) +static void dumpFontInfo(char*loglevel, GfxFont*font) { char* name = getFontID(font); Ref* r=font->getID(); @@ -457,19 +465,14 @@ void dumpFontInfo(char*loglevel, GfxFont*font) //void SWFOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str, int width, int height, GBool invert, GBool inlineImg) {printf("void SWFOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str, int width, int height, GBool invert, GBool inlineImg) \n");} //void SWFOutputDev::drawImage(GfxState *state, Object *ref, Stream *str, int width, int height, GfxImageColorMap *colorMap, GBool inlineImg) {printf("void SWFOutputDev::drawImage(GfxState *state, Object *ref, Stream *str, int width, int height, GfxImageColorMap *colorMap, GBool inlineImg) \n");} -SWFOutputDev::SWFOutputDev() +static void free_outline(SWF_OUTLINE*outline) { - jpeginfo = 0; - ttfinfo = 0; - linkinfo = 0; - pbminfo = 0; - type3active = 0; - clippos = 0; - clipping[clippos] = 0; - outputstarted = 0; - xref = 0; -// printf("SWFOutputDev::SWFOutputDev() \n"); -}; + while(outline) { + SWF_OUTLINE*next = outline->link; + free(outline); + outline = next; + } +} SWF_OUTLINE* gfxPath_to_SWF_OUTLINE(GfxState*state, GfxPath*path) { @@ -580,6 +583,7 @@ void SWFOutputDev::stroke(GfxState *state) updateStrokeColor(state); //reset updateFillColor(state); //reset } + free_outline(outline); } void SWFOutputDev::fill(GfxState *state) { @@ -629,6 +633,7 @@ void SWFOutputDev::eoClip(GfxState *state) SWFOutputDev::~SWFOutputDev() { + swfoutput_save(&output, swffilename); swfoutput_destroy(&output); outputstarted = 0; }; @@ -641,6 +646,15 @@ GBool SWFOutputDev::useDrawChar() { return gTrue; } +GBool SWFOutputDev::useGradients() +{ + if(!gradientinfo) + { + msg(" File contains gradients"); + gradientinfo = 1; + } + return gTrue; +} void SWFOutputDev::beginString(GfxState *state, GString *s) { @@ -650,9 +664,6 @@ void SWFOutputDev::beginString(GfxState *state, GString *s) m11 *= state->getHorizScaling(); m21 *= state->getHorizScaling(); swfoutput_setfontmatrix(&output, m11, -m21, m12, -m22); - - msg(" fontmatrix %7.3f %7.3f\n", m11,-m21); - msg(" fontmatrix %7.3f %7.3f\n", m12,-m22); } void SWFOutputDev::drawChar(GfxState *state, double x, double y, @@ -676,9 +687,9 @@ void SWFOutputDev::drawChar(GfxState *state, double x, double y, state->transform(x, y, &x1, &y1); Unicode u=0; - if(_u) + if(_u && uLen) u = *_u; - + /* find out the character name */ char*name=0; if(font->isCIDFont() && u) { @@ -736,8 +747,6 @@ void SWFOutputDev::startPage(int pageNum, GfxState *state, double crop_x1, doubl if(rot!=0) msg(" page is rotated %d degrees\n", rot); - msg(" processing page %d", pageNum); - /* state->transform(state->getX1(),state->getY1(),&x1,&y1); state->transform(state->getX2(),state->getY2(),&x2,&y2); Use CropBox, not MediaBox, as page size @@ -755,24 +764,26 @@ void SWFOutputDev::startPage(int pageNum, GfxState *state, double crop_x1, doubl if(!outputstarted) { msg(" Bounding box is (%f,%f)-(%f,%f)", x1,y1,x2,y2); - swfoutput_init(&output, swffilename,(int)x1,(int)y1,(int)x2,(int)y2); + swfoutput_init(&output); outputstarted = 1; } - else - swfoutput_newpage(&output); + + swfoutput_newpage(&output, pageNum, (int)x1, (int)y1, (int)x2, (int)y2); } void SWFOutputDev::drawLink(Link *link, Catalog *catalog) { - msg(" drawlink\n"); - double x1, y1, x2, y2, w; - GfxRGB rgb; - swfcoord points[5]; - int x, y; + msg(" drawlink\n"); + double x1, y1, x2, y2, w; + GfxRGB rgb; + swfcoord points[5]; + int x, y; - link->getBorder(&x1, &y1, &x2, &y2, &w); -// if (w > 0) - { +#ifdef XPDF_101 + link->getBorder(&x1, &y1, &x2, &y2, &w); +#else + link->getRect(&x1, &y1, &x2, &y2); +#endif rgb.r = 0; rgb.g = 0; rgb.b = 1; @@ -791,121 +802,124 @@ void SWFOutputDev::drawLink(Link *link, Catalog *catalog) LinkAction*action=link->getAction(); char buf[128]; - char*s = "-?-"; + char*s = 0; char*type = "-?-"; char*url = 0; char*named = 0; int page = -1; switch(action->getKind()) { - case actionGoTo: { - 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; - } - } + case actionGoTo: { + 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 = strdup(buf); + } + } break; - case actionGoToR: { - type = "GoToR"; - LinkGoToR*l = (LinkGoToR*)action; - GString*g = l->getNamedDest(); - if(g) - s = g->getCString(); - } + case actionGoToR: { + type = "GoToR"; + LinkGoToR*l = (LinkGoToR*)action; + GString*g = l->getNamedDest(); + if(g) + s = strdup(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; - } - } - } - } + case actionNamed: { + type = "Named"; + LinkNamed*l = (LinkNamed*)action; + GString*name = l->getName(); + if(name) { + s = strdup(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()); - s = str->getCString(); - } + case actionLaunch: { + type = "Launch"; + LinkLaunch*l = (LinkLaunch*)action; + GString * str = new GString(l->getFileName()); + str->append(l->getParams()); + s = strdup(str->getCString()); + delete str; + } break; - case actionURI: { - type = "URI"; - LinkURI*l = (LinkURI*)action; - GString*g = l->getURI(); - if(g) { - url = g->getCString(); - s = url; - } - } + case actionURI: { + type = "URI"; + LinkURI*l = (LinkURI*)action; + GString*g = l->getURI(); + if(g) { + url = g->getCString(); + s = strdup(url); + } + } break; - case actionUnknown: { - type = "Unknown"; - LinkUnknown*l = (LinkUnknown*)action; - s = ""; - } + case actionUnknown: { + type = "Unknown"; + LinkUnknown*l = (LinkUnknown*)action; + s = strdup(""); + } break; - default: { - msg(" Unknown link type!\n"); - break; - } + default: { + msg(" Unknown link type!\n"); + break; + } } + if(!s) s = strdup("-?-"); + if(!linkinfo && (page || url)) { - msg(" File contains links"); - linkinfo = 1; + msg(" File contains links"); + linkinfo = 1; } if(page>0) { - int t; - for(t=0;t \"%s\" link to \"%s\" (%d)\n", type, FIXNULL(s), page); - } + free(s);s=0; } void SWFOutputDev::saveState(GfxState *state) { @@ -928,8 +942,6 @@ void SWFOutputDev::restoreState(GfxState *state) { clippos--; } -char type3Warning=0; - char* SWFOutputDev::searchFont(char*name) { int i; @@ -1001,6 +1013,11 @@ void SWFOutputDev::updateStrokeColor(GfxState *state) (char)(rgb.b*255), (char)(opaq*255)); } +void FoFiWrite(void *stream, char *data, int len) +{ + fwrite(data, len, 1, (FILE*)stream); +} + char*SWFOutputDev::writeEmbeddedFontToFile(XRef*ref, GfxFont*font) { char*tmpFileName = NULL; @@ -1041,8 +1058,13 @@ char*SWFOutputDev::writeEmbeddedFontToFile(XRef*ref, GfxFont*font) msg(" Couldn't read embedded font file"); return 0; } +#ifdef XPDF_101 Type1CFontFile *cvt = new Type1CFontFile(fontBuf, fontLen); cvt->convertToType1(f); +#else + FoFiType1C *cvt = FoFiType1C::make(fontBuf, fontLen); + cvt->convertToType1(NULL, gTrue, FoFiWrite, f); +#endif //cvt->convertToCIDType0("test", f); //cvt->convertToType0("test", f); delete cvt; @@ -1054,8 +1076,13 @@ char*SWFOutputDev::writeEmbeddedFontToFile(XRef*ref, GfxFont*font) msg(" Couldn't read embedded font file"); return 0; } +#ifdef XPDF_101 TrueTypeFontFile *cvt = new TrueTypeFontFile(fontBuf, fontLen); cvt->writeTTF(f); +#else + FoFiTrueType *cvt = FoFiTrueType::make(fontBuf, fontLen); + cvt->writeTTF(FoFiWrite, f); +#endif delete cvt; gfree(fontBuf); } else { @@ -1097,11 +1124,6 @@ char*SWFOutputDev::writeEmbeddedFontToFile(XRef*ref, GfxFont*font) return strdup(tmpFileName); } - -char* substitutetarget[256]; -char* substitutesource[256]; -int substitutepos = 0; - char* searchForSuitableFont(GfxFont*gfxFont) { char*name = getFontName(gfxFont); @@ -1335,14 +1357,6 @@ void SWFOutputDev::updateFont(GfxState *state) unlinkfont(fileName); } -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) @@ -1712,66 +1726,70 @@ static void printInfoDate(Dict *infoDict, char *key, char *fmt) { void pdfswf_init(char*filename, char*userPassword) { - GString *fileName = new GString(filename); - GString *userPW; - Object info; - - // read config file - globalParams = new GlobalParams(""); - - // open PDF file - if (userPassword && userPassword[0]) { - userPW = new GString(userPassword); - } else { - userPW = NULL; - } - doc = new PDFDoc(fileName, userPW); - if (userPW) { - delete userPW; - } - if (!doc->isOk()) { - exit(1); - } + GString *fileName = new GString(filename); + GString *userPW; + Object info; - // print doc info - doc->getDocInfo(&info); - 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"); - printInfoString(info.getDict(), "Author", "Author: %s\n"); - printInfoString(info.getDict(), "Creator", "Creator: %s\n"); - 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"); + // read config file + globalParams = new GlobalParams(""); + + // open PDF file + if (userPassword && userPassword[0]) { + userPW = new GString(userPassword); } else { - printf("no\n"); + userPW = NULL; + } + doc = new PDFDoc(fileName, userPW); + if (userPW) { + delete userPW; + } + if (!doc->isOk()) { + exit(1); } - } - info.free(); - - numpages = doc->getNumPages(); - if (doc->isEncrypted()) { - if(!doc->okToCopy()) { - printf("PDF disallows copying. Bailing out.\n"); - exit(1); //bail out - } - if(!doc->okToChange() || !doc->okToAddNotes()) - swfoutput_setprotected(); - } - output = new SWFOutputDev(); - output->startDoc(doc->getXRef()); + // print doc info + doc->getDocInfo(&info); + 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"); + printInfoString(info.getDict(), "Author", "Author: %s\n"); + printInfoString(info.getDict(), "Creator", "Creator: %s\n"); + 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(); + + numpages = doc->getNumPages(); + int protect = 0; + if (doc->isEncrypted()) { + if(!doc->okToCopy()) { + printf("PDF disallows copying. Terminating.\n"); + exit(1); //bail out + } + if(!doc->okToChange() || !doc->okToAddNotes()) + protect = 1; + } + + if(protect) + swfoutput_setparameter("protect", "1"); + + output = new SWFOutputDev(); + output->startDoc(doc->getXRef()); } void pdfswf_setparameter(char*name, char*value) @@ -1795,27 +1813,7 @@ void pdfswf_addfont(char*filename) fonts[fontnum++] = f; } -/* TODO: get rid of this */ -void pdfswf_drawonlyshapes() { pdfswf_setparameter("drawonlyshapes", "1"); } -void pdfswf_ignoredraworder() { pdfswf_setparameter("ignoredraworder", "1"); } -void pdfswf_linksopennewwindow() { pdfswf_setparameter("opennewwindow", "1"); } -void pdfswf_storeallcharacters() { pdfswf_setparameter("storeallcharacters", "1"); } -void pdfswf_enablezlib() { pdfswf_setparameter("enablezlib", "1"); } void pdfswf_setoutputfilename(char*_filename) { swffilename = _filename; } -void pdfswf_insertstop() { pdfswf_setparameter("insertstoptag", "1"); } - -void pdfswf_jpegquality(int val) { - char tmp[32]; - sprintf(tmp, "%d", val); - pdfswf_setparameter("jpegquality", tmp); -} -void pdfswf_setversion(int n) { - char tmp[32]; - sprintf(tmp, "%d", n); - pdfswf_setparameter("flashversion", tmp); -} - - void pdfswf_convertpage(int page) { @@ -1839,19 +1837,23 @@ void pdfswf_performconversion() for(t=0;tdisplayPage((OutputDev*)output, currentpage, /*zoom*/zoom, /*rotate*/0, /*doLinks*/(int)1); +#else + doc->displayPage((OutputDev*)output, currentpage, zoom, zoom, /*rotate*/0, true, /*doLinks*/(int)1); +#endif } } int pdfswf_numpages() { return doc->getNumPages(); } -int closed=0; void pdfswf_close() { msg(" pdfswf.cc: pdfswf_close()"); - delete output; - delete doc; + delete output; output=0; + delete doc; doc=0; + free(pages); pages = 0; //freeParams(); // check for memory leaks Object::memCheck(stderr);