@breakside/jskit 2026.11.0 → 2026.26.0

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.
Files changed (85) hide show
  1. package/Frameworks/DOM.jsframework/Info.json +2 -2
  2. package/Frameworks/DOM.jsframework/io.breakside.JSKit.DOM-bundle.js +2 -2
  3. package/Frameworks/FontKit.jsframework/Info.json +2 -2
  4. package/Frameworks/FontKit.jsframework/JS/FNTOpenTypeFont.js +331 -22
  5. package/Frameworks/FontKit.jsframework/io.breakside.JSKit.FontKit-bundle.js +2 -2
  6. package/Frameworks/Foundation.jsframework/Info.json +2 -2
  7. package/Frameworks/Foundation.jsframework/JS/JSAttributedString.js +13 -1
  8. package/Frameworks/Foundation.jsframework/JS/JSContext.js +44 -17
  9. package/Frameworks/Foundation.jsframework/JS/JSCubicBezier.js +54 -1
  10. package/Frameworks/Foundation.jsframework/JS/JSFont.js +8 -9
  11. package/Frameworks/Foundation.jsframework/JS/JSGradient.js +28 -2
  12. package/Frameworks/Foundation.jsframework/JS/JSImage+HTML.js +27 -1
  13. package/Frameworks/Foundation.jsframework/JS/JSNumberFormatter.js +23 -1
  14. package/Frameworks/Foundation.jsframework/JS/JSPath.js +192 -6
  15. package/Frameworks/Foundation.jsframework/JS/JSPoint.js +56 -0
  16. package/Frameworks/Foundation.jsframework/JS/JSTextRun.js +21 -4
  17. package/Frameworks/Foundation.jsframework/JS/JSTextStorage.js +5 -0
  18. package/Frameworks/Foundation.jsframework/JS/JSTextTypesetter.js +6 -1
  19. package/Frameworks/Foundation.jsframework/JS/JSXMLParser.js +1 -1
  20. package/Frameworks/Foundation.jsframework/io.breakside.JSKit.Foundation-bundle.js +2 -2
  21. package/Frameworks/Foundation.jsframework/sources.json +1 -0
  22. package/Frameworks/SecurityKit.jsframework/Info.json +2 -2
  23. package/Frameworks/SecurityKit.jsframework/io.breakside.JSKit.SecurityKit-bundle.js +2 -2
  24. package/Info.json +2 -2
  25. package/Node/io.breakside.jskit-bundle.js +2 -2
  26. package/Root/Frameworks/APIKit/Info.yaml +1 -1
  27. package/Root/Frameworks/APIKitTesting/Info.yaml +1 -1
  28. package/Root/Frameworks/AuthKit/Info.yaml +1 -1
  29. package/Root/Frameworks/CSSOM/Info.yaml +1 -1
  30. package/Root/Frameworks/ChartKit/Info.yaml +1 -1
  31. package/Root/Frameworks/ConferenceKit/Info.yaml +1 -1
  32. package/Root/Frameworks/DBKit/Info.yaml +1 -1
  33. package/Root/Frameworks/DOM/Info.yaml +1 -1
  34. package/Root/Frameworks/Dispatch/Info.yaml +1 -1
  35. package/Root/Frameworks/FontKit/FNTOpenTypeFont.js +331 -22
  36. package/Root/Frameworks/FontKit/Info.yaml +1 -1
  37. package/Root/Frameworks/Foundation/Info.yaml +1 -1
  38. package/Root/Frameworks/Foundation/JSAttributedString.js +13 -1
  39. package/Root/Frameworks/Foundation/JSContext.js +44 -17
  40. package/Root/Frameworks/Foundation/JSCubicBezier.js +54 -1
  41. package/Root/Frameworks/Foundation/JSFont.js +8 -9
  42. package/Root/Frameworks/Foundation/JSGradient.js +28 -2
  43. package/Root/Frameworks/Foundation/JSImage+HTML.js +27 -1
  44. package/Root/Frameworks/Foundation/JSNumberFormatter.js +23 -1
  45. package/Root/Frameworks/Foundation/JSPath.js +192 -6
  46. package/Root/Frameworks/Foundation/JSPoint.js +56 -0
  47. package/Root/Frameworks/Foundation/JSTextRun.js +21 -4
  48. package/Root/Frameworks/Foundation/JSTextStorage.js +5 -0
  49. package/Root/Frameworks/Foundation/JSTextTypesetter.js +6 -1
  50. package/Root/Frameworks/Foundation/JSXMLParser.js +1 -1
  51. package/Root/Frameworks/ImageKit/IKHTMLCanvasBitmapContext.js +187 -101
  52. package/Root/Frameworks/ImageKit/IKNodeBitmapContext.js +4 -4
  53. package/Root/Frameworks/ImageKit/Info.yaml +1 -1
  54. package/Root/Frameworks/MediaKit/Info.yaml +1 -1
  55. package/Root/Frameworks/MediaKitUI/Info.yaml +1 -1
  56. package/Root/Frameworks/NotificationKit/Info.yaml +1 -1
  57. package/Root/Frameworks/PDFKit/Info.yaml +1 -1
  58. package/Root/Frameworks/QRKit/Info.yaml +1 -1
  59. package/Root/Frameworks/SearchKit/Info.yaml +1 -1
  60. package/Root/Frameworks/SecurityKit/Info.yaml +1 -1
  61. package/Root/Frameworks/ServerKit/Info.yaml +1 -1
  62. package/Root/Frameworks/ServerKitTesting/Info.yaml +1 -1
  63. package/Root/Frameworks/TestKit/Info.yaml +1 -1
  64. package/Root/Frameworks/TestKit/TKAssert.js +4 -4
  65. package/Root/Frameworks/UIKit/Info.yaml +1 -1
  66. package/Root/Frameworks/UIKit/UIApplication.js +9 -1
  67. package/Root/Frameworks/UIKit/UICollectionView.js +4 -0
  68. package/Root/Frameworks/UIKit/UIColorPanel.js +46 -0
  69. package/Root/Frameworks/UIKit/UIColorWell.js +8 -0
  70. package/Root/Frameworks/UIKit/UIHTMLDisplayServer.js +21 -2
  71. package/Root/Frameworks/UIKit/UIHTMLDisplayServerCanvasContext.js +150 -69
  72. package/Root/Frameworks/UIKit/UIHTMLTextRun.js +5 -0
  73. package/Root/Frameworks/UIKit/UIHTMLTextTypesetter.js +18 -3
  74. package/Root/Frameworks/UIKit/UIListView.js +7 -5
  75. package/Root/Frameworks/UIKit/UIMenu.js +50 -32
  76. package/Root/Frameworks/UIKit/UIMenuItem.js +12 -0
  77. package/Root/Frameworks/UIKit/UIMenuView.js +27 -5
  78. package/Root/Frameworks/UIKit/UIPlatform.js +7 -0
  79. package/Root/Frameworks/UIKit/UIPopupButton.js +7 -1
  80. package/Root/Frameworks/UIKit/UIResponder.js +8 -0
  81. package/Root/Frameworks/UIKit/UITextEditor.js +14 -7
  82. package/Root/Frameworks/UIKit/UITokenField.js +65 -0
  83. package/Root/Frameworks/UIKit/UIToolbar.js +1 -1
  84. package/Root/Frameworks/UIKitTesting/Info.yaml +1 -1
  85. package/package.json +1 -1
