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