X-Git-Url: http://git.asbjorn.biz/?p=swftools.git;a=blobdiff_plain;f=pdf2swf%2Fswfoutput.cc;h=8a129bc719e8cd815f108e23c13170c006d43e81;hp=2161d9e3fed2e074857df4a99a4204a7030207d0;hb=e38efb466240e266a9c0491c4be56b66af2429ee;hpb=602d0f0a1c8ad614029f235cc6ff38bfe26334e8 diff --git a/pdf2swf/swfoutput.cc b/pdf2swf/swfoutput.cc index 2161d9e..8a129bc 100644 --- a/pdf2swf/swfoutput.cc +++ b/pdf2swf/swfoutput.cc @@ -36,6 +36,8 @@ int drawonlyshapes=0; int jpegquality=85; int storeallcharacters=0; int enablezlib=0; +int insertstoptag=0; +int flashversion=4; static int flag_protected = 0; typedef unsigned char u8; @@ -90,16 +92,18 @@ static void transform (plotxy*p0,struct swfmatrix*m) } // write a move-to command into the swf -static void moveto(TAG*tag, plotxy p0) +static int moveto(TAG*tag, plotxy p0) { int rx = (int)(p0.x*20); int ry = (int)(p0.y*20); if(rx!=swflastx || ry!=swflasty || fillstylechanged) { swf_ShapeSetMove (tag, shape, rx,ry); fillstylechanged = 0; + swflastx=rx; + swflasty=ry; + return 1; } - swflastx=rx; - swflasty=ry; + return 0; } // write a line-to command into the swf @@ -144,17 +148,29 @@ static void line(TAG*tag, plotxy p0, plotxy p1, struct swfmatrix*m) static void spline(TAG*tag,plotxy p0,plotxy p1,plotxy p2,plotxy p3,struct swfmatrix*m) { double d; - struct qspline q[16]; + struct qspline q[128]; int num; int t; transform(&p0,m); transform(&p1,m); transform(&p2,m); transform(&p3,m); - - num = approximate(p0,p1,p2,p3,q); + cspline c; + c.start = p3; + c.control1 = p2; + c.control2 = p1; + c.end = p0; + + if(storefont) { + /* fonts use a different approximation than shapes */ + num = cspline_approximate(&c, q, 10.0, APPROXIMATE_RECURSIVE_BINARY); + //num = cspline_approximate(&c, q, 10.0, APPROXIMATE_INFLECTION); + } else { + num = cspline_approximate(&c, q, 1.0, APPROXIMATE_RECURSIVE_BINARY); + } for(t=0;tgetOutline(character); + T1_OUTLINE*outline = font->getOutline(character, charnr); char* charname = character; if(!outline) { @@ -698,40 +714,51 @@ SWFFont::~SWFFont() free(char2swfcharid); } -T1_OUTLINE*SWFFont::getOutline(char*name) +T1_OUTLINE*SWFFont::getOutline(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; - swfcharpos++; - used[t] = 1; - } 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) { + return getOutline(this->standardtable[charnr], -1); + } + + logf(" Didn't find character '%s' in font '%s'", FIXNULL(name), this->name); return 0; } -int SWFFont::getWidth(char*name) +int SWFFont::getSWFCharID(char*name, int charnr) { int t; for(t=0;tcharnum;t++) { if(!strcmp(this->charname[t],name)) { - return this->width[t]; + if(!used[t]) + { + swfcharid2char[swfcharpos] = t; + char2swfcharid[t] = swfcharpos++; + used[t] = 1; + } + return char2swfcharid[t]; } } - return 0; -} -int SWFFont::getSWFCharID(char*name, int charnr) -{ - int t; + /* if we didn't find the character, maybe + we can find the capitalized version */ for(t=0;tcharnum;t++) { - if(!strcmp(this->charname[t],name)) { + if(!strcasecmp(this->charname[t],name)) { if(!used[t]) { swfcharid2char[swfcharpos] = t; @@ -741,6 +768,9 @@ int SWFFont::getSWFCharID(char*name, int charnr) 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) { return getSWFCharID(this->standardtable[charnr], -1); } @@ -748,6 +778,17 @@ int SWFFont::getSWFCharID(char*name, int charnr) return 0; } +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; @@ -854,7 +895,7 @@ void swfoutput_init(struct swfoutput* obj, char*_filename, int _sizex, int _size memset(&swf,0x00,sizeof(SWF)); - swf.fileVersion = 4; + swf.fileVersion = flashversion; swf.frameRate = 0x0040; // 1 frame per 4 seconds swf.movieSize.xmax = 20*sizex; swf.movieSize.ymax = 20*sizey; @@ -969,6 +1010,14 @@ static void endpage(struct swfoutput*obj) endtext(); while(clippos) swfoutput_endclip(obj); + + if(insertstoptag) { + ActionTAG*atag=0; + atag = action_Stop(atag); + atag = action_End(atag); + tag = swf_InsertTag(tag,ST_DOACTION); + swf_ActionSet(tag,atag); + } tag = swf_InsertTag(tag,ST_SHOWFRAME); } @@ -1003,7 +1052,7 @@ void swfoutput_destroy(struct swfoutput* obj) if(!filename) return; if(filename) - fi = open(filename, O_CREAT|O_TRUNC|O_WRONLY, 0777); + fi = open(filename, O_BINARY|O_CREAT|O_TRUNC|O_WRONLY, 0777); else fi = 1; // stdout @@ -1131,6 +1180,15 @@ static void drawlink(struct swfoutput*obj, ActionTAG*,ActionTAG*, swfcoord*point void swfoutput_linktourl(struct swfoutput*obj, char*url, swfcoord*points) { ActionTAG* actions; + if(!strncmp("http://pdf2swf:", url, 15)) { + char*tmp = strdup(url); + int l = strlen(tmp); + if(tmp[l-1] == '/') + tmp[l-1] = 0; + swfoutput_namedlink(obj, tmp+15, points); + free(tmp); + return; + } if(shapeid>=0) endshape(); @@ -1159,29 +1217,56 @@ void swfoutput_linktopage(struct swfoutput*obj, int page, swfcoord*points) drawlink(obj, actions, 0, points,0); } + +/* Named Links (a.k.a. Acrobatmenu) are used to implement various gadgets + of the viewer objects, like subtitles, index elements etc. +*/ void swfoutput_namedlink(struct swfoutput*obj, char*name, swfcoord*points) { ActionTAG *actions1,*actions2; + char*tmp = strdup(name); + char mouseover = 1; if(shapeid>=0) endshape(); if(textid>=0) endtext(); - - actions1 = action_PushString(0, "/:subtitle"); - actions1 = action_PushString(actions1, name); - actions1 = action_SetVariable(actions1); - actions1 = action_End(actions1); - actions2 = action_PushString(0, "/:subtitle"); - actions2 = action_PushString(actions2, ""); - actions2 = action_SetVariable(actions2); - actions2 = action_End(actions2); + if(!strncmp(tmp, "call:", 5)) + { + char*x = strchr(&tmp[5], ':'); + if(!x) { + actions1 = action_PushInt(0, 0); //number of parameters (0) + actions1 = action_PushString(actions1, &tmp[5]); //function name + actions1 = action_CallFunction(actions1); + } else { + *x = 0; + actions1 = action_PushString(0, x+1); //parameter + actions1 = action_PushInt(actions1, 1); //number of parameters (1) + actions1 = action_PushString(actions1, &tmp[5]); //function name + actions1 = action_CallFunction(actions1); + } + actions2 = action_End(0); + mouseover = 0; + } + else + { + actions1 = action_PushString(0, "/:subtitle"); + actions1 = action_PushString(actions1, name); + actions1 = action_SetVariable(actions1); + actions1 = action_End(actions1); + + actions2 = action_PushString(0, "/:subtitle"); + actions2 = action_PushString(actions2, ""); + actions2 = action_SetVariable(actions2); + actions2 = action_End(actions2); + } - drawlink(obj, actions1, actions2, points,1); + drawlink(obj, actions1, actions2, points,mouseover); swf_ActionFree(actions1); swf_ActionFree(actions2); + free(tmp); } static void drawlink(struct swfoutput*obj, ActionTAG*actions1, ActionTAG*actions2, swfcoord*points, char mouseover)