tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

t1gload.c (20377B)


      1 /****************************************************************************
      2 *
      3 * t1gload.c
      4 *
      5 *   Type 1 Glyph Loader (body).
      6 *
      7 * Copyright (C) 1996-2025 by
      8 * David Turner, Robert Wilhelm, and Werner Lemberg.
      9 *
     10 * This file is part of the FreeType project, and may only be used,
     11 * modified, and distributed under the terms of the FreeType project
     12 * license, LICENSE.TXT.  By continuing to use, modify, or distribute
     13 * this file you indicate that you have read the license and
     14 * understand and accept it fully.
     15 *
     16 */
     17 
     18 
     19 #include "t1gload.h"
     20 #include <freetype/internal/ftcalc.h>
     21 #include <freetype/internal/ftdebug.h>
     22 #include <freetype/internal/ftstream.h>
     23 #include <freetype/ftoutln.h>
     24 #include <freetype/internal/psaux.h>
     25 #include <freetype/internal/cfftypes.h>
     26 #include <freetype/ftdriver.h>
     27 
     28 #include "t1errors.h"
     29 
     30 
     31  /**************************************************************************
     32   *
     33   * The macro FT_COMPONENT is used in trace mode.  It is an implicit
     34   * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
     35   * messages during execution.
     36   */
     37 #undef  FT_COMPONENT
     38 #define FT_COMPONENT  t1gload
     39 
     40 
     41  static FT_Error
     42  T1_Parse_Glyph_And_Get_Char_String( T1_Decoder  decoder,
     43                                      FT_UInt     glyph_index,
     44                                      FT_Data*    char_string,
     45                                      FT_Bool*    force_scaling )
     46  {
     47    T1_Face   face  = (T1_Face)decoder->builder.face;
     48    T1_Font   type1 = &face->type1;
     49    FT_Error  error = FT_Err_Ok;
     50 
     51    PSAux_Service           psaux         = (PSAux_Service)face->psaux;
     52    const T1_Decoder_Funcs  decoder_funcs = psaux->t1_decoder_funcs;
     53    PS_Decoder              psdecoder;
     54 
     55 #ifdef FT_CONFIG_OPTION_INCREMENTAL
     56    FT_Incremental_InterfaceRec *inc =
     57                      face->root.internal->incremental_interface;
     58 #endif
     59 
     60 #ifdef T1_CONFIG_OPTION_OLD_ENGINE
     61    PS_Driver  driver = (PS_Driver)FT_FACE_DRIVER( face );
     62 #endif
     63 
     64 
     65    decoder->font_matrix = type1->font_matrix;
     66    decoder->font_offset = type1->font_offset;
     67 
     68 #ifdef FT_CONFIG_OPTION_INCREMENTAL
     69 
     70    /* For incremental fonts get the character data using the */
     71    /* callback function.                                     */
     72    if ( inc )
     73    {
     74      /* So `free_glyph_data` knows whether to free it. */
     75      char_string->pointer = NULL;
     76 
     77      error = inc->funcs->get_glyph_data( inc->object,
     78                                          glyph_index, char_string );
     79    }
     80    else
     81 
     82 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
     83 
     84    /* For ordinary fonts get the character data stored in the face record. */
     85    {
     86      char_string->pointer = type1->charstrings[glyph_index];
     87      char_string->length  = type1->charstrings_len[glyph_index];
     88    }
     89 
     90    if ( !error )
     91    {
     92      /* choose which renderer to use */
     93 #ifdef T1_CONFIG_OPTION_OLD_ENGINE
     94      if ( driver->hinting_engine == FT_HINTING_FREETYPE ||
     95           decoder->builder.metrics_only                 )
     96        error = decoder_funcs->parse_charstrings_old(
     97                  decoder,
     98                  (FT_Byte*)char_string->pointer,
     99                  (FT_UInt)char_string->length );
    100 #else
    101      if ( decoder->builder.metrics_only )
    102        error = decoder_funcs->parse_metrics(
    103                  decoder,
    104                  (FT_Byte*)char_string->pointer,
    105                  (FT_UInt)char_string->length );
    106 #endif
    107      else
    108      {
    109        CFF_SubFontRec  subfont;
    110 
    111 
    112        psaux->ps_decoder_init( &psdecoder, decoder, TRUE );
    113 
    114        psaux->t1_make_subfont( FT_FACE( face ),
    115                                &face->type1.private_dict, &subfont );
    116        psdecoder.current_subfont = &subfont;
    117 
    118        error = decoder_funcs->parse_charstrings(
    119                  &psdecoder,
    120                  (FT_Byte*)char_string->pointer,
    121                  (FT_ULong)char_string->length );
    122 
    123        /* Adobe's engine uses 16.16 numbers everywhere;              */
    124        /* as a consequence, glyphs larger than 2000ppem get rejected */
    125        if ( FT_ERR_EQ( error, Glyph_Too_Big ) )
    126        {
    127          /* this time, we retry unhinted and scale up the glyph later on */
    128          /* (the engine uses and sets the hardcoded value 0x10000 / 64 = */
    129          /* 0x400 for both `x_scale' and `y_scale' in this case)         */
    130          ((T1_GlyphSlot)decoder->builder.glyph)->hint = FALSE;
    131 
    132          *force_scaling = TRUE;
    133 
    134          error = decoder_funcs->parse_charstrings(
    135                    &psdecoder,
    136                    (FT_Byte*)char_string->pointer,
    137                    (FT_ULong)char_string->length );
    138        }
    139      }
    140    }
    141 
    142 #ifdef FT_CONFIG_OPTION_INCREMENTAL
    143 
    144    /* Incremental fonts can optionally override the metrics. */
    145    if ( !error && inc && inc->funcs->get_glyph_metrics )
    146    {
    147      FT_Incremental_MetricsRec  metrics;
    148 
    149 
    150      metrics.bearing_x = FIXED_TO_INT( decoder->builder.left_bearing.x );
    151      metrics.bearing_y = 0;
    152      metrics.advance   = FIXED_TO_INT( decoder->builder.advance.x );
    153      metrics.advance_v = FIXED_TO_INT( decoder->builder.advance.y );
    154 
    155      error = inc->funcs->get_glyph_metrics( inc->object,
    156                                             glyph_index, FALSE, &metrics );
    157 
    158      decoder->builder.left_bearing.x = INT_TO_FIXED( metrics.bearing_x );
    159      decoder->builder.advance.x      = INT_TO_FIXED( metrics.advance );
    160      decoder->builder.advance.y      = INT_TO_FIXED( metrics.advance_v );
    161    }
    162 
    163    if ( error && inc )
    164      inc->funcs->free_glyph_data( inc->object, char_string );
    165 
    166 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
    167 
    168    return error;
    169  }
    170 
    171 
    172  FT_CALLBACK_DEF( FT_Error )
    173  T1_Parse_Glyph( T1_Decoder  decoder,
    174                  FT_UInt     glyph_index )
    175  {
    176    FT_Data   glyph_data;
    177    FT_Bool   force_scaling = FALSE;
    178    FT_Error  error         = T1_Parse_Glyph_And_Get_Char_String(
    179                                decoder, glyph_index, &glyph_data,
    180                                &force_scaling );
    181 
    182 
    183 #ifdef FT_CONFIG_OPTION_INCREMENTAL
    184 
    185    if ( !error )
    186    {
    187      T1_Face  face = (T1_Face)decoder->builder.face;
    188 
    189 
    190      if ( face->root.internal->incremental_interface )
    191        face->root.internal->incremental_interface->funcs->free_glyph_data(
    192          face->root.internal->incremental_interface->object,
    193          &glyph_data );
    194    }
    195 
    196 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
    197 
    198    return error;
    199  }
    200 
    201 
    202  /*************************************************************************/
    203  /*************************************************************************/
    204  /*************************************************************************/
    205  /**********                                                      *********/
    206  /**********            COMPUTE THE MAXIMUM ADVANCE WIDTH         *********/
    207  /**********                                                      *********/
    208  /**********    The following code is in charge of computing      *********/
    209  /**********    the maximum advance width of the font.  It        *********/
    210  /**********    quickly processes each glyph charstring to        *********/
    211  /**********    extract the value from either a `sbw' or `seac'   *********/
    212  /**********    operator.                                         *********/
    213  /**********                                                      *********/
    214  /*************************************************************************/
    215  /*************************************************************************/
    216  /*************************************************************************/
    217 
    218 
    219  FT_LOCAL_DEF( FT_Error )
    220  T1_Compute_Max_Advance( T1_Face  face,
    221                          FT_Pos*  max_advance )
    222  {
    223    FT_Error       error;
    224    T1_DecoderRec  decoder;
    225    FT_Int         glyph_index;
    226    T1_Font        type1 = &face->type1;
    227    PSAux_Service  psaux = (PSAux_Service)face->psaux;
    228 
    229 
    230    FT_ASSERT( ( face->len_buildchar == 0 ) == ( face->buildchar == NULL ) );
    231 
    232    *max_advance = 0;
    233 
    234    /* initialize load decoder */
    235    error = psaux->t1_decoder_funcs->init( &decoder,
    236                                           (FT_Face)face,
    237                                           0, /* size       */
    238                                           0, /* glyph slot */
    239                                           (FT_Byte**)type1->glyph_names,
    240                                           face->blend,
    241                                           0,
    242                                           FT_RENDER_MODE_NORMAL,
    243                                           T1_Parse_Glyph );
    244    if ( error )
    245      return error;
    246 
    247    decoder.builder.metrics_only = 1;
    248    decoder.builder.load_points  = 0;
    249 
    250    decoder.num_subrs     = type1->num_subrs;
    251    decoder.subrs         = type1->subrs;
    252    decoder.subrs_len     = type1->subrs_len;
    253    decoder.subrs_hash    = type1->subrs_hash;
    254 
    255    decoder.buildchar     = face->buildchar;
    256    decoder.len_buildchar = face->len_buildchar;
    257 
    258    *max_advance = 0;
    259 
    260    FT_TRACE6(( "T1_Compute_Max_Advance:\n" ));
    261 
    262    /* for each glyph, parse the glyph charstring and extract */
    263    /* the advance width                                      */
    264    for ( glyph_index = 0; glyph_index < type1->num_glyphs; glyph_index++ )
    265    {
    266      /* now get load the unscaled outline */
    267      (void)T1_Parse_Glyph( &decoder, (FT_UInt)glyph_index );
    268      if ( glyph_index == 0 || decoder.builder.advance.x > *max_advance )
    269        *max_advance = decoder.builder.advance.x;
    270 
    271      /* ignore the error if one occurred - skip to next glyph */
    272    }
    273 
    274    FT_TRACE6(( "T1_Compute_Max_Advance: max advance: %f\n",
    275                (double)*max_advance / 65536 ));
    276 
    277    psaux->t1_decoder_funcs->done( &decoder );
    278 
    279    return FT_Err_Ok;
    280  }
    281 
    282 
    283  FT_LOCAL_DEF( FT_Error )
    284  T1_Get_Advances( FT_Face    t1face,        /* T1_Face */
    285                   FT_UInt    first,
    286                   FT_UInt    count,
    287                   FT_Int32   load_flags,
    288                   FT_Fixed*  advances )
    289  {
    290    T1_Face        face  = (T1_Face)t1face;
    291    T1_DecoderRec  decoder;
    292    T1_Font        type1 = &face->type1;
    293    PSAux_Service  psaux = (PSAux_Service)face->psaux;
    294    FT_UInt        nn;
    295    FT_Error       error;
    296 
    297 
    298    FT_TRACE5(( "T1_Get_Advances:\n" ));
    299 
    300    if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )
    301    {
    302      for ( nn = 0; nn < count; nn++ )
    303      {
    304        advances[nn] = 0;
    305 
    306        FT_TRACE5(( "  idx %u: advance height 0 font units\n",
    307                    first + nn ));
    308      }
    309 
    310      return FT_Err_Ok;
    311    }
    312 
    313    error = psaux->t1_decoder_funcs->init( &decoder,
    314                                           (FT_Face)face,
    315                                           0, /* size       */
    316                                           0, /* glyph slot */
    317                                           (FT_Byte**)type1->glyph_names,
    318                                           face->blend,
    319                                           0,
    320                                           FT_RENDER_MODE_NORMAL,
    321                                           T1_Parse_Glyph );
    322    if ( error )
    323      return error;
    324 
    325    decoder.builder.metrics_only = 1;
    326    decoder.builder.load_points  = 0;
    327 
    328    decoder.num_subrs  = type1->num_subrs;
    329    decoder.subrs      = type1->subrs;
    330    decoder.subrs_len  = type1->subrs_len;
    331    decoder.subrs_hash = type1->subrs_hash;
    332 
    333    decoder.buildchar     = face->buildchar;
    334    decoder.len_buildchar = face->len_buildchar;
    335 
    336    for ( nn = 0; nn < count; nn++ )
    337    {
    338      error = T1_Parse_Glyph( &decoder, first + nn );
    339      if ( !error )
    340        advances[nn] = FIXED_TO_INT( decoder.builder.advance.x );
    341      else
    342        advances[nn] = 0;
    343 
    344      FT_TRACE5(( "  idx %u: advance width %ld font unit%s\n",
    345                  first + nn,
    346                  advances[nn],
    347                  advances[nn] == 1 ? "" : "s" ));
    348    }
    349 
    350    return FT_Err_Ok;
    351  }
    352 
    353 
    354  FT_LOCAL_DEF( FT_Error )
    355  T1_Load_Glyph( FT_GlyphSlot  t1glyph,          /* T1_GlyphSlot */
    356                 FT_Size       t1size,           /* T1_Size      */
    357                 FT_UInt       glyph_index,
    358                 FT_Int32      load_flags )
    359  {
    360    T1_GlyphSlot            glyph = (T1_GlyphSlot)t1glyph;
    361    FT_Error                error;
    362    T1_DecoderRec           decoder;
    363    T1_Face                 face = (T1_Face)t1glyph->face;
    364    FT_Bool                 hinting;
    365    FT_Bool                 scaled;
    366    FT_Bool                 force_scaling = FALSE;
    367    T1_Font                 type1         = &face->type1;
    368    PSAux_Service           psaux         = (PSAux_Service)face->psaux;
    369    const T1_Decoder_Funcs  decoder_funcs = psaux->t1_decoder_funcs;
    370 
    371    FT_Matrix               font_matrix;
    372    FT_Vector               font_offset;
    373    FT_Data                 glyph_data;
    374    FT_Bool                 must_finish_decoder = FALSE;
    375 #ifdef FT_CONFIG_OPTION_INCREMENTAL
    376    FT_Bool                 glyph_data_loaded = 0;
    377 #endif
    378 
    379 
    380 #ifdef FT_CONFIG_OPTION_INCREMENTAL
    381    if ( glyph_index >= (FT_UInt)face->root.num_glyphs &&
    382         !face->root.internal->incremental_interface   )
    383 #else
    384    if ( glyph_index >= (FT_UInt)face->root.num_glyphs )
    385 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
    386    {
    387      error = FT_THROW( Invalid_Argument );
    388      goto Exit;
    389    }
    390 
    391    FT_TRACE1(( "T1_Load_Glyph: glyph index %u\n", glyph_index ));
    392 
    393    FT_ASSERT( ( face->len_buildchar == 0 ) == ( face->buildchar == NULL ) );
    394 
    395    if ( load_flags & FT_LOAD_NO_RECURSE )
    396      load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
    397 
    398    if ( t1size )
    399    {
    400      glyph->x_scale = t1size->metrics.x_scale;
    401      glyph->y_scale = t1size->metrics.y_scale;
    402    }
    403    else
    404    {
    405      glyph->x_scale = 0x10000L;
    406      glyph->y_scale = 0x10000L;
    407    }
    408 
    409    hinting = FT_BOOL( !( load_flags & FT_LOAD_NO_SCALE   ) &&
    410                       !( load_flags & FT_LOAD_NO_HINTING ) );
    411    scaled  = FT_BOOL( !( load_flags & FT_LOAD_NO_SCALE   ) );
    412 
    413    glyph->hint     = hinting;
    414    glyph->scaled   = scaled;
    415 
    416    error = decoder_funcs->init( &decoder,
    417                                 t1glyph->face,
    418                                 t1size,
    419                                 t1glyph,
    420                                 (FT_Byte**)type1->glyph_names,
    421                                 face->blend,
    422                                 hinting,
    423                                 FT_LOAD_TARGET_MODE( load_flags ),
    424                                 T1_Parse_Glyph );
    425    if ( error )
    426      goto Exit;
    427 
    428    must_finish_decoder = TRUE;
    429 
    430    decoder.builder.no_recurse = FT_BOOL( load_flags & FT_LOAD_NO_RECURSE );
    431 
    432    decoder.num_subrs     = type1->num_subrs;
    433    decoder.subrs         = type1->subrs;
    434    decoder.subrs_len     = type1->subrs_len;
    435    decoder.subrs_hash    = type1->subrs_hash;
    436 
    437    decoder.buildchar     = face->buildchar;
    438    decoder.len_buildchar = face->len_buildchar;
    439 
    440    /* now load the unscaled outline */
    441    error = T1_Parse_Glyph_And_Get_Char_String( &decoder, glyph_index,
    442                                                &glyph_data,
    443                                                &force_scaling );
    444    if ( error )
    445      goto Exit;
    446 #ifdef FT_CONFIG_OPTION_INCREMENTAL
    447    glyph_data_loaded = 1;
    448 #endif
    449 
    450    hinting     = glyph->hint;
    451    font_matrix = decoder.font_matrix;
    452    font_offset = decoder.font_offset;
    453 
    454    /* save new glyph tables */
    455    decoder_funcs->done( &decoder );
    456 
    457    must_finish_decoder = FALSE;
    458 
    459    if ( !error )
    460    {
    461      /* now, set the metrics -- this is rather simple, as   */
    462      /* the left side bearing is the xMin, and the top side */
    463      /* bearing the yMax; for composite glyphs, return only */
    464      /* left side bearing and advance width                 */
    465      if ( load_flags & FT_LOAD_NO_RECURSE )
    466      {
    467        FT_Slot_Internal  internal = t1glyph->internal;
    468 
    469 
    470        t1glyph->metrics.horiBearingX =
    471          FIXED_TO_INT( decoder.builder.left_bearing.x );
    472        t1glyph->metrics.horiAdvance  =
    473          FIXED_TO_INT( decoder.builder.advance.x );
    474 
    475        internal->glyph_matrix      = font_matrix;
    476        internal->glyph_delta       = font_offset;
    477        internal->glyph_transformed = 1;
    478      }
    479      else
    480      {
    481        FT_BBox            cbox;
    482        FT_Glyph_Metrics*  metrics = &t1glyph->metrics;
    483 
    484 
    485        t1glyph->format = FT_GLYPH_FORMAT_OUTLINE;
    486 
    487        t1glyph->outline.flags &= FT_OUTLINE_OWNER;
    488        t1glyph->outline.flags |= FT_OUTLINE_REVERSE_FILL;
    489        if ( t1size && t1size->metrics.y_ppem < 24 )
    490          t1glyph->outline.flags |= FT_OUTLINE_HIGH_PRECISION;
    491 
    492        /* copy the _unscaled_ advance width */
    493        metrics->horiAdvance =
    494          FIXED_TO_INT( decoder.builder.advance.x );
    495        t1glyph->linearHoriAdvance =
    496          FIXED_TO_INT( decoder.builder.advance.x );
    497        t1glyph->internal->glyph_transformed = 0;
    498 
    499        if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )
    500        {
    501          /* make up vertical ones */
    502          metrics->vertAdvance = ( face->type1.font_bbox.yMax -
    503                                   face->type1.font_bbox.yMin ) >> 16;
    504          t1glyph->linearVertAdvance = metrics->vertAdvance;
    505        }
    506        else
    507        {
    508          metrics->vertAdvance =
    509            FIXED_TO_INT( decoder.builder.advance.y );
    510          t1glyph->linearVertAdvance =
    511            FIXED_TO_INT( decoder.builder.advance.y );
    512        }
    513 
    514 #if 1
    515        /* apply the font matrix, if any */
    516        if ( font_matrix.xx != 0x10000L || font_matrix.yy != 0x10000L ||
    517             font_matrix.xy != 0        || font_matrix.yx != 0        )
    518        {
    519          FT_Outline_Transform( &t1glyph->outline, &font_matrix );
    520 
    521          metrics->horiAdvance = FT_MulFix( metrics->horiAdvance,
    522                                            font_matrix.xx );
    523          metrics->vertAdvance = FT_MulFix( metrics->vertAdvance,
    524                                            font_matrix.yy );
    525        }
    526 
    527        if ( font_offset.x || font_offset.y )
    528        {
    529          FT_Outline_Translate( &t1glyph->outline,
    530                                font_offset.x,
    531                                font_offset.y );
    532 
    533          metrics->horiAdvance += font_offset.x;
    534          metrics->vertAdvance += font_offset.y;
    535        }
    536 #endif
    537 
    538        if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 || force_scaling )
    539        {
    540          /* scale the outline and the metrics */
    541          FT_Int       n;
    542          FT_Outline*  cur = decoder.builder.base;
    543          FT_Vector*   vec = cur->points;
    544          FT_Fixed     x_scale = glyph->x_scale;
    545          FT_Fixed     y_scale = glyph->y_scale;
    546 
    547 
    548          /* First of all, scale the points, if we are not hinting */
    549          if ( !hinting || !decoder.builder.hints_funcs )
    550            for ( n = cur->n_points; n > 0; n--, vec++ )
    551            {
    552              vec->x = FT_MulFix( vec->x, x_scale );
    553              vec->y = FT_MulFix( vec->y, y_scale );
    554            }
    555 
    556          /* Then scale the metrics */
    557          metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale );
    558          metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale );
    559        }
    560 
    561        /* compute the other metrics */
    562        FT_Outline_Get_CBox( &t1glyph->outline, &cbox );
    563 
    564        metrics->width  = cbox.xMax - cbox.xMin;
    565        metrics->height = cbox.yMax - cbox.yMin;
    566 
    567        metrics->horiBearingX = cbox.xMin;
    568        metrics->horiBearingY = cbox.yMax;
    569 
    570        if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )
    571        {
    572          /* make up vertical ones */
    573          ft_synthesize_vertical_metrics( metrics,
    574                                          metrics->vertAdvance );
    575        }
    576      }
    577 
    578      /* Set control data to the glyph charstrings.  Note that this is */
    579      /* _not_ zero-terminated.                                        */
    580      t1glyph->control_data = (FT_Byte*)glyph_data.pointer;
    581      t1glyph->control_len  = glyph_data.length;
    582    }
    583 
    584 
    585  Exit:
    586 
    587 #ifdef FT_CONFIG_OPTION_INCREMENTAL
    588    if ( glyph_data_loaded && face->root.internal->incremental_interface )
    589    {
    590      face->root.internal->incremental_interface->funcs->free_glyph_data(
    591        face->root.internal->incremental_interface->object,
    592        &glyph_data );
    593 
    594      /* Set the control data to null - it is no longer available if   */
    595      /* loaded incrementally.                                         */
    596      t1glyph->control_data = NULL;
    597      t1glyph->control_len  = 0;
    598    }
    599 #endif
    600 
    601    if ( must_finish_decoder )
    602      decoder_funcs->done( &decoder );
    603 
    604    return error;
    605  }
    606 
    607 
    608 /* END */