cmap.js 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932
  1. /**
  2. * @licstart The following is the entire license notice for the
  3. * Javascript code in this page
  4. *
  5. * Copyright 2021 Mozilla Foundation
  6. *
  7. * Licensed under the Apache License, Version 2.0 (the "License");
  8. * you may not use this file except in compliance with the License.
  9. * You may obtain a copy of the License at
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing, software
  14. * distributed under the License is distributed on an "AS IS" BASIS,
  15. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16. * See the License for the specific language governing permissions and
  17. * limitations under the License.
  18. *
  19. * @licend The above is the entire license notice for the
  20. * Javascript code in this page
  21. */
  22. "use strict";
  23. Object.defineProperty(exports, "__esModule", {
  24. value: true
  25. });
  26. exports.IdentityCMap = exports.CMapFactory = exports.CMap = void 0;
  27. var _util = require("../shared/util.js");
  28. var _primitives = require("./primitives.js");
  29. var _parser = require("./parser.js");
  30. var _core_utils = require("./core_utils.js");
  31. var _stream = require("./stream.js");
  32. const BUILT_IN_CMAPS = ["Adobe-GB1-UCS2", "Adobe-CNS1-UCS2", "Adobe-Japan1-UCS2", "Adobe-Korea1-UCS2", "78-EUC-H", "78-EUC-V", "78-H", "78-RKSJ-H", "78-RKSJ-V", "78-V", "78ms-RKSJ-H", "78ms-RKSJ-V", "83pv-RKSJ-H", "90ms-RKSJ-H", "90ms-RKSJ-V", "90msp-RKSJ-H", "90msp-RKSJ-V", "90pv-RKSJ-H", "90pv-RKSJ-V", "Add-H", "Add-RKSJ-H", "Add-RKSJ-V", "Add-V", "Adobe-CNS1-0", "Adobe-CNS1-1", "Adobe-CNS1-2", "Adobe-CNS1-3", "Adobe-CNS1-4", "Adobe-CNS1-5", "Adobe-CNS1-6", "Adobe-GB1-0", "Adobe-GB1-1", "Adobe-GB1-2", "Adobe-GB1-3", "Adobe-GB1-4", "Adobe-GB1-5", "Adobe-Japan1-0", "Adobe-Japan1-1", "Adobe-Japan1-2", "Adobe-Japan1-3", "Adobe-Japan1-4", "Adobe-Japan1-5", "Adobe-Japan1-6", "Adobe-Korea1-0", "Adobe-Korea1-1", "Adobe-Korea1-2", "B5-H", "B5-V", "B5pc-H", "B5pc-V", "CNS-EUC-H", "CNS-EUC-V", "CNS1-H", "CNS1-V", "CNS2-H", "CNS2-V", "ETHK-B5-H", "ETHK-B5-V", "ETen-B5-H", "ETen-B5-V", "ETenms-B5-H", "ETenms-B5-V", "EUC-H", "EUC-V", "Ext-H", "Ext-RKSJ-H", "Ext-RKSJ-V", "Ext-V", "GB-EUC-H", "GB-EUC-V", "GB-H", "GB-V", "GBK-EUC-H", "GBK-EUC-V", "GBK2K-H", "GBK2K-V", "GBKp-EUC-H", "GBKp-EUC-V", "GBT-EUC-H", "GBT-EUC-V", "GBT-H", "GBT-V", "GBTpc-EUC-H", "GBTpc-EUC-V", "GBpc-EUC-H", "GBpc-EUC-V", "H", "HKdla-B5-H", "HKdla-B5-V", "HKdlb-B5-H", "HKdlb-B5-V", "HKgccs-B5-H", "HKgccs-B5-V", "HKm314-B5-H", "HKm314-B5-V", "HKm471-B5-H", "HKm471-B5-V", "HKscs-B5-H", "HKscs-B5-V", "Hankaku", "Hiragana", "KSC-EUC-H", "KSC-EUC-V", "KSC-H", "KSC-Johab-H", "KSC-Johab-V", "KSC-V", "KSCms-UHC-H", "KSCms-UHC-HW-H", "KSCms-UHC-HW-V", "KSCms-UHC-V", "KSCpc-EUC-H", "KSCpc-EUC-V", "Katakana", "NWP-H", "NWP-V", "RKSJ-H", "RKSJ-V", "Roman", "UniCNS-UCS2-H", "UniCNS-UCS2-V", "UniCNS-UTF16-H", "UniCNS-UTF16-V", "UniCNS-UTF32-H", "UniCNS-UTF32-V", "UniCNS-UTF8-H", "UniCNS-UTF8-V", "UniGB-UCS2-H", "UniGB-UCS2-V", "UniGB-UTF16-H", "UniGB-UTF16-V", "UniGB-UTF32-H", "UniGB-UTF32-V", "UniGB-UTF8-H", "UniGB-UTF8-V", "UniJIS-UCS2-H", "UniJIS-UCS2-HW-H", "UniJIS-UCS2-HW-V", "UniJIS-UCS2-V", "UniJIS-UTF16-H", "UniJIS-UTF16-V", "UniJIS-UTF32-H", "UniJIS-UTF32-V", "UniJIS-UTF8-H", "UniJIS-UTF8-V", "UniJIS2004-UTF16-H", "UniJIS2004-UTF16-V", "UniJIS2004-UTF32-H", "UniJIS2004-UTF32-V", "UniJIS2004-UTF8-H", "UniJIS2004-UTF8-V", "UniJISPro-UCS2-HW-V", "UniJISPro-UCS2-V", "UniJISPro-UTF8-V", "UniJISX0213-UTF32-H", "UniJISX0213-UTF32-V", "UniJISX02132004-UTF32-H", "UniJISX02132004-UTF32-V", "UniKS-UCS2-H", "UniKS-UCS2-V", "UniKS-UTF16-H", "UniKS-UTF16-V", "UniKS-UTF32-H", "UniKS-UTF32-V", "UniKS-UTF8-H", "UniKS-UTF8-V", "V", "WP-Symbol"];
  33. const MAX_MAP_RANGE = 2 ** 24 - 1;
  34. class CMap {
  35. constructor(builtInCMap = false) {
  36. this.codespaceRanges = [[], [], [], []];
  37. this.numCodespaceRanges = 0;
  38. this._map = [];
  39. this.name = "";
  40. this.vertical = false;
  41. this.useCMap = null;
  42. this.builtInCMap = builtInCMap;
  43. }
  44. addCodespaceRange(n, low, high) {
  45. this.codespaceRanges[n - 1].push(low, high);
  46. this.numCodespaceRanges++;
  47. }
  48. mapCidRange(low, high, dstLow) {
  49. if (high - low > MAX_MAP_RANGE) {
  50. throw new Error("mapCidRange - ignoring data above MAX_MAP_RANGE.");
  51. }
  52. while (low <= high) {
  53. this._map[low++] = dstLow++;
  54. }
  55. }
  56. mapBfRange(low, high, dstLow) {
  57. if (high - low > MAX_MAP_RANGE) {
  58. throw new Error("mapBfRange - ignoring data above MAX_MAP_RANGE.");
  59. }
  60. const lastByte = dstLow.length - 1;
  61. while (low <= high) {
  62. this._map[low++] = dstLow;
  63. dstLow = dstLow.substring(0, lastByte) + String.fromCharCode(dstLow.charCodeAt(lastByte) + 1);
  64. }
  65. }
  66. mapBfRangeToArray(low, high, array) {
  67. if (high - low > MAX_MAP_RANGE) {
  68. throw new Error("mapBfRangeToArray - ignoring data above MAX_MAP_RANGE.");
  69. }
  70. const ii = array.length;
  71. let i = 0;
  72. while (low <= high && i < ii) {
  73. this._map[low] = array[i++];
  74. ++low;
  75. }
  76. }
  77. mapOne(src, dst) {
  78. this._map[src] = dst;
  79. }
  80. lookup(code) {
  81. return this._map[code];
  82. }
  83. contains(code) {
  84. return this._map[code] !== undefined;
  85. }
  86. forEach(callback) {
  87. const map = this._map;
  88. const length = map.length;
  89. if (length <= 0x10000) {
  90. for (let i = 0; i < length; i++) {
  91. if (map[i] !== undefined) {
  92. callback(i, map[i]);
  93. }
  94. }
  95. } else {
  96. for (const i in map) {
  97. callback(i, map[i]);
  98. }
  99. }
  100. }
  101. charCodeOf(value) {
  102. const map = this._map;
  103. if (map.length <= 0x10000) {
  104. return map.indexOf(value);
  105. }
  106. for (const charCode in map) {
  107. if (map[charCode] === value) {
  108. return charCode | 0;
  109. }
  110. }
  111. return -1;
  112. }
  113. getMap() {
  114. return this._map;
  115. }
  116. readCharCode(str, offset, out) {
  117. let c = 0;
  118. const codespaceRanges = this.codespaceRanges;
  119. for (let n = 0, nn = codespaceRanges.length; n < nn; n++) {
  120. c = (c << 8 | str.charCodeAt(offset + n)) >>> 0;
  121. const codespaceRange = codespaceRanges[n];
  122. for (let k = 0, kk = codespaceRange.length; k < kk;) {
  123. const low = codespaceRange[k++];
  124. const high = codespaceRange[k++];
  125. if (c >= low && c <= high) {
  126. out.charcode = c;
  127. out.length = n + 1;
  128. return;
  129. }
  130. }
  131. }
  132. out.charcode = 0;
  133. out.length = 1;
  134. }
  135. getCharCodeLength(charCode) {
  136. const codespaceRanges = this.codespaceRanges;
  137. for (let n = 0, nn = codespaceRanges.length; n < nn; n++) {
  138. const codespaceRange = codespaceRanges[n];
  139. for (let k = 0, kk = codespaceRange.length; k < kk;) {
  140. const low = codespaceRange[k++];
  141. const high = codespaceRange[k++];
  142. if (charCode >= low && charCode <= high) {
  143. return n + 1;
  144. }
  145. }
  146. }
  147. return 1;
  148. }
  149. get length() {
  150. return this._map.length;
  151. }
  152. get isIdentityCMap() {
  153. if (!(this.name === "Identity-H" || this.name === "Identity-V")) {
  154. return false;
  155. }
  156. if (this._map.length !== 0x10000) {
  157. return false;
  158. }
  159. for (let i = 0; i < 0x10000; i++) {
  160. if (this._map[i] !== i) {
  161. return false;
  162. }
  163. }
  164. return true;
  165. }
  166. }
  167. exports.CMap = CMap;
  168. class IdentityCMap extends CMap {
  169. constructor(vertical, n) {
  170. super();
  171. this.vertical = vertical;
  172. this.addCodespaceRange(n, 0, 0xffff);
  173. }
  174. mapCidRange(low, high, dstLow) {
  175. (0, _util.unreachable)("should not call mapCidRange");
  176. }
  177. mapBfRange(low, high, dstLow) {
  178. (0, _util.unreachable)("should not call mapBfRange");
  179. }
  180. mapBfRangeToArray(low, high, array) {
  181. (0, _util.unreachable)("should not call mapBfRangeToArray");
  182. }
  183. mapOne(src, dst) {
  184. (0, _util.unreachable)("should not call mapCidOne");
  185. }
  186. lookup(code) {
  187. return Number.isInteger(code) && code <= 0xffff ? code : undefined;
  188. }
  189. contains(code) {
  190. return Number.isInteger(code) && code <= 0xffff;
  191. }
  192. forEach(callback) {
  193. for (let i = 0; i <= 0xffff; i++) {
  194. callback(i, i);
  195. }
  196. }
  197. charCodeOf(value) {
  198. return Number.isInteger(value) && value <= 0xffff ? value : -1;
  199. }
  200. getMap() {
  201. const map = new Array(0x10000);
  202. for (let i = 0; i <= 0xffff; i++) {
  203. map[i] = i;
  204. }
  205. return map;
  206. }
  207. get length() {
  208. return 0x10000;
  209. }
  210. get isIdentityCMap() {
  211. (0, _util.unreachable)("should not access .isIdentityCMap");
  212. }
  213. }
  214. exports.IdentityCMap = IdentityCMap;
  215. const BinaryCMapReader = function BinaryCMapReaderClosure() {
  216. function hexToInt(a, size) {
  217. let n = 0;
  218. for (let i = 0; i <= size; i++) {
  219. n = n << 8 | a[i];
  220. }
  221. return n >>> 0;
  222. }
  223. function hexToStr(a, size) {
  224. if (size === 1) {
  225. return String.fromCharCode(a[0], a[1]);
  226. }
  227. if (size === 3) {
  228. return String.fromCharCode(a[0], a[1], a[2], a[3]);
  229. }
  230. return String.fromCharCode.apply(null, a.subarray(0, size + 1));
  231. }
  232. function addHex(a, b, size) {
  233. let c = 0;
  234. for (let i = size; i >= 0; i--) {
  235. c += a[i] + b[i];
  236. a[i] = c & 255;
  237. c >>= 8;
  238. }
  239. }
  240. function incHex(a, size) {
  241. let c = 1;
  242. for (let i = size; i >= 0 && c > 0; i--) {
  243. c += a[i];
  244. a[i] = c & 255;
  245. c >>= 8;
  246. }
  247. }
  248. const MAX_NUM_SIZE = 16;
  249. const MAX_ENCODED_NUM_SIZE = 19;
  250. class BinaryCMapStream {
  251. constructor(data) {
  252. this.buffer = data;
  253. this.pos = 0;
  254. this.end = data.length;
  255. this.tmpBuf = new Uint8Array(MAX_ENCODED_NUM_SIZE);
  256. }
  257. readByte() {
  258. if (this.pos >= this.end) {
  259. return -1;
  260. }
  261. return this.buffer[this.pos++];
  262. }
  263. readNumber() {
  264. let n = 0;
  265. let last;
  266. do {
  267. const b = this.readByte();
  268. if (b < 0) {
  269. throw new _util.FormatError("unexpected EOF in bcmap");
  270. }
  271. last = !(b & 0x80);
  272. n = n << 7 | b & 0x7f;
  273. } while (!last);
  274. return n;
  275. }
  276. readSigned() {
  277. const n = this.readNumber();
  278. return n & 1 ? ~(n >>> 1) : n >>> 1;
  279. }
  280. readHex(num, size) {
  281. num.set(this.buffer.subarray(this.pos, this.pos + size + 1));
  282. this.pos += size + 1;
  283. }
  284. readHexNumber(num, size) {
  285. let last;
  286. const stack = this.tmpBuf;
  287. let sp = 0;
  288. do {
  289. const b = this.readByte();
  290. if (b < 0) {
  291. throw new _util.FormatError("unexpected EOF in bcmap");
  292. }
  293. last = !(b & 0x80);
  294. stack[sp++] = b & 0x7f;
  295. } while (!last);
  296. let i = size,
  297. buffer = 0,
  298. bufferSize = 0;
  299. while (i >= 0) {
  300. while (bufferSize < 8 && stack.length > 0) {
  301. buffer = stack[--sp] << bufferSize | buffer;
  302. bufferSize += 7;
  303. }
  304. num[i] = buffer & 255;
  305. i--;
  306. buffer >>= 8;
  307. bufferSize -= 8;
  308. }
  309. }
  310. readHexSigned(num, size) {
  311. this.readHexNumber(num, size);
  312. const sign = num[size] & 1 ? 255 : 0;
  313. let c = 0;
  314. for (let i = 0; i <= size; i++) {
  315. c = (c & 1) << 8 | num[i];
  316. num[i] = c >> 1 ^ sign;
  317. }
  318. }
  319. readString() {
  320. const len = this.readNumber();
  321. let s = "";
  322. for (let i = 0; i < len; i++) {
  323. s += String.fromCharCode(this.readNumber());
  324. }
  325. return s;
  326. }
  327. }
  328. class BinaryCMapReader {
  329. async process(data, cMap, extend) {
  330. const stream = new BinaryCMapStream(data);
  331. const header = stream.readByte();
  332. cMap.vertical = !!(header & 1);
  333. let useCMap = null;
  334. const start = new Uint8Array(MAX_NUM_SIZE);
  335. const end = new Uint8Array(MAX_NUM_SIZE);
  336. const char = new Uint8Array(MAX_NUM_SIZE);
  337. const charCode = new Uint8Array(MAX_NUM_SIZE);
  338. const tmp = new Uint8Array(MAX_NUM_SIZE);
  339. let code;
  340. let b;
  341. while ((b = stream.readByte()) >= 0) {
  342. const type = b >> 5;
  343. if (type === 7) {
  344. switch (b & 0x1f) {
  345. case 0:
  346. stream.readString();
  347. break;
  348. case 1:
  349. useCMap = stream.readString();
  350. break;
  351. }
  352. continue;
  353. }
  354. const sequence = !!(b & 0x10);
  355. const dataSize = b & 15;
  356. if (dataSize + 1 > MAX_NUM_SIZE) {
  357. throw new Error("BinaryCMapReader.process: Invalid dataSize.");
  358. }
  359. const ucs2DataSize = 1;
  360. const subitemsCount = stream.readNumber();
  361. switch (type) {
  362. case 0:
  363. stream.readHex(start, dataSize);
  364. stream.readHexNumber(end, dataSize);
  365. addHex(end, start, dataSize);
  366. cMap.addCodespaceRange(dataSize + 1, hexToInt(start, dataSize), hexToInt(end, dataSize));
  367. for (let i = 1; i < subitemsCount; i++) {
  368. incHex(end, dataSize);
  369. stream.readHexNumber(start, dataSize);
  370. addHex(start, end, dataSize);
  371. stream.readHexNumber(end, dataSize);
  372. addHex(end, start, dataSize);
  373. cMap.addCodespaceRange(dataSize + 1, hexToInt(start, dataSize), hexToInt(end, dataSize));
  374. }
  375. break;
  376. case 1:
  377. stream.readHex(start, dataSize);
  378. stream.readHexNumber(end, dataSize);
  379. addHex(end, start, dataSize);
  380. stream.readNumber();
  381. for (let i = 1; i < subitemsCount; i++) {
  382. incHex(end, dataSize);
  383. stream.readHexNumber(start, dataSize);
  384. addHex(start, end, dataSize);
  385. stream.readHexNumber(end, dataSize);
  386. addHex(end, start, dataSize);
  387. stream.readNumber();
  388. }
  389. break;
  390. case 2:
  391. stream.readHex(char, dataSize);
  392. code = stream.readNumber();
  393. cMap.mapOne(hexToInt(char, dataSize), code);
  394. for (let i = 1; i < subitemsCount; i++) {
  395. incHex(char, dataSize);
  396. if (!sequence) {
  397. stream.readHexNumber(tmp, dataSize);
  398. addHex(char, tmp, dataSize);
  399. }
  400. code = stream.readSigned() + (code + 1);
  401. cMap.mapOne(hexToInt(char, dataSize), code);
  402. }
  403. break;
  404. case 3:
  405. stream.readHex(start, dataSize);
  406. stream.readHexNumber(end, dataSize);
  407. addHex(end, start, dataSize);
  408. code = stream.readNumber();
  409. cMap.mapCidRange(hexToInt(start, dataSize), hexToInt(end, dataSize), code);
  410. for (let i = 1; i < subitemsCount; i++) {
  411. incHex(end, dataSize);
  412. if (!sequence) {
  413. stream.readHexNumber(start, dataSize);
  414. addHex(start, end, dataSize);
  415. } else {
  416. start.set(end);
  417. }
  418. stream.readHexNumber(end, dataSize);
  419. addHex(end, start, dataSize);
  420. code = stream.readNumber();
  421. cMap.mapCidRange(hexToInt(start, dataSize), hexToInt(end, dataSize), code);
  422. }
  423. break;
  424. case 4:
  425. stream.readHex(char, ucs2DataSize);
  426. stream.readHex(charCode, dataSize);
  427. cMap.mapOne(hexToInt(char, ucs2DataSize), hexToStr(charCode, dataSize));
  428. for (let i = 1; i < subitemsCount; i++) {
  429. incHex(char, ucs2DataSize);
  430. if (!sequence) {
  431. stream.readHexNumber(tmp, ucs2DataSize);
  432. addHex(char, tmp, ucs2DataSize);
  433. }
  434. incHex(charCode, dataSize);
  435. stream.readHexSigned(tmp, dataSize);
  436. addHex(charCode, tmp, dataSize);
  437. cMap.mapOne(hexToInt(char, ucs2DataSize), hexToStr(charCode, dataSize));
  438. }
  439. break;
  440. case 5:
  441. stream.readHex(start, ucs2DataSize);
  442. stream.readHexNumber(end, ucs2DataSize);
  443. addHex(end, start, ucs2DataSize);
  444. stream.readHex(charCode, dataSize);
  445. cMap.mapBfRange(hexToInt(start, ucs2DataSize), hexToInt(end, ucs2DataSize), hexToStr(charCode, dataSize));
  446. for (let i = 1; i < subitemsCount; i++) {
  447. incHex(end, ucs2DataSize);
  448. if (!sequence) {
  449. stream.readHexNumber(start, ucs2DataSize);
  450. addHex(start, end, ucs2DataSize);
  451. } else {
  452. start.set(end);
  453. }
  454. stream.readHexNumber(end, ucs2DataSize);
  455. addHex(end, start, ucs2DataSize);
  456. stream.readHex(charCode, dataSize);
  457. cMap.mapBfRange(hexToInt(start, ucs2DataSize), hexToInt(end, ucs2DataSize), hexToStr(charCode, dataSize));
  458. }
  459. break;
  460. default:
  461. throw new Error(`BinaryCMapReader.process - unknown type: ${type}`);
  462. }
  463. }
  464. if (useCMap) {
  465. return extend(useCMap);
  466. }
  467. return cMap;
  468. }
  469. }
  470. return BinaryCMapReader;
  471. }();
  472. const CMapFactory = function CMapFactoryClosure() {
  473. function strToInt(str) {
  474. let a = 0;
  475. for (let i = 0; i < str.length; i++) {
  476. a = a << 8 | str.charCodeAt(i);
  477. }
  478. return a >>> 0;
  479. }
  480. function expectString(obj) {
  481. if (!(0, _util.isString)(obj)) {
  482. throw new _util.FormatError("Malformed CMap: expected string.");
  483. }
  484. }
  485. function expectInt(obj) {
  486. if (!Number.isInteger(obj)) {
  487. throw new _util.FormatError("Malformed CMap: expected int.");
  488. }
  489. }
  490. function parseBfChar(cMap, lexer) {
  491. while (true) {
  492. let obj = lexer.getObj();
  493. if ((0, _primitives.isEOF)(obj)) {
  494. break;
  495. }
  496. if ((0, _primitives.isCmd)(obj, "endbfchar")) {
  497. return;
  498. }
  499. expectString(obj);
  500. const src = strToInt(obj);
  501. obj = lexer.getObj();
  502. expectString(obj);
  503. const dst = obj;
  504. cMap.mapOne(src, dst);
  505. }
  506. }
  507. function parseBfRange(cMap, lexer) {
  508. while (true) {
  509. let obj = lexer.getObj();
  510. if ((0, _primitives.isEOF)(obj)) {
  511. break;
  512. }
  513. if ((0, _primitives.isCmd)(obj, "endbfrange")) {
  514. return;
  515. }
  516. expectString(obj);
  517. const low = strToInt(obj);
  518. obj = lexer.getObj();
  519. expectString(obj);
  520. const high = strToInt(obj);
  521. obj = lexer.getObj();
  522. if (Number.isInteger(obj) || (0, _util.isString)(obj)) {
  523. const dstLow = Number.isInteger(obj) ? String.fromCharCode(obj) : obj;
  524. cMap.mapBfRange(low, high, dstLow);
  525. } else if ((0, _primitives.isCmd)(obj, "[")) {
  526. obj = lexer.getObj();
  527. const array = [];
  528. while (!(0, _primitives.isCmd)(obj, "]") && !(0, _primitives.isEOF)(obj)) {
  529. array.push(obj);
  530. obj = lexer.getObj();
  531. }
  532. cMap.mapBfRangeToArray(low, high, array);
  533. } else {
  534. break;
  535. }
  536. }
  537. throw new _util.FormatError("Invalid bf range.");
  538. }
  539. function parseCidChar(cMap, lexer) {
  540. while (true) {
  541. let obj = lexer.getObj();
  542. if ((0, _primitives.isEOF)(obj)) {
  543. break;
  544. }
  545. if ((0, _primitives.isCmd)(obj, "endcidchar")) {
  546. return;
  547. }
  548. expectString(obj);
  549. const src = strToInt(obj);
  550. obj = lexer.getObj();
  551. expectInt(obj);
  552. const dst = obj;
  553. cMap.mapOne(src, dst);
  554. }
  555. }
  556. function parseCidRange(cMap, lexer) {
  557. while (true) {
  558. let obj = lexer.getObj();
  559. if ((0, _primitives.isEOF)(obj)) {
  560. break;
  561. }
  562. if ((0, _primitives.isCmd)(obj, "endcidrange")) {
  563. return;
  564. }
  565. expectString(obj);
  566. const low = strToInt(obj);
  567. obj = lexer.getObj();
  568. expectString(obj);
  569. const high = strToInt(obj);
  570. obj = lexer.getObj();
  571. expectInt(obj);
  572. const dstLow = obj;
  573. cMap.mapCidRange(low, high, dstLow);
  574. }
  575. }
  576. function parseCodespaceRange(cMap, lexer) {
  577. while (true) {
  578. let obj = lexer.getObj();
  579. if ((0, _primitives.isEOF)(obj)) {
  580. break;
  581. }
  582. if ((0, _primitives.isCmd)(obj, "endcodespacerange")) {
  583. return;
  584. }
  585. if (!(0, _util.isString)(obj)) {
  586. break;
  587. }
  588. const low = strToInt(obj);
  589. obj = lexer.getObj();
  590. if (!(0, _util.isString)(obj)) {
  591. break;
  592. }
  593. const high = strToInt(obj);
  594. cMap.addCodespaceRange(obj.length, low, high);
  595. }
  596. throw new _util.FormatError("Invalid codespace range.");
  597. }
  598. function parseWMode(cMap, lexer) {
  599. const obj = lexer.getObj();
  600. if (Number.isInteger(obj)) {
  601. cMap.vertical = !!obj;
  602. }
  603. }
  604. function parseCMapName(cMap, lexer) {
  605. const obj = lexer.getObj();
  606. if ((0, _primitives.isName)(obj) && (0, _util.isString)(obj.name)) {
  607. cMap.name = obj.name;
  608. }
  609. }
  610. async function parseCMap(cMap, lexer, fetchBuiltInCMap, useCMap) {
  611. let previous, embeddedUseCMap;
  612. objLoop: while (true) {
  613. try {
  614. const obj = lexer.getObj();
  615. if ((0, _primitives.isEOF)(obj)) {
  616. break;
  617. } else if ((0, _primitives.isName)(obj)) {
  618. if (obj.name === "WMode") {
  619. parseWMode(cMap, lexer);
  620. } else if (obj.name === "CMapName") {
  621. parseCMapName(cMap, lexer);
  622. }
  623. previous = obj;
  624. } else if ((0, _primitives.isCmd)(obj)) {
  625. switch (obj.cmd) {
  626. case "endcmap":
  627. break objLoop;
  628. case "usecmap":
  629. if ((0, _primitives.isName)(previous)) {
  630. embeddedUseCMap = previous.name;
  631. }
  632. break;
  633. case "begincodespacerange":
  634. parseCodespaceRange(cMap, lexer);
  635. break;
  636. case "beginbfchar":
  637. parseBfChar(cMap, lexer);
  638. break;
  639. case "begincidchar":
  640. parseCidChar(cMap, lexer);
  641. break;
  642. case "beginbfrange":
  643. parseBfRange(cMap, lexer);
  644. break;
  645. case "begincidrange":
  646. parseCidRange(cMap, lexer);
  647. break;
  648. }
  649. }
  650. } catch (ex) {
  651. if (ex instanceof _core_utils.MissingDataException) {
  652. throw ex;
  653. }
  654. (0, _util.warn)("Invalid cMap data: " + ex);
  655. continue;
  656. }
  657. }
  658. if (!useCMap && embeddedUseCMap) {
  659. useCMap = embeddedUseCMap;
  660. }
  661. if (useCMap) {
  662. return extendCMap(cMap, fetchBuiltInCMap, useCMap);
  663. }
  664. return cMap;
  665. }
  666. async function extendCMap(cMap, fetchBuiltInCMap, useCMap) {
  667. cMap.useCMap = await createBuiltInCMap(useCMap, fetchBuiltInCMap);
  668. if (cMap.numCodespaceRanges === 0) {
  669. const useCodespaceRanges = cMap.useCMap.codespaceRanges;
  670. for (let i = 0; i < useCodespaceRanges.length; i++) {
  671. cMap.codespaceRanges[i] = useCodespaceRanges[i].slice();
  672. }
  673. cMap.numCodespaceRanges = cMap.useCMap.numCodespaceRanges;
  674. }
  675. cMap.useCMap.forEach(function (key, value) {
  676. if (!cMap.contains(key)) {
  677. cMap.mapOne(key, cMap.useCMap.lookup(key));
  678. }
  679. });
  680. return cMap;
  681. }
  682. async function createBuiltInCMap(name, fetchBuiltInCMap) {
  683. if (name === "Identity-H") {
  684. return new IdentityCMap(false, 2);
  685. } else if (name === "Identity-V") {
  686. return new IdentityCMap(true, 2);
  687. }
  688. if (!BUILT_IN_CMAPS.includes(name)) {
  689. throw new Error("Unknown CMap name: " + name);
  690. }
  691. if (!fetchBuiltInCMap) {
  692. throw new Error("Built-in CMap parameters are not provided.");
  693. }
  694. const {
  695. cMapData,
  696. compressionType
  697. } = await fetchBuiltInCMap(name);
  698. const cMap = new CMap(true);
  699. if (compressionType === _util.CMapCompressionType.BINARY) {
  700. return new BinaryCMapReader().process(cMapData, cMap, useCMap => {
  701. return extendCMap(cMap, fetchBuiltInCMap, useCMap);
  702. });
  703. }
  704. if (compressionType === _util.CMapCompressionType.NONE) {
  705. const lexer = new _parser.Lexer(new _stream.Stream(cMapData));
  706. return parseCMap(cMap, lexer, fetchBuiltInCMap, null);
  707. }
  708. throw new Error("TODO: Only BINARY/NONE CMap compression is currently supported.");
  709. }
  710. return {
  711. async create(params) {
  712. const encoding = params.encoding;
  713. const fetchBuiltInCMap = params.fetchBuiltInCMap;
  714. const useCMap = params.useCMap;
  715. if ((0, _primitives.isName)(encoding)) {
  716. return createBuiltInCMap(encoding.name, fetchBuiltInCMap);
  717. } else if ((0, _primitives.isStream)(encoding)) {
  718. const parsedCMap = await parseCMap(new CMap(), new _parser.Lexer(encoding), fetchBuiltInCMap, useCMap);
  719. if (parsedCMap.isIdentityCMap) {
  720. return createBuiltInCMap(parsedCMap.name, fetchBuiltInCMap);
  721. }
  722. return parsedCMap;
  723. }
  724. throw new Error("Encoding required.");
  725. }
  726. };
  727. }();
  728. exports.CMapFactory = CMapFactory;