X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=pdf2swf%2Fswfoutput.cc;h=3511eee721e81d4faeb73a0aac7d2d0ba8d12e9e;hb=e52974a544099e9497126e51d3f7943270d21199;hp=eed7fad716340972974887d8ae6f98895a455aff;hpb=d42969cc2441a91c6bc318e9e705d7cb8366b553;p=swftools.git diff --git a/pdf2swf/swfoutput.cc b/pdf2swf/swfoutput.cc index eed7fad..3511eee 100644 --- a/pdf2swf/swfoutput.cc +++ b/pdf2swf/swfoutput.cc @@ -48,6 +48,7 @@ int flashversion=5; int splinemaxerror=1; int fontsplinemaxerror=1; int filloverlap=0; +float minlinewidth=0.05; static char storefont = 0; static int flag_protected = 0; @@ -93,7 +94,7 @@ SRECT bboxrect; static void startshape(struct swfoutput* obj); static void starttext(struct swfoutput* obj); -static void endshape(int clip); +static void endshape(struct swfoutput* obj,int clip); static void endtext(struct swfoutput* obj); // matrix multiplication. changes p0 @@ -120,7 +121,13 @@ static int moveto(TAG*tag, plotxy p0) } return 0; } - +static int moveto(TAG*tag, float x, float y) +{ + plotxy p; + p.x = x; + p.y = y; + return moveto(tag, p); +} static void addPointToBBox(int px, int py) { SPOINT p; @@ -151,6 +158,14 @@ static void lineto(TAG*tag, plotxy p0) swflastx+=rx; swflasty+=ry; } +static void lineto(TAG*tag, double x, double y) +{ + plotxy p; + p.x = x; + p.y = y; + lineto(tag, p); +} + // write a spline-to command into the swf static void splineto(TAG*tag, plotxy control,plotxy end) @@ -272,7 +287,7 @@ void drawpath(struct swfoutput*output, SWF_OUTLINE*outline, struct swfmatrix*m, On SWF side, we need to start a new shape for each closed polygon, because SWF only knows EOFILL. */ - endshape(0); + endshape(output,0); startshape(output); startFill(); } @@ -497,7 +512,7 @@ void drawShortPathWithEnds(struct swfoutput*output, double x, double y, struct s int back = 0; if(line_cap == LINE_CAP_BUTT || line_cap == LINE_CAP_SQUARE) { - endshape(0); + endshape(output,0); startshape(output); SWF_OUTLINE *last, *tmp=outline; plotxy s,e,p0,p1,p2,p3,m0,m1,m2,m3; @@ -576,7 +591,7 @@ void drawShortPathWithEnds(struct swfoutput*output, double x, double y, struct s if(line_cap == LINE_CAP_BUTT) { lineto(tag, q0); - endshape(depth+2-nr); + endshape(output, depth+2-nr); startshape(output); } p0 = m0; @@ -591,7 +606,7 @@ void drawShortPathWithEnds(struct swfoutput*output, double x, double y, struct s drawShortPath(output,x,y,m,outline); if(line_cap == LINE_CAP_BUTT) { - endshape(0); + endshape(output,0); startshape(output); } } @@ -653,7 +668,7 @@ void drawShortPathWithStraightEnds(struct swfoutput*output, double x, double y, need to draw) are very likely to overlap. To avoid that they cancel each other out at the end points, start a new shape for the second one */ - endshape(0);startshape(output); + endshape(output,0);startshape(output); startFill(); } @@ -760,7 +775,7 @@ static inline int colorcompare(RGBA*a,RGBA*b) static const int CHARDATAMAX = 8192; struct chardata { int charid; - int fontid; + int fontid; /* TODO: use a SWFFONT instead */ int x; int y; int size; @@ -986,8 +1001,10 @@ struct fontlist_t fontlist_t*next; } *fontlist = 0; -/* todo: why don't higher values (64, 1024) work here? */ -#define FONT_INTERNAL_SIZE 1 +/* Notice: we can only put chars in the range -1639,1638 (-32768/20,32768/20). + So if we set this value to high, the char coordinates will overflow. + If we set it to low, however, the char positions will be inaccurate */ +#define FONT_INTERNAL_SIZE 4 /* process a character. */ static int drawchar(struct swfoutput*obj, SWFFONT *swffont, char*character, int charnr, int u, swfmatrix*m) @@ -1006,7 +1023,7 @@ static int drawchar(struct swfoutput*obj, SWFFONT *swffont, char*character, int } if(shapeid>=0) - endshape(0); + endshape(obj,0); if(textid<0) starttext(obj); @@ -1094,7 +1111,7 @@ void swfoutput_drawpath(swfoutput*output, SWF_OUTLINE*outline, so we better start a new shape here if the polygon is filled */ if(shapeid>=0 && fill && !ignoredraworder) { - endshape(0); + endshape(output,0); } if(shapeid<0) @@ -1113,7 +1130,7 @@ void swfoutput_drawpath2poly(struct swfoutput*output, SWF_OUTLINE*outline, struc if(textid>=0) endtext(output); if(shapeid>=0) - endshape(0); + endshape(output,0); assert(shapeid<0); startshape(output); stopFill(); @@ -1150,12 +1167,14 @@ int getCharID(SWFFONT *font, int charnr, char *charname, int u) return charnr; } - /* the following is technically wrong, and only works if the font encoding - is US-ASCII based. It's needed for fonts which return broken unicode - indices */ -/* if(charnr>=0 && charnrmaxascii && font->ascii2glyph[charnr]>=0) { - return font->ascii2glyph[charnr]; - }*/ + if(font->encoding != FONT_ENCODING_UNICODE) { + /* the following only works if the font encoding + is US-ASCII based. It's needed for fonts which return broken unicode + indices */ + if(charnr>=0 && charnrmaxascii && font->ascii2glyph[charnr]>=0) { + return font->ascii2glyph[charnr]; + } + } return -1; } @@ -1219,6 +1238,11 @@ void swfoutput_setfont(struct swfoutput*obj, char*fontid, char*filename) swffont->layout->bounds[iii].xmax/20.0, swffont->layout->bounds[iii].ymax/20.0 ); + int t; + for(t=0;tmaxascii;t++) { + if(swffont->ascii2glyph[t] == iii) + msg(" | - maps to %d",t); + } } } @@ -1378,7 +1402,6 @@ static void startshape(struct swfoutput*obj) shapeid = ++currentswfid; swf_SetU16(tag,shapeid); // ID - /* TODO: patch back */ bboxrectpos = tag->len; r.xmin = 0; r.ymin = 0; @@ -1402,7 +1425,7 @@ static void startshape(struct swfoutput*obj) static void starttext(struct swfoutput*obj) { if(shapeid>=0) - endshape(0); + endshape(obj,0); textid = ++currentswfid; @@ -1432,21 +1455,72 @@ void changeRect(TAG*tag, int pos, SRECT*newrect) tag->pos = tag->readBit = 0; } -static void endshape(int clipdepth) +void cancelshape(swfoutput*obj) +{ + /* delete old shape tag */ + TAG*todel = tag; + tag = tag->prev; + swf_DeleteTag(todel); + shapeid = -1; + bboxrectpos = -1; +} + +void fixAreas(swfoutput*obj) +{ + if(!shapeisempty && fill && + (bboxrect.xmin == bboxrect.xmax || + bboxrect.ymin == bboxrect.ymax) && + minlinewidth >= 0.001 + ) { + msg(" Shape has size 0: width=%.2f height=%.2f", + (bboxrect.xmax-bboxrect.xmin)/20.0, + (bboxrect.ymax-bboxrect.ymin)/20.0 + ); + + SRECT r = bboxrect; + + if(r.xmin == r.xmax && r.ymin == r.ymax) { + /* this thing comes down to a single dot- nothing to fix here */ + return; + } + + cancelshape(obj); + + RGBA save_col = obj->strokergb; + int save_width = linewidth; + + obj->strokergb = obj->fillrgb; + linewidth = (int)(minlinewidth*20); + if(linewidth==0) linewidth = 1; + + startshape(obj); + + moveto(tag, r.xmin/20.0,r.ymin/20.0); + lineto(tag, r.xmax/20.0,r.ymax/20.0); + + obj->strokergb = save_col; + linewidth = save_width; + } + +} + +static void endshape(swfoutput*obj, int clipdepth) { if(shapeid<0) return; - swf_ShapeSetEnd(tag); - if(shapeisempty) { - // delete the tag again, we didn't do anything - TAG*todel = tag; - tag = tag->prev; - swf_DeleteTag(todel); - shapeid = -1; - bboxrectpos = -1; + if(!clipdepth) + fixAreas(obj); + + if(shapeisempty || + (bboxrect.xmin == bboxrect.xmax && bboxrect.ymin == bboxrect.ymax)) + { + // delete the shape again, we didn't do anything + cancelshape(obj); return; } + + swf_ShapeSetEnd(tag); changeRect(tag, bboxrectpos, &bboxrect); @@ -1463,7 +1537,7 @@ static void endshape(int clipdepth) static void endpage(struct swfoutput*obj) { if(shapeid>=0) - endshape(0); + endshape(obj,0); if(textid>=0) endtext(obj); while(clippos) @@ -1560,7 +1634,7 @@ void swfoutput_setfillcolor(swfoutput* obj, u8 r, u8 g, u8 b, u8 a) obj->fillrgb.b == b && obj->fillrgb.a == a) return; if(shapeid>=0) - endshape(0); + endshape(obj,0); obj->fillrgb.r = r; obj->fillrgb.g = g; @@ -1576,21 +1650,21 @@ void swfoutput_setstrokecolor(swfoutput* obj, u8 r, u8 g, u8 b, u8 a) obj->strokergb.a == a) return; if(shapeid>=0) - endshape(0); + endshape(obj,0); obj->strokergb.r = r; obj->strokergb.g = g; obj->strokergb.b = b; obj->strokergb.a = a; } -void swfoutput_setlinewidth(struct swfoutput*obj, double linewidth) +void swfoutput_setlinewidth(struct swfoutput*obj, double _linewidth) { - if(linewidth == (u16)(linewidth*20)) + if(linewidth == (u16)(_linewidth*20)) return; if(shapeid>=0) - endshape(0); - linewidth = (u16)(linewidth*20); + endshape(obj,0); + linewidth = (u16)(_linewidth*20); } @@ -1599,7 +1673,7 @@ void swfoutput_startclip(swfoutput*obj, SWF_OUTLINE*outline, struct swfmatrix*m) if(textid>=0) endtext(obj); if(shapeid>=0) - endshape(0); + endshape(obj,0); if(clippos >= 127) { @@ -1627,7 +1701,7 @@ void swfoutput_endclip(swfoutput*obj) if(textid>=0) endtext(obj); if(shapeid>=0) - endshape(0); + endshape(obj,0); if(!clippos) { msg(" Invalid end of clipping region"); @@ -1653,7 +1727,7 @@ void swfoutput_linktourl(struct swfoutput*obj, char*url, swfcoord*points) } if(shapeid>=0) - endshape(0); + endshape(obj,0); if(textid>=0) endtext(obj); @@ -1670,7 +1744,7 @@ void swfoutput_linktopage(struct swfoutput*obj, int page, swfcoord*points) ActionTAG* actions; if(shapeid>=0) - endshape(0); + endshape(obj,0); if(textid>=0) endtext(obj); @@ -1690,7 +1764,7 @@ void swfoutput_namedlink(struct swfoutput*obj, char*name, swfcoord*points) char mouseover = 1; if(shapeid>=0) - endshape(0); + endshape(obj,0); if(textid>=0) endtext(obj); @@ -1957,7 +2031,7 @@ int swfoutput_drawimagejpeg_old(struct swfoutput*obj, char*filename, int sizex,i { TAG*oldtag; if(shapeid>=0) - endshape(0); + endshape(obj,0); if(textid>=0) endtext(obj); @@ -1985,7 +2059,7 @@ int swfoutput_drawimagejpeg(struct swfoutput*obj, RGBA*mem, int sizex,int sizey, JPEGBITS*jpeg; if(shapeid>=0) - endshape(0); + endshape(obj,0); if(textid>=0) endtext(obj); @@ -2006,7 +2080,7 @@ int swfoutput_drawimagelossless(struct swfoutput*obj, RGBA*mem, int sizex,int si { TAG*oldtag; if(shapeid>=0) - endshape(0); + endshape(obj,0); if(textid>=0) endtext(obj); @@ -2033,7 +2107,7 @@ int swfoutput_drawimagelosslessN(struct swfoutput*obj, U8*mem, RGBA*pal, int siz TAG*oldtag; U8*mem2 = 0; if(shapeid>=0) - endshape(0); + endshape(obj,0); if(textid>=0) endtext(obj); @@ -2077,7 +2151,7 @@ void swfoutput_drawimageagain(struct swfoutput*obj, int id, int sizex,int sizey, { if(id<0) return; if(shapeid>=0) - endshape(0); + endshape(obj,0); if(textid>=0) endtext(obj); @@ -2104,6 +2178,8 @@ void swfoutput_setparameter(char*name, char*value) insertstoptag = atoi(value); } else if(!strcmp(name, "flashversion")) { flashversion = atoi(value); + } else if(!strcmp(name, "minlinewidth")) { + minlinewidth = atof(value); } else if(!strcmp(name, "jpegquality")) { int val = atoi(value); if(val<0) val=0;