~ubuntu-branches/ubuntu/hardy/freetype/hardy

« back to all changes in this revision

Viewing changes to debian/patches/012-freetype-2.1.7-autohint-cjkfonts-20031130.diff

  • Committer: Bazaar Package Importer
  • Author(s): Keith Packard
  • Date: 2006-05-17 00:00:35 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20060517000035-odcclen30oc10kmk
Tags: 2.2.1-2
* Enable full bytecode interpreter instead of just the
  "non-patented portions".
* Use $(CURDIR) instead of $(PWD) to build with sudo. Closes: #367579.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
4
 
@@ -30,7 +30,7 @@
5
 
   /* cf. AH_BLUE_XXX constants in ahtypes.h */
6
 
 
7
 
   static
8
 
-  const char* const  blue_chars[AH_BLUE_MAX] =
9
 
+  const char* const  blue_chars_latin[AH_BLUE_MAX] =
10
 
   {
11
 
     "THEZOCQS",
12
 
     "HEZLOCUS",
13
 
@@ -43,6 +43,35 @@
14
 
   };
15
 
 
16
 
 
17
 
+  typedef struct AH_BlueTable_
18
 
+  {
19
 
+    FT_ULong      offset_blue_chars;
20
 
+    const char**  blue_chars;
21
 
+    FT_ULong      char_for_widths;
22
 
+
23
 
+  } AH_BlueTable;
24
 
+
25
 
+
26
 
+  static const AH_BlueTable  blue_table[AH_CHAR_TYPE_COUNT] =
27
 
+  {
28
 
+    { 0,       blue_chars_latin, (FT_ULong)'o' },
29
 
+    { 0xFEE0L, blue_chars_latin,  0xFF4FL      },
30
 
+    { 0,       0,                 0            },
31
 
+    { 0,       0,                 0            }
32
 
+  };
33
 
+
34
 
+
35
 
+#ifdef AH_DEBUG
36
 
+  static const char* const  blue_names[AH_CHAR_TYPE_COUNT] =
37
 
+  {
38
 
+    "general latinate chars",
39
 
+    "CJK fullwidth latin chars",
40
 
+    0,
41
 
+    0
42
 
+  };
43
 
+#endif
44
 
+
45
 
+
46
 
   /* simple insertion sort */
47
 
   static void
48
 
   sort_values( FT_Int   count,
49
 
@@ -71,7 +100,7 @@
50
 
   ah_hinter_compute_blues( AH_Hinter  hinter )
51
 
   {
52
 
     AH_Blue       blue;
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];
57
 
     FT_Int        num_flats;
58
 
@@ -81,6 +110,9 @@
59
 
     FT_GlyphSlot  glyph;
60
 
     FT_Error      error;
61
 
     FT_CharMap    charmap;
62
 
+    FT_ULong      offset;
63
 
+    FT_Byte       type;
64
 
+    const char**  blue_chars;
65
 
 
66
 
 
67
 
     face  = hinter->face;
68
 
@@ -97,8 +129,19 @@
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;
73
 
 
74
 
-    AH_LOG(( "blue zones computation\n" ));
75
 
+  Compute_Blues:
76
 
+    globals->has_blues = FALSE;
77
 
+    globals->baseline  = 0;
78
 
+
79
 
+    offset     = blue_table[type].offset_blue_chars;
80
 
+    blue_chars = blue_table[type].blue_chars;
81
 
+
82
 
+    if ( !blue_chars )
83
 
+      goto Next_Type;
84
 
+
85
 
+    AH_LOG(( "blue zones computation for %s\n", blue_names[type] ));
86
 
     AH_LOG(( "------------------------------------------------\n" ));
87
 
 
88
 
     for ( blue = AH_BLUE_CAPITAL_TOP; blue < AH_BLUE_MAX; blue++ )
89
 
@@ -131,7 +174,7 @@
90
 
         AH_LOG(( "`%c'", *p ));
91
 
 
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 )
96
 
           continue;
97
 
 
98
 
@@ -221,10 +264,30 @@
99
 
 
100
 
           } while ( next != idx );
101
 
 
102
 
-          /* now, set the `round' flag depending on the segment's kind */
103
 
-          round = FT_BOOL(
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.            */
108
 
+          round = TRUE;
109
 
+
110
 
+          {
111
 
+            FT_Int   n = 0, p = prev;
112
 
+            FT_Bool  is_top = AH_IS_TOP_BLUE( blue );
113
 
+
114
 
+
115
 
+            while ( ( p = ( p >= last )? first : p + 1 ) != next )
116
 
+            {
117
 
+              if ( FT_CURVE_TAG( glyph->outline.tags[p] ) == FT_CURVE_TAG_ON )
118
 
+              {
119
 
+                if ( (  is_top && points[p].y < extremum->y ) ||
120
 
+                     ( !is_top && points[p].y > extremum->y )  )
121
 
+                  break;
122
 
+
123
 
+                n++;
124
 
+              }
125
 
+            }
126
 
+
127
 
+            if ( n >= 2 && p == next )
128
 
+              round = FALSE;
129
 
+          }
130
 
 
131
 
           AH_LOG(( "%c ", round ? 'r' : 'f' ));
132
 
         }
133
 
@@ -281,6 +344,30 @@
134
 
       }
135
 
 
136
 
       AH_LOG(( "-- ref = %ld, shoot = %ld\n", *blue_ref, *blue_shoot ));
137
 
+
138
 
+      if ( num_flats > 0 || num_rounds > 0 )
139
 
+        globals->has_blues = TRUE;
140
 
+    }
141
 
+
142
 
+    globals->baseline = globals->blue_refs[AH_BLUE_SMALL_BOTTOM];
143
 
+
144
 
+    if ( globals->baseline > -10000 )
145
 
+    {
146
 
+      for ( blue = AH_BLUE_CAPITAL_TOP; blue < AH_BLUE_MAX; blue++ )
147
 
+      {
148
 
+        if ( globals->blue_refs[blue] > -10000 )
149
 
+        {
150
 
+          globals->blue_refs[blue]   -= globals->baseline;
151
 
+          globals->blue_shoots[blue] -= globals->baseline;
152
 
+        }
153
 
+      }
154
 
+    }
155
 
+
156
 
+  Next_Type:
157
 
+    if ( ++type < AH_CHAR_TYPE_COUNT )
158
 
+    {
159
 
+      globals++;
160
 
+      goto Compute_Blues;
161
 
     }
162
 
 
163
 
     /* reset original face charmap */
164
 
@@ -299,13 +386,23 @@
165
 
     AH_Outline  outline = hinter->glyph;
166
 
     AH_Segment  segments;
167
 
     AH_Segment  limit;
168
 
-    AH_Globals  globals = &hinter->globals->design;
169
 
+    AH_Globals  globals = hinter->globals->designs;
170
 
     FT_Pos*     widths;
171
 
     FT_Int      dimension;
172
 
     FT_Int*     p_num_widths;
173
 
     FT_Error    error = 0;
174
 
     FT_Pos      edge_distance_threshold = 32000;
175
 
+    FT_Byte     type;
176
 
+    FT_ULong    char_for_widths;
177
 
+
178
 
+
179
 
+    type = AH_CHAR_TYPE_LATINATE;
180
 
 
181
 
+  Compute_Widths:
182
 
+    char_for_widths = blue_table[type].char_for_widths;
183
 
+
184
 
+    if ( !char_for_widths )
185
 
+      goto Next_Type;
186
 
 
187
 
     globals->num_widths  = 0;
188
 
     globals->num_heights = 0;
189
 
@@ -318,18 +415,18 @@
190
 
       FT_UInt  glyph_index;
191
 
 
192
 
 
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 )
196
 
-        return 0;
197
 
+        goto Next_Type;
198
 
 
199
 
       error = FT_Load_Glyph( hinter->face, glyph_index, FT_LOAD_NO_SCALE );
200
 
       if ( error )
201
 
-        goto Exit;
202
 
+        goto Next_Type;
203
 
 
204
 
       error = ah_outline_load( hinter->glyph, 0x10000L, 0x10000L,
205
 
                                hinter->face );
206
 
       if ( error )
207
 
-        goto Exit;
208
 
+        goto Next_Type;
209
 
 
210
 
       ah_outline_compute_segments( hinter->glyph );
211
 
       ah_outline_link_segments( hinter->glyph );
212
 
@@ -378,6 +475,13 @@
213
 
       p_num_widths = &globals->num_widths;
214
 
     }
215
 
 
216
 
+  Next_Type:
217
 
+    if ( type++ < AH_CHAR_TYPE_COUNT )
218
 
+    {
219
 
+      globals++;
220
 
+      goto Compute_Widths;
221
 
+    }
222
 
+
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 )
226
 
@@ -386,8 +490,7 @@
227
 
     /* let's try 20% */
228
 
     hinter->glyph->edge_distance_threshold = edge_distance_threshold / 5;
229
 
 
230
 
-  Exit:
231
 
-    return error;
232
 
+    return 0;
233
 
   }
234
 
 
235
 
 
236
 
@@ -396,6 +499,192 @@
237
 
   {
238
 
     return ah_hinter_compute_widths( hinter ) ||
239
 
            ah_hinter_compute_blues ( hinter );
240
 
+  }
241
 
+
242
 
+
243
 
+  static const AH_CharType
244
 
+  ah_types_for_unicode[] =
245
 
+  {
246
 
+     /* Latin, Greek, Cyrillic */
247
 
+    { AH_CHAR_TYPE_LATINATE,        0x21L,   0x52FL  },
248
 
+
249
 
+     /* Hebrew */
250
 
+    { AH_CHAR_TYPE_LATINATE,        0x5D0L,  0x600L  },
251
 
+
252
 
+     /* Latin, Greek */
253
 
+    { AH_CHAR_TYPE_LATINATE,        0x1E00L, 0x2000L },
254
 
+
255
 
+     /* CJK fullwidth Latin */
256
 
+    { AH_CHAR_TYPE_LATIN_FULLWIDTH, 0xFF00L, 0xFF60L }
257
 
+  };
258
 
