[mapserver-commits] r12878 - trunk/mapserver
svn at osgeo.org
svn at osgeo.org
Sat Dec 10 07:09:44 EST 2011
Author: tbonfort
Date: 2011-12-10 04:09:44 -0800 (Sat, 10 Dec 2011)
New Revision: 12878
Modified:
trunk/mapserver/HISTORY.TXT
trunk/mapserver/mapagg.cpp
trunk/mapserver/mapcairo.c
trunk/mapserver/mapdummyrenderer.c
trunk/mapserver/mapgd.c
trunk/mapserver/mapkml.cpp
trunk/mapserver/mapkmlrenderer.h
trunk/mapserver/maplabel.c
trunk/mapserver/mapogl.cpp
trunk/mapserver/mapoglrenderer.cpp
trunk/mapserver/mapoglrenderer.h
trunk/mapserver/maprendering.c
trunk/mapserver/mapserver.h
trunk/mapserver/mapsymbol.c
trunk/mapserver/maputil.c
Log:
add RFC80 font fallback
Modified: trunk/mapserver/HISTORY.TXT
===================================================================
--- trunk/mapserver/HISTORY.TXT 2011-12-10 09:29:20 UTC (rev 12877)
+++ trunk/mapserver/HISTORY.TXT 2011-12-10 12:09:44 UTC (rev 12878)
@@ -14,6 +14,7 @@
Current Version (SVN trunk, 6.1-dev, future 6.2):
-------------------------------------------------
+- Add RFC80 font fallback support (#4114)
- Added POLAROFFSET style option for a different symbol transform (#4117)
Modified: trunk/mapserver/mapagg.cpp
===================================================================
--- trunk/mapserver/mapagg.cpp 2011-12-10 09:29:20 UTC (rev 12877)
+++ trunk/mapserver/mapagg.cpp 2011-12-10 12:09:44 UTC (rev 12878)
@@ -286,12 +286,13 @@
int agg2RenderGlyphs(imageObj *img, double x, double y, labelStyleObj *style, char *text) {
AGG2Renderer *r = AGG_RENDERER(img);
aggRendererCache *cache = (aggRendererCache*)MS_RENDERER_CACHE(MS_IMAGE_RENDERER(img));
- if (!cache->m_feng.load_font(style->font, 0, mapserver::glyph_ren_outline)) {
- msSetError(MS_TTFERR, "AGG error loading font (%s)", "agg2RenderGlyphs()", style->font);
+ if (!cache->m_feng.load_font(style->fonts[0], 0, mapserver::glyph_ren_outline)) {
+ msSetError(MS_TTFERR, "AGG error loading font (%s)", "agg2RenderGlyphs()", style->fonts[0]);
return MS_FAILURE;
}
r->m_rasterizer_aa.filling_rule(mapserver::fill_non_zero);
+ int curfontidx = 0;
const mapserver::glyph_cache* glyph;
int unicode;
//cache->m_feng.hinting(true);
@@ -323,11 +324,38 @@
continue;
}
utfptr += msUTF8ToUniChar(utfptr, &unicode);
+ if(curfontidx != 0) {
+ if (!cache->m_feng.load_font(style->fonts[0], 0, mapserver::glyph_ren_outline)) {
+ msSetError(MS_TTFERR, "AGG error loading font (%s)", "agg2RenderGlyphs()", style->fonts[0]);
+ return MS_FAILURE;
+ }
+ curfontidx = 0;
+ }
+
glyph = cache->m_fman.glyph(unicode);
- ;
+
+ if(!glyph || glyph->glyph_index == 0) {
+ int i;
+ for(i=1;i<style->numfonts;i++) {
+ if (!cache->m_feng.load_font(style->fonts[i], 0, mapserver::glyph_ren_outline)) {
+ msSetError(MS_TTFERR, "AGG error loading font (%s)", "agg2RenderGlyphs()", style->fonts[i]);
+ return MS_FAILURE;
+ }
+ curfontidx = i;
+ cache->m_feng.height(style->size);
+ cache->m_feng.resolution(96);
+ cache->m_feng.flip_y(true);
+ glyph = cache->m_fman.glyph(unicode);
+ if(glyph && glyph->glyph_index != 0) {
+ break;
+ }
+ }
+ }
+
+
if (glyph) {
//cache->m_fman.add_kerning(&fx, &fy);
- cache->m_fman.init_embedded_adaptors(glyph, fx, fy);
+ cache->m_fman.init_embedded_adaptors(glyph, fx, fy);
mapserver::conv_transform<font_curve_type, mapserver::trans_affine> trans_c(m_curves, mtx);
glyphs.concat_path(trans_c);
fx += glyph->advance_x;
@@ -410,14 +438,15 @@
int agg2RenderGlyphsLine(imageObj *img, labelPathObj *labelpath, labelStyleObj *style, char *text) {
AGG2Renderer *r = AGG_RENDERER(img);
aggRendererCache *cache = (aggRendererCache*)MS_RENDERER_CACHE(MS_IMAGE_RENDERER(img));
- if (!cache->m_feng.load_font(style->font, 0, mapserver::glyph_ren_outline)) {
- msSetError(MS_TTFERR, "AGG error loading font (%s)", "agg2RenderGlyphs()", style->font);
+ if (!cache->m_feng.load_font(style->fonts[0], 0, mapserver::glyph_ren_outline)) {
+ msSetError(MS_TTFERR, "AGG error loading font (%s)", "agg2RenderGlyphsLine()", style->fonts[0]);
return MS_FAILURE;
}
r->m_rasterizer_aa.filling_rule(mapserver::fill_non_zero);
const mapserver::glyph_cache* glyph;
int unicode;
+ int curfontidx = 0;
//cache->m_feng.hinting(true);
cache->m_feng.height(style->size);
cache->m_feng.resolution(96);
@@ -433,7 +462,34 @@
mtx *= mapserver::trans_affine_rotation(-labelpath->angles[i]);
mtx *= mapserver::trans_affine_translation(labelpath->path.point[i].x,labelpath->path.point[i].y);
text += msUTF8ToUniChar(text, &unicode);
+
+ if(curfontidx != 0) {
+ if (!cache->m_feng.load_font(style->fonts[0], 0, mapserver::glyph_ren_outline)) {
+ msSetError(MS_TTFERR, "AGG error loading font (%s)", "agg2RenderGlyphsLine()", style->fonts[0]);
+ return MS_FAILURE;
+ }
+ curfontidx = 0;
+ }
+
glyph = cache->m_fman.glyph(unicode);
+
+ if(!glyph || glyph->glyph_index == 0) {
+ int i;
+ for(i=1;i<style->numfonts;i++) {
+ if (!cache->m_feng.load_font(style->fonts[i], 0, mapserver::glyph_ren_outline)) {
+ msSetError(MS_TTFERR, "AGG error loading font (%s)", "agg2RenderGlyphsLine()", style->fonts[i]);
+ return MS_FAILURE;
+ }
+ curfontidx = i;
+ cache->m_feng.height(style->size);
+ cache->m_feng.resolution(96);
+ cache->m_feng.flip_y(true);
+ glyph = cache->m_fman.glyph(unicode);
+ if(glyph && glyph->glyph_index != 0) {
+ break;
+ }
+ }
+ }
if (glyph) {
cache->m_fman.init_embedded_adaptors(glyph, labelpath->path.point[i].x,labelpath->path.point[i].y);
mapserver::conv_transform<font_curve_type, mapserver::trans_affine> trans_c(m_curves, mtx);
@@ -793,25 +849,55 @@
/*...*/
/* helper functions */
-int agg2GetTruetypeTextBBox(rendererVTableObj *renderer, char *font, double size, char *string,
+int agg2GetTruetypeTextBBox(rendererVTableObj *renderer, char **fonts, int numfonts, double size, char *string,
rectObj *rect, double **advances) {
aggRendererCache *cache = (aggRendererCache*)MS_RENDERER_CACHE(renderer);
- if (!cache->m_feng.load_font(font, 0, mapserver::glyph_ren_outline)) {
- msSetError(MS_TTFERR, "AGG error loading font (%s)", "agg2GetTruetypeTextBBox()", font);
+ if (!cache->m_feng.load_font(fonts[0], 0, mapserver::glyph_ren_outline)) {
+ msSetError(MS_TTFERR, "AGG error loading font (%s)", "agg2GetTruetypeTextBBox()", fonts[0]);
return MS_FAILURE;
}
cache->m_feng.hinting(true);
cache->m_feng.height(size);
cache->m_feng.resolution(96);
cache->m_feng.flip_y(true);
+ int curfontidx = 0;
+
int unicode, curGlyph = 1, numglyphs = 0;
if (advances) {
numglyphs = msGetNumGlyphs(string);
}
const mapserver::glyph_cache* glyph;
string += msUTF8ToUniChar(string, &unicode);
+
+ if(curfontidx != 0) {
+ if (!cache->m_feng.load_font(fonts[0], 0, mapserver::glyph_ren_outline)) {
+ msSetError(MS_TTFERR, "AGG error loading font (%s)", "agg2RenderGlyphs()", fonts[0]);
+ return MS_FAILURE;
+ }
+ cache->m_feng.height(size);
+ cache->m_feng.resolution(96);
+ cache->m_feng.flip_y(true);
+ curfontidx = 0;
+ }
glyph = cache->m_fman.glyph(unicode);
+ if(!glyph || glyph->glyph_index == 0) {
+ int i;
+ for(i=1;i<numfonts;i++) {
+ if (!cache->m_feng.load_font(fonts[i], 0, mapserver::glyph_ren_outline)) {
+ msSetError(MS_TTFERR, "AGG error loading font (%s)", "agg2RenderGlyphs()", fonts[i]);
+ return MS_FAILURE;
+ }
+ curfontidx = i;
+ cache->m_feng.height(size);
+ cache->m_feng.resolution(96);
+ cache->m_feng.flip_y(true);
+ glyph = cache->m_fman.glyph(unicode);
+ if(glyph && glyph->glyph_index != 0) {
+ break;
+ }
+ }
+ }
if (glyph) {
rect->minx = glyph->bounds.x1;
rect->maxx = glyph->bounds.x2;
@@ -842,7 +928,34 @@
continue;
}
string += msUTF8ToUniChar(string, &unicode);
+ if(curfontidx != 0) {
+ if (!cache->m_feng.load_font(fonts[0], 0, mapserver::glyph_ren_outline)) {
+ msSetError(MS_TTFERR, "AGG error loading font (%s)", "agg2RenderGlyphs()", fonts[0]);
+ return MS_FAILURE;
+ }
+ cache->m_feng.height(size);
+ cache->m_feng.resolution(96);
+ cache->m_feng.flip_y(true);
+ curfontidx = 0;
+ }
glyph = cache->m_fman.glyph(unicode);
+ if(!glyph || glyph->glyph_index == 0) {
+ int i;
+ for(i=1;i<numfonts;i++) {
+ if (!cache->m_feng.load_font(fonts[i], 0, mapserver::glyph_ren_outline)) {
+ msSetError(MS_TTFERR, "AGG error loading font (%s)", "agg2RenderGlyphs()", fonts[i]);
+ return MS_FAILURE;
+ }
+ curfontidx = i;
+ cache->m_feng.height(size);
+ cache->m_feng.resolution(96);
+ cache->m_feng.flip_y(true);
+ glyph = cache->m_fman.glyph(unicode);
+ if(glyph && glyph->glyph_index != 0) {
+ break;
+ }
+ }
+ }
if (glyph) {
rect->minx = MS_MIN(rect->minx, fx+glyph->bounds.x1);
rect->miny = MS_MIN(rect->miny, fy+glyph->bounds.y1);
Modified: trunk/mapserver/mapcairo.c
===================================================================
--- trunk/mapserver/mapcairo.c 2011-12-10 09:29:20 UTC (rev 12877)
+++ trunk/mapserver/mapcairo.c 2011-12-10 12:09:44 UTC (rev 12878)
@@ -64,8 +64,9 @@
};
int freeFaceCache(faceCacheObj *fc) {
- /* printf("***\nface has %d references\n***\n",cairo_font_face_get_reference_count(fc->face)); */
+ /* printf("***\nface %s has %d cairo references\n***\n",fc->path,cairo_font_face_get_reference_count(fc->face)); */
cairo_font_face_destroy(fc->face);
+ FT_Done_Face(fc->ftface);
free(fc->path);
return MS_SUCCESS;
}
@@ -166,7 +167,7 @@
newface->face = cairo_ft_font_face_create_for_ft_face(newface->ftface, 0);
cairo_font_face_set_user_data (newface->face, &newface->facekey,
- &(newface->ftface), (cairo_destroy_func_t) FT_Done_Face);
+ &(newface->ftface), (cairo_destroy_func_t) NULL); // we call FT_Done_Face ourselves in freeFaceCache
newface->path = msStrdup(font);
return newface;
@@ -450,29 +451,27 @@
#define CAIROLINESPACE 1.33
-int getTruetypeTextBBoxCairo(rendererVTableObj *renderer, char *font, double size, char *text, rectObj *rect, double **advances) {
-
-
+int getTruetypeTextBBoxCairo(rendererVTableObj *renderer, char **fonts, int numfonts, double size, char *text, rectObj *rect, double **advances) {
cairoCacheData *cache = MS_RENDERER_CACHE(renderer);
- faceCacheObj *face = getFontFace(cache,font);
+ faceCacheObj* face = getFontFace(cache,fonts[0]);
+ int curfontidx = 0;
char *utfptr=text;
- int i,has_kerning,unicode;
+ int i,unicode;
unsigned long previdx=0;
+ faceCacheObj* prevface = face;
int numglyphs = msGetNumGlyphs(text);
cairo_glyph_t glyph;
cairo_text_extents_t extents;
double px=0,py=0;
-
+
if(face == NULL) {
- return MS_FAILURE;
+ return MS_FAILURE;
}
cairo_set_font_face(cache->dummycr,face->face);
cairo_set_font_size(cache->dummycr,size*96/72.0);
- has_kerning = FT_HAS_KERNING((face->ftface));
-
if(advances != NULL) {
*advances = (double*)malloc(numglyphs*sizeof(double));
}
@@ -487,10 +486,31 @@
previdx=0;
continue;
}
+
+ if(curfontidx != 0) {
+ face = getFontFace(cache,fonts[0]);
+ cairo_set_font_face(cache->dummycr,face->face);
+ curfontidx = 0;
+ }
+
glyph.index = FT_Get_Char_Index(face->ftface, unicode);
- if( has_kerning && previdx ) {
+
+ if(glyph.index == 0) {
+ int j;
+ for(j=1;j<numfonts;j++) {
+ curfontidx = j;
+ face = getFontFace(cache,fonts[j]);
+ glyph.index = FT_Get_Char_Index(face->ftface, unicode);
+ if(glyph.index != 0) {
+ cairo_set_font_face(cache->dummycr,face->face);
+ break;
+ }
+ }
+ }
+
+ if( FT_HAS_KERNING((prevface->ftface)) && previdx ) {
FT_Vector delta;
- FT_Get_Kerning( face->ftface, previdx, glyph.index, FT_KERNING_DEFAULT, &delta );
+ FT_Get_Kerning( prevface->ftface, previdx, glyph.index, FT_KERNING_DEFAULT, &delta );
px += delta.x / 64.;
}
cairo_glyph_extents(cache->dummycr,&glyph,1,&extents);
@@ -510,6 +530,7 @@
(*advances)[i]=extents.x_advance;
px += extents.x_advance;
previdx=glyph.index;
+ prevface = face;
}
/*
rect->minx = 0;
@@ -523,18 +544,20 @@
int renderGlyphsCairo(imageObj *img,double x, double y, labelStyleObj *style, char *text) {
cairo_renderer *r = CAIRO_RENDERER(img);
cairoCacheData *cache = MS_IMAGE_RENDERER_CACHE(img);
- faceCacheObj *face = getFontFace(cache,style->font);
+ faceCacheObj* face = getFontFace(cache,style->fonts[0]);
+ int curfontidx = 0;
char *utfptr=text;
- int i,has_kerning,unicode;
+ int i,unicode;
unsigned long previdx=0;
+ faceCacheObj* prevface = face;
int numglyphs = msGetNumGlyphs(text);
cairo_glyph_t glyph;
cairo_text_extents_t extents;
double px=0,py=0;
if(face == NULL) {
- return MS_FAILURE;
+ return MS_FAILURE;
}
cairo_set_font_face(r->cr,face->face);
@@ -545,7 +568,6 @@
if(style->rotation != 0.0)
cairo_rotate(r->cr, -style->rotation);
- has_kerning = FT_HAS_KERNING((face->ftface));
for(i=0;i<numglyphs;i++) {
utfptr+=msUTF8ToUniChar(utfptr, &unicode);
glyph.x=px;
@@ -556,16 +578,35 @@
previdx=0;
continue;
}
+ if(curfontidx != 0) {
+ face = getFontFace(cache,style->fonts[0]);
+ cairo_set_font_face(r->cr,face->face);
+ curfontidx = 0;
+ }
glyph.index = FT_Get_Char_Index(face->ftface, unicode);
- if( has_kerning && previdx ) {
+ if(glyph.index == 0) {
+ int j;
+ for(j=1;j<style->numfonts;j++) {
+ curfontidx = j;
+ face = getFontFace(cache,style->fonts[j]);
+ glyph.index = FT_Get_Char_Index(face->ftface, unicode);
+ if(glyph.index != 0) {
+ cairo_set_font_face(r->cr,face->face);
+ break;
+ }
+ }
+ }
+
+ if( FT_HAS_KERNING((prevface->ftface)) && previdx ) {
FT_Vector delta;
- FT_Get_Kerning( face->ftface, previdx, glyph.index, FT_KERNING_DEFAULT, &delta );
+ FT_Get_Kerning( prevface->ftface, previdx, glyph.index, FT_KERNING_DEFAULT, &delta );
px += delta.x / 64.;
}
cairo_glyph_extents(r->cr,&glyph,1,&extents);
cairo_glyph_path(r->cr,&glyph,1);
px += extents.x_advance;
previdx=glyph.index;
+ prevface=face;
}
if (style->outlinewidth > 0) {
Modified: trunk/mapserver/mapdummyrenderer.c
===================================================================
--- trunk/mapserver/mapdummyrenderer.c 2011-12-10 09:29:20 UTC (rev 12877)
+++ trunk/mapserver/mapdummyrenderer.c 2011-12-10 12:09:44 UTC (rev 12878)
@@ -166,7 +166,7 @@
/*...*/
/* helper functions */
-int getTruetypeTextBBoxDummy(rendererVTableObj *renderer, char *font, double size, char *string,rectObj *rect, double **advances) {
+int getTruetypeTextBBoxDummy(rendererVTableObj *renderer, char **fonts, int numfonts, double size, char *string,rectObj *rect, double **advances) {
msSetError(MS_RENDERERERR,"getTruetypeTextBBox not implemented","getTruetypeTextBBox()");
return MS_FAILURE;
}
Modified: trunk/mapserver/mapgd.c
===================================================================
--- trunk/mapserver/mapgd.c 2011-12-10 09:29:20 UTC (rev 12877)
+++ trunk/mapserver/mapgd.c 2011-12-10 12:09:44 UTC (rev 12878)
@@ -411,23 +411,23 @@
}
if(style->outlinewidth > 0) { /* handle the outline color */
- error = gdImageStringFT(ip, bbox, oc, style->font, style->size, style->rotation, x, y-1, text);
+ error = gdImageStringFT(ip, bbox, oc, style->fonts[0], style->size, style->rotation, x, y-1, text);
if(error) {
msSetError(MS_TTFERR, error, "msDrawTextGD()");
return(MS_FAILURE);
}
- gdImageStringFT(ip, bbox, oc, style->font, style->size, style->rotation, x, y+1, text);
- gdImageStringFT(ip, bbox, oc, style->font, style->size, style->rotation, x+1, y, text);
- gdImageStringFT(ip, bbox, oc, style->font, style->size, style->rotation, x-1, y, text);
- gdImageStringFT(ip, bbox, oc, style->font, style->size, style->rotation, x-1, y-1, text);
- gdImageStringFT(ip, bbox, oc, style->font, style->size, style->rotation, x-1, y+1, text);
- gdImageStringFT(ip, bbox, oc, style->font, style->size, style->rotation, x+1, y-1, text);
- gdImageStringFT(ip, bbox, oc, style->font, style->size, style->rotation, x+1, y+1, text);
+ gdImageStringFT(ip, bbox, oc, style->fonts[0], style->size, style->rotation, x, y+1, text);
+ gdImageStringFT(ip, bbox, oc, style->fonts[0], style->size, style->rotation, x+1, y, text);
+ gdImageStringFT(ip, bbox, oc, style->fonts[0], style->size, style->rotation, x-1, y, text);
+ gdImageStringFT(ip, bbox, oc, style->fonts[0], style->size, style->rotation, x-1, y-1, text);
+ gdImageStringFT(ip, bbox, oc, style->fonts[0], style->size, style->rotation, x-1, y+1, text);
+ gdImageStringFT(ip, bbox, oc, style->fonts[0], style->size, style->rotation, x+1, y-1, text);
+ gdImageStringFT(ip, bbox, oc, style->fonts[0], style->size, style->rotation, x+1, y+1, text);
}
if(style->color)
- gdImageStringFT(ip, bbox, c, style->font, style->size, style->rotation, x, y, text);
+ gdImageStringFT(ip, bbox, c, style->fonts[0], style->size, style->rotation, x, y, text);
return MS_SUCCESS;
}
@@ -833,7 +833,7 @@
return MS_SUCCESS;
}
-int getTruetypeTextBBoxGD(rendererVTableObj *renderer, char *font, double size, char *string, rectObj *rect, double **advances) {
+int getTruetypeTextBBoxGD(rendererVTableObj *renderer, char **fonts, int numfonts, double size, char *string, rectObj *rect, double **advances) {
#ifdef USE_GD_FT
int bbox[8];
char *error;
@@ -843,7 +843,7 @@
int k;
gdFTStringExtra strex;
strex.flags = gdFTEX_XSHOW;
- error = gdImageStringFTEx(NULL, bbox, 0, font, size, 0, 0, 0, string, &strex);
+ error = gdImageStringFTEx(NULL, bbox, 0, fonts[0], size, 0, 0, 0, string, &strex);
if(error) {
msSetError(MS_TTFERR, error, "gdImageStringFTEx()");
return(MS_FAILURE);
@@ -873,7 +873,7 @@
return(MS_FAILURE);
#endif
} else {
- error = gdImageStringFT(NULL, bbox, 0, font, size, 0, 0, 0, string);
+ error = gdImageStringFT(NULL, bbox, 0, fonts[0], size, 0, 0, 0, string);
if(error) {
msSetError(MS_TTFERR, error, "msGetTruetypeTextBBox()");
return(MS_FAILURE);
Modified: trunk/mapserver/mapkml.cpp
===================================================================
--- trunk/mapserver/mapkml.cpp 2011-12-10 09:29:20 UTC (rev 12877)
+++ trunk/mapserver/mapkml.cpp 2011-12-10 12:09:44 UTC (rev 12878)
@@ -138,7 +138,7 @@
}
-int msGetTruetypeTextBBoxKml(rendererVTableObj *r,char *font, double size, char *string,
+int msGetTruetypeTextBBoxKml(rendererVTableObj *r,char** fonts, int numfonts, double size, char *string,
rectObj *rect, double **advances)
{
rect->minx=0.0;
Modified: trunk/mapserver/mapkmlrenderer.h
===================================================================
--- trunk/mapserver/mapkmlrenderer.h 2011-12-10 09:29:20 UTC (rev 12877)
+++ trunk/mapserver/mapkmlrenderer.h 2011-12-10 12:09:44 UTC (rev 12878)
@@ -167,7 +167,7 @@
void renderEllipseSymbol(imageObj *img, double x, double y, symbolObj *symbol, symbolStyleObj *style);
void renderTruetypeSymbol(imageObj *img, double x, double y, symbolObj *symbol, symbolStyleObj *style);
- int getTruetypeTextBBox(imageObj *img,char *font, double size, char *string, rectObj *rect, double **advances);
+ int getTruetypeTextBBox(imageObj *img,char **fonts, int numfonts, double size, char *string, rectObj *rect, double **advances);
int mergeRasterBuffer(imageObj *image, rasterBufferObj *rb);
};
Modified: trunk/mapserver/maplabel.c
===================================================================
--- trunk/mapserver/maplabel.c 2011-12-10 09:29:20 UTC (rev 12877)
+++ trunk/mapserver/maplabel.c 2011-12-10 12:09:44 UTC (rev 12878)
@@ -699,10 +699,14 @@
#endif
}
-int msGetTruetypeTextBBox(rendererVTableObj *renderer, char *font, double size, char *string, rectObj *rect, double **advances) {
- if(renderer) {
- return renderer->getTruetypeTextBBox(renderer,font,size,string,rect,advances);
- }
+int msGetTruetypeTextBBox(rendererVTableObj *renderer, char* fontstring, fontSetObj *fontset, double size, char *string, rectObj *rect, double **advances) {
+ const char *lookedUpFonts[MS_MAX_LABEL_FONTS];
+ int numfonts;
+ if(MS_FAILURE == msFontsetLookupFonts(fontstring, &numfonts, fontset, lookedUpFonts))
+ return MS_FAILURE;
+ if(renderer) {
+ return renderer->getTruetypeTextBBox(renderer,lookedUpFonts,numfonts,size,string,rect,advances);
+ }
#ifdef USE_GD_FT
else {
int bbox[8];
@@ -713,9 +717,9 @@
int k;
gdFTStringExtra strex;
strex.flags = gdFTEX_XSHOW;
- error = gdImageStringFTEx(NULL, bbox, 0, font, size, 0, 0, 0, string, &strex);
+ error = gdImageStringFTEx(NULL, bbox, 0, lookedUpFonts[0], size, 0, 0, 0, string, &strex);
if(error) {
- msSetError(MS_TTFERR, error, "gdImageStringFTEx()");
+ msSetError(MS_TTFERR, "gdImageStringFT: %s (%s)", "msGetTruetypeTextBBox()", error, lookedUpFonts[0]);
return(MS_FAILURE);
}
@@ -743,9 +747,9 @@
return MS_FAILURE;
#endif
} else {
- error = gdImageStringFT(NULL, bbox, 0, font, size, 0, 0, 0, string);
+ error = gdImageStringFT(NULL, bbox, 0, lookedUpFonts[0], size, 0, 0, 0, string);
if(error) {
- msSetError(MS_TTFERR, "gdImageStringFT: %s (%s)", "msGetTruetypeTextBBox()", error, font);
+ msSetError(MS_TTFERR, "gdImageStringFT: %s (%s)", "msGetTruetypeTextBBox()", error, lookedUpFonts[0]);
return(MS_FAILURE);
}
@@ -808,6 +812,47 @@
}
return font;
}
+
+int msFontsetLookupFonts(char* fontstring, int *numfonts, fontSetObj *fontset, const char **lookedUpFonts) {
+ char *start,*ptr;
+ *numfonts = 0;
+ start = ptr = fontstring;
+ while(*numfonts<MS_MAX_LABEL_FONTS) {
+ if(*ptr==',') {
+ if(start==ptr) { /*first char is a comma, or two successive commas*/
+ start = ++ptr;
+ continue;
+ }
+ *ptr = 0;
+ lookedUpFonts[*numfonts] = msLookupHashTable(&(fontset->fonts), start);
+ *ptr = ',';
+ if (!lookedUpFonts[*numfonts]) {
+ msSetError(MS_TTFERR, "Requested font (%s) not found.","msFontsetLookupFonts()", fontstring);
+ return MS_FAILURE;
+ }
+ start = ++ptr;
+ (*numfonts)++;
+ } else if(*ptr==0) {
+ if(start==ptr) { /* last char of string was a comma */
+ return MS_SUCCESS;
+ }
+ lookedUpFonts[*numfonts] = msLookupHashTable(&(fontset->fonts), start);
+ if (!lookedUpFonts[*numfonts]) {
+ msSetError(MS_TTFERR, "Requested font (%s) not found.","msFontsetLookupFonts()", fontstring);
+ return (MS_FAILURE);
+ }
+ (*numfonts)++;
+ return MS_SUCCESS;
+ } else {
+ ptr++;
+ }
+ }
+ msSetError(MS_TTFERR, "Requested font (%s) not has too many members (max is %d)",
+ "msFontsetLookupFonts()", fontstring, MS_MAX_LABEL_FONTS);
+ return MS_FAILURE;
+}
+
+
/*
** Note: All these routines assume a reference point at the LL corner of the text. GD's
** bitmapped fonts use UL and this is compensated for. Note the rect is relative to the
@@ -825,12 +870,11 @@
if (!renderer)
return MS_FAILURE;
if(label->type == MS_TRUETYPE) {
- char *font=msFontsetLookupFont(&(map->fontset), label->font);
- if(!font) {
- /* error message already set in fontset lookup */
- return MS_FAILURE;
- }
- return msGetTruetypeTextBBox(renderer,font,size,string,rect,advances);
+ if(!label->font) {
+ msSetError(MS_MISCERR, "label has no true type font", "msGetLabelSize()");
+ return MS_FAILURE;
+ }
+ return msGetTruetypeTextBBox(renderer,label->font,&(map->fontset),size,string,rect,advances);
} else if(label->type == MS_BITMAP){
if(renderer->supports_bitmap_fonts)
return msGetRasterTextBBox(renderer,MS_NINT(label->size),string,rect);
Modified: trunk/mapserver/mapogl.cpp
===================================================================
--- trunk/mapserver/mapogl.cpp 2011-12-10 09:29:20 UTC (rev 12877)
+++ trunk/mapserver/mapogl.cpp 2011-12-10 12:09:44 UTC (rev 12878)
@@ -126,9 +126,9 @@
return MS_SUCCESS;
}
-int msGetTruetypeTextBBoxOgl(rendererVTableObj *renderer, char *font, double size, char *string, rectObj *rect, double **advances)
+int msGetTruetypeTextBBoxOgl(rendererVTableObj *renderer, char **fonts, int numfonts, double size, char *string, rectObj *rect, double **advances)
{
- if (OglRenderer::getStringBBox(font, size, string, rect, advances))
+ if (OglRenderer::getStringBBox(fonts[0], size, string, rect, advances))
{
return MS_SUCCESS;
}
@@ -142,7 +142,7 @@
labelStyleObj *style, char *text)
{
OglRenderer* renderer = getOglRenderer(img);
- renderer->renderGlyphs(x, y, style->color, style->outlinecolor, style->size, style->font, text, style->rotation, NULL, 0.0, 0.0);
+ renderer->renderGlyphs(x, y, style->color, style->outlinecolor, style->size, style->fonts[0], text, style->rotation, NULL, 0.0, 0.0);
return MS_SUCCESS;
}
Modified: trunk/mapserver/mapoglrenderer.cpp
===================================================================
--- trunk/mapserver/mapoglrenderer.cpp 2011-12-10 09:29:20 UTC (rev 12877)
+++ trunk/mapserver/mapoglrenderer.cpp 2011-12-10 12:09:44 UTC (rev 12878)
@@ -579,7 +579,7 @@
}
void OglRenderer::renderGlyphs(double x, double y, colorObj *color,
- colorObj *outlinecolor, double size, char* font, char *thechars, double angle,
+ colorObj *outlinecolor, double size, const char* font, char *thechars, double angle,
colorObj *shadowcolor, double shdx, double shdy)
{
makeCurrent();
@@ -734,7 +734,7 @@
return true;
}
-FTFont* OglRenderer::getFTFont(char* font, double size)
+FTFont* OglRenderer::getFTFont(const char* font, double size)
{
FTFont** face = &fontCache[font][size];
if (*face == NULL && ifstream(font))
Modified: trunk/mapserver/mapoglrenderer.h
===================================================================
--- trunk/mapserver/mapoglrenderer.h 2011-12-10 09:29:20 UTC (rev 12877)
+++ trunk/mapserver/mapoglrenderer.h 2011-12-10 12:09:44 UTC (rev 12878)
@@ -65,7 +65,7 @@
void renderPolyline(shapeObj *p, colorObj *c, double width, int patternlength, double* pattern, int lineCap = MS_CJC_ROUND, int joinStyle = MS_CJC_ROUND, colorObj *outlinecolor = NULL, double outlinewidth = 0);
void renderPolygon(shapeObj*, colorObj *color, colorObj *outlinecolor, double outlinewidth, const OglCachePtr& tile = OglCachePtr(), int lineCap=MS_CJC_ROUND, int joinStyle=MS_CJC_ROUND);
- void renderGlyphs(double x, double y, colorObj *color, colorObj *outlinecolor, double size, char* font, char *thechars, double angle, colorObj *shadowcolor, double shdx, double shdy);
+ void renderGlyphs(double x, double y, colorObj *color, colorObj *outlinecolor, double size, const char* font, char *thechars, double angle, colorObj *shadowcolor, double shdx, double shdy);
void renderPixmap(symbolObj *symbol, double x, double y, double angle, double scale);
void renderEllipse(double x, double y, double angle, double w, double h, colorObj *color, colorObj *outlinecolor, double outlinewidth);
void renderVectorSymbol(double x, double y, symbolObj *symbol, double scale, double angle, colorObj *c, colorObj *oc, double ow);
@@ -96,10 +96,10 @@
GLsizei viewportWidth;
GLsizei viewportHeight;
- typedef std::map<char*,std::map<double,FTFont*> > fontCache_t;
+ typedef std::map<const char*,std::map<double,FTFont*> > fontCache_t;
typedef std::map<symbolObj*,std::map<double,GLuint> > dashCache_t;
- static FTFont* getFTFont(char* font, double size);
+ static FTFont* getFTFont(const char* font, double size);
bool loadLine(shapeObj* shape, double width, int patternlength, double *pattern);
double drawQuad(pointObj *p1, pointObj *p2, double width, double tilelength = 0.0, double textureStart = 0.0);
double drawTriangles(pointObj *p1, pointObj *p2, double width, double tilelength = 0.0, double textureStart = 0.0);
Modified: trunk/mapserver/maprendering.c
===================================================================
--- trunk/mapserver/maprendering.c 2011-12-10 09:29:20 UTC (rev 12877)
+++ trunk/mapserver/maprendering.c 2011-12-10 12:09:44 UTC (rev 12878)
@@ -48,14 +48,12 @@
return (MS_FAILURE);
}
- if (!l->font) {
- msSetError(MS_TTFERR, "No Trueype font defined.","msDrawText()");
+ if (!l->font || !(*l->font)) {
return (MS_FAILURE);
}
- s->font = msLookupHashTable(&(fontset->fonts), l->font);
- if (!s->font) {
- return (MS_FAILURE);
+ if(MS_FAILURE == msFontsetLookupFonts(l->font,&s->numfonts,fontset,&s->fonts)) {
+ return MS_FAILURE;
}
}
s->rotation = l->angle * MS_DEG_TO_RAD;
@@ -325,7 +323,7 @@
symbol_height = MS_MAX(1,symbol->sizey*style->scale);
} else {
rectObj rect;
- if(MS_SUCCESS != renderer->getTruetypeTextBBox(renderer,symbol->full_font_path,style->scale,
+ if(MS_SUCCESS != renderer->getTruetypeTextBBox(renderer,&symbol->full_font_path,1,style->scale,
symbol->character,&rect,NULL))
return MS_FAILURE;
symbol_width=rect.maxx-rect.minx;
Modified: trunk/mapserver/mapserver.h
===================================================================
--- trunk/mapserver/mapserver.h 2011-12-10 09:29:20 UTC (rev 12877)
+++ trunk/mapserver/mapserver.h 2011-12-10 12:09:44 UTC (rev 12878)
@@ -228,6 +228,7 @@
#define MS_STYLE_ALLOCSIZE 4
#define MS_MAX_LABEL_PRIORITY 10
+#define MS_MAX_LABEL_FONTS 5
#define MS_DEFAULT_LABEL_PRIORITY 1
/* General defines, not wrapable */
@@ -1990,9 +1991,10 @@
MS_DLL_EXPORT int msInitFontSet(fontSetObj *fontset);
MS_DLL_EXPORT int msFreeFontSet(fontSetObj *fontset);
MS_DLL_EXPORT char *msFontsetLookupFont(fontSetObj *fontset, char *fontKey);
+MS_DLL_EXPORT int msFontsetLookupFonts(char* fontstring, int *numfonts, fontSetObj *fontset, const char **lookedUpFonts);
MS_DLL_EXPORT char *msTransformLabelText(mapObj *map, imageObj* image, labelObj *label, char *text);
-MS_DLL_EXPORT int msGetTruetypeTextBBox(rendererVTableObj *renderer, char *font, double size, char *string, rectObj *rect, double **advances);
+MS_DLL_EXPORT int msGetTruetypeTextBBox(rendererVTableObj *renderer, char* fontstring, fontSetObj *fontset, double size, char *string, rectObj *rect, double **advances);
MS_DLL_EXPORT int msGetLabelSize(mapObj *map, labelObj *label, char *string, double size, rectObj *rect, double **advances);
MS_DLL_EXPORT int msAddLabel(mapObj *map, int layerindex, int classindex, shapeObj *shape, pointObj *point, labelPathObj *labelpath, char *string, double featuresize, labelObj *label);
@@ -2615,7 +2617,8 @@
*/
typedef struct {
/* full path to truetype font file */
- char *font;
+ const char* fonts[MS_MAX_LABEL_FONTS];
+ int numfonts;
double size;
double rotation;
colorObj *color;
@@ -2624,7 +2627,7 @@
int antialias; /*only for GD*/
} labelStyleObj;
-#define INIT_LABEL_STYLE(s) {(s).font=NULL; (s).size=0; (s).rotation=0; (s).color=NULL; (s).outlinewidth=0; (s).outlinecolor=NULL;}
+#define INIT_LABEL_STYLE(s) {memset(&(s),'\0',sizeof(labelStyleObj));}
#ifndef SWIG
MS_DLL_EXPORT int msInitializeDummyRenderer(rendererVTableObj *vtable);
@@ -2749,7 +2752,7 @@
/*...*/
/* helper functions */
- int (*getTruetypeTextBBox)(rendererVTableObj *renderer, char *font, double size, char *string, rectObj *rect, double **advances);
+ int (*getTruetypeTextBBox)(rendererVTableObj *renderer, char **fonts, int numfonts, double size, char *string, rectObj *rect, double **advances);
int (*startLayer)(imageObj *img, mapObj *map, layerObj *layer);
int (*endLayer)(imageObj *img, mapObj *map, layerObj *layer);
Modified: trunk/mapserver/mapsymbol.c
===================================================================
--- trunk/mapserver/mapsymbol.c 2011-12-10 09:29:20 UTC (rev 12877)
+++ trunk/mapserver/mapsymbol.c 2011-12-10 12:09:44 UTC (rev 12878)
@@ -664,15 +664,7 @@
#ifdef USE_GD_FT
case(MS_SYMBOL_TRUETYPE):
- if(!symbol->full_font_path) {
- char *font = msLookupHashTable(&(symbolset->fontset->fonts),symbol->font);
- if(!font) {
- msSetError(MS_MISCERR,"font (%s) not found in fontset","msGetMarkerSize()",symbol->font);
- return(MS_FAILURE);
- }
- symbol->full_font_path = msStrdup(font);
- }
- if(msGetTruetypeTextBBox(MS_MAP_RENDERER(symbolset->map),symbol->full_font_path,size,symbol->character,&rect,NULL) != MS_SUCCESS)
+ if(msGetTruetypeTextBBox(MS_MAP_RENDERER(symbolset->map),symbol->font,symbolset->fontset,size,symbol->character,&rect,NULL) != MS_SUCCESS)
return(MS_FAILURE);
*width = (int) MS_MAX(*width, rect.maxx - rect.minx);
Modified: trunk/mapserver/maputil.c
===================================================================
--- trunk/mapserver/maputil.c 2011-12-10 09:29:20 UTC (rev 12877)
+++ trunk/mapserver/maputil.c 2011-12-10 12:09:44 UTC (rev 12878)
@@ -231,8 +231,10 @@
}
if(label->bindings[MS_LABEL_BINDING_FONT].index != -1) {
- msFree(label->font);
- label->font = msStrdup(shape->values[label->bindings[MS_LABEL_BINDING_FONT].index]);
+ if(strcmp(label->font,shape->values[label->bindings[MS_LABEL_BINDING_FONT].index])) {
+ msFree(label->font);
+ label->font = msStrdup(shape->values[label->bindings[MS_LABEL_BINDING_FONT].index]);
+ }
}
if(label->bindings[MS_LABEL_BINDING_PRIORITY].index != -1) {
More information about the mapserver-commits
mailing list