@@ -475,7 +475,7 @@ JSClass("JSXMLParser", JSObject, {
475
475
  }
476
476
  obj = readObject();
477
477
  }
478
- if (!this.isStopped && this.delegate.xmlParserDidEndDocument){
478
+ if (!this.isStopped && this.delegate && this.delegate.xmlParserDidEndDocument){
479
479
  this.delegate.xmlParserDidEndDocument(this);
480
480
  }
481
481
  }catch (e){
@@ -3,7 +3,7 @@ JSBundle.bundles['io.breakside.JSKit.Foundation'] = {
3
3
  "Info": {
4
4
  "JSBundleType": "framework",
5
5
  "JSBundleIdentifier": "io.breakside.JSKit.Foundation",
6
- "JSBundleVersion": "2026.11.0",
6
+ "JSBundleVersion": "2026.26.0",
7
7
  "JSDevelopmentLanguage": "en",
8
8
  "JSCopyright": "Copyright © 2020 Breakside Inc.",
9
9
  "JSBundleEnvironments": {
@@ -11,7 +11,7 @@ JSBundle.bundles['io.breakside.JSKit.Foundation'] = {
11
11
  "node": "Foundation+Node.js"
12
12
  },
13
13
  "JSLicenseNotice": "Licensed under the Breakside Public License, Version 1.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nIf a copy of the License was not distributed with this file, you may\nobtain a copy at\n\n http://breakside.io/licenses/LICENSE-1.0.txt\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n",
14
- "GitRevision": "812100aa4c3e5b1ec1d0d432be903bba4db01b0e"
14
+ "GitRevision": "b8843098f47d4217cca519ae844e7f57f33ceae1"
15
15
  },
16
16
  "Resources": [
17
17
  {
@@ -233,6 +233,7 @@
233
233
  "JSSparseArrayController",
234
234
  "JSGradient",
235
235
  "JSPath",
236
+ "JSPathElement",
236
237
  "JSContext",
237
238
  "JSDateFormatter",
238
239
  "JSNumberFormatter",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "JSBundleType": "framework",
3
3
  "JSBundleIdentifier": "io.breakside.JSKit.SecurityKit",
4
- "JSBundleVersion": "2026.11.0",
4
+ "JSBundleVersion": "2026.26.0",
5
5
  "JSDevelopmentLanguage": "en",
6
6
  "JSCopyright": "Copyright © 2020 Breakside Inc.",
7
7
  "JSBundleEnvironments": {
@@ -9,5 +9,5 @@
9
9
  "node": "SecurityKit+Node.js"
10
10
  },
11
11
  "JSLicenseNotice": "Licensed under the Breakside Public License, Version 1.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nIf a copy of the License was not distributed with this file, you may\nobtain a copy at\n\n http://breakside.io/licenses/LICENSE-1.0.txt\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n",
12
- "GitRevision": "812100aa4c3e5b1ec1d0d432be903bba4db01b0e"
12
+ "GitRevision": "b8843098f47d4217cca519ae844e7f57f33ceae1"
13
13
  }
@@ -3,7 +3,7 @@ JSBundle.bundles['io.breakside.JSKit.SecurityKit'] = {
3
3
  "Info": {
4
4
  "JSBundleType": "framework",
5
5
  "JSBundleIdentifier": "io.breakside.JSKit.SecurityKit",
6
- "JSBundleVersion": "2026.11.0",
6
+ "JSBundleVersion": "2026.26.0",
7
7
  "JSDevelopmentLanguage": "en",
8
8
  "JSCopyright": "Copyright © 2020 Breakside Inc.",
9
9
  "JSBundleEnvironments": {
@@ -11,7 +11,7 @@ JSBundle.bundles['io.breakside.JSKit.SecurityKit'] = {
11
11
  "node": "SecurityKit+Node.js"
12
12
  },
13
13
  "JSLicenseNotice": "Licensed under the Breakside Public License, Version 1.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nIf a copy of the License was not distributed with this file, you may\nobtain a copy at\n\n http://breakside.io/licenses/LICENSE-1.0.txt\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n",
14
- "GitRevision": "812100aa4c3e5b1ec1d0d432be903bba4db01b0e"
14
+ "GitRevision": "b8843098f47d4217cca519ae844e7f57f33ceae1"
15
15
  },
16
16
  "Resources": [],
17
17
  "ResourceLookup": {
package/Info.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "JSBundleType": "node",
3
3
  "JSBundleIdentifier": "io.breakside.jskit",
4
- "JSBundleVersion": "2026.11.0",
4
+ "JSBundleVersion": "2026.26.0",
5
5
  "JSExecutableName": "jskit",
6
6
  "NPMOrganization": "breakside",
7
7
  "JSResources": [
8
8
  "Tests/HTMLTestRunner.js",
9
9
  "Tests/NodeTestRunner.js"
10
10
  ],
11
- "GitRevision": "812100aa4c3e5b1ec1d0d432be903bba4db01b0e"
11
+ "GitRevision": "b8843098f47d4217cca519ae844e7f57f33ceae1"
12
12
  }
@@ -3,14 +3,14 @@ JSBundle.bundles['io.breakside.jskit'] = {
3
3
  "Info": {
4
4
  "JSBundleType": "node",
5
5
  "JSBundleIdentifier": "io.breakside.jskit",
6
- "JSBundleVersion": "2026.11.0",
6
+ "JSBundleVersion": "2026.26.0",
7
7
  "JSExecutableName": "jskit",
8
8
  "NPMOrganization": "breakside",
9
9
  "JSResources": [
10
10
  "Tests/HTMLTestRunner.js",
11
11
  "Tests/NodeTestRunner.js"
12
12
  ],
13
- "GitRevision": "812100aa4c3e5b1ec1d0d432be903bba4db01b0e"
13
+ "GitRevision": "b8843098f47d4217cca519ae844e7f57f33ceae1"
14
14
  },
15
15
  "Resources": [
16
16
  {
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.APIKit
3
- JSBundleVersion: 2026.11.0
3
+ JSBundleVersion: 2026.26.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSIncludeDirectories:
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.APIKitTesting
3
- JSBundleVersion: 2026.11.0
3
+ JSBundleVersion: 2026.26.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSLicenseNotice: |
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.AuthKit
3
- JSBundleVersion: 2026.11.0
3
+ JSBundleVersion: 2026.26.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSLicenseNotice: |
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.CSSOM
3
- JSBundleVersion: 2026.11.0
3
+ JSBundleVersion: 2026.26.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.ChartKit
3
- JSBundleVersion: 2026.11.0
3
+ JSBundleVersion: 2026.26.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2021 Breakside Inc.
6
6
  # JSBundleEnvironments:
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.ConferenceKit
3
- JSBundleVersion: 2026.11.0
3
+ JSBundleVersion: 2026.26.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.DBKit
3
- JSBundleVersion: 2026.11.0
3
+ JSBundleVersion: 2026.26.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.DOM
3
- JSBundleVersion: 2026.11.0
3
+ JSBundleVersion: 2026.26.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.Dispatch
3
- JSBundleVersion: 2026.11.0
3
+ JSBundleVersion: 2026.26.0
4
4
  JSCopyright: Copyright © 2020 Breakside Inc.
5
5
  JSBundleEnvironments:
6
6
  html: Dispatch+HTML.js
@@ -14,7 +14,7 @@
14
14
  // limitations under the License.
15
15
 
16
16
  // #import Foundation
17
- /* global FNTOpenTypeConstructor */
17
+ /* global FNTOpenTypeConstructor, DataView */
18
18
  'use strict';
19
19
 
20
20
  (function(){
@@ -496,6 +496,10 @@ JSClass("FNTOpenTypeFont", JSObject, {
496
496
  return completion.promise;
497
497
  },
498
498
 
499
+ pathForGlyph: function(glyphIndex, transform){
500
+ return this.tables.glyf.pathForGlyph(glyphIndex, this.tables.loca, this.tables.head.indexToLocFormat, transform);
501
+ },
502
+
499
503
  });
500
504
 
501
505
  var tableChecksum = function(data){
@@ -1183,7 +1187,25 @@ JSClass("FNTOpenTypeFontTableCFF", FNTOpenTypeFontTable, {
1183
1187
  });
1184
1188
 
1185
1189
  JSClass("FNTOpenTypeFontTableGlyf", FNTOpenTypeFontTable, {
1186
- tag: 'glyf'
1190
+ tag: 'glyf',
1191
+
1192
+ glyph: function(glyphIndex, loca, format){
1193
+ var range = loca.rangeForGlyph(glyphIndex, format);
1194
+ var data = this.data.subdataInRange(range);
1195
+ var glyph = FNTOpenTypeGlyph.initWithData(data);
1196
+ if (glyph.isKindOfClass(FNTOpenTypeCompoundGlyph)){
1197
+ glyph.glyf = this;
1198
+ glyph.loca = loca;
1199
+ glyph.locaFormat = format;
1200
+ }
1201
+ return glyph;
1202
+ },
1203
+
1204
+ pathForGlyph: function(glyphIndex, loca, format, transform){
1205
+ var glyph = this.glyph(glyphIndex, loca, format);
1206
+ return glyph.getPath(transform);
1207
+ },
1208
+
1187
1209
  });
1188
1210
 
1189
1211
  JSClass("FNTOpenTypeFontTableLoca", FNTOpenTypeFontTable, {
@@ -1790,10 +1812,14 @@ JSClass("FNTOpenTypeFontCmap13", FNTOpenTypeFontCmap, {
1790
1812
  JSClass("FNTOpenTypeGlyph", JSObject, {
1791
1813
 
1792
1814
  initWithData: function(data){
1793
- if (data.length >= 2 && data.dataView().getInt16(0) < 0){
1794
- return FNTOpenTypeCompoundGlyph.initWithData(data);
1815
+ if (this.$class === FNTOpenTypeGlyph){
1816
+ if (data.length >= 2 && data.dataView().getInt16(0) < 0){
1817
+ return FNTOpenTypeCompoundGlyph.initWithData(data);
1818
+ }
1819
+ return FNTOpenTypeSimpleGlyph.initWithData(data);
1795
1820
  }
1796
- return FNTOpenTypeSimpleGlyph.initWithData(data);
1821
+ this.data = data;
1822
+ this.dataView = data.dataView();
1797
1823
  },
1798
1824
 
1799
1825
  data: null,
@@ -1802,27 +1828,184 @@ JSClass("FNTOpenTypeGlyph", JSObject, {
1802
1828
  xMin: DataBackedProperty(2, "int16"),
1803
1829
  yMin: DataBackedProperty(4, "int16"),
1804
1830
  xMax: DataBackedProperty(6, "int16"),
1805
- yMax: DataBackedProperty(8, "int16")
1831
+ yMax: DataBackedProperty(8, "int16"),
1832
+
1833
+ getPath: function(){
1834
+ return null;
1835
+ },
1806
1836
 
1807
1837
  });
1808
1838
 
1809
- JSClass("FNTOpenTypeSimpleGlyph", JSObject, {
1839
+ JSClass("FNTOpenTypeSimpleGlyph", FNTOpenTypeGlyph, {
1810
1840
 
1811
- initWithData: function(data){
1812
- this.data = data;
1813
- this.dataView = data.dataView();
1814
- },
1841
+ numberOfCountours: DataBackedProperty(0, "int16"),
1815
1842
 
1816
- numberOfCountours: DataBackedProperty(0, "int16")
1843
+ endPointIndexes: null,
1844
+ flags: null,
1845
+
1846
+ points: JSLazyInitProperty(function(){
1847
+ var points = [];
1848
+ var offset = 10;
1849
+ var end = this.data.length;
1850
+ var i, l;
1851
+ if (offset + this.numberOfCountours * 2 > end){
1852
+ throw new Error("not enough data for glyph end point indexes");
1853
+ }
1854
+ this.endPointIndexes = [];
1855
+ for (i = 0; i < this.numberOfCountours; ++i){
1856
+ this.endPointIndexes.push(this.dataView.getUint16(offset));
1857
+ offset += 2;
1858
+ }
1859
+ if (offset + 2 > end){
1860
+ throw new Error("not enough data for glyph instructions");
1861
+ }
1862
+ var instructionLength = this.dataView.getUint16(offset);
1863
+ offset += 2;
1864
+ if (offset + instructionLength > end){
1865
+ throw new Error("not enough data for glyph instructions");
1866
+ }
1867
+ offset += instructionLength;
1868
+ var numberOfPoints = this.endPointIndexes[this.endPointIndexes.length - 1] + 1;
1869
+ var repeatCount;
1870
+ var j, k;
1871
+ var flags;
1872
+ i = 0;
1873
+ this.flags = [];
1874
+ while (i < numberOfPoints){
1875
+ if (offset >= end){
1876
+ return null;
1877
+ }
1878
+ flags = this.data[offset];
1879
+ ++offset;
1880
+ this.flags.push(flags);
1881
+ ++i;
1882
+ if ((flags & 0x08) !== 0){
1883
+ if (offset >= end){
1884
+ return null;
1885
+ }
1886
+ repeatCount = this.data[offset];
1887
+ ++offset;
1888
+ for (j = 0; j < repeatCount; ++j){
1889
+ this.flags.push(flags);
1890
+ ++i;
1891
+ }
1892
+ }
1893
+ }
1894
+ i = 0;
1895
+ var point = JSPoint.Zero;
1896
+ var dx, dy;
1897
+ while (i < numberOfPoints){
1898
+ point = JSPoint(point);
1899
+ flags = this.flags[i];
1900
+ if ((flags & 0x02) === 0){
1901
+ if ((flags & 0x10) === 0){
1902
+ if (offset + 2 > end){
1903
+ throw new Error("not enough data for x delta");
1904
+ }
1905
+ dx = this.dataView.getInt16(offset);
1906
+ offset += 2;
1907
+ }else{
1908
+ dx = 0;
1909
+ }
1910
+ }else{
1911
+ if (offset >= end){
1912
+ throw new Error("not enough data for x delta");
1913
+ }
1914
+ dx = this.data[offset];
1915
+ ++offset;
1916
+ if ((flags & 0x10) === 0){
1917
+ dx = -dx;
1918
+ }
1919
+ }
1920
+ point.x += dx;
1921
+ points.push(point);
1922
+ ++i;
1923
+ }
1924
+ i = 0;
1925
+ while (i < numberOfPoints){
1926
+ points[i].y = point.y;
1927
+ point = points[i];
1928
+ flags = this.flags[i];
1929
+ if ((flags & 0x04) === 0){
1930
+ if ((flags & 0x20) === 0){
1931
+ if (offset + 2 > end){
1932
+ throw new Error("not enough data for y delta");
1933
+ }
1934
+ dy = this.dataView.getInt16(offset);
1935
+ offset += 2;
1936
+ }else{
1937
+ dy = 0;
1938
+ }
1939
+ }else{
1940
+ if (offset >= end){
1941
+ throw new Error("not enough data for y delta");
1942
+ }
1943
+ dy = this.data[offset];
1944
+ ++offset;
1945
+ if ((flags & 0x20) === 0){
1946
+ dy = -dy;
1947
+ }
1948
+ }
1949
+ point.y += dy;
1950
+ ++i;
1951
+ }
1952
+ return points;
1953
+ }),
1954
+
1955
+ getPath: function(transform){
1956
+ if (this.data.length < 2 || this.numberOfCountours === 0){
1957
+ return JSPath.init();
1958
+ }
1959
+ var flags;
1960
+ var point;
1961
+ var i, j, k;
1962
+ var p0;
1963
+ var path = JSPath.init();
1964
+ var cp = null;
1965
+ j = 0;
1966
+ var points = this.points;
1967
+ for (i = 0; i < this.numberOfCountours; ++i){
1968
+ flags = this.flags[j];
1969
+ point = points[j];
1970
+ p0 = point;
1971
+ if ((flags & 0x01) === 0){
1972
+ throw new Error("first point is off-curve");
1973
+ }
1974
+ path.moveToPoint(point, transform);
1975
+ ++j;
1976
+ for (k = this.endPointIndexes[i]; j <= k; ++j){
1977
+ flags = this.flags[j];
1978
+ point = points[j];
1979
+ if ((flags & 0x01) === 0){
1980
+ if (cp !== null){
1981
+ path.addQuadraticCurveToPoint(cp.interpolation(point, 0.5), cp, transform);
1982
+ }
1983
+ cp = point;
1984
+ }else{
1985
+ if (cp !== null){
1986
+ path.addQuadraticCurveToPoint(point, cp, transform);
1987
+ }else{
1988
+ path.addLineToPoint(point, transform);
1989
+ }
1990
+ cp = null;
1991
+ }
1992
+ }
1993
+ if (cp !== null){
1994
+ path.addQuadraticCurveToPoint(p0, cp, transform);
1995
+ cp = null;
1996
+ }
1997
+ path.closeSubpath();
1998
+ }
1999
+ return path;
2000
+ },
1817
2001
 
1818
2002
  });
1819
2003
 
1820
- JSClass("FNTOpenTypeCompoundGlyph", JSObject, {
2004
+ JSClass("FNTOpenTypeCompoundGlyph", FNTOpenTypeGlyph, {
1821
2005
 
1822
- initWithData: function(data){
1823
- this.data = data;
1824
- this.dataView = data.dataView();
1825
- },
2006
+ glyf: null,
2007
+ loca: null,
2008
+ locaFormat: null,
1826
2009
 
1827
2010
  updateReferencedGlyphs: function(glyphIndexByOriginalIndex, nextGlyphIndex){
1828
2011
  this.data = JSData.initWithCopyOfData(this.data);
@@ -1859,16 +2042,142 @@ JSClass("FNTOpenTypeCompoundGlyph", JSObject, {
1859
2042
  }
1860
2043
  }while ((flags & 0x20) == 0x20);
1861
2044
  return newGlyphs;
1862
- }
2045
+ },
2046
+
2047
+ getPath: function(transform){
2048
+ if (!transform){
2049
+ transform = JSAffineTransform.Identity;
2050
+ }
2051
+ var points = [];
2052
+ var path = JSPath.init();
2053
+ var offset = 10;
2054
+ var end = this.data.length;
2055
+ var flags;
2056
+ var glyphIndex;
2057
+ var arg1;
2058
+ var arg2;
2059
+ var glyph;
2060
+ var glyphTransform;
2061
+ var glyphPath;
2062
+ var hasMore = true;
2063
+ var p1;
2064
+ var p2;
2065
+ while (hasMore && offset < end){
2066
+ if (offset + 4 > end){
2067
+ throw new Error("not enough data for compound glyph");
2068
+ }
2069
+ flags = this.dataView.getUint16(offset);
2070
+ hasMore = (flags & 0x20) !== 0;
2071
+ offset += 2;
2072
+ glyphIndex = this.dataView.getUint16(offset);
2073
+ offset += 2;
2074
+ glyph = this.glyf.glyph(glyphIndex, this.loca, this.locaFormat);
2075
+ glyphPath = glyph.getPath();
2076
+ glyphTransform = JSAffineTransform.Identity;
2077
+ points = points.concat(glyph.points);
2078
+ if ((flags & 0x01) !== 0){
2079
+ if (offset + 4 > end){
2080
+ throw new Error("not enough data for compound glyph args");
2081
+ }
2082
+ if ((flags & 0x02) !== 0){
2083
+ // x-y values
2084
+ arg1 = this.dataView.getInt16(offset);
2085
+ offset += 2;
2086
+ arg2 = this.dataView.getInt16(offset);
2087
+ offset += 2;
2088
+ }else{
2089
+ // point indexes
2090
+ arg1 = this.dataView.getUint16(offset);
2091
+ offset += 2;
2092
+ arg2 = this.dataView.getUint16(offset);
2093
+ offset += 2;
2094
+ }
2095
+ }else{
2096
+ if (offset + 2 > end){
2097
+ throw new Error("not enough data for compound glyph args");
2098
+ }
2099
+ if ((flags & 0x02) !== 0){
2100
+ // x-y values
2101
+ arg1 = this.dataView.getInt8(offset);
2102
+ ++offset;
2103
+ arg2 = this.dataView.getInt8(offset);
2104
+ ++offset;
2105
+ }else{
2106
+ // point indexes
2107
+ arg1 = this.data[offset];
2108
+ ++offset;
2109
+ arg2 = this.data[offset];
2110
+ ++offset;
2111
+ }
2112
+ }
2113
+ if ((flags & 0x08) !== 0){
2114
+ if (offset + 2 > end){
2115
+ throw new Error("not enough data for compound glyph scale");
2116
+ }
2117
+ glyphTransform.a = this.dataView.getOTFFixedGlyphTranform(offset);
2118
+ glyphTransform.d = glyphTransform.a;
2119
+ offset += 2;
2120
+ }
2121
+ if ((flags & 0x40) !== 0){
2122
+ if (offset + 4 > end){
2123
+ throw new Error("not enough data for compound glyph scales");
2124
+ }
2125
+ glyphTransform.a = this.dataView.getOTFFixedGlyphTranform(offset);
2126
+ offset += 2;
2127
+ glyphTransform.d = this.dataView.getOTFFixedGlyphTranform(offset + 2);
2128
+ offset += 2;
2129
+ }
2130
+ if ((flags & 0x80) !== 0){
2131
+ if (offset + 8 > end){
2132
+ throw new Error("not enough data for compound glyph scale 2x2");
2133
+ }
2134
+ glyphTransform.a = this.dataView.getOTFFixedGlyphTranform(offset);
2135
+ offset += 2;
2136
+ glyphTransform.b = this.dataView.getOTFFixedGlyphTranform(offset);
2137
+ offset += 2;
2138
+ glyphTransform.c = this.dataView.getOTFFixedGlyphTranform(offset);
2139
+ offset += 2;
2140
+ glyphTransform.d = this.dataView.getOTFFixedGlyphTranform(offset);
2141
+ offset += 2;
2142
+ }
2143
+
2144
+ if ((flags & 0x02) !== 0){
2145
+ // x-y values
2146
+ glyphTransform = glyphTransform.translatedBy(arg1, arg2);
2147
+ }else{
2148
+ // point indexes
2149
+ p1 = points[arg1];
2150
+ p2 = glyph.points[arg2];
2151
+ glyphTransform.tx = p1.x - p2.x;
2152
+ glyphTransform.ty = p1.y - p2.y;
2153
+ }
2154
+ path.addPath(glyphPath, glyphTransform.concatenatedWith(transform));
2155
+ }
2156
+ return path;
2157
+ },
1863
2158
 
1864
2159
  });
1865
2160
 
1866
2161
  Object.defineProperties(DataView.prototype, {
1867
2162
 
1868
- getOTFFixed: function(offset){
1869
- var whole = this.getUint16(offset);
1870
- var frac = this.getUint16(offset + 2);
1871
- return whole + frac / 0x10000;
2163
+ getOTFFixed: {
2164
+ value: function DataView_getOTFFixed(offset){
2165
+ var whole = this.getUint16(offset);
2166
+ var frac = this.getUint16(offset + 2);
2167
+ return whole + frac / 0x10000;
2168
+ }
2169
+ },
2170
+
2171
+ getOTFFixedGlyphTranform: {
2172
+ value: function DataView_getOTFFixedGlyphTransform(offset){
2173
+ var n = this.getUint16(offset);
2174
+ var whole = ((n & 0x4000) !== 0) ? 1 : 0;
2175
+ if ((n & 0x8000) !== 0){
2176
+ whole = -whole;
2177
+ }
2178
+ var frac = n & 0x3FFF;
2179
+ return whole + frac / 0x4000;
2180
+ }
1872
2181
  }
1873
2182
 
1874
2183
  });
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.FontKit
3
- JSBundleVersion: 2026.11.0
3
+ JSBundleVersion: 2026.26.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.Foundation
3
- JSBundleVersion: 2026.11.0
3
+ JSBundleVersion: 2026.26.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSBundleEnvironments: