pdfjs-dist 2.0.487 → 2.1.266

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of pdfjs-dist might be problematic. Click here for more details.

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