Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 31347
Collapse All | Expand All

(-)freetype-2.1.5-orig/src/autohint/ahglobal.c (-15 / +304 lines)
Lines 30-36 Link Here
30
  /* cf. AH_BLUE_XXX constants in ahtypes.h */
30
  /* cf. AH_BLUE_XXX constants in ahtypes.h */
31
31
32
  static
32
  static
33
  const char*  blue_chars[AH_BLUE_MAX] =
33
  const char*  blue_chars_latin[AH_BLUE_MAX] =
34
  {
34
  {
35
    "THEZOCQS",
35
    "THEZOCQS",
36
    "HEZLOCUS",
36
    "HEZLOCUS",
Lines 43-48 Link Here
43
  };
43
  };
44
44
45
45
46
  typedef struct AH_BlueTable_
47
  {
48
    FT_ULong      offset_blue_chars;
49
    const char**  blue_chars;
50
    FT_ULong      char_for_widths;
51
52
  } AH_BlueTable;
53
54
55
  static const AH_BlueTable  blue_table[AH_CHAR_TYPE_COUNT] =
56
  {
57
    { 0,       blue_chars_latin, (FT_ULong)'o' },
58
    { 0xFEE0L, blue_chars_latin,  0xFF4FL      },
59
    { 0,       0,                 0            },
60
    { 0,       0,                 0            }
61
  };
62
63
64
#ifdef AH_DEBUG
65
  static const char*  blue_names[AH_CHAR_TYPE_COUNT] =
66
  {
67
    "general latinate chars",
68
    "CJK fullwidth latin chars",
69
    0,
70
    0
71
  };
72
#endif
73
74
46
  /* simple insertion sort */
75
  /* simple insertion sort */
47
  static void
76
  static void
48
  sort_values( FT_Int   count,
77
  sort_values( FT_Int   count,
Lines 71-77 Link Here
71
  ah_hinter_compute_blues( AH_Hinter  hinter )
100
  ah_hinter_compute_blues( AH_Hinter  hinter )
72
  {
101
  {
73
    AH_Blue       blue;
102
    AH_Blue       blue;
74
    AH_Globals    globals = &hinter->globals->design;
103
    AH_Globals    globals = hinter->globals->designs;
75
    FT_Pos        flats [MAX_TEST_CHARACTERS];
104
    FT_Pos        flats [MAX_TEST_CHARACTERS];
76
    FT_Pos        rounds[MAX_TEST_CHARACTERS];
105
    FT_Pos        rounds[MAX_TEST_CHARACTERS];
77
    FT_Int        num_flats;
106
    FT_Int        num_flats;
Lines 81-86 Link Here
81
    FT_GlyphSlot  glyph;
110
    FT_GlyphSlot  glyph;
82
    FT_Error      error;
111
    FT_Error      error;
83
    FT_CharMap    charmap;
112
    FT_CharMap    charmap;
113
    FT_ULong      offset;
114
    FT_Byte       type;
115
    const char**  blue_chars;
84
116
85
117
86
    face  = hinter->face;
118
    face  = hinter->face;
Lines 97-104 Link Here
97
    /* we compute the blues simply by loading each character from the */
129
    /* we compute the blues simply by loading each character from the */
98
    /* 'blue_chars[blues]' string, then compute its top-most or       */
130
    /* 'blue_chars[blues]' string, then compute its top-most or       */
99
    /* bottom-most points (depending on `AH_IS_TOP_BLUE')             */
131
    /* bottom-most points (depending on `AH_IS_TOP_BLUE')             */
132
    type = AH_CHAR_TYPE_LATINATE;
100
133
101
    AH_LOG(( "blue zones computation\n" ));
134
  Compute_Blues:
135
    globals->has_blues = FALSE;
136
    globals->baseline  = 0;
137
138
    offset     = blue_table[type].offset_blue_chars;
139
    blue_chars = blue_table[type].blue_chars;
140
141
    if ( !blue_chars )
142
      goto Next_Type;
143
144
    AH_LOG(( "blue zones computation for %s\n", blue_names[type] ));
102
    AH_LOG(( "------------------------------------------------\n" ));
145
    AH_LOG(( "------------------------------------------------\n" ));
103
146
104
    for ( blue = AH_BLUE_CAPITAL_TOP; blue < AH_BLUE_MAX; blue++ )
147
    for ( blue = AH_BLUE_CAPITAL_TOP; blue < AH_BLUE_MAX; blue++ )
Lines 131-137 Link Here
131
        AH_LOG(( "`%c'", *p ));
174
        AH_LOG(( "`%c'", *p ));
132
175
133
        /* load the character in the face -- skip unknown or empty ones */
176
        /* load the character in the face -- skip unknown or empty ones */
134
        glyph_index = FT_Get_Char_Index( face, (FT_UInt)*p );
177
        glyph_index = FT_Get_Char_Index( face, offset + (FT_ULong)*p );
135
        if ( glyph_index == 0 )
178
        if ( glyph_index == 0 )
136
          continue;
179
          continue;
137
180
Lines 221-230 Link Here
221
264
222
          } while ( next != idx );
265
          } while ( next != idx );
223
266
224
          /* now, set the `round' flag depending on the segment's kind */
267
          /* now, set the `round' flag depending on whether there exists */
225
          round = FT_BOOL(
268
          /* a extremum line segment within the current zone.            */
226
            FT_CURVE_TAG( glyph->outline.tags[prev] ) != FT_CURVE_TAG_ON ||
269
          round = TRUE;
227
            FT_CURVE_TAG( glyph->outline.tags[next] ) != FT_CURVE_TAG_ON );
270
271
          {
272
            FT_Int   n = 0, p = prev;
273
            FT_Bool  is_top = AH_IS_TOP_BLUE( blue );
274
275
276
            while ( ( p = ( p >= last )? first : p + 1 ) != next )
277
            {
278
              if ( FT_CURVE_TAG( glyph->outline.tags[p] ) == FT_CURVE_TAG_ON )
279
              {
280
                if ( (  is_top && points[p].y < extremum->y ) ||
281
                     ( !is_top && points[p].y > extremum->y )  )
282
                  break;
283
284
                n++;
285
              }
286
            }
287
288
            if ( n >= 2 && p == next )
289
              round = FALSE;
290
          }
228
291
229
          AH_LOG(( "%c ", round ? 'r' : 'f' ));
292
          AH_LOG(( "%c ", round ? 'r' : 'f' ));
230
        }
293
        }
Lines 281-286 Link Here
281
      }
344
      }
282
345
283
      AH_LOG(( "-- ref = %ld, shoot = %ld\n", *blue_ref, *blue_shoot ));
346
      AH_LOG(( "-- ref = %ld, shoot = %ld\n", *blue_ref, *blue_shoot ));
347
348
      if ( num_flats > 0 || num_rounds > 0 )
349
        globals->has_blues = TRUE;
350
    }
351
352
    globals->baseline = globals->blue_refs[AH_BLUE_SMALL_BOTTOM];
353
354
    if ( globals->baseline > -10000 )
355
    {
356
      for ( blue = AH_BLUE_CAPITAL_TOP; blue < AH_BLUE_MAX; blue++ )
357
      {
358
        if ( globals->blue_refs[blue] > -10000 )
359
        {
360
          globals->blue_refs[blue]   -= globals->baseline;
361
          globals->blue_shoots[blue] -= globals->baseline;
362
        }
363
      }
364
    }
365
366
  Next_Type:
367
    if ( ++type < AH_CHAR_TYPE_COUNT )
368
    {
369
      globals++;
370
      goto Compute_Blues;
284
    }
371
    }
285
372
286
    /* reset original face charmap */
373
    /* reset original face charmap */
Lines 299-311 Link Here
299
    AH_Outline  outline = hinter->glyph;
386
    AH_Outline  outline = hinter->glyph;
300
    AH_Segment  segments;
387
    AH_Segment  segments;
301
    AH_Segment  limit;
388
    AH_Segment  limit;
302
    AH_Globals  globals = &hinter->globals->design;
389
    AH_Globals  globals = hinter->globals->designs;
303
    FT_Pos*     widths;
390
    FT_Pos*     widths;
304
    FT_Int      dimension;
391
    FT_Int      dimension;
305
    FT_Int*     p_num_widths;
392
    FT_Int*     p_num_widths;
306
    FT_Error    error = 0;
393
    FT_Error    error = 0;
307
    FT_Pos      edge_distance_threshold = 32000;
394
    FT_Pos      edge_distance_threshold = 32000;
395
    FT_Byte     type;
396
    FT_ULong    char_for_widths;
397
398
399
    type = AH_CHAR_TYPE_LATINATE;
308
400
401
  Compute_Widths:
402
    char_for_widths = blue_table[type].char_for_widths;
403
404
    if ( !char_for_widths )
405
      goto Next_Type;
309
406
310
    globals->num_widths  = 0;
407
    globals->num_widths  = 0;
311
    globals->num_heights = 0;
408
    globals->num_heights = 0;
Lines 318-335 Link Here
318
      FT_UInt  glyph_index;
415
      FT_UInt  glyph_index;
319
416
320
417
321
      glyph_index = FT_Get_Char_Index( hinter->face, 'o' );
418
      glyph_index = FT_Get_Char_Index( hinter->face, char_for_widths );
322
      if ( glyph_index == 0 )
419
      if ( glyph_index == 0 )
323
        return 0;
420
        goto Next_Type;
324
421
325
      error = FT_Load_Glyph( hinter->face, glyph_index, FT_LOAD_NO_SCALE );
422
      error = FT_Load_Glyph( hinter->face, glyph_index, FT_LOAD_NO_SCALE );
326
      if ( error )
423
      if ( error )
327
        goto Exit;
424
        goto Next_Type;
328
425
329
      error = ah_outline_load( hinter->glyph, 0x10000L, 0x10000L,
426
      error = ah_outline_load( hinter->glyph, 0x10000L, 0x10000L,
330
                               hinter->face );
427
                               hinter->face );
331
      if ( error )
428
      if ( error )
332
        goto Exit;
429
        goto Next_Type;
333
430
334
      ah_outline_compute_segments( hinter->glyph );
431
      ah_outline_compute_segments( hinter->glyph );
335
      ah_outline_link_segments( hinter->glyph );
432
      ah_outline_link_segments( hinter->glyph );
Lines 378-383 Link Here
378
      p_num_widths = &globals->num_widths;
475
      p_num_widths = &globals->num_widths;
379
    }
476
    }
380
477
478
  Next_Type:
479
    if ( type++ < AH_CHAR_TYPE_COUNT )
480
    {
481
      globals++;
482
      goto Compute_Widths;
483
    }
484
381
    /* Now, compute the edge distance threshold as a fraction of the */
485
    /* Now, compute the edge distance threshold as a fraction of the */
382
    /* smallest width in the font. Set it in `hinter->glyph' too!    */
486
    /* smallest width in the font. Set it in `hinter->glyph' too!    */
383
    if ( edge_distance_threshold == 32000 )
487
    if ( edge_distance_threshold == 32000 )
Lines 386-393 Link Here
386
    /* let's try 20% */
490
    /* let's try 20% */
387
    hinter->glyph->edge_distance_threshold = edge_distance_threshold / 5;
491
    hinter->glyph->edge_distance_threshold = edge_distance_threshold / 5;
388
492
389
  Exit:
493
    return 0;
390
    return error;
391
  }
494
  }
