1
diff -u freetype-2.1.7-orig/src/autohint/ahglobal.c freetype-2.1.7/src/autohint/ahglobal.c
2
--- freetype-2.1.7-orig/src/autohint/ahglobal.c Thu Oct 16 07:20:56 2003
3
+++ freetype-2.1.7/src/autohint/ahglobal.c Sat Nov 29 08:37:15 2003
5
/* cf. AH_BLUE_XXX constants in ahtypes.h */
8
- const char* const blue_chars[AH_BLUE_MAX] =
9
+ const char* const blue_chars_latin[AH_BLUE_MAX] =
17
+ typedef struct AH_BlueTable_
19
+ FT_ULong offset_blue_chars;
20
+ const char** blue_chars;
21
+ FT_ULong char_for_widths;
26
+ static const AH_BlueTable blue_table[AH_CHAR_TYPE_COUNT] =
28
+ { 0, blue_chars_latin, (FT_ULong)'o' },
29
+ { 0xFEE0L, blue_chars_latin, 0xFF4FL },
36
+ static const char* const blue_names[AH_CHAR_TYPE_COUNT] =
38
+ "general latinate chars",
39
+ "CJK fullwidth latin chars",
46
/* simple insertion sort */
48
sort_values( FT_Int count,
50
ah_hinter_compute_blues( AH_Hinter hinter )
53
- AH_Globals globals = &hinter->globals->design;
54
+ AH_Globals globals = hinter->globals->designs;
55
FT_Pos flats [MAX_TEST_CHARACTERS];
56
FT_Pos rounds[MAX_TEST_CHARACTERS];
64
+ const char** blue_chars;
69
/* we compute the blues simply by loading each character from the */
70
/* 'blue_chars[blues]' string, then compute its top-most or */
71
/* bottom-most points (depending on `AH_IS_TOP_BLUE') */
72
+ type = AH_CHAR_TYPE_LATINATE;
74
- AH_LOG(( "blue zones computation\n" ));
76
+ globals->has_blues = FALSE;
77
+ globals->baseline = 0;
79
+ offset = blue_table[type].offset_blue_chars;
80
+ blue_chars = blue_table[type].blue_chars;
85
+ AH_LOG(( "blue zones computation for %s\n", blue_names[type] ));
86
AH_LOG(( "------------------------------------------------\n" ));
88
for ( blue = AH_BLUE_CAPITAL_TOP; blue < AH_BLUE_MAX; blue++ )
90
AH_LOG(( "`%c'", *p ));
92
/* load the character in the face -- skip unknown or empty ones */
93
- glyph_index = FT_Get_Char_Index( face, (FT_UInt)*p );
94
+ glyph_index = FT_Get_Char_Index( face, offset + (FT_ULong)*p );
95
if ( glyph_index == 0 )
100
} while ( next != idx );
102
- /* now, set the `round' flag depending on the segment's kind */
104
- FT_CURVE_TAG( glyph->outline.tags[prev] ) != FT_CURVE_TAG_ON ||
105
- FT_CURVE_TAG( glyph->outline.tags[next] ) != FT_CURVE_TAG_ON );
106
+ /* now, set the `round' flag depending on whether there exists */
107
+ /* a extremum line segment within the current zone. */
111
+ FT_Int n = 0, p = prev;
112
+ FT_Bool is_top = AH_IS_TOP_BLUE( blue );
115
+ while ( ( p = ( p >= last )? first : p + 1 ) != next )
117
+ if ( FT_CURVE_TAG( glyph->outline.tags[p] ) == FT_CURVE_TAG_ON )
119
+ if ( ( is_top && points[p].y < extremum->y ) ||
120
+ ( !is_top && points[p].y > extremum->y ) )
127
+ if ( n >= 2 && p == next )
131
AH_LOG(( "%c ", round ? 'r' : 'f' ));
136
AH_LOG(( "-- ref = %ld, shoot = %ld\n", *blue_ref, *blue_shoot ));
138
+ if ( num_flats > 0 || num_rounds > 0 )
139
+ globals->has_blues = TRUE;
142
+ globals->baseline = globals->blue_refs[AH_BLUE_SMALL_BOTTOM];
144
+ if ( globals->baseline > -10000 )
146
+ for ( blue = AH_BLUE_CAPITAL_TOP; blue < AH_BLUE_MAX; blue++ )
148
+ if ( globals->blue_refs[blue] > -10000 )
150
+ globals->blue_refs[blue] -= globals->baseline;
151
+ globals->blue_shoots[blue] -= globals->baseline;
157
+ if ( ++type < AH_CHAR_TYPE_COUNT )
160
+ goto Compute_Blues;
163
/* reset original face charmap */
164
@@ -299,13 +386,23 @@
165
AH_Outline outline = hinter->glyph;
168
- AH_Globals globals = &hinter->globals->design;
169
+ AH_Globals globals = hinter->globals->designs;
172
FT_Int* p_num_widths;
174
FT_Pos edge_distance_threshold = 32000;
176
+ FT_ULong char_for_widths;
179
+ type = AH_CHAR_TYPE_LATINATE;
182
+ char_for_widths = blue_table[type].char_for_widths;
184
+ if ( !char_for_widths )
187
globals->num_widths = 0;
188
globals->num_heights = 0;
189
@@ -318,18 +415,18 @@
193
- glyph_index = FT_Get_Char_Index( hinter->face, 'o' );
194
+ glyph_index = FT_Get_Char_Index( hinter->face, char_for_widths );
195
if ( glyph_index == 0 )
199
error = FT_Load_Glyph( hinter->face, glyph_index, FT_LOAD_NO_SCALE );
204
error = ah_outline_load( hinter->glyph, 0x10000L, 0x10000L,
210
ah_outline_compute_segments( hinter->glyph );
211
ah_outline_link_segments( hinter->glyph );
213
p_num_widths = &globals->num_widths;
217
+ if ( type++ < AH_CHAR_TYPE_COUNT )
220
+ goto Compute_Widths;
223
/* Now, compute the edge distance threshold as a fraction of the */
224
/* smallest width in the font. Set it in `hinter->glyph' too! */
225
if ( edge_distance_threshold == 32000 )
228
hinter->glyph->edge_distance_threshold = edge_distance_threshold / 5;
236
@@ -396,6 +499,192 @@
238
return ah_hinter_compute_widths( hinter ) ||
239
ah_hinter_compute_blues ( hinter );
243
+ static const AH_CharType
244
+ ah_types_for_unicode[] =
246
+ /* Latin, Greek, Cyrillic */
247
+ { AH_CHAR_TYPE_LATINATE, 0x21L, 0x52FL },
250
+ { AH_CHAR_TYPE_LATINATE, 0x5D0L, 0x600L },
253
+ { AH_CHAR_TYPE_LATINATE, 0x1E00L, 0x2000L },
255
+ /* CJK fullwidth Latin */
256
+ { AH_CHAR_TYPE_LATIN_FULLWIDTH, 0xFF00L, 0xFF60L }
260
+ static const AH_CharTypeTable
261
+ ah_types_table_unicode =
263
+ sizeof( ah_types_for_unicode ) / sizeof( AH_CharType ),
264
+ (AH_CharType *)ah_types_for_unicode
268
+ FT_LOCAL_DEF( void )
269
+ ah_hinter_compute_char_table( AH_Hinter hinter )
271
+ FT_Memory memory = hinter->memory;
272
+ FT_Face face = hinter->face;
273
+ AH_CharTypeTable* table = hinter->globals->table;
274
+ FT_ULong num_glyphs = face->num_glyphs;
277
+ FT_CharMap charmap;
283
+ if ( num_glyphs <= 0 )
286
+ if ( FT_NEW_ARRAY( types, num_glyphs ) )
289
+ FT_MEM_SET( types, AH_CHAR_TYPE_OTHER, num_glyphs );
291
+ charmap = face->charmap;
292
+ if ( FT_Select_Charmap( face, FT_ENCODING_UNICODE ) )
297
+ FT_Bool empty = TRUE;
301
+ for ( i = 0; i < ah_types_table_unicode.size; i++ )
303
+ FT_UInt glyph_index;
304
+ FT_ULong start = ah_types_table_unicode.types[i].start;
305
+ FT_ULong last = ah_types_table_unicode.types[i].last;
306
+ FT_Byte type = ah_types_table_unicode.types[i].type;
307
+ FT_ULong ucs = FT_Get_Next_Char( face, start - 1, &glyph_index );
310
+ while ( ucs && ucs <= last )
312
+ if ( glyph_index < num_glyphs )
315
+ types[glyph_index] = type;
318
+ ucs = FT_Get_Next_Char( face, ucs, &glyph_index );
328
+ FT_Byte* cur = types;
329
+ FT_Byte* last = types + num_glyphs - 1;
330
+ FT_Byte type = AH_CHAR_TYPE_OTHER;
332
+ FT_ULong alloc_size;
335
+ while ( ++cur <= last )
337
+ if ( *cur != type )
341
+ if ( type < AH_CHAR_TYPE_OTHER )
346
+ alloc_size = sizeof( AH_CharTypeTable ) + num * sizeof( AH_CharType );
347
+ if ( FT_ALLOC( table, alloc_size ) )
351
+ table->types = (AH_CharType *)( table + 1 );
356
+ FT_Byte* cur = types + 1;
357
+ FT_Byte* last = types + face->num_glyphs - 1;
358
+ FT_Byte type = AH_CHAR_TYPE_OTHER;
363
+ for ( i = 1; cur <= last; i++, cur++ )
365
+ if ( *cur != type )
367
+ if ( type < AH_CHAR_TYPE_OTHER )
368
+ table->types[num - 1].last = i - 1;
371
+ if ( type < AH_CHAR_TYPE_OTHER )
373
+ table->types[num].type = type;
374
+ table->types[num++].start = i;
379
+ if ( type < AH_CHAR_TYPE_OTHER )
380
+ table->types[num - 1].last = i - 1;
383
+ hinter->globals->table = table;
386
+ FT_Set_Charmap( face, charmap );
391
+ FT_LOCAL_DEF( FT_Byte )
392
+ ah_hinter_get_char_type( AH_Hinter hinter,
393
+ FT_ULong glyph_index )
395
+ AH_CharTypeTable* table = hinter->globals->table;
398
+ if ( table && table->size > 0 && glyph_index )
401
+ AH_CharType* types = table->types;
403
+ FT_ULong max = table->size - 1;
407
+ if ( glyph_index < types[min].start ||
408
+ glyph_index > types[max].last )
409
+ return AH_CHAR_TYPE_OTHER;
411
+ while ( min <= max )
413
+ mid = ( min + max ) / 2;
416
+ if ( glyph_index < cur->start )
418
+ else if ( glyph_index > cur->last )
425
+ return AH_CHAR_TYPE_OTHER;
429
diff -u freetype-2.1.7-orig/src/autohint/ahglobal.h freetype-2.1.7/src/autohint/ahglobal.h
430
--- freetype-2.1.7-orig/src/autohint/ahglobal.h Tue Apr 22 16:49:24 2003
431
+++ freetype-2.1.7/src/autohint/ahglobal.h Sat Nov 29 08:24:42 2003
433
ah_hinter_compute_globals( AH_Hinter hinter );
437
+ ah_hinter_compute_char_table( AH_Hinter hinter );
440
+ FT_LOCAL( FT_Byte )
441
+ ah_hinter_get_char_type( AH_Hinter hinter,
442
+ FT_ULong glyph_index );
446
#endif /* __AHGLOBAL_H__ */
447
diff -u freetype-2.1.7-orig/src/autohint/ahglyph.c freetype-2.1.7/src/autohint/ahglyph.c
448
--- freetype-2.1.7-orig/src/autohint/ahglyph.c Wed May 28 14:52:05 2003
449
+++ freetype-2.1.7/src/autohint/ahglyph.c Sat Nov 29 08:24:42 2003
452
#include <ft2build.h>
454
-#include "ahangles.h"
455
#include "ahglobal.h"
456
#include "aherrors.h"
459
printf ( "Table of %s edges:\n",
460
!dimension ? "vertical" : "horizontal" );
461
printf ( " [ index | pos | dir | link |"
462
- " serif | blue | opos | pos ]\n" );
463
+ " serif | blue | opos | pos | diff ]\n" );
465
for ( edge = edges; edge < edge_limit; edge++ )
467
- printf ( " [ %5d | %4d | %5s | %4d | %5d | %c | %5.2f | %5.2f ]\n",
468
+ printf ( " [ %5d | %4d | %5s | %4d | %6d | %c | %5.2f | %5.2f | %5.2f ]\n",
471
edge->dir == AH_DIR_UP
473
edge->serif ? ( edge->serif - edges ) : -1,
474
edge->blue_edge ? 'y' : 'n',
476
- edge->pos / 64.0 );
478
+ ( edge->pos - edge->opos ) / 64.0 );
481
edges = outline->vert_edges;
483
char* tag = gloader->current.outline.tags;
487
+ ah_dump_segments( outline );
488
+ ah_dump_edges( outline );
492
/* we assume that the glyph loader has already been checked for storage */
493
for ( ; point < point_limit; point++, vec++, tag++ )
497
point->out_dir = ah_compute_direction( ovec.x, ovec.y );
500
#ifndef AH_OPTION_NO_WEAK_INTERPOLATION
501
if ( point->flags & ( AH_FLAG_CONIC | AH_FLAG_CUBIC ) )
504
else if ( point->in_dir == -point->out_dir )
516
/* compute all inflex points in a given glyph */
518
ah_outline_compute_inflections( AH_Outline outline )
526
+ /* compute all strong points in a given glyph */
528
+ ah_outline_compute_strongs( AH_Outline outline )
530
+ AH_Point* contour = outline->contours;
531
+ AH_Point* contour_limit = contour + outline->num_contours;
534
+ /* load original coordinates in (u,v) */
535
+ ah_setup_uv( outline, AH_UV_FXY );
537
+ for ( ; contour < contour_limit; contour++ )
539
+ FT_Pos dx1, dx2, dy1, dy2;
540
+ AH_Point point = contour[0];
541
+ AH_Point first = point;
546
+ after = point->next;
547
+ before = point->prev;
548
+ dx1 = point->u - before->u;
549
+ dy1 = point->v - before->v;
553
+ dx2 = after->u - point->u;
554
+ dy2 = after->v - point->v;
556
+ if ( dx1 == 0 || dx2 == 0 || ( dx1 ^ dx2 ) < 0 )
557
+ point->flags |= AH_FLAG_STRONG_X;
559
+ if ( dy1 == 0 || dy2 == 0 || ( dy1 ^ dy2 ) < 0 )
560
+ point->flags |= AH_FLAG_STRONG_Y;
564
+ after = after->next;
568
+ } while ( point != first );
574
@@ -925,11 +982,34 @@
575
segment->last = point;
576
segment->pos = ( min_pos + max_pos ) >> 1;
579
/* a segment is round if either its first or last point */
580
/* is a control point */
581
if ( ( segment->first->flags | point->flags ) &
583
segment->flags |= AH_EDGE_ROUND;
585
+ /* a segment is round if it doesn't have successive */
586
+ /* on-curve points. */
588
+ AH_Point pt = segment->first;
589
+ AH_Flags f0 = pt->flags & AH_FLAG_CONTROL;
593
+ for ( ; pt != point; f0 = f1 )
596
+ f1 = pt->flags & AH_FLAG_CONTROL;
602
+ segment->flags |= AH_EDGE_ROUND;
607
/* compute segment size */
608
min_pos = max_pos = point->v;
609
@@ -972,7 +1052,10 @@
610
segment->first = point;
611
segment->last = point;
612
segment->contour = contour;
613
- segment->score = 32000;
614
+ segment->score1 = 0x7FFFFFFFL;
615
+ segment->score2 = 0x7FFFFFFFL;
616
+ segment->length = 0;
618
segment->link = NULL;
621
@@ -1035,7 +1118,10 @@
622
segment->first = min_point;
623
segment->last = min_point;
624
segment->pos = min_pos;
625
- segment->score = 32000;
626
+ segment->score1 = 0x7FFFFFFFL;
627
+ segment->score2 = 0x7FFFFFFFL;
628
+ segment->length = 0;
630
segment->link = NULL;
633
@@ -1053,7 +1139,10 @@
634
segment->first = max_point;
635
segment->last = max_point;
636
segment->pos = max_pos;
637
- segment->score = 32000;
638
+ segment->score1 = 0x7FFFFFFFL;
639
+ segment->score2 = 0x7FFFFFFFL;
640
+ segment->length = 0;
642
segment->link = NULL;
645
@@ -1080,11 +1169,13 @@
646
AH_Segment segment_limit;
647
AH_Direction major_dir;
649
+ FT_Pos score_limit;
652
segments = outline->horz_segments;
653
segment_limit = segments + outline->num_hsegments;
654
major_dir = outline->horz_major_dir;
655
+ score_limit = FT_DivFix( 64*3*9, outline->y_scale );
657
for ( dimension = 1; dimension >= 0; dimension-- )
659
@@ -1203,20 +1294,28 @@
660
max = seg2->max_coord;
666
- score = dist + 3000 / len;
669
- if ( score < seg1->score )
670
+ if ( score < seg1->score1 &&
671
+ !( score > seg1->score2 && 4*len < seg1->length ) )
673
- seg1->score = score;
675
+ seg1->score1 = 9*dist;
676
+ seg1->score2 = 7*dist;
677
+ seg1->length = len;
682
- if ( score < seg2->score )
683
+ if ( score < seg2->score1 &&
684
+ !( score > seg2->score2 && 4*len < seg2->length ) )
686
- seg2->score = score;
688
+ seg2->score1 = 9*dist;
689
+ seg2->score2 = 7*dist;
690
+ seg2->length = len;
696
@@ -1225,6 +1324,73 @@
699
/* now, compute the `serif' segments */
701
+ AH_Segment seg, link1, link2;
705
+ for ( seg1 = segments; seg1 < segment_limit; seg1++ )
707
+ if ( seg1->sign >= 0 || seg1->score1 >= score_limit )
710
+ link1 = seg1->link;
711
+ if ( link1->link != seg1 )
718
+ for ( seg2 = segments; seg2 < segment_limit; seg2++ )
720
+ if ( seg2->sign >= 0 ||
721
+ seg2->score1 <= seg1->score1 || seg2->pos > pos1 )
724
+ link2 = seg2->link;
725
+ if ( link2->link != seg2 )
728
+ if ( link2->pos < pos2 ||
729
+ seg1->score1*4 <= seg2->score1 )
732
+ /* seg2->pos < pos1 < pos2 < seg2->link->pos */
734
+ if ( seg1->length < seg2->length*2 )
736
+ seg1->link = link1->link = 0;
737
+ seg1->sign = link1->sign = 0;
741
+ for ( seg = segments; seg < segment_limit; seg++ )
743
+ AH_Segment link = seg->link;
746
+ if ( link == seg2 )
750
+ seg->serif = link1;
752
+ else if ( link == link2 )
767
for ( seg1 = segments; seg1 < segment_limit; seg1++ )
770
@@ -1234,8 +1400,13 @@
772
if ( seg2->link != seg1 )
775
- seg1->serif = seg2->link;
778
+ if ( seg2->score1 < score_limit ||
779
+ seg1->score1 < seg2->score1*4 )
780
+ seg1->serif = seg2->link;
782
+ seg2->num_linked--;
786
@@ -1243,6 +1414,7 @@
787
segments = outline->vert_segments;
788
segment_limit = segments + outline->num_vsegments;
789
major_dir = outline->vert_major_dir;
790
+ score_limit = FT_DivFix( 64*3*9, outline->x_scale );
794
@@ -1310,12 +1482,46 @@
798
+ if ( edge->dir != seg->dir )
801
dist = seg->pos - edge->fpos;
805
if ( dist < edge_distance_threshold )
807
+ AH_Segment link = seg->link;
810
+ /* check if all linked segments of the candidate edge */
811
+ /* can make a single edge. */
814
+ AH_Segment seg1 = edge->first;
820
+ link1 = seg1->link;
823
+ dist = link->pos - link1->pos;
827
+ dist = FT_MulFix( dist, scale );
828
+ if ( dist >= edge_distance_threshold )
832
+ } while ( ( seg1 = seg1->edge_next ) != edge->first );
834
+ if ( dist >= edge_distance_threshold )
841
@@ -1341,6 +1547,7 @@
842
edge->fpos = seg->pos;
843
edge->opos = edge->pos = FT_MulFix( seg->pos, scale );
844
seg->edge_next = seg;
845
+ edge->dir = seg->dir;
849
@@ -1391,8 +1598,6 @@
851
FT_Int is_round = 0; /* does it contain round segments? */
852
FT_Int is_straight = 0; /* does it contain straight segments? */
853
- FT_Pos ups = 0; /* number of upwards segments */
854
- FT_Pos downs = 0; /* number of downwards segments */
858
@@ -1408,12 +1613,6 @@
862
- /* check for segment direction */
863
- if ( seg->dir == up_dir )
864
- ups += seg->max_coord-seg->min_coord;
866
- downs += seg->max_coord-seg->min_coord;
868
/* check for links -- if seg->serif is set, then seg->link must */
870
is_serif = (FT_Bool)( seg->serif && seg->serif->edge != edge );
871
@@ -1479,18 +1678,6 @@
872
if ( is_round > 0 && is_round >= is_straight )
873
edge->flags |= AH_EDGE_ROUND;
875
- /* set the edge's main direction */
876
- edge->dir = AH_DIR_NONE;
879
- edge->dir = up_dir;
881
- else if ( ups < downs )
882
- edge->dir = -up_dir;
884
- else if ( ups == downs )
885
- edge->dir = 0; /* both up and down! */
887
/* gets rid of serifs if link is set */
888
/* XXX: This gets rid of many unpleasant artefacts! */
889
/* Example: the `c' in cour.pfa at size 13 */
890
@@ -1523,7 +1710,7 @@
891
ah_outline_compute_segments ( outline );
892
ah_outline_link_segments ( outline );
893
ah_outline_compute_edges ( outline );
894
- ah_outline_compute_inflections( outline );
895
+ ah_outline_compute_strongs ( outline );
899
@@ -1542,12 +1729,15 @@
901
AH_Edge edge = outline->horz_edges;
902
AH_Edge edge_limit = edge + outline->num_hedges;
903
- AH_Globals globals = &face_globals->design;
904
+ AH_Globals globals = &face_globals->designs[face_globals->cur_type];
905
FT_Fixed y_scale = outline->y_scale;
907
FT_Bool blue_active[AH_BLUE_MAX];
910
+ if ( !globals->has_blues )
913
/* compute which blue zones are active, i.e. have their scaled */
914
/* size < 3/4 pixels */
916
@@ -1588,6 +1778,18 @@
917
FT_Pos best_dist; /* initial threshold */
922
+ FT_Pos dist = edge->serif->pos - edge->pos;
932
/* compute the initial threshold as a fraction of the EM size */
933
best_dist = FT_MulFix( face_globals->face->units_per_EM / 40, y_scale );
935
@@ -1686,7 +1888,11 @@
939
- delta = globals->scaled.blue_refs - globals->design.blue_refs;
940
+ if ( !globals->scaled.has_blues )
943
+ delta = globals->scaled.blue_refs -
944
+ globals->designs[globals->cur_type].blue_refs;
946
for ( ; edge < edge_limit; edge++ )
948
diff -u freetype-2.1.7-orig/src/autohint/ahhint.c freetype-2.1.7/src/autohint/ahhint.c
949
--- freetype-2.1.7-orig/src/autohint/ahhint.c Mon Oct 20 17:29:45 2003
950
+++ freetype-2.1.7/src/autohint/ahhint.c Sat Nov 29 08:39:27 2003
952
#include <ft2build.h>
955
-#include "ahangles.h"
956
#include "aherrors.h"
957
#include FT_OUTLINE_H
958
+#include FT_TRUETYPE_TABLES_H
961
#define FACE_GLOBALS( face ) ( (AH_Face_Globals)(face)->autohint.data )
964
if ( !hinter->do_stem_adjust )
966
- /* leave stem widths unchanged */
968
+ dist += ( 48 - dist )/2 ;
970
else if ( ( vertical && !hinter->do_vert_snapping ) ||
971
( !vertical && !hinter->do_horz_snapping ) )
973
/* smooth hinting process: very lightly quantize the stem width */
977
/* leave the widths of serifs alone */
979
if ( ( stem_flags & AH_EDGE_SERIF ) && vertical && ( dist < 3 * 64 ) )
980
@@ -132,24 +134,35 @@
982
else if ( dist < 56 )
987
- FT_Pos delta = dist - globals->stds[vertical];
995
+ if ( ( vertical && globals->num_heights > 0 ) ||
996
+ ( !vertical && globals->num_widths > 0 ) )
998
- dist = globals->stds[vertical];
1001
+ delta = dist - globals->stds[vertical];
1009
+ dist = globals->stds[vertical];
1017
- if ( dist < 3 * 64 )
1020
+ dist += ( 54 - dist )/2 ;
1022
+ else if ( dist < 3 * 64 )
1026
@@ -157,17 +170,18 @@
1030
- else if ( delta < 32 )
1031
+ else if ( delta < 22 )
1034
+ else if ( delta < 42 )
1037
else if ( delta < 54 )
1044
- dist = ( dist + 32 ) & -64;
1048
@@ -409,6 +423,129 @@
1049
serif->pos = base->pos + sign * dist;
1054
+ ah_hint_normal_stem( AH_Hinter hinter,
1060
+ FT_Pos org_len, cur_len, org_center;
1061
+ FT_Pos cur_pos1, cur_pos2;
1062
+ FT_Pos d_off1, u_off1, d_off2, u_off2, delta;
1064
+ FT_Pos threshold = 64;
1067
+ if ( !hinter->do_stem_adjust )
1069
+ if ( ( edge->flags & AH_EDGE_ROUND ) &&
1070
+ ( edge2->flags & AH_EDGE_ROUND ) )
1073
+ threshold = 64 - AH_LIGHT_MODE_MAX_HORZ_GAP;
1075
+ threshold = 64 - AH_LIGHT_MODE_MAX_VERT_GAP;
1080
+ threshold = 64 - AH_LIGHT_MODE_MAX_HORZ_GAP/3;
1082
+ threshold = 64 - AH_LIGHT_MODE_MAX_VERT_GAP/3;
1086
+ org_len = edge2->opos - edge->opos;
1087
+ cur_len = ah_compute_stem_width( hinter, vertical, org_len,
1088
+ edge->flags, edge2->flags );
1089
+ org_center = ( edge->opos + edge2->opos ) / 2 + anchor;
1090
+ cur_pos1 = org_center - cur_len / 2;
1091
+ cur_pos2 = cur_pos1 + cur_len;
1092
+ d_off1 = cur_pos1 - ( cur_pos1 & -64 );
1093
+ d_off2 = cur_pos2 - ( cur_pos2 & -64 );
1094
+ u_off1 = 64 - d_off1;
1095
+ u_off2 = 64 - d_off2;
1099
+ if ( d_off1 == 0 || d_off2 == 0 )
1102
+ if ( cur_len <= threshold )
1104
+ if ( d_off2 < cur_len )
1106
+ if ( u_off1 <= d_off2 )
1115
+ if ( threshold < 64 )
1117
+ if ( d_off1 >= threshold || u_off1 >= threshold ||
1118
+ d_off2 >= threshold || u_off2 >= threshold )
1122
+ offset = cur_len % 64;
1124
+ if ( offset < 32 )
1126
+ if ( u_off1 <= offset || d_off2 <= offset )
1130
+ offset = 64 - threshold;
1132
+ d_off1 = threshold - u_off1;
1133
+ u_off1 = u_off1 - offset;
1134
+ u_off2 = threshold - d_off2;
1135
+ d_off2 = d_off2 - offset;
1137
+ if ( d_off1 <= u_off1 )
1140
+ if ( d_off2 <= u_off2 )
1143
+ if ( ABS( u_off1 ) <= ABS( u_off2 ) )
1150
+ if ( !hinter->do_stem_adjust )
1152
+ if ( delta > AH_LIGHT_MODE_MAX_DELTA_ABS )
1153
+ delta = AH_LIGHT_MODE_MAX_DELTA_ABS;
1154
+ else if ( delta < -AH_LIGHT_MODE_MAX_DELTA_ABS )
1155
+ delta = -AH_LIGHT_MODE_MAX_DELTA_ABS;
1159
+ cur_pos1 += delta;
1161
+ if ( edge->opos < edge2->opos )
1163
+ edge->pos = cur_pos1;
1164
+ edge2->pos = cur_pos1 + cur_len;
1168
+ edge->pos = cur_pos1 + cur_len;
1169
+ edge2->pos = cur_pos1;
1176
/*************************************************************************/
1177
/*************************************************************************/
1188
/* we begin by aligning all stems relative to the blue zone */
1189
/* if needed -- that's only for horizontal edges */
1191
+ if ( dimension && hinter->do_blue_hints )
1193
for ( edge = edges; edge < edge_limit; edge++ )
1195
@@ -486,14 +624,10 @@
1196
ah_align_linked_edge( hinter, edge1, edge2, dimension );
1197
edge2->flags |= AH_EDGE_DONE;
1205
- /* now we will align all stem edges, trying to maintain the */
1206
- /* relative order of stems in the glyph */
1207
+ /* now we will align all stem edges. */
1208
for ( edge = edges; edge < edge_limit; edge++ )
1219
@@ -686,6 +821,93 @@
1220
if ( edge > edges && edge->pos < edge[-1].pos )
1221
edge->pos = edge[-1].pos;
1225
+ if ( !dimension && !anchor )
1227
+ if ( hinter->globals->is_fixedpitch && !hinter->composite )
1229
+ AH_Edge left = edge;
1230
+ AH_Edge right = edge_limit - 1;
1231
+ AH_EdgeRec left1, left2, right1, right2;
1232
+ FT_Pos target, center1, center2;
1233
+ FT_Pos delta1, delta2, d1, d2;
1236
+ while ( right > left && !right->link )
1240
+ left2 = *left->link;
1241
+ right1 = *right->link;
1244
+ delta = ( ( ( hinter->pp2.x + 32 ) & -64 ) - hinter->pp2.x )/2;
1245
+ target = left->opos + ( right->opos - left->opos )/2 + delta - 16;
1248
+ delta1 += ah_hint_normal_stem( hinter, left, left->link,
1251
+ if ( left->link != right )
1252
+ ah_hint_normal_stem( hinter, right->link, right, delta1, 0 );
1254
+ center1 = left->pos + ( right->pos - left->pos )/2;
1256
+ if ( center1 >= target )
1257
+ delta2 = delta - 32;
1259
+ delta2 = delta + 32;
1261
+ delta2 += ah_hint_normal_stem( hinter, &left1, &left2, delta2, 0 );
1263
+ if ( delta1 != delta2 )
1265
+ if ( left->link != right )
1266
+ ah_hint_normal_stem( hinter, &right1, &right2, delta2, 0 );
1268
+ center2 = left1.pos + ( right2.pos - left1.pos )/2;
1270
+ d1 = center1 - target;
1271
+ d2 = center2 - target;
1273
+ if ( ABS( d2 ) < ABS( d1 ) )
1275
+ left->pos = left1.pos;
1276
+ left->link->pos = left2.pos;
1278
+ if ( left->link != right )
1280
+ right->link->pos = right1.pos;
1281
+ right->pos = right2.pos;
1289
+ right->link->flags |= AH_EDGE_DONE;
1290
+ right->flags |= AH_EDGE_DONE;
1294
+ delta = ah_hint_normal_stem( hinter, edge, edge2, 0, 0 );
1301
+ ah_hint_normal_stem( hinter, edge, edge2,
1302
+ delta, dimension );
1306
+ edge->flags |= AH_EDGE_DONE;
1307
+ edge2->flags |= AH_EDGE_DONE;
1312
/* make sure that lowercase m's maintain their symmetry */
1314
/* one pixel higher or lower. */
1316
n_edges = edge_limit - edges;
1317
- if ( !dimension && ( n_edges == 6 || n_edges == 12 ) )
1318
+ if ( hinter->do_blue_hints &&
1319
+ !dimension && ( n_edges == 6 || n_edges == 12 ) )
1321
AH_EdgeRec *edge1, *edge2, *edge3;
1322
FT_Pos dist1, dist2, span, delta;
1328
+ if ( edge1->link == edge1 + 1 &&
1329
+ edge2->link == edge2 + 1 &&
1330
+ edge3->link == edge3 + 1 && span < 8 )
1332
delta = edge3->pos - ( 2 * edge2->pos - edge1->pos );
1333
edge3->pos -= delta;
1334
@@ -761,25 +986,48 @@
1338
- ah_align_serif_edge( hinter, edge->serif, edge, dimension );
1339
- else if ( !anchor )
1341
- edge->pos = ( edge->opos + 32 ) & -64;
1343
+ ah_align_serif_edge( hinter, edge->serif, edge, dimension );
1344
+ edge->flags |= AH_EDGE_DONE;
1348
- edge->pos = anchor->pos +
1349
- ( ( edge->opos-anchor->opos + 32 ) & -64 );
1352
+ if ( !has_serifs )
1353
+ goto Next_Dimension;
1355
+ for ( edge = edges; edge < edge_limit; edge++ )
1357
+ AH_Edge before, after;
1359
- edge->flags |= AH_EDGE_DONE;
1361
- if ( edge > edges && edge->pos < edge[-1].pos )
1362
- edge->pos = edge[-1].pos;
1363
+ if ( edge->flags & AH_EDGE_DONE )
1366
+ before = after = edge;
1368
+ while ( --before >= edges )
1369
+ if ( before->flags & AH_EDGE_DONE )
1372
+ while ( ++after < edge_limit )
1373
+ if ( after->flags & AH_EDGE_DONE )
1376
+ if ( before >= edges || after < edge_limit )
1378
+ if ( before < edges )
1379
+ edge->pos = edge->opos + ( after->pos - after->opos );
1381
+ else if ( after >= edge_limit )
1382
+ edge->pos = edge->opos + ( before->pos - before->opos );
1384
- if ( edge + 1 < edge_limit &&
1385
- edge[1].flags & AH_EDGE_DONE &&
1386
- edge->pos > edge[1].pos )
1387
- edge->pos = edge[1].pos;
1389
+ edge->pos = before->pos +
1390
+ FT_MulDiv( edge->fpos - before->fpos,
1391
+ after->pos - before->pos,
1392
+ after->fpos - before->fpos );
1397
@@ -806,10 +1054,12 @@
1404
edges = outline->horz_edges;
1405
edge_limit = edges + outline->num_hedges;
1406
+ snapping = hinter->do_vert_snapping;
1408
for ( dimension = 1; dimension >= 0; dimension-- )
1410
@@ -821,7 +1071,8 @@
1412
/* move the points of each segment */
1413
/* in each edge to the edge's position */
1414
- AH_Segment seg = edge->first;
1415
+ AH_Segment seg = edge->first;
1416
+ FT_Pos delta = edge->pos - edge->opos;
1420
@@ -829,23 +1080,47 @@
1421
AH_Point point = seg->first;
1430
- point->y = edge->pos;
1431
- point->flags |= AH_FLAG_TOUCH_Y;
1434
+ point->y = edge->pos;
1435
+ point->flags |= AH_FLAG_TOUCH_Y;
1439
+ point->x = edge->pos;
1440
+ point->flags |= AH_FLAG_TOUCH_X;
1443
+ if ( point == seg->last )
1446
+ point = point->next;
1454
- point->x = edge->pos;
1455
- point->flags |= AH_FLAG_TOUCH_X;
1459
+ point->y += delta;
1460
+ point->flags |= AH_FLAG_TOUCH_Y;
1464
+ point->x += delta;
1465
+ point->flags |= AH_FLAG_TOUCH_X;
1468
- if ( point == seg->last )
1470
+ if ( point == seg->last )
1473
- point = point->next;
1474
+ point = point->next;
1478
seg = seg->edge_next;
1479
@@ -855,6 +1130,7 @@
1481
edges = outline->vert_edges;
1482
edge_limit = edges + outline->num_vedges;
1483
+ snapping = hinter->do_horz_snapping;
1487
@@ -871,6 +1147,7 @@
1489
AH_Point point_limit;
1490
AH_Flags touch_flag;
1491
+ AH_Flags strong_flag;
1494
points = outline->points;
1495
@@ -879,6 +1156,7 @@
1496
edges = outline->horz_edges;
1497
edge_limit = edges + outline->num_hedges;
1498
touch_flag = AH_FLAG_TOUCH_Y;
1499
+ strong_flag = AH_FLAG_STRONG_Y;
1501
for ( dimension = 1; dimension >= 0; dimension-- )
1503
@@ -899,8 +1177,7 @@
1504
#ifndef AH_OPTION_NO_WEAK_INTERPOLATION
1505
/* if this point is candidate to weak interpolation, we will */
1506
/* interpolate it after all strong points have been processed */
1507
- if ( ( point->flags & AH_FLAG_WEAK_INTERPOLATION ) &&
1508
- !( point->flags & AH_FLAG_INFLECTION ) )
1509
+ if ( !( point->flags & strong_flag ) )
1513
@@ -1034,6 +1311,7 @@
1514
edges = outline->vert_edges;
1515
edge_limit = edges + outline->num_vedges;
1516
touch_flag = AH_FLAG_TOUCH_X;
1517
+ strong_flag = AH_FLAG_STRONG_X;
1521
@@ -1234,10 +1512,8 @@
1524
FT_LOCAL_DEF( void )
1525
- ah_hinter_align_points( AH_Hinter hinter )
1526
+ ah_hinter_align_normal_points( AH_Hinter hinter )
1528
- ah_hinter_align_edge_points( hinter );
1530
#ifndef AH_OPTION_NO_STRONG_INTERPOLATION
1531
ah_hinter_align_strong_points( hinter );
1533
@@ -1263,17 +1539,69 @@
1535
ah_hinter_scale_globals( AH_Hinter hinter,
1537
- FT_Fixed y_scale )
1542
AH_Face_Globals globals = hinter->globals;
1543
- AH_Globals design = &globals->design;
1544
+ AH_Globals design = &globals->designs[type];
1545
AH_Globals scaled = &globals->scaled;
1546
+ FT_Pos baseline = design->baseline;
1549
+ globals->x_scale_linear = x_scale;
1550
+ globals->y_scale_linear = y_scale;
1551
+ globals->cur_type = type;
1556
+#ifdef FT_CONFIG_CHESTER_BLUE_SCALE
1558
+ /* try to optimize the y_scale so that the top of non-capital letters
1559
+ * is aligned on a pixel boundary whenever possible
1561
+ if ( design->has_blues )
1563
+ FT_Pos shoot = design->blue_shoots[AH_BLUE_SMALL_TOP];
1564
+ FT_Pos ref = design->blue_refs[AH_BLUE_SMALL_TOP];
1567
+ baseline = FT_MulFix( baseline, y_scale );
1569
+ /* the value of 'shoot' will be -1000 if the font doesn't have */
1570
+ /* small latin letters; we simply check the sign here... */
1576
+ shoot = FT_MulFix( shoot, y_scale );
1577
+ ref = FT_MulFix( ref, y_scale );
1579
+ if ( shoot < 6*64 )
1580
+ fitted = ( shoot + 44 ) & -64;
1581
+ else if ( shoot < 8*64 )
1582
+ fitted = ( shoot + 38 ) & -64;
1584
+ fitted = ( shoot + 32 ) & -64;
1587
+ if ( ref <= fitted && fitted < shoot )
1589
+ else if ( fitted < ref )
1592
+ if ( fitted > shoot )
1594
+ y_scale = FT_MulDiv( y_scale, fitted, shoot );
1595
+ baseline -= ( fitted - shoot )/2;
1600
+#endif /* FT_CONFIG_CHESTER_BLUE_SCALE */
1602
/* scale the standard widths & heights */
1603
for ( n = 0; n < design->num_widths; n++ )
1604
scaled->widths[n] = FT_MulFix( design->widths[n], x_scale );
1605
@@ -1284,10 +1612,20 @@
1606
scaled->stds[0] = ( design->num_widths > 0 ) ? scaled->widths[0] : 32000;
1607
scaled->stds[1] = ( design->num_heights > 0 ) ? scaled->heights[0] : 32000;
1609
+ globals->x_scale = x_scale;
1610
+ globals->y_scale = y_scale;
1612
+ if ( !design->has_blues )
1616
+ scaled->baseline = ( baseline + 32 ) & -64;
1618
/* scale the blue zones */
1619
for ( n = 0; n < AH_BLUE_MAX; n++ )
1621
FT_Pos delta, delta2;
1622
+ FT_Pos ref, shoot, delta3, delta4;
1625
delta = design->blue_shoots[n] - design->blue_refs[n];
1626
@@ -1306,13 +1644,37 @@
1630
- scaled->blue_refs[n] =
1631
- ( FT_MulFix( design->blue_refs[n], y_scale ) + 32 ) & -64;
1632
- scaled->blue_shoots[n] = scaled->blue_refs[n] + delta2;
1634
+ if ( n == AH_BLUE_SMALL_BOTTOM )
1636
+ scaled->blue_shoots[n] = delta2;
1637
+ scaled->blue_refs[n] = 0;
1641
- globals->x_scale = x_scale;
1642
- globals->y_scale = y_scale;
1643
+ shoot = FT_MulFix( design->blue_shoots[n], y_scale );
1644
+ ref = FT_MulFix( design->blue_refs[n], y_scale );
1645
+ delta3 = ( ( shoot + 32 ) & -64 ) - shoot;
1646
+ delta4 = ( ( ref + 32 ) & -64 ) - ref;
1648
+ if ( !hinter->do_stem_adjust )
1650
+ if ( delta3 > 16 ) delta3 = 16;
1651
+ if ( delta3 < -16 ) delta3 = -16;
1652
+ if ( delta4 > 16 ) delta4 = 16;
1653
+ if ( delta4 < -16 ) delta4 = -16;
1659
+ if ( ABS( delta3 ) < ABS( delta4 ) )
1660
+ ref = shoot - delta2;
1662
+ shoot = ref + delta2;
1664
+ scaled->blue_refs[n] = ref;
1665
+ scaled->blue_shoots[n] = shoot;
1670
@@ -1320,7 +1682,7 @@
1671
ah_hinter_align( AH_Hinter hinter )
1673
ah_hinter_align_edge_points( hinter );
1674
- ah_hinter_align_points( hinter );
1675
+ ah_hinter_align_normal_points( hinter );
1679
@@ -1401,7 +1763,7 @@
1680
hinter->globals = face_globals;
1683
- face_globals->design = *globals;
1684
+ face_globals->designs[0] = *globals;
1686
ah_hinter_compute_globals( hinter );
1688
@@ -1410,6 +1772,27 @@
1689
ah_hinter_done_face_globals;
1690
face_globals->face = face;
1692
+ ah_hinter_compute_char_table( hinter );
1695
+ TT_OS2* os2 = FT_Get_Sfnt_Table( face, ft_sfnt_os2 );
1698
+ if ( os2 && os2->version != 0xFFFFU )
1699
+ face_globals->is_fixedpitch = FT_BOOL( os2->panose[3] == 9 );
1701
+ face_globals->is_fixedpitch = FT_BOOL( FT_IS_FIXED_WIDTH( face ) != 0 );
1704
+ face_globals->has_tt_bytecode_interp = FALSE;
1706
+#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
1707
+ if ( !strcmp( face->driver->root.clazz->module_name, "truetype" ) ||
1708
+ !strcmp( face->driver->root.clazz->module_name, "type42" ) )
1709
+ face_globals->has_tt_bytecode_interp = TRUE;
1716
@@ -1423,6 +1806,8 @@
1717
FT_Memory memory = face->memory;
1720
+ FT_Done_Size( globals->size_EM );
1721
+ FT_FREE( globals->table );
1725
@@ -1441,12 +1826,17 @@
1727
AH_Outline outline = hinter->glyph;
1728
AH_Loader gloader = hinter->loader;
1729
+ FT_Pos baseline = 0;
1730
+ FT_Byte type = hinter->globals->cur_type;
1733
/* load the glyph */
1734
- error = FT_Load_Glyph( face, glyph_index, load_flags );
1737
+ if ( !hinter->globals->has_tt_bytecode_interp )
1739
+ error = FT_Load_Glyph( face, glyph_index, load_flags );
1744
/* Set `hinter->transformed' after loading with FT_LOAD_NO_RECURSE. */
1745
hinter->transformed = internal->glyph_transformed;
1746
@@ -1463,6 +1853,11 @@
1747
FT_Matrix_Invert( &imatrix );
1748
FT_Vector_Transform( &hinter->trans_delta, &imatrix );
1752
+ hinter->trans_delta.x = 0;
1753
+ hinter->trans_delta.y = 0;
1756
/* set linear horizontal metrics */
1757
slot->linearHoriAdvance = slot->metrics.horiAdvance;
1758
@@ -1472,17 +1867,22 @@
1760
case FT_GLYPH_FORMAT_OUTLINE:
1762
+ if ( hinter->do_blue_hints )
1763
+ baseline = hinter->globals->designs[type].baseline;
1765
/* translate glyph outline if we need to */
1766
- if ( hinter->transformed )
1767
+ if ( hinter->transformed || baseline != 0 )
1769
FT_UInt n = slot->outline.n_points;
1770
FT_Vector* point = slot->outline.points;
1771
+ FT_Pos x_off = hinter->trans_delta.x;
1772
+ FT_Pos y_off = hinter->trans_delta.y - baseline;
1775
for ( ; n > 0; point++, n-- )
1777
- point->x += hinter->trans_delta.x;
1778
- point->y += hinter->trans_delta.y;
1779
+ point->x += x_off;
1780
+ point->y += y_off;
1784
@@ -1524,7 +1924,7 @@
1785
/* perform feature detection */
1786
ah_outline_detect_features( outline );
1788
- if ( hinter->do_vert_hints )
1789
+ if ( hinter->do_blue_hints )
1791
ah_outline_compute_blue_edges( outline, hinter->globals );
1792
ah_outline_scale_blue_edges( outline, hinter->globals );
1793
@@ -1539,6 +1939,8 @@
1795
/* we now need to hint the metrics according to the change in */
1796
/* width/positioning that occured during the hinting process */
1797
+ if ( !hinter->globals->is_fixedpitch && !hinter->composite &&
1798
+ type <= AH_CHAR_TYPE_HORIZONTAL )
1800
FT_Pos old_advance, old_rsb, old_lsb, new_lsb;
1801
AH_Edge edge1 = outline->vert_edges; /* leftmost edge */
1802
@@ -1551,8 +1953,8 @@
1803
old_lsb = edge1->opos;
1804
new_lsb = edge1->pos;
1806
- hinter->pp1.x = ( ( new_lsb - old_lsb ) + 32 ) & -64;
1807
- hinter->pp2.x = ( ( edge2->pos + old_rsb ) + 32 ) & -64;
1808
+ hinter->pp1.x = ( ( new_lsb - old_lsb ) + 32 ) & -64;
1809
+ hinter->pp2.x = ( ( edge2->pos + old_rsb ) + 40 ) & -64;
1812
/* try to fix certain bad advance computations */
1813
@@ -1705,6 +2107,13 @@
1817
+ if ( hinter->do_blue_hints )
1819
+ if ( hinter->globals->scaled.baseline != 0 )
1820
+ FT_Outline_Translate( &gloader->base.outline,
1821
+ 0, hinter->globals->scaled.baseline );
1824
/* transform the hinted outline if needed */
1825
if ( hinter->transformed )
1826
FT_Outline_Transform( &gloader->base.outline, &hinter->trans_matrix );
1827
@@ -1725,14 +2134,7 @@
1828
slot->metrics.horiBearingX = bbox.xMin;
1829
slot->metrics.horiBearingY = bbox.yMax;
1831
- /* for mono-width fonts (like Andale, Courier, etc.) we need */
1832
- /* to keep the original rounded advance width */
1833
- if ( !FT_IS_FIXED_WIDTH( slot->face ) )
1834
- slot->metrics.horiAdvance = hinter->pp2.x - hinter->pp1.x;
1836
- slot->metrics.horiAdvance = FT_MulFix( slot->metrics.horiAdvance,
1839
+ slot->metrics.horiAdvance = hinter->pp2.x - hinter->pp1.x;
1840
slot->metrics.horiAdvance = ( slot->metrics.horiAdvance + 32 ) & -64;
1842
/* now copy outline into glyph slot */
1843
@@ -1754,6 +2156,236 @@
1847
+#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
1849
+#define AH_MAX_COMPOSITE_RECURSE 5
1852
+ ah_hinter_load_truetype( AH_Hinter hinter,
1853
+ FT_UInt glyph_index,
1854
+ FT_Int32 load_flags,
1856
+ short **num_contours,
1857
+ short **num_points,
1858
+ int *num_simple_glyphs,
1861
+ FT_Face face = hinter->face;
1862
+ FT_Memory memory = hinter->memory;
1863
+ FT_GlyphSlot slot = face->glyph;
1864
+ FT_Error error = FT_Err_Ok;
1869
+ *num_contours = 0;
1871
+ *num_simple_glyphs = 0;
1875
+ error = FT_Load_Glyph( face, glyph_index, load_flags );
1880
+ switch ( slot->format )
1882
+ case FT_GLYPH_FORMAT_OUTLINE:
1884
+ int size_cur = *size_array;
1888
+ return ah_hinter_load( hinter, 0, load_flags, 0 );
1890
+ if ( slot->outline.n_contours == 0 )
1893
+ if ( *num_simple_glyphs >= size_cur )
1895
+ if ( FT_RENEW_ARRAY( *num_contours, size_cur, size_cur + 16 ) ||
1896
+ FT_RENEW_ARRAY( *num_points, size_cur, size_cur + 16 ) )
1898
+ *size_array += 16;
1901
+ (*num_contours)[ (*num_simple_glyphs) ] = slot->outline.n_contours;
1902
+ (*num_points)[ (*num_simple_glyphs)++ ] = slot->outline.n_points;
1906
+ case FT_GLYPH_FORMAT_COMPOSITE:
1907
+ if ( depth + 1 >= AH_MAX_COMPOSITE_RECURSE )
1908
+ return AH_Err_Invalid_Composite;
1910
+ if ( slot->num_subglyphs > 0 )
1913
+ int num_subglyphs = slot->num_subglyphs;
1917
+ hinter->composite = TRUE;
1919
+ if ( FT_NEW_ARRAY( indices, num_subglyphs ) )
1922
+ for ( i = 0; i < num_subglyphs; i++ )
1923
+ indices[i] = slot->subglyphs[i].index;
1926
+ for ( i = 0; i < num_subglyphs; i++ )
1928
+ error = ah_hinter_load_truetype( hinter,
1934
+ num_simple_glyphs,
1938
+ FT_FREE( indices );
1943
+ FT_FREE( indices );
1947
+ FT_Size size_EM, size;
1948
+ FT_Vector* points;
1950
+ int num = *num_simple_glyphs, j;
1951
+ short n_contours, n_points;
1952
+ short *array_c, *array_p;
1958
+ size = face->size;
1959
+ size_EM = hinter->globals->size_EM;
1963
+ error = FT_New_Size( face, &hinter->globals->size_EM );
1967
+ size_EM = hinter->globals->size_EM;
1968
+ FT_Activate_Size( size_EM );
1970
+ error = FT_Set_Pixel_Sizes( face,
1971
+ face->units_per_EM,
1972
+ face->units_per_EM );
1975
+ FT_Activate_Size( size );
1980
+ FT_Activate_Size( size_EM );
1983
+ load_flags &= ~FT_LOAD_NO_RECURSE &
1984
+ ~FT_LOAD_NO_SCALE;
1985
+ load_flags |= FT_LOAD_NO_BITMAP |
1986
+ FT_LOAD_NO_AUTOHINT |
1987
+ FT_LOAD_IGNORE_TRANSFORM;
1989
+ error = FT_Load_Glyph( face, glyph_index, load_flags );
1991
+ FT_Activate_Size( size );
1997
+ array_c = *num_contours;
1998
+ array_p = *num_points;
2002
+ for ( i = 0; i < num; i++ )
2004
+ n_contours += *array_c++;
2005
+ n_points += *array_p++;
2008
+ if ( slot->outline.n_points != n_points ||
2009
+ slot->outline.n_contours != n_contours )
2011
+ error = AH_Err_Invalid_Composite;
2016
+ points = slot->outline.points;
2017
+ limit = points + slot->outline.n_points;
2019
+ while ( points < limit )
2026
+ slot->metrics.horiAdvance >>= 6;
2027
+ slot->metrics.vertAdvance >>= 6;
2029
+ array_c = *num_contours;
2030
+ array_p = *num_points;
2032
+ for ( i = 0; i < num - 1; i++ )
2034
+ slot->outline.n_contours = *array_c++;
2035
+ slot->outline.n_points = *array_p++;
2037
+ error = ah_hinter_load( hinter, 0, load_flags, 1 );
2041
+ n_points = slot->outline.n_points;
2042
+ slot->outline.points += n_points;
2043
+ slot->outline.tags += n_points;
2044
+ slot->outline.contours += slot->outline.n_contours;
2045
+ n_contours -= slot->outline.n_contours;
2047
+ for ( j = 0; j < n_contours; j++ )
2048
+ slot->outline.contours[j] -= n_points;
2051
+ slot->outline.n_contours = *array_c;
2052
+ slot->outline.n_points = *array_p;
2054
+ error = ah_hinter_load( hinter, 0, load_flags, 0 );
2060
+ error = AH_Err_Unimplemented_Feature;
2067
+ FT_FREE( *num_contours );
2068
+ FT_FREE( *num_points );
2074
+#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
2077
/* load and hint a given glyph */
2078
FT_LOCAL_DEF( FT_Error )
2079
ah_hinter_load_glyph( AH_Hinter hinter,
2080
@@ -1768,6 +2400,7 @@
2081
FT_Fixed y_scale = size->metrics.y_scale;
2082
AH_Face_Globals face_globals = FACE_GLOBALS( face );
2083
FT_Render_Mode hint_mode = FT_LOAD_TARGET_MODE( load_flags );
2087
/* first of all, we need to check that we're using the correct face and */
2088
@@ -1787,46 +2420,6 @@
2092
-#ifdef FT_CONFIG_CHESTER_BLUE_SCALE
2094
- /* try to optimize the y_scale so that the top of non-capital letters
2095
- * is aligned on a pixel boundary whenever possible
2098
- AH_Globals design = &face_globals->design;
2099
- FT_Pos shoot = design->blue_shoots[AH_BLUE_SMALL_TOP];
2102
- /* the value of 'shoot' will be -1000 if the font doesn't have */
2103
- /* small latin letters; we simply check the sign here... */
2106
- FT_Pos scaled = FT_MulFix( shoot, y_scale );
2107
- FT_Pos fitted = ( scaled + 32 ) & -64;
2110
- if ( scaled != fitted )
2114
- y_scale = FT_MulDiv( y_scale, fitted, scaled );
2118
- if ( fitted < scaled )
2119
- x_scale -= x_scale / 50; /* x_scale*0.98 with integers */
2124
-#endif /* FT_CONFIG_CHESTER_BLUE_SCALE */
2126
- /* now, we must check the current character pixel size to see if we */
2127
- /* need to rescale the global metrics */
2128
- if ( face_globals->x_scale != x_scale ||
2129
- face_globals->y_scale != y_scale )
2130
- ah_hinter_scale_globals( hinter, x_scale, y_scale );
2132
ah_loader_rewind( hinter->loader );
2134
/* reset hinting flags according to load flags and current render target */
2135
@@ -1850,11 +2443,51 @@
2137
hinter->do_stem_adjust = FT_BOOL( hint_mode != FT_RENDER_MODE_LIGHT );
2139
+ type = ah_hinter_get_char_type( hinter, glyph_index );
2141
+ hinter->do_blue_hints = face_globals->designs[type].has_blues;
2142
+ hinter->composite = FALSE;
2144
+ /* now, we must check the current character pixel size to see if we */
2145
+ /* need to rescale the global metrics */
2146
+ if ( face_globals->x_scale_linear != x_scale ||
2147
+ face_globals->y_scale_linear != y_scale ||
2148
+ face_globals->cur_type != type )
2149
+ ah_hinter_scale_globals( hinter, x_scale, y_scale, type );
2151
load_flags |= FT_LOAD_NO_SCALE
2152
| FT_LOAD_IGNORE_TRANSFORM;
2153
load_flags &= ~FT_LOAD_RENDER;
2155
- error = ah_hinter_load( hinter, glyph_index, load_flags, 0 );
2156
+#ifndef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
2158
+ error = ah_hinter_load( hinter, glyph_index, load_flags, 0 );
2162
+ if ( face_globals->has_tt_bytecode_interp )
2164
+ short* num_contours;
2165
+ short* num_points;
2166
+ int num_simple_glyphs;
2170
+ load_flags |= FT_LOAD_NO_RECURSE;
2172
+ error = ah_hinter_load_truetype( hinter,
2178
+ &num_simple_glyphs,
2182
+ error = ah_hinter_load( hinter, glyph_index, load_flags, 0 );
2184
+#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
2188
@@ -1885,7 +2518,7 @@
2192
- *globals = FACE_GLOBALS( face )->design;
2193
+ *globals = FACE_GLOBALS( face )->designs[0];
2194
*global_hints = globals;
2195
*global_len = sizeof( *globals );
2197
diff -u freetype-2.1.7-orig/src/autohint/ahtypes.h freetype-2.1.7/src/autohint/ahtypes.h
2198
--- freetype-2.1.7-orig/src/autohint/ahtypes.h Wed May 28 14:52:05 2003
2199
+++ freetype-2.1.7/src/autohint/ahtypes.h Sat Nov 29 08:24:43 2003
2201
/* weak interpolation */
2202
#define AH_FLAG_WEAK_INTERPOLATION 256
2203
#define AH_FLAG_INFLECTION 512
2204
+#define AH_FLAG_STRONG_X 1024
2205
+#define AH_FLAG_STRONG_Y 2048
2207
typedef FT_Int AH_Flags;
2209
@@ -264,7 +266,10 @@
2210
AH_Segment link; /* link segment */
2211
AH_Segment serif; /* primary segment for serifs */
2212
FT_Pos num_linked; /* number of linked segments */
2219
AH_Point first; /* first point in edge segment */
2220
AH_Point last; /* last point in edge segment */
2221
@@ -402,6 +407,37 @@
2222
typedef FT_Int AH_Hinter_Flags;
2225
+#define AH_LIGHT_MODE_MAX_HORZ_GAP 9
2226
+#define AH_LIGHT_MODE_MAX_VERT_GAP 15
2227
+#define AH_LIGHT_MODE_MAX_DELTA_ABS 14
2231
+ AH_CHAR_TYPE_LATINATE = 0,
2232
+ AH_CHAR_TYPE_LATIN_FULLWIDTH,
2233
+ AH_CHAR_TYPE_HORIZONTAL,
2234
+ AH_CHAR_TYPE_OTHER,
2235
+ AH_CHAR_TYPE_COUNT
2239
+ typedef struct AH_CharType_
2248
+ typedef struct AH_CharTypeTable_
2251
+ AH_CharType* types;
2253
+ } AH_CharTypeTable;
2256
/*************************************************************************/
2259
@@ -440,6 +476,10 @@
2260
FT_Pos blue_refs [AH_BLUE_MAX];
2261
FT_Pos blue_shoots[AH_BLUE_MAX];
2265
+ FT_Bool has_blues;
2267
} AH_GlobalsRec, *AH_Globals;
2270
@@ -470,12 +510,21 @@
2271
typedef struct AH_Face_GlobalsRec_
2274
- AH_GlobalsRec design;
2275
+ AH_GlobalsRec designs[AH_CHAR_TYPE_COUNT];
2276
AH_GlobalsRec scaled;
2279
FT_Bool control_overshoot;
2281
+ FT_Fixed x_scale_linear;
2282
+ FT_Fixed y_scale_linear;
2284
+ AH_CharTypeTable* table;
2287
+ FT_Bool is_fixedpitch;
2288
+ FT_Bool has_tt_bytecode_interp;
2290
} AH_Face_GlobalsRec, *AH_Face_Globals;
2297
+ FT_Bool composite;
2299
FT_Bool transformed;
2300
FT_Vector trans_delta;
2302
FT_Bool do_horz_snapping; /* disable X stem size snapping */
2303
FT_Bool do_vert_snapping; /* disable Y stem size snapping */
2304
FT_Bool do_stem_adjust; /* disable light stem snapping */
2305
+ FT_Bool do_blue_hints; /* disable blue hinting */
2307
} AH_HinterRec, *AH_Hinter;
2309
diff -u freetype-2.1.7-orig/src/autohint/autohint.c freetype-2.1.7/src/autohint/autohint.c
2310
--- freetype-2.1.7-orig/src/autohint/autohint.c Fri Jun 29 02:48:46 2001
2311
+++ freetype-2.1.7/src/autohint/autohint.c Sat Nov 29 08:24:43 2003
2313
#define FT_MAKE_OPTION_SINGLE_OBJECT
2315
#include <ft2build.h>
2316
-#include "ahangles.c"
2317
#include "ahglyph.c"
2318
#include "ahglobal.c"