Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

340 lines
6.6 KiB

  1. /***
  2. **
  3. ** Module: FReader
  4. **
  5. ** Description:
  6. ** This is a module of the T1 to TT font converter. The module
  7. ** contains functions that decodes and decrypts the data of a
  8. ** T1 font file.
  9. **
  10. ** Author: Michael Jansson
  11. **
  12. ** Created: 5/26/93
  13. **
  14. ***/
  15. /**** INCLUDES */
  16. /* General types and definitions. */
  17. #include <ctype.h>
  18. #include <string.h>
  19. /* Special types and definitions. */
  20. #include "titott.h"
  21. #include "types.h"
  22. #include "safemem.h"
  23. #include "t1msg.h"
  24. /* Module dependent types and prototypes. */
  25. #include "freader.h"
  26. #include "pfb.h"
  27. /***** LOCAL TYPES */
  28. struct FontFile {
  29. /* Low-level I/O functions. */
  30. errcode (FASTCALL *fclose)(struct t1file *);
  31. short (FASTCALL *fgetc)(struct t1file *);
  32. struct t1file *(*fopen)(const char *);
  33. boolean (FASTCALL *fstatus)(const struct t1file *);
  34. struct t1file *io;
  35. /* Font file state. */
  36. enum {prolog, eexec} state;
  37. short nextbyte;
  38. USHORT r;
  39. };
  40. /***** CONSTANTS */
  41. static const USHORT c1 = 52845;
  42. static const USHORT c2 = 22719;
  43. /***** MACROS */
  44. #define IOGetByte(f) ((*f->fgetc)(f->io))
  45. #define IOError(f) ((*f->fstatus)(f->io))
  46. #define IOOpen(f,n) ((*f->fopen)(n))
  47. #define IOClose(f) ((*f->fclose)(f->io))
  48. #define SetNextByte(ff, b) ff->nextbyte = (b)
  49. #define NextByte(ff) (ff->nextbyte)
  50. #define Eexec(ff) (boolean)(ff->state == eexec)
  51. #define StartEexec(ff) ff->state = eexec
  52. /***** STATIC FUNCTIONS */
  53. /*-none-*/
  54. /***** FUNCTIONS */
  55. /***
  56. ** Function: GetByte
  57. **
  58. ** Description:
  59. ** Pull one byte out of the T1 font file.
  60. ***/
  61. short FASTCALL GetByte(struct FontFile *ff)
  62. {
  63. short b, nb;
  64. b = IOGetByte(ff);
  65. /* Decrypt it? */
  66. if (Eexec(ff))
  67. b = (short)Decrypt(&ff->r, (UBYTE)b);
  68. /* Record look-a-head */
  69. nb = NextByte(ff);
  70. SetNextByte(ff, b);
  71. return nb;
  72. }
  73. /***
  74. ** Function: GetNewLine
  75. **
  76. ** Description:
  77. ** Pull one whole line from the T1 font file, starting at
  78. ** the current position.
  79. ***/
  80. char *GetNewLine(struct FontFile *ff, char *buf, const USHORT len)
  81. {
  82. short i = 0;
  83. /* Get string. */
  84. while ((buf[i] = (char)GetByte(ff))!='\n' &&
  85. buf[i]!='\r' && ++i<((short)len-1));
  86. /* Skip extra characters. */
  87. if (buf[i]!='\n' && buf[i]!='\r')
  88. while (!IOError(ff) && NextByte(ff)!='\n' && NextByte(ff)!='\r')
  89. (void)GetByte(ff);
  90. /* Terminate string. */
  91. buf[i] = '\0';
  92. /* Check for the start of the eexec section. */
  93. if (!strcmp(buf, "eexec"))
  94. StartEexec(ff);
  95. /* Check error condition. */
  96. if (IOError(ff))
  97. return NULL;
  98. return buf;
  99. }
  100. /***
  101. ** Function: Get_Token
  102. **
  103. ** Description:
  104. ** Pull one token from the T1 font file. A token
  105. ** is delimited by white space and various brackets.
  106. ***/
  107. char *Get_Token(struct FontFile *ff, char *buf, const USHORT len)
  108. {
  109. short i = 0;
  110. short nb;
  111. /* Skip leading blanks. */
  112. while (isspace(NextByte(ff)))
  113. (void)GetByte(ff);
  114. /* Get string. */
  115. do {
  116. buf[i] = (char)GetByte(ff);
  117. nb = NextByte(ff);
  118. } while (++i<((short)len-1) && !isspace(nb) && nb!='{' &&
  119. nb!='(' && nb!='[' && nb!='/');
  120. /* Skip extra characters. */
  121. while (!IOError(ff) && !isspace(nb) && nb!='{' &&
  122. nb!='(' && nb!='[' && nb!='/') {
  123. (void)GetByte(ff);
  124. nb = NextByte(ff);
  125. }
  126. /* Terminate string. */
  127. buf[i] = '\0';
  128. /* Check for the start of the eexec section. */
  129. if (!strcmp(buf, "eexec"))
  130. StartEexec(ff);
  131. /* Check error condition. */
  132. if (IOError(ff))
  133. return NULL;
  134. return buf;
  135. }
  136. /***
  137. ** Function: GetSeq
  138. **
  139. ** Description:
  140. ** Pull one sequence of bytes that are delimited by
  141. ** a given pair of characters, e.g. '[' and ']'.
  142. ***/
  143. char *GetSeq(struct FontFile *ff,
  144. char *buf,
  145. const USHORT len)
  146. {
  147. char d1, d2;
  148. short i = 0;
  149. short inside = 0;
  150. /* Skip leading blanks. */
  151. while (NextByte(ff)!='[' &&
  152. NextByte(ff)!='{' &&
  153. NextByte(ff)!='(' &&
  154. !IOError(ff))
  155. (void)GetByte(ff);
  156. /* match the bracket. */
  157. d1 = (char)NextByte(ff);
  158. if (d1=='[')
  159. d2 = ']';
  160. else if (d1=='{')
  161. d2 = '}';
  162. else if (d1=='(')
  163. d2 = ')';
  164. else
  165. return NULL;
  166. /* Get string. */
  167. (void)GetByte(ff);
  168. inside=1;
  169. do {
  170. buf[i] = (char)GetByte(ff);
  171. if (buf[i]==d1)
  172. inside++;
  173. if (buf[i]==d2)
  174. inside--;
  175. } while (inside && ++i<((short)len-1));
  176. /* Terminate string. */
  177. buf[i] = '\0';
  178. /* Check error condition. */
  179. if (IOError(ff))
  180. return NULL;
  181. return buf;
  182. }
  183. /***
  184. ** Function: FRInit
  185. **
  186. ** Description:
  187. ** Initite the resources needed to read/decode data from
  188. ** a T1 font file.
  189. ***/
  190. errcode FRInit(const char *name, const enum ftype type, struct FontFile **ff)
  191. {
  192. errcode status = SUCCESS;
  193. short b;
  194. if (((*ff)=(struct FontFile *)Malloc(sizeof(struct FontFile)))==NULL) {
  195. SetError(status = NOMEM);
  196. } else {
  197. /* Initiat the handle. */
  198. memset((*ff), '\0', sizeof(**ff));
  199. /* Initiate low-level I/O. */
  200. switch (type) {
  201. case pfb_file:
  202. (*ff)->fgetc = PFBGetByte;
  203. (*ff)->fclose = PFBFreeIOBlock;
  204. (*ff)->fstatus = PFBFileError;
  205. (*ff)->fopen = PFBAllocIOBlock;
  206. break;
  207. case mac_file:
  208. #if MACFILEFORMAT
  209. (*ff)->fgetc = MACGetByte;
  210. (*ff)->fclose = MACFreeIOBlock;
  211. (*ff)->fstatus = MACFileError;
  212. (*ff)->fopen = MACAllocIOBlock;
  213. break;
  214. #endif
  215. case ascii_file:
  216. #if ASCIIFILEFORMAT
  217. (*ff)->fgetc = ASCIIGetByte;
  218. (*ff)->fclose = ASCIIFreeIOBlock;
  219. (*ff)->fstatus = ASCIFileError;
  220. (*ff)->fopen = ASCIIAllocIOBlock;
  221. break;
  222. #endif
  223. default:
  224. LogError(MSG_ERROR, MSG_BADFMT, NULL);
  225. SetError(status = BADINPUTFILE);
  226. break;
  227. }
  228. (*ff)->io = NULL;
  229. if (((*ff)->io = IOOpen((*ff),name))==NULL) {
  230. SetError(status = BADINPUTFILE);
  231. } else {
  232. (*ff)->state = prolog;
  233. (*ff)->r = 55665;
  234. b=GetByte(*ff);
  235. SetNextByte((*ff), b);
  236. }
  237. }
  238. return status;
  239. }
  240. /***
  241. ** Function: FRCleanUp
  242. **
  243. ** Description:
  244. ** Free the resources used when reading/decoding data from
  245. ** a T1 font file.
  246. ***/
  247. errcode FRCleanUp(struct FontFile *ff)
  248. {
  249. errcode status = SUCCESS;
  250. if (ff) {
  251. if (ff->io)
  252. status = IOClose(ff);
  253. Free(ff);
  254. }
  255. return status;
  256. }
  257. /***
  258. ** Function: Decrypt
  259. **
  260. ** Description:
  261. ** Decrypt a byte.
  262. ***/
  263. UBYTE FASTCALL Decrypt(USHORT *r, const UBYTE cipher)
  264. {
  265. UBYTE plain;
  266. plain = (UBYTE)(cipher ^ (*r>>8));
  267. *r = (USHORT)((cipher+*r) * c1 + c2);
  268. return plain;
  269. }