Werner Lemberg | b94f3d3 | 2002-07-26 14:52:29 +0000 | [diff] [blame] | 1 | /***************************************************************************/ |
| 2 | /* */ |
| 3 | /* cffcmap.c */ |
| 4 | /* */ |
| 5 | /* CFF character mapping table (cmap) support (body). */ |
| 6 | /* */ |
Werner Lemberg | 47bf95d | 2006-01-17 16:55:32 +0000 | [diff] [blame] | 7 | /* Copyright 2002, 2003, 2004, 2005, 2006 by */ |
Werner Lemberg | b94f3d3 | 2002-07-26 14:52:29 +0000 | [diff] [blame] | 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 | |
David Turner | b9b2cac | 2002-07-10 16:52:06 +0000 | [diff] [blame] | 19 | #include "cffcmap.h" |
| 20 | #include "cffload.h" |
| 21 | |
Werner Lemberg | 754d558 | 2003-09-12 20:32:51 +0000 | [diff] [blame] | 22 | #include "cfferrs.h" |
| 23 | |
Werner Lemberg | b94f3d3 | 2002-07-26 14:52:29 +0000 | [diff] [blame] | 24 | |
David Turner | b9b2cac | 2002-07-10 16:52:06 +0000 | [diff] [blame] | 25 | /*************************************************************************/ |
| 26 | /*************************************************************************/ |
| 27 | /***** *****/ |
Werner Lemberg | b94f3d3 | 2002-07-26 14:52:29 +0000 | [diff] [blame] | 28 | /***** CFF STANDARD (AND EXPERT) ENCODING CMAPS *****/ |
David Turner | b9b2cac | 2002-07-10 16:52:06 +0000 | [diff] [blame] | 29 | /***** *****/ |
| 30 | /*************************************************************************/ |
| 31 | /*************************************************************************/ |
| 32 | |
| 33 | FT_CALLBACK_DEF( FT_Error ) |
| 34 | cff_cmap_encoding_init( CFF_CMapStd cmap ) |
| 35 | { |
Werner Lemberg | 7f74a52 | 2002-07-26 09:09:10 +0000 | [diff] [blame] | 36 | TT_Face face = (TT_Face)FT_CMAP_FACE( cmap ); |
Werner Lemberg | 3c403e4 | 2002-08-06 21:47:40 +0000 | [diff] [blame] | 37 | CFF_Font cff = (CFF_Font)face->extra.data; |
Werner Lemberg | 7f74a52 | 2002-07-26 09:09:10 +0000 | [diff] [blame] | 38 | CFF_Encoding encoding = &cff->encoding; |
| 39 | |
David Turner | b9b2cac | 2002-07-10 16:52:06 +0000 | [diff] [blame] | 40 | |
David Turner | b9b2cac | 2002-07-10 16:52:06 +0000 | [diff] [blame] | 41 | cmap->gids = encoding->codes; |
David Turner | b72d8a8 | 2003-09-29 20:33:37 +0000 | [diff] [blame] | 42 | |
David Turner | b9b2cac | 2002-07-10 16:52:06 +0000 | [diff] [blame] | 43 | return 0; |
| 44 | } |
| 45 | |
| 46 | |
| 47 | FT_CALLBACK_DEF( void ) |
| 48 | cff_cmap_encoding_done( CFF_CMapStd cmap ) |
| 49 | { |
David Turner | b9b2cac | 2002-07-10 16:52:06 +0000 | [diff] [blame] | 50 | cmap->gids = NULL; |
| 51 | } |
| 52 | |
| 53 | |
| 54 | FT_CALLBACK_DEF( FT_UInt ) |
| 55 | cff_cmap_encoding_char_index( CFF_CMapStd cmap, |
| 56 | FT_UInt32 char_code ) |
| 57 | { |
| 58 | FT_UInt result = 0; |
| 59 | |
Werner Lemberg | b94f3d3 | 2002-07-26 14:52:29 +0000 | [diff] [blame] | 60 | |
Werner Lemberg | f35ff80 | 2003-06-02 21:58:05 +0000 | [diff] [blame] | 61 | if ( char_code < 256 ) |
Werner Lemberg | b94f3d3 | 2002-07-26 14:52:29 +0000 | [diff] [blame] | 62 | result = cmap->gids[char_code]; |
David Turner | b72d8a8 | 2003-09-29 20:33:37 +0000 | [diff] [blame] | 63 | |
David Turner | b9b2cac | 2002-07-10 16:52:06 +0000 | [diff] [blame] | 64 | return result; |
| 65 | } |
| 66 | |
| 67 | |
| 68 | FT_CALLBACK_DEF( FT_UInt ) |
| 69 | cff_cmap_encoding_char_next( CFF_CMapStd cmap, |
Werner Lemberg | b94f3d3 | 2002-07-26 14:52:29 +0000 | [diff] [blame] | 70 | FT_UInt32 *pchar_code ) |
David Turner | b9b2cac | 2002-07-10 16:52:06 +0000 | [diff] [blame] | 71 | { |
| 72 | FT_UInt result = 0; |
| 73 | FT_UInt32 char_code = *pchar_code; |
David Turner | b72d8a8 | 2003-09-29 20:33:37 +0000 | [diff] [blame] | 74 | |
Werner Lemberg | b94f3d3 | 2002-07-26 14:52:29 +0000 | [diff] [blame] | 75 | |
David Turner | b9b2cac | 2002-07-10 16:52:06 +0000 | [diff] [blame] | 76 | *pchar_code = 0; |
| 77 | |
Werner Lemberg | f35ff80 | 2003-06-02 21:58:05 +0000 | [diff] [blame] | 78 | if ( char_code < 255 ) |
David Turner | b9b2cac | 2002-07-10 16:52:06 +0000 | [diff] [blame] | 79 | { |
Werner Lemberg | b94f3d3 | 2002-07-26 14:52:29 +0000 | [diff] [blame] | 80 | FT_UInt code = (FT_UInt)(char_code + 1); |
David Turner | b72d8a8 | 2003-09-29 20:33:37 +0000 | [diff] [blame] | 81 | |
Werner Lemberg | b94f3d3 | 2002-07-26 14:52:29 +0000 | [diff] [blame] | 82 | |
David Turner | b9b2cac | 2002-07-10 16:52:06 +0000 | [diff] [blame] | 83 | for (;;) |
| 84 | { |
Werner Lemberg | f35ff80 | 2003-06-02 21:58:05 +0000 | [diff] [blame] | 85 | if ( code >= 256 ) |
David Turner | b9b2cac | 2002-07-10 16:52:06 +0000 | [diff] [blame] | 86 | break; |
David Turner | b72d8a8 | 2003-09-29 20:33:37 +0000 | [diff] [blame] | 87 | |
Werner Lemberg | b94f3d3 | 2002-07-26 14:52:29 +0000 | [diff] [blame] | 88 | result = cmap->gids[code]; |
David Turner | b9b2cac | 2002-07-10 16:52:06 +0000 | [diff] [blame] | 89 | if ( result != 0 ) |
| 90 | { |
| 91 | *pchar_code = code; |
| 92 | break; |
| 93 | } |
David Turner | b72d8a8 | 2003-09-29 20:33:37 +0000 | [diff] [blame] | 94 | |
David Turner | b9b2cac | 2002-07-10 16:52:06 +0000 | [diff] [blame] | 95 | code++; |
| 96 | } |
| 97 | } |
| 98 | return result; |
| 99 | } |
| 100 | |
| 101 | |
David Turner | b9b2cac | 2002-07-10 16:52:06 +0000 | [diff] [blame] | 102 | FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec |
| 103 | cff_cmap_encoding_class_rec = |
| 104 | { |
| 105 | sizeof ( CFF_CMapStdRec ), |
| 106 | |
| 107 | (FT_CMap_InitFunc) cff_cmap_encoding_init, |
| 108 | (FT_CMap_DoneFunc) cff_cmap_encoding_done, |
| 109 | (FT_CMap_CharIndexFunc)cff_cmap_encoding_char_index, |
| 110 | (FT_CMap_CharNextFunc) cff_cmap_encoding_char_next |
| 111 | }; |
| 112 | |
| 113 | |
| 114 | /*************************************************************************/ |
| 115 | /*************************************************************************/ |
| 116 | /***** *****/ |
| 117 | /***** CFF SYNTHETIC UNICODE ENCODING CMAP *****/ |
| 118 | /***** *****/ |
| 119 | /*************************************************************************/ |
| 120 | /*************************************************************************/ |
| 121 | |
Werner Lemberg | 47bf95d | 2006-01-17 16:55:32 +0000 | [diff] [blame] | 122 | const char * |
| 123 | cff_sid_to_glyph_name( CFF_Font cff, |
| 124 | FT_UInt idx ) |
David Turner | b9b2cac | 2002-07-10 16:52:06 +0000 | [diff] [blame] | 125 | { |
Werner Lemberg | 47bf95d | 2006-01-17 16:55:32 +0000 | [diff] [blame] | 126 | CFF_Charset charset = &cff->charset; |
| 127 | FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)cff->psnames; |
| 128 | FT_UInt sid = charset->sids[idx]; |
David Turner | b72d8a8 | 2003-09-29 20:33:37 +0000 | [diff] [blame] | 129 | |
David Turner | b9b2cac | 2002-07-10 16:52:06 +0000 | [diff] [blame] | 130 | |
Werner Lemberg | 47bf95d | 2006-01-17 16:55:32 +0000 | [diff] [blame] | 131 | return cff_index_get_sid_string( &cff->string_index, sid, psnames ); |
David Turner | b72d8a8 | 2003-09-29 20:33:37 +0000 | [diff] [blame] | 132 | } |
David Turner | b9b2cac | 2002-07-10 16:52:06 +0000 | [diff] [blame] | 133 | |
| 134 | |
| 135 | FT_CALLBACK_DEF( FT_Error ) |
Werner Lemberg | 47bf95d | 2006-01-17 16:55:32 +0000 | [diff] [blame] | 136 | cff_cmap_unicode_init( PS_Unicodes unicodes ) |
David Turner | b9b2cac | 2002-07-10 16:52:06 +0000 | [diff] [blame] | 137 | { |
Werner Lemberg | 47bf95d | 2006-01-17 16:55:32 +0000 | [diff] [blame] | 138 | TT_Face face = (TT_Face)FT_CMAP_FACE( unicodes ); |
David Turner | b72d8a8 | 2003-09-29 20:33:37 +0000 | [diff] [blame] | 139 | FT_Memory memory = FT_FACE_MEMORY( face ); |
| 140 | CFF_Font cff = (CFF_Font)face->extra.data; |
| 141 | CFF_Charset charset = &cff->charset; |
David Turner | 7760595 | 2003-10-29 21:43:52 +0000 | [diff] [blame] | 142 | FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)cff->psnames; |
David Turner | b9b2cac | 2002-07-10 16:52:06 +0000 | [diff] [blame] | 143 | |
| 144 | |
Werner Lemberg | 8e58ff2 | 2005-02-14 07:25:07 +0000 | [diff] [blame] | 145 | /* can't build Unicode map for CID-keyed font */ |
| 146 | if ( !charset->sids ) |
Werner Lemberg | 47bf95d | 2006-01-17 16:55:32 +0000 | [diff] [blame] | 147 | return CFF_Err_Invalid_Argument; |
Werner Lemberg | 8e58ff2 | 2005-02-14 07:25:07 +0000 | [diff] [blame] | 148 | |
Werner Lemberg | 47bf95d | 2006-01-17 16:55:32 +0000 | [diff] [blame] | 149 | return psnames->unicodes_init( memory, |
| 150 | unicodes, |
| 151 | cff->num_glyphs, |
| 152 | (PS_Glyph_NameFunc)&cff_sid_to_glyph_name, |
| 153 | (FT_Pointer)cff ); |
David Turner | b9b2cac | 2002-07-10 16:52:06 +0000 | [diff] [blame] | 154 | } |
| 155 | |
| 156 | |
| 157 | FT_CALLBACK_DEF( void ) |
Werner Lemberg | 47bf95d | 2006-01-17 16:55:32 +0000 | [diff] [blame] | 158 | cff_cmap_unicode_done( PS_Unicodes unicodes ) |
David Turner | b9b2cac | 2002-07-10 16:52:06 +0000 | [diff] [blame] | 159 | { |
Werner Lemberg | 47bf95d | 2006-01-17 16:55:32 +0000 | [diff] [blame] | 160 | FT_Face face = FT_CMAP_FACE( unicodes ); |
Werner Lemberg | b94f3d3 | 2002-07-26 14:52:29 +0000 | [diff] [blame] | 161 | FT_Memory memory = FT_FACE_MEMORY( face ); |
David Turner | b9b2cac | 2002-07-10 16:52:06 +0000 | [diff] [blame] | 162 | |
David Turner | b72d8a8 | 2003-09-29 20:33:37 +0000 | [diff] [blame] | 163 | |
Werner Lemberg | 47bf95d | 2006-01-17 16:55:32 +0000 | [diff] [blame] | 164 | FT_FREE( unicodes->maps ); |
| 165 | unicodes->num_maps = 0; |
David Turner | b9b2cac | 2002-07-10 16:52:06 +0000 | [diff] [blame] | 166 | } |
| 167 | |
| 168 | |
| 169 | FT_CALLBACK_DEF( FT_UInt ) |
Werner Lemberg | 47bf95d | 2006-01-17 16:55:32 +0000 | [diff] [blame] | 170 | cff_cmap_unicode_char_index( PS_Unicodes unicodes, |
| 171 | FT_UInt32 char_code ) |
David Turner | b9b2cac | 2002-07-10 16:52:06 +0000 | [diff] [blame] | 172 | { |
Werner Lemberg | 47bf95d | 2006-01-17 16:55:32 +0000 | [diff] [blame] | 173 | TT_Face face = (TT_Face)FT_CMAP_FACE( unicodes ); |
| 174 | CFF_Font cff = (CFF_Font)face->extra.data; |
| 175 | FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)cff->psnames; |
David Turner | b9b2cac | 2002-07-10 16:52:06 +0000 | [diff] [blame] | 176 | |
| 177 | |
Werner Lemberg | 47bf95d | 2006-01-17 16:55:32 +0000 | [diff] [blame] | 178 | return psnames->unicodes_char_index( unicodes, char_code ); |
David Turner | b9b2cac | 2002-07-10 16:52:06 +0000 | [diff] [blame] | 179 | } |
| 180 | |
| 181 | |
| 182 | FT_CALLBACK_DEF( FT_UInt ) |
Werner Lemberg | 47bf95d | 2006-01-17 16:55:32 +0000 | [diff] [blame] | 183 | cff_cmap_unicode_char_next( PS_Unicodes unicodes, |
| 184 | FT_UInt32 *pchar_code ) |
David Turner | b9b2cac | 2002-07-10 16:52:06 +0000 | [diff] [blame] | 185 | { |
Werner Lemberg | 47bf95d | 2006-01-17 16:55:32 +0000 | [diff] [blame] | 186 | TT_Face face = (TT_Face)FT_CMAP_FACE( unicodes ); |
| 187 | CFF_Font cff = (CFF_Font)face->extra.data; |
| 188 | FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)cff->psnames; |
David Turner | b9b2cac | 2002-07-10 16:52:06 +0000 | [diff] [blame] | 189 | |
| 190 | |
Werner Lemberg | 47bf95d | 2006-01-17 16:55:32 +0000 | [diff] [blame] | 191 | return psnames->unicodes_char_next( unicodes, pchar_code ); |
David Turner | b9b2cac | 2002-07-10 16:52:06 +0000 | [diff] [blame] | 192 | } |
| 193 | |
| 194 | |
| 195 | FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec |
| 196 | cff_cmap_unicode_class_rec = |
| 197 | { |
Werner Lemberg | 47bf95d | 2006-01-17 16:55:32 +0000 | [diff] [blame] | 198 | sizeof ( PS_UnicodesRec ), |
David Turner | b9b2cac | 2002-07-10 16:52:06 +0000 | [diff] [blame] | 199 | |
| 200 | (FT_CMap_InitFunc) cff_cmap_unicode_init, |
| 201 | (FT_CMap_DoneFunc) cff_cmap_unicode_done, |
| 202 | (FT_CMap_CharIndexFunc)cff_cmap_unicode_char_index, |
| 203 | (FT_CMap_CharNextFunc) cff_cmap_unicode_char_next |
| 204 | }; |
| 205 | |
Werner Lemberg | b94f3d3 | 2002-07-26 14:52:29 +0000 | [diff] [blame] | 206 | |
| 207 | /* END */ |