/Build/source/libs/xpdf/xpdf-3.03/fofi/FoFiType1.cc

https://bitbucket.org/preining/tex-live · C++ · 338 lines · 282 code · 30 blank · 26 comment · 146 complexity · 81fbcd445695548d1061ef6e09b944c0 MD5 · raw file

  1. //========================================================================
  2. //
  3. // FoFiType1.cc
  4. //
  5. // Copyright 1999-2003 Glyph & Cog, LLC
  6. //
  7. //========================================================================
  8. #include <aconf.h>
  9. #ifdef USE_GCC_PRAGMAS
  10. #pragma implementation
  11. #endif
  12. #include <stdlib.h>
  13. #include <string.h>
  14. #include "gmem.h"
  15. #include "FoFiEncodings.h"
  16. #include "FoFiType1.h"
  17. //------------------------------------------------------------------------
  18. // FoFiType1
  19. //------------------------------------------------------------------------
  20. FoFiType1 *FoFiType1::make(char *fileA, int lenA) {
  21. return new FoFiType1(fileA, lenA, gFalse);
  22. }
  23. FoFiType1 *FoFiType1::load(char *fileName) {
  24. char *fileA;
  25. int lenA;
  26. if (!(fileA = FoFiBase::readFile(fileName, &lenA))) {
  27. return NULL;
  28. }
  29. return new FoFiType1(fileA, lenA, gTrue);
  30. }
  31. FoFiType1::FoFiType1(char *fileA, int lenA, GBool freeFileDataA):
  32. FoFiBase(fileA, lenA, freeFileDataA)
  33. {
  34. name = NULL;
  35. encoding = NULL;
  36. fontMatrix[0] = 0.001;
  37. fontMatrix[1] = 0;
  38. fontMatrix[2] = 0;
  39. fontMatrix[3] = 0.001;
  40. fontMatrix[4] = 0;
  41. fontMatrix[5] = 0;
  42. parsed = gFalse;
  43. undoPFB();
  44. }
  45. FoFiType1::~FoFiType1() {
  46. int i;
  47. if (name) {
  48. gfree(name);
  49. }
  50. if (encoding && encoding != (char **)fofiType1StandardEncoding) {
  51. for (i = 0; i < 256; ++i) {
  52. gfree(encoding[i]);
  53. }
  54. gfree(encoding);
  55. }
  56. }
  57. char *FoFiType1::getName() {
  58. if (!parsed) {
  59. parse();
  60. }
  61. return name;
  62. }
  63. char **FoFiType1::getEncoding() {
  64. if (!parsed) {
  65. parse();
  66. }
  67. return encoding;
  68. }
  69. void FoFiType1::getFontMatrix(double *mat) {
  70. int i;
  71. if (!parsed) {
  72. parse();
  73. }
  74. for (i = 0; i < 6; ++i) {
  75. mat[i] = fontMatrix[i];
  76. }
  77. }
  78. void FoFiType1::writeEncoded(const char **newEncoding,
  79. FoFiOutputFunc outputFunc, void *outputStream) {
  80. char buf[512];
  81. char *line, *line2, *p;
  82. int i;
  83. // copy everything up to the encoding
  84. for (line = (char *)file;
  85. line && strncmp(line, "/Encoding", 9);
  86. line = getNextLine(line)) ;
  87. if (!line) {
  88. // no encoding - just copy the whole font file
  89. (*outputFunc)(outputStream, (char *)file, len);
  90. return;
  91. }
  92. (*outputFunc)(outputStream, (char *)file, (int)(line - (char *)file));
  93. // write the new encoding
  94. (*outputFunc)(outputStream, "/Encoding 256 array\n", 20);
  95. (*outputFunc)(outputStream,
  96. "0 1 255 {1 index exch /.notdef put} for\n", 40);
  97. for (i = 0; i < 256; ++i) {
  98. if (newEncoding[i]) {
  99. sprintf(buf, "dup %d /%s put\n", i, newEncoding[i]);
  100. (*outputFunc)(outputStream, buf, (int)strlen(buf));
  101. }
  102. }
  103. (*outputFunc)(outputStream, "readonly def\n", 13);
  104. // find the end of the encoding data
  105. //~ this ought to parse PostScript tokens
  106. if (!strncmp(line, "/Encoding StandardEncoding def", 30)) {
  107. line = getNextLine(line);
  108. } else {
  109. // skip "/Encoding" + one whitespace char,
  110. // then look for 'def' preceded by PostScript whitespace
  111. p = line + 10;
  112. line = NULL;
  113. for (; p < (char *)file + len; ++p) {
  114. if ((*p == ' ' || *p == '\t' || *p == '\x0a' ||
  115. *p == '\x0d' || *p == '\x0c' || *p == '\0') &&
  116. p + 4 <= (char *)file + len &&
  117. !strncmp(p + 1, "def", 3)) {
  118. line = p + 4;
  119. break;
  120. }
  121. }
  122. }
  123. // some fonts have two /Encoding entries in their dictionary, so we
  124. // check for a second one here
  125. if (line) {
  126. for (line2 = line, i = 0;
  127. i < 20 && line2 && strncmp(line2, "/Encoding", 9);
  128. line2 = getNextLine(line2), ++i) ;
  129. if (i < 20 && line2) {
  130. (*outputFunc)(outputStream, line, (int)(line2 - line));
  131. if (!strncmp(line2, "/Encoding StandardEncoding def", 30)) {
  132. line = getNextLine(line2);
  133. } else {
  134. // skip "/Encoding" + one whitespace char,
  135. // then look for 'def' preceded by PostScript whitespace
  136. p = line2 + 10;
  137. line = NULL;
  138. for (; p < (char *)file + len; ++p) {
  139. if ((*p == ' ' || *p == '\t' || *p == '\x0a' ||
  140. *p == '\x0d' || *p == '\x0c' || *p == '\0') &&
  141. p + 4 <= (char *)file + len &&
  142. !strncmp(p + 1, "def", 3)) {
  143. line = p + 4;
  144. break;
  145. }
  146. }
  147. }
  148. }
  149. // copy everything after the encoding
  150. if (line) {
  151. (*outputFunc)(outputStream, line, (int)(((char *)file + len) - line));
  152. }
  153. }
  154. }
  155. char *FoFiType1::getNextLine(char *line) {
  156. while (line < (char *)file + len && *line != '\x0a' && *line != '\x0d') {
  157. ++line;
  158. }
  159. if (line < (char *)file + len && *line == '\x0d') {
  160. ++line;
  161. }
  162. if (line < (char *)file + len && *line == '\x0a') {
  163. ++line;
  164. }
  165. if (line >= (char *)file + len) {
  166. return NULL;
  167. }
  168. return line;
  169. }
  170. void FoFiType1::parse() {
  171. char *line, *line1, *p, *p2;
  172. char buf[256];
  173. char c;
  174. int n, code, base, i, j;
  175. GBool gotMatrix;
  176. gotMatrix = gFalse;
  177. for (i = 1, line = (char *)file;
  178. i <= 100 && line && (!name || !encoding);
  179. ++i) {
  180. // get font name
  181. if (!name && !strncmp(line, "/FontName", 9)) {
  182. strncpy(buf, line, 255);
  183. buf[255] = '\0';
  184. if ((p = strchr(buf+9, '/')) &&
  185. (p = strtok(p+1, " \t\n\r"))) {
  186. name = copyString(p);
  187. }
  188. line = getNextLine(line);
  189. // get encoding
  190. } else if (!encoding &&
  191. !strncmp(line, "/Encoding StandardEncoding def", 30)) {
  192. encoding = (char **)fofiType1StandardEncoding;
  193. } else if (!encoding &&
  194. !strncmp(line, "/Encoding 256 array", 19)) {
  195. encoding = (char **)gmallocn(256, sizeof(char *));
  196. for (j = 0; j < 256; ++j) {
  197. encoding[j] = NULL;
  198. }
  199. for (j = 0, line = getNextLine(line);
  200. j < 300 && line && (line1 = getNextLine(line));
  201. ++j, line = line1) {
  202. if ((n = (int)(line1 - line)) > 255) {
  203. n = 255;
  204. }
  205. strncpy(buf, line, n);
  206. buf[n] = '\0';
  207. for (p = buf; *p == ' ' || *p == '\t'; ++p) ;
  208. if (!strncmp(p, "dup", 3)) {
  209. while (1) {
  210. p += 3;
  211. for (; *p == ' ' || *p == '\t'; ++p) ;
  212. code = 0;
  213. if (*p == '8' && p[1] == '#') {
  214. base = 8;
  215. p += 2;
  216. } else if (*p >= '0' && *p <= '9') {
  217. base = 10;
  218. } else {
  219. break;
  220. }
  221. for (; *p >= '0' && *p < '0' + base; ++p) {
  222. code = code * base + (*p - '0');
  223. }
  224. for (; *p == ' ' || *p == '\t'; ++p) ;
  225. if (*p != '/') {
  226. break;
  227. }
  228. ++p;
  229. for (p2 = p; *p2 && *p2 != ' ' && *p2 != '\t'; ++p2) ;
  230. if (code >= 0 && code < 256) {
  231. c = *p2;
  232. *p2 = '\0';
  233. encoding[code] = copyString(p);
  234. *p2 = c;
  235. }
  236. for (p = p2; *p == ' ' || *p == '\t'; ++p) ;
  237. if (strncmp(p, "put", 3)) {
  238. break;
  239. }
  240. for (p += 3; *p == ' ' || *p == '\t'; ++p) ;
  241. if (strncmp(p, "dup", 3)) {
  242. break;
  243. }
  244. }
  245. } else {
  246. if (strtok(buf, " \t") &&
  247. (p = strtok(NULL, " \t\n\r")) && !strcmp(p, "def")) {
  248. break;
  249. }
  250. }
  251. }
  252. //~ check for getinterval/putinterval junk
  253. } else if (!gotMatrix && !strncmp(line, "/FontMatrix", 11)) {
  254. strncpy(buf, line + 11, 255);
  255. buf[255] = '\0';
  256. if ((p = strchr(buf, '['))) {
  257. ++p;
  258. if ((p2 = strchr(p, ']'))) {
  259. *p2 = '\0';
  260. for (j = 0; j < 6; ++j) {
  261. if ((p = strtok(j == 0 ? p : (char *)NULL, " \t\n\r"))) {
  262. fontMatrix[j] = atof(p);
  263. } else {
  264. break;
  265. }
  266. }
  267. }
  268. }
  269. gotMatrix = gTrue;
  270. } else {
  271. line = getNextLine(line);
  272. }
  273. }
  274. parsed = gTrue;
  275. }
  276. // Undo the PFB encoding, i.e., remove the PFB headers.
  277. void FoFiType1::undoPFB() {
  278. GBool ok;
  279. Guchar *file2;
  280. int pos1, pos2, type;
  281. Guint segLen;
  282. ok = gTrue;
  283. if (getU8(0, &ok) != 0x80 || !ok) {
  284. return;
  285. }
  286. file2 = (Guchar *)gmalloc(len);
  287. pos1 = pos2 = 0;
  288. while (getU8(pos1, &ok) == 0x80 && ok) {
  289. type = getU8(pos1 + 1, &ok);
  290. if (type < 1 || type > 2 || !ok) {
  291. break;
  292. }
  293. segLen = getU32LE(pos1 + 2, &ok);
  294. pos1 += 6;
  295. if (!ok || !checkRegion(pos1, segLen)) {
  296. break;
  297. }
  298. memcpy(file2 + pos2, file + pos1, segLen);
  299. pos1 += segLen;
  300. pos2 += segLen;
  301. }
  302. if (freeFileData) {
  303. gfree(fileData);
  304. }
  305. file = fileData = file2;
  306. freeFileData = gTrue;
  307. len = pos2;
  308. }