+
259
 
+
260
 
+  static const AH_CharTypeTable
261
 
+  ah_types_table_unicode =
262
 
+  {
263
 
+    sizeof( ah_types_for_unicode ) / sizeof( AH_CharType ),
264
 
+    (AH_CharType *)ah_types_for_unicode
265
 
+  };
266
 
+
267
 
+
268
 
+  FT_LOCAL_DEF( void )
269
 
+  ah_hinter_compute_char_table( AH_Hinter  hinter )
270
 
+  {
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;
275
 
+    FT_Byte*           types;
276
 
+    FT_Error           error;
277
 
+    FT_CharMap         charmap;
278
 
+
279
 
+
280
 
+    if ( table )
281
 
+      return;
282
 
+
283
 
+    if ( num_glyphs <= 0 )
284
 
+      return;
285
 
+
286
 
+    if ( FT_NEW_ARRAY( types, num_glyphs ) )
287
 
+      return;
288
 
+
289
 
+    FT_MEM_SET( types, AH_CHAR_TYPE_OTHER, num_glyphs );
290
 
+
291
 
+    charmap = face->charmap;
292
 
+    if ( FT_Select_Charmap( face, FT_ENCODING_UNICODE ) )
293
 
+      goto Exit;
294
 
+
295
 
+
296
 
+    {
297
 
+      FT_Bool   empty = TRUE;
298
 
+      FT_ULong  i;
299
 
+
300
 
+
301
 
+      for ( i = 0; i < ah_types_table_unicode.size; i++ )
302
 
+      {
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 );
308
 
+
309
 
+
310
 
+        while ( ucs && ucs <= last )
311
 
+        {
312
 
+          if ( glyph_index < num_glyphs )
313
 
+          {
314
 
+            empty = FALSE;
315
 
+            types[glyph_index] = type;
316
 
+          }
317
 
+
318
 
+          ucs = FT_Get_Next_Char( face, ucs, &glyph_index );
319
 
+        }
320
 
+      }
321
 
+
322
 
+      if ( empty )
323
 
+        goto Exit;
324
 
+    }
325
 
+
326
 
+
327
 
+    {
328
 
+      FT_Byte*  cur  = types;
329
 
+      FT_Byte*  last = types + num_glyphs - 1;
330
 
+      FT_Byte   type = AH_CHAR_TYPE_OTHER;
331
 
+      FT_ULong  num  = 0;
332
 
+      FT_ULong  alloc_size;
333
 
+
334
 
+
335
 
+      while ( ++cur <= last )
336
 
+      {
337
 
+        if ( *cur != type )
338
 
+        {
339
 
+          type = *cur;
340
 
+
341
 
+          if ( type < AH_CHAR_TYPE_OTHER )
342
 
+            num++;
343
 
+        }
344
 
+      }
345
 
+
346
 
+      alloc_size = sizeof( AH_CharTypeTable ) + num * sizeof( AH_CharType );
347
 
+      if ( FT_ALLOC( table, alloc_size ) )
348
 
+        goto Exit;
349
 
+
350
 
+      table->size  = num;
351
 
+      table->types = (AH_CharType *)( table + 1 );
352
 
+    }
353
 
+
354
 
+
355
 
+    {
356
 
+      FT_Byte*  cur  = types + 1;
357
 
+      FT_Byte*  last = types + face->num_glyphs - 1;
358
 
+      FT_Byte   type = AH_CHAR_TYPE_OTHER;
359
 
+      FT_ULong  num  = 0;
360
 
+      FT_ULong  i;
361
 
+
362
 
+
363
 
+      for ( i = 1; cur <= last; i++, cur++ )
364
 
+      {
365
 
+        if ( *cur != type )
366
 
+        {
367
 
+          if ( type < AH_CHAR_TYPE_OTHER )
368
 
+            table->types[num - 1].last = i - 1;
369
 
+
370
 
+          type = *cur;
371
 
+          if ( type < AH_CHAR_TYPE_OTHER )
372
 
+          {
373
 
+            table->types[num].type    = type;
374
 
+            table->types[num++].start = i;
375
 
+          }
376
 
+        }
377
 
+      }
378
 
+
379
 
+      if ( type < AH_CHAR_TYPE_OTHER )
380
 
+        table->types[num - 1].last = i - 1;
381
 
+    }
382
 
+
383
 
+    hinter->globals->table = table;
384
 
+
385
 
+  Exit:
386
 
+    FT_Set_Charmap( face, charmap );
387
 
+    FT_FREE( types );
388
 
+  }
389
 
+
390
 
+
391
 
+  FT_LOCAL_DEF( FT_Byte )
392
 
+  ah_hinter_get_char_type( AH_Hinter  hinter,
393
 
+                           FT_ULong   glyph_index )
394
 
+  {
395
 
+    AH_CharTypeTable*  table = hinter->globals->table;
396
 
+
397
 
+
398
 
+    if ( table && table->size > 0 && glyph_index )
399
 
+    {
400
 
+      AH_CharType*  cur;
401
 
+      AH_CharType*  types = table->types;
402
 
+      FT_ULong      min   = 0;
403
 
+      FT_ULong      max   = table->size - 1;
404
 
+      FT_ULong      mid;
405
 
+
406
 
+
407
 
+      if ( glyph_index < types[min].start ||
408
 
+           glyph_index > types[max].last )
409
 
+        return AH_CHAR_TYPE_OTHER;
410
 
+
411
 
+      while ( min <= max )
412
 
+      {
413
 
+        mid = ( min + max ) / 2;
414
 
+        cur = types + mid;
415
 
+
416
 
+        if ( glyph_index < cur->start )
417
 
+          max = mid - 1;
418
 
+        else if ( glyph_index > cur->last )
419
 
+          min = mid + 1;
420
 
+        else
421
 
+          return cur->type;
422
 
+      }
423
 
+    }
424
 
+
425
 
+    return AH_CHAR_TYPE_OTHER;
426
 
   }
427
 
 
428
 
 
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
432
 
@@ -51,6 +51,14 @@
433
 
   ah_hinter_compute_globals( AH_Hinter  hinter );
434
 
 
435
 
 
436
 
+  FT_LOCAL( void )
437
 
+  ah_hinter_compute_char_table( AH_Hinter  hinter );
438
 
+
439
 
+
440
 
+  FT_LOCAL( FT_Byte )
441
 
+  ah_hinter_get_char_type( AH_Hinter  hinter,
442
 
+                           FT_ULong   glyph_index );
443
 
+
444
 
 FT_END_HEADER
445
 
 
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
450
 
@@ -22,7 +22,6 @@
451
 
 
452
 
 #include <ft2build.h>
453
 
 #include "ahglyph.h"
454
 
-#include "ahangles.h"
455
 
 #include "ahglobal.h"
456
 
 #include "aherrors.h"
457
 
 
458
 
@@ -52,11 +51,11 @@
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" );
464
 
 
465
 
       for ( edge = edges; edge < edge_limit; edge++ )
466
 
       {
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",
469
 
                  edge - edges,
470
 
                  (int)edge->fpos,
471
 
                  edge->dir == AH_DIR_UP
472
 
@@ -72,7 +71,8 @@
473
 
                  edge->serif ? ( edge->serif - edges ) : -1,
474
 
                  edge->blue_edge ? 'y' : 'n',
475
 
                  edge->opos / 64.0,
476
 
-                 edge->pos / 64.0 );
477
 
+                 edge->pos / 64.0,
478
 
+                 ( edge->pos - edge->opos ) / 64.0 );
479
 
       }
480
 
 
481
 
       edges      = outline->vert_edges;
482
 
@@ -370,6 +370,12 @@
483
 
     char*       tag         = gloader->current.outline.tags;
484
 
 
485
 
 
486
 
+#ifdef AH_DEBUG
487
 
+    ah_dump_segments( outline );
488
 
+    ah_dump_edges( outline );
489
 
+    printf( "\n" );
490
 
+ #endif
491
 
+
492
 
     /* we assume that the glyph loader has already been checked for storage */
493
 
     for ( ; point < point_limit; point++, vec++, tag++ )
494
 
     {
495
 
@@ -594,6 +600,7 @@
496
 
 
497
 
           point->out_dir = ah_compute_direction( ovec.x, ovec.y );
498
 
 
499
 
+#if 0
500
 
 #ifndef AH_OPTION_NO_WEAK_INTERPOLATION
501
 
           if ( point->flags & ( AH_FLAG_CONIC | AH_FLAG_CUBIC ) )
502
 
           {
503
 
@@ -624,6 +631,7 @@
504
 
           else if ( point->in_dir == -point->out_dir )
505
 
             goto Is_Weak_Point;
506
 
 #endif
507
 
+#endif
508
 
         }
509
 
       }
510
 
     }
511
 
@@ -709,6 +717,7 @@
512
 
   }
513
 
 
514
 
 
515
 
+#if 0
516
 
   /* compute all inflex points in a given glyph */
517
 
   static void
518
 
   ah_outline_compute_inflections( AH_Outline  outline )
519
 
@@ -822,6 +831,54 @@
520
 
       ;
521
 
     }
522
 
   }
523
 
+#endif
524
 
+
525
 
+
526
 
+  /* compute all strong points in a given glyph */
527
 
+  static void
528
 
+  ah_outline_compute_strongs( AH_Outline  outline )
529
 
