int storeallcharacters=0;
int enablezlib=0;
int insertstoptag=0;
+int flashversion=4;
static int flag_protected = 0;
typedef unsigned char u8;
}
// 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
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, 0.05, APPROXIMATE_RECURSIVE_BINARY);
+ //num = cspline_approximate(&c, q, 10.0, APPROXIMATE_INFLECTION);
+ } else {
+ num = cspline_approximate(&c, q, 0.05, APPROXIMATE_RECURSIVE_BINARY);
+ }
for(t=0;t<num;t++) {
- moveto(tag,q[t].start);
+ if(!t)
+ moveto(tag,q[t].start);
splineto(tag,q[t].control, q[t].end);
}
}
}
else
{
- T1_OUTLINE*outline = font->getOutline(character);
+ T1_OUTLINE*outline = font->getOutline(character, charnr);
char* charname = character;
if(!outline) {
free(char2swfcharid);
}
-T1_OUTLINE*SWFFont::getOutline(char*name)
+T1_OUTLINE*SWFFont::getOutline(char*name, int charnr)
{
int t;
for(t=0;t<this->charnum;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;t<this->charnum;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("<warning> 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;t<this->charnum;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;t<this->charnum;t++) {
- if(!strcmp(this->charname[t],name)) {
+ if(!strcasecmp(this->charname[t],name)) {
if(!used[t])
{
swfcharid2char[swfcharpos] = t;
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);
}
return 0;
}
+int SWFFont::getWidth(char*name)
+{
+ int t;
+ for(t=0;t<this->charnum;t++) {
+ if(!strcmp(this->charname[t],name)) {
+ return this->width[t];
+ }
+ }
+ return 0;
+}
+
char*SWFFont::getName()
{
return this->name;
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;
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
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();
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)