392
495
393
496
Lines 396-401 Link Here
396
  {
499
  {
397
    return ah_hinter_compute_widths( hinter ) ||
500
    return ah_hinter_compute_widths( hinter ) ||
398
           ah_hinter_compute_blues ( hinter );
501
           ah_hinter_compute_blues ( hinter );
502
  }
503
504
505
  static const AH_CharType
506
  ah_types_for_unicode[] =
507
  {
508
     /* Latin, Greek, Cyrillic */
509
    { AH_CHAR_TYPE_LATINATE,        0x21L,   0x52FL  },
510
511
     /* Hebrew */
512
    { AH_CHAR_TYPE_LATINATE,        0x5D0L,  0x600L  },
513
514
     /* Latin, Greek */
515
    { AH_CHAR_TYPE_LATINATE,        0x1E00L, 0x2000L },
516
517
     /* CJK fullwidth Latin */
518
    { AH_CHAR_TYPE_LATIN_FULLWIDTH, 0xFF00L, 0xFF60L }
519
  };
520
521
522
  static const AH_CharTypeTable
523
  ah_types_table_unicode =
524
  {
525
    sizeof( ah_types_for_unicode ) / sizeof( AH_CharType ),
526
    (AH_CharType *)ah_types_for_unicode
527
  };
528
529
530
  FT_LOCAL_DEF( void )
531
  ah_hinter_compute_char_table( AH_Hinter  hinter )
532
  {
533
    FT_Memory          memory     = hinter->memory;
534
    FT_Face            face       = hinter->face;
535
    AH_CharTypeTable*  table      = hinter->globals->table;
536
    FT_ULong           num_glyphs = face->num_glyphs;
537
    FT_Byte*           types;
538
    FT_Error           error;
539
    FT_CharMap         charmap;
540
541
542
    if ( table )
543
      return;
544
545
    if ( num_glyphs <= 0 )
546
      return;
547
548
    if ( FT_NEW_ARRAY( types, num_glyphs ) )
549
      return;
550
551
    FT_MEM_SET( types, AH_CHAR_TYPE_OTHER, num_glyphs );
552
553
    charmap = face->charmap;
554
    if ( FT_Select_Charmap( face, FT_ENCODING_UNICODE ) )
555
      goto Exit;
556
557
558
    {
559
      FT_Bool   empty = TRUE;
560
      FT_ULong  i;
561
562
563
      for ( i = 0; i < ah_types_table_unicode.size; i++ )
564
      {
565
        FT_UInt   glyph_index;
566
        FT_ULong  start = ah_types_table_unicode.types[i].start;
567
        FT_ULong  last  = ah_types_table_unicode.types[i].last;
568
        FT_Byte   type  = ah_types_table_unicode.types[i].type;
569
        FT_ULong  ucs   = FT_Get_Next_Char( face, start - 1, &glyph_index );
570
571
572
        while ( ucs && ucs <= last )
573
        {
574
          if ( glyph_index < num_glyphs )
575
          {
576
            empty = FALSE;
577
            types[glyph_index] = type;
578
          }
579
580
          ucs = FT_Get_Next_Char( face, ucs, &glyph_index );
581
        }
582
      }
583
584
      if ( empty )
585
        goto Exit;
586
    }
587
588
589
    {
590
      FT_Byte*  cur  = types;
591
      FT_Byte*  last = types + num_glyphs - 1;
592
      FT_Byte   type = AH_CHAR_TYPE_OTHER;
593
      FT_ULong  num  = 0;
594
      FT_ULong  alloc_size;
595
596
597
      while ( ++cur <= last )
598
      {
599
        if ( *cur != type )
600
        {
601
          type = *cur;
602
603
          if ( type < AH_CHAR_TYPE_OTHER )
604
            num++;
605
        }
606
      }
607
608
      alloc_size = sizeof( AH_CharTypeTable ) + num * sizeof( AH_CharType );
609
      if ( FT_ALLOC( table, alloc_size ) )
610
        goto Exit;
611
612
      table->size  = num;
613
      table->types = (AH_CharType *)( table + 1 );
614
    }
615
616
617
    {
618
      FT_Byte*  cur  = types + 1;
619
      FT_Byte*  last = types + face->num_glyphs - 1;
620
      FT_Byte   type = AH_CHAR_TYPE_OTHER;
621
      FT_ULong  num  = 0;
622
      FT_ULong  i;
623
624
625
      for ( i = 1; cur <= last; i++, cur++ )
626
      {
627
        if ( *cur != type )
628
        {
629
          if ( type < AH_CHAR_TYPE_OTHER )
630
            table->types[num - 1].last = i - 1;
631
632
          type = *cur;
633
          if ( type < AH_CHAR_TYPE_OTHER )
634
          {
635
            table->types[num].type    = type;
636
            table->types[num++].start = i;
637
          }
638
        }
639
      }
640
641
      if ( type < AH_CHAR_TYPE_OTHER )
642
        table->types[num - 1].last = i - 1;
643
    }
644
645
    hinter->globals->table = table;
646
647
  Exit:
648
    FT_Set_Charmap( face, charmap );
649
    FT_FREE( types );
650
  }
651
652
653
  FT_LOCAL_DEF( FT_Byte )
654
  ah_hinter_get_char_type( AH_Hinter  hinter,
655
                           FT_ULong   glyph_index )
656
  {
657
    AH_CharTypeTable*  table = hinter->globals->table;
658
659
660
    if ( table && table->size > 0 && glyph_index )
661
    {
662
      AH_CharType*  cur;
663
      AH_CharType*  types = table->types;
664
      FT_ULong      min   = 0;
665
      FT_ULong      max   = table->size - 1;
666
      FT_ULong      mid;
667
668
669
      if ( glyph_index < types[min].start ||
670
           glyph_index > types[max].last )
671
        return AH_CHAR_TYPE_OTHER;
672
673
      while ( min <= max )
674
      {
675
        mid = ( min + max ) / 2;
676
        cur = types + mid;
677
678
        if ( glyph_index < cur->start )
679
          max = mid - 1;
680
        else if ( glyph_index > cur->last )
681
          min = mid + 1;
682
        else
683
          return cur->type;
684
      }
685
    }
686
687
    return AH_CHAR_TYPE_OTHER;
399
  }
688
  }
400
689
401
690
(-)freetype-2.1.5-orig/src/autohint/ahglobal.h (+8 lines)
Lines 51-56 Link Here
51
  ah_hinter_compute_globals( AH_Hinter  hinter );
51
  ah_hinter_compute_globals( AH_Hinter  hinter );
52
52
53
53
54
  FT_LOCAL( void )
55
  ah_hinter_compute_char_table( AH_Hinter  hinter );
56
57
58
  FT_LOCAL( FT_Byte )
59
  ah_hinter_get_char_type( AH_Hinter  hinter,
60
                           FT_ULong   glyph_index );
61
54
FT_END_HEADER
62
FT_END_HEADER
55
63
56
#endif /* __AHGLOBAL_H__ */
64
#endif /* __AHGLOBAL_H__ */
(-)freetype-2.1.5-orig/src/autohint/ahglyph.c (-40 / +246 lines)
Lines 22-28 Link Here
22
22
23
#include <ft2build.h>
23
#include <ft2build.h>
24
#include "ahglyph.h"
24
#include "ahglyph.h"
25
#include "ahangles.h"
26
#include "ahglobal.h"
25
#include "ahglobal.h"
27
#include "aherrors.h"
26
#include "aherrors.h"
28
27
Lines 52-62 Link Here
52
      printf ( "Table of %s edges:\n",
51
      printf ( "Table of %s edges:\n",
53
               !dimension ? "vertical" : "horizontal" );
52
               !dimension ? "vertical" : "horizontal" );
54
      printf ( "  [ index |  pos |  dir  | link |"
53
      printf ( "  [ index |  pos |  dir  | link |"
55
               " serif | blue | opos  |  pos  ]\n" );
54
               " serif | blue | opos  |  pos  |  diff ]\n" );
56
55
57
      for ( edge = edges; edge < edge_limit; edge++ )
56
      for ( edge = edges; edge < edge_limit; edge++ )
58
      {
57
      {
59
        printf ( "  [ %5d | %4d | %5s | %4d | %5d |  %c  | %5.2f | %5.2f ]\n",
58
        printf ( "  [ %5d | %4d | %5s | %4d | %6d |  %c  | %5.2f | %5.2f | %5.2f ]\n",
60
                 edge - edges,
59
                 edge - edges,
61
                 (int)edge->fpos,
60
                 (int)edge->fpos,
62
                 edge->dir == AH_DIR_UP
61
                 edge->dir == AH_DIR_UP
Lines 72-78 Link Here
72
                 edge->serif ? ( edge->serif - edges ) : -1,
71
                 edge->serif ? ( edge->serif - edges ) : -1,
73
                 edge->blue_edge ? 'y' : 'n',
72
                 edge->blue_edge ? 'y' : 'n',
74
                 edge->opos / 64.0,
73
                 edge->opos / 64.0,
75
                 edge->pos / 64.0 );
74
                 edge->pos / 64.0,
75
                 ( edge->pos - edge->opos ) / 64.0 );
76
      }
76
      }
77
77
78
      edges      = outline->vert_edges;
78
      edges      = outline->vert_edges;
Lines 370-375 Link Here
370
    char*       tag         = gloader->current.outline.tags;
370
    char*       tag         = gloader->current.outline.tags;
371
371
372
372
373
#ifdef AH_DEBUG
374
    ah_dump_segments( outline );
375
    ah_dump_edges( outline );
376
    printf( "\n" );
377
 #endif
378
373
    /* we assume that the glyph loader has already been checked for storage */
379
    /* we assume that the glyph loader has already been checked for storage */
374
    for ( ; point < point_limit; point++, vec++, tag++ )
380
    for ( ; point < point_limit; point++, vec++, tag++ )
375
    {
381
    {
Lines 594-599 Link Here
594
600
595
          point->out_dir = ah_compute_direction( ovec.x, ovec.y );
601
          point->out_dir = ah_compute_direction( ovec.x, ovec.y );
596
602
603
#if 0
597
#ifndef AH_OPTION_NO_WEAK_INTERPOLATION
604
#ifndef AH_OPTION_NO_WEAK_INTERPOLATION
598
          if ( point->flags & ( AH_FLAG_CONIC | AH_FLAG_CUBIC ) )
605
          if ( point->flags & ( AH_FLAG_CONIC | AH_FLAG_CUBIC ) )
599
          {
606
          {
Lines 624-629 Link Here
624
          else if ( point->in_dir == -point->out_dir )
631
          else if ( point->in_dir == -point->out_dir )
625
            goto Is_Weak_Point;
632
            goto Is_Weak_Point;
626
#endif
633
#endif
634
#endif
627
        }
635
        }
628
      }
636
      }
629
    }
637
    }
Lines 709-714 Link Here
709
  }
717
  }
710
718
711
719
720
#if 0
712
  /* compute all inflex points in a given glyph */
721
  /* compute all inflex points in a given glyph */
713
  static void
722
  static void
714
  ah_outline_compute_inflections( AH_Outline  outline )
723
  ah_outline_compute_inflections( AH_Outline  outline )
Lines 822-827 Link Here
822
      ;
831
      ;
823
    }
832
    }
824
  }
833
  }
834
#endif
835
836
837
  /* compute all strong points in a given glyph */
838
  static void
839
  ah_outline_compute_strongs( AH_Outline  outline )
840
  {
841
    AH_Point*   contour       = outline->contours;
842
    AH_Point*   contour_limit = contour + outline->num_contours;
843
844
845
    /* load original coordinates in (u,v) */
846
    ah_setup_uv( outline, AH_UV_FXY );
847
848
    for ( ; contour < contour_limit; contour++ )
849
    {
850
      FT_Pos     dx1, dx2, dy1, dy2;
851
      AH_Point   point = contour[0];
852
      AH_Point   first = point;
853
      AH_Point   before;
854
      AH_Point   after;
855
856
857
      after  = point->next;
858
      before = point->prev;
859
      dx1    = point->u - before->u;
860
      dy1    = point->v - before->v;
861
862
      do
863
      {
864
        dx2 = after->u - point->u;
865
        dy2 = after->v - point->v;
866
867
        if ( dx1 == 0 || dx2 == 0 || ( dx1 ^ dx2 ) < 0 )
868
          point->flags |= AH_FLAG_STRONG_X;
869
870
        if ( dy1 == 0 || dy2 == 0 || ( dy1 ^ dy2 ) < 0 )
871
          point->flags |= AH_FLAG_STRONG_Y;
872
873
        before = point;
874
        point  = after;
875
        after  = after->next;
876
        dx1    = dx2;
877
        dy1    = dy2;
878
879
      } while ( point != first );
880
    }
881
  }
825
882
826
883
827
  FT_LOCAL_DEF( void )
884
  FT_LOCAL_DEF( void )
Lines 925-935 Link Here
925
              segment->last = point;
982
              segment->last = point;
926
              segment->pos  = ( min_pos + max_pos ) >> 1;
983
              segment->pos  = ( min_pos + max_pos ) >> 1;
927
984
985
#if 0
928
              /* a segment is round if either its first or last point */
986
              /* a segment is round if either its first or last point */
929
              /* is a control point                                   */
987
              /* is a control point                                   */
930
              if ( ( segment->first->flags | point->flags ) &
988
              if ( ( segment->first->flags | point->flags ) &
931
                     AH_FLAG_CONTROL                        )
989
                     AH_FLAG_CONTROL                        )
932
                segment->flags |= AH_EDGE_ROUND;
990
                segment->flags |= AH_EDGE_ROUND;
991
#else
992
              /* a segment is round if it doesn't have successive */
993
              /* on-curve points.                                 */