+  {
530
 
+    AH_Point*   contour       = outline->contours;
531
 
+    AH_Point*   contour_limit = contour + outline->num_contours;
532
 
+
533
 
+
534
 
+    /* load original coordinates in (u,v) */
535
 
+    ah_setup_uv( outline, AH_UV_FXY );
536
 
+
537
 
+    for ( ; contour < contour_limit; contour++ )
538
 
+    {
539
 
+      FT_Pos     dx1, dx2, dy1, dy2;
540
 
+      AH_Point   point = contour[0];
541
 
+      AH_Point   first = point;
542
 
+      AH_Point   before;
543
 
+      AH_Point   after;
544
 
+
545
 
+
546
 
+      after  = point->next;
547
 
+      before = point->prev;
548
 
+      dx1    = point->u - before->u;
549
 
+      dy1    = point->v - before->v;
550
 
+
551
 
+      do
552
 
+      {
553
 
+        dx2 = after->u - point->u;
554
 
+        dy2 = after->v - point->v;
555
 
+
556
 
+        if ( dx1 == 0 || dx2 == 0 || ( dx1 ^ dx2 ) < 0 )
557
 
+          point->flags |= AH_FLAG_STRONG_X;
558
 
+
559
 
+        if ( dy1 == 0 || dy2 == 0 || ( dy1 ^ dy2 ) < 0 )
560
 
+          point->flags |= AH_FLAG_STRONG_Y;
561
 
+
562
 
+        before = point;
563
 
+        point  = after;
564
 
+        after  = after->next;
565
 
+        dx1    = dx2;
566
 
+        dy1    = dy2;
567
 
+
568
 
+      } while ( point != first );
569
 
+    }
570
 
+  }
571
 
 
572
 
 
573
 
   FT_LOCAL_DEF( void )
574
 
@@ -925,11 +982,34 @@
575
 
               segment->last = point;
576
 
               segment->pos  = ( min_pos + max_pos ) >> 1;
577
 
 
578
 
+#if 0
579
 
               /* a segment is round if either its first or last point */
580
 
               /* is a control point                                   */
581
 
               if ( ( segment->first->flags | point->flags ) &
582
 
                      AH_FLAG_CONTROL                        )
583
 
                 segment->flags |= AH_EDGE_ROUND;
584
 
+#else
585
 
+              /* a segment is round if it doesn't have successive */
586
 
+              /* on-curve points.                                 */
587
 
+              {
588
 
+                AH_Point  pt = segment->first;
589
 
+                AH_Flags  f0 = pt->flags & AH_FLAG_CONTROL;
590
 
+                AH_Flags  f1;
591
 
+
592
 
+
593
 
+                for ( ; pt != point; f0 = f1 )
594
 
+                {
595
 
+                  pt = pt->next;
596
 
+                  f1 = pt->flags & AH_FLAG_CONTROL;
597
 
+
598
 
+                  if ( !f0 && !f1 )
599
 
+                    break;
600
 
+
601
 
+                  if ( pt == point )
602
 
+                    segment->flags |= AH_EDGE_ROUND;
603
 
+                }
604
 
+              }
605
 
+#endif
606
 
 
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;
617
 
+            segment->sign     = 0;
618
 
             segment->link     = NULL;
619
 
             on_edge           = 1;
620
 
 
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;
629
 
+          segment->sign   = 0;
630
 
           segment->link  = NULL;
631
 
 
632
 
           num_segments++;
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;
641
 
+          segment->sign   = 0;
642
 
           segment->link  = NULL;
643
 
 
644
 
           num_segments++;
645
 
@@ -1080,11 +1169,13 @@
646
 
     AH_Segment    segment_limit;
647
 
     AH_Direction  major_dir;
648
 
     int           dimension;
649
 
+    FT_Pos        score_limit;
650
 
 
651
 
 
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 );
656
 
 
657
 
     for ( dimension = 1; dimension >= 0; dimension-- )
658
 
     {
659
 
@@ -1203,20 +1294,28 @@
660
 
                 max = seg2->max_coord;
661
 
 
662
 
               len = max - min;
663
 
-              if ( len >= 8 )
664
 
+              if ( len >= 4 )
665
 
               {
666
 
-                score = dist + 3000 / len;
667
 
+                score = 8*dist;
668
 
 
669
 
-                if ( score < seg1->score )
670
 
+                if ( score < seg1->score1 &&
671
 
+                     !( score > seg1->score2 && 4*len < seg1->length ) )
672
 
                 {
673
 
-                  seg1->score = score;
674
 
-                  seg1->link  = seg2;
675
 
+                  seg1->score1 = 9*dist;
676
 
+                  seg1->score2 = 7*dist;
677
 
+                  seg1->length = len;
678
 
+                  seg1->sign   = -1;
679
 
+                  seg1->link   = seg2;
680
 
                 }
681
 
 
682
 
-                if ( score < seg2->score )
683
 
+                if ( score < seg2->score1 &&
684
 
+                     !( score > seg2->score2 && 4*len < seg2->length ) )
685
 
                 {
686
 
-                  seg2->score = score;
687
 
-                  seg2->link  = seg1;
688
 
+                  seg2->score1 = 9*dist;
689
 
+                  seg2->score2 = 7*dist;
690
 
+                  seg2->length = len;
691
 
+                  seg2->sign   = +1;
692
 
+                  seg2->link   = seg1;
693
 
                 }
694
 
               }
695
 
             }
696
 
@@ -1225,6 +1324,73 @@
697
 
 #endif /* 1 */
698
 
 
699
 
       /* now, compute the `serif' segments */
700
 
+      {
701
 
+        AH_Segment  seg, link1, link2;
702
 
+        FT_Pos      pos1, pos2;
703
 
+
704
 
+
705
 
+        for ( seg1 = segments; seg1 < segment_limit; seg1++ )
706
 
+        {
707
 
+          if ( seg1->sign >= 0 || seg1->score1 >= score_limit )
708
 
+            continue;
709
 
+
710
 
+          link1 = seg1->link;
711
 
+          if ( link1->link != seg1 )
712
 
+            continue;
713
 
+
714
 
+          pos1 = seg1->pos;
715
 
+          pos2 = link1->pos;
716
 
+
717
 
+
718
 
+          for ( seg2 = segments; seg2 < segment_limit; seg2++ )
719
 
+          {
720
 
+            if ( seg2->sign >= 0 ||
721
 
+                 seg2->score1 <= seg1->score1 || seg2->pos > pos1 )
722
 
+              continue;
723
 
+
724
 
+            link2 = seg2->link;
725
 
+            if ( link2->link != seg2 )
726
 
+              continue;
727
 
+
728
 
+            if ( link2->pos < pos2              ||
729
 
+                 seg1->score1*4 <= seg2->score1 )
730
 
+              continue;
731
 
+
732
 
+            /* seg2->pos < pos1 < pos2 < seg2->link->pos */
733
 
+
734
 
+            if ( seg1->length < seg2->length*2 )
735
 
+            {
736
 
+              seg1->link = link1->link = 0;
737
 
+              seg1->sign = link1->sign = 0;
738
 
+            }
739
 
+            else
740
 
+            {
741
 
+              for ( seg = segments; seg < segment_limit; seg++ )
742
 
+              {
743
 
+                AH_Segment  link = seg->link;
744
 
+
745
 
+
746
 
+                if ( link == seg2 )
747
 
+                {
748
 
+                  seg->sign  = 0;
749
 
+                  seg->link  = 0;
750
 
+                  seg->serif = link1;
751
 
+                }
752
 
+                else if ( link == link2 )
753
 
+                {
754
 
+                  seg->sign  = 0;
755
 
+                  seg->link  = 0;
756
 
+                  seg->serif = seg1;
757
 
+                }
758
 
+              }
759
 
+            }
760
 
+
761
 
+            break;
762
 
+          }
763
 
+        }
764
 
+      }
765
 
+
766
 
+
767
 
       for ( seg1 = segments; seg1 < segment_limit; seg1++ )
768
 
       {
769
 
         seg2 = seg1->link;
770
 
@@ -1234,8 +1400,13 @@
771
 
           seg2->num_linked++;
772
 
           if ( seg2->link != seg1 )
773
 
           {
774
 
-            seg1->link  = 0;
775
 
-            seg1->serif = seg2->link;
776
 
+            seg1->link = 0;
777
 
+
778
 
+            if ( seg2->score1 < score_limit    ||
779
 
+                 seg1->score1 < seg2->score1*4 )
780
 
+              seg1->serif = seg2->link;
781
 
+            else
782
 
+              seg2->num_linked--;
783
 
           }
784
 
         }
785
 
       }
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 );
791
 
     }
792
 
   }
793
 
 
794
 
@@ -1310,12 +1482,46 @@
795
 
           FT_Pos  dist;
796
 
 
797
 
 
798
 
+          if ( edge->dir != seg->dir )
799
 
+            continue;
800
 
+
801
 
           dist = seg->pos - edge->fpos;
802
 
           if ( dist < 0 )
803
 
             dist = -dist;
804
 
 
805
 
           if ( dist < edge_distance_threshold )
806
 
           {
807
 
+            AH_Segment  link = seg->link;
808
 
+
809
 
+
810
 
+            /* check if all linked segments of the candidate edge */
811
 
+            /* can make a single edge.                            */
812
 
+            if ( link )
813
 
+            {
814
 
+              AH_Segment  seg1 = edge->first;
815
 
+              AH_Segment  link1;
816
 
+
817
 
+
818
 
+              do
819
 
+              {
820
 
+                link1 = seg1->link;
821
 
+                if ( link1 )
822
 
+                {
823
 
+                  dist = link->pos - link1->pos;
824
 
+                  if ( dist < 0 )
825
 
+                    dist = -dist;
826
 
+
827
 
+                  dist = FT_MulFix( dist, scale );
828
 
+                  if ( dist >= edge_distance_threshold )
829
 
+                    break;
830
 
+                }
831
 
+
832
 
+              } while ( ( seg1 = seg1->edge_next ) != edge->first );
833
 
+
834
 
+              if ( dist >= edge_distance_threshold )
835
 
+                continue;
836
 
+            }
837
 
+
838
 
             found = edge;
839
 
             break;
840
 
           }
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;
846
 
         }
847
 
         else
