cmap_spec.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. /**
  2. * @licstart The following is the entire license notice for the
  3. * Javascript code in this page
  4. *
  5. * Copyright 2020 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. var _cmap = require("../../core/cmap.js");
  24. var _display_utils = require("../../display/display_utils.js");
  25. var _is_node = require("../../shared/is_node.js");
  26. var _primitives = require("../../core/primitives.js");
  27. var _node_utils = require("../../display/node_utils.js");
  28. var _stream = require("../../core/stream.js");
  29. var cMapUrl = {
  30. dom: "../../external/bcmaps/",
  31. node: "./external/bcmaps/"
  32. };
  33. var cMapPacked = true;
  34. describe("cmap", function () {
  35. var fetchBuiltInCMap;
  36. beforeAll(function (done) {
  37. var CMapReaderFactory;
  38. if (_is_node.isNodeJS) {
  39. CMapReaderFactory = new _node_utils.NodeCMapReaderFactory({
  40. baseUrl: cMapUrl.node,
  41. isCompressed: cMapPacked
  42. });
  43. } else {
  44. CMapReaderFactory = new _display_utils.DOMCMapReaderFactory({
  45. baseUrl: cMapUrl.dom,
  46. isCompressed: cMapPacked
  47. });
  48. }
  49. fetchBuiltInCMap = function (name) {
  50. return CMapReaderFactory.fetch({
  51. name
  52. });
  53. };
  54. done();
  55. });
  56. afterAll(function () {
  57. fetchBuiltInCMap = null;
  58. });
  59. it("parses beginbfchar", function (done) {
  60. var str = "2 beginbfchar\n" + "<03> <00>\n" + "<04> <01>\n" + "endbfchar\n";
  61. var stream = new _stream.StringStream(str);
  62. var cmapPromise = _cmap.CMapFactory.create({
  63. encoding: stream
  64. });
  65. cmapPromise.then(function (cmap) {
  66. expect(cmap.lookup(0x03)).toEqual(String.fromCharCode(0x00));
  67. expect(cmap.lookup(0x04)).toEqual(String.fromCharCode(0x01));
  68. expect(cmap.lookup(0x05)).toBeUndefined();
  69. done();
  70. }).catch(function (reason) {
  71. done.fail(reason);
  72. });
  73. });
  74. it("parses beginbfrange with range", function (done) {
  75. var str = "1 beginbfrange\n" + "<06> <0B> 0\n" + "endbfrange\n";
  76. var stream = new _stream.StringStream(str);
  77. var cmapPromise = _cmap.CMapFactory.create({
  78. encoding: stream
  79. });
  80. cmapPromise.then(function (cmap) {
  81. expect(cmap.lookup(0x05)).toBeUndefined();
  82. expect(cmap.lookup(0x06)).toEqual(String.fromCharCode(0x00));
  83. expect(cmap.lookup(0x0b)).toEqual(String.fromCharCode(0x05));
  84. expect(cmap.lookup(0x0c)).toBeUndefined();
  85. done();
  86. }).catch(function (reason) {
  87. done.fail(reason);
  88. });
  89. });
  90. it("parses beginbfrange with array", function (done) {
  91. var str = "1 beginbfrange\n" + "<0D> <12> [ 0 1 2 3 4 5 ]\n" + "endbfrange\n";
  92. var stream = new _stream.StringStream(str);
  93. var cmapPromise = _cmap.CMapFactory.create({
  94. encoding: stream
  95. });
  96. cmapPromise.then(function (cmap) {
  97. expect(cmap.lookup(0x0c)).toBeUndefined();
  98. expect(cmap.lookup(0x0d)).toEqual(0x00);
  99. expect(cmap.lookup(0x12)).toEqual(0x05);
  100. expect(cmap.lookup(0x13)).toBeUndefined();
  101. done();
  102. }).catch(function (reason) {
  103. done.fail(reason);
  104. });
  105. });
  106. it("parses begincidchar", function (done) {
  107. var str = "1 begincidchar\n" + "<14> 0\n" + "endcidchar\n";
  108. var stream = new _stream.StringStream(str);
  109. var cmapPromise = _cmap.CMapFactory.create({
  110. encoding: stream
  111. });
  112. cmapPromise.then(function (cmap) {
  113. expect(cmap.lookup(0x14)).toEqual(0x00);
  114. expect(cmap.lookup(0x15)).toBeUndefined();
  115. done();
  116. }).catch(function (reason) {
  117. done.fail(reason);
  118. });
  119. });
  120. it("parses begincidrange", function (done) {
  121. var str = "1 begincidrange\n" + "<0016> <001B> 0\n" + "endcidrange\n";
  122. var stream = new _stream.StringStream(str);
  123. var cmapPromise = _cmap.CMapFactory.create({
  124. encoding: stream
  125. });
  126. cmapPromise.then(function (cmap) {
  127. expect(cmap.lookup(0x15)).toBeUndefined();
  128. expect(cmap.lookup(0x16)).toEqual(0x00);
  129. expect(cmap.lookup(0x1b)).toEqual(0x05);
  130. expect(cmap.lookup(0x1c)).toBeUndefined();
  131. done();
  132. }).catch(function (reason) {
  133. done.fail(reason);
  134. });
  135. });
  136. it("decodes codespace ranges", function (done) {
  137. var str = "1 begincodespacerange\n" + "<01> <02>\n" + "<00000003> <00000004>\n" + "endcodespacerange\n";
  138. var stream = new _stream.StringStream(str);
  139. var cmapPromise = _cmap.CMapFactory.create({
  140. encoding: stream
  141. });
  142. cmapPromise.then(function (cmap) {
  143. var c = {};
  144. cmap.readCharCode(String.fromCharCode(1), 0, c);
  145. expect(c.charcode).toEqual(1);
  146. expect(c.length).toEqual(1);
  147. cmap.readCharCode(String.fromCharCode(0, 0, 0, 3), 0, c);
  148. expect(c.charcode).toEqual(3);
  149. expect(c.length).toEqual(4);
  150. done();
  151. }).catch(function (reason) {
  152. done.fail(reason);
  153. });
  154. });
  155. it("decodes 4 byte codespace ranges", function (done) {
  156. var str = "1 begincodespacerange\n" + "<8EA1A1A1> <8EA1FEFE>\n" + "endcodespacerange\n";
  157. var stream = new _stream.StringStream(str);
  158. var cmapPromise = _cmap.CMapFactory.create({
  159. encoding: stream
  160. });
  161. cmapPromise.then(function (cmap) {
  162. var c = {};
  163. cmap.readCharCode(String.fromCharCode(0x8e, 0xa1, 0xa1, 0xa1), 0, c);
  164. expect(c.charcode).toEqual(0x8ea1a1a1);
  165. expect(c.length).toEqual(4);
  166. done();
  167. }).catch(function (reason) {
  168. done.fail(reason);
  169. });
  170. });
  171. it("read usecmap", function (done) {
  172. var str = "/Adobe-Japan1-1 usecmap\n";
  173. var stream = new _stream.StringStream(str);
  174. var cmapPromise = _cmap.CMapFactory.create({
  175. encoding: stream,
  176. fetchBuiltInCMap,
  177. useCMap: null
  178. });
  179. cmapPromise.then(function (cmap) {
  180. expect(cmap instanceof _cmap.CMap).toEqual(true);
  181. expect(cmap.useCMap).not.toBeNull();
  182. expect(cmap.builtInCMap).toBeFalsy();
  183. expect(cmap.length).toEqual(0x20a7);
  184. expect(cmap.isIdentityCMap).toEqual(false);
  185. done();
  186. }).catch(function (reason) {
  187. done.fail(reason);
  188. });
  189. });
  190. it("parses cmapname", function (done) {
  191. var str = "/CMapName /Identity-H def\n";
  192. var stream = new _stream.StringStream(str);
  193. var cmapPromise = _cmap.CMapFactory.create({
  194. encoding: stream
  195. });
  196. cmapPromise.then(function (cmap) {
  197. expect(cmap.name).toEqual("Identity-H");
  198. done();
  199. }).catch(function (reason) {
  200. done.fail(reason);
  201. });
  202. });
  203. it("parses wmode", function (done) {
  204. var str = "/WMode 1 def\n";
  205. var stream = new _stream.StringStream(str);
  206. var cmapPromise = _cmap.CMapFactory.create({
  207. encoding: stream
  208. });
  209. cmapPromise.then(function (cmap) {
  210. expect(cmap.vertical).toEqual(true);
  211. done();
  212. }).catch(function (reason) {
  213. done.fail(reason);
  214. });
  215. });
  216. it("loads built in cmap", function (done) {
  217. var cmapPromise = _cmap.CMapFactory.create({
  218. encoding: _primitives.Name.get("Adobe-Japan1-1"),
  219. fetchBuiltInCMap,
  220. useCMap: null
  221. });
  222. cmapPromise.then(function (cmap) {
  223. expect(cmap instanceof _cmap.CMap).toEqual(true);
  224. expect(cmap.useCMap).toBeNull();
  225. expect(cmap.builtInCMap).toBeTruthy();
  226. expect(cmap.length).toEqual(0x20a7);
  227. expect(cmap.isIdentityCMap).toEqual(false);
  228. done();
  229. }).catch(function (reason) {
  230. done.fail(reason);
  231. });
  232. });
  233. it("loads built in identity cmap", function (done) {
  234. var cmapPromise = _cmap.CMapFactory.create({
  235. encoding: _primitives.Name.get("Identity-H"),
  236. fetchBuiltInCMap,
  237. useCMap: null
  238. });
  239. cmapPromise.then(function (cmap) {
  240. expect(cmap instanceof _cmap.IdentityCMap).toEqual(true);
  241. expect(cmap.vertical).toEqual(false);
  242. expect(cmap.length).toEqual(0x10000);
  243. expect(function () {
  244. return cmap.isIdentityCMap;
  245. }).toThrow(new Error("should not access .isIdentityCMap"));
  246. done();
  247. }).catch(function (reason) {
  248. done.fail(reason);
  249. });
  250. });
  251. it("attempts to load a non-existent built-in CMap", function (done) {
  252. var cmapPromise = _cmap.CMapFactory.create({
  253. encoding: _primitives.Name.get("null"),
  254. fetchBuiltInCMap,
  255. useCMap: null
  256. });
  257. cmapPromise.then(function () {
  258. done.fail("No CMap should be loaded");
  259. }, function (reason) {
  260. expect(reason instanceof Error).toEqual(true);
  261. expect(reason.message).toEqual("Unknown CMap name: null");
  262. done();
  263. });
  264. });
  265. it("attempts to load a built-in CMap without the necessary API parameters", function (done) {
  266. function tmpFetchBuiltInCMap(name) {
  267. var CMapReaderFactory = _is_node.isNodeJS ? new _node_utils.NodeCMapReaderFactory({}) : new _display_utils.DOMCMapReaderFactory({});
  268. return CMapReaderFactory.fetch({
  269. name
  270. });
  271. }
  272. var cmapPromise = _cmap.CMapFactory.create({
  273. encoding: _primitives.Name.get("Adobe-Japan1-1"),
  274. fetchBuiltInCMap: tmpFetchBuiltInCMap,
  275. useCMap: null
  276. });
  277. cmapPromise.then(function () {
  278. done.fail("No CMap should be loaded");
  279. }, function (reason) {
  280. expect(reason instanceof Error).toEqual(true);
  281. expect(reason.message).toEqual('The CMap "baseUrl" parameter must be specified, ensure that ' + 'the "cMapUrl" and "cMapPacked" API parameters are provided.');
  282. done();
  283. });
  284. });
  285. it("attempts to load a built-in CMap with inconsistent API parameters", function (done) {
  286. function tmpFetchBuiltInCMap(name) {
  287. let CMapReaderFactory;
  288. if (_is_node.isNodeJS) {
  289. CMapReaderFactory = new _node_utils.NodeCMapReaderFactory({
  290. baseUrl: cMapUrl.node,
  291. isCompressed: false
  292. });
  293. } else {
  294. CMapReaderFactory = new _display_utils.DOMCMapReaderFactory({
  295. baseUrl: cMapUrl.dom,
  296. isCompressed: false
  297. });
  298. }
  299. return CMapReaderFactory.fetch({
  300. name
  301. });
  302. }
  303. const cmapPromise = _cmap.CMapFactory.create({
  304. encoding: _primitives.Name.get("Adobe-Japan1-1"),
  305. fetchBuiltInCMap: tmpFetchBuiltInCMap,
  306. useCMap: null
  307. });
  308. cmapPromise.then(function () {
  309. done.fail("No CMap should be loaded");
  310. }, function (reason) {
  311. expect(reason instanceof Error).toEqual(true);
  312. const message = reason.message;
  313. expect(message.startsWith("Unable to load CMap at: ")).toEqual(true);
  314. expect(message.endsWith("/external/bcmaps/Adobe-Japan1-1")).toEqual(true);
  315. done();
  316. });
  317. });
  318. });