994
              {
995
                AH_Point  pt = segment->first;
996
                AH_Flags  f0 = pt->flags & AH_FLAG_CONTROL;
997
                AH_Flags  f1;
998
999
1000
                for ( ; pt != point; f0 = f1 )
1001
                {
1002
                  pt = pt->next;
1003
                  f1 = pt->flags & AH_FLAG_CONTROL;
1004
1005
                  if ( !f0 && !f1 )
1006
                    break;
1007
1008
                  if ( pt == point )
1009
                    segment->flags |= AH_EDGE_ROUND;
1010
                }
1011
              }
1012
#endif
933
1013
934
              /* compute segment size */
1014
              /* compute segment size */
935
              min_pos = max_pos = point->v;
1015
              min_pos = max_pos = point->v;
Lines 972-978 Link Here
972
            segment->first    = point;
1052
            segment->first    = point;
973
            segment->last     = point;
1053
            segment->last     = point;
974
            segment->contour  = contour;
1054
            segment->contour  = contour;
975
            segment->score    = 32000;
1055
            segment->score1   = 0x7FFFFFFFL;
1056
            segment->score2   = 0x7FFFFFFFL;
1057
            segment->length   = 0;
1058
            segment->sign     = 0;
976
            segment->link     = NULL;
1059
            segment->link     = NULL;
977
            on_edge           = 1;
1060
            on_edge           = 1;
978
1061
Lines 1035-1041 Link Here
1035
          segment->first = min_point;
1118
          segment->first = min_point;
1036
          segment->last  = min_point;
1119
          segment->last  = min_point;
1037
          segment->pos   = min_pos;
1120
          segment->pos   = min_pos;
1038
          segment->score = 32000;
1121
          segment->score1 = 0x7FFFFFFFL;
1122
          segment->score2 = 0x7FFFFFFFL;
1123
          segment->length = 0;
1124
          segment->sign   = 0;
1039
          segment->link  = NULL;
1125
          segment->link  = NULL;
1040
1126
1041
          num_segments++;
1127
          num_segments++;
Lines 1053-1059 Link Here
1053
          segment->first = max_point;
1139
          segment->first = max_point;
1054
          segment->last  = max_point;
1140
          segment->last  = max_point;
1055
          segment->pos   = max_pos;
1141
          segment->pos   = max_pos;
1056
          segment->score = 32000;
1142
          segment->score1 = 0x7FFFFFFFL;
1143
          segment->score2 = 0x7FFFFFFFL;
1144
          segment->length = 0;
1145
          segment->sign   = 0;
1057
          segment->link  = NULL;
1146
          segment->link  = NULL;
1058
1147
1059
          num_segments++;
1148
          num_segments++;
Lines 1080-1090 Link Here
1080
    AH_Segment    segment_limit;
1169
    AH_Segment    segment_limit;
1081
    AH_Direction  major_dir;
1170
    AH_Direction  major_dir;
1082
    int           dimension;
1171
    int           dimension;
1172
    FT_Pos        score_limit;
1083
1173
1084
1174
1085
    segments      = outline->horz_segments;
1175
    segments      = outline->horz_segments;
1086
    segment_limit = segments + outline->num_hsegments;
1176
    segment_limit = segments + outline->num_hsegments;
1087
    major_dir     = outline->horz_major_dir;
1177
    major_dir     = outline->horz_major_dir;
1178
    score_limit   = FT_DivFix( 64*3*9, outline->y_scale );
1088
1179
1089
    for ( dimension = 1; dimension >= 0; dimension-- )
1180
    for ( dimension = 1; dimension >= 0; dimension-- )
1090
    {
1181
    {
Lines 1203-1222 Link Here
1203
                max = seg2->max_coord;
1294
                max = seg2->max_coord;
1204
1295
1205
              len = max - min;
1296
              len = max - min;
1206
              if ( len >= 8 )
1297
              if ( len >= 4 )
1207
              {
1298
              {
1208
                score = dist + 3000 / len;
1299
                score = 8*dist;
1209
1300
1210
                if ( score < seg1->score )
1301
                if ( score < seg1->score1 &&
1302
                     !( score > seg1->score2 && 4*len < seg1->length ) )
1211
                {
1303
                {
1212
                  seg1->score = score;
1304
                  seg1->score1 = 9*dist;
1213
                  seg1->link  = seg2;
1305
                  seg1->score2 = 7*dist;
1306
                  seg1->length = len;
1307
                  seg1->sign   = -1;
1308
                  seg1->link   = seg2;
1214
                }
1309
                }
1215
1310
1216
                if ( score < seg2->score )
1311
                if ( score < seg2->score1 &&
1312
                     !( score > seg2->score2 && 4*len < seg2->length ) )
1217
                {
1313
                {
1218
                  seg2->score = score;
1314
                  seg2->score1 = 9*dist;
1219
                  seg2->link  = seg1;
1315
                  seg2->score2 = 7*dist;
1316
                  seg2->length = len;
1317
                  seg2->sign   = +1;
1318
                  seg2->link   = seg1;
1220
                }
1319
                }
1221
              }
1320
              }
1222
            }
1321
            }
Lines 1225-1230 Link Here
1225
#endif /* 1 */
1324
#endif /* 1 */
1226
1325
1227
      /* now, compute the `serif' segments */
1326
      /* now, compute the `serif' segments */
1327
      {
1328
        AH_Segment  seg, link1, link2;
1329
        FT_Pos      pos1, pos2;
1330
1331
1332
        for ( seg1 = segments; seg1 < segment_limit; seg1++ )
1333
        {
1334
          if ( seg1->sign >= 0 || seg1->score1 >= score_limit )
1335
            continue;
1336
1337
          link1 = seg1->link;
1338
          if ( link1->link != seg1 )
1339
            continue;
1340
1341
          pos1 = seg1->pos;
1342
          pos2 = link1->pos;
1343
1344
1345
          for ( seg2 = segments; seg2 < segment_limit; seg2++ )
1346
          {
1347
            if ( seg2->sign >= 0 ||
1348
                 seg2->score1 <= seg1->score1 || seg2->pos > pos1 )
1349
              continue;
1350
1351
            link2 = seg2->link;
1352
            if ( link2->link != seg2 )
1353
              continue;
1354
1355
            if ( link2->pos < pos2              ||
1356
                 seg1->score1*4 <= seg2->score1 )
1357
              continue;
1358
1359
            /* seg2->pos < pos1 < pos2 < seg2->link->pos */
1360
1361
            if ( seg1->length < seg2->length*2 )
1362
            {
1363
              seg1->link = link1->link = 0;
1364
              seg1->sign = link1->sign = 0;
1365
            }
1366
            else
1367
            {
1368
              for ( seg = segments; seg < segment_limit; seg++ )
1369
              {
1370
                AH_Segment  link = seg->link;
1371
1372
1373
                if ( link == seg2 )
1374
                {
1375
                  seg->sign  = 0;
1376
                  seg->link  = 0;
1377
                  seg->serif = link1;
1378
                }
1379
                else if ( link == link2 )
1380
                {
1381
                  seg->sign  = 0;
1382
                  seg->link  = 0;
1383
                  seg->serif = seg1;
1384
                }
1385
              }
1386
            }
1387
1388
            break;
1389
          }
1390
        }
1391
      }
1392
1393
1228
      for ( seg1 = segments; seg1 < segment_limit; seg1++ )
1394
      for ( seg1 = segments; seg1 < segment_limit; seg1++ )
1229
      {
1395
      {
1230
        seg2 = seg1->link;
1396
        seg2 = seg1->link;
Lines 1234-1241 Link Here
1234
          seg2->num_linked++;
1400
          seg2->num_linked++;
1235
          if ( seg2->link != seg1 )
1401
          if ( seg2->link != seg1 )
1236
          {
1402
          {
1237
            seg1->link  = 0;
1403
            seg1->link = 0;
1238
            seg1->serif = seg2->link;
1404
1405
            if ( seg2->score1 < score_limit    ||
1406
                 seg1->score1 < seg2->score1*4 )
1407
              seg1->serif = seg2->link;
1408
            else
1409
              seg2->num_linked--;
1239
          }
1410
          }
1240
        }
1411
        }
1241
      }
1412
      }
Lines 1243-1248 Link Here
1243
      segments      = outline->vert_segments;
1414
      segments      = outline->vert_segments;
1244
      segment_limit = segments + outline->num_vsegments;
1415
      segment_limit = segments + outline->num_vsegments;
1245
      major_dir     = outline->vert_major_dir;
1416
      major_dir     = outline->vert_major_dir;
1417
      score_limit   = FT_DivFix( 64*3*9, outline->x_scale );
1246
    }
1418
    }
1247
  }
1419
  }
1248
1420
Lines 1310-1321 Link Here
1310
          FT_Pos  dist;
1482
          FT_Pos  dist;
1311
1483
1312
1484
1485
          if ( edge->dir != seg->dir )
1486
            continue;
1487
1313
          dist = seg->pos - edge->fpos;
1488
          dist = seg->pos - edge->fpos;
1314
          if ( dist < 0 )
1489
          if ( dist < 0 )
1315
            dist = -dist;
1490
            dist = -dist;
1316
1491
1317
          if ( dist < edge_distance_threshold )
1492
          if ( dist < edge_distance_threshold )
1318
          {
1493
          {
1494
            AH_Segment  link = seg->link;
1495
1496
1497
            /* check if all linked segments of the candidate edge */
1498
            /* can make a single edge.                            */
1499
            if ( link )
1500
            {
1501
              AH_Segment  seg1 = edge->first;
1502
              AH_Segment  link1;
1503
1504
1505
              do
1506
              {
1507
                link1 = seg1->link;
1508
                if ( link1 )
1509
                {
1510
                  dist = link->pos - link1->pos;
1511
                  if ( dist < 0 )
1512
                    dist = -dist;
1513
1514
                  dist = FT_MulFix( dist, scale );
1515
                  if ( dist >= edge_distance_threshold )
1516
                    break;
1517
                }
1518
1519
              } while ( ( seg1 = seg1->edge_next ) != edge->first );
1520
1521
              if ( dist >= edge_distance_threshold )
1522
                continue;
1523
            }
1524
1319
            found = edge;
1525
            found = edge;
1320
            break;
1526
            break;
1321
          }
1527
          }
Lines 1341-1346 Link Here
1341
          edge->fpos     = seg->pos;
1547
          edge->fpos     = seg->pos;
1342
          edge->opos     = edge->pos = FT_MulFix( seg->pos, scale );
1548
          edge->opos     = edge->pos = FT_MulFix( seg->pos, scale );
1343
          seg->edge_next = seg;
1549
          seg->edge_next = seg;
1550
          edge->dir      = seg->dir;
1344
        }
1551
        }
1345
        else
1552
        else
