[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