psmodule.c 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. /***************************************************************************/
  2. /* */
  3. /* psmodule.c */
  4. /* */
  5. /* PSNames module implementation (body). */
  6. /* */
  7. /* Copyright 1996-2001, 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. #include <ft2build.h>
  18. #include FT_INTERNAL_POSTSCRIPT_NAMES_H
  19. #include FT_INTERNAL_OBJECTS_H
  20. #include "psmodule.h"
  21. #include "pstables.h"
  22. #include "psnamerr.h"
  23. #ifndef FT_CONFIG_OPTION_NO_POSTSCRIPT_NAMES
  24. #ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST
  25. /* return the Unicode value corresponding to a given glyph. Note that */
  26. /* we do deal with glyph variants by detecting a non-initial dot in */
  27. /* the name, as in `A.swash' or `e.final', etc. */
  28. /* */
  29. static FT_UInt32
  30. ps_unicode_value( const char* glyph_name )
  31. {
  32. FT_Int n;
  33. char first = glyph_name[0];
  34. char temp[64];
  35. /* if the name begins with `uni', then the glyph name may be a */
  36. /* hard-coded unicode character code. */
  37. if ( glyph_name[0] == 'u' &&
  38. glyph_name[1] == 'n' &&
  39. glyph_name[2] == 'i' )
  40. {
  41. /* determine whether the next four characters following are */
  42. /* hexadecimal. */
  43. /* XXX: Add code to deal with ligatures, i.e. glyph names like */
  44. /* `uniXXXXYYYYZZZZ'... */
  45. FT_Int count;
  46. FT_ULong value = 0;
  47. const char* p = glyph_name + 3;
  48. for ( count = 4; count > 0; count--, p++ )
  49. {
  50. char c = *p;
  51. unsigned int d;
  52. d = (unsigned char)c - '0';
  53. if ( d >= 10 )
  54. {
  55. d = (unsigned char)c - 'A';
  56. if ( d >= 6 )
  57. d = 16;
  58. else
  59. d += 10;
  60. }
  61. /* exit if a non-uppercase hexadecimal character was found */
  62. if ( d >= 16 )
  63. break;
  64. value = ( value << 4 ) + d;
  65. }
  66. if ( count == 0 )
  67. return value;
  68. }
  69. /* look for a non-initial dot in the glyph name in order to */
  70. /* sort-out variants like `A.swash', `e.final', etc. */
  71. {
  72. const char* p;
  73. int len;
  74. p = glyph_name;
  75. while ( *p && *p != '.' )
  76. p++;
  77. len = (int)( p - glyph_name );
  78. if ( *p && len < 64 )
  79. {
  80. ft_strncpy( temp, glyph_name, len );
  81. temp[len] = 0;
  82. glyph_name = temp;
  83. }
  84. }
  85. /* now, look up the glyph in the Adobe Glyph List */
  86. for ( n = 0; n < NUM_ADOBE_GLYPHS; n++ )
  87. {
  88. const char* name = sid_standard_names[n];
  89. if ( first == name[0] && ft_strcmp( glyph_name, name ) == 0 )
  90. return ps_names_to_unicode[n];
  91. }
  92. /* not found, there is probably no Unicode value for this glyph name */
  93. return 0;
  94. }
  95. /* ft_qsort callback to sort the unicode map */
  96. FT_CALLBACK_DEF( int )
  97. compare_uni_maps( const void* a,
  98. const void* b )
  99. {
  100. PS_UniMap* map1 = (PS_UniMap*)a;
  101. PS_UniMap* map2 = (PS_UniMap*)b;
  102. return ( map1->unicode - map2->unicode );
  103. }
  104. /* Builds a table that maps Unicode values to glyph indices */
  105. static FT_Error
  106. ps_build_unicode_table( FT_Memory memory,
  107. FT_UInt num_glyphs,
  108. const char** glyph_names,
  109. PS_Unicodes* table )
  110. {
  111. FT_Error error;
  112. /* we first allocate the table */
  113. table->num_maps = 0;
  114. table->maps = 0;
  115. if ( !FT_NEW_ARRAY( table->maps, num_glyphs ) )
  116. {
  117. FT_UInt n;
  118. FT_UInt count;
  119. PS_UniMap* map;
  120. FT_UInt32 uni_char;
  121. map = table->maps;
  122. for ( n = 0; n < num_glyphs; n++ )
  123. {
  124. const char* gname = glyph_names[n];
  125. if ( gname )
  126. {
  127. uni_char = ps_unicode_value( gname );
  128. if ( uni_char != 0 && uni_char != 0xFFFF )
  129. {
  130. map->unicode = uni_char;
  131. map->glyph_index = n;
  132. map++;
  133. }
  134. }
  135. }
  136. /* now, compress the table a bit */
  137. count = (FT_UInt)( map - table->maps );
  138. if ( count > 0 && FT_REALLOC( table->maps,
  139. num_glyphs * sizeof ( PS_UniMap ),
  140. count * sizeof ( PS_UniMap ) ) )
  141. count = 0;
  142. if ( count == 0 )
  143. {
  144. FT_FREE( table->maps );
  145. if ( !error )
  146. error = PSnames_Err_Invalid_Argument; /* no unicode chars here! */
  147. }
  148. else
  149. /* sort the table in increasing order of unicode values */
  150. ft_qsort( table->maps, count, sizeof ( PS_UniMap ), compare_uni_maps );
  151. table->num_maps = count;
  152. }
  153. return error;
  154. }
  155. static FT_UInt
  156. ps_lookup_unicode( PS_Unicodes* table,
  157. FT_ULong unicode )
  158. {
  159. PS_UniMap *min, *max, *mid;
  160. /* perform a binary search on the table */
  161. min = table->maps;
  162. max = min + table->num_maps - 1;
  163. while ( min <= max )
  164. {
  165. mid = min + ( max - min ) / 2;
  166. if ( mid->unicode == unicode )
  167. return mid->glyph_index;
  168. if ( min == max )
  169. break;
  170. if ( mid->unicode < unicode )
  171. min = mid + 1;
  172. else
  173. max = mid - 1;
  174. }
  175. return 0xFFFF;
  176. }
  177. static FT_ULong
  178. ps_next_unicode( PS_Unicodes* table,
  179. FT_ULong unicode )
  180. {
  181. PS_UniMap *min, *max, *mid;
  182. unicode++;
  183. /* perform a binary search on the table */
  184. min = table->maps;
  185. max = min + table->num_maps - 1;
  186. while ( min <= max )
  187. {
  188. mid = min + ( max - min ) / 2;
  189. if ( mid->unicode == unicode )
  190. return unicode;
  191. if ( min == max )
  192. break;
  193. if ( mid->unicode < unicode )
  194. min = mid + 1;
  195. else
  196. max = mid - 1;
  197. }
  198. if ( max < table->maps )
  199. max = table->maps;
  200. while ( max < table->maps + table->num_maps )
  201. {
  202. if ( unicode < max->unicode )
  203. return max->unicode;
  204. max++;
  205. }
  206. return 0;
  207. }
  208. #endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */
  209. static const char*
  210. ps_get_macintosh_name( FT_UInt name_index )
  211. {
  212. if ( name_index >= 258 )
  213. name_index = 0;
  214. return ps_glyph_names[mac_standard_names[name_index]];
  215. }
  216. static const char*
  217. ps_get_standard_strings( FT_UInt sid )
  218. {
  219. return ( sid < NUM_SID_GLYPHS ? sid_standard_names[sid] : 0 );
  220. }
  221. static
  222. const PSNames_Interface psnames_interface =
  223. {
  224. #ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST
  225. (PS_Unicode_Value_Func) ps_unicode_value,
  226. (PS_Build_Unicodes_Func) ps_build_unicode_table,
  227. (PS_Lookup_Unicode_Func) ps_lookup_unicode,
  228. #else
  229. 0,
  230. 0,
  231. 0,
  232. #endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */
  233. (PS_Macintosh_Name_Func) ps_get_macintosh_name,
  234. (PS_Adobe_Std_Strings_Func) ps_get_standard_strings,
  235. t1_standard_encoding,
  236. t1_expert_encoding,
  237. #ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST
  238. (PS_Next_Unicode_Func) ps_next_unicode
  239. #else
  240. 0
  241. #endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */
  242. };
  243. #endif /* !FT_CONFIG_OPTION_NO_POSTSCRIPT_NAMES */
  244. FT_CALLBACK_TABLE_DEF
  245. const FT_Module_Class psnames_module_class =
  246. {
  247. 0, /* this is not a font driver, nor a renderer */
  248. sizeof ( FT_ModuleRec ),
  249. "psnames", /* driver name */
  250. 0x10000L, /* driver version */
  251. 0x20000L, /* driver requires FreeType 2 or above */
  252. #ifdef FT_CONFIG_OPTION_NO_POSTSCRIPT_NAMES
  253. 0,
  254. #else
  255. (void*)&psnames_interface, /* module specific interface */
  256. #endif
  257. (FT_Module_Constructor)0,
  258. (FT_Module_Destructor) 0,
  259. (FT_Module_Requester) 0
  260. };
  261. /* END */