pdfjs-dist 2.0.487 → 2.1.266
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of pdfjs-dist might be problematic. Click here for more details.
- package/bower.json +1 -1
- package/build/pdf.js +15564 -9476
- package/build/pdf.js.map +1 -1
- package/build/pdf.min.js +1 -1
- package/build/pdf.worker.js +46644 -36309
- package/build/pdf.worker.js.map +1 -1
- package/build/pdf.worker.min.js +1 -1
- package/external/url/url-lib.js +627 -0
- package/image_decoders/pdf.image_decoders.js +11430 -0
- package/image_decoders/pdf.image_decoders.js.map +1 -0
- package/image_decoders/pdf.image_decoders.min.js +1 -0
- package/lib/core/annotation.js +406 -131
- package/lib/core/arithmetic_decoder.js +275 -245
- package/lib/core/bidi.js +65 -6
- package/lib/core/ccitt.js +173 -18
- package/lib/core/ccitt_stream.js +15 -6
- package/lib/core/cff_parser.js +376 -53
- package/lib/core/charsets.js +5 -4
- package/lib/core/chunked_stream.js +387 -149
- package/lib/core/cmap.js +310 -75
- package/lib/core/colorspace.js +874 -594
- package/lib/core/crypto.js +290 -45
- package/lib/core/document.js +545 -260
- package/lib/core/encodings.js +19 -10
- package/lib/core/evaluator.js +725 -147
- package/lib/core/font_renderer.js +360 -91
- package/lib/core/fonts.js +791 -186
- package/lib/core/function.js +284 -71
- package/lib/core/glyphlist.js +3 -2
- package/lib/core/image.js +168 -61
- package/lib/core/jbig2.js +479 -66
- package/lib/core/jbig2_stream.js +19 -8
- package/lib/core/jpeg_stream.js +38 -13
- package/lib/core/jpg.js +252 -29
- package/lib/core/jpx.js +396 -6
- package/lib/core/jpx_stream.js +18 -6
- package/lib/core/metrics.js +4 -4
- package/lib/core/murmurhash3.js +24 -6
- package/lib/core/obj.js +1137 -475
- package/lib/core/operator_list.js +108 -6
- package/lib/core/parser.js +321 -68
- package/lib/core/pattern.js +145 -13
- package/lib/core/pdf_manager.js +321 -133
- package/lib/core/primitives.js +75 -22
- package/lib/core/ps_parser.js +134 -45
- package/lib/core/standard_fonts.js +10 -10
- package/lib/core/stream.js +313 -34
- package/lib/core/type1_parser.js +143 -13
- package/lib/core/unicode.js +31 -4
- package/lib/core/worker.js +210 -66
- package/lib/display/annotation_layer.js +361 -123
- package/lib/display/api.js +1454 -729
- package/lib/display/api_compatibility.js +11 -13
- package/lib/display/canvas.js +324 -29
- package/lib/display/content_disposition.js +83 -32
- package/lib/display/dom_utils.js +226 -41
- package/lib/display/fetch_stream.js +208 -84
- package/lib/display/font_loader.js +465 -236
- package/lib/display/metadata.js +38 -16
- package/lib/display/network.js +216 -51
- package/lib/display/network_utils.js +32 -19
- package/lib/display/node_stream.js +352 -169
- package/lib/display/pattern_helper.js +58 -7
- package/lib/display/svg.js +242 -29
- package/lib/display/text_layer.js +132 -18
- package/lib/display/transport_stream.js +171 -42
- package/lib/display/webgl.js +64 -18
- package/lib/display/worker_options.js +5 -4
- package/lib/display/xml_parser.js +166 -53
- package/lib/examples/node/domstubs.js +57 -4
- package/lib/pdf.js +21 -4
- package/lib/pdf.worker.js +5 -3
- package/lib/shared/compatibility.js +158 -564
- package/lib/shared/global_scope.js +2 -2
- package/lib/shared/is_node.js +4 -4
- package/lib/shared/message_handler.js +521 -0
- package/lib/shared/streams_polyfill.js +21 -17
- package/lib/shared/url_polyfill.js +56 -0
- package/lib/shared/util.js +295 -650
- package/lib/test/unit/annotation_spec.js +629 -345
- package/lib/test/unit/api_spec.js +555 -253
- package/lib/test/unit/bidi_spec.js +7 -7
- package/lib/test/unit/cff_parser_spec.js +40 -11
- package/lib/test/unit/clitests_helper.js +9 -7
- package/lib/test/unit/cmap_spec.js +80 -26
- package/lib/test/unit/colorspace_spec.js +99 -52
- package/lib/test/unit/crypto_spec.js +17 -5
- package/lib/test/unit/custom_spec.js +41 -53
- package/lib/test/unit/display_svg_spec.js +33 -17
- package/lib/test/unit/document_spec.js +3 -3
- package/lib/test/unit/dom_utils_spec.js +9 -9
- package/lib/test/unit/encodings_spec.js +25 -45
- package/lib/test/unit/evaluator_spec.js +34 -9
- package/lib/test/unit/function_spec.js +17 -5
- package/lib/test/unit/jasmine-boot.js +31 -18
- package/lib/test/unit/{util_stream_spec.js → message_handler_spec.js} +41 -69
- package/lib/test/unit/metadata_spec.js +71 -11
- package/lib/test/unit/murmurhash3_spec.js +3 -3
- package/lib/test/unit/network_spec.js +20 -5
- package/lib/test/unit/network_utils_spec.js +41 -14
- package/lib/test/unit/node_stream_spec.js +51 -27
- package/lib/test/unit/parser_spec.js +35 -8
- package/lib/test/unit/pdf_find_controller_spec.js +230 -0
- package/lib/test/unit/pdf_find_utils_spec.js +63 -0
- package/lib/test/unit/pdf_history_spec.js +21 -9
- package/lib/test/unit/primitives_spec.js +24 -4
- package/lib/test/unit/stream_spec.js +12 -4
- package/lib/test/unit/test_utils.js +90 -27
- package/lib/test/unit/testreporter.js +21 -3
- package/lib/test/unit/type1_parser_spec.js +8 -6
- package/lib/test/unit/ui_utils_spec.js +452 -14
- package/lib/test/unit/unicode_spec.js +14 -11
- package/lib/test/unit/util_spec.js +131 -9
- package/lib/web/annotation_layer_builder.js +39 -22
- package/lib/web/app.js +1240 -582
- package/lib/web/app_options.js +71 -41
- package/lib/web/base_viewer.js +508 -179
- package/lib/web/chromecom.js +261 -117
- package/lib/web/debugger.js +166 -22
- package/lib/web/download_manager.js +31 -13
- package/lib/web/firefox_print_service.js +17 -9
- package/lib/web/firefoxcom.js +283 -79
- package/lib/web/genericcom.js +89 -30
- package/lib/web/genericl10n.js +142 -30
- package/lib/web/grab_to_pan.js +26 -4
- package/lib/web/interfaces.js +170 -47
- package/lib/web/overlay_manager.js +235 -85
- package/lib/web/password_prompt.js +21 -13
- package/lib/web/pdf_attachment_viewer.js +38 -18
- package/lib/web/pdf_cursor_tools.js +39 -16
- package/lib/web/pdf_document_properties.js +80 -30
- package/lib/web/pdf_find_bar.js +84 -40
- package/lib/web/pdf_find_controller.js +495 -184
- package/lib/web/pdf_find_utils.js +111 -0
- package/lib/web/pdf_history.js +190 -53
- package/lib/web/pdf_link_service.js +137 -76
- package/lib/web/pdf_outline_viewer.js +73 -22
- package/lib/web/pdf_page_view.js +196 -63
- package/lib/web/pdf_presentation_mode.js +99 -34
- package/lib/web/pdf_print_service.js +57 -11
- package/lib/web/pdf_rendering_queue.js +27 -5
- package/lib/web/pdf_sidebar.js +120 -67
- package/lib/web/pdf_sidebar_resizer.js +42 -16
- package/lib/web/pdf_single_page_viewer.js +74 -66
- package/lib/web/pdf_thumbnail_view.js +103 -32
- package/lib/web/pdf_thumbnail_viewer.js +64 -24
- package/lib/web/pdf_viewer.component.js +112 -32
- package/lib/web/pdf_viewer.js +91 -52
- package/lib/web/preferences.js +275 -80
- package/lib/web/secondary_toolbar.js +165 -40
- package/lib/web/text_layer_builder.js +162 -65
- package/lib/web/toolbar.js +78 -43
- package/lib/web/ui_utils.js +462 -136
- package/lib/web/view_history.js +215 -67
- package/lib/web/viewer_compatibility.js +4 -13
- package/package.json +5 -4
- package/web/pdf_viewer.css +58 -1
- package/web/pdf_viewer.js +6346 -3919
- package/web/pdf_viewer.js.map +1 -1
- package/lib/test/unit/fonts_spec.js +0 -81
- package/lib/web/dom_events.js +0 -137
package/lib/core/fonts.js
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
* @licstart The following is the entire license notice for the
|
3
3
|
* Javascript code in this page
|
4
4
|
*
|
5
|
-
* Copyright
|
5
|
+
* Copyright 2018 Mozilla Foundation
|
6
6
|
*
|
7
7
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
8
8
|
* you may not use this file except in compliance with the License.
|
@@ -19,36 +19,46 @@
|
|
19
19
|
* @licend The above is the entire license notice for the
|
20
20
|
* Javascript code in this page
|
21
21
|
*/
|
22
|
-
|
22
|
+
"use strict";
|
23
23
|
|
24
24
|
Object.defineProperty(exports, "__esModule", {
|
25
25
|
value: true
|
26
26
|
});
|
27
|
-
exports.getFontType =
|
27
|
+
exports.getFontType = getFontType;
|
28
|
+
exports.IdentityToUnicodeMap = exports.ToUnicodeMap = exports.FontFlags = exports.Font = exports.ErrorFont = exports.SEAC_ANALYSIS_ENABLED = void 0;
|
28
29
|
|
29
|
-
var _util = require(
|
30
|
+
var _util = require("../shared/util");
|
30
31
|
|
31
|
-
var _cff_parser = require(
|
32
|
+
var _cff_parser = require("./cff_parser");
|
32
33
|
|
33
|
-
var _glyphlist = require(
|
34
|
+
var _glyphlist = require("./glyphlist");
|
34
35
|
|
35
|
-
var _encodings = require(
|
36
|
+
var _encodings = require("./encodings");
|
36
37
|
|
37
|
-
var _standard_fonts = require(
|
38
|
+
var _standard_fonts = require("./standard_fonts");
|
38
39
|
|
39
|
-
var _unicode = require(
|
40
|
+
var _unicode = require("./unicode");
|
40
41
|
|
41
|
-
var _font_renderer = require(
|
42
|
+
var _font_renderer = require("./font_renderer");
|
42
43
|
|
43
|
-
var
|
44
|
+
var _cmap = require("./cmap");
|
44
45
|
|
45
|
-
var
|
46
|
+
var _stream = require("./stream");
|
46
47
|
|
47
|
-
var
|
48
|
-
|
49
|
-
|
48
|
+
var _type1_parser = require("./type1_parser");
|
49
|
+
|
50
|
+
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }
|
51
|
+
|
52
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }
|
53
|
+
|
54
|
+
function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
55
|
+
|
56
|
+
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
57
|
+
|
58
|
+
var PRIVATE_USE_AREAS = [[0xE000, 0xF8FF], [0x100000, 0x10FFFD]];
|
50
59
|
var PDF_GLYPH_SPACE_UNITS = 1000;
|
51
|
-
var SEAC_ANALYSIS_ENABLED =
|
60
|
+
var SEAC_ANALYSIS_ENABLED = true;
|
61
|
+
exports.SEAC_ANALYSIS_ENABLED = SEAC_ANALYSIS_ENABLED;
|
52
62
|
var FontFlags = {
|
53
63
|
FixedPitch: 1,
|
54
64
|
Serif: 2,
|
@@ -60,70 +70,95 @@ var FontFlags = {
|
|
60
70
|
SmallCap: 131072,
|
61
71
|
ForceBold: 262144
|
62
72
|
};
|
73
|
+
exports.FontFlags = FontFlags;
|
63
74
|
var MacStandardGlyphOrdering = ['.notdef', '.null', 'nonmarkingreturn', 'space', 'exclam', 'quotedbl', 'numbersign', 'dollar', 'percent', 'ampersand', 'quotesingle', 'parenleft', 'parenright', 'asterisk', 'plus', 'comma', 'hyphen', 'period', 'slash', 'zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'colon', 'semicolon', 'less', 'equal', 'greater', 'question', 'at', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'bracketleft', 'backslash', 'bracketright', 'asciicircum', 'underscore', 'grave', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'braceleft', 'bar', 'braceright', 'asciitilde', 'Adieresis', 'Aring', 'Ccedilla', 'Eacute', 'Ntilde', 'Odieresis', 'Udieresis', 'aacute', 'agrave', 'acircumflex', 'adieresis', 'atilde', 'aring', 'ccedilla', 'eacute', 'egrave', 'ecircumflex', 'edieresis', 'iacute', 'igrave', 'icircumflex', 'idieresis', 'ntilde', 'oacute', 'ograve', 'ocircumflex', 'odieresis', 'otilde', 'uacute', 'ugrave', 'ucircumflex', 'udieresis', 'dagger', 'degree', 'cent', 'sterling', 'section', 'bullet', 'paragraph', 'germandbls', 'registered', 'copyright', 'trademark', 'acute', 'dieresis', 'notequal', 'AE', 'Oslash', 'infinity', 'plusminus', 'lessequal', 'greaterequal', 'yen', 'mu', 'partialdiff', 'summation', 'product', 'pi', 'integral', 'ordfeminine', 'ordmasculine', 'Omega', 'ae', 'oslash', 'questiondown', 'exclamdown', 'logicalnot', 'radical', 'florin', 'approxequal', 'Delta', 'guillemotleft', 'guillemotright', 'ellipsis', 'nonbreakingspace', 'Agrave', 'Atilde', 'Otilde', 'OE', 'oe', 'endash', 'emdash', 'quotedblleft', 'quotedblright', 'quoteleft', 'quoteright', 'divide', 'lozenge', 'ydieresis', 'Ydieresis', 'fraction', 'currency', 'guilsinglleft', 'guilsinglright', 'fi', 'fl', 'daggerdbl', 'periodcentered', 'quotesinglbase', 'quotedblbase', 'perthousand', 'Acircumflex', 'Ecircumflex', 'Aacute', 'Edieresis', 'Egrave', 'Iacute', 'Icircumflex', 'Idieresis', 'Igrave', 'Oacute', 'Ocircumflex', 'apple', 'Ograve', 'Uacute', 'Ucircumflex', 'Ugrave', 'dotlessi', 'circumflex', 'tilde', 'macron', 'breve', 'dotaccent', 'ring', 'cedilla', 'hungarumlaut', 'ogonek', 'caron', 'Lslash', 'lslash', 'Scaron', 'scaron', 'Zcaron', 'zcaron', 'brokenbar', 'Eth', 'eth', 'Yacute', 'yacute', 'Thorn', 'thorn', 'minus', 'multiply', 'onesuperior', 'twosuperior', 'threesuperior', 'onehalf', 'onequarter', 'threequarters', 'franc', 'Gbreve', 'gbreve', 'Idotaccent', 'Scedilla', 'scedilla', 'Cacute', 'cacute', 'Ccaron', 'ccaron', 'dcroat'];
|
75
|
+
|
64
76
|
function adjustWidths(properties) {
|
65
77
|
if (!properties.fontMatrix) {
|
66
78
|
return;
|
67
79
|
}
|
80
|
+
|
68
81
|
if (properties.fontMatrix[0] === _util.FONT_IDENTITY_MATRIX[0]) {
|
69
82
|
return;
|
70
83
|
}
|
84
|
+
|
71
85
|
var scale = 0.001 / properties.fontMatrix[0];
|
72
86
|
var glyphsWidths = properties.widths;
|
87
|
+
|
73
88
|
for (var glyph in glyphsWidths) {
|
74
89
|
glyphsWidths[glyph] *= scale;
|
75
90
|
}
|
91
|
+
|
76
92
|
properties.defaultWidth *= scale;
|
77
93
|
}
|
94
|
+
|
78
95
|
function adjustToUnicode(properties, builtInEncoding) {
|
79
96
|
if (properties.hasIncludedToUnicodeMap) {
|
80
97
|
return;
|
81
98
|
}
|
99
|
+
|
82
100
|
if (properties.hasEncoding) {
|
83
101
|
return;
|
84
102
|
}
|
103
|
+
|
85
104
|
if (builtInEncoding === properties.defaultEncoding) {
|
86
105
|
return;
|
87
106
|
}
|
107
|
+
|
88
108
|
if (properties.toUnicode instanceof IdentityToUnicodeMap) {
|
89
109
|
return;
|
90
110
|
}
|
111
|
+
|
91
112
|
var toUnicode = [],
|
92
113
|
glyphsUnicodeMap = (0, _glyphlist.getGlyphsUnicode)();
|
114
|
+
|
93
115
|
for (var charCode in builtInEncoding) {
|
94
116
|
var glyphName = builtInEncoding[charCode];
|
95
117
|
var unicode = (0, _unicode.getUnicodeForGlyph)(glyphName, glyphsUnicodeMap);
|
118
|
+
|
96
119
|
if (unicode !== -1) {
|
97
120
|
toUnicode[charCode] = String.fromCharCode(unicode);
|
98
121
|
}
|
99
122
|
}
|
123
|
+
|
100
124
|
properties.toUnicode.amend(toUnicode);
|
101
125
|
}
|
126
|
+
|
102
127
|
function getFontType(type, subtype) {
|
103
128
|
switch (type) {
|
104
129
|
case 'Type1':
|
105
130
|
return subtype === 'Type1C' ? _util.FontType.TYPE1C : _util.FontType.TYPE1;
|
131
|
+
|
106
132
|
case 'CIDFontType0':
|
107
133
|
return subtype === 'CIDFontType0C' ? _util.FontType.CIDFONTTYPE0C : _util.FontType.CIDFONTTYPE0;
|
134
|
+
|
108
135
|
case 'OpenType':
|
109
136
|
return _util.FontType.OPENTYPE;
|
137
|
+
|
110
138
|
case 'TrueType':
|
111
139
|
return _util.FontType.TRUETYPE;
|
140
|
+
|
112
141
|
case 'CIDFontType2':
|
113
142
|
return _util.FontType.CIDFONTTYPE2;
|
143
|
+
|
114
144
|
case 'MMType1':
|
115
145
|
return _util.FontType.MMTYPE1;
|
146
|
+
|
116
147
|
case 'Type0':
|
117
148
|
return _util.FontType.TYPE0;
|
149
|
+
|
118
150
|
default:
|
119
151
|
return _util.FontType.UNKNOWN;
|
120
152
|
}
|
121
153
|
}
|
154
|
+
|
122
155
|
function recoverGlyphName(name, glyphsUnicodeMap) {
|
123
156
|
if (glyphsUnicodeMap[name] !== undefined) {
|
124
157
|
return name;
|
125
158
|
}
|
159
|
+
|
126
160
|
var unicode = (0, _unicode.getUnicodeForGlyph)(name, glyphsUnicodeMap);
|
161
|
+
|
127
162
|
if (unicode !== -1) {
|
128
163
|
for (var key in glyphsUnicodeMap) {
|
129
164
|
if (glyphsUnicodeMap[key] === unicode) {
|
@@ -131,9 +166,11 @@ function recoverGlyphName(name, glyphsUnicodeMap) {
|
|
131
166
|
}
|
132
167
|
}
|
133
168
|
}
|
169
|
+
|
134
170
|
(0, _util.info)('Unable to recover a standard glyph name for: ' + name);
|
135
171
|
return name;
|
136
172
|
}
|
173
|
+
|
137
174
|
var Glyph = function GlyphClosure() {
|
138
175
|
function Glyph(fontChar, unicode, accent, width, vmetric, operatorListId, isSpace, isInFont) {
|
139
176
|
this.fontChar = fontChar;
|
@@ -145,21 +182,25 @@ var Glyph = function GlyphClosure() {
|
|
145
182
|
this.isSpace = isSpace;
|
146
183
|
this.isInFont = isInFont;
|
147
184
|
}
|
185
|
+
|
148
186
|
Glyph.prototype.matchesForCache = function (fontChar, unicode, accent, width, vmetric, operatorListId, isSpace, isInFont) {
|
149
187
|
return this.fontChar === fontChar && this.unicode === unicode && this.accent === accent && this.width === width && this.vmetric === vmetric && this.operatorListId === operatorListId && this.isSpace === isSpace && this.isInFont === isInFont;
|
150
188
|
};
|
189
|
+
|
151
190
|
return Glyph;
|
152
191
|
}();
|
192
|
+
|
153
193
|
var ToUnicodeMap = function ToUnicodeMapClosure() {
|
154
194
|
function ToUnicodeMap() {
|
155
195
|
var cmap = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
|
156
|
-
|
157
196
|
this._map = cmap;
|
158
197
|
}
|
198
|
+
|
159
199
|
ToUnicodeMap.prototype = {
|
160
200
|
get length() {
|
161
201
|
return this._map.length;
|
162
202
|
},
|
203
|
+
|
163
204
|
forEach: function forEach(callback) {
|
164
205
|
for (var charCode in this._map) {
|
165
206
|
callback(charCode, this._map[charCode].charCodeAt(0));
|
@@ -173,14 +214,17 @@ var ToUnicodeMap = function ToUnicodeMapClosure() {
|
|
173
214
|
},
|
174
215
|
charCodeOf: function charCodeOf(value) {
|
175
216
|
var map = this._map;
|
217
|
+
|
176
218
|
if (map.length <= 0x10000) {
|
177
219
|
return map.indexOf(value);
|
178
220
|
}
|
221
|
+
|
179
222
|
for (var charCode in map) {
|
180
223
|
if (map[charCode] === value) {
|
181
224
|
return charCode | 0;
|
182
225
|
}
|
183
226
|
}
|
227
|
+
|
184
228
|
return -1;
|
185
229
|
},
|
186
230
|
amend: function amend(map) {
|
@@ -191,15 +235,20 @@ var ToUnicodeMap = function ToUnicodeMapClosure() {
|
|
191
235
|
};
|
192
236
|
return ToUnicodeMap;
|
193
237
|
}();
|
238
|
+
|
239
|
+
exports.ToUnicodeMap = ToUnicodeMap;
|
240
|
+
|
194
241
|
var IdentityToUnicodeMap = function IdentityToUnicodeMapClosure() {
|
195
242
|
function IdentityToUnicodeMap(firstChar, lastChar) {
|
196
243
|
this.firstChar = firstChar;
|
197
244
|
this.lastChar = lastChar;
|
198
245
|
}
|
246
|
+
|
199
247
|
IdentityToUnicodeMap.prototype = {
|
200
248
|
get length() {
|
201
249
|
return this.lastChar + 1 - this.firstChar;
|
202
250
|
},
|
251
|
+
|
203
252
|
forEach: function forEach(callback) {
|
204
253
|
for (var i = this.firstChar, ii = this.lastChar; i <= ii; i++) {
|
205
254
|
callback(i, i);
|
@@ -212,6 +261,7 @@ var IdentityToUnicodeMap = function IdentityToUnicodeMapClosure() {
|
|
212
261
|
if (this.firstChar <= i && i <= this.lastChar) {
|
213
262
|
return String.fromCharCode(i);
|
214
263
|
}
|
264
|
+
|
215
265
|
return undefined;
|
216
266
|
},
|
217
267
|
charCodeOf: function charCodeOf(v) {
|
@@ -223,19 +273,25 @@ var IdentityToUnicodeMap = function IdentityToUnicodeMapClosure() {
|
|
223
273
|
};
|
224
274
|
return IdentityToUnicodeMap;
|
225
275
|
}();
|
276
|
+
|
277
|
+
exports.IdentityToUnicodeMap = IdentityToUnicodeMap;
|
278
|
+
|
226
279
|
var OpenTypeFileBuilder = function OpenTypeFileBuilderClosure() {
|
227
280
|
function writeInt16(dest, offset, num) {
|
228
281
|
dest[offset] = num >> 8 & 0xFF;
|
229
282
|
dest[offset + 1] = num & 0xFF;
|
230
283
|
}
|
284
|
+
|
231
285
|
function writeInt32(dest, offset, num) {
|
232
286
|
dest[offset] = num >> 24 & 0xFF;
|
233
287
|
dest[offset + 1] = num >> 16 & 0xFF;
|
234
288
|
dest[offset + 2] = num >> 8 & 0xFF;
|
235
289
|
dest[offset + 3] = num & 0xFF;
|
236
290
|
}
|
291
|
+
|
237
292
|
function writeData(dest, offset, data) {
|
238
293
|
var i, ii;
|
294
|
+
|
239
295
|
if (data instanceof Uint8Array) {
|
240
296
|
dest.set(data, offset);
|
241
297
|
} else if (typeof data === 'string') {
|
@@ -248,17 +304,21 @@ var OpenTypeFileBuilder = function OpenTypeFileBuilderClosure() {
|
|
248
304
|
}
|
249
305
|
}
|
250
306
|
}
|
307
|
+
|
251
308
|
function OpenTypeFileBuilder(sfnt) {
|
252
309
|
this.sfnt = sfnt;
|
253
310
|
this.tables = Object.create(null);
|
254
311
|
}
|
312
|
+
|
255
313
|
OpenTypeFileBuilder.getSearchParams = function OpenTypeFileBuilder_getSearchParams(entriesCount, entrySize) {
|
256
314
|
var maxPower2 = 1,
|
257
315
|
log2 = 0;
|
316
|
+
|
258
317
|
while ((maxPower2 ^ entriesCount) > maxPower2) {
|
259
318
|
maxPower2 <<= 1;
|
260
319
|
log2++;
|
261
320
|
}
|
321
|
+
|
262
322
|
var searchRange = maxPower2 * entrySize;
|
263
323
|
return {
|
264
324
|
range: searchRange,
|
@@ -266,6 +326,7 @@ var OpenTypeFileBuilder = function OpenTypeFileBuilderClosure() {
|
|
266
326
|
rangeShift: entrySize * entriesCount - searchRange
|
267
327
|
};
|
268
328
|
};
|
329
|
+
|
269
330
|
var OTF_HEADER_SIZE = 12;
|
270
331
|
var OTF_TABLE_ENTRY_SIZE = 16;
|
271
332
|
OpenTypeFileBuilder.prototype = {
|
@@ -278,20 +339,25 @@ var OpenTypeFileBuilder = function OpenTypeFileBuilderClosure() {
|
|
278
339
|
var i, j, jj, table, tableName;
|
279
340
|
var offset = OTF_HEADER_SIZE + numTables * OTF_TABLE_ENTRY_SIZE;
|
280
341
|
var tableOffsets = [offset];
|
342
|
+
|
281
343
|
for (i = 0; i < numTables; i++) {
|
282
344
|
table = tables[tablesNames[i]];
|
283
345
|
var paddedLength = (table.length + 3 & ~3) >>> 0;
|
284
346
|
offset += paddedLength;
|
285
347
|
tableOffsets.push(offset);
|
286
348
|
}
|
349
|
+
|
287
350
|
var file = new Uint8Array(offset);
|
351
|
+
|
288
352
|
for (i = 0; i < numTables; i++) {
|
289
353
|
table = tables[tablesNames[i]];
|
290
354
|
writeData(file, tableOffsets[i], table);
|
291
355
|
}
|
356
|
+
|
292
357
|
if (sfnt === 'true') {
|
293
358
|
sfnt = (0, _util.string32)(0x00010000);
|
294
359
|
}
|
360
|
+
|
295
361
|
file[0] = sfnt.charCodeAt(0) & 0xFF;
|
296
362
|
file[1] = sfnt.charCodeAt(1) & 0xFF;
|
297
363
|
file[2] = sfnt.charCodeAt(2) & 0xFF;
|
@@ -302,6 +368,7 @@ var OpenTypeFileBuilder = function OpenTypeFileBuilderClosure() {
|
|
302
368
|
writeInt16(file, 8, searchParams.entry);
|
303
369
|
writeInt16(file, 10, searchParams.rangeShift);
|
304
370
|
offset = OTF_HEADER_SIZE;
|
371
|
+
|
305
372
|
for (i = 0; i < numTables; i++) {
|
306
373
|
tableName = tablesNames[i];
|
307
374
|
file[offset] = tableName.charCodeAt(0) & 0xFF;
|
@@ -309,27 +376,31 @@ var OpenTypeFileBuilder = function OpenTypeFileBuilderClosure() {
|
|
309
376
|
file[offset + 2] = tableName.charCodeAt(2) & 0xFF;
|
310
377
|
file[offset + 3] = tableName.charCodeAt(3) & 0xFF;
|
311
378
|
var checksum = 0;
|
379
|
+
|
312
380
|
for (j = tableOffsets[i], jj = tableOffsets[i + 1]; j < jj; j += 4) {
|
313
381
|
var quad = (0, _util.readUint32)(file, j);
|
314
382
|
checksum = checksum + quad >>> 0;
|
315
383
|
}
|
384
|
+
|
316
385
|
writeInt32(file, offset + 4, checksum);
|
317
386
|
writeInt32(file, offset + 8, tableOffsets[i]);
|
318
387
|
writeInt32(file, offset + 12, tables[tableName].length);
|
319
388
|
offset += OTF_TABLE_ENTRY_SIZE;
|
320
389
|
}
|
390
|
+
|
321
391
|
return file;
|
322
392
|
},
|
323
393
|
addTable: function OpenTypeFileBuilder_addTable(tag, data) {
|
324
394
|
if (tag in this.tables) {
|
325
395
|
throw new Error('Table ' + tag + ' already exists');
|
326
396
|
}
|
397
|
+
|
327
398
|
this.tables[tag] = data;
|
328
399
|
}
|
329
400
|
};
|
330
401
|
return OpenTypeFileBuilder;
|
331
402
|
}();
|
332
|
-
|
403
|
+
|
333
404
|
var Font = function FontClosure() {
|
334
405
|
function Font(name, file, properties) {
|
335
406
|
var charCode;
|
@@ -361,57 +432,51 @@ var Font = function FontClosure() {
|
|
361
432
|
this.toUnicode = properties.toUnicode;
|
362
433
|
this.fallbackToUnicode = properties.fallbackToUnicode || new ToUnicodeMap();
|
363
434
|
this.toFontChar = [];
|
435
|
+
|
364
436
|
if (properties.type === 'Type3') {
|
365
437
|
for (charCode = 0; charCode < 256; charCode++) {
|
366
438
|
this.toFontChar[charCode] = this.differences[charCode] || properties.defaultEncoding[charCode];
|
367
439
|
}
|
440
|
+
|
368
441
|
this.fontType = _util.FontType.TYPE3;
|
369
442
|
return;
|
370
443
|
}
|
444
|
+
|
371
445
|
this.cidEncoding = properties.cidEncoding;
|
372
446
|
this.vertical = properties.vertical;
|
447
|
+
|
373
448
|
if (this.vertical) {
|
374
449
|
this.vmetrics = properties.vmetrics;
|
375
450
|
this.defaultVMetrics = properties.defaultVMetrics;
|
376
451
|
}
|
452
|
+
|
377
453
|
if (!file || file.isEmpty) {
|
378
454
|
if (file) {
|
379
455
|
(0, _util.warn)('Font file is empty in "' + name + '" (' + this.loadedName + ')');
|
380
456
|
}
|
457
|
+
|
381
458
|
this.fallbackToSystemFont();
|
382
459
|
return;
|
383
460
|
}
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
}
|
395
|
-
if (subtype === 'CIDFontType0C' && type !== 'CIDFontType0') {
|
396
|
-
type = 'CIDFontType0';
|
397
|
-
}
|
398
|
-
if (type === 'CIDFontType0') {
|
399
|
-
if (isType1File(file)) {
|
400
|
-
subtype = 'CIDFontType0';
|
401
|
-
} else if (isOpenTypeFile(file)) {
|
402
|
-
subtype = 'OpenType';
|
403
|
-
} else {
|
404
|
-
subtype = 'CIDFontType0C';
|
405
|
-
}
|
406
|
-
}
|
407
|
-
if (subtype === 'OpenType' && type !== 'OpenType') {
|
408
|
-
type = 'OpenType';
|
461
|
+
|
462
|
+
var _getFontFileType = getFontFileType(file, properties);
|
463
|
+
|
464
|
+
var _getFontFileType2 = _slicedToArray(_getFontFileType, 2);
|
465
|
+
|
466
|
+
type = _getFontFileType2[0];
|
467
|
+
subtype = _getFontFileType2[1];
|
468
|
+
|
469
|
+
if (type !== this.type || subtype !== this.subtype) {
|
470
|
+
(0, _util.info)('Inconsistent font file Type/SubType, expected: ' + "".concat(this.type, "/").concat(this.subtype, " but found: ").concat(type, "/").concat(subtype, "."));
|
409
471
|
}
|
472
|
+
|
410
473
|
try {
|
411
474
|
var data;
|
475
|
+
|
412
476
|
switch (type) {
|
413
477
|
case 'MMType1':
|
414
478
|
(0, _util.info)('MMType1 font (' + name + '), falling back to Type1.');
|
479
|
+
|
415
480
|
case 'Type1':
|
416
481
|
case 'CIDFontType0':
|
417
482
|
this.mimetype = 'font/opentype';
|
@@ -419,27 +484,29 @@ var Font = function FontClosure() {
|
|
419
484
|
adjustWidths(properties);
|
420
485
|
data = this.convert(name, cff, properties);
|
421
486
|
break;
|
487
|
+
|
422
488
|
case 'OpenType':
|
423
489
|
case 'TrueType':
|
424
490
|
case 'CIDFontType2':
|
425
491
|
this.mimetype = 'font/opentype';
|
426
492
|
data = this.checkAndRepair(name, file, properties);
|
493
|
+
|
427
494
|
if (this.isOpenType) {
|
428
495
|
adjustWidths(properties);
|
429
496
|
type = 'OpenType';
|
430
497
|
}
|
498
|
+
|
431
499
|
break;
|
500
|
+
|
432
501
|
default:
|
433
|
-
throw new _util.FormatError(
|
502
|
+
throw new _util.FormatError("Font ".concat(type, " is not supported"));
|
434
503
|
}
|
435
504
|
} catch (e) {
|
436
|
-
if (!(e instanceof _util.FormatError)) {
|
437
|
-
throw e;
|
438
|
-
}
|
439
505
|
(0, _util.warn)(e);
|
440
506
|
this.fallbackToSystemFont();
|
441
507
|
return;
|
442
508
|
}
|
509
|
+
|
443
510
|
this.data = data;
|
444
511
|
this.fontType = getFontType(type, subtype);
|
445
512
|
this.fontMatrix = properties.fontMatrix;
|
@@ -448,186 +515,256 @@ var Font = function FontClosure() {
|
|
448
515
|
this.toUnicode = properties.toUnicode;
|
449
516
|
this.encoding = properties.baseEncoding;
|
450
517
|
this.seacMap = properties.seacMap;
|
451
|
-
this.loading = true;
|
452
518
|
}
|
519
|
+
|
453
520
|
Font.getFontID = function () {
|
454
521
|
var ID = 1;
|
455
522
|
return function Font_getFontID() {
|
456
523
|
return String(ID++);
|
457
524
|
};
|
458
525
|
}();
|
526
|
+
|
459
527
|
function int16(b0, b1) {
|
460
528
|
return (b0 << 8) + b1;
|
461
529
|
}
|
530
|
+
|
462
531
|
function writeSignedInt16(bytes, index, value) {
|
463
532
|
bytes[index + 1] = value;
|
464
533
|
bytes[index] = value >>> 8;
|
465
534
|
}
|
535
|
+
|
466
536
|
function signedInt16(b0, b1) {
|
467
537
|
var value = (b0 << 8) + b1;
|
468
538
|
return value & 1 << 15 ? value - 0x10000 : value;
|
469
539
|
}
|
540
|
+
|
470
541
|
function int32(b0, b1, b2, b3) {
|
471
542
|
return (b0 << 24) + (b1 << 16) + (b2 << 8) + b3;
|
472
543
|
}
|
544
|
+
|
473
545
|
function string16(value) {
|
474
546
|
return String.fromCharCode(value >> 8 & 0xff, value & 0xff);
|
475
547
|
}
|
548
|
+
|
476
549
|
function safeString16(value) {
|
477
550
|
value = value > 0x7FFF ? 0x7FFF : value < -0x8000 ? -0x8000 : value;
|
478
551
|
return String.fromCharCode(value >> 8 & 0xff, value & 0xff);
|
479
552
|
}
|
553
|
+
|
480
554
|
function isTrueTypeFile(file) {
|
481
555
|
var header = file.peekBytes(4);
|
482
|
-
return (0, _util.readUint32)(header, 0) === 0x00010000;
|
556
|
+
return (0, _util.readUint32)(header, 0) === 0x00010000 || (0, _util.bytesToString)(header) === 'true';
|
483
557
|
}
|
558
|
+
|
484
559
|
function isTrueTypeCollectionFile(file) {
|
485
560
|
var header = file.peekBytes(4);
|
486
561
|
return (0, _util.bytesToString)(header) === 'ttcf';
|
487
562
|
}
|
563
|
+
|
488
564
|
function isOpenTypeFile(file) {
|
489
565
|
var header = file.peekBytes(4);
|
490
566
|
return (0, _util.bytesToString)(header) === 'OTTO';
|
491
567
|
}
|
568
|
+
|
492
569
|
function isType1File(file) {
|
493
570
|
var header = file.peekBytes(2);
|
571
|
+
|
494
572
|
if (header[0] === 0x25 && header[1] === 0x21) {
|
495
573
|
return true;
|
496
574
|
}
|
575
|
+
|
497
576
|
if (header[0] === 0x80 && header[1] === 0x01) {
|
498
577
|
return true;
|
499
578
|
}
|
579
|
+
|
580
|
+
return false;
|
581
|
+
}
|
582
|
+
|
583
|
+
function isCFFFile(file) {
|
584
|
+
var header = file.peekBytes(4);
|
585
|
+
|
586
|
+
if (header[0] >= 1 && header[3] >= 1 && header[3] <= 4) {
|
587
|
+
return true;
|
588
|
+
}
|
589
|
+
|
500
590
|
return false;
|
501
591
|
}
|
592
|
+
|
593
|
+
function getFontFileType(file, _ref) {
|
594
|
+
var type = _ref.type,
|
595
|
+
subtype = _ref.subtype,
|
596
|
+
composite = _ref.composite;
|
597
|
+
var fileType, fileSubtype;
|
598
|
+
|
599
|
+
if (isTrueTypeFile(file) || isTrueTypeCollectionFile(file)) {
|
600
|
+
if (composite) {
|
601
|
+
fileType = 'CIDFontType2';
|
602
|
+
} else {
|
603
|
+
fileType = 'TrueType';
|
604
|
+
}
|
605
|
+
} else if (isOpenTypeFile(file)) {
|
606
|
+
if (composite) {
|
607
|
+
fileType = 'CIDFontType2';
|
608
|
+
} else {
|
609
|
+
fileType = 'OpenType';
|
610
|
+
}
|
611
|
+
} else if (isType1File(file)) {
|
612
|
+
if (composite) {
|
613
|
+
fileType = 'CIDFontType0';
|
614
|
+
} else {
|
615
|
+
fileType = type === 'MMType1' ? 'MMType1' : 'Type1';
|
616
|
+
}
|
617
|
+
} else if (isCFFFile(file)) {
|
618
|
+
if (composite) {
|
619
|
+
fileType = 'CIDFontType0';
|
620
|
+
fileSubtype = 'CIDFontType0C';
|
621
|
+
} else {
|
622
|
+
fileType = type === 'MMType1' ? 'MMType1' : 'Type1';
|
623
|
+
fileSubtype = 'Type1C';
|
624
|
+
}
|
625
|
+
} else {
|
626
|
+
(0, _util.warn)('getFontFileType: Unable to detect correct font file Type/Subtype.');
|
627
|
+
fileType = type;
|
628
|
+
fileSubtype = subtype;
|
629
|
+
}
|
630
|
+
|
631
|
+
return [fileType, fileSubtype];
|
632
|
+
}
|
633
|
+
|
502
634
|
function buildToFontChar(encoding, glyphsUnicodeMap, differences) {
|
503
635
|
var toFontChar = [],
|
504
636
|
unicode;
|
637
|
+
|
505
638
|
for (var i = 0, ii = encoding.length; i < ii; i++) {
|
506
639
|
unicode = (0, _unicode.getUnicodeForGlyph)(encoding[i], glyphsUnicodeMap);
|
640
|
+
|
507
641
|
if (unicode !== -1) {
|
508
642
|
toFontChar[i] = unicode;
|
509
643
|
}
|
510
644
|
}
|
645
|
+
|
511
646
|
for (var charCode in differences) {
|
512
647
|
unicode = (0, _unicode.getUnicodeForGlyph)(differences[charCode], glyphsUnicodeMap);
|
648
|
+
|
513
649
|
if (unicode !== -1) {
|
514
650
|
toFontChar[+charCode] = unicode;
|
515
651
|
}
|
516
652
|
}
|
653
|
+
|
517
654
|
return toFontChar;
|
518
655
|
}
|
519
|
-
|
520
|
-
|
521
|
-
j = ProblematicCharRanges.length - 1;
|
522
|
-
while (i < j) {
|
523
|
-
var c = i + j + 1 >> 1;
|
524
|
-
if (code < ProblematicCharRanges[c]) {
|
525
|
-
j = c - 1;
|
526
|
-
} else {
|
527
|
-
i = c;
|
528
|
-
}
|
529
|
-
}
|
530
|
-
return !(i & 1);
|
531
|
-
}
|
532
|
-
function adjustMapping(charCodeToGlyphId, properties, missingGlyphs) {
|
533
|
-
var toUnicode = properties.toUnicode;
|
534
|
-
var isSymbolic = !!(properties.flags & FontFlags.Symbolic);
|
535
|
-
var isIdentityUnicode = properties.toUnicode instanceof IdentityToUnicodeMap;
|
656
|
+
|
657
|
+
function adjustMapping(charCodeToGlyphId, hasGlyph, newGlyphZeroId) {
|
536
658
|
var newMap = Object.create(null);
|
537
659
|
var toFontChar = [];
|
538
|
-
var
|
539
|
-
var nextAvailableFontCharCode =
|
660
|
+
var privateUseAreaIndex = 0;
|
661
|
+
var nextAvailableFontCharCode = PRIVATE_USE_AREAS[privateUseAreaIndex][0];
|
662
|
+
var privateUseOffetEnd = PRIVATE_USE_AREAS[privateUseAreaIndex][1];
|
663
|
+
|
540
664
|
for (var originalCharCode in charCodeToGlyphId) {
|
541
665
|
originalCharCode |= 0;
|
542
666
|
var glyphId = charCodeToGlyphId[originalCharCode];
|
543
|
-
|
667
|
+
|
668
|
+
if (!hasGlyph(glyphId)) {
|
544
669
|
continue;
|
545
670
|
}
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
671
|
+
|
672
|
+
if (nextAvailableFontCharCode > privateUseOffetEnd) {
|
673
|
+
privateUseAreaIndex++;
|
674
|
+
|
675
|
+
if (privateUseAreaIndex >= PRIVATE_USE_AREAS.length) {
|
676
|
+
(0, _util.warn)('Ran out of space in font private use area.');
|
677
|
+
break;
|
553
678
|
}
|
679
|
+
|
680
|
+
nextAvailableFontCharCode = PRIVATE_USE_AREAS[privateUseAreaIndex][0];
|
681
|
+
privateUseOffetEnd = PRIVATE_USE_AREAS[privateUseAreaIndex][1];
|
554
682
|
}
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
}
|
561
|
-
fontCharCode = nextAvailableFontCharCode++;
|
562
|
-
if (SKIP_PRIVATE_USE_RANGE_F000_TO_F01F && fontCharCode === 0xF000) {
|
563
|
-
fontCharCode = 0xF020;
|
564
|
-
nextAvailableFontCharCode = fontCharCode + 1;
|
565
|
-
}
|
566
|
-
} while (usedFontCharCodes[fontCharCode] !== undefined);
|
683
|
+
|
684
|
+
var fontCharCode = nextAvailableFontCharCode++;
|
685
|
+
|
686
|
+
if (glyphId === 0) {
|
687
|
+
glyphId = newGlyphZeroId;
|
567
688
|
}
|
689
|
+
|
568
690
|
newMap[fontCharCode] = glyphId;
|
569
691
|
toFontChar[originalCharCode] = fontCharCode;
|
570
|
-
usedFontCharCodes[fontCharCode] = true;
|
571
692
|
}
|
693
|
+
|
572
694
|
return {
|
573
695
|
toFontChar: toFontChar,
|
574
696
|
charCodeToGlyphId: newMap,
|
575
697
|
nextAvailableFontCharCode: nextAvailableFontCharCode
|
576
698
|
};
|
577
699
|
}
|
700
|
+
|
578
701
|
function getRanges(glyphs, numGlyphs) {
|
579
702
|
var codes = [];
|
703
|
+
|
580
704
|
for (var charCode in glyphs) {
|
581
705
|
if (glyphs[charCode] >= numGlyphs) {
|
582
706
|
continue;
|
583
707
|
}
|
708
|
+
|
584
709
|
codes.push({
|
585
710
|
fontCharCode: charCode | 0,
|
586
711
|
glyphId: glyphs[charCode]
|
587
712
|
});
|
588
713
|
}
|
714
|
+
|
589
715
|
if (codes.length === 0) {
|
590
716
|
codes.push({
|
591
717
|
fontCharCode: 0,
|
592
718
|
glyphId: 0
|
593
719
|
});
|
594
720
|
}
|
721
|
+
|
595
722
|
codes.sort(function fontGetRangesSort(a, b) {
|
596
723
|
return a.fontCharCode - b.fontCharCode;
|
597
724
|
});
|
598
725
|
var ranges = [];
|
599
726
|
var length = codes.length;
|
727
|
+
|
600
728
|
for (var n = 0; n < length;) {
|
601
729
|
var start = codes[n].fontCharCode;
|
602
730
|
var codeIndices = [codes[n].glyphId];
|
603
731
|
++n;
|
604
732
|
var end = start;
|
733
|
+
|
605
734
|
while (n < length && end + 1 === codes[n].fontCharCode) {
|
606
735
|
codeIndices.push(codes[n].glyphId);
|
607
736
|
++end;
|
608
737
|
++n;
|
738
|
+
|
609
739
|
if (end === 0xFFFF) {
|
610
740
|
break;
|
611
741
|
}
|
612
742
|
}
|
743
|
+
|
613
744
|
ranges.push([start, end, codeIndices]);
|
614
745
|
}
|
746
|
+
|
615
747
|
return ranges;
|
616
748
|
}
|
749
|
+
|
617
750
|
function createCmapTable(glyphs, numGlyphs) {
|
618
751
|
var ranges = getRanges(glyphs, numGlyphs);
|
619
752
|
var numTables = ranges[ranges.length - 1][1] > 0xFFFF ? 2 : 1;
|
620
753
|
var cmap = '\x00\x00' + string16(numTables) + '\x00\x03' + '\x00\x01' + (0, _util.string32)(4 + numTables * 8);
|
621
754
|
var i, ii, j, jj;
|
755
|
+
|
622
756
|
for (i = ranges.length - 1; i >= 0; --i) {
|
623
757
|
if (ranges[i][0] <= 0xFFFF) {
|
624
758
|
break;
|
625
759
|
}
|
626
760
|
}
|
761
|
+
|
627
762
|
var bmpLength = i + 1;
|
763
|
+
|
628
764
|
if (ranges[i][0] < 0xFFFF && ranges[i][1] === 0xFFFF) {
|
629
765
|
ranges[i][1] = 0xFFFE;
|
630
766
|
}
|
767
|
+
|
631
768
|
var trailingRangesCount = ranges[i][1] < 0xFFFF ? 1 : 0;
|
632
769
|
var segCount = bmpLength + trailingRangesCount;
|
633
770
|
var searchParams = OpenTypeFileBuilder.getSearchParams(segCount, 2);
|
@@ -638,6 +775,7 @@ var Font = function FontClosure() {
|
|
638
775
|
var glyphsIds = '';
|
639
776
|
var bias = 0;
|
640
777
|
var range, start, end, codes;
|
778
|
+
|
641
779
|
for (i = 0, ii = bmpLength; i < ii; i++) {
|
642
780
|
range = ranges[i];
|
643
781
|
start = range[0];
|
@@ -646,17 +784,20 @@ var Font = function FontClosure() {
|
|
646
784
|
endCount += string16(end);
|
647
785
|
codes = range[2];
|
648
786
|
var contiguous = true;
|
787
|
+
|
649
788
|
for (j = 1, jj = codes.length; j < jj; ++j) {
|
650
789
|
if (codes[j] !== codes[j - 1] + 1) {
|
651
790
|
contiguous = false;
|
652
791
|
break;
|
653
792
|
}
|
654
793
|
}
|
794
|
+
|
655
795
|
if (!contiguous) {
|
656
796
|
var offset = (segCount - i) * 2 + bias * 2;
|
657
797
|
bias += end - start + 1;
|
658
798
|
idDeltas += string16(0);
|
659
799
|
idRangeOffsets += string16(offset);
|
800
|
+
|
660
801
|
for (j = 0, jj = codes.length; j < jj; ++j) {
|
661
802
|
glyphsIds += string16(codes[j]);
|
662
803
|
}
|
@@ -666,23 +807,28 @@ var Font = function FontClosure() {
|
|
666
807
|
idRangeOffsets += string16(0);
|
667
808
|
}
|
668
809
|
}
|
810
|
+
|
669
811
|
if (trailingRangesCount > 0) {
|
670
812
|
endCount += '\xFF\xFF';
|
671
813
|
startCount += '\xFF\xFF';
|
672
814
|
idDeltas += '\x00\x01';
|
673
815
|
idRangeOffsets += '\x00\x00';
|
674
816
|
}
|
817
|
+
|
675
818
|
var format314 = '\x00\x00' + string16(2 * segCount) + string16(searchParams.range) + string16(searchParams.entry) + string16(searchParams.rangeShift) + endCount + '\x00\x00' + startCount + idDeltas + idRangeOffsets + glyphsIds;
|
676
819
|
var format31012 = '';
|
677
820
|
var header31012 = '';
|
821
|
+
|
678
822
|
if (numTables > 1) {
|
679
823
|
cmap += '\x00\x03' + '\x00\x0A' + (0, _util.string32)(4 + numTables * 8 + 4 + format314.length);
|
680
824
|
format31012 = '';
|
825
|
+
|
681
826
|
for (i = 0, ii = ranges.length; i < ii; i++) {
|
682
827
|
range = ranges[i];
|
683
828
|
start = range[0];
|
684
829
|
codes = range[2];
|
685
830
|
var code = codes[0];
|
831
|
+
|
686
832
|
for (j = 1, jj = codes.length; j < jj; ++j) {
|
687
833
|
if (codes[j] !== codes[j - 1] + 1) {
|
688
834
|
end = range[0] + j - 1;
|
@@ -691,33 +837,44 @@ var Font = function FontClosure() {
|
|
691
837
|
code = codes[j];
|
692
838
|
}
|
693
839
|
}
|
840
|
+
|
694
841
|
format31012 += (0, _util.string32)(start) + (0, _util.string32)(range[1]) + (0, _util.string32)(code);
|
695
842
|
}
|
843
|
+
|
696
844
|
header31012 = '\x00\x0C' + '\x00\x00' + (0, _util.string32)(format31012.length + 16) + '\x00\x00\x00\x00' + (0, _util.string32)(format31012.length / 12);
|
697
845
|
}
|
846
|
+
|
698
847
|
return cmap + '\x00\x04' + string16(format314.length + 4) + format314 + header31012 + format31012;
|
699
848
|
}
|
849
|
+
|
700
850
|
function validateOS2Table(os2) {
|
701
851
|
var stream = new _stream.Stream(os2.data);
|
702
852
|
var version = stream.getUint16();
|
703
853
|
stream.getBytes(60);
|
704
854
|
var selection = stream.getUint16();
|
855
|
+
|
705
856
|
if (version < 4 && selection & 0x0300) {
|
706
857
|
return false;
|
707
858
|
}
|
859
|
+
|
708
860
|
var firstChar = stream.getUint16();
|
709
861
|
var lastChar = stream.getUint16();
|
862
|
+
|
710
863
|
if (firstChar > lastChar) {
|
711
864
|
return false;
|
712
865
|
}
|
866
|
+
|
713
867
|
stream.getBytes(6);
|
714
868
|
var usWinAscent = stream.getUint16();
|
869
|
+
|
715
870
|
if (usWinAscent === 0) {
|
716
871
|
return false;
|
717
872
|
}
|
873
|
+
|
718
874
|
os2.data[8] = os2.data[9] = 0;
|
719
875
|
return true;
|
720
876
|
}
|
877
|
+
|
721
878
|
function createOS2Table(properties, charstrings, override) {
|
722
879
|
override = override || {
|
723
880
|
unitsPerEm: 0,
|
@@ -732,16 +889,21 @@ var Font = function FontClosure() {
|
|
732
889
|
var ulUnicodeRange4 = 0;
|
733
890
|
var firstCharIndex = null;
|
734
891
|
var lastCharIndex = 0;
|
892
|
+
|
735
893
|
if (charstrings) {
|
736
894
|
for (var code in charstrings) {
|
737
895
|
code |= 0;
|
896
|
+
|
738
897
|
if (firstCharIndex > code || !firstCharIndex) {
|
739
898
|
firstCharIndex = code;
|
740
899
|
}
|
900
|
+
|
741
901
|
if (lastCharIndex < code) {
|
742
902
|
lastCharIndex = code;
|
743
903
|
}
|
904
|
+
|
744
905
|
var position = (0, _unicode.getUnicodeRangeFor)(code);
|
906
|
+
|
745
907
|
if (position < 32) {
|
746
908
|
ulUnicodeRange1 |= 1 << position;
|
747
909
|
} else if (position < 64) {
|
@@ -754,41 +916,55 @@ var Font = function FontClosure() {
|
|
754
916
|
throw new _util.FormatError('Unicode ranges Bits > 123 are reserved for internal usage');
|
755
917
|
}
|
756
918
|
}
|
919
|
+
|
920
|
+
if (lastCharIndex > 0xFFFF) {
|
921
|
+
lastCharIndex = 0xFFFF;
|
922
|
+
}
|
757
923
|
} else {
|
758
924
|
firstCharIndex = 0;
|
759
925
|
lastCharIndex = 255;
|
760
926
|
}
|
927
|
+
|
761
928
|
var bbox = properties.bbox || [0, 0, 0, 0];
|
762
929
|
var unitsPerEm = override.unitsPerEm || 1 / (properties.fontMatrix || _util.FONT_IDENTITY_MATRIX)[0];
|
763
930
|
var scale = properties.ascentScaled ? 1.0 : unitsPerEm / PDF_GLYPH_SPACE_UNITS;
|
764
931
|
var typoAscent = override.ascent || Math.round(scale * (properties.ascent || bbox[3]));
|
765
932
|
var typoDescent = override.descent || Math.round(scale * (properties.descent || bbox[1]));
|
933
|
+
|
766
934
|
if (typoDescent > 0 && properties.descent > 0 && bbox[1] < 0) {
|
767
935
|
typoDescent = -typoDescent;
|
768
936
|
}
|
937
|
+
|
769
938
|
var winAscent = override.yMax || typoAscent;
|
770
939
|
var winDescent = -override.yMin || -typoDescent;
|
771
940
|
return '\x00\x03' + '\x02\x24' + '\x01\xF4' + '\x00\x05' + '\x00\x00' + '\x02\x8A' + '\x02\xBB' + '\x00\x00' + '\x00\x8C' + '\x02\x8A' + '\x02\xBB' + '\x00\x00' + '\x01\xDF' + '\x00\x31' + '\x01\x02' + '\x00\x00' + '\x00\x00\x06' + String.fromCharCode(properties.fixedPitch ? 0x09 : 0x00) + '\x00\x00\x00\x00\x00\x00' + (0, _util.string32)(ulUnicodeRange1) + (0, _util.string32)(ulUnicodeRange2) + (0, _util.string32)(ulUnicodeRange3) + (0, _util.string32)(ulUnicodeRange4) + '\x2A\x32\x31\x2A' + string16(properties.italicAngle ? 1 : 0) + string16(firstCharIndex || properties.firstChar) + string16(lastCharIndex || properties.lastChar) + string16(typoAscent) + string16(typoDescent) + '\x00\x64' + string16(winAscent) + string16(winDescent) + '\x00\x00\x00\x00' + '\x00\x00\x00\x00' + string16(properties.xHeight) + string16(properties.capHeight) + string16(0) + string16(firstCharIndex || properties.firstChar) + '\x00\x03';
|
772
941
|
}
|
942
|
+
|
773
943
|
function createPostTable(properties) {
|
774
944
|
var angle = Math.floor(properties.italicAngle * Math.pow(2, 16));
|
775
945
|
return '\x00\x03\x00\x00' + (0, _util.string32)(angle) + '\x00\x00' + '\x00\x00' + (0, _util.string32)(properties.fixedPitch) + '\x00\x00\x00\x00' + '\x00\x00\x00\x00' + '\x00\x00\x00\x00' + '\x00\x00\x00\x00';
|
776
946
|
}
|
947
|
+
|
777
948
|
function createNameTable(name, proto) {
|
778
949
|
if (!proto) {
|
779
950
|
proto = [[], []];
|
780
951
|
}
|
952
|
+
|
781
953
|
var strings = [proto[0][0] || 'Original licence', proto[0][1] || name, proto[0][2] || 'Unknown', proto[0][3] || 'uniqueID', proto[0][4] || name, proto[0][5] || 'Version 0.11', proto[0][6] || '', proto[0][7] || 'Unknown', proto[0][8] || 'Unknown', proto[0][9] || 'Unknown'];
|
782
954
|
var stringsUnicode = [];
|
783
955
|
var i, ii, j, jj, str;
|
956
|
+
|
784
957
|
for (i = 0, ii = strings.length; i < ii; i++) {
|
785
958
|
str = proto[1][i] || strings[i];
|
786
959
|
var strBufUnicode = [];
|
960
|
+
|
787
961
|
for (j = 0, jj = str.length; j < jj; j++) {
|
788
962
|
strBufUnicode.push(string16(str.charCodeAt(j)));
|
789
963
|
}
|
964
|
+
|
790
965
|
stringsUnicode.push(strBufUnicode.join(''));
|
791
966
|
}
|
967
|
+
|
792
968
|
var names = [strings, stringsUnicode];
|
793
969
|
var platforms = ['\x00\x01', '\x00\x03'];
|
794
970
|
var encodings = ['\x00\x00', '\x00\x01'];
|
@@ -796,8 +972,10 @@ var Font = function FontClosure() {
|
|
796
972
|
var namesRecordCount = strings.length * platforms.length;
|
797
973
|
var nameTable = '\x00\x00' + string16(namesRecordCount) + string16(namesRecordCount * 12 + 6);
|
798
974
|
var strOffset = 0;
|
975
|
+
|
799
976
|
for (i = 0, ii = platforms.length; i < ii; i++) {
|
800
977
|
var strs = names[i];
|
978
|
+
|
801
979
|
for (j = 0, jj = strs.length; j < jj; j++) {
|
802
980
|
str = strs[j];
|
803
981
|
var nameRecord = platforms[i] + encodings[i] + languages[i] + string16(j) + string16(str.length) + string16(strOffset);
|
@@ -805,25 +983,33 @@ var Font = function FontClosure() {
|
|
805
983
|
strOffset += str.length;
|
806
984
|
}
|
807
985
|
}
|
986
|
+
|
808
987
|
nameTable += strings.join('') + stringsUnicode.join('');
|
809
988
|
return nameTable;
|
810
989
|
}
|
990
|
+
|
811
991
|
Font.prototype = {
|
812
992
|
name: null,
|
813
993
|
font: null,
|
814
994
|
mimetype: null,
|
815
995
|
encoding: null,
|
996
|
+
disableFontFace: false,
|
997
|
+
|
816
998
|
get renderer() {
|
817
999
|
var renderer = _font_renderer.FontRendererFactory.create(this, SEAC_ANALYSIS_ENABLED);
|
1000
|
+
|
818
1001
|
return (0, _util.shadow)(this, 'renderer', renderer);
|
819
1002
|
},
|
1003
|
+
|
820
1004
|
exportData: function Font_exportData() {
|
821
1005
|
var data = {};
|
1006
|
+
|
822
1007
|
for (var i in this) {
|
823
1008
|
if (this.hasOwnProperty(i)) {
|
824
1009
|
data[i] = this[i];
|
825
1010
|
}
|
826
1011
|
}
|
1012
|
+
|
827
1013
|
return data;
|
828
1014
|
},
|
829
1015
|
fallbackToSystemFont: function Font_fallbackToSystemFont() {
|
@@ -843,29 +1029,37 @@ var Font = function FontClosure() {
|
|
843
1029
|
this.italic = fontName.search(/oblique/gi) !== -1 || fontName.search(/italic/gi) !== -1;
|
844
1030
|
this.black = name.search(/Black/g) !== -1;
|
845
1031
|
this.remeasure = Object.keys(this.widths).length > 0;
|
846
|
-
|
1032
|
+
|
1033
|
+
if (isStandardFont && type === 'CIDFontType2' && this.cidEncoding.startsWith('Identity-')) {
|
847
1034
|
var GlyphMapForStandardFonts = (0, _standard_fonts.getGlyphMapForStandardFonts)();
|
848
1035
|
var map = [];
|
1036
|
+
|
849
1037
|
for (charCode in GlyphMapForStandardFonts) {
|
850
1038
|
map[+charCode] = GlyphMapForStandardFonts[charCode];
|
851
1039
|
}
|
1040
|
+
|
852
1041
|
if (/Arial-?Black/i.test(name)) {
|
853
1042
|
var SupplementalGlyphMapForArialBlack = (0, _standard_fonts.getSupplementalGlyphMapForArialBlack)();
|
1043
|
+
|
854
1044
|
for (charCode in SupplementalGlyphMapForArialBlack) {
|
855
1045
|
map[+charCode] = SupplementalGlyphMapForArialBlack[charCode];
|
856
1046
|
}
|
857
1047
|
} else if (/Calibri/i.test(name)) {
|
858
1048
|
var SupplementalGlyphMapForCalibri = (0, _standard_fonts.getSupplementalGlyphMapForCalibri)();
|
1049
|
+
|
859
1050
|
for (charCode in SupplementalGlyphMapForCalibri) {
|
860
1051
|
map[+charCode] = SupplementalGlyphMapForCalibri[charCode];
|
861
1052
|
}
|
862
1053
|
}
|
1054
|
+
|
863
1055
|
var isIdentityUnicode = this.toUnicode instanceof IdentityToUnicodeMap;
|
1056
|
+
|
864
1057
|
if (!isIdentityUnicode) {
|
865
1058
|
this.toUnicode.forEach(function (charCode, unicodeCharCode) {
|
866
1059
|
map[+charCode] = unicodeCharCode;
|
867
1060
|
});
|
868
1061
|
}
|
1062
|
+
|
869
1063
|
this.toFontChar = map;
|
870
1064
|
this.toUnicode = new ToUnicodeMap(map);
|
871
1065
|
} else if (/Symbol/i.test(fontName)) {
|
@@ -874,6 +1068,7 @@ var Font = function FontClosure() {
|
|
874
1068
|
if (/Wingdings/i.test(name)) {
|
875
1069
|
(0, _util.warn)('Non-embedded Wingdings font, falling back to ZapfDingbats.');
|
876
1070
|
}
|
1071
|
+
|
877
1072
|
this.toFontChar = buildToFontChar(_encodings.ZapfDingbatsEncoding, (0, _glyphlist.getDingbatsGlyphsUnicode)(), this.differences);
|
878
1073
|
} else if (isStandardFont) {
|
879
1074
|
this.toFontChar = buildToFontChar(this.defaultEncoding, (0, _glyphlist.getGlyphsUnicode)(), this.differences);
|
@@ -883,19 +1078,22 @@ var Font = function FontClosure() {
|
|
883
1078
|
if (!_this.composite) {
|
884
1079
|
var glyphName = _this.differences[charCode] || _this.defaultEncoding[charCode];
|
885
1080
|
unicode = (0, _unicode.getUnicodeForGlyph)(glyphName, glyphsUnicodeMap);
|
1081
|
+
|
886
1082
|
if (unicode !== -1) {
|
887
1083
|
unicodeCharCode = unicode;
|
888
1084
|
}
|
889
1085
|
}
|
1086
|
+
|
890
1087
|
_this.toFontChar[charCode] = unicodeCharCode;
|
891
1088
|
});
|
892
1089
|
}
|
1090
|
+
|
893
1091
|
this.loadedName = fontName.split('-')[0];
|
894
|
-
this.loading = false;
|
895
1092
|
this.fontType = getFontType(type, subtype);
|
896
1093
|
},
|
897
1094
|
checkAndRepair: function Font_checkAndRepair(name, font, properties) {
|
898
1095
|
var VALID_TABLES = ['OS/2', 'cmap', 'head', 'hhea', 'hmtx', 'maxp', 'name', 'post', 'loca', 'glyf', 'fpgm', 'prep', 'cvt ', 'CFF '];
|
1096
|
+
|
899
1097
|
function readTables(file, numTables) {
|
900
1098
|
var tables = Object.create(null);
|
901
1099
|
tables['OS/2'] = null;
|
@@ -906,18 +1104,24 @@ var Font = function FontClosure() {
|
|
906
1104
|
tables['maxp'] = null;
|
907
1105
|
tables['name'] = null;
|
908
1106
|
tables['post'] = null;
|
1107
|
+
|
909
1108
|
for (var i = 0; i < numTables; i++) {
|
910
1109
|
var table = readTableEntry(font);
|
1110
|
+
|
911
1111
|
if (!VALID_TABLES.includes(table.tag)) {
|
912
1112
|
continue;
|
913
1113
|
}
|
1114
|
+
|
914
1115
|
if (table.length === 0) {
|
915
1116
|
continue;
|
916
1117
|
}
|
1118
|
+
|
917
1119
|
tables[table.tag] = table;
|
918
1120
|
}
|
1121
|
+
|
919
1122
|
return tables;
|
920
1123
|
}
|
1124
|
+
|
921
1125
|
function readTableEntry(file) {
|
922
1126
|
var tag = (0, _util.bytesToString)(file.getBytes(4));
|
923
1127
|
var checksum = file.getInt32() >>> 0;
|
@@ -928,10 +1132,12 @@ var Font = function FontClosure() {
|
|
928
1132
|
file.skip(offset);
|
929
1133
|
var data = file.getBytes(length);
|
930
1134
|
file.pos = previousPosition;
|
1135
|
+
|
931
1136
|
if (tag === 'head') {
|
932
1137
|
data[8] = data[9] = data[10] = data[11] = 0;
|
933
1138
|
data[17] |= 0x20;
|
934
1139
|
}
|
1140
|
+
|
935
1141
|
return {
|
936
1142
|
tag: tag,
|
937
1143
|
checksum: checksum,
|
@@ -940,6 +1146,7 @@ var Font = function FontClosure() {
|
|
940
1146
|
data: data
|
941
1147
|
};
|
942
1148
|
}
|
1149
|
+
|
943
1150
|
function readOpenTypeHeader(ttf) {
|
944
1151
|
return {
|
945
1152
|
version: (0, _util.bytesToString)(ttf.getBytes(4)),
|
@@ -949,6 +1156,7 @@ var Font = function FontClosure() {
|
|
949
1156
|
rangeShift: ttf.getUint16()
|
950
1157
|
};
|
951
1158
|
}
|
1159
|
+
|
952
1160
|
function readTrueTypeCollectionHeader(ttc) {
|
953
1161
|
var ttcTag = (0, _util.bytesToString)(ttc.getBytes(4));
|
954
1162
|
(0, _util.assert)(ttcTag === 'ttcf', 'Must be a TrueType Collection font.');
|
@@ -956,9 +1164,11 @@ var Font = function FontClosure() {
|
|
956
1164
|
var minorVersion = ttc.getUint16();
|
957
1165
|
var numFonts = ttc.getInt32() >>> 0;
|
958
1166
|
var offsetTable = [];
|
1167
|
+
|
959
1168
|
for (var i = 0; i < numFonts; i++) {
|
960
1169
|
offsetTable.push(ttc.getInt32() >>> 0);
|
961
1170
|
}
|
1171
|
+
|
962
1172
|
var header = {
|
963
1173
|
ttcTag: ttcTag,
|
964
1174
|
majorVersion: majorVersion,
|
@@ -966,17 +1176,21 @@ var Font = function FontClosure() {
|
|
966
1176
|
numFonts: numFonts,
|
967
1177
|
offsetTable: offsetTable
|
968
1178
|
};
|
1179
|
+
|
969
1180
|
switch (majorVersion) {
|
970
1181
|
case 1:
|
971
1182
|
return header;
|
1183
|
+
|
972
1184
|
case 2:
|
973
1185
|
header.dsigTag = ttc.getInt32() >>> 0;
|
974
1186
|
header.dsigLength = ttc.getInt32() >>> 0;
|
975
1187
|
header.dsigOffset = ttc.getInt32() >>> 0;
|
976
1188
|
return header;
|
977
1189
|
}
|
978
|
-
|
1190
|
+
|
1191
|
+
throw new _util.FormatError("Invalid TrueType Collection majorVersion: ".concat(majorVersion, "."));
|
979
1192
|
}
|
1193
|
+
|
980
1194
|
function readTrueTypeCollectionData(ttc, fontName) {
|
981
1195
|
var _readTrueTypeCollecti = readTrueTypeCollectionHeader(ttc),
|
982
1196
|
numFonts = _readTrueTypeCollecti.numFonts,
|
@@ -986,13 +1200,17 @@ var Font = function FontClosure() {
|
|
986
1200
|
ttc.pos = (ttc.start || 0) + offsetTable[i];
|
987
1201
|
var potentialHeader = readOpenTypeHeader(ttc);
|
988
1202
|
var potentialTables = readTables(ttc, potentialHeader.numTables);
|
1203
|
+
|
989
1204
|
if (!potentialTables['name']) {
|
990
1205
|
throw new _util.FormatError('TrueType Collection font must contain a "name" table.');
|
991
1206
|
}
|
1207
|
+
|
992
1208
|
var nameTable = readNameTable(potentialTables['name']);
|
1209
|
+
|
993
1210
|
for (var j = 0, jj = nameTable.length; j < jj; j++) {
|
994
1211
|
for (var k = 0, kk = nameTable[j].length; k < kk; k++) {
|
995
1212
|
var nameEntry = nameTable[j][k];
|
1213
|
+
|
996
1214
|
if (nameEntry && nameEntry.replace(/\s/g, '') === fontName) {
|
997
1215
|
return {
|
998
1216
|
header: potentialHeader,
|
@@ -1002,8 +1220,10 @@ var Font = function FontClosure() {
|
|
1002
1220
|
}
|
1003
1221
|
}
|
1004
1222
|
}
|
1005
|
-
|
1223
|
+
|
1224
|
+
throw new _util.FormatError("TrueType Collection does not contain \"".concat(fontName, "\" font."));
|
1006
1225
|
}
|
1226
|
+
|
1007
1227
|
function readCmapTable(cmap, font, isSymbolicFont, hasEncoding) {
|
1008
1228
|
if (!cmap) {
|
1009
1229
|
(0, _util.warn)('No cmap table available.');
|
@@ -1014,6 +1234,7 @@ var Font = function FontClosure() {
|
|
1014
1234
|
hasShortCmap: false
|
1015
1235
|
};
|
1016
1236
|
}
|
1237
|
+
|
1017
1238
|
var segment;
|
1018
1239
|
var start = (font.start ? font.start : 0) + cmap.offset;
|
1019
1240
|
font.pos = start;
|
@@ -1021,20 +1242,24 @@ var Font = function FontClosure() {
|
|
1021
1242
|
var numTables = font.getUint16();
|
1022
1243
|
var potentialTable;
|
1023
1244
|
var canBreak = false;
|
1245
|
+
|
1024
1246
|
for (var i = 0; i < numTables; i++) {
|
1025
1247
|
var platformId = font.getUint16();
|
1026
1248
|
var encodingId = font.getUint16();
|
1027
1249
|
var offset = font.getInt32() >>> 0;
|
1028
1250
|
var useTable = false;
|
1251
|
+
|
1029
1252
|
if (potentialTable && potentialTable.platformId === platformId && potentialTable.encodingId === encodingId) {
|
1030
1253
|
continue;
|
1031
1254
|
}
|
1255
|
+
|
1032
1256
|
if (platformId === 0 && encodingId === 0) {
|
1033
1257
|
useTable = true;
|
1034
1258
|
} else if (platformId === 1 && encodingId === 0) {
|
1035
1259
|
useTable = true;
|
1036
1260
|
} else if (platformId === 3 && encodingId === 1 && (hasEncoding || !potentialTable)) {
|
1037
1261
|
useTable = true;
|
1262
|
+
|
1038
1263
|
if (!isSymbolicFont) {
|
1039
1264
|
canBreak = true;
|
1040
1265
|
}
|
@@ -1042,6 +1267,7 @@ var Font = function FontClosure() {
|
|
1042
1267
|
useTable = true;
|
1043
1268
|
canBreak = true;
|
1044
1269
|
}
|
1270
|
+
|
1045
1271
|
if (useTable) {
|
1046
1272
|
potentialTable = {
|
1047
1273
|
platformId: platformId,
|
@@ -1049,13 +1275,16 @@ var Font = function FontClosure() {
|
|
1049
1275
|
offset: offset
|
1050
1276
|
};
|
1051
1277
|
}
|
1278
|
+
|
1052
1279
|
if (canBreak) {
|
1053
1280
|
break;
|
1054
1281
|
}
|
1055
1282
|
}
|
1283
|
+
|
1056
1284
|
if (potentialTable) {
|
1057
1285
|
font.pos = start + potentialTable.offset;
|
1058
1286
|
}
|
1287
|
+
|
1059
1288
|
if (!potentialTable || font.peekByte() === -1) {
|
1060
1289
|
(0, _util.warn)('Could not find a preferred cmap table.');
|
1061
1290
|
return {
|
@@ -1065,65 +1294,85 @@ var Font = function FontClosure() {
|
|
1065
1294
|
hasShortCmap: false
|
1066
1295
|
};
|
1067
1296
|
}
|
1297
|
+
|
1068
1298
|
var format = font.getUint16();
|
1069
1299
|
font.getUint16();
|
1070
1300
|
font.getUint16();
|
1071
1301
|
var hasShortCmap = false;
|
1072
1302
|
var mappings = [];
|
1073
1303
|
var j, glyphId;
|
1304
|
+
|
1074
1305
|
if (format === 0) {
|
1075
1306
|
for (j = 0; j < 256; j++) {
|
1076
1307
|
var index = font.getByte();
|
1308
|
+
|
1077
1309
|
if (!index) {
|
1078
1310
|
continue;
|
1079
1311
|
}
|
1312
|
+
|
1080
1313
|
mappings.push({
|
1081
1314
|
charCode: j,
|
1082
1315
|
glyphId: index
|
1083
1316
|
});
|
1084
1317
|
}
|
1318
|
+
|
1085
1319
|
hasShortCmap = true;
|
1086
1320
|
} else if (format === 4) {
|
1087
1321
|
var segCount = font.getUint16() >> 1;
|
1088
1322
|
font.getBytes(6);
|
1089
1323
|
var segIndex,
|
1090
1324
|
segments = [];
|
1325
|
+
|
1091
1326
|
for (segIndex = 0; segIndex < segCount; segIndex++) {
|
1092
|
-
segments.push({
|
1327
|
+
segments.push({
|
1328
|
+
end: font.getUint16()
|
1329
|
+
});
|
1093
1330
|
}
|
1331
|
+
|
1094
1332
|
font.getUint16();
|
1333
|
+
|
1095
1334
|
for (segIndex = 0; segIndex < segCount; segIndex++) {
|
1096
1335
|
segments[segIndex].start = font.getUint16();
|
1097
1336
|
}
|
1337
|
+
|
1098
1338
|
for (segIndex = 0; segIndex < segCount; segIndex++) {
|
1099
1339
|
segments[segIndex].delta = font.getUint16();
|
1100
1340
|
}
|
1341
|
+
|
1101
1342
|
var offsetsCount = 0;
|
1343
|
+
|
1102
1344
|
for (segIndex = 0; segIndex < segCount; segIndex++) {
|
1103
1345
|
segment = segments[segIndex];
|
1104
1346
|
var rangeOffset = font.getUint16();
|
1347
|
+
|
1105
1348
|
if (!rangeOffset) {
|
1106
1349
|
segment.offsetIndex = -1;
|
1107
1350
|
continue;
|
1108
1351
|
}
|
1352
|
+
|
1109
1353
|
var offsetIndex = (rangeOffset >> 1) - (segCount - segIndex);
|
1110
1354
|
segment.offsetIndex = offsetIndex;
|
1111
1355
|
offsetsCount = Math.max(offsetsCount, offsetIndex + segment.end - segment.start + 1);
|
1112
1356
|
}
|
1357
|
+
|
1113
1358
|
var offsets = [];
|
1359
|
+
|
1114
1360
|
for (j = 0; j < offsetsCount; j++) {
|
1115
1361
|
offsets.push(font.getUint16());
|
1116
1362
|
}
|
1363
|
+
|
1117
1364
|
for (segIndex = 0; segIndex < segCount; segIndex++) {
|
1118
1365
|
segment = segments[segIndex];
|
1119
1366
|
start = segment.start;
|
1120
1367
|
var end = segment.end;
|
1121
1368
|
var delta = segment.delta;
|
1122
1369
|
offsetIndex = segment.offsetIndex;
|
1370
|
+
|
1123
1371
|
for (j = start; j <= end; j++) {
|
1124
1372
|
if (j === 0xFFFF) {
|
1125
1373
|
continue;
|
1126
1374
|
}
|
1375
|
+
|
1127
1376
|
glyphId = offsetIndex < 0 ? j : offsets[offsetIndex + j - start];
|
1128
1377
|
glyphId = glyphId + delta & 0xFFFF;
|
1129
1378
|
mappings.push({
|
@@ -1135,6 +1384,7 @@ var Font = function FontClosure() {
|
|
1135
1384
|
} else if (format === 6) {
|
1136
1385
|
var firstCode = font.getUint16();
|
1137
1386
|
var entryCount = font.getUint16();
|
1387
|
+
|
1138
1388
|
for (j = 0; j < entryCount; j++) {
|
1139
1389
|
glyphId = font.getUint16();
|
1140
1390
|
var charCode = firstCode + j;
|
@@ -1152,15 +1402,18 @@ var Font = function FontClosure() {
|
|
1152
1402
|
hasShortCmap: false
|
1153
1403
|
};
|
1154
1404
|
}
|
1405
|
+
|
1155
1406
|
mappings.sort(function (a, b) {
|
1156
1407
|
return a.charCode - b.charCode;
|
1157
1408
|
});
|
1409
|
+
|
1158
1410
|
for (i = 1; i < mappings.length; i++) {
|
1159
1411
|
if (mappings[i - 1].charCode === mappings[i].charCode) {
|
1160
1412
|
mappings.splice(i, 1);
|
1161
1413
|
i--;
|
1162
1414
|
}
|
1163
1415
|
}
|
1416
|
+
|
1164
1417
|
return {
|
1165
1418
|
platformId: potentialTable.platformId,
|
1166
1419
|
encodingId: potentialTable.encodingId,
|
@@ -1168,40 +1421,62 @@ var Font = function FontClosure() {
|
|
1168
1421
|
hasShortCmap: hasShortCmap
|
1169
1422
|
};
|
1170
1423
|
}
|
1424
|
+
|
1171
1425
|
function sanitizeMetrics(font, header, metrics, numGlyphs) {
|
1172
1426
|
if (!header) {
|
1173
1427
|
if (metrics) {
|
1174
1428
|
metrics.data = null;
|
1175
1429
|
}
|
1430
|
+
|
1176
1431
|
return;
|
1177
1432
|
}
|
1433
|
+
|
1178
1434
|
font.pos = (font.start ? font.start : 0) + header.offset;
|
1179
|
-
font.pos +=
|
1435
|
+
font.pos += 4;
|
1436
|
+
font.pos += 2;
|
1437
|
+
font.pos += 2;
|
1438
|
+
font.pos += 2;
|
1439
|
+
font.pos += 2;
|
1440
|
+
font.pos += 2;
|
1441
|
+
font.pos += 2;
|
1442
|
+
font.pos += 2;
|
1443
|
+
font.pos += 2;
|
1444
|
+
font.pos += 2;
|
1445
|
+
font.pos += 2;
|
1446
|
+
font.pos += 8;
|
1447
|
+
font.pos += 2;
|
1180
1448
|
var numOfMetrics = font.getUint16();
|
1449
|
+
|
1181
1450
|
if (numOfMetrics > numGlyphs) {
|
1182
1451
|
(0, _util.info)('The numOfMetrics (' + numOfMetrics + ') should not be ' + 'greater than the numGlyphs (' + numGlyphs + ')');
|
1183
1452
|
numOfMetrics = numGlyphs;
|
1184
1453
|
header.data[34] = (numOfMetrics & 0xff00) >> 8;
|
1185
1454
|
header.data[35] = numOfMetrics & 0x00ff;
|
1186
1455
|
}
|
1456
|
+
|
1187
1457
|
var numOfSidebearings = numGlyphs - numOfMetrics;
|
1188
1458
|
var numMissing = numOfSidebearings - (metrics.length - numOfMetrics * 4 >> 1);
|
1459
|
+
|
1189
1460
|
if (numMissing > 0) {
|
1190
1461
|
var entries = new Uint8Array(metrics.length + numMissing * 2);
|
1191
1462
|
entries.set(metrics.data);
|
1192
1463
|
metrics.data = entries;
|
1193
1464
|
}
|
1194
1465
|
}
|
1466
|
+
|
1195
1467
|
function sanitizeGlyph(source, sourceStart, sourceEnd, dest, destStart, hintsValid) {
|
1196
1468
|
var glyphProfile = {
|
1197
1469
|
length: 0,
|
1198
1470
|
sizeOfInstructions: 0
|
1199
1471
|
};
|
1472
|
+
|
1200
1473
|
if (sourceEnd - sourceStart <= 12) {
|
1201
1474
|
return glyphProfile;
|
1202
1475
|
}
|
1476
|
+
|
1203
1477
|
var glyf = source.subarray(sourceStart, sourceEnd);
|
1204
1478
|
var contoursCount = signedInt16(glyf[0], glyf[1]);
|
1479
|
+
|
1205
1480
|
if (contoursCount < 0) {
|
1206
1481
|
contoursCount = -1;
|
1207
1482
|
writeSignedInt16(glyf, 0, contoursCount);
|
@@ -1209,64 +1484,81 @@ var Font = function FontClosure() {
|
|
1209
1484
|
glyphProfile.length = glyf.length;
|
1210
1485
|
return glyphProfile;
|
1211
1486
|
}
|
1487
|
+
|
1212
1488
|
var i,
|
1213
1489
|
j = 10,
|
1214
1490
|
flagsCount = 0;
|
1491
|
+
|
1215
1492
|
for (i = 0; i < contoursCount; i++) {
|
1216
1493
|
var endPoint = glyf[j] << 8 | glyf[j + 1];
|
1217
1494
|
flagsCount = endPoint + 1;
|
1218
1495
|
j += 2;
|
1219
1496
|
}
|
1497
|
+
|
1220
1498
|
var instructionsStart = j;
|
1221
1499
|
var instructionsLength = glyf[j] << 8 | glyf[j + 1];
|
1222
1500
|
glyphProfile.sizeOfInstructions = instructionsLength;
|
1223
1501
|
j += 2 + instructionsLength;
|
1224
1502
|
var instructionsEnd = j;
|
1225
1503
|
var coordinatesLength = 0;
|
1504
|
+
|
1226
1505
|
for (i = 0; i < flagsCount; i++) {
|
1227
1506
|
var flag = glyf[j++];
|
1507
|
+
|
1228
1508
|
if (flag & 0xC0) {
|
1229
1509
|
glyf[j - 1] = flag & 0x3F;
|
1230
1510
|
}
|
1511
|
+
|
1231
1512
|
var xyLength = (flag & 2 ? 1 : flag & 16 ? 0 : 2) + (flag & 4 ? 1 : flag & 32 ? 0 : 2);
|
1232
1513
|
coordinatesLength += xyLength;
|
1514
|
+
|
1233
1515
|
if (flag & 8) {
|
1234
1516
|
var repeat = glyf[j++];
|
1235
1517
|
i += repeat;
|
1236
1518
|
coordinatesLength += repeat * xyLength;
|
1237
1519
|
}
|
1238
1520
|
}
|
1521
|
+
|
1239
1522
|
if (coordinatesLength === 0) {
|
1240
1523
|
return glyphProfile;
|
1241
1524
|
}
|
1525
|
+
|
1242
1526
|
var glyphDataLength = j + coordinatesLength;
|
1527
|
+
|
1243
1528
|
if (glyphDataLength > glyf.length) {
|
1244
1529
|
return glyphProfile;
|
1245
1530
|
}
|
1531
|
+
|
1246
1532
|
if (!hintsValid && instructionsLength > 0) {
|
1247
1533
|
dest.set(glyf.subarray(0, instructionsStart), destStart);
|
1248
1534
|
dest.set([0, 0], destStart + instructionsStart);
|
1249
1535
|
dest.set(glyf.subarray(instructionsEnd, glyphDataLength), destStart + instructionsStart + 2);
|
1250
1536
|
glyphDataLength -= instructionsLength;
|
1537
|
+
|
1251
1538
|
if (glyf.length - glyphDataLength > 3) {
|
1252
1539
|
glyphDataLength = glyphDataLength + 3 & ~3;
|
1253
1540
|
}
|
1541
|
+
|
1254
1542
|
glyphProfile.length = glyphDataLength;
|
1255
1543
|
return glyphProfile;
|
1256
1544
|
}
|
1545
|
+
|
1257
1546
|
if (glyf.length - glyphDataLength > 3) {
|
1258
1547
|
glyphDataLength = glyphDataLength + 3 & ~3;
|
1259
1548
|
dest.set(glyf.subarray(0, glyphDataLength), destStart);
|
1260
1549
|
glyphProfile.length = glyphDataLength;
|
1261
1550
|
return glyphProfile;
|
1262
1551
|
}
|
1552
|
+
|
1263
1553
|
dest.set(glyf, destStart);
|
1264
1554
|
glyphProfile.length = glyf.length;
|
1265
1555
|
return glyphProfile;
|
1266
1556
|
}
|
1557
|
+
|
1267
1558
|
function sanitizeHead(head, numGlyphs, locaLength) {
|
1268
1559
|
var data = head.data;
|
1269
1560
|
var version = int32(data[0], data[1], data[2], data[3]);
|
1561
|
+
|
1270
1562
|
if (version >> 16 !== 1) {
|
1271
1563
|
(0, _util.info)('Attempting to fix invalid version in head table: ' + version);
|
1272
1564
|
data[0] = 0;
|
@@ -1274,10 +1566,13 @@ var Font = function FontClosure() {
|
|
1274
1566
|
data[2] = 0;
|
1275
1567
|
data[3] = 0;
|
1276
1568
|
}
|
1569
|
+
|
1277
1570
|
var indexToLocFormat = int16(data[50], data[51]);
|
1571
|
+
|
1278
1572
|
if (indexToLocFormat < 0 || indexToLocFormat > 1) {
|
1279
1573
|
(0, _util.info)('Attempting to fix invalid indexToLocFormat in head table: ' + indexToLocFormat);
|
1280
1574
|
var numGlyphsPlusOne = numGlyphs + 1;
|
1575
|
+
|
1281
1576
|
if (locaLength === numGlyphsPlusOne << 1) {
|
1282
1577
|
data[50] = 0;
|
1283
1578
|
data[51] = 0;
|
@@ -1289,13 +1584,17 @@ var Font = function FontClosure() {
|
|
1289
1584
|
}
|
1290
1585
|
}
|
1291
1586
|
}
|
1587
|
+
|
1292
1588
|
function sanitizeGlyphLocations(loca, glyf, numGlyphs, isGlyphLocationsLong, hintsValid, dupFirstEntry, maxSizeOfInstructions) {
|
1293
1589
|
var itemSize, itemDecode, itemEncode;
|
1590
|
+
|
1294
1591
|
if (isGlyphLocationsLong) {
|
1295
1592
|
itemSize = 4;
|
1593
|
+
|
1296
1594
|
itemDecode = function fontItemDecodeLong(data, offset) {
|
1297
1595
|
return data[offset] << 24 | data[offset + 1] << 16 | data[offset + 2] << 8 | data[offset + 3];
|
1298
1596
|
};
|
1597
|
+
|
1299
1598
|
itemEncode = function fontItemEncodeLong(data, offset, value) {
|
1300
1599
|
data[offset] = value >>> 24 & 0xFF;
|
1301
1600
|
data[offset + 1] = value >> 16 & 0xFF;
|
@@ -1304,21 +1603,23 @@ var Font = function FontClosure() {
|
|
1304
1603
|
};
|
1305
1604
|
} else {
|
1306
1605
|
itemSize = 2;
|
1606
|
+
|
1307
1607
|
itemDecode = function fontItemDecode(data, offset) {
|
1308
1608
|
return data[offset] << 9 | data[offset + 1] << 1;
|
1309
1609
|
};
|
1610
|
+
|
1310
1611
|
itemEncode = function fontItemEncode(data, offset, value) {
|
1311
1612
|
data[offset] = value >> 9 & 0xFF;
|
1312
1613
|
data[offset + 1] = value >> 1 & 0xFF;
|
1313
1614
|
};
|
1314
1615
|
}
|
1616
|
+
|
1617
|
+
var numGlyphsOut = dupFirstEntry ? numGlyphs + 1 : numGlyphs;
|
1315
1618
|
var locaData = loca.data;
|
1316
|
-
var locaDataSize = itemSize * (1 +
|
1317
|
-
|
1318
|
-
|
1319
|
-
|
1320
|
-
loca.data = locaData;
|
1321
|
-
}
|
1619
|
+
var locaDataSize = itemSize * (1 + numGlyphsOut);
|
1620
|
+
locaData = new Uint8Array(locaDataSize);
|
1621
|
+
locaData.set(loca.data.subarray(0, locaDataSize));
|
1622
|
+
loca.data = locaData;
|
1322
1623
|
var oldGlyfData = glyf.data;
|
1323
1624
|
var oldGlyfDataLength = oldGlyfData.length;
|
1324
1625
|
var newGlyfData = new Uint8Array(oldGlyfDataLength);
|
@@ -1327,54 +1628,68 @@ var Font = function FontClosure() {
|
|
1327
1628
|
var missingGlyphs = Object.create(null);
|
1328
1629
|
itemEncode(locaData, 0, writeOffset);
|
1329
1630
|
var i, j;
|
1330
|
-
|
1331
|
-
for (i = 0, j = itemSize; i <
|
1631
|
+
|
1632
|
+
for (i = 0, j = itemSize; i < numGlyphs; i++, j += itemSize) {
|
1332
1633
|
var endOffset = itemDecode(locaData, j);
|
1634
|
+
|
1333
1635
|
if (endOffset === 0) {
|
1334
1636
|
endOffset = startOffset;
|
1335
1637
|
}
|
1638
|
+
|
1336
1639
|
if (endOffset > oldGlyfDataLength && (oldGlyfDataLength + 3 & ~3) === endOffset) {
|
1337
1640
|
endOffset = oldGlyfDataLength;
|
1338
1641
|
}
|
1642
|
+
|
1339
1643
|
if (endOffset > oldGlyfDataLength) {
|
1340
1644
|
startOffset = endOffset;
|
1341
1645
|
}
|
1646
|
+
|
1342
1647
|
var glyphProfile = sanitizeGlyph(oldGlyfData, startOffset, endOffset, newGlyfData, writeOffset, hintsValid);
|
1343
1648
|
var newLength = glyphProfile.length;
|
1649
|
+
|
1344
1650
|
if (newLength === 0) {
|
1345
1651
|
missingGlyphs[i] = true;
|
1346
1652
|
}
|
1653
|
+
|
1347
1654
|
if (glyphProfile.sizeOfInstructions > maxSizeOfInstructions) {
|
1348
1655
|
maxSizeOfInstructions = glyphProfile.sizeOfInstructions;
|
1349
1656
|
}
|
1657
|
+
|
1350
1658
|
writeOffset += newLength;
|
1351
1659
|
itemEncode(locaData, j, writeOffset);
|
1352
1660
|
startOffset = endOffset;
|
1353
1661
|
}
|
1662
|
+
|
1354
1663
|
if (writeOffset === 0) {
|
1355
1664
|
var simpleGlyph = new Uint8Array([0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 0]);
|
1356
|
-
|
1665
|
+
|
1666
|
+
for (i = 0, j = itemSize; i < numGlyphsOut; i++, j += itemSize) {
|
1357
1667
|
itemEncode(locaData, j, simpleGlyph.length);
|
1358
1668
|
}
|
1669
|
+
|
1359
1670
|
glyf.data = simpleGlyph;
|
1360
1671
|
} else if (dupFirstEntry) {
|
1361
1672
|
var firstEntryLength = itemDecode(locaData, itemSize);
|
1673
|
+
|
1362
1674
|
if (newGlyfData.length > firstEntryLength + writeOffset) {
|
1363
1675
|
glyf.data = newGlyfData.subarray(0, firstEntryLength + writeOffset);
|
1364
1676
|
} else {
|
1365
1677
|
glyf.data = new Uint8Array(firstEntryLength + writeOffset);
|
1366
1678
|
glyf.data.set(newGlyfData.subarray(0, writeOffset));
|
1367
1679
|
}
|
1680
|
+
|
1368
1681
|
glyf.data.set(newGlyfData.subarray(0, firstEntryLength), writeOffset);
|
1369
1682
|
itemEncode(loca.data, locaData.length - itemSize, writeOffset + firstEntryLength);
|
1370
1683
|
} else {
|
1371
1684
|
glyf.data = newGlyfData.subarray(0, writeOffset);
|
1372
1685
|
}
|
1686
|
+
|
1373
1687
|
return {
|
1374
1688
|
missingGlyphs: missingGlyphs,
|
1375
1689
|
maxSizeOfInstructions: maxSizeOfInstructions
|
1376
1690
|
};
|
1377
1691
|
}
|
1692
|
+
|
1378
1693
|
function readPostScriptTable(post, properties, maxpNumGlyphs) {
|
1379
1694
|
var start = (font.start ? font.start : 0) + post.offset;
|
1380
1695
|
font.pos = start;
|
@@ -1385,61 +1700,84 @@ var Font = function FontClosure() {
|
|
1385
1700
|
var glyphNames;
|
1386
1701
|
var valid = true;
|
1387
1702
|
var i;
|
1703
|
+
|
1388
1704
|
switch (version) {
|
1389
1705
|
case 0x00010000:
|
1390
1706
|
glyphNames = MacStandardGlyphOrdering;
|
1391
1707
|
break;
|
1708
|
+
|
1392
1709
|
case 0x00020000:
|
1393
1710
|
var numGlyphs = font.getUint16();
|
1711
|
+
|
1394
1712
|
if (numGlyphs !== maxpNumGlyphs) {
|
1395
1713
|
valid = false;
|
1396
1714
|
break;
|
1397
1715
|
}
|
1716
|
+
|
1398
1717
|
var glyphNameIndexes = [];
|
1718
|
+
|
1399
1719
|
for (i = 0; i < numGlyphs; ++i) {
|
1400
1720
|
var index = font.getUint16();
|
1721
|
+
|
1401
1722
|
if (index >= 32768) {
|
1402
1723
|
valid = false;
|
1403
1724
|
break;
|
1404
1725
|
}
|
1726
|
+
|
1405
1727
|
glyphNameIndexes.push(index);
|
1406
1728
|
}
|
1729
|
+
|
1407
1730
|
if (!valid) {
|
1408
1731
|
break;
|
1409
1732
|
}
|
1733
|
+
|
1410
1734
|
var customNames = [];
|
1411
1735
|
var strBuf = [];
|
1736
|
+
|
1412
1737
|
while (font.pos < end) {
|
1413
1738
|
var stringLength = font.getByte();
|
1414
1739
|
strBuf.length = stringLength;
|
1740
|
+
|
1415
1741
|
for (i = 0; i < stringLength; ++i) {
|
1416
1742
|
strBuf[i] = String.fromCharCode(font.getByte());
|
1417
1743
|
}
|
1744
|
+
|
1418
1745
|
customNames.push(strBuf.join(''));
|
1419
1746
|
}
|
1747
|
+
|
1420
1748
|
glyphNames = [];
|
1749
|
+
|
1421
1750
|
for (i = 0; i < numGlyphs; ++i) {
|
1422
1751
|
var j = glyphNameIndexes[i];
|
1752
|
+
|
1423
1753
|
if (j < 258) {
|
1424
1754
|
glyphNames.push(MacStandardGlyphOrdering[j]);
|
1425
1755
|
continue;
|
1426
1756
|
}
|
1757
|
+
|
1427
1758
|
glyphNames.push(customNames[j - 258]);
|
1428
1759
|
}
|
1760
|
+
|
1429
1761
|
break;
|
1762
|
+
|
1430
1763
|
case 0x00030000:
|
1431
1764
|
break;
|
1765
|
+
|
1432
1766
|
default:
|
1433
1767
|
(0, _util.warn)('Unknown/unsupported post table version ' + version);
|
1434
1768
|
valid = false;
|
1769
|
+
|
1435
1770
|
if (properties.defaultEncoding) {
|
1436
1771
|
glyphNames = properties.defaultEncoding;
|
1437
1772
|
}
|
1773
|
+
|
1438
1774
|
break;
|
1439
1775
|
}
|
1776
|
+
|
1440
1777
|
properties.glyphNames = glyphNames;
|
1441
1778
|
return valid;
|
1442
1779
|
}
|
1780
|
+
|
1443
1781
|
function readNameTable(nameTable) {
|
1444
1782
|
var start = (font.start ? font.start : 0) + nameTable.offset;
|
1445
1783
|
font.pos = start;
|
@@ -1448,14 +1786,17 @@ var Font = function FontClosure() {
|
|
1448
1786
|
end = start + length;
|
1449
1787
|
var format = font.getUint16();
|
1450
1788
|
var FORMAT_0_HEADER_LENGTH = 6;
|
1789
|
+
|
1451
1790
|
if (format !== 0 || length < FORMAT_0_HEADER_LENGTH) {
|
1452
1791
|
return names;
|
1453
1792
|
}
|
1793
|
+
|
1454
1794
|
var numRecords = font.getUint16();
|
1455
1795
|
var stringsStart = font.getUint16();
|
1456
1796
|
var records = [];
|
1457
1797
|
var NAME_RECORD_LENGTH = 12;
|
1458
1798
|
var i, ii;
|
1799
|
+
|
1459
1800
|
for (i = 0; i < numRecords && font.pos + NAME_RECORD_LENGTH <= end; i++) {
|
1460
1801
|
var r = {
|
1461
1802
|
platform: font.getUint16(),
|
@@ -1465,34 +1806,46 @@ var Font = function FontClosure() {
|
|
1465
1806
|
length: font.getUint16(),
|
1466
1807
|
offset: font.getUint16()
|
1467
1808
|
};
|
1809
|
+
|
1468
1810
|
if (r.platform === 1 && r.encoding === 0 && r.language === 0 || r.platform === 3 && r.encoding === 1 && r.language === 0x409) {
|
1469
1811
|
records.push(r);
|
1470
1812
|
}
|
1471
1813
|
}
|
1814
|
+
|
1472
1815
|
for (i = 0, ii = records.length; i < ii; i++) {
|
1473
1816
|
var record = records[i];
|
1817
|
+
|
1474
1818
|
if (record.length <= 0) {
|
1475
1819
|
continue;
|
1476
1820
|
}
|
1821
|
+
|
1477
1822
|
var pos = start + stringsStart + record.offset;
|
1823
|
+
|
1478
1824
|
if (pos + record.length > end) {
|
1479
1825
|
continue;
|
1480
1826
|
}
|
1827
|
+
|
1481
1828
|
font.pos = pos;
|
1482
1829
|
var nameIndex = record.name;
|
1830
|
+
|
1483
1831
|
if (record.encoding) {
|
1484
1832
|
var str = '';
|
1833
|
+
|
1485
1834
|
for (var j = 0, jj = record.length; j < jj; j += 2) {
|
1486
1835
|
str += String.fromCharCode(font.getUint16());
|
1487
1836
|
}
|
1837
|
+
|
1488
1838
|
names[1][nameIndex] = str;
|
1489
1839
|
} else {
|
1490
1840
|
names[0][nameIndex] = (0, _util.bytesToString)(font.getBytes(record.length));
|
1491
1841
|
}
|
1492
1842
|
}
|
1843
|
+
|
1493
1844
|
return names;
|
1494
1845
|
}
|
1846
|
+
|
1495
1847
|
var TTOpsStackDeltas = [0, 0, 0, 0, 0, 0, 0, 0, -2, -2, -2, -2, 0, 0, -2, -5, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, -1, 0, -1, -1, -1, -1, 1, -1, -999, 0, 1, 0, -1, -2, 0, -1, -2, -1, -1, 0, -1, -1, 0, 0, -999, -999, -1, -1, -1, -1, -2, -999, -2, -2, -999, 0, -2, -2, 0, 0, -2, 0, -2, 0, 0, 0, -2, -1, -1, 1, 1, 0, 0, -1, -1, -1, -1, -1, -1, -1, 0, 0, -1, 0, -1, -1, 0, -999, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, -999, -999, -999, -999, -999, -1, -1, -2, -2, 0, 0, 0, 0, -1, -1, -999, -2, -2, 0, 0, -1, -2, -2, 0, 0, 0, -1, -1, -1, -2];
|
1848
|
+
|
1496
1849
|
function sanitizeTTProgram(table, ttContext) {
|
1497
1850
|
var data = table.data;
|
1498
1851
|
var i = 0,
|
@@ -1510,10 +1863,13 @@ var Font = function FontClosure() {
|
|
1510
1863
|
var inFDEF = false,
|
1511
1864
|
ifLevel = 0,
|
1512
1865
|
inELSE = 0;
|
1866
|
+
|
1513
1867
|
for (var ii = data.length; i < ii;) {
|
1514
1868
|
var op = data[i++];
|
1869
|
+
|
1515
1870
|
if (op === 0x40) {
|
1516
1871
|
n = data[i++];
|
1872
|
+
|
1517
1873
|
if (inFDEF || inELSE) {
|
1518
1874
|
i += n;
|
1519
1875
|
} else {
|
@@ -1523,6 +1879,7 @@ var Font = function FontClosure() {
|
|
1523
1879
|
}
|
1524
1880
|
} else if (op === 0x41) {
|
1525
1881
|
n = data[i++];
|
1882
|
+
|
1526
1883
|
if (inFDEF || inELSE) {
|
1527
1884
|
i += n * 2;
|
1528
1885
|
} else {
|
@@ -1533,6 +1890,7 @@ var Font = function FontClosure() {
|
|
1533
1890
|
}
|
1534
1891
|
} else if ((op & 0xF8) === 0xB0) {
|
1535
1892
|
n = op - 0xB0 + 1;
|
1893
|
+
|
1536
1894
|
if (inFDEF || inELSE) {
|
1537
1895
|
i += n;
|
1538
1896
|
} else {
|
@@ -1542,6 +1900,7 @@ var Font = function FontClosure() {
|
|
1542
1900
|
}
|
1543
1901
|
} else if ((op & 0xF8) === 0xB8) {
|
1544
1902
|
n = op - 0xB8 + 1;
|
1903
|
+
|
1545
1904
|
if (inFDEF || inELSE) {
|
1546
1905
|
i += n * 2;
|
1547
1906
|
} else {
|
@@ -1553,24 +1912,40 @@ var Font = function FontClosure() {
|
|
1553
1912
|
} else if (op === 0x2B && !tooComplexToFollowFunctions) {
|
1554
1913
|
if (!inFDEF && !inELSE) {
|
1555
1914
|
funcId = stack[stack.length - 1];
|
1556
|
-
|
1557
|
-
if (funcId
|
1558
|
-
|
1559
|
-
} else
|
1560
|
-
|
1561
|
-
|
1562
|
-
|
1563
|
-
|
1564
|
-
|
1565
|
-
|
1566
|
-
|
1567
|
-
|
1568
|
-
|
1569
|
-
|
1570
|
-
|
1915
|
+
|
1916
|
+
if (isNaN(funcId)) {
|
1917
|
+
(0, _util.info)('TT: CALL empty stack (or invalid entry).');
|
1918
|
+
} else {
|
1919
|
+
ttContext.functionsUsed[funcId] = true;
|
1920
|
+
|
1921
|
+
if (funcId in ttContext.functionsStackDeltas) {
|
1922
|
+
var newStackLength = stack.length + ttContext.functionsStackDeltas[funcId];
|
1923
|
+
|
1924
|
+
if (newStackLength < 0) {
|
1925
|
+
(0, _util.warn)('TT: CALL invalid functions stack delta.');
|
1926
|
+
ttContext.hintsValid = false;
|
1927
|
+
return;
|
1928
|
+
}
|
1929
|
+
|
1930
|
+
stack.length = newStackLength;
|
1931
|
+
} else if (funcId in ttContext.functionsDefined && !functionsCalled.includes(funcId)) {
|
1932
|
+
callstack.push({
|
1933
|
+
data: data,
|
1934
|
+
i: i,
|
1935
|
+
stackTop: stack.length - 1
|
1936
|
+
});
|
1937
|
+
functionsCalled.push(funcId);
|
1938
|
+
pc = ttContext.functionsDefined[funcId];
|
1939
|
+
|
1940
|
+
if (!pc) {
|
1941
|
+
(0, _util.warn)('TT: CALL non-existent function');
|
1942
|
+
ttContext.hintsValid = false;
|
1943
|
+
return;
|
1944
|
+
}
|
1945
|
+
|
1946
|
+
data = pc.data;
|
1947
|
+
i = pc.i;
|
1571
1948
|
}
|
1572
|
-
data = pc.data;
|
1573
|
-
i = pc.i;
|
1574
1949
|
}
|
1575
1950
|
}
|
1576
1951
|
} else if (op === 0x2C && !tooComplexToFollowFunctions) {
|
@@ -1578,6 +1953,7 @@ var Font = function FontClosure() {
|
|
1578
1953
|
(0, _util.warn)('TT: nested FDEFs not allowed');
|
1579
1954
|
tooComplexToFollowFunctions = true;
|
1580
1955
|
}
|
1956
|
+
|
1581
1957
|
inFDEF = true;
|
1582
1958
|
lastDeff = i;
|
1583
1959
|
funcId = stack.pop();
|
@@ -1591,11 +1967,13 @@ var Font = function FontClosure() {
|
|
1591
1967
|
lastEndf = i;
|
1592
1968
|
} else {
|
1593
1969
|
pc = callstack.pop();
|
1970
|
+
|
1594
1971
|
if (!pc) {
|
1595
1972
|
(0, _util.warn)('TT: ENDF bad stack');
|
1596
1973
|
ttContext.hintsValid = false;
|
1597
1974
|
return;
|
1598
1975
|
}
|
1976
|
+
|
1599
1977
|
funcId = functionsCalled.pop();
|
1600
1978
|
data = pc.data;
|
1601
1979
|
i = pc.i;
|
@@ -1606,6 +1984,7 @@ var Font = function FontClosure() {
|
|
1606
1984
|
(0, _util.warn)('TT: nested IDEFs not allowed');
|
1607
1985
|
tooComplexToFollowFunctions = true;
|
1608
1986
|
}
|
1987
|
+
|
1609
1988
|
inFDEF = true;
|
1610
1989
|
lastDeff = i;
|
1611
1990
|
} else if (op === 0x58) {
|
@@ -1616,59 +1995,74 @@ var Font = function FontClosure() {
|
|
1616
1995
|
if (inELSE === ifLevel) {
|
1617
1996
|
inELSE = 0;
|
1618
1997
|
}
|
1998
|
+
|
1619
1999
|
--ifLevel;
|
1620
2000
|
} else if (op === 0x1C) {
|
1621
2001
|
if (!inFDEF && !inELSE) {
|
1622
2002
|
var offset = stack[stack.length - 1];
|
2003
|
+
|
1623
2004
|
if (offset > 0) {
|
1624
2005
|
i += offset - 1;
|
1625
2006
|
}
|
1626
2007
|
}
|
1627
2008
|
}
|
2009
|
+
|
1628
2010
|
if (!inFDEF && !inELSE) {
|
1629
2011
|
var stackDelta = op <= 0x8E ? TTOpsStackDeltas[op] : op >= 0xC0 && op <= 0xDF ? -1 : op >= 0xE0 ? -2 : 0;
|
2012
|
+
|
1630
2013
|
if (op >= 0x71 && op <= 0x75) {
|
1631
2014
|
n = stack.pop();
|
2015
|
+
|
1632
2016
|
if (!isNaN(n)) {
|
1633
2017
|
stackDelta = -n * 2;
|
1634
2018
|
}
|
1635
2019
|
}
|
2020
|
+
|
1636
2021
|
while (stackDelta < 0 && stack.length > 0) {
|
1637
2022
|
stack.pop();
|
1638
2023
|
stackDelta++;
|
1639
2024
|
}
|
2025
|
+
|
1640
2026
|
while (stackDelta > 0) {
|
1641
2027
|
stack.push(NaN);
|
1642
2028
|
stackDelta--;
|
1643
2029
|
}
|
1644
2030
|
}
|
1645
2031
|
}
|
2032
|
+
|
1646
2033
|
ttContext.tooComplexToFollowFunctions = tooComplexToFollowFunctions;
|
1647
2034
|
var content = [data];
|
2035
|
+
|
1648
2036
|
if (i > data.length) {
|
1649
2037
|
content.push(new Uint8Array(i - data.length));
|
1650
2038
|
}
|
2039
|
+
|
1651
2040
|
if (lastDeff > lastEndf) {
|
1652
2041
|
(0, _util.warn)('TT: complementing a missing function tail');
|
1653
2042
|
content.push(new Uint8Array([0x22, 0x2D]));
|
1654
2043
|
}
|
2044
|
+
|
1655
2045
|
foldTTTable(table, content);
|
1656
2046
|
}
|
2047
|
+
|
1657
2048
|
function checkInvalidFunctions(ttContext, maxFunctionDefs) {
|
1658
2049
|
if (ttContext.tooComplexToFollowFunctions) {
|
1659
2050
|
return;
|
1660
2051
|
}
|
2052
|
+
|
1661
2053
|
if (ttContext.functionsDefined.length > maxFunctionDefs) {
|
1662
2054
|
(0, _util.warn)('TT: more functions defined than expected');
|
1663
2055
|
ttContext.hintsValid = false;
|
1664
2056
|
return;
|
1665
2057
|
}
|
2058
|
+
|
1666
2059
|
for (var j = 0, jj = ttContext.functionsUsed.length; j < jj; j++) {
|
1667
2060
|
if (j > maxFunctionDefs) {
|
1668
2061
|
(0, _util.warn)('TT: invalid function id: ' + j);
|
1669
2062
|
ttContext.hintsValid = false;
|
1670
2063
|
return;
|
1671
2064
|
}
|
2065
|
+
|
1672
2066
|
if (ttContext.functionsUsed[j] && !ttContext.functionsDefined[j]) {
|
1673
2067
|
(0, _util.warn)('TT: undefined function: ' + j);
|
1674
2068
|
ttContext.hintsValid = false;
|
@@ -1676,24 +2070,30 @@ var Font = function FontClosure() {
|
|
1676
2070
|
}
|
1677
2071
|
}
|
1678
2072
|
}
|
2073
|
+
|
1679
2074
|
function foldTTTable(table, content) {
|
1680
2075
|
if (content.length > 1) {
|
1681
2076
|
var newLength = 0;
|
1682
2077
|
var j, jj;
|
2078
|
+
|
1683
2079
|
for (j = 0, jj = content.length; j < jj; j++) {
|
1684
2080
|
newLength += content[j].length;
|
1685
2081
|
}
|
2082
|
+
|
1686
2083
|
newLength = newLength + 3 & ~3;
|
1687
2084
|
var result = new Uint8Array(newLength);
|
1688
2085
|
var pos = 0;
|
2086
|
+
|
1689
2087
|
for (j = 0, jj = content.length; j < jj; j++) {
|
1690
2088
|
result.set(content[j], pos);
|
1691
2089
|
pos += content[j].length;
|
1692
2090
|
}
|
2091
|
+
|
1693
2092
|
table.data = result;
|
1694
2093
|
table.length = newLength;
|
1695
2094
|
}
|
1696
2095
|
}
|
2096
|
+
|
1697
2097
|
function sanitizeTTPrograms(fpgm, prep, cvt, maxFunctionDefs) {
|
1698
2098
|
var ttContext = {
|
1699
2099
|
functionsDefined: [],
|
@@ -1702,25 +2102,31 @@ var Font = function FontClosure() {
|
|
1702
2102
|
tooComplexToFollowFunctions: false,
|
1703
2103
|
hintsValid: true
|
1704
2104
|
};
|
2105
|
+
|
1705
2106
|
if (fpgm) {
|
1706
2107
|
sanitizeTTProgram(fpgm, ttContext);
|
1707
2108
|
}
|
2109
|
+
|
1708
2110
|
if (prep) {
|
1709
2111
|
sanitizeTTProgram(prep, ttContext);
|
1710
2112
|
}
|
2113
|
+
|
1711
2114
|
if (fpgm) {
|
1712
2115
|
checkInvalidFunctions(ttContext, maxFunctionDefs);
|
1713
2116
|
}
|
2117
|
+
|
1714
2118
|
if (cvt && cvt.length & 1) {
|
1715
2119
|
var cvtData = new Uint8Array(cvt.length + 1);
|
1716
2120
|
cvtData.set(cvt.data);
|
1717
2121
|
cvt.data = cvtData;
|
1718
2122
|
}
|
2123
|
+
|
1719
2124
|
return ttContext.hintsValid;
|
1720
2125
|
}
|
2126
|
+
|
1721
2127
|
font = new _stream.Stream(new Uint8Array(font.getBytes()));
|
1722
|
-
var header
|
1723
|
-
|
2128
|
+
var header, tables;
|
2129
|
+
|
1724
2130
|
if (isTrueTypeCollectionFile(font)) {
|
1725
2131
|
var ttcData = readTrueTypeCollectionData(font, this.name);
|
1726
2132
|
header = ttcData.header;
|
@@ -1729,16 +2135,20 @@ var Font = function FontClosure() {
|
|
1729
2135
|
header = readOpenTypeHeader(font);
|
1730
2136
|
tables = readTables(font, header.numTables);
|
1731
2137
|
}
|
1732
|
-
|
1733
|
-
|
2138
|
+
|
2139
|
+
var cff, cffFile;
|
1734
2140
|
var isTrueType = !tables['CFF '];
|
2141
|
+
|
1735
2142
|
if (!isTrueType) {
|
1736
|
-
|
2143
|
+
var isComposite = properties.composite && ((properties.cidToGidMap || []).length > 0 || !(properties.cMap instanceof _cmap.IdentityCMap));
|
2144
|
+
|
2145
|
+
if (header.version === 'OTTO' && !isComposite || !tables['head'] || !tables['hhea'] || !tables['maxp'] || !tables['post']) {
|
1737
2146
|
cffFile = new _stream.Stream(tables['CFF '].data);
|
1738
2147
|
cff = new CFFFont(cffFile, properties);
|
1739
2148
|
adjustWidths(properties);
|
1740
2149
|
return this.convert(name, cff, properties);
|
1741
2150
|
}
|
2151
|
+
|
1742
2152
|
delete tables['glyf'];
|
1743
2153
|
delete tables['loca'];
|
1744
2154
|
delete tables['fpgm'];
|
@@ -1749,6 +2159,7 @@ var Font = function FontClosure() {
|
|
1749
2159
|
if (!tables['loca']) {
|
1750
2160
|
throw new _util.FormatError('Required "loca" table is not found');
|
1751
2161
|
}
|
2162
|
+
|
1752
2163
|
if (!tables['glyf']) {
|
1753
2164
|
(0, _util.warn)('Required "glyf" table is not found -- trying to recover.');
|
1754
2165
|
tables['glyf'] = {
|
@@ -1756,63 +2167,83 @@ var Font = function FontClosure() {
|
|
1756
2167
|
data: new Uint8Array(0)
|
1757
2168
|
};
|
1758
2169
|
}
|
2170
|
+
|
1759
2171
|
this.isOpenType = false;
|
1760
2172
|
}
|
2173
|
+
|
1761
2174
|
if (!tables['maxp']) {
|
1762
2175
|
throw new _util.FormatError('Required "maxp" table is not found');
|
1763
2176
|
}
|
2177
|
+
|
1764
2178
|
font.pos = (font.start || 0) + tables['maxp'].offset;
|
1765
2179
|
var version = font.getInt32();
|
1766
2180
|
var numGlyphs = font.getUint16();
|
2181
|
+
var numGlyphsOut = numGlyphs + 1;
|
2182
|
+
var dupFirstEntry = true;
|
2183
|
+
|
2184
|
+
if (numGlyphsOut > 0xFFFF) {
|
2185
|
+
dupFirstEntry = false;
|
2186
|
+
numGlyphsOut = numGlyphs;
|
2187
|
+
(0, _util.warn)('Not enough space in glyfs to duplicate first glyph.');
|
2188
|
+
}
|
2189
|
+
|
1767
2190
|
var maxFunctionDefs = 0;
|
1768
2191
|
var maxSizeOfInstructions = 0;
|
2192
|
+
|
1769
2193
|
if (version >= 0x00010000 && tables['maxp'].length >= 22) {
|
1770
2194
|
font.pos += 8;
|
1771
2195
|
var maxZones = font.getUint16();
|
2196
|
+
|
1772
2197
|
if (maxZones > 2) {
|
1773
2198
|
tables['maxp'].data[14] = 0;
|
1774
2199
|
tables['maxp'].data[15] = 2;
|
1775
2200
|
}
|
2201
|
+
|
1776
2202
|
font.pos += 4;
|
1777
2203
|
maxFunctionDefs = font.getUint16();
|
1778
2204
|
font.pos += 4;
|
1779
2205
|
maxSizeOfInstructions = font.getUint16();
|
1780
2206
|
}
|
1781
|
-
|
1782
|
-
|
1783
|
-
|
1784
|
-
numGlyphs++;
|
1785
|
-
tables['maxp'].data[4] = numGlyphs >> 8;
|
1786
|
-
tables['maxp'].data[5] = numGlyphs & 255;
|
1787
|
-
}
|
2207
|
+
|
2208
|
+
tables['maxp'].data[4] = numGlyphsOut >> 8;
|
2209
|
+
tables['maxp'].data[5] = numGlyphsOut & 255;
|
1788
2210
|
var hintsValid = sanitizeTTPrograms(tables['fpgm'], tables['prep'], tables['cvt '], maxFunctionDefs);
|
2211
|
+
|
1789
2212
|
if (!hintsValid) {
|
1790
2213
|
delete tables['fpgm'];
|
1791
2214
|
delete tables['prep'];
|
1792
2215
|
delete tables['cvt '];
|
1793
2216
|
}
|
1794
|
-
|
2217
|
+
|
2218
|
+
sanitizeMetrics(font, tables['hhea'], tables['hmtx'], numGlyphsOut);
|
2219
|
+
|
1795
2220
|
if (!tables['head']) {
|
1796
2221
|
throw new _util.FormatError('Required "head" table is not found');
|
1797
2222
|
}
|
2223
|
+
|
1798
2224
|
sanitizeHead(tables['head'], numGlyphs, isTrueType ? tables['loca'].length : 0);
|
1799
2225
|
var missingGlyphs = Object.create(null);
|
2226
|
+
|
1800
2227
|
if (isTrueType) {
|
1801
2228
|
var isGlyphLocationsLong = int16(tables['head'].data[50], tables['head'].data[51]);
|
1802
2229
|
var glyphsInfo = sanitizeGlyphLocations(tables['loca'], tables['glyf'], numGlyphs, isGlyphLocationsLong, hintsValid, dupFirstEntry, maxSizeOfInstructions);
|
1803
2230
|
missingGlyphs = glyphsInfo.missingGlyphs;
|
2231
|
+
|
1804
2232
|
if (version >= 0x00010000 && tables['maxp'].length >= 22) {
|
1805
2233
|
tables['maxp'].data[26] = glyphsInfo.maxSizeOfInstructions >> 8;
|
1806
2234
|
tables['maxp'].data[27] = glyphsInfo.maxSizeOfInstructions & 255;
|
1807
2235
|
}
|
1808
2236
|
}
|
2237
|
+
|
1809
2238
|
if (!tables['hhea']) {
|
1810
2239
|
throw new _util.FormatError('Required "hhea" table is not found');
|
1811
2240
|
}
|
2241
|
+
|
1812
2242
|
if (tables['hhea'].data[10] === 0 && tables['hhea'].data[11] === 0) {
|
1813
2243
|
tables['hhea'].data[10] = 0xFF;
|
1814
2244
|
tables['hhea'].data[11] = 0xFF;
|
1815
2245
|
}
|
2246
|
+
|
1816
2247
|
var metricsOverride = {
|
1817
2248
|
unitsPerEm: int16(tables['head'].data[18], tables['head'].data[19]),
|
1818
2249
|
yMax: int16(tables['head'].data[42], tables['head'].data[43]),
|
@@ -1822,17 +2253,22 @@ var Font = function FontClosure() {
|
|
1822
2253
|
};
|
1823
2254
|
this.ascent = metricsOverride.ascent / metricsOverride.unitsPerEm;
|
1824
2255
|
this.descent = metricsOverride.descent / metricsOverride.unitsPerEm;
|
2256
|
+
|
1825
2257
|
if (tables['post']) {
|
1826
|
-
|
1827
|
-
if (!valid) {
|
1828
|
-
tables['post'] = null;
|
1829
|
-
}
|
2258
|
+
readPostScriptTable(tables['post'], properties, numGlyphs);
|
1830
2259
|
}
|
2260
|
+
|
2261
|
+
tables['post'] = {
|
2262
|
+
tag: 'post',
|
2263
|
+
data: createPostTable(properties)
|
2264
|
+
};
|
1831
2265
|
var charCodeToGlyphId = [],
|
1832
2266
|
charCode;
|
2267
|
+
|
1833
2268
|
function hasGlyph(glyphId) {
|
1834
2269
|
return !missingGlyphs[glyphId];
|
1835
2270
|
}
|
2271
|
+
|
1836
2272
|
if (properties.composite) {
|
1837
2273
|
var cidToGidMap = properties.cidToGidMap || [];
|
1838
2274
|
var isCidToGidMapEmpty = cidToGidMap.length === 0;
|
@@ -1840,33 +2276,38 @@ var Font = function FontClosure() {
|
|
1840
2276
|
if (cid > 0xffff) {
|
1841
2277
|
throw new _util.FormatError('Max size of CID is 65,535');
|
1842
2278
|
}
|
2279
|
+
|
1843
2280
|
var glyphId = -1;
|
2281
|
+
|
1844
2282
|
if (isCidToGidMapEmpty) {
|
1845
2283
|
glyphId = cid;
|
1846
2284
|
} else if (cidToGidMap[cid] !== undefined) {
|
1847
2285
|
glyphId = cidToGidMap[cid];
|
1848
2286
|
}
|
2287
|
+
|
1849
2288
|
if (glyphId >= 0 && glyphId < numGlyphs && hasGlyph(glyphId)) {
|
1850
2289
|
charCodeToGlyphId[charCode] = glyphId;
|
1851
2290
|
}
|
1852
2291
|
});
|
1853
|
-
if (dupFirstEntry && (isCidToGidMapEmpty || !charCodeToGlyphId[0])) {
|
1854
|
-
charCodeToGlyphId[0] = numGlyphs - 1;
|
1855
|
-
}
|
1856
2292
|
} else {
|
1857
2293
|
var cmapTable = readCmapTable(tables['cmap'], font, this.isSymbolicFont, properties.hasEncoding);
|
1858
2294
|
var cmapPlatformId = cmapTable.platformId;
|
1859
2295
|
var cmapEncodingId = cmapTable.encodingId;
|
1860
2296
|
var cmapMappings = cmapTable.mappings;
|
1861
2297
|
var cmapMappingsLength = cmapMappings.length;
|
2298
|
+
|
1862
2299
|
if (properties.hasEncoding && (cmapPlatformId === 3 && cmapEncodingId === 1 || cmapPlatformId === 1 && cmapEncodingId === 0) || cmapPlatformId === -1 && cmapEncodingId === -1 && !!(0, _encodings.getEncoding)(properties.baseEncodingName)) {
|
1863
2300
|
var baseEncoding = [];
|
2301
|
+
|
1864
2302
|
if (properties.baseEncodingName === 'MacRomanEncoding' || properties.baseEncodingName === 'WinAnsiEncoding') {
|
1865
2303
|
baseEncoding = (0, _encodings.getEncoding)(properties.baseEncodingName);
|
1866
2304
|
}
|
2305
|
+
|
1867
2306
|
var glyphsUnicodeMap = (0, _glyphlist.getGlyphsUnicode)();
|
2307
|
+
|
1868
2308
|
for (charCode = 0; charCode < 256; charCode++) {
|
1869
2309
|
var glyphName, standardGlyphName;
|
2310
|
+
|
1870
2311
|
if (this.differences && charCode in this.differences) {
|
1871
2312
|
glyphName = this.differences[charCode];
|
1872
2313
|
} else if (charCode in baseEncoding && baseEncoding[charCode] !== '') {
|
@@ -1874,81 +2315,98 @@ var Font = function FontClosure() {
|
|
1874
2315
|
} else {
|
1875
2316
|
glyphName = _encodings.StandardEncoding[charCode];
|
1876
2317
|
}
|
2318
|
+
|
1877
2319
|
if (!glyphName) {
|
1878
2320
|
continue;
|
1879
2321
|
}
|
2322
|
+
|
1880
2323
|
standardGlyphName = recoverGlyphName(glyphName, glyphsUnicodeMap);
|
1881
2324
|
var unicodeOrCharCode;
|
2325
|
+
|
1882
2326
|
if (cmapPlatformId === 3 && cmapEncodingId === 1) {
|
1883
2327
|
unicodeOrCharCode = glyphsUnicodeMap[standardGlyphName];
|
1884
2328
|
} else if (cmapPlatformId === 1 && cmapEncodingId === 0) {
|
1885
2329
|
unicodeOrCharCode = _encodings.MacRomanEncoding.indexOf(standardGlyphName);
|
1886
2330
|
}
|
2331
|
+
|
1887
2332
|
var found = false;
|
2333
|
+
|
1888
2334
|
for (var i = 0; i < cmapMappingsLength; ++i) {
|
1889
2335
|
if (cmapMappings[i].charCode !== unicodeOrCharCode) {
|
1890
2336
|
continue;
|
1891
2337
|
}
|
2338
|
+
|
1892
2339
|
charCodeToGlyphId[charCode] = cmapMappings[i].glyphId;
|
1893
2340
|
found = true;
|
1894
2341
|
break;
|
1895
2342
|
}
|
2343
|
+
|
1896
2344
|
if (!found && properties.glyphNames) {
|
1897
2345
|
var glyphId = properties.glyphNames.indexOf(glyphName);
|
2346
|
+
|
1898
2347
|
if (glyphId === -1 && standardGlyphName !== glyphName) {
|
1899
2348
|
glyphId = properties.glyphNames.indexOf(standardGlyphName);
|
1900
2349
|
}
|
2350
|
+
|
1901
2351
|
if (glyphId > 0 && hasGlyph(glyphId)) {
|
1902
2352
|
charCodeToGlyphId[charCode] = glyphId;
|
1903
2353
|
}
|
1904
2354
|
}
|
1905
2355
|
}
|
1906
2356
|
} else if (cmapPlatformId === 0 && cmapEncodingId === 0) {
|
1907
|
-
for (var
|
1908
|
-
charCodeToGlyphId[cmapMappings[
|
2357
|
+
for (var _i2 = 0; _i2 < cmapMappingsLength; ++_i2) {
|
2358
|
+
charCodeToGlyphId[cmapMappings[_i2].charCode] = cmapMappings[_i2].glyphId;
|
1909
2359
|
}
|
1910
2360
|
} else {
|
1911
|
-
for (var
|
1912
|
-
charCode = cmapMappings[
|
2361
|
+
for (var _i3 = 0; _i3 < cmapMappingsLength; ++_i3) {
|
2362
|
+
charCode = cmapMappings[_i3].charCode;
|
2363
|
+
|
1913
2364
|
if (cmapPlatformId === 3 && charCode >= 0xF000 && charCode <= 0xF0FF) {
|
1914
2365
|
charCode &= 0xFF;
|
1915
2366
|
}
|
1916
|
-
|
2367
|
+
|
2368
|
+
charCodeToGlyphId[charCode] = cmapMappings[_i3].glyphId;
|
1917
2369
|
}
|
1918
2370
|
}
|
1919
2371
|
}
|
2372
|
+
|
1920
2373
|
if (charCodeToGlyphId.length === 0) {
|
1921
2374
|
charCodeToGlyphId[0] = 0;
|
1922
2375
|
}
|
1923
|
-
|
2376
|
+
|
2377
|
+
var glyphZeroId = numGlyphsOut - 1;
|
2378
|
+
|
2379
|
+
if (!dupFirstEntry) {
|
2380
|
+
glyphZeroId = 0;
|
2381
|
+
}
|
2382
|
+
|
2383
|
+
var newMapping = adjustMapping(charCodeToGlyphId, hasGlyph, glyphZeroId);
|
1924
2384
|
this.toFontChar = newMapping.toFontChar;
|
1925
2385
|
tables['cmap'] = {
|
1926
2386
|
tag: 'cmap',
|
1927
|
-
data: createCmapTable(newMapping.charCodeToGlyphId,
|
2387
|
+
data: createCmapTable(newMapping.charCodeToGlyphId, numGlyphsOut)
|
1928
2388
|
};
|
2389
|
+
|
1929
2390
|
if (!tables['OS/2'] || !validateOS2Table(tables['OS/2'])) {
|
1930
2391
|
tables['OS/2'] = {
|
1931
2392
|
tag: 'OS/2',
|
1932
2393
|
data: createOS2Table(properties, newMapping.charCodeToGlyphId, metricsOverride)
|
1933
2394
|
};
|
1934
2395
|
}
|
1935
|
-
|
1936
|
-
tables['post'] = {
|
1937
|
-
tag: 'post',
|
1938
|
-
data: createPostTable(properties)
|
1939
|
-
};
|
1940
|
-
}
|
2396
|
+
|
1941
2397
|
if (!isTrueType) {
|
1942
2398
|
try {
|
1943
2399
|
cffFile = new _stream.Stream(tables['CFF '].data);
|
1944
2400
|
var parser = new _cff_parser.CFFParser(cffFile, properties, SEAC_ANALYSIS_ENABLED);
|
1945
2401
|
cff = parser.parse();
|
2402
|
+
cff.duplicateFirstGlyph();
|
1946
2403
|
var compiler = new _cff_parser.CFFCompiler(cff);
|
1947
2404
|
tables['CFF '].data = compiler.compile();
|
1948
2405
|
} catch (e) {
|
1949
2406
|
(0, _util.warn)('Failed to compile font ' + properties.loadedName);
|
1950
2407
|
}
|
1951
2408
|
}
|
2409
|
+
|
1952
2410
|
if (!tables['name']) {
|
1953
2411
|
tables['name'] = {
|
1954
2412
|
tag: 'name',
|
@@ -1958,47 +2416,67 @@ var Font = function FontClosure() {
|
|
1958
2416
|
var namePrototype = readNameTable(tables['name']);
|
1959
2417
|
tables['name'].data = createNameTable(name, namePrototype);
|
1960
2418
|
}
|
2419
|
+
|
1961
2420
|
var builder = new OpenTypeFileBuilder(header.version);
|
2421
|
+
|
1962
2422
|
for (var tableTag in tables) {
|
1963
2423
|
builder.addTable(tableTag, tables[tableTag].data);
|
1964
2424
|
}
|
2425
|
+
|
1965
2426
|
return builder.toArray();
|
1966
2427
|
},
|
1967
2428
|
convert: function Font_convert(fontName, font, properties) {
|
1968
2429
|
properties.fixedPitch = false;
|
2430
|
+
|
1969
2431
|
if (properties.builtInEncoding) {
|
1970
2432
|
adjustToUnicode(properties, properties.builtInEncoding);
|
1971
2433
|
}
|
2434
|
+
|
2435
|
+
var glyphZeroId = 1;
|
2436
|
+
|
2437
|
+
if (font instanceof CFFFont) {
|
2438
|
+
glyphZeroId = font.numGlyphs - 1;
|
2439
|
+
}
|
2440
|
+
|
1972
2441
|
var mapping = font.getGlyphMapping(properties);
|
1973
|
-
var newMapping = adjustMapping(mapping,
|
2442
|
+
var newMapping = adjustMapping(mapping, font.hasGlyphId.bind(font), glyphZeroId);
|
1974
2443
|
this.toFontChar = newMapping.toFontChar;
|
1975
2444
|
var numGlyphs = font.numGlyphs;
|
2445
|
+
|
1976
2446
|
function getCharCodes(charCodeToGlyphId, glyphId) {
|
1977
2447
|
var charCodes = null;
|
2448
|
+
|
1978
2449
|
for (var charCode in charCodeToGlyphId) {
|
1979
2450
|
if (glyphId === charCodeToGlyphId[charCode]) {
|
1980
2451
|
if (!charCodes) {
|
1981
2452
|
charCodes = [];
|
1982
2453
|
}
|
2454
|
+
|
1983
2455
|
charCodes.push(charCode | 0);
|
1984
2456
|
}
|
1985
2457
|
}
|
2458
|
+
|
1986
2459
|
return charCodes;
|
1987
2460
|
}
|
2461
|
+
|
1988
2462
|
function createCharCode(charCodeToGlyphId, glyphId) {
|
1989
2463
|
for (var charCode in charCodeToGlyphId) {
|
1990
2464
|
if (glyphId === charCodeToGlyphId[charCode]) {
|
1991
2465
|
return charCode | 0;
|
1992
2466
|
}
|
1993
2467
|
}
|
2468
|
+
|
1994
2469
|
newMapping.charCodeToGlyphId[newMapping.nextAvailableFontCharCode] = glyphId;
|
1995
2470
|
return newMapping.nextAvailableFontCharCode++;
|
1996
2471
|
}
|
2472
|
+
|
1997
2473
|
var seacs = font.seacs;
|
2474
|
+
|
1998
2475
|
if (SEAC_ANALYSIS_ENABLED && seacs && seacs.length) {
|
1999
2476
|
var matrix = properties.fontMatrix || _util.FONT_IDENTITY_MATRIX;
|
2000
2477
|
var charset = font.getCharset();
|
2001
2478
|
var seacMap = Object.create(null);
|
2479
|
+
|
2002
2480
|
for (var glyphId in seacs) {
|
2003
2481
|
glyphId |= 0;
|
2004
2482
|
var seac = seacs[glyphId];
|
@@ -2006,17 +2484,21 @@ var Font = function FontClosure() {
|
|
2006
2484
|
var accentGlyphName = _encodings.StandardEncoding[seac[3]];
|
2007
2485
|
var baseGlyphId = charset.indexOf(baseGlyphName);
|
2008
2486
|
var accentGlyphId = charset.indexOf(accentGlyphName);
|
2487
|
+
|
2009
2488
|
if (baseGlyphId < 0 || accentGlyphId < 0) {
|
2010
2489
|
continue;
|
2011
2490
|
}
|
2491
|
+
|
2012
2492
|
var accentOffset = {
|
2013
2493
|
x: seac[0] * matrix[0] + seac[1] * matrix[2] + matrix[4],
|
2014
2494
|
y: seac[0] * matrix[1] + seac[1] * matrix[3] + matrix[5]
|
2015
2495
|
};
|
2016
2496
|
var charCodes = getCharCodes(mapping, glyphId);
|
2497
|
+
|
2017
2498
|
if (!charCodes) {
|
2018
2499
|
continue;
|
2019
2500
|
}
|
2501
|
+
|
2020
2502
|
for (var i = 0, ii = charCodes.length; i < ii; i++) {
|
2021
2503
|
var charCode = charCodes[i];
|
2022
2504
|
var charCodeToGlyphId = newMapping.charCodeToGlyphId;
|
@@ -2029,8 +2511,10 @@ var Font = function FontClosure() {
|
|
2029
2511
|
};
|
2030
2512
|
}
|
2031
2513
|
}
|
2514
|
+
|
2032
2515
|
properties.seacMap = seacMap;
|
2033
2516
|
}
|
2517
|
+
|
2034
2518
|
var unitsPerEm = 1 / (properties.fontMatrix || _util.FONT_IDENTITY_MATRIX)[0];
|
2035
2519
|
var builder = new OpenTypeFileBuilder('\x4F\x54\x54\x4F');
|
2036
2520
|
builder.addTable('CFF ', font.data);
|
@@ -2042,16 +2526,20 @@ var Font = function FontClosure() {
|
|
2042
2526
|
var charstrings = font.charstrings;
|
2043
2527
|
var cffWidths = font.cff ? font.cff.widths : null;
|
2044
2528
|
var hmtx = '\x00\x00\x00\x00';
|
2529
|
+
|
2045
2530
|
for (var i = 1, ii = numGlyphs; i < ii; i++) {
|
2046
2531
|
var width = 0;
|
2532
|
+
|
2047
2533
|
if (charstrings) {
|
2048
2534
|
var charstring = charstrings[i - 1];
|
2049
2535
|
width = 'width' in charstring ? charstring.width : 0;
|
2050
2536
|
} else if (cffWidths) {
|
2051
2537
|
width = Math.ceil(cffWidths[i] || 0);
|
2052
2538
|
}
|
2539
|
+
|
2053
2540
|
hmtx += string16(width) + string16(0);
|
2054
2541
|
}
|
2542
|
+
|
2055
2543
|
return hmtx;
|
2056
2544
|
}());
|
2057
2545
|
builder.addTable('maxp', '\x00\x00\x50\x00' + string16(numGlyphs));
|
@@ -2059,98 +2547,127 @@ var Font = function FontClosure() {
|
|
2059
2547
|
builder.addTable('post', createPostTable(properties));
|
2060
2548
|
return builder.toArray();
|
2061
2549
|
},
|
2550
|
+
|
2062
2551
|
get spaceWidth() {
|
2063
2552
|
if ('_shadowWidth' in this) {
|
2064
2553
|
return this._shadowWidth;
|
2065
2554
|
}
|
2555
|
+
|
2066
2556
|
var possibleSpaceReplacements = ['space', 'minus', 'one', 'i', 'I'];
|
2067
2557
|
var width;
|
2558
|
+
|
2068
2559
|
for (var i = 0, ii = possibleSpaceReplacements.length; i < ii; i++) {
|
2069
2560
|
var glyphName = possibleSpaceReplacements[i];
|
2561
|
+
|
2070
2562
|
if (glyphName in this.widths) {
|
2071
2563
|
width = this.widths[glyphName];
|
2072
2564
|
break;
|
2073
2565
|
}
|
2566
|
+
|
2074
2567
|
var glyphsUnicodeMap = (0, _glyphlist.getGlyphsUnicode)();
|
2075
2568
|
var glyphUnicode = glyphsUnicodeMap[glyphName];
|
2076
2569
|
var charcode = 0;
|
2570
|
+
|
2077
2571
|
if (this.composite) {
|
2078
2572
|
if (this.cMap.contains(glyphUnicode)) {
|
2079
2573
|
charcode = this.cMap.lookup(glyphUnicode);
|
2080
2574
|
}
|
2081
2575
|
}
|
2576
|
+
|
2082
2577
|
if (!charcode && this.toUnicode) {
|
2083
2578
|
charcode = this.toUnicode.charCodeOf(glyphUnicode);
|
2084
2579
|
}
|
2580
|
+
|
2085
2581
|
if (charcode <= 0) {
|
2086
2582
|
charcode = glyphUnicode;
|
2087
2583
|
}
|
2584
|
+
|
2088
2585
|
width = this.widths[charcode];
|
2586
|
+
|
2089
2587
|
if (width) {
|
2090
2588
|
break;
|
2091
2589
|
}
|
2092
2590
|
}
|
2591
|
+
|
2093
2592
|
width = width || this.defaultWidth;
|
2094
2593
|
this._shadowWidth = width;
|
2095
2594
|
return width;
|
2096
2595
|
},
|
2596
|
+
|
2097
2597
|
charToGlyph: function Font_charToGlyph(charcode, isSpace) {
|
2098
2598
|
var fontCharCode, width, operatorListId;
|
2099
2599
|
var widthCode = charcode;
|
2600
|
+
|
2100
2601
|
if (this.cMap && this.cMap.contains(charcode)) {
|
2101
2602
|
widthCode = this.cMap.lookup(charcode);
|
2102
2603
|
}
|
2604
|
+
|
2103
2605
|
width = this.widths[widthCode];
|
2104
2606
|
width = (0, _util.isNum)(width) ? width : this.defaultWidth;
|
2105
2607
|
var vmetric = this.vmetrics && this.vmetrics[widthCode];
|
2106
2608
|
var unicode = this.toUnicode.get(charcode) || this.fallbackToUnicode.get(charcode) || charcode;
|
2609
|
+
|
2107
2610
|
if (typeof unicode === 'number') {
|
2108
2611
|
unicode = String.fromCharCode(unicode);
|
2109
2612
|
}
|
2613
|
+
|
2110
2614
|
var isInFont = charcode in this.toFontChar;
|
2111
2615
|
fontCharCode = this.toFontChar[charcode] || charcode;
|
2616
|
+
|
2112
2617
|
if (this.missingFile) {
|
2113
2618
|
fontCharCode = (0, _unicode.mapSpecialUnicodeValues)(fontCharCode);
|
2114
2619
|
}
|
2620
|
+
|
2115
2621
|
if (this.isType3Font) {
|
2116
2622
|
operatorListId = fontCharCode;
|
2117
2623
|
}
|
2624
|
+
|
2118
2625
|
var accent = null;
|
2626
|
+
|
2119
2627
|
if (this.seacMap && this.seacMap[charcode]) {
|
2120
2628
|
isInFont = true;
|
2121
2629
|
var seac = this.seacMap[charcode];
|
2122
2630
|
fontCharCode = seac.baseFontCharCode;
|
2123
2631
|
accent = {
|
2124
|
-
fontChar: String.
|
2632
|
+
fontChar: String.fromCodePoint(seac.accentFontCharCode),
|
2125
2633
|
offset: seac.accentOffset
|
2126
2634
|
};
|
2127
2635
|
}
|
2128
|
-
|
2636
|
+
|
2637
|
+
var fontChar = typeof fontCharCode === 'number' ? String.fromCodePoint(fontCharCode) : '';
|
2129
2638
|
var glyph = this.glyphCache[charcode];
|
2639
|
+
|
2130
2640
|
if (!glyph || !glyph.matchesForCache(fontChar, unicode, accent, width, vmetric, operatorListId, isSpace, isInFont)) {
|
2131
2641
|
glyph = new Glyph(fontChar, unicode, accent, width, vmetric, operatorListId, isSpace, isInFont);
|
2132
2642
|
this.glyphCache[charcode] = glyph;
|
2133
2643
|
}
|
2644
|
+
|
2134
2645
|
return glyph;
|
2135
2646
|
},
|
2136
2647
|
charsToGlyphs: function Font_charsToGlyphs(chars) {
|
2137
2648
|
var charsCache = this.charsCache;
|
2138
2649
|
var glyphs, glyph, charcode;
|
2650
|
+
|
2139
2651
|
if (charsCache) {
|
2140
2652
|
glyphs = charsCache[chars];
|
2653
|
+
|
2141
2654
|
if (glyphs) {
|
2142
2655
|
return glyphs;
|
2143
2656
|
}
|
2144
2657
|
}
|
2658
|
+
|
2145
2659
|
if (!charsCache) {
|
2146
2660
|
charsCache = this.charsCache = Object.create(null);
|
2147
2661
|
}
|
2662
|
+
|
2148
2663
|
glyphs = [];
|
2149
2664
|
var charsCacheKey = chars;
|
2150
2665
|
var i = 0,
|
2151
2666
|
ii;
|
2667
|
+
|
2152
2668
|
if (this.cMap) {
|
2153
2669
|
var c = Object.create(null);
|
2670
|
+
|
2154
2671
|
while (i < chars.length) {
|
2155
2672
|
this.cMap.readCharCode(chars, i, c);
|
2156
2673
|
charcode = c.charcode;
|
@@ -2167,35 +2684,53 @@ var Font = function FontClosure() {
|
|
2167
2684
|
glyphs.push(glyph);
|
2168
2685
|
}
|
2169
2686
|
}
|
2687
|
+
|
2170
2688
|
return charsCache[charsCacheKey] = glyphs;
|
2689
|
+
},
|
2690
|
+
|
2691
|
+
get glyphCacheValues() {
|
2692
|
+
return Object.values(this.glyphCache);
|
2171
2693
|
}
|
2694
|
+
|
2172
2695
|
};
|
2173
2696
|
return Font;
|
2174
2697
|
}();
|
2698
|
+
|
2699
|
+
exports.Font = Font;
|
2700
|
+
|
2175
2701
|
var ErrorFont = function ErrorFontClosure() {
|
2176
2702
|
function ErrorFont(error) {
|
2177
2703
|
this.error = error;
|
2178
2704
|
this.loadedName = 'g_font_error';
|
2179
|
-
this.
|
2705
|
+
this.missingFile = true;
|
2180
2706
|
}
|
2707
|
+
|
2181
2708
|
ErrorFont.prototype = {
|
2182
2709
|
charsToGlyphs: function ErrorFont_charsToGlyphs() {
|
2183
2710
|
return [];
|
2184
2711
|
},
|
2185
2712
|
exportData: function ErrorFont_exportData() {
|
2186
|
-
return {
|
2713
|
+
return {
|
2714
|
+
error: this.error
|
2715
|
+
};
|
2187
2716
|
}
|
2188
2717
|
};
|
2189
2718
|
return ErrorFont;
|
2190
2719
|
}();
|
2720
|
+
|
2721
|
+
exports.ErrorFont = ErrorFont;
|
2722
|
+
|
2191
2723
|
function type1FontGlyphMapping(properties, builtInEncoding, glyphNames) {
|
2192
2724
|
var charCodeToGlyphId = Object.create(null);
|
2193
2725
|
var glyphId, charCode, baseEncoding;
|
2194
2726
|
var isSymbolicFont = !!(properties.flags & FontFlags.Symbolic);
|
2727
|
+
|
2195
2728
|
if (properties.baseEncodingName) {
|
2196
2729
|
baseEncoding = (0, _encodings.getEncoding)(properties.baseEncodingName);
|
2730
|
+
|
2197
2731
|
for (charCode = 0; charCode < baseEncoding.length; charCode++) {
|
2198
2732
|
glyphId = glyphNames.indexOf(baseEncoding[charCode]);
|
2733
|
+
|
2199
2734
|
if (glyphId >= 0) {
|
2200
2735
|
charCodeToGlyphId[charCode] = glyphId;
|
2201
2736
|
} else {
|
@@ -2208,8 +2743,10 @@ function type1FontGlyphMapping(properties, builtInEncoding, glyphNames) {
|
|
2208
2743
|
}
|
2209
2744
|
} else {
|
2210
2745
|
baseEncoding = _encodings.StandardEncoding;
|
2746
|
+
|
2211
2747
|
for (charCode = 0; charCode < baseEncoding.length; charCode++) {
|
2212
2748
|
glyphId = glyphNames.indexOf(baseEncoding[charCode]);
|
2749
|
+
|
2213
2750
|
if (glyphId >= 0) {
|
2214
2751
|
charCodeToGlyphId[charCode] = glyphId;
|
2215
2752
|
} else {
|
@@ -2217,21 +2754,27 @@ function type1FontGlyphMapping(properties, builtInEncoding, glyphNames) {
|
|
2217
2754
|
}
|
2218
2755
|
}
|
2219
2756
|
}
|
2757
|
+
|
2220
2758
|
var differences = properties.differences,
|
2221
2759
|
glyphsUnicodeMap;
|
2760
|
+
|
2222
2761
|
if (differences) {
|
2223
2762
|
for (charCode in differences) {
|
2224
2763
|
var glyphName = differences[charCode];
|
2225
2764
|
glyphId = glyphNames.indexOf(glyphName);
|
2765
|
+
|
2226
2766
|
if (glyphId === -1) {
|
2227
2767
|
if (!glyphsUnicodeMap) {
|
2228
2768
|
glyphsUnicodeMap = (0, _glyphlist.getGlyphsUnicode)();
|
2229
2769
|
}
|
2770
|
+
|
2230
2771
|
var standardGlyphName = recoverGlyphName(glyphName, glyphsUnicodeMap);
|
2772
|
+
|
2231
2773
|
if (standardGlyphName !== glyphName) {
|
2232
2774
|
glyphId = glyphNames.indexOf(standardGlyphName);
|
2233
2775
|
}
|
2234
2776
|
}
|
2777
|
+
|
2235
2778
|
if (glyphId >= 0) {
|
2236
2779
|
charCodeToGlyphId[charCode] = glyphId;
|
2237
2780
|
} else {
|
@@ -2239,8 +2782,10 @@ function type1FontGlyphMapping(properties, builtInEncoding, glyphNames) {
|
|
2239
2782
|
}
|
2240
2783
|
}
|
2241
2784
|
}
|
2785
|
+
|
2242
2786
|
return charCodeToGlyphId;
|
2243
2787
|
}
|
2788
|
+
|
2244
2789
|
var Type1Font = function Type1FontClosure() {
|
2245
2790
|
function findBlock(streamBytes, signature, startIndex) {
|
2246
2791
|
var streamBytesLength = streamBytes.length;
|
@@ -2249,30 +2794,39 @@ var Type1Font = function Type1FontClosure() {
|
|
2249
2794
|
var i = startIndex,
|
2250
2795
|
j,
|
2251
2796
|
found = false;
|
2797
|
+
|
2252
2798
|
while (i < scanLength) {
|
2253
2799
|
j = 0;
|
2800
|
+
|
2254
2801
|
while (j < signatureLength && streamBytes[i + j] === signature[j]) {
|
2255
2802
|
j++;
|
2256
2803
|
}
|
2804
|
+
|
2257
2805
|
if (j >= signatureLength) {
|
2258
2806
|
i += j;
|
2807
|
+
|
2259
2808
|
while (i < streamBytesLength && (0, _util.isSpace)(streamBytes[i])) {
|
2260
2809
|
i++;
|
2261
2810
|
}
|
2811
|
+
|
2262
2812
|
found = true;
|
2263
2813
|
break;
|
2264
2814
|
}
|
2815
|
+
|
2265
2816
|
i++;
|
2266
2817
|
}
|
2818
|
+
|
2267
2819
|
return {
|
2268
2820
|
found: found,
|
2269
2821
|
length: i
|
2270
2822
|
};
|
2271
2823
|
}
|
2824
|
+
|
2272
2825
|
function getHeaderBlock(stream, suggestedLength) {
|
2273
2826
|
var EEXEC_SIGNATURE = [0x65, 0x65, 0x78, 0x65, 0x63];
|
2274
2827
|
var streamStartPos = stream.pos;
|
2275
2828
|
var headerBytes, headerBytesLength, block;
|
2829
|
+
|
2276
2830
|
try {
|
2277
2831
|
headerBytes = stream.getBytes(suggestedLength);
|
2278
2832
|
headerBytesLength = headerBytes.length;
|
@@ -2281,8 +2835,10 @@ var Type1Font = function Type1FontClosure() {
|
|
2281
2835
|
throw ex;
|
2282
2836
|
}
|
2283
2837
|
}
|
2838
|
+
|
2284
2839
|
if (headerBytesLength === suggestedLength) {
|
2285
2840
|
block = findBlock(headerBytes, EEXEC_SIGNATURE, suggestedLength - 2 * EEXEC_SIGNATURE.length);
|
2841
|
+
|
2286
2842
|
if (block.found && block.length === suggestedLength) {
|
2287
2843
|
return {
|
2288
2844
|
stream: new _stream.Stream(headerBytes),
|
@@ -2290,35 +2846,44 @@ var Type1Font = function Type1FontClosure() {
|
|
2290
2846
|
};
|
2291
2847
|
}
|
2292
2848
|
}
|
2849
|
+
|
2293
2850
|
(0, _util.warn)('Invalid "Length1" property in Type1 font -- trying to recover.');
|
2294
2851
|
stream.pos = streamStartPos;
|
2295
2852
|
var SCAN_BLOCK_LENGTH = 2048;
|
2296
2853
|
var actualLength;
|
2854
|
+
|
2297
2855
|
while (true) {
|
2298
2856
|
var scanBytes = stream.peekBytes(SCAN_BLOCK_LENGTH);
|
2299
2857
|
block = findBlock(scanBytes, EEXEC_SIGNATURE, 0);
|
2858
|
+
|
2300
2859
|
if (block.length === 0) {
|
2301
2860
|
break;
|
2302
2861
|
}
|
2862
|
+
|
2303
2863
|
stream.pos += block.length;
|
2864
|
+
|
2304
2865
|
if (block.found) {
|
2305
2866
|
actualLength = stream.pos - streamStartPos;
|
2306
2867
|
break;
|
2307
2868
|
}
|
2308
2869
|
}
|
2870
|
+
|
2309
2871
|
stream.pos = streamStartPos;
|
2872
|
+
|
2310
2873
|
if (actualLength) {
|
2311
2874
|
return {
|
2312
2875
|
stream: new _stream.Stream(stream.getBytes(actualLength)),
|
2313
2876
|
length: actualLength
|
2314
2877
|
};
|
2315
2878
|
}
|
2879
|
+
|
2316
2880
|
(0, _util.warn)('Unable to recover "Length1" property in Type1 font -- using as is.');
|
2317
2881
|
return {
|
2318
2882
|
stream: new _stream.Stream(stream.getBytes(suggestedLength)),
|
2319
2883
|
length: suggestedLength
|
2320
2884
|
};
|
2321
2885
|
}
|
2886
|
+
|
2322
2887
|
function getEexecBlock(stream, suggestedLength) {
|
2323
2888
|
var eexecBytes = stream.getBytes();
|
2324
2889
|
return {
|
@@ -2326,29 +2891,36 @@ var Type1Font = function Type1FontClosure() {
|
|
2326
2891
|
length: eexecBytes.length
|
2327
2892
|
};
|
2328
2893
|
}
|
2894
|
+
|
2329
2895
|
function Type1Font(name, file, properties) {
|
2330
2896
|
var PFB_HEADER_SIZE = 6;
|
2331
2897
|
var headerBlockLength = properties.length1;
|
2332
2898
|
var eexecBlockLength = properties.length2;
|
2333
2899
|
var pfbHeader = file.peekBytes(PFB_HEADER_SIZE);
|
2334
2900
|
var pfbHeaderPresent = pfbHeader[0] === 0x80 && pfbHeader[1] === 0x01;
|
2901
|
+
|
2335
2902
|
if (pfbHeaderPresent) {
|
2336
2903
|
file.skip(PFB_HEADER_SIZE);
|
2337
2904
|
headerBlockLength = pfbHeader[5] << 24 | pfbHeader[4] << 16 | pfbHeader[3] << 8 | pfbHeader[2];
|
2338
2905
|
}
|
2906
|
+
|
2339
2907
|
var headerBlock = getHeaderBlock(file, headerBlockLength);
|
2340
2908
|
var headerBlockParser = new _type1_parser.Type1Parser(headerBlock.stream, false, SEAC_ANALYSIS_ENABLED);
|
2341
2909
|
headerBlockParser.extractFontHeader(properties);
|
2910
|
+
|
2342
2911
|
if (pfbHeaderPresent) {
|
2343
2912
|
pfbHeader = file.getBytes(PFB_HEADER_SIZE);
|
2344
2913
|
eexecBlockLength = pfbHeader[5] << 24 | pfbHeader[4] << 16 | pfbHeader[3] << 8 | pfbHeader[2];
|
2345
2914
|
}
|
2915
|
+
|
2346
2916
|
var eexecBlock = getEexecBlock(file, eexecBlockLength);
|
2347
2917
|
var eexecBlockParser = new _type1_parser.Type1Parser(eexecBlock.stream, true, SEAC_ANALYSIS_ENABLED);
|
2348
2918
|
var data = eexecBlockParser.extractFontProgram();
|
2919
|
+
|
2349
2920
|
for (var info in data.properties) {
|
2350
2921
|
properties[info] = data.properties[info];
|
2351
2922
|
}
|
2923
|
+
|
2352
2924
|
var charstrings = data.charstrings;
|
2353
2925
|
var type2Charstrings = this.getType2Charstrings(charstrings);
|
2354
2926
|
var subrs = this.getType2Subrs(data.subrs);
|
@@ -2356,58 +2928,86 @@ var Type1Font = function Type1FontClosure() {
|
|
2356
2928
|
this.data = this.wrap(name, type2Charstrings, this.charstrings, subrs, properties);
|
2357
2929
|
this.seacs = this.getSeacs(data.charstrings);
|
2358
2930
|
}
|
2931
|
+
|
2359
2932
|
Type1Font.prototype = {
|
2360
2933
|
get numGlyphs() {
|
2361
2934
|
return this.charstrings.length + 1;
|
2362
2935
|
},
|
2936
|
+
|
2363
2937
|
getCharset: function Type1Font_getCharset() {
|
2364
2938
|
var charset = ['.notdef'];
|
2365
2939
|
var charstrings = this.charstrings;
|
2940
|
+
|
2366
2941
|
for (var glyphId = 0; glyphId < charstrings.length; glyphId++) {
|
2367
2942
|
charset.push(charstrings[glyphId].glyphName);
|
2368
2943
|
}
|
2944
|
+
|
2369
2945
|
return charset;
|
2370
2946
|
},
|
2371
2947
|
getGlyphMapping: function Type1Font_getGlyphMapping(properties) {
|
2372
2948
|
var charstrings = this.charstrings;
|
2373
2949
|
var glyphNames = ['.notdef'],
|
2374
2950
|
glyphId;
|
2951
|
+
|
2375
2952
|
for (glyphId = 0; glyphId < charstrings.length; glyphId++) {
|
2376
2953
|
glyphNames.push(charstrings[glyphId].glyphName);
|
2377
2954
|
}
|
2955
|
+
|
2378
2956
|
var encoding = properties.builtInEncoding;
|
2957
|
+
|
2379
2958
|
if (encoding) {
|
2380
2959
|
var builtInEncoding = Object.create(null);
|
2960
|
+
|
2381
2961
|
for (var charCode in encoding) {
|
2382
2962
|
glyphId = glyphNames.indexOf(encoding[charCode]);
|
2963
|
+
|
2383
2964
|
if (glyphId >= 0) {
|
2384
2965
|
builtInEncoding[charCode] = glyphId;
|
2385
2966
|
}
|
2386
2967
|
}
|
2387
2968
|
}
|
2969
|
+
|
2388
2970
|
return type1FontGlyphMapping(properties, builtInEncoding, glyphNames);
|
2389
2971
|
},
|
2972
|
+
hasGlyphId: function Type1Font_hasGlyphID(id) {
|
2973
|
+
if (id < 0 || id >= this.numGlyphs) {
|
2974
|
+
return false;
|
2975
|
+
}
|
2976
|
+
|
2977
|
+
if (id === 0) {
|
2978
|
+
return true;
|
2979
|
+
}
|
2980
|
+
|
2981
|
+
var glyph = this.charstrings[id - 1];
|
2982
|
+
return glyph.charstring.length > 0;
|
2983
|
+
},
|
2390
2984
|
getSeacs: function Type1Font_getSeacs(charstrings) {
|
2391
2985
|
var i, ii;
|
2392
2986
|
var seacMap = [];
|
2987
|
+
|
2393
2988
|
for (i = 0, ii = charstrings.length; i < ii; i++) {
|
2394
2989
|
var charstring = charstrings[i];
|
2990
|
+
|
2395
2991
|
if (charstring.seac) {
|
2396
2992
|
seacMap[i + 1] = charstring.seac;
|
2397
2993
|
}
|
2398
2994
|
}
|
2995
|
+
|
2399
2996
|
return seacMap;
|
2400
2997
|
},
|
2401
2998
|
getType2Charstrings: function Type1Font_getType2Charstrings(type1Charstrings) {
|
2402
2999
|
var type2Charstrings = [];
|
3000
|
+
|
2403
3001
|
for (var i = 0, ii = type1Charstrings.length; i < ii; i++) {
|
2404
3002
|
type2Charstrings.push(type1Charstrings[i].charstring);
|
2405
3003
|
}
|
3004
|
+
|
2406
3005
|
return type2Charstrings;
|
2407
3006
|
},
|
2408
3007
|
getType2Subrs: function Type1Font_getType2Subrs(type1Subrs) {
|
2409
3008
|
var bias = 0;
|
2410
3009
|
var count = type1Subrs.length;
|
3010
|
+
|
2411
3011
|
if (count < 1133) {
|
2412
3012
|
bias = 107;
|
2413
3013
|
} else if (count < 33769) {
|
@@ -2415,14 +3015,18 @@ var Type1Font = function Type1FontClosure() {
|
|
2415
3015
|
} else {
|
2416
3016
|
bias = 32768;
|
2417
3017
|
}
|
3018
|
+
|
2418
3019
|
var type2Subrs = [];
|
2419
3020
|
var i;
|
3021
|
+
|
2420
3022
|
for (i = 0; i < bias; i++) {
|
2421
3023
|
type2Subrs.push([0x0B]);
|
2422
3024
|
}
|
3025
|
+
|
2423
3026
|
for (i = 0; i < count; i++) {
|
2424
3027
|
type2Subrs.push(type1Subrs[i]);
|
2425
3028
|
}
|
3029
|
+
|
2426
3030
|
return type2Subrs;
|
2427
3031
|
},
|
2428
3032
|
wrap: function Type1Font_wrap(name, glyphs, charstrings, subrs, properties) {
|
@@ -2453,46 +3057,55 @@ var Type1Font = function Type1FontClosure() {
|
|
2453
3057
|
var count = glyphs.length;
|
2454
3058
|
var charsetArray = [0];
|
2455
3059
|
var i, ii;
|
3060
|
+
|
2456
3061
|
for (i = 0; i < count; i++) {
|
2457
3062
|
var index = _cff_parser.CFFStandardStrings.indexOf(charstrings[i].glyphName);
|
3063
|
+
|
2458
3064
|
if (index === -1) {
|
2459
3065
|
index = 0;
|
2460
3066
|
}
|
3067
|
+
|
2461
3068
|
charsetArray.push(index >> 8 & 0xff, index & 0xff);
|
2462
3069
|
}
|
3070
|
+
|
2463
3071
|
cff.charset = new _cff_parser.CFFCharset(false, 0, [], charsetArray);
|
2464
3072
|
var charStringsIndex = new _cff_parser.CFFIndex();
|
2465
3073
|
charStringsIndex.add([0x8B, 0x0E]);
|
3074
|
+
|
2466
3075
|
for (i = 0; i < count; i++) {
|
2467
|
-
|
2468
|
-
if (glyph.length === 0) {
|
2469
|
-
charStringsIndex.add([0x8B, 0x0E]);
|
2470
|
-
continue;
|
2471
|
-
}
|
2472
|
-
charStringsIndex.add(glyph);
|
3076
|
+
charStringsIndex.add(glyphs[i]);
|
2473
3077
|
}
|
3078
|
+
|
2474
3079
|
cff.charStrings = charStringsIndex;
|
2475
3080
|
var privateDict = new _cff_parser.CFFPrivateDict();
|
2476
3081
|
privateDict.setByName('Subrs', null);
|
2477
3082
|
var fields = ['BlueValues', 'OtherBlues', 'FamilyBlues', 'FamilyOtherBlues', 'StemSnapH', 'StemSnapV', 'BlueShift', 'BlueFuzz', 'BlueScale', 'LanguageGroup', 'ExpansionFactor', 'ForceBold', 'StdHW', 'StdVW'];
|
3083
|
+
|
2478
3084
|
for (i = 0, ii = fields.length; i < ii; i++) {
|
2479
3085
|
var field = fields[i];
|
3086
|
+
|
2480
3087
|
if (!(field in properties.privateData)) {
|
2481
3088
|
continue;
|
2482
3089
|
}
|
3090
|
+
|
2483
3091
|
var value = properties.privateData[field];
|
3092
|
+
|
2484
3093
|
if (Array.isArray(value)) {
|
2485
3094
|
for (var j = value.length - 1; j > 0; j--) {
|
2486
3095
|
value[j] -= value[j - 1];
|
2487
3096
|
}
|
2488
3097
|
}
|
3098
|
+
|
2489
3099
|
privateDict.setByName(field, value);
|
2490
3100
|
}
|
3101
|
+
|
2491
3102
|
cff.topDict.privateDict = privateDict;
|
2492
3103
|
var subrIndex = new _cff_parser.CFFIndex();
|
3104
|
+
|
2493
3105
|
for (i = 0, ii = subrs.length; i < ii; i++) {
|
2494
3106
|
subrIndex.add(subrs[i]);
|
2495
3107
|
}
|
3108
|
+
|
2496
3109
|
privateDict.subrsIndex = subrIndex;
|
2497
3110
|
var compiler = new _cff_parser.CFFCompiler(cff);
|
2498
3111
|
return compiler.compile();
|
@@ -2500,13 +3113,16 @@ var Type1Font = function Type1FontClosure() {
|
|
2500
3113
|
};
|
2501
3114
|
return Type1Font;
|
2502
3115
|
}();
|
3116
|
+
|
2503
3117
|
var CFFFont = function CFFFontClosure() {
|
2504
3118
|
function CFFFont(file, properties) {
|
2505
3119
|
this.properties = properties;
|
2506
3120
|
var parser = new _cff_parser.CFFParser(file, properties, SEAC_ANALYSIS_ENABLED);
|
2507
3121
|
this.cff = parser.parse();
|
3122
|
+
this.cff.duplicateFirstGlyph();
|
2508
3123
|
var compiler = new _cff_parser.CFFCompiler(this.cff);
|
2509
3124
|
this.seacs = this.cff.seacs;
|
3125
|
+
|
2510
3126
|
try {
|
2511
3127
|
this.data = compiler.compile();
|
2512
3128
|
} catch (e) {
|
@@ -2514,10 +3130,12 @@ var CFFFont = function CFFFontClosure() {
|
|
2514
3130
|
this.data = file;
|
2515
3131
|
}
|
2516
3132
|
}
|
3133
|
+
|
2517
3134
|
CFFFont.prototype = {
|
2518
3135
|
get numGlyphs() {
|
2519
3136
|
return this.cff.charStrings.count;
|
2520
3137
|
},
|
3138
|
+
|
2521
3139
|
getCharset: function CFFFont_getCharset() {
|
2522
3140
|
return this.cff.charset.charset;
|
2523
3141
|
},
|
@@ -2527,8 +3145,10 @@ var CFFFont = function CFFFontClosure() {
|
|
2527
3145
|
var charsets = cff.charset.charset;
|
2528
3146
|
var charCodeToGlyphId;
|
2529
3147
|
var glyphId;
|
3148
|
+
|
2530
3149
|
if (properties.composite) {
|
2531
3150
|
charCodeToGlyphId = Object.create(null);
|
3151
|
+
|
2532
3152
|
if (cff.isCIDFont) {
|
2533
3153
|
for (glyphId = 0; glyphId < charsets.length; glyphId++) {
|
2534
3154
|
var cid = charsets[glyphId];
|
@@ -2540,32 +3160,17 @@ var CFFFont = function CFFFontClosure() {
|
|
2540
3160
|
charCodeToGlyphId[glyphId] = glyphId;
|
2541
3161
|
}
|
2542
3162
|
}
|
3163
|
+
|
2543
3164
|
return charCodeToGlyphId;
|
2544
3165
|
}
|
3166
|
+
|
2545
3167
|
var encoding = cff.encoding ? cff.encoding.encoding : null;
|
2546
3168
|
charCodeToGlyphId = type1FontGlyphMapping(properties, encoding, charsets);
|
2547
3169
|
return charCodeToGlyphId;
|
3170
|
+
},
|
3171
|
+
hasGlyphId: function CFFFont_hasGlyphID(id) {
|
3172
|
+
return this.cff.hasGlyphId(id);
|
2548
3173
|
}
|
2549
3174
|
};
|
2550
3175
|
return CFFFont;
|
2551
|
-
}();
|
2552
|
-
(function checkSeacSupport() {
|
2553
|
-
if (typeof navigator !== 'undefined' && /Windows/.test(navigator.userAgent)) {
|
2554
|
-
exports.SEAC_ANALYSIS_ENABLED = SEAC_ANALYSIS_ENABLED = true;
|
2555
|
-
}
|
2556
|
-
})();
|
2557
|
-
(function checkChromeWindows() {
|
2558
|
-
if (typeof navigator !== 'undefined' && /Windows.*Chrome/.test(navigator.userAgent)) {
|
2559
|
-
SKIP_PRIVATE_USE_RANGE_F000_TO_F01F = true;
|
2560
|
-
}
|
2561
|
-
})();
|
2562
|
-
exports.SEAC_ANALYSIS_ENABLED = SEAC_ANALYSIS_ENABLED;
|
2563
|
-
exports.PRIVATE_USE_OFFSET_START = PRIVATE_USE_OFFSET_START;
|
2564
|
-
exports.PRIVATE_USE_OFFSET_END = PRIVATE_USE_OFFSET_END;
|
2565
|
-
exports.ErrorFont = ErrorFont;
|
2566
|
-
exports.Font = Font;
|
2567
|
-
exports.FontFlags = FontFlags;
|
2568
|
-
exports.ToUnicodeMap = ToUnicodeMap;
|
2569
|
-
exports.IdentityToUnicodeMap = IdentityToUnicodeMap;
|
2570
|
-
exports.ProblematicCharRanges = ProblematicCharRanges;
|
2571
|
-
exports.getFontType = getFontType;
|
3176
|
+
}();
|