1346
        {
1553
        {
Lines 1391-1398 Link Here
1391
      {
1598
      {
1392
        FT_Int  is_round    = 0;  /* does it contain round segments?    */
1599
        FT_Int  is_round    = 0;  /* does it contain round segments?    */
1393
        FT_Int  is_straight = 0;  /* does it contain straight segments? */
1600
        FT_Int  is_straight = 0;  /* does it contain straight segments? */
1394
        FT_Pos  ups         = 0;  /* number of upwards segments         */
1395
        FT_Pos  downs       = 0;  /* number of downwards segments       */
1396
1601
1397
1602
1398
        seg = edge->first;
1603
        seg = edge->first;
Lines 1408-1419 Link Here
1408
          else
1613
          else
1409
            is_straight++;
1614
            is_straight++;
1410
1615
1411
          /* check for segment direction */
1412
          if ( seg->dir == up_dir )
1413
            ups   += seg->max_coord-seg->min_coord;
1414
          else
1415
            downs += seg->max_coord-seg->min_coord;
1416
1417
          /* check for links -- if seg->serif is set, then seg->link must */
1616
          /* check for links -- if seg->serif is set, then seg->link must */
1418
          /* be ignored                                                   */
1617
          /* be ignored                                                   */
1419
          is_serif = (FT_Bool)( seg->serif && seg->serif->edge != edge );
1618
          is_serif = (FT_Bool)( seg->serif && seg->serif->edge != edge );
Lines 1479-1496 Link Here
1479
        if ( is_round > 0 && is_round >= is_straight )
1678
        if ( is_round > 0 && is_round >= is_straight )
1480
          edge->flags |= AH_EDGE_ROUND;
1679
          edge->flags |= AH_EDGE_ROUND;
1481
1680
1482
        /* set the edge's main direction */
1483
        edge->dir = AH_DIR_NONE;
1484
1485
        if ( ups > downs )
1486
          edge->dir = up_dir;
1487
1488
        else if ( ups < downs )
1489
          edge->dir = -up_dir;
1490
1491
        else if ( ups == downs )
1492
          edge->dir = 0;  /* both up and down! */
1493
1494
        /* gets rid of serifs if link is set                */
1681
        /* gets rid of serifs if link is set                */
1495
        /* XXX: This gets rid of many unpleasant artefacts! */
1682
        /* XXX: This gets rid of many unpleasant artefacts! */
1496
        /*      Example: the `c' in cour.pfa at size 13     */
1683
        /*      Example: the `c' in cour.pfa at size 13     */
Lines 1523-1529 Link Here
1523
    ah_outline_compute_segments   ( outline );
1710
    ah_outline_compute_segments   ( outline );
1524
    ah_outline_link_segments      ( outline );
1711
    ah_outline_link_segments      ( outline );
1525
    ah_outline_compute_edges      ( outline );
1712
    ah_outline_compute_edges      ( outline );
1526
    ah_outline_compute_inflections( outline );
1713
    ah_outline_compute_strongs    ( outline );
1527
  }
1714
  }
1528
1715
1529
1716
Lines 1542-1553 Link Here
1542
  {
1729
  {
1543
    AH_Edge     edge       = outline->horz_edges;
1730
    AH_Edge     edge       = outline->horz_edges;
1544
    AH_Edge     edge_limit = edge + outline->num_hedges;
1731
    AH_Edge     edge_limit = edge + outline->num_hedges;
1545
    AH_Globals  globals    = &face_globals->design;
1732
    AH_Globals  globals    = &face_globals->designs[face_globals->cur_type];
1546
    FT_Fixed    y_scale    = outline->y_scale;
1733
    FT_Fixed    y_scale    = outline->y_scale;
1547
1734
1548
    FT_Bool     blue_active[AH_BLUE_MAX];
1735
    FT_Bool     blue_active[AH_BLUE_MAX];
1549
1736
1550
1737
1738
    if ( !globals->has_blues )
1739
      return;
1740
1551
    /* compute which blue zones are active, i.e. have their scaled */
1741
    /* compute which blue zones are active, i.e. have their scaled */
1552
    /* size < 3/4 pixels                                           */
1742
    /* size < 3/4 pixels                                           */
1553
    {
1743
    {
Lines 1588-1593 Link Here
1588
      FT_Pos   best_dist;  /* initial threshold */
1778
      FT_Pos   best_dist;  /* initial threshold */
1589
1779
1590
1780
1781
      if ( edge->serif )
1782
      {
1783
        FT_Pos  dist = edge->serif->pos - edge->pos;
1784
1785
1786
        if ( dist < 0 )
1787
          dist = -dist;
1788
1789
        if ( dist < 128 )
1790
          continue;
1791
      }
1792
1591
      /* compute the initial threshold as a fraction of the EM size */
1793
      /* compute the initial threshold as a fraction of the EM size */
1592
      best_dist = FT_MulFix( face_globals->face->units_per_EM / 40, y_scale );
1794
      best_dist = FT_MulFix( face_globals->face->units_per_EM / 40, y_scale );
1593
1795
Lines 1686-1692 Link Here
1686
    FT_Pos   delta;
1888
    FT_Pos   delta;
1687
1889
1688
1890
1689
    delta = globals->scaled.blue_refs - globals->design.blue_refs;
1891
    if ( !globals->scaled.has_blues )
1892
      return;
1893
1894
    delta = globals->scaled.blue_refs -
1895
            globals->designs[globals->cur_type].blue_refs;
1690
1896
1691
    for ( ; edge < edge_limit; edge++ )
1897
    for ( ; edge < edge_limit; edge++ )
1692
    {
1898
    {
(-)freetype-2.1.5-orig/src/autohint/ahhint.c (-123 / +756 lines)
Lines 22-30 Link Here
22
#include <ft2build.h>
22
#include <ft2build.h>
23
#include "ahhint.h"
23
#include "ahhint.h"
24
#include "ahglyph.h"
24
#include "ahglyph.h"
25
#include "ahangles.h"
26
#include "aherrors.h"
25
#include "aherrors.h"
27
#include FT_OUTLINE_H
26
#include FT_OUTLINE_H
27
#include FT_TRUETYPE_TABLES_H
28
28
29
29
30
#define FACE_GLOBALS( face )  ( (AH_Face_Globals)(face)->autohint.data )
30
#define FACE_GLOBALS( face )  ( (AH_Face_Globals)(face)->autohint.data )
Lines 112-118 Link Here
112
112
113
    if ( !hinter->do_stem_adjust )
113
    if ( !hinter->do_stem_adjust )
114
    {
114
    {
115
      /* leave stem widths unchanged */
115
      if ( dist < 48 )
116
        dist += ( 48 - dist )/2 ;
116
    }
117
    }
117
    else if ( (  vertical && !hinter->do_vert_snapping ) ||
118
    else if ( (  vertical && !hinter->do_vert_snapping ) ||
118
              ( !vertical && !hinter->do_horz_snapping ) )
119
              ( !vertical && !hinter->do_horz_snapping ) )
Lines 120-125 Link Here
120
      /* smooth hinting process: very lightly quantize the stem width */
121
      /* smooth hinting process: very lightly quantize the stem width */
121
      /*                                                              */
122
      /*                                                              */
122
123
124
#if 0
123
      /* leave the widths of serifs alone */
125
      /* leave the widths of serifs alone */
124
126
125
      if ( ( stem_flags & AH_EDGE_SERIF ) && vertical && ( dist < 3 * 64 ) )
127
      if ( ( stem_flags & AH_EDGE_SERIF ) && vertical && ( dist < 3 * 64 ) )
Lines 132-155 Link Here
132
      }
134
      }
133
      else if ( dist < 56 )
135
      else if ( dist < 56 )
134
        dist = 56;
136
        dist = 56;
137
#endif
135
138
136
      {
139
      {
137
        FT_Pos  delta = dist - globals->stds[vertical];
140
        FT_Pos  delta;
138
141
139
142
140
        if ( delta < 0 )
143
        if ( (  vertical && globals->num_heights > 0 ) ||
141
          delta = -delta;
144
             ( !vertical && globals->num_widths  > 0 ) )
142
143
        if ( delta < 40 )
144
        {
145
        {
145
          dist = globals->stds[vertical];
146
          delta = dist - globals->stds[vertical];
146
          if ( dist < 48 )
147
147
            dist = 48;
148
          if ( delta < 0 )
149
            delta = -delta;
148
150
149
          goto Done_Width;
151
          if ( delta < 40 )
152
          {
153
            dist = globals->stds[vertical];
154
            if ( dist < 48 )
155
              dist = 48;
156
157
            goto Done_Width;
158
          }
150
        }
159
        }
151
160
152
        if ( dist < 3 * 64 )
161
        if ( dist < 54 )
162
        {
163
          dist += ( 54 - dist )/2 ;
164
        }
165
        else if ( dist < 3 * 64 )
153
        {
166
        {
154
          delta  = dist & 63;
167
          delta  = dist & 63;
155
          dist  &= -64;
168
          dist  &= -64;
Lines 157-173 Link Here
157
          if ( delta < 10 )
170
          if ( delta < 10 )
158
            dist += delta;
171
            dist += delta;
159
172
160
          else if ( delta < 32 )
173
          else if ( delta < 22 )
161
            dist += 10;
174
            dist += 10;
162
175
176
          else if ( delta < 42 )
177
            dist += delta;
178
163
          else if ( delta < 54 )
179
          else if ( delta < 54 )
164
            dist += 54;
180
            dist += 54;
165
181
166
          else
182
          else
167
            dist += delta;
183
            dist += delta;
168
        }
184
        }
169
        else
170
          dist = ( dist + 32 ) & -64;
171
      }
185
      }
172
    }
186
    }
173
    else
187
    else
Lines 409-414 Link Here
409
    serif->pos = base->pos + sign * dist;
423
    serif->pos = base->pos + sign * dist;
410
  }
424
  }
411
425
426
 
427
  static FT_Pos
428
  ah_hint_normal_stem( AH_Hinter  hinter,
429
                       AH_Edge    edge,
430
                       AH_Edge    edge2,
431
                       FT_Pos     anchor,
432
                       FT_Int     vertical )
433
  {
434
    FT_Pos   org_len, cur_len, org_center;
435
    FT_Pos   cur_pos1, cur_pos2;
436
    FT_Pos   d_off1, u_off1, d_off2, u_off2, delta;
437
    FT_Pos   offset;
438
    FT_Pos   threshold = 64;
439
440
441
    if ( !hinter->do_stem_adjust )
442
    {
443
      if ( ( edge->flags  & AH_EDGE_ROUND ) &&
444
           ( edge2->flags & AH_EDGE_ROUND )  )
445
      {
446
        if ( vertical )
447
          threshold = 64 - AH_LIGHT_MODE_MAX_HORZ_GAP;
448
        else
449
          threshold = 64 - AH_LIGHT_MODE_MAX_VERT_GAP;
450
      }
451
      else
452
      {
453
        if ( vertical )
454
          threshold = 64 - AH_LIGHT_MODE_MAX_HORZ_GAP/3;
455
        else
456
          threshold = 64 - AH_LIGHT_MODE_MAX_VERT_GAP/3;
457
      }
458
    }
459
460
    org_len    = edge2->opos - edge->opos;
461
    cur_len    = ah_compute_stem_width( hinter, vertical, org_len,
462
                                        edge->flags, edge2->flags );
463
    org_center = ( edge->opos + edge2->opos ) / 2 + anchor;
464
    cur_pos1   = org_center - cur_len / 2;
465
    cur_pos2   = cur_pos1 + cur_len;
466
    d_off1     = cur_pos1 - ( cur_pos1 & -64 );
467
    d_off2     = cur_pos2 - ( cur_pos2 & -64 );
468
    u_off1     = 64 - d_off1;
469
    u_off2     = 64 - d_off2;
470
    delta      = 0;
471
472
473
    if ( d_off1 == 0 || d_off2 == 0 )
474
      goto Exit;
475
476
    if ( cur_len <= threshold )
477
    {
478
      if ( d_off2 < cur_len )
479
      {
480
        if ( u_off1 <= d_off2 )
481
          delta =  u_off1;
482
        else
483
          delta = -d_off2;
484
      }
485
486
      goto Exit;
487
    }
488
489
    if ( threshold < 64 )
490
    {
491
      if ( d_off1 >= threshold || u_off1 >= threshold ||
492
           d_off2 >= threshold || u_off2 >= threshold )
493
        goto Exit;
494
    }
495
496
    offset = cur_len % 64;
497
498
    if ( offset < 32 )
499
    {
500
      if ( u_off1 <= offset || d_off2 <= offset )
501
        goto Exit;
502
    }
503
    else
504
      offset = 64 - threshold;
505
506
    d_off1 = threshold - u_off1;
507
    u_off1 = u_off1    - offset;
508
    u_off2 = threshold - d_off2;
509
    d_off2 = d_off2    - offset;
510
511
    if ( d_off1 <= u_off1 )
512
      u_off1 = -d_off1;
513
514
    if ( d_off2 <= u_off2 )
515
      u_off2 = -d_off2;
516
517
    if ( ABS( u_off1 ) <= ABS( u_off2 ) )
518
      delta = u_off1;
519
    else
520
      delta = u_off2;
521
522
  Exit:
523
#if 1
524
    if ( !hinter->do_stem_adjust )
525
    {
526
      if ( delta > AH_LIGHT_MODE_MAX_DELTA_ABS )
527
        delta = AH_LIGHT_MODE_MAX_DELTA_ABS;
528
      else if ( delta < -AH_LIGHT_MODE_MAX_DELTA_ABS )
529
        delta = -AH_LIGHT_MODE_MAX_DELTA_ABS;
530
    }
531
#endif
532
533
    cur_pos1 += delta;
534
535
    if ( edge->opos < edge2->opos )
536
    {
537
      edge->pos  = cur_pos1;
538
      edge2->pos = cur_pos1 + cur_len;
539
    }
540
    else
541
    {
542
      edge->pos  = cur_pos1 + cur_len;
543
      edge2->pos = cur_pos1;
544
    }
545
546
    return delta;
547
  }
548
412
549
413
  /*************************************************************************/
550
  /*************************************************************************/
414
  /*************************************************************************/
551
  /*************************************************************************/
Lines 438-443 Link Here
438
    {
575
    {
439
      AH_Edge  edge;
576
      AH_Edge  edge;
440
      AH_Edge  anchor = 0;
577
      AH_Edge  anchor = 0;
578
      FT_Pos   delta  = 0;
441
      int      has_serifs = 0;
579
      int      has_serifs = 0;
442
580
443
581
Lines 449-455 Link Here
449
587
450
      /* we begin by aligning all stems relative to the blue zone */
588
      /* we begin by aligning all stems relative to the blue zone */
451
      /* if needed -- that's only for horizontal edges            */
589
      /* if needed -- that's only for horizontal edges            */
452
      if ( dimension )
590
      if ( dimension && hinter->do_blue_hints )
453
      {
591
      {
454
        for ( edge = edges; edge < edge_limit; edge++ )
592
        for ( edge = edges; edge < edge_limit; edge++ )
455
        {
593
        {
Lines 486-499 Link Here
486
            ah_align_linked_edge( hinter, edge1, edge2, dimension );
624
            ah_align_linked_edge( hinter, edge1, edge2, dimension );
487
            edge2->flags |= AH_EDGE_DONE;
625
            edge2->flags |= AH_EDGE_DONE;
488
          }
626
          }
489
490
          if ( !anchor )
491
            anchor = edge;
492
        }
627
        }
493
      }
628
      }
494
629
495
      /* now we will align all stem edges, trying to maintain the */
630
      /* now we will align all stem edges. */
496
      /* relative order of stems in the glyph                     */
497
      for ( edge = edges; edge < edge_limit; edge++ )
631
      for ( edge = edges; edge < edge_limit; edge++ )
498
      {
632
      {
499
        AH_EdgeRec*  edge2;
633
        AH_EdgeRec*  edge2;
Lines 520-525 Link Here
520
          continue;
654
          continue;
521
        }
655
        }
522
656
657
#if 0
523
        if ( !anchor )
658
        if ( !anchor )
524
        {
659
        {
525
660
Lines 686-691 Link Here
686
          if ( edge > edges && edge->pos < edge[-1].pos )
821
          if ( edge > edges && edge->pos < edge[-1].pos )
687
            edge->pos = edge[-1].pos;
822
            edge->pos = edge[-1].pos;
688
        }
823
        }
824
#else /* 1 */
825
826
        if ( !dimension && !anchor )
827
        {
828
          if ( hinter->globals->is_fixedpitch && !hinter->composite )
829
          {
830
            AH_Edge     left  = edge;
831
            AH_Edge     right = edge_limit - 1;
832
            AH_EdgeRec  left1, left2, right1, right2;
833
            FT_Pos      target, center1, center2;
834
            FT_Pos      delta1, delta2, d1, d2;
835
836
837
            while ( right > left && !right->link )
838
              right--;
839
840
            left1  = *left;
841
            left2  = *left->link;
842
            right1 = *right->link;
843
            right2 = *right;
844
845
            delta  = ( ( ( hinter->pp2.x + 32 ) & -64 ) - hinter->pp2.x )/2;
846
            target = left->opos + ( right->opos - left->opos )/2 + delta - 16;
847
848
            delta1  = delta;
849
            delta1 += ah_hint_normal_stem( hinter, left, left->link,
850
                                           delta1, 0 );
851
852
            if ( left->link != right )
853
              ah_hint_normal_stem( hinter, right->link, right, delta1, 0 );
854
855
            center1 = left->pos + ( right->pos - left->pos )/2;
856
857
            if ( center1 >= target )
858
              delta2 = delta - 32;
859
            else
860
              delta2 = delta + 32;
861
862
            delta2 += ah_hint_normal_stem( hinter, &left1, &left2, delta2, 0 );
863
864
            if ( delta1 != delta2 )
865
            {
866
              if ( left->link != right )
867
                ah_hint_normal_stem( hinter, &right1, &right2, delta2, 0 );
868
869
              center2 = left1.pos + ( right2.pos - left1.pos )/2;
870
871
              d1 = center1 - target;
872
              d2 = center2 - target;
873
874
              if ( ABS( d2 ) < ABS( d1 ) )
875
              {
876
                left->pos       = left1.pos;
877
                left->link->pos = left2.pos;
878
879
                if ( left->link != right )
880
                {
881
                  right->link->pos = right1.pos;
882
                  right->pos       = right2.pos;
883
                }
884
885
                delta1 = delta2;
886
              }
887
            }
888
889
            delta               = delta1;
890
            right->link->flags |= AH_EDGE_DONE;
891
            right->flags       |= AH_EDGE_DONE;
892
          }
893
          else
894
          {
895
            delta = ah_hint_normal_stem( hinter, edge, edge2, 0, 0 );
896
          }
897
898
          anchor = edge;
899
        }
900
        else
901
        {
902
          ah_hint_normal_stem( hinter, edge, edge2,
903
                               delta, dimension );
904
          anchor = edge;
905
        }
906
907
        edge->flags  |= AH_EDGE_DONE;
908
        edge2->flags |= AH_EDGE_DONE;
909
910
#endif /* 1 */
689
      }
911
      }
