~ubuntu-branches/ubuntu/gutsy/vnc4/gutsy

« back to all changes in this revision

Viewing changes to unix/xc/extras/freetype2/tests/gview.c

  • Committer: Bazaar Package Importer
  • Author(s): Ola Lundqvist
  • Date: 2006-05-15 20:35:17 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20060515203517-l4lre1ku942mn26k
Tags: 4.1.1+X4.3.0-10
* Correction of critical security issue. Thanks to Martin Kogler
  <e9925248@student.tuwien.ac.at> that informed me about the issue,
  and provided the patch.
  This flaw was originally found by Steve Wiseman of intelliadmin.com.
* Applied patch from Javier Kohen <jkohen@users.sourceforge.net> that
  inform the user that only 8 first characters of the password will
  actually be used when typing more than 8 characters, closes:
  #355619.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <nirvana.h>
 
2
#include NV_VIEWPORT_H
 
3
#include <stdio.h>
 
4
 
 
5
#include <ft2build.h>
 
6
#include FT_FREETYPE_H
 
7
 
 
8
/* include FreeType internals to debug hints */
 
9
#include <../src/pshinter/pshrec.h>
 
10
#include <../src/pshinter/pshalgo1.h>
 
11
#include <../src/pshinter/pshalgo2.h>
 
12
 
 
13
#include <../src/autohint/ahtypes.h>
 
14
 
 
15
 /************************************************************************/
 
16
 /************************************************************************/
 
17
 /*****                                                              *****/
 
18
 /*****                     ROOT DEFINITIONS                         *****/
 
19
 /*****                                                              *****/
 
20
 /************************************************************************/
 
21
 /************************************************************************/
 
22
 
 
23
 
 
24
#include <time.h>    /* for clock() */
 
25
 
 
26
/* SunOS 4.1.* does not define CLOCKS_PER_SEC, so include <sys/param.h> */
 
27
/* to get the HZ macro which is the equivalent.                         */
 
28
#if defined(__sun__) && !defined(SVR4) && !defined(__SVR4)
 
29
#include <sys/param.h>
 
30
#define CLOCKS_PER_SEC HZ
 
31
#endif
 
32
 
 
33
static int  first_glyph = 0;
 
34
 
 
35
static NV_Renderer   renderer;
 
36
static NV_Painter    painter;
 
37
static NV_Pixmap     target;
 
38
static NV_Error      error;
 
39
static NV_Memory     memory;
 
40
static NVV_Display   display;
 
41
static NVV_Surface   surface;
 
42
 
 
43
static FT_Library    freetype;
 
44
static FT_Face       face;
 
45
 
 
46
 
 
47
static  NV_Pos        glyph_scale;
 
48
static  NV_Pos        glyph_org_x;
 
49
static  NV_Pos        glyph_org_y;
 
50
static  NV_Transform  glyph_transform;  /* font units -> device pixels */
 
51
static  NV_Transform  size_transform;   /* subpixels  -> device pixels */
 
52
 
 
53
static  NV_Scale      grid_scale = 1.0;
 
54
 
 
55
static  int   glyph_index;
 
56
static  int   pixel_size = 12;
 
57
 
 
58
 /************************************************************************/
 
59
 /************************************************************************/
 
60
 /*****                                                              *****/
 
61
 /*****                 OPTIONS, COLORS and OTHERS                   *****/
 
62
 /*****                                                              *****/
 
63
 /************************************************************************/
 
64
 /************************************************************************/
 
65
 
 
66
static  int   option_show_axis     = 1;
 
67
static  int   option_show_dots     = 1;
 
68
static  int   option_show_stroke   = 0;
 
69
static  int   option_show_glyph    = 1;
 
70
static  int   option_show_grid     = 1;
 
71
static  int   option_show_em       = 0;
 
72
static  int   option_show_smooth   = 1;
 
73
static  int   option_show_blues    = 0;
 
74
static  int   option_show_edges    = 0;
 
75
static  int   option_show_segments = 1;
 
76
static  int   option_show_links    = 1;
 
77
static  int   option_show_indices  = 0;
 
78
 
 
79
static  int   option_show_ps_hints   = 1;
 
80
static  int   option_show_horz_hints = 1;
 
81
static  int   option_show_vert_hints = 1;
 
82
 
 
83
 
 
84
static  int   option_hinting = 1;
 
85
 
 
86
static  char  temp_message[1024];
 
87
 
 
88
static  NV_Path   symbol_dot     = NULL;
 
89
static  NV_Path   symbol_circle  = NULL;
 
90
static  NV_Path   symbol_square  = NULL;
 
91
static  NV_Path   symbol_rect_h  = NULL;
 
92
static  NV_Path   symbol_rect_v  = NULL;
 
93
 
 
94
 
 
95
 
 
96
#define  AXIS_COLOR        0xFFFF0000
 
97
#define  GRID_COLOR        0xFFD0D0D0
 
98
#define  ON_COLOR          0xFFFF2000
 
99
#define  OFF_COLOR         0xFFFF0080
 
100
#define  STRONG_COLOR      0xFF404040
 
101
#define  INTERP_COLOR      0xFF206040
 
102
#define  SMOOTH_COLOR      0xF000B040
 
103
#define  BACKGROUND_COLOR  0xFFFFFFFF
 
104
#define  TEXT_COLOR        0xFF000000
 
105
#define  EM_COLOR          0x80008000
 
106
#define  BLUES_TOP_COLOR   0x4000008F
 
107
#define  BLUES_BOT_COLOR   0x40008F00
 
108
 
 
109
#define  GHOST_HINT_COLOR  0xE00000FF
 
110
#define  STEM_HINT_COLOR   0xE02020FF
 
111
#define  STEM_JOIN_COLOR   0xE020FF20
 
112
 
 
113
#define  EDGE_COLOR        0xF0704070
 
114
#define  SEGMENT_COLOR     0xF0206040
 
115
#define  LINK_COLOR        0xF0FFFF00
 
116
#define  SERIF_LINK_COLOR  0xF0FF808F
 
117
 
 
118
/* print message and abort program */
 
119
static void
 
120
Panic( const char*  message )
 
121
{
 
122
  fprintf( stderr, "PANIC: %s\n", message );
 
123
  exit(1);
 
124
}
 
125
 
 
126
 
 
127
static void
 
128
init_symbols( void )
 
129
{
 
130
  nv_path_new_rectangle( renderer, -1, -1, 3, 3, 0, 0, &symbol_square );
 
131
  nv_path_new_rectangle( renderer, -1, -6, 2, 12, 0, 0, &symbol_rect_v );
 
132
  nv_path_new_rectangle( renderer, -6, -1, 12, 2, 0, 0, &symbol_rect_h );
 
133
  nv_path_new_circle( renderer, 0, 0, 3., &symbol_dot );
 
134
  nv_path_stroke( symbol_dot, 0.6,
 
135
                  nv_path_linecap_butt,
 
136
                  nv_path_linejoin_miter, 1.,
 
137
                  &symbol_circle );
 
138
 
 
139
  nv_path_destroy( symbol_dot );
 
140
  nv_path_new_circle( renderer, 0, 0, 2., &symbol_dot );
 
141
 
 
142
 }
 
