/[freetype]/ft2demos/src/ftview.c
ViewVC logotype

Diff of /ft2demos/src/ftview.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.59 by wl, Thu May 26 05:35:59 2005 UTC revision 1.60 by wl, Fri Jun 17 15:26:31 2005 UTC
# Line 16  Line 16 
16  /****************************************************************************/  /****************************************************************************/
17    
18    
19  #include "ftcommon.i"  #include "ftcommon.h"
20    #include "common.h"
21  #include <math.h>  #include <math.h>
22    
23      /* the following header shouldn't be used in normal programs */
24    #include FT_INTERNAL_DEBUG_H
25    #include FT_STROKER_H
26    #include FT_SYNTHESIS_H
27    
28    #define MAXPTSIZE      500                 /* dtp */
29    #define HEADER_HEIGHT  8
30    
31    static FT_Error  #ifdef CEIL
32    Render_GammaGrid( void )  #undef CEIL
33    {  #endif
34      int   g;  #define CEIL( x )   ( ( (x) + 63 ) >> 6 )
     int   yside  = 11;  
     int   xside  = 10;  
     int   levels = 17;  
     int   gammas = 30;  
     int   x_0    = (bit.width - levels*xside)/2;  
     int   y_0    = (bit.rows  - gammas*(yside+1))/2;  
     int   pitch  = bit.pitch;  
   
     if ( pitch < 0 )  
       pitch = -pitch;  
   
     memset( bit.buffer, 100, pitch*bit.rows );  
   
     grGotobitmap( &bit );  
   
     for ( g = 1; g <= gammas; g += 1 )  
     {  
       double ggamma = g/10.0;  
       char   temp[6];  
       int    y = y_0 + (yside+1)*(g-1);  
       int    nx, ny;  
   
       unsigned char*  line = bit.buffer + y*bit.pitch;  
   
       if ( bit.pitch < 0 )  
         line -= bit.pitch*(bit.rows-1);  
   
       line += x_0*3;  
   
       grSetPixelMargin( x_0-32, y + (yside-8)/2 );  
       grGotoxy( 0, 0 );  
   
       sprintf( temp, "%.1f", ggamma );  
       grWrite( temp );  
   
       for ( ny = 0; ny < yside; ny++, line += bit.pitch )  
       {  
         unsigned char*  dst = line;  
35    
36          for ( nx = 0; nx < levels; nx++, dst += 3 * xside )  #define INIT_SIZE( size, start_x, start_y, step_x, step_y, x, y )        \
37          {            do {                                                           \
38            double  p   = nx/(double)(levels - 1);              start_x = 4;                                                 \
39            int     gm  = (int)( 255.0 * pow( p, ggamma ) );              start_y = CEIL( size->metrics.height ) + 2 * HEADER_HEIGHT;  \
40                step_x  = CEIL( size->metrics.max_advance );                 \
41                step_y  = CEIL( size->metrics.height ) + 4;                  \
42                                                                             \
43                x = start_x;                                                 \
44                y = start_y;                                                 \
45              } while ( 0 )
46    
47    #define X_TOO_LONG( x, size, display) \
48              ( ( x ) + ( ( size )->metrics.max_advance >> 6 ) > ( display )->bitmap->width )
49    #define Y_TOO_LONG( y, size, display) \
50              ( ( y ) >= ( display )->bitmap->rows )
51              
52      enum {
53        RENDER_MODE_ALL = 0,
54        RENDER_MODE_EMBOLDEN,
55        RENDER_MODE_STROKE,
56        RENDER_MODE_TEXT,
57        RENDER_MODE_WATERFALL,
58        N_RENDER_MODES
59      };
60    
61      static struct {
62        int          render_mode;
63        FT_Encoding  encoding;
64        int          res;
65        int          ptsize;            /* current point size */
66        double       gamma;
67    
68        int          debug;
69        int          trace_level;
70        int          font_index;
71        int          dump_cache_stats;  /* do we need to dump cache statistics? */
72        int          Num;               /* current first index */
73        char*        header;
74        char         header_buffer[256];
75        int          Fail;
76    
77      } status = { RENDER_MODE_ALL, FT_ENCODING_NONE, 72, 48, 1.0 };
78    
79    
80      static FTDemo_Display*  display;
81      static FTDemo_Handle*   handle;
82    
83    
84      static const unsigned char*  Text = (unsigned char*)
85        "The quick brown fox jumps over the lazy dog 0123456789 "
86        "\342\352\356\373\364\344\353\357\366\374\377\340\371\351\350\347 "
87        "&#~\"\'(-`_^@)=+\260 ABCDEFGHIJKLMNOPQRSTUVWXYZ "
88        "$\243^\250*\265\371%!\247:/;.,?<>";
89    
           memset( dst, gm, xside * 3 );  
         }  
       }  
     }  
     return 0;  
   }  
