2
0

cmap_spec.js 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. /**
  2. * @licstart The following is the entire license notice for the
  3. * JavaScript code in this page
  4. *
  5. * Copyright 2022 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 _test_utils = require("./test_utils.js");
  25. var _api = require("../../display/api.js");
  26. var _primitives = require("../../core/primitives.js");
  27. var _stream = require("../../core/stream.js");
  28. describe("cmap", function () {
  29. let fetchBuiltInCMap;
  30. beforeAll(function () {
  31. const CMapReaderFactory = new _api.DefaultCMapReaderFactory({
  32. baseUrl: _test_utils.CMAP_PARAMS.cMapUrl,
  33. isCompressed: _test_utils.CMAP_PARAMS.cMapPacked
  34. });
  35. fetchBuiltInCMap = function (name) {
  36. return CMapReaderFactory.fetch({
  37. name
  38. });
  39. };
  40. });
  41. afterAll(function () {
  42. fetchBuiltInCMap = null;
  43. });
  44. it("parses beginbfchar", async function () {
  45. const str = "2 beginbfchar\n" + "<03> <00>\n" + "<04> <01>\n" + "endbfchar\n";
  46. const stream = new _stream.StringStream(str);
  47. const cmap = await _cmap.CMapFactory.create({
  48. encoding: stream
  49. });
  50. expect(cmap.lookup(0x03)).toEqual(String.fromCharCode(0x00));
  51. expect(cmap.lookup(0x04)).toEqual(String.fromCharCode(0x01));
  52. expect(cmap.lookup(0x05)).toBeUndefined();
  53. });
  54. it("parses beginbfrange with range", async function () {
  55. const str = "1 beginbfrange\n" + "<06> <0B> 0\n" + "endbfrange\n";
  56. const stream = new _stream.StringStream(str);
  57. const cmap = await _cmap.CMapFactory.create({
  58. encoding: stream
  59. });
  60. expect(cmap.lookup(0x05)).toBeUndefined();
  61. expect(cmap.lookup(0x06)).toEqual(String.fromCharCode(0x00));
  62. expect(cmap.lookup(0x0b)).toEqual(String.fromCharCode(0x05));
  63. expect(cmap.lookup(0x0c)).toBeUndefined();
  64. });
  65. it("parses beginbfrange with array", async function () {
  66. const str = "1 beginbfrange\n" + "<0D> <12> [ 0 1 2 3 4 5 ]\n" + "endbfrange\n";
  67. const stream = new _stream.StringStream(str);
  68. const cmap = await _cmap.CMapFactory.create({
  69. encoding: stream
  70. });
  71. expect(cmap.lookup(0x0c)).toBeUndefined();
  72. expect(cmap.lookup(0x0d)).toEqual(0x00);
  73. expect(cmap.lookup(0x12)).toEqual(0x05);
  74. expect(cmap.lookup(0x13)).toBeUndefined();
  75. });
  76. it("parses begincidchar", async function () {
  77. const str = "1 begincidchar\n" + "<14> 0\n" + "endcidchar\n";
  78. const stream = new _stream.StringStream(str);
  79. const cmap = await _cmap.CMapFactory.create({
  80. encoding: stream
  81. });
  82. expect(cmap.lookup(0x14)).toEqual(0x00);
  83. expect(cmap.lookup(0x15)).toBeUndefined();
  84. });
  85. it("parses begincidrange", async function () {
  86. const str = "1 begincidrange\n" + "<0016> <001B> 0\n" + "endcidrange\n";
  87. const stream = new _stream.StringStream(str);
  88. const cmap = await _cmap.CMapFactory.create({
  89. encoding: stream
  90. });
  91. expect(cmap.lookup(0x15)).toBeUndefined();
  92. expect(cmap.lookup(0x16)).toEqual(0x00);
  93. expect(cmap.lookup(0x1b)).toEqual(0x05);
  94. expect(cmap.lookup(0x1c)).toBeUndefined();
  95. });
  96. it("decodes codespace ranges", async function () {
  97. const str = "1 begincodespacerange\n" + "<01> <02>\n" + "<00000003> <00000004>\n" + "endcodespacerange\n";
  98. const stream = new _stream.StringStream(str);
  99. const cmap = await _cmap.CMapFactory.create({
  100. encoding: stream
  101. });
  102. const c = {};
  103. cmap.readCharCode(String.fromCharCode(1), 0, c);
  104. expect(c.charcode).toEqual(1);
  105. expect(c.length).toEqual(1);
  106. cmap.readCharCode(String.fromCharCode(0, 0, 0, 3), 0, c);
  107. expect(c.charcode).toEqual(3);
  108. expect(c.length).toEqual(4);
  109. });
  110. it("decodes 4 byte codespace ranges", async function () {
  111. const str = "1 begincodespacerange\n" + "<8EA1A1A1> <8EA1FEFE>\n" + "endcodespacerange\n";
  112. const stream = new _stream.StringStream(str);
  113. const cmap = await _cmap.CMapFactory.create({
  114. encoding: stream
  115. });
  116. const c = {};
  117. cmap.readCharCode(String.fromCharCode(0x8e, 0xa1, 0xa1, 0xa1), 0, c);
  118. expect(c.charcode).toEqual(0x8ea1a1a1);
  119. expect(c.length).toEqual(4);
  120. });
  121. it("read usecmap", async function () {
  122. const str = "/Adobe-Japan1-1 usecmap\n";
  123. const stream = new _stream.StringStream(str);
  124. const cmap = await _cmap.CMapFactory.create({
  125. encoding: stream,
  126. fetchBuiltInCMap,
  127. useCMap: null
  128. });
  129. expect(cmap instanceof _cmap.CMap).toEqual(true);
  130. expect(cmap.useCMap).not.toBeNull();
  131. expect(cmap.builtInCMap).toBeFalsy();
  132. expect(cmap.length).toEqual(0x20a7);
  133. expect(cmap.isIdentityCMap).toEqual(false);
  134. });
  135. it("parses cmapname", async function () {
  136. const str = "/CMapName /Identity-H def\n";
  137. const stream = new _stream.StringStream(str);
  138. const cmap = await _cmap.CMapFactory.create({
  139. encoding: stream
  140. });
  141. expect(cmap.name).toEqual("Identity-H");
  142. });
  143. it("parses wmode", async function () {
  144. const str = "/WMode 1 def\n";
  145. const stream = new _stream.StringStream(str);
  146. const cmap = await _cmap.CMapFactory.create({
  147. encoding: stream
  148. });
  149. expect(cmap.vertical).toEqual(true);
  150. });
  151. it("loads built in cmap", async function () {
  152. const cmap = await _cmap.CMapFactory.create({
  153. encoding: _primitives.Name.get("Adobe-Japan1-1"),
  154. fetchBuiltInCMap,
  155. useCMap: null
  156. });
  157. expect(cmap instanceof _cmap.CMap).toEqual(true);
  158. expect(cmap.useCMap).toBeNull();
  159. expect(cmap.builtInCMap).toBeTruthy();
  160. expect(cmap.length).toEqual(0x20a7);
  161. expect(cmap.isIdentityCMap).toEqual(false);
  162. });
  163. it("loads built in identity cmap", async function () {
  164. const cmap = await _cmap.CMapFactory.create({
  165. encoding: _primitives.Name.get("Identity-H"),
  166. fetchBuiltInCMap,
  167. useCMap: null
  168. });
  169. expect(cmap instanceof _cmap.IdentityCMap).toEqual(true);
  170. expect(cmap.vertical).toEqual(false);
  171. expect(cmap.length).toEqual(0x10000);
  172. expect(function () {
  173. return cmap.isIdentityCMap;
  174. }).toThrow(new Error("should not access .isIdentityCMap"));
  175. });
  176. it("attempts to load a non-existent built-in CMap", async function () {
  177. try {
  178. await _cmap.CMapFactory.create({
  179. encoding: _primitives.Name.get("null"),
  180. fetchBuiltInCMap,
  181. useCMap: null
  182. });
  183. expect(false).toEqual(true);
  184. } catch (reason) {
  185. expect(reason instanceof Error).toEqual(true);
  186. expect(reason.message).toEqual("Unknown CMap name: null");
  187. }
  188. });
  189. it("attempts to load a built-in CMap without the necessary API parameters", async function () {
  190. function tmpFetchBuiltInCMap(name) {
  191. const CMapReaderFactory = new _api.DefaultCMapReaderFactory({});
  192. return CMapReaderFactory.fetch({
  193. name
  194. });
  195. }
  196. try {
  197. await _cmap.CMapFactory.create({
  198. encoding: _primitives.Name.get("Adobe-Japan1-1"),
  199. fetchBuiltInCMap: tmpFetchBuiltInCMap,
  200. useCMap: null
  201. });
  202. expect(false).toEqual(true);
  203. } catch (reason) {
  204. expect(reason instanceof Error).toEqual(true);
  205. expect(reason.message).toEqual('The CMap "baseUrl" parameter must be specified, ensure that ' + 'the "cMapUrl" and "cMapPacked" API parameters are provided.');
  206. }
  207. });
  208. it("attempts to load a built-in CMap with inconsistent API parameters", async function () {
  209. function tmpFetchBuiltInCMap(name) {
  210. const CMapReaderFactory = new _api.DefaultCMapReaderFactory({
  211. baseUrl: _test_utils.CMAP_PARAMS.cMapUrl,
  212. isCompressed: false
  213. });
  214. return CMapReaderFactory.fetch({
  215. name
  216. });
  217. }
  218. try {
  219. await _cmap.CMapFactory.create({
  220. encoding: _primitives.Name.get("Adobe-Japan1-1"),
  221. fetchBuiltInCMap: tmpFetchBuiltInCMap,
  222. useCMap: null
  223. });
  224. expect(false).toEqual(true);
  225. } catch (reason) {
  226. expect(reason instanceof Error).toEqual(true);
  227. const message = reason.message;
  228. expect(message.startsWith("Unable to load CMap at: ")).toEqual(true);
  229. expect(message.endsWith("/external/bcmaps/Adobe-Japan1-1")).toEqual(true);
  230. }
  231. });
  232. });