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 ) pfr_cmap_init(FT_CMap cmap,FT_Pointer pointer)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 ) pfr_cmap_done(FT_CMap cmap)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 ) pfr_cmap_char_index(FT_CMap cmap,FT_UInt32 char_code)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 ) pfr_cmap_char_next(FT_CMap cmap,FT_UInt32 * pchar_code)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 */ 189