cmap_spec.js 11 KB

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