/* Ming, an SWF output library Copyright (C) 2002 Opaque Industries - http://www.opaque.net/ This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include "ming.h" #include "shape_util.h" #include "blocks/character.h" #include "blocks/shape.h" #include "blocks/matrix.h" #include "movie.h" #include "fill.h" #include "libming.h" /* This function returns a characters width. * The characters width is return in px. If a character has no bounds * -1 is returned. */ float SWFCharacter_getWidth(SWFCharacter character) { if(character->bounds == NULL) return -1; return SWFCharacter_getScaledWidth(character) / Ming_scale; } /* This function returns a characters height. * The characters height is return in px. If a character has no bounds * -1 is returned. */ float SWFCharacter_getHeight(SWFCharacter character) { if(character->bounds == NULL) return -1; return SWFCharacter_getScaledHeight(character) / Ming_scale; } /* * set line width and line color * * set line width in px * set line color as {r, g, b, a} * */ void SWFShape_setLine(SWFShape shape, unsigned short width, byte r, byte g, byte b, byte a) { SWFShape_setLineStyle_internal(shape, width * Ming_scale, r, g, b, a); } /* * set Linestyle2 introduce with SWF 8. * * set line width in pixel * set color {r, g, b, a} * * Linestyle2 extends Linestyle1 with some extra flags: * * Line cap style: select one of the following flags (default is round cap style) * SWF_LINESTYLE_CAP_ROUND * SWF_LINESTYLE_CAP_NONE * SWF_LINESTYLE_CAP_SQUARE * * Line join style: select one of the following flags (default is round join style) * SWF_LINESTYLE_JOIN_ROUND * SWF_LINESTYLE_JOIN_BEVEL * SWF_LINESTYLE_JOIN_MITER * * Scaling flags: disable horizontal / vertical scaling * SWF_LINESTYLE_FLAG_NOHSCALE * SWF_LINESTYLE_FLAG_NOVSCALE * * Enable pixel hinting to correct blurry vertical / horizontal lines * -> all anchors will be aligned to full pixels * SWF_LINESTYLE_FLAG_HINTING * * Disable stroke closure: if no-close flag is set caps will be applied * instead of joins * SWF_LINESTYLE_FLAG_NOCLOSE * * End-cap style: default round * SWF_LINESTYLE_FLAG_ENDCAP_ROUND * SWF_LINESTYLE_FLAG_ENDCAP_NONE * SWF_LINESTYLE_FLAG_ENDCAP_SQUARE * * If join style is SWF_LINESTYLE_JOIN_MITER a miter limit factor * must be set. Miter max length is then calculated as: * max miter len = miter limit * width. * If join style is not miter, this value will be ignored. */ void SWFShape_setLine2(SWFShape shape, unsigned short width, byte r, byte g, byte b, byte a, int flags, float miterLimit) { SWFShape_setLineStyle2_internal(shape, width * Ming_scale, r, g, b, a, flags, miterLimit); } /* * set filled Linestyle2 introduce with SWF 8. * * set line width in pixel * * Instead of providing a fill color, a FillStyle can be applied * to a line. * * Linestyle2 also extends Linestyle1 with some extra flags: * * Line cap style: select one of the following flags (default is round cap style) * SWF_LINESTYLE_CAP_ROUND * SWF_LINESTYLE_CAP_NONE * SWF_LINESTYLE_CAP_SQUARE * * Line join style: select one of the following flags (default is round join style) * SWF_LINESTYLE_JOIN_ROUND * SWF_LINESTYLE_JOIN_BEVEL * SWF_LINESTYLE_JOIN_MITER * * Scaling flags: disable horizontal / vertical scaling * SWF_LINESTYLE_FLAG_NOHSCALE * SWF_LINESTYLE_FLAG_NOVSCALE * * Enable pixel hinting to correct blurry vertical / horizontal lines * -> all anchors will be aligned to full pixels * SWF_LINESTYLE_FLAG_HINTING * * Disable stroke closure: if no-close flag is set caps will be applied * instead of joins * SWF_LINESTYLE_FLAG_NOCLOSE * * End-cap style: default round * SWF_LINESTYLE_FLAG_ENDCAP_ROUND * SWF_LINESTYLE_FLAG_ENDCAP_NONE * SWF_LINESTYLE_FLAG_ENDCAP_SQUARE * * If join style is SWF_LINESTYLE_JOIN_MITER a miter limit factor * must be set. Miter max length is then calculated as: * max miter len = miter limit * width. * If join style is not miter, this value will be ignored. */ void SWFShape_setLine2Filled(SWFShape shape, unsigned short width, SWFFillStyle fill, int flags, float miterLimit) { SWFShape_setLineStyle2filled_internal(shape, width * Ming_scale, fill, flags, miterLimit); } SWFFill SWFShape_addSolidFill(SWFShape shape, byte r, byte g, byte b, byte a) { return newSWFFill(SWFShape_addSolidFillStyle(shape, r, g, b, a)); } SWFFill SWFShape_addGradientFill(SWFShape shape, SWFGradient gradient, byte flags) { return newSWFFill(SWFShape_addGradientFillStyle(shape, gradient, flags)); } SWFFill SWFShape_addBitmapFill(SWFShape shape, SWFBitmap bitmap, byte flags) { SWFFill fill = newSWFFill(SWFShape_addBitmapFillStyle(shape, bitmap, flags)); return fill; } void SWFShape_setLeftFill(SWFShape shape, SWFFill fill) { SWFShape_setLeftFillStyle(shape, fill==NULL ? NULL : SWFFill_getFillStyle(fill)); } void SWFShape_setRightFill(SWFShape shape, SWFFill fill) { SWFShape_setRightFillStyle(shape, fill==NULL ? NULL : SWFFill_getFillStyle(fill)); } void SWFShape_drawCharacterBounds(SWFShape shape, SWFCharacter character) { SWFShape_drawLine(shape, SWFCharacter_getWidth(character), 0); SWFShape_drawLine(shape, 0, SWFCharacter_getHeight(character)); SWFShape_drawLine(shape, -SWFCharacter_getWidth(character), 0); SWFShape_drawLine(shape, 0, -SWFCharacter_getHeight(character)); } void SWFShape_drawCircle(SWFShape shape, double r) { SWFShape_drawArc(shape, r, 0, 360); } /* draw an arc of radius r, centered at (x,y), from angle startAngle to angle endAngle (measured in degrees clockwise from due north) */ void SWFShape_drawArc(SWFShape shape, double r, double startAngle, double endAngle) { int i, nSegs; double controlx, controly, anchorx, anchory, x, y; double angle, subangle, controlRadius; // Normalize the angles double delta = endAngle - startAngle; if ( ((delta>0)?delta:(-delta)) >= 360) delta = 360; else if (delta < 0) delta += 360; else if (delta == 0) return; startAngle = fmod(startAngle, 360); /* first determine number of segments, 8 at most */ nSegs = 1 + (int)rint(7 * (delta / 360)); /* subangle is half the angle of each segment */ subangle = M_PI * delta / nSegs / 360; angle = M_PI * startAngle / 180; x = r * sin(angle); y = -r * cos(angle); SWFShape_movePen(shape, x, y); controlRadius = r / cos(subangle); for ( i=0; i