xref: /inferno-os/libfreetype/pfrcmap.c (revision 7ef44d652ae9e5e1f5b3465d73684e4a54de73c0)
1  /***************************************************************************/
2  /*                                                                         */
3  /*  pfrcmap.c                                                              */
4  /*                                                                         */
5  /*    FreeType PFR cmap handling (body).                                   */
6  /*                                                                         */
7  /*  Copyright 2002 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 "pfrcmap.h"
20  #include "pfrobjs.h"
21  #include FT_INTERNAL_DEBUG_H
22  
23  
24    FT_CALLBACK_DEF( FT_Error )
25    pfr_cmap_init( PFR_CMap  cmap )
26    {
27      PFR_Face  face = (PFR_Face)FT_CMAP_FACE( cmap );
28  
29  
30      cmap->num_chars = face->phy_font.num_chars;
31      cmap->chars     = face->phy_font.chars;
32  
33      /* just for safety, check that the character entries are correctly */
34      /* sorted in increasing character code order                       */
35      {
36        FT_UInt  n;
37  
38  
39        for ( n = 1; n < cmap->num_chars; n++ )
40        {
41          if ( cmap->chars[n - 1].char_code >= cmap->chars[n].char_code )
42            FT_ASSERT( 0 );
43        }
44      }
45  
46      return 0;
47    }
48  
49  
50    FT_CALLBACK_DEF( void )
51    pfr_cmap_done( PFR_CMap  cmap )
52    {
53      cmap->chars     = NULL;
54      cmap->num_chars = 0;
55    }
56  
57  
58    FT_CALLBACK_DEF( FT_UInt )
59    pfr_cmap_char_index( PFR_CMap   cmap,
60                         FT_UInt32  char_code )
61    {
62      FT_UInt   min = 0;
63      FT_UInt   max = cmap->num_chars;
64      FT_UInt   mid;
65      PFR_Char  gchar;
66  
67  
68      while ( min < max )
69      {
70        mid   = min + ( max - min ) / 2;
71        gchar = cmap->chars + mid;
72  
73        if ( gchar->char_code == char_code )
74          return mid + 1;
75  
76        if ( gchar->char_code < char_code )
77          min = mid + 1;
78        else
79          max = mid;
80      }
81      return 0;
82    }
83  
84  
85    FT_CALLBACK_DEF( FT_UInt )
86    pfr_cmap_char_next( PFR_CMap    cmap,
87                        FT_UInt32  *pchar_code )
88    {
89      FT_UInt    result    = 0;
90      FT_UInt32  char_code = *pchar_code + 1;
91  
92  
93    Restart:
94      {
95        FT_UInt   min = 0;
96        FT_UInt   max = cmap->num_chars;
97        FT_UInt   mid;
98        PFR_Char  gchar;
99  
100  
101        while ( min < max )
102        {
103          mid   = min + ( ( max - min ) >> 1 );
104          gchar = cmap->chars + mid;
105  
106          if ( gchar->char_code == char_code )
107          {
108            result = mid;
109            if ( result != 0 )
110            {
111              result++;
112              goto Exit;
113            }
114  
115            char_code++;
116            goto Restart;
117          }
118  
119          if ( gchar->char_code < char_code )
120            min = mid+1;
121          else
122            max = mid;
123        }
124  
125        /* we didn't find it, but we have a pair just above it */
126        char_code = 0;
127  
128        if ( min < cmap->num_chars )
129        {
130          gchar  = cmap->chars + min;
131          result = min;
132          if ( result != 0 )
133          {
134            result++;
135            char_code = gchar->char_code;
136          }
137        }
138      }
139  
140    Exit:
141      *pchar_code = char_code;
142      return result;
143    }
144  
145  
146    FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec
147    pfr_cmap_class_rec =
148    {
149      sizeof ( PFR_CMapRec ),
150  
151      (FT_CMap_InitFunc)     pfr_cmap_init,
152      (FT_CMap_DoneFunc)     pfr_cmap_done,
153      (FT_CMap_CharIndexFunc)pfr_cmap_char_index,
154      (FT_CMap_CharNextFunc) pfr_cmap_char_next
155    };
156  
157  
158  /* END */
159