143
 
 
144
static void
 
145
done_symbols( void )
 
146
{
 
147
  nv_path_destroy( symbol_circle );
 
148
  nv_path_destroy( symbol_dot );
 
149
  nv_path_destroy( symbol_rect_v );
 
150
  nv_path_destroy( symbol_rect_h );
 
151
  nv_path_destroy( symbol_square );
 
152
}
 
153
 
 
154
 /************************************************************************/
 
155
 /************************************************************************/
 
156
 /*****                                                              *****/
 
157
 /*****                     COMMON GRID DRAWING ROUTINES             *****/
 
158
 /*****                                                              *****/
 
159
 /************************************************************************/
 
160
 /************************************************************************/
 
161
 
 
162
static void
 
163
reset_scale( NV_Scale  scale )
 
164
{
 
165
 /* compute font units -> grid pixels scale factor */
 
166
  glyph_scale = target->width*0.75 / face->units_per_EM * scale;
 
167
 
 
168
 /* setup font units -> grid pixels transform */
 
169
  nv_transform_set_scale( &glyph_transform, glyph_scale, -glyph_scale );
 
170
  glyph_org_x = glyph_transform.delta.x = target->width*0.125;
 
171
  glyph_org_y = glyph_transform.delta.y = target->height*0.875;
 
172
 
 
173
 /* setup subpixels -> grid pixels transform */
 
174
  nv_transform_set_scale( &size_transform,
 
175
                            glyph_scale/nv_fromfixed(face->size->metrics.x_scale),
 
176
                          - glyph_scale/nv_fromfixed(face->size->metrics.y_scale) );
 
177
 
 
178
  size_transform.delta = glyph_transform.delta;
 
179
}
 
180
 
 
181
 
 
182
static void
 
183
reset_size( int  pixel_size, NV_Scale  scale )
 
184
{
 
185
  FT_Set_Pixel_Sizes( face, pixel_size, pixel_size );
 
186
  reset_scale( scale );
 
187
}
 
188
 
 
189
 
 
190
static void
 
191
clear_background( void )
 
192
{
 
193
  nv_pixmap_fill_rect( target, 0, 0, target->width, target->height,
 
194
                       BACKGROUND_COLOR );
 
195
}
 
196
 
 
197
 
 
198
static void
 
199
draw_grid( void )
 
200
{
 
201
  int  x = (int)glyph_org_x;
 
202
  int  y = (int)glyph_org_y;
 
203
 
 
204
  /* draw grid */
 
205
  if ( option_show_grid )
 
206
  {
 
207
    NV_Scale  min, max, x, step;
 
208
 
 
209
    /* draw vertical grid bars */
 
210
    step = 64. * size_transform.matrix.xx;
 
211
    if (step > 1.)
 
212
    {
 
213
      min  = max = glyph_org_x;
 
214
      while ( min - step >= 0 )             min -= step;
 
215
      while ( max + step < target->width )  max += step;
 
216
 
 
217
      for ( x = min; x <= max; x += step )
 
218
        nv_pixmap_fill_rect( target, (NV_Int)(x+.5), 0,
 
219
                             1, target->height, GRID_COLOR );
 
220
    }
 
221
 
 
222
    /* draw horizontal grid bars */
 
223
    step = -64. * size_transform.matrix.yy;
 
224
    if (step > 1.)
 
225
    {
 
226
      min  = max = glyph_org_y;
 
227
      while ( min - step >= 0 )              min -= step;
 
228
      while ( max + step < target->height )  max += step;
 
229
 
 
230
      for ( x = min; x <= max; x += step )
 
231
        nv_pixmap_fill_rect( target, 0, (NV_Int)(x+.5),
 
232
                             target->width, 1, GRID_COLOR );
 
233
    }
 
234
  }
 
235
 
 
236
  /* draw axis */
 
237
  if ( option_show_axis )
 
238
  {
 
239
    nv_pixmap_fill_rect( target, x, 0, 1, target->height, AXIS_COLOR );
 
240
    nv_pixmap_fill_rect( target, 0, y, target->width, 1, AXIS_COLOR );
 
241
  }
 
242
 
 
243
  if ( option_show_em )
 
244
  {
 
245
    NV_Path  path;
 
246
    NV_Path  stroke;
 
247
    NV_UInt  units = (NV_UInt)face->units_per_EM;
 
248
 
 
249
    nv_path_new_rectangle( renderer, 0, 0, units, units, 0, 0, &path );
 
250
    nv_path_transform( path, &glyph_transform );
 
251
 
 
252
    nv_path_stroke( path, 1.5, nv_path_linecap_butt, nv_path_linejoin_miter,
 
253
                    4.0, &stroke );
 
254
 
 
255
    nv_painter_set_color( painter, EM_COLOR, 256 );
 
256
    nv_painter_fill_path( painter, NULL, 0, stroke );
 
257
 
 
258
    nv_path_destroy( stroke );
 
259
    nv_path_destroy( path );
 
260
  }
 
261
 
 
262
}
 
263
 
 
264
 
 
265
 /************************************************************************/
 
266
 /************************************************************************/
 
267
 /*****                                                              *****/
 
268
 /*****            POSTSCRIPT GLOBALS ROUTINES                       *****/
 
269
 /*****                                                              *****/
 
270
 /************************************************************************/
 
271
 /************************************************************************/
 
272
 
 
273
#include <../src/pshinter/pshglob.h>
 
274
 
 
275
static void
 
276
draw_ps_blue_zones( void )
 