848
 
         {
849
 
@@ -1391,8 +1598,6 @@
850
 
       {
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       */
855
 
 
856
 
 
857
 
         seg = edge->first;
858
 
@@ -1408,12 +1613,6 @@
859
 
           else
860
 
             is_straight++;
861
 
 
862
 
-          /* check for segment direction */
863
 
-          if ( seg->dir == up_dir )
864
 
-            ups   += seg->max_coord-seg->min_coord;
865
 
-          else
866
 
-            downs += seg->max_coord-seg->min_coord;
867
 
-
868
 
           /* check for links -- if seg->serif is set, then seg->link must */
869
 
           /* be ignored                                                   */
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;
874
 
 
875
 
-        /* set the edge's main direction */
876
 
-        edge->dir = AH_DIR_NONE;
877
 
-
878
 
-        if ( ups > downs )
879
 
-          edge->dir = up_dir;
880
 
-
881
 
-        else if ( ups < downs )
882
 
-          edge->dir = -up_dir;
883
 
-
884
 
-        else if ( ups == downs )
885
 
-          edge->dir = 0;  /* both up and down! */
886
 
-
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 );
896
 
   }
897
 
 
898
 
 
899
 
@@ -1542,12 +1729,15 @@
900
 
   {
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;
906
 
 
907
 
     FT_Bool     blue_active[AH_BLUE_MAX];
908
 
 
909
 
 
910
 
+    if ( !globals->has_blues )
911
 
+      return;
912
 
+
913
 
     /* compute which blue zones are active, i.e. have their scaled */
914
 
     /* size < 3/4 pixels                                           */
915
 
     {
916
 
@@ -1588,6 +1778,18 @@
917
 
       FT_Pos   best_dist;  /* initial threshold */
918
 
 
919
 
 
920
 
+      if ( edge->serif )
921
 
+      {
922
 
+        FT_Pos  dist = edge->serif->pos - edge->pos;
923
 
+
924
 
+
925
 
+        if ( dist < 0 )
926
 
+          dist = -dist;
927
 
+
928
 
+        if ( dist < 128 )
929
 
+          continue;
930
 
+      }
931
 
+
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 );
934
 
 
935
 
@@ -1686,7 +1888,11 @@
936
 
     FT_Pos   delta;
937
 
 
938
 
 
939
 
-    delta = globals->scaled.blue_refs - globals->design.blue_refs;
940
 
+    if ( !globals->scaled.has_blues )
941
 
+      return;
942
 
+
943
 
+    delta = globals->scaled.blue_refs -
944
 
+            globals->designs[globals->cur_type].blue_refs;
945
 
 
946
 
     for ( ; edge < edge_limit; edge++ )
947
 
     {
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
951
 
@@ -22,9 +22,9 @@
952
 
 #include <ft2build.h>
953
 
 #include "ahhint.h"
954
 
 #include "ahglyph.h"
955
 
-#include "ahangles.h"
956
 
 #include "aherrors.h"
957
 
 #include FT_OUTLINE_H
958
 
+#include FT_TRUETYPE_TABLES_H
959
 
 
960
 
 
961
 
 #define FACE_GLOBALS( face )  ( (AH_Face_Globals)(face)->autohint.data )
962
 
@@ -112,7 +112,8 @@
963
 
 
964
 
     if ( !hinter->do_stem_adjust )
965
 
     {
966
 
-      /* leave stem widths unchanged */
967
 
+      if ( dist < 48 )
968
 
+        dist += ( 48 - dist )/2 ;
969
 
     }
970
 
     else if ( (  vertical && !hinter->do_vert_snapping ) ||
971
 
               ( !vertical && !hinter->do_horz_snapping ) )
972
 
@@ -120,6 +121,7 @@
973
 
       /* smooth hinting process: very lightly quantize the stem width */
974
 
       /*                                                              */
975
 
 
976
 
+#if 0
977
 
       /* leave the widths of serifs alone */
978
 
 
979
 
       if ( ( stem_flags & AH_EDGE_SERIF ) && vertical && ( dist < 3 * 64 ) )
980
 
@@ -132,24 +134,35 @@
981
 
       }
982
 
       else if ( dist < 56 )
983
 
         dist = 56;
984
 
+#endif
985
 
 
986
 
       {
987
 
-        FT_Pos  delta = dist - globals->stds[vertical];
988
 
+        FT_Pos  delta;
989
 
 
990
 
 
991
 
-        if ( delta < 0 )
992
 
-          delta = -delta;
993
 
-
994
 
-        if ( delta < 40 )
995
 
+        if ( (  vertical && globals->num_heights > 0 ) ||
996
 
+             ( !vertical && globals->num_widths  > 0 ) )
997
 
         {
998
 
-          dist = globals->stds[vertical];
999
 
-          if ( dist < 48 )
1000
 
-            dist = 48;
1001
 
+          delta = dist - globals->stds[vertical];
1002
 
+
1003
 
+          if ( delta < 0 )
1004
 
+            delta = -delta;
1005
 
 
1006
 
-          goto Done_Width;
1007
 
+          if ( delta < 40 )
1008
 
+          {
1009
 
+            dist = globals->stds[vertical];
1010
 
+            if ( dist < 48 )
1011
 
+              dist = 48;
1012
 
+
1013
 
+            goto Done_Width;
1014
 
+          }
1015
 
         }
1016
 
 
1017
 
-        if ( dist < 3 * 64 )
1018
 
+        if ( dist < 54 )
1019
 
+        {
1020
 
+          dist += ( 54 - dist )/2 ;
1021
 
+        }
1022
 
+        else if ( dist < 3 * 64 )
1023
 
         {
1024
 
           delta  = dist & 63;
1025
 
           dist  &= -64;
1026
 
@@ -157,17 +170,18 @@
1027
 
           if ( delta < 10 )
1028
 
             dist += delta;
1029
 
 
1030
 
-          else if ( delta < 32 )
1031
 
+          else if ( delta < 22 )
1032
 
             dist += 10;
1033
 
 
1034
 
+          else if ( delta < 42 )
1035
 
+            dist += delta;
1036
 
+
1037
 
           else if ( delta < 54 )
1038
 
             dist += 54;
1039
 
 
1040
 
           else
1041
 
             dist += delta;
1042
 
         }
1043
 
-        else
1044
 
-          dist = ( dist + 32 ) & -64;
1045
 
       }
1046
 
     }
1047
 
     else
1048
 
@@ -409,6 +423,129 @@
1049
 
     serif->pos = base->pos + sign * dist;
1050
 
   }
1051
 
 
1052
 
1053
 
+  static FT_Pos
1054
 
+  ah_hint_normal_stem( AH_Hinter  hinter,
1055
 
+                       AH_Edge    edge,
1056
 
+                       AH_Edge    edge2,
1057
 
+                       FT_Pos     anchor,
1058
 
+                       FT_Int     vertical )
1059
 
+  {
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;
1063
 
+    FT_Pos   offset;
1064
 
+    FT_Pos   threshold = 64;
1065
 
+
1066
 
+
1067
 
+    if ( !hinter->do_stem_adjust )
1068
 
+    {
1069
 
+      if ( ( edge->flags  & AH_EDGE_ROUND ) &&
1070
 
+           ( edge2->flags & AH_EDGE_ROUND )  )
1071
 
+      {
1072
 
+        if ( vertical )
1073
 
+          threshold = 64 - AH_LIGHT_MODE_MAX_HORZ_GAP;
1074
 
+        else
1075
 
+          threshold = 64 - AH_LIGHT_MODE_MAX_VERT_GAP;
1076
 
+      }
1077
 
+      else
1078
 
+      {
1079
 
+        if ( vertical )
1080
 
+          threshold = 64 - AH_LIGHT_MODE_MAX_HORZ_GAP/3;
1081
 
+        else
1082
 
+          threshold = 64 - AH_LIGHT_MODE_MAX_VERT_GAP/3;
1083
 
+      }
1084
 
+    }
1085
 
+
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;
1096
 
+    delta      = 0;
1097
 
+
1098
 
+
1099
 
+    if ( d_off1 == 0 || d_off2 == 0 )
1100
 
+      goto Exit;
1101
 
+
1102
 
+    if ( cur_len <= threshold )
1103
 
+    {
1104
 
+      if ( d_off2 < cur_len )
1105
 
+      {
1106
 
+        if ( u_off1 <= d_off2 )
1107
 
+          delta =  u_off1;
1108
 
+        else
1109
 
+          delta = -d_off2;
1110
 
+      }
1111
 
+
1112
 
+      goto Exit;
1113
 
+    }
1114
 
+
1115
 
+    if ( threshold < 64 )
1116
 
+    {
1117
 
+      if ( d_off1 >= threshold || u_off1 >= threshold ||
1118
 
+           d_off2 >= threshold || u_off2 >= threshold )
1119
 
+        goto Exit;
1120
 
+    }
1121
 
+
1122
 
+    offset = cur_len % 64;
1123
 
+
1124
 
+    if ( offset < 32 )
1125
 
+    {
1126
 
+      if ( u_off1 <= offset || d_off2 <= offset )
1127
 
+        goto Exit;
1128
 
+    }
1129
 
+    else
1130
 
+      offset = 64 - threshold;
1131
 
+
1132
 
+    d_off1 = threshold - u_off1;
1133
 
+    u_off1 = u_off1    - offset;
1134
 
+    u_off2 = threshold - d_off2;
1135
 
+    d_off2 = d_off2    - offset;
1136
 
+
1137
 
+    if ( d_off1 <= u_off1 )
1138
 
+      u_off1 = -d_off1;
1139
 
+
1140
 
+    if ( d_off2 <= u_off2 )
1141
 
+      u_off2 = -d_off2;
1142
 
+
1143
 
+    if ( ABS( u_off1 ) <= ABS( u_off2 ) )
1144
 
+      delta = u_off1;
1145
 
+    else
1146
 
+      delta = u_off2;
1147
 
+
1148
 
+  Exit:
1149
 
+#if 1
1150
 
+    if ( !hinter->do_stem_adjust )
1151
 
+    {
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;
1156
 
+    }
1157
 
+#endif
1158
 
+
1159
 
+    cur_pos1 += delta;
1160
 
+
1161
 
+    if ( edge->opos < edge2->opos )
1162
 
+    {
1163
 
+      edge->pos  = cur_pos1;
1164
 
+      edge2->pos = cur_pos1 + cur_len;
1165
 
+    }
1166
 
+    else
1167
 
+    {
1168
 
+      edge->pos  = cur_pos1 + cur_len;
1169
 
+      edge2->pos = cur_pos1;
1170
 
+    }
1171
 
+
1172
 
+    return delta;
1173
 
+  }
1174
 
