freetype-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Git][freetype/freetype][gsoc-craig-2023] 2 commits: Improve validation


From: Craig White (@gerzytet)
Subject: [Git][freetype/freetype][gsoc-craig-2023] 2 commits: Improve validation for vertical seperation adjustments, and use new approach for tilde unflattening
Date: Sun, 27 Aug 2023 03:00:36 +0000

Craig White pushed to branch gsoc-craig-2023 at FreeType / FreeType

Commits:

  • fa336db6
    by Craig White at 2023-08-12T22:47:00-04:00
    Improve validation for vertical seperation adjustments, and use new approach for tilde unflattening
    
  • 86e5080e
    by Craig White at 2023-08-26T22:58:43-04:00
    Add support for simple cases of GSUB lookups
    

4 changed files:

Changes:

  • src/autofit/afadjust.c
    ... ... @@ -8,12 +8,20 @@
    8 8
     #undef  FT_COMPONENT
    
    9 9
     #define FT_COMPONENT  afadjust
    
    10 10
     
    
    11
    +#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
    
    12
    +    #include <hb.h>
    
    13
    +    #include <hb-ot.h>
    
    14
    +#endif
    
    15
    +
    
    11 16
     /*TODO: find out whether capital u/U with accent entries are needed*/
    
    12 17
     /*the accent won't merge with the rest of the glyph because the accent mark is sitting above empty space*/
    
    18
    +/*
    
    19
    +  All entries in this list must be sorted by unicode codepoint ascending
    
    20
    +*/
    
    13 21
     FT_LOCAL_ARRAY_DEF( AF_AdjustmentDatabaseEntry )
    
    14 22
     adjustment_database[] =
    
    15 23
     {
    
    16
    -    {0x21,  AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP}, /* ! */
    
    24
    +    {0x21,  AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP}, /* ! *
    
    17 25
         {0x69,  AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP}, /* i */
    
    18 26
         {0x6A,  AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP}, /* j */
    
    19 27
         {0xA1,  AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP}, /*Inverted Exclamation Mark*/
    
    ... ... @@ -130,6 +138,12 @@ adjustment_database[] =
    130 138
         {0x17E, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP}
    
    131 139
     };
    
    132 140
     
    
    141
    +FT_LOCAL_DEF( FT_Bool )
    
    142
    +af_adjustment_database_entry_equals( const AF_AdjustmentDatabaseEntry* a, const AF_AdjustmentDatabaseEntry* b )
    
    143
    +{
    
    144
    +    return a->codepoint == b->codepoint && a->vertical_separation_adjustment_type == b->vertical_separation_adjustment_type;
    
    145
    +}
    
    146
    +
    
    133 147
     /*Helper function: get the adjustment database entry for a codepoint*/
    
    134 148
     FT_LOCAL_DEF( const AF_AdjustmentDatabaseEntry* )
    
    135 149
     af_adjustment_database_lookup( FT_UInt32 codepoint ) {
    
    ... ... @@ -187,12 +201,12 @@ typedef struct AF_ReverseMapEntry_
    187 201
     
    
    188 202
     typedef struct AF_ReverseCharacterMap_
    
    189 203
     {
    
    190
    -    FT_UInt length;
    
    204
    +    FT_Long length;
    
    191 205
         AF_ReverseMapEntry *entries;
    
    192 206
     } AF_ReverseCharacterMap_Rec;
    
    193 207
     
    
    194 208
     FT_LOCAL_DEF( FT_UInt32 )
    
    195
    -af_reverse_character_map_lookup( AF_ReverseCharacterMap map, FT_Int glyph_index )
    
    209
    +af_reverse_character_map_lookup_( AF_ReverseCharacterMap map, FT_Int glyph_index, FT_Long length )
    
    196 210
     {
    
    197 211
         if ( map == NULL )
    
    198 212
         {
    
    ... ... @@ -222,19 +236,59 @@ af_reverse_character_map_lookup( AF_ReverseCharacterMap map, FT_Int glyph_index
    222 236
         return 0;
    
    223 237
     }
    
    224 238
     
    
    239
    +FT_LOCAL_DEF( FT_UInt32 )
    
    240
    +af_reverse_character_map_lookup( AF_ReverseCharacterMap map, FT_Int glyph_index )
    
    241
    +{
    
    242
    +    return af_reverse_character_map_lookup_( map, glyph_index, map->length );
    
    243
    +}
    
    244
    +
    
    245
    +/*prepare to add one more entry to the reverse character map
    
    246
    +  this is a helper for af_reverse_character_map_new*/
    
    247
    +FT_LOCAL_DEF( FT_Error )
    
    248
    +af_reverse_character_map_expand( AF_ReverseCharacterMap map, FT_Long *capacity, FT_Memory memory )
    
    249
    +{
    
    250
    +    FT_Error error;
    
    251
    +    if ( map->length < *capacity )
    
    252
    +    {
    
    253
    +        return FT_Err_Ok;
    
    254
    +    }
    
    255
    +
    
    256
    +    if ( map->length == *capacity )
    
    257
    +    {
    
    258
    +        FT_Long new_capacity = *capacity + *capacity / 2;
    
    259
    +        if ( FT_RENEW_ARRAY( map->entries, map->length, new_capacity ) ) {
    
    260
    +            return error;
    
    261
    +        }
    
    262
    +        *capacity = new_capacity;
    
    263
    +    }
    
    264
    +
    
    265
    +    return FT_Err_Ok;
    
    266
    +}
    
    267
    +
    
    268
    +/* qsort compare function for reverse character map */
    
    269
    +FT_LOCAL_DEF( FT_Int )
    
    270
    +af_reverse_character_map_entry_compare( const void *a, const void *b ) {
    
    271
    +    const AF_ReverseMapEntry entry_a = *((const AF_ReverseMapEntry *)a);
    
    272
    +    const AF_ReverseMapEntry entry_b = *((const AF_ReverseMapEntry *)b);
    
    273
    +    return entry_a.glyph_index < entry_b.glyph_index ? -1 : entry_a.glyph_index > entry_b.glyph_index ? 1 : 0;
    
    274
    +}
    
    275
    +
    
    225 276
     FT_LOCAL_DEF( FT_Error )
    
    226
    -af_reverse_character_map_new( FT_Face face, AF_ReverseCharacterMap *map, FT_Memory memory )
    
    277
    +af_reverse_character_map_new( AF_ReverseCharacterMap *map, AF_FaceGlobals globals )
    
    227 278
     {
    
    279
    +    FT_Face face = globals->face;
    
    280
    +    FT_Memory memory = face->memory;
    
    228 281
         /* Search for a unicode charmap */
    
    229 282
         /* If there isn't one, create a blank map */
    
    230 283
     
    
    284
    +
    
    231 285
         /*TODO: use GSUB lookups    */
    
    232 286
         FT_TRACE4(( "af_reverse_character_map_new: building reverse character map\n" ));
    
    233 287
     
    
    234 288
         FT_Error error;
    
    235 289
         /* backup face->charmap because find_unicode_charmap sets it */
    
    236 290
         FT_CharMap old_charmap = face->charmap;
    
    237
    -    if (( error = find_unicode_charmap( face ) )) {
    
    291
    +    if ( ( error = find_unicode_charmap( face ) ) ) {
    
    238 292
             *map = NULL;
    
    239 293
             goto Exit;
    
    240 294
         }
    
    ... ... @@ -244,8 +298,8 @@ af_reverse_character_map_new( FT_Face face, AF_ReverseCharacterMap *map, FT_Memo
    244 298
             goto Exit;
    
    245 299
         }
    
    246 300
     
    
    247
    -    FT_Int capacity = 10;
    
    248
    -    FT_Int size = 0;
    
    301
    +    FT_Long capacity = 10;
    
    302
    +    ( *map )->length = 0;
    
    249 303
     
    
    250 304
         if ( FT_NEW_ARRAY( ( *map )->entries, capacity) )
    
    251 305
         {
    
    ... ... @@ -265,19 +319,117 @@ af_reverse_character_map_new( FT_Face face, AF_ReverseCharacterMap *map, FT_Memo
    265 319
     #endif
    
    266 320
                 continue;
    
    267 321
             }
    
    268
    -        if ( size == capacity )
    
    322
    +        error = af_reverse_character_map_expand( *map, &capacity, memory );
    
    323
    +        if ( error ) {
    
    324
    +            goto Exit;
    
    325
    +        }
    
    326
    +
    
    327
    +        ( *map )->length++;
    
    328
    +        ( *map )->entries[i].glyph_index = glyph;
    
    329
    +        ( *map )->entries[i].codepoint = codepoint;
    
    330
    +    }
    
    331
    +
    
    332
    +    ft_qsort(
    
    333
    +        ( *map )->entries,
    
    334
    +        ( *map )->length,
    
    335
    +        sizeof( AF_ReverseMapEntry ),
    
    336
    +        af_reverse_character_map_entry_compare
    
    337
    +    );
    
    338
    +
    
    339
    +#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
    
    340
    +    hb_font_t *hb_font = globals->hb_font;
    
    341
    +    hb_face_t *hb_face = hb_font_get_face( hb_font );
    
    342
    +    hb_set_t  *feature_indicies = hb_set_create();
    
    343
    +    FT_Long oldlength = ( *map )->length;
    
    344
    +    hb_ot_layout_collect_lookups(
    
    345
    +        hb_face,
    
    346
    +        HB_OT_TAG_GSUB,
    
    347
    +        NULL, /*all scripts*/
    
    348
    +        NULL, /*all languages*/
    
    349
    +        NULL, /*all features*/
    
    350
    +        feature_indicies
    
    351
    +    );
    
    352
    +    hb_codepoint_t feature_index = HB_SET_VALUE_INVALID;
    
    353
    +
    
    354
    +    FT_UInt added_entries = 0;
    
    355
    +    while ( hb_set_next(feature_indicies, &feature_index) )
    
    356
    +    {
    
    357
    +        hb_codepoint_t output_glyph_index;
    
    358
    +        /*TODO: find out whether I can reuse set instances instead of recreating*/
    
    359
    +        hb_set_t *glyphs_before = hb_set_create();
    
    360
    +        hb_set_t *glyphs_input = hb_set_create();
    
    361
    +        hb_set_t *glyphs_after = hb_set_create();
    
    362
    +        hb_set_t *glyphs_output = hb_set_create();
    
    363
    +        hb_ot_layout_lookup_collect_glyphs( hb_face, HB_OT_TAG_GSUB,
    
    364
    +                                            feature_index, glyphs_before,
    
    365
    +                                            glyphs_input, glyphs_after,
    
    366
    +                                            glyphs_output);
    
    367
    +        /*Don't consider anything involving context.  Just do the
    
    368
    +          simple cases*/
    
    369
    +        if ( hb_set_get_population( glyphs_before ) > 0 ||
    
    370
    +             hb_set_get_population( glyphs_after ) > 0 )
    
    371
    +        {
    
    372
    +            continue;
    
    373
    +        }
    
    374
    +        if ( hb_set_get_population( glyphs_output ) != 1 )
    
    269 375
             {
    
    270
    -            capacity += capacity / 2;
    
    271
    -            if ( FT_RENEW_ARRAY((*map)->entries, size, capacity) )
    
    376
    +            continue;
    
    377
    +        }
    
    378
    +
    
    379
    +        hb_codepoint_t input_glyph_index = HB_SET_VALUE_INVALID;
    
    380
    +        const AF_AdjustmentDatabaseEntry* input_entry = NULL;
    
    381
    +        FT_UInt32 input_codepoint;
    
    382
    +        while ( hb_set_next( glyphs_input, &input_glyph_index ) ) {
    
    383
    +            input_codepoint = af_reverse_character_map_lookup_( *map, input_glyph_index, oldlength );
    
    384
    +            if ( input_codepoint == 0 )
    
    385
    +            {
    
    386
    +                continue;
    
    387
    +            }
    
    388
    +            const AF_AdjustmentDatabaseEntry* entry = af_adjustment_database_lookup( input_codepoint );
    
    389
    +            if ( entry == NULL )
    
    272 390
                 {
    
    273
    -                goto Exit;
    
    391
    +                continue;
    
    392
    +            }
    
    393
    +
    
    394
    +            if ( input_entry == NULL )
    
    395
    +            {
    
    396
    +                input_entry = entry;
    
    397
    +            }
    
    398
    +            else
    
    399
    +            {
    
    400
    +                if ( !af_adjustment_database_entry_equals( input_entry, entry ) )
    
    401
    +                {
    
    402
    +                    goto end;
    
    403
    +                }
    
    274 404
                 }
    
    275 405
             }
    
    276
    -        size++;
    
    277
    -        ( *map )->entries[i].glyph_index = glyph;
    
    278
    -        ( *map )->entries[i].codepoint = codepoint;
    
    406
    +
    
    407
    +
    
    408
    +        output_glyph_index = HB_SET_VALUE_INVALID;
    
    409
    +        hb_set_next( glyphs_output, &output_glyph_index );
    
    410
    +
    
    411
    +        /*Make pair output glyph index -> input unicode*/
    
    412
    +        error = af_reverse_character_map_expand( *map, &capacity, memory );
    
    413
    +        if ( error ) {
    
    414
    +            goto Exit;
    
    415
    +        }
    
    416
    +
    
    417
    +        FT_Long index = ( *map )->length++;
    
    418
    +        ( *map )->entries[index].glyph_index = output_glyph_index;
    
    419
    +        ( *map )->entries[index].codepoint = input_codepoint;
    
    420
    +        FT_TRACE4(("Adding entry: %d -> %d\n", output_glyph_index, input_codepoint));
    
    421
    +
    
    422
    +        end: ;
    
    279 423
         }
    
    280
    -    ( *map )->length = size;
    
    424
    +
    
    425
    +    ft_qsort(
    
    426
    +        ( *map )->entries,
    
    427
    +        ( *map )->length,
    
    428
    +        sizeof( AF_ReverseMapEntry ),
    
    429
    +        af_reverse_character_map_entry_compare
    
    430
    +    );
    
    431
    +
    
    432
    +#endif /*FT_CONFIG_OPTION_USE_HARFBUZZ*/
    
    281 433
     
    
    282 434
     Exit:
    
    283 435
         face->charmap = old_charmap;
    
    ... ... @@ -293,7 +445,7 @@ Exit:
    293 445
         }
    
    294 446
     #ifdef FT_DEBUG_LEVEL_TRACE
    
    295 447
         FT_TRACE4(( "    reverse character map built successfully"\
    
    296
    -                " with %d entries and %d failed lookups.\n", size, failed_lookups ));
    
    448
    +                " with %d entries and %d failed lookups.\n", (*map)->length, failed_lookups ));
    
    297 449
     #endif
    
    298 450
         return FT_Err_Ok;
    
    299 451
     }
    

  • src/autofit/afadjust.h
    1 1
     #ifndef AFADJUST_H_
    
    2 2
     #define AFADJUST_H_
    
    3
    -
    
    4 3
     #include <freetype/fttypes.h>
    
    4
    +#include "aftypes.h"
    
    5
    +#include "afglobal.h"
    
    5 6
     
    
    6 7
     FT_BEGIN_HEADER
    
    7 8
     
    
    ... ... @@ -28,10 +29,6 @@ typedef struct AF_AdjustmentDatabaseEntry_
    28 29
       AF_VerticalSeparationAdjustmentType vertical_separation_adjustment_type;
    
    29 30
     } AF_AdjustmentDatabaseEntry;
    
    30 31
     
    
    31
    -struct AF_ReverseCharacterMap_;
    
    32
    -
    
    33
    -typedef struct AF_ReverseCharacterMap_ *AF_ReverseCharacterMap;
    
    34
    -
    
    35 32
     FT_LOCAL(AF_VerticalSeparationAdjustmentType)
    
    36 33
     af_lookup_vertical_seperation_type( AF_ReverseCharacterMap map, FT_Int glyph_index );
    
    37 34
     
    
    ... ... @@ -43,7 +40,7 @@ af_reverse_character_map_lookup( AF_ReverseCharacterMap map, FT_Int glyph_index
    43 40
     
    
    44 41
     /*allocate and populate the reverse character map, using the character map within the face*/
    
    45 42
     FT_LOCAL( FT_Error )
    
    46
    -af_reverse_character_map_new( FT_Face face, AF_ReverseCharacterMap *map, FT_Memory memory );
    
    43
    +af_reverse_character_map_new( AF_ReverseCharacterMap *map, AF_FaceGlobals globals );
    
    47 44
     
    
    48 45
     /*free the reverse character map*/
    
    49 46
     FT_LOCAL( FT_Error )
    

  • src/autofit/aflatin.c
    ... ... @@ -1154,7 +1154,7 @@
    1154 1154
           }
    
    1155 1155
           af_latin_metrics_check_digits( metrics, face );
    
    1156 1156
     
    
    1157
    -      af_reverse_character_map_new( face, &metrics->root.reverse_charmap, face->memory );
    
    1157
    +      af_reverse_character_map_new( &metrics->root.reverse_charmap, metrics->root.globals );
    
    1158 1158
         }
    
    1159 1159
     
    
    1160 1160
       Exit:
    
    ... ... @@ -2799,6 +2799,87 @@ af_find_highest_contour( AF_GlyphHints hints ) {
    2799 2799
       return highest_contour;
    
    2800 2800
     }
    
    2801 2801
     
    
    2802
    +static void
    
    2803
    +af_remove_segments_containing_point(AF_GlyphHints hints, AF_Point point)
    
    2804
    +{
    
    2805
    +  AF_AxisHints axis = &hints->axis[AF_DIMENSION_VERT];
    
    2806
    +  AF_Segment segments = axis->segments;
    
    2807
    +  AF_Segment segment_limit = FT_OFFSET( segments, axis->num_segments );
    
    2808
    +  for ( FT_Int i = 0; i < axis->num_segments; i++ )
    
    2809
    +  {
    
    2810
    +    AF_Segment seg = &segments[i];
    
    2811
    +    FT_Bool remove = 0;
    
    2812
    +    for ( AF_Point p = seg->first; p <= seg->last; p = p->next )
    
    2813
    +    {
    
    2814
    +      if ( p == point )
    
    2815
    +      {
    
    2816
    +        remove = 1;
    
    2817
    +        break;
    
    2818
    +      }
    
    2819
    +    }
    
    2820
    +
    
    2821
    +    if ( remove )
    
    2822
    +    {
    
    2823
    +      FT_TRACE4(("Removing segment %d\n", i));
    
    2824
    +      /* first, check the first and last fields of the edge */
    
    2825
    +      AF_Edge edge = seg->edge;
    
    2826
    +      if ( edge->first == seg && edge->last == seg )
    
    2827
    +      {
    
    2828
    +        /* The edge only consists of the segment to be removed.  remove the edge*/
    
    2829
    +          *edge = axis->edges[--axis->num_edges];
    
    2830
    +      }
    
    2831
    +      else
    
    2832
    +      {
    
    2833
    +        if ( edge->first == seg )
    
    2834
    +        {
    
    2835
    +          edge->first = seg->edge_next;
    
    2836
    +        }
    
    2837
    +        if ( edge->last == seg )
    
    2838
    +        {
    
    2839
    +          edge->last = edge->first;
    
    2840
    +          while ( edge->last->edge_next != seg )
    
    2841
    +          {
    
    2842
    +            edge->last = edge->last->edge_next;
    
    2843
    +          }
    
    2844
    +        }
    
    2845
    +      }
    
    2846
    +
    
    2847
    +      /* Now, delete the segment */
    
    2848
    +      *seg = axis->segments[--axis->num_segments];
    
    2849
    +
    
    2850
    +      i--; /* we have to check the new segment at this position */
    
    2851
    +    }
    
    2852
    +  }
    
    2853
    +}
    
    2854
    +
    
    2855
    +static void
    
    2856
    +af_latin_stretch_tildes_step_2( AF_GlyphHints hints,
    
    2857
    +                                FT_Int glyph_index,
    
    2858
    +                                AF_ReverseCharacterMap reverse_charmap )
    
    2859
    +{
    
    2860
    +  if (af_lookup_tilde_correction_type(reverse_charmap, glyph_index)) {
    
    2861
    +    FT_Int highest_contour = af_find_highest_contour(hints);
    
    2862
    +    AF_Point first_point = hints->contours[highest_contour];
    
    2863
    +
    
    2864
    +    /* search for any curve tips that are on a y extrema, and delete any
    
    2865
    +      segments that contain this point.*/
    
    2866
    +    AF_Point p = first_point;
    
    2867
    +
    
    2868
    +    do
    
    2869
    +    {
    
    2870
    +      p = p->next;
    
    2871
    +      if ( /*!(p->flags & AF_FLAG_CONTROL)
    
    2872
    +            && p->prev->y == p->y && p->next->y == p->y
    
    2873
    +            && p->prev->flags & AF_FLAG_CONTROL
    
    2874
    +            && p->next->flags & AF_FLAG_CONTROL*/ 1 )
    
    2875
    +      {
    
    2876
    +        af_remove_segments_containing_point( hints, p );
    
    2877
    +      }
    
    2878
    +    } while ( p != first_point );
    
    2879
    +  }
    
    2880
    +
    
    2881
    +}
    
    2882
    +
    
    2802 2883
     void
    
    2803 2884
     af_latin_stretch_tildes( AF_GlyphHints hints,
    
    2804 2885
                              FT_Int glyph_index,
    
    ... ... @@ -2814,82 +2895,99 @@ af_latin_stretch_tildes( AF_GlyphHints hints,
    2814 2895
         FT_Short min_fy, max_fy;
    
    2815 2896
         min_fy = max_fy = p->fy;
    
    2816 2897
     
    
    2817
    -    do {
    
    2898
    +    do
    
    2899
    +    {
    
    2818 2900
           p = p->next;
    
    2819
    -      if ( p->y < min_y ) {
    
    2901
    +      if ( p->y < min_y )
    
    2902
    +      {
    
    2820 2903
             min_y = p->y;
    
    2821 2904
           }
    
    2822
    -      if ( p->y > max_y ) {
    
    2905
    +      if ( p->y > max_y )
    
    2906
    +      {
    
    2823 2907
             max_y = p->y;
    
    2824 2908
           }
    
    2825 2909
     
    
    2826
    -      if ( p->fy < min_fy ) {
    
    2910
    +      if ( p->fy < min_fy )
    
    2911
    +      {
    
    2827 2912
             min_fy = p->fy;
    
    2828 2913
           }
    
    2829 2914
     
    
    2830
    -      if ( p->fy > max_fy ) {
    
    2915
    +      if ( p->fy > max_fy )
    
    2916
    +      {
    
    2831 2917
             max_fy = p->fy;
    
    2832 2918
           }
    
    2833 2919
     
    
    2834
    -    } while ( p != first_point );
    
    2920
    +    }
    
    2921
    +    while ( p != first_point );
    
    2835 2922
     
    
    2836 2923
         FT_Pos min_measurement = 32000;
    
    2837 2924
         FT_UInt measurements_taken = 0;
    
    2838 2925
     
    
    2839
    -    do {
    
    2926
    +    do
    
    2927
    +    {
    
    2840 2928
           p = p->next;
    
    2841 2929
           if ( !(p->flags & AF_FLAG_CONTROL)
    
    2842 2930
                && p->prev->y == p->y && p->next->y == p->y
    
    2843 2931
                && p->y != min_y && p->y != max_y
    
    2844 2932
                && p->prev->flags & AF_FLAG_CONTROL
    
    2845
    -           && p->next->flags & AF_FLAG_CONTROL ) {
    
    2933
    +           && p->next->flags & AF_FLAG_CONTROL )
    
    2934
    +      {
    
    2846 2935
             /* This point could be a candidate.  Find the next and previous on-curve */
    
    2847 2936
             /* points, and make sure they are both either above or below the point, */
    
    2848 2937
             /* Then make the measurement */
    
    2849 2938
             AF_Point prevOn = p->prev;
    
    2850 2939
             AF_Point nextOn = p->next;
    
    2851
    -        while ( prevOn->flags & AF_FLAG_CONTROL ) {
    
    2940
    +        while ( prevOn->flags & AF_FLAG_CONTROL )
    
    2941
    +        {
    
    2852 2942
               prevOn = prevOn->prev;
    
    2853 2943
             }
    
    2854
    -        while ( nextOn->flags & AF_FLAG_CONTROL ) {
    
    2944
    +        while ( nextOn->flags & AF_FLAG_CONTROL )
    
    2945
    +        {
    
    2855 2946
               nextOn = nextOn->next;
    
    2856 2947
             }
    
    2857 2948
             FT_Pos measurement;
    
    2858
    -        if ( nextOn->y > p->y && prevOn->y > p->y ) {
    
    2949
    +        if ( nextOn->y > p->y && prevOn->y > p->y )
    
    2950
    +        {
    
    2859 2951
               measurement = p->y - min_y;
    
    2860
    -        } else if ( nextOn->y < p->y && prevOn->y < p->y ) {
    
    2952
    +        }
    
    2953
    +        else if ( nextOn->y < p->y && prevOn->y < p->y )
    
    2954
    +        {
    
    2861 2955
               measurement = max_y - p->y;
    
    2862
    -        } else {
    
    2956
    +        }
    
    2957
    +        else
    
    2958
    +        {
    
    2863 2959
               continue;
    
    2864 2960
             }
    
    2865 2961
     
    
    2866
    -        if (measurement < min_measurement) {
    
    2962
    +        if (measurement < min_measurement)
    
    2963
    +        {
    
    2867 2964
               min_measurement = measurement;
    
    2868 2965
             }
    
    2869 2966
             measurements_taken++;
    
    2870 2967
           }
    
    2871 2968
     
    
    2872
    -    } while ( p != first_point );
    
    2969
    +    }
    
    2970
    +    while ( p != first_point );
    
    2873 2971
     
    
    2874 2972
         FT_Pos height = max_y - min_y;
    
    2875 2973
     
    
    2876 2974
         FT_Pos target_height = min_measurement + 64;
    
    2877
    -    if ( height >= target_height ) {
    
    2975
    +    if ( height >= target_height )
    
    2976
    +    {
    
    2878 2977
           return;
    
    2879 2978
         }
    
    2880 2979
     
    
    2881 2980
         p = first_point;
    
    2882
    -    do {
    
    2981
    +    do
    
    2982
    +    {
    
    2883 2983
           p = p->next;
    
    2884
    -      /*if ( p->flags & AF_FLAG_CONTROL ) {
    
    2885
    -        continue;
    
    2886
    -      }*/
    
    2887 2984
           p->y = ((p->y - min_y) * target_height / height) + min_y;
    
    2888 2985
           p->fy = ((p->fy - min_fy) * target_height / height) + min_fy;
    
    2889 2986
           p->oy = p->y;
    
    2890 2987
           if ( !(p->flags & AF_FLAG_CONTROL) )
    
    2891 2988
             p->flags |= AF_FLAG_TOUCH_Y;
    
    2892
    -    } while ( p != first_point );
    
    2989
    +    }
    
    2990
    +    while ( p != first_point );
    
    2893 2991
     
    
    2894 2992
         FT_TRACE4(( "af_latin_stretch_tildes: Height: %d, measurement: %d, measurements taken: %d\n", height, min_measurement, measurements_taken ));
    
    2895 2993
     
    
    ... ... @@ -2898,18 +2996,73 @@ af_latin_stretch_tildes( AF_GlyphHints hints,
    2898 2996
         p = first_point;
    
    2899 2997
         do {
    
    2900 2998
           p = p->next;
    
    2901
    -      if ( p->y < new_min_y ) {
    
    2999
    +      if ( p->y < new_min_y )
    
    3000
    +      {
    
    2902 3001
             new_min_y = p->y;
    
    2903 3002
           }
    
    2904
    -      if ( p->y > new_max_y ) {
    
    3003
    +      if ( p->y > new_max_y )
    
    3004
    +      {
    
    2905 3005
             new_max_y = p->y;
    
    2906 3006
           }
    
    2907
    -    } while ( p != first_point );
    
    3007
    +    }
    
    3008
    +    while ( p != first_point );
    
    3009
    +
    
    3010
    +    FT_TRACE4(( "af_latin_stretch_tildes: New height: %d\n, miny: %d, maxy: %d", new_max_y - new_min_y, new_min_y, new_max_y));
    
    3011
    +  }
    
    3012
    +}
    
    3013
    +
    
    3014
    +/*True if the given contour overlaps horizontally with the bounding box
    
    3015
    +  Of all other contours combined.
    
    3016
    +  This is a helper for af_glyph_hints_apply_vertical_separation_adjustments */
    
    3017
    +FT_Bool
    
    3018
    +af_check_contour_horizontal_overlap( AF_GlyphHints hints,
    
    3019
    +                                     FT_Int contour_index )
    
    3020
    +{
    
    3021
    +  FT_Pos contour_max_x = -32000;
    
    3022
    +  FT_Pos contour_min_x = 32000;
    
    3023
    +  FT_Pos others_max_x = -32000;
    
    3024
    +  FT_Pos others_min_x = 32000;
    
    2908 3025
     
    
    2909
    -    FT_TRACE4(( "af_latin_stretch_tildes_merp: New height: %d\n, miny: %d, maxy: %d", new_max_y - new_min_y, new_min_y, new_max_y));
    
    3026
    +  for ( FT_Int contour = 0; contour < hints->num_contours; contour++ )
    
    3027
    +  {
    
    3028
    +    AF_Point first_point = hints->contours[contour];
    
    3029
    +    AF_Point p = first_point;
    
    3030
    +
    
    3031
    +    do
    
    3032
    +    {
    
    3033
    +      p = p->next;
    
    3034
    +      if ( contour == contour_index )
    
    3035
    +      {
    
    3036
    +        if ( p->x < contour_min_x )
    
    3037
    +        {
    
    3038
    +          contour_min_x = p->x;
    
    3039
    +        }
    
    3040
    +        if ( p->x > contour_max_x )
    
    3041
    +        {
    
    3042
    +          contour_max_x = p->x;
    
    3043
    +        }
    
    3044
    +      }
    
    3045
    +      else /* ( contour != contour_index ) */
    
    3046
    +      {
    
    3047
    +        if ( p->x < others_min_x )
    
    3048
    +        {
    
    3049
    +          others_min_x = p->x;
    
    3050
    +        }
    
    3051
    +        if ( p->x > others_max_x )
    
    3052
    +        {
    
    3053
    +          others_max_x = p->x;
    
    3054
    +        }
    
    3055
    +      }
    
    3056
    +    }
    
    3057
    +    while (p != first_point);
    
    2910 3058
       }
    
    2911 3059
     
    
    3060
    +  FT_Bool horizontal_overlap =
    
    3061
    +    (others_min_x <= contour_max_x && contour_max_x <= others_max_x) ||
    
    3062
    +    (others_min_x <= contour_min_x && contour_min_x <= others_max_x) ||
    
    3063
    +    (contour_max_x >= others_max_x && contour_min_x <= others_min_x);
    
    2912 3064
     
    
    3065
    +  return horizontal_overlap;
    
    2913 3066
     }
    
    2914 3067
     
    
    2915 3068
     void
    
    ... ... @@ -2961,6 +3114,15 @@ af_glyph_hints_apply_vertical_separation_adjustments( AF_GlyphHints hints,
    2961 3114
           }
    
    2962 3115
         }
    
    2963 3116
     
    
    3117
    +    /* check for a horizontal overtap between the top contour and the rest */
    
    3118
    +    /* if there is no overlap, do not adjust. */
    
    3119
    +
    
    3120
    +    FT_Bool horizontal_overlap = af_check_contour_horizontal_overlap( hints, highest_contour );
    
    3121
    +    if (!horizontal_overlap) {
    
    3122
    +      FT_TRACE4(( "    Top contour does not horizontally overlap with other contours.  Skipping adjustment.\n" ));
    
    3123
    +      return;
    
    3124
    +    }
    
    3125
    +
    
    2964 3126
         /* If there are any contours that have a maximum y coordinate */
    
    2965 3127
         /* greater or equal to the minimum y coordinate of the previously found highest*/
    
    2966 3128
         /* contour, bump the high contour up until the distance is one pixel */
    
    ... ... @@ -2995,9 +3157,13 @@ af_glyph_hints_apply_vertical_separation_adjustments( AF_GlyphHints hints,
    2995 3157
           }
    
    2996 3158
         }
    
    2997 3159
     
    
    2998
    -    FT_TRACE4(( "    Pushing top contour %d units up\n", adjustment_amount ));
    
    2999
    -    if ( adjustment_amount > 0 )
    
    3160
    +    if ( adjustment_amount > 64 )
    
    3161
    +    {
    
    3162
    +      FT_TRACE4(( "    Calculated adjustment amount %d was more than threshold of 64.  Not adjusting\n", adjustment_amount ));
    
    3163
    +    }
    
    3164
    +    else if ( adjustment_amount > 0 )
    
    3000 3165
         {
    
    3166
    +      FT_TRACE4(( "    Pushing top contour %d units up\n", adjustment_amount ));
    
    3001 3167
           af_move_contour_vertically(hints->contours[highest_contour], adjustment_amount);
    
    3002 3168
         }
    
    3003 3169
       } else if ( af_lookup_vertical_seperation_type( reverse_charmap, glyph_index ) == AF_VERTICAL_ADJUSTMENT_BOTTOM_CONTOUR_DOWN
    
    ... ... @@ -3065,9 +3231,13 @@ af_glyph_hints_apply_vertical_separation_adjustments( AF_GlyphHints hints,
    3065 3231
             adjustment_amount = 64 - ( min_y - lowest_max_y );
    
    3066 3232
           }
    
    3067 3233
     
    
    3068
    -      FT_TRACE4(( "    Pushing bottom contour %d units down\n", adjustment_amount ));
    
    3069
    -      if ( adjustment_amount > 0 )
    
    3234
    +      if ( adjustment_amount > 64 )
    
    3235
    +      {
    
    3236
    +        FT_TRACE4(( "    Calculated adjustment amount %d was more than threshold of 64.  Not adjusting\n", adjustment_amount ));
    
    3237
    +      }
    
    3238
    +      else if ( adjustment_amount > 0 )
    
    3070 3239
           {
    
    3240
    +        FT_TRACE4(( "    Pushing bottom contour %d units down\n", adjustment_amount ));
    
    3071 3241
             af_move_contour_vertically(hints->contours[lowest_contour], -adjustment_amount);
    
    3072 3242
           }
    
    3073 3243
         }
    
    ... ... @@ -3900,7 +4070,6 @@ static void traceheight(FT_UInt num, AF_GlyphHints hints) {
    3900 4070
     
    
    3901 4071
       FT_Pos min_y, max_y;
    
    3902 4072
       min_y = max_y = p->y;
    
    3903
    -  FT_UInt candidates = 0;
    
    3904 4073
     
    
    3905 4074
       do {
    
    3906 4075
         p = p->next;
    
    ... ... @@ -3952,12 +4121,13 @@ static void traceheight(FT_UInt num, AF_GlyphHints hints) {
    3952 4121
     
    
    3953 4122
         if ( AF_HINTS_DO_VERTICAL( hints ) )
    
    3954 4123
         {
    
    3955
    -      af_latin_stretch_tildes( hints, glyph_index, metrics->root.reverse_charmap );
    
    4124
    +      /*af_latin_stretch_tildes( hints, glyph_index, metrics->root.reverse_charmap );*/
    
    3956 4125
           axis  = &metrics->axis[AF_DIMENSION_VERT];
    
    3957 4126
           error = af_latin_hints_detect_features( hints,
    
    3958 4127
                                                   axis->width_count,
    
    3959 4128
                                                   axis->widths,
    
    3960 4129
                                                   AF_DIMENSION_VERT );
    
    4130
    +      af_latin_stretch_tildes_step_2( hints, glyph_index, metrics->root.reverse_charmap );
    
    3961 4131
           if ( error )
    
    3962 4132
             goto Exit;
    
    3963 4133
     
    

  • src/autofit/aftypes.h
    ... ... @@ -39,7 +39,6 @@
    39 39
     #include <freetype/internal/ftdebug.h>
    
    40 40
     
    
    41 41
     #include "afblue.h"
    
    42
    -#include "afadjust.h"
    
    43 42
     
    
    44 43
     #ifdef FT_DEBUG_AUTOFIT
    
    45 44
     #include FT_CONFIG_STANDARD_LIBRARY_H
    
    ... ... @@ -411,6 +410,10 @@ extern void* af_debug_hints_;
    411 410
       /* specific to writing systems derive their structures from it, for      */
    
    412 411
       /* example `AF_LatinMetrics'.                                            */
    
    413 412
     
    
    413
    +  struct AF_ReverseCharacterMap_;
    
    414
    +
    
    415
    +  typedef struct AF_ReverseCharacterMap_ *AF_ReverseCharacterMap;
    
    416
    +
    
    414 417
       typedef struct  AF_StyleMetricsRec_
    
    415 418
       {
    
    416 419
         AF_StyleClass   style_class;
    


  • reply via email to

    [Prev in Thread] Current Thread [Next in Thread]