690
912
691
      /* make sure that lowercase m's maintain their symmetry */
913
      /* make sure that lowercase m's maintain their symmetry */
Lines 704-710 Link Here
704
      /* one pixel higher or lower.                                         */
926
      /* one pixel higher or lower.                                         */
705
927
706
      n_edges = edge_limit - edges;
928
      n_edges = edge_limit - edges;
707
      if ( !dimension && ( n_edges == 6 || n_edges == 12 ) )
929
      if ( hinter->do_blue_hints &&
930
           !dimension && ( n_edges == 6 || n_edges == 12 ) )
708
      {
931
      {
709
        AH_EdgeRec  *edge1, *edge2, *edge3;
932
        AH_EdgeRec  *edge1, *edge2, *edge3;
710
        FT_Pos       dist1, dist2, span, delta;
933
        FT_Pos       dist1, dist2, span, delta;
Lines 730-736 Link Here
730
        if ( span < 0 )
953
        if ( span < 0 )
731
          span = -span;
954
          span = -span;
732
955
733
        if ( span < 8 )
956
        if ( edge1->link == edge1 + 1 &&
957
             edge2->link == edge2 + 1 &&
958
             edge3->link == edge3 + 1 && span < 8 )
734
        {
959
        {
735
          delta = edge3->pos - ( 2 * edge2->pos - edge1->pos );
960
          delta = edge3->pos - ( 2 * edge2->pos - edge1->pos );
736
          edge3->pos -= delta;
961
          edge3->pos -= delta;
Lines 761-785 Link Here
761
          continue;
986
          continue;
762
987
763
        if ( edge->serif )
988
        if ( edge->serif )
764
          ah_align_serif_edge( hinter, edge->serif, edge, dimension );
765
        else if ( !anchor )
766
        {
989
        {
767
          edge->pos = ( edge->opos + 32 ) & -64;
990
          ah_align_serif_edge( hinter, edge->serif, edge, dimension );
768
          anchor    = edge;
991
          edge->flags |= AH_EDGE_DONE;
992
          has_serifs--;
769
        }
993
        }
770
        else
994
      }
771
          edge->pos = anchor->pos +
995
772
                      ( ( edge->opos-anchor->opos + 32 ) & -64 );
996
      if ( !has_serifs )
997
        goto Next_Dimension;
998
999
      for ( edge = edges; edge < edge_limit; edge++ )
1000
      {
1001
        AH_Edge  before, after;
773
1002
774
        edge->flags |= AH_EDGE_DONE;
775
1003
776
        if ( edge > edges && edge->pos < edge[-1].pos )
1004
        if ( edge->flags & AH_EDGE_DONE )
777
          edge->pos = edge[-1].pos;
1005
          continue;
1006
1007
        before = after = edge;
1008
1009
        while ( --before >= edges )
1010
          if ( before->flags & AH_EDGE_DONE )
1011
            break;
1012
1013
        while ( ++after < edge_limit )
1014
          if ( after->flags & AH_EDGE_DONE )
1015
            break;
1016
1017
        if ( before >= edges || after < edge_limit )
1018
        {
1019
          if ( before < edges )
1020
            edge->pos = edge->opos + ( after->pos - after->opos );
1021
1022
          else if ( after >= edge_limit )
1023
            edge->pos = edge->opos + ( before->pos - before->opos );
778
1024
779
        if ( edge + 1 < edge_limit        &&
1025
          else
780
             edge[1].flags & AH_EDGE_DONE &&
1026
            edge->pos = before->pos +
781
             edge->pos > edge[1].pos      )
1027
                        FT_MulDiv( edge->fpos - before->fpos,
782
          edge->pos = edge[1].pos;
1028
                                   after->pos - before->pos,
1029
                                   after->fpos - before->fpos );
1030
        }
783
      }
1031
      }
784
1032
785
    Next_Dimension:
1033
    Next_Dimension:
Lines 806-815 Link Here
806
    AH_Edge     edges;
1054
    AH_Edge     edges;
807
    AH_Edge     edge_limit;
1055
    AH_Edge     edge_limit;
808
    FT_Int      dimension;
1056
    FT_Int      dimension;
1057
    FT_Bool     snapping;
809
1058
810
1059
811
    edges      = outline->horz_edges;
1060
    edges      = outline->horz_edges;
812
    edge_limit = edges + outline->num_hedges;
1061
    edge_limit = edges + outline->num_hedges;
1062
    snapping   = hinter->do_vert_snapping;
813
1063
814
    for ( dimension = 1; dimension >= 0; dimension-- )
1064
    for ( dimension = 1; dimension >= 0; dimension-- )
815
    {
1065
    {
Lines 821-827 Link Here
821
      {
1071
      {
822
        /* move the points of each segment     */
1072
        /* move the points of each segment     */
823
        /* in each edge to the edge's position */
1073
        /* in each edge to the edge's position */
824
        AH_Segment  seg = edge->first;
1074
        AH_Segment  seg   = edge->first;
1075
        FT_Pos      delta = edge->pos - edge->opos;
825
1076
826
1077
827
        do
1078
        do
Lines 829-851 Link Here
829
          AH_Point  point = seg->first;
1080
          AH_Point  point = seg->first;
830
1081
831
1082
832
          for (;;)
1083
          if ( snapping )
833
          {
1084
          {
834
            if ( dimension )
1085
            for (;;)
835
            {
1086
            {
836
              point->y      = edge->pos;
1087
              if ( dimension )
837
              point->flags |= AH_FLAG_TOUCH_Y;
1088
              {
1089
                point->y      = edge->pos;
1090
                point->flags |= AH_FLAG_TOUCH_Y;
1091
              }
1092
              else
1093
              {
1094
                point->x      = edge->pos;
1095
                point->flags |= AH_FLAG_TOUCH_X;
1096
              }
1097
1098
              if ( point == seg->last )
1099
                break;
1100
1101
              point = point->next;
838
            }
1102
            }
839
            else
1103
          }
1104
          else
1105
          {
1106
            for (;;)
840
            {
1107
            {
841
              point->x      = edge->pos;
1108
              if ( dimension )
842
              point->flags |= AH_FLAG_TOUCH_X;
1109
              {
843
            }
1110
                point->y     += delta;
1111
                point->flags |= AH_FLAG_TOUCH_Y;
1112
              }
1113
              else
1114
              {
1115
                point->x     += delta;
1116
                point->flags |= AH_FLAG_TOUCH_X;
1117
              }
844
1118
845
            if ( point == seg->last )
1119
              if ( point == seg->last )
846
              break;
1120
                break;
847
1121
848
            point = point->next;
1122
              point = point->next;
1123
            }
849
          }
1124
          }
850
1125
851
          seg = seg->edge_next;
1126
          seg = seg->edge_next;
Lines 855-860 Link Here
855
1130
856
      edges      = outline->vert_edges;
1131
      edges      = outline->vert_edges;
857
      edge_limit = edges + outline->num_vedges;
1132
      edge_limit = edges + outline->num_vedges;
1133
      snapping   = hinter->do_horz_snapping;
858
    }
1134
    }
859
  }
1135
  }
860
1136
Lines 871-876 Link Here
871
    AH_Point    points;
1147
    AH_Point    points;
872
    AH_Point    point_limit;
1148
    AH_Point    point_limit;
873
    AH_Flags    touch_flag;
1149
    AH_Flags    touch_flag;
1150
    AH_Flags    strong_flag;
874
1151
875
1152
876
    points      = outline->points;
1153
    points      = outline->points;
Lines 879-884 Link Here
879
    edges       = outline->horz_edges;
1156
    edges       = outline->horz_edges;
880
    edge_limit  = edges + outline->num_hedges;
1157
    edge_limit  = edges + outline->num_hedges;
881
    touch_flag  = AH_FLAG_TOUCH_Y;
1158
    touch_flag  = AH_FLAG_TOUCH_Y;
1159
    strong_flag = AH_FLAG_STRONG_Y;
882
1160
883
    for ( dimension = 1; dimension >= 0; dimension-- )
1161
    for ( dimension = 1; dimension >= 0; dimension-- )
884
    {
1162
    {
Lines 899-906 Link Here
899
#ifndef AH_OPTION_NO_WEAK_INTERPOLATION
1177
#ifndef AH_OPTION_NO_WEAK_INTERPOLATION
900
          /* if this point is candidate to weak interpolation, we will  */
1178
          /* if this point is candidate to weak interpolation, we will  */
901
          /* interpolate it after all strong points have been processed */
1179
          /* interpolate it after all strong points have been processed */
902
          if (  ( point->flags & AH_FLAG_WEAK_INTERPOLATION ) &&
1180
          if ( !( point->flags & strong_flag ) )
903
               !( point->flags & AH_FLAG_INFLECTION )         )
904
            continue;
1181
            continue;
905
#endif
1182
#endif
906
1183
Lines 1034-1039 Link Here
1034
      edges      = outline->vert_edges;
1311
      edges      = outline->vert_edges;
1035
      edge_limit = edges + outline->num_vedges;
1312
      edge_limit = edges + outline->num_vedges;
1036
      touch_flag = AH_FLAG_TOUCH_X;
1313
      touch_flag = AH_FLAG_TOUCH_X;
1314
      strong_flag = AH_FLAG_STRONG_X;
1037
    }
1315
    }
1038
  }
1316
  }
