UNPKG

11.6 kBJavaScriptView Raw
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
24var _cff_parser = require('../../core/cff_parser');
25
26var _fonts = require('../../core/fonts');
27
28var _stream = require('../../core/stream');
29
30describe('CFFParser', function () {
31 function createWithNullProto(obj) {
32 var result = Object.create(null);
33 for (var i in obj) {
34 result[i] = obj[i];
35 }
36 return result;
37 }
38 var privateDictStub = {
39 getByName: function getByName(name) {
40 return 0;
41 }
42 };
43 var fontData, parser, cff;
44 beforeAll(function (done) {
45 var exampleFont = '0100040100010101134142434445462b' + '54696d65732d526f6d616e000101011f' + 'f81b00f81c02f81d03f819041c6f000d' + 'fb3cfb6efa7cfa1605e911b8f1120003' + '01010813183030312e30303754696d65' + '7320526f6d616e54696d657300000002' + '010102030e0e7d99f92a99fb7695f773' + '8b06f79a93fc7c8c077d99f85695f75e' + '9908fb6e8cf87393f7108b09a70adf0b' + 'f78e14';
46 var fontArr = [];
47 for (var i = 0, ii = exampleFont.length; i < ii; i += 2) {
48 var hex = exampleFont.substr(i, 2);
49 fontArr.push(parseInt(hex, 16));
50 }
51 fontData = new _stream.Stream(fontArr);
52 done();
53 });
54 afterAll(function () {
55 fontData = null;
56 });
57 beforeEach(function (done) {
58 parser = new _cff_parser.CFFParser(fontData, {}, _fonts.SEAC_ANALYSIS_ENABLED);
59 cff = parser.parse();
60 done();
61 });
62 afterEach(function (done) {
63 parser = cff = null;
64 done();
65 });
66 it('parses header', function () {
67 var header = cff.header;
68 expect(header.major).toEqual(1);
69 expect(header.minor).toEqual(0);
70 expect(header.hdrSize).toEqual(4);
71 expect(header.offSize).toEqual(1);
72 });
73 it('parses name index', function () {
74 var names = cff.names;
75 expect(names.length).toEqual(1);
76 expect(names[0]).toEqual('ABCDEF+Times-Roman');
77 });
78 it('parses string index', function () {
79 var strings = cff.strings;
80 expect(strings.count).toEqual(3);
81 expect(strings.get(0)).toEqual('.notdef');
82 expect(strings.get(391)).toEqual('001.007');
83 });
84 it('parses top dict', function () {
85 var topDict = cff.topDict;
86 expect(topDict.getByName('version')).toEqual(391);
87 expect(topDict.getByName('FullName')).toEqual(392);
88 expect(topDict.getByName('FamilyName')).toEqual(393);
89 expect(topDict.getByName('Weight')).toEqual(389);
90 expect(topDict.getByName('UniqueID')).toEqual(28416);
91 expect(topDict.getByName('FontBBox')).toEqual([-168, -218, 1000, 898]);
92 expect(topDict.getByName('CharStrings')).toEqual(94);
93 expect(topDict.getByName('Private')).toEqual([45, 102]);
94 });
95 it('refuses to add topDict key with invalid value (bug 1068432)', function () {
96 var topDict = cff.topDict;
97 var defaultValue = topDict.getByName('UnderlinePosition');
98 topDict.setByKey(3075, [NaN]);
99 expect(topDict.getByName('UnderlinePosition')).toEqual(defaultValue);
100 });
101 it('ignores reserved commands in parseDict, and refuses to add privateDict ' + 'keys with invalid values (bug 1308536)', function () {
102 var bytes = new Uint8Array([64, 39, 31, 30, 252, 114, 137, 115, 79, 30, 197, 119, 2, 99, 127, 6]);
103 parser.bytes = bytes;
104 var topDict = cff.topDict;
105 topDict.setByName('Private', [bytes.length, 0]);
106 var parsePrivateDict = function parsePrivateDict() {
107 parser.parsePrivateDict(topDict);
108 };
109 expect(parsePrivateDict).not.toThrow();
110 var privateDict = topDict.privateDict;
111 expect(privateDict.getByName('BlueValues')).toBeNull();
112 });
113 it('parses a CharString having cntrmask', function () {
114 var bytes = new Uint8Array([0, 1, 1, 0, 38, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 1, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 3, 20, 22, 22, 14]);
115 parser.bytes = bytes;
116 var charStringsIndex = parser.parseIndex(0).obj;
117 var charStrings = parser.parseCharStrings({
118 charStrings: charStringsIndex,
119 privateDict: privateDictStub
120 }).charStrings;
121 expect(charStrings.count).toEqual(1);
122 expect(charStrings.get(0).length).toEqual(38);
123 });
124 it('parses a CharString endchar with 4 args w/seac enabled', function () {
125 var parser = new _cff_parser.CFFParser(fontData, {}, true);
126 parser.parse();
127 var bytes = new Uint8Array([0, 1, 1, 0, 237, 247, 22, 247, 72, 204, 247, 86, 14]);
128 parser.bytes = bytes;
129 var charStringsIndex = parser.parseIndex(0).obj;
130 var result = parser.parseCharStrings({
131 charStrings: charStringsIndex,
132 privateDict: privateDictStub
133 });
134 expect(result.charStrings.count).toEqual(1);
135 expect(result.charStrings.get(0).length).toEqual(1);
136 expect(result.seacs.length).toEqual(1);
137 expect(result.seacs[0].length).toEqual(4);
138 expect(result.seacs[0][0]).toEqual(130);
139 expect(result.seacs[0][1]).toEqual(180);
140 expect(result.seacs[0][2]).toEqual(65);
141 expect(result.seacs[0][3]).toEqual(194);
142 });
143 it('parses a CharString endchar with 4 args w/seac disabled', function () {
144 var parser = new _cff_parser.CFFParser(fontData, {}, false);
145 parser.parse();
146 var bytes = new Uint8Array([0, 1, 1, 0, 237, 247, 22, 247, 72, 204, 247, 86, 14]);
147 parser.bytes = bytes;
148 var charStringsIndex = parser.parseIndex(0).obj;
149 var result = parser.parseCharStrings({
150 charStrings: charStringsIndex,
151 privateDict: privateDictStub
152 });
153 expect(result.charStrings.count).toEqual(1);
154 expect(result.charStrings.get(0).length).toEqual(9);
155 expect(result.seacs.length).toEqual(0);
156 });
157 it('parses a CharString endchar no args', function () {
158 var bytes = new Uint8Array([0, 1, 1, 0, 14]);
159 parser.bytes = bytes;
160 var charStringsIndex = parser.parseIndex(0).obj;
161 var result = parser.parseCharStrings({
162 charStrings: charStringsIndex,
163 privateDict: privateDictStub
164 });
165 expect(result.charStrings.count).toEqual(1);
166 expect(result.charStrings.get(0)[0]).toEqual(14);
167 expect(result.seacs.length).toEqual(0);
168 });
169 it('parses predefined charsets', function () {
170 var charset = parser.parseCharsets(0, 0, null, true);
171 expect(charset.predefined).toEqual(true);
172 });
173 it('parses charset format 0', function () {
174 var bytes = new Uint8Array([0x00, 0x00, 0x00, 0x00, 0x00, 0x02]);
175 parser.bytes = bytes;
176 var charset = parser.parseCharsets(3, 2, new _cff_parser.CFFStrings(), false);
177 expect(charset.charset[1]).toEqual('exclam');
178 charset = parser.parseCharsets(3, 2, new _cff_parser.CFFStrings(), true);
179 expect(charset.charset[1]).toEqual(2);
180 });
181 it('parses charset format 1', function () {
182 var bytes = new Uint8Array([0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x01]);
183 parser.bytes = bytes;
184 var charset = parser.parseCharsets(3, 2, new _cff_parser.CFFStrings(), false);
185 expect(charset.charset).toEqual(['.notdef', 'quoteright', 'parenleft']);
186 charset = parser.parseCharsets(3, 2, new _cff_parser.CFFStrings(), true);
187 expect(charset.charset).toEqual(['.notdef', 8, 9]);
188 });
189 it('parses charset format 2', function () {
190 var bytes = new Uint8Array([0x00, 0x00, 0x00, 0x02, 0x00, 0x08, 0x00, 0x01]);
191 parser.bytes = bytes;
192 var charset = parser.parseCharsets(3, 2, new _cff_parser.CFFStrings(), false);
193 expect(charset.charset).toEqual(['.notdef', 'quoteright', 'parenleft']);
194 charset = parser.parseCharsets(3, 2, new _cff_parser.CFFStrings(), true);
195 expect(charset.charset).toEqual(['.notdef', 8, 9]);
196 });
197 it('parses encoding format 0', function () {
198 var bytes = new Uint8Array([0x00, 0x00, 0x00, 0x01, 0x08]);
199 parser.bytes = bytes;
200 var encoding = parser.parseEncoding(2, {}, new _cff_parser.CFFStrings(), null);
201 expect(encoding.encoding).toEqual(createWithNullProto({ 0x8: 1 }));
202 });
203 it('parses encoding format 1', function () {
204 var bytes = new Uint8Array([0x00, 0x00, 0x01, 0x01, 0x07, 0x01]);
205 parser.bytes = bytes;
206 var encoding = parser.parseEncoding(2, {}, new _cff_parser.CFFStrings(), null);
207 expect(encoding.encoding).toEqual(createWithNullProto({
208 0x7: 0x01,
209 0x08: 0x02
210 }));
211 });
212 it('parses fdselect format 0', function () {
213 var bytes = new Uint8Array([0x00, 0x00, 0x01]);
214 parser.bytes = bytes.slice();
215 var fdSelect = parser.parseFDSelect(0, 2);
216 expect(fdSelect.fdSelect).toEqual([0, 1]);
217 expect(fdSelect.raw).toEqual(bytes);
218 });
219 it('parses fdselect format 3', function () {
220 var bytes = new Uint8Array([0x03, 0x00, 0x02, 0x00, 0x00, 0x09, 0x00, 0x02, 0x0a, 0x00, 0x04]);
221 parser.bytes = bytes.slice();
222 var fdSelect = parser.parseFDSelect(0, 4);
223 expect(fdSelect.fdSelect).toEqual([9, 9, 0xa, 0xa]);
224 expect(fdSelect.raw).toEqual(bytes);
225 });
226 it('parses invalid fdselect format 3 (bug 1146106)', function () {
227 var bytes = new Uint8Array([0x03, 0x00, 0x02, 0x00, 0x01, 0x09, 0x00, 0x02, 0x0a, 0x00, 0x04]);
228 parser.bytes = bytes.slice();
229 var fdSelect = parser.parseFDSelect(0, 4);
230 expect(fdSelect.fdSelect).toEqual([9, 9, 0xa, 0xa]);
231 bytes[3] = bytes[4] = 0x00;
232 expect(fdSelect.raw).toEqual(bytes);
233 });
234});
235describe('CFFCompiler', function () {
236 function testParser(bytes) {
237 bytes = new Uint8Array(bytes);
238 return new _cff_parser.CFFParser({
239 getBytes: function getBytes() {
240 return bytes;
241 }
242 }, {}, _fonts.SEAC_ANALYSIS_ENABLED);
243 }
244 it('encodes integers', function () {
245 var c = new _cff_parser.CFFCompiler();
246 expect(c.encodeInteger(0)).toEqual([0x8b]);
247 expect(c.encodeInteger(100)).toEqual([0xef]);
248 expect(c.encodeInteger(-100)).toEqual([0x27]);
249 expect(c.encodeInteger(1000)).toEqual([0xfa, 0x7c]);
250 expect(c.encodeInteger(-1000)).toEqual([0xfe, 0x7c]);
251 expect(c.encodeInteger(10000)).toEqual([0x1c, 0x27, 0x10]);
252 expect(c.encodeInteger(-10000)).toEqual([0x1c, 0xd8, 0xf0]);
253 expect(c.encodeInteger(100000)).toEqual([0x1d, 0x00, 0x01, 0x86, 0xa0]);
254 expect(c.encodeInteger(-100000)).toEqual([0x1d, 0xff, 0xfe, 0x79, 0x60]);
255 });
256 it('encodes floats', function () {
257 var c = new _cff_parser.CFFCompiler();
258 expect(c.encodeFloat(-2.25)).toEqual([0x1e, 0xe2, 0xa2, 0x5f]);
259 expect(c.encodeFloat(5e-11)).toEqual([0x1e, 0x5c, 0x11, 0xff]);
260 });
261 it('sanitizes name index', function () {
262 var c = new _cff_parser.CFFCompiler();
263 var nameIndexCompiled = c.compileNameIndex(['[a']);
264 var parser = testParser(nameIndexCompiled);
265 var nameIndex = parser.parseIndex(0);
266 var names = parser.parseNameIndex(nameIndex.obj);
267 expect(names).toEqual(['_a']);
268 var longName = '';
269 for (var i = 0; i < 129; i++) {
270 longName += '_';
271 }
272 nameIndexCompiled = c.compileNameIndex([longName]);
273 parser = testParser(nameIndexCompiled);
274 nameIndex = parser.parseIndex(0);
275 names = parser.parseNameIndex(nameIndex.obj);
276 expect(names[0].length).toEqual(127);
277 });
278});
\No newline at end of file