X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=lib%2Fdevices%2Fswf.c;h=a544f7eade8b0433e287db084aa03c5b95e85fb5;hb=8c4213f182478b88c8f830a16c1910d9c5a88e53;hp=7a28fce8ba4cfa76d8c017719e480fc5b98c7668;hpb=b0d012f83219d898e9cd92281d9996bc9ff13b5f;p=swftools.git diff --git a/lib/devices/swf.c b/lib/devices/swf.c index 7a28fce..a544f7e 100644 --- a/lib/devices/swf.c +++ b/lib/devices/swf.c @@ -82,6 +82,7 @@ typedef struct _swfoutput_internal int config_filloverlap; int config_protect; int config_bboxvars; + int config_disable_polygon_conversion; RGBA config_linkcolor; float config_minlinewidth; double config_caplinewidth; @@ -155,6 +156,8 @@ typedef struct _swfoutput_internal 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); @@ -189,6 +192,8 @@ static swfoutput_internal* init_internal_struct() i->frameno = 0; i->lastframeno = 0; + i->mark = 0; + i->fillstyleid; i->linestyleid; i->swflastx=0; @@ -243,6 +248,7 @@ static U16 getNewID(gfxdevice_t* dev) msg(" ID Table overflow"); id_error=1; i->overflow = 1; + exit(1); } return ++i->currentswfid; } @@ -254,6 +260,7 @@ static U16 getNewDepth(gfxdevice_t* dev) msg(" Depth Table overflow"); id_error=1; i->overflow = 1; + exit(1); } return ++i->depth; } @@ -917,11 +924,15 @@ static void startshape(gfxdevice_t*dev) 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); @@ -995,6 +1006,8 @@ void cancelshape(gfxdevice_t*dev) 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) @@ -1151,6 +1164,10 @@ void swfoutput_finalize(gfxdevice_t*dev) 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) { @@ -1674,6 +1691,15 @@ int swf_setparameter(gfxdevice_t*dev, const char*name, const char*value) 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")) { @@ -1688,6 +1714,8 @@ int swf_setparameter(gfxdevice_t*dev, const char*name, const char*value) i->config_bboxvars = atoi(value); } else if(!strcmp(name, "internallinkfunction")) { i->config_internallinkfunction = 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")) { @@ -2058,12 +2086,16 @@ static void swf_startclip(gfxdevice_t*dev, gfxline_t*line) } 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); @@ -2135,12 +2167,24 @@ static int gfxline_type(gfxline_t*line) 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; @@ -2157,7 +2201,7 @@ static int gfxline_has_dots(gfxline_t*line) y = line->y; line = line->next; } - if(isline && dist < 1) { + if(isline && dist < 1 && !short_gap) { return 1; } return 0; @@ -2236,10 +2280,11 @@ static void swf_stroke(gfxdevice_t*dev, gfxline_t*line, gfxcoord_t width, gfxcol /* 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(" draw as polygon, type=%d dots=%d", type, has_dots); @@ -2344,13 +2389,14 @@ static SWFFONT* gfxfont_to_swffont(gfxfont_t*font, char* id) for(t=0;tnum_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; @@ -2370,6 +2416,18 @@ static SWFFONT* gfxfont_to_swffont(gfxfont_t*font, char* id) 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]);