277
{
 
278
  if ( option_show_blues && ps_debug_globals )
 
279
  {
 
280
    PSH_Blues       blues = &ps_debug_globals->blues;
 
281
    PSH_Blue_Table  table;
 
282
    NV_Vector       v;
 
283
    FT_Int          y1, y2;
 
284
    FT_UInt         count;
 
285
    PSH_Blue_Zone   zone;
 
286
 
 
287
    /* draw top zones */
 
288
    table = &blues->normal_top;
 
289
    count = table->count;
 
290
    zone  = table->zones;
 
291
 
 
292
    for ( ; count > 0; count--, zone++ )
 
293
    {
 
294
      v.x = 0;
 
295
      if ( !ps_debug_no_horz_hints )
 
296
      {
 
297
        v.y = zone->cur_ref + zone->cur_delta;
 
298
        nv_vector_transform( &v, &size_transform );
 
299
      }
 
300
      else
 
301
      {
 
302
        v.y = zone->org_ref + zone->org_delta;
 
303
        nv_vector_transform( &v, &glyph_transform );
 
304
      }
 
305
      y1  = (int)(v.y + 0.5);
 
306
 
 
307
      v.x = 0;
 
308
      if ( !ps_debug_no_horz_hints )
 
309
      {
 
310
        v.y = zone->cur_ref;
 
311
        nv_vector_transform( &v, &size_transform );
 
312
      }
 
313
      else
 
314
      {
 
315
        v.y = zone->org_ref;
 
316
        nv_vector_transform( &v, &glyph_transform );
 
317
      }
 
318
      y2 = (int)(v.y + 0.5);
 
319
 
 
320
      nv_pixmap_fill_rect( target, 0, y1,
 
321
                           target->width, y2-y1+1,
 
322
                           BLUES_TOP_COLOR );
 
323
 
 
324
#if 0
 
325
      printf( "top [%.3f %.3f]\n", zone->cur_bottom/64.0, zone->cur_top/64.0 );
 
326
#endif
 
327
    }
 
328
 
 
329
 
 
330
    /* draw bottom zones */
 
331
    table = &blues->normal_bottom;
 
332
    count = table->count;
 
333
    zone  = table->zones;
 
334
 
 
335
    for ( ; count > 0; count--, zone++ )
 
336
    {
 
337
      v.x = 0;
 
338
      v.y = zone->cur_ref;
 
339
      nv_vector_transform( &v, &size_transform );
 
340
      y1  = (int)(v.y + 0.5);
 
341
 
 
342
      v.x = 0;
 
343
      v.y = zone->cur_ref + zone->cur_delta;
 
344
      nv_vector_transform( &v, &size_transform );
 
345
      y2 = (int)(v.y + 0.5);
 
346
 
 
347
      nv_pixmap_fill_rect( target, 0, y1,
 
348
                           target->width, y2-y1+1,
 
349
                           BLUES_BOT_COLOR );
 
350
 
 
351
#if 0
 
352
      printf( "bot [%.3f %.3f]\n", zone->cur_bottom/64.0, zone->cur_top/64.0 );
 
353
#endif
 
354
    }
 
355
  }
 
356
}
 
357
 
 
358
 /************************************************************************/
 
359
 /************************************************************************/
 
360
 /*****                                                              *****/
 
361
 /*****            POSTSCRIPT HINTER ALGORITHM 1 ROUTINES            *****/
 
362
 /*****                                                              *****/
 
363
 /************************************************************************/
 
364
 /************************************************************************/
 
365
 
 
366
#include <../src/pshinter/pshalgo1.h>
 
367
 
 
368
static int pshint_cpos     = 0;
 
369
static int pshint_vertical = -1;
 
370
 
 
371
static void
 
372
draw_ps1_hint( PSH1_Hint   hint, FT_Bool  vertical )
 
373
{
 
374
  int        x1, x2;
 
375
  NV_Vector  v;
 
376
 
 
377
 
 
378
  if ( pshint_vertical != vertical )
 
379
  {
 
380
    if (vertical)
 
381
      pshint_cpos = 40;
 
382
    else
 
383
      pshint_cpos = 10;
 
384
 
 
385
    pshint_vertical = vertical;
 
386
  }
 
387
 
 
388
  if (vertical)
 
389
  {
 
390
    if ( !option_show_vert_hints )
 
391
      return;
 
392
 
 
393
    v.x = hint->cur_pos;
 
394
    v.y = 0;
 
395
    nv_vector_transform( &v, &size_transform );
 
396
    x1 = (int)(v.x + 0.5);
 
397
 
 
398
    v.x = hint->cur_pos + hint->cur_len;
 
399
    v.y = 0;
 
400
    nv_vector_transform( &v, &size_transform );
 
401
    x2 = (int)(v.x + 0.5);
 
402
 
 
403
    nv_pixmap_fill_rect( target, x1, 0, 1, target->height,
 
404
                         psh1_hint_is_ghost(hint)
 
405
                         ? GHOST_HINT_COLOR : STEM_HINT_COLOR );
 
406
 
 
407
    if ( psh1_hint_is_ghost(hint) )
 
408
    {
 
409
      x1 --;
 
410
      x2 = x1 + 2;
 
411
    }
 
412
    else
 
413
      nv_pixmap_fill_rect( target, x2, 0, 1, target->height,
 
414
                           psh1_hint_is_ghost(hint)
 
415
                           ? GHOST_HINT_COLOR : STEM_HINT_COLOR );
 
416
 
 
417
    nv_pixmap_fill_rect( target, x1, pshint_cpos, x2+1-x1, 1,
 
418
                         STEM_JOIN_COLOR );
 
419
  }
 
420
  else
 
421
  {
 
422
    if (!option_show_horz_hints)
 
423
      return;
 
424
 
 
425
    v.y = hint->cur_pos;
 
426
    v.x = 0;
 
427
    nv_vector_transform( &v, &size_transform );
 
428
    x1 = (int)(v.y + 0.5);
 
429
 
 
430
    v.y = hint->cur_pos + hint->cur_len;
 
431
    v.x = 0;
 
432
    nv_vector_transform( &v, &size_transform );
 
433
    x2 = (int)(v.y + 0.5);
 
434
 
 
435
    nv_pixmap_fill_rect( target, 0, x1, target->width, 1,
 
436
                         psh1_hint_is_ghost(hint)
 
437
                         ? GHOST_HINT_COLOR : STEM_HINT_COLOR );
 
438
 
 
439
    if ( psh1_hint_is_ghost(hint) )
 
440
    {
 
441
      x1 --;
 
442
      x2 = x1 + 2;
 
443
    }
 
444
    else
 
445
      nv_pixmap_fill_rect( target, 0, x2, target->width, 1,
 
446
                           psh1_hint_is_ghost(hint)
 
447
                           ? GHOST_HINT_COLOR : STEM_HINT_COLOR );
 
448
 
 
449
    nv_pixmap_fill_rect( target, pshint_cpos, x2, 1, x1+1-x2,
 
450
                         STEM_JOIN_COLOR );
 
451
  }
 
452
 
 
453
#if 0
 
454
  printf( "[%7.3f %7.3f] %c\n", hint->cur_pos/64.0, (hint->cur_pos+hint->cur_len)/64.0, vertical ? 'v' : 'h' );
 
455
#endif
 
456
 
 
457
  pshint_cpos += 10;
 
458
}
 
459
 
 
460
 
 
461
 
 
462
 /************************************************************************/
 
463
 /************************************************************************/
 
464
 /*****                                                              *****/
 
465
 /*****            POSTSCRIPT HINTER ALGORITHM 2 ROUTINES            *****/
 
