@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.
- package/Frameworks/DOM.jsframework/Info.json +2 -2
- package/Frameworks/DOM.jsframework/io.breakside.JSKit.DOM-bundle.js +2 -2
- package/Frameworks/FontKit.jsframework/Info.json +2 -2
- package/Frameworks/FontKit.jsframework/JS/FNTOpenTypeFont.js +331 -22
- package/Frameworks/FontKit.jsframework/io.breakside.JSKit.FontKit-bundle.js +2 -2
- package/Frameworks/Foundation.jsframework/Info.json +2 -2
- package/Frameworks/Foundation.jsframework/JS/JSAttributedString.js +13 -1
- package/Frameworks/Foundation.jsframework/JS/JSContext.js +44 -17
- package/Frameworks/Foundation.jsframework/JS/JSCubicBezier.js +54 -1
- package/Frameworks/Foundation.jsframework/JS/JSFont.js +8 -9
- package/Frameworks/Foundation.jsframework/JS/JSGradient.js +28 -2
- package/Frameworks/Foundation.jsframework/JS/JSImage+HTML.js +27 -1
- package/Frameworks/Foundation.jsframework/JS/JSNumberFormatter.js +23 -1
- package/Frameworks/Foundation.jsframework/JS/JSPath.js +192 -6
- package/Frameworks/Foundation.jsframework/JS/JSPoint.js +56 -0
- package/Frameworks/Foundation.jsframework/JS/JSTextRun.js +21 -4
- package/Frameworks/Foundation.jsframework/JS/JSTextStorage.js +5 -0
- package/Frameworks/Foundation.jsframework/JS/JSTextTypesetter.js +6 -1
- package/Frameworks/Foundation.jsframework/JS/JSXMLParser.js +1 -1
- package/Frameworks/Foundation.jsframework/io.breakside.JSKit.Foundation-bundle.js +2 -2
- package/Frameworks/Foundation.jsframework/sources.json +1 -0
- package/Frameworks/SecurityKit.jsframework/Info.json +2 -2
- package/Frameworks/SecurityKit.jsframework/io.breakside.JSKit.SecurityKit-bundle.js +2 -2
- package/Info.json +2 -2
- package/Node/io.breakside.jskit-bundle.js +2 -2
- package/Root/Frameworks/APIKit/Info.yaml +1 -1
- package/Root/Frameworks/APIKitTesting/Info.yaml +1 -1
- package/Root/Frameworks/AuthKit/Info.yaml +1 -1
- package/Root/Frameworks/CSSOM/Info.yaml +1 -1
- package/Root/Frameworks/ChartKit/Info.yaml +1 -1
- package/Root/Frameworks/ConferenceKit/Info.yaml +1 -1
- package/Root/Frameworks/DBKit/Info.yaml +1 -1
- package/Root/Frameworks/DOM/Info.yaml +1 -1
- package/Root/Frameworks/Dispatch/Info.yaml +1 -1
- package/Root/Frameworks/FontKit/FNTOpenTypeFont.js +331 -22
- package/Root/Frameworks/FontKit/Info.yaml +1 -1
- package/Root/Frameworks/Foundation/Info.yaml +1 -1
- package/Root/Frameworks/Foundation/JSAttributedString.js +13 -1
- package/Root/Frameworks/Foundation/JSContext.js +44 -17
- package/Root/Frameworks/Foundation/JSCubicBezier.js +54 -1
- package/Root/Frameworks/Foundation/JSFont.js +8 -9
- package/Root/Frameworks/Foundation/JSGradient.js +28 -2
- package/Root/Frameworks/Foundation/JSImage+HTML.js +27 -1
- package/Root/Frameworks/Foundation/JSNumberFormatter.js +23 -1
- package/Root/Frameworks/Foundation/JSPath.js +192 -6
- package/Root/Frameworks/Foundation/JSPoint.js +56 -0
- package/Root/Frameworks/Foundation/JSTextRun.js +21 -4
- package/Root/Frameworks/Foundation/JSTextStorage.js +5 -0
- package/Root/Frameworks/Foundation/JSTextTypesetter.js +6 -1
- package/Root/Frameworks/Foundation/JSXMLParser.js +1 -1
- package/Root/Frameworks/ImageKit/IKHTMLCanvasBitmapContext.js +187 -101
- package/Root/Frameworks/ImageKit/IKNodeBitmapContext.js +4 -4
- package/Root/Frameworks/ImageKit/Info.yaml +1 -1
- package/Root/Frameworks/MediaKit/Info.yaml +1 -1
- package/Root/Frameworks/MediaKitUI/Info.yaml +1 -1
- package/Root/Frameworks/NotificationKit/Info.yaml +1 -1
- package/Root/Frameworks/PDFKit/Info.yaml +1 -1
- package/Root/Frameworks/QRKit/Info.yaml +1 -1
- package/Root/Frameworks/SearchKit/Info.yaml +1 -1
- package/Root/Frameworks/SecurityKit/Info.yaml +1 -1
- package/Root/Frameworks/ServerKit/Info.yaml +1 -1
- package/Root/Frameworks/ServerKitTesting/Info.yaml +1 -1
- package/Root/Frameworks/TestKit/Info.yaml +1 -1
- package/Root/Frameworks/TestKit/TKAssert.js +4 -4
- package/Root/Frameworks/UIKit/Info.yaml +1 -1
- package/Root/Frameworks/UIKit/UIApplication.js +9 -1
- package/Root/Frameworks/UIKit/UICollectionView.js +4 -0
- package/Root/Frameworks/UIKit/UIColorPanel.js +46 -0
- package/Root/Frameworks/UIKit/UIColorWell.js +8 -0
- package/Root/Frameworks/UIKit/UIHTMLDisplayServer.js +21 -2
- package/Root/Frameworks/UIKit/UIHTMLDisplayServerCanvasContext.js +150 -69
- package/Root/Frameworks/UIKit/UIHTMLTextRun.js +5 -0
- package/Root/Frameworks/UIKit/UIHTMLTextTypesetter.js +18 -3
- package/Root/Frameworks/UIKit/UIListView.js +7 -5
- package/Root/Frameworks/UIKit/UIMenu.js +50 -32
- package/Root/Frameworks/UIKit/UIMenuItem.js +12 -0
- package/Root/Frameworks/UIKit/UIMenuView.js +27 -5
- package/Root/Frameworks/UIKit/UIPlatform.js +7 -0
- package/Root/Frameworks/UIKit/UIPopupButton.js +7 -1
- package/Root/Frameworks/UIKit/UIResponder.js +8 -0
- package/Root/Frameworks/UIKit/UITextEditor.js +14 -7
- package/Root/Frameworks/UIKit/UITokenField.js +65 -0
- package/Root/Frameworks/UIKit/UIToolbar.js +1 -1
- package/Root/Frameworks/UIKitTesting/Info.yaml +1 -1
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"JSBundleType": "framework",
|
|
3
3
|
"JSBundleIdentifier": "io.breakside.JSKit.DOM",
|
|
4
|
-
"JSBundleVersion": "2026.
|
|
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": "DOM+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": "
|
|
12
|
+
"GitRevision": "b8843098f47d4217cca519ae844e7f57f33ceae1"
|
|
13
13
|
}
|
|
@@ -3,7 +3,7 @@ JSBundle.bundles['io.breakside.JSKit.DOM'] = {
|
|
|
3
3
|
"Info": {
|
|
4
4
|
"JSBundleType": "framework",
|
|
5
5
|
"JSBundleIdentifier": "io.breakside.JSKit.DOM",
|
|
6
|
-
"JSBundleVersion": "2026.
|
|
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.DOM'] = {
|
|
|
11
11
|
"node": "DOM+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": "
|
|
14
|
+
"GitRevision": "b8843098f47d4217cca519ae844e7f57f33ceae1"
|
|
15
15
|
},
|
|
16
16
|
"Resources": [],
|
|
17
17
|
"ResourceLookup": {
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"JSBundleType": "framework",
|
|
3
3
|
"JSBundleIdentifier": "io.breakside.JSKit.FontKit",
|
|
4
|
-
"JSBundleVersion": "2026.
|
|
4
|
+
"JSBundleVersion": "2026.26.0",
|
|
5
5
|
"JSDevelopmentLanguage": "en",
|
|
6
6
|
"JSCopyright": "Copyright © 2020 Breakside Inc.",
|
|
7
7
|
"JSBundleEnvironments": {
|
|
8
8
|
"html": "FontKit+HTML.js"
|
|
9
9
|
},
|
|
10
10
|
"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",
|
|
11
|
-
"GitRevision": "
|
|
11
|
+
"GitRevision": "b8843098f47d4217cca519ae844e7f57f33ceae1"
|
|
12
12
|
}
|
|
@@ -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 (
|
|
1794
|
-
|
|
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
|
-
|
|
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",
|
|
1839
|
+
JSClass("FNTOpenTypeSimpleGlyph", FNTOpenTypeGlyph, {
|
|
1810
1840
|
|
|
1811
|
-
|
|
1812
|
-
this.data = data;
|
|
1813
|
-
this.dataView = data.dataView();
|
|
1814
|
-
},
|
|
1841
|
+
numberOfCountours: DataBackedProperty(0, "int16"),
|
|
1815
1842
|
|
|
1816
|
-
|
|
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",
|
|
2004
|
+
JSClass("FNTOpenTypeCompoundGlyph", FNTOpenTypeGlyph, {
|
|
1821
2005
|
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
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:
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
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
|
});
|
|
@@ -3,14 +3,14 @@ JSBundle.bundles['io.breakside.JSKit.FontKit'] = {
|
|
|
3
3
|
"Info": {
|
|
4
4
|
"JSBundleType": "framework",
|
|
5
5
|
"JSBundleIdentifier": "io.breakside.JSKit.FontKit",
|
|
6
|
-
"JSBundleVersion": "2026.
|
|
6
|
+
"JSBundleVersion": "2026.26.0",
|
|
7
7
|
"JSDevelopmentLanguage": "en",
|
|
8
8
|
"JSCopyright": "Copyright © 2020 Breakside Inc.",
|
|
9
9
|
"JSBundleEnvironments": {
|
|
10
10
|
"html": "FontKit+HTML.js"
|
|
11
11
|
},
|
|
12
12
|
"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",
|
|
13
|
-
"GitRevision": "
|
|
13
|
+
"GitRevision": "b8843098f47d4217cca519ae844e7f57f33ceae1"
|
|
14
14
|
},
|
|
15
15
|
"Resources": [],
|
|
16
16
|
"ResourceLookup": {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"JSBundleType": "framework",
|
|
3
3
|
"JSBundleIdentifier": "io.breakside.JSKit.Foundation",
|
|
4
|
-
"JSBundleVersion": "2026.
|
|
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": "Foundation+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": "
|
|
12
|
+
"GitRevision": "b8843098f47d4217cca519ae844e7f57f33ceae1"
|
|
13
13
|
}
|
|
@@ -65,6 +65,7 @@ JSClass("JSAttributedString", JSObject, {
|
|
|
65
65
|
case JSAttributedString.Attribute.font:
|
|
66
66
|
return JSAttributedString.AttributeDecoder.font(value);
|
|
67
67
|
case JSAttributedString.Attribute.textColor:
|
|
68
|
+
case JSAttributedString.Attribute.strokeColor:
|
|
68
69
|
case JSAttributedString.Attribute.backgroundColor:
|
|
69
70
|
return JSAttributedString.AttributeDecoder.color(value);
|
|
70
71
|
case JSAttributedString.Attribute.link:
|
|
@@ -90,6 +91,7 @@ JSClass("JSAttributedString", JSObject, {
|
|
|
90
91
|
case JSAttributedString.Attribute.headIndent:
|
|
91
92
|
case JSAttributedString.Attribute.tailIndent:
|
|
92
93
|
case JSAttributedString.Attribute.minimumLineHeight:
|
|
94
|
+
case JSAttributedString.Attribute.strokeWidth:
|
|
93
95
|
return JSAttributedString.AttributeDecoder.number(value);
|
|
94
96
|
case JSAttributedString.Attribute.textAlignment:
|
|
95
97
|
return JSAttributedString.AttributeDecoder.enumValue(JSTextAlignment)(value);
|
|
@@ -137,6 +139,7 @@ JSClass("JSAttributedString", JSObject, {
|
|
|
137
139
|
case JSAttributedString.Attribute.font:
|
|
138
140
|
return JSAttributedString.AttributeEncoder.font(value);
|
|
139
141
|
case JSAttributedString.Attribute.textColor:
|
|
142
|
+
case JSAttributedString.Attribute.strokeColor:
|
|
140
143
|
case JSAttributedString.Attribute.backgroundColor:
|
|
141
144
|
return JSAttributedString.AttributeEncoder.color(value);
|
|
142
145
|
case JSAttributedString.Attribute.link:
|
|
@@ -162,6 +165,7 @@ JSClass("JSAttributedString", JSObject, {
|
|
|
162
165
|
case JSAttributedString.Attribute.lineBreakMode:
|
|
163
166
|
case JSAttributedString.Attribute.maskCharacter:
|
|
164
167
|
case JSAttributedString.Attribute.paragraphStyleName:
|
|
168
|
+
case JSAttributedString.Attribute.strokeWidth:
|
|
165
169
|
default:
|
|
166
170
|
return value;
|
|
167
171
|
}
|
|
@@ -680,6 +684,7 @@ JSClass("JSAttributedString", JSObject, {
|
|
|
680
684
|
JSAttributedString.Attribute = {
|
|
681
685
|
font: "font",
|
|
682
686
|
textColor: "textColor",
|
|
687
|
+
strokeColor: "strokeColor",
|
|
683
688
|
backgroundColor: "backgroundColor",
|
|
684
689
|
bold: "bold",
|
|
685
690
|
italic: "italic",
|
|
@@ -689,6 +694,7 @@ JSAttributedString.Attribute = {
|
|
|
689
694
|
maskCharacter: "maskCharacter",
|
|
690
695
|
cursor: "cursor",
|
|
691
696
|
link: "link",
|
|
697
|
+
strokeWidth: "strokeWidth",
|
|
692
698
|
|
|
693
699
|
// Paragraph
|
|
694
700
|
paragraphStyleName: "paragraphStyleName",
|
|
@@ -745,7 +751,13 @@ JSAttributedString.AttributeDecoder = {
|
|
|
745
751
|
dataBase64URL: function(value){ return value.dataByDecodingBase64URL(); },
|
|
746
752
|
dataHex: function(value){ return value.dataByDecodingHex(); },
|
|
747
753
|
url: function(value){ return JSURL.initWithString(value); },
|
|
748
|
-
font: function(value){
|
|
754
|
+
font: function(value){
|
|
755
|
+
var font = JSFont.initFromDictionary(value);
|
|
756
|
+
if (font === null){
|
|
757
|
+
font = JSFont.initWithDescriptor(JSFontDescriptor.system, value.size);
|
|
758
|
+
}
|
|
759
|
+
return font;
|
|
760
|
+
},
|
|
749
761
|
color: function(value){ return JSColor.initFromDictionary(value); },
|
|
750
762
|
boolean: function(value){ return typeof(value) === "boolean" ? value : undefined; },
|
|
751
763
|
number: function(value){ return typeof(value) === "number" ? value : undefined; },
|
|
@@ -88,8 +88,7 @@ JSClass("JSContext", JSObject, {
|
|
|
88
88
|
|
|
89
89
|
addQuadraticCurveToPoint: function(point, control){
|
|
90
90
|
this.beginPathIfNeeded();
|
|
91
|
-
|
|
92
|
-
this.path.addCurveToPoint(point, control, point, this.state.transform);
|
|
91
|
+
this.path.addQuadraticCurveToPoint(point, control, this.state.transform);
|
|
93
92
|
},
|
|
94
93
|
|
|
95
94
|
addEllipseInRect: function(rect){
|
|
@@ -100,21 +99,17 @@ JSClass("JSContext", JSObject, {
|
|
|
100
99
|
addPath: function(path){
|
|
101
100
|
this.beginPathIfNeeded();
|
|
102
101
|
var i, l;
|
|
103
|
-
var
|
|
104
|
-
var
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
this.addCurveToPoint(segment.curve.p2, segment.curve.cp1, segment.curve.cp2);
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
if (subpath.closed){
|
|
102
|
+
var elements = path.elements;
|
|
103
|
+
var element;
|
|
104
|
+
for (i = 0, l = elements.length; i < l; ++i){
|
|
105
|
+
element = elements[i];
|
|
106
|
+
if (element.type === JSPathElement.Type.move){
|
|
107
|
+
this.moveToPoint(element.point.x, element.point.y);
|
|
108
|
+
}else if (element.type === JSPathElement.Type.line){
|
|
109
|
+
this.addLineToPoint(element.point.x, element.point.y);
|
|
110
|
+
}else if (element.type === JSPathElement.Type.cubicCurve){
|
|
111
|
+
this.addCurveToPoint(element.curve.p2, element.curve.cp1, element.curve.cp2);
|
|
112
|
+
}else if (element.type === JSPathElement.Type.close){
|
|
118
113
|
this.closePath();
|
|
119
114
|
}
|
|
120
115
|
}
|
|
@@ -212,6 +207,12 @@ JSClass("JSContext", JSObject, {
|
|
|
212
207
|
drawRadialGradient: function(gradient, rect){
|
|
213
208
|
},
|
|
214
209
|
|
|
210
|
+
drawMaskedLinearGradient: function(gradient, rect, maskImage){
|
|
211
|
+
},
|
|
212
|
+
|
|
213
|
+
drawMaskedRadialGradient: function(gradient, rect, maskImage){
|
|
214
|
+
},
|
|
215
|
+
|
|
215
216
|
drawLinearGradientStroke: function(gradient, path){
|
|
216
217
|
// FIXME: gradient should be aligned to original path rect
|
|
217
218
|
var strokePath = path.pathThatFillsStroke(this.state.lineWidth, this.state.lineCap, this.state.lineJoin, this.state.miterLimit);
|
|
@@ -282,6 +283,30 @@ JSClass("JSContext", JSObject, {
|
|
|
282
283
|
this.state.shadowColor = color;
|
|
283
284
|
},
|
|
284
285
|
|
|
286
|
+
// ----------------------------------------------------------------------
|
|
287
|
+
// MARK: - Transparency Layers
|
|
288
|
+
|
|
289
|
+
beginTransparencyLayer: function(){
|
|
290
|
+
this.save();
|
|
291
|
+
this.state.transparencyLayer = this.createTransparencyLayer();
|
|
292
|
+
this.setAlpha(1);
|
|
293
|
+
this.setShadow(JSPoint.Zero, 0, null);
|
|
294
|
+
},
|
|
295
|
+
|
|
296
|
+
endTransparencyLayer: function(){
|
|
297
|
+
if (this.state.transparencyLayer === null){
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
this.drawTransparencyLayer(this.state.transparencyLayer);
|
|
301
|
+
this.restore();
|
|
302
|
+
},
|
|
303
|
+
|
|
304
|
+
createTransparencyLayer: function(){
|
|
305
|
+
},
|
|
306
|
+
|
|
307
|
+
drawTransparencyLayer: function(transparencyLayer){
|
|
308
|
+
},
|
|
309
|
+
|
|
285
310
|
// ----------------------------------------------------------------------
|
|
286
311
|
// MARK: - Clipping
|
|
287
312
|
|
|
@@ -411,6 +436,8 @@ JSContext.State = {
|
|
|
411
436
|
characterSpacing: 0,
|
|
412
437
|
textDrawingMode: JSContext.TextDrawingMode.fill,
|
|
413
438
|
|
|
439
|
+
transparencyLayer: null
|
|
440
|
+
|
|
414
441
|
};
|
|
415
442
|
|
|
416
443
|
})();
|