+
1175
 
 
1176
 
   /*************************************************************************/
1177
 
   /*************************************************************************/
1178
 
@@ -438,6 +575,7 @@
1179
 
     {
1180
 
       AH_Edge  edge;
1181
 
       AH_Edge  anchor = 0;
1182
 
+      FT_Pos   delta  = 0;
1183
 
       int      has_serifs = 0;
1184
 
 
1185
 
 
1186
 
@@ -449,7 +587,7 @@
1187
 
 
1188
 
       /* we begin by aligning all stems relative to the blue zone */
1189
 
       /* if needed -- that's only for horizontal edges            */
1190
 
-      if ( dimension )
1191
 
+      if ( dimension && hinter->do_blue_hints )
1192
 
       {
1193
 
         for ( edge = edges; edge < edge_limit; edge++ )
1194
 
         {
1195
 
@@ -486,14 +624,10 @@
1196
 
             ah_align_linked_edge( hinter, edge1, edge2, dimension );
1197
 
             edge2->flags |= AH_EDGE_DONE;
1198
 
           }
1199
 
-
1200
 
-          if ( !anchor )
1201
 
-            anchor = edge;
1202
 
         }
1203
 
       }
1204
 
 
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++ )
1209
 
       {
1210
 
         AH_EdgeRec*  edge2;
1211
 
@@ -520,6 +654,7 @@
1212
 
           continue;
1213
 
         }
1214
 
 
1215
 
+#if 0
1216
 
         if ( !anchor )
1217
 
         {
1218
 
 
1219
 
@@ -686,6 +821,93 @@
1220
 
           if ( edge > edges && edge->pos < edge[-1].pos )
1221
 
             edge->pos = edge[-1].pos;
1222
 
         }
1223
 
+#else /* 1 */
1224
 
+
1225
 
+        if ( !dimension && !anchor )
1226
 
+        {
1227
 
+          if ( hinter->globals->is_fixedpitch && !hinter->composite )
1228
 
+          {
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;
1234
 
+
1235
 
+
1236
 
+            while ( right > left && !right->link )
1237
 
+              right--;
1238
 
+
1239
 
+            left1  = *left;
1240
 
+            left2  = *left->link;
1241
 
+            right1 = *right->link;
1242
 
+            right2 = *right;
1243
 
+
1244
 
+            delta  = ( ( ( hinter->pp2.x + 32 ) & -64 ) - hinter->pp2.x )/2;
1245
 
+            target = left->opos + ( right->opos - left->opos )/2 + delta - 16;
1246
 
+
1247
 
+            delta1  = delta;
1248
 
+            delta1 += ah_hint_normal_stem( hinter, left, left->link,
1249
 
+                                           delta1, 0 );
1250
 
+
1251
 
+            if ( left->link != right )
1252
 
+              ah_hint_normal_stem( hinter, right->link, right, delta1, 0 );
1253
 
+
1254
 
+            center1 = left->pos + ( right->pos - left->pos )/2;
1255
 
+
1256
 
+            if ( center1 >= target )
1257
 
+              delta2 = delta - 32;
1258
 
+            else
1259
 
+              delta2 = delta + 32;
1260
 
+
1261
 
+            delta2 += ah_hint_normal_stem( hinter, &left1, &left2, delta2, 0 );
1262
 
+
1263
 
+            if ( delta1 != delta2 )
1264
 
+            {
1265
 
+              if ( left->link != right )
1266
 
+                ah_hint_normal_stem( hinter, &right1, &right2, delta2, 0 );
1267
 
+
1268
 
+              center2 = left1.pos + ( right2.pos - left1.pos )/2;
1269
 
+
1270
 
+              d1 = center1 - target;
1271
 
+              d2 = center2 - target;
1272
 
+
1273
 
+              if ( ABS( d2 ) < ABS( d1 ) )
1274
 
+              {
1275
 
+                left->pos       = left1.pos;
1276
 
+                left->link->pos = left2.pos;
1277
 
+
1278
 
+                if ( left->link != right )
1279
 
+                {
1280
 
+                  right->link->pos = right1.pos;
1281
 
+                  right->pos       = right2.pos;
1282
 
+                }
1283
 
+
1284
 
+                delta1 = delta2;
1285
 
+              }
1286
 
+            }
1287
 
+
1288
 
+            delta               = delta1;
1289
 
+            right->link->flags |= AH_EDGE_DONE;
1290
 
+            right->flags       |= AH_EDGE_DONE;
1291
 
+          }
1292
 
+          else
1293
 
+          {
1294
 
+            delta = ah_hint_normal_stem( hinter, edge, edge2, 0, 0 );
1295
 
+          }
1296
 
+
1297
 
+          anchor = edge;
1298
 
+        }
1299
 
+        else
1300
 
+        {
1301
 
+          ah_hint_normal_stem( hinter, edge, edge2,
1302
 
+                               delta, dimension );
1303
 
+          anchor = edge;
1304
 
+        }
1305
 
+
1306
 
+        edge->flags  |= AH_EDGE_DONE;
1307
 
+        edge2->flags |= AH_EDGE_DONE;
1308
 
+
1309
 
+#endif /* 1 */
1310
 
       }
1311
 
 
1312
 
       /* make sure that lowercase m's maintain their symmetry */
1313
 
@@ -704,7 +926,8 @@
1314
 
       /* one pixel higher or lower.                                         */
1315
 
 
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 ) )
1320
 
       {
1321
 
         AH_EdgeRec  *edge1, *edge2, *edge3;
1322
 
         FT_Pos       dist1, dist2, span, delta;
1323
 
@@ -730,7 +953,9 @@
1324
 
         if ( span < 0 )
1325
 
           span = -span;
1326
 
 
1327
 
-        if ( span < 8 )
1328
 
+        if ( edge1->link == edge1 + 1 &&
1329
 
+             edge2->link == edge2 + 1 &&
1330
 
+             edge3->link == edge3 + 1 && span < 8 )
1331
 
         {
1332
 
           delta = edge3->pos - ( 2 * edge2->pos - edge1->pos );
1333
 
           edge3->pos -= delta;
1334
 
@@ -761,25 +986,48 @@
1335
 
           continue;
1336
 
 
1337
 
         if ( edge->serif )
1338
 
-          ah_align_serif_edge( hinter, edge->serif, edge, dimension );
1339
 
-        else if ( !anchor )
1340
 
         {
1341
 
-          edge->pos = ( edge->opos + 32 ) & -64;
1342
 
-          anchor    = edge;
1343
 
+          ah_align_serif_edge( hinter, edge->serif, edge, dimension );
1344
 
+          edge->flags |= AH_EDGE_DONE;
1345
 
+          has_serifs--;
1346
 
         }
1347
 
-        else
1348
 
-          edge->pos = anchor->pos +
1349
 
-                      ( ( edge->opos-anchor->opos + 32 ) & -64 );
1350
 
+      }
1351
 
+
1352
 
+      if ( !has_serifs )
1353
 
+        goto Next_Dimension;
1354
 
+
1355
 
+      for ( edge = edges; edge < edge_limit; edge++ )
1356
 
+      {
1357
 
+        AH_Edge  before, after;
1358
 
 
1359
 
-        edge->flags |= AH_EDGE_DONE;
1360
 
 
1361
 
-        if ( edge > edges && edge->pos < edge[-1].pos )
1362
 
-          edge->pos = edge[-1].pos;
1363
 
+        if ( edge->flags & AH_EDGE_DONE )
1364
 
+          continue;
1365
 
+
1366
 
+        before = after = edge;
1367
 
+
1368
 
+        while ( --before >= edges )
1369
 
+          if ( before->flags & AH_EDGE_DONE )
1370
 
+            break;
1371
 
+
1372
 
+        while ( ++after < edge_limit )
1373
 
+          if ( after->flags & AH_EDGE_DONE )
1374
 
+            break;
1375
 
+
1376
 
+        if ( before >= edges || after < edge_limit )
1377
 
+        {
1378
 
+          if ( before < edges )
1379
 
+            edge->pos = edge->opos + ( after->pos - after->opos );
1380
 
+
1381
 
+          else if ( after >= edge_limit )
1382
 
+            edge->pos = edge->opos + ( before->pos - before->opos );
1383
 
 
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;
1388
 
+          else
1389
 
+            edge->pos = before->pos +
1390
 
+                        FT_MulDiv( edge->fpos - before->fpos,
1391
 
+                                   after->pos - before->pos,
1392
 
+                                   after->fpos - before->fpos );
1393
 
+        }
1394
 
       }
1395
 
 
1396
 
     Next_Dimension:
1397
 
@@ -806,10 +1054,12 @@
1398
 
     AH_Edge     edges;
1399
 
     AH_Edge     edge_limit;
1400
 
     FT_Int      dimension;
1401
 
+    FT_Bool     snapping;
1402
 
 
1403
 
 
1404
 
     edges      = outline->horz_edges;
1405
 
     edge_limit = edges + outline->num_hedges;
1406
 
+    snapping   = hinter->do_vert_snapping;
1407
 
 
1408
 
     for ( dimension = 1; dimension >= 0; dimension-- )
1409
 
     {
1410
 
@@ -821,7 +1071,8 @@
1411
 
       {
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;
1417
 
 
1418
 
 
1419
 
         do
1420
 
@@ -829,23 +1080,47 @@
1421
 
           AH_Point  point = seg->first;
1422
 
 
1423
 
 
1424
 
-          for (;;)
1425
 
+          if ( snapping )
1426
 
           {
1427
 
-            if ( dimension )
1428
 
+            for (;;)
1429
 
             {
1430
 
-              point->y      = edge->pos;
1431
 
-              point->flags |= AH_FLAG_TOUCH_Y;
1432
 
+              if ( dimension )
1433
 
+              {
1434
 
+                point->y      = edge->pos;
1435
 
+                point->flags |= AH_FLAG_TOUCH_Y;
1436
 
+              }
1437
 
+              else
1438
 
+              {
1439
 
+                point->x      = edge->pos;
1440
 
+                point->flags |= AH_FLAG_TOUCH_X;
1441
 
+              }
1442
 
+
1443
 
+              if ( point == seg->last )
1444
 
+                break;
1445
 
+
1446
 
+              point = point->next;
1447
 
             }
1448
 
-            else
1449
 
+          }
1450
 
+          else
1451
 
+          {
1452
 
+            for (;;)
1453
 
             {
1454
 
-              point->x      = edge->pos;
1455
 
-              point->flags |= AH_FLAG_TOUCH_X;
1456
 
-            }
1457
 
+              if ( dimension )
1458
 
+              {
1459
 
+                point->y     += delta;
1460
 
+                point->flags |= AH_FLAG_TOUCH_Y;
1461
 
+              }
1462
 
+              else
1463
 
+              {
1464
 
+                point->x     += delta;
1465
 
+                point->flags |= AH_FLAG_TOUCH_X;
1466
 
+              }
1467
 
 
1468
 
-            if ( point == seg->last )
1469
 
-              break;
1470
 
+              if ( point == seg->last )
1471
 
+                break;
1472
 
 
1473
 
-            point = point->next;
1474
 
+              point = point->next;
1475
 
+            }
1476
 
           }
1477
 
 
1478
 
           seg = seg->edge_next;
1479
 
@@ -855,6 +1130,7 @@
1480
 
 
1481
 
       edges      = outline->vert_edges;
1482
 
       edge_limit = edges + outline->num_vedges;
1483
 
+      snapping   = hinter->do_horz_snapping;
1484
 
     }
1485
 
   }