1039
1317
Lines 1234-1243 Link Here
1234
1512
1235
1513
1236
  FT_LOCAL_DEF( void )
1514
  FT_LOCAL_DEF( void )
1237
  ah_hinter_align_points( AH_Hinter  hinter )
1515
  ah_hinter_align_normal_points( AH_Hinter  hinter )
1238
  {
1516
  {
1239
    ah_hinter_align_edge_points( hinter );
1240
1241
#ifndef AH_OPTION_NO_STRONG_INTERPOLATION
1517
#ifndef AH_OPTION_NO_STRONG_INTERPOLATION
1242
    ah_hinter_align_strong_points( hinter );
1518
    ah_hinter_align_strong_points( hinter );
1243
#endif
1519
#endif
Lines 1263-1279 Link Here
1263
  static void
1539
  static void
1264
  ah_hinter_scale_globals( AH_Hinter  hinter,
1540
  ah_hinter_scale_globals( AH_Hinter  hinter,
1265
                           FT_Fixed   x_scale,
1541
                           FT_Fixed   x_scale,
1266
                           FT_Fixed   y_scale )
1542
                           FT_Fixed   y_scale,
1543
                           FT_Byte    type )
1267
  {
1544
  {
1268
    FT_Int           n;
1545
    FT_Int           n;
1269
    AH_Face_Globals  globals = hinter->globals;
1546
    AH_Face_Globals  globals = hinter->globals;
1270
    AH_Globals       design  = &globals->design;
1547
    AH_Globals       design  = &globals->designs[type];
1271
    AH_Globals       scaled  = &globals->scaled;
1548
    AH_Globals       scaled  = &globals->scaled;
1549
    FT_Pos           baseline = design->baseline;
1550
1272
1551
1552
    globals->x_scale_linear = x_scale;
1553
    globals->y_scale_linear = y_scale;
1554
    globals->cur_type       = type;
1273
1555
1274
    /* copy content */
1556
    /* copy content */
1275
    *scaled = *design;
1557
    *scaled = *design;
1276
1558
1559
#ifdef FT_CONFIG_CHESTER_BLUE_SCALE
1560
1561
   /* try to optimize the y_scale so that the top of non-capital letters
1562
    * is aligned on a pixel boundary whenever possible
1563
    */
1564
    if ( design->has_blues )
1565
    {
1566
      FT_Pos  shoot = design->blue_shoots[AH_BLUE_SMALL_TOP];
1567
      FT_Pos  ref   = design->blue_refs[AH_BLUE_SMALL_TOP];
1568
1569
1570
      baseline = FT_MulFix( baseline, y_scale );
1571
1572
      /* the value of 'shoot' will be -1000 if the font doesn't have */
1573
      /* small latin letters; we simply check the sign here...       */
1574
      if ( shoot > 0 )
1575
      {
1576
        FT_Pos  fitted;
1577
1578
1579
        shoot = FT_MulFix( shoot, y_scale );
1580
        ref   = FT_MulFix( ref,   y_scale );
1581
1582
        if ( shoot < 6*64 )
1583
          fitted = ( shoot + 44 ) & -64;
1584
        else if ( shoot < 8*64 )
1585
          fitted = ( shoot + 38 ) & -64;
1586
        else
1587
          fitted = ( shoot + 32 ) & -64;
1588
1589
1590
        if ( ref <= fitted && fitted < shoot )
1591
          fitted = shoot;
1592
        else if ( fitted < ref )
1593
          shoot = ref;
1594
1595
        if ( fitted > shoot )
1596
        {
1597
          y_scale   = FT_MulDiv( y_scale, fitted, shoot );
1598
          baseline -= ( fitted - shoot )/2;
1599
        }
1600
      }
1601
    }
1602
1603
#endif /* FT_CONFIG_CHESTER_BLUE_SCALE */
1604
1277
    /* scale the standard widths & heights */
1605
    /* scale the standard widths & heights */
1278
    for ( n = 0; n < design->num_widths; n++ )
1606
    for ( n = 0; n < design->num_widths; n++ )
1279
      scaled->widths[n] = FT_MulFix( design->widths[n], x_scale );
1607
      scaled->widths[n] = FT_MulFix( design->widths[n], x_scale );
Lines 1284-1293 Link Here
1284
    scaled->stds[0] = ( design->num_widths  > 0 ) ? scaled->widths[0]  : 32000;
1612
    scaled->stds[0] = ( design->num_widths  > 0 ) ? scaled->widths[0]  : 32000;
1285
    scaled->stds[1] = ( design->num_heights > 0 ) ? scaled->heights[0] : 32000;
1613
    scaled->stds[1] = ( design->num_heights > 0 ) ? scaled->heights[0] : 32000;
1286
1614
1615
    globals->x_scale = x_scale;
1616
    globals->y_scale = y_scale;
1617
1618
    if ( !design->has_blues )
1619
      return;
1620
1621
1622
    scaled->baseline = ( baseline + 32 ) & -64;
1623
1287
    /* scale the blue zones */
1624
    /* scale the blue zones */
1288
    for ( n = 0; n < AH_BLUE_MAX; n++ )
1625
    for ( n = 0; n < AH_BLUE_MAX; n++ )
1289
    {
1626
    {
1290
      FT_Pos  delta, delta2;
1627
      FT_Pos  delta, delta2;
1628
      FT_Pos  ref, shoot, delta3, delta4;
1291
1629
1292
1630
1293
      delta = design->blue_shoots[n] - design->blue_refs[n];
1631
      delta = design->blue_shoots[n] - design->blue_refs[n];
Lines 1306-1318 Link Here
1306
      if ( delta < 0 )
1644
      if ( delta < 0 )
1307
        delta2 = -delta2;
1645
        delta2 = -delta2;
1308
1646
1309
      scaled->blue_refs[n] =
1647
      if ( n == AH_BLUE_SMALL_BOTTOM )
1310
        ( FT_MulFix( design->blue_refs[n], y_scale ) + 32 ) & -64;
1648
      {
1311
      scaled->blue_shoots[n] = scaled->blue_refs[n] + delta2;
1649
        scaled->blue_shoots[n] = delta2;
1312
    }
1650
        scaled->blue_refs[n]   = 0;
1651
        continue;
1652
      }
1313
1653
1314
    globals->x_scale = x_scale;
1654
      shoot  = FT_MulFix( design->blue_shoots[n], y_scale );
1315
    globals->y_scale = y_scale;
1655
      ref    = FT_MulFix( design->blue_refs[n],   y_scale );
1656
      delta3 = ( ( shoot + 32 ) & -64 ) - shoot;
1657
      delta4 = ( ( ref   + 32 ) & -64 ) - ref;
1658
1659
      if ( !hinter->do_stem_adjust )
1660
      {
1661
        if ( delta3 >  16 ) delta3 =  16;
1662
        if ( delta3 < -16 ) delta3 = -16;
1663
        if ( delta4 >  16 ) delta4 =  16;
1664
        if ( delta4 < -16 ) delta4 = -16;
1665
      }
1666
1667
      shoot += delta3;
1668
      ref   += delta4;
1669
1670
      if ( ABS( delta3 ) < ABS( delta4 ) )
1671
        ref = shoot - delta2;
1672
      else
1673
        shoot = ref + delta2;
1674
1675
      scaled->blue_refs[n]   = ref;
1676
      scaled->blue_shoots[n] = shoot;
1677
    }
1316
  }
1678
  }
1317
1679
1318
1680
Lines 1320-1326 Link Here
1320
  ah_hinter_align( AH_Hinter  hinter )
1682
  ah_hinter_align( AH_Hinter  hinter )
1321
  {
1683
  {
1322
    ah_hinter_align_edge_points( hinter );
1684
    ah_hinter_align_edge_points( hinter );
1323
    ah_hinter_align_points( hinter );
1685
    ah_hinter_align_normal_points( hinter );
1324
  }
1686
  }
1325
1687
1326
1688
Lines 1401-1407 Link Here
1401
    hinter->globals = face_globals;
1763
    hinter->globals = face_globals;
1402
1764
1403
    if ( globals )
1765
    if ( globals )
1404
      face_globals->design = *globals;
1766
      face_globals->designs[0] = *globals;
1405
    else
1767
    else
1406
      ah_hinter_compute_globals( hinter );
1768
      ah_hinter_compute_globals( hinter );
1407
1769
Lines 1410-1415 Link Here
1410
                                 ah_hinter_done_face_globals;
1772
                                 ah_hinter_done_face_globals;
1411
    face_globals->face       = face;
1773
    face_globals->face       = face;
1412
1774
1775
    ah_hinter_compute_char_table( hinter );
1776
1777
    {
1778
      TT_OS2*  os2 = FT_Get_Sfnt_Table( face, ft_sfnt_os2 );
1779
1780
1781
      if ( os2 && os2->version != 0xFFFFU )
1782
        face_globals->is_fixedpitch = FT_BOOL( os2->panose[3] == 9 );
1783
      else
1784
        face_globals->is_fixedpitch = FT_BOOL( FT_IS_FIXED_WIDTH( face ) != 0 );
1785
1786
1787
      face_globals->has_tt_bytecode_interp = FALSE;
1788
1789
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
1790
      if ( !strcmp( face->driver->root.clazz->module_name, "truetype" ) ||
1791
           !strcmp( face->driver->root.clazz->module_name, "type42"   ) )
1792
        face_globals->has_tt_bytecode_interp = TRUE;
1793
#endif
1794
    }
1795
1413
  Exit:
1796
  Exit:
1414
    return error;
1797
    return error;
1415
  }
1798
  }
Lines 1423-1428 Link Here
1423
    FT_Memory  memory = face->memory;
1806
    FT_Memory  memory = face->memory;
1424
1807
1425
1808
1809
    FT_Done_Size( globals->size_EM );
1810
    FT_FREE( globals->table );
1426
    FT_FREE( globals );
1811
    FT_FREE( globals );
1427
  }
1812
  }
1428
1813
Lines 1441-1452 Link Here
1441
    FT_Error          error;
1826
    FT_Error          error;
1442
    AH_Outline        outline  = hinter->glyph;
1827
    AH_Outline        outline  = hinter->glyph;
1443
    AH_Loader         gloader  = hinter->loader;
1828
    AH_Loader         gloader  = hinter->loader;
1829
    FT_Pos            baseline = 0;
1830
    FT_Byte           type     = hinter->globals->cur_type;
1444
1831
1445
1832
1446
    /* load the glyph */
1833
    /* load the glyph */
1447
    error = FT_Load_Glyph( face, glyph_index, load_flags );
1834
    if ( !hinter->globals->has_tt_bytecode_interp )
1448
    if ( error )
1835
    {
1449
      goto Exit;
1836
      error = FT_Load_Glyph( face, glyph_index, load_flags );
1837
      if ( error )
1838
        goto Exit;
1839
    }
1450
1840
1451
    /* Set `hinter->transformed' after loading with FT_LOAD_NO_RECURSE. */
1841
    /* Set `hinter->transformed' after loading with FT_LOAD_NO_RECURSE. */
1452
    hinter->transformed = internal->glyph_transformed;
1842
    hinter->transformed = internal->glyph_transformed;
Lines 1463-1468 Link Here
1463
      FT_Matrix_Invert( &imatrix );
1853
      FT_Matrix_Invert( &imatrix );
1464
      FT_Vector_Transform( &hinter->trans_delta, &imatrix );
1854
      FT_Vector_Transform( &hinter->trans_delta, &imatrix );
1465
    }
1855
    }
1856
    else
1857
    {
1858
      hinter->trans_delta.x = 0;
1859
      hinter->trans_delta.y = 0;
1860
    }
1466
1861
1467
    /* set linear horizontal metrics */
1862
    /* set linear horizontal metrics */
