root/src/shape_util.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. SWFCharacter_getWidth
  2. SWFCharacter_getHeight
  3. SWFShape_setLine
  4. SWFShape_setLine2
  5. SWFShape_setLine2Filled
  6. SWFShape_addSolidFill
  7. SWFShape_addGradientFill
  8. SWFShape_addBitmapFill
  9. SWFShape_setLeftFill
  10. SWFShape_setRightFill
  11. SWFShape_drawCharacterBounds
  12. SWFShape_drawCircle
  13. SWFShape_drawArc
  14. SWFShape_movePenTo
  15. SWFShape_movePen
  16. SWFShape_getPenX
  17. SWFShape_getPenY
  18. SWFShape_getPen
  19. SWFShape_drawLineTo
  20. SWFShape_drawLine
  21. SWFShape_drawCurveTo
  22. SWFShape_drawCurve
  23. SWFShape_drawGlyph
  24. SWFShape_drawSizedGlyph

/*
    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 <math.h>
#include <stdlib.h>

#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 ( abs(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<nSegs; ++i )
        {
                angle += subangle;
                controlx = controlRadius * sin(angle);
                controly = -controlRadius * cos(angle);
                angle += subangle;
                anchorx = (r*sin(angle));
                anchory = (-r*cos(angle));

                SWFShape_drawCurve(shape, controlx-x, controly-y,
                                   anchorx-controlx, anchory-controly);

                x = anchorx;
                y = anchory;
        }
}


/* x,y relative to shape origin */

void SWFShape_movePenTo(SWFShape shape, double x, double y)
{
        SWFShape_moveScaledPenTo(shape, (int)rint(x*Ming_scale),
                                 (int)rint(y*Ming_scale));
}


void SWFShape_movePen(SWFShape shape, double dx, double dy)
{
        SWFShape_moveScaledPen(shape, (int)rint(dx*Ming_scale),
                         (int)rint(dy*Ming_scale));
}

double SWFShape_getPenX(SWFShape shape)
{
        return SWFShape_getScaledPenX(shape)/Ming_scale;
}

double SWFShape_getPenY(SWFShape shape)
{
        return SWFShape_getScaledPenY(shape)/Ming_scale;
}



void SWFShape_getPen(SWFShape shape, double* penX, double* penY)
{
        *penX = SWFShape_getScaledPenX(shape)/ Ming_scale;
        *penY = SWFShape_getScaledPenY(shape)/ Ming_scale;
}


void SWFShape_drawLineTo(SWFShape shape, double x, double y)
{
        SWFShape_drawScaledLineTo(shape, (int)rint(x*Ming_scale),
                                        (int)rint(y*Ming_scale));
}


void SWFShape_drawLine(SWFShape shape, double dx, double dy)
{
        SWFShape_drawScaledLine(shape, (int)rint(dx*Ming_scale),
                                (int)rint(dy*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_drawCurve(SWFShape shape, double controldx, double controldy,
                        double anchordx, double anchordy)
{
        SWFShape_drawScaledCurve(shape,
                                 (int)rint(controldx*Ming_scale),
                                 (int)rint(controldy*Ming_scale),
                                 (int)rint(anchordx*Ming_scale),
                                 (int)rint(anchordy*Ming_scale));
}


void SWFShape_drawGlyph(SWFShape shape, SWFFont font, unsigned short c)
{
        SWFShape_drawScaledGlyph(shape, font, c, 1024);
}


void SWFShape_drawSizedGlyph(SWFShape shape,
                                         SWFFont font, unsigned short c, int size)
{
        if(size == 0)
                SWFShape_drawScaledGlyph(shape, font, c, 1024);
        else
                SWFShape_drawScaledGlyph(shape, font, c, (int)(size*Ming_scale));
}


/*
 * Local variables:
 * tab-width: 2
 * c-basic-offset: 2
 * End:
 */

/* [<][>][^][v][top][bottom][index][help] */