freetype-commit
[Top][All Lists]
Advanced

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

[Git][freetype/freetype][gsoc-craig-2023-final] [autofit] add functions


From: Craig White (@gerzytet)
Subject: [Git][freetype/freetype][gsoc-craig-2023-final] [autofit] add functions for creating and using reverse character maps
Date: Wed, 01 Nov 2023 03:35:05 +0000

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

Commits:

  • b9095238
    by Craig White at 2023-10-31T23:20:01-04:00
    [autofit] add functions for creating and using reverse character maps
    as well as looking up entries in the adjustment database.
    
    * include/freetype/internal/ftobjs.h (find_unicode_charmap) Move documentation
    and function prototype from ftobjs.c to this file so that it can be called
    from afadjust.c
    * src/base/ftobjs.c (find_unicode_charmap) make this function non-static
    * src/autofit/afadjust.c Add functions for looking up vertical adjustment
    type, tilde correction type, creating and deleting reverse character maps
    * src/autofit/afadjust.h Add headers for the above functions.  Correct
    definition of AF_AdjustmentDatabaseEntry_ to include tilde correction
    type
    * src/autofit/aftypes.h Add prototype of AF_ReverseCharacterMap
    * src/autofit/autofit.c Add include of afadjust.c
    

6 changed files:

Changes:

  • include/freetype/internal/ftobjs.h
    ... ... @@ -275,6 +275,26 @@ FT_BEGIN_HEADER
    275 275
                       FT_GlyphSlot    slot,
    
    276 276
                       FT_Render_Mode  mode );
    
    277 277
     
    
    278
    +  /**************************************************************************
    
    279
    +   *
    
    280
    +   * @Function:
    
    281
    +   *   find_unicode_charmap
    
    282
    +   *
    
    283
    +   * @Description:
    
    284
    +   *   This function finds a Unicode charmap, if there is one.
    
    285
    +   *   And if there is more than one, it tries to favour the more
    
    286
    +   *   extensive one, i.e., one that supports UCS-4 against those which
    
    287
    +   *   are limited to the BMP ( UCS-2 encoding.)
    
    288
    +   *
    
    289
    +   *   If a unicode charmap is found, face->charmap is set to it.
    
    290
    +   *
    
    291
    +   *   This function is called from open_face(),
    
    292
    +   *   from FT_Select_Charmap( ..., FT_ENCODING_UNICODE ),
    
    293
    +   *   and also from afadjust.c in the autofit module.
    
    294
    +   */
    
    295
    +  FT_BASE( FT_Error )
    
    296
    +  find_unicode_charmap( FT_Face  face );
    
    297
    +
    
    278 298
     #ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
    
    279 299
     
    
    280 300
       typedef void  (*FT_Bitmap_LcdFilterFunc)( FT_Bitmap*      bitmap,
    

  • src/autofit/afadjust.c
    ... ... @@ -136,3 +136,222 @@ adjustment_database[] =
    136 136
         {0x17D, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0},
    
    137 137
         {0x17E, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0}
    
    138 138
     };
    
    139
    +
    
    140
    +/*Helper function: get the adjustment database entry for a codepoint*/
    
    141
    +FT_LOCAL_DEF( const AF_AdjustmentDatabaseEntry* )
    
    142
    +af_adjustment_database_lookup( FT_UInt32 codepoint ) {
    
    143
    +    /* Binary search for database entry */
    
    144
    +    FT_Int low = 0;
    
    145
    +    FT_Int high = AF_ADJUSTMENT_DATABASE_LENGTH - 1;
    
    146
    +    while ( high >= low )
    
    147
    +    {
    
    148
    +        FT_Int mid = ( low + high ) / 2;
    
    149
    +        FT_UInt32 mid_codepoint = adjustment_database[mid].codepoint;
    
    150
    +        if ( mid_codepoint < codepoint )
    
    151
    +        {
    
    152
    +            low = mid + 1;
    
    153
    +        }
    
    154
    +        else if ( mid_codepoint > codepoint )
    
    155
    +        {
    
    156
    +            high = mid - 1;
    
    157
    +        }
    
    158
    +        else
    
    159
    +        {
    
    160
    +            return &adjustment_database[mid];
    
    161
    +        }
    
    162
    +    }
    
    163
    +
    
    164
    +    return NULL;
    
    165
    +}
    
    166
    +
    
    167
    +FT_LOCAL_DEF( AF_VerticalSeparationAdjustmentType )
    
    168
    +af_lookup_vertical_seperation_type( AF_ReverseCharacterMap map, FT_Int glyph_index ) {
    
    169
    +    FT_UInt32 codepoint = af_reverse_character_map_lookup( map, glyph_index );
    
    170
    +    const AF_AdjustmentDatabaseEntry *entry = af_adjustment_database_lookup( codepoint );
    
    171
    +    if ( entry == NULL )
    
    172
    +    {
    
    173
    +        return AF_VERTICAL_ADJUSTMENT_NONE;
    
    174
    +    }
    
    175
    +    return entry->vertical_separation_adjustment_type;
    
    176
    +}
    
    177
    +
    
    178
    +/*1 if tilde correction should be applied to the topmost contour
    
    179
    +else 0*/
    
    180
    +FT_LOCAL_DEF( FT_Bool )
    
    181
    +af_lookup_tilde_correction_type( AF_ReverseCharacterMap map, FT_Int glyph_index ) {
    
    182
    +    FT_UInt32 codepoint = af_reverse_character_map_lookup( map, glyph_index );
    
    183
    +    const AF_AdjustmentDatabaseEntry *entry = af_adjustment_database_lookup( codepoint );
    
    184
    +    if ( entry == NULL )
    
    185
    +    {
    
    186
    +        return 0;
    
    187
    +    }
    
    188
    +    return entry->apply_tilde;
    
    189
    +}
    
    190
    +
    
    191
    +typedef struct AF_ReverseMapEntry_
    
    192
    +{
    
    193
    +    FT_Int glyph_index;
    
    194
    +    FT_UInt32 codepoint;
    
    195
    +} AF_ReverseMapEntry;
    
    196
    +
    
    197
    +typedef struct AF_ReverseCharacterMap_
    
    198
    +{
    
    199
    +    FT_Long length;
    
    200
    +    AF_ReverseMapEntry *entries;
    
    201
    +} AF_ReverseCharacterMap_Rec;
    
    202
    +
    
    203
    +/* qsort compare function for reverse character map */
    
    204
    +FT_LOCAL_DEF( FT_Int )
    
    205
    +af_reverse_character_map_entry_compare( const void *a, const void *b ) {
    
    206
    +    const AF_ReverseMapEntry entry_a = *((const AF_ReverseMapEntry *)a);
    
    207
    +    const AF_ReverseMapEntry entry_b = *((const AF_ReverseMapEntry *)b);
    
    208
    +    return entry_a.glyph_index < entry_b.glyph_index ? -1 : entry_a.glyph_index > entry_b.glyph_index ? 1 : 0;
    
    209
    +}
    
    210
    +
    
    211
    +FT_LOCAL_DEF( FT_UInt32 )
    
    212
    +af_reverse_character_map_lookup_( AF_ReverseCharacterMap map, FT_Int glyph_index, FT_Long length )
    
    213
    +{
    
    214
    +    if ( map == NULL )
    
    215
    +    {
    
    216
    +        return 0;
    
    217
    +    }
    
    218
    +    /* Binary search for reverse character map entry */
    
    219
    +    FT_Int low = 0;
    
    220
    +    FT_Int high = length - 1;
    
    221
    +    while ( high >= low )
    
    222
    +    {
    
    223
    +        FT_Int mid = ( high + low ) / 2;
    
    224
    +        FT_Int mid_glyph_index = map->entries[mid].glyph_index;
    
    225
    +        if ( glyph_index < mid_glyph_index )
    
    226
    +        {
    
    227
    +            high = mid - 1;
    
    228
    +        }
    
    229
    +        else if ( glyph_index > mid_glyph_index )
    
    230
    +        {
    
    231
    +            low = mid + 1;
    
    232
    +        }
    
    233
    +        else
    
    234
    +        {
    
    235
    +            return map->entries[mid].codepoint;
    
    236
    +        }
    
    237
    +    }
    
    238
    +
    
    239
    +    return 0;
    
    240
    +}
    
    241
    +
    
    242
    +FT_LOCAL_DEF( FT_UInt32 )
    
    243
    +af_reverse_character_map_lookup( AF_ReverseCharacterMap map, FT_Int glyph_index )
    
    244
    +{
    
    245
    +    return af_reverse_character_map_lookup_( map, glyph_index, map->length );
    
    246
    +}
    
    247
    +
    
    248
    +/*prepare to add one more entry to the reverse character map
    
    249
    +  this is a helper for af_reverse_character_map_new*/
    
    250
    +FT_LOCAL_DEF( FT_Error )
    
    251
    +af_reverse_character_map_expand( AF_ReverseCharacterMap map, FT_Long *capacity, FT_Memory memory )
    
    252
    +{
    
    253
    +    FT_Error error;
    
    254
    +    if ( map->length < *capacity )
    
    255
    +    {
    
    256
    +        return FT_Err_Ok;
    
    257
    +    }
    
    258
    +
    
    259
    +    if ( map->length == *capacity )
    
    260
    +    {
    
    261
    +        FT_Long new_capacity = *capacity + *capacity / 2;
    
    262
    +        if ( FT_RENEW_ARRAY( map->entries, map->length, new_capacity ) ) {
    
    263
    +            return error;
    
    264
    +        }
    
    265
    +        *capacity = new_capacity;
    
    266
    +    }
    
    267
    +
    
    268
    +    return FT_Err_Ok;
    
    269
    +}
    
    270
    +
    
    271
    +FT_LOCAL_DEF( FT_Error )
    
    272
    +af_reverse_character_map_new( AF_ReverseCharacterMap *map, AF_FaceGlobals globals )
    
    273
    +{
    
    274
    +    FT_Face face = globals->face;
    
    275
    +    FT_Memory memory = face->memory;
    
    276
    +    /* Search for a unicode charmap */
    
    277
    +    /* If there isn't one, create a blank map */
    
    278
    +
    
    279
    +    FT_TRACE4(( "af_reverse_character_map_new: building reverse character map\n" ));
    
    280
    +
    
    281
    +    FT_Error error;
    
    282
    +    /* backup face->charmap because find_unicode_charmap sets it */
    
    283
    +    FT_CharMap old_charmap = face->charmap;
    
    284
    +    if ( ( error = find_unicode_charmap( face ) ) )
    
    285
    +    {
    
    286
    +        *map = NULL;
    
    287
    +        goto Exit;
    
    288
    +    }
    
    289
    +
    
    290
    +    if ( FT_NEW( *map ) )
    
    291
    +    {
    
    292
    +        goto Exit;
    
    293
    +    }
    
    294
    +
    
    295
    +    FT_Long capacity = 10;
    
    296
    +    ( *map )->length = 0;
    
    297
    +
    
    298
    +    if ( FT_NEW_ARRAY( ( *map )->entries, capacity) )
    
    299
    +    {
    
    300
    +        goto Exit;
    
    301
    +    }
    
    302
    +
    
    303
    +#ifdef FT_DEBUG_LEVEL_TRACE
    
    304
    +    int failed_lookups = 0;
    
    305
    +#endif
    
    306
    +    for ( FT_Int i = 0; i < AF_ADJUSTMENT_DATABASE_LENGTH; i++ )
    
    307
    +    {
    
    308
    +        FT_UInt32 codepoint = adjustment_database[i].codepoint;
    
    309
    +        FT_Int glyph = FT_Get_Char_Index( face, codepoint );
    
    310
    +        if ( glyph == 0 )
    
    311
    +        {
    
    312
    +#ifdef FT_DEBUG_LEVEL_TRACE
    
    313
    +            failed_lookups++;
    
    314
    +#endif
    
    315
    +            continue;
    
    316
    +        }
    
    317
    +        error = af_reverse_character_map_expand( *map, &capacity, memory );
    
    318
    +        if ( error ) {
    
    319
    +            goto Exit;
    
    320
    +        }
    
    321
    +
    
    322
    +        ( *map )->length++;
    
    323
    +        ( *map )->entries[i].glyph_index = glyph;
    
    324
    +        ( *map )->entries[i].codepoint = codepoint;
    
    325
    +    }
    
    326
    +
    
    327
    +    ft_qsort(
    
    328
    +        ( *map )->entries,
    
    329
    +        ( *map )->length,
    
    330
    +        sizeof( AF_ReverseMapEntry ),
    
    331
    +        af_reverse_character_map_entry_compare
    
    332
    +    );
    
    333
    +
    
    334
    +    FT_TRACE4(( "    reverse character map built successfully"\
    
    335
    +                " with %d entries\n", (*map)->length ));
    
    336
    +
    
    337
    +Exit:
    
    338
    +    face->charmap = old_charmap;
    
    339
    +    if ( error )
    
    340
    +    {
    
    341
    +        FT_TRACE4(( "    error while building reverse character map.  Using blank map.\n" ));
    
    342
    +        if ( *map )
    
    343
    +        {
    
    344
    +            FT_FREE( ( *map )->entries );
    
    345
    +        }
    
    346
    +        FT_FREE( *map );
    
    347
    +        return error;
    
    348
    +    }
    
    349
    +
    
    350
    +    return FT_Err_Ok;
    
    351
    +}
    
    352
    +
    
    353
    +FT_LOCAL_DEF( FT_Error )
    
    354
    +af_reverse_character_map_done( AF_ReverseCharacterMap map, FT_Memory memory ) {
    
    355
    +    FT_FREE( map->entries );
    
    356
    +    return FT_Err_Ok;
    
    357
    +}

  • src/autofit/afadjust.h
    ... ... @@ -2,6 +2,7 @@
    2 2
     #define AFADJUST_H_
    
    3 3
     
    
    4 4
     #include <freetype/fttypes.h>
    
    5
    +#include "afglobal.h"
    
    5 6
     
    
    6 7
     FT_BEGIN_HEADER
    
    7 8
     
    
    ... ... @@ -20,10 +21,29 @@ typedef enum AF_VerticalSeparationAdjustmentType_
    20 21
         AF_VERTICAL_ADJUSTMENT_NONE
    
    21 22
     } AF_VerticalSeparationAdjustmentType;
    
    22 23
     
    
    23
    -typedef struct AF_AdjustmentDatabaseEntry_ {
    
    24
    -    FT_UInt32 codepoint;
    
    25
    -    AF_VerticalSeparationAdjustmentType vertical_separation_adjustment_type;
    
    26
    -  } AF_AdjustmentDatabaseEntry;
    
    24
    +typedef struct AF_AdjustmentDatabaseEntry_
    
    25
    +{
    
    26
    +  FT_UInt32 codepoint;
    
    27
    +  AF_VerticalSeparationAdjustmentType vertical_separation_adjustment_type;
    
    28
    +  FT_Bool apply_tilde;
    
    29
    +} AF_AdjustmentDatabaseEntry;
    
    30
    +
    
    31
    +FT_LOCAL(AF_VerticalSeparationAdjustmentType)
    
    32
    +af_lookup_vertical_seperation_type( AF_ReverseCharacterMap map, FT_Int glyph_index );
    
    33
    +
    
    34
    +FT_LOCAL( FT_Bool )
    
    35
    +af_lookup_tilde_correction_type( AF_ReverseCharacterMap map, FT_Int glyph_index );
    
    36
    +
    
    37
    +FT_LOCAL( FT_UInt32 )
    
    38
    +af_reverse_character_map_lookup( AF_ReverseCharacterMap map, FT_Int glyph_index );
    
    39
    +
    
    40
    +/*allocate and populate the reverse character map, using the character map within the face*/
    
    41
    +FT_LOCAL( FT_Error )
    
    42
    +af_reverse_character_map_new( AF_ReverseCharacterMap *map, AF_FaceGlobals globals );
    
    43
    +
    
    44
    +/*free the reverse character map*/
    
    45
    +FT_LOCAL( FT_Error )
    
    46
    +af_reverse_character_map_done( AF_ReverseCharacterMap map, FT_Memory memory );
    
    27 47
     
    
    28 48
     struct AF_ReverseCharacterMap_;
    
    29 49
     
    

  • src/autofit/aftypes.h
    ... ... @@ -406,6 +406,12 @@ extern void* af_debug_hints_;
    406 406
     
    
    407 407
       typedef struct AF_FaceGlobalsRec_*  AF_FaceGlobals;
    
    408 408
     
    
    409
    +  /*stores a mapping from glyphs to unicode codepoints
    
    410
    +  see afadjust.c for details */
    
    411
    +  struct AF_ReverseCharacterMap_;
    
    412
    +
    
    413
    +  typedef struct AF_ReverseCharacterMap_ *AF_ReverseCharacterMap;
    
    414
    +
    
    409 415
       /* This is the main structure that combines everything.  Autofit modules */
    
    410 416
       /* specific to writing systems derive their structures from it, for      */
    
    411 417
       /* example `AF_LatinMetrics'.                                            */
    

  • src/autofit/autofit.c
    ... ... @@ -30,6 +30,7 @@
    30 30
     #include "afmodule.c"
    
    31 31
     #include "afranges.c"
    
    32 32
     #include "afshaper.c"
    
    33
    +#include "afadjust.c"
    
    33 34
     
    
    34 35
     
    
    35 36
     /* END */

  • src/base/ftobjs.c
    ... ... @@ -1358,22 +1358,7 @@
    1358 1358
                           driver );
    
    1359 1359
       }
    
    1360 1360
     
    
    1361
    -
    
    1362
    -  /**************************************************************************
    
    1363
    -   *
    
    1364
    -   * @Function:
    
    1365
    -   *   find_unicode_charmap
    
    1366
    -   *
    
    1367
    -   * @Description:
    
    1368
    -   *   This function finds a Unicode charmap, if there is one.
    
    1369
    -   *   And if there is more than one, it tries to favour the more
    
    1370
    -   *   extensive one, i.e., one that supports UCS-4 against those which
    
    1371
    -   *   are limited to the BMP (said UCS-2 encoding.)
    
    1372
    -   *
    
    1373
    -   *   This function is called from open_face() (just below), and also
    
    1374
    -   *   from FT_Select_Charmap( ..., FT_ENCODING_UNICODE ).
    
    1375
    -   */
    
    1376
    -  static FT_Error
    
    1361
    +  FT_Error
    
    1377 1362
       find_unicode_charmap( FT_Face  face )
    
    1378 1363
       {
    
    1379 1364
         FT_CharMap*  first;
    


  • reply via email to

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