1486
 
 
1487
 
@@ -871,6 +1147,7 @@
1488
 
     AH_Point    points;
1489
 
     AH_Point    point_limit;
1490
 
     AH_Flags    touch_flag;
1491
 
+    AH_Flags    strong_flag;
1492
 
 
1493
 
 
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;
1500
 
 
1501
 
     for ( dimension = 1; dimension >= 0; dimension-- )
1502
 
     {
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 ) )
1510
 
             continue;
1511
 
 #endif
1512
 
 
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;
1518
 
     }
1519
 
   }
1520
 
 
1521
 
@@ -1234,10 +1512,8 @@
1522
 
 
1523
 
 
1524
 
   FT_LOCAL_DEF( void )
1525
 
-  ah_hinter_align_points( AH_Hinter  hinter )
1526
 
+  ah_hinter_align_normal_points( AH_Hinter  hinter )
1527
 
   {
1528
 
-    ah_hinter_align_edge_points( hinter );
1529
 
-
1530
 
 #ifndef AH_OPTION_NO_STRONG_INTERPOLATION
1531
 
     ah_hinter_align_strong_points( hinter );
1532
 
 #endif
1533
 
@@ -1263,17 +1539,69 @@
1534
 
   static void
1535
 
   ah_hinter_scale_globals( AH_Hinter  hinter,
1536
 
                            FT_Fixed   x_scale,
1537
 
-                           FT_Fixed   y_scale )
1538
 
+                           FT_Fixed   y_scale,
1539
 
+                           FT_Byte    type )
1540
 
   {
1541
 
     FT_Int           n;
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;
1547
 
+
1548
 
 
1549
 
+    globals->x_scale_linear = x_scale;
1550
 
+    globals->y_scale_linear = y_scale;
1551
 
+    globals->cur_type       = type;
1552
 
 
1553
 
     /* copy content */
1554
 
     *scaled = *design;
1555
 
 
1556
 
+#ifdef FT_CONFIG_CHESTER_BLUE_SCALE
1557
 
+
1558
 
+   /* try to optimize the y_scale so that the top of non-capital letters
1559
 
+    * is aligned on a pixel boundary whenever possible
1560
 
+    */
1561
 
+    if ( design->has_blues )
1562
 
+    {
1563
 
+      FT_Pos  shoot = design->blue_shoots[AH_BLUE_SMALL_TOP];
1564
 
+      FT_Pos  ref   = design->blue_refs[AH_BLUE_SMALL_TOP];
1565
 
+
1566
 
+
1567
 
+      baseline = FT_MulFix( baseline, y_scale );
1568
 
+
1569
 
+      /* the value of 'shoot' will be -1000 if the font doesn't have */
1570
 
+      /* small latin letters; we simply check the sign here...       */
1571
 
+      if ( shoot > 0 )
1572
 
+      {
1573
 
+        FT_Pos  fitted;
1574
 
+
1575
 
+
1576
 
+        shoot = FT_MulFix( shoot, y_scale );
1577
 
+        ref   = FT_MulFix( ref,   y_scale );
1578
 
+
1579
 
+        if ( shoot < 6*64 )
1580
 
+          fitted = ( shoot + 44 ) & -64;
1581
 
+        else if ( shoot < 8*64 )
1582
 
+          fitted = ( shoot + 38 ) & -64;
1583
 
+        else
1584
 
+          fitted = ( shoot + 32 ) & -64;
1585
 
+
1586
 
+
1587
 
+        if ( ref <= fitted && fitted < shoot )
1588
 
+          fitted = shoot;
1589
 
+        else if ( fitted < ref )
1590
 
+          shoot = ref;
1591
 
+
1592
 
+        if ( fitted > shoot )
1593
 
+        {
1594
 
+          y_scale   = FT_MulDiv( y_scale, fitted, shoot );
1595
 
+          baseline -= ( fitted - shoot )/2;
1596
 
+        }
1597
 
+      }
1598
 
+    }
1599
 
+
1600
 
+#endif /* FT_CONFIG_CHESTER_BLUE_SCALE */
1601
 
+
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;
1608
 
 
1609
 
+    globals->x_scale = x_scale;
1610
 
+    globals->y_scale = y_scale;
1611
 
+
1612
 
+    if ( !design->has_blues )
1613
 
+      return;
1614
 
+
1615
 
+
1616
 
+    scaled->baseline = ( baseline + 32 ) & -64;
1617
 
+
1618
 
     /* scale the blue zones */
1619
 
     for ( n = 0; n < AH_BLUE_MAX; n++ )
1620
 
     {
1621
 
       FT_Pos  delta, delta2;
1622
 
+      FT_Pos  ref, shoot, delta3, delta4;
1623
 
 
1624
 
 
1625
 
       delta = design->blue_shoots[n] - design->blue_refs[n];
1626
 
@@ -1306,13 +1644,37 @@
1627
 
       if ( delta < 0 )
1628
 
         delta2 = -delta2;
1629
 
 
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;
1633
 
-    }
1634
 
+      if ( n == AH_BLUE_SMALL_BOTTOM )
1635
 
+      {
1636
 
+        scaled->blue_shoots[n] = delta2;
1637
 
+        scaled->blue_refs[n]   = 0;
1638
 
+        continue;
1639
 
+      }
1640
 
 
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;
1647
 
+
1648
 
+      if ( !hinter->do_stem_adjust )
1649
 
+      {
1650
 
+        if ( delta3 >  16 ) delta3 =  16;
1651
 
+        if ( delta3 < -16 ) delta3 = -16;
1652
 
+        if ( delta4 >  16 ) delta4 =  16;
1653
 
+        if ( delta4 < -16 ) delta4 = -16;
1654
 
+      }
1655
 
+
1656
 
+      shoot += delta3;
1657
 
+      ref   += delta4;
1658
 
+
1659
 
+      if ( ABS( delta3 ) < ABS( delta4 ) )
1660
 
+        ref = shoot - delta2;
1661
 
+      else
1662
 
+        shoot = ref + delta2;
1663
 
+
1664
 
+      scaled->blue_refs[n]   = ref;
1665
 
+      scaled->blue_shoots[n] = shoot;
1666
 
+    }
1667
 
   }
1668
 
 
1669
 
 
1670
 
@@ -1320,7 +1682,7 @@
1671
 
   ah_hinter_align( AH_Hinter  hinter )
1672
 
   {
1673
 
     ah_hinter_align_edge_points( hinter );
1674
 
-    ah_hinter_align_points( hinter );
1675
 
+    ah_hinter_align_normal_points( hinter );
1676
 
   }
1677
 
 
1678
 
 
1679
 
@@ -1401,7 +1763,7 @@
1680
 
     hinter->globals = face_globals;
1681
 
 
1682
 
     if ( globals )
1683
 
-      face_globals->design = *globals;
1684
 
+      face_globals->designs[0] = *globals;
1685
 
     else
1686
 
       ah_hinter_compute_globals( hinter );
1687
 
 
1688
 
@@ -1410,6 +1772,27 @@
1689
 
                                  ah_hinter_done_face_globals;
1690
 
     face_globals->face       = face;
1691
 
 
1692
 
+    ah_hinter_compute_char_table( hinter );
1693
 
+
1694
 
+    {
1695
 
+      TT_OS2*  os2 = FT_Get_Sfnt_Table( face, ft_sfnt_os2 );
1696
 
+
1697
 
+
1698
 
+      if ( os2 && os2->version != 0xFFFFU )
1699
 
+        face_globals->is_fixedpitch = FT_BOOL( os2->panose[3] == 9 );
1700
 
+      else
1701
 
+        face_globals->is_fixedpitch = FT_BOOL( FT_IS_FIXED_WIDTH( face ) != 0 );
1702
 
+
1703
 
+
1704
 
+      face_globals->has_tt_bytecode_interp = FALSE;
1705
 
+
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;
1710
 
+#endif
1711
 
+    }
1712
 
+
1713
 
   Exit:
1714
 
     return error;
1715
 
   }
1716
 
@@ -1423,6 +1806,8 @@
1717
 
     FT_Memory  memory = face->memory;
1718
 
 
1719
 
 
1720
 
+    FT_Done_Size( globals->size_EM );
1721
 
+    FT_FREE( globals->table );
1722
 
     FT_FREE( globals );
1723
 
   }
1724
 
 
1725
 
