pdfjs-dist 2.0.489 → 2.2.228

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