/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- newSWFLineStyle
- newSWFLineStyle2
- newSWFLineStyle2_filled
- SWFLineStyle_equals
- SWFLineStyle_equals2filled
- SWFLineStyle_getWidth
- writeLineStyle1
- writeLineStyle2
- SWFOutput_writeLineStyles
- SWFOutput_writeMorphLineStyles2
- SWFOutput_writeMorphLineStyles
/*
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
*/
/* $Id: linestyle.c,v 1.18 2009/05/20 10:06:00 strk Exp $ */
#include <stdlib.h>
#include "libming.h"
#include "linestyle.h"
#include "fillstyle.h"
#include "error.h"
#define SWF_LINESTYLE_FLAG_FILL (1<<11)
struct SWFLineStyle_s
{
unsigned short width;
byte r;
byte g;
byte b;
byte a;
/* LINESTYLE2 extensions */
// 16 bit flags
int flags;
float miterLimit;
SWFFillStyle fill;
};
/*
* sets simple linestyle
* width is set in TWIPS
*/
SWFLineStyle newSWFLineStyle(unsigned short width,
byte r, byte g, byte b, byte a)
{
SWFLineStyle line = (SWFLineStyle)malloc(sizeof(struct SWFLineStyle_s));
line->width = width;
line->r = r;
line->g = g;
line->b = b;
line->a = a;
line->flags = 0;
return line;
}
/*
* create Linestyle2 introduce with SWF 8.
* 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.
*/
SWFLineStyle newSWFLineStyle2(unsigned short width, byte r, byte g, byte b, byte a,
int flags, float miterLimit)
{
SWFLineStyle line = (SWFLineStyle)malloc(sizeof(struct SWFLineStyle_s));
line->width = width;
line->r = r;
line->g = g;
line->b = b;
line->a = a;
line->flags = 0 | flags;
line->miterLimit = miterLimit;
line->fill = NULL;
return line;
}
/*
* create Linestyle2 introduce with SWF 8.
*
* 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.
*/
SWFLineStyle newSWFLineStyle2_filled(unsigned short width, SWFFillStyle fill,
int flags, float miterLimit)
{
SWFLineStyle line;
if(fill == NULL)
return NULL;
line = (SWFLineStyle)malloc(sizeof(struct SWFLineStyle_s));
line->width = width;
line->flags = SWF_LINESTYLE_FLAG_FILL | flags;
line->miterLimit = miterLimit;
line->fill = fill;
return line;
}
byte SWFLineStyle_equals(SWFLineStyle line, unsigned short width,
byte r, byte g, byte b, byte a, int flags)
{
// if(line->width == 0 && width == 0)
// return TRUE;
if(line->width == width &&
line->r == r &&
line->g == g &&
line->b == b &&
line->a == a &&
line->flags == flags)
{
return TRUE;
}
return FALSE;
}
byte SWFLineStyle_equals2filled(SWFLineStyle line, unsigned short width,
SWFFillStyle fill, int flags)
{
if(line->width == width &&
line->flags == flags &&
SWFFillStyle_equals(line->fill, fill))
{
return TRUE;
}
return FALSE;
}
unsigned short SWFLineStyle_getWidth(SWFLineStyle line)
{
return line->width;
}
static inline void writeLineStyle1(SWFOutput out, SWFLineStyle line, int shapeType)
{
SWFOutput_writeUInt16(out, line->width);
SWFOutput_writeUInt8(out, line->r);
SWFOutput_writeUInt8(out, line->g);
SWFOutput_writeUInt8(out, line->b);
if(shapeType >= SWF_DEFINESHAPE3)
SWFOutput_writeUInt8(out, line->a);
}
static inline void writeLineStyle2(SWFOutput out, SWFLineStyle line, SWFBlocktype shapeType, SWFRect bounds)
{
SWFOutput_writeUInt16(out, line->width);
SWFOutput_writeUInt8(out, (line->flags >> 8));
SWFOutput_writeUInt8(out, line->flags);
if(line->flags & SWF_LINESTYLE_JOIN_MITER)
SWFOutput_writeFixed8(out, line->miterLimit);
if(line->flags & SWF_LINESTYLE_FLAG_FILL)
SWFOutput_writeFillStyle(out, line->fill, shapeType, bounds);
else
{
SWFOutput_writeUInt8(out, line->r);
SWFOutput_writeUInt8(out, line->g);
SWFOutput_writeUInt8(out, line->b);
SWFOutput_writeUInt8(out, line->a);
}
}
void SWFOutput_writeLineStyles(SWFOutput out,
SWFLineStyle *lines, int nLines,
SWFBlocktype shapeType,
SWFRect bounds)
{
SWFLineStyle line;
int i;
if(nLines<255)
SWFOutput_writeUInt8(out, nLines);
else
{
SWFOutput_writeUInt8(out, 255);
SWFOutput_writeUInt16(out, nLines);
}
for(i=0; i<nLines; ++i)
{
line = lines[i];
if(shapeType == SWF_DEFINESHAPE4)
writeLineStyle2(out, line, shapeType, bounds);
else
writeLineStyle1(out, line, shapeType);
}
}
void SWFOutput_writeMorphLineStyles2(SWFOutput out,
SWFLineStyle *lines1, int nLines1,
SWFLineStyle *lines2, int nLines2)
{
SWFLineStyle line1, line2;
int i;
SWF_assert(nLines1 == nLines2);
if(nLines1<255)
SWFOutput_writeUInt8(out, nLines1);
else
{
SWFOutput_writeUInt8(out, 255);
SWFOutput_writeUInt16(out, nLines1);
}
for(i=0; i<nLines1; ++i)
{
line1 = lines1[i];
line2 = lines2[i];
SWFOutput_writeUInt16(out, line1->width);
SWFOutput_writeUInt16(out, line2->width);
if(line1->flags != line2->flags)
SWF_warnOnce("Morph: shapes _must_ us equal line flags\n");
SWFOutput_writeUInt8(out, (line1->flags >> 8));
SWFOutput_writeUInt8(out, line1->flags);
if(line1->flags & SWF_LINESTYLE_JOIN_MITER)
SWFOutput_writeFixed8(out, line1->miterLimit);
if(line1->flags & SWF_LINESTYLE_FLAG_FILL)
SWFOutput_writeMorphFillStyle(out, line1->fill, NULL, line2->fill, NULL);
else
{
SWFOutput_writeUInt8(out, line1->r);
SWFOutput_writeUInt8(out, line1->g);
SWFOutput_writeUInt8(out, line1->b);
SWFOutput_writeUInt8(out, line1->a);
SWFOutput_writeUInt8(out, line2->r);
SWFOutput_writeUInt8(out, line2->g);
SWFOutput_writeUInt8(out, line2->b);
SWFOutput_writeUInt8(out, line2->a);
}
}
}
void SWFOutput_writeMorphLineStyles(SWFOutput out,
SWFLineStyle *lines1, int nLines1,
SWFLineStyle *lines2, int nLines2)
{
SWFLineStyle line1, line2;
int i;
SWF_assert(nLines1 == nLines2);
if(nLines1<255)
SWFOutput_writeUInt8(out, nLines1);
else
{
SWFOutput_writeUInt8(out, 255);
SWFOutput_writeUInt16(out, nLines1);
}
for(i=0; i<nLines1; ++i)
{
line1 = lines1[i];
line2 = lines2[i];
SWFOutput_writeUInt16(out, line1->width);
SWFOutput_writeUInt16(out, line2->width);
SWFOutput_writeUInt8(out, line1->r);
SWFOutput_writeUInt8(out, line1->g);
SWFOutput_writeUInt8(out, line1->b);
SWFOutput_writeUInt8(out, line1->a);
SWFOutput_writeUInt8(out, line2->r);
SWFOutput_writeUInt8(out, line2->g);
SWFOutput_writeUInt8(out, line2->b);
SWFOutput_writeUInt8(out, line2->a);
}
}
/*
* Local variables:
* tab-width: 2
* c-basic-offset: 2
* End:
*/