[mapserver-commits] r12841 - trunk/mapserver
svn at osgeo.org
svn at osgeo.org
Sun Dec 4 08:48:20 EST 2011
Author: assefa
Date: 2011-12-04 05:48:20 -0800 (Sun, 04 Dec 2011)
New Revision: 12841
Modified:
trunk/mapserver/HISTORY.TXT
trunk/mapserver/Makefile.in
trunk/mapserver/configure.in
trunk/mapserver/mapagg.cpp
trunk/mapserver/mapcairo.c
trunk/mapserver/mapdraw.c
trunk/mapserver/mapdummyrenderer.c
trunk/mapserver/maprendering.c
trunk/mapserver/mapserver.h
trunk/mapserver/mapsymbol.c
trunk/mapserver/mapsymbol.h
Log:
Add svg symbols support (#3671)
Modified: trunk/mapserver/HISTORY.TXT
===================================================================
--- trunk/mapserver/HISTORY.TXT 2011-12-03 11:43:00 UTC (rev 12840)
+++ trunk/mapserver/HISTORY.TXT 2011-12-04 13:48:20 UTC (rev 12841)
@@ -14,6 +14,9 @@
Current Version (SVN trunk, 6.1-dev, future 6.2):
-------------------------------------------------
+
+- Add svg symbols support (#3671)
+
- Fixed subsetting in WCS 2.0 (#4099)
- Upgrade clipper library to 4.6.3
Modified: trunk/mapserver/Makefile.in
===================================================================
--- trunk/mapserver/Makefile.in 2011-12-03 11:43:00 UTC (rev 12840)
+++ trunk/mapserver/Makefile.in 2011-12-04 13:48:20 UTC (rev 12841)
@@ -222,6 +222,10 @@
CAIRO_LIB=@CAIRO_LIB@
CAIRO_INC=@CAIRO_INC@
+LIBSVG_CAIRO=@LIBSVG_CAIRO_ENABLED@
+LIBSVG_CAIRO_LIB=@LIBSVG_CAIRO_LIB@
+LIBSVG_CAIRO_INC=@LIBSVG_CAIRO_INC@
+
#
# Pick a compiler, etc. Flex and bison are only required if you need to modify the mapserver lexer (maplexer.l) or expression parser (mapparser.y).
#
@@ -238,7 +242,7 @@
# most of the relevant stuff is in AC_LD_SHARED in
# aclocal.m4
-LD_SHARED = @LD_SHARED@
+LD_SHARED = @LD_SHARED@ @LDFLAGS@
LD_SONAME_LIBMAP = -W1, at SO_COMMAND_NAME@,$(LIBMAP_SH_VER)
XTRALIBS= @XTRALIBS@
@@ -250,7 +254,7 @@
$(AGG_INC) $(OGL_INC) $(FTGL_INC) $(PROJ_INC) $(EGIS_INC) \
$(SDE_INC) $(GDAL_INC) $(POSTGIS_INC) $(MYSQL_INC) \
$(CURL_INC) $(ORACLESPATIAL_INC) $(GEOS_INC) $(ICONV_INC) \
- $(FASTCGI_INC) $(EXEMPI_INC) $(ZLIB_INC) $(XML2_INC) $(FRIBIDI_INC) $(CAIRO_INC)
+ $(FASTCGI_INC) $(EXEMPI_INC) $(ZLIB_INC) $(XML2_INC) $(FRIBIDI_INC) $(CAIRO_INC) $(LIBSVG_CAIRO_INC)
FLAGS = @DEBUG_FLAGS@ $(DEFINES) $(INCLUDES)
@@ -262,7 +266,7 @@
$(JPEG_LIB) $(PNG_LIB) $(GIF_LIB) $(SDE_LIB) $(GDAL_LIB) $(POSTGIS_LIB) \
$(MYSQL_LIB) $(CURL_LIB) $(ORACLESPATIAL_LIB) $(GEOS_LIB) \
$(THREAD_LIB) $(ICONV_LIB) $(FASTCGI_LIB) $(EXEMPI_LIB) $(XSLT_LIB) $(EXSLT_LIB) \
- $(ZLIB_LIB) $(XML2_LIB) $(FRIBIDI_LIB) $(XTRALIBS) $(CAIRO_LIB)
+ $(ZLIB_LIB) $(XML2_LIB) $(FRIBIDI_LIB) $(XTRALIBS) $(CAIRO_LIB) $(LIBSVG_CAIRO_LIB)
# STATIC_LIBS is full filename with path of libs that will be statically linked
STATIC_LIBS= $(GD_STATIC)
Modified: trunk/mapserver/configure.in
===================================================================
--- trunk/mapserver/configure.in 2011-12-03 11:43:00 UTC (rev 12840)
+++ trunk/mapserver/configure.in 2011-12-04 13:48:20 UTC (rev 12841)
@@ -2281,7 +2281,7 @@
AC_MSG_ERROR([pkg-config required for cairo support, try using --with-pkg-config=PATH])
fi
else
- CAIRO_CONFIG=$with_cairo_config
+ CAIRO_CONFIG=$with_cairo
fi
if test "$CAIRO_CONFIG" = "no" ; then
@@ -2304,6 +2304,57 @@
ALL_LIB="$CAIRO_LIB $ALL_LIB"
+dnl ---------------------------------------------------------------------------
+dnl Look for Cairo SVG parser if requested.
+dnl ---------------------------------------------------------------------------
+
+AC_MSG_CHECKING(if Cairo svg parser support requested)
+
+AC_ARG_WITH(libsvg-cairo,
+[ --with-libsvg-cairo[[=ARG]] Include Cairo SVG Parser Support (ARG=yes/path to cairo.pc)],,)
+
+if test "$with_libsvg_cairo" = "no" -o "$with_libsvg_cairo" = "" ; then
+ AC_MSG_RESULT(no)
+ LIBSVG_CAIRO_CONFIG="no"
+
+elif test "$with_libsvg_cairo" = "yes" ; then
+ AC_MSG_RESULT(yes)
+ if test "$PKG_CONFIG" != "no" ; then
+ AC_MSG_CHECKING(for libsvg-cairo pkg-config path)
+ `$PKG_CONFIG --silence-errors -- libsvg-cairo >> /dev/null`
+ if test $? -eq 0 ; then
+ AC_MSG_RESULT(yes)
+ LIBSVG_CAIRO_CONFIG="libsvg-cairo"
+ else
+ AC_MSG_ERROR([libsvg-cairo support requested, but not found.])
+ fi
+ else
+ AC_MSG_ERROR([pkg-config required for libsvg-cairo support, try using --with-pkg-config=PATH])
+ fi
+else
+ LIBSVG_CAIRO_CONFIG=$with_libsvg_cairo
+fi
+
+if test "$LIBSVG_CAIRO_CONFIG" = "no" ; then
+ LIBSVG_CAIRO_ENABLED=
+ LIBSVG_CAIRO_INC=
+ LIBSVG_CAIRO_LIB=
+else
+ AC_MSG_RESULT([yes, pkg-config defaults, or user supplied path to cairo.pc])
+ LIBSVG_CAIRO_ENABLED="-DUSE_SVG_CAIRO"
+ LIBSVG_CAIRO_LIB=`$PKG_CONFIG --libs $LIBSVG_CAIRO_CONFIG`
+ LIBSVG_CAIRO_INC=`$PKG_CONFIG --cflags $LIBSVG_CAIRO_CONFIG`
+fi
+
+AC_SUBST(LIBSVG_CAIRO_ENABLED,$LIBSVG_CAIRO_ENABLED)
+AC_SUBST(LIBSVG_CAIRO_INC,$LIBSVG_CAIRO_INC)
+AC_SUBST(LIBSVG_CAIRO_LIB,$LIBSVG_CAIRO_LIB)
+
+ALL_ENABLED="$LIBSVG_CAIRO_ENABLED $ALL_ENABLED"
+ALL_INC="$LIBSVG_CAIRO_INC $ALL_INC"
+ALL_LIB="$LIBSVG_CAIRO_LIB $ALL_LIB"
+
+
dnl ---------------------------------------------------------------------
dnl Support for FastCGI enabled builds.
dnl ---------------------------------------------------------------------
@@ -2902,6 +2953,7 @@
AC_MSG_RESULT([ AGG support: ${AGG_ENABLED}])
AC_MSG_RESULT([ SVG Symbol support: ${AGG_SVG_SYMBOLS_ENABLED}])
AC_MSG_RESULT([ Cairo (SVG,PDF) support: ${CAIRO_ENABLED}])
+AC_MSG_RESULT([ Cairo SVG parser support: ${LIBSVG_CAIRO_ENABLED}])
AC_MSG_RESULT([ KML support: ${KML_ENABLED}])
AC_MSG_RESULT()
Modified: trunk/mapserver/mapagg.cpp
===================================================================
--- trunk/mapserver/mapagg.cpp 2011-12-03 11:43:00 UTC (rev 12840)
+++ trunk/mapserver/mapagg.cpp 2011-12-04 13:48:20 UTC (rev 12841)
@@ -551,7 +551,7 @@
r->m_rasterizer_aa.reset();
r->m_rasterizer_aa.filling_rule(mapserver::fill_non_zero);
- if( (style->rotation != 0 && style->rotation != MS_PI*2.)|| style->scale != 1) {
+ if ( (style->rotation != 0 && style->rotation != MS_PI*2.)|| style->scale != 1) {
mapserver::trans_affine image_mtx;
image_mtx *= mapserver::trans_affine_translation(-(pf.width()/2.),-(pf.height()/2.));
/*agg angles are antitrigonometric*/
@@ -878,6 +878,7 @@
int agg2FreeSymbol(symbolObj * symbol) {
switch(symbol->type) {
case MS_SYMBOL_PIXMAP:
+ case MS_SYMBOL_SVG:
if(symbol->renderer_cache) {
rendering_buffer *rb = (rendering_buffer*)symbol->renderer_cache;
free(rb->buf());
@@ -1133,8 +1134,8 @@
renderer->supports_pixel_buffer = 1;
renderer->use_imagecache = 0;
renderer->supports_clipping = 0;
+ renderer->supports_svg = 0;
renderer->default_transform_mode = MS_TRANSFORM_SIMPLIFY;
-
agg2InitCache(&(MS_RENDERER_CACHE(renderer)));
renderer->cleanup = agg2Cleanup;
renderer->renderLine = &agg2RenderLine;
Modified: trunk/mapserver/mapcairo.c
===================================================================
--- trunk/mapserver/mapcairo.c 2011-12-03 11:43:00 UTC (rev 12840)
+++ trunk/mapserver/mapcairo.c 2011-12-04 13:48:20 UTC (rev 12841)
@@ -39,6 +39,10 @@
#include <cairo/cairo-svg.h>
#endif
+#ifdef USE_SVG_CAIRO
+#include <svg-cairo.h>
+#endif
+
# include <cairo-ft.h>
/*
#include <pango/pangocairo.h>
@@ -267,13 +271,13 @@
assert(symbol->renderer_cache);
im=(cairo_surface_t*)symbol->renderer_cache;
cairo_save(r->cr);
- if(style->rotation != 0 || style-> scale != 1) {
+ if(style->rotation != 0 || style->scale != 1) {
cairo_translate (r->cr, x,y);
cairo_rotate (r->cr, -style->rotation);
cairo_scale (r->cr, style->scale,style->scale);
cairo_translate (r->cr, -0.5*b->width, -0.5*b->height);
} else {
- cairo_translate (r->cr, MS_NINT(x-0.5*b->width),MS_NINT(y-0.5*b->height));
+ cairo_translate (r->cr, MS_NINT(x-0.5*b->width),MS_NINT(y-0.5*b->height));
}
cairo_set_source_surface (r->cr, im, 0, 0);
cairo_paint (r->cr);
@@ -318,6 +322,65 @@
return MS_SUCCESS;
}
+int renderSVGSymbolCairo(imageObj *img, double x, double y, symbolObj *symbol,
+ symbolStyleObj *style) {
+#ifdef USE_SVG_CAIRO
+ cairo_renderer *r = CAIRO_RENDERER(img);
+ //double ox=symbol->sizex*0.5,oy=symbol->sizey*0.5;
+
+ unsigned int svg_width, svg_height;
+ svg_cairo_status_t status;
+ svg_cairo_t *svgc;
+ double scale;
+
+ //use cache for svg surface
+ if(!symbol->renderer_cache) {
+ status = svg_cairo_create(&svgc);
+ status = svg_cairo_parse_buffer(svgc, symbol->svg_text, strlen(symbol->svg_text));
+ if (status) {
+ msSetError(MS_RENDERERERR, "problem creating cairo svg", "renderSVGSymbolCairo()");
+ return MS_FAILURE;
+ }
+ symbol->renderer_cache = svgc;
+ }
+ assert(symbol->renderer_cache);
+ svgc=(svg_cairo_t *)symbol->renderer_cache;
+
+ svg_cairo_get_size (svgc, &svg_width, &svg_height);
+
+ //scale such that the SVG is rendered at the desired size in pixels
+ scale = style->scale;
+ /*
+ if (style->scale != 1) {
+ scale = MS_MIN(style->scale / (double) svg_width,
+ style->scale / (double) svg_height);
+ } else {
+ scale = style->scale;
+ }
+ */
+
+ cairo_save(r->cr);
+ cairo_translate(r->cr,x,y);
+ cairo_scale(r->cr,scale,scale);
+
+ if (style->rotation != 0) {
+ cairo_rotate(r->cr, -style->rotation);
+ cairo_translate (r->cr, -(int)svg_width/2, -(int)svg_height/2);
+ }
+ else
+ cairo_translate (r->cr, -(int)svg_width/2, -(int)svg_height/2);
+
+ status = svg_cairo_render(svgc, r->cr);
+ cairo_restore(r->cr);
+ return MS_SUCCESS;
+
+#else
+ msSetError(MS_MISCERR, "SVG Symbols requested but is not built with libsvgcairo",
+ "renderSVGSymbolCairo()");
+ return MS_FAILURE;
+#endif
+}
+
int renderTruetypeSymbolCairo(imageObj *img, double x, double y, symbolObj *symbol,
symbolStyleObj *s) {
int unicode;
@@ -575,7 +638,7 @@
r->cr = cairo_create(r->surface);
if(format->transparent || !bg || !MS_VALID_COLOR(*bg)) {
r->use_alpha = 1;
- cairo_set_source_rgba (r->cr, 0,0,0,0);
+ cairo_set_source_rgba (r->cr, 255,255,255,1);
} else {
r->use_alpha = 0;
msCairoSetSourceColor(r->cr,bg);
@@ -767,8 +830,11 @@
cairo_path_destroy(s->renderer_cache);
break;
case MS_SYMBOL_PIXMAP:
- cairo_surface_finish(s->renderer_cache);
+ case MS_SYMBOL_SVG:
+ if (s->renderer_cache) {
+ //cairo_surface_finish(s->renderer_cache);
cairo_surface_destroy(s->renderer_cache);
+ }
break;
}
s->renderer_cache=NULL;
@@ -789,6 +855,138 @@
return MS_SUCCESS;
}
+int msPreloadSVGSymbol(symbolObj *symbol)
+{
+#ifdef USE_SVG_CAIRO
+ svg_cairo_t *svgc;
+ int status;
+ unsigned int svg_width, svg_height;
+
+ if(symbol->svg_cairo_surface)
+ return MS_SUCCESS;
+
+ if(!symbol->svg_text)
+ return MS_FAILURE;
+
+ status = svg_cairo_create(&svgc);
+ if (status) {
+ msSetError(MS_RENDERERERR, "problem creating cairo svg", "msPreloadSVGSymbol()");
+ return MS_FAILURE;
+ }
+ status = svg_cairo_parse_buffer(svgc, symbol->svg_text, strlen(symbol->svg_text));
+ if (status) {
+ msSetError(MS_RENDERERERR, "problem parsing svg symbol", "msPreloadSVGSymbol()");
+ return MS_FAILURE;
+ }
+ svg_cairo_get_size (svgc, &svg_width, &svg_height);
+ if (svg_width == 0 || svg_height == 0)
+ {
+ msSetError(MS_RENDERERERR, "problem parsing svg symbol", "msPreloadSVGSymbol()");
+ return MS_FAILURE;
+ }
+
+ symbol->sizex = svg_width;
+ symbol->sizey = svg_height;
+
+ symbol->svg_cairo_surface = (void *)svgc;
+
+ return MS_SUCCESS;
+
+#else
+ msSetError(MS_MISCERR, "SVG Symbols requested but is not built with libsvgcairo",
+ "msPreloadSVGSymbol()");
+ return MS_FAILURE;
+#endif
+}
+
+int msRenderSVGToPixmap(symbolObj *symbol, symbolStyleObj *style) {
+
+#ifdef USE_SVG_CAIRO
+ unsigned int svg_width, svg_height;
+ svg_cairo_status_t status;
+ cairo_t *cr;
+ svg_cairo_t *svgc;
+ cairo_surface_t *surface;
+ unsigned char *pb;
+ rasterBufferObj *rb;
+ //rendering_buffer *rc;
+ int width, height, surface_w, surface_h;
+ double scale;
+
+ //already rendered at the right size and scale? return
+ if (symbol->pixmap_buffer) {
+ if (style->scale == symbol->pixmap_buffer->scale &&
+ style->rotation == symbol->pixmap_buffer->rotation) {
+ return MS_SUCCESS;
+ } else {
+ if(symbol->renderer!=NULL)
+ symbol->renderer->freeSymbol(symbol);
+ msFreeRasterBuffer(symbol->pixmap_buffer);
+ }
+ }
+
+ if (!symbol->svg_cairo_surface )
+ msPreloadSVGSymbol(symbol);
+
+ if (!symbol->svg_cairo_surface)
+ return MS_FAILURE;
+
+ //set up raster
+
+ svgc =symbol->svg_cairo_surface;
+
+ svg_cairo_get_size (svgc, &svg_width, &svg_height);
+ width = surface_w = svg_width;
+ height = surface_h = svg_height;
+
+ //scale such that the SVG is rendered at the desired size in pixels
+ scale = style->scale; /*MS_MIN(style->scale / (double) svg_width,
+ style->scale / (double) svg_height);*/
+
+ //increase pixmap size to accomodate scaling/rotation
+ if (scale != 1.0 && style->scale != 1.0) {
+ width = surface_w = (svg_width * scale + 0.5);
+ height = surface_h = (svg_height * scale + 0.5);
+ }
+ if (style->rotation != 0) {
+ surface_w = MS_NINT(width * 1.415);
+ surface_h = MS_NINT(height * 1.415);
+ }
+
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, surface_w, surface_h);
+ cr = cairo_create(surface);
+
+ if (style->rotation != 0) {
+ cairo_translate (cr, surface_w/2, surface_h/2);
+ cairo_rotate(cr, -style->rotation);
+ cairo_translate (cr, -width/2, -height/2);
+ }
+ if (style->scale != 1.0) {
+ cairo_scale(cr,scale,scale);
+ }
+ status = svg_cairo_render(svgc, cr);
+
+ pb = cairo_image_surface_get_data(surface);
+
+ //set up raster
+ symbol->pixmap_buffer = (rasterBufferObj*)calloc(1,sizeof(rasterBufferObj));
+ MS_CHECK_ALLOC(symbol->pixmap_buffer, sizeof(rasterBufferObj), MS_FAILURE);
+ initializeRasterBufferCairo(symbol->pixmap_buffer, surface_w, surface_h, 0);
+ rb = symbol->pixmap_buffer;
+ memcpy(rb->data.rgba.pixels, pb, surface_w * surface_h * 4 * sizeof(unsigned char));
+ rb->scale = style->scale;
+ rb->rotation = style->rotation;
+ cairo_destroy(cr);
+ cairo_surface_destroy(surface);
+
+ return MS_SUCCESS;
+#else
+ msSetError(MS_MISCERR, "SVG Symbols requested but MapServer is not built with libsvgcairo",
+ "renderSVGSymbolCairo()");
+ return MS_FAILURE;
+#endif
+}
+
#endif /*USE_CAIRO*/
@@ -796,6 +994,7 @@
#ifdef USE_CAIRO
renderer->supports_pixel_buffer=1;
renderer->supports_transparent_layers = 0;
+ renderer->supports_svg = 1;
renderer->default_transform_mode = MS_TRANSFORM_SIMPLIFY;
initializeCache(&MS_RENDERER_CACHE(renderer));
renderer->startLayer = startLayerRasterCairo;
@@ -812,6 +1011,7 @@
renderer->renderEllipseSymbol = &renderEllipseSymbolCairo;
renderer->renderVectorSymbol = &renderVectorSymbolCairo;
renderer->renderTruetypeSymbol = &renderTruetypeSymbolCairo;
+ renderer->renderSVGSymbol = &renderSVGSymbolCairo;
renderer->renderPixmapSymbol = &renderPixmapSymbolCairo;
renderer->mergeRasterBuffer = &mergeRasterBufferCairo;
renderer->getTruetypeTextBBox = &getTruetypeTextBBoxCairo;
@@ -822,7 +1022,7 @@
renderer->cleanup = &cleanupCairo;
return MS_SUCCESS;
#else
- msSetError(MS_MISCERR, "Cairo Driver requested but is not built in",
+ msSetError(MS_MISCERR, "Cairo Driver requested but MapServer is not built in",
"msPopulateRendererVTableCairoRaster()");
return MS_FAILURE;
#endif
@@ -833,6 +1033,7 @@
renderer->use_imagecache=0;
renderer->supports_pixel_buffer=0;
renderer->supports_transparent_layers = 1;
+ renderer->supports_svg = 1;
renderer->default_transform_mode = MS_TRANSFORM_SIMPLIFY;
initializeCache(&MS_RENDERER_CACHE(renderer));
renderer->startLayer = startLayerVectorCairo;
@@ -848,6 +1049,7 @@
renderer->renderEllipseSymbol = &renderEllipseSymbolCairo;
renderer->renderVectorSymbol = &renderVectorSymbolCairo;
renderer->renderTruetypeSymbol = &renderTruetypeSymbolCairo;
+ renderer->renderSVGSymbol = &renderSVGSymbolCairo;
renderer->renderPixmapSymbol = &renderPixmapSymbolCairo;
renderer->loadImageFromFile = &msLoadMSRasterBufferFromFile;
renderer->mergeRasterBuffer = &mergeRasterBufferCairo;
@@ -859,7 +1061,7 @@
renderer->cleanup = &cleanupCairo;
return MS_SUCCESS;
#else
- msSetError(MS_MISCERR, "Cairo Driver requested but is not built in",
+ msSetError(MS_MISCERR, "Cairo Driver requested but MapServer is not built in",
"msPopulateRendererVTableCairoRaster()");
return MS_FAILURE;
#endif
Modified: trunk/mapserver/mapdraw.c
===================================================================
--- trunk/mapserver/mapdraw.c 2011-12-03 11:43:00 UTC (rev 12840)
+++ trunk/mapserver/mapdraw.c 2011-12-04 13:48:20 UTC (rev 12841)
@@ -1455,6 +1455,15 @@
if(MS_SUCCESS != msPreloadImageSymbol(MS_MAP_RENDERER(map),symbol))
return MS_FAILURE;
}
+ else if(symbol->type == MS_SYMBOL_SVG) {
+#ifdef USE_SVG_CAIRO
+ if(MS_SUCCESS != msPreloadSVGSymbol(symbol))
+ return MS_FAILURE;
+#else
+ msSetError(MS_SYMERR, "SVG symbol support is not enabled.", "msDrawShape()");
+ return MS_FAILURE;
+#endif
+ }
maxsize = MS_MAX(
msSymbolGetDefaultSize(symbol),MS_MAX(style->size,style->width)
);
Modified: trunk/mapserver/mapdummyrenderer.c
===================================================================
--- trunk/mapserver/mapdummyrenderer.c 2011-12-03 11:43:00 UTC (rev 12840)
+++ trunk/mapserver/mapdummyrenderer.c 2011-12-04 13:48:20 UTC (rev 12841)
@@ -226,6 +226,7 @@
renderer->supports_transparent_layers = 0;
renderer->supports_clipping = 0;
renderer->supports_bitmap_fonts = 0;
+ renderer->supports_svg = 0;
renderer->renderer_data = NULL;
renderer->transform_mode = MS_TRANSFORM_SIMPLIFY;
renderer->startLayer = &startLayerDummy;
Modified: trunk/mapserver/maprendering.c
===================================================================
--- trunk/mapserver/maprendering.c 2011-12-03 11:43:00 UTC (rev 12840)
+++ trunk/mapserver/maprendering.c 2011-12-04 13:48:20 UTC (rev 12841)
@@ -190,6 +190,7 @@
if(tile==NULL) {
imageObj *tileimg;
double p_x,p_y;
+ double scale, rotation;
tileimg = msImageCreate(width,height,img->format,NULL,NULL,img->resolution, img->resolution, NULL);
if(!seamlessmode) {
p_x = width/2.0;
@@ -208,8 +209,33 @@
renderer->renderEllipseSymbol(tileimg, p_x, p_y,symbol, s);
break;
case (MS_SYMBOL_VECTOR):
- renderer->renderVectorSymbol(tileimg, p_x, p_y, symbol, s);
+ renderer->renderVectorSymbol(tileimg, p_x, p_y, symbol, s);
break;
+
+ case (MS_SYMBOL_SVG):
+#ifdef USE_SVG_CAIRO
+ if(msPreloadSVGSymbol(symbol) != MS_SUCCESS) {
+ return NULL; //failed to load image, renderer should have set the error message
+ }
+ if (renderer->supports_svg)
+ renderer->renderSVGSymbol(tileimg, p_x, p_y, symbol, s);
+ else
+ {
+ if (msRenderSVGToPixmap(symbol, s) == MS_SUCCESS){
+ scale = s->scale;
+ rotation = s->rotation;
+ s->scale = 1.0;
+ s->rotation = 0;
+ renderer->renderPixmapSymbol(tileimg, p_x, p_y, symbol, s);
+ s->scale = scale;
+ s->rotation = rotation;
+ }
+ }
+#else
+ msSetError(MS_SYMERR, "SVG symbol support is not enabled.", "getTile()");
+ return NULL;
+#endif
+ break;
default:
break;
}
@@ -227,7 +253,7 @@
for(j=1;j<=3;j++) {
p_y = (j+0.5) * height;
switch(symbol->type) {
- case (MS_SYMBOL_TRUETYPE):
+ case (MS_SYMBOL_TRUETYPE):
renderer->renderTruetypeSymbol(tile3img, p_x, p_y, symbol, s);
break;
case (MS_SYMBOL_PIXMAP):
@@ -242,7 +268,32 @@
case (MS_SYMBOL_VECTOR):
renderer->renderVectorSymbol(tile3img, p_x, p_y, symbol, s);
break;
- default:
+ /*we should never get into these cases since the seamlessmode mode seems to
+ only be for vector symbols. But if that changes ...*/
+ case (MS_SYMBOL_SVG):
+#ifdef USE_SVG_CAIRO
+ if(msPreloadSVGSymbol(symbol) != MS_SUCCESS) {
+ return NULL; //failed to load image, renderer should have set the error message
+ }
+ if (renderer->supports_svg) {
+ renderer->renderSVGSymbol(tile3img, p_x, p_y, symbol, s);
+ } else {
+ if (msRenderSVGToPixmap(symbol, s) == MS_SUCCESS){
+ scale = s->scale;
+ rotation = s->rotation;
+ s->scale = 1.0;
+ s->rotation = 0;
+ renderer->renderPixmapSymbol(tile3img, p_x, p_y, symbol, s);
+ s->scale = scale;
+ s->rotation = rotation;
+ }
+ }
+#else
+ msSetError(MS_SYMERR, "SVG symbol support is not enabled.", "getTile()");
+ return NULL;
+#endif
+ break;
+ default:
break;
}
}
@@ -577,16 +628,16 @@
* this behavior is kind of a mapfile hack, and must be
* kept for backwards compatibility
*/
- if (symbolset->symbol[style->symbol]->type != MS_SYMBOL_PIXMAP) {
- if (!MS_VALID_COLOR(style->color)) {
- if(MS_VALID_COLOR(style->outlinecolor))
- return msDrawLineSymbol(symbolset, image, p, style, scalefactor);
- else {
- /* just do nothing if no color has been set */
- return MS_SUCCESS;
- }
- }
- }
+// if (symbolset->symbol[style->symbol]->type != MS_SYMBOL_PIXMAP) {
+// if (!MS_VALID_COLOR(style->color)) {
+// if(MS_VALID_COLOR(style->outlinecolor))
+// return msDrawLineSymbol(symbolset, image, p, style, scalefactor);
+// else {
+// /* just do nothing if no color has been set */
+// return MS_SUCCESS;
+// }
+// }
+// }
if (image)
{
if (MS_RENDERER_PLUGIN(image->format)) {
@@ -650,6 +701,8 @@
int pw,ph;
imageObj *tile;
int seamless = 0;
+
+
switch(symbol->type) {
case MS_SYMBOL_PIXMAP:
if(MS_SUCCESS != msPreloadImageSymbol(renderer,symbol)) {
@@ -662,11 +715,22 @@
symbol->full_font_path = msStrdup(msLookupHashTable(&(symbolset->fontset->fonts),
symbol->font));
if(!symbol->full_font_path) {
- msSetError(MS_MEMERR,"allocation error", "msDrawMArkerSymbol()");
+ msSetError(MS_MEMERR,"allocation error", "msDrawMarkerSymbol()");
ret = MS_FAILURE;
goto cleanup;
}
break;
+ case MS_SYMBOL_SVG:
+#ifdef USE_SVG_CAIRO
+ if(MS_SUCCESS != msPreloadSVGSymbol(symbol)) {
+ ret = MS_FAILURE;
+ goto cleanup;
+ }
+#else
+ msSetError(MS_SYMERR, "SVG symbol support is not enabled.", "msDrawMarkerSymbol()");
+ return MS_FAILURE;
+#endif
+ break;
case MS_SYMBOL_VECTOR:
case MS_SYMBOL_ELLIPSE:
break;
@@ -680,9 +744,9 @@
computeSymbolStyle(&s,style,symbol,scalefactor);
s.style = style;
- if (!s.color && !s.outlinecolor && symbol->type != MS_SYMBOL_PIXMAP) {
- ret = MS_SUCCESS; /* nothing to do (colors are required except for PIXMAP symbols */
- goto cleanup;
+ if (!s.color && !s.outlinecolor && symbol->type != MS_SYMBOL_PIXMAP && symbol->type != MS_SYMBOL_SVG) {
+ ret = MS_SUCCESS; /* nothing to do (colors are required except for PIXMAP symbols */
+ goto cleanup;
}
if(s.backgroundcolor) {
@@ -754,30 +818,48 @@
symbolObj *symbol = symbolset->symbol[style->symbol];
/* store a reference to the renderer to be used for freeing */
symbol->renderer = renderer;
- switch (symbol->type) {
- case (MS_SYMBOL_TRUETYPE): {
- if(!symbol->full_font_path)
+ switch (symbol->type)
+ {
+ case (MS_SYMBOL_TRUETYPE): {
+ if(!symbol->full_font_path)
symbol->full_font_path = msStrdup(msLookupHashTable(&(symbolset->fontset->fonts),
- symbol->font));
- if(!symbol->full_font_path) {
- msSetError(MS_MEMERR,"allocation error", "msDrawMArkerSymbol()");
+ symbol->font));
+ if(!symbol->full_font_path) {
+ msSetError(MS_MEMERR,"allocation error", "msDrawMarkerSymbol()");
return MS_FAILURE;
- }
- }
- break;
- case (MS_SYMBOL_PIXMAP): {
- if(!symbol->pixmap_buffer) {
+ }
+ }
+ break;
+ case (MS_SYMBOL_PIXMAP): {
+ if(!symbol->pixmap_buffer) {
if(MS_SUCCESS != msPreloadImageSymbol(renderer,symbol))
- return MS_FAILURE;
- }
- }
- break;
- }
+ return MS_FAILURE;
+ }
+ }
+ break;
+
+ case (MS_SYMBOL_SVG): {
+#ifdef USE_SVG_CAIRO
+ if(!symbol->svg_cairo_surface) {
+ if(MS_SUCCESS != msPreloadSVGSymbol(symbol))
+ return MS_FAILURE;
+ }
+#else
+ msSetError(MS_SYMERR, "SVG symbol support is not enabled.", "msDrawMarkerSymbol()");
+ return MS_FAILURE;
+#endif
+ }
+ break;
+ }
+
s.style = style;
computeSymbolStyle(&s,style,symbol,scalefactor);
s.style = style;
- if (!s.color && !s.outlinecolor && symbol->type != MS_SYMBOL_PIXMAP)
- return MS_SUCCESS; /* nothing to do if no color, except for pixmap symbols */
+ if (!s.color && !s.outlinecolor && symbol->type != MS_SYMBOL_PIXMAP &&
+ symbol->type != MS_SYMBOL_SVG)
+ {
+ return MS_SUCCESS; // nothing to do if no color, except for pixmap symbols
+ }
@@ -840,11 +922,35 @@
ret = renderer->renderVectorSymbol(image, p_x, p_y, symbol, &s);
}
break;
+ case (MS_SYMBOL_SVG): {
+ if (renderer->supports_svg) {
+ ret = renderer->renderSVGSymbol(image, p_x, p_y, symbol, &s);
+ } else {
+#ifdef USE_SVG_CAIRO
+ if (msRenderSVGToPixmap(symbol, &s) == MS_SUCCESS){
+ //store style, render pixmap then reset style
+ double scale, rotation;
+ scale = s.scale;
+ rotation = s.rotation;
+ s.scale = 1.0;
+ s.rotation = 0;
+ ret = renderer->renderPixmapSymbol(image,p_x,p_y,symbol,&s);
+ s.scale = scale;
+ s.rotation = rotation;
+ }
+#else
+ msSetError(MS_SYMERR, "SVG symbol support is not enabled.", "msDrawMarkerSymbol()");
+ return MS_FAILURE;
+#endif
+ }
+ }
+ break;
default:
break;
- }
+ //}
return ret;
}
+ }
else if( MS_RENDERER_IMAGEMAP(image->format) )
msDrawMarkerSymbolIM(symbolset, image, p, style, scalefactor);
Modified: trunk/mapserver/mapserver.h
===================================================================
--- trunk/mapserver/mapserver.h 2011-12-03 11:43:00 UTC (rev 12840)
+++ trunk/mapserver/mapserver.h 2011-12-04 13:48:20 UTC (rev 12841)
@@ -1960,6 +1960,7 @@
MS_DLL_EXPORT int msSaveSymbolSet(symbolSetObj *symbolset, const char *filename);
MS_DLL_EXPORT int msLoadImageSymbol(symbolObj *symbol, const char *filename);
MS_DLL_EXPORT int msPreloadImageSymbol(rendererVTableObj *renderer, symbolObj *symbol);
+MS_DLL_EXPORT int msPreloadSVGSymbol(symbolObj *symbol);
MS_DLL_EXPORT symbolObj *msRotateSymbol(symbolObj *symbol, double angle);
MS_DLL_EXPORT imageObj *msSymbolGetImageGD(symbolObj *symbol, outputFormatObj *format);
@@ -2666,6 +2667,7 @@
int supports_pixel_buffer;
int supports_clipping;
int supports_bitmap_fonts;
+ int supports_svg;
int use_imagecache;
enum MS_TRANSFORM_MODE default_transform_mode;
enum MS_TRANSFORM_MODE transform_mode;
@@ -2708,12 +2710,18 @@
void* (*createEllipseSymbolTile)(int width, int height,
symbolObj *symbol, symbolStyleObj *style);
- int (*renderTruetypeSymbol)(imageObj *img, double x, double y,
- symbolObj *symbol, symbolStyleObj *style);
+ int (*renderTruetypeSymbol)(imageObj *img, double x, double y,
+ symbolObj *symbol, symbolStyleObj *style);
- void* (*createTruetypeSymbolTile)(int width, int height,
- symbolObj *symbol, symbolStyleObj *style);
+ void* (*createTruetypeSymbolTile)(int width, int height,
+ symbolObj *symbol, symbolStyleObj *style);
+ int (*renderSVGSymbol)(imageObj *img, double x, double y,
+ symbolObj *symbol, symbolStyleObj *style);
+
+ void* (*createSVGSymbolTile)(int width, int height,
+ symbolObj *symbol, symbolStyleObj *style);
+
int (*renderTile)(imageObj *img, imageObj *tile, double x, double y);
int (*loadImageFromFile)(char *path, rasterBufferObj *rb);
Modified: trunk/mapserver/mapsymbol.c
===================================================================
--- trunk/mapserver/mapsymbol.c 2011-12-03 11:43:00 UTC (rev 12840)
+++ trunk/mapserver/mapsymbol.c 2011-12-04 13:48:20 UTC (rev 12841)
@@ -68,8 +68,9 @@
*/
double msSymbolGetDefaultSize(symbolObj *s) {
double size;
+ unsigned int svg_width, svg_height;
- if(s == NULL)
+ if(s == NULL)
return 1;
switch(s->type) {
@@ -81,6 +82,15 @@
if(s->pixmap_buffer == NULL) return 1; /* FIXME */
size = (double)s->pixmap_buffer->height;
break;
+ case(MS_SYMBOL_SVG):
+ size = 1;
+#ifdef USE_SVG_CAIRO
+ assert(s->svg_cairo_surface != NULL);
+ if(s->svg_cairo_surface == NULL) return 1; //FIXME
+ svg_cairo_get_size(s->svg_cairo_surface, &svg_width, &svg_height);
+ size = (double)svg_height;
+#endif
+ break;
default: /* vector and ellipses, scalable */
size = s->sizey;
break;
@@ -116,6 +126,8 @@
s->anchorpoint_x = s->anchorpoint_y = 0.5;
s->svg_text = NULL;
+ s->svg_cairo_surface=NULL;
+
}
int msFreeSymbol(symbolObj *s) {
@@ -133,12 +145,20 @@
free(s->pixmap_buffer);
}
+#ifdef USE_SVG_CAIRO
+ if(s->svg_cairo_surface)
+ svg_cairo_destroy(s->svg_cairo_surface);
+#endif
+
if(s->font) free(s->font);
msFree(s->full_font_path);
msFree(s->full_pixmap_path);
if(s->imagepath) free(s->imagepath);
if(s->character) free(s->character);
+ if (s->svg_text)
+ msFree(s->svg_text);
+
return MS_SUCCESS;
}
@@ -223,6 +243,7 @@
free(s->svg_text);
return -1;
}
+ s->svg_text[file_len-1]= '\0';
fclose(stream);
break;
}
Modified: trunk/mapserver/mapsymbol.h
===================================================================
--- trunk/mapserver/mapsymbol.h 2011-12-03 11:43:00 UTC (rev 12840)
+++ trunk/mapserver/mapsymbol.h 2011-12-04 13:48:20 UTC (rev 12841)
@@ -78,6 +78,9 @@
typedef struct {
int type;
unsigned int width,height;
+#ifdef USE_SVG_CAIRO
+ double scale, rotation;
+#endif
union {
rgbaArrayObj rgba;
paletteArrayObj palette;
@@ -189,6 +192,7 @@
void *renderer_cache;
char *full_font_path;
char *full_pixmap_path;
+ void *svg_cairo_surface;
#endif /* SWIG */
#ifdef SWIG
More information about the mapserver-commits
mailing list