[mapserver-commits] r8987 - sandbox/graphics

svn at osgeo.org svn at osgeo.org
Fri May 1 14:19:13 EDT 2009


Author: tbonfort
Date: 2009-05-01 14:19:13 -0400 (Fri, 01 May 2009)
New Revision: 8987

Modified:
   sandbox/graphics/mapcairo.c
Log:
stop using cairo text api, but use our own text to glyph decoding


Modified: sandbox/graphics/mapcairo.c
===================================================================
--- sandbox/graphics/mapcairo.c	2009-05-01 10:19:31 UTC (rev 8986)
+++ sandbox/graphics/mapcairo.c	2009-05-01 18:19:13 UTC (rev 8987)
@@ -283,29 +283,44 @@
 
 void renderTruetypeSymbolCairo(imageObj *img, double x, double y, symbolObj *symbol,
         symbolStyleObj *s) {
+    
     cairo_renderer *r = getCairoRenderer(img);
     cairo_font_face_t *ff = getFontFace(r,symbol->full_font_path);
+
+    int unicode;
+    cairo_glyph_t glyph;
     cairo_text_extents_t extents;
+    FT_Face *f;
+
     cairo_matrix_t trans;
     double ox,oy;
+    cairo_save(r->cr); 
+    cairo_set_font_face(r->cr,ff);
+    cairo_set_font_size(r->cr,s->scale*96/72.0);
 
-    cairo_save(r->cr);
-	cairo_set_font_face(r->cr, ff);
-	cairo_set_font_size(r->cr, s->scale * 96 / 72.0);
-	cairo_text_extents(r->cr, symbol->character, &extents);
 
+    f = cairo_font_face_get_user_data(
+            cairo_get_font_face(r->cr),
+            &facekey);
+    msUTF8ToUniChar(symbol->character, &unicode);
+    glyph.index = FT_Get_Char_Index(*f, unicode);
+    cairo_glyph_extents(r->cr,&glyph,1,&extents);
+	ox=extents.x_bearing+extents.width/2.;
+	oy=extents.y_bearing+extents.height/2.;
+    glyph.x=0;
+    glyph.y=0;
+
+
 	cairo_matrix_init_rotate(&trans,-s->rotation);
 
-	ox=extents.x_bearing+extents.width/2.;
-	oy=extents.y_bearing+extents.height/2.;
 	cairo_matrix_transform_point(&trans,&ox,&oy);
 	//cairo_translate(cr,-extents.width/2,-extents.height/2);
 
-	cairo_move_to(r->cr,x-ox,y-oy);
+	cairo_translate(r->cr,x-ox,y-oy);
 	cairo_rotate(r->cr, -s->rotation);
-	cairo_set_font_size(r->cr, s->scale * 96 / 72.0);
 	
-	cairo_text_path(r->cr, symbol->character);
+    cairo_glyph_path(r->cr,&glyph,1);
+	
 	if (s->outlinewidth) {
 		msCairoSetSourceColor(r->cr, &s->outlinecolor);
 		cairo_set_line_width(r->cr, s->outlinewidth);
@@ -332,191 +347,200 @@
 
 #define CAIROLINESPACE 1.33
 
-int getTruetypeTextBBoxCairo(imageObj *img,char *font, double size, char *string,
+int getTruetypeTextBBoxCairo(imageObj *img,char *font, double size, char *text,
         		rectObj *rect, double **advances) {
-	cairo_renderer *r = getCairoRenderer(img);
 
-	cairo_font_face_t *ff = getFontFace(r,font);
-	int numlines, i;
-	char **lines = msStringSplit(string, '\n', &numlines);
-	cairo_text_extents_t extents;
+    cairo_renderer *r = getCairoRenderer(img);
+    cairo_font_face_t *ff = getFontFace(r,font);
 
-	cairo_set_font_face(r->cr, ff);
-	cairo_set_font_size(r->cr, size * 96 / 72.0);
+    char *utfptr=text;
+    int i,has_kerning,unicode;
+    unsigned long previdx=0;
+    int numglyphs = msGetNumGlyphs(text);
+    cairo_glyph_t glyph;
+    cairo_text_extents_t extents;
+    double px=0,py=0;
+    FT_Face *f;
 
-	for(i=0;i<numlines;i++) {
-		cairo_text_extents(r->cr, lines[i], &extents);
+    cairo_set_font_face(r->cr,ff);
+    cairo_set_font_size(r->cr,size*96/72.0);
+
+    f = cairo_font_face_get_user_data(
+            cairo_get_font_face(r->cr),
+            &facekey);
+    has_kerning = FT_HAS_KERNING((*f));
+
+    if(advances != NULL) {
+        *advances = (double*)malloc(numglyphs*sizeof(double));
+    }
+
+    for(i=0;i<numglyphs;i++) {
+        utfptr+=msUTF8ToUniChar(utfptr, &unicode);
+        glyph.x=px;
+        glyph.y=py;
+        if(unicode=='\n') {
+            py += ceil(size*CAIROLINESPACE);
+            px = 0;
+            previdx=0;
+            continue;
+        }
+        glyph.index = FT_Get_Char_Index(*f, unicode);
+        if( has_kerning && previdx ) {
+            FT_Vector delta;
+            FT_Get_Kerning( *f, previdx, glyph.index, FT_KERNING_DEFAULT, &delta );
+            px += delta.x / 64.;
+        }
+        cairo_glyph_extents(r->cr,&glyph,1,&extents);
+        
 		if(i==0) {
-			rect->minx = extents.x_bearing;
-			rect->miny = extents.y_bearing;
-			rect->maxx = extents.x_bearing+extents.width;
-			rect->maxy = extents.y_bearing+extents.height;
+			rect->minx = px+extents.x_bearing;
+			rect->miny = py+extents.y_bearing;
+			rect->maxx = px+extents.x_bearing+extents.width;
+			rect->maxy = px+extents.y_bearing+extents.height;
 		} else {
-			rect->minx = MS_MIN(rect->minx,extents.x_bearing);
-			rect->miny = MS_MIN(rect->miny,extents.y_bearing);
-			rect->maxy += CAIROLINESPACE*size;
-			rect->maxx = MS_MAX(rect->maxx,extents.x_bearing+extents.width);
+			rect->minx = MS_MIN(rect->minx,px+extents.x_bearing);
+			rect->miny = MS_MIN(rect->miny,px+extents.y_bearing);
+			rect->maxy = MS_MAX(rect->maxy,py+extents.y_bearing+extents.height);
+			rect->maxx = MS_MAX(rect->maxx,px+extents.x_bearing+extents.width);
 		}
-	}
-    if(advances != NULL) {
-        char s[11];
-        const char *string_ptr = string;
-        int numglyphs = msGetNumGlyphs(string);
-        *advances = (double*)malloc(numglyphs*sizeof(double));
-        for(i=0; i < numglyphs; i++) {
-            msGetNextGlyph(&string_ptr,s);
-            cairo_text_extents(r->cr, s, &extents);
+        if(advances!=NULL)
             (*advances)[i]=extents.x_advance;
-        }
+        px += extents.x_advance;
+        previdx=glyph.index;
     }
-
-	msFreeCharArray(lines,numlines);
 	return MS_SUCCESS;
 }
 
-void renderGlyphs(cairo_t *cr, double x, double y, unsigned long *glyphs, unsigned int numglyphs) {
-    int i;
+void renderGlyphsCairo(imageObj *img,double x, double y, labelStyleObj *style, char *text) {
+    cairo_renderer *r = getCairoRenderer(img);
+
+    cairo_font_face_t *ff = getFontFace(r,style->font);
+
+    char *utfptr=text;
+    int i,has_kerning,unicode;
+    unsigned long previdx=0;
+    int numglyphs = msGetNumGlyphs(text);
     cairo_glyph_t glyph;
     cairo_text_extents_t extents;
-    double px=x,py=y;
-    FT_Face *f = cairo_font_face_get_user_data(
-                cairo_get_font_face(cr),
-                &facekey);
-    int has_kerning = FT_HAS_KERNING((*f));
-    unsigned long previdx=0;
+    double px=0,py=0;
+    FT_Face *f;
+
+    cairo_set_font_face(r->cr,ff);
+    cairo_set_font_size(r->cr,style->size*96/72.0);
+
+    cairo_save(r->cr);
+    cairo_translate(r->cr,x,y);
+    cairo_rotate(r->cr, -style->rotation);
+
+    f = cairo_font_face_get_user_data(
+            cairo_get_font_face(r->cr),
+            &facekey);
+    has_kerning = FT_HAS_KERNING((*f));
     for(i=0;i<numglyphs;i++) {
+        utfptr+=msUTF8ToUniChar(utfptr, &unicode);
         glyph.x=px;
         glyph.y=py;
-        if(glyphs[i]=='\n') {
-            py += 10;
-            px = x;
+        if(unicode=='\n') {
+            py += ceil(style->size*CAIROLINESPACE);
+            px = 0;
             previdx=0;
             continue;
         }
-        glyph.index = FT_Get_Char_Index(*f, glyphs[i]);
+        glyph.index = FT_Get_Char_Index(*f, unicode);
         if( has_kerning && previdx ) {
             FT_Vector delta;
-            FT_Get_Kerning( *f, previdx, glyph.index, FT_KERNING_UNFITTED, &delta );
+            FT_Get_Kerning( *f, previdx, glyph.index, FT_KERNING_DEFAULT, &delta );
             px += delta.x / 64.;
-
-            //printf("adding %f kerning\n",delta.x/64.);
         }
-        cairo_glyph_extents(cr,&glyph,1,&extents);
-        cairo_glyph_path(cr,&glyph,1);
+        cairo_glyph_extents(r->cr,&glyph,1,&extents);
+        cairo_glyph_path(r->cr,&glyph,1);
         px += extents.x_advance;
         previdx=glyph.index;
     }
-}
 
-void renderGlyphsCairo(imageObj *img,double x, double y, labelStyleObj *style, char *text) {
-	cairo_renderer *r = getCairoRenderer(img);
+    /* NOT SUPPORTED
+       if (style->shadowsizex !=0 || style->shadowsizey != 0) {
+       cairo_save(r->cr);
+       msCairoSetSourceColor(r->cr, &style->shadowcolor);
+       cairo_rel_move_to(r->cr, style->shadowsizex, style->shadowsizey);
+       cairo_fill(r->cr);
+       cairo_restore(r->cr);
+       }*/
 
-	cairo_font_face_t *ff = getFontFace(r,style->font);
 
-	int numlines,i;
-	char **lines = msStringSplit(text,'\n',&numlines);
-	cairo_set_font_face(r->cr,ff);
-	cairo_set_font_size(r->cr,style->size*96/72.0);
+    if (style->outlinewidth > 0) {
+        cairo_save(r->cr);
+        msCairoSetSourceColor(r->cr, &style->outlinecolor);
+        cairo_set_line_width(r->cr, style->outlinewidth);
+        cairo_stroke_preserve(r->cr);
+        cairo_restore(r->cr);
+    }
 
-//	for(i=0;i<numlines;i++) {
-		cairo_save(r->cr);
-		cairo_translate(r->cr,x,y);
-		cairo_rotate(r->cr, -style->rotation);
-
-/*		if (style->shadowsizex !=0 || style->shadowsizey != 0) {
-			cairo_save(r->cr);
-			msCairoSetSourceColor(r->cr, &style->shadowcolor);
-			cairo_rel_move_to(r->cr, style->shadowsizex, style->shadowsizey);
-			cairo_show_text(r->cr, lines[i]);
-			cairo_restore(r->cr);
-		}
-*/
-        int nglyphs = msGetNumGlyphs(text);
-        unsigned long *glyphs = malloc(nglyphs*sizeof(long));
-        char *utfptr=text;
-        
-        for(i=0;i<nglyphs;i++) {
-            utfptr+=msUTF8ToUniChar(utfptr, &(glyphs[i]));
-        }
-		renderGlyphs(r->cr, 0,0,glyphs,nglyphs);
-		if (style->outlinewidth > 0) {
-			cairo_save(r->cr);
-			msCairoSetSourceColor(r->cr, &style->outlinecolor);
-			cairo_set_line_width(r->cr, style->outlinewidth);
-			cairo_stroke_preserve(r->cr);
-			cairo_restore(r->cr);
-		}
-
-		msCairoSetSourceColor(r->cr, &style->color);
-		cairo_fill_preserve(r->cr);
-		cairo_new_path(r->cr);
-		cairo_restore(r->cr);
-	//}
-	msFreeCharArray(lines,numlines);
-	return;
+    msCairoSetSourceColor(r->cr, &style->color);
+    cairo_fill(r->cr);
+    cairo_restore(r->cr);
+    return;
 }
 
 
-void renderGlyphsLineCairo(imageObj *image, labelPathObj *labelpath,
+void renderGlyphsLineCairo(imageObj *img, labelPathObj *labelpath,
         labelStyleObj *style, char *text)
 {
-	cairo_renderer *r = getCairoRenderer(image);
 
-	cairo_font_face_t *ff = getFontFace(r,style->font);
-        const char *string_ptr;
-        char s[11];
-        int i = 0;
+    cairo_renderer *r = getCairoRenderer(img);
 
+    cairo_font_face_t *ff = getFontFace(r,style->font);
+
+    char *utfptr=text;
+    int i,unicode;
+    cairo_glyph_t glyph;
+    FT_Face *f;
+
     cairo_set_font_face(r->cr,ff);
     cairo_set_font_size(r->cr,style->size*96/72.0);
 
 
-    if (&style->outlinecolor != NULL && MS_VALID_COLOR(style->outlinecolor)) {
-        msCairoSetSourceColor(r->cr, &style->outlinecolor);
-        string_ptr = text;
-        for (i = 0; i < labelpath->path.numpoints; i++) {
-            double x, y;
-            double theta;
+    f = cairo_font_face_get_user_data(
+            cairo_get_font_face(r->cr),
+            &facekey);
+    for(i=0;i<labelpath->path.numpoints;i++) {
+        cairo_save(r->cr);
 
-            if (msGetNextGlyph(&string_ptr, s) == -1)
-                break;  /* Premature end of string??? */
-
-            theta = labelpath->angles[i];
-            x = labelpath->path.point[i].x;
-            y = labelpath->path.point[i].y;
-            cairo_save(r->cr);
-            cairo_move_to(r->cr,x,y);
-            cairo_rotate(r->cr, -theta);
-
-
-            cairo_text_path(r->cr, s);
-
-            cairo_set_line_width(r->cr, style->outlinewidth);
-            cairo_stroke(r->cr);
-            cairo_restore(r->cr);
+        cairo_translate(r->cr,labelpath->path.point[i].x,labelpath->path.point[i].y);
+        cairo_rotate(r->cr, -labelpath->angles[i]);
+        utfptr+=msUTF8ToUniChar(utfptr, &unicode);
+        glyph.x=0;
+        glyph.y=0;
+        if(unicode=='\n') {
+            continue;
         }
+        glyph.index = FT_Get_Char_Index(*f, unicode);
+        cairo_glyph_path(r->cr,&glyph,1);
+        cairo_restore(r->cr);
     }
-    msCairoSetSourceColor(r->cr, &style->color);
-    string_ptr = text;
-    for (i = 0; i < labelpath->path.numpoints; i++) {
-        double x, y;
-        double theta;
 
-        if (msGetNextGlyph(&string_ptr, s) == -1)
-            break;  /* Premature end of string??? */
+    /* NOT SUPPORTED
+       if (style->shadowsizex !=0 || style->shadowsizey != 0) {
+       cairo_save(r->cr);
+       msCairoSetSourceColor(r->cr, &style->shadowcolor);
+       cairo_rel_move_to(r->cr, style->shadowsizex, style->shadowsizey);
+       cairo_fill(r->cr);
+       cairo_restore(r->cr);
+       }*/
 
-        theta = labelpath->angles[i];
-        x = labelpath->path.point[i].x;
-        y = labelpath->path.point[i].y;
+
+    if (style->outlinewidth > 0) {
         cairo_save(r->cr);
-        cairo_move_to(r->cr,x,y);
-        cairo_rotate(r->cr, -theta);
-
-        cairo_text_path(r->cr, s);
-
-        cairo_fill(r->cr);
+        msCairoSetSourceColor(r->cr, &style->outlinecolor);
+        cairo_set_line_width(r->cr, style->outlinewidth);
+        cairo_stroke_preserve(r->cr);
         cairo_restore(r->cr);
     }
+
+    msCairoSetSourceColor(r->cr, &style->color);
+    cairo_fill(r->cr);
+    return;
+    
 }
 
 



More information about the mapserver-commits mailing list