X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=pdf2swf%2FSWFOutputDev.cc;h=23cb0c361d0d19a36b6172757f716fe77ccb5e53;hb=b4d8a377dda2304c89718985b2c2309d2109e036;hp=81a62117f43ab8917600fd340b1fbd2d405b6bae;hpb=74d13887e9c68f8e4aa2cda5ba7b0c764df0bf86;p=swftools.git diff --git a/pdf2swf/SWFOutputDev.cc b/pdf2swf/SWFOutputDev.cc index 81a6211..23cb0c3 100644 --- a/pdf2swf/SWFOutputDev.cc +++ b/pdf2swf/SWFOutputDev.cc @@ -61,25 +61,23 @@ #include -static PDFDoc*doc = 0; -static char* swffilename = 0; -static int numpages; -static int currentpage; - typedef struct _fontfile { char*filename; int used; } fontfile_t; +// for pdfswf_addfont static fontfile_t fonts[2048]; static int fontnum = 0; // swf <-> pdf pages +// TODO: move into pdf_doc_t static int*pages = 0; static int pagebuflen = 0; static int pagepos = 0; +/* config */ static double caplinewidth = 3.0; static int zoom = 72; /* xpdf: 86 */ @@ -89,7 +87,6 @@ static void printInfoDate(Dict *infoDict, char *key, char *fmt); struct mapping { char*pdffont; char*filename; - int id; } pdf2t1map[] ={ {"Times-Roman", "n021003l"}, {"Times-Italic", "n021023l"}, @@ -117,6 +114,11 @@ public: // Destructor. virtual ~SWFOutputDev() ; + void setMove(int x,int y); + void setClip(int x1,int y1,int x2,int y2); + + void save(char*filename); + //----- get info about output device // Does this device use upside-down coordinates? @@ -133,7 +135,7 @@ public: //----- initialization and control - void startDoc(XRef *xref); + void setXRef(PDFDoc*doc, XRef *xref); // Start a page. virtual void startPage(int pageNum, GfxState *state, double x1, double y1, double x2, double y2) ; @@ -200,6 +202,9 @@ public: int clipping[64]; int clippos; + int currentpage; + + PDFDoc*doc; XRef*xref; char* searchFont(char*name); @@ -228,6 +233,71 @@ public: char* substitutetarget[256]; char* substitutesource[256]; int substitutepos; + + int user_movex,user_movey; + int user_clipx1,user_clipx2,user_clipy1,user_clipy2; +}; + +static char*getFontID(GfxFont*font); + +class InfoOutputDev: public OutputDev +{ + public: + int x1,y1,x2,y2; + int num_links; + int num_images; + int num_fonts; + + InfoOutputDev() + { + num_links = 0; + num_images = 0; + num_fonts = 0; + } + virtual ~InfoOutputDev() + { + } + virtual GBool upsideDown() {return gTrue;} + virtual GBool useDrawChar() {return gTrue;} + virtual GBool useGradients() {return gTrue;} + virtual GBool interpretType3Chars() {return gTrue;} + virtual void startPage(int pageNum, GfxState *state, double crop_x1, double crop_y1, double crop_x2, double crop_y2) + { + double x1,y1,x2,y2; + state->transform(crop_x1,crop_y1,&x1,&y1); + state->transform(crop_x2,crop_y2,&x2,&y2); + if(x2x1 = (int)x1; + this->y1 = (int)y1; + this->x2 = (int)x2; + this->y2 = (int)y2; + } + virtual void drawLink(Link *link, Catalog *catalog) + { + num_links++; + } + virtual void updateFont(GfxState *state) + { + GfxFont*font = state->getFont(); + if(!font) + return; + char*id = getFontID(font); + /* FIXME*/ + num_fonts++; + } + virtual void drawImageMask(GfxState *state, Object *ref, Stream *str, + int width, int height, GBool invert, + GBool inlineImg) + { + num_images++; + } + virtual void drawImage(GfxState *state, Object *ref, Stream *str, + int width, int height, GfxImageColorMap *colorMap, + int *maskColors, GBool inlineImg) + { + num_images++; + } }; SWFOutputDev::SWFOutputDev() @@ -245,8 +315,32 @@ SWFOutputDev::SWFOutputDev() pic_id = 0; substitutepos = 0; type3Warning = 0; + user_movex = 0; + user_movey = 0; + user_clipx1 = 0; + user_clipy1 = 0; + user_clipx2 = 0; + user_clipy2 = 0; + memset(&output, 0, sizeof(output)); // printf("SWFOutputDev::SWFOutputDev() \n"); }; + +void SWFOutputDev::setMove(int x,int y) +{ + this->user_movex = x; + this->user_movey = y; +} + +void SWFOutputDev::setClip(int x1,int y1,int x2,int y2) +{ + if(x2user_clipx1 = x1; + this->user_clipy1 = y1; + this->user_clipx2 = x2; + this->user_clipy2 = y2; +} static char*getFontID(GfxFont*font) { @@ -258,15 +352,20 @@ static char*getFontID(GfxFont*font) sprintf(buf, "UFONT%d", r->num); return strdup(buf); } - return fontname; + return strdup(fontname); } static char*getFontName(GfxFont*font) { - char*fontname = getFontID(font); - char* plus = strchr(fontname, '+'); - if(plus && plus < &fontname[strlen(fontname)-1]) - fontname = plus+1; + char*fontid = getFontID(font); + char*fontname= 0; + char* plus = strchr(fontid, '+'); + if(plus && plus < &fontid[strlen(fontid)-1]) { + fontname = strdup(plus+1); + } else { + fontname = strdup(fontid); + } + free(fontid); return fontname; } @@ -466,12 +565,44 @@ static void dumpFontInfo(char*loglevel, GfxFont*font) //void SWFOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str, int width, int height, GBool invert, GBool inlineImg) {printf("void SWFOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str, int width, int height, GBool invert, GBool inlineImg) \n");} //void SWFOutputDev::drawImage(GfxState *state, Object *ref, Stream *str, int width, int height, GfxImageColorMap *colorMap, GBool inlineImg) {printf("void SWFOutputDev::drawImage(GfxState *state, Object *ref, Stream *str, int width, int height, GfxImageColorMap *colorMap, GBool inlineImg) \n");} +static void free_outline(SWF_OUTLINE*outline) +{ + while(outline) { + SWF_OUTLINE*next = outline->link; + free(outline); + outline = next; + } +} + +static void dump_outline(SWF_OUTLINE*outline) +{ + double x=0,y=0; + while(outline) { + double lastx=x,lasty=y; + x += (outline->dest.x/(float)0xffff); + y += (outline->dest.y/(float)0xffff); + if(outline->type == SWF_PATHTYPE_MOVE) { + msg(" | moveto %f,%f", x,y); + } else if(outline->type == SWF_PATHTYPE_LINE) { + msg(" | lineto: %f,%f\n",x,y); + } else if(outline->type == SWF_PATHTYPE_BEZIER) { + SWF_BEZIERSEGMENT*o2 = (SWF_BEZIERSEGMENT*)outline; + float x1 = o2->C.x/(float)0xffff+lastx; + float y1 = o2->C.y/(float)0xffff+lasty; + float x2 = o2->B.x/(float)0xffff+lastx; + float y2 = o2->B.y/(float)0xffff+lasty; + msg(" | spline: %f,%f -> %f,%f -> %f,%f\n",x1,y1,x2,y2,x,y); + } + outline = outline->link; + } +} + SWF_OUTLINE* gfxPath_to_SWF_OUTLINE(GfxState*state, GfxPath*path) { int num = path->getNumSubpaths(); int s,t; bezierpathsegment*start,*last=0; - bezierpathsegment*outline = start = new bezierpathsegment(); + bezierpathsegment*outline = start = (bezierpathsegment*)malloc(sizeof(bezierpathsegment)); int cpos = 0; double lastx=0,lasty=0; if(!num) { @@ -497,7 +628,7 @@ SWF_OUTLINE* gfxPath_to_SWF_OUTLINE(GfxState*state, GfxPath*path) outline->type = SWF_PATHTYPE_MOVE; outline->dest.x = x; outline->dest.y = y; - outline->link = (SWF_OUTLINE*)new bezierpathsegment(); + outline->link = (SWF_OUTLINE*)malloc(sizeof(bezierpathsegment)); outline = (bezierpathsegment*)outline->link; cpos = 0; lastx = nx; @@ -521,8 +652,7 @@ SWF_OUTLINE* gfxPath_to_SWF_OUTLINE(GfxState*state, GfxPath*path) outline->dest.x = x; outline->dest.y = y; outline->type = cpos?SWF_PATHTYPE_BEZIER:SWF_PATHTYPE_LINE; - outline->link = 0; - outline->link = (SWF_OUTLINE*)new bezierpathsegment(); + outline->link = (SWF_OUTLINE*)malloc(sizeof(bezierpathsegment)); outline = (bezierpathsegment*)outline->link; cpos = 0; lastx = nx; @@ -530,7 +660,9 @@ SWF_OUTLINE* gfxPath_to_SWF_OUTLINE(GfxState*state, GfxPath*path) } } } + if(last->link) {free(last->link);} last->link = 0; + return (SWF_OUTLINE*)start; } /*---------------------------------------------------------------------------- @@ -539,7 +671,6 @@ SWF_OUTLINE* gfxPath_to_SWF_OUTLINE(GfxState*state, GfxPath*path) void SWFOutputDev::stroke(GfxState *state) { - msg(" 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 @@ -553,6 +684,11 @@ void SWFOutputDev::stroke(GfxState *state) m.m11 = 1; m.m21 = 0; m.m22 = 1; m.m12 = 0; m.m13 = 0; m.m23 = 0; SWF_OUTLINE*outline = gfxPath_to_SWF_OUTLINE(state, path); + + if(screenloglevel >= LOGLEVEL_TRACE) { + msg(" stroke\n"); + dump_outline(outline); + } lineJoin = 1; // other line joins are not yet supported by the swf encoder // TODO: support bevel joints @@ -575,51 +711,80 @@ void SWFOutputDev::stroke(GfxState *state) updateStrokeColor(state); //reset updateFillColor(state); //reset } + free_outline(outline); } void SWFOutputDev::fill(GfxState *state) { - msg(" fill\n"); GfxPath * path = state->getPath(); struct swfmatrix m; m.m11 = 1; m.m21 = 0; m.m22 = 1; m.m12 = 0; m.m13 = 0; m.m23 = 0; SWF_OUTLINE*outline = gfxPath_to_SWF_OUTLINE(state, path); + + if(screenloglevel >= LOGLEVEL_TRACE) { + msg(" fill\n"); + dump_outline(outline); + } + swfoutput_setdrawmode(&output, DRAWMODE_FILL); swfoutput_drawpath(&output, outline, &m); + free_outline(outline); } void SWFOutputDev::eoFill(GfxState *state) { - msg(" eofill\n"); GfxPath * path = state->getPath(); struct swfmatrix m; m.m11 = 1; m.m21 = 0; m.m22 = 1; m.m12 = 0; m.m13 = 0; m.m23 = 0; SWF_OUTLINE*outline = gfxPath_to_SWF_OUTLINE(state, path); + + if(screenloglevel >= LOGLEVEL_TRACE) { + msg(" eofill\n"); + dump_outline(outline); + } + swfoutput_setdrawmode(&output, DRAWMODE_EOFILL); swfoutput_drawpath(&output, outline, &m); + free_outline(outline); } void SWFOutputDev::clip(GfxState *state) { - msg(" clip\n"); GfxPath * path = state->getPath(); struct swfmatrix m; m.m11 = 1; m.m22 = 1; m.m12 = 0; m.m21 = 0; m.m13 = 0; m.m23 = 0; SWF_OUTLINE*outline = gfxPath_to_SWF_OUTLINE(state, path); + + if(screenloglevel >= LOGLEVEL_TRACE) { + msg(" clip\n"); + dump_outline(outline); + } + swfoutput_startclip(&output, outline, &m); clipping[clippos] ++; + free_outline(outline); } void SWFOutputDev::eoClip(GfxState *state) { - msg(" eoclip\n"); GfxPath * path = state->getPath(); struct swfmatrix m; m.m11 = 1; m.m21 = 0; m.m22 = 1; m.m12 = 0; m.m13 = 0; m.m23 = 0; SWF_OUTLINE*outline = gfxPath_to_SWF_OUTLINE(state, path); + + if(screenloglevel >= LOGLEVEL_TRACE) { + msg(" eoclip\n"); + dump_outline(outline); + } + swfoutput_startclip(&output, outline, &m); clipping[clippos] ++; + free_outline(outline); +} +void SWFOutputDev::save(char*filename) +{ + swfoutput_save(&output, filename); } SWFOutputDev::~SWFOutputDev() @@ -730,52 +895,59 @@ void SWFOutputDev::endType3Char(GfxState *state) void SWFOutputDev::startPage(int pageNum, GfxState *state, double crop_x1, double crop_y1, double crop_x2, double crop_y2) { - double x1,y1,x2,y2; - int rot = doc->getPageRotate(1); - laststate = state; - msg(" startPage %d (%f,%f,%f,%f)\n", pageNum, crop_x1, crop_y1, crop_x2, crop_y2); - if(rot!=0) - msg(" page is rotated %d degrees\n", rot); - - /* state->transform(state->getX1(),state->getY1(),&x1,&y1); - state->transform(state->getX2(),state->getY2(),&x2,&y2); - Use CropBox, not MediaBox, as page size - */ - - /*x1 = crop_x1; - y1 = crop_y1; - x2 = crop_x2; - y2 = crop_y2;*/ - state->transform(crop_x1,crop_y1,&x1,&y1); - state->transform(crop_x2,crop_y2,&x2,&y2); - - if(x2 Bounding box is (%f,%f)-(%f,%f)", x1,y1,x2,y2); - swfoutput_init(&output, swffilename); - outputstarted = 1; - } + this->currentpage = pageNum; + double x1,y1,x2,y2; + int rot = doc->getPageRotate(1); + laststate = state; + msg(" startPage %d (%f,%f,%f,%f)\n", pageNum, crop_x1, crop_y1, crop_x2, crop_y2); + if(rot!=0) + msg(" page is rotated %d degrees\n", rot); + + /* state->transform(state->getX1(),state->getY1(),&x1,&y1); + state->transform(state->getX2(),state->getY2(),&x2,&y2); + Use CropBox, not MediaBox, as page size + */ - swfoutput_newpage(&output, pageNum, (int)x1, (int)y1, (int)x2, (int)y2); + /*x1 = crop_x1; + y1 = crop_y1; + x2 = crop_x2; + y2 = crop_y2;*/ + state->transform(crop_x1,crop_y1,&x1,&y1); + state->transform(crop_x2,crop_y2,&x2,&y2); + + if(x2 x1) x1 = user_clipx1; + if(user_clipx2 < x2) x2 = user_clipx2; + if(user_clipy1 > y1) y1 = user_clipy1; + if(user_clipy2 < y2) y2 = user_clipy2; + } + + if(!outputstarted) { + msg(" Bounding box is (%f,%f)-(%f,%f)", x1,y1,x2,y2); + swfoutput_init(&output); + outputstarted = 1; + } + + swfoutput_newpage(&output, pageNum, user_movex, user_movey, (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; #ifdef XPDF_101 - link->getBorder(&x1, &y1, &x2, &y2, &w); + link->getBorder(&x1, &y1, &x2, &y2, &w); #else - link->getRect(&x1, &y1, &x2, &y2); + link->getRect(&x1, &y1, &x2, &y2); #endif -// if (w > 0) - { rgb.r = 0; rgb.g = 0; rgb.b = 1; @@ -794,121 +966,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 = pagepos>0?pages[pagepos-1]:0; + } + 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) { @@ -960,7 +1135,7 @@ char* SWFOutputDev::searchFont(char*name) if(!is_standard_font) msg(" Using %s for %s", fonts[i].filename, name); } - return fonts[i].filename; + return strdup(fonts[i].filename); } } return 0; @@ -1112,7 +1287,7 @@ char*SWFOutputDev::writeEmbeddedFontToFile(XRef*ref, GfxFont*font) return strdup(tmpFileName); } - + char* searchForSuitableFont(GfxFont*gfxFont) { char*name = getFontName(gfxFont); @@ -1124,11 +1299,12 @@ char* searchForSuitableFont(GfxFont*gfxFont) FcResult result; FcChar8 *v; - // call init ony once static int fcinitcalled = false; + + // call init ony once if (!fcinitcalled) { fcinitcalled = true; - FcInit(); + FcInit(); //leaks } pattern = FcPatternBuild(NULL, FC_FAMILY, FcTypeString, name, NULL); @@ -1223,7 +1399,7 @@ char* SWFOutputDev::substituteFont(GfxFont*gfxFont, char* oldname) msg(" substituting %s -> %s", FIXNULL(oldname), FIXNULL(fontname)); substitutepos ++; } - return filename; + return strdup(filename); } void unlinkfont(char* filename) @@ -1255,8 +1431,9 @@ void unlinkfont(char* filename) } } -void SWFOutputDev::startDoc(XRef *xref) +void SWFOutputDev::setXRef(PDFDoc*doc, XRef *xref) { + this->doc = doc; this->xref = xref; } @@ -1344,6 +1521,8 @@ void SWFOutputDev::updateFont(GfxState *state) if(fileName && del) unlinkfont(fileName); + if(fileName) + free(fileName); } #define SQR(x) ((x)*(x)) @@ -1713,8 +1892,49 @@ static void printInfoDate(Dict *infoDict, char *key, char *fmt) { obj.free(); } -void pdfswf_init(char*filename, char*userPassword) +void pdfswf_setparameter(char*name, char*value) +{ + if(!strcmp(name, "caplinewidth")) { + caplinewidth = atof(value); + } else if(!strcmp(name, "zoom")) { + zoom = atoi(value); + } else { + swfoutput_setparameter(name, value); + } +} +void pdfswf_addfont(char*filename) +{ + fontfile_t f; + memset(&f, 0, sizeof(fontfile_t)); + f.filename = filename; + if(fontnum < sizeof(fonts)/sizeof(fonts[0])) { + fonts[fontnum++] = f; + } else { + msg(" Too many external fonts. Not adding font file \"%s\".", filename); + } +} + +typedef struct _pdf_doc_internal +{ + int protect; + PDFDoc*doc; +} pdf_doc_internal_t; +typedef struct _pdf_page_internal +{ +} pdf_page_internal_t; +typedef struct _swf_output_internal +{ + SWFOutputDev*outputDev; +} swf_output_internal_t; + +pdf_doc_t* pdf_init(char*filename, char*userPassword) { + pdf_doc_t*pdf_doc = (pdf_doc_t*)malloc(sizeof(pdf_doc_t)); + memset(pdf_doc, 0, sizeof(pdf_doc_t)); + pdf_doc_internal_t*i= (pdf_doc_internal_t*)malloc(sizeof(pdf_doc_internal_t)); + memset(i, 0, sizeof(pdf_doc_internal_t)); + pdf_doc->internal = i; + GString *fileName = new GString(filename); GString *userPW; Object info; @@ -1728,16 +1948,16 @@ void pdfswf_init(char*filename, char*userPassword) } else { userPW = NULL; } - doc = new PDFDoc(fileName, userPW); + i->doc = new PDFDoc(fileName, userPW); if (userPW) { delete userPW; } - if (!doc->isOk()) { - exit(1); + if (!i->doc->isOk()) { + return 0; } // print doc info - doc->getDocInfo(&info); + i->doc->getDocInfo(&info); if (info.isDict() && (screenloglevel>=LOGLEVEL_NOTICE)) { printInfoString(info.getDict(), "Title", "Title: %s\n"); @@ -1748,66 +1968,39 @@ 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("Pages: %d\n", i->doc->getNumPages()); + printf("Linearized: %s\n", i->doc->isLinearized() ? "yes" : "no"); printf("Encrypted: "); - if (doc->isEncrypted()) { + if (i->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"); + i->doc->okToPrint() ? "yes" : "no", + i->doc->okToCopy() ? "yes" : "no", + i->doc->okToChange() ? "yes" : "no", + i->doc->okToAddNotes() ? "yes" : "no"); } else { printf("no\n"); } } info.free(); - numpages = doc->getNumPages(); - int protect = 0; - if (doc->isEncrypted()) { - if(!doc->okToCopy()) { + pdf_doc->num_pages = i->doc->getNumPages(); + i->protect = 0; + if (i->doc->isEncrypted()) { + if(!i->doc->okToCopy()) { printf("PDF disallows copying. Terminating.\n"); exit(1); //bail out } - if(!doc->okToChange() || !doc->okToAddNotes()) - protect = 1; + if(!i->doc->okToChange() || !i->doc->okToAddNotes()) + i->protect = 1; } - if(protect) - swfoutput_setparameter("protect", "1"); - - output = new SWFOutputDev(); - output->startDoc(doc->getXRef()); -} - -void pdfswf_setparameter(char*name, char*value) -{ - if(!strcmp(name, "outputfilename")) { - swffilename = value; - } else if(!strcmp(name, "caplinewidth")) { - caplinewidth = atof(value); - } else if(!strcmp(name, "zoom")) { - zoom = atoi(value); - } else { - swfoutput_setparameter(name, value); - } + return pdf_doc; } -void pdfswf_addfont(char*filename) +void pdfswf_preparepage(int page) { - fontfile_t f; - memset(&f, 0, sizeof(fontfile_t)); - f.filename = filename; - fonts[fontnum++] = f; -} - -void pdfswf_setoutputfilename(char*_filename) { swffilename = _filename; } - -void pdfswf_convertpage(int page) -{ - if(!pages) - { + /*FIXME*/ + if(!pages) { pages = (int*)malloc(1024*sizeof(int)); pagebuflen = 1024; } else { @@ -1820,32 +2013,153 @@ void pdfswf_convertpage(int page) pages[pagepos++] = page; } -void pdfswf_performconversion() +class MemCheck { - int t; - for(t=0;tinternal; + + msg(" pdfswf.cc: pdfswf_close()"); + delete i->doc; i->doc=0; + + free(pages); pages = 0; //FIXME + + free(pdf_doc->internal);pdf_doc->internal=0; + free(pdf_doc);pdf_doc=0; +} + +pdf_page_t* pdf_getpage(pdf_doc_t*pdf_doc, int page) +{ + pdf_doc_internal_t*di= (pdf_doc_internal_t*)pdf_doc->internal; + + if(page < 1 || page > pdf_doc->num_pages) + return 0; + + pdf_page_t* pdf_page = (pdf_page_t*)malloc(sizeof(pdf_page_t)); + pdf_page_internal_t*pi= (pdf_page_internal_t*)malloc(sizeof(pdf_page_internal_t)); + memset(pi, 0, sizeof(pdf_page_internal_t)); + pdf_page->internal = pi; + + pdf_page->parent = pdf_doc; + pdf_page->nr = page; + return pdf_page; +} + +void pdf_page_destroy(pdf_page_t*pdf_page) +{ + pdf_page_internal_t*i= (pdf_page_internal_t*)pdf_page->internal; + free(pdf_page->internal);pdf_page->internal = 0; + free(pdf_page);pdf_page=0; +} + +swf_output_t* swf_output_init() +{ + swf_output_t*swf_output = (swf_output_t*)malloc(sizeof(swf_output_t)); + memset(swf_output, 0, sizeof(swf_output_t)); + swf_output_internal_t*i= (swf_output_internal_t*)malloc(sizeof(swf_output_internal_t)); + memset(i, 0, sizeof(swf_output_internal_t)); + swf_output->internal = i; + + i->outputDev = new SWFOutputDev(); + return swf_output; +} + +void swf_output_setparameter(swf_output_t*swf_output, char*name, char*value) +{ + /* FIXME */ + pdfswf_setparameter(name, value); +} + +void swf_output_save(swf_output_t*swf, char*filename) +{ + swf_output_internal_t*i= (swf_output_internal_t*)swf->internal; + i->outputDev->save(filename); +} + +void swf_output_destroy(swf_output_t*output) +{ + swf_output_internal_t*i = (swf_output_internal_t*)output->internal; + delete i->outputDev; i->outputDev=0; + free(output->internal);output->internal=0; + free(output); +} + +void pdf_page_render2(pdf_page_t*page, swf_output_t*output) +{ + pdf_doc_internal_t*pi = (pdf_doc_internal_t*)page->parent->internal; + swf_output_internal_t*si = (swf_output_internal_t*)output->internal; + + if(pi->protect) { + swfoutput_setparameter("protect", "1"); + } + si->outputDev->setXRef(pi->doc, pi->doc->getXRef()); #ifdef XPDF_101 - doc->displayPage((OutputDev*)output, currentpage, /*zoom*/zoom, /*rotate*/0, /*doLinks*/(int)1); + pi->doc->displayPage((OutputDev*)si->outputDev, page->nr, /*zoom*/zoom, /*rotate*/0, /*doLinks*/(int)1); #else - doc->displayPage((OutputDev*)output, currentpage, zoom, zoom, /*rotate*/0, true, /*doLinks*/(int)1); + pi->doc->displayPage((OutputDev*)si->outputDev, page->nr, zoom, zoom, /*rotate*/0, true, /*doLinks*/(int)1); #endif - } } -int pdfswf_numpages() + +void pdf_page_rendersection(pdf_page_t*page, swf_output_t*output, int x, int y, int x1, int y1, int x2, int y2) { - return doc->getNumPages(); + pdf_doc_internal_t*pi = (pdf_doc_internal_t*)page->parent->internal; + swf_output_internal_t*si = (swf_output_internal_t*)output->internal; + + si->outputDev->setMove(x,y); + if((x1|y1|x2|y2)==0) x2++; + si->outputDev->setClip(x1,y1,x2,y2); + + pdf_page_render2(page, output); } -void pdfswf_close() +void pdf_page_render(pdf_page_t*page, swf_output_t*output) { - msg(" pdfswf.cc: pdfswf_close()"); - delete output; - delete doc; - //freeParams(); - // check for memory leaks - Object::memCheck(stderr); - gMemReport(stderr); + pdf_doc_internal_t*pi = (pdf_doc_internal_t*)page->parent->internal; + swf_output_internal_t*si = (swf_output_internal_t*)output->internal; + + si->outputDev->setMove(0,0); + si->outputDev->setClip(0,0,0,0); + + pdf_page_render2(page, output); } +pdf_page_info_t* pdf_page_getinfo(pdf_page_t*page) +{ + pdf_doc_internal_t*pi = (pdf_doc_internal_t*)page->parent->internal; + pdf_page_internal_t*i= (pdf_page_internal_t*)page->internal; + pdf_page_info_t*info = (pdf_page_info_t*)malloc(sizeof(pdf_page_info_t)); + memset(info, 0, sizeof(pdf_page_info_t)); + + InfoOutputDev*output = new InfoOutputDev; + +#ifdef XPDF_101 + pi->doc->displayPage((OutputDev*)output, page->nr, /*zoom*/zoom, /*rotate*/0, /*doLinks*/(int)1); +#else + pi->doc->displayPage((OutputDev*)output, page->nr, zoom, zoom, /*rotate*/0, true, /*doLinks*/(int)1); +#endif + + info->xMin = output->x1; + info->yMin = output->y1; + info->xMax = output->x2; + info->yMax = output->y2; + info->number_of_images = output->num_images; + info->number_of_links = output->num_links; + info->number_of_fonts = output->num_fonts; + + delete output; + + return info; +} + +void pdf_page_info_destroy(pdf_page_info_t*info) +{ + free(info); +}