/src/freetype/src/psaux/psconv.c

https://bitbucket.org/cabalistic/ogredeps/ · C · 480 lines · 329 code · 122 blank · 29 comment · 80 complexity · 33e82531950fbcba12e608e6b8d00297 MD5 · raw file

  1. /***************************************************************************/
  2. /* */
  3. /* psconv.c */
  4. /* */
  5. /* Some convenience conversions (body). */
  6. /* */
  7. /* Copyright 2006, 2008, 2009, 2012 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_AUX_H
  19. #include "psconv.h"
  20. #include "psauxerr.h"
  21. /* The following array is used by various functions to quickly convert */
  22. /* digits (both decimal and non-decimal) into numbers. */
  23. #if 'A' == 65
  24. /* ASCII */
  25. static const FT_Char ft_char_table[128] =
  26. {
  27. /* 0x00 */
  28. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  29. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  30. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  31. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1,
  32. -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
  33. 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1,
  34. -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
  35. 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1,
  36. };
  37. /* no character >= 0x80 can represent a valid number */
  38. #define OP >=
  39. #endif /* 'A' == 65 */
  40. #if 'A' == 193
  41. /* EBCDIC */
  42. static const FT_Char ft_char_table[128] =
  43. {
  44. /* 0x80 */
  45. -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, -1, -1, -1, -1, -1, -1,
  46. -1, 19, 20, 21, 22, 23, 24, 25, 26, 27, -1, -1, -1, -1, -1, -1,
  47. -1, -1, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, -1,
  48. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  49. -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, -1, -1, -1, -1, -1, -1,
  50. -1, 19, 20, 21, 22, 23, 24, 25, 26, 27, -1, -1, -1, -1, -1, -1,
  51. -1, -1, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, -1,
  52. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1,
  53. };
  54. /* no character < 0x80 can represent a valid number */
  55. #define OP <
  56. #endif /* 'A' == 193 */
  57. FT_LOCAL_DEF( FT_Int )
  58. PS_Conv_Strtol( FT_Byte** cursor,
  59. FT_Byte* limit,
  60. FT_Int base )
  61. {
  62. FT_Byte* p = *cursor;
  63. FT_Int num = 0;
  64. FT_Bool sign = 0;
  65. if ( p >= limit || base < 2 || base > 36 )
  66. return 0;
  67. if ( *p == '-' || *p == '+' )
  68. {
  69. sign = FT_BOOL( *p == '-' );
  70. p++;
  71. if ( p == limit )
  72. return 0;
  73. }
  74. for ( ; p < limit; p++ )
  75. {
  76. FT_Char c;
  77. if ( IS_PS_SPACE( *p ) || *p OP 0x80 )
  78. break;
  79. c = ft_char_table[*p & 0x7f];
  80. if ( c < 0 || c >= base )
  81. break;
  82. num = num * base + c;
  83. }
  84. if ( sign )
  85. num = -num;
  86. *cursor = p;
  87. return num;
  88. }
  89. FT_LOCAL_DEF( FT_Int )
  90. PS_Conv_ToInt( FT_Byte** cursor,
  91. FT_Byte* limit )
  92. {
  93. FT_Byte* p;
  94. FT_Int num;
  95. num = PS_Conv_Strtol( cursor, limit, 10 );
  96. p = *cursor;
  97. if ( p < limit && *p == '#' )
  98. {
  99. *cursor = p + 1;
  100. return PS_Conv_Strtol( cursor, limit, num );
  101. }
  102. else
  103. return num;
  104. }
  105. FT_LOCAL_DEF( FT_Fixed )
  106. PS_Conv_ToFixed( FT_Byte** cursor,
  107. FT_Byte* limit,
  108. FT_Int power_ten )
  109. {
  110. FT_Byte* p = *cursor;
  111. FT_Fixed integral;
  112. FT_Long decimal = 0, divider = 1;
  113. FT_Bool sign = 0;
  114. if ( p >= limit )
  115. return 0;
  116. if ( *p == '-' || *p == '+' )
  117. {
  118. sign = FT_BOOL( *p == '-' );
  119. p++;
  120. if ( p == limit )
  121. return 0;
  122. }
  123. if ( *p != '.' )
  124. integral = PS_Conv_ToInt( &p, limit ) << 16;
  125. else
  126. integral = 0;
  127. /* read the decimal part */
  128. if ( p < limit && *p == '.' )
  129. {
  130. p++;
  131. for ( ; p < limit; p++ )
  132. {
  133. FT_Char c;
  134. if ( IS_PS_SPACE( *p ) || *p OP 0x80 )
  135. break;
  136. c = ft_char_table[*p & 0x7f];
  137. if ( c < 0 || c >= 10 )
  138. break;
  139. if ( !integral && power_ten > 0 )
  140. {
  141. power_ten--;
  142. decimal = decimal * 10 + c;
  143. }
  144. else
  145. {
  146. if ( divider < 10000000L )
  147. {
  148. decimal = decimal * 10 + c;
  149. divider *= 10;
  150. }
  151. }
  152. }
  153. }
  154. /* read exponent, if any */
  155. if ( p + 1 < limit && ( *p == 'e' || *p == 'E' ) )
  156. {
  157. p++;
  158. power_ten += PS_Conv_ToInt( &p, limit );
  159. }
  160. while ( power_ten > 0 )
  161. {
  162. integral *= 10;
  163. decimal *= 10;
  164. power_ten--;
  165. }
  166. while ( power_ten < 0 )
  167. {
  168. integral /= 10;
  169. divider *= 10;
  170. power_ten++;
  171. }
  172. if ( decimal )
  173. integral += FT_DivFix( decimal, divider );
  174. if ( sign )
  175. integral = -integral;
  176. *cursor = p;
  177. return integral;
  178. }
  179. #if 0
  180. FT_LOCAL_DEF( FT_UInt )
  181. PS_Conv_StringDecode( FT_Byte** cursor,
  182. FT_Byte* limit,
  183. FT_Byte* buffer,
  184. FT_Offset n )
  185. {
  186. FT_Byte* p;
  187. FT_UInt r = 0;
  188. for ( p = *cursor; r < n && p < limit; p++ )
  189. {
  190. FT_Byte b;
  191. if ( *p != '\\' )
  192. {
  193. buffer[r++] = *p;
  194. continue;
  195. }
  196. p++;
  197. switch ( *p )
  198. {
  199. case 'n':
  200. b = '\n';
  201. break;
  202. case 'r':
  203. b = '\r';
  204. break;
  205. case 't':
  206. b = '\t';
  207. break;
  208. case 'b':
  209. b = '\b';
  210. break;
  211. case 'f':
  212. b = '\f';
  213. break;
  214. case '\r':
  215. p++;
  216. if ( *p != '\n' )
  217. {
  218. b = *p;
  219. break;
  220. }
  221. /* no break */
  222. case '\n':
  223. continue;
  224. break;
  225. default:
  226. if ( IS_PS_DIGIT( *p ) )
  227. {
  228. b = *p - '0';
  229. p++;
  230. if ( IS_PS_DIGIT( *p ) )
  231. {
  232. b = b * 8 + *p - '0';
  233. p++;
  234. if ( IS_PS_DIGIT( *p ) )
  235. b = b * 8 + *p - '0';
  236. else
  237. {
  238. buffer[r++] = b;
  239. b = *p;
  240. }
  241. }
  242. else
  243. {
  244. buffer[r++] = b;
  245. b = *p;
  246. }
  247. }
  248. else
  249. b = *p;
  250. break;
  251. }
  252. buffer[r++] = b;
  253. }
  254. *cursor = p;
  255. return r;
  256. }
  257. #endif /* 0 */
  258. FT_LOCAL_DEF( FT_UInt )
  259. PS_Conv_ASCIIHexDecode( FT_Byte** cursor,
  260. FT_Byte* limit,
  261. FT_Byte* buffer,
  262. FT_Offset n )
  263. {
  264. FT_Byte* p;
  265. FT_UInt r = 0;
  266. FT_UInt w = 0;
  267. FT_UInt pad = 0x01;
  268. n *= 2;
  269. #if 1
  270. p = *cursor;
  271. if ( p >= limit )
  272. return 0;
  273. if ( n > (FT_UInt)( limit - p ) )
  274. n = (FT_UInt)( limit - p );
  275. /* we try to process two nibbles at a time to be as fast as possible */
  276. for ( ; r < n; r++ )
  277. {
  278. FT_UInt c = p[r];
  279. if ( IS_PS_SPACE( c ) )
  280. continue;
  281. if ( c OP 0x80 )
  282. break;
  283. c = ft_char_table[c & 0x7F];
  284. if ( (unsigned)c >= 16 )
  285. break;
  286. pad = ( pad << 4 ) | c;
  287. if ( pad & 0x100 )
  288. {
  289. buffer[w++] = (FT_Byte)pad;
  290. pad = 0x01;
  291. }
  292. }
  293. if ( pad != 0x01 )
  294. buffer[w++] = (FT_Byte)( pad << 4 );
  295. *cursor = p + r;
  296. return w;
  297. #else /* 0 */
  298. for ( r = 0; r < n; r++ )
  299. {
  300. FT_Char c;
  301. if ( IS_PS_SPACE( *p ) )
  302. continue;
  303. if ( *p OP 0x80 )
  304. break;
  305. c = ft_char_table[*p & 0x7f];
  306. if ( (unsigned)c >= 16 )
  307. break;
  308. if ( r & 1 )
  309. {
  310. *buffer = (FT_Byte)(*buffer + c);
  311. buffer++;
  312. }
  313. else
  314. *buffer = (FT_Byte)(c << 4);
  315. r++;
  316. }
  317. *cursor = p;
  318. return ( r + 1 ) / 2;
  319. #endif /* 0 */
  320. }
  321. FT_LOCAL_DEF( FT_UInt )
  322. PS_Conv_EexecDecode( FT_Byte** cursor,
  323. FT_Byte* limit,
  324. FT_Byte* buffer,
  325. FT_Offset n,
  326. FT_UShort* seed )
  327. {
  328. FT_Byte* p;
  329. FT_UInt r;
  330. FT_UInt s = *seed;
  331. #if 1
  332. p = *cursor;
  333. if ( p >= limit )
  334. return 0;
  335. if ( n > (FT_UInt)(limit - p) )
  336. n = (FT_UInt)(limit - p);
  337. for ( r = 0; r < n; r++ )
  338. {
  339. FT_UInt val = p[r];
  340. FT_UInt b = ( val ^ ( s >> 8 ) );
  341. s = ( (val + s)*52845U + 22719 ) & 0xFFFFU;
  342. buffer[r] = (FT_Byte) b;
  343. }
  344. *cursor = p + n;
  345. *seed = (FT_UShort)s;
  346. #else /* 0 */
  347. for ( r = 0, p = *cursor; r < n && p < limit; r++, p++ )
  348. {
  349. FT_Byte b = (FT_Byte)( *p ^ ( s >> 8 ) );
  350. s = (FT_UShort)( ( *p + s ) * 52845U + 22719 );
  351. *buffer++ = b;
  352. }
  353. *cursor = p;
  354. *seed = s;
  355. #endif /* 0 */
  356. return r;
  357. }
  358. /* END */