466
 /*****                                                              *****/
 
467
 /************************************************************************/
 
468
 /************************************************************************/
 
469
 
 
470
#include <../src/pshinter/pshalgo2.h>
 
471
 
 
472
static void
 
473
draw_ps2_hint( PSH2_Hint   hint, FT_Bool  vertical )
 
474
{
 
475
  int        x1, x2;
 
476
  NV_Vector  v;
 
477
 
 
478
  if ( pshint_vertical != vertical )
 
479
  {
 
480
    if (vertical)
 
481
      pshint_cpos = 40;
 
482
    else
 
483
      pshint_cpos = 10;
 
484
 
 
485
    pshint_vertical = vertical;
 
486
  }
 
487
 
 
488
  if (vertical)
 
489
  {
 
490
    if ( !option_show_vert_hints )
 
491
      return;
 
492
 
 
493
    v.x = hint->cur_pos;
 
494
    v.y = 0;
 
495
    nv_vector_transform( &v, &size_transform );
 
496
    x1 = (int)(v.x + 0.5);
 
497
 
 
498
    v.x = hint->cur_pos + hint->cur_len;
 
499
    v.y = 0;
 
500
    nv_vector_transform( &v, &size_transform );
 
501
    x2 = (int)(v.x + 0.5);
 
502
 
 
503
    nv_pixmap_fill_rect( target, x1, 0, 1, target->height,
 
504
                         psh2_hint_is_ghost(hint)
 
505
                         ? GHOST_HINT_COLOR : STEM_HINT_COLOR );
 
506
 
 
507
    if ( psh2_hint_is_ghost(hint) )
 
508
    {
 
509
      x1 --;
 
510
      x2 = x1 + 2;
 
511
    }
 
512
    else
 
513
      nv_pixmap_fill_rect( target, x2, 0, 1, target->height,
 
514
                           psh2_hint_is_ghost(hint)
 
515
                           ? GHOST_HINT_COLOR : STEM_HINT_COLOR );
 
516
 
 
517
    nv_pixmap_fill_rect( target, x1, pshint_cpos, x2+1-x1, 1,
 
518
                         STEM_JOIN_COLOR );
 
519
  }
 
520
  else
 
521
  {
 
522
    if (!option_show_horz_hints)
 
523
      return;
 
524
 
 
525
    v.y = hint->cur_pos;
 
526
    v.x = 0;
 
527
    nv_vector_transform( &v, &size_transform );
 
528
    x1 = (int)(v.y + 0.5);
 
529
 
 
530
    v.y = hint->cur_pos + hint->cur_len;
 
531
    v.x = 0;
 
532
    nv_vector_transform( &v, &size_transform );
 
533
    x2 = (int)(v.y + 0.5);
 
534
 
 
535
    nv_pixmap_fill_rect( target, 0, x1, target->width, 1,
 
536
                         psh2_hint_is_ghost(hint)
 
537
                         ? GHOST_HINT_COLOR : STEM_HINT_COLOR );
 
538
 
 
539
    if ( psh2_hint_is_ghost(hint) )
 
540
    {
 
541
      x1 --;
 
542
      x2 = x1 + 2;
 
543
    }
 
544
    else
 
545
      nv_pixmap_fill_rect( target, 0, x2, target->width, 1,
 
546
                           psh2_hint_is_ghost(hint)
 
547
                           ? GHOST_HINT_COLOR : STEM_HINT_COLOR );
 
548
 
 
549
    nv_pixmap_fill_rect( target, pshint_cpos, x2, 1, x1+1-x2,
 
550
                         STEM_JOIN_COLOR );
 
551
  }
 
552
 
 
553
#if 0
 
554
  printf( "[%7.3f %7.3f] %c\n", hint->cur_pos/64.0, (hint->cur_pos+hint->cur_len)/64.0, vertical ? 'v' : 'h' );
 
555
#endif
 
556
 
 
557
  pshint_cpos += 10;
 
558
}
 
559
 
 
560
 
 
561
static void
 
562
ps2_draw_control_points( void )
 
563
{
 
564
  if ( ps2_debug_glyph )
 
565
  {
 
566
    PSH2_Glyph    glyph = ps2_debug_glyph;
 
567
    PSH2_Point    point = glyph->points;
 
568
    FT_UInt       count = glyph->num_points;
 
569
    NV_Transform  transform, *trans = &transform;
 
570
    NV_Path       vert_rect;
 
571
    NV_Path       horz_rect;
 
572
    NV_Path       dot, circle;
 
573
 
 
574
    for ( ; count > 0; count--, point++ )
 
575
    {
 
576
      NV_Vector  vec;
 
577
 
 
578
      vec.x = point->cur_x;
 
579
      vec.y = point->cur_y;
 
580
      nv_vector_transform( &vec, &size_transform );
 
581
 
 
582
      nv_transform_set_translate( trans, vec.x, vec.y );
 
583
 
 
584
      if ( option_show_smooth && !psh2_point_is_smooth(point) )
 
585
      {
 
586
        nv_painter_set_color( painter, SMOOTH_COLOR, 256 );
 
587
        nv_painter_fill_path( painter, trans, 0, symbol_circle );
 
588
      }
 
589
 
 
590
      if (option_show_horz_hints)
 
591
      {
 
592
        if ( point->flags_y & PSH2_POINT_STRONG )
 
593
        {
 
594
          nv_painter_set_color( painter, STRONG_COLOR, 256 );
 
595
          nv_painter_fill_path( painter, trans, 0, symbol_rect_h );
 
596
        }
 
597
      }
 
598
 
 
599
      if (option_show_vert_hints)
 
600
      {
 
601
        if ( point->flags_x & PSH2_POINT_STRONG )
 
602
        {
 
603
          nv_painter_set_color( painter, STRONG_COLOR, 256 );
 
604
          nv_painter_fill_path( painter, trans, 0, symbol_rect_v );
 
605
        }
 
606
      }
 
607
    }
 
608
  }
 
609
}
 
610
 
 
611
 
 
612
static void
 
613
ps_print_hints( void )
 
614
{
 
615
  if ( ps_debug_hints )
 
616
  {
 
617
    FT_Int         dimension;
 
618
    PSH_Dimension  dim;
 
619
 
 
620
    for ( dimension = 1; dimension >= 0; dimension-- )
 
621
    {
 
622
      PS_Dimension  dim   = &ps_debug_hints->dimension[ dimension ];
 
623
      PS_Mask       mask  = dim->masks.masks;
 
624
      FT_UInt       count = dim->masks.num_masks;
 
625
 
 
626
      printf( "%s hints -------------------------\n",
 
627
              dimension ? "vertical" : "horizontal" );
 
628
 
 
629
      for ( ; count > 0; count--, mask++ )
 
630
      {
 
631
        FT_UInt  index;
 
632
 
 
633
        printf( "mask -> %d\n", mask->end_point );
 
634
        for ( index = 0; index < mask->num_bits; index++ )
 
635
        {
 
636
          if ( mask->bytes[ index >> 3 ] & (0x80 >> (index & 7)) )
 
637
          {
 
638
            PS_Hint  hint = dim->hints.hints + index;
 
639
 
 
640
            printf( "%c [%3d %3d (%4d)]\n", dimension ? "v" : "h",
 
641
                    hint->pos, hint->pos + hint->len, hint->len );
 
642
          }
 
643
        }
 
644
      }
 
645
    }
 
646
  }
 
647
}
 
