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>
13
#include <../src/autohint/ahtypes.h>
15
/************************************************************************/
16
/************************************************************************/
18
/***** ROOT DEFINITIONS *****/
20
/************************************************************************/
21
/************************************************************************/
24
#include <time.h> /* for clock() */
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
33
static int first_glyph = 0;
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;
43
static FT_Library freetype;
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 */
53
static NV_Scale grid_scale = 1.0;
55
static int glyph_index;
56
static int pixel_size = 12;
58
/************************************************************************/
59
/************************************************************************/
61
/***** OPTIONS, COLORS and OTHERS *****/
63
/************************************************************************/
64
/************************************************************************/
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;
79
static int option_show_ps_hints = 1;
80
static int option_show_horz_hints = 1;
81
static int option_show_vert_hints = 1;
84
static int option_hinting = 1;
86
static char temp_message[1024];
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;
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
109
#define GHOST_HINT_COLOR 0xE00000FF
110
#define STEM_HINT_COLOR 0xE02020FF
111
#define STEM_JOIN_COLOR 0xE020FF20
113
#define EDGE_COLOR 0xF0704070
114
#define SEGMENT_COLOR 0xF0206040
115
#define LINK_COLOR 0xF0FFFF00
116
#define SERIF_LINK_COLOR 0xF0FF808F
118
/* print message and abort program */
120
Panic( const char* message )
122
fprintf( stderr, "PANIC: %s\n", message );
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.,
139
nv_path_destroy( symbol_dot );
140
nv_path_new_circle( renderer, 0, 0, 2., &symbol_dot );
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 );
154
/************************************************************************/
155
/************************************************************************/
157
/***** COMMON GRID DRAWING ROUTINES *****/
159
/************************************************************************/
160
/************************************************************************/
163
reset_scale( NV_Scale scale )
165
/* compute font units -> grid pixels scale factor */
166
glyph_scale = target->width*0.75 / face->units_per_EM * scale;
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;
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) );
178
size_transform.delta = glyph_transform.delta;
183
reset_size( int pixel_size, NV_Scale scale )
185
FT_Set_Pixel_Sizes( face, pixel_size, pixel_size );
186
reset_scale( scale );
191
clear_background( void )
193
nv_pixmap_fill_rect( target, 0, 0, target->width, target->height,
201
int x = (int)glyph_org_x;
202
int y = (int)glyph_org_y;
205
if ( option_show_grid )
207
NV_Scale min, max, x, step;
209
/* draw vertical grid bars */
210
step = 64. * size_transform.matrix.xx;
213
min = max = glyph_org_x;
214
while ( min - step >= 0 ) min -= step;
215
while ( max + step < target->width ) max += step;
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 );
222
/* draw horizontal grid bars */
223
step = -64. * size_transform.matrix.yy;
226
min = max = glyph_org_y;
227
while ( min - step >= 0 ) min -= step;
228
while ( max + step < target->height ) max += step;
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 );
237
if ( option_show_axis )
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 );
243
if ( option_show_em )
247
NV_UInt units = (NV_UInt)face->units_per_EM;
249
nv_path_new_rectangle( renderer, 0, 0, units, units, 0, 0, &path );
250
nv_path_transform( path, &glyph_transform );
252
nv_path_stroke( path, 1.5, nv_path_linecap_butt, nv_path_linejoin_miter,
255
nv_painter_set_color( painter, EM_COLOR, 256 );
256
nv_painter_fill_path( painter, NULL, 0, stroke );
258
nv_path_destroy( stroke );
259
nv_path_destroy( path );
265
/************************************************************************/
266
/************************************************************************/
268
/***** POSTSCRIPT GLOBALS ROUTINES *****/
270
/************************************************************************/
271
/************************************************************************/
273
#include <../src/pshinter/pshglob.h>
276
draw_ps_blue_zones( void )
278
if ( option_show_blues && ps_debug_globals )
280
PSH_Blues blues = &ps_debug_globals->blues;
281
PSH_Blue_Table table;
288
table = &blues->normal_top;
289
count = table->count;
292
for ( ; count > 0; count--, zone++ )
295
if ( !ps_debug_no_horz_hints )
297
v.y = zone->cur_ref + zone->cur_delta;
298
nv_vector_transform( &v, &size_transform );
302
v.y = zone->org_ref + zone->org_delta;
303
nv_vector_transform( &v, &glyph_transform );
305
y1 = (int)(v.y + 0.5);
308
if ( !ps_debug_no_horz_hints )
311
nv_vector_transform( &v, &size_transform );
316
nv_vector_transform( &v, &glyph_transform );
318
y2 = (int)(v.y + 0.5);
320
nv_pixmap_fill_rect( target, 0, y1,
321
target->width, y2-y1+1,
325
printf( "top [%.3f %.3f]\n", zone->cur_bottom/64.0, zone->cur_top/64.0 );
330
/* draw bottom zones */
331
table = &blues->normal_bottom;
332
count = table->count;
335
for ( ; count > 0; count--, zone++ )
339
nv_vector_transform( &v, &size_transform );
340
y1 = (int)(v.y + 0.5);
343
v.y = zone->cur_ref + zone->cur_delta;
344
nv_vector_transform( &v, &size_transform );
345
y2 = (int)(v.y + 0.5);
347
nv_pixmap_fill_rect( target, 0, y1,
348
target->width, y2-y1+1,
352
printf( "bot [%.3f %.3f]\n", zone->cur_bottom/64.0, zone->cur_top/64.0 );
358
/************************************************************************/
359
/************************************************************************/
361
/***** POSTSCRIPT HINTER ALGORITHM 1 ROUTINES *****/
363
/************************************************************************/
364
/************************************************************************/
366
#include <../src/pshinter/pshalgo1.h>
368
static int pshint_cpos = 0;
369
static int pshint_vertical = -1;
372
draw_ps1_hint( PSH1_Hint hint, FT_Bool vertical )
378
if ( pshint_vertical != vertical )
385
pshint_vertical = vertical;
390
if ( !option_show_vert_hints )
395
nv_vector_transform( &v, &size_transform );
396
x1 = (int)(v.x + 0.5);
398
v.x = hint->cur_pos + hint->cur_len;
400
nv_vector_transform( &v, &size_transform );
401
x2 = (int)(v.x + 0.5);
403
nv_pixmap_fill_rect( target, x1, 0, 1, target->height,
404
psh1_hint_is_ghost(hint)
405
? GHOST_HINT_COLOR : STEM_HINT_COLOR );
407
if ( psh1_hint_is_ghost(hint) )
413
nv_pixmap_fill_rect( target, x2, 0, 1, target->height,
414
psh1_hint_is_ghost(hint)
415
? GHOST_HINT_COLOR : STEM_HINT_COLOR );
417
nv_pixmap_fill_rect( target, x1, pshint_cpos, x2+1-x1, 1,
422
if (!option_show_horz_hints)
427
nv_vector_transform( &v, &size_transform );
428
x1 = (int)(v.y + 0.5);
430
v.y = hint->cur_pos + hint->cur_len;
432
nv_vector_transform( &v, &size_transform );
433
x2 = (int)(v.y + 0.5);
435
nv_pixmap_fill_rect( target, 0, x1, target->width, 1,
436
psh1_hint_is_ghost(hint)
437
? GHOST_HINT_COLOR : STEM_HINT_COLOR );
439
if ( psh1_hint_is_ghost(hint) )
445
nv_pixmap_fill_rect( target, 0, x2, target->width, 1,
446
psh1_hint_is_ghost(hint)
447
? GHOST_HINT_COLOR : STEM_HINT_COLOR );
449
nv_pixmap_fill_rect( target, pshint_cpos, x2, 1, x1+1-x2,
454
printf( "[%7.3f %7.3f] %c\n", hint->cur_pos/64.0, (hint->cur_pos+hint->cur_len)/64.0, vertical ? 'v' : 'h' );
462
/************************************************************************/
463
/************************************************************************/
465
/***** POSTSCRIPT HINTER ALGORITHM 2 ROUTINES *****/
467
/************************************************************************/
468
/************************************************************************/
470
#include <../src/pshinter/pshalgo2.h>
473
draw_ps2_hint( PSH2_Hint hint, FT_Bool vertical )
478
if ( pshint_vertical != vertical )
485
pshint_vertical = vertical;
490
if ( !option_show_vert_hints )
495
nv_vector_transform( &v, &size_transform );
496
x1 = (int)(v.x + 0.5);
498
v.x = hint->cur_pos + hint->cur_len;
500
nv_vector_transform( &v, &size_transform );
501
x2 = (int)(v.x + 0.5);
503
nv_pixmap_fill_rect( target, x1, 0, 1, target->height,
504
psh2_hint_is_ghost(hint)
505
? GHOST_HINT_COLOR : STEM_HINT_COLOR );
507
if ( psh2_hint_is_ghost(hint) )
513
nv_pixmap_fill_rect( target, x2, 0, 1, target->height,
514
psh2_hint_is_ghost(hint)
515
? GHOST_HINT_COLOR : STEM_HINT_COLOR );
517
nv_pixmap_fill_rect( target, x1, pshint_cpos, x2+1-x1, 1,
522
if (!option_show_horz_hints)
527
nv_vector_transform( &v, &size_transform );
528
x1 = (int)(v.y + 0.5);
530
v.y = hint->cur_pos + hint->cur_len;
532
nv_vector_transform( &v, &size_transform );
533
x2 = (int)(v.y + 0.5);
535
nv_pixmap_fill_rect( target, 0, x1, target->width, 1,
536
psh2_hint_is_ghost(hint)
537
? GHOST_HINT_COLOR : STEM_HINT_COLOR );
539
if ( psh2_hint_is_ghost(hint) )
545
nv_pixmap_fill_rect( target, 0, x2, target->width, 1,
546
psh2_hint_is_ghost(hint)
547
? GHOST_HINT_COLOR : STEM_HINT_COLOR );
549
nv_pixmap_fill_rect( target, pshint_cpos, x2, 1, x1+1-x2,
554
printf( "[%7.3f %7.3f] %c\n", hint->cur_pos/64.0, (hint->cur_pos+hint->cur_len)/64.0, vertical ? 'v' : 'h' );
562
ps2_draw_control_points( void )
564
if ( ps2_debug_glyph )
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;
574
for ( ; count > 0; count--, point++ )
578
vec.x = point->cur_x;
579
vec.y = point->cur_y;
580
nv_vector_transform( &vec, &size_transform );
582
nv_transform_set_translate( trans, vec.x, vec.y );
584
if ( option_show_smooth && !psh2_point_is_smooth(point) )
586
nv_painter_set_color( painter, SMOOTH_COLOR, 256 );
587
nv_painter_fill_path( painter, trans, 0, symbol_circle );
590
if (option_show_horz_hints)
592
if ( point->flags_y & PSH2_POINT_STRONG )
594
nv_painter_set_color( painter, STRONG_COLOR, 256 );
595
nv_painter_fill_path( painter, trans, 0, symbol_rect_h );
599
if (option_show_vert_hints)
601
if ( point->flags_x & PSH2_POINT_STRONG )
603
nv_painter_set_color( painter, STRONG_COLOR, 256 );
604
nv_painter_fill_path( painter, trans, 0, symbol_rect_v );
613
ps_print_hints( void )
615
if ( ps_debug_hints )
620
for ( dimension = 1; dimension >= 0; dimension-- )
622
PS_Dimension dim = &ps_debug_hints->dimension[ dimension ];
623
PS_Mask mask = dim->masks.masks;
624
FT_UInt count = dim->masks.num_masks;
626
printf( "%s hints -------------------------\n",
627
dimension ? "vertical" : "horizontal" );
629
for ( ; count > 0; count--, mask++ )
633
printf( "mask -> %d\n", mask->end_point );
634
for ( index = 0; index < mask->num_bits; index++ )
636
if ( mask->bytes[ index >> 3 ] & (0x80 >> (index & 7)) )
638
PS_Hint hint = dim->hints.hints + index;
640
printf( "%c [%3d %3d (%4d)]\n", dimension ? "v" : "h",
641
hint->pos, hint->pos + hint->len, hint->len );
649
/************************************************************************/
650
/************************************************************************/
652
/***** AUTOHINTER DRAWING ROUTINES *****/
654
/************************************************************************/
655
/************************************************************************/
658
ah_link_path( NV_Vector* p1,
662
NV_PathWriter writer;
664
NV_Path path, stroke;
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 );
688
path = nv_path_writer_get_path( writer );
689
nv_path_writer_destroy( writer );
691
nv_path_stroke( path, 1., nv_path_linecap_butt, nv_path_linejoin_round, 1., &stroke );
693
nv_path_destroy( path );
700
ah_draw_smooth_points( void )
702
if ( ah_debug_hinter && option_show_smooth )
704
AH_Outline* glyph = ah_debug_hinter->glyph;
705
FT_UInt count = glyph->num_points;
706
AH_Point* point = glyph->points;
708
nv_painter_set_color( painter, SMOOTH_COLOR, 256 );
710
for ( ; count > 0; count--, point++ )
712
if ( !( point->flags & ah_flag_weak_interpolation ) )
714
NV_Transform transform, *trans = &transform;
717
vec.x = point->x - ah_debug_hinter->pp1.x;
719
nv_vector_transform( &vec, &size_transform );
721
nv_transform_set_translate( &transform, vec.x, vec.y );
722
nv_painter_fill_path( painter, trans, 0, symbol_circle );
730
ah_draw_edges( void )
732
if ( ah_debug_hinter )
734
AH_Outline* glyph = ah_debug_hinter->glyph;
737
FT_Pos pp1 = ah_debug_hinter->pp1.x;
739
nv_painter_set_color( painter, EDGE_COLOR, 256 );
741
if ( option_show_edges )
743
/* draw verticla edges */
744
if ( option_show_vert_hints )
746
count = glyph->num_vedges;
747
edge = glyph->vert_edges;
748
for ( ; count > 0; count--, edge++ )
753
vec.x = edge->pos - pp1;
756
nv_vector_transform( &vec, &size_transform );
757
x = (FT_Pos)( vec.x + 0.5 );
759
nv_pixmap_fill_rect( target, x, 0, 1, target->height, EDGE_COLOR );
763
/* draw horizontal edges */
764
if ( option_show_horz_hints )
766
count = glyph->num_hedges;
767
edge = glyph->horz_edges;
768
for ( ; count > 0; count--, edge++ )
776
nv_vector_transform( &vec, &size_transform );
777
x = (FT_Pos)( vec.y + 0.5 );
779
nv_pixmap_fill_rect( target, 0, x, target->width, 1, EDGE_COLOR );
784
if ( option_show_segments )
786
/* draw vertical segments */
787
if ( option_show_vert_hints )
789
AH_Segment* seg = glyph->vert_segments;
790
FT_UInt count = glyph->num_vsegments;
792
for ( ; count > 0; count--, seg++ )
794
AH_Point *first, *last;
801
v1.x = v2.x = first->x - pp1;
803
if ( first->y <= last->y )
814
nv_vector_transform( &v1, &size_transform );
815
nv_vector_transform( &v2, &size_transform );
817
y1 = (NV_Pos)( v1.y + 0.5 );
818
y2 = (NV_Pos)( v2.y + 0.5 );
819
x = (NV_Pos)( v1.x + 0.5 );
821
nv_pixmap_fill_rect( target, x-1, y2, 3, ABS(y1-y2)+1, SEGMENT_COLOR );
825
/* draw horizontal segments */
826
if ( option_show_horz_hints )
828
AH_Segment* seg = glyph->horz_segments;
829
FT_UInt count = glyph->num_hsegments;
831
for ( ; count > 0; count--, seg++ )
833
AH_Point *first, *last;
840
v1.y = v2.y = first->y;
842
if ( first->x <= last->x )
844
v1.x = first->x - pp1;
845
v2.x = last->x - pp1;
849
v1.x = last->x - pp1;
850
v2.x = first->x - pp1;
853
nv_vector_transform( &v1, &size_transform );
854
nv_vector_transform( &v2, &size_transform );
856
y1 = (NV_Pos)( v1.x + 0.5 );
857
y2 = (NV_Pos)( v2.x + 0.5 );
858
x = (NV_Pos)( v1.y + 0.5 );
860
nv_pixmap_fill_rect( target, y1, x-1, ABS(y1-y2)+1, 3, SEGMENT_COLOR );
865
if ( option_show_vert_hints && option_show_links )
867
AH_Segment* seg = glyph->vert_segments;
868
FT_UInt count = glyph->num_vsegments;
870
for ( ; count > 0; count--, seg++ )
872
AH_Segment* seg2 = NULL;
878
if ( seg->link > seg )
881
else if ( seg->serif )
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;
891
link = ah_link_path( &v1, &v2, 1 );
893
nv_painter_set_color( painter, seg->serif ? SERIF_LINK_COLOR : LINK_COLOR, 256 );
894
nv_painter_fill_path( painter, &size_transform, 0, link );
896
nv_path_destroy( link );
901
if ( option_show_horz_hints && option_show_links )
903
AH_Segment* seg = glyph->horz_segments;
904
FT_UInt count = glyph->num_hsegments;
906
for ( ; count > 0; count--, seg++ )
908
AH_Segment* seg2 = NULL;
914
if ( seg->link > seg )
917
else if ( seg->serif )
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;
927
link = ah_link_path( &v1, &v2, 0 );
929
nv_painter_set_color( painter, seg->serif ? SERIF_LINK_COLOR : LINK_COLOR, 256 );
930
nv_painter_fill_path( painter, &size_transform, 0, link );
932
nv_path_destroy( link );
940
/************************************************************************/
941
/************************************************************************/
943
/***** MAIN LOOP(S) *****/
945
/************************************************************************/
946
/************************************************************************/
949
draw_glyph( int glyph_index )
953
pshint_vertical = -1;
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;
958
ah_debug_hinter = NULL;
960
error = FT_Load_Glyph( face, glyph_index, option_hinting
962
: FT_LOAD_NO_BITMAP | FT_LOAD_NO_HINTING );
963
if (error) Panic( "could not load glyph" );
965
if ( face->glyph->format != ft_glyph_format_outline )
966
Panic( "could not load glyph outline" );
968
error = nv_path_new_from_outline( renderer,
969
(NV_Outline*)&face->glyph->outline,
972
if (error) Panic( "could not create glyph path" );
974
/* trac� du glyphe plein */
975
if ( option_show_glyph )
977
nv_painter_set_color ( painter, 0xFF404080, 128 );
978
nv_painter_fill_path ( painter, 0, 0, path );
981
if ( option_show_stroke )
985
error = nv_path_stroke( path, 0.6,
986
nv_path_linecap_butt,
987
nv_path_linejoin_miter,
989
if (error) Panic( "could not stroke glyph path" );
991
nv_painter_set_color ( painter, 0xFF000040, 256 );
992
nv_painter_fill_path ( painter, 0, 0, stroke );
994
nv_path_destroy( stroke );
997
/* trac� des points de controle */
998
if ( option_show_dots )
1003
NV_Int n, first, last;
1005
nv_path_get_outline( path, NULL, memory, &out );
1008
for ( n = 0; n < out.n_contours; n++ )
1015
last = out.contours[n];
1017
for ( m = first; m <= last; m++ )
1019
color = (out.tags[m] & FT_Curve_Tag_On)
1023
vec = out.points + m;
1025
nv_transform_set_translate( &trans, vec->x/64.0, vec->y/64.0 );
1027
nv_painter_set_color( painter, color, 256 );
1028
nv_painter_fill_path( painter, &trans, 0, symbol_dot );
1030
if ( option_show_indices )
1034
sprintf( temp, "%d", m );
1035
nv_pixmap_cell_text( target, vec->x/64 + 4, vec->y/64 - 4,
1044
ah_draw_smooth_points();
1047
nv_path_destroy( path );
1054
sprintf( temp, "font name : %s (%s)", face->family_name, face->style_name );
1055
nv_pixmap_cell_text( target, 0, 0, temp, TEXT_COLOR );
1057
FT_Get_Glyph_Name( face, glyph_index, temp2, 63 );
1060
sprintf( temp, "glyph %4d: %s", glyph_index, temp2 );
1061
nv_pixmap_cell_text( target, 0, 8, temp, TEXT_COLOR );
1063
if ( temp_message[0] )
1065
nv_pixmap_cell_text( target, 0, 16, temp_message, TEXT_COLOR );
1066
temp_message[0] = 0;
1073
#define TOGGLE_OPTION(var,prefix) \
1076
sprintf( temp_message, prefix " is now %s", \
1077
var ? "on" : "off" ); \
1082
#define TOGGLE_OPTION_NEG(var,prefix) \
1085
sprintf( temp_message, prefix " is now %s", \
1086
!var ? "on" : "off" ); \
1092
handle_event( NVV_EventRec* ev )
1098
if ( glyph_index > 0 )
1105
if ( glyph_index+1 < face->num_glyphs )
1111
TOGGLE_OPTION( option_show_axis, "grid axis display" )
1114
TOGGLE_OPTION( option_show_stroke, "glyph stroke display" )
1117
TOGGLE_OPTION( option_show_glyph, "glyph fill display" )
1120
TOGGLE_OPTION( option_show_dots, "control points display" )
1123
TOGGLE_OPTION( option_show_em, "EM square display" )
1128
reset_scale( grid_scale );
1134
if (grid_scale > 0.3)
1137
reset_scale( grid_scale );
1145
reset_size( pixel_size, grid_scale );
1146
sprintf( temp_message, "pixel size = %d", pixel_size );
1155
reset_size( pixel_size, grid_scale );
1156
sprintf( temp_message, "pixel size = %d", pixel_size );
1162
TOGGLE_OPTION_NEG( ps_debug_no_vert_hints, "vertical hints processing" )
1165
TOGGLE_OPTION_NEG( ps_debug_no_horz_hints, "horizontal hints processing" )
1168
TOGGLE_OPTION( option_show_vert_hints, "vertical hints display" )
1171
TOGGLE_OPTION( option_show_horz_hints, "horizontal hints display" )
1174
TOGGLE_OPTION( option_show_smooth, "smooth points display" );
1177
TOGGLE_OPTION( option_show_indices, "point index display" );
1180
TOGGLE_OPTION( option_show_blues, "blue zones display" );
1183
TOGGLE_OPTION( option_hinting, "hinting" )
1199
Panic( "no usage" );
1203
#define OPTION1(n,code) \
1210
#define OPTION2(n,code) \
1219
parse_options( int* argc_p, char*** argv_p )
1222
char** argv = *argv_p;
1224
while (argc > 2 && argv[1][0] == '-')
1228
OPTION2( 'f', first_glyph = atoi( argv[2] ); )
1230
OPTION2( 's', pixel_size = atoi( argv[2] ); )
1243
int main( int argc, char** argv )
1245
char* filename = "/winnt/fonts/arial.ttf";
1247
parse_options( &argc, &argv );
1253
/* create library */
1254
error = nv_renderer_new( 0, &renderer );
1255
if (error) Panic( "could not create Nirvana renderer" );
1257
memory = nv_renderer_get_memory( renderer );
1260
error = nvv_display_new( renderer, &display );
1261
if (error) Panic( "could not create display" );
1263
error = nvv_surface_new( display, 460, 460, nv_pixmap_type_argb, &surface );
1264
if (error) Panic( "could not create surface" );
1266
target = nvv_surface_get_pixmap( surface );
1268
error = nv_painter_new( renderer, &painter );
1269
if (error) Panic( "could not create painter" );
1271
nv_painter_set_target( painter, target );
1275
error = FT_Init_FreeType( &freetype );
1276
if (error) Panic( "could not initialise FreeType" );
1278
error = FT_New_Face( freetype, filename, 0, &face );
1279
if (error) Panic( "could not open font face" );
1281
reset_size( pixel_size, grid_scale );
1284
nvv_surface_set_title( surface, "FreeType Glyph Viewer" );
1289
glyph_index = first_glyph;
1296
ah_debug_hinter = 0;
1298
ah_debug_disable_vert = ps_debug_no_vert_hints;
1299
ah_debug_disable_horz = ps_debug_no_horz_hints;
1301
draw_ps_blue_zones();
1302
draw_glyph( glyph_index );
1303
ps2_draw_control_points();
1305
nvv_surface_refresh( surface, NULL );
1307
nvv_surface_listen( surface, 0, &event );
1308
if ( event.key == NVV_Key_Esc )
1311
handle_event( &event );
1324
/* wait for escape */
1327
/* destroy display (and surface) */
1328
nvv_display_unref( display );
1331
nv_renderer_unref( renderer );