[rrd-developers] use utf-16 to display text

罗 翼 luoyi_ly82 at yahoo.com.cn
Wed May 16 05:19:35 CEST 2007


Hi, in order to display CJK and some other charset
letters, we should use utf-16 to display the text (
FreeType2 will try to load UNICODE charmap on default
). below is the patch:

--- src/rrd_gfx.c.orig  2007-05-16 10:20:14.000000000
+0800
+++ src/rrd_gfx.c       2007-05-16 10:48:17.000000000
+0800
@@ -25,6 +25,7 @@
 #include "rrd_gfx.h"
 #include "rrd_afm.h"
 #include "unused.h"
+#include <iconv.h>
 
 /* lines are better drawn on the pixle than between
pixles */
 #define LINEOFFSET 0.5
@@ -389,6 +390,16 @@
   int          n;
   int           error;
   int        gottab = 0;    
+  size_t       ilen = strlen(text);
+  size_t       olen = ilen * 3 + 4;                /*
maybe 3 times is enough ! */
+  char         *ubuf = (char*)malloc(olen);          
 /* utf-16 buffer */
+  char         *in = (char*)text, *out = ubuf;       
 /* iconv's in & out */
+  size_t       ss;
+  iconv_t      cv;
+  unsigned short* ps = NULL;
+  int          xx=0;
+
+  string->count = ilen;
 
 #ifdef HAVE_MBSTOWCS
   wchar_t      *cstr;
@@ -403,17 +414,47 @@
         }
   }
 #else
+  /*
   char         *cstr = strdup(text);
   string->count = strlen (text);
+  */
 #endif
 
+
+  /* if ( ilen < 1 ) return string;    */ /* if text
= null, return */
+
+  if ( ubuf == NULL ){
+         fprintf(stderr, "malloc iconv output buffer
failed: %s\n", strerror(errno));
+         exit(-1);
+  }
+
+  cv = iconv_open("UTF-16", "UTF-8");
+  if ( cv == (iconv_t)(-1) ) {
+         fprintf(stderr, "iconv_open failed!\n");
+         exit(-1);
+  }
+
+  memset(ubuf, 0, olen);
+  ss = iconv(cv, &in, &ilen, &out, &olen);
+
+  /* we can continue our process even if iconv failed
+   * because some chars may have been converted
+   */
+  if ( ss == (size_t)-1 ){
+    fprintf(stderr, "iconv failed, errno = %d, text =
%s\n", errno, text);
+  }
+  iconv_close(cv);
+
+  ps = (unsigned short*)&ubuf[0];
+  if (ps[0] == 0xfeff) ps++;           /* ignore utf
head */
+  for(xx=0;ps[xx];xx++);
+
   ft_pen.x = 0;   /* start at (0,0) !! */
   ft_pen.y = 0;
 
-
   string->width = 0;
   string->height = 0;
-  string->glyphs = (gfx_char) calloc
(string->count,sizeof(struct gfx_char_s));
+  string->glyphs = (gfx_char) calloc
(xx,sizeof(struct gfx_char_s));
   string->num_glyphs = 0;
   string->transform.xx = (FT_Fixed)(
cos(M_PI*(rotation)/180.0)*0x10000);
   string->transform.xy =
(FT_Fixed)(-sin(M_PI*(rotation)/180.0)*0x10000);
@@ -423,16 +464,16 @@
   use_kerning = FT_HAS_KERNING(face);
   previous    = 0;
   glyph = string->glyphs;
-  for (n=0; n<string->count;glyph++,n++) {
+  for (n=0; n<xx;glyph++,n++) {
     FT_Vector   vec;
     /* handle the tabs ...
        have a witespace glyph inserted, but set its
width such that the distance
     of the new right edge is x times tabwidth from
0,0 where x is an integer. */    
-    unsigned int letter = cstr[n];
+    unsigned int letter =ps[n];
        letter = afm_fix_osx_charset(letter); /*
unsafe macro */
           
     gottab = 0;
-    if (letter == '\\' && n+1 < string->count &&
cstr[n+1] == 't'){
+    if (letter == '\\' && n+1 < xx && ps[n+1] ==
't'){
             /* we have a tab here so skip the
backslash and
                set t to ' ' so that we get a white
space */
             gottab = 1;
@@ -449,7 +490,6 @@
     glyph->pos.y = 0;
     glyph->image = NULL;
     glyph->index = FT_Get_Char_Index( face, letter );
-
     /* compute glyph origin */
     if ( use_kerning && previous && glyph->index ) {
       FT_Vector kerning;
@@ -511,7 +551,7 @@
     previous = glyph->index;
     string->num_glyphs++;
   }
-  free(cstr);
+  free(ubuf);
 /*  printf ("number of glyphs = %d\n",
string->num_glyphs);*/
   compute_string_bbox( string );
   /* the last character was a tab */  
@@ -610,11 +650,11 @@
                                  (char
*)node->filename,
                                  0,
                                  &face );
-           if ( error ) {
-               rrd_set_error("failed to load
%s",node->filename);
-               
-               break;
-           }
+                       if ( error ) {
+                               rrd_set_error("failed
to load %s",node->filename);
+
+                               break;
+                       }
             error = FT_Set_Char_Size(face,   /*
handle to face object            */
                                     
(long)(node->size*64),
                                     
(long)(node->size*64),




		
___________________________________________________________ 
抢注雅虎免费邮箱-3.5G容量,20M附件! 
http://cn.mail.yahoo.com



More information about the rrd-developers mailing list