improve freetype 1.x text output efficiency
authorTony Cook <tony@develop=help.com>
Fri, 4 May 2007 10:45:14 +0000 (10:45 +0000)
committerTony Cook <tony@develop=help.com>
Fri, 4 May 2007 10:45:14 +0000 (10:45 +0000)
Changes
font.c
t/t35ttfont.t

diff --git a/Changes b/Changes
index 8a727695bcfebe713e91321e59101015bca3b5be..b972979945e5de2bd0892a980d0f5f6b81c8614c 100644 (file)
--- a/Changes
+++ b/Changes
@@ -5,6 +5,8 @@ Imager 0.58 -
 
  - added to_rgb16 to produce a 16-bit/sample version of an image
 
+ - improve freetype 1.x text output efficiency
+
 Bug fixes:
 
  - search another place for rgb.txt, and check all the places 
diff --git a/font.c b/font.c
index bd35a756312a80959b49412e22553a7c01b78df4..87c70bc550abba4d9f14d283bc6e83dd7854c5da 100644 (file)
--- a/font.c
+++ b/font.c
@@ -873,6 +873,8 @@ Initializes the freetype font rendering engine
 undef_int
 i_init_tt() {
   TT_Error  error;
+  TT_Byte palette[] = { 0, 64, 127, 191, 255 };
+
   mm_log((1,"init_tt()\n"));
   error = TT_Init_FreeType( &engine );
   if ( error ){
@@ -888,6 +890,12 @@ i_init_tt() {
   }
 #endif
 
+  error = TT_Set_Raster_Gray_Palette(engine, palette);
+  if (error) {
+    mm_log((1, "Initialization of gray levels failed = 0x%x\n", error));
+    return 1;
+  }
+
   return(0);
 }
 
@@ -1176,7 +1184,7 @@ void
 i_tt_blit_or( TT_Raster_Map *dst, TT_Raster_Map *src,int x_off, int y_off ) {
   int  x,  y;
   int  x1, x2, y1, y2;
-  char *s, *d;
+  unsigned char *s, *d;
   
   x1 = x_off < 0 ? -x_off : 0;
   y1 = y_off < 0 ? -y_off : 0;
@@ -1192,8 +1200,8 @@ i_tt_blit_or( TT_Raster_Map *dst, TT_Raster_Map *src,int x_off, int y_off ) {
   /* do the real work now */
 
   for ( y = y1; y < y2; ++y ) {
-    s = ( (char*)src->bitmap ) + y * src->cols + x1;
-    d = ( (char*)dst->bitmap ) + ( y + y_off ) * dst->cols + x1 + x_off;
+    s = ( (unsigned char*)src->bitmap ) + y * src->cols + x1;
+    d = ( (unsigned char*)dst->bitmap ) + ( y + y_off ) * dst->cols + x1 + x_off;
     
     for ( x = x1; x < x2; ++x ) {
       if (*s > *d)
@@ -1505,31 +1513,41 @@ Function to dump a raster onto an image in color used by i_tt_text() (internal).
 static
 void
 i_tt_dump_raster_map2( i_img* im, TT_Raster_Map* bit, int xb, int yb, const i_color *cl, int smooth ) {
-  char *bmap;
+  unsigned char *bmap;
   i_color val;
   int c, i, ch, x, y;
   mm_log((1,"i_tt_dump_raster_map2(im 0x%x, bit 0x%X, xb %d, yb %d, cl 0x%X)\n",im,bit,xb,yb,cl));
   
-  bmap = (char *)bit->bitmap;
+  bmap = bit->bitmap;
 
   if ( smooth ) {
 
-    for(y=0;y<bit->rows;y++) for(x=0;x<bit->width;x++) {
-      c=(255*bmap[y*(bit->cols)+x])/4;
-      i=255-c;
-      i_gpix(im,x+xb,y+yb,&val);
-      for(ch=0;ch<im->channels;ch++) val.channel[ch]=(c*cl->channel[ch]+i*val.channel[ch])/255;
-      i_ppix(im,x+xb,y+yb,&val);
+    for(y=0;y<bit->rows;y++) {
+      for(x=0;x<bit->width;x++) {
+       c = (unsigned char)bmap[y*(bit->cols)+x];
+       i=255-c;
+       i_gpix(im,x+xb,y+yb,&val);
+       for(ch=0;ch<im->channels;ch++) 
+         val.channel[ch] = (c*cl->channel[ch]+i*val.channel[ch])/255;
+       i_ppix(im,x+xb,y+yb,&val);
+      }
     }
 
   } else {
-
-    for(y=0;y<bit->rows;y++) for(x=0;x<bit->width;x++) {
-      c=( bmap[y*bit->cols+x/8] & (128>>(x%8)) ) ? 255 : 0;
-      i=255-c;
-      i_gpix(im,x+xb,y+yb,&val);
-      for(ch=0;ch<im->channels;ch++) val.channel[ch]=(c*cl->channel[ch]+i*val.channel[ch])/255;
-      i_ppix(im,x+xb,y+yb,&val);
+    for(y=0;y<bit->rows;y++) {
+      unsigned mask = 0x80;
+      unsigned char *p = bmap + y * bit->cols;
+
+      for(x = 0; x < bit->width; x++) {
+       if (*p & mask) {
+         i_ppix(im, x+xb, y+yb, cl);
+       }
+       mask >>= 1;
+       if (!mask) {
+         mask = 0x80;
+         ++p;
+       }
+      }
     }
 
   }
@@ -1563,17 +1581,27 @@ i_tt_dump_raster_map_channel( i_img* im, TT_Raster_Map*  bit, int xb, int yb, in
   
   if ( smooth ) {
     for(y=0;y<bit->rows;y++) for(x=0;x<bit->width;x++) {
-      c=(255*bmap[y*(bit->cols)+x])/4;
+      c = (unsigned char)bmap[y*(bit->cols)+x];
       i_gpix(im,x+xb,y+yb,&val);
       val.channel[channel]=c;
       i_ppix(im,x+xb,y+yb,&val);
     }
   } else {
-    for(y=0;y<bit->rows;y++) for(x=0;x<bit->width;x++) {
-      c=( bmap[y*bit->cols+x/8] & (128>>(x%8)) ) ? 255 : 0;
-      i_gpix(im,x+xb,y+yb,&val);
-      val.channel[channel]=c;
-      i_ppix(im,x+xb,y+yb,&val);
+    for(y=0;y<bit->rows;y++) {
+      unsigned mask = 0x80;
+      unsigned char *p = bmap + y * bit->cols;
+
+      for(x=0;x<bit->width;x++) {
+       i_gpix(im,x+xb,y+yb,&val);
+       val.channel[channel] = (*p & mask) ? 255 : 0;
+       i_ppix(im,x+xb,y+yb,&val);
+       
+       mask >>= 1;
+       if (!mask) {
+         ++p;
+         mask = 0x80;
+       }
+      }
     }
   }
 }
index 5ab3133e9cdf2b53e8d5e55d5a9517b07bc67399..666c6bfa1db336fae46b29ffa94574546dd00489 100644 (file)
@@ -1,6 +1,6 @@
 #!perl -w
 use strict;
-use Test::More tests => 85;
+use Test::More tests => 87;
 
 $|=1;
 
@@ -12,7 +12,7 @@ init_log("testout/t35ttfont.log",2);
 
 SKIP:
 {
-  skip("freetype 1.x unavailable or disabled", 84
+  skip("freetype 1.x unavailable or disabled", 86
     unless i_has_format("tt");
   print "# has tt\n";
   
@@ -21,14 +21,15 @@ SKIP:
 
   if (!ok(-f $fontname, "check test font file exists")) {
     print "# cannot find fontfile for truetype test $fontname\n";
-    skip('Cannot load test font', 83);
+    skip('Cannot load test font', 85);
   }
 
   i_init_fonts();
   #     i_tt_set_aa(1);
   
   my $bgcolor = i_color_new(255,0,0,0);
-  my $overlay = Imager::ImgRaw::new(200,70,3);
+  my $overlay = Imager::ImgRaw::new(320,140,3);
+  i_box_filled($overlay, 0, 0, 319, 139, i_color_new(128, 128, 128));
   
   my $ttraw = Imager::i_tt_new($fontname);
   ok($ttraw, "create font");
@@ -38,6 +39,7 @@ SKIP:
   print "#bbox: ($bbox[0], $bbox[1]) - ($bbox[2], $bbox[3])\n";
 
   ok(i_tt_cp($ttraw,$overlay,5,50,1,50.0,'XM CLH',6,1,0), "cp output");
+  ok(i_tt_cp($ttraw,$overlay,5,120,1,50.0,'XM CLH',6,0,0), "cp output (non AA)");
   i_line($overlay,0,50,100,50,$bgcolor,1);
 
   open(FH,">testout/t35ttfont.ppm") || die "cannot open testout/t35ttfont.ppm\n";
@@ -53,6 +55,8 @@ SKIP:
   
   ok(i_tt_text($ttraw,$backgr,100,120,$bgcolor,50.0,'te st',5,1,0),
       "normal output");
+  ok(i_tt_text($ttraw,$backgr,100,200,$bgcolor,50.0,'te st',5,0,0),
+      "normal output (non AA)");
 
   my $ugly = Imager::i_tt_new("./fontfiles/ImUgly.ttf");
   ok($ugly, "create ugly font");