void SWFShape_drawCurveTo(SWFShape shape, float controlx, float controly, float anchorx, float anchory) { SWFShape_drawScaledCurveTo(shape, (int)rint(controlx*Ming_scale), (int)rint(controly*Ming_scale), (int)rint(anchorx*Ming_scale), (int)rint(anchory*Ming_scale)); }
void SWFShape_drawCurveTo(SWFShape shape, double controlx, double controly, double anchorx, double anchory) { SWFShape_drawScaledCurveTo(shape, (int)rint(controlx*Ming_scale), (int)rint(controly*Ming_scale), (int)rint(anchorx*Ming_scale), (int)rint(anchory*Ming_scale)); }
void SWFShape_drawScaledGlyph(SWFShape shape, SWFFont font, unsigned short c, int size) { byte *p = SWFFont_findGlyph(font, c); byte **f = &p; int moveBits, x=0, y=0; int straight, numBits; int numFillBits, numLineBits; /* moveTos in the record are absolute, but we want to draw from the current location. grr. */ int startX = shape->xpos; int startY = shape->ypos; int style; byteAlign(); if ( (numFillBits = readBitsP(f, 4)) != 1 ) /* fill bits */ SWF_error("SWFShape_drawGlyph: bad file format (was expecting fill bits = 1)"); if ( (numLineBits = readBitsP(f, 4)) > 1 ) /* line bits */ SWF_error("SWFShape_drawGlyph: bad file format (was expecting line bits = 0)"); /* now we get to parse the shape commands. Oh boy. the first one will be a non-edge block- grab the moveto loc */ readBitsP(f, 2); /* type 0, newstyles */ style = readBitsP(f, 3); if(readBitsP(f, 1)) { moveBits = readBitsP(f, 5); x = startX + readSBitsP(f, moveBits); y = startY + readSBitsP(f, moveBits); } else if(style == 0) /* no style, no move => space character */ return; SWFShape_moveScaledPenTo(shape, x*size/1024, y*size/1024); if ( style & 1 ) if ( readBitsP(f, numFillBits) != 0 ) /* fill0 = 0 */ SWF_error("SWFFont_getShape: bad file format (was expecting fill0 = 0)"); if ( style & 2 ) if ( readBitsP(f, numFillBits) != 1 ) /* fill1 = 1 */ SWF_error("SWFFont_getShape: bad file format (was expecting fill1 = 1)"); if ( style & 4 ) if ( readBitsP(f, numLineBits) != 0 ) /* line = 1 */ SWF_error("SWFFont_getShape: bad file format (was expecting line = 0)"); /* translate the glyph's shape records into drawing commands */ for ( ;; ) { if ( readBitsP(f, 1) == 0 ) { /* it's a moveTo or a shape end */ if ( readBitsP(f, 5) == 0 ) break; moveBits = readBitsP(f, 5); x = startX + readSBitsP(f, moveBits); y = startY + readSBitsP(f, moveBits); SWFShape_moveScaledPenTo(shape, x*size/1024, y*size/1024); continue; } straight = readBitsP(f, 1); numBits = readBitsP(f, 4)+2; if ( straight==1 ) { if ( readBitsP(f, 1) ) /* general line */ { x += readSBitsP(f, numBits); y += readSBitsP(f, numBits); } else { if ( readBitsP(f, 1) ) /* vert = 1 */ y += readSBitsP(f, numBits); else x += readSBitsP(f, numBits); } SWFShape_drawScaledLineTo(shape, x*size/1024, y*size/1024); } else { int controlX = readSBitsP(f, numBits); int controlY = readSBitsP(f, numBits); int anchorX = readSBitsP(f, numBits); int anchorY = readSBitsP(f, numBits); SWFShape_drawScaledCurveTo(shape, (x+controlX)*size/1024, (y+controlY)*size/1024, (x+controlX+anchorX)*size/1024, (y+controlY+anchorY)*size/1024); x += controlX + anchorX; y += controlY + anchorY; } } /* no idea where the pen was left */ SWFShape_moveScaledPenTo(shape, startX, startY); }
static int SWFShape_approxCubic(SWFShape shape, cubic *c) { quadratic q; float cx, cy, qx, qy; if(c->b.x == c->a.x && c->b.y == c->a.y) { q.a = c->a; q.b = c->c; q.c = c->d; } else if(c->d.x == c->c.x && c->d.y == c->c.y) { q.a = c->a; q.b = c->b; q.c = c->d; } else if((c->a.x-c->b.x)*(c->c.x-c->b.x)+(c->a.y-c->b.y)*(c->c.y-c->b.y) >= 0 || (c->b.x-c->c.x)*(c->d.x-c->c.x)+(c->b.y-c->c.y)*(c->d.y-c->c.y) >= 0) { /* make sure that angles B and C are obtuse, so that outside edges meet on the right side */ return subdivideCubic(shape, c); } else { float bcrossa = c->b.x*c->a.y - c->a.x*c->b.y; float ccrossd = c->c.x*c->d.y - c->d.x*c->c.y; float denom = (c->a.y-c->b.y)*(c->d.x-c->c.x) - (c->a.x-c->b.x)*(c->d.y-c->c.y); if(denom == 0) { /* XXX - they're collinear?? */ SWFShape_drawScaledLineTo(shape, (int)rint(c->d.x), (int)rint(c->d.y)); return 1; } q.a = c->a; q.b.x = ((c->d.x-c->c.x)*bcrossa + (c->b.x-c->a.x)*ccrossd) / denom; q.b.y = ((c->d.y-c->c.y)*bcrossa + (c->b.y-c->a.y)*ccrossd) / denom; q.c = c->d; } halfpointCubic(c, &cx, &cy); halfpointQuadratic(&q, &qx, &qy); if(errorPoints(cx, cy, qx, qy) > Ming_cubicThreshold) { return subdivideCubic(shape, c); } else { /* draw quadratic w/ control point at intersection of outside edges */ SWFShape_drawScaledCurveTo(shape, (int)rint(q.b.x), (int)rint(q.b.y), (int)rint(q.c.x), (int)rint(q.c.y)); return 1; } }