- myshapeid = ++shapecount;
- tag = InsertTag(tag,ST_DEFINESHAPE);
- NewShape(&shape);
- //lsid = ShapeAddLineStyle(shape,obj->linewidth,&obj->strokergb);
- //fsid = ShapeAddSolidFillStyle(shape,&obj->fillrgb);
- fsid = ShapeAddBitmapFillStyle(shape,&m,bitid,0);
- SetU16(tag, myshapeid);
- r.xmin = (int)(xmin*20);
- r.ymin = (int)(ymin*20);
- r.xmax = (int)(xmax*20);
- r.ymax = (int)(ymax*20);
- SetRect(tag,&r);
- SetShapeStyles(tag,shape);
- ShapeCountBits(shape,NULL,NULL);
- SetShapeBits(tag,shape);
- ShapeSetAll(tag,shape,/*x*/0,/*y*/0,lsid,fsid,0);
- swflastx = swflasty = 0;
- moveto(p1);
- lineto(p2);
- lineto(p3);
- lineto(p4);
- lineto(p1);
- /*
- ShapeMoveTo (tag, shape, (int)(x1*20),(int)(y1*20));
- ShapeSetLine (tag, shape, (int)(x1*20);
- ShapeSetLine (tag, shape, x*20,0);
- ShapeSetLine (tag, shape, 0,-y*20);
- ShapeSetLine (tag, shape, -x*20,0);*/
- ShapeSetEnd(tag);
-
- /* instance */
- tag = InsertTag(tag,ST_PLACEOBJECT2);
- ObjectPlace(tag,myshapeid,/*depth*/depth++,NULL,NULL,NULL);
+ int myshapeid = getNewID(dev);
+ i->tag = swf_InsertTag(i->tag,ST_DEFINESHAPE);
+ SHAPE*shape;
+ swf_ShapeNew(&shape);
+ int fsid = swf_ShapeAddBitmapFillStyle(shape,&m,bitid,1);
+ swf_SetU16(i->tag, myshapeid);
+ SRECT r = gfxline_getSWFbbox(line);
+ swf_SetRect(i->tag,&r);
+ swf_SetShapeStyles(i->tag,shape);
+ swf_ShapeCountBits(shape,NULL,NULL);
+ swf_SetShapeBits(i->tag,shape);
+ swf_ShapeSetAll(i->tag,shape,UNDEFINED_COORD,UNDEFINED_COORD,0,fsid,0);
+ i->swflastx = i->swflasty = UNDEFINED_COORD;
+ drawgfxline(dev, line);
+ swf_ShapeSetEnd(i->tag);
+ swf_ShapeFree(shape);
+
+ i->tag = swf_InsertTag(i->tag,ST_PLACEOBJECT2);
+ CXFORM cxform2 = gfxcxform_to_cxform(cxform);
+ swf_ObjectPlace(i->tag,myshapeid,getNewDepth(dev),&i->page_matrix,&cxform2,NULL);
+}
+
+static void swf_startclip(gfxdevice_t*dev, gfxline_t*line)
+{
+ swfoutput_internal*i = (swfoutput_internal*)dev->internal;
+
+ endtext(dev);
+ endshape(dev);
+
+ if(i->clippos >= 127)
+ {
+ msg("<warning> Too many clip levels.");
+ i->clippos --;
+ }
+
+ int myshapeid = getNewID(dev);
+ i->tag = swf_InsertTag(i->tag,ST_DEFINESHAPE);
+ RGBA col;
+ memset(&col, 0, sizeof(RGBA));
+ SHAPE*shape;
+ swf_ShapeNew(&shape);
+ int fsid = swf_ShapeAddSolidFillStyle(shape,&col);
+ swf_SetU16(i->tag,myshapeid);
+ SRECT r = gfxline_getSWFbbox(line);
+ swf_SetRect(i->tag,&r);
+ swf_SetShapeStyles(i->tag,shape);
+ swf_ShapeCountBits(shape,NULL,NULL);
+ swf_SetShapeBits(i->tag,shape);
+ swf_ShapeSetAll(i->tag,shape,UNDEFINED_COORD,UNDEFINED_COORD,0,fsid,0);
+ i->swflastx = i->swflasty = UNDEFINED_COORD;
+ drawgfxline(dev, line);
+ swf_ShapeSetEnd(i->tag);
+ swf_ShapeFree(shape);
+
+ /* TODO: remember the bbox, and check all shapes against it */
+
+ i->tag = swf_InsertTag(i->tag,ST_PLACEOBJECT2);
+ i->cliptags[i->clippos] = i->tag;
+ i->clipshapes[i->clippos] = myshapeid;
+ i->clipdepths[i->clippos] = getNewDepth(dev);
+ i->clippos++;
+}
+
+static void swf_endclip(gfxdevice_t*dev)
+{
+ swfoutput_internal*i = (swfoutput_internal*)dev->internal;
+ if(i->textid>=0)
+ endtext(dev);
+ if(i->shapeid>=0)
+ endshape(dev);
+
+ if(!i->clippos) {
+ msg("<error> Invalid end of clipping region");
+ return;
+ }
+ i->clippos--;
+ /*swf_ObjectPlaceClip(i->cliptags[i->clippos],i->clipshapes[i->clippos],i->clipdepths[i->clippos],&i->page_matrix,NULL,NULL,
+ / * clip to depth: * / i->depth <= i->clipdepths[i->clippos]? i->depth : i->depth - 1);
+ i->depth ++;*/
+ swf_ObjectPlaceClip(i->cliptags[i->clippos],i->clipshapes[i->clippos],i->clipdepths[i->clippos],&i->page_matrix,NULL,NULL,i->depth);
+}
+static int gfxline_type(gfxline_t*line)
+{
+ int tmplines=0;
+ int tmpsplines=0;
+ int lines=0;
+ int splines=0;
+ int haszerosegments=0;
+ while(line) {
+ if(line->type == gfx_moveTo) {
+ tmplines=0;
+ tmpsplines=0;
+ } else if(line->type == gfx_lineTo) {
+ tmplines++;
+ if(tmplines>lines)
+ lines=tmplines;
+ } else if(line->type == gfx_splineTo) {
+ tmpsplines++;
+ if(tmpsplines>lines)
+ splines=tmpsplines;
+ }
+ line = line->next;
+ }
+ if(lines==0 && splines==0) return 0;
+ else if(lines==1 && splines==0) return 1;
+ else if(lines==0 && splines==1) return 2;
+ else if(splines==0) return 3;
+ else return 4;
+}
+
+static int gfxline_has_dots(gfxline_t*line)
+{
+ int tmplines=0;
+ double x,y;
+ double dist = 0;
+ int isline = 0;
+ while(line) {
+ if(line->type == gfx_moveTo) {
+ if(isline && dist < 1) {
+ return 1;
+ }
+ dist = 0;
+ isline = 0;
+ } else if(line->type == gfx_lineTo) {
+ dist += fabs(line->x - x) + fabs(line->y - y);
+ isline = 1;
+ } else if(line->type == gfx_splineTo) {
+ dist += fabs(line->sx - x) + fabs(line->sy - y) +
+ fabs(line->x - line->sx) + fabs(line->y - line->sy);
+ isline = 1;
+ }
+ x = line->x;
+ y = line->y;
+ line = line->next;
+ }
+ if(isline && dist < 1) {
+ return 1;
+ }
+ return 0;
+}
+
+static int gfxline_fix_short_edges(gfxline_t*line)
+{
+ double x,y;
+ while(line) {
+ if(line->type == gfx_lineTo) {
+ if(fabs(line->x - x) + fabs(line->y - y) < 0.01) {
+ line->x += 0.01;
+ }
+ } else if(line->type == gfx_splineTo) {
+ if(fabs(line->sx - x) + fabs(line->sy - y) +
+ fabs(line->x - line->sx) + fabs(line->y - line->sy) < 0.01) {
+ line->x += 0.01;
+ }
+ }
+ x = line->x;
+ y = line->y;
+ line = line->next;
+ }
+ return 0;
+}
+
+static char is_inside_page(gfxdevice_t*dev, gfxcoord_t x, gfxcoord_t y)
+{
+ swfoutput_internal*i = (swfoutput_internal*)dev->internal;
+ if(x<i->min_x || x>i->max_x) return 0;
+ if(y<i->min_y || y>i->max_y) return 0;
+ return 1;
+}
+
+static void show_path(ArtSVP*path)
+{
+ int t;
+ printf("Segments: %d\n", path->n_segs);
+ for(t=0;t<path->n_segs;t++) {
+ ArtSVPSeg* seg = &path->segs[t];
+ printf("Segment %d: %d points, %s, BBox: (%f,%f,%f,%f)\n",
+ t, seg->n_points, seg->dir==0?"UP ":"DOWN",
+ seg->bbox.x0, seg->bbox.y0, seg->bbox.x1, seg->bbox.y1);
+ int p;
+ for(p=0;p<seg->n_points;p++) {
+ ArtPoint* point = &seg->points[p];
+ printf(" (%f,%f)\n", point->x, point->y);
+ }
+ }
+ printf("\n");
+}
+
+
+static void swf_stroke(gfxdevice_t*dev, gfxline_t*line, gfxcoord_t width, gfxcolor_t*color, gfx_capType cap_style, gfx_joinType joint_style, gfxcoord_t miterLimit)
+{
+ swfoutput_internal*i = (swfoutput_internal*)dev->internal;
+ int type = gfxline_type(line);
+ int has_dots = gfxline_has_dots(line);
+ gfxbbox_t r = gfxline_getbbox(line);
+ int is_outside_page = !is_inside_page(dev, r.xmin, r.ymin) || !is_inside_page(dev, r.xmax, r.ymax);
+
+ /* TODO: * split line into segments, and perform this check for all segments */
+
+ if(!has_dots &&
+ (width <= i->config_caplinewidth
+ || (cap_style == gfx_capRound && joint_style == gfx_joinRound)
+ || (cap_style == gfx_capRound && type<=2))) {
+ msg("<trace> draw as stroke, type=%d dots=%d", type, has_dots);
+ endtext(dev);
+ swfoutput_setstrokecolor(dev, color->r, color->g, color->b, color->a);
+ swfoutput_setlinewidth(dev, width);
+ startshape(dev);
+ stopFill(dev);
+ drawgfxline(dev, line);
+ } else {
+ msg("<trace> draw as polygon, type=%d dots=%d", type, has_dots);
+ if(has_dots)
+ gfxline_fix_short_edges(line);
+ /* we need to convert the line into a polygon */
+ ArtSVP* svp = gfxstrokeToSVP(line, width, cap_style, joint_style, miterLimit);
+ gfxline_t*gfxline = SVPtogfxline(svp);
+ dev->fill(dev, gfxline, color);
+ free(gfxline);
+ art_svp_free(svp);
+ }
+}
+static void swf_fill(gfxdevice_t*dev, gfxline_t*line, gfxcolor_t*color)
+{
+ swfoutput_internal*i = (swfoutput_internal*)dev->internal;
+ gfxbbox_t r = gfxline_getbbox(line);
+ int is_outside_page = !is_inside_page(dev, r.xmin, r.ymin) || !is_inside_page(dev, r.xmax, r.ymax);
+
+ endtext(dev);
+ if(!i->config_ignoredraworder)
+ endshape(dev);
+ swfoutput_setfillcolor(dev, color->r, color->g, color->b, color->a);
+ startshape(dev);
+ startFill(dev);
+ i->fill=1;
+ drawgfxline(dev, line);
+ msg("<trace> end of swf_fill (shapeid=%d)", i->shapeid);
+}
+static void swf_fillgradient(gfxdevice_t*dev, gfxline_t*line, gfxgradient_t*gradient, gfxgradienttype_t type, gfxmatrix_t*matrix)
+{
+ msg("<error> Gradient filling not implemented yet");