int config_filloverlap;
int config_protect;
int config_bboxvars;
+ int config_disable_polygon_conversion;
RGBA config_linkcolor;
float config_minlinewidth;
double config_caplinewidth;
char* config_linktarget;
+ char*config_internallinkfunction;
+ char*config_externallinkfunction;
SWF* swf;
int shapeposx;
int shapeposy;
+ char* mark;
+
} swfoutput_internal;
static void swf_fillbitmap(gfxdevice_t*driver, gfxline_t*line, gfximage_t*img, gfxmatrix_t*move, gfxcxform_t*cxform);
i->frameno = 0;
i->lastframeno = 0;
+ i->mark = 0;
+
i->fillstyleid;
i->linestyleid;
i->swflastx=0;
i->config_minlinewidth=0.05;
i->config_caplinewidth=1;
i->config_linktarget=0;
+ i->config_internallinkfunction=0;
+ i->config_externallinkfunction=0;
i->config_linkcolor.r = i->config_linkcolor.g = i->config_linkcolor.b = 255;
i->config_linkcolor.a = 0x40;
msg("<error> ID Table overflow");
id_error=1;
i->overflow = 1;
+ exit(1);
}
return ++i->currentswfid;
}
msg("<error> Depth Table overflow");
id_error=1;
i->overflow = 1;
+ exit(1);
}
return ++i->depth;
}
i->swflastx += ex;
i->swflasty += ey;
- if(cx || cy || ex || ey) {
- swf_ShapeSetCurve(tag, i->shape, cx,cy,ex,ey);
- addPointToBBox(dev, lastlastx ,lastlasty );
- addPointToBBox(dev, lastlastx+cx,lastlasty+cy);
- addPointToBBox(dev, lastlastx+cx+ex,lastlasty+cy+ey);
- }/* else if(!i->fill) {
- // treat splines of length 0 as plots
- plot(dev, lastlastx, lastlasty, tag);
- }*/
+ if((cx || cy) && (ex || ey)) {
+ swf_ShapeSetCurve(tag, i->shape, cx,cy,ex,ey);
+ addPointToBBox(dev, lastlastx ,lastlasty );
+ addPointToBBox(dev, lastlastx+cx,lastlasty+cy);
+ addPointToBBox(dev, lastlastx+cx+ex,lastlasty+cy+ey);
+ } else if(cx || cy || ex || ey) {
+ swf_ShapeSetLine(tag, i->shape, cx+ex,cy+ey);
+ addPointToBBox(dev, lastlastx ,lastlasty );
+ addPointToBBox(dev, lastlastx+cx,lastlasty+cy);
+ addPointToBBox(dev, lastlastx+cx+ex,lastlasty+cy+ey);
+ }
+
i->shapeisempty = 0;
}
static void stopFill(gfxdevice_t*dev)
{
swfoutput_internal*i = (swfoutput_internal*)dev->internal;
- if(i->lastwasfill)
+ if(i->lastwasfill!=0)
{
swf_ShapeSetStyle(i->tag,i->shape,i->linestyleid,0x8000,0);
i->fillstylechanged = 1;
static void startFill(gfxdevice_t*dev)
{
swfoutput_internal*i = (swfoutput_internal*)dev->internal;
- if(!i->lastwasfill)
+ if(i->lastwasfill!=1)
{
swf_ShapeSetStyle(i->tag,i->shape,0x8000,i->fillstyleid,0);
i->fillstylechanged = 1;
if(i->textid>=0)
endtext(dev);
- i->tag = swf_InsertTag(i->tag,ST_DEFINESHAPE);
+ i->tag = swf_InsertTag(i->tag,ST_DEFINESHAPE3);
swf_ShapeNew(&i->shape);
i->linestyleid = swf_ShapeAddLineStyle(i->shape,i->linewidth,&i->strokergb);
i->fillstyleid = swf_ShapeAddSolidFillStyle(i->shape,&i->fillrgb);
+ if(i->mark) {
+ RGBA markcol = {0,i->mark[0],i->mark[1],i->mark[2]};
+ swf_ShapeAddSolidFillStyle(i->shape,&markcol);
+ }
i->shapeid = getNewID(dev);
swf_SetShapeBits(i->tag,i->shape);
/* TODO: do we really need this? */
- swf_ShapeSetAll(i->tag,i->shape,/*x*/0,/*y*/0,i->linestyleid,0,0);
- i->swflastx=i->swflasty=0;
- i->lastwasfill = 0;
+ //swf_ShapeSetAll(i->tag,i->shape,/*x*/0,/*y*/0,i->linestyleid,0,0);
+ //swf_ShapeSetAll(i->tag,i->shape,/*x*/UNDEFINED_COORD,/*y*/UNDEFINED_COORD,i->linestyleid,0,0);
+ i->swflastx=i->swflasty=UNDEFINED_COORD;
+ i->lastwasfill = -1;
i->shapeisempty = 1;
}
if(i->shape) {swf_ShapeFree(i->shape);i->shape=0;}
i->shapeid = -1;
i->bboxrectpos = -1;
+
+// i->currentswfid--; // this was an *exceptionally* bad idea
}
void fixAreas(gfxdevice_t*dev)
if(i->linewidth==0) i->linewidth = 1;
startshape(dev);
+ stopFill(dev);
moveto(dev, i->tag, r.xmin/20.0,r.ymin/20.0);
lineto(dev, i->tag, r.xmax/20.0,r.ymax/20.0);
if(i->frameno == i->lastframeno) // fix: add missing pagefeed
dev->endpage(dev);
+ if(i->mark) {
+ free(i->mark);i->mark = 0;
+ }
+
endpage(dev);
fontlist_t *tmp,*iterator = i->fontlist;
while(iterator) {
}
void swfoutput_linktourl(gfxdevice_t*dev, char*url, gfxline_t*points)
{
- ActionTAG* actions;
+ ActionTAG* actions = 0;
swfoutput_internal*i = (swfoutput_internal*)dev->internal;
if(i->shapeid>=0)
endshape(dev);
if(i->textid>=0)
endtext(dev);
-
- if(!i->config_linktarget) {
+
+ if(i->config_externallinkfunction) {
+ actions = action_PushString(actions, url); //parameter
+ actions = action_PushInt(actions, 1); //number of parameters (1)
+ actions = action_PushString(actions, i->config_externallinkfunction); //function name
+ actions = action_CallFunction(actions);
+ } else if(!i->config_linktarget) {
if(!i->config_opennewwindow)
- actions = action_GetUrl(0, url, "_parent");
+ actions = action_GetUrl(actions, url, "_parent");
else
- actions = action_GetUrl(0, url, "_this");
+ actions = action_GetUrl(actions, url, "_this");
} else {
- actions = action_GetUrl(0, url, i->config_linktarget);
+ actions = action_GetUrl(actions, url, i->config_linktarget);
}
actions = action_End(actions);
void swfoutput_linktopage(gfxdevice_t*dev, int page, gfxline_t*points)
{
swfoutput_internal*i = (swfoutput_internal*)dev->internal;
- ActionTAG* actions;
+ ActionTAG* actions = 0;
if(i->shapeid>=0)
endshape(dev);
if(i->textid>=0)
endtext(dev);
-
- actions = action_GotoFrame(0, page);
- actions = action_End(actions);
+
+ if(!i->config_internallinkfunction) {
+ actions = action_GotoFrame(actions, page);
+ actions = action_End(actions);
+ } else {
+ actions = action_PushInt(actions, page); //parameter
+ actions = action_PushInt(actions, 1); //number of parameters (1)
+ actions = action_PushString(actions, i->config_internallinkfunction); //function name
+ actions = action_CallFunction(actions);
+ actions = action_End(actions);
+ }
drawlink(dev, actions, 0, points,0);
}
actions1 = action_PushInt(0, 0); //number of parameters (0)
actions1 = action_PushString(actions1, &tmp[5]); //function name
actions1 = action_CallFunction(actions1);
+ actions1 = action_End(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);
+ actions1 = action_End(actions1);
}
actions2 = action_End(0);
mouseover = 0;
i->config_drawonlyshapes = atoi(value);
} else if(!strcmp(name, "ignoredraworder")) {
i->config_ignoredraworder = atoi(value);
+ } else if(!strcmp(name, "mark")) {
+ if(!value || !value[0]) {
+ if(i->mark) free(i->mark);
+ i->mark = 0;
+ } else {
+ int t;
+ i->mark = strdup("...");
+ for(t=0;t<3;t++) if(value[t]) i->mark[t] = value[t];
+ }
} else if(!strcmp(name, "filloverlap")) {
i->config_filloverlap = atoi(value);
} else if(!strcmp(name, "linksopennewwindow")) {
i->config_enablezlib = atoi(value);
} else if(!strcmp(name, "bboxvars")) {
i->config_bboxvars = atoi(value);
+ } else if(!strcmp(name, "internallinkfunction")) {
+ i->config_internallinkfunction = strdup(value);
+ } else if(!strcmp(name, "externallinkfunction")) {
+ i->config_externallinkfunction = strdup(value);
+ } else if(!strcmp(name, "disable_polygon_conversion")) {
+ i->config_disable_polygon_conversion = atoi(value);
} else if(!strcmp(name, "insertstop")) {
i->config_insertstoptag = atoi(value);
} else if(!strcmp(name, "protect")) {
}
int myshapeid = getNewID(dev);
- i->tag = swf_InsertTag(i->tag,ST_DEFINESHAPE);
+ i->tag = swf_InsertTag(i->tag,ST_DEFINESHAPE3);
RGBA col;
memset(&col, 0, sizeof(RGBA));
SHAPE*shape;
swf_ShapeNew(&shape);
int fsid = swf_ShapeAddSolidFillStyle(shape,&col);
+ if(i->mark) {
+ RGBA markcol = {0,i->mark[0],i->mark[1],i->mark[2]};
+ swf_ShapeAddSolidFillStyle(shape,&markcol);
+ }
swf_SetU16(i->tag,myshapeid);
SRECT r = gfxline_getSWFbbox(line);
swf_SetRect(i->tag,&r);
static int gfxline_has_dots(gfxline_t*line)
{
int tmplines=0;
- double x,y;
+ double x=0,y=0;
double dist = 0;
int isline = 0;
+ int short_gap = 0;
while(line) {
if(line->type == gfx_moveTo) {
- if(isline && dist < 1) {
+ /* test the length of the preceding line, and assume it is a dot if
+ it's length is less than 1.0. But *only* if there's a noticable
+ gap between the previous line and the next moveTo. (I've come
+ across a PDF where thousands of "dots" were stringed together,
+ forming a line) */
+ int last_short_gap = short_gap;
+ if((fabs(line->x - x) + fabs(line->y - y)) < 1.0) {
+ short_gap = 1;
+ } else {
+ short_gap = 0;
+ }
+ if(isline && dist < 1 && !short_gap && !last_short_gap) {
return 1;
}
dist = 0;
y = line->y;
line = line->next;
}
- if(isline && dist < 1) {
+ if(isline && dist < 1 && !short_gap) {
return 1;
}
return 0;
/* TODO: * split line into segments, and perform this check for all segments */
- if(!has_dots &&
- (width <= i->config_caplinewidth
+ if(i->config_disable_polygon_conversion ||
+ (!has_dots &&
+ (width <= i->config_caplinewidth
|| (cap_style == gfx_capRound && joint_style == gfx_joinRound)
- || (cap_style == gfx_capRound && type<=2))) {} else
+ || (cap_style == gfx_capRound && type<=2)))) {} else
{
/* convert line to polygon */
msg("<trace> draw as polygon, type=%d dots=%d", type, has_dots);
{
SWFFONT*swffont = (SWFFONT*)rfx_calloc(sizeof(SWFFONT));
int t;
+ SRECT bounds = {0,0,0,0};
swffont->id = -1;
swffont->version = 2;
swffont->name = (U8*)strdup(id);
for(t=0;t<font->num_glyphs;t++) {
drawer_t draw;
gfxline_t*line;
+ int advance = 0;
swffont->glyph2ascii[t] = font->glyphs[t].unicode;
if(font->glyphs[t].name) {
swffont->glyphnames[t] = strdup(font->glyphs[t].name);
} else {
swffont->glyphnames[t] = 0;
}
- swffont->glyph[t].advance = (int)(font->glyphs[t].advance * 20);
+ advance = (int)(font->glyphs[t].advance);
swf_Shape01DrawerInit(&draw, 0);
line = font->glyphs[t].line;
draw.finish(&draw);
swffont->glyph[t].shape = swf_ShapeDrawerToShape(&draw);
swffont->layout->bounds[t] = swf_ShapeDrawerGetBBox(&draw);
+
+ if(swffont->layout->bounds[t].xmax && swffont->layout->bounds[t].xmax*2 < advance) {
+ printf("fix bad advance value: bbox=%d, advance=%d (%f)\n", swffont->layout->bounds[t].xmax, advance, font->glyphs[t].advance);
+ advance = swffont->layout->bounds[t].xmax;
+ }
+
+ if(advance<32768) {
+ swffont->glyph[t].advance = advance;
+ } else {
+ swffont->glyph[t].advance = 32767;
+ }
+
draw.dealloc(&draw);
+
+ swf_ExpandRect2(&bounds, &swffont->layout->bounds[t]);
+ }
+ if(bounds.ymin < 0 && bounds.ymax > 0) {
+ swffont->layout->ascent = -bounds.ymin;
+ swffont->layout->descent = bounds.ymax;
+ swffont->layout->leading = bounds.ymax - bounds.ymin;
+ } else {
+ swffont->layout->ascent = (bounds.ymax - bounds.ymin)/2;
+ swffont->layout->descent = (bounds.ymax - bounds.ymin)/2;
+ swffont->layout->leading = bounds.ymax - bounds.ymin;
}
+
return swffont;
}