1468
    slot->linearHoriAdvance = slot->metrics.horiAdvance;
1863
    slot->linearHoriAdvance = slot->metrics.horiAdvance;
Lines 1472-1488 Link Here
1472
    {
1867
    {
1473
    case FT_GLYPH_FORMAT_OUTLINE:
1868
    case FT_GLYPH_FORMAT_OUTLINE:
1474
1869
1870
      if ( hinter->do_blue_hints )
1871
        baseline = hinter->globals->designs[type].baseline;
1872
1475
      /* translate glyph outline if we need to */
1873
      /* translate glyph outline if we need to */
1476
      if ( hinter->transformed )
1874
      if ( hinter->transformed || baseline != 0 )
1477
      {
1875
      {
1478
        FT_UInt     n     = slot->outline.n_points;
1876
        FT_UInt     n     = slot->outline.n_points;
1479
        FT_Vector*  point = slot->outline.points;
1877
        FT_Vector*  point = slot->outline.points;
1878
        FT_Pos      x_off = hinter->trans_delta.x;
1879
        FT_Pos      y_off = hinter->trans_delta.y - baseline;
1480
1880
1481
1881
1482
        for ( ; n > 0; point++, n-- )
1882
        for ( ; n > 0; point++, n-- )
1483
        {
1883
        {
1484
          point->x += hinter->trans_delta.x;
1884
          point->x += x_off;
1485
          point->y += hinter->trans_delta.y;
1885
          point->y += y_off;
1486
        }
1886
        }
1487
      }
1887
      }
1488
1888
Lines 1524-1530 Link Here
1524
      /* perform feature detection */
1924
      /* perform feature detection */
1525
      ah_outline_detect_features( outline );
1925
      ah_outline_detect_features( outline );
1526
1926
1527
      if ( hinter->do_vert_hints )
1927
      if ( hinter->do_blue_hints )
1528
      {
1928
      {
1529
        ah_outline_compute_blue_edges( outline, hinter->globals );
1929
        ah_outline_compute_blue_edges( outline, hinter->globals );
1530
        ah_outline_scale_blue_edges( outline, hinter->globals );
1930
        ah_outline_scale_blue_edges( outline, hinter->globals );
Lines 1539-1544 Link Here
1539
1939
1540
      /* we now need to hint the metrics according to the change in */
1940
      /* we now need to hint the metrics according to the change in */
1541
      /* width/positioning that occured during the hinting process  */
1941
      /* width/positioning that occured during the hinting process  */
1942
      if ( !hinter->globals->is_fixedpitch && !hinter->composite &&
1943
           type <= AH_CHAR_TYPE_HORIZONTAL )
1542
      {
1944
      {
1543
        FT_Pos   old_advance, old_rsb, old_lsb, new_lsb;
1945
        FT_Pos   old_advance, old_rsb, old_lsb, new_lsb;
1544
        AH_Edge  edge1 = outline->vert_edges;     /* leftmost edge  */
1946
        AH_Edge  edge1 = outline->vert_edges;     /* leftmost edge  */
Lines 1551-1558 Link Here
1551
        old_lsb     = edge1->opos;
1953
        old_lsb     = edge1->opos;
1552
        new_lsb     = edge1->pos;
1954
        new_lsb     = edge1->pos;
1553
1955
1554
        hinter->pp1.x = ( ( new_lsb    - old_lsb ) + 32 ) & -64;
1956
        hinter->pp1.x = ( ( new_lsb - old_lsb ) + 32 ) & -64;
1555
        hinter->pp2.x = ( ( edge2->pos + old_rsb ) + 32 ) & -64;
1957
        hinter->pp2.x = ( ( edge2->pos + old_rsb ) + 40 ) & -64;
1556
1958
1557
#if 0
1959
#if 0
1558
        /* try to fix certain bad advance computations */
1960
        /* try to fix certain bad advance computations */
Lines 1705-1710 Link Here
1705
      FT_BBox  bbox;
2107
      FT_BBox  bbox;
1706
2108
1707
2109
2110
      if ( hinter->do_blue_hints )
2111
      {
2112
        if ( hinter->globals->scaled.baseline != 0 )
2113
          FT_Outline_Translate( &gloader->base.outline,
2114
                                0, hinter->globals->scaled.baseline );
2115
      }
2116
1708
      /* transform the hinted outline if needed */
2117
      /* transform the hinted outline if needed */
1709
      if ( hinter->transformed )
2118
      if ( hinter->transformed )
1710
        FT_Outline_Transform( &gloader->base.outline, &hinter->trans_matrix );
2119
        FT_Outline_Transform( &gloader->base.outline, &hinter->trans_matrix );
Lines 1725-1738 Link Here
1725
      slot->metrics.horiBearingX = bbox.xMin;
2134
      slot->metrics.horiBearingX = bbox.xMin;
1726
      slot->metrics.horiBearingY = bbox.yMax;
2135
      slot->metrics.horiBearingY = bbox.yMax;
1727
2136
1728
      /* for mono-width fonts (like Andale, Courier, etc.) we need */
2137
      slot->metrics.horiAdvance = hinter->pp2.x - hinter->pp1.x;
1729
      /* to keep the original rounded advance width                */
1730
      if ( !FT_IS_FIXED_WIDTH( slot->face ) )
1731
        slot->metrics.horiAdvance = hinter->pp2.x - hinter->pp1.x;
1732
      else
1733
        slot->metrics.horiAdvance = FT_MulFix( slot->metrics.horiAdvance,
1734
                                               x_scale );
1735
1736
      slot->metrics.horiAdvance = ( slot->metrics.horiAdvance + 32 ) & -64;
2138
      slot->metrics.horiAdvance = ( slot->metrics.horiAdvance + 32 ) & -64;
1737
2139
1738
      /* now copy outline into glyph slot */
2140
      /* now copy outline into glyph slot */
Lines 1754-1759 Link Here
1754
  }
2156
  }
1755
2157
1756
2158
2159
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
2160
2161
#define AH_MAX_COMPOSITE_RECURSE 5
2162
2163
  static FT_Error
2164
  ah_hinter_load_truetype( AH_Hinter  hinter,
2165
                           FT_UInt    glyph_index,
2166
                           FT_Int32   load_flags,
2167
                           int        depth,
2168
                           short    **num_contours,
2169
                           short    **num_points,
2170
                           int       *num_simple_glyphs,
2171
                           int       *size_array )
2172
  {
2173
    FT_Face        face   = hinter->face;
2174
    FT_Memory      memory = hinter->memory;
2175
    FT_GlyphSlot   slot   = face->glyph;
2176
    FT_Error       error  = FT_Err_Ok;
2177
2178
2179
    if ( depth == 0 )
2180
    {
2181
      *num_contours      = 0;
2182
      *num_points        = 0;
2183
      *num_simple_glyphs = 0;
2184
      *size_array        = 0;
2185
    }
2186
2187
    error = FT_Load_Glyph( face, glyph_index, load_flags );
2188
2189
    if ( error )
2190
      return error;
2191
2192
    switch ( slot->format )
2193
    {
2194
    case FT_GLYPH_FORMAT_OUTLINE:
2195
      {
2196
        int  size_cur = *size_array;
2197
2198
2199
        if ( depth == 0 )
2200
          return ah_hinter_load( hinter, 0, load_flags, 0 );
2201
2202
        if ( slot->outline.n_contours == 0 )
2203
          break;
2204
2205
        if ( *num_simple_glyphs >= size_cur )
2206
        {
2207
          if ( FT_RENEW_ARRAY( *num_contours, size_cur, size_cur + 16 ) ||
2208
               FT_RENEW_ARRAY( *num_points,   size_cur, size_cur + 16 ) )
2209
            goto Exit;
2210
          *size_array += 16;
2211
        }
2212
2213
        (*num_contours)[ (*num_simple_glyphs) ] = slot->outline.n_contours;
2214
        (*num_points)[ (*num_simple_glyphs)++ ] = slot->outline.n_points;
2215
        break;
2216
      }
2217
2218
    case FT_GLYPH_FORMAT_COMPOSITE:
2219
      if ( depth + 1 >= AH_MAX_COMPOSITE_RECURSE )
2220
        return AH_Err_Invalid_Composite;
2221
2222
      if ( slot->num_subglyphs > 0 )
2223
      {
2224
        FT_UInt*  indices;
2225
        int       num_subglyphs = slot->num_subglyphs;
2226
        int       i;
2227
2228
2229
        hinter->composite = TRUE;
2230
2231
        if ( FT_NEW_ARRAY( indices, num_subglyphs ) )
2232
          goto Exit;
2233
2234
        for ( i = 0; i < num_subglyphs; i++ )
2235
          indices[i] = slot->subglyphs[i].index;
2236
2237
2238
        for ( i = 0; i < num_subglyphs; i++ )
2239
        {
2240
          error = ah_hinter_load_truetype( hinter,
2241
                                           indices[i],
2242
                                           load_flags,
2243
                                           depth + 1,
2244
                                           num_contours,
2245
                                           num_points,
2246
                                           num_simple_glyphs,
2247
                                           size_array );
2248
          if ( error )
2249
          {
2250
            FT_FREE( indices );
2251
            goto Exit;
2252
          }
2253
        }
2254
2255
        FT_FREE( indices );
2256
2257
        if ( depth == 0 )
2258
        {
2259
          FT_Size      size_EM, size;
2260
          FT_Vector*   points;
2261
          FT_Vector*   limit;
2262
          int          num = *num_simple_glyphs, j;
2263
          short        n_contours, n_points;
2264
          short        *array_c, *array_p;
2265
2266
2267
          if ( num == 0 )
2268
            break;
2269
2270
          size    = face->size;
2271
          size_EM = hinter->globals->size_EM;
2272
2273
          if ( !size_EM )
2274
          {
2275
            error = FT_New_Size( face, &hinter->globals->size_EM );
2276
            if ( error )
2277
              goto Exit;
2278
2279
            size_EM = hinter->globals->size_EM;
2280
            FT_Activate_Size( size_EM );
2281
2282
            error = FT_Set_Pixel_Sizes( face,
2283
                                        face->units_per_EM,
2284
                                        face->units_per_EM );
2285
            if ( error )
2286
            {
2287
              FT_Activate_Size( size );
2288
              goto  Exit;
2289
            }
2290
          }
2291
          else
2292
            FT_Activate_Size( size_EM );
2293
2294
2295
          load_flags &= ~FT_LOAD_NO_RECURSE &
2296
                        ~FT_LOAD_NO_SCALE;
2297
          load_flags |= FT_LOAD_NO_BITMAP   |
2298
                        FT_LOAD_NO_AUTOHINT |
2299
                        FT_LOAD_IGNORE_TRANSFORM;
2300
2301
          error = FT_Load_Glyph( face, glyph_index, load_flags );
2302
2303
          FT_Activate_Size( size );
2304
2305
          if ( error )
2306
            goto Exit;
2307
2308
2309
          array_c    = *num_contours;
2310
          array_p    = *num_points;
2311
          n_contours = 0;
2312
          n_points   = 0;
2313
2314
          for ( i = 0; i < num; i++ )
2315
          {
2316
            n_contours += *array_c++;
2317
            n_points   += *array_p++;
2318
          }
2319
2320
          if ( slot->outline.n_points   != n_points ||
2321
               slot->outline.n_contours != n_contours )
2322
          {
2323
            error = AH_Err_Invalid_Composite;
2324
            goto Exit;
2325
          }
2326
2327
2328
          points = slot->outline.points;
2329
          limit  = points + slot->outline.n_points;
2330
2331
          while ( points < limit )
2332
          {
2333
            points->x >>= 6;
2334
            points->y >>= 6;
2335
            points++;
2336
          }
2337
2338
          slot->metrics.horiAdvance >>= 6;
2339
          slot->metrics.vertAdvance >>= 6;
2340
2341
          array_c = *num_contours;
2342
          array_p = *num_points;
2343
2344
          for ( i = 0; i < num - 1; i++ )
2345
          {
2346
            slot->outline.n_contours = *array_c++;
2347
            slot->outline.n_points   = *array_p++;
2348
2349
            error = ah_hinter_load( hinter, 0, load_flags, 1 );
2350
            if ( error )
2351
              goto Exit;
2352
2353
            n_points = slot->outline.n_points;
2354
            slot->outline.points   += n_points;
2355
            slot->outline.tags     += n_points;
2356
            slot->outline.contours += slot->outline.n_contours;
2357
            n_contours             -= slot->outline.n_contours;
2358
2359
            for ( j = 0; j < n_contours; j++ )
2360
              slot->outline.contours[j] -= n_points;
2361
          }
2362
2363
          slot->outline.n_contours = *array_c;
2364
          slot->outline.n_points   = *array_p;
2365
2366
          error = ah_hinter_load( hinter, 0, load_flags, 0 );
2367
        }
2368
      }
2369
      break;
2370
2371
     default:
2372
      error = AH_Err_Unimplemented_Feature;
2373
    }
2374
2375
2376
  Exit:
2377
    if ( depth == 0 )
2378
    {
2379
      FT_FREE( *num_contours );
2380
      FT_FREE( *num_points   );
2381
    }
2382
2383
    return  error;
2384
  }
2385
2386
#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
2387
2388
1757
  /* load and hint a given glyph */
2389
  /* load and hint a given glyph */
1758
  FT_LOCAL_DEF( FT_Error )
2390
  FT_LOCAL_DEF( FT_Error )
1759
  ah_hinter_load_glyph( AH_Hinter     hinter,
2391
  ah_hinter_load_glyph( AH_Hinter     hinter,
Lines 1768-1773 Link Here
1768
    FT_Fixed         y_scale      = size->metrics.y_scale;
2400
    FT_Fixed         y_scale      = size->metrics.y_scale;
1769
    AH_Face_Globals  face_globals = FACE_GLOBALS( face );
2401
    AH_Face_Globals  face_globals = FACE_GLOBALS( face );
1770
    FT_Render_Mode   hint_mode    = FT_LOAD_TARGET_MODE( load_flags );
2402
    FT_Render_Mode   hint_mode    = FT_LOAD_TARGET_MODE( load_flags );
2403
    FT_Byte          type;
1771
2404
1772
2405
1773
    /* first of all, we need to check that we're using the correct face and */
2406
    /* first of all, we need to check that we're using the correct face and */
Lines 1787-1832 Link Here
1787
2420
1788
    }
2421
    }
1789
2422
1790
#ifdef FT_CONFIG_CHESTER_BLUE_SCALE
1791
1792
   /* try to optimize the y_scale so that the top of non-capital letters
1793
    * is aligned on a pixel boundary whenever possible
1794
    */
1795
    {
1796
      AH_Globals  design = &face_globals->design;
1797
      FT_Pos      shoot  = design->blue_shoots[AH_BLUE_SMALL_TOP];
1798
1799
1800
      /* the value of 'shoot' will be -1000 if the font doesn't have */
1801
      /* small latin letters; we simply check the sign here...       */
1802
      if ( shoot > 0 )
1803
      {
1804
        FT_Pos  scaled = FT_MulFix( shoot, y_scale );
1805
        FT_Pos  fitted = ( scaled + 32 ) & -64;
1806
1807
1808
        if ( scaled != fitted )
1809
        {
1810
         /* adjust y_scale
1811
          */
1812
          y_scale = FT_MulDiv( y_scale, fitted, scaled );
1813
1814
         /* adust x_scale
1815
          */
1816
          if ( fitted < scaled )
1817
            x_scale -= x_scale / 50;  /* x_scale*0.98 with integers */
1818
        }
1819
      }
1820
    }
1821
1822
#endif /* FT_CONFIG_CHESTER_BLUE_SCALE */
1823
1824
    /* now, we must check the current character pixel size to see if we */
1825
    /* need to rescale the global metrics                               */
1826
    if ( face_globals->x_scale != x_scale ||
1827
         face_globals->y_scale != y_scale )
1828
      ah_hinter_scale_globals( hinter, x_scale, y_scale );
1829
1830
    ah_loader_rewind( hinter->loader );
2423
    ah_loader_rewind( hinter->loader );
1831
2424
1832
    /* reset hinting flags according to load flags and current render target */
2425
    /* reset hinting flags according to load flags and current render target */
Lines 1850-1860 Link Here
1850
2443
1851
    hinter->do_stem_adjust   = FT_BOOL( hint_mode != FT_RENDER_MODE_LIGHT );
2444
    hinter->do_stem_adjust   = FT_BOOL( hint_mode != FT_RENDER_MODE_LIGHT );
1852
2445
2446
    type = ah_hinter_get_char_type( hinter, glyph_index );
2447
2448
    hinter->do_blue_hints = face_globals->designs[type].has_blues;
2449
    hinter->composite     = FALSE;
2450
2451
    /* now, we must check the current character pixel size to see if we */
2452
    /* need to rescale the global metrics                               */
2453
    if ( face_globals->x_scale_linear != x_scale ||
2454
         face_globals->y_scale_linear != y_scale ||
2455
         face_globals->cur_type       != type    )
2456
      ah_hinter_scale_globals( hinter, x_scale, y_scale, type );
2457
1853
2458
1854
    load_flags  |= FT_LOAD_NO_SCALE
2459
    load_flags  |= FT_LOAD_NO_SCALE
1855
                 | FT_LOAD_IGNORE_TRANSFORM ;
2460
                 | FT_LOAD_IGNORE_TRANSFORM ;
1856
2461
1857
    error = ah_hinter_load( hinter, glyph_index, load_flags, 0 );
2462
#ifndef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
2463
2464
     error = ah_hinter_load( hinter, glyph_index, load_flags, 0 );
2465
2466
#else
2467
2468
    if ( face_globals->has_tt_bytecode_interp )
2469
    {
2470
      short*  num_contours;
2471
      short*  num_points;
2472
      int     num_simple_glyphs;
2473
      int     size_array;
2474
2475
2476
      load_flags |= FT_LOAD_NO_RECURSE;
2477
2478
      error = ah_hinter_load_truetype( hinter,
2479
                                       glyph_index,
2480
                                       load_flags,
2481
                                       0,
2482
                                       &num_contours,
2483
                                       &num_points,
2484
                                       &num_simple_glyphs,
2485
                                       &size_array );
2486
    }
2487
    else
2488
      error = ah_hinter_load( hinter, glyph_index, load_flags, 0 );
2489
2490
#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
1858
2491
1859
  Exit:
2492
  Exit:
1860
    return error;
2493
    return error;
Lines 1885-1891 Link Here
1885
        goto Fail;
2518
        goto Fail;
1886
    }
2519
    }
1887
2520
1888
    *globals      = FACE_GLOBALS( face )->design;
2521
    *globals      = FACE_GLOBALS( face )->designs[0];
1889
    *global_hints = globals;
2522
    *global_hints = globals;
1890
    *global_len   = sizeof( *globals );
2523
    *global_len   = sizeof( *globals );
1891
2524
(-)freetype-2.1.5-orig/src/autohint/ahtypes.h (-2 / +53 lines)
Lines 138-143 Link Here
138
  /* weak interpolation */
138
  /* weak interpolation */
139
#define AH_FLAG_WEAK_INTERPOLATION  256
139
#define AH_FLAG_WEAK_INTERPOLATION  256
140
#define AH_FLAG_INFLECTION          512
140
#define AH_FLAG_INFLECTION          512
141
#define AH_FLAG_STRONG_X           1024
142
#define AH_FLAG_STRONG_Y           2048
141
143
142
  typedef FT_Int AH_Flags;
144
  typedef FT_Int AH_Flags;
143
145
Lines 264-270 Link Here
264
    AH_Segment     link;        /* link segment               */
266
    AH_Segment     link;        /* link segment               */
265
    AH_Segment     serif;       /* primary segment for serifs */
267
    AH_Segment     serif;       /* primary segment for serifs */
266
    FT_Pos         num_linked;  /* number of linked segments  */
268
    FT_Pos         num_linked;  /* number of linked segments  */
267
    FT_Pos         score;
269
    FT_Pos         score1;
270
    FT_Pos         score2;
271
    FT_Pos         length;
272
    FT_Int         sign;
268
273
269
    AH_Point       first;       /* first point in edge segment             */
274
    AH_Point       first;       /* first point in edge segment             */
270
    AH_Point       last;        /* last point in edge segment              */
275
    AH_Point       last;        /* last point in edge segment              */
Lines 402-407 Link Here
402
  typedef FT_Int  AH_Hinter_Flags;
407
  typedef FT_Int  AH_Hinter_Flags;
403
408
404
409
410
#define AH_LIGHT_MODE_MAX_HORZ_GAP      9
411
#define AH_LIGHT_MODE_MAX_VERT_GAP     15
412
#define AH_LIGHT_MODE_MAX_DELTA_ABS    14
413
414
  enum
415
  {
416
    AH_CHAR_TYPE_LATINATE = 0,
417
    AH_CHAR_TYPE_LATIN_FULLWIDTH,
418
    AH_CHAR_TYPE_HORIZONTAL,
419
    AH_CHAR_TYPE_OTHER,
420
    AH_CHAR_TYPE_COUNT
421
  };
422
423
424
  typedef struct AH_CharType_
425
  {
426
    FT_Byte    type;
427
    FT_ULong   start;
428
    FT_ULong   last;
429
430
  } AH_CharType;
431
432
433
  typedef struct AH_CharTypeTable_
434
  {
435
    FT_ULong       size;
436
    AH_CharType*   types;
437
438
  } AH_CharTypeTable;
439
440
405
  /*************************************************************************/
441
  /*************************************************************************/
406
  /*                                                                       */
442
  /*                                                                       */
407
  /* <Struct>                                                              */
443
  /* <Struct>                                                              */
Lines 440-445 Link Here
440
    FT_Pos  blue_refs  [AH_BLUE_MAX];
476
    FT_Pos  blue_refs  [AH_BLUE_MAX];
441
    FT_Pos  blue_shoots[AH_BLUE_MAX];
477
    FT_Pos  blue_shoots[AH_BLUE_MAX];
442
478
479
    FT_Pos  baseline;
480
481
    FT_Bool  has_blues;
482
443
  } AH_GlobalsRec, *AH_Globals;
483
  } AH_GlobalsRec, *AH_Globals;
