[mapserver-dev] SWF Output : Labels + Ming 0.4
laurent.baey at free.fr
laurent.baey at free.fr
Mon Jan 12 05:26:21 EST 2009
Hi all,
I've been working on mapswf.c to enhance label readability. I decided
to use filters on movieClips in order to add
- a Glowing Effect when an outline is set on the label
- a DropShadow Effect when a shadow is set on the label
these are not too shiny, but really enhance the map I think.
It reduces the memory size of the map as well, as the label is not
duplicated, but enhanced at Flash run time.
I had to switch to Ming 0.4.1 to do so. It adds a lot of new features
and is quite stable for now.
Some functions where deprecated, I choose to use the new ones, so I
think there's a little work to do in order to detect which Ming
version is present at configure time, and then choose the old, or the
new set of functions.
Everything works quite well, so I give here my mapswf.c, maybe Assefa
can take a look, add the necessary ifdefs, and if someone likes the
effects, commit :).
Thank you
Laurent Baey
----------------------------------------------------------------
This message was sent using IMP, the Internet Messaging Program.
-------------- next part --------------
/******************************************************************************
* $Id: mapswf.c 7544 2008-04-29 18:16:05Z pramsey $
*
* Project: MapServer
* Purpose: Macromedia flash output
* Author: Y. Assefa, DM Solutions Group (assefa at dmsolutions.ca)
*
* Note:
* This api is based on the ming swf library :
* http://www.opaque.net/ming/
*
******************************************************************************
* Copyright (c) 1996-2005 Regents of the University of Minnesota.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies of this Software or works derived from this Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
****************************************************************************/
#ifdef USE_MING_FLASH
#include <assert.h>
#if !defined(_WIN32)
#include <zlib.h>
#endif
#include "mapserver.h"
#include "mapswf.h"
MS_CVSID("$Id: mapswf.c 7544 2008-04-29 18:16:05Z pramsey $")
static char gszFilename[128];
static char gszAction[256];
static char gszTmp[256];
#define MOUSEUP 1
#define MOUSEDOWN 2
#define MOUSEOVER 3
#define MOUSEOUT 4
/* -------------------------------------------------------------------- */
/* prototypes. */
/* -------------------------------------------------------------------- */
SWFMovie GetCurrentMovie(mapObj *map, imageObj *image);
/************************************************************************/
/* void StoreDblData */
/* */
/* Keep tracks of the DblData allocated to properly free them */
/* Ticket #2555 */
/************************************************************************/
void StoreDblData(unsigned char *oDblData, imageObj *image)
{
int nDblData;
((SWFObj *)image->img.swf)->nDblDatas += 1;
nDblData = ((SWFObj *)image->img.swf)->nDblDatas;
if (!((SWFObj *)image->img.swf)->DblDatas)
{
((SWFObj *)image->img.swf)->DblDatas =
(unsigned char **)malloc(sizeof(oDblData)*1);
}
else
{
((SWFObj *)image->img.swf)->DblDatas =
(unsigned char **)realloc(((SWFObj *)image->img.swf)->DblDatas,
sizeof(oDblData)*nDblData);
}
((SWFObj *)image->img.swf)->DblDatas[nDblData-1] = oDblData;
}
/************************************************************************/
/* void StoreShape */
/* */
/* Keep tracks of the SWFShape allocated to properly free them */
/* Ticket #2555 */
/************************************************************************/
void StoreShape(SWFShape oShape, imageObj *image)
{
int nShape;
((SWFObj *)image->img.swf)->nShapes += 1;
nShape = ((SWFObj *)image->img.swf)->nShapes;
if (!((SWFObj *)image->img.swf)->Shapes)
{
((SWFObj *)image->img.swf)->Shapes =
(SWFShape *)malloc(sizeof(SWFShape));
}
else
{
((SWFObj *)image->img.swf)->Shapes =
(SWFShape *)realloc(((SWFObj *)image->img.swf)->Shapes,
sizeof(SWFShape)*nShape);
}
((SWFObj *)image->img.swf)->Shapes[nShape-1] = oShape;
}
/************************************************************************/
/* void StoreInput */
/* */
/* Keep tracks of the SWFInput allocated to properly free them */
/* Ticket #2555 */
/************************************************************************/
void StoreInput(SWFInput oInput, imageObj *image)
{
int nInput;
((SWFObj *)image->img.swf)->nInputs += 1;
nInput = ((SWFObj *)image->img.swf)->nInputs;
if (!((SWFObj *)image->img.swf)->Inputs)
{
((SWFObj *)image->img.swf)->Inputs =
(SWFInput *)malloc(sizeof(SWFInput));
}
else
{
((SWFObj *)image->img.swf)->Inputs =
(SWFInput *)realloc(((SWFObj *)image->img.swf)->Inputs,
sizeof(SWFInput)*nInput);
}
((SWFObj *)image->img.swf)->Inputs[nInput-1] = oInput;
}
/************************************************************************/
/* void StoreBitmap */
/* */
/* Keep tracks of the SWFBitmap allocated to properly free them */
/* Ticket #2555 */
/************************************************************************/
void StoreBitmap(SWFBitmap oBitmap, imageObj *image)
{
int nBitmap;
((SWFObj *)image->img.swf)->nBitmaps += 1;
nBitmap = ((SWFObj *)image->img.swf)->nBitmaps;
if (!((SWFObj *)image->img.swf)->Bitmaps)
{
((SWFObj *)image->img.swf)->Bitmaps =
(SWFBitmap *)malloc(sizeof(SWFBitmap));
}
else
{
((SWFObj *)image->img.swf)->Bitmaps =
(SWFBitmap *)realloc(((SWFObj *)image->img.swf)->Bitmaps,
sizeof(SWFBitmap)*nBitmap);
}
((SWFObj *)image->img.swf)->Bitmaps[nBitmap-1] = oBitmap;
}
/************************************************************************/
/* void StoreButton */
/* */
/* Keep tracks of the SWFButton allocated to properly free them */
/* Ticket #2555 */
/************************************************************************/
void StoreButton(SWFButton oButton, imageObj *image)
{
int nButton;
((SWFObj *)image->img.swf)->nButtons += 1;
nButton = ((SWFObj *)image->img.swf)->nButtons;
if (!((SWFObj *)image->img.swf)->Buttons)
{
((SWFObj *)image->img.swf)->Buttons =
(SWFButton *)malloc(sizeof(oButton));
}
else
{
((SWFObj *)image->img.swf)->Buttons =
(SWFButton *)realloc(((SWFObj *)image->img.swf)->Buttons,
sizeof(oButton)*nButton);
}
((SWFObj *)image->img.swf)->Buttons[nButton-1] = oButton;
}
/************************************************************************/
/* void StoreFont */
/* */
/* Keep tracks of the SWFFont allocated to properly free them */
/* Ticket #2555 */
/************************************************************************/
void StoreFont(SWFFont oFont, imageObj *image)
{
int nFont;
((SWFObj *)image->img.swf)->nFonts += 1;
nFont = ((SWFObj *)image->img.swf)->nFonts;
if (!((SWFObj *)image->img.swf)->Fonts)
{
((SWFObj *)image->img.swf)->Fonts =
(SWFFont *)malloc(sizeof(oFont));
}
else
{
((SWFObj *)image->img.swf)->Fonts =
(SWFFont *)realloc(((SWFObj *)image->img.swf)->Fonts,
sizeof(oFont)*nFont);
}
((SWFObj *)image->img.swf)->Fonts[nFont-1] = oFont;
}
/************************************************************************/
/* void StoreText */
/* */
/* Keep tracks of the SWFText allocated to properly free them */
/* Ticket #2555 */
/************************************************************************/
void StoreText(SWFText oText, imageObj *image)
{
int nText;
((SWFObj *)image->img.swf)->nTexts += 1;
nText = ((SWFObj *)image->img.swf)->nTexts;
if (!((SWFObj *)image->img.swf)->Texts)
{
((SWFObj *)image->img.swf)->Texts =
(SWFText *)malloc(sizeof(oText));
}
else
{
((SWFObj *)image->img.swf)->Texts =
(SWFText *)realloc(((SWFObj *)image->img.swf)->Texts,
sizeof(oText)*nText);
}
((SWFObj *)image->img.swf)->Texts[nText-1] = oText;
}
/************************************************************************/
/* gdImagePtr getTileImageFromSymbol */
/* */
/* Returns a gdimage from a symbol that will be used to fill */
/* polygons. Returns NULL on error. */
/* */
/* Returned image should only be destroyed by caller if the */
/* bDestroyImage is set to 1. */
/* */
/************************************************************************/
#ifdef unused
gdImagePtr getTileImageFromSymbol(mapObj *map, symbolSetObj *symbolset,
int sy, int fc, int bc, int oc,
double sz, int *bDestroyImage)
{
#ifdef undef
symbolObj *symbol;
int i;
gdPoint oldpnt,newpnt;
gdPoint sPoints[MS_MAXVECTORPOINTS];
gdImagePtr tile = NULL;
int x,y;
int tile_bg=-1, tile_fg=-1; /*colors (background and foreground)*/
double scale=1.0;
int bbox[8];
rectObj rect;
char *font=NULL;
colorObj sFc;
colorObj sBc;
colorObj sOc;
colorObj sColor0;
/* -------------------------------------------------------------------- */
/* validate params. */
/* -------------------------------------------------------------------- */
if (!map || !symbolset || sy > symbolset->numsymbols || sy < 0)
return NULL;
/* -------------------------------------------------------------------- */
/* extract the colors. */
/* -------------------------------------------------------------------- */
getRgbColor(map, fc, &sFc.red, &sFc.green, &sFc.blue);
getRgbColor(map, bc, &sBc.red, &sBc.green, &sBc.blue);
getRgbColor(map, oc, &sOc.red, &sOc.green, &sOc.blue);
getRgbColor(map, 0, &sColor0.red, &sColor0.green, &sColor0.blue);
symbol = &(symbolset->symbol[sy]);
switch(symbol->type)
{
case(MS_SYMBOL_TRUETYPE):
#if defined (USE_GD_FT) || defined (USE_GD_TTF)
font = msLookupHashTable(&(symbolset->fontset->fonts),
symbolset->symbol[sy]->font);
if(!font)
return NULL;
if(msGetCharacterSize(symbol->character, sz, font, &rect) != MS_SUCCESS)
return NULL;
x = rect.maxx - rect.minx;
y = rect.maxy - rect.miny;
tile = gdImageCreate(x, y);
if(bc >= 0)
tile_bg =
gdImageColorAllocate(tile, sBc.red, sBc.green, sBc.blue);
else
{
tile_bg = gdImageColorAllocate(tile, sColor0.red,
sColor0.green,
sColor0.blue);
gdImageColorTransparent(tile,0);
}
tile_fg = gdImageColorAllocate(tile, sFc.red, sFc.green, sFc.blue);
x = -rect.minx;
y = -rect.miny;
gdImageStringFT(tile, bbox,
((symbol->antialias)?(tile_fg):-(tile_fg)),
font, sz, 0, x, y, symbol->character);
#endif
if (bDestroyImage)
*bDestroyImage = 1;
break;
case(MS_SYMBOL_PIXMAP):
tile = symbol->img;
if (bDestroyImage)
*bDestroyImage = 0;
break;
case(MS_SYMBOL_ELLIPSE):
scale = sz/symbol->sizey; /* sz ~ height in pixels */
x = MS_NINT(symbol->sizex*scale)+1;
y = MS_NINT(symbol->sizey*scale)+1;
if((x <= 1) && (y <= 1))
{ /* No sense using a tile, just fill solid */
if (bDestroyImage)
*bDestroyImage = 0;
tile = NULL;
break;
}
tile = gdImageCreate(x, y);
if(bc >= 0)
tile_bg = gdImageColorAllocate(tile, sBc.red,
sBc.green, sBc.blue);
else
{
tile_bg = gdImageColorAllocate(tile, sColor0.red,
sColor0.green,
sColor0.blue);
gdImageColorTransparent(tile,0);
}
tile_fg = gdImageColorAllocate(tile, sFc.red, sFc.green, sFc.blue);
x = MS_NINT(tile->sx/2);
y = MS_NINT(tile->sy/2);
/*
** draw in the tile image
*/
gdImageArc(tile, x, y, MS_NINT(scale*symbol->points[0].x),
MS_NINT(scale*symbol->points[0].y), 0, 360, tile_fg);
if(symbol->filled)
gdImageFillToBorder(tile, x, y, tile_fg, tile_fg);
if (bDestroyImage)
*bDestroyImage = 1;
break;
case(MS_SYMBOL_VECTOR):
if(fc < 0)
{
if (bDestroyImage)
*bDestroyImage = 0;
tile = NULL;
break;
}
scale = sz/symbol->sizey; /* sz ~ height in pixels */
x = MS_NINT(symbol->sizex*scale)+1;
y = MS_NINT(symbol->sizey*scale)+1;
if((x <= 1) && (y <= 1))
{ /* No sense using a tile, just fill solid */
if (bDestroyImage)
*bDestroyImage = 0;
tile = NULL;
break;
}
/*
** create tile image
*/
tile = gdImageCreate(x, y);
if(bc >= 0)
tile_bg = gdImageColorAllocate(tile, sBc.red,
sBc.green, sBc.blue);
else
{
tile_bg = gdImageColorAllocate(tile, sColor0.red,
sColor0.green,
sColor0.blue);
gdImageColorTransparent(tile,0);
}
tile_fg = gdImageColorAllocate(tile, sFc.red, sFc.green, sFc.blue);
/*
** draw in the tile image
*/
if(symbol->filled)
{
for(i=0;i < symbol->numpoints;i++)
{
sPoints[i].x = MS_NINT(scale*symbol->points[i].x);
sPoints[i].y = MS_NINT(scale*symbol->points[i].y);
}
gdImageFilledPolygon(tile, sPoints, symbol->numpoints, tile_fg);
}
else
{ /* shade is a vector drawing */
oldpnt.x = MS_NINT(scale*symbol->points[0].x); /* convert first point in shade smbol */
oldpnt.y = MS_NINT(scale*symbol->points[0].y);
/* step through the shade sy */
for(i=1;i < symbol->numpoints;i++) {
if((symbol->points[i].x < 0) && (symbol->points[i].y < 0)) {
oldpnt.x = MS_NINT(scale*symbol->points[i].x);
oldpnt.y = MS_NINT(scale*symbol->points[i].y);
} else {
if((symbol->points[i-1].x < 0) && (symbol->points[i-1].y < 0)) { /* Last point was PENUP, now a new beginning */
oldpnt.x = MS_NINT(scale*symbol->points[i].x);
oldpnt.y = MS_NINT(scale*symbol->points[i].y);
} else {
newpnt.x = MS_NINT(scale*symbol->points[i].x);
newpnt.y = MS_NINT(scale*symbol->points[i].y);
gdImageLine(tile, oldpnt.x, oldpnt.y, newpnt.x, newpnt.y, tile_fg);
oldpnt = newpnt;
}
}
} /* end for loop */
}
if (bDestroyImage)
*bDestroyImage = 1;
break;
default:
break;
}
return tile;
#endif /* undef */
return NULL;
}
#endif /* unused */
/************************************************************************/
/* SWFShape bitmap2shape */
/* */
/* Return a filled polygon shape using a bitmap. */
/************************************************************************/
SWFShape bitmap2shape(unsigned char *data,unsigned long size,int width,
int height, byte flags, imageObj *image)
{
SWFShape oShape;
SWFInput oBuffer;
SWFFill oFill;
SWFBitmap oBitmap;
if (!data || width <= 0 || height <= 0)
return NULL;
oShape = newSWFShape();
oBuffer = newSWFInput_buffer(data,size);
StoreInput(oBuffer, image);
oBitmap = newSWFBitmap_fromInput(oBuffer);
StoreBitmap(oBitmap, image);
oFill = SWFShape_addBitmapFill(oShape, oBitmap, flags);
/* oFill = SWFShape_addBitmapFill(oShape, oBitmap, 0); */
SWFShape_setRightFill(oShape, oFill);
destroySWFFill(oFill);
SWFShape_drawLine(oShape, (float)width, 0.0);
SWFShape_drawLine(oShape, 0.0, (float)height);
SWFShape_drawLine(oShape, (float)-width, 0.0);
SWFShape_drawLine(oShape, 0.0, (float)-height);
return oShape;
}
/************************************************************************/
/* unsigned char *bitmap2dbl */
/* */
/* Converts a bitmap to dbl bitmap suitable for ming. */
/************************************************************************/
unsigned char *bitmap2dbl(unsigned char *data,int *size, int *bytesPerColor)
{
unsigned char *outdata,*dbldata;
unsigned long outsize;
int i,j;
outsize = (int) floor(*size*1.01+12);
dbldata = (unsigned char *) malloc(outsize + 14);
outdata=&dbldata[14];
compress2(outdata,&outsize,data+6,*size-6,6);
dbldata[0] = 'D';
dbldata[1] = 'B';
dbldata[2] = 'l';
dbldata[3] = (unsigned char)(*bytesPerColor == 3 ? 1 : 2);
dbldata[4] = (unsigned char)(((outsize+6) >> 24) & 0xFF);
dbldata[5] = (unsigned char)(((outsize+6) >> 16) & 0xFF);
dbldata[6] = (unsigned char)(((outsize+6) >> 8) & 0xFF);
dbldata[7] = (unsigned char)(((outsize+6) >> 0) & 0xFF);
for (i=8,j=0;i<14;i++,j++) {
dbldata[i] = data[j];
}
*size = outsize + 14;
return(dbldata);
}
/************************************************************************/
/* nsigned char *gd2bitmap */
/* */
/* Convert a gd image to a bitmap. */
/************************************************************************/
unsigned char *gd2bitmap(gdImagePtr img,int *size, int *bytesPerColor)
{
int width,height;
int alignedWidth;
unsigned char *data;
unsigned char *p;
unsigned char *line;
int i;
width = img->sx;
height = img->sy;
alignedWidth = (width + 3) & ~3;
*bytesPerColor = 3;
if (img->transparent >= 0 ) *bytesPerColor += 1;
*size = 6 + (img->colorsTotal * *bytesPerColor) + (alignedWidth * height);
data= (unsigned char *)malloc(*size);
p=data;
*p++ = 3;
*p++ = (unsigned char)((width>> 0) & 0xFF);
*p++ = (unsigned char)((width >> 8) & 0xFF);
*p++ = (unsigned char)((height >> 0) & 0xFF);
*p++ = (unsigned char)((height >> 8) & 0xFF);
*p++ = (unsigned char)(img->colorsTotal - 1);
for (i=0;i<img->colorsTotal;++i) {
if (*bytesPerColor == 3) {
*p++ = (unsigned char)(img->red[i]);
*p++ = (unsigned char)(img->green[i]);
*p++ = (unsigned char)(img->blue[i]);
} else {
if (i != img->transparent) {
*p++ = (unsigned char)(img->red[i]);
*p++ = (unsigned char)(img->green[i]);
*p++ = (unsigned char)(img->blue[i]);
*p++ = 255;
} else {
*p++ = 0;
*p++ = 0;
*p++ = 0;
*p++ = 0;
}
}
}
line=*(img->pixels);
for (i=0;i<height;i++) {
line = img->pixels[i];
memset(p,1,alignedWidth);
memcpy(p,line,width);
p += alignedWidth;
}
return(data);
}
/************************************************************************/
/* SWFShape gdImage2Shape */
/* */
/* Utility function to create an SWF filled shape using a gd */
/* image. */
/* */
/* Conversion functions were provided by : */
/* Jan Hartmann <jhart at frw.uva.nl> */
/************************************************************************/
SWFShape gdImage2Shape(gdImagePtr img, imageObj *image)
{
unsigned char *data, *dbldata;
int size;
int bytesPerColor;
SWFShape oShape;
if (!img)
return NULL;
data = gd2bitmap(img, &size, &bytesPerColor);
dbldata = bitmap2dbl(data,&size,&bytesPerColor);
free(data); /* memory leak cf ticket #2555 */
oShape = bitmap2shape(dbldata, size, img->sx, img->sy, SWFFILL_SOLID, image);
StoreDblData(dbldata, image); /* memory leak cf ticket #2555 */
return oShape;
}
/************************************************************************/
/* SWFButton BuildButtonFromGD */
/* */
/* Return a button object using a GD image. */
/************************************************************************/
SWFButton BuildButtonFromGD(gdImagePtr img, imageObj *image)/* , colorObj *psHighlightColor) */
{
SWFShape oShape;
SWFButton oButton;
/* TODO : highlight of the pixmap symbol */
if (!img)
return NULL;
oShape = gdImage2Shape(img, image);
StoreShape(oShape, image);
oButton = newSWFButton();
SWFButton_addCharacter(oButton, (SWFCharacter) oShape,
SWFBUTTON_UP | SWFBUTTON_HIT | SWFBUTTON_DOWN | SWFBUTTON_OVER);
return oButton;
}
/************************************************************************/
/* SWFShape BuildEllipseShape */
/* */
/* Build an circle shape centered at nX, nY with the width and */
/* height being the circumfernce. */
/************************************************************************/
SWFShape BuildEllipseShape(int nX, int nY, int nWidth, int nHeight,
colorObj *psFillColor, colorObj *psOutlineColor)
{
SWFShape oShape;
SWFFill oFill;
oShape = newSWFShape();
if (psFillColor == NULL && psOutlineColor == NULL)
return NULL;
if (psOutlineColor)
SWFShape_setLine(oShape, 0, (byte)psOutlineColor->red,
(byte)psOutlineColor->green, (byte)psOutlineColor->blue, 0xff);
if (psFillColor) {
/* correct memory leak by catching the SWFFill*/
oFill = SWFShape_addSolidFill(oShape, (byte)psFillColor->red,
(byte)psFillColor->green,
(byte)psFillColor->blue,
0xff);
SWFShape_setRightFill(oShape, oFill);
/* and destroying it */
destroySWFFill(oFill);
}
SWFShape_movePenTo(oShape, (float)(nX-(nWidth/2)), (float)nY);
/* TODO : we should maybe use SWFShape_drawArc(shape, r, 0, 360) */
/* Bottom Left */
SWFShape_drawCurveTo(oShape, (float)(nX-(nWidth/2)),
(float)(nY+(nHeight/2)),
(float)nX, (float)(nY+(nHeight/2)));
/* Bottom Right */
SWFShape_drawCurveTo(oShape, (float)(nX + (nWidth/2)),
(float)(nY+(nHeight/2)),
(float)(nX+(nWidth/2)), (float)nY);
/* Top Right */
SWFShape_drawCurveTo(oShape, (float)(nX +(nWidth/2)),
(float)(nY-(nHeight/2)),
(float)nX, (float)(nY-(nHeight/2)));
/* Top Left */
SWFShape_drawCurveTo(oShape, (float)(nX - (nWidth/2)),
(float)(nY-(nHeight/2)),
(float)(nX-(nWidth/2)), (float)nY);
return oShape;
}
/************************************************************************/
/* AddMouseActions */
/* */
/* addActions in an SWF Button. */
/************************************************************************/
void AddMouseActions(SWFButton oButton, int nLayerIndex, int nShapeIndex)
{
SWFAction oAction;
if (nLayerIndex >=0 && nShapeIndex >= 0)
{
sprintf(gszAction, "_root.ElementSelected(%d,%d,%d);", nLayerIndex,
nShapeIndex, MOUSEUP);
oAction = newSWFAction(gszAction);
SWFButton_addAction(oButton, oAction, SWFBUTTON_MOUSEUP);
sprintf(gszAction, "_root.ElementSelected(%d,%d,%d);", nLayerIndex,
nShapeIndex, MOUSEDOWN);
oAction = newSWFAction(gszAction);
SWFButton_addAction(oButton, oAction, SWFBUTTON_MOUSEDOWN);
sprintf(gszAction, "_root.ElementSelected(%d,%d,%d);", nLayerIndex,
nShapeIndex, MOUSEOVER);
oAction = newSWFAction(gszAction);
SWFButton_addAction(oButton, oAction, SWFBUTTON_MOUSEOVER);
sprintf(gszAction, "_root.ElementSelected(%d,%d,%d);", nLayerIndex,
nShapeIndex, MOUSEOUT);
oAction = newSWFAction(gszAction);
SWFButton_addAction(oButton, oAction, SWFBUTTON_MOUSEOUT);
}
}
/************************************************************************/
/* SWFButton BuildEllipseButton */
/* */
/* Returns a button object containg a circle shape. */
/************************************************************************/
SWFButton BuildEllipseButton(int nX, int nY, int nWidth, int nHeight,
colorObj *psFillColor, colorObj *psOutlineColor,
colorObj *psHightlightColor,
int nLayerIndex, int nShapeIndex, imageObj *image)
{
SWFShape oShape;
SWFButton oButton;
if (nX < 0 || nY < 0 || nWidth < 0 || nHeight < 0 ||
(psFillColor == NULL && psOutlineColor == NULL))
return NULL;
oShape = BuildEllipseShape(nX, nY, nWidth, nHeight, psFillColor,
psOutlineColor);
StoreShape(oShape, image);
oButton = newSWFButton();
SWFButton_addCharacter(oButton, (SWFCharacter) oShape,
SWFBUTTON_UP | SWFBUTTON_HIT | SWFBUTTON_DOWN);
if (psHightlightColor)
{
oShape = BuildEllipseShape(nX, nY, nWidth, nHeight, psHightlightColor,
NULL);
StoreShape(oShape, image);
}
SWFButton_addCharacter(oButton, (SWFCharacter) oShape, SWFBUTTON_OVER);
if (nLayerIndex >=0 && nShapeIndex >= 0)
{
AddMouseActions(oButton, nLayerIndex, nShapeIndex);
}
return oButton;
}
/************************************************************************/
/* SWFShape BuildPolygonShape */
/* */
/* Build a polygon shape. */
/************************************************************************/
SWFShape BuildPolygonShape(shapeObj *p, colorObj *psFillColor,
colorObj *psOutlineColor, int width)
{
int i, j;
SWFShape oShape;
SWFFill oFill;
if (p && p->numlines > 0 && (psFillColor !=NULL || psOutlineColor != NULL))
{
oShape = newSWFShape();
if (psOutlineColor)
SWFShape_setLine(oShape, width, (byte)psOutlineColor->red,
(byte)psOutlineColor->green, (byte)psOutlineColor->blue, 0xff);
if (psFillColor)
{
oFill = SWFShape_addSolidFill(oShape,
(byte)psFillColor->red,
(byte)psFillColor->green,
(byte)psFillColor->blue,
0xff);
SWFShape_setRightFill(oShape, oFill);
destroySWFFill(oFill);
}
for (i = 0; i < p->numlines; i++)
{
if (p->line[i].numpoints)
{
SWFShape_movePenTo(oShape, (float)p->line[i].point[0].x,
(float)p->line[i].point[0].y);
}
for(j=1; j<p->line[i].numpoints; j++)
{
SWFShape_drawLineTo(oShape, (float)p->line[i].point[j].x,
(float)p->line[i].point[j].y);
}
}
return oShape;
}
return NULL;
}
/************************************************************************/
/* SWFShape BuildShape(gdPoint adfPoints[], int nPoints, */
/* colorObj *psFillColor, */
/* colorObj *psOutlineColor) */
/* */
/* Build a polygon shape. Used for symbols */
/************************************************************************/
SWFShape BuildShape(gdPoint adfPoints[], int nPoints,
colorObj *psFillColor,
colorObj *psOutlineColor)
{
SWFShape oShape = newSWFShape();
SWFFill oFill;
int i = 0;
if (psFillColor == NULL && psOutlineColor == NULL)
return NULL;
if (psFillColor)
{
if (psOutlineColor)
SWFShape_setLine(oShape, 0, (byte)psOutlineColor->red,
(byte)psOutlineColor->green, (byte)psOutlineColor->blue, 0xff);
oFill = SWFShape_addSolidFill(oShape,
(byte)psFillColor->red,
(byte)psFillColor->green,
(byte)psFillColor->blue,
0xff);
SWFShape_setRightFill(oShape, oFill);
destroySWFFill(oFill);
/*SWFShape_setRightFill(oShape,
SWFShape_addSolidFill(oShape, 0xFF,
0,
0, 0xff));*/
}
else
SWFShape_setLine(oShape, 5, (byte)psOutlineColor->red,
(byte)psOutlineColor->green,
(byte)psOutlineColor->blue, 0xff);
SWFShape_movePenTo(oShape, (float)adfPoints[0].x, (float)adfPoints[0].y);
for (i=1; i<nPoints; i++)
{
SWFShape_drawLineTo(oShape, (float)adfPoints[i].x,
(float)adfPoints[i].y);
}
/* close the polygon */
SWFShape_drawLineTo(oShape, (float)adfPoints[0].x, (float)adfPoints[0].y);
return oShape;
}
/************************************************************************/
/* SWFShape BuildShapeLine(gdPoint adfPoints[], int nPoints, */
/* colorObj *psColor) */
/* */
/* Build a shape line : used for symbols. */
/************************************************************************/
SWFShape BuildShapeLine(gdPoint adfPoints[], int nPoints,
colorObj *psColor)
{
SWFShape oShape = newSWFShape();
int i = 0;
if (psColor == NULL || nPoints <= 0)
return NULL;
SWFShape_setLine(oShape, 0, (byte)psColor->red,
(byte)psColor->green, (byte)psColor->blue, 0xff);
SWFShape_movePenTo(oShape, (float)adfPoints[0].x, (float)adfPoints[0].y);
for (i=1; i<nPoints; i++)
{
if (adfPoints[i].x >= 0 && adfPoints[i].y >= 0)
{
if (adfPoints[i-1].x < 0 && adfPoints[i-1].y < 0)
{
SWFShape_movePenTo(oShape, (float)adfPoints[i].x,
(float)adfPoints[i].y);
}
else
SWFShape_drawLineTo(oShape, (float)adfPoints[i].x,
(float)adfPoints[i].y);
}
}
return oShape;
}
/************************************************************************/
/* SWFButton BuildButtonPolygon */
/* */
/* Build a button and add a polygon shape in it. */
/* */
/************************************************************************/
SWFButton BuildButtonPolygon(gdPoint adfPoints[], int nPoints,
colorObj *psFillColor,
colorObj *psOutlineColor,
colorObj *psHighlightColor,
int nLayerIndex, int nShapeIndex, imageObj *image)
{
SWFButton oButton;
SWFShape oShape;
/* int bFill = 0; */
oButton = newSWFButton();
oShape = BuildShape(adfPoints, nPoints, psFillColor, psOutlineColor);
StoreShape(oShape, image);
SWFButton_addCharacter(oButton, (SWFCharacter) oShape,
SWFBUTTON_UP | SWFBUTTON_HIT | SWFBUTTON_DOWN);
if (psHighlightColor)
{
if(psFillColor)
{
oShape = BuildShape(adfPoints, nPoints, psHighlightColor, NULL);
StoreShape(oShape, image);
SWFButton_addCharacter(oButton, (SWFCharacter) oShape, SWFBUTTON_OVER);
}
else if (psOutlineColor)
{
oShape = BuildShape(adfPoints, nPoints, NULL, psHighlightColor);
StoreShape(oShape, image);
SWFButton_addCharacter(oButton, (SWFCharacter) oShape, SWFBUTTON_OVER);
}
}
if (nLayerIndex >=0 && nShapeIndex >= 0)
{
AddMouseActions(oButton, nLayerIndex, nShapeIndex);
}
return oButton;
}
/************************************************************************/
/* SWFButton BuildButtonLine */
/* */
/* Build a button and add a line shape in it. */
/************************************************************************/
SWFButton BuildButtonLine(gdPoint adfPoints[], int nPoints,
colorObj *psFillColor,
colorObj *psHighlightColor,
int nLayerIndex, int nShapeIndex)
{
SWFButton oButton;
/* int bFill = 0; */
oButton = newSWFButton();
if (psFillColor == NULL)
return NULL;
SWFButton_addCharacter(oButton,
(SWFCharacter)BuildShapeLine(adfPoints, nPoints, psFillColor),
SWFBUTTON_UP | SWFBUTTON_HIT | SWFBUTTON_DOWN);
if (psHighlightColor)
{
SWFButton_addCharacter(oButton,
(SWFCharacter)BuildShapeLine(adfPoints, nPoints, psHighlightColor),
SWFBUTTON_OVER);
}
if (nLayerIndex >=0 && nShapeIndex >= 0)
{
AddMouseActions(oButton, nLayerIndex, nShapeIndex);
}
return oButton;
}
/************************************************************************/
/* imageObj *msImageCreateSWF */
/* */
/* Utility function to create an image object of SWF type */
/************************************************************************/
imageObj *msImageCreateSWF(int width, int height, outputFormatObj *format,
char *imagepath, char *imageurl, mapObj *map)
{
imageObj *image = NULL;
char *driver = strdup("GD/GIF");
assert( strcasecmp(format->driver,"SWF") == 0 );
image = (imageObj *)calloc(1,sizeof(imageObj));
image->format = format;
format->refcount++;
image->width = width;
image->height = height;
image->imagepath = NULL;
image->imageurl = NULL;
if (imagepath)
{
image->imagepath = strdup(imagepath);
}
if (imageurl)
{
image->imageurl = strdup(imageurl);
}
image->img.swf = (SWFObj *)malloc(sizeof(SWFObj));
((SWFObj *)image->img.swf)->map = map;
((SWFObj *)image->img.swf)->nCurrentLayerIdx = -1;
((SWFObj *)image->img.swf)->nCurrentShapeIdx = -1;
((SWFObj *)image->img.swf)->nLayerMovies = 0;
((SWFObj *)image->img.swf)->pasMovies = NULL;
((SWFObj *)image->img.swf)->nCurrentMovie = -1;
((SWFObj *)image->img.swf)->nFonts = 0;
((SWFObj *)image->img.swf)->Fonts = NULL;
((SWFObj *)image->img.swf)->nTexts = 0;
((SWFObj *)image->img.swf)->Texts = NULL;
((SWFObj *)image->img.swf)->nShapes = 0;
((SWFObj *)image->img.swf)->Shapes = NULL;
((SWFObj *)image->img.swf)->nBitmaps = 0;
((SWFObj *)image->img.swf)->Bitmaps = NULL;
((SWFObj *)image->img.swf)->nInputs = 0;
((SWFObj *)image->img.swf)->Inputs = NULL;
((SWFObj *)image->img.swf)->nButtons = 0;
((SWFObj *)image->img.swf)->Buttons = NULL;
((SWFObj *)image->img.swf)->nDblDatas = 0;
((SWFObj *)image->img.swf)->DblDatas = NULL;
((SWFObj *)image->img.swf)->panLayerIndex = NULL;
((SWFObj *)image->img.swf)->nTmpCount = 0;
/* initalize main movie */
((SWFObj *)image->img.swf)->sMainMovie = newSWFMovie();
SWFMovie_setDimension(((SWFObj *)image->img.swf)->sMainMovie, (float)width,
(float)height);
SWFMovie_setBackground(((SWFObj *)image->img.swf)->sMainMovie, map->imagecolor.red,
map->imagecolor.green, map->imagecolor.blue);
/* -------------------------------------------------------------------- */
/* if the output is a single movie, we crate a GD image that */
/* will be used to conating the rendering of al the layers. */
/* -------------------------------------------------------------------- */
if (strcasecmp(msGetOutputFormatOption(image->format,"OUTPUT_MOVIE",""),
"MULTIPLE") == 0)
{
((SWFObj *)image->img.swf)->imagetmp = NULL;
}
else
{
#ifdef USE_GD_GIF
driver = strdup("GD/GIF");
#else
#ifdef USE_GD_PNG
driver = strdup("GD/PNG");
#else
#ifdef USE_GD_JPEG
driver = strdup("GD/JPEG");
#else
#ifdef USE_GD_WBMP
driver = strdup("GD/WBMP");
#endif
#endif
#endif
#endif
((SWFObj *)image->img.swf)->imagetmp = (imageObj *)
msImageCreateGD(map->width, map->height,
msCreateDefaultOutputFormat(map, driver),
map->web.imagepath, map->web.imageurl);
}
free(driver);
return image;
}
/************************************************************************/
/* void msImageStartLayerSWF */
/* */
/* Strart of layer drawing. Create a new movie for the layer. */
/* */
/************************************************************************/
void msImageStartLayerSWF(mapObj *map, layerObj *layer, imageObj *image)
{
int nTmp = 0;
char szAction[200];
SWFAction oAction;
int i = 0;
int n = -1;
char **tokens;
char *metadata;
if (image && MS_DRIVER_SWF(image->format))
{
/* -------------------------------------------------------------------- */
/* If the output is not multiple layers, do nothing. */
/* -------------------------------------------------------------------- */
if (strcasecmp(msGetOutputFormatOption(image->format,"OUTPUT_MOVIE",
""),
"MULTIPLE") != 0)
return;
((SWFObj *)image->img.swf)->nLayerMovies++;
nTmp = ((SWFObj *)image->img.swf)->nLayerMovies;
if (!((SWFObj *)image->img.swf)->pasMovies)
{
((SWFObj *)image->img.swf)->pasMovies =
(SWFMovie *)malloc(sizeof(SWFMovie)*nTmp);
((SWFObj *)image->img.swf)->panLayerIndex =
(int *)malloc(sizeof(int)*nTmp);
}
else
{
((SWFObj *)image->img.swf)->pasMovies =
(SWFMovie *)realloc(((SWFObj *)image->img.swf)->pasMovies,
sizeof(SWFMovie)*nTmp);
((SWFObj *)image->img.swf)->panLayerIndex =
(int *)realloc(((SWFObj *)image->img.swf)->panLayerIndex,
sizeof(int)*nTmp);
}
((SWFObj *)image->img.swf)->nCurrentMovie = nTmp -1;
((SWFObj *)image->img.swf)->pasMovies[nTmp -1] = newSWFMovie();
/* keeps the layer index for each movie so we can use */
/* it to get a movie index based on the layer index. */
((SWFObj *)image->img.swf)->panLayerIndex[nTmp -1] = layer->index;
SWFMovie_setDimension(((SWFObj *)image->img.swf)->pasMovies[nTmp -1],
(float)image->width, (float)image->height);
SWFMovie_setBackground(((SWFObj *)image->img.swf)->pasMovies[nTmp -1], map->imagecolor.red,
map->imagecolor.green, map->imagecolor.blue);
((SWFObj *)image->img.swf)->nCurrentLayerIdx = layer->index;
/* msLayerGetItems(layer); */
/* -------------------------------------------------------------------- */
/* Start the Element array that will contain the values of the */
/* attributes. */
/* -------------------------------------------------------------------- */
if( (metadata=msLookupHashTable(&(layer->metadata),"SWFDUMPATTRIBUTES"))
!= NULL )
{
tokens = msStringSplit(metadata, ',', &n);
if (tokens && n > 0)
{
sprintf(gszAction, "nAttributes=%d;", n);
oAction = newSWFAction(gszAction);
SWFMovie_add(((SWFObj *)image->img.swf)->pasMovies[nTmp -1], oAction);
sprintf(gszAction, "%s", "Attributes=new Array();");
oAction = newSWFAction(gszAction);
SWFMovie_add(((SWFObj *)image->img.swf)->pasMovies[nTmp -1], oAction);
for (i=0; i<n; i++)
{
sprintf(gszAction, "Attributes[%d]=\"%s\";", i, tokens[i]);
oAction = newSWFAction(gszAction);
SWFMovie_add(((SWFObj *)image->img.swf)->pasMovies[nTmp -1], oAction);
}
sprintf(szAction, "%s", "Element=new Array();");
oAction = newSWFAction(gszAction);
SWFMovie_add(((SWFObj *)image->img.swf)->pasMovies[nTmp -1], oAction);
msFreeCharArray(tokens, n);
}
}
}
}
/************************************************************************/
/* void msDrawStartShapeSWF */
/* */
/* Strat rendering a shape. */
/************************************************************************/
void msDrawStartShapeSWF(mapObj *map, layerObj *layer, imageObj *image,
shapeObj *shape)
{
char *metadata = NULL;
int *panIndex = NULL;
int iIndex = 0;
int i,j = 0;
int bFound = 0;
SWFAction oAction;
/* int nTmp = 0; */
if (image && MS_DRIVER_SWF(image->format))
{
((SWFObj *)image->img.swf)->nCurrentShapeIdx = shape->index;
/* nTmp = ((SWFObj *)image->img.swf)->nCurrentMovie; */
/* -------------------------------------------------------------------- */
/* get an array of indexes corresponding to the attributes. We */
/* will use this array to retreive the values. */
/* -------------------------------------------------------------------- */
if( (metadata=msLookupHashTable(&(layer->metadata),"SWFDUMPATTRIBUTES"))
!= NULL )
{
char **tokens;
int n = 0;
tokens = msStringSplit(metadata, ',', &n);
if (tokens && n > 0)
{
panIndex = (int *)malloc(sizeof(int)*n);
iIndex = 0;
for (i=0; i<n; i++)
{
bFound = 0;
for (j=0; j<layer->numitems; j++)
{
if (strcmp(tokens[i], layer->items[j]) == 0)
{
bFound = 1;
break;
}
}
if (bFound)
{
panIndex[iIndex] = j;
iIndex++;
}
}
}
}
/* -------------------------------------------------------------------- */
/* Build the value string for the specified attributes. */
/* -------------------------------------------------------------------- */
if (panIndex)
{
sprintf(gszAction, "Element[%d]=new Array();", (int)shape->index);
oAction = newSWFAction(gszAction);
/* SWFMovie_add(((SWFObj *)image->img.swf)->pasMovies[nTmp], oAction); */
SWFMovie_add(GetCurrentMovie(map, image), oAction);
for (i=0; i<iIndex; i++)
{
sprintf(gszAction, "Element[%d][%d]=\"%s\";", (int)shape->index,
i, shape->values[panIndex[i]]);
oAction = newSWFAction(gszAction);
/* SWFMovie_add(((SWFObj *)image->img.swf)->pasMovies[nTmp], oAction); */
SWFMovie_add(GetCurrentMovie(map, image), oAction);
}
}
}
else
((SWFObj *)image->img.swf)->nCurrentShapeIdx = -1;
}
void msDrawStartShapeUsingIdxSWF(mapObj *map, layerObj *layer, imageObj *image,
labelCacheMemberObj * cachePtr)
{
shapeObj shape;
int retval = 0;
if (map && layer && image && cachePtr->shapeindex >=0)
{
msInitShape(&shape);
retval = msLayerGetShape(layer, &shape, cachePtr->tileindex,
cachePtr->shapeindex);
if (retval == MS_SUCCESS)
{
msDrawStartShapeSWF(map, layer, image, &shape);
}
else
{
msSetError(MS_MISCERR, "Cannot find shape for shapeidx:%d",
"msDrawStartShapeUsingIdxSWF()", cachePtr->shapeindex);
}
}
}
/************************************************************************/
/* msDrawMarkerSymbolSWF */
/* */
/* Draw symbols in an SWF Movie. */
/************************************************************************/
void msDrawMarkerSymbolSWF(symbolSetObj *symbolset, imageObj *image,
pointObj *p, styleObj *style, double scalefactor)
{
symbolObj *symbol;
int offset_x, offset_y;
double x, y;
int size;
int j;
gdPoint mPoints[MS_MAXVECTORPOINTS];
double scale=1.0;
rectObj rect;
char *font=NULL;
int bbox[8];
gdImagePtr imgtmp = NULL;
SWFButton oButton;
SWFDisplayItem oDisplay = NULL;
colorObj sFc;
colorObj sBc;
colorObj sOc;
colorObj sColorHighlightObj;
colorObj *psFillColor = NULL;
colorObj *psOutlineColor = NULL;
mapObj *map;
layerObj *psLayerTmp = NULL;
/* int nTmp = 0; */
int nLayerIndex = -1;
int nShapeIndex = -1;
int fc = 0; /* only used for TTF */
/* -------------------------------------------------------------------- */
/* if not SWF, return. */
/* -------------------------------------------------------------------- */
if (image == NULL || !MS_DRIVER_SWF(image->format) )
return;
symbol = symbolset->symbol[style->symbol];
if(style->size == -1) {
size = (int)msSymbolGetDefaultSize( symbol );
size = MS_NINT(size*scalefactor);
}
else
size = MS_NINT(style->size*scalefactor);
size = MS_MAX(size, style->minsize);
size = MS_MIN(size, style->maxsize);
if(style->symbol > symbolset->numsymbols || style->symbol < 0) /* no such symbol, 0 is OK */
return;
/* if(fc >= gdImageColorsTotal(img)) */ /* invalid color, -1 is valid */
/* return; */
if(size < 1) /* size too small */
return;
/* -------------------------------------------------------------------- */
/* extract the colors. */
/* -------------------------------------------------------------------- */
map = ((SWFObj *)image->img.swf)->map;
sFc.red = style->color.red;
sFc.green = style->color.green;
sFc.blue = style->color.blue;
sBc.red = style->backgroundcolor.red;
sBc.green = style->backgroundcolor.green;
sBc.blue = style->backgroundcolor.blue;
sOc.red = style->outlinecolor.red;
sOc.green = style->outlinecolor.green;
sOc.blue = style->outlinecolor.blue;
/* this comes from the map file querymap obj. */
sColorHighlightObj.red = map->querymap.color.red;
sColorHighlightObj.green = map->querymap.color.green;
sColorHighlightObj.blue = map->querymap.color.blue;
/* -------------------------------------------------------------------- */
/* the layer index and shape index will be set if the layer has */
/* the metadata SWFDUMPATTRIBUTES set. */
/* */
/* If they are set, we will write the Action Script (AS) for */
/* the attributes of the shape. */
/* -------------------------------------------------------------------- */
psLayerTmp =
((GET_LAYER(((SWFObj *)image->img.swf)->map, ((SWFObj *)image->img.swf)->nCurrentLayerIdx)));
if (msLookupHashTable(&(psLayerTmp->metadata), "SWFDUMPATTRIBUTES"))
{
nLayerIndex = ((SWFObj *)image->img.swf)->nCurrentLayerIdx;
nShapeIndex = ((SWFObj *)image->img.swf)->nCurrentShapeIdx;
}
/* -------------------------------------------------------------------- */
/* Render the diffrent type of symbols. */
/* -------------------------------------------------------------------- */
/* symbol = &(symbolset->symbol[sy]); */
/* nTmp = ((SWFObj *)image->img.swf)->nCurrentMovie; */
switch(symbol->type)
{
/* -------------------------------------------------------------------- */
/* Symbol : true type. */
/* -------------------------------------------------------------------- */
case(MS_SYMBOL_TRUETYPE):
#if defined (USE_GD_FT) || defined (USE_GD_TTF)
font = msLookupHashTable(&(symbolset->fontset->fonts), symbol->font);
if(!font)
return;
if(msGetCharacterSize(symbol->character, size, font, &rect) != MS_SUCCESS)
return;
x = p->x - (rect.maxx - rect.minx)/2 - rect.minx;
y = p->y - rect.maxy + (rect.maxy - rect.miny)/2;
imgtmp = gdImageCreate((int)((rect.maxx - rect.minx)+2),
(int)((rect.maxy - rect.miny)+2));
/* gdImageStringFT(img, bbox, ((symbol->antialias)?(fc):-(fc)), */
/* font, sz, 0, x, y, symbol->character); */
gdImageStringFT(imgtmp, bbox, ((symbol->antialias)?(fc):-(fc)),
font, size, 0, 1, 1, symbol->character);
/* oShape = gdImage2Shape(imgtmp); */
oButton = BuildButtonFromGD(imgtmp, image);/* , NULL); */
StoreButton(oButton, image);
AddMouseActions(oButton, nLayerIndex, nShapeIndex);
oDisplay = SWFMovie_add(GetCurrentMovie(map, image),
oButton);
SWFDisplayItem_moveTo(oDisplay, (float)x, (float)y);
#endif
/* -------------------------------------------------------------------- */
/* Symbol : pixmap. */
/* -------------------------------------------------------------------- */
case(MS_SYMBOL_PIXMAP):
if(size == 1)
{ /* don't scale */
offset_x = MS_NINT(p->x - .5*symbol->img->sx);
offset_y = MS_NINT(p->y - .5*symbol->img->sy);
/* gdImageCopy(img, symbol->img, offset_x, offset_y, 0, 0, */
/* symbol->img->sx, symbol->img->sy); */
oButton = BuildButtonFromGD(symbol->img, image);/* , NULL); */
StoreButton(oButton, image);
AddMouseActions(oButton, nLayerIndex, nShapeIndex);
oDisplay = SWFMovie_add(GetCurrentMovie(map, image),
oButton);
SWFDisplayItem_moveTo(oDisplay, (float)offset_x,
(float)offset_y);
}
else
{
scale = size/symbol->img->sy;
offset_x = MS_NINT(p->x - .5*symbol->img->sx*scale);
offset_y = MS_NINT(p->y - .5*symbol->img->sy*scale);
imgtmp = gdImageCreate((int)(symbol->img->sx*scale),
(int)(symbol->img->sy*scale));
gdImageCopyResized(imgtmp, symbol->img, 0, 0, 0, 0,
(int)(symbol->img->sx*scale),
(int)(symbol->img->sy*scale), symbol->img->sx,
symbol->img->sy);
/* out = fopen("c:/tmp/ms_tmp/test.jpg", "wb"); */
/* And save the image -- could also use gdImageJpeg */
/* gdImageJpeg(imgtmp, out, 0); */
oButton = BuildButtonFromGD(imgtmp, image);/* , NULL); */
StoreButton(oButton, image);
AddMouseActions(oButton, nLayerIndex, nShapeIndex);
oDisplay = SWFMovie_add(GetCurrentMovie(map, image),
oButton);
SWFDisplayItem_moveTo(oDisplay, (float)offset_x,
(float)offset_y);
/* gdImageDestroy(imgtmp); */
}
if (oDisplay)
{
sprintf(gszTmp, "button%d",((SWFObj *)image->img.swf)->nTmpCount);
((SWFObj *)image->img.swf)->nTmpCount++;
SWFDisplayItem_setName(oDisplay, gszTmp);
}
break;
/* -------------------------------------------------------------------- */
/* symbol : Ellipse */
/* -------------------------------------------------------------------- */
case(MS_SYMBOL_ELLIPSE):
scale = size/symbol->sizey;
x = MS_NINT(symbol->sizex*scale)+1;
y = MS_NINT(symbol->sizey*scale)+1;
offset_x = MS_NINT(p->x - .5*x);
offset_y = MS_NINT(p->y - .5*x);
psFillColor = NULL;
psOutlineColor = NULL;
if (MS_VALID_COLOR(sFc))
psFillColor = &sFc;
if (MS_VALID_COLOR(sOc))
psOutlineColor = &sOc;
if(MS_VALID_COLOR(sOc))
{
if (!symbol->filled)
psFillColor = NULL;
oButton =
BuildEllipseButton(offset_x, offset_y,
MS_NINT(scale*symbol->points[0].x),
MS_NINT(scale*symbol->points[0].y),
psFillColor, psOutlineColor,
&sColorHighlightObj,
nLayerIndex, nShapeIndex, image);
/* Ticket #2555 memory leak : need to store buttons to properly destroy them */
StoreButton(oButton, image);
oDisplay = SWFMovie_add(GetCurrentMovie(map, image), oButton);
}
else
{
if(MS_VALID_COLOR(sFc))
{
oButton =
BuildEllipseButton(offset_x, offset_y,
MS_NINT(scale*symbol->points[0].x),
MS_NINT(scale*symbol->points[0].y),
psFillColor, NULL,
&sColorHighlightObj,
nLayerIndex, nShapeIndex, image);
StoreButton(oButton, image);
oDisplay = SWFMovie_add(GetCurrentMovie(map, image), oButton);
}
}
if (oDisplay)
{
sprintf(gszTmp, "button%d",((SWFObj *)image->img.swf)->nTmpCount);
((SWFObj *)image->img.swf)->nTmpCount++;
SWFDisplayItem_setName(oDisplay, gszTmp);
}
break;
/* -------------------------------------------------------------------- */
/* symbol : Vector. */
/* -------------------------------------------------------------------- */
case(MS_SYMBOL_VECTOR):
scale = size/symbol->sizey;
offset_x = MS_NINT(p->x - scale*.5*symbol->sizex);
offset_y = MS_NINT(p->y - scale*.5*symbol->sizey);
/* -------------------------------------------------------------------- */
/* Symbol Vector : Filled. */
/* -------------------------------------------------------------------- */
if(symbol->filled)
{
for(j=0;j < symbol->numpoints;j++)
{
mPoints[j].x = MS_NINT(scale*symbol->points[j].x + offset_x);
mPoints[j].y = MS_NINT(scale*symbol->points[j].y + offset_y);
}
psFillColor = NULL;
psOutlineColor = NULL;
if (MS_VALID_COLOR(sFc))
psFillColor = &sFc;
if (MS_VALID_COLOR(sOc))
psOutlineColor = &sOc;
oButton = BuildButtonPolygon(mPoints, symbol->numpoints,
psFillColor, psOutlineColor,
&sColorHighlightObj,
nLayerIndex, nShapeIndex, image);
StoreButton(oButton, image);
oDisplay = SWFMovie_add(GetCurrentMovie(map, image), oButton);
}
/* -------------------------------------------------------------------- */
/* symbol VECTOR : not filled. */
/* -------------------------------------------------------------------- */
else
{
if(!MS_VALID_COLOR(sFc))
return;
for(j=0;j < symbol->numpoints;j++)
{
mPoints[j].x = MS_NINT(scale*symbol->points[j].x + offset_x);
mPoints[j].y = MS_NINT(scale*symbol->points[j].y + offset_y);
}
psFillColor = &sFc;
oButton = BuildButtonLine(mPoints, symbol->numpoints,
psFillColor,
&sColorHighlightObj,
nLayerIndex, nShapeIndex);
StoreButton(oButton, image);
oDisplay = SWFMovie_add(GetCurrentMovie(map, image), oButton);
} /* end if-then-else */
if (oDisplay)
{
sprintf(gszTmp, "button%d",((SWFObj *)image->img.swf)->nTmpCount);
((SWFObj *)image->img.swf)->nTmpCount++;
SWFDisplayItem_setName(oDisplay, gszTmp);
}
break;
default:
break;
} /* end switch statement */
return;
}
/************************************************************************/
/* SWFShape DrawShapePolyline(shapeObj *p, colorObj *psColor) */
/* */
/* Draws a simple line using the color passed as argument. */
/************************************************************************/
SWFShape DrawShapePolyline(shapeObj *p, colorObj *psColor, int pixwidth)
{
int i, j;
SWFShape oShape = NULL;
int width = 0;
/*the flash specification indicates a scale of twenty units per pixel
but it does not to work like that at least when loading the swf
in a browser. So for now just set the width value, It */
width = pixwidth;/* 20 */
if (p && psColor && p->numlines > 0)
{
oShape = newSWFShape();
SWFShape_setLine(oShape, width, (byte)psColor->red,
(byte)psColor->green, (byte)psColor->blue, 0xff);
for (i = 0; i < p->numlines; i++)
{
SWFShape_movePenTo(oShape, (float)p->line[i].point[0].x,
(float)p->line[i].point[0].y);
for(j=1; j<p->line[i].numpoints; j++)
{
SWFShape_drawLineTo(oShape, (float)p->line[i].point[j].x,
(float)p->line[i].point[j].y);
}
}
}
return oShape;
}
/************************************************************************/
/* DrawShapeFilledPolygon */
/* */
/* Draws a filled polygon using the fill and outline color. */
/************************************************************************/
SWFShape DrawShapeFilledPolygon(shapeObj *p, colorObj *psFillColor,
colorObj *psOutlineColor, int width)
{
return BuildPolygonShape(p, psFillColor, psOutlineColor, width);
}
/************************************************************************/
/* DrawButtonFilledPolygon */
/* */
/* returns a button with a polygon shape in it. */
/************************************************************************/
SWFButton DrawButtonFilledPolygon(shapeObj *p, colorObj *psFillColor,
colorObj *psOutlineColor,
colorObj *psHighlightColor, int nLayerIndex,
int nShapeIndex, int width)
{
SWFButton oButton;
oButton = newSWFButton();
SWFButton_addCharacter(oButton,
(SWFCharacter)BuildPolygonShape(p, psFillColor, psOutlineColor, width),
SWFBUTTON_UP | SWFBUTTON_HIT | SWFBUTTON_DOWN);
if (psHighlightColor)
{
if(psFillColor)
SWFButton_addCharacter(oButton,
(SWFCharacter)BuildPolygonShape(p, psHighlightColor, NULL, width),
SWFBUTTON_OVER);
else if (psOutlineColor)
SWFButton_addCharacter(oButton,
(SWFCharacter)BuildPolygonShape(p, NULL, psHighlightColor, width),
SWFBUTTON_OVER);
}
if (nLayerIndex >=0 && nShapeIndex >= 0)
{
AddMouseActions(oButton, nLayerIndex, nShapeIndex);
}
return oButton;
}
SWFButton DrawButtonPolyline(shapeObj *p, colorObj *psColor,
colorObj *psHighlightColor, int nLayerIndex,
int nShapeIndex, int width)
{
SWFButton oButton;
oButton = newSWFButton();
SWFButton_addCharacter(oButton,
(SWFCharacter)DrawShapePolyline(p, psColor, width),
SWFBUTTON_UP | SWFBUTTON_HIT | SWFBUTTON_DOWN);
if (psHighlightColor)
{
SWFButton_addCharacter(oButton,
(SWFCharacter)DrawShapePolyline(p, psHighlightColor, width),
SWFBUTTON_OVER);
}
if (nLayerIndex >=0 && nShapeIndex >= 0)
{
AddMouseActions(oButton, nLayerIndex, nShapeIndex);
}
return oButton;
}
/************************************************************************/
/* SWFText DrawText(char *string, int nX, int nY, char *pszFontFile, */
/* double dfSize, colorObj *psColor) */
/* */
/* Draws a text of size dfSize and color psColor at position */
/* nX,nY using the font pszFontFile. */
/************************************************************************/
SWFText DrawText(char *string, int nX, int nY, char *pszFontFile,
double dfSize, colorObj *psColor, imageObj *image)
{
SWFText oText = NULL;
SWFFont oFont = NULL;
if (!string || !pszFontFile || !psColor)
return NULL;
oFont = newSWFFont_fromFile(pszFontFile);
/* oFont = newSWFFont("_sans"); */
if (oFont)
{
/* ticket #2555 memory leak */
StoreFont(oFont, image);
oText = newSWFText();
SWFText_setFont(oText, oFont);
SWFText_moveTo(oText, (float)nX, (float)nY);
SWFText_setColor(oText, (byte)psColor->red, (byte)psColor->green, (byte)psColor->blue,
0xff);
SWFText_setHeight(oText, (float)dfSize);
SWFText_addString(oText, string, NULL);
return oText;
}
return NULL;
}
/************************************************************************/
/* void msDrawLineSymbolSWF */
/* */
/* Draws a polyline. */
/* */
/* TODO : lines with symbols is not yet implemented. */
/************************************************************************/
void msDrawLineSymbolSWF(symbolSetObj *symbolset, imageObj *image, shapeObj *p,
styleObj *style, double scalefactor)
{
colorObj sFc;
colorObj sBc;
colorObj sColorHighlightObj;
mapObj *map = NULL;
/* int nTmp = 0; */
SWFShape oShape;
SWFButton oButton;
SWFDisplayItem oDisplay = NULL;
int nLayerIndex = -1;
int nShapeIndex = -1;
layerObj *psLayerTmp = NULL;
int size = 0;
symbolObj *symbol;
int width;
/* -------------------------------------------------------------------- */
/* if not SWF, return. */
/* -------------------------------------------------------------------- */
if (image == NULL || !MS_DRIVER_SWF(image->format) )
return;
if(p == NULL || p->numlines <= 0)
return;
symbol = symbolset->symbol[style->symbol];
if(style->size == -1) {
size = (int)msSymbolGetDefaultSize( symbol );
size = MS_NINT(size*scalefactor);
}
else
size = MS_NINT(style->size*scalefactor);
/* TODO: Don't get this modification, is it needed elsewhere? */
if(size*scalefactor > style->maxsize) scalefactor = (float)style->maxsize/(float)size;
if(size*scalefactor < style->minsize) scalefactor = (float)style->minsize/(float)size;
size = MS_NINT(size*scalefactor);
size = MS_MAX(size, style->minsize);
size = MS_MIN(size, style->maxsize);
width = MS_NINT(style->width*scalefactor);
width = MS_MAX(width, style->minwidth);
width = MS_MIN(width, style->maxwidth);
if(style->symbol > symbolset->numsymbols || style->symbol < 0) /* no such symbol, 0 is OK */
return;
if (!MS_VALID_COLOR( style->color))
return;
/* -------------------------------------------------------------------- */
/* extract the colors. */
/* -------------------------------------------------------------------- */
map = ((SWFObj *)image->img.swf)->map;
sFc.red = style->color.red;
sFc.green = style->color.green;
sFc.blue = style->color.blue;
sBc.red = style->backgroundcolor.red;
sBc.green = style->backgroundcolor.green;
sBc.blue = style->backgroundcolor.blue;
/* nTmp = ((SWFObj *)image->img.swf)->nCurrentMovie; */
/* -------------------------------------------------------------------- */
/* the layer index and shape index will be set if the layer has */
/* the metadata SWFDUMPATTRIBUTES set. */
/* */
/* If they are set, we will write the Action Script (AS) for */
/* the attributes of the shape. */
/* -------------------------------------------------------------------- */
psLayerTmp =
(GET_LAYER(((SWFObj *)image->img.swf)->map, ((SWFObj *)image->img.swf)->nCurrentLayerIdx));
if (msLookupHashTable(&(psLayerTmp->metadata), "SWFDUMPATTRIBUTES"))
{
nLayerIndex = ((SWFObj *)image->img.swf)->nCurrentLayerIdx;
nShapeIndex = ((SWFObj *)image->img.swf)->nCurrentShapeIdx;
}
/* this comes from the map file querymap obj. */
sColorHighlightObj.red = map->querymap.color.red;
sColorHighlightObj.green = map->querymap.color.green;
sColorHighlightObj.blue = map->querymap.color.blue;
/* For now just draw lines without symbols. */
/* if(sy == 0) */
/* { */
/* just draw a single width line */
if (nLayerIndex < 0 || nShapeIndex < 0)
{
oShape = DrawShapePolyline(p, &sFc, width);
StoreShape(oShape, image);
SWFMovie_add(GetCurrentMovie(map, image), oShape);
}
else
{
oButton = DrawButtonPolyline(p, &sFc, &sColorHighlightObj, nLayerIndex,
nShapeIndex, width);
StoreButton(oButton, image);
oDisplay = SWFMovie_add(GetCurrentMovie(map, image), oButton);
sprintf(gszTmp, "button%d",((SWFObj *)image->img.swf)->nTmpCount);
((SWFObj *)image->img.swf)->nTmpCount++;
SWFDisplayItem_setName(oDisplay, gszTmp);
}
return;
/* } */
/* TODO : lines with symbols */
}
/************************************************************************/
/* msDrawShadeSymbolSWF */
/* */
/* Draw polygon features. Only supports solid filled polgons. */
/************************************************************************/
void msDrawShadeSymbolSWF(symbolSetObj *symbolset, imageObj *image,
shapeObj *p, styleObj *style, double scalefactor)
{
colorObj sFc;
colorObj sBc;
colorObj sOc;
mapObj *map = NULL;
layerObj *psLayerTmp = NULL;
SWFShape oShape;
SWFButton oButton;
SWFDisplayItem oDisplay;
/* int nTmp = 0; */
colorObj *psFillColor = NULL;
colorObj *psOutlineColor = NULL;
colorObj sColorHighlightObj;
gdImagePtr tile = NULL;
/* int bDestroyImage = 0; */
unsigned char *data, *dbldata;
int size;
int bytesPerColor;
int nLayerIndex = -1;
int nShapeIndex = -1;
symbolObj *symbol;
int width;
/* -------------------------------------------------------------------- */
/* if not SWF, return. */
/* -------------------------------------------------------------------- */
if (image == NULL || !MS_DRIVER_SWF(image->format) )
return;
if(p == NULL || p->numlines <= 0)
return;
symbol = symbolset->symbol[style->symbol];
if(style->size == -1) {
size = (int)msSymbolGetDefaultSize( symbol );
size = MS_NINT(size*scalefactor);
}
else
size = MS_NINT(style->size*scalefactor);
size = MS_MAX(size, style->minsize);
size = MS_MIN(size, style->maxsize);
width = MS_NINT(style->width*scalefactor);
width = MS_MAX(width, style->minwidth);
width = MS_MIN(width, style->maxwidth);
if(style->symbol > symbolset->numsymbols || style->symbol < 0) /* no such symbol, 0 is OK */
return;
/* if(fc >= gdImageColorsTotal(img)) */ /* invalid color, -1 is valid */
/* return; */
if(size < 1) /* size too small */
return;
/* -------------------------------------------------------------------- */
/* the layer index and shape index will be set if the layer has */
/* the metadata SWFDUMPATTRIBUTES set. */
/* */
/* If they are set, we will write the Action Script (AS) for */
/* the attributes of the shape. */
/* -------------------------------------------------------------------- */
psLayerTmp =
(GET_LAYER(((SWFObj *)image->img.swf)->map, ((SWFObj *)image->img.swf)->nCurrentLayerIdx));
if (msLookupHashTable(&(psLayerTmp->metadata), "SWFDUMPATTRIBUTES"))
{
nLayerIndex = ((SWFObj *)image->img.swf)->nCurrentLayerIdx;
nShapeIndex = ((SWFObj *)image->img.swf)->nCurrentShapeIdx;
}
/* -------------------------------------------------------------------- */
/* extract the colors. */
/* -------------------------------------------------------------------- */
map = ((SWFObj *)image->img.swf)->map;
sFc.red = style->color.red;
sFc.green = style->color.green;
sFc.blue = style->color.blue;
sBc.red = style->backgroundcolor.red;
sBc.green = style->backgroundcolor.green;
sBc.blue = style->backgroundcolor.blue;
sOc.red = style->outlinecolor.red;
sOc.green = style->outlinecolor.green;
sOc.blue = style->outlinecolor.blue;
/* TODO : this should come from the map file. */
sColorHighlightObj.red = map->querymap.color.red;
sColorHighlightObj.green = map->querymap.color.green;
sColorHighlightObj.blue = map->querymap.color.blue;
if (MS_VALID_COLOR(sFc))
psFillColor = &sFc;
if (MS_VALID_COLOR(sOc))
psOutlineColor = &sOc;
/* nTmp = ((SWFObj *)image->img.swf)->nCurrentMovie; */
if (size == 0)
{
if (nLayerIndex < 0 || nShapeIndex < 0)
{
oShape = DrawShapeFilledPolygon(p, psFillColor, psOutlineColor,
width);
StoreShape(oShape, image);
SWFMovie_add(GetCurrentMovie(map, image), oShape);
}
else
{
oButton = DrawButtonFilledPolygon(p, psFillColor, psOutlineColor,
&sColorHighlightObj, nLayerIndex,
nShapeIndex, width);
StoreButton(oButton, image);
oDisplay = SWFMovie_add(GetCurrentMovie(map, image), oButton);
sprintf(gszTmp, "button%d",((SWFObj *)image->img.swf)->nTmpCount);
((SWFObj *)image->img.swf)->nTmpCount++;
SWFDisplayItem_setName(oDisplay, gszTmp);
}
return;
}
/* ==================================================================== */
/* The idea is to create the tile image and fill the shape with it.*/
/* */
/* Won't work for now : files created are huge. */
/* ==================================================================== */
/* tile = getTileImageFromSymbol(map, symbolset, sy, fc, bc, oc, sz, */
/* &bDestroyImage); */
if (tile)
{
/* out = fopen("c:/tmp/ms_tmp/tile.jpg", "wb"); */
/* And save the image -- could also use gdImageJpeg */
/* gdImageJpeg(tile, out, 95); */
}
if (tile)
{
data = gd2bitmap(tile, &size, &bytesPerColor);
dbldata = bitmap2dbl(data,&size,&bytesPerColor);
oShape = bitmap2shape(dbldata, size, tile->sx, tile->sy,
SWFFILL_SOLID, image);/* SWFFILL_TILED_BITMAP); */
StoreShape(oShape, image);
}
else
{
if (MS_VALID_COLOR(sFc) || MS_VALID_COLOR(sOc))
{
if (nLayerIndex < 0 || nShapeIndex < 0)
{
oShape = DrawShapeFilledPolygon(p, psFillColor, psOutlineColor,
width);
StoreShape(oShape, image);
SWFMovie_add(GetCurrentMovie(map, image), oShape);
}
else
{
oButton = DrawButtonFilledPolygon(p, psFillColor, psOutlineColor,
&sColorHighlightObj, nLayerIndex,
nShapeIndex, width);
StoreButton(oButton, image);
oDisplay = SWFMovie_add(GetCurrentMovie(map, image), oButton);
sprintf(gszTmp, "button%d",((SWFObj *)image->img.swf)->nTmpCount);
((SWFObj *)image->img.swf)->nTmpCount++;
SWFDisplayItem_setName(oDisplay, gszTmp);
}
}
}
}
/************************************************************************/
/* int draw_textSWF */
/* */
/* Renders a text using FDB fonts. FDB fonts are specific to */
/* ming library. Returns 0 on success and -1 on error. */
/************************************************************************/
int draw_textSWF(imageObj *image, pointObj labelPnt, char *string,
labelObj *label, fontSetObj *fontset, double scalefactor)
{
int x, y;
char *font=NULL;
/* int nTmp = 0; */
colorObj sColor;
mapObj *map = NULL;
SWFText oText = NULL;
double size = 0;
double angle, dist;
int drawShadow=0;
int drawOutline=0;
char szPath[MS_MAXPATHLEN];
SWFDisplayItem oDisplay;
SWFBlur blur;
SWFShadow shadow;
SWFFilter f;
SWFColor swfShadowColor, swfOutlineColor;
/* -------------------------------------------------------------------- */
/* if not SWF, return. */
/* -------------------------------------------------------------------- */
if (image == NULL || !MS_DRIVER_SWF(image->format))
return 0;
/* -------------------------------------------------------------------- */
/* validate arguments. */
/* -------------------------------------------------------------------- */
if(!string || strlen(string) == 0 || !label || !fontset)
return(0); /* not an error, just don't want to do anything */
if(strlen(string) == 0)
return(0); /* not an error, just don't want to do anything */
x = MS_NINT(labelPnt.x);
y = MS_NINT(labelPnt.y);
/* char *error=NULL, *font=NULL; */
/* int bbox[8]; */
/* double angle_radians = MS_DEG_TO_RAD*label->angle; */
size = label->size*scalefactor;
if(!fontset)
{
msSetError(MS_TTFERR, "No fontset defined.", "draw_textSWF()");
return(-1);
}
if(!label->font)
{
msSetError(MS_TTFERR, "No font defined.", "draw_textSWF()");
return(-1);
}
font = msLookupHashTable(&(fontset->fonts), label->font);
if(!font)
{
msSetError(MS_TTFERR, "Requested font (%s) not found.", "draw_textSWF()",
label->font);
return(-1);
}
/* -------------------------------------------------------------------- */
/* extract the colors. */
/* -------------------------------------------------------------------- */
map = ((SWFObj *)image->img.swf)->map;
sColor.red = 0;
sColor.green = 0;
sColor.blue = 0;
if (MS_VALID_COLOR(label->color))
{
sColor.red = label->color.red;
sColor.green = label->color.green;
sColor.blue = label->color.blue;
}
else
{
msSetError(MS_TTFERR, "Invalid color", "draw_textSWF()");
return(-1);
}
if (MS_VALID_COLOR(label->shadowcolor))
{
swfShadowColor.red = (byte)(label->shadowcolor.red);
swfShadowColor.green = (byte)(label->shadowcolor.green);
swfShadowColor.blue = (byte)(label->shadowcolor.blue);
swfShadowColor.alpha = 0xff;
drawShadow = 1;
}
if (MS_VALID_COLOR(label->outlinecolor))
{
swfOutlineColor.red = (byte)(label->outlinecolor.red);
swfOutlineColor.green = (byte)(label->outlinecolor.green);
swfOutlineColor.blue = (byte)(label->outlinecolor.blue);
swfOutlineColor.alpha = 0xff;
drawOutline = 1;
}
/* ==================================================================== */
/* Create a text object at "0,0".. this sets it's rotation */
/* axis.... We will then move the text SWFDisplayItem_moveTo */
/* and rotate it. */
/* ==================================================================== */
/* oText = DrawText(string, x, y, msBuildPath(szPath, fontset->filename, font), size, &sColor); */
oText = DrawText(string, 0, 0, msBuildPath(szPath, fontset->filename, font), size, &sColor, image);
if (oText)
{
StoreText(oText, image);
/* nTmp = ((SWFObj *)image->img.swf)->nCurrentMovie; */
oDisplay = SWFMovie_add(GetCurrentMovie(map, image), oText);
if (drawShadow) {
blur = newSWFBlur(5, 5, 1);
angle = cos( label->shadowsizex / label->shadowsizey );
dist = sqrt( label->shadowsizex ^ 2 / label->shadowsizey ^ 2 );
shadow = newSWFShadow(angle, dist, 2);
f = newDropShadowFilter(swfShadowColor, blur, shadow, FILTER_MODE_COMPOSITE );
SWFDisplayItem_addFilter(oDisplay, f);
}
if (drawOutline) {
if (label->outlinewidth > 0) {
blur = newSWFBlur(label->outlinewidth * 5, label->outlinewidth * 5, 2);
}
else
{
blur = newSWFBlur(5, 5, 2);
}
f = newGlowFilter(swfOutlineColor, blur, 1.0, FILTER_MODE_COMPOSITE );
SWFDisplayItem_addFilter(oDisplay, f);
}
SWFDisplayItem_moveTo(oDisplay, (float)x, (float)y);
SWFDisplayItem_rotate(oDisplay, (float)label->angle);
}
return 0;
}
/************************************************************************/
/* int msGetLabelSizeSWF */
/* */
/* Initialize the rect object with the size of the text. Return */
/* 0 on sucess or -1. */
/************************************************************************/
int msGetLabelSizeSWF(char *string, labelObj *label, rectObj *rect,
fontSetObj *fontset, double scalefactor)
{
SWFText oText = NULL;
SWFFont oFont = NULL;
char *font;
double dfWidth = 0.0;
char szPath[MS_MAXPATHLEN];
if (!string || strlen(string) == 0 || !label || !rect ||
!fontset)
return -1;
font = msLookupHashTable(&(fontset->fonts), label->font);
if(!font)
{
if(label->font)
msSetError(MS_TTFERR, "Requested font (%s) not found.",
"msGetLabelSizeSWF()", label->font);
else
msSetError(MS_TTFERR, "Requested font (NULL) not found.",
"msGetLabelSizeSWF()" );
return(-1);
}
oFont = newSWFFont_fromFile(msBuildPath(szPath, fontset->filename, font));
if (oFont)
{
oText = newSWFText();
SWFText_setFont(oText, oFont);
/* SWFText_addString(oText, string, NULL); */
dfWidth = 0.0;
dfWidth = (double)SWFText_getStringWidth(oText, (char *)string);
if (dfWidth <=0)
return -1;
destroySWFText(oText);
destroySWFFont(oFont);
}
rect->minx = 0;
rect->miny = 0;
rect->maxx = dfWidth;
rect->maxy = label->size*scalefactor;
return(0);
}
/************************************************************************/
/* msSWFGetMovieIndex */
/* */
/* Utility function to look in an array of int for a specific */
/* value. Returns the indice of the array on succsess or -1. */
/************************************************************************/
static int msSWFGetMovieIndex(int *panIndex, int nSize, int nIndex)
{
int i = 0;
int nIndice = -1;
if (panIndex && nSize > 0)
{
for (i=0; i<nSize; i++)
{
if (panIndex[i] == nIndex)
{
nIndice = i;
break;
}
}
}
return nIndice;
}
/************************************************************************/
/* int msDrawLabelCacheSWF */
/* */
/* Draws labels saved in the cache. Each label is drawn to */
/* the approporiate movie pointer. */
/************************************************************************/
/* ==================================================================== */
/* This could easily be integrated with a more generic */
/* msDrawLabelCache. */
/* The only functions that need to be wrapped here are : */
/* */
/* - billboard */
/* - draw_text */
/* - labelInImage */
/* ==================================================================== */
int msDrawLabelCacheSWF(imageObj *image, mapObj *map)
{
pointObj p;
int i, j, l, priority;
rectObj r;
labelCacheMemberObj *cachePtr=NULL;
layerObj *layerPtr=NULL;
labelObj *labelPtr=NULL;
int draw_marker;
int marker_width, marker_height;
int marker_offset_x, marker_offset_y;
rectObj marker_rect;
int nCurrentMovie = 0;
int bLayerOpen = 0;
imageObj *imagetmp = NULL;
/* int nTmp = -1; */
SWFShape oShape;
/* -------------------------------------------------------------------- */
/* test for driver. */
/* -------------------------------------------------------------------- */
if (!image || !MS_DRIVER_SWF(image->format))
return -1;
marker_rect.minx = marker_rect.miny = marker_rect.maxx = marker_rect.maxy = 0;
#ifdef USE_POINT_Z_M
p.x = p.y = p.z = 0;
#else
p.x = p.y = 0;
#endif
/* -------------------------------------------------------------------- */
/* if the output is single (SWF file based on one raster that */
/* will contain all the rendering), draw the lables using the */
/* GD driver. */
/* -------------------------------------------------------------------- */
if(strcasecmp(msGetOutputFormatOption(image->format,
"OUTPUT_MOVIE",""),
"SINGLE") == 0)
{
int orig_renderer;
imagetmp = (imageObj *)((SWFObj *)image->img.swf)->imagetmp;
msImageInitGD( imagetmp, &map->imagecolor);
orig_renderer=image->format->renderer;
image->format->renderer = MS_RENDER_WITH_GD;
msDrawLabelCache(imagetmp, map);
image->format->renderer = orig_renderer;
oShape = gdImage2Shape(imagetmp->img.gd, image);
StoreShape(oShape, image);
/* nTmp = ((SWFObj *)image->img.swf)->nCurrentMovie; */
SWFMovie_add(GetCurrentMovie(map, image), oShape);
return 0;
}
/* -------------------------------------------------------------------- */
/* keep the current layer index. */
/* -------------------------------------------------------------------- */
nCurrentMovie = ((SWFObj *)image->img.swf)->nCurrentMovie;
for(priority=MS_MAX_LABEL_PRIORITY-1; priority>=0; priority--) {
labelCacheSlotObj *cacheslot;
cacheslot = &(map->labelcache.slots[priority]);
for(l=cacheslot->numlabels-1; l>=0; l--) {
cachePtr = &(cacheslot->labels[l]); /* point to right spot in cache */
layerPtr = (GET_LAYER(map, cachePtr->layerindex)); /* set a couple of other pointers, avoids nasty references */
/* ==================================================================== */
/* set the current layer so the label will be drawn in the */
/* using the correct SWF handle. */
/* ==================================================================== */
((SWFObj *)image->img.swf)->nCurrentMovie =
msSWFGetMovieIndex(((SWFObj *)image->img.swf)->panLayerIndex,
((SWFObj *)image->img.swf)->nLayerMovies,
cachePtr->layerindex);
if (((SWFObj *)image->img.swf)->nCurrentMovie < 0)
continue;
/* msImageStartLayerSWF(map, layerPtr, image); */
((SWFObj *)image->img.swf)->nCurrentLayerIdx = cachePtr->layerindex;
/* ==================================================================== */
/* at this point the layer (at the shape level is closed). So */
/* we will open it if necessary. */
/* ==================================================================== */
bLayerOpen = 0;
if (msLookupHashTable(&(layerPtr->metadata), "SWFDUMPATTRIBUTES") &&
layerPtr->numitems <= 0)
{
msLayerOpen(layerPtr);
msLayerWhichItems(layerPtr, MS_TRUE, MS_FALSE,
msLookupHashTable(&(layerPtr->metadata),
"SWFDUMPATTRIBUTES"));
bLayerOpen = 1;
}
/* ((SWFObj *)image->img.swf)->nCurrentShapeIdx = cachePtr->shapeidx; */
msDrawStartShapeUsingIdxSWF(map, layerPtr, image, cachePtr);
/* classPtr = &(cachePtr->class); */
labelPtr = &(cachePtr->label);
if(!cachePtr->text)
continue; /* not an error, just don't want to do anything */
if(strlen(cachePtr->text) == 0)
continue; /* not an error, just don't want to do anything */
if(msGetLabelSizeSWF(cachePtr->text, labelPtr, &r,
&(map->fontset), layerPtr->scalefactor) == -1)
return(-1);
if(labelPtr->autominfeaturesize && ((r.maxx-r.minx) > cachePtr->featuresize))
continue; /* label too large relative to the feature */
draw_marker = marker_offset_x = marker_offset_y = 0; /* assume no marker */
if((layerPtr->type == MS_LAYER_ANNOTATION && cachePtr->numstyles > 0) || layerPtr->type == MS_LAYER_POINT) { /* there *is* a marker */
/* TO DO: at the moment only checks the bottom style, perhaps should check all of them */
if(msGetMarkerSize(&map->symbolset, &(cachePtr->styles[0]), &marker_width, &marker_height, layerPtr->scalefactor) != MS_SUCCESS)
return(-1);
marker_width = (int)(marker_width);
marker_height = (int)(marker_height);
marker_offset_x = MS_NINT(marker_width/2.0);
marker_offset_y = MS_NINT(marker_height/2.0);
marker_rect.minx = MS_NINT(cachePtr->point.x - .5 * marker_width);
marker_rect.miny = MS_NINT(cachePtr->point.y - .5 * marker_height);
marker_rect.maxx = marker_rect.minx + (marker_width-1);
marker_rect.maxy = marker_rect.miny + (marker_height-1);
for(i=0; i<cachePtr->numstyles; i++)
cachePtr->styles[i].size = (int)(cachePtr->styles[i].size * layerPtr->scalefactor);
/* if(layerPtr->type == MS_LAYER_ANNOTATION) draw_marker = 1; */ /* actually draw the marker */
}
if(labelPtr->position == MS_AUTO) {
if(layerPtr->type == MS_LAYER_LINE) {
int position = MS_UC;
for(j=0; j<2; j++) { /* Two angles or two positions, depending on angle. Steep angles will use the angle approach, otherwise we'll rotate between UC and LC. */
msFreeShape(cachePtr->poly);
cachePtr->status = MS_TRUE; /* assume label *can* be drawn */
p = get_metrics(&(cachePtr->point), position, r, (marker_offset_x + labelPtr->offsetx), (marker_offset_y + labelPtr->offsety), labelPtr->angle, labelPtr->buffer, cachePtr->poly);
if(draw_marker)
msRectToPolygon(marker_rect, cachePtr->poly); /* save marker bounding polygon */
/* Compare against image bounds, rendered labels and markers (sets cachePtr->status) */
msTestLabelCacheCollisions(&(map->labelcache), labelPtr,
map->width, map->height,
labelPtr->buffer, cachePtr, priority, l);
if(cachePtr->status) /* found a suitable place for this label */
break;
} /* next angle */
} else {
for(j=0; j<=7; j++) { /* loop through the outer label positions */
msFreeShape(cachePtr->poly);
cachePtr->status = MS_TRUE; /* assume label *can* be drawn */
p = get_metrics(&(cachePtr->point), j, r, (marker_offset_x + labelPtr->offsetx), (marker_offset_y + labelPtr->offsety), labelPtr->angle, labelPtr->buffer, cachePtr->poly);
if(draw_marker)
msRectToPolygon(marker_rect, cachePtr->poly); /* save marker bounding polygon */
/* Compare against image bounds, rendered labels and markers (sets cachePtr->status) */
msTestLabelCacheCollisions(&(map->labelcache), labelPtr,
map->width, map->height,
labelPtr->buffer, cachePtr, priority, l);
if(cachePtr->status) /* found a suitable place for this label */
break;
} /* next position */
}
if(labelPtr->force) cachePtr->status = MS_TRUE; /* draw in spite of collisions based on last position, need a *best* position */
} else {
cachePtr->status = MS_TRUE; /* assume label *can* be drawn */
if(labelPtr->position == MS_CC) /* don't need the marker_offset */
p = get_metrics(&(cachePtr->point), labelPtr->position, r, labelPtr->offsetx, labelPtr->offsety, labelPtr->angle, labelPtr->buffer, cachePtr->poly);
else
p = get_metrics(&(cachePtr->point), labelPtr->position, r, (marker_offset_x + labelPtr->offsetx), (marker_offset_y + labelPtr->offsety), labelPtr->angle, labelPtr->buffer, cachePtr->poly);
if(draw_marker)
msRectToPolygon(marker_rect, cachePtr->poly); /* save marker bounding polygon, part of overlap tests */
if(!labelPtr->force) { /* no need to check anything else */
/* Compare against image bounds, rendered labels and markers (sets cachePtr->status) */
msTestLabelCacheCollisions(&(map->labelcache), labelPtr,
map->width, map->height,
labelPtr->buffer, cachePtr, priority, l);
}
} /* end position if-then-else */
/* msImagePolyline(img, cachePtr->poly, 1); */
if(!cachePtr->status)
continue; /* next label */
if(layerPtr->type == MS_LAYER_ANNOTATION && cachePtr->numstyles > 0){ /* need to draw a marker */
for(i=0; i<cachePtr->numstyles; i++)
msDrawMarkerSymbolSWF(&map->symbolset, image, &(cachePtr->point),
&(cachePtr->styles[i]), layerPtr->scalefactor);
}
/* TODO */
/* if(labelPtr->backgroundcolor >= 0) */
/* billboard(img, cachePtr->poly, labelPtr); */
draw_textSWF(image, p, cachePtr->text, labelPtr, &(map->fontset), layerPtr->scalefactor); /* actually draw the label */
if (bLayerOpen)
msLayerClose(layerPtr);
} /* next in cache */
} /* next priority */
((SWFObj *)image->img.swf)->nCurrentMovie = nCurrentMovie;
return(0);
}
/************************************************************************/
/* msDrawLabelSWF */
/* */
/* Draw a label. */
/************************************************************************/
int msDrawLabelSWF(imageObj *image, pointObj labelPnt, char *string,
labelObj *label, fontSetObj *fontset, double scalefactor)
{
pointObj p;
rectObj r;
if (!image || !MS_DRIVER_SWF(image->format))
return 0;
if(!string)
return(0); /* not an error, just don't want to do anything */
if(strlen(string) == 0)
return(0); /* not an error, just don't want to do anything */
msGetLabelSizeSWF(string, label, &r, fontset, scalefactor);
p = get_metrics(&labelPnt, label->position, r, label->offsetx,
label->offsety, label->angle, 0, NULL);
/* labelPnt.x += label->offsetx; */
/* labelPnt.y += label->offsety; */
return draw_textSWF(image, p, string, label, fontset, scalefactor);
}
/************************************************************************/
/* int msDrawWMSLayerSWF */
/* */
/* Use low level gd functions to draw a wms layer in a gd */
/* images and then save it in the movie, */
/************************************************************************/
int msDrawWMSLayerSWF(int nLayerId, httpRequestObj *pasReqInfo,
int numRequests, mapObj *map, layerObj *layer, imageObj *image)
{
imageObj *image_tmp = NULL;
SWFShape oShape;
int iReq = -1;
const char *driver = "GD/GIF";
int bFreeImage = 0;
#ifdef USE_GD_GIF
driver = "GD/GIF";
#else
#ifdef USE_GD_PNG
driver = "GD/PNG";
#else
#ifdef USE_GD_JPEG
driver = "GD/JPEG";
#else
#ifdef USE_GD_WBMP
driver = "GD/WBMP";
#endif
#endif
#endif
#endif
if (!image || !MS_DRIVER_SWF(image->format) || image->width <= 0 ||
image->height <= 0)
return -1;
/* ==================================================================== */
/* WMS requests are done simultaniously for all WMS layer. */
/* ==================================================================== */
for(iReq=0; iReq<numRequests; iReq++)
{
if (pasReqInfo[iReq].nLayerId == nLayerId)
break;
}
if (iReq == numRequests)
return MS_SUCCESS;
/* -------------------------------------------------------------------- */
/* create a temprary GD image and render in it. */
/* -------------------------------------------------------------------- */
if (strcasecmp(msGetOutputFormatOption(image->format,
"OUTPUT_MOVIE",""),
"MULTIPLE") == 0)
{
image_tmp = msImageCreateGD(map->width, map->height,
msCreateDefaultOutputFormat(map, driver),
map->web.imagepath, map->web.imageurl);
bFreeImage = 1;
}
else
image_tmp = (imageObj *)((SWFObj *)image->img.swf)->imagetmp;
/* gdImageColorAllocate(image_tmp->img.gd, */
/* map->imagecolor.red, map->imagecolor.green, */
/* map->imagecolor.blue); */
msImageInitGD( image_tmp, &map->imagecolor );
if (msDrawWMSLayerLow(nLayerId, pasReqInfo, numRequests, map, layer,
image_tmp) != -1)
{
oShape = gdImage2Shape(image_tmp->img.gd, image);
/* nTmp = ((SWFObj *)image->img.swf)->nCurrentMovie; */
StoreShape(oShape, image);
SWFMovie_add(GetCurrentMovie(map, image), oShape);
if (bFreeImage)
msFreeImage( image_tmp );
}
return MS_SUCCESS;
}
/************************************************************************/
/* int msDrawRasterLayerSWF */
/* */
/* Renders a raster layer in a temporary GD image and adds it */
/* in the current movie. */
/************************************************************************/
int msDrawRasterLayerSWF(mapObj *map, layerObj *layer, imageObj *image)
{
/* int nTmp = 0; */
SWFShape oShape;
outputFormatObj *format = NULL;
imageObj *image_tmp = NULL;
int bFreeImage = 0;
if (!image || !MS_DRIVER_SWF(image->format) || image->width <= 0 ||
image->height <= 0)
return -1;
/* -------------------------------------------------------------------- */
/* create a temprary GD image and render in it. */
/* -------------------------------------------------------------------- */
format = msCreateDefaultOutputFormat( NULL, "GD/PC256" );
if( format == NULL )
return -1;
if (strcasecmp(msGetOutputFormatOption(image->format,
"OUTPUT_MOVIE",""),
"MULTIPLE") == 0)
{
image_tmp = msImageCreate( image->width, image->height, format,
NULL, NULL, map );
bFreeImage = 1;
}
else
image_tmp = (imageObj *)((SWFObj *)image->img.swf)->imagetmp;
if( image_tmp == NULL )
return -1;
if (msDrawRasterLayerLow(map, layer, image_tmp) != -1)
{
oShape = gdImage2Shape(image_tmp->img.gd, image);
/* nTmp = ((SWFObj *)image->img.swf)->nCurrentMovie; */
StoreShape(oShape, image);
SWFMovie_add(GetCurrentMovie(map, image), oShape);
if (bFreeImage)
msFreeImage( image_tmp );
}
return 0;
}
static int SWFIsInArray(int *panArray, int nSize, int nValue)
{
int i = 0;
if (panArray && nSize > 0)
{
for (i=0; i<nSize; i++)
{
if (panArray[i] == nValue)
return MS_TRUE;
if (panArray[i] > nValue)
return MS_FALSE;
}
}
return MS_FALSE;
}
/************************************************************************/
/* int msSaveImageSWF */
/* */
/* Save to SWF files. */
/************************************************************************/
int msSaveImageSWF(imageObj *image, char *filename)
{
int i=0, j=0, k=0, nLayers=0, iMovie= 0;
char szBase[100];
char szExt[5];
char szTmp[20];
int nLength;
int iPointPos;
int iSlashPos;
char szAction[200];
SWFAction oAction;
mapObj *map = NULL;
char *pszRelativeName = NULL;
int iSaveResult;
int bFileIsTemporary = MS_FALSE;
const char *pszExtension = NULL;
FILE *fp;
unsigned char block[4000];
int bytes_read;
int bLoadAutomatically = MS_TRUE;
/*do not load all the movie for the layers automatically if flag is set to off
Bug 1696*/
if (strcasecmp(msGetOutputFormatOption(image->format,
"LOAD_AUTOMATICALLY",""), "OFF") != 0)
bLoadAutomatically = MS_FALSE;
if (image && MS_DRIVER_SWF(image->format))/* && filename) */
{
map = ((SWFObj *)image->img.swf)->map;
/* -------------------------------------------------------------------- */
/* We will need to write the output to a temporary file. */
/* -------------------------------------------------------------------- */
if( filename == NULL )
{
pszExtension = image->format->extension;
if( pszExtension == NULL )
pszExtension = "swf";
if( map && map->web.imagepath && map->web.imageurl)
filename = msTmpFile(map->mappath,map->web.imagepath,pszExtension);
if (!filename)
return(MS_FAILURE);
bFileIsTemporary = MS_TRUE;
}
if (!filename)
return(MS_FAILURE);
/* ==================================================================== */
/* if the output is single movie, save the main movie and exit. */
/* ==================================================================== */
if (strcasecmp(msGetOutputFormatOption(image->format,
"OUTPUT_MOVIE",""),
"MULTIPLE") != 0)
{
#ifdef MING_VERSION_03
iSaveResult = SWFMovie_save(((SWFObj *)image->img.swf)->sMainMovie, filename, -1);
#else
iSaveResult = SWFMovie_save(((SWFObj *)image->img.swf)->sMainMovie, filename);
#endif
/* -------------------------------------------------------------------- */
/* Is this supposed to be a temporary file? If so, stream to */
/* stdout and delete the file. */
/* -------------------------------------------------------------------- */
if( bFileIsTemporary )
{
if( msIO_needBinaryStdout() == MS_FAILURE )
return MS_FAILURE;
fp = fopen( filename, "rb" );
if( fp == NULL )
{
msSetError( MS_MISCERR,
"Failed to open %s for streaming to stdout.",
"msSaveImageSWF()", filename );
return MS_FAILURE;
}
while( (bytes_read = fread(block, 1, sizeof(block), fp)) > 0 )
msIO_fwrite( block, 1, bytes_read, stdout );
fclose( fp );
unlink( filename );
free( filename );
/*
char *pszURL = (char *)malloc(sizeof(char)*(strlen(map->web.imageurl)+
strlen(filename)+
strlen(pszExtension)+2));
sprintf(pszURL, "%s%s.%s", map->web.imageurl, msGetBasename(filename),
pszExtension);
msIO_printf("<OBJECT classid=\"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\" codebase=\"http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=5,0,0,0\" WIDTH=%d HEIGHT=%d> <PARAM NAME=movie VALUE=\"%s\"><PARAM NAME=quality VALUE=medium><EMBED src=\"%s\" quality=medium WIDTH=%d HEIGHT=%d TYPE=\"application/x-shockwave-flash\" PLUGINSPAGE=\"http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash\"></EMBED></OBJECT>", map->width, map->height, pszURL, pszURL, map->width, map->height);
// unlink( filename );
free( filename );
*/
}
if (iSaveResult > 0)
return(MS_SUCCESS);
else
return(MS_FAILURE);
}
/* -------------------------------------------------------------------- */
/* If the output is MULTIPLE save individual movies as well as */
/* the main movie. */
/* -------------------------------------------------------------------- */
/* -------------------------------------------------------------------- */
/* write some AS related to the map file. */
/* -------------------------------------------------------------------- */
sprintf(szAction, "%s", "mapObj=new Object();");
oAction = newSWFAction(szAction);
SWFMovie_add(((SWFObj *)image->img.swf)->sMainMovie, oAction);
sprintf(szAction, "mapObj.name=\"%s\";", ((SWFObj *)image->img.swf)->map->name);
oAction = newSWFAction(szAction);
SWFMovie_add(((SWFObj *)image->img.swf)->sMainMovie, oAction);
sprintf(szAction, "mapObj.width=%d;", ((SWFObj *)image->img.swf)->map->width);
oAction = newSWFAction(szAction);
SWFMovie_add(((SWFObj *)image->img.swf)->sMainMovie, oAction);
sprintf(szAction, "mapObj.height=%d;",
((SWFObj *)image->img.swf)->map->height);
oAction = newSWFAction(szAction);
SWFMovie_add(((SWFObj *)image->img.swf)->sMainMovie, oAction);
sprintf(szAction, "mapObj.extent=\"%f,%f,%f,%f\";",
((SWFObj *)image->img.swf)->map->extent.minx,
((SWFObj *)image->img.swf)->map->extent.miny,
((SWFObj *)image->img.swf)->map->extent.maxx,
((SWFObj *)image->img.swf)->map->extent.maxy);
oAction = newSWFAction(szAction);
SWFMovie_add(((SWFObj *)image->img.swf)->sMainMovie, oAction);
sprintf(szAction, "mapObj.numlayers=%d;",
((SWFObj *)image->img.swf)->map->numlayers);
oAction = newSWFAction(szAction);
SWFMovie_add(((SWFObj *)image->img.swf)->sMainMovie, oAction);
sprintf(szAction, "%s", "mapObj.layers=new Array();");
oAction = newSWFAction(szAction);
SWFMovie_add(((SWFObj *)image->img.swf)->sMainMovie, oAction);
/* -------------------------------------------------------------------- */
/* Write class for layer object. */
/* -------------------------------------------------------------------- */
sprintf(szAction, "%s", "function LayerObj(name, type, fullname, relativename){ this.name=name; this.type=type; this.fullname=fullname; this.relativename=relativename;}");
oAction = newSWFAction(szAction);
SWFMovie_add(((SWFObj *)image->img.swf)->sMainMovie, oAction);
/* -------------------------------------------------------------------- */
/* extract the name of the file to save and use it to save the */
/* layer files. For example for file name /tmp/ms_tmp/test.swf, */
/* the first layer name will be /tmp/ms_tmp/test_layer0.swf. */
/* -------------------------------------------------------------------- */
nLength = strlen(filename);
iPointPos = -1;
for (i=nLength-1; i>=0; i--)
{
if (filename[i] == '.')
{
iPointPos = i;
break;
}
}
szBase[0] = '\0';
szExt[0] = '\0';
if (iPointPos >= 0)
{
strncpy(szBase, filename, iPointPos);
szBase[iPointPos] = '\0';
strcpy(szExt, filename+iPointPos+1);
}
/* ==================================================================== */
/* For layers that have not be drawn for some reason (status */
/* off, out of scale ...), It will output AS layer objects */
/* where the full name and relative name are set to "undefined" */
/* (See Bug 804 for more details). */
/* ==================================================================== */
nLayers = map->numlayers; /*((SWFObj *)image->img.swf)->nLayerMovies;*/
/* -------------------------------------------------------------------- */
/* save layers. */
/* -------------------------------------------------------------------- */
iMovie = -1;
for (i=0; i<nLayers; i++)
{
if (SWFIsInArray(((SWFObj *)image->img.swf)->panLayerIndex,
((SWFObj *)image->img.swf)->nLayerMovies, i))
{
iMovie++;
/* -------------------------------------------------------------------- */
/* build full filename. */
/* -------------------------------------------------------------------- */
sprintf(szTmp, "%s%d", "_layer_", i);
gszFilename[0] = '\0';
sprintf(gszFilename, szBase);
strcat(gszFilename, szTmp);
strcat(gszFilename, ".");
strcat(gszFilename, szExt);
/* -------------------------------------------------------------------- */
/* build relative name. */
/* -------------------------------------------------------------------- */
nLength = strlen(gszFilename);
iSlashPos = -1;
for (j=nLength-1; j>=0; j--)
{
if (gszFilename[j] == '/' || gszFilename[j] == '\\')
{
iSlashPos = j;
break;
}
}
if (iSlashPos >=0)
{
gszTmp[0]='\0';
k = 0;
for (j=iSlashPos+1; j<nLength; j++)
{
gszTmp[k] = gszFilename[j];
k++;
}
gszTmp[k] = '\0';
pszRelativeName = gszTmp;
}
else
pszRelativeName = gszFilename;
/* test */
/* sprintf(gszFilename, "%s%d.swf", "c:/tmp/ms_tmp/layer_", i); */
SWFMovie_setBackground(((SWFObj *)image->img.swf)->pasMovies[iMovie],
0xff, 0xff, 0xff);
#ifdef MING_VERSION_03
SWFMovie_save(((SWFObj *)image->img.swf)->pasMovies[iMovie], gszFilename, -1);
#else
SWFMovie_save(((SWFObj *)image->img.swf)->pasMovies[iMovie], gszFilename);
#endif
/* test */
/* sprintf(gszFilename, "%s%d.swf", "layer_", i); */
/* sprintf(szAction, "mapObj.layers[%d]=\"%s\";", i, gszFilename); */
sprintf(szAction, "mapObj.layers[%d]= new LayerObj(\"%s\",\"%d\",\"%s\",\"%s\");", i,
GET_LAYER(map, i)->name, GET_LAYER(map, i)->type, gszFilename,
pszRelativeName);
oAction = newSWFAction(szAction);
SWFMovie_add(((SWFObj *)image->img.swf)->sMainMovie, oAction);
/* ==================================================================== */
/* when we have a temporary file, we are assuming that the */
/* intention is to send the swf to the browser. So we use */
/* output the URL for the loadMovieNum. Else we output only the */
/* name of the file. */
/* ==================================================================== */
/* sprintf(szAction, "loadMovie(\"%s\",%d);", gszFilename, i+1); */
if ( bLoadAutomatically )
{
if( bFileIsTemporary )
sprintf(szAction, "loadMovieNum(\"%s%s\",%d);", map->web.imageurl,
pszRelativeName, i+1);
else
sprintf(szAction, "loadMovieNum(\"%s\",%d);", pszRelativeName, i+1);
oAction = newSWFAction(szAction);
SWFMovie_add(((SWFObj *)image->img.swf)->sMainMovie, oAction);
}
}
else /*layer which was not drawn */
{
sprintf(szAction,
"mapObj.layers[%d]= new LayerObj(\"%s\",\"%d\",\"undefined\",\"undefined\");", i,
GET_LAYER(map, i)->name, GET_LAYER(map, i)->type);
oAction = newSWFAction(szAction);
SWFMovie_add(((SWFObj *)image->img.swf)->sMainMovie, oAction);
}
}
sprintf(szAction, "stop();");
oAction = newSWFAction(szAction);
SWFMovie_add(((SWFObj *)image->img.swf)->sMainMovie, oAction);
#ifdef MING_VERSION_03
SWFMovie_save(((SWFObj *)image->img.swf)->sMainMovie, filename, -1);
#else
SWFMovie_save(((SWFObj *)image->img.swf)->sMainMovie, filename);
#endif
/* test */
/* SWFMovie_save(((SWFObj *)image->img.swf)->sMainMovie, "c:/tmp/ms_tmp/main.swf"); */
if( bFileIsTemporary )
{
fp = fopen( filename, "rb" );
if( fp == NULL )
{
msSetError( MS_MISCERR,
"Failed to open %s for streaming to stdout.",
"msSaveImageGDAL()", filename );
return MS_FAILURE;
}
while( (bytes_read = fread(block, 1, sizeof(block), fp)) > 0 )
msIO_fwrite( block, 1, bytes_read, stdout );
fclose( fp );
/* unlink( filename ); */
free( filename );
/*
char *pszURL = (char *)malloc(sizeof(char)*(strlen(map->web.imageurl)+
strlen(filename)+
strlen(pszExtension)+2));
sprintf(pszURL, "%s%s.%s", map->web.imageurl, msGetBasename(filename),
pszExtension);
msIO_printf("<OBJECT classid=\"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\" codebase=\"http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=5,0,0,0\" WIDTH=%d HEIGHT=%d> <PARAM NAME=movie VALUE=\"%s\"><PARAM NAME=quality VALUE=medium> <EMBED src=\"%s\" quality=medium WIDTH=%d HEIGHT=%d TYPE=\"application/x-shockwave-flash\" PLUGINSPAGE=\"http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash\"></EMBED></OBJECT>", map->width, map->height, pszURL, pszURL, map->width, map->height);
// unlink( filename );
free( filename );
*/
}
return(MS_SUCCESS);
}
return(MS_FAILURE);
}
/************************************************************************/
/* void msFreeImageSWF */
/* */
/* Free SWF Object structure */
/************************************************************************/
void msFreeImageSWF(imageObj *image)
{
int i = 0;
if (image && MS_DRIVER_SWF(image->format) )
{
/* fonts */
for (i=0; i<((SWFObj *)image->img.swf)->nFonts; i++)
destroySWFFont(((SWFObj *)image->img.swf)->Fonts[i]);
free(((SWFObj *)image->img.swf)->Fonts);
((SWFObj *)image->img.swf)->nFonts = 0;
/* texts */
for (i=0; i<((SWFObj *)image->img.swf)->nTexts; i++)
destroySWFText(((SWFObj *)image->img.swf)->Texts[i]);
free(((SWFObj *)image->img.swf)->Texts);
((SWFObj *)image->img.swf)->nFonts = 0;
/* bitmaps */
for (i=0; i<((SWFObj *)image->img.swf)->nBitmaps; i++)
destroySWFBitmap(((SWFObj *)image->img.swf)->Bitmaps[i]);
free(((SWFObj *)image->img.swf)->Bitmaps);
((SWFObj *)image->img.swf)->nBitmaps = 0;
/* inputs */
for (i=0; i<((SWFObj *)image->img.swf)->nInputs; i++)
destroySWFInput(((SWFObj *)image->img.swf)->Inputs[i]);
free(((SWFObj *)image->img.swf)->Inputs);
((SWFObj *)image->img.swf)->nInputs = 0;
/* shapes */
for (i=0; i<((SWFObj *)image->img.swf)->nShapes; i++)
destroySWFShape(((SWFObj *)image->img.swf)->Shapes[i]);
free(((SWFObj *)image->img.swf)->Shapes);
((SWFObj *)image->img.swf)->nShapes = 0;
/* buttons */
for (i=0; i<((SWFObj *)image->img.swf)->nButtons; i++)
/* need to check if some of the buttons disappeared or couldn't be created ! */
if (((SWFObj *)image->img.swf)->Buttons[i])
destroySWFButton(((SWFObj *)image->img.swf)->Buttons[i]);
free(((SWFObj *)image->img.swf)->Buttons);
((SWFObj *)image->img.swf)->nButtons = 0;
/* movies */
for (i=0; i<((SWFObj *)image->img.swf)->nLayerMovies; i++)
destroySWFMovie(((SWFObj *)image->img.swf)->pasMovies[i]);
free(((SWFObj *)image->img.swf)->pasMovies);
destroySWFMovie(((SWFObj *)image->img.swf)->sMainMovie);
((SWFObj *)image->img.swf)->nLayerMovies = 0;
((SWFObj *)image->img.swf)->nCurrentMovie = -1;
/* DblData images */
for (i=0; i<((SWFObj *)image->img.swf)->nDblDatas; i++)
free(((SWFObj *)image->img.swf)->DblDatas[i]);
((SWFObj *)image->img.swf)->nDblDatas = 0;
free(((SWFObj *)image->img.swf)->DblDatas);
((SWFObj *)image->img.swf)->map = NULL;
free(((SWFObj *)image->img.swf)->panLayerIndex);
free(image->img.swf);
}
}
/************************************************************************/
/* msTransformShapeSWF */
/* */
/* Transform geographic coordinated to output coordinates. */
/************************************************************************/
void msTransformShapeSWF(shapeObj *shape, rectObj extent, double cellsize)
{
int i,j;
if(shape->numlines == 0) return;
if(shape->type == MS_SHAPE_LINE || shape->type == MS_SHAPE_POLYGON)
{
for(i=0; i<shape->numlines; i++)
{
for(j=0; j < shape->line[i].numpoints; j++ )
{
shape->line[i].point[j].x =
(shape->line[i].point[j].x - extent.minx)/cellsize;
shape->line[i].point[j].y =
(extent.maxy - shape->line[i].point[j].y)/cellsize;
}
}
return;
}
}
/************************************************************************/
/* int msDrawVectorLayerAsRasterSWF */
/* */
/* Draw a vector line as raster in a temporary GD image and */
/* save it. */
/************************************************************************/
int msDrawVectorLayerAsRasterSWF(mapObj *map, layerObj *layer, imageObj *image)
{
imageObj *imagetmp;
/* int nTmp = -1; */
SWFShape oShape;
char *driver = strdup("GD/GIF");
int bFreeImage = 0;
#ifdef USE_GD_GIF
driver = strdup("GD/GIF");
#else
#ifdef USE_GD_PNG
driver = strdup("GD/PNG");
#else
#ifdef USE_GD_JPEG
driver = strdup("GD/JPEG");
#else
#ifdef USE_GD_WBMP
driver = strdup("GD/WBMP");
#endif
#endif
#endif
#endif
if (!image || !MS_DRIVER_SWF(image->format) )
return MS_FAILURE;
if (strcasecmp(msGetOutputFormatOption(image->format,
"OUTPUT_MOVIE",""),
"MULTIPLE") == 0)
{
imagetmp = msImageCreateGD(map->width, map->height,
msCreateDefaultOutputFormat(map, driver),
map->web.imagepath, map->web.imageurl);
bFreeImage = 1;
}
else
imagetmp = (imageObj *)((SWFObj *)image->img.swf)->imagetmp;
if (imagetmp)
{
msImageInitGD( imagetmp, &map->imagecolor );
/* msLoadPalette(imagetmp->img.gd, &(map->palette), map->imagecolor); */
msDrawVectorLayer(map, layer, imagetmp);
oShape = gdImage2Shape(imagetmp->img.gd, image);
/* nTmp = ((SWFObj *)image->img.swf)->nCurrentMovie; */
StoreShape(oShape, image);
SWFMovie_add(GetCurrentMovie(map, image), oShape);
if (bFreeImage)
msFreeImage(imagetmp);
return MS_SUCCESS;
}
return MS_FAILURE;
}
/************************************************************************/
/* SWFMovie GetCurrentMovie(mapObj *map, imageObj *image) */
/* */
/* Get the current movie : If the settings are 1movie per */
/* layer, it reurns the movie assocaited for the layer. Else */
/* return the main movie. */
/************************************************************************/
SWFMovie GetCurrentMovie(mapObj *map, imageObj *image)
{
int nTmp;
if (!image || !map || !MS_DRIVER_SWF(image->format) )
return NULL;
if (strcasecmp(msGetOutputFormatOption(image->format,"OUTPUT_MOVIE",""),
"MULTIPLE") == 0 && ((SWFObj *)image->img.swf)->nCurrentMovie >=0)
{
nTmp = ((SWFObj *)image->img.swf)->nCurrentMovie;
return ((SWFObj *)image->img.swf)->pasMovies[nTmp];
}
else
return ((SWFObj *)image->img.swf)->sMainMovie;
}
#endif
More information about the mapserver-dev
mailing list