@@ -1441,12 +1826,17 @@
1726
 
     FT_Error          error;
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;
1731
 
 
1732
 
 
1733
 
     /* load the glyph */
1734
 
-    error = FT_Load_Glyph( face, glyph_index, load_flags );
1735
 
-    if ( error )
1736
 
-      goto Exit;
1737
 
+    if ( !hinter->globals->has_tt_bytecode_interp )
1738
 
+    {
1739
 
+      error = FT_Load_Glyph( face, glyph_index, load_flags );
1740
 
+      if ( error )
1741
 
+        goto Exit;
1742
 
+    }
1743
 
 
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 );
1749
 
     }
1750
 
+    else
1751
 
+    {
1752
 
+      hinter->trans_delta.x = 0;
1753
 
+      hinter->trans_delta.y = 0;
1754
 
+    }
1755
 
 
1756
 
     /* set linear horizontal metrics */
1757
 
     slot->linearHoriAdvance = slot->metrics.horiAdvance;
1758
 
@@ -1472,17 +1867,22 @@
1759
 
     {
1760
 
     case FT_GLYPH_FORMAT_OUTLINE:
1761
 
 
1762
 
+      if ( hinter->do_blue_hints )
1763
 
+        baseline = hinter->globals->designs[type].baseline;
1764
 
+
1765
 
       /* translate glyph outline if we need to */
1766
 
-      if ( hinter->transformed )
1767
 
+      if ( hinter->transformed || baseline != 0 )
1768
 
       {
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;
1773
 
 
1774
 
 
1775
 
         for ( ; n > 0; point++, n-- )
1776
 
         {
1777
 
-          point->x += hinter->trans_delta.x;
1778
 
-          point->y += hinter->trans_delta.y;
1779
 
+          point->x += x_off;
1780
 
+          point->y += y_off;
1781
 
         }
1782
 
       }
1783
 
 
1784
 
@@ -1524,7 +1924,7 @@
1785
 
       /* perform feature detection */
1786
 
       ah_outline_detect_features( outline );
1787
 
 
1788
 
-      if ( hinter->do_vert_hints )
1789
 
+      if ( hinter->do_blue_hints )
1790
 
       {
1791
 
         ah_outline_compute_blue_edges( outline, hinter->globals );
1792
 
         ah_outline_scale_blue_edges( outline, hinter->globals );
1793
 
@@ -1539,6 +1939,8 @@
1794
 
 
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 )
1799
 
       {
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;
1805
 
 
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;
1810
 
 
1811
 
 #if 0
1812
 
         /* try to fix certain bad advance computations */
1813
 
@@ -1705,6 +2107,13 @@
1814
 
       FT_BBox  bbox;
1815
 
 
1816
 
 
1817
 
+      if ( hinter->do_blue_hints )
1818
 
+      {
1819
 
+        if ( hinter->globals->scaled.baseline != 0 )
1820
 
+          FT_Outline_Translate( &gloader->base.outline,
1821
 
+                                0, hinter->globals->scaled.baseline );
1822
 
+      }
1823
 
+
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;
1830
 
 
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;
1835
 
-      else
1836
 
-        slot->metrics.horiAdvance = FT_MulFix( slot->metrics.horiAdvance,
1837
 
-                                               x_scale );
1838
 
-
1839
 
+      slot->metrics.horiAdvance = hinter->pp2.x - hinter->pp1.x;
1840
 
       slot->metrics.horiAdvance = ( slot->metrics.horiAdvance + 32 ) & -64;
1841
 
 
1842
 
       /* now copy outline into glyph slot */
1843
 
@@ -1754,6 +2156,236 @@
1844
 
   }
1845
 
 
1846
 
 
1847
 
+#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
1848
 
+
1849
 
+#define AH_MAX_COMPOSITE_RECURSE 5
1850
 
+
1851
 
+  static FT_Error
1852
 
+  ah_hinter_load_truetype( AH_Hinter  hinter,
1853
 
+                           FT_UInt    glyph_index,
1854
 
+                           FT_Int32   load_flags,
1855
 
+                           int        depth,
1856
 
+                           short    **num_contours,
1857
 
+                           short    **num_points,
1858
 
+                           int       *num_simple_glyphs,
1859
 
+                           int       *size_array )
1860
 
+  {
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;
1865
 
+
1866
 
+
1867
 
+    if ( depth == 0 )
1868
 
+    {
1869
 
+      *num_contours      = 0;
1870
 
+      *num_points        = 0;
1871
 
+      *num_simple_glyphs = 0;
1872
 
+      *size_array        = 0;
1873
 
+    }
1874
 
+
1875
 
+    error = FT_Load_Glyph( face, glyph_index, load_flags );
1876
 
+
1877
 
+    if ( error )
1878
 
+      return error;
1879
 
+
1880
 
+    switch ( slot->format )
1881
 
+    {
1882
 
+    case FT_GLYPH_FORMAT_OUTLINE:
1883
 
+      {
1884
 
+        int  size_cur = *size_array;
1885
 
+
1886
 
+
1887
 
+        if ( depth == 0 )
1888
 
+          return ah_hinter_load( hinter, 0, load_flags, 0 );
1889
 
+
1890
 
+        if ( slot->outline.n_contours == 0 )
1891
 
+          break;
1892
 
+
1893
 
+        if ( *num_simple_glyphs >= size_cur )
1894
 
+        {
1895
 
+          if ( FT_RENEW_ARRAY( *num_contours, size_cur, size_cur + 16 ) ||
1896
 
+               FT_RENEW_ARRAY( *num_points,   size_cur, size_cur + 16 ) )
1897
 
+            goto Exit;
1898
 
+          *size_array += 16;
1899
 
+        }
1900
 
+
1901
 
+        (*num_contours)[ (*num_simple_glyphs) ] = slot->outline.n_contours;
1902
 
+        (*num_points)[ (*num_simple_glyphs)++ ] = slot->outline.n_points;
1903
 
+        break;
1904
 
+      }
1905
 
+
1906
 
+    case FT_GLYPH_FORMAT_COMPOSITE:
1907
 
+      if ( depth + 1 >= AH_MAX_COMPOSITE_RECURSE )
1908
 
+        return AH_Err_Invalid_Composite;
1909
 
+
1910
 
+      if ( slot->num_subglyphs > 0 )
1911
 
+      {
1912
 
+        FT_UInt*  indices;
1913
 
+        int       num_subglyphs = slot->num_subglyphs;
1914
 
+        int       i;
1915
 
+
1916
 
+
1917
 
+        hinter->composite = TRUE;
1918
 
+
1919
 
+        if ( FT_NEW_ARRAY( indices, num_subglyphs ) )
1920
 
+          goto Exit;
1921
 
+
1922
 
+        for ( i = 0; i < num_subglyphs; i++ )
1923
 
+          indices[i] = slot->subglyphs[i].index;
1924
 
+
1925
 
+
1926
 
+        for ( i = 0; i < num_subglyphs; i++ )
1927
 
+        {
1928
 
+          error = ah_hinter_load_truetype( hinter,
1929
 
+                                           indices[i],
1930
 
+                                           load_flags,
1931
 
+                                           depth + 1,
1932
 
+                                           num_contours,
1933
 
+                                           num_points,
1934
 
+                                           num_simple_glyphs,
1935
 
+                                           size_array );
1936
 
+          if ( error )
1937
 
+          {
1938
 
+            FT_FREE( indices );
1939
 
+            goto Exit;
1940
 
+          }
1941
 
+        }
1942
 
+
1943
 
+        FT_FREE( indices );
1944
 
+
1945
 
+        if ( depth == 0 )
1946
 
+        {
1947
 
+          FT_Size      size_EM, size;
1948
 
+          FT_Vector*   points;
1949
 
+          FT_Vector*   limit;
1950
 
+          int          num = *num_simple_glyphs, j;
1951
 
+          short        n_contours, n_points;
1952
 
+          short        *array_c, *array_p;
1953
 
+
1954
 
+
1955
 
+          if ( num == 0 )
1956
 
+            break;
1957
 
+
1958
 
+          size    = face->size;
1959
 
+          size_EM = hinter->globals->size_EM;
1960
 
+
1961
 
+          if ( !size_EM )
1962
 
+          {
1963
 
+            error = FT_New_Size( face, &hinter->globals->size_EM );
1964
 
+            if ( error )
1965
 
+              goto Exit;
1966
 
+
1967
 
+            size_EM = hinter->globals->size_EM;
1968
 
+            FT_Activate_Size( size_EM );
1969
 
+
1970
 
+            error = FT_Set_Pixel_Sizes( face,
1971
 
+                                        face->units_per_EM,
1972
 
+                                        face->units_per_EM );
1973
 
+            if ( error )
1974
 
+            {
1975
 
+              FT_Activate_Size( size );
1976
 
+              goto  Exit;
1977
 
+            }
1978
 
+          }
1979
 
+          else
1980
 
+            FT_Activate_Size( size_EM );
1981
 
+
1982
 
+
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;
1988
 
+
1989
 
+          error = FT_Load_Glyph( face, glyph_index, load_flags );
1990
 
+
1991
 
+          FT_Activate_Size( size );
1992
 
+
1993
 
+          if ( error )
1994
 
+            goto Exit;
1995
 
+
1996
 
+
1997
 
+          array_c    = *num_contours;
1998
 
+          array_p    = *num_points;
1999
 
+          n_contours = 0;
2000
 
+          n_points   = 0;
2001
 
+
2002
 
+          for ( i = 0; i < num; i++ )
2003
 
+          {
2004
 
+            n_contours += *array_c++;
2005
 
+            n_points   += *array_p++;
2006
 
+          }
2007
 
+
2008
 
+          if ( slot->outline.n_points   != n_points ||
2009
 
+               slot->outline.n_contours != n_contours )
2010
 
+          {
2011
 
+            error = AH_Err_Invalid_Composite;
2012
 
+            goto Exit;
2013
 
+          }
2014
 
+
2015
 
+
2016
 
+          points = slot->outline.points;
2017
 
+          limit  = points + slot->outline.n_points;
2018
 
+
2019
 
+          while ( points < limit )
2020
 
+          {
2021
 
+            points->x >>= 6;
2022
 
+            points->y >>= 6;
2023
 
+            points++;
2024
 
+          }
2025
 
+
2026
 
+          slot->metrics.horiAdvance >>= 6;
2027
 
+          slot->metrics.vertAdvance >>= 6;
2028
 
+
2029
 
+          array_c = *num_contours;
2030
 
+          array_p = *num_points;
2031
 
+
2032
 
+          for ( i = 0; i < num - 1; i++ )
2033
 
+          {
2034
 
+            slot->outline.n_contours = *array_c++;
2035
 
+            slot->outline.n_points   = *array_p++;
2036
 
+
2037
 
+            error = ah_hinter_load( hinter, 0, load_flags, 1 );
2038
 
+            if ( error )
2039
 
+              goto Exit;
2040
 
+
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;
2046
 
+
2047
 
+            for ( j = 0; j < n_contours; j++ )
2048
 
+              slot->outline.contours[j] -= n_points;
2049
 
+          }
2050
 
+
2051
 
+          slot->outline.n_contours = *array_c;
2052
 
+          slot->outline.n_points   = *array_p;
2053
 
+
2054
 
+          error = ah_hinter_load( hinter, 0, load_flags, 0 );
2055
 
+        }
2056
 
+      }
2057
 
+      break;
2058
 
+
2059
 
+     default:
2060
 
+      error = AH_Err_Unimplemented_Feature;
2061
 
+    }
2062
 
+
2063
 
+
2064
 
+  Exit:
2065
 
+    if ( depth == 0 )
2066
 
+    {
2067
 
+      FT_FREE( *num_contours );
2068
 
+      FT_FREE( *num_points   );
2069
 
+    }
2070
 
+
2071
 
+    return  error;
2072
 
+  }
2073
 
+
2074
 
+#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
2075
 
+
2076
 
+
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 );
2084
 