444
484
445
485
Lines 470-481 Link Here
470
  typedef struct  AH_Face_GlobalsRec_
510
  typedef struct  AH_Face_GlobalsRec_
471
  {
511
  {
472
    FT_Face        face;
512
    FT_Face        face;
473
    AH_GlobalsRec  design;
513
    AH_GlobalsRec  designs[AH_CHAR_TYPE_COUNT];
474
    AH_GlobalsRec  scaled;
514
    AH_GlobalsRec  scaled;
475
    FT_Fixed       x_scale;
515
    FT_Fixed       x_scale;
476
    FT_Fixed       y_scale;
516
    FT_Fixed       y_scale;
477
    FT_Bool        control_overshoot;
517
    FT_Bool        control_overshoot;
478
518
519
    FT_Fixed       x_scale_linear;
520
    FT_Fixed       y_scale_linear;
521
522
    AH_CharTypeTable*  table;
523
    FT_Byte            cur_type;
524
    FT_Size            size_EM;
525
    FT_Bool            is_fixedpitch;
526
    FT_Bool            has_tt_bytecode_interp;
527
479
  } AH_Face_GlobalsRec, *AH_Face_Globals;
528
  } AH_Face_GlobalsRec, *AH_Face_Globals;
480
529
481
530
Lines 494-499 Link Here
494
    AH_Loader        loader;
543
    AH_Loader        loader;
495
    FT_Vector        pp1;
544
    FT_Vector        pp1;
496
    FT_Vector        pp2;
545
    FT_Vector        pp2;
546
    FT_Bool          composite;
497
547
498
    FT_Bool          transformed;
548
    FT_Bool          transformed;
499
    FT_Vector        trans_delta;
549
    FT_Vector        trans_delta;
Lines 504-509 Link Here
504
    FT_Bool          do_horz_snapping;  /* disable X stem size snapping */
554
    FT_Bool          do_horz_snapping;  /* disable X stem size snapping */
505
    FT_Bool          do_vert_snapping;  /* disable Y stem size snapping */
555
    FT_Bool          do_vert_snapping;  /* disable Y stem size snapping */
506
    FT_Bool          do_stem_adjust;    /* disable light stem snapping  */
556
    FT_Bool          do_stem_adjust;    /* disable light stem snapping  */
557
    FT_Bool          do_blue_hints;     /* disable blue hinting         */
507
558
508
  } AH_HinterRec, *AH_Hinter;
559
  } AH_HinterRec, *AH_Hinter;
509
560
(-)freetype-2.1.5-orig/src/autohint/autohint.c (-1 lines)
Lines 22-28 Link Here
22
#define FT_MAKE_OPTION_SINGLE_OBJECT
22
#define FT_MAKE_OPTION_SINGLE_OBJECT
23
23
24
#include <ft2build.h>
24
#include <ft2build.h>
25
#include "ahangles.c"
26
#include "ahglyph.c"
25
#include "ahglyph.c"
27
#include "ahglobal.c"
26
#include "ahglobal.c"
28
#include "ahhint.c"
27
#include "ahhint.c"

Return to bug 31347