648
 
 
649
 /************************************************************************/
 
650
 /************************************************************************/
 
651
 /*****                                                              *****/
 
652
 /*****            AUTOHINTER DRAWING ROUTINES                       *****/
 
653
 /*****                                                              *****/
 
654
 /************************************************************************/
 
655
 /************************************************************************/
 
656
 
 
657
static NV_Path
 
658
ah_link_path( NV_Vector*   p1,
 
659
              NV_Vector*   p4,
 
660
              NV_Bool      vertical )
 
661
{
 
662
  NV_PathWriter  writer;
 
663
  NV_Vector      p2, p3;
 
664
  NV_Path        path, stroke;
 
665
 
 
666
  if ( vertical )
 
667
  {
 
668
    p2.x = p4->x;
 
669
    p2.y = p1->y;
 
670
 
 
671
    p3.x = p1->x;
 
672
    p3.y = p4->y;
 
673
  }
 
674
  else
 
675
  {
 
676
    p2.x = p1->x;
 
677
    p2.y = p4->y;
 
678
 
 
679
    p3.x = p4->x;
 
680
    p3.y = p1->y;
 
681
  }
 
682
 
 
683
  nv_path_writer_new( renderer, &writer );
 
684
  nv_path_writer_moveto( writer, p1 );
 
685
  nv_path_writer_cubicto( writer, &p2, &p3, p4 );
 
686
  nv_path_writer_end( writer );
 
687
 
 
688
  path = nv_path_writer_get_path( writer );
 
689
  nv_path_writer_destroy( writer );
 
690
 
 
691
  nv_path_stroke( path, 1., nv_path_linecap_butt, nv_path_linejoin_round, 1.,  &stroke );
 
692
 
 
693
  nv_path_destroy( path );
 
694
 
 
695
  return stroke;
 
696
}
 
697
 
 
698
 
 
699
static void
 
700
ah_draw_smooth_points( void )
 
701
{
 
702
  if ( ah_debug_hinter && option_show_smooth )
 
703
  {
 
704
    AH_Outline*  glyph = ah_debug_hinter->glyph;
 
705
    FT_UInt      count = glyph->num_points;
 
706
    AH_Point*    point = glyph->points;
 
707
 
 
708
    nv_painter_set_color( painter, SMOOTH_COLOR, 256 );
 
709
 
 
710
    for ( ; count > 0; count--, point++ )
 
711
    {
 
712
      if ( !( point->flags & ah_flag_weak_interpolation ) )
 
713
      {
 
714
        NV_Transform  transform, *trans = &transform;
 
715
        NV_Vector     vec;
 
716
 
 
717
        vec.x = point->x - ah_debug_hinter->pp1.x;
 
718
        vec.y = point->y;
 
719
        nv_vector_transform( &vec, &size_transform );
 
720
 
 
721
        nv_transform_set_translate( &transform, vec.x, vec.y );
 
722
        nv_painter_fill_path( painter, trans, 0, symbol_circle );
 
723
      }
 
724
    }
 
725
  }
 
726
}
 
727
 
 
728
 
 
729
static void
 
730
ah_draw_edges( void )
 
