(root)/
freetype-2.13.2/
src/
pfr/
pfrcmap.c
       1  /****************************************************************************
       2   *
       3   * pfrcmap.c
       4   *
       5   *   FreeType PFR cmap handling (body).
       6   *
       7   * Copyright (C) 2002-2023 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 */