X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=pdf2swf%2Fswfoutput.cc;h=93f2a847049e0d22710e86649e3446aeeff4237f;hb=ef0c7e7e45b0084d411395e75553db77742b2632;hp=1e79026c9bd2a4ed2a7da10ed0253873eee7ce53;hpb=8e87afb52ee4c10c314d163bc8846ba555755724;p=swftools.git diff --git a/pdf2swf/swfoutput.cc b/pdf2swf/swfoutput.cc index 1e79026..93f2a84 100644 --- a/pdf2swf/swfoutput.cc +++ b/pdf2swf/swfoutput.cc @@ -56,38 +56,35 @@ struct fontlist_t fontlist_t*next; }; -static struct _config -{ - int opennewwindow; - int ignoredraworder; - int drawonlyshapes; - int jpegquality; - int storeallcharacters; - int enablezlib; - int insertstoptag; - int flashversion; - int splinemaxerror; - int fontsplinemaxerror; - int filloverlap; - int protect; - float minlinewidth; -} config; +int config_opennewwindow=0; +int config_ignoredraworder=0; +int config_drawonlyshapes=0; +int config_jpegquality=85; +int config_storeallcharacters=0; +int config_enablezlib=0; +int config_insertstoptag=0; +int config_flashversion=5; +int config_splinemaxerror=1; +int config_fontsplinemaxerror=1; +int config_filloverlap=0; +int config_protect=0; +float config_minlinewidth=0.05; typedef struct _swfoutput_internal { - + SWF swf; + fontlist_t* fontlist; char storefont; - int flag_protected; - - SWF swf; + + MATRIX page_matrix; + TAG *tag; int currentswfid; int depth; int startdepth; int linewidth; - SRECT lastpagesize; SHAPE* shape; int shapeid; @@ -100,53 +97,44 @@ typedef struct _swfoutput_internal int lastwasfill; int shapeisempty; char fill; - int sizex; - int sizey; + int min_x,max_x; + int min_y,max_y; TAG* cliptags[128]; int clipshapes[128]; U32 clipdepths[128]; int clippos; + + int frameno; + int lastframeno; char fillstylechanged; int bboxrectpos; SRECT bboxrect; + + TAG*cliptag; chardata_t chardata[CHARDATAMAX]; int chardatapos; int firstpage; + char pagefinished; } swfoutput_internal; -static int global_init; - static swfoutput_internal* init_internal_struct() { swfoutput_internal*i = (swfoutput_internal*)malloc(sizeof(swfoutput_internal)); memset(i, 0, sizeof(swfoutput_internal)); - if(!global_init) { - config.opennewwindow=0; - config.ignoredraworder=0; - config.drawonlyshapes=0; - config.jpegquality=85; - config.storeallcharacters=0; - config.enablezlib=0; - config.insertstoptag=0; - config.flashversion=5; - config.splinemaxerror=1; - config.fontsplinemaxerror=1; - config.filloverlap=0; - config.minlinewidth=0.05; - } i->storefont = 0; - i->flag_protected = 0; i->currentswfid = 0; i->depth = 1; i->startdepth = 1; i->linewidth = 0; i->shapeid = -1; i->textid = -1; + i->frameno = 0; + i->lastframeno = 0; i->fillstyleid; i->linestyleid; @@ -162,6 +150,7 @@ static swfoutput_internal* init_internal_struct() i->bboxrectpos = -1; i->chardatapos = 0; i->firstpage = 1; + i->pagefinished = 1; return i; }; @@ -301,10 +290,10 @@ static void spline(struct swfoutput*obj, TAG*tag,plotxy p0,plotxy p1,plotxy p2,p if(i->storefont) { /* fonts use a different approximation than shapes */ - num = cspline_approximate(&c, q, config.fontsplinemaxerror/20.0, APPROXIMATE_RECURSIVE_BINARY); + num = cspline_approximate(&c, q, config_fontsplinemaxerror/20.0, APPROXIMATE_RECURSIVE_BINARY); //num = cspline_approximate(&c, q, 10.0, APPROXIMATE_INFLECTION); } else { - num = cspline_approximate(&c, q, config.splinemaxerror/20.0, APPROXIMATE_RECURSIVE_BINARY); + num = cspline_approximate(&c, q, config_splinemaxerror/20.0, APPROXIMATE_RECURSIVE_BINARY); } for(t=0;ttype == SWF_PATHTYPE_MOVE) { //if(!init && fill && obj->drawmode != DRAWMODE_EOFILL && !ignoredraworder) { - if(config.filloverlap && !init && i->fill && obj->drawmode != DRAWMODE_EOFILL) { + if(config_filloverlap && !init && i->fill && obj->drawmode != DRAWMODE_EOFILL) { /* drawmode=FILL (not EOFILL) means that seperate shapes do not cancel each other out. On SWF side, we need to start a new shape for each @@ -651,15 +640,15 @@ void drawShortPathWithEnds(struct swfoutput*obj, double x, double y, struct swfm if(dir) { /* FIXME: box should be smaller */ q0.x = 0; q0.y = 0; - q1.x = i->sizex; q1.y = 0; - q2.x = i->sizex; q2.y = i->sizey; - q3.x = 0; q3.y = i->sizey; + q1.x = i->max_x; q1.y = 0; + q2.x = i->max_x; q2.y = i->max_y; + q3.x = 0; q3.y = i->max_y; } else { /* FIXME: box should be smaller */ - q0.x = i->sizex; q0.y = i->sizey; - q1.x = 0; q1.y = i->sizey; + q0.x = i->max_x; q0.y = i->max_y; + q1.x = 0; q1.y = i->max_y; q2.x = 0; q2.y = 0; - q3.x = i->sizex; q3.y = 0; + q3.x = i->max_x; q3.y = 0; } q4.x = p0.x; q4.y = p0.y; @@ -819,12 +808,18 @@ void drawpath2poly(struct swfoutput *obj, SWF_OUTLINE*outline, struct swfmatrix* tmp->last = 0; while(1) { + double previousx = x, previousy = y; if(tmp) { x += (tmp->dest.x/(float)0xffff); y += (tmp->dest.y/(float)0xffff); } if(!tmp || tmp->type == SWF_PATHTYPE_MOVE) { if(valid && last) { + if(fabs(lastx-previousx)<0.001 && fabs(lasty-previousy)<0.001) { + /* endpoints match- the path is closed. + Don't bother to draw endings */ + drawShortPath(obj, lastx, lasty, m, last); + } if(last->type == SWF_PATHTYPE_LINE && t1linelen(obj,last)>line_width*2 && lastwasline && line_cap != LINE_CAP_ROUND) drawShortPathWithStraightEnds(obj, lastx, lasty, m, last, valid, line_cap, line_join, line_width); @@ -839,7 +834,7 @@ void drawpath2poly(struct swfoutput *obj, SWF_OUTLINE*outline, struct swfmatrix* lasty = y; } else { if(!last) - last = tmp; + last = tmp; //remember last stroke start (first segment after moveto) valid++; } @@ -1171,13 +1166,17 @@ static void endtext(swfoutput*obj) swf_SetRect(i->tag,&r); MATRIX m; - swf_GetMatrix(0, &m); + swf_GetMatrix(0, &m); /* set unit matrix- the real matrix is in the placeobject */ swf_SetMatrix(i->tag,&m); putcharacters(obj, i->tag); swf_SetU8(i->tag,0); i->tag = swf_InsertTag(i->tag,ST_PLACEOBJECT2); - swf_ObjectPlace(i->tag,i->textid,/*depth*/i->depth++,&obj->fontmatrix,NULL,NULL); + //swf_ObjectPlace(i->tag,i->textid,/*depth*/i->depth++,&i->page_matrix,NULL,NULL); + MATRIX m2; + swf_MatrixJoin(&m2,&obj->fontmatrix, &i->page_matrix); + + swf_ObjectPlace(i->tag,i->textid,/*depth*/i->depth++,&m2,NULL,NULL); i->textid = -1; } @@ -1193,12 +1192,13 @@ void swfoutput_drawpath(swfoutput*obj, SWF_OUTLINE*outline, /* Multiple polygons in one shape don't overlap correctly, so we better start a new shape here if the polygon is filled */ - if(i->shapeid>=0 && i->fill && !config.ignoredraworder) { + if(i->shapeid>=0 && i->fill && !config_ignoredraworder) { endshape(obj,0); } - if(i->shapeid<0) + if(i->shapeid<0) { startshape(obj); + } if(!i->fill) stopFill(obj); @@ -1242,7 +1242,7 @@ int getCharID(SWFFONT *font, int charnr, char *charname, int u) } } - if(u>0) { + if(u>0 && font->encoding != 255) { /* try to use the unicode id */ if(u>=0 && umaxascii && font->ascii2glyph[u]>=0) { msg(" Char [%d,%s,>%d<] maps to %d\n", charnr, charname, u, font->ascii2glyph[u]); @@ -1308,10 +1308,31 @@ void swfoutput_setfont(struct swfoutput*obj, char*fontid, char*filename) msg(" Couldn't load font %s (%s)", fontid, filename); swffont = swf_LoadFont(0); } + + if(swffont->glyph2ascii) { + int t; + int bad = 0; + /* check whether the Unicode indices look o.k. + If they don't, disable the unicode lookup by setting + the encoding to 255 */ + for(t=0;tnumchars;t++) { + int c = swffont->glyph2ascii[t]; + if(c && c < 32 && swffont->glyph[t].shape->bitlen > 16) { + // the character maps into the unicode control character range + // between 0001-001f. Yet it is not empty. Treat the one + // mapping as broken, and look how many of those we find. + bad ++; + } + } + if(bad>5) { + msg(" Font %s has bad unicode mapping", swffont->name); + swffont->encoding = 255; + } + } swf_FontSetID(swffont, ++i->currentswfid); - if(screenloglevel >= LOGLEVEL_DEBUG) { + if(getScreenLogLevel() >= LOGLEVEL_DEBUG) { // print font information msg(" Font %s (%s)",swffont->name, filename); msg(" | ID: %d", swffont->id); @@ -1413,8 +1434,17 @@ static void endpage(struct swfoutput*obj) endtext(obj); while(i->clippos) swfoutput_endclip(obj); + i->pagefinished = 1; +} - if(config.insertstoptag) { +void swfoutput_pagefeed(struct swfoutput*obj) +{ + swfoutput_internal*i = (swfoutput_internal*)obj->internal; + + if(!i->pagefinished) + endpage(obj); + + if(config_insertstoptag) { ActionTAG*atag=0; atag = action_Stop(atag); atag = action_End(atag); @@ -1422,77 +1452,91 @@ static void endpage(struct swfoutput*obj) swf_ActionSet(i->tag,atag); } i->tag = swf_InsertTag(i->tag,ST_SHOWFRAME); + i->frameno ++; + + for(i->depth--;i->depth>=i->startdepth;i->depth--) { + i->tag = swf_InsertTag(i->tag,ST_REMOVEOBJECT2); + swf_SetU16(i->tag,i->depth); + } + i->depth = i->startdepth; +} + +static void setBackground(struct swfoutput*obj, int x1, int y1, int x2, int y2) +{ + swfoutput_internal*i = (swfoutput_internal*)obj->internal; + RGBA rgb; + rgb.a = rgb.r = rgb.g = rgb.b = 0xff; + SRECT r; + SHAPE* s; + int ls1=0,fs1=0; + int shapeid = ++i->currentswfid; + r.xmin = x1; + r.ymin = y1; + r.xmax = x2; + r.ymax = y2; + i->tag = swf_InsertTag(i->tag, ST_DEFINESHAPE); + swf_ShapeNew(&s); + fs1 = swf_ShapeAddSolidFillStyle(s, &rgb); + swf_SetU16(i->tag,shapeid); + swf_SetRect(i->tag,&r); + swf_SetShapeHeader(i->tag,s); + swf_ShapeSetAll(i->tag,s,x1,y1,ls1,fs1,0); + swf_ShapeSetLine(i->tag,s,(x2-x1),0); + swf_ShapeSetLine(i->tag,s,0,(y2-y1)); + swf_ShapeSetLine(i->tag,s,(x1-x2),0); + swf_ShapeSetLine(i->tag,s,0,(y1-y2)); + swf_ShapeSetEnd(i->tag); + swf_ShapeFree(s); + i->tag = swf_InsertTag(i->tag, ST_PLACEOBJECT2); + swf_ObjectPlace(i->tag,shapeid,i->depth++,0,0,0); + i->tag = swf_InsertTag(i->tag, ST_PLACEOBJECT2); + swf_ObjectPlaceClip(i->tag,shapeid,i->depth++,0,0,0,65535); + i->cliptag = i->tag; } -void swfoutput_newpage(struct swfoutput*obj, int pageNum, int x1, int y1, int x2, int y2) +void swfoutput_newpage(struct swfoutput*obj, int pageNum, int movex, int movey, int x1, int y1, int x2, int y2) { swfoutput_internal*i = (swfoutput_internal*)obj->internal; - if(!i->firstpage) + if(!i->firstpage && !i->pagefinished) endpage(obj); - for(i->depth--;i->depth>=i->startdepth;i->depth--) { - i->tag = swf_InsertTag(i->tag,ST_REMOVEOBJECT2); - swf_SetU16(i->tag,i->depth); + swf_GetMatrix(0, &i->page_matrix); + i->page_matrix.tx = movex*20; + i->page_matrix.ty = movey*20; + + if(i->cliptag && i->frameno == i->lastframeno) { + SWFPLACEOBJECT obj; + swf_GetPlaceObject(i->cliptag, &obj); + obj.clipdepth = i->depth++; + swf_ResetTag(i->cliptag, i->cliptag->id); + swf_SetPlaceObject(i->cliptag, &obj); + swf_PlaceObjectFree(&obj); } - i->depth = i->startdepth = 3; /* leave room for clip and background rectangle */ - i->sizex = x2; - i->sizey = y2; - x1*=20;y1*=20;x2*=20;y2*=20; + i->min_x = x1; + i->min_y = y1; + i->max_x = x2; + i->max_y = y2; + + msg(" processing page %d (%dx%d:%d:%d)", pageNum,x2-x1,y2-y1, x1, y1); - if(i->lastpagesize.xmin != x1 || - i->lastpagesize.xmax != x2 || - i->lastpagesize.ymin != y1 || - i->lastpagesize.ymax != y2) - {/* add white clipping rectangle */ - msg(" processing page %d (%dx%d)", pageNum,i->sizex,i->sizey); - - if(!i->firstpage) { - msg(" Page has a different size than previous ones"); - i->tag = swf_InsertTag(i->tag,ST_REMOVEOBJECT2); - swf_SetU16(i->tag,1); - i->tag = swf_InsertTag(i->tag,ST_REMOVEOBJECT2); - swf_SetU16(i->tag,2); - } + x1*=20;y1*=20;x2*=20;y2*=20; - RGBA rgb; - rgb.a = rgb.r = rgb.g = rgb.b = 0xff; - SRECT r; - SHAPE* s; - int ls1=0,fs1=0; - int shapeid = ++i->currentswfid; - r.xmin = x1; - r.ymin = y1; - r.xmax = x2; - r.ymax = y2; - i->tag = swf_InsertTag(i->tag, ST_DEFINESHAPE); - swf_ShapeNew(&s); - fs1 = swf_ShapeAddSolidFillStyle(s, &rgb); - swf_SetU16(i->tag,shapeid); - swf_SetRect(i->tag,&r); - swf_SetShapeHeader(i->tag,s); - swf_ShapeSetAll(i->tag,s,x1,y1,ls1,fs1,0); - swf_ShapeSetLine(i->tag,s,(x2-x1),0); - swf_ShapeSetLine(i->tag,s,0,(y2-y1)); - swf_ShapeSetLine(i->tag,s,(x1-x2),0); - swf_ShapeSetLine(i->tag,s,0,(y1-y2)); - swf_ShapeSetEnd(i->tag); - swf_ShapeFree(s); - i->tag = swf_InsertTag(i->tag, ST_PLACEOBJECT2); - swf_ObjectPlace(i->tag,shapeid,/*depth*/1,0,0,0); - i->tag = swf_InsertTag(i->tag, ST_PLACEOBJECT2); - swf_ObjectPlaceClip(i->tag,shapeid,/*depth*/2,0,0,0,65535); - } else { - msg(" processing page %d", pageNum); - } + /* set clipping/background rectangle */ + /* TODO: this should all be done in SWFOutputDev */ + setBackground(obj, x1, y1, x2, y2); - i->lastpagesize.xmin = x1; - i->lastpagesize.xmax = x2; - i->lastpagesize.ymin = y1; - i->lastpagesize.ymax = y2; - swf_ExpandRect2(&i->swf.movieSize, &i->lastpagesize); + /* increase SWF's bounding box */ + SRECT r; + r.xmin = x1; + r.ymin = y1; + r.xmax = x2; + r.ymax = y2; + swf_ExpandRect2(&i->swf.movieSize, &r); + i->lastframeno = i->frameno; i->firstpage = 0; + i->pagefinished = 0; } /* initialize the swf writer */ @@ -1506,15 +1550,14 @@ void swfoutput_init(struct swfoutput* obj) SRECT r; RGBA rgb; - msg(" initializing swf output for size %d*%d\n", i->sizex,i->sizey); + msg(" initializing swf output for size %d*%d\n", i->max_x,i->max_y); obj->swffont = 0; obj->drawmode = -1; memset(&i->swf,0x00,sizeof(SWF)); - memset(&i->lastpagesize,0x00,sizeof(SRECT)); - i->swf.fileVersion = config.flashversion; + i->swf.fileVersion = config_flashversion; i->swf.frameRate = 0x0040; // 1 frame per 4 seconds i->swf.movieSize.xmin = 0; i->swf.movieSize.ymin = 0; @@ -1526,15 +1569,10 @@ void swfoutput_init(struct swfoutput* obj) rgb.a = rgb.r = rgb.g = rgb.b = 0xff; swf_SetRGB(i->tag,&rgb); - i->startdepth = i->depth = 0; -} - -void swfoutput_setprotected(struct swfoutput*obj) //write PROTECT tag -{ - swfoutput_internal*i = (swfoutput_internal*)obj->internal; - if(!i->flag_protected) + i->startdepth = i->depth = 3; /* leave room for clip and background rectangle */ + + if(config_protect) i->tag = swf_InsertTag(i->tag, ST_PROTECT); - i->flag_protected = 1; } static void startshape(struct swfoutput*obj) @@ -1561,8 +1599,8 @@ static void startshape(struct swfoutput*obj) i->bboxrectpos = i->tag->len; r.xmin = 0; r.ymin = 0; - r.xmax = 20*i->sizex; - r.ymax = 20*i->sizey; + r.xmax = 20*i->max_x; + r.ymax = 20*i->max_y; swf_SetRect(i->tag,&r); memset(&i->bboxrect, 0, sizeof(i->bboxrect)); @@ -1620,6 +1658,7 @@ void cancelshape(swfoutput*obj) TAG*todel = i->tag; i->tag = i->tag->prev; swf_DeleteTag(todel); + if(i->shape) {swf_ShapeFree(i->shape);i->shape=0;} i->shapeid = -1; i->bboxrectpos = -1; } @@ -1630,7 +1669,7 @@ void fixAreas(swfoutput*obj) if(!i->shapeisempty && i->fill && (i->bboxrect.xmin == i->bboxrect.xmax || i->bboxrect.ymin == i->bboxrect.ymax) && - config.minlinewidth >= 0.001 + config_minlinewidth >= 0.001 ) { msg(" Shape has size 0: width=%.2f height=%.2f", (i->bboxrect.xmax-i->bboxrect.xmin)/20.0, @@ -1650,7 +1689,7 @@ void fixAreas(swfoutput*obj) int save_width = i->linewidth; obj->strokergb = obj->fillrgb; - i->linewidth = (int)(config.minlinewidth*20); + i->linewidth = (int)(config_minlinewidth*20); if(i->linewidth==0) i->linewidth = 1; startshape(obj); @@ -1664,6 +1703,19 @@ void fixAreas(swfoutput*obj) } +static void endshape_noput(swfoutput*obj) +{ + swfoutput_internal*i = (swfoutput_internal*)obj->internal; + if(i->shapeid<0) + return; + //changeRect(obj, i->tag, i->bboxrectpos, &i->bboxrect); + i->shapeid = -1; + if(i->shape) { + swf_ShapeFree(i->shape); + i->shape=0; + } +} + static void endshape(swfoutput*obj, int clipdepth) { swfoutput_internal*i = (swfoutput_internal*)obj->internal; @@ -1674,8 +1726,9 @@ static void endshape(swfoutput*obj, int clipdepth) fixAreas(obj); if(i->shapeisempty || + /*bbox empty?*/ (i->bboxrect.xmin == i->bboxrect.xmax && - i->bboxrect.ymin == i->bboxrect.ymax)) + i->bboxrect.ymin == i->bboxrect.ymax)) { // delete the shape again, we didn't do anything cancelshape(obj); @@ -1687,18 +1740,28 @@ static void endshape(swfoutput*obj, int clipdepth) changeRect(obj, i->tag, i->bboxrectpos, &i->bboxrect); i->tag = swf_InsertTag(i->tag,ST_PLACEOBJECT2); + if(clipdepth) - swf_ObjectPlaceClip(i->tag,i->shapeid,i->depth++,NULL,NULL,NULL,clipdepth); + swf_ObjectPlaceClip(i->tag,i->shapeid,i->depth++,&i->page_matrix,NULL,NULL,clipdepth); else - swf_ObjectPlace(i->tag,i->shapeid,/*depth*/i->depth++,NULL,NULL,NULL); + swf_ObjectPlace(i->tag,i->shapeid,/*depth*/i->depth++,&i->page_matrix,NULL,NULL); + swf_ShapeFree(i->shape); + i->shape = 0; i->shapeid = -1; i->bboxrectpos = -1; } -void swfoutput_save(struct swfoutput* obj, char*filename) +void swfoutput_finalize(struct swfoutput*obj) { swfoutput_internal*i = (swfoutput_internal*)obj->internal; + + if(i->tag && i->tag->id == ST_END) + return; //already done + + if(i->frameno == i->lastframeno) // fix: add missing pagefeed + swfoutput_pagefeed(obj); + endpage(obj); fontlist_t *tmp,*iterator = i->fontlist; while(iterator) { @@ -1712,8 +1775,42 @@ void swfoutput_save(struct swfoutput* obj, char*filename) iterator = iterator->next; } - int fi; + i->tag = swf_InsertTag(i->tag,ST_END); + TAG* tag = i->tag->prev; + + /* remove the removeobject2 tags between the last ST_SHOWFRAME + and the ST_END- they confuse the flash player */ + while(tag->id == ST_REMOVEOBJECT2) { + TAG* prev = tag->prev; + swf_DeleteTag(tag); + tag = prev; + } +} + +SWF* swfoutput_get(struct swfoutput*obj) +{ + swfoutput_internal*i = (swfoutput_internal*)obj->internal; + + swfoutput_finalize(obj); + return swf_CopySWF(&i->swf); +} + +void swfoutput_getdimensions(struct swfoutput*obj, int*x1, int*y1, int*x2, int*y2) +{ + swfoutput_internal*i = (swfoutput_internal*)obj->internal; + if(x1) *x1 = i->swf.movieSize.xmin/20; + if(y1) *y1 = i->swf.movieSize.ymin/20; + if(x2) *x2 = i->swf.movieSize.xmax/20; + if(y2) *y2 = i->swf.movieSize.ymax/20; +} + +int swfoutput_save(struct swfoutput* obj, char*filename) +{ + swfoutput_internal*i = (swfoutput_internal*)obj->internal; + swfoutput_finalize(obj); + + int fi; if(filename) fi = open(filename, O_BINARY|O_CREAT|O_TRUNC|O_WRONLY, 0777); else @@ -1721,12 +1818,10 @@ void swfoutput_save(struct swfoutput* obj, char*filename) if(fi<=0) { msg(" Could not create \"%s\". ", FIXNULL(filename)); - exit(1); + return 0; } - - i->tag = swf_InsertTag(i->tag,ST_END); - - if(config.enablezlib || config.flashversion>=6) { + + if(config_enablezlib || config_flashversion>=6) { if FAILED(swf_WriteSWC(fi,&i->swf)) msg(" WriteSWC() failed.\n"); } else { @@ -1737,23 +1832,30 @@ void swfoutput_save(struct swfoutput* obj, char*filename) if(filename) close(fi); msg(" SWF written\n"); + return 1; } /* Perform cleaning up, complete the swf, and write it out. */ void swfoutput_destroy(struct swfoutput* obj) { swfoutput_internal*i = (swfoutput_internal*)obj->internal; + if(!i) { + /* not initialized yet- nothing to destroy */ + return; + } fontlist_t *tmp,*iterator = i->fontlist; while(iterator) { if(iterator->swffont) { - swf_FontFree(iterator->swffont); + swf_FontFree(iterator->swffont);iterator->swffont=0; } tmp = iterator; iterator = iterator->next; delete tmp; } - free(i); + swf_FreeTags(&i->swf); + + free(i);i=0; memset(obj, 0, sizeof(swfoutput)); } @@ -1843,7 +1945,8 @@ void swfoutput_startclip(swfoutput*obj, SWF_OUTLINE*outline, struct swfmatrix*m) i->clipshapes[i->clippos] = i->shapeid; i->clipdepths[i->clippos] = i->depth++; i->clippos++; - i->shapeid = -1; + + endshape_noput(obj); } void swfoutput_endclip(swfoutput*obj) @@ -1859,7 +1962,7 @@ void swfoutput_endclip(swfoutput*obj) return; } i->clippos--; - swf_ObjectPlaceClip(i->cliptags[i->clippos],i->clipshapes[i->clippos],i->clipdepths[i->clippos],NULL,NULL,NULL,i->depth++); + swf_ObjectPlaceClip(i->cliptags[i->clippos],i->clipshapes[i->clippos],i->clipdepths[i->clippos],&i->page_matrix,NULL,NULL,i->depth++); } static void drawlink(struct swfoutput*obj, ActionTAG*,ActionTAG*, swfcoord*points, char mouseover); @@ -1883,7 +1986,7 @@ void swfoutput_linktourl(struct swfoutput*obj, char*url, swfcoord*points) if(i->textid>=0) endtext(obj); - if(config.opennewwindow) + if(config_opennewwindow) actions = action_GetUrl(0, url, "_parent"); else actions = action_GetUrl(0, url, "_this"); @@ -2083,14 +2186,18 @@ static void drawlink(struct swfoutput*obj, ActionTAG*actions1, ActionTAG*actions i->tag = swf_InsertTag(i->tag,ST_PLACEOBJECT2); if(posx!=0 || posy!=0) { + SPOINT p; + p.x = (int)(posx*20); + p.y = (int)(posy*20); + p = swf_TurnPoint(p, &i->page_matrix); MATRIX m; - swf_GetMatrix(0,&m); - m.tx = (int)(posx*20); - m.ty = (int)(posy*20); + m = i->page_matrix; + m.tx = p.x; + m.ty = p.y; swf_ObjectPlace(i->tag, buttonid, i->depth++,&m,0,0); } else { - swf_ObjectPlace(i->tag, buttonid, i->depth++,0,0,0); + swf_ObjectPlace(i->tag, buttonid, i->depth++,&i->page_matrix,0,0); } } @@ -2140,26 +2247,27 @@ static void drawimage(struct swfoutput*obj, int bitid, int sizex,int sizey, m.r0 = (int)(65536*20*(p1.x-p2.x)/sizey); m.sy = -(int)(65536*20*(p1.y-p2.y)/sizey); - m.tx = (int)(p1.x*20); - m.ty = (int)(p1.y*20); + m.tx = (int)(p1.x*20) - 10; + m.ty = (int)(p1.y*20) - 10; /* shape */ myshapeid = ++i->currentswfid; i->tag = swf_InsertTag(i->tag,ST_DEFINESHAPE); - swf_ShapeNew(&i->shape); + SHAPE*shape; + swf_ShapeNew(&shape); //lsid = ShapeAddLineStyle(shape,linewidth,&obj->strokergb); //fsid = ShapeAddSolidFillStyle(shape,&obj->fillrgb); - fsid = swf_ShapeAddBitmapFillStyle(i->shape,&m,bitid,1); + fsid = swf_ShapeAddBitmapFillStyle(shape,&m,bitid,1); swf_SetU16(i->tag, myshapeid); r.xmin = (int)(xmin*20); r.ymin = (int)(ymin*20); r.xmax = (int)(xmax*20); r.ymax = (int)(ymax*20); swf_SetRect(i->tag,&r); - swf_SetShapeStyles(i->tag,i->shape); - swf_ShapeCountBits(i->shape,NULL,NULL); - swf_SetShapeBits(i->tag,i->shape); - swf_ShapeSetAll(i->tag,i->shape,/*x*/0,/*y*/0,lsid,fsid,0); + swf_SetShapeStyles(i->tag,shape); + swf_ShapeCountBits(shape,NULL,NULL); + swf_SetShapeBits(i->tag,shape); + swf_ShapeSetAll(i->tag,shape,/*x*/0,/*y*/0,lsid,fsid,0); i->swflastx = i->swflasty = 0; moveto(obj, i->tag, p1); lineto(obj, i->tag, p2); @@ -2173,10 +2281,12 @@ static void drawimage(struct swfoutput*obj, int bitid, int sizex,int sizey, ShapeSetLine (tag, shape, 0,-y*20); ShapeSetLine (tag, shape, -x*20,0);*/ swf_ShapeSetEnd(i->tag); + swf_ShapeFree(shape); /* instance */ i->tag = swf_InsertTag(i->tag,ST_PLACEOBJECT2); - swf_ObjectPlace(i->tag,myshapeid,/*depth*/i->depth++,NULL,NULL,NULL); + + swf_ObjectPlace(i->tag,myshapeid,/*depth*/i->depth++,&i->page_matrix,NULL,NULL); } int swfoutput_drawimagejpeg_old(struct swfoutput*obj, char*filename, int sizex,int sizey, @@ -2196,7 +2306,7 @@ int swfoutput_drawimagejpeg_old(struct swfoutput*obj, char*filename, int sizex,i oldtag = i->tag; i->tag = swf_InsertTag(i->tag,ST_DEFINEBITSJPEG2); swf_SetU16(i->tag, bitid); - if(swf_SetJPEGBits(i->tag, filename, config.jpegquality)<0) { + if(swf_SetJPEGBits(i->tag, filename, config_jpegquality)<0) { swf_DeleteTag(i->tag); i->tag = oldtag; return -1; @@ -2225,7 +2335,7 @@ int swfoutput_drawimagejpeg(struct swfoutput*obj, RGBA*mem, int sizex,int sizey, oldtag = i->tag; i->tag = swf_InsertTag(i->tag,ST_DEFINEBITSJPEG2); swf_SetU16(i->tag, bitid); - swf_SetJPEGBits2(i->tag,sizex,sizey,mem,config.jpegquality); + swf_SetJPEGBits2(i->tag,sizex,sizey,mem,config_jpegquality); drawimage(obj, bitid, sizex, sizey, x1,y1,x2,y2,x3,y3,x4,y4); return bitid; } @@ -2322,42 +2432,42 @@ void swfoutput_drawimageagain(struct swfoutput*obj, int id, int sizex,int sizey, void swfoutput_setparameter(char*name, char*value) { if(!strcmp(name, "drawonlyshapes")) { - config.drawonlyshapes = atoi(value); + config_drawonlyshapes = atoi(value); } else if(!strcmp(name, "ignoredraworder")) { - config.ignoredraworder = atoi(value); + config_ignoredraworder = atoi(value); } else if(!strcmp(name, "filloverlap")) { - config.filloverlap = atoi(value); + config_filloverlap = atoi(value); } else if(!strcmp(name, "linksopennewwindow")) { - config.opennewwindow = atoi(value); + config_opennewwindow = atoi(value); } else if(!strcmp(name, "opennewwindow")) { - config.opennewwindow = atoi(value); + config_opennewwindow = atoi(value); } else if(!strcmp(name, "storeallcharacters")) { - config.storeallcharacters = atoi(value); + config_storeallcharacters = atoi(value); } else if(!strcmp(name, "enablezlib")) { - config.enablezlib = atoi(value); + config_enablezlib = atoi(value); } else if(!strcmp(name, "insertstop")) { - config.insertstoptag = atoi(value); + config_insertstoptag = atoi(value); } else if(!strcmp(name, "protected")) { - config.protect = atoi(value); + config_protect = atoi(value); } else if(!strcmp(name, "flashversion")) { - config.flashversion = atoi(value); + config_flashversion = atoi(value); } else if(!strcmp(name, "minlinewidth")) { - config.minlinewidth = atof(value); + config_minlinewidth = atof(value); } else if(!strcmp(name, "jpegquality")) { int val = atoi(value); if(val<0) val=0; if(val>100) val=100; - config.jpegquality = val; + config_jpegquality = val; } else if(!strcmp(name, "splinequality")) { int v = atoi(value); v = 500-(v*5); // 100% = 0.25 pixel, 0% = 25 pixel if(v<1) v = 1; - config.splinemaxerror = v; + config_splinemaxerror = v; } else if(!strcmp(name, "fontquality")) { int v = atoi(value); v = 500-(v*5); // 100% = 0.25 pixel, 0% = 25 pixel if(v<1) v = 1; - config.fontsplinemaxerror = v; + config_fontsplinemaxerror = v; } else { fprintf(stderr, "unknown parameter: %s (=%s)\n", name, value); }