731
{
 
732
  if ( ah_debug_hinter )
 
733
  {
 
734
    AH_Outline*  glyph = ah_debug_hinter->glyph;
 
735
    FT_UInt      count;
 
736
    AH_Edge*     edge;
 
737
    FT_Pos       pp1 = ah_debug_hinter->pp1.x;
 
738
 
 
739
    nv_painter_set_color( painter, EDGE_COLOR, 256 );
 
740
 
 
741
    if ( option_show_edges )
 
742
    {
 
743
      /* draw verticla edges */
 
744
      if ( option_show_vert_hints )
 
745
      {
 
746
        count = glyph->num_vedges;
 
747
        edge  = glyph->vert_edges;
 
748
        for ( ; count > 0; count--, edge++ )
 
749
        {
 
750
          NV_Vector     vec;
 
751
          NV_Pos        x;
 
752
 
 
753
          vec.x = edge->pos - pp1;
 
754
          vec.y = 0;
 
755
 
 
756
          nv_vector_transform( &vec, &size_transform );
 
757
          x = (FT_Pos)( vec.x + 0.5 );
 
758
 
 
759
          nv_pixmap_fill_rect( target, x, 0, 1, target->height, EDGE_COLOR );
 
760
        }
 
761
      }
 
762
 
 
763
      /* draw horizontal edges */
 
764
      if ( option_show_horz_hints )
 
765
      {
 
766
        count = glyph->num_hedges;
 
767
        edge  = glyph->horz_edges;
 
768
        for ( ; count > 0; count--, edge++ )
 
769
        {
 
770
          NV_Vector     vec;
 
771
          NV_Pos        x;
 
772
 
 
773
          vec.x = 0;
 
774
          vec.y = edge->pos;
 
775
 
 
776
          nv_vector_transform( &vec, &size_transform );
 
777
          x = (FT_Pos)( vec.y + 0.5 );
 
778
 
 
779
          nv_pixmap_fill_rect( target, 0, x, target->width, 1, EDGE_COLOR );
 
780
        }
 
781
      }
 
782
    }
 
783
 
 
784
    if ( option_show_segments )
 
785
    {
 
786
      /* draw vertical segments */
 
787
      if ( option_show_vert_hints )
 
788
      {
 
789
        AH_Segment*  seg   = glyph->vert_segments;
 
790
        FT_UInt      count = glyph->num_vsegments;
 
791
 
 
792
        for ( ; count > 0; count--, seg++ )
 
793
        {
 
794
          AH_Point  *first, *last;
 
795
          NV_Vector  v1, v2;
 
796
          NV_Pos     y1, y2, x;
 
797
 
 
798
          first = seg->first;
 
799
          last  = seg->last;
 
800
 
 
801
          v1.x = v2.x = first->x - pp1;
 
802
 
 
803
          if ( first->y <= last->y )
 
804
          {
 
805
            v1.y = first->y;
 
806
            v2.y = last->y;
 
807
          }
 
808
          else
 
809
          {
 
810
            v1.y = last->y;
 
811
            v2.y = first->y;
 
812
          }
 
813
 
 
814
          nv_vector_transform( &v1, &size_transform );
 
815
          nv_vector_transform( &v2, &size_transform );
 
816
 
 
817
          y1 = (NV_Pos)( v1.y + 0.5 );
 
818
          y2 = (NV_Pos)( v2.y + 0.5 );
 
819
          x  = (NV_Pos)( v1.x + 0.5 );
 
820
 
 
821
          nv_pixmap_fill_rect( target, x-1, y2, 3, ABS(y1-y2)+1, SEGMENT_COLOR );
 
822
        }
 
823
      }
 
824
 
 
825
      /* draw horizontal segments */
 
826
      if ( option_show_horz_hints )
 
827
      {
 
828
        AH_Segment*  seg   = glyph->horz_segments;
 
829
        FT_UInt      count = glyph->num_hsegments;
 
830
 
 
831
        for ( ; count > 0; count--, seg++ )
 
832
        {
 
833
          AH_Point  *first, *last;
 
834
          NV_Vector  v1, v2;
 
835
          NV_Pos     y1, y2, x;
 
836
 
 
837
          first = seg->first;
 
838
          last  = seg->last;
 
839
 
 
840
          v1.y = v2.y = first->y;
 
841
 
 
842
          if ( first->x <= last->x )
 
843
          {
 
844
            v1.x = first->x - pp1;
 
845
            v2.x = last->x - pp1;
 
846
          }
 
847
          else
 
848
          {
 
849
            v1.x = last->x - pp1;
 
850
            v2.x = first->x - pp1;
 
851
          }
 
852
 
 
853
          nv_vector_transform( &v1, &size_transform );
 
854
          nv_vector_transform( &v2, &size_transform );
 
855
 
 
856
          y1 = (NV_Pos)( v1.x + 0.5 );
 
857
          y2 = (NV_Pos)( v2.x + 0.5 );
 
858
          x  = (NV_Pos)( v1.y + 0.5 );
 
859
 
 
860
          nv_pixmap_fill_rect( target, y1, x-1, ABS(y1-y2)+1, 3, SEGMENT_COLOR );
 
861
        }
 
862
      }
 
863
 
 
864
 
 
865
      if ( option_show_vert_hints && option_show_links )
 
866
      {
 
867
        AH_Segment*  seg   = glyph->vert_segments;
 
868
        FT_UInt      count = glyph->num_vsegments;
 
869
 
 
870
        for ( ; count > 0; count--, seg++ )
 
871
        {
 
872
          AH_Segment*  seg2 = NULL;
 
873
          NV_Path      link;
 
874
          NV_Vector    v1, v2;
 
875
 
 
876
          if ( seg->link )
 
877
          {
 
878
            if ( seg->link > seg )
 
879
              seg2 = seg->link;
 
880
          }
 
881
          else if ( seg->serif )
 
882
            seg2 = seg->serif;
 
883
 
 
884
          if ( seg2 )
 
885
          {
 
886
            v1.x = seg->first->x  - pp1;
 
887
            v2.x = seg2->first->x - pp1;
 
888
            v1.y = (seg->first->y + seg->last->y)/2;
 
889
            v2.y = (seg2->first->y + seg2->last->y)/2;
 
890
 
 
891
            link = ah_link_path( &v1, &v2, 1 );
 
892
 
 
893
            nv_painter_set_color( painter, seg->serif ? SERIF_LINK_COLOR : LINK_COLOR, 256 );
 
894
            nv_painter_fill_path( painter, &size_transform, 0, link );
 
895
 
 
896
            nv_path_destroy( link );
 
897
          }
 
898
        }
 
899
      }
 
900
 
 
901
      if ( option_show_horz_hints && option_show_links )
 
902
      {
 
903
        AH_Segment*  seg   = glyph->horz_segments;
 
904
        FT_UInt      count = glyph->num_hsegments;
 
905
 
 
906
        for ( ; count > 0; count--, seg++ )
 
907
        {
 
908
          AH_Segment*  seg2 = NULL;
 
909
          NV_Path      link;
 
910
          NV_Vector    v1, v2;
 
911
 
 
912
          if ( seg->link )
 
913
          {
 
914
            if ( seg->link > seg )
 
915
              seg2 = seg->link;
 
916
          }
 
917
          else if ( seg->serif )
 
918
            seg2 = seg->serif;
 
919
 
 
920
          if ( seg2 )
 
921
          {
 
922
            v1.y = seg->first->y;
 
923
            v2.y = seg2->first->y;
 
924
            v1.x = (seg->first->x + seg->last->x)/2 - pp1;
 
925
            v2.x = (seg2->first->x + seg2->last->x)/2 - pp1;
 
926
 
 
927
            link = ah_link_path( &v1, &v2, 0 );
 
928
 
 
929
            nv_painter_set_color( painter, seg->serif ? SERIF_LINK_COLOR : LINK_COLOR, 256 );
 
930
            nv_painter_fill_path( painter, &size_transform, 0, link );
 
931
 
 
932
            nv_path_destroy( link );
 
933
          }
 
934
        }
 
935
      }
 
936
    }
 
937
  }
 
938
}
 
939
 
 
940
 /************************************************************************/
 
941
 /************************************************************************/
 
942
 /*****                                                              *****/
 
943
 /*****                        MAIN LOOP(S)                          *****/
 
944
 /*****                                                              *****/
 
945
 /************************************************************************/
 
946
 /************************************************************************/
 
947
 
 
948
static void
 
949
draw_glyph( int  glyph_index )
 
