static int currentswfid = 0;
static int depth = 1;
static int startdepth = 1;
+static int linewidth = 0;
static SHAPE* shape;
static int shapeid = -1;
char fillstylechanged = 0;
+int bboxrectpos = -1;
+SRECT bboxrect;
+
static void startshape(struct swfoutput* obj);
static void starttext(struct swfoutput* obj);
-static void endshape();
+static void endshape(int clip);
static void endtext(struct swfoutput* obj);
// matrix multiplication. changes p0
return 0;
}
+static void addPointToBBox(int px, int py)
+{
+ SPOINT p;
+ p.x = px;
+ p.y = py;
+ if(fill) {
+ swf_ExpandRect(&bboxrect, p);
+ } else {
+ swf_ExpandRect3(&bboxrect, p, linewidth*3/2);
+ }
+}
+
// write a line-to command into the swf
static void lineto(TAG*tag, plotxy p0)
{
are plots */
swf_ShapeSetLine (tag, shape, rx,ry);
- //swf_ExpandRect3(boundingBox, px, py, linewidth);
- //swf_ExpandRect3(boundingBox, swflastx, swflasty, linewidth);
+ addPointToBBox(swflastx,swflasty);
+ addPointToBBox(px,py);
shapeisempty = 0;
swflastx+=rx;
// write a spline-to command into the swf
static void splineto(TAG*tag, plotxy control,plotxy end)
{
+ int lastlastx = swflastx;
+ int lastlasty = swflasty;
+
int cx = ((int)(control.x*20)-swflastx);
int cy = ((int)(control.y*20)-swflasty);
swflastx += cx;
int ey = ((int)(end.y*20)-swflasty);
swflastx += ex;
swflasty += ey;
- if(cx || cy || ex || ey)
+
+ if(cx || cy || ex || ey) {
swf_ShapeSetCurve(tag, shape, cx,cy,ex,ey);
+ addPointToBBox(lastlastx ,lastlasty );
+ addPointToBBox(lastlastx+cx,lastlasty+cy);
+ addPointToBBox(lastlastx+cx+ex,lastlasty+cy+ey);
+ }
shapeisempty = 0;
}
On SWF side, we need to start a new shape for each
closed polygon, because SWF only knows EOFILL.
*/
- endshape();
+ endshape(0);
startshape(output);
startFill();
}
int back = 0;
if(line_cap == LINE_CAP_BUTT || line_cap == LINE_CAP_SQUARE) {
- endshape();
+ endshape(0);
startshape(output);
SWF_OUTLINE *last, *tmp=outline;
plotxy s,e,p0,p1,p2,p3,m0,m1,m2,m3;
for(nr=0;nr<2;nr++) {
int dir=0;
struct plotxy q0,q1,q2,q3,q4,q5;
+
startFill();
if(line_cap == LINE_CAP_BUTT) {
if(dir) {
if(line_cap == LINE_CAP_BUTT) {
lineto(tag, q0);
- swf_ShapeSetEnd(tag);
- tag = swf_InsertTag(tag, ST_PLACEOBJECT2);
- swf_ObjectPlaceClip(tag,shapeid,depth,NULL,NULL,NULL,depth+2-nr);
- depth++;
- shapeid = -1;
+ endshape(depth+2-nr);
startshape(output);
}
p0 = m0;
drawShortPath(output,x,y,m,outline);
if(line_cap == LINE_CAP_BUTT) {
- endshape();
+ endshape(0);
startshape(output);
}
}
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();startshape(output);
+ endshape(0);startshape(output);
startFill();
}
}
if(shapeid>=0)
- endshape();
+ endshape(0);
if(textid<0)
starttext(obj);
so we better start a new shape here if the polygon is filled
*/
if(shapeid>=0 && fill && !ignoredraworder) {
- endshape();
+ endshape(0);
}
if(shapeid<0)
if(textid>=0)
endtext(output);
if(shapeid>=0)
- endshape();
+ endshape(0);
assert(shapeid<0);
startshape(output);
stopFill();
tag = swf_InsertTag(tag,ST_DEFINESHAPE);
swf_ShapeNew(&shape);
- linestyleid = swf_ShapeAddLineStyle(shape,obj->linewidth,&obj->strokergb);
+ linestyleid = swf_ShapeAddLineStyle(shape,linewidth,&obj->strokergb);
rgb.r = obj->fillrgb.r;
rgb.g = obj->fillrgb.g;
rgb.b = obj->fillrgb.b;
swf_SetU16(tag,shapeid); // ID
/* TODO: patch back */
+ bboxrectpos = tag->len;
r.xmin = 0;
r.ymin = 0;
r.xmax = 20*sizex;
r.ymax = 20*sizey;
-
swf_SetRect(tag,&r);
+
+ memset(&bboxrect, 0, sizeof(bboxrect));
swf_SetShapeStyles(tag,shape);
swf_ShapeCountBits(shape,NULL,NULL);
swf_SetShapeBits(tag,shape);
+ /* TODO: do we really need this? */
swf_ShapeSetAll(tag,shape,/*x*/0,/*y*/0,linestyleid,0,0);
swflastx=swflasty=0;
lastwasfill = 0;
static void starttext(struct swfoutput*obj)
{
if(shapeid>=0)
- endshape();
+ endshape(0);
textid = ++currentswfid;
swflastx=swflasty=0;
}
+
+
+/* TODO: move to ../lib/rfxswf */
+void changeRect(TAG*tag, int pos, SRECT*newrect)
+{
+ /* determine length of old rect */
+ tag->pos = pos;
+ tag->readBit = 0;
+ SRECT old;
+ swf_GetRect(tag, &old);
+ swf_ResetReadBits(tag);
+ int pos_end = tag->pos;
+
+ int len = tag->len - pos_end;
+ U8*data = (U8*)malloc(len);
+ memcpy(data, &tag->data[pos_end], len);
+ tag->writeBit = 0;
+ tag->len = pos;
+ swf_SetRect(tag, newrect);
+ swf_SetBlock(tag, data, len);
+ free(data);
+ tag->pos = tag->readBit = 0;
+}
-static void endshape()
+static void endshape(int clipdepth)
{
if(shapeid<0)
return;
TAG*todel = tag;
tag = tag->prev;
swf_DeleteTag(todel);
- } else {
- /* TODO: fix bounding box */
- tag = swf_InsertTag(tag,ST_PLACEOBJECT2);
- swf_ObjectPlace(tag,shapeid,/*depth*/depth++,NULL,NULL,NULL);
+ shapeid = -1;
+ bboxrectpos = -1;
+ return;
}
+
+ changeRect(tag, bboxrectpos, &bboxrect);
+
+ tag = swf_InsertTag(tag,ST_PLACEOBJECT2);
+ if(clipdepth)
+ swf_ObjectPlaceClip(tag,shapeid,depth++,NULL,NULL,NULL,clipdepth);
+ else
+ swf_ObjectPlace(tag,shapeid,/*depth*/depth++,NULL,NULL,NULL);
+
shapeid = -1;
+ bboxrectpos = -1;
}
static void endpage(struct swfoutput*obj)
{
if(shapeid>=0)
- endshape();
+ endshape(0);
if(textid>=0)
endtext(obj);
while(clippos)
obj->fillrgb.b == b &&
obj->fillrgb.a == a) return;
if(shapeid>=0)
- endshape();
+ endshape(0);
obj->fillrgb.r = r;
obj->fillrgb.g = g;
obj->strokergb.a == a) return;
if(shapeid>=0)
- endshape();
+ endshape(0);
obj->strokergb.r = r;
obj->strokergb.g = g;
obj->strokergb.b = b;
void swfoutput_setlinewidth(struct swfoutput*obj, double linewidth)
{
- if(obj->linewidth == (u16)(linewidth*20))
+ if(linewidth == (u16)(linewidth*20))
return;
if(shapeid>=0)
- endshape();
- obj->linewidth = (u16)(linewidth*20);
+ endshape(0);
+ linewidth = (u16)(linewidth*20);
}
if(textid>=0)
endtext(obj);
if(shapeid>=0)
- endshape();
+ endshape(0);
if(clippos >= 127)
{
void swfoutput_endclip(swfoutput*obj)
{
if(textid>=0)
- endtext(obj);
+ endtext(obj);
if(shapeid>=0)
- endshape();
+ endshape(0);
if(!clippos) {
msg("<error> Invalid end of clipping region");
}
if(shapeid>=0)
- endshape();
+ endshape(0);
if(textid>=0)
- endtext(obj);
+ endtext(obj);
if(opennewwindow)
actions = action_GetUrl(0, url, "_parent");
ActionTAG* actions;
if(shapeid>=0)
- endshape();
+ endshape(0);
if(textid>=0)
- endtext(obj);
+ endtext(obj);
actions = action_GotoFrame(0, page);
actions = action_End(actions);
char mouseover = 1;
if(shapeid>=0)
- endshape();
+ endshape(0);
if(textid>=0)
- endtext(obj);
+ endtext(obj);
if(!strncmp(tmp, "call:", 5))
{
myshapeid = ++currentswfid;
tag = swf_InsertTag(tag,ST_DEFINESHAPE);
swf_ShapeNew(&shape);
- //lsid = ShapeAddLineStyle(shape,obj->linewidth,&obj->strokergb);
+ //lsid = ShapeAddLineStyle(shape,linewidth,&obj->strokergb);
//fsid = ShapeAddSolidFillStyle(shape,&obj->fillrgb);
fsid = swf_ShapeAddBitmapFillStyle(shape,&m,bitid,1);
swf_SetU16(tag, myshapeid);
{
TAG*oldtag;
if(shapeid>=0)
- endshape();
+ endshape(0);
if(textid>=0)
- endtext(obj);
+ endtext(obj);
int bitid = ++currentswfid;
oldtag = tag;
JPEGBITS*jpeg;
if(shapeid>=0)
- endshape();
+ endshape(0);
if(textid>=0)
- endtext(obj);
+ endtext(obj);
int bitid = ++currentswfid;
oldtag = tag;
{
TAG*oldtag;
if(shapeid>=0)
- endshape();
+ endshape(0);
if(textid>=0)
- endtext(obj);
+ endtext(obj);
int bitid = ++currentswfid;
oldtag = tag;
TAG*oldtag;
U8*mem2 = 0;
if(shapeid>=0)
- endshape();
+ endshape(0);
if(textid>=0)
- endtext(obj);
+ endtext(obj);
if(sizex&3)
{
{
if(id<0) return;
if(shapeid>=0)
- endshape();
+ endshape(0);
if(textid>=0)
- endtext(obj);
+ endtext(obj);
drawimage(obj, id, sizex, sizey, x1,y1,x2,y2,x3,y3,x4,y4);
}