+    FT_Byte          type;
2085
 
 
2086
 
 
2087
 
     /* first of all, we need to check that we're using the correct face and */
2088
 
@@ -1787,46 +2420,6 @@
2089
 
 
2090
 
     }
2091
 
 
2092
 
-#ifdef FT_CONFIG_CHESTER_BLUE_SCALE
2093
 
-
2094
 
-   /* try to optimize the y_scale so that the top of non-capital letters
2095
 
-    * is aligned on a pixel boundary whenever possible
2096
 
-    */
2097
 
-    {
2098
 
-      AH_Globals  design = &face_globals->design;
2099
 
-      FT_Pos      shoot  = design->blue_shoots[AH_BLUE_SMALL_TOP];
2100
 
-
2101
 
-
2102
 
-      /* the value of 'shoot' will be -1000 if the font doesn't have */
2103
 
-      /* small latin letters; we simply check the sign here...       */
2104
 
-      if ( shoot > 0 )
2105
 
-      {
2106
 
-        FT_Pos  scaled = FT_MulFix( shoot, y_scale );
2107
 
-        FT_Pos  fitted = ( scaled + 32 ) & -64;
2108
 
-
2109
 
-
2110
 
-        if ( scaled != fitted )
2111
 
-        {
2112
 
-         /* adjust y_scale
2113
 
-          */
2114
 
-          y_scale = FT_MulDiv( y_scale, fitted, scaled );
2115
 
-
2116
 
-         /* adust x_scale
2117
 
-          */
2118
 
-          if ( fitted < scaled )
2119
 
-            x_scale -= x_scale / 50;  /* x_scale*0.98 with integers */
2120
 
-        }
2121
 
-      }
2122
 
-    }
2123
 
-
2124
 
-#endif /* FT_CONFIG_CHESTER_BLUE_SCALE */
2125
 
-
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 );
2131
 
-
2132
 
     ah_loader_rewind( hinter->loader );
2133
 
 
2134
 
     /* reset hinting flags according to load flags and current render target */
2135
 
@@ -1850,11 +2443,51 @@
2136
 
 
2137
 
     hinter->do_stem_adjust   = FT_BOOL( hint_mode != FT_RENDER_MODE_LIGHT );
2138
 
 
2139
 
+    type = ah_hinter_get_char_type( hinter, glyph_index );
2140
 
+
2141
 
+    hinter->do_blue_hints = face_globals->designs[type].has_blues;
2142
 
+    hinter->composite     = FALSE;
2143
 
+
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 );
2150
 
+
2151
 
     load_flags |= FT_LOAD_NO_SCALE
2152
 
                 | FT_LOAD_IGNORE_TRANSFORM;
2153
 
     load_flags &= ~FT_LOAD_RENDER;
2154
 
 
2155
 
-    error = ah_hinter_load( hinter, glyph_index, load_flags, 0 );
2156
 
+#ifndef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
2157
 
+
2158
 
+     error = ah_hinter_load( hinter, glyph_index, load_flags, 0 );
2159
 
+
2160
 
+#else
2161
 
+
2162
 
+    if ( face_globals->has_tt_bytecode_interp )
2163
 
+    {
2164
 
+      short*  num_contours;
2165
 
+      short*  num_points;
2166
 
+      int     num_simple_glyphs;
2167
 
+      int     size_array;
2168
 
+
2169
 
+
2170
 
+      load_flags |= FT_LOAD_NO_RECURSE;
2171
 
+
2172
 
+      error = ah_hinter_load_truetype( hinter,
2173
 
+                                       glyph_index,
2174
 
+                                       load_flags,
2175
 
+                                       0,
2176
 
+                                       &num_contours,
2177
 
+                                       &num_points,
2178
 
+                                       &num_simple_glyphs,
2179
 
+                                       &size_array );
2180
 
+    }
2181
 
+    else
2182
 
+      error = ah_hinter_load( hinter, glyph_index, load_flags, 0 );
2183
 
+
2184
 
+#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
2185
 
 
2186
 
   Exit:
2187
 
     return error;
2188
 
@@ -1885,7 +2518,7 @@
2189
 
         goto Fail;
2190
 
     }
2191
 
 
2192
 
-    *globals      = FACE_GLOBALS( face )->design;
2193
 
+    *globals      = FACE_GLOBALS( face )->designs[0];
2194
 
     *global_hints = globals;
2195
 
     *global_len   = sizeof( *globals );
2196
 
 
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
2200
 
@@ -138,6 +138,8 @@
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
2206
 
 
2207
 
   typedef FT_Int AH_Flags;
2208
 
 
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  */
2213
 
-    FT_Pos         score;
2214
 
+    FT_Pos         score1;
2215
 
+    FT_Pos         score2;
2216
 
+    FT_Pos         length;
2217
 
+    FT_Int         sign;
2218
 
 
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;
2223
 
 
2224
 
 
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
2228
 
+
2229
 
+  enum
2230
 
+  {
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
2236
 
+  };
2237
 
+
2238
 
+
2239
 
+  typedef struct AH_CharType_
2240
 
+  {
2241
 
+    FT_Byte    type;
2242
 
+    FT_ULong   start;
2243
 
+    FT_ULong   last;
2244
 
+
2245
 
+  } AH_CharType;
2246
 
+
2247
 
+
2248
 
+  typedef struct AH_CharTypeTable_
2249
 
+  {
2250
 
+    FT_ULong       size;
2251
 
+    AH_CharType*   types;
2252
 
+
2253
 
+  } AH_CharTypeTable;
2254
 
+
2255
 
+
2256
 
   /*************************************************************************/
2257
 
   /*                                                                       */
2258
 
   /* <Struct>                                                              */
2259
 
@@ -440,6 +476,10 @@
2260
 
     FT_Pos  blue_refs  [AH_BLUE_MAX];
2261
 
     FT_Pos  blue_shoots[AH_BLUE_MAX];
2262
 
 
2263
 
+    FT_Pos  baseline;
2264
 
+
2265
 
+    FT_Bool  has_blues;
2266
 
+
2267
 
   } AH_GlobalsRec, *AH_Globals;
2268
 
 
2269
 
 
2270
 
@@ -470,12 +510,21 @@
2271
 
   typedef struct  AH_Face_GlobalsRec_
2272
 
   {
2273
 
     FT_Face        face;
2274
 
-    AH_GlobalsRec  design;
2275
 
+    AH_GlobalsRec  designs[AH_CHAR_TYPE_COUNT];
2276
 
     AH_GlobalsRec  scaled;
2277
 
     FT_Fixed       x_scale;
2278
 
     FT_Fixed       y_scale;
2279
 
     FT_Bool        control_overshoot;
2280
 
 
2281
 
+    FT_Fixed       x_scale_linear;
2282
 
+    FT_Fixed       y_scale_linear;
2283
 
+
2284
 
+    AH_CharTypeTable*  table;
2285
 
+    FT_Byte            cur_type;
2286
 
+    FT_Size            size_EM;
2287
 
+    FT_Bool            is_fixedpitch;
2288
 
+    FT_Bool            has_tt_bytecode_interp;
2289
 
+
2290
 
   } AH_Face_GlobalsRec, *AH_Face_Globals;
2291
 
 
2292
 
 
2293
 
@@ -494,6 +543,7 @@
2294
 
     AH_Loader        loader;
2295
 
     FT_Vector        pp1;
2296
 
     FT_Vector        pp2;
2297
 
+    FT_Bool          composite;
2298
 
 
2299
 
     FT_Bool          transformed;
2300
 
     FT_Vector        trans_delta;
2301
 
@@ -504,6 +554,7 @@
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         */
2306
 
 
2307
 
   } AH_HinterRec, *AH_Hinter;
2308
 
 
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
2312
 
@@ -22,7 +22,6 @@
2313
 
 #define FT_MAKE_OPTION_SINGLE_OBJECT
2314
 
 
2315
 
 #include <ft2build.h>
2316
 
-#include "ahangles.c"
2317
 
 #include "ahglyph.c"
2318
 
 #include "ahglobal.c"
2319
 
 #include "ahhint.c"