950
{
 
951
  NV_Path   path;
 
952
 
 
953
  pshint_vertical    = -1;
 
954
 
 
955
  ps1_debug_hint_func = option_show_ps_hints ? draw_ps1_hint : 0;
 
956
  ps2_debug_hint_func = option_show_ps_hints ? draw_ps2_hint : 0;
 
957
 
 
958
  ah_debug_hinter = NULL;
 
959
 
 
960
  error = FT_Load_Glyph( face, glyph_index, option_hinting
 
961
                                          ? FT_LOAD_NO_BITMAP
 
962
                                          : FT_LOAD_NO_BITMAP | FT_LOAD_NO_HINTING );
 
963
  if (error) Panic( "could not load glyph" );
 
964
 
 
965
  if ( face->glyph->format != ft_glyph_format_outline )
 
966
    Panic( "could not load glyph outline" );
 
967
 
 
968
  error = nv_path_new_from_outline( renderer,
 
969
                                    (NV_Outline*)&face->glyph->outline,
 
970
                                    &size_transform,
 
971
                                    &path );
 
972
  if (error) Panic( "could not create glyph path" );
 
973
 
 
974
  /* trac� du glyphe plein */
 
975
  if ( option_show_glyph )
 
976
  {
 
977
    nv_painter_set_color ( painter, 0xFF404080, 128 );
 
978
    nv_painter_fill_path ( painter, 0, 0, path );
 
979
  }
 
980
 
 
981
  if ( option_show_stroke )
 
982
  {
 
983
    NV_Path   stroke;
 
984
 
 
985
    error = nv_path_stroke( path, 0.6,
 
986
                            nv_path_linecap_butt,
 
987
                            nv_path_linejoin_miter,
 
988
                            1.0, &stroke );
 
989
    if (error) Panic( "could not stroke glyph path" );
 
990
 
 
991
    nv_painter_set_color ( painter, 0xFF000040, 256 );
 
992
    nv_painter_fill_path ( painter, 0, 0, stroke );
 
993
 
 
994
    nv_path_destroy( stroke );
 
995
  }
 
996
 
 
997
  /* trac� des points de controle */
 
998
  if ( option_show_dots )
 
999
  {
 
1000
    NV_Path     plot;
 
1001
    NV_Outline  out;
 
1002
    NV_Scale    r = 2;
 
1003
    NV_Int      n, first, last;
 
1004
 
 
1005
    nv_path_get_outline( path, NULL, memory, &out );
 
1006
 
 
1007
    first = 0;
 
1008
    for ( n = 0; n < out.n_contours; n++ )
 
1009
    {
 
1010
      int            m;
 
1011
      NV_Transform   trans;
 
1012
      NV_Color       color;
 
1013
      NV_SubVector*  vec;
 
1014
 
 
1015
      last  = out.contours[n];
 
1016
 
 
1017
      for ( m = first; m <= last; m++ )
 
1018
      {
 
1019
        color = (out.tags[m] & FT_Curve_Tag_On)
 
1020
              ? ON_COLOR
 
1021
              : OFF_COLOR;
 
1022
 
 
1023
        vec = out.points + m;
 
1024
 
 
1025
        nv_transform_set_translate( &trans, vec->x/64.0, vec->y/64.0 );
 
1026
 
 
1027
        nv_painter_set_color( painter, color, 256 );
 
1028
        nv_painter_fill_path( painter, &trans, 0, symbol_dot );
 
1029
 
 
1030
        if ( option_show_indices )
 
1031
        {
 
1032
          char  temp[5];
 
1033
 
 
1034
          sprintf( temp, "%d", m );
 
1035
          nv_pixmap_cell_text( target, vec->x/64 + 4, vec->y/64 - 4,
 
1036
                               temp, TEXT_COLOR );
 
1037
        }
 
1038
      }
 
1039
 
 
1040
      first = last + 1;
 
1041
    }
 
1042
  }
 
1043
 
 
1044
  ah_draw_smooth_points();
 
1045
  ah_draw_edges();
 
1046
 
 
1047
  nv_path_destroy( path );
 
1048
 
 
1049
  /* autre infos */
 
1050
  {
 
1051
    char  temp[1024];
 
1052
    char  temp2[64];
 
1053
 
 
1054
    sprintf( temp, "font name : %s (%s)", face->family_name, face->style_name );
 
1055
    nv_pixmap_cell_text( target, 0, 0, temp, TEXT_COLOR );
 
1056
 
 
1057
    FT_Get_Glyph_Name( face, glyph_index, temp2, 63 );
 
1058
    temp2[63] = 0;
 
1059
 
 
1060
    sprintf( temp, "glyph %4d: %s", glyph_index, temp2 );
 
1061
    nv_pixmap_cell_text( target, 0, 8, temp, TEXT_COLOR );
 
1062
 
 
1063
    if ( temp_message[0] )
 
1064
    {
 
1065
      nv_pixmap_cell_text( target, 0, 16, temp_message, TEXT_COLOR );
 
1066
      temp_message[0] = 0;
 
1067
    }
 
1068
  }
 
1069
}
 
1070
 
 
1071
 
 
1072
 
 
1073
#define  TOGGLE_OPTION(var,prefix)                           \
 
1074
            {                                                \
 
1075
              var = !var;                                    \
 
1076
              sprintf( temp_message, prefix " is now %s",    \
 
1077
                       var ? "on" : "off" );                 \
 
1078
              break;                                         \
 
1079
            }
 
1080
 
 
1081
 
 
1082
#define  TOGGLE_OPTION_NEG(var,prefix)                       \
 
1083
            {                                                \
 
1084
              var = !var;                                    \
 
1085
              sprintf( temp_message, prefix " is now %s",    \
 
1086
                       !var ? "on" : "off" );                \
 
1087
              break;                                         \
 
1088
            }
 
1089
 
 
1090
 
 
1091
static void
 
1092
handle_event( NVV_EventRec*   ev )
 
1093
{
 
1094
  switch (ev->key)
 
1095
  {
 
1096
    case NVV_Key_Left:
 
1097
      {
 
1098
        if ( glyph_index > 0 )
 
1099
          glyph_index--;
 
1100
        break;
 
1101
      }
 
1102
 
 
1103
    case NVV_Key_Right:
 
1104
      {
 
1105
        if ( glyph_index+1 < face->num_glyphs )
 
1106
          glyph_index++;
 
1107
        break;
 
1108
      }
 
1109
 
 
1110
    case NVV_KEY('x'):
 
1111
      TOGGLE_OPTION( option_show_axis, "grid axis display" )
 
1112
 
 
1113
    case NVV_KEY('s'):
 
1114
      TOGGLE_OPTION( option_show_stroke, "glyph stroke display" )
 
1115
 
 
1116
    case NVV_KEY('g'):
 
1117
      TOGGLE_OPTION( option_show_glyph, "glyph fill display" )
 
1118
 
 
1119
    case NVV_KEY('d'):
 
1120
      TOGGLE_OPTION( option_show_dots, "control points display" )
 
1121
 
 
1122
    case NVV_KEY('e'):
 
1123
      TOGGLE_OPTION( option_show_em, "EM square display" )
 
1124
 
 
1125
    case NVV_KEY('+'):
 
1126
      {
 
1127
        grid_scale *= 1.2;
 
1128
        reset_scale( grid_scale );
 
1129
        break;
 
1130
      }
 
1131
 
 
1132
    case NVV_KEY('-'):
 
1133
      {
 
1134
        if (grid_scale > 0.3)
 
1135
        {
 
1136
          grid_scale /= 1.2;
 
1137
          reset_scale( grid_scale );
 
1138
        }
 
1139
        break;
 
1140
      }
 
1141
 
 
1142
    case NVV_Key_Up:
 
1143
      {
 
1144
        pixel_size++;
 
1145
        reset_size( pixel_size, grid_scale );
 
1146
        sprintf( temp_message, "pixel size = %d", pixel_size );
 
1147
        break;
 
1148
      }
 
1149
 
 
1150
    case NVV_Key_Down:
 
1151
      {
 
1152
        if (pixel_size > 1)
 
1153
        {
 
1154
          pixel_size--;
 
1155
          reset_size( pixel_size, grid_scale );
 
1156
          sprintf( temp_message, "pixel size = %d", pixel_size );
 
1157
        }
 
1158
        break;
 
1159
      }
 
1160
 
 
1161
    case NVV_KEY('z'):
 
1162
      TOGGLE_OPTION_NEG( ps_debug_no_vert_hints, "vertical hints processing" )
 
1163
 
 
1164
    case NVV_KEY('a'):
 
1165
      TOGGLE_OPTION_NEG( ps_debug_no_horz_hints, "horizontal hints processing" )
 
1166
 
 
1167
    case NVV_KEY('Z'):
 
1168
      TOGGLE_OPTION( option_show_vert_hints, "vertical hints display" )
 
1169
 
 
1170
    case NVV_KEY('A'):
 
1171
      TOGGLE_OPTION( option_show_horz_hints, "horizontal hints display" )
 
1172
 
 
1173
    case NVV_KEY('S'):
 
1174
      TOGGLE_OPTION( option_show_smooth, "smooth points display" );
 
1175
 
 
1176
    case NVV_KEY('i'):
 
1177
      TOGGLE_OPTION( option_show_indices, "point index display" );
 
1178
 
 
1179
    case NVV_KEY('b'):
 
1180
      TOGGLE_OPTION( option_show_blues, "blue zones display" );
 
1181
 
 
1182
    case NVV_KEY('h'):
 
1183
      TOGGLE_OPTION( option_hinting, "hinting" )
 
1184
 
 
1185
    case NVV_KEY('H'):
 
1186
      ps_print_hints();
 
1187
      break;
 
1188
 
 
1189
    default:
 
1190
      ;
 
1191
  }
 
1192
}
 