90    
91    
92    static FT_Error    static FT_Error
93    Render_Stroke( int  first_index )    Render_Stroke( int  num_indices,
94                     int  first_index )
95    {    {
96      FT_F26Dot6     start_x, start_y, step_x, step_y, x, y;      int         start_x, start_y, step_x, step_y, x, y;
97      FTC_ScalerRec  scaler;      int         i;
98      FT_Stroker     stroker = NULL;      FT_Size     size;
99      int            i;      FT_Stroker  stroker = NULL;
     grBitmap       bit3;  
100    
101    
102      start_x = 4;      error = FTDemo_Get_Size( handle, &size );
     start_y = 16 + current_font.height;  
103    
104        if ( error )
105        {
106          /* probably a non-existent bitmap font size */
107          return error;
108        }
109    
110      scaler.face_id = current_font.face_id;      INIT_SIZE( size, start_x, start_y, step_x, step_y, x, y );
     scaler.width   = current_font.width;  
     scaler.height  = current_font.height;  
     scaler.pixel   = 1;  
111    
112      error = FTC_Manager_LookupSize( cache_manager, &scaler, &size );      i = first_index;
     if ( error )  
       goto Exit;  
113    
114      error = FT_Stroker_New( size->face->memory, &stroker );      error = FT_Stroker_New( size->face->memory, &stroker );
115      if ( error )      if ( error )
116        goto Exit;        goto Exit;
117    
118      FT_Stroker_Set( stroker,      FT_Stroker_Set( stroker, 64,
                     64,  
119                      FT_STROKER_LINECAP_ROUND,                      FT_STROKER_LINECAP_ROUND,
120                      FT_STROKER_LINEJOIN_ROUND,                      FT_STROKER_LINEJOIN_ROUND,
121                      0 );                      0 );
122    
123      step_x = size->metrics.x_ppem + 4;      while ( i < num_indices )
124      step_y = ( size->metrics.height >> 6 ) + 4;      {
125          int           gindex;
126          FT_GlyphSlot  slot;
127    
     x = start_x;  
     y = start_y;  
128    
129      i = first_index;        if ( handle->encoding == FT_ENCODING_NONE )
130      i = first_index;          gindex = i;
131          else
132            gindex = FTDemo_Get_Index( handle, i );
133    
134          error = FT_Load_Glyph( size->face, gindex,
135                                 handle->image_type.flags | FT_LOAD_NO_BITMAP );
136          slot = size->face->glyph;
137    
     while ( i < face->num_glyphs )  
     {  
       int           left, top, x_advance, y_advance, x_top, y_top;  
       FT_GlyphSlot  slot = size->face->glyph;  
       FT_Glyph      glyphp;  
   
 #if 0  
       gindex = *(unsigned char*)p;  
       if ( encoding == FT_ENCODING_NONE )  
         gindex = get_glyph_index( gindex );  
 #endif  
       error = FT_Load_Glyph( size->face, i, FT_LOAD_NO_BITMAP );  
138        if ( !error && slot->format == FT_GLYPH_FORMAT_OUTLINE )        if ( !error && slot->format == FT_GLYPH_FORMAT_OUTLINE )
139        {        {
140          FT_Glyph  glyphb;          FT_Glyph  glyph;
141    
142          error = FT_Get_Glyph( slot, &glyphp );          error = FT_Get_Glyph( slot, &glyph );
143          if ( error )          if ( error )
144            goto Next;            goto Next;
145    
146          error = FT_Glyph_Stroke( &glyphp, stroker, 1 );          error = FT_Glyph_Stroke( &glyph, stroker, 1 );
147          if ( error )          if ( error )
148          {          {
149            FT_Done_Glyph( glyphp );            FT_Done_Glyph( glyph );
150            goto Next;            goto Next;
151          }          }
152    
153          error = glyph_to_bitmap( glyphp, &bit3, &left, &top,          error = FTDemo_Draw_Glyph( handle, display, glyph, &x, &y );
154                                   &x_advance, &y_advance, (FT_Pointer*)&glyphb );          FT_Done_Glyph( glyph );
         if ( !error )  
         {  
           /* now render the bitmap into the display surface */  
           x_top = x + left;  
           y_top = y - top;  
           grBlitGlyphToBitmap( &bit, &bit3, x_top, y_top, fore_color );  
   
           FT_Done_Glyph( glyphb );  
           FT_Done_Glyph( glyphp );  
   
           x += x_advance + 1;  
   
           if ( x + size->metrics.x_ppem > bit.width )  
           {  
             x  = start_x;  
             y += step_y;  
   
             if ( y >= bit.rows )  
               goto Exit;  
           }  
         }  
         else  
           FT_Done_Glyph( glyphp );  
155    
156          if ( error )          if ( error )
157            goto Next;            status.Fail++;
158            else if ( X_TOO_LONG( x, size, display ) )
159            {
160              x  = start_x;
161              y += step_y;
162    
163              if ( Y_TOO_LONG( y, size, display ) )
164                break;
165            }
166        }        }
167        else        else
168        {        {
169        Next:  Next:
170          Fail++;          status.Fail++;
171        }        }
172    
173        i++;        i++;
# Line 192  Line 181 
181    }    }
182    
183    
   /* most code is copied from Render_Stroke */  
184    static FT_Error    static FT_Error
185    Render_Embolden( int  first_index )    Render_Embolden( int  num_indices,
186                       int  first_index )
187    {    {
188      FT_F26Dot6     start_x, start_y, step_x, step_y, x, y;      int       start_x, start_y, step_x, step_y, x, y;
189      FTC_ScalerRec  scaler;      int       i;
190      int            i;      FT_Size   size;
     grBitmap       bit3;  
   
   
     start_x = 4;  
     start_y = 16 + current_font.height;  
191    
192    
193      scaler.face_id = current_font.face_id;      error = FTDemo_Get_Size( handle, &size );
     scaler.width   = current_font.width;  
     scaler.height  = current_font.height;  
     scaler.pixel   = 1;  
194    
     error = FTC_Manager_LookupSize( cache_manager, &scaler, &size );  
195      if ( error )      if ( error )
196        goto Exit;      {
197          /* probably a non-existent bitmap font size */
198      step_x = size->metrics.x_ppem + 4;        return error;
199      step_y = ( size->metrics.height >> 6 ) + 4;      }
200    
201      x = start_x;      INIT_SIZE( size, start_x, start_y, step_x, step_y, x, y );
     y = start_y;  
202    
203      i = first_index;      i = first_index;
     i = first_index;  
204    
205      while ( i < face->num_glyphs )      while ( i < num_indices )
206      {      {
207        int           left, top, x_advance, y_advance, x_top, y_top;        int           gindex;
208        FT_GlyphSlot  slot = size->face->glyph;        FT_Face       face = size->face;
209        FT_Glyph      glyphp;  
210          if ( handle->encoding == FT_ENCODING_NONE )
211  #if 0          gindex = i;
212        gindex = *(unsigned char*)p;        else
213        if ( encoding == FT_ENCODING_NONE )          gindex = FTDemo_Get_Index( handle, i );
214          gindex = get_glyph_index( gindex );  
215  #endif        error = FT_Load_Glyph( face, gindex, handle->image_type.flags );
       error = FT_Load_Glyph( size->face, i, FT_LOAD_DEFAULT );  
216        if ( !error )        if ( !error )
217        {        {
218          FT_Glyph  glyphb;          FT_GlyphSlot_Embolden( face->glyph );
219    
220            error = FTDemo_Draw_Slot( handle, display, face->glyph, &x, &y );
221    
         FT_GlyphSlot_Embolden( slot );  
         error = FT_Get_Glyph( slot, &glyphp );  
222          if ( error )          if ( error )
223            goto Next;            status.Fail++;
224            else if ( X_TOO_LONG( x, size, display ) )
         error = glyph_to_bitmap( glyphp, &bit3, &left, &top,  
                                  &x_advance, &y_advance,  
                                  (FT_Pointer*)&glyphb );  
         if ( !error )  
225          {          {
226            /* now render the bitmap into the display surface */            x  = start_x;
227            x_top = x + left;            y += step_y;
           y_top = y - top;  
           grBlitGlyphToBitmap( &bit, &bit3, x_top, y_top, fore_color );  
   
           FT_Done_Glyph( glyphb );  
           FT_Done_Glyph( glyphp );  
   
           x += x_advance + 1;  
   
           if ( x + size->metrics.x_ppem > bit.width )  
           {  
             x  = start_x;  
             y += step_y;  
   
             if ( y >= bit.rows )  
               goto Exit;  
           }  
         }  
         else  
           FT_Done_Glyph( glyphp );  
228    
229          if ( error )            if ( Y_TOO_LONG( y, size, display ) )
230            goto Next;              break;
231            }
232        }        }
233        else        else
234        {          status.Fail++;
       Next:  
         Fail++;  
       }  
235    
236        i++;        i++;
237      }      }
238    
   Exit:  
239      return error;      return error;
240    }    }
241    
242    
243    static FT_Error    static FT_Error
244    Render_All( int  first_index )    Render_All( int  num_indices,
245                  int  first_index )
246    {    {
247      FT_F26Dot6     start_x, start_y, step_x, step_y, x, y;      int         start_x, start_y, step_x, step_y, x, y;
248      FTC_ScalerRec  scaler;      int         i;
249      FT_Pointer     glyf;      FT_Size     size;
     int            i;  
     grBitmap       bit3;  
   
250    
     start_x = 4;  
     start_y = 16 + current_font.height;  
251    
252      scaler.face_id = current_font.face_id;      error = FTDemo_Get_Size( handle, &size );
     scaler.width   = current_font.width;  
     scaler.height  = current_font.height;  
     scaler.pixel   = 1;  
253    
     error = FTC_Manager_LookupSize( cache_manager, &scaler, &size );  
254      if ( error )      if ( error )
255      {      {
256        /* probably a non-existent bitmap font size */        /* probably a non-existent bitmap font size */
257        return error;        return error;
258      }      }
259    
260      step_x = size->metrics.x_ppem + 4;      INIT_SIZE( size, start_x, start_y, step_x, step_y, x, y );
     step_y = ( size->metrics.height >> 6 ) + 4;  
   
     x = start_x;  
     y = start_y;  
261    
262      i = first_index;      i = first_index;
263    
 #if 0  
     while ( i < first_index + 1 )  
 #else  
264      while ( i < num_indices )      while ( i < num_indices )
 #endif  
265      {      {
266        int  x_top, y_top, left, top, x_advance, y_advance;        int  gindex;
267    
268    
269        error = get_glyph_bitmap( i, &bit3, &left, &top,        if ( handle->encoding == FT_ENCODING_NONE )
270                                  &x_advance, &y_advance, &glyf );          gindex = i;
271        if ( !error )        else
272        {          gindex = FTDemo_Get_Index( handle, i );
         /* now render the bitmap into the display surface */  
         x_top = x + left;  
         y_top = y - top;  
         grBlitGlyphToBitmap( &bit, &bit3, x_top, y_top, fore_color );  
   
         if ( glyf )  
           done_glyph_bitmap( glyf );  
   
         x += x_advance + 1;  
273    
274          if ( x + size->metrics.x_ppem > bit.width )        error = FTDemo_Draw_Index( handle, display, gindex, &x, &y );
275          {        if ( error )
276            x  = start_x;          status.Fail++;
277            y += step_y;        else if ( X_TOO_LONG( x, size, display ) )
278          {
279            x  = start_x;
280            y += step_y;
281    
282            if ( y >= bit.rows )          if ( Y_TOO_LONG( y, size, display ) )
283              return FT_Err_Ok;            break;
         }  
284        }        }
       else  
         Fail++;  
285    
286        i++;        i++;
287      }      }
# Line 366  Line 291 
291    
292    
293    static FT_Error    static FT_Error
294    Render_Text( int  first_index )    Render_Text( int  num_indices,
295                   int  first_index )
296    {    {
297      FT_F26Dot6     start_x, start_y, step_x, step_y, x, y;      int      start_x, start_y, step_x, step_y, x, y;
298      FTC_ScalerRec  scaler;      int      i;
299      FT_Pointer     glyf;      FT_Size  size;
     int            i;  
     grBitmap       bit3;  
300    
301      const unsigned char*  p;      const unsigned char*  p;
302    
303    
304      start_x = 4;      error = FTDemo_Get_Size( handle, &size );
     start_y = 16 + current_font.height;  
   
     scaler.face_id = current_font.face_id;  
     scaler.width   = current_font.width;  
     scaler.height  = current_font.height;  
     scaler.pixel   = 1;  
   
     error = FTC_Manager_LookupSize( cache_manager, &scaler, &size );  
305      if ( error )      if ( error )
306      {      {
307        /* probably a non-existent bitmap font size */        /* probably a non-existent bitmap font size */
308        return error;        return error;
309      }      }
310    
311      step_x = size->metrics.x_ppem + 4;      INIT_SIZE( size, start_x, start_y, step_x, step_y, x, y );
     step_y = ( size->metrics.height >> 6 ) + 4;  
   
     x = start_x;  
     y = start_y;  
312    
313      i = first_index;      i = first_index;
314    
315      p = Text;      p = Text;
316    
317      while ( i > 0 && *p )      while ( i > 0 && *p )
318      {      {
319        p++;        p++;
# Line 408  Line 322 
322    
323      while ( *p )      while ( *p )
324      {      {
       int      left, top, x_advance, y_advance, x_top, y_top;  
325        FT_UInt  gindex;        FT_UInt  gindex;
326    
327    
328        gindex = *(unsigned char*)p;        gindex = FTDemo_Get_Index( handle, *p );
       if ( encoding == FT_ENCODING_NONE )  
         gindex = get_glyph_index( gindex );  
   
       /* if a cmap is active, `get_glyph_bitmap' will convert the */  
       /* char code in `gindex' to a real glyph index              */  
       error = get_glyph_bitmap( gindex, &bit3, &left, &top,  
                                 &x_advance, &y_advance, &glyf );  
       if ( !error )  
       {  
         /* now render the bitmap into the display surface */  
         x_top = x + left;  
         y_top = y - top;  
         grBlitGlyphToBitmap( &bit, &bit3, x_top, y_top, fore_color );  
   
         if ( glyf )  
           done_glyph_bitmap( glyf );  
   
         x += x_advance + 1;  
329    
330          if ( x + size->metrics.x_ppem > bit.width )        error = FTDemo_Draw_Index( handle, display, gindex, &x, &y );
331          {        if ( error )
332            x  = start_x;          status.Fail++;
333            y += step_y;        else if ( X_TOO_LONG( x, size, display ) )
334          {
335            x  = start_x;
336            y += step_y;
337    
338            if ( y >= bit.rows )          if ( Y_TOO_LONG( y, size, display ) )
339              return FT_Err_Ok;            break;
         }  
340        }        }
       else  
         Fail++;  
341    
342        p++;        p++;
343      }      }
# Line 454  Line 349 
349    static FT_Error    static FT_Error
350    Render_Waterfall( int  first_size )    Render_Waterfall( int  first_size )
351    {    {
352      FT_F26Dot6  start_x, start_y, step_x, step_y, x, y;      int         start_x, start_y, step_x, step_y, x, y;
     FT_Pointer  glyf;  
353      int         pt_size, max_size = 100000;      int         pt_size, max_size = 100000;
354      grBitmap    bit3;      FT_Size     size;
355        FT_Face     face;
356    
357      unsigned char         text[256];      unsigned char         text[256];
358      const unsigned char*  p;      const unsigned char*  p;
359    
360    
     start_x = 4;  
     start_y = 16;  
   
     pt_size = first_size;  
   
361      {      {
362        error = FTC_Manager_LookupFace( cache_manager, current_font.face_id, &face );        error = FTC_Manager_LookupFace( handle->cache_manager, handle->image_type.face_id, &face );
363        if ( error )        if ( error )
364        {        {
365          /* can't access the font file. do not render anything */          /* can't access the font file. do not render anything */
366          fprintf( stderr, "can't access font file %p\n", current_font.face_id );          fprintf( stderr, "can't access font file %p\n", handle->image_type.face_id );
367          return 0;          return 0;
368        }        }
369    
# Line 489  Line 379 
379        }        }
380      }      }
381    
382      for (;;)      start_x = 4;
383      {      start_y = 2 * HEADER_HEIGHT;
       FTC_ScalerRec  scaler;  
   
384    
385        for ( pt_size = first_size; pt_size < max_size; pt_size++ )
386        {
387        sprintf( (char*)text,        sprintf( (char*)text,
388                  "%d: the quick brown fox jumps over the lazy dog "                  "%d: the quick brown fox jumps over the lazy dog "
389                  "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", pt_size );                  "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", pt_size );
390    
391        p = text;        p = text;
392    
393        set_current_pointsize( pt_size );        FTDemo_Set_Current_Pointsize( handle, pt_size, status.res );
   
       if ( pt_size > max_size )  
         break;  
       pt_size++;  
   
       scaler.face_id = current_font.face_id;  
       scaler.width   = current_font.width;  
       scaler.height  = current_font.height;  
       scaler.pixel   = 1;  
394    
395        error = FTC_Manager_LookupSize( cache_manager, &scaler, &size );        error = FTDemo_Get_Size( handle, &size );
396        if ( error )        if ( error )
397        {        {
398          /* probably a non-existent bitmap font size */          /* probably a non-existent bitmap font size */
399          continue;          continue;
400        }        }
401    
402        step_x = size->metrics.x_ppem + 4;        step_x = ( size->metrics.max_advance >> 6 ) + 4;
403        step_y = ( size->metrics.height >> 6 ) + 1;        step_y = ( size->metrics.height >> 6 ) + 1;
404    
405        x = start_x;        x = start_x;
# Line 526  Line 407 
407    
408        start_y += step_y;        start_y += step_y;
409    
410        if ( y >= bit.rows )        if ( y >= display->bitmap->rows )
411          break;          break;
412    
413        while ( *p )        while ( *p )
414        {        {
         int      left, top, x_advance, y_advance, x_top, y_top;  
415          FT_UInt  gindex;          FT_UInt  gindex;
416    
417    
418          gindex = *(unsigned char*)p;          gindex = FTDemo_Get_Index( handle, *p );
         if ( encoding == FT_ENCODING_NONE )  
           gindex = get_glyph_index( gindex );  
   
         /* if a cmap is active, `get_glyph_bitmap' will convert the */  
         /* char code in `gindex' to a real glyph index              */  
         error = get_glyph_bitmap( gindex, &bit3, &left, &top,  
                                   &x_advance, &y_advance, &glyf );  
         if ( !error )  
         {  
           /* now render the bitmap into the display surface */  
           x_top = x + left;  
           y_top = y - top;  
           grBlitGlyphToBitmap( &bit, &bit3, x_top, y_top, fore_color );  
   
           if ( glyf )  
             done_glyph_bitmap( glyf );  
   
           x += x_advance + 1;  
419    
420            if ( x + size->metrics.x_ppem > bit.width )          error = FTDemo_Draw_Index( handle, display, gindex, &x, &y );
421              break;          if ( error )
422          }            status.Fail++;
423          else          else if ( X_TOO_LONG( x, size, display ) )
424            Fail++;            break;
425    
426          p++;          p++;
427        }        }
428      }      }
429    
430      set_current_pointsize( first_size );      FTDemo_Set_Current_Pointsize( handle, first_size, status.res );
431    
432      return FT_Err_Ok;      return FT_Err_Ok;
433    }    }
# Line 580  Line 442 
442    /*************************************************************************/    /*************************************************************************/
443    
444    static void    static void
445    Help( void )    event_help( void )
446    {    {
447      grEvent  dummy_event;      grEvent  dummy_event;
448    
449    
450      Clear_Display();      FTDemo_Display_Clear( display );
451      grGotoxy( 0, 0 );      grGotoxy( 0, 0 );
452      grSetMargin( 2, 1 );      grSetMargin( 2, 1 );
453      grGotobitmap( &bit );      grGotobitmap( display->bitmap );
454    
455      grWriteln( "FreeType Glyph Viewer - part of the FreeType test suite" );      grWriteln( "FreeType Glyph Viewer - part of the FreeType test suite" );
456      grLn();      grLn();
# Line 597  Line 459 
459      grLn();      grLn();
460      grWriteln( "Use the following keys:" );      grWriteln( "Use the following keys:" );
461      grLn();      grLn();
462      grWriteln( "  F1 or ?   : display this help screen" );      grWriteln( "  F1 or ?    : display this help screen" );
     grWriteln( "  a         : toggle anti-aliasing" );  
     grWriteln( "  L         : cycle through rendering modes" );  
     grWriteln( "  h         : toggle outline hinting" );  
     grWriteln( "  b         : toggle embedded bitmaps" );  
     grWriteln( "  l         : toggle low precision rendering" );  
     grWriteln( "  f         : toggle forced auto-hinting" );  
     grWriteln( "  space     : toggle rendering mode" );  
463      grLn();      grLn();
464      grWriteln( "  c         : toggle between cache modes" );      grWriteln( "  a          : toggle anti-aliasing" );
465        grWriteln( "  b          : toggle embedded bitmaps" );
466        grWriteln( "  c          : toggle between cache modes" );
467        grWriteln( "  f          : toggle forced auto-hinting" );
468        grWriteln( "  h          : toggle outline hinting" );
469        grWriteln( "  l          : toggle low precision rendering" );
470      grLn();      grLn();
471      grWriteln( "  n         : next font" );      grWriteln( "  L          : cycle through LCD modes" );
472      grWriteln( "  p         : previous font" );      grWriteln( "  space      : toggle rendering mode" );
473        grWriteln( "  1-5        : select rendering mode" );
474      grLn();      grLn();
475      grWriteln( "  g         : increase gamma by 0.1" );      grWriteln( "  G          : show gamma ramp" );
476      grWriteln( "  v         : decrease gamma by 0.1" );      grWriteln( "  g          : increase gamma by 0.1" );
477        grWriteln( "  v          : decrease gamma by 0.1" );
478      grLn();      grLn();
479      grWriteln( "  K         : show gamma ramp" );      grWriteln( "  n          : next font" );
480        grWriteln( "  p          : previous font" );
481      grLn();      grLn();
482      grWriteln( "  Up        : increase pointsize by 1 unit" );      grWriteln( "  Up         : increase pointsize by 1 unit" );
483      grWriteln( "  Down      : decrease pointsize by 1 unit" );      grWriteln( "  Down       : decrease pointsize by 1 unit" );
484      grWriteln( "  Page Up   : increase pointsize by 10 units" );      grWriteln( "  Page Up    : increase pointsize by 10 units" );
485      grWriteln( "  Page Down : decrease pointsize by 10 units" );      grWriteln( "  Page Down  : decrease pointsize by 10 units" );
486      grLn();      grLn();
487      grWriteln( "  Right     : increment index" );      grWriteln( "  Right      : increment index" );
488      grWriteln( "  Left      : decrement index" );      grWriteln( "  Left       : decrement index" );
489      grLn();      grLn();
490      grWriteln( "  F7        : decrement index by 10" );      grWriteln( "  F7         : decrement index by 10" );
491      grWriteln( "  F8        : increment index by 10" );      grWriteln( "  F8         : increment index by 10" );
492      grWriteln( "  F9        : decrement index by 100" );      grWriteln( "  F9         : decrement index by 100" );
493      grWriteln( "  F10       : increment index by 100" );      grWriteln( "  F10        : increment index by 100" );
494      grWriteln( "  F11       : decrement index by 1000" );      grWriteln( "  F11        : decrement index by 1000" );
495      grWriteln( "  F12       : increment index by 1000" );      grWriteln( "  F12        : increment index by 1000" );
496      grLn();      grLn();
497      grWriteln( "press any key to exit this help screen" );      grWriteln( "press any key to exit this help screen" );
498    
499      grRefreshSurface( surface );      grRefreshSurface( display->surface );
500      grListenSurface( surface, gr_event_key, &dummy_event );      grListenSurface( display->surface, gr_event_key, &dummy_event );
501      }
502    
503    
504      static void
505      event_gamma_grid( void )
506      {
507        grEvent  dummy_event;
508        int      g;
509        int      yside  = 11;
510        int      xside  = 10;
511        int      levels = 17;
512        int      gammas = 30;
513        int      x_0    = (display->bitmap->width - levels*xside)/2;
514        int      y_0    = (display->bitmap->rows  - gammas*(yside+1))/2;
515        int      pitch  = display->bitmap->pitch;
516    
517    
518        FTDemo_Display_Clear( display );
519        grGotobitmap( display->bitmap );
520    
521        if ( pitch < 0 )
522          pitch = -pitch;
523    
524        memset( display->bitmap->buffer, 100, pitch*display->bitmap->rows );
525    
526        grWriteCellString( display->bitmap, 0, 0, "Gamma grid", display->fore_color );
527    
528        for ( g = 1; g <= gammas; g += 1 )
529        {
530          double ggamma = g / 10.0;
531          char   temp[6];
532          int    y = y_0 + ( yside + 1 ) * ( g - 1 );
533          int    nx, ny;
534    
535          unsigned char*  line = display->bitmap->buffer + y * display->bitmap->pitch;
536    
537          if ( display->bitmap->pitch < 0 )
538            line -= display->bitmap->pitch * ( display->bitmap->rows - 1 );
539    
540          line += x_0 * 3;
541    
542          grSetPixelMargin( x_0 - 32, y + ( yside - 8 ) / 2 );
543          grGotoxy( 0, 0 );
544    
545          sprintf( temp, "%.1f", ggamma );
546          grWrite( temp );
547    
548          for ( ny = 0; ny < yside; ny++, line += display->bitmap->pitch )
549          {
550            unsigned char*  dst = line;
551    
552            for ( nx = 0; nx < levels; nx++, dst += 3 * xside )
553            {
554              double  p   = nx/(double)(levels - 1);
555              int     gm  = (int)( 255.0 * pow( p, ggamma ) );
556    
557              memset( dst, gm, xside * 3 );
558            }
559          }
560        }
561    
562    
563        grRefreshSurface( display->surface );
564        grListenSurface( display->surface, gr_event_key, &dummy_event );
565      }
566    
567    
568      static void
569      event_gamma_change( double delta )
570      {
571        status.gamma += delta;
572    
573        if ( status.gamma > 3.0 )
574          status.gamma = 3.0;
575        else if ( status.gamma < 0.0 )
576          status.gamma = 0.0;
577    
578        grSetGlyphGamma( status.gamma );
579    
580        sprintf( status.header_buffer, "gamma changed to %.1f%s",
581                 status.gamma, status.gamma == 0.0 ? " (sRGB mode)" : "" );
582    
583        status.header = status.header_buffer;
584      }
585    
586    
587      static void
588      event_size_change( int delta )
589      {
590        status.ptsize += delta;
591    
592        if ( status.ptsize < 1 )
593          status.ptsize = 1;
594        else if ( status.ptsize > MAXPTSIZE )
595          status.ptsize = MAXPTSIZE;
596    
597        FTDemo_Set_Current_Pointsize( handle, status.ptsize, status.res );
598      }
599    
600    
601      static void
602      event_index_change( int delta )
603      {
604        int num_indices = handle->current_font->num_indices;
605    
606    
607        status.Num += delta;
608    
609        if ( status.Num < 0 )
610          status.Num = 0;
611        else if ( status.Num >= num_indices )
612          status.Num = num_indices - 1;
613      }
614    
615    
616      static void
617      event_render_mode_change( int delta )
618      {
619    
620        if ( delta )
621        {
622          status.render_mode = ( status.render_mode + delta ) % N_RENDER_MODES;
623    
624          if ( status.render_mode < 0 )
625            status.render_mode += N_RENDER_MODES;
626        }
627    
628        switch ( status.render_mode )
629        {
630        case RENDER_MODE_ALL:
631          status.header = (char *)"rendering all glyphs in font";
632          break;
633        case RENDER_MODE_EMBOLDEN:
634          status.header = (char *)"rendering emboldened text";
635          break;
636        case RENDER_MODE_STROKE:
637          status.header = (char *)"rendering stroked text";
638          break;
639        case RENDER_MODE_TEXT:
640          status.header = (char *)"rendering test text string";
641          break;
642        case RENDER_MODE_WATERFALL:
643          status.header = (char *)"rendering glyph waterfall";
644          break;
645        }
646      }
647    
648    
649      static void
650      event_font_change( int  delta )
651      {
652        int      num_indices;
653    
654    
655        if ( status.font_index + delta >= handle->num_fonts ||
656             status.font_index + delta < 0 )
657          return;
658    
659        status.font_index += delta;
660    
661        FTDemo_Set_Current_Font( handle, handle->fonts[status.font_index] );
662        FTDemo_Set_Current_Pointsize( handle, status.ptsize, status.res );
663        FTDemo_Update_Current_Flags( handle );
664    
665        num_indices = handle->current_font->num_indices;
666    
667        if ( status.Num >= num_indices )
668          status.Num = num_indices - 1;
669    }    }
670    
671    
672    static int    static int
673    Process_Event( grEvent*  event )    Process_Event( grEvent*  event )
674    {    {
675      int  i;      int  ret = 0;
676    
677        if ( event->key >= '1' && event->key < '1' + N_RENDER_MODES )
678        {
679          status.render_mode = event->key - '1';
680          event_render_mode_change( 0 );
681    
682          return ret;
683        }
684    
685      switch ( event->key )      switch ( event->key )
686      {      {
687      case grKeyEsc:            /* ESC or q */      case grKeyEsc:
688      case grKEY( 'q' ):      case grKEY( 'q' ):
689        return 0;        ret = 1;
690          break;
691    
692        case grKeyF1:
693        case grKEY( '?' ):
694          event_help();
695          break;
696    
697      case grKEY( 'a' ):      case grKEY( 'a' ):
698        antialias  = !antialias;        handle->antialias = !handle->antialias;
699        new_header = antialias ? (char *)"anti-aliasing is now on"        status.header     = handle->antialias
700                               : (char *)"anti-aliasing is now off";                             ? (char *)"anti-aliasing is now on"
701        set_current_image_type();                             : (char *)"anti-aliasing is now off";
       return 1;  
702    
703      case grKEY( 'g' ):        FTDemo_Update_Current_Flags( handle );
704        if ( the_gamma >= 3.0 )        break;
705          the_gamma = 3.0;  
706        else      case grKEY( 'b' ):
707          the_gamma += 0.1;        handle->use_sbits = !handle->use_sbits;
708          status.header     = handle->use_sbits
709                               ? (char *)"embedded bitmaps are now used when available"
710                               : (char *)"embedded bitmaps are now ignored";
711    
712        goto SetGamma;        FTDemo_Update_Current_Flags( handle );
713          break;
714    
715      case grKEY( 'v' ):      case grKEY( 'c' ):
716        if ( the_gamma <= 0 )        handle->use_sbits_cache = !handle->use_sbits_cache;
717          the_gamma = 0;        status.header           = handle->use_sbits_cache
718        else                                   ? (char *)"now using sbits cache"
719          the_gamma -= 0.1;                                   : (char *)"now using normal cache";
720          break;
721    
722        goto SetGamma;      case grKEY( 'f' ):
723          handle->autohint = !handle->autohint;
724          status.header    = handle->autohint
725                              ? (char *)"forced auto-hinting is now on"
726                              : (char *)"forced auto-hinting is now off";
727    
728          FTDemo_Update_Current_Flags( handle );
729          break;
730    
731        case grKEY( 'h' ):
732          handle->hinted = !handle->hinted;
733          status.header  = handle->hinted
734                            ? (char *)"glyph hinting is now active"
735                            : (char *)"glyph hinting is now ignored";
736    
737          FTDemo_Update_Current_Flags( handle );
738          break;
739    
740        case grKEY( 'l' ):
741          handle->low_prec = !handle->low_prec;
742          status.header    = handle->low_prec
743                              ? (char *)"rendering precision is now forced to low"
744                              : (char *)"rendering precision is now normal";
745    
746      SetGamma:        FTDemo_Update_Current_Flags( handle );
       grSetGlyphGamma( the_gamma );  
       sprintf( Header, "gamma changed to %.1f %s", the_gamma, the_gamma == 0.0 ? "(sRGB mode)" : "" );  
       new_header = Header;  
747        break;        break;
748    
749      case grKEY( 'L' ):      case grKEY( 'L' ):
750        lcd_mode = ( lcd_mode + 1 ) % 6;        handle->lcd_mode = ( handle->lcd_mode + 1 ) % N_LCD_MODES;
751    
752        switch ( lcd_mode )        switch ( handle->lcd_mode )
753        {        {
754        case 0:        case LCD_MODE_AA:
755          new_header = (char *)"normal anti-aliased rendering on";          status.header = (char *)"normal anti-aliased rendering on";
756          break;          break;
757        case 1:        case LCD_MODE_LIGHT:
758          new_header = (char *)"light anti-aliased rendering on";          status.header = (char *)"light anti-aliased rendering on";
759          break;          break;
760        case 2:        case LCD_MODE_RGB:
761          new_header = (char *)"horizontal LCD-optimized rendering on (RGB)";          status.header = (char *)"horizontal LCD-optimized rendering on (RGB)";
762          break;          break;
763        case 3:        case LCD_MODE_BGR:
764          new_header = (char *)"horizontal LCD-optimized rendering on (BGR)";          status.header = (char *)"horizontal LCD-optimized rendering on (BGR)";
765          break;          break;
766        case 4:        case LCD_MODE_VRGB:
767          new_header = (char *)"vertical LCD-optimized rendering on (RGB)";          status.header = (char *)"vertical LCD-optimized rendering on (RGB)";
768          break;          break;
769        case 5:        case LCD_MODE_VBGR:
770          new_header = (char *)"vertical LCD-optimized rendering on (BGR)";          status.header = (char *)"vertical LCD-optimized rendering on (BGR)";
771          break;          break;
       default:  
         ;  
772        }        }
       set_current_image_type();  
       return 1;  
   
     case grKEY( 'c' ):  
       use_sbits_cache = !use_sbits_cache;  
       new_header = use_sbits_cache ? (char *)"now using sbits cache"  
                                    : (char *)"now using normal cache";  
       return 1;  
773    
774      case grKEY( 'f' ):        FTDemo_Update_Current_Flags( handle );
775        autohint = !autohint;        break;
       new_header = autohint ? (char *)"forced auto-hinting is now on"  
                             : (char *)"forced auto-hinting is now off";  
       set_current_image_type();  
       return 1;  
   
     case grKEY( 'b' ):  
       use_sbits  = !use_sbits;  
       new_header = use_sbits  
                      ? (char *)"embedded bitmaps are now used when available"  
                      : (char *)"embedded bitmaps are now ignored";  
       set_current_image_type();  
       return 1;  
776    
777      case grKEY( 'n' ):      case grKEY( ' ' ):
778      case grKEY( 'p' ):        event_render_mode_change( 1 );
779        return (int)event->key;        break;
780    
781      case grKEY( 'l' ):      case grKEY( 'G' ):
782        low_prec   = !low_prec;        event_gamma_grid();
       new_header = low_prec  
                      ? (char *)"rendering precision is now forced to low"  
                      : (char *)"rendering precision is now normal";  
783        break;        break;
784    
785      case grKEY( 'h' ):      case grKEY( 'g' ):
786        hinted     = !hinted;        event_gamma_change( 0.1 );
       new_header = hinted ? (char *)"glyph hinting is now active"  
                           : (char *)"glyph hinting is now ignored";  
       set_current_image_type();  
787        break;        break;
788    
789      case grKEY( 'K' ):      case grKEY( 'v' ):
790        render_mode = RENDER_MODE_GAMMAGRID;        event_gamma_change( -0.1 );
       new_header = (char*)"rendering gamma grid";  
791        break;        break;
792    
793      case grKEY( ' ' ):      case grKEY( 'n' ):
794        render_mode = ( render_mode + 1 ) % RENDER_MODE_GAMMAGRID;        event_font_change( 1 );
       switch ( render_mode )  
       {  
       case RENDER_MODE_ALL:  
         new_header = (char*)"rendering all glyphs in font";  
         break;  
       case RENDER_MODE_EMBOLDEN:  
         new_header = (char*)"rendering emboldened text";  
         break;  
       case RENDER_MODE_STROKE:  
         new_header = (char*)"rendering stroked text";  
         break;  
       case RENDER_MODE_TEXT:  
         new_header = (char*)"rendering test text string";  
         break;  
       case RENDER_MODE_WATERFALL:  
         new_header = (char*)"rendering glyph waterfall";  
         break;  
       case RENDER_MODE_GAMMAGRID: /* never happen */  
         new_header = (char*)"rendering gamma grid";  
         break;  
       }  
795        break;        break;
796    
797      case grKeyF1:      case grKEY( 'p' ):
798      case grKEY( '?' ):        event_font_change( -1 );
799        Help();        break;
       return 1;  
800    
801      case grKeyPageUp:   i =    10; goto Do_Scale;      case grKeyUp:       event_size_change(   1 ); break;
802      case grKeyPageDown: i =   -10; goto Do_Scale;      case grKeyDown:     event_size_change(  -1 ); break;
803      case grKeyUp:       i =     1; goto Do_Scale;      case grKeyPageUp:   event_size_change(  10 ); break;
804      case grKeyDown:     i =    -1; goto Do_Scale;      case grKeyPageDown: event_size_change( -10 ); break;
805    
806      case grKeyLeft:     i =    -1; goto Do_Glyph;      case grKeyLeft:  event_index_change(    -1 ); break;
807      case grKeyRight:    i =     1; goto Do_Glyph;      case grKeyRight: event_index_change(     1 ); break;
808      case grKeyF7:       i =   -10; goto Do_Glyph;      case grKeyF7:    event_index_change(   -10 ); break;
809      case grKeyF8:       i =    10; goto Do_Glyph;      case grKeyF8:    event_index_change(    10 ); break;
810      case grKeyF9:       i =  -100; goto Do_Glyph;      case grKeyF9:    event_index_change(  -100 ); break;
811      case grKeyF10:      i =   100; goto Do_Glyph;      case grKeyF10:   event_index_change(   100 ); break;
812      case grKeyF11:      i = -1000; goto Do_Glyph;      case grKeyF11:   event_index_change( -1000 ); break;
813      case grKeyF12:      i =  1000; goto Do_Glyph;      case grKeyF12:   event_index_change(  1000 ); break;
814    
815      default:      default:
816        ;        ;
817      }      }
     return 1;  
   
   Do_Scale:  
     ptsize += i;  
     if ( ptsize < 1 )         ptsize = 1;  
     if ( ptsize > MAXPTSIZE ) ptsize = MAXPTSIZE;  
     return 1;  
   
   Do_Glyph:  
     Num += i;  
     if ( Num < 0 )            Num = 0;  
     if ( Num >= num_indices ) Num = num_indices - 1;  
818    
819      return 1;      return ret;
820    }    }
821    
822    
823      static char*
824      error_message( FT_Error error_code )
825      {
826        FT_Face      face;
827        const char*  basename;
828    
829    
830        error = FTC_Manager_LookupFace( handle->cache_manager,
831                                        handle->image_type.face_id, &face );
832        if ( error )
833          PanicZ( "can't access font file" );
834          
835        basename = ft_basename( handle->current_font->filepathname );
836    
837        switch ( error_code )
838        {
839          case FT_Err_Ok:
840            sprintf( status.header_buffer, "%s %s (file `%s')", face->family_name,
841                face->style_name, basename );
842            break;
843          case FT_Err_Invalid_Pixel_Size:
844            sprintf( status.header_buffer, "Invalid pixel size (file `%s')", basename );
845            break;
846          case FT_Err_Invalid_PPem:
847            sprintf( status.header_buffer, "Invalid ppem value (file `%s')", basename );
848            break;
849          default:
850            sprintf( status.header_buffer, "File `%s': error 0x%04x", basename,
851                (FT_UShort)error_code );
852            break;
853        }
854    
855        return status.header_buffer;
856      }
857    
858    static void    static void
859    usage( char*  execname )    usage( char*  execname )
860    {    {
# Line 823  Line 862 
862      fprintf( stderr,  "ftview: simple glyph viewer -- part of the FreeType project\n" );      fprintf( stderr,  "ftview: simple glyph viewer -- part of the FreeType project\n" );
863      fprintf( stderr,  "-----------------------------------------------------------\n" );      fprintf( stderr,  "-----------------------------------------------------------\n" );
864      fprintf( stderr,  "\n" );      fprintf( stderr,  "\n" );
865      fprintf( stderr,  "Usage: %s [options below] ppem fontname[.ttf|.ttc] ...\n",      fprintf( stderr,  "Usage: %s [status below] ppem fontname[.ttf|.ttc] ...\n",
866               execname );               execname );
867      fprintf( stderr,  "\n" );      fprintf( stderr,  "\n" );
868      fprintf( stderr,  "  -r R      use resolution R dpi (default: 72 dpi)\n" );      fprintf( stderr,  "  -r R      use resolution R dpi (default: 72 dpi)\n" );
# Line 836  Line 875 
875    }    }
876    
877    
878    int    static void
879    main( int    argc,    parse_cmdline( int*    argc,
880          char*  argv[] )                   char**  argv[] )
881    {    {
882      int          old_ptsize, orig_ptsize, font_index;      char*  execname;
883      int          first_index = 0;      int    option;
     int          XisSetup = 0;  
     char*        execname;  
     int          option;  
     const char*  Header_format;  
   
     grEvent      event;  
884    
885    
886      execname = ft_basename( argv[0] );      execname = ft_basename( (*argv)[0] );
887    
888      while ( 1 )      while ( 1 )
889      {      {
890        option = getopt( argc, argv, "Dde:f:l:r:" );        option = getopt( *argc, *argv, "Dde:f:l:r:" );
891    
892        if ( option == -1 )        if ( option == -1 )
893          break;          break;
# Line 862  Line 895 
895        switch ( option )        switch ( option )
896        {        {
897        case 'd':        case 'd':
898          debug = 1;          status.debug = 1;
899          break;          break;
900    
901        case 'D':        case 'D':
902          dump_cache_stats = 1;          status.dump_cache_stats = 1;
903          break;          break;
904    
905        case 'e':        case 'e':
906          encoding = (FT_Encoding)make_tag( optarg );          status.encoding = FTDemo_Make_Encoding_Tag( optarg );
907          break;          break;
908    
909        case 'f':        case 'f':
910          first_index = atoi( optarg );          status.Num  = atoi( optarg );
911          break;          break;
912    
913        case 'l':        case 'l':
914          trace_level = atoi( optarg );          status.trace_level = atoi( optarg );
915          if ( trace_level < 1 || trace_level > 7 )          if ( status.trace_level < 1 || status.trace_level > 7 )
916            usage( execname );            usage( execname );
917          break;          break;
918    
919        case 'r':        case 'r':
920          res = atoi( optarg );          status.res = atoi( optarg );
921          if ( res < 1 )          if ( status.res < 1 )
922            usage( execname );            usage( execname );
923          break;          break;
924    
# Line 895  Line 928 
928        }        }
929      }      }
930    
931      argc -= optind;      *argc -= optind;
932      argv += optind;      *argv += optind;
933    
934      Header_format = encoding != FT_ENCODING_NONE      if ( *argc <= 1 )
                       ? "at %d points, first char code = 0x%x"  
                       : "at %d points, first glyph index = %d";  
   
     if ( argc <= 1 )  
935        usage( execname );        usage( execname );
936    
937      if ( sscanf( argv[0], "%d", &orig_ptsize ) != 1 )      status.ptsize = atoi( *argv[0] );
938        orig_ptsize = 64;      if ( status.ptsize == 0 )
939          status.ptsize = 64;
940    
941        (*argc)--;
942        (*argv)++;
943      }
944    
945    
946      int
947      main( int    argc,
948            char*  argv[] )
949      {
950        grEvent      event;
951        const char*  header_format;
952        
953    
954        parse_cmdline( &argc, &argv );
955    
956  #if FREETYPE_MAJOR == 2 && FREETYPE_MINOR == 0 && FREETYPE_PATCH <= 8  #if FREETYPE_MAJOR == 2 && FREETYPE_MINOR == 0 && FREETYPE_PATCH <= 8
957      if ( debug )      if ( status.debug )
958      {      {
959  #  ifdef FT_DEBUG_LEVEL_TRACE  #  ifdef FT_DEBUG_LEVEL_TRACE
960        FT_SetTraceLevel( trace_any, (FT_Byte)trace_level );        FT_SetTraceLevel( trace_any, (FT_Byte)status.trace_level );
961  #  else  #  else
962        trace_level = 0;        status.trace_level = 0;
963  #  endif  #  endif
964      }      }
965  #elif 0  #elif 0
966         /* "setenv/putenv" is not ANSI and I don't want to mess */         /* "setenv/putenv" is not ANSI and I don't want to mess */
967         /* with this portability issue right now..              */         /* with this portability issue right now..              */
968      if ( debug )      if ( status.debug )
969      {      {
970        char  temp[32];        char  temp[32];
971    
972        sprintf( temp, "any=%d", trace_level );        sprintf( temp, "any=%d", status.trace_level );
973        setenv( "FT2_DEBUG", temp );        setenv( "FT2_DEBUG", temp );
974      }      }
975  #endif  #endif
976    
977        header_format = status.encoding != FT_ENCODING_NONE
978                        ? "at %d points, first char code = 0x%x"
979                        : "at %d points, first glyph index = %d";
980    
981      /* Initialize engine */      /* Initialize engine */
982      init_freetype();      handle = FTDemo_New( status.encoding );
983    
     argc--;  
     argv++;  
984      for ( ; argc > 0; argc--, argv++ )      for ( ; argc > 0; argc--, argv++ )
985        install_font_file( argv[0] );        FTDemo_Install_Font( handle, argv[0] );
986    
987      if ( num_fonts == 0 )      if ( handle->num_fonts == 0 )
988        PanicZ( "could not find/open any font file" );        PanicZ( "could not find/open any font file" );
989    
990      font_index = 0;      display = FTDemo_Display_New( gr_pixel_mode_rgb24 );
991      ptsize     = orig_ptsize;      if ( !display )
992          PanicZ( "could not allocate display surface" );
   NewFile:  
     set_current_face( fonts[font_index] );  
     set_current_pointsize( ptsize );  
     set_current_image_type();  
     num_indices = fonts[font_index]->num_indices;  
   
     error = FTC_Manager_LookupFace( cache_manager,  
                                     current_font.face_id, &face );  
     if ( error )  
     {  
       /* can't access the font file; do not render anything */  
       fprintf( stderr, "can't access font file %p\n",  
                current_font.face_id );  
       exit( 1 );  
     }  
   
     /* initialize graphics if needed */  
     if ( !XisSetup )  
     {  
       XisSetup = 1;  
       Init_Display();  
     }  
   
     grSetTitle( surface, "FreeType Glyph Viewer - press F1 for help" );  
     old_ptsize = ptsize;  
993    
994      if ( num_fonts >= 1 )      memset( display->fore_color.chroma, 0, 4 );
995      {      memset( display->back_color.chroma, 0xff, 4 );
996        Fail = 0;      grSetTitle( display->surface, "FreeType Glyph Viewer - press F1 for help" );
       Num  = first_index;  
997    
998        if ( Num >= num_indices )      status.Fail = 0;
         Num = num_indices - 1;  
999    
1000        if ( Num < 0 )      event_font_change( 0 );
         Num = 0;  
     }  
1001    
1002      for ( ;; )      for ( ;; )
1003      {      {
1004        int  key;        FTDemo_Display_Clear( display );
1005    
1006          switch ( status.render_mode )
       Clear_Display();  
   
       if ( num_fonts >= 1 )  
1007        {        {
1008          error = FT_Err_Ok;        case RENDER_MODE_ALL:
1009            error = Render_All( handle->current_font->num_indices, status.Num );
1010            break;
         switch ( render_mode )  
         {  
         case RENDER_MODE_ALL:  
           error = Render_All( Num );  
           break;  
   
         case RENDER_MODE_EMBOLDEN:  
           error = Render_Embolden( Num );  
           break;  
   
         case RENDER_MODE_STROKE:  
           error = Render_Stroke( Num );  
           break;  
   
         case RENDER_MODE_TEXT:  
           error = Render_Text( Num );  
           break;  
1011    
1012          case RENDER_MODE_WATERFALL:        case RENDER_MODE_EMBOLDEN:
1013            error = Render_Waterfall( ptsize );          error = Render_Embolden( handle->current_font->num_indices, status.Num );
1014            break;          break;
1015    
1016          case RENDER_MODE_GAMMAGRID:        case RENDER_MODE_STROKE:
1017            error = Render_GammaGrid();          error = Render_Stroke( handle->current_font->num_indices, status.Num );
1018            render_mode = RENDER_MODE_ALL;          break;
         }  
1019    
1020          if ( !new_header )        case RENDER_MODE_TEXT:
1021          {          error = Render_Text( handle->current_font->num_indices, status.Num );
1022            if ( size )          break;
             sprintf( Header, "%s %s (file `%s')",  
               face->family_name,  
               face->style_name,  
               ft_basename( ((PFont)current_font.face_id)->filepathname ) );  
           else  
           {  
             if ( error == FT_Err_Invalid_Pixel_Size )  
               sprintf( Header, "Invalid pixel size (file `%s')",  
                 ft_basename( ((PFont)current_font.face_id)->filepathname ) );  
             else if ( error == FT_Err_Invalid_PPem )  
               sprintf( Header, "Invalid ppem value (file `%s')",  
                 ft_basename( ((PFont)current_font.face_id)->filepathname ) );  
             else  
               sprintf( Header, "File `%s': error 0x%04x",  
                 ft_basename( ((PFont)current_font.face_id)->filepathname ),  
                 (FT_UShort)error );  
           }  
1023    
1024            new_header = Header;        case RENDER_MODE_WATERFALL:
1025          }          error = Render_Waterfall( status.ptsize );
1026            break;
1027          }
1028    
1029          grWriteCellString( &bit, 0, 0, new_header, fore_color );        if ( !status.header )
1030          new_header = 0;          status.header = error_message( error );
1031    
1032          sprintf( Header, Header_format, ptsize, Num );        /* write header */
1033        }        grWriteCellString( display->bitmap, 0, 0, status.header, display->fore_color );
1034          sprintf( status.header_buffer, header_format, status.ptsize, status.Num );
1035          grWriteCellString( display->bitmap, 0, HEADER_HEIGHT, status.header_buffer,
1036                             display->fore_color );
1037    
1038        grWriteCellString( &bit, 0, 8, Header, fore_color );        grRefreshSurface( display->surface );
       grRefreshSurface( surface );  
1039    
1040        if ( dump_cache_stats )        if ( status.dump_cache_stats )
1041        {        {
1042          /* dump simple cache manager statistics */          /* dump simple cache manager statistics */
1043          fprintf( stderr, "cache manager [ nodes, bytes, average ] = "          fprintf( stderr, "cache manager [ nodes, bytes, average ] = "
1044                           " [ %d, %ld, %f ]\n",                           " [ %d, %ld, %f ]\n",
1045                           cache_manager->num_nodes,                           handle->cache_manager->num_nodes,
1046                           cache_manager->cur_weight,                           handle->cache_manager->cur_weight,
1047                           cache_manager->num_nodes > 0                           handle->cache_manager->num_nodes > 0
1048                             ? cache_manager->cur_weight * 1.0 /                             ? handle->cache_manager->cur_weight * 1.0 /
1049                                 cache_manager->num_nodes                                 handle->cache_manager->num_nodes
1050                             : 0.0 );                             : 0.0 );
1051        }        }
1052    
1053        grListenSurface( surface, 0, &event );        status.header = 0;
1054        if ( !( key = Process_Event( &event ) ) )        grListenSurface( display->surface, 0, &event );
1055          goto End;        if ( Process_Event( &event ) )
1056            break;
       if ( key == 'n' )  
       {  
         if ( font_index + 1 < num_fonts )  
           font_index++;  
   
         goto NewFile;  
       }  
   
       if ( key == 'p' )  
       {  
         if ( font_index > 0 )  
           font_index--;  
   
         goto NewFile;  
       }  
   
       if ( ptsize != old_ptsize )  
       {  
         set_current_pointsize( ptsize );  
         old_ptsize = ptsize;  
       }  
1057      }      }
1058    
   End:  
1059      printf( "Execution completed successfully.\n" );      printf( "Execution completed successfully.\n" );
1060      printf( "Fails = %d\n", Fail );      printf( "Fails = %d\n", status.Fail );
1061    
1062      done_freetype();      FTDemo_Display_Done( display );
1063        FTDemo_Done( handle );
1064      exit( 0 );      /* for safety reasons */      exit( 0 );      /* for safety reasons */
1065    
1066      return 0;       /* never reached */      return 0;       /* never reached */
1067    }    }
1068    

Legend:
Removed from v.1.59  
changed lines
  Added in v.1.60

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26