PageRenderTime 48ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/texlive-2007/libs/libttf/extend/ftxcmap.c

#
C | 348 lines | 204 code | 69 blank | 75 comment | 44 complexity | 34b14440b328cd2d65389693ae3dd485 MD5 | raw file
Possible License(s): AGPL-1.0, BSD-3-Clause, LGPL-3.0, GPL-2.0, CPL-1.0, LGPL-2.1, LGPL-2.0
  1. /*******************************************************************
  2. *
  3. * ftxcmap.h 1.0
  4. *
  5. * API extension for iterating over Cmaps
  6. *
  7. * Copyright 1996-1999 by Juliusz Chroboczek,
  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. #include "ttconfig.h"
  19. #include "ftxcmap.h"
  20. #include "tttypes.h"
  21. #include "ttobjs.h"
  22. #include "tttables.h"
  23. static Long charmap_first4 ( PCMap4, UShort* );
  24. static Long charmap_next4 ( PCMap4, UShort, UShort* );
  25. static Long charmap_last4 ( PCMap4, UShort* );
  26. static UShort charmap_find_id4( PCMap4, UShort, TCMap4Segment*, UShort );
  27. /*******************************************************************
  28. *
  29. * Function : TT_CharMap_First
  30. *
  31. * Description : Returns the first valid character code in a
  32. * given character map. Also returns the corresponding
  33. * glyph index.
  34. *
  35. * Input : charMap handle to the target character map
  36. * id address where the glyph index will be
  37. * be returned in case of success
  38. *
  39. * Output : First valid character code. -1 in case of failure.
  40. *
  41. * Notes :
  42. *
  43. ******************************************************************/
  44. EXPORT_FUNC
  45. TT_Long TT_CharMap_First( TT_CharMap charMap,
  46. TT_UShort* id )
  47. {
  48. PCMapTable cmap;
  49. UShort i, c;
  50. if ( !( cmap = HANDLE_CharMap( charMap ) ) )
  51. return -1;
  52. switch ( cmap->format )
  53. {
  54. case 0:
  55. if ( id )
  56. *id = cmap->c.cmap0.glyphIdArray[0];
  57. return 0;
  58. case 4:
  59. return charmap_first4( &cmap->c.cmap4, id );
  60. case 6:
  61. if ( cmap->c.cmap6.entryCount < 1 )
  62. return -1;
  63. if ( id )
  64. *id = cmap->c.cmap6.glyphIdArray[0];
  65. return cmap->c.cmap6.firstCode;
  66. default:
  67. /* Now loop from 0 to 65535. We can't use a simple "for' on */
  68. /* 16-bits systems, hence the "strange" loop here.. */
  69. i = 0;
  70. do
  71. {
  72. c = TT_Char_Index( charMap, i );
  73. if ( c > 0 )
  74. {
  75. if ( id )
  76. *id = c;
  77. return i;
  78. }
  79. i++;
  80. } while ( i != 0 ); /* because i is UShort! */
  81. return -1;
  82. }
  83. }
  84. static Long charmap_first4( PCMap4 cmap4,
  85. UShort* id )
  86. {
  87. UShort firstCode;
  88. if ( cmap4->segCountX2 / 2 < 1 )
  89. return -1;
  90. firstCode = cmap4->segments[0].startCount;
  91. if ( id )
  92. *id = charmap_find_id4( cmap4, firstCode, &(cmap4->segments[0]), 0 );
  93. return firstCode;
  94. }
  95. /*******************************************************************
  96. *
  97. * Function : TT_CharMap_Next
  98. *
  99. * Description : Returns the next valid character code in a given
  100. * charMap.
  101. *
  102. * Input : charMap handle to the target char. map
  103. * index starting character code
  104. * id address where the glyph index of the next
  105. * character will be returned
  106. *
  107. * Output : Next valid character code after 'index'. -1 in case
  108. * of failure.
  109. *
  110. * Notes :
  111. *
  112. ******************************************************************/
  113. EXPORT_FUNC
  114. TT_Long TT_CharMap_Next( TT_CharMap charMap,
  115. TT_UShort index,
  116. TT_UShort* id )
  117. {
  118. PCMapTable cmap;
  119. UShort i, c;
  120. cmap = HANDLE_CharMap( charMap );
  121. if ( !cmap )
  122. return -1;
  123. switch ( cmap->format )
  124. {
  125. case 0:
  126. if ( index < 255 )
  127. {
  128. if ( id )
  129. *id = cmap->c.cmap0.glyphIdArray[index + 1];
  130. return index + 1;
  131. }
  132. else
  133. return -1;
  134. case 4:
  135. return charmap_next4( &cmap->c.cmap4, index, id );
  136. case 6:
  137. {
  138. UShort firstCode = cmap->c.cmap6.firstCode;
  139. if ( index + 1 < firstCode + cmap->c.cmap6.entryCount )
  140. {
  141. if ( id )
  142. *id = cmap->c.cmap6.glyphIdArray[index + 1 - firstCode];
  143. return index + 1;
  144. }
  145. else
  146. return -1;
  147. }
  148. default:
  149. /* Now loop from 0 to 65535. We can't use a simple "for" on */
  150. /* 16-bits systems, hence the "strange" loop here.. */
  151. i = 0;
  152. do
  153. {
  154. c = TT_Char_Index( charMap, i );
  155. if ( c > 0 )
  156. {
  157. if ( id )
  158. *id = c;
  159. return i;
  160. }
  161. i++;
  162. } while ( i != 0 ); /* because i is UShort! */
  163. return -1;
  164. }
  165. }
  166. static Long charmap_next4( PCMap4 cmap4,
  167. UShort charCode,
  168. UShort* id)
  169. {
  170. UShort segCount, nextCode;
  171. UShort i;
  172. TCMap4Segment seg4;
  173. if ( charCode == 0xFFFF )
  174. return -1; /* get it out of the way now */
  175. segCount = cmap4->segCountX2 / 2;
  176. for ( i = 0; i < segCount; i++ )
  177. if ( charCode < cmap4->segments[i].endCount )
  178. break;
  179. /* Safety check - even though the last endCount should be 0xFFFF */
  180. if ( i >= segCount )
  181. return -1;
  182. seg4 = cmap4->segments[i];
  183. if ( charCode < seg4.startCount )
  184. nextCode = seg4.startCount;
  185. else
  186. nextCode = charCode + 1;
  187. if ( id )
  188. *id = charmap_find_id4( cmap4, nextCode, &seg4, i );
  189. return nextCode;
  190. }
  191. static UShort
  192. charmap_find_id4( PCMap4 cmap4,
  193. UShort charCode,
  194. TCMap4Segment* seg4,
  195. UShort i )
  196. {
  197. UShort index1;
  198. if ( seg4->idRangeOffset == 0 )
  199. return (charCode + seg4->idDelta) & 0xFFFF;
  200. else
  201. {
  202. index1 = seg4->idRangeOffset / 2 + charCode-seg4->startCount -
  203. ( cmap4->segCountX2 / 2 - i );
  204. if ( index1 >= cmap4->numGlyphId || cmap4->glyphIdArray[index1] == 0 )
  205. return 0;
  206. else
  207. return (cmap4->glyphIdArray[index1] + seg4->idDelta) & 0xFFFF;
  208. }
  209. }
  210. /*******************************************************************
  211. *
  212. * Function : TT_CharMap_Last
  213. *
  214. * Description : Returns the last valid character code in a
  215. * given character map. Also returns the corresponding
  216. * glyph index.
  217. *
  218. * Input : charMap handle to the target character map
  219. * id address where the glyph index will be
  220. * be returned in case of success
  221. *
  222. * Output : Last valid character code. -1 in case of failure.
  223. *
  224. * Notes :
  225. *
  226. ******************************************************************/
  227. EXPORT_FUNC
  228. TT_Long TT_CharMap_Last( TT_CharMap charMap,
  229. TT_UShort* id )
  230. {
  231. PCMapTable cmap;
  232. UShort i, c;
  233. if ( !( cmap = HANDLE_CharMap( charMap ) ) )
  234. return -1;
  235. switch ( cmap->format )
  236. {
  237. case 0:
  238. if ( id )
  239. *id = cmap->c.cmap0.glyphIdArray[255];
  240. return 255;
  241. case 4:
  242. return charmap_last4( &cmap->c.cmap4, id );
  243. case 6:
  244. if ( cmap->c.cmap6.entryCount < 1 )
  245. return -1;
  246. if ( id )
  247. *id = cmap->c.cmap6.glyphIdArray[cmap->c.cmap6.entryCount - 1];
  248. return cmap->c.cmap6.firstCode + cmap->c.cmap6.entryCount - 1;
  249. default:
  250. i = 65535;
  251. do
  252. {
  253. c = TT_Char_Index( charMap, i );
  254. if ( c > 0 )
  255. {
  256. if ( id )
  257. *id = c;
  258. return i;
  259. }
  260. i--;
  261. } while ( i != 0 );
  262. return -1;
  263. }
  264. }
  265. static Long charmap_last4( PCMap4 cmap4,
  266. UShort* id )
  267. {
  268. UShort lastCode;
  269. if ( cmap4->segCountX2 / 2 < 1 )
  270. return -1;
  271. lastCode = cmap4->segments[cmap4->segCountX2 / 2 - 1].endCount;
  272. if ( id )
  273. *id = charmap_find_id4( cmap4,
  274. lastCode,
  275. &(cmap4->segments[cmap4->segCountX2 / 2 - 1]),
  276. 0 );
  277. return lastCode;
  278. }
  279. /* END */