1193
 
 
1194
 
 
1195
 
 
1196
static void
 
1197
usage()
 
1198
{
 
1199
  Panic( "no usage" );
 
1200
}
 
1201
 
 
1202
 
 
1203
#define  OPTION1(n,code)   \
 
1204
           case n :        \
 
1205
             code          \
 
1206
             argc--;       \
 
1207
             argv++;       \
 
1208
             break;
 
1209
 
 
1210
#define  OPTION2(n,code)     \
 
1211
           case n :          \
 
1212
             code            \
 
1213
             argc -= 2;      \
 
1214
             argv += 2;      \
 
1215
             break;
 
1216
 
 
1217
 
 
1218
static void
 
1219
parse_options( int*  argc_p, char*** argv_p )
 
1220
{
 
1221
  int    argc = *argc_p;
 
1222
  char** argv = *argv_p;
 
1223
 
 
1224
  while (argc > 2 && argv[1][0] == '-')
 
1225
  {
 
1226
    switch (argv[1][1])
 
1227
    {
 
1228
      OPTION2( 'f', first_glyph = atoi( argv[2] ); )
 
1229
 
 
1230
      OPTION2( 's', pixel_size = atoi( argv[2] ); )
 
1231
 
 
1232
      default:
 
1233
        usage();
 
1234
    }
 
1235
  }
 
1236
 
 
1237
  *argc_p = argc;
 
1238
  *argv_p = argv;
 
1239
}
 
1240
 
 
1241
 
 
1242
 
 
1243
int  main( int  argc, char**  argv )
 
1244
{
 
1245
  char*  filename = "/winnt/fonts/arial.ttf";
 
1246
 
 
1247
  parse_options( &argc, &argv );
 
1248
 
 
1249
  if ( argc >= 2 )
 
1250
    filename = argv[1];
 
1251
 
 
1252
 
 
1253
  /* create library */
 
1254
  error = nv_renderer_new( 0, &renderer );
 
1255
  if (error) Panic( "could not create Nirvana renderer" );
 
1256
 
 
1257
  memory = nv_renderer_get_memory( renderer );
 
1258
  init_symbols();
 
1259
 
 
1260
  error = nvv_display_new( renderer, &display );
 
1261
  if (error) Panic( "could not create display" );
 
1262
 
 
1263
  error = nvv_surface_new( display, 460, 460, nv_pixmap_type_argb, &surface );
 
1264
  if (error) Panic( "could not create surface" );
 
1265
 
 
1266
  target = nvv_surface_get_pixmap( surface );
 
1267
 
 
1268
  error = nv_painter_new( renderer, &painter );
 
1269
  if (error) Panic( "could not create painter" );
 
1270
 
 
1271
  nv_painter_set_target( painter, target );
 
1272
 
 
1273
  clear_background();
 
1274
 
 
1275
  error = FT_Init_FreeType( &freetype );
 
1276
  if (error) Panic( "could not initialise FreeType" );
 
1277
 
 
1278
  error = FT_New_Face( freetype, filename, 0, &face );
 
1279
  if (error) Panic( "could not open font face" );
 
1280
 
 
1281
  reset_size( pixel_size, grid_scale );
 
1282
 
 
1283
 
 
1284
  nvv_surface_set_title( surface, "FreeType Glyph Viewer" );
 
1285
 
 
1286
  {
 
1287
    NVV_EventRec  event;
 
1288
 
 
1289
    glyph_index = first_glyph;
 
1290
    for ( ;; )
 
1291
    {
 
1292
      clear_background();
 
1293
      draw_grid();
 
1294
 
 
1295
      ps_debug_hints  = 0;
 
1296
      ah_debug_hinter = 0;
 
1297
 
 
1298
      ah_debug_disable_vert = ps_debug_no_vert_hints;
 
1299
      ah_debug_disable_horz = ps_debug_no_horz_hints;
 
1300
 
 
1301
      draw_ps_blue_zones();
 
1302
      draw_glyph( glyph_index );
 
1303
      ps2_draw_control_points();
 
1304
 
 
1305
      nvv_surface_refresh( surface, NULL );
 
1306
 
 
1307
      nvv_surface_listen( surface, 0, &event );
 
1308
      if ( event.key == NVV_Key_Esc )
 
1309
        break;
 
1310
 
 
1311
      handle_event( &event );
 
1312
      switch (event.key)
 
1313
      {
 
1314
        case NVV_Key_Esc:
 
1315
          goto Exit;
 
1316
 
 
1317
        default:
 
1318
          ;
 
1319
      }
 
1320
    }
 
1321
  }
 
1322
 
 
1323
 Exit:
 
1324
  /* wait for escape */
 
1325
 
 
1326
 
 
1327
  /* destroy display (and surface) */
 
1328
  nvv_display_unref( display );
 
1329
 
 
1330
  done_symbols();
 
1331
  nv_renderer_unref( renderer );
 
1332
 
 
1333
  return 0;
 
1334
}