tor-browser

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

pfrcmap.c (4519B)


      1 /****************************************************************************
      2 *
      3 * pfrcmap.c
      4 *
      5 *   FreeType PFR cmap handling (body).
      6 *
      7 * Copyright (C) 2002-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 <freetype/internal/ftdebug.h>
     20 #include "pfrcmap.h"
     21 #include "pfrobjs.h"
     22 
     23 #include "pfrerror.h"
     24 
     25 
     26  FT_CALLBACK_DEF( FT_Error )
     27  pfr_cmap_init( FT_CMap     cmap,     /* PFR_CMap */
     28                 FT_Pointer  pointer )
     29  {
     30    PFR_CMap  pfrcmap = (PFR_CMap)cmap;
     31    FT_Error  error   = FT_Err_Ok;
     32    PFR_Face  face    = (PFR_Face)FT_CMAP_FACE( cmap );
     33 
     34    FT_UNUSED( pointer );
     35 
     36 
     37    pfrcmap->num_chars = face->phy_font.num_chars;
     38    pfrcmap->chars     = face->phy_font.chars;
     39 
     40    /* just for safety, check that the character entries are correctly */
     41    /* sorted in increasing character code order                       */
     42    {
     43      FT_UInt  n;
     44 
     45 
     46      for ( n = 1; n < pfrcmap->num_chars; n++ )
     47      {
     48        if ( pfrcmap->chars[n - 1].char_code >= pfrcmap->chars[n].char_code )
     49        {
     50          error = FT_THROW( Invalid_Table );
     51          goto Exit;
     52        }
     53      }
     54    }
     55 
     56  Exit:
     57    return error;
     58  }
     59 
     60 
     61  FT_CALLBACK_DEF( void )
     62  pfr_cmap_done( FT_CMap  cmap )    /* PFR_CMap */
     63  {
     64    PFR_CMap  pfrcmap = (PFR_CMap)cmap;
     65 
     66 
     67    pfrcmap->chars     = NULL;
     68    pfrcmap->num_chars = 0;
     69  }
     70 
     71 
     72  FT_CALLBACK_DEF( FT_UInt )
     73  pfr_cmap_char_index( FT_CMap    cmap,       /* PFR_CMap */
     74                       FT_UInt32  char_code )
     75  {
     76    PFR_CMap  pfrcmap = (PFR_CMap)cmap;
     77    FT_UInt   min     = 0;
     78    FT_UInt   max     = pfrcmap->num_chars;
     79    FT_UInt   mid     = min + ( max - min ) / 2;
     80    PFR_Char  gchar;
     81 
     82 
     83    while ( min < max )
     84    {
     85      gchar = pfrcmap->chars + mid;
     86 
     87      if ( gchar->char_code == char_code )
     88        return mid + 1;
     89 
     90      if ( gchar->char_code < char_code )
     91        min = mid + 1;
     92      else
     93        max = mid;
     94 
     95      /* reasonable prediction in a continuous block */
     96      mid += char_code - gchar->char_code;
     97      if ( mid >= max || mid < min )
     98        mid = min + ( max - min ) / 2;
     99    }
    100    return 0;
    101  }
    102 
    103 
    104  FT_CALLBACK_DEF( FT_UInt )
    105  pfr_cmap_char_next( FT_CMap     cmap,        /* PFR_CMap */
    106                      FT_UInt32  *pchar_code )
    107  {
    108    PFR_CMap   pfrcmap   = (PFR_CMap)cmap;
    109    FT_UInt    result    = 0;
    110    FT_UInt32  char_code = *pchar_code + 1;
    111 
    112 
    113  Restart:
    114    {
    115      FT_UInt   min = 0;
    116      FT_UInt   max = pfrcmap->num_chars;
    117      FT_UInt   mid = min + ( max - min ) / 2;
    118      PFR_Char  gchar;
    119 
    120 
    121      while ( min < max )
    122      {
    123        gchar = pfrcmap->chars + mid;
    124 
    125        if ( gchar->char_code == char_code )
    126        {
    127          result = mid;
    128          if ( result != 0 )
    129          {
    130            result++;
    131            goto Exit;
    132          }
    133 
    134          char_code++;
    135          goto Restart;
    136        }
    137 
    138        if ( gchar->char_code < char_code )
    139          min = mid + 1;
    140        else
    141          max = mid;
    142 
    143        /* reasonable prediction in a continuous block */
    144        mid += char_code - gchar->char_code;
    145        if ( mid >= max || mid < min )
    146          mid = min + ( max - min ) / 2;
    147      }
    148 
    149      /* we didn't find it, but we have a pair just above it */
    150      char_code = 0;
    151 
    152      if ( min < pfrcmap->num_chars )
    153      {
    154        gchar  = pfrcmap->chars + min;
    155        result = min;
    156        if ( result != 0 )
    157        {
    158          result++;
    159          char_code = gchar->char_code;
    160        }
    161      }
    162    }
    163 
    164  Exit:
    165    *pchar_code = char_code;
    166    return result;
    167  }
    168 
    169 
    170  FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec
    171  pfr_cmap_class_rec =
    172  {
    173    sizeof ( PFR_CMapRec ),
    174 
    175    (FT_CMap_InitFunc)     pfr_cmap_init,        /* init       */
    176    (FT_CMap_DoneFunc)     pfr_cmap_done,        /* done       */
    177    (FT_CMap_CharIndexFunc)pfr_cmap_char_index,  /* char_index */
    178    (FT_CMap_CharNextFunc) pfr_cmap_char_next,   /* char_next  */
    179 
    180    (FT_CMap_CharVarIndexFunc)    NULL,  /* char_var_index   */
    181    (FT_CMap_CharVarIsDefaultFunc)NULL,  /* char_var_default */
    182    (FT_CMap_VariantListFunc)     NULL,  /* variant_list     */
    183    (FT_CMap_CharVariantListFunc) NULL,  /* charvariant_list */
    184    (FT_CMap_VariantCharListFunc) NULL   /* variantchar_list */
    185  };
    186 
    187 
    188 /* END */