[mapserver-commits] r9941 - branches/branch-5-6/mapserver
svn at osgeo.org
svn at osgeo.org
Mon Mar 15 10:36:46 EDT 2010
Author: assefa
Date: 2010-03-15 10:36:43 -0400 (Mon, 15 Mar 2010)
New Revision: 9941
Modified:
branches/branch-5-6/mapserver/HISTORY.TXT
branches/branch-5-6/mapserver/mapsvg.c
Log:
Support wrap character for SVG output (#3367)
Modified: branches/branch-5-6/mapserver/HISTORY.TXT
===================================================================
--- branches/branch-5-6/mapserver/HISTORY.TXT 2010-03-12 16:54:49 UTC (rev 9940)
+++ branches/branch-5-6/mapserver/HISTORY.TXT 2010-03-15 14:36:43 UTC (rev 9941)
@@ -15,6 +15,8 @@
Current Version (SVN branch-5-6):
--------------------------------
+- Support wrap character for SVG output (#3367)
+
- Fixed msMSSQL2008CloseConnection() to free the statement handle
properly (#3244)
Modified: branches/branch-5-6/mapserver/mapsvg.c
===================================================================
--- branches/branch-5-6/mapserver/mapsvg.c 2010-03-12 16:54:49 UTC (rev 9940)
+++ branches/branch-5-6/mapserver/mapsvg.c 2010-03-15 14:36:43 UTC (rev 9941)
@@ -36,6 +36,7 @@
#include "zlib.h"
#endif
#include "mapserver.h"
+#include "mapcopy.h"
MS_CVSID("$Id$")
@@ -911,6 +912,8 @@
char szTmp[100];
/* char *next; */
/* int len, i, ch; */
+ int nTokens = 0, i=0;
+ char **tokens = NULL;
pszFontStyleString = msStringConcatenate(pszFontStyleString, "");
pszFontWeightString = msStringConcatenate(pszFontWeightString, "");
@@ -957,52 +960,40 @@
pszAngleString = msStringConcatenate(pszAngleString, szTmp);
}
+ /*anchor positions are alreay taken into account when calculationg the
+ label position. Do not write them here*/
/* anchor point */
- if (nAnchorPosition == MS_UL || nAnchorPosition == MS_CL ||
- nAnchorPosition == MS_LL)
- {
- sprintf(szTmp, " text-anchor=\"end\"");
- pszAngleAnchorString = msStringConcatenate(pszAngleAnchorString, szTmp);
- }
- else if (nAnchorPosition == MS_UC || nAnchorPosition == MS_CC ||
- nAnchorPosition == MS_LC)
- {
- sprintf(szTmp, " text-anchor=\"middle\"");
- pszAngleAnchorString = msStringConcatenate(pszAngleAnchorString, szTmp);
- }
- else if (nAnchorPosition == MS_UR || nAnchorPosition == MS_CR ||
- nAnchorPosition == MS_LR)
- {
- sprintf(szTmp, " text-anchor=\"start\"");
- pszAngleAnchorString = msStringConcatenate(pszAngleAnchorString, szTmp);
- }
+
-/* if (bEncoding)
+ pszFinalString = string;
+
+ /*check for line breaks and produce multi lines if needed*/
+ nTokens = 0;
+ tokens = msStringSplit(pszFinalString, '\n', &nTokens);
+ if (tokens && nTokens > 1)
{
- pszTmpStr = msStringConcatenate(pszTmpStr, string);
- next = pszTmpStr;
- for (i=0; *next; i++)
+ /*+1 postion the text better. More inline with what we see froma raster(agg) output*/
+ msIO_fprintfgz(fp, bCompressed,"<text x=\"%d\" y=\"%d\" font-family=\"%s\" font-size=\"%dpt\"%s%s%s%s%s>\n",
+ x, (y-((int)(size+1))), pszFontFamilily, (int)size,
+ pszFontStyleString, pszFontWeightString,
+ pszFillString, pszStrokeString, pszAngleString);
+ for (i=0; i<nTokens; i++)
{
- ch = *next;
-
-
- len = gdTcl_UtfToUniChar (next, &ch);
- next += len;
-
- sprintf(szTmp, "&#x%x;",ch);
- pszFinalString = msStringConcatenate(pszFinalString, szTmp);
- }
+ msIO_fprintfgz(fp, bCompressed,"<tspan x=\"%d\" dy=\"%dpt\">%s</tspan>\n",x,(int)size,tokens[i]);
+ }
+ msIO_fprintfgz(fp, bCompressed, "</text>\n");
}
- else*/
- pszFinalString = string;
+ else
+ /* TODO : font size set to unit pt */
+ msIO_fprintfgz(fp, bCompressed,"<text x=\"%d\" y=\"%d\" font-family=\"%s\" font-size=\"%dpt\"%s%s%s%s%s>%s</text>\n" ,
+ x, y, pszFontFamilily, (int)size,
+ pszFontStyleString, pszFontWeightString,
+ pszFillString, pszStrokeString, pszAngleString,
+ pszFinalString);
- /* TODO : font size set to unit pt */
- msIO_fprintfgz(fp, bCompressed,"<text x=\"%d\" y=\"%d\" font-family=\"%s\" font-size=\"%dpt\"%s%s%s%s%s%s>%s</text>\n",
- x, y, pszFontFamilily, (int)size,
- pszFontStyleString, pszFontWeightString,
- pszFillString, pszStrokeString, pszAngleString,
- pszAngleAnchorString, pszFinalString);
-
+
+ if (tokens && nTokens > 0)
+ msFreeCharArray(tokens, nTokens);
if (pszFontStyleString)
msFree(pszFontStyleString);
if (pszFontWeightString)
@@ -1167,13 +1158,17 @@
int msDrawLabelCacheSVG(imageObj *image, mapObj *map)
{
pointObj p;
- int i, j, l, priority;
+ int i, l, priority;
rectObj r;
labelCacheMemberObj *cachePtr=NULL;
layerObj *layerPtr=NULL;
labelObj *labelPtr=NULL;
+ shapeObj billboard;
+ lineObj billboard_line;
+ pointObj billboard_points[5];
+
int marker_width, marker_height, label_offset_x, label_offset_y;
int marker_offset_x, marker_offset_y;
rectObj marker_rect;
@@ -1188,7 +1183,11 @@
if (!image || !map || !MS_DRIVER_SVG(image->format) )
return (0);
-
+ billboard.numlines = 1;
+ billboard.line = &billboard_line;
+ billboard.line->numpoints = 5;
+ billboard.line->point = billboard_points;
+
for(priority=MS_MAX_LABEL_PRIORITY-1; priority>=0; priority--) {
labelCacheSlotObj *cacheslot;
cacheslot = &(map->labelcache.slots[priority]);
@@ -1231,62 +1230,68 @@
}
if(labelPtr->position == MS_AUTO) {
+ int positions[MS_POSITIONS_LENGTH], npositions=0;
- if(layerPtr->type == MS_LAYER_LINE) {
- int position = MS_UC;
+ /*
+ ** If the ANNOTATION has an associated marker then the position is handled like a point regardless of underlying shape type. (#2993)
+ ** (Note: might be able to re-order this for more speed.)
+ */
+ if(layerPtr->type == MS_LAYER_POLYGON || (layerPtr->type == MS_LAYER_ANNOTATION && cachePtr->shapetype == MS_SHAPE_POLYGON && cachePtr->numstyles == 0)) {
+ positions[0]=MS_CC; positions[1]=MS_UC; positions[2]=MS_LC; positions[3]=MS_CL; positions[4]=MS_CR;
+ npositions = 5;
+ } else if(layerPtr->type == MS_LAYER_LINE || (layerPtr->type == MS_LAYER_ANNOTATION && cachePtr->shapetype == MS_SHAPE_LINE && cachePtr->numstyles == 0)) {
+ positions[0]=MS_UC; positions[1]=MS_LC; positions[2]=MS_CC;
+ npositions = 3;
+ } else {
+ positions[0]=MS_UL; positions[1]=MS_LR; positions[2]=MS_UR; positions[3]=MS_LL; positions[4]=MS_CR; positions[5]=MS_CL; positions[6]=MS_UC; positions[7]=MS_LC;
+ npositions = 8;
+ }
- 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. */
+ for(i=0; i<npositions; i++) {
+ msFreeShape(cachePtr->poly);
+ cachePtr->status = MS_TRUE; /* assume label *can* be drawn */
- msFreeShape(cachePtr->poly);
- cachePtr->status = MS_TRUE; /* assume label *can* be drawn */
+ p = get_metrics(&(cachePtr->point), positions[i], r, (marker_offset_x + label_offset_x), (marker_offset_y + label_offset_y), labelPtr->angle, label_buffer, cachePtr->poly);
+ if(layerPtr->type == MS_LAYER_ANNOTATION && cachePtr->numstyles > 0)
+ msRectToPolygon(marker_rect, cachePtr->poly); /* save marker bounding polygon */
- p = get_metrics(&(cachePtr->point), position, r, (marker_offset_x + label_offset_x), (marker_offset_y + label_offset_y), labelPtr->angle, label_buffer, cachePtr->poly);
+ /* Compare against image bounds, rendered labels and markers (sets cachePtr->status) */
+ msTestLabelCacheCollisions(&(map->labelcache), labelPtr, image->width, image->height, label_buffer, cachePtr, priority, l, label_mindistance, (r.maxx-r.minx));
- if(layerPtr->type == MS_LAYER_ANNOTATION && cachePtr->numstyles > 0)
- msRectToPolygon(marker_rect, cachePtr->poly); /* save marker bounding polygon */
+ if(cachePtr->status) /* found a suitable place for this label */ {
+ if(MS_VALID_COLOR(labelPtr->backgroundcolor))
+ get_metrics_line(&(cachePtr->point), positions[i], r, (marker_offset_x + label_offset_x), (marker_offset_y + label_offset_y), labelPtr->angle, 1, billboard.line);
+ break; /* ...out of position loop */
+ }
- /* Compare against image bounds, rendered labels and markers (sets cachePtr->status) */
- msTestLabelCacheCollisions(&(map->labelcache), labelPtr,
- map->width, map->height,
- label_buffer, cachePtr, priority, l, label_mindistance, (r.maxx-r.minx));
+ } /* next position */
+ if(labelPtr->force) {
- if(cachePtr->status) /* found a suitable place for this label */
- break;
+ /*billboard wasn't initialized if no non-coliding position was found*/
+ if(!cachePtr->status && MS_VALID_COLOR(labelPtr->backgroundcolor))
+ get_metrics_line(&(cachePtr->point), positions[npositions-1], r,
+ (marker_offset_x + label_offset_x),
+ (marker_offset_y + label_offset_y),
+ labelPtr->angle, 1, billboard.line);
- } /* next angle */
+ cachePtr->status = MS_TRUE; /* draw in spite of collisions based on last position, need a *best* position */
+ }
- } 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 + label_offset_x), (marker_offset_y + label_offset_y), labelPtr->angle, label_buffer, cachePtr->poly);
-
- if(layerPtr->type == MS_LAYER_ANNOTATION && cachePtr->numstyles > 0)
- 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,
- label_buffer, cachePtr, priority, l, label_mindistance, (r.maxx-r.minx));
-
- 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 {
+ } else {
cachePtr->status = MS_TRUE; /* assume label *can* be drawn */
- if(labelPtr->position == MS_CC) /* don't need the marker_offset */
+ if(labelPtr->position == MS_CC) { /* don't need the marker_offset */
p = get_metrics(&(cachePtr->point), labelPtr->position, r, label_offset_x, label_offset_y, labelPtr->angle, label_buffer, cachePtr->poly);
- else
+ if(MS_VALID_COLOR(labelPtr->backgroundcolor))
+ get_metrics_line(&(cachePtr->point), labelPtr->position, r, label_offset_x, label_offset_y, labelPtr->angle, 1, billboard.line);
+ }
+ else {
p = get_metrics(&(cachePtr->point), labelPtr->position, r, (marker_offset_x + label_offset_x), (marker_offset_y + label_offset_y), labelPtr->angle, label_buffer, cachePtr->poly);
-
+ if(MS_VALID_COLOR(labelPtr->backgroundcolor))
+ get_metrics_line(&(cachePtr->point), labelPtr->position, r, (marker_offset_x + label_offset_x), (marker_offset_y + label_offset_y), labelPtr->angle, 1, billboard.line);
+ }
+
if(layerPtr->type == MS_LAYER_ANNOTATION && cachePtr->numstyles > 0)
msRectToPolygon(marker_rect, cachePtr->poly); /* save marker bounding polygon, part of overlap tests */
@@ -1309,7 +1314,23 @@
msDrawMarkerSymbolSVG(&map->symbolset, image, &(cachePtr->point), &(cachePtr->styles[i]), layerPtr->scalefactor);
}
- /* background not supported */
+
+ /*draw the background, only if we're not using FOLLOW labels*/
+ if(!cachePtr->labelpath && MS_VALID_COLOR(labelPtr->backgroundcolor)) {
+ styleObj style;
+
+ initStyle(&style);
+ if(MS_VALID_COLOR(labelPtr->backgroundshadowcolor)) {
+ MS_COPYCOLOR(&(style.color),&(labelPtr->backgroundshadowcolor));
+ style.offsetx = labelPtr->backgroundshadowsizex*image->resolutionfactor;
+ style.offsety = labelPtr->backgroundshadowsizey*image->resolutionfactor;
+ msDrawShadeSymbol(&map->symbolset,image,&billboard,&style,1);
+ style.offsetx = 0;
+ style.offsety = 0;
+ }
+ MS_COPYCOLOR(&(style.color), &(labelPtr->backgroundcolor));
+ msDrawShadeSymbol(&map->symbolset, image, &billboard, &style, 1);
+ }
/* if(MS_VALID_COLOR(labelPtr->backgroundcolor)) billboardGD(img, cachePtr->poly, labelPtr); */
msDrawTextSVG(image, p, cachePtr->text, labelPtr, &(map->fontset), layerPtr->scalefactor); /* actually draw the label */
More information about the mapserver-commits
mailing list