monaco-editor-core 0.56.0-dev-20260101 → 0.56.0-dev-20260103
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/esm/nls.messages.cs.js +1 -1
- package/esm/nls.messages.de.js +1 -1
- package/esm/nls.messages.es.js +1 -1
- package/esm/nls.messages.fr.js +1 -1
- package/esm/nls.messages.it.js +1 -1
- package/esm/nls.messages.ja.js +1 -1
- package/esm/nls.messages.ko.js +1 -1
- package/esm/nls.messages.pl.js +1 -1
- package/esm/nls.messages.pt-br.js +1 -1
- package/esm/nls.messages.ru.js +1 -1
- package/esm/nls.messages.tr.js +1 -1
- package/esm/nls.messages.zh-cn.js +1 -1
- package/esm/nls.messages.zh-tw.js +1 -1
- package/esm/vs/editor/browser/gpu/css/decorationCssRuleExtractor.js +10 -1
- package/esm/vs/editor/browser/gpu/css/decorationCssRuleExtractor.js.map +1 -1
- package/esm/vs/editor/browser/gpu/css/decorationStyleCache.js +7 -4
- package/esm/vs/editor/browser/gpu/css/decorationStyleCache.js.map +1 -1
- package/esm/vs/editor/browser/gpu/raster/glyphRasterizer.js +31 -6
- package/esm/vs/editor/browser/gpu/raster/glyphRasterizer.js.map +1 -1
- package/esm/vs/editor/browser/gpu/renderStrategy/fullFileRenderStrategy.js +37 -1
- package/esm/vs/editor/browser/gpu/renderStrategy/fullFileRenderStrategy.js.map +1 -1
- package/esm/vs/editor/browser/gpu/renderStrategy/viewportRenderStrategy.js +37 -1
- package/esm/vs/editor/browser/gpu/renderStrategy/viewportRenderStrategy.js.map +1 -1
- package/esm/vs/editor/browser/gpu/viewGpuContext.js +31 -0
- package/esm/vs/editor/browser/gpu/viewGpuContext.js.map +1 -1
- package/package.json +2 -2
package/esm/nls.messages.cs.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*!-----------------------------------------------------------
|
|
2
2
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
-
* Version: 0.56.0-dev-
|
|
3
|
+
* Version: 0.56.0-dev-20260103(ec78a33c7b34dba19e9d3cbe1b3b378465bbd8b8)
|
|
4
4
|
* Released under the MIT license
|
|
5
5
|
* https://github.com/microsoft/vscode/blob/main/LICENSE.txt
|
|
6
6
|
*-----------------------------------------------------------*/
|
package/esm/nls.messages.de.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*!-----------------------------------------------------------
|
|
2
2
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
-
* Version: 0.56.0-dev-
|
|
3
|
+
* Version: 0.56.0-dev-20260103(ec78a33c7b34dba19e9d3cbe1b3b378465bbd8b8)
|
|
4
4
|
* Released under the MIT license
|
|
5
5
|
* https://github.com/microsoft/vscode/blob/main/LICENSE.txt
|
|
6
6
|
*-----------------------------------------------------------*/
|
package/esm/nls.messages.es.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*!-----------------------------------------------------------
|
|
2
2
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
-
* Version: 0.56.0-dev-
|
|
3
|
+
* Version: 0.56.0-dev-20260103(ec78a33c7b34dba19e9d3cbe1b3b378465bbd8b8)
|
|
4
4
|
* Released under the MIT license
|
|
5
5
|
* https://github.com/microsoft/vscode/blob/main/LICENSE.txt
|
|
6
6
|
*-----------------------------------------------------------*/
|
package/esm/nls.messages.fr.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*!-----------------------------------------------------------
|
|
2
2
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
-
* Version: 0.56.0-dev-
|
|
3
|
+
* Version: 0.56.0-dev-20260103(ec78a33c7b34dba19e9d3cbe1b3b378465bbd8b8)
|
|
4
4
|
* Released under the MIT license
|
|
5
5
|
* https://github.com/microsoft/vscode/blob/main/LICENSE.txt
|
|
6
6
|
*-----------------------------------------------------------*/
|
package/esm/nls.messages.it.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*!-----------------------------------------------------------
|
|
2
2
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
-
* Version: 0.56.0-dev-
|
|
3
|
+
* Version: 0.56.0-dev-20260103(ec78a33c7b34dba19e9d3cbe1b3b378465bbd8b8)
|
|
4
4
|
* Released under the MIT license
|
|
5
5
|
* https://github.com/microsoft/vscode/blob/main/LICENSE.txt
|
|
6
6
|
*-----------------------------------------------------------*/
|
package/esm/nls.messages.ja.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*!-----------------------------------------------------------
|
|
2
2
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
-
* Version: 0.56.0-dev-
|
|
3
|
+
* Version: 0.56.0-dev-20260103(ec78a33c7b34dba19e9d3cbe1b3b378465bbd8b8)
|
|
4
4
|
* Released under the MIT license
|
|
5
5
|
* https://github.com/microsoft/vscode/blob/main/LICENSE.txt
|
|
6
6
|
*-----------------------------------------------------------*/
|
package/esm/nls.messages.ko.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*!-----------------------------------------------------------
|
|
2
2
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
-
* Version: 0.56.0-dev-
|
|
3
|
+
* Version: 0.56.0-dev-20260103(ec78a33c7b34dba19e9d3cbe1b3b378465bbd8b8)
|
|
4
4
|
* Released under the MIT license
|
|
5
5
|
* https://github.com/microsoft/vscode/blob/main/LICENSE.txt
|
|
6
6
|
*-----------------------------------------------------------*/
|
package/esm/nls.messages.pl.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*!-----------------------------------------------------------
|
|
2
2
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
-
* Version: 0.56.0-dev-
|
|
3
|
+
* Version: 0.56.0-dev-20260103(ec78a33c7b34dba19e9d3cbe1b3b378465bbd8b8)
|
|
4
4
|
* Released under the MIT license
|
|
5
5
|
* https://github.com/microsoft/vscode/blob/main/LICENSE.txt
|
|
6
6
|
*-----------------------------------------------------------*/
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*!-----------------------------------------------------------
|
|
2
2
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
-
* Version: 0.56.0-dev-
|
|
3
|
+
* Version: 0.56.0-dev-20260103(ec78a33c7b34dba19e9d3cbe1b3b378465bbd8b8)
|
|
4
4
|
* Released under the MIT license
|
|
5
5
|
* https://github.com/microsoft/vscode/blob/main/LICENSE.txt
|
|
6
6
|
*-----------------------------------------------------------*/
|
package/esm/nls.messages.ru.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*!-----------------------------------------------------------
|
|
2
2
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
-
* Version: 0.56.0-dev-
|
|
3
|
+
* Version: 0.56.0-dev-20260103(ec78a33c7b34dba19e9d3cbe1b3b378465bbd8b8)
|
|
4
4
|
* Released under the MIT license
|
|
5
5
|
* https://github.com/microsoft/vscode/blob/main/LICENSE.txt
|
|
6
6
|
*-----------------------------------------------------------*/
|
package/esm/nls.messages.tr.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*!-----------------------------------------------------------
|
|
2
2
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
-
* Version: 0.56.0-dev-
|
|
3
|
+
* Version: 0.56.0-dev-20260103(ec78a33c7b34dba19e9d3cbe1b3b378465bbd8b8)
|
|
4
4
|
* Released under the MIT license
|
|
5
5
|
* https://github.com/microsoft/vscode/blob/main/LICENSE.txt
|
|
6
6
|
*-----------------------------------------------------------*/
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*!-----------------------------------------------------------
|
|
2
2
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
-
* Version: 0.56.0-dev-
|
|
3
|
+
* Version: 0.56.0-dev-20260103(ec78a33c7b34dba19e9d3cbe1b3b378465bbd8b8)
|
|
4
4
|
* Released under the MIT license
|
|
5
5
|
* https://github.com/microsoft/vscode/blob/main/LICENSE.txt
|
|
6
6
|
*-----------------------------------------------------------*/
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*!-----------------------------------------------------------
|
|
2
2
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
-
* Version: 0.56.0-dev-
|
|
3
|
+
* Version: 0.56.0-dev-20260103(ec78a33c7b34dba19e9d3cbe1b3b378465bbd8b8)
|
|
4
4
|
* Released under the MIT license
|
|
5
5
|
* https://github.com/microsoft/vscode/blob/main/LICENSE.txt
|
|
6
6
|
*-----------------------------------------------------------*/
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
3
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
4
4
|
*--------------------------------------------------------------------------------------------*/
|
|
5
|
-
import { $, getActiveDocument } from '../../../../base/browser/dom.js';
|
|
5
|
+
import { $, getActiveDocument, getActiveWindow } from '../../../../base/browser/dom.js';
|
|
6
6
|
import { Disposable, toDisposable } from '../../../../base/common/lifecycle.js';
|
|
7
7
|
import './media/decorationCssRuleExtractor.css';
|
|
8
8
|
/**
|
|
@@ -67,5 +67,14 @@ export class DecorationCssRuleExtractor extends Disposable {
|
|
|
67
67
|
}
|
|
68
68
|
return rules;
|
|
69
69
|
}
|
|
70
|
+
/**
|
|
71
|
+
* Resolves a CSS variable to its computed value using the container element.
|
|
72
|
+
*/
|
|
73
|
+
resolveCssVariable(canvas, variableName) {
|
|
74
|
+
canvas.appendChild(this._container);
|
|
75
|
+
const result = getActiveWindow().getComputedStyle(this._container).getPropertyValue(variableName).trim();
|
|
76
|
+
canvas.removeChild(this._container);
|
|
77
|
+
return result;
|
|
78
|
+
}
|
|
70
79
|
}
|
|
71
80
|
//# sourceMappingURL=decorationCssRuleExtractor.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src/vs/editor/browser/gpu/css/decorationCssRuleExtractor.ts","vs/editor/browser/gpu/css/decorationCssRuleExtractor.ts"],"names":[],"mappings":"AAAA;;;gGAGgG;AAEhG,OAAO,EAAE,CAAC,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"sources":["file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src/vs/editor/browser/gpu/css/decorationCssRuleExtractor.ts","vs/editor/browser/gpu/css/decorationCssRuleExtractor.ts"],"names":[],"mappings":"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","file":"decorationCssRuleExtractor.js","sourceRoot":"file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { $, getActiveDocument, getActiveWindow } from '../../../../base/browser/dom.js';\nimport { Disposable, toDisposable } from '../../../../base/common/lifecycle.js';\nimport './media/decorationCssRuleExtractor.css';\n\n/**\n * Extracts CSS rules that would be applied to certain decoration classes.\n */\nexport class DecorationCssRuleExtractor extends Disposable {\n\tprivate _container: HTMLElement;\n\tprivate _dummyElement: HTMLSpanElement;\n\n\tprivate _ruleCache: Map</* className */string, CSSStyleRule[]> = new Map();\n\n\tconstructor() {\n\t\tsuper();\n\n\t\tthis._container = $('div.monaco-decoration-css-rule-extractor');\n\t\tthis._dummyElement = $('span');\n\t\tthis._container.appendChild(this._dummyElement);\n\n\t\tthis._register(toDisposable(() => this._container.remove()));\n\t}\n\n\tgetStyleRules(canvas: HTMLElement, decorationClassName: string): CSSStyleRule[] {\n\t\t// Check cache\n\t\tconst existing = this._ruleCache.get(decorationClassName);\n\t\tif (existing) {\n\t\t\treturn existing;\n\t\t}\n\n\t\t// Set up DOM\n\t\tthis._dummyElement.className = decorationClassName;\n\t\tcanvas.appendChild(this._container);\n\n\t\t// Get rules\n\t\tconst rules = this._getStyleRules(decorationClassName);\n\t\tthis._ruleCache.set(decorationClassName, rules);\n\n\t\t// Tear down DOM\n\t\tcanvas.removeChild(this._container);\n\n\t\treturn rules;\n\t}\n\n\tprivate _getStyleRules(className: string) {\n\t\t// Iterate through all stylesheets and imported stylesheets to find matching rules\n\t\tconst rules = [];\n\t\tconst doc = getActiveDocument();\n\t\tconst stylesheets = [...doc.styleSheets];\n\t\tfor (let i = 0; i < stylesheets.length; i++) {\n\t\t\tconst stylesheet = stylesheets[i];\n\t\t\tfor (const rule of stylesheet.cssRules) {\n\t\t\t\tif (rule instanceof CSSImportRule) {\n\t\t\t\t\tif (rule.styleSheet) {\n\t\t\t\t\t\tstylesheets.push(rule.styleSheet);\n\t\t\t\t\t}\n\t\t\t\t} else if (rule instanceof CSSStyleRule) {\n\t\t\t\t\t// Note that originally `.matches(rule.selectorText)` was used but this would\n\t\t\t\t\t// not pick up pseudo-classes which are important to determine support of the\n\t\t\t\t\t// returned styles.\n\t\t\t\t\t//\n\t\t\t\t\t// Since a selector could contain a class name lookup that is simple a prefix of\n\t\t\t\t\t// the class name we are looking for, we need to also check the character after\n\t\t\t\t\t// it.\n\t\t\t\t\tconst searchTerm = `.${className}`;\n\t\t\t\t\tconst index = rule.selectorText.indexOf(searchTerm);\n\t\t\t\t\tif (index !== -1) {\n\t\t\t\t\t\tconst endOfResult = index + searchTerm.length;\n\t\t\t\t\t\tif (rule.selectorText.length === endOfResult || rule.selectorText.substring(endOfResult, endOfResult + 1).match(/[ :]/)) {\n\t\t\t\t\t\t\trules.push(rule);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn rules;\n\t}\n\n\t/**\n\t * Resolves a CSS variable to its computed value using the container element.\n\t */\n\tresolveCssVariable(canvas: HTMLCanvasElement, variableName: string): string {\n\t\tcanvas.appendChild(this._container);\n\t\tconst result = getActiveWindow().getComputedStyle(this._container).getPropertyValue(variableName).trim();\n\t\tcanvas.removeChild(this._container);\n\t\treturn result;\n\t}\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { $, getActiveDocument, getActiveWindow } from '../../../../base/browser/dom.js';\nimport { Disposable, toDisposable } from '../../../../base/common/lifecycle.js';\nimport './media/decorationCssRuleExtractor.css';\n\n/**\n * Extracts CSS rules that would be applied to certain decoration classes.\n */\nexport class DecorationCssRuleExtractor extends Disposable {\n\tprivate _container: HTMLElement;\n\tprivate _dummyElement: HTMLSpanElement;\n\n\tprivate _ruleCache: Map</* className */string, CSSStyleRule[]> = new Map();\n\n\tconstructor() {\n\t\tsuper();\n\n\t\tthis._container = $('div.monaco-decoration-css-rule-extractor');\n\t\tthis._dummyElement = $('span');\n\t\tthis._container.appendChild(this._dummyElement);\n\n\t\tthis._register(toDisposable(() => this._container.remove()));\n\t}\n\n\tgetStyleRules(canvas: HTMLElement, decorationClassName: string): CSSStyleRule[] {\n\t\t// Check cache\n\t\tconst existing = this._ruleCache.get(decorationClassName);\n\t\tif (existing) {\n\t\t\treturn existing;\n\t\t}\n\n\t\t// Set up DOM\n\t\tthis._dummyElement.className = decorationClassName;\n\t\tcanvas.appendChild(this._container);\n\n\t\t// Get rules\n\t\tconst rules = this._getStyleRules(decorationClassName);\n\t\tthis._ruleCache.set(decorationClassName, rules);\n\n\t\t// Tear down DOM\n\t\tcanvas.removeChild(this._container);\n\n\t\treturn rules;\n\t}\n\n\tprivate _getStyleRules(className: string) {\n\t\t// Iterate through all stylesheets and imported stylesheets to find matching rules\n\t\tconst rules = [];\n\t\tconst doc = getActiveDocument();\n\t\tconst stylesheets = [...doc.styleSheets];\n\t\tfor (let i = 0; i < stylesheets.length; i++) {\n\t\t\tconst stylesheet = stylesheets[i];\n\t\t\tfor (const rule of stylesheet.cssRules) {\n\t\t\t\tif (rule instanceof CSSImportRule) {\n\t\t\t\t\tif (rule.styleSheet) {\n\t\t\t\t\t\tstylesheets.push(rule.styleSheet);\n\t\t\t\t\t}\n\t\t\t\t} else if (rule instanceof CSSStyleRule) {\n\t\t\t\t\t// Note that originally `.matches(rule.selectorText)` was used but this would\n\t\t\t\t\t// not pick up pseudo-classes which are important to determine support of the\n\t\t\t\t\t// returned styles.\n\t\t\t\t\t//\n\t\t\t\t\t// Since a selector could contain a class name lookup that is simple a prefix of\n\t\t\t\t\t// the class name we are looking for, we need to also check the character after\n\t\t\t\t\t// it.\n\t\t\t\t\tconst searchTerm = `.${className}`;\n\t\t\t\t\tconst index = rule.selectorText.indexOf(searchTerm);\n\t\t\t\t\tif (index !== -1) {\n\t\t\t\t\t\tconst endOfResult = index + searchTerm.length;\n\t\t\t\t\t\tif (rule.selectorText.length === endOfResult || rule.selectorText.substring(endOfResult, endOfResult + 1).match(/[ :]/)) {\n\t\t\t\t\t\t\trules.push(rule);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn rules;\n\t}\n\n\t/**\n\t * Resolves a CSS variable to its computed value using the container element.\n\t */\n\tresolveCssVariable(canvas: HTMLCanvasElement, variableName: string): string {\n\t\tcanvas.appendChild(this._container);\n\t\tconst result = getActiveWindow().getComputedStyle(this._container).getPropertyValue(variableName).trim();\n\t\tcanvas.removeChild(this._container);\n\t\treturn result;\n\t}\n}\n"]}
|
|
@@ -9,11 +9,11 @@ export class DecorationStyleCache {
|
|
|
9
9
|
this._cacheById = new Map();
|
|
10
10
|
this._cacheByStyle = new NKeyMap();
|
|
11
11
|
}
|
|
12
|
-
getOrCreateEntry(color, bold, opacity) {
|
|
13
|
-
if (color === undefined && bold === undefined && opacity === undefined) {
|
|
12
|
+
getOrCreateEntry(color, bold, opacity, strikethrough, strikethroughThickness, strikethroughColor) {
|
|
13
|
+
if (color === undefined && bold === undefined && opacity === undefined && strikethrough === undefined && strikethroughThickness === undefined && strikethroughColor === undefined) {
|
|
14
14
|
return 0;
|
|
15
15
|
}
|
|
16
|
-
const result = this._cacheByStyle.get(color ?? 0, bold ? 1 : 0, opacity === undefined ? '' : opacity.toFixed(2));
|
|
16
|
+
const result = this._cacheByStyle.get(color ?? 0, bold ? 1 : 0, opacity === undefined ? '' : opacity.toFixed(2), strikethrough ? 1 : 0, strikethroughThickness === undefined ? '' : strikethroughThickness.toFixed(2), strikethroughColor ?? 0);
|
|
17
17
|
if (result) {
|
|
18
18
|
return result.id;
|
|
19
19
|
}
|
|
@@ -23,9 +23,12 @@ export class DecorationStyleCache {
|
|
|
23
23
|
color,
|
|
24
24
|
bold,
|
|
25
25
|
opacity,
|
|
26
|
+
strikethrough,
|
|
27
|
+
strikethroughThickness,
|
|
28
|
+
strikethroughColor,
|
|
26
29
|
};
|
|
27
30
|
this._cacheById.set(id, entry);
|
|
28
|
-
this._cacheByStyle.set(entry, color ?? 0, bold ? 1 : 0, opacity === undefined ? '' : opacity.toFixed(2));
|
|
31
|
+
this._cacheByStyle.set(entry, color ?? 0, bold ? 1 : 0, opacity === undefined ? '' : opacity.toFixed(2), strikethrough ? 1 : 0, strikethroughThickness === undefined ? '' : strikethroughThickness.toFixed(2), strikethroughColor ?? 0);
|
|
29
32
|
return id;
|
|
30
33
|
}
|
|
31
34
|
getStyleSet(id) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src/vs/editor/browser/gpu/css/decorationStyleCache.ts","vs/editor/browser/gpu/css/decorationStyleCache.ts"],"names":[],"mappings":"AAAA;;;gGAGgG;AAEhG,OAAO,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAC;
|
|
1
|
+
{"version":3,"sources":["file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src/vs/editor/browser/gpu/css/decorationStyleCache.ts","vs/editor/browser/gpu/css/decorationStyleCache.ts"],"names":[],"mappings":"AAAA;;;gGAGgG;AAEhG,OAAO,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAC;AAoCzD,MAAM,OAAO,oBAAoB;IAAjC;QAES,YAAO,GAAG,CAAC,CAAC;QAEH,eAAU,GAAG,IAAI,GAAG,EAAsC,CAAC;QAC3D,kBAAa,GAAG,IAAI,OAAO,EAAgF,CAAC;IAoD9H,CAAC;IAlDA,gBAAgB,CACf,KAAyB,EACzB,IAAyB,EACzB,OAA2B,EAC3B,aAAkC,EAClC,sBAA0C,EAC1C,kBAAsC;QAEtC,IAAI,KAAK,KAAK,SAAS,IAAI,IAAI,KAAK,SAAS,IAAI,OAAO,KAAK,SAAS,IAAI,aAAa,KAAK,SAAS,IAAI,sBAAsB,KAAK,SAAS,IAAI,kBAAkB,KAAK,SAAS,EAAE,CAAC;YACnL,OAAO,CAAC,CAAC;QACV,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CACpC,KAAK,IAAI,CAAC,EACV,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EACZ,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAC/C,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EACrB,sBAAsB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,sBAAsB,CAAC,OAAO,CAAC,CAAC,CAAC,EAC7E,kBAAkB,IAAI,CAAC,CACvB,CAAC;QACF,IAAI,MAAM,EAAE,CAAC;YACZ,OAAO,MAAM,CAAC,EAAE,CAAC;QAClB,CAAC;QACD,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;QAC1B,MAAM,KAAK,GAA+B;YACzC,EAAE;YACF,KAAK;YACL,IAAI;YACJ,OAAO;YACP,aAAa;YACb,sBAAsB;YACtB,kBAAkB;SAClB,CAAC;QACF,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;QAC/B,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,EAC3B,KAAK,IAAI,CAAC,EACV,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EACZ,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAC/C,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EACrB,sBAAsB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,sBAAsB,CAAC,OAAO,CAAC,CAAC,CAAC,EAC7E,kBAAkB,IAAI,CAAC,CACvB,CAAC;QACF,OAAO,EAAE,CAAC;IACX,CAAC;IAED,WAAW,CAAC,EAAU;QACrB,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC;YACd,OAAO,SAAS,CAAC;QAClB,CAAC;QACD,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChC,CAAC;CACD","file":"decorationStyleCache.js","sourceRoot":"file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { NKeyMap } from '../../../../base/common/map.js';\n\nexport interface IDecorationStyleSet {\n\t/**\n\t * A 24-bit number representing `color`.\n\t */\n\tcolor: number | undefined;\n\t/**\n\t * Whether the text should be rendered in bold.\n\t */\n\tbold: boolean | undefined;\n\t/**\n\t * A number between 0 and 1 representing the opacity of the text.\n\t */\n\topacity: number | undefined;\n\t/**\n\t * Whether the text should be rendered with a strikethrough.\n\t */\n\tstrikethrough: boolean | undefined;\n\t/**\n\t * The thickness of the strikethrough line in pixels (CSS pixels, not device pixels).\n\t */\n\tstrikethroughThickness: number | undefined;\n\t/**\n\t * A 32-bit number representing the strikethrough color.\n\t */\n\tstrikethroughColor: number | undefined;\n}\n\nexport interface IDecorationStyleCacheEntry extends IDecorationStyleSet {\n\t/**\n\t * A unique identifier for this set of styles.\n\t */\n\tid: number;\n}\n\nexport class DecorationStyleCache {\n\n\tprivate _nextId = 1;\n\n\tprivate readonly _cacheById = new Map<number, IDecorationStyleCacheEntry>();\n\tprivate readonly _cacheByStyle = new NKeyMap<IDecorationStyleCacheEntry, [number, number, string, number, string, number]>();\n\n\tgetOrCreateEntry(\n\t\tcolor: number | undefined,\n\t\tbold: boolean | undefined,\n\t\topacity: number | undefined,\n\t\tstrikethrough: boolean | undefined,\n\t\tstrikethroughThickness: number | undefined,\n\t\tstrikethroughColor: number | undefined\n\t): number {\n\t\tif (color === undefined && bold === undefined && opacity === undefined && strikethrough === undefined && strikethroughThickness === undefined && strikethroughColor === undefined) {\n\t\t\treturn 0;\n\t\t}\n\t\tconst result = this._cacheByStyle.get(\n\t\t\tcolor ?? 0,\n\t\t\tbold ? 1 : 0,\n\t\t\topacity === undefined ? '' : opacity.toFixed(2),\n\t\t\tstrikethrough ? 1 : 0,\n\t\t\tstrikethroughThickness === undefined ? '' : strikethroughThickness.toFixed(2),\n\t\t\tstrikethroughColor ?? 0\n\t\t);\n\t\tif (result) {\n\t\t\treturn result.id;\n\t\t}\n\t\tconst id = this._nextId++;\n\t\tconst entry: IDecorationStyleCacheEntry = {\n\t\t\tid,\n\t\t\tcolor,\n\t\t\tbold,\n\t\t\topacity,\n\t\t\tstrikethrough,\n\t\t\tstrikethroughThickness,\n\t\t\tstrikethroughColor,\n\t\t};\n\t\tthis._cacheById.set(id, entry);\n\t\tthis._cacheByStyle.set(entry,\n\t\t\tcolor ?? 0,\n\t\t\tbold ? 1 : 0,\n\t\t\topacity === undefined ? '' : opacity.toFixed(2),\n\t\t\tstrikethrough ? 1 : 0,\n\t\t\tstrikethroughThickness === undefined ? '' : strikethroughThickness.toFixed(2),\n\t\t\tstrikethroughColor ?? 0\n\t\t);\n\t\treturn id;\n\t}\n\n\tgetStyleSet(id: number): IDecorationStyleSet | undefined {\n\t\tif (id === 0) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn this._cacheById.get(id);\n\t}\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { NKeyMap } from '../../../../base/common/map.js';\n\nexport interface IDecorationStyleSet {\n\t/**\n\t * A 24-bit number representing `color`.\n\t */\n\tcolor: number | undefined;\n\t/**\n\t * Whether the text should be rendered in bold.\n\t */\n\tbold: boolean | undefined;\n\t/**\n\t * A number between 0 and 1 representing the opacity of the text.\n\t */\n\topacity: number | undefined;\n\t/**\n\t * Whether the text should be rendered with a strikethrough.\n\t */\n\tstrikethrough: boolean | undefined;\n\t/**\n\t * The thickness of the strikethrough line in pixels (CSS pixels, not device pixels).\n\t */\n\tstrikethroughThickness: number | undefined;\n\t/**\n\t * A 32-bit number representing the strikethrough color.\n\t */\n\tstrikethroughColor: number | undefined;\n}\n\nexport interface IDecorationStyleCacheEntry extends IDecorationStyleSet {\n\t/**\n\t * A unique identifier for this set of styles.\n\t */\n\tid: number;\n}\n\nexport class DecorationStyleCache {\n\n\tprivate _nextId = 1;\n\n\tprivate readonly _cacheById = new Map<number, IDecorationStyleCacheEntry>();\n\tprivate readonly _cacheByStyle = new NKeyMap<IDecorationStyleCacheEntry, [number, number, string, number, string, number]>();\n\n\tgetOrCreateEntry(\n\t\tcolor: number | undefined,\n\t\tbold: boolean | undefined,\n\t\topacity: number | undefined,\n\t\tstrikethrough: boolean | undefined,\n\t\tstrikethroughThickness: number | undefined,\n\t\tstrikethroughColor: number | undefined\n\t): number {\n\t\tif (color === undefined && bold === undefined && opacity === undefined && strikethrough === undefined && strikethroughThickness === undefined && strikethroughColor === undefined) {\n\t\t\treturn 0;\n\t\t}\n\t\tconst result = this._cacheByStyle.get(\n\t\t\tcolor ?? 0,\n\t\t\tbold ? 1 : 0,\n\t\t\topacity === undefined ? '' : opacity.toFixed(2),\n\t\t\tstrikethrough ? 1 : 0,\n\t\t\tstrikethroughThickness === undefined ? '' : strikethroughThickness.toFixed(2),\n\t\t\tstrikethroughColor ?? 0\n\t\t);\n\t\tif (result) {\n\t\t\treturn result.id;\n\t\t}\n\t\tconst id = this._nextId++;\n\t\tconst entry: IDecorationStyleCacheEntry = {\n\t\t\tid,\n\t\t\tcolor,\n\t\t\tbold,\n\t\t\topacity,\n\t\t\tstrikethrough,\n\t\t\tstrikethroughThickness,\n\t\t\tstrikethroughColor,\n\t\t};\n\t\tthis._cacheById.set(id, entry);\n\t\tthis._cacheByStyle.set(entry,\n\t\t\tcolor ?? 0,\n\t\t\tbold ? 1 : 0,\n\t\t\topacity === undefined ? '' : opacity.toFixed(2),\n\t\t\tstrikethrough ? 1 : 0,\n\t\t\tstrikethroughThickness === undefined ? '' : strikethroughThickness.toFixed(2),\n\t\t\tstrikethroughColor ?? 0\n\t\t);\n\t\treturn id;\n\t}\n\n\tgetStyleSet(id: number): IDecorationStyleSet | undefined {\n\t\tif (id === 0) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn this._cacheById.get(id);\n\t}\n}\n"]}
|
|
@@ -90,7 +90,7 @@ export class GlyphRasterizer extends Disposable {
|
|
|
90
90
|
this._ctx.save();
|
|
91
91
|
// The sub-pixel x offset is the fractional part of the x pixel coordinate of the cell, this
|
|
92
92
|
// is used to improve the spacing between rendered characters.
|
|
93
|
-
const
|
|
93
|
+
const subPixelXOffset = (tokenMetadata & 0b1111) / 10;
|
|
94
94
|
const bgId = TokenMetadata.getBackground(tokenMetadata);
|
|
95
95
|
const bg = colorMap[bgId];
|
|
96
96
|
const decorationStyleSet = this._decorationStyleCache.getStyleSet(decorationStyleSetId);
|
|
@@ -117,23 +117,47 @@ export class GlyphRasterizer extends Disposable {
|
|
|
117
117
|
}
|
|
118
118
|
fontSb.appendString(`${devicePixelFontSize}px ${this.fontFamily}`);
|
|
119
119
|
this._ctx.font = fontSb.build();
|
|
120
|
-
// TODO: Support FontStyle.
|
|
121
|
-
//
|
|
122
|
-
// underlines.
|
|
120
|
+
// TODO: Support FontStyle.Underline text decorations, these need to be drawn manually to
|
|
121
|
+
// the canvas. See xterm.js for "dodging" the text for underlines.
|
|
123
122
|
const originX = devicePixelFontSize;
|
|
124
123
|
const originY = devicePixelFontSize;
|
|
124
|
+
// Apply text color
|
|
125
125
|
if (decorationStyleSet?.color !== undefined) {
|
|
126
126
|
this._ctx.fillStyle = `#${decorationStyleSet.color.toString(16).padStart(8, '0')}`;
|
|
127
127
|
}
|
|
128
128
|
else {
|
|
129
129
|
this._ctx.fillStyle = colorMap[TokenMetadata.getForeground(tokenMetadata)];
|
|
130
130
|
}
|
|
131
|
-
|
|
131
|
+
// Apply opacity
|
|
132
132
|
if (decorationStyleSet?.opacity !== undefined) {
|
|
133
133
|
this._ctx.globalAlpha = decorationStyleSet.opacity;
|
|
134
134
|
}
|
|
135
|
-
|
|
135
|
+
// The glyph baseline is top, meaning it's drawn at the top-left of the
|
|
136
|
+
// cell. Add `TextMetrics.alphabeticBaseline` to the drawn position to
|
|
137
|
+
// get the alphabetic baseline.
|
|
138
|
+
this._ctx.textBaseline = 'top';
|
|
139
|
+
// Draw the text
|
|
140
|
+
this._ctx.fillText(chars, originX + subPixelXOffset, originY);
|
|
141
|
+
// Draw strikethrough
|
|
142
|
+
if (decorationStyleSet?.strikethrough) {
|
|
143
|
+
// TODO: This position could be refined further by checking
|
|
144
|
+
// TextMetrics of lowercase letters.
|
|
145
|
+
// Position strikethrough at approximately the vertical center of
|
|
146
|
+
// lowercase letters.
|
|
147
|
+
const strikethroughY = Math.round(originY - this._textMetrics.alphabeticBaseline * 0.65);
|
|
148
|
+
const lineWidth = decorationStyleSet?.strikethroughThickness !== undefined
|
|
149
|
+
? Math.round(decorationStyleSet.strikethroughThickness * this.devicePixelRatio)
|
|
150
|
+
: Math.max(1, Math.floor(devicePixelFontSize / 10));
|
|
151
|
+
// Apply strikethrough color if specified
|
|
152
|
+
if (decorationStyleSet?.strikethroughColor !== undefined) {
|
|
153
|
+
this._ctx.fillStyle = `#${decorationStyleSet.strikethroughColor.toString(16).padStart(8, '0')}`;
|
|
154
|
+
}
|
|
155
|
+
// Intentionally do not apply the sub pixel x offset to
|
|
156
|
+
// strikethrough to ensure successive glyphs form a contiguous line.
|
|
157
|
+
this._ctx.fillRect(originX, strikethroughY - Math.floor(lineWidth / 2), Math.ceil(this._textMetrics.width), lineWidth);
|
|
158
|
+
}
|
|
136
159
|
this._ctx.restore();
|
|
160
|
+
// Extract the image data and clear the background color
|
|
137
161
|
const imageData = this._ctx.getImageData(0, 0, this._canvas.width, this._canvas.height);
|
|
138
162
|
if (this._antiAliasing === 'subpixel') {
|
|
139
163
|
const bgR = parseInt(bg.substring(1, 3), 16);
|
|
@@ -142,6 +166,7 @@ export class GlyphRasterizer extends Disposable {
|
|
|
142
166
|
this._clearColor(imageData, bgR, bgG, bgB);
|
|
143
167
|
this._ctx.putImageData(imageData, 0, 0);
|
|
144
168
|
}
|
|
169
|
+
// Find the bounding box
|
|
145
170
|
this._findGlyphBoundingBox(imageData, this._workGlyph.boundingBox);
|
|
146
171
|
// const offset = {
|
|
147
172
|
// x: textMetrics.actualBoundingBoxLeft,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src/vs/editor/browser/gpu/raster/glyphRasterizer.ts","vs/editor/browser/gpu/raster/glyphRasterizer.ts"],"names":[],"mappings":"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","file":"glyphRasterizer.js","sourceRoot":"file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { memoize } from '../../../../base/common/decorators.js';\nimport { Disposable } from '../../../../base/common/lifecycle.js';\nimport { isMacintosh } from '../../../../base/common/platform.js';\nimport { StringBuilder } from '../../../common/core/stringBuilder.js';\nimport { FontStyle, TokenMetadata } from '../../../common/encodedTokenAttributes.js';\nimport { DecorationStyleCache } from '../css/decorationStyleCache.js';\nimport { ensureNonNullable } from '../gpuUtils.js';\nimport { type IBoundingBox, type IGlyphRasterizer, type IRasterizedGlyph } from './raster.js';\n\nlet nextId = 0;\n\nexport class GlyphRasterizer extends Disposable implements IGlyphRasterizer {\n\tpublic readonly id = nextId++;\n\n\t@memoize\n\tpublic get cacheKey(): string {\n\t\treturn `${this.fontFamily}_${this.fontSize}px`;\n\t}\n\n\tprivate _canvas: OffscreenCanvas;\n\tprivate _ctx: OffscreenCanvasRenderingContext2D;\n\n\tprivate readonly _textMetrics: TextMetrics;\n\n\tprivate _workGlyph: IRasterizedGlyph = {\n\t\tsource: null!,\n\t\tboundingBox: {\n\t\t\tleft: 0,\n\t\t\tbottom: 0,\n\t\t\tright: 0,\n\t\t\ttop: 0,\n\t\t},\n\t\toriginOffset: {\n\t\t\tx: 0,\n\t\t\ty: 0,\n\t\t},\n\t\tfontBoundingBoxAscent: 0,\n\t\tfontBoundingBoxDescent: 0,\n\t};\n\tprivate _workGlyphConfig: { chars: string | undefined; tokenMetadata: number; decorationStyleSetId: number } = { chars: undefined, tokenMetadata: 0, decorationStyleSetId: 0 };\n\n\t// TODO: Support workbench.fontAliasing correctly\n\tprivate _antiAliasing: 'subpixel' | 'greyscale' = isMacintosh ? 'greyscale' : 'subpixel';\n\n\tconstructor(\n\t\treadonly fontSize: number,\n\t\treadonly fontFamily: string,\n\t\treadonly devicePixelRatio: number,\n\t\tprivate readonly _decorationStyleCache: DecorationStyleCache,\n\t) {\n\t\tsuper();\n\n\t\tconst devicePixelFontSize = Math.ceil(this.fontSize * devicePixelRatio);\n\t\tthis._canvas = new OffscreenCanvas(devicePixelFontSize * 3, devicePixelFontSize * 3);\n\t\tthis._ctx = ensureNonNullable(this._canvas.getContext('2d', {\n\t\t\twillReadFrequently: true,\n\t\t\talpha: this._antiAliasing === 'greyscale',\n\t\t}));\n\t\tthis._ctx.textBaseline = 'top';\n\t\tthis._ctx.fillStyle = '#FFFFFF';\n\t\tthis._ctx.font = `${devicePixelFontSize}px ${this.fontFamily}`;\n\t\tthis._textMetrics = this._ctx.measureText('A');\n\t}\n\n\t/**\n\t * Rasterizes a glyph. Note that the returned object is reused across different glyphs and\n\t * therefore is only safe for synchronous access.\n\t */\n\tpublic rasterizeGlyph(\n\t\tchars: string,\n\t\ttokenMetadata: number,\n\t\tdecorationStyleSetId: number,\n\t\tcolorMap: string[],\n\t): Readonly<IRasterizedGlyph> {\n\t\tif (chars === '') {\n\t\t\treturn {\n\t\t\t\tsource: this._canvas,\n\t\t\t\tboundingBox: { top: 0, left: 0, bottom: -1, right: -1 },\n\t\t\t\toriginOffset: { x: 0, y: 0 },\n\t\t\t\tfontBoundingBoxAscent: 0,\n\t\t\t\tfontBoundingBoxDescent: 0,\n\t\t\t};\n\t\t}\n\t\t// Check if the last glyph matches the config, reuse if so. This helps avoid unnecessary\n\t\t// work when the rasterizer is called multiple times like when the glyph doesn't fit into a\n\t\t// page.\n\t\tif (this._workGlyphConfig.chars === chars && this._workGlyphConfig.tokenMetadata === tokenMetadata && this._workGlyphConfig.decorationStyleSetId === decorationStyleSetId) {\n\t\t\treturn this._workGlyph;\n\t\t}\n\t\tthis._workGlyphConfig.chars = chars;\n\t\tthis._workGlyphConfig.tokenMetadata = tokenMetadata;\n\t\tthis._workGlyphConfig.decorationStyleSetId = decorationStyleSetId;\n\t\treturn this._rasterizeGlyph(chars, tokenMetadata, decorationStyleSetId, colorMap);\n\t}\n\n\tpublic _rasterizeGlyph(\n\t\tchars: string,\n\t\ttokenMetadata: number,\n\t\tdecorationStyleSetId: number,\n\t\tcolorMap: string[],\n\t): Readonly<IRasterizedGlyph> {\n\t\tconst devicePixelFontSize = Math.ceil(this.fontSize * this.devicePixelRatio);\n\t\tconst canvasDim = devicePixelFontSize * 3;\n\t\tif (this._canvas.width !== canvasDim) {\n\t\t\tthis._canvas.width = canvasDim;\n\t\t\tthis._canvas.height = canvasDim;\n\t\t}\n\n\t\tthis._ctx.save();\n\n\t\t// The sub-pixel x offset is the fractional part of the x pixel coordinate of the cell, this\n\t\t// is used to improve the spacing between rendered characters.\n\t\tconst xSubPixelXOffset = (tokenMetadata & 0b1111) / 10;\n\n\t\tconst bgId = TokenMetadata.getBackground(tokenMetadata);\n\t\tconst bg = colorMap[bgId];\n\n\t\tconst decorationStyleSet = this._decorationStyleCache.getStyleSet(decorationStyleSetId);\n\n\t\t// When SPAA is used, the background color must be present to get the right glyph\n\t\tif (this._antiAliasing === 'subpixel') {\n\t\t\tthis._ctx.fillStyle = bg;\n\t\t\tthis._ctx.fillRect(0, 0, this._canvas.width, this._canvas.height);\n\t\t} else {\n\t\t\tthis._ctx.clearRect(0, 0, this._canvas.width, this._canvas.height);\n\t\t}\n\n\t\tconst fontSb = new StringBuilder(200);\n\t\tconst fontStyle = TokenMetadata.getFontStyle(tokenMetadata);\n\t\tif (fontStyle & FontStyle.Italic) {\n\t\t\tfontSb.appendString('italic ');\n\t\t}\n\t\tif (decorationStyleSet?.bold !== undefined) {\n\t\t\tif (decorationStyleSet.bold) {\n\t\t\t\tfontSb.appendString('bold ');\n\t\t\t}\n\t\t} else if (fontStyle & FontStyle.Bold) {\n\t\t\tfontSb.appendString('bold ');\n\t\t}\n\t\tfontSb.appendString(`${devicePixelFontSize}px ${this.fontFamily}`);\n\t\tthis._ctx.font = fontSb.build();\n\n\t\t// TODO: Support FontStyle.Strikethrough and FontStyle.Underline text decorations, these\n\t\t// need to be drawn manually to the canvas. See xterm.js for \"dodging\" the text for\n\t\t// underlines.\n\n\t\tconst originX = devicePixelFontSize;\n\t\tconst originY = devicePixelFontSize;\n\t\tif (decorationStyleSet?.color !== undefined) {\n\t\t\tthis._ctx.fillStyle = `#${decorationStyleSet.color.toString(16).padStart(8, '0')}`;\n\t\t} else {\n\t\t\tthis._ctx.fillStyle = colorMap[TokenMetadata.getForeground(tokenMetadata)];\n\t\t}\n\t\tthis._ctx.textBaseline = 'top';\n\n\t\tif (decorationStyleSet?.opacity !== undefined) {\n\t\t\tthis._ctx.globalAlpha = decorationStyleSet.opacity;\n\t\t}\n\n\t\tthis._ctx.fillText(chars, originX + xSubPixelXOffset, originY);\n\t\tthis._ctx.restore();\n\n\t\tconst imageData = this._ctx.getImageData(0, 0, this._canvas.width, this._canvas.height);\n\t\tif (this._antiAliasing === 'subpixel') {\n\t\t\tconst bgR = parseInt(bg.substring(1, 3), 16);\n\t\t\tconst bgG = parseInt(bg.substring(3, 5), 16);\n\t\t\tconst bgB = parseInt(bg.substring(5, 7), 16);\n\t\t\tthis._clearColor(imageData, bgR, bgG, bgB);\n\t\t\tthis._ctx.putImageData(imageData, 0, 0);\n\t\t}\n\t\tthis._findGlyphBoundingBox(imageData, this._workGlyph.boundingBox);\n\t\t// const offset = {\n\t\t// \tx: textMetrics.actualBoundingBoxLeft,\n\t\t// \ty: textMetrics.actualBoundingBoxAscent\n\t\t// };\n\t\t// const size = {\n\t\t// \tw: textMetrics.actualBoundingBoxRight + textMetrics.actualBoundingBoxLeft,\n\t\t// \ty: textMetrics.actualBoundingBoxDescent + textMetrics.actualBoundingBoxAscent,\n\t\t// \twInt: Math.ceil(textMetrics.actualBoundingBoxRight + textMetrics.actualBoundingBoxLeft),\n\t\t// \tyInt: Math.ceil(textMetrics.actualBoundingBoxDescent + textMetrics.actualBoundingBoxAscent),\n\t\t// };\n\t\t// console.log(`${chars}_${fg}`, textMetrics, boundingBox, originX, originY, { width: boundingBox.right - boundingBox.left, height: boundingBox.bottom - boundingBox.top });\n\t\tthis._workGlyph.source = this._canvas;\n\t\tthis._workGlyph.originOffset.x = this._workGlyph.boundingBox.left - originX;\n\t\tthis._workGlyph.originOffset.y = this._workGlyph.boundingBox.top - originY;\n\t\tthis._workGlyph.fontBoundingBoxAscent = this._textMetrics.fontBoundingBoxAscent;\n\t\tthis._workGlyph.fontBoundingBoxDescent = this._textMetrics.fontBoundingBoxDescent;\n\n\t\t// const result2: IRasterizedGlyph = {\n\t\t// \tsource: this._canvas,\n\t\t// \tboundingBox: {\n\t\t// \t\tleft: Math.floor(originX - textMetrics.actualBoundingBoxLeft),\n\t\t// \t\tright: Math.ceil(originX + textMetrics.actualBoundingBoxRight),\n\t\t// \t\ttop: Math.floor(originY - textMetrics.actualBoundingBoxAscent),\n\t\t// \t\tbottom: Math.ceil(originY + textMetrics.actualBoundingBoxDescent),\n\t\t// \t},\n\t\t// \toriginOffset: {\n\t\t// \t\tx: Math.floor(boundingBox.left - originX),\n\t\t// \t\ty: Math.floor(boundingBox.top - originY)\n\t\t// \t}\n\t\t// };\n\n\t\t// TODO: Verify result 1 and 2 are the same\n\n\t\t// if (result2.boundingBox.left > result.boundingBox.left) {\n\t\t// \tdebugger;\n\t\t// }\n\t\t// if (result2.boundingBox.top > result.boundingBox.top) {\n\t\t// \tdebugger;\n\t\t// }\n\t\t// if (result2.boundingBox.right < result.boundingBox.right) {\n\t\t// \tdebugger;\n\t\t// }\n\t\t// if (result2.boundingBox.bottom < result.boundingBox.bottom) {\n\t\t// \tdebugger;\n\t\t// }\n\t\t// if (JSON.stringify(result2.originOffset) !== JSON.stringify(result.originOffset)) {\n\t\t// \tdebugger;\n\t\t// }\n\n\n\n\t\treturn this._workGlyph;\n\t}\n\n\tprivate _clearColor(imageData: ImageData, r: number, g: number, b: number) {\n\t\tfor (let offset = 0; offset < imageData.data.length; offset += 4) {\n\t\t\t// Check exact match\n\t\t\tif (imageData.data[offset] === r &&\n\t\t\t\timageData.data[offset + 1] === g &&\n\t\t\t\timageData.data[offset + 2] === b) {\n\t\t\t\timageData.data[offset + 3] = 0;\n\t\t\t}\n\t\t}\n\t}\n\n\t// TODO: Does this even need to happen when measure text is used?\n\tprivate _findGlyphBoundingBox(imageData: ImageData, outBoundingBox: IBoundingBox) {\n\t\tconst height = this._canvas.height;\n\t\tconst width = this._canvas.width;\n\t\tlet found = false;\n\t\tfor (let y = 0; y < height; y++) {\n\t\t\tfor (let x = 0; x < width; x++) {\n\t\t\t\tconst alphaOffset = y * width * 4 + x * 4 + 3;\n\t\t\t\tif (imageData.data[alphaOffset] !== 0) {\n\t\t\t\t\toutBoundingBox.top = y;\n\t\t\t\t\tfound = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (found) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\toutBoundingBox.left = 0;\n\t\tfound = false;\n\t\tfor (let x = 0; x < width; x++) {\n\t\t\tfor (let y = 0; y < height; y++) {\n\t\t\t\tconst alphaOffset = y * width * 4 + x * 4 + 3;\n\t\t\t\tif (imageData.data[alphaOffset] !== 0) {\n\t\t\t\t\toutBoundingBox.left = x;\n\t\t\t\t\tfound = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (found) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\toutBoundingBox.right = width;\n\t\tfound = false;\n\t\tfor (let x = width - 1; x >= outBoundingBox.left; x--) {\n\t\t\tfor (let y = 0; y < height; y++) {\n\t\t\t\tconst alphaOffset = y * width * 4 + x * 4 + 3;\n\t\t\t\tif (imageData.data[alphaOffset] !== 0) {\n\t\t\t\t\toutBoundingBox.right = x;\n\t\t\t\t\tfound = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (found) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\toutBoundingBox.bottom = outBoundingBox.top;\n\t\tfound = false;\n\t\tfor (let y = height - 1; y >= 0; y--) {\n\t\t\tfor (let x = 0; x < width; x++) {\n\t\t\t\tconst alphaOffset = y * width * 4 + x * 4 + 3;\n\t\t\t\tif (imageData.data[alphaOffset] !== 0) {\n\t\t\t\t\toutBoundingBox.bottom = y;\n\t\t\t\t\tfound = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (found) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic getTextMetrics(text: string): TextMetrics {\n\t\treturn this._ctx.measureText(text);\n\t}\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { memoize } from '../../../../base/common/decorators.js';\nimport { Disposable } from '../../../../base/common/lifecycle.js';\nimport { isMacintosh } from '../../../../base/common/platform.js';\nimport { StringBuilder } from '../../../common/core/stringBuilder.js';\nimport { FontStyle, TokenMetadata } from '../../../common/encodedTokenAttributes.js';\nimport { DecorationStyleCache } from '../css/decorationStyleCache.js';\nimport { ensureNonNullable } from '../gpuUtils.js';\nimport { type IBoundingBox, type IGlyphRasterizer, type IRasterizedGlyph } from './raster.js';\n\nlet nextId = 0;\n\nexport class GlyphRasterizer extends Disposable implements IGlyphRasterizer {\n\tpublic readonly id = nextId++;\n\n\t@memoize\n\tpublic get cacheKey(): string {\n\t\treturn `${this.fontFamily}_${this.fontSize}px`;\n\t}\n\n\tprivate _canvas: OffscreenCanvas;\n\tprivate _ctx: OffscreenCanvasRenderingContext2D;\n\n\tprivate readonly _textMetrics: TextMetrics;\n\n\tprivate _workGlyph: IRasterizedGlyph = {\n\t\tsource: null!,\n\t\tboundingBox: {\n\t\t\tleft: 0,\n\t\t\tbottom: 0,\n\t\t\tright: 0,\n\t\t\ttop: 0,\n\t\t},\n\t\toriginOffset: {\n\t\t\tx: 0,\n\t\t\ty: 0,\n\t\t},\n\t\tfontBoundingBoxAscent: 0,\n\t\tfontBoundingBoxDescent: 0,\n\t};\n\tprivate _workGlyphConfig: { chars: string | undefined; tokenMetadata: number; decorationStyleSetId: number } = { chars: undefined, tokenMetadata: 0, decorationStyleSetId: 0 };\n\n\t// TODO: Support workbench.fontAliasing correctly\n\tprivate _antiAliasing: 'subpixel' | 'greyscale' = isMacintosh ? 'greyscale' : 'subpixel';\n\n\tconstructor(\n\t\treadonly fontSize: number,\n\t\treadonly fontFamily: string,\n\t\treadonly devicePixelRatio: number,\n\t\tprivate readonly _decorationStyleCache: DecorationStyleCache,\n\t) {\n\t\tsuper();\n\n\t\tconst devicePixelFontSize = Math.ceil(this.fontSize * devicePixelRatio);\n\t\tthis._canvas = new OffscreenCanvas(devicePixelFontSize * 3, devicePixelFontSize * 3);\n\t\tthis._ctx = ensureNonNullable(this._canvas.getContext('2d', {\n\t\t\twillReadFrequently: true,\n\t\t\talpha: this._antiAliasing === 'greyscale',\n\t\t}));\n\t\tthis._ctx.textBaseline = 'top';\n\t\tthis._ctx.fillStyle = '#FFFFFF';\n\t\tthis._ctx.font = `${devicePixelFontSize}px ${this.fontFamily}`;\n\t\tthis._textMetrics = this._ctx.measureText('A');\n\t}\n\n\t/**\n\t * Rasterizes a glyph. Note that the returned object is reused across different glyphs and\n\t * therefore is only safe for synchronous access.\n\t */\n\tpublic rasterizeGlyph(\n\t\tchars: string,\n\t\ttokenMetadata: number,\n\t\tdecorationStyleSetId: number,\n\t\tcolorMap: string[],\n\t): Readonly<IRasterizedGlyph> {\n\t\tif (chars === '') {\n\t\t\treturn {\n\t\t\t\tsource: this._canvas,\n\t\t\t\tboundingBox: { top: 0, left: 0, bottom: -1, right: -1 },\n\t\t\t\toriginOffset: { x: 0, y: 0 },\n\t\t\t\tfontBoundingBoxAscent: 0,\n\t\t\t\tfontBoundingBoxDescent: 0,\n\t\t\t};\n\t\t}\n\t\t// Check if the last glyph matches the config, reuse if so. This helps avoid unnecessary\n\t\t// work when the rasterizer is called multiple times like when the glyph doesn't fit into a\n\t\t// page.\n\t\tif (this._workGlyphConfig.chars === chars && this._workGlyphConfig.tokenMetadata === tokenMetadata && this._workGlyphConfig.decorationStyleSetId === decorationStyleSetId) {\n\t\t\treturn this._workGlyph;\n\t\t}\n\t\tthis._workGlyphConfig.chars = chars;\n\t\tthis._workGlyphConfig.tokenMetadata = tokenMetadata;\n\t\tthis._workGlyphConfig.decorationStyleSetId = decorationStyleSetId;\n\t\treturn this._rasterizeGlyph(chars, tokenMetadata, decorationStyleSetId, colorMap);\n\t}\n\n\tpublic _rasterizeGlyph(\n\t\tchars: string,\n\t\ttokenMetadata: number,\n\t\tdecorationStyleSetId: number,\n\t\tcolorMap: string[],\n\t): Readonly<IRasterizedGlyph> {\n\t\tconst devicePixelFontSize = Math.ceil(this.fontSize * this.devicePixelRatio);\n\t\tconst canvasDim = devicePixelFontSize * 3;\n\t\tif (this._canvas.width !== canvasDim) {\n\t\t\tthis._canvas.width = canvasDim;\n\t\t\tthis._canvas.height = canvasDim;\n\t\t}\n\n\t\tthis._ctx.save();\n\n\t\t// The sub-pixel x offset is the fractional part of the x pixel coordinate of the cell, this\n\t\t// is used to improve the spacing between rendered characters.\n\t\tconst xSubPixelXOffset = (tokenMetadata & 0b1111) / 10;\n\n\t\tconst bgId = TokenMetadata.getBackground(tokenMetadata);\n\t\tconst bg = colorMap[bgId];\n\n\t\tconst decorationStyleSet = this._decorationStyleCache.getStyleSet(decorationStyleSetId);\n\n\t\t// When SPAA is used, the background color must be present to get the right glyph\n\t\tif (this._antiAliasing === 'subpixel') {\n\t\t\tthis._ctx.fillStyle = bg;\n\t\t\tthis._ctx.fillRect(0, 0, this._canvas.width, this._canvas.height);\n\t\t} else {\n\t\t\tthis._ctx.clearRect(0, 0, this._canvas.width, this._canvas.height);\n\t\t}\n\n\t\tconst fontSb = new StringBuilder(200);\n\t\tconst fontStyle = TokenMetadata.getFontStyle(tokenMetadata);\n\t\tif (fontStyle & FontStyle.Italic) {\n\t\t\tfontSb.appendString('italic ');\n\t\t}\n\t\tif (decorationStyleSet?.bold !== undefined) {\n\t\t\tif (decorationStyleSet.bold) {\n\t\t\t\tfontSb.appendString('bold ');\n\t\t\t}\n\t\t} else if (fontStyle & FontStyle.Bold) {\n\t\t\tfontSb.appendString('bold ');\n\t\t}\n\t\tfontSb.appendString(`${devicePixelFontSize}px ${this.fontFamily}`);\n\t\tthis._ctx.font = fontSb.build();\n\n\t\t// TODO: Support FontStyle.Strikethrough and FontStyle.Underline text decorations, these\n\t\t// need to be drawn manually to the canvas. See xterm.js for \"dodging\" the text for\n\t\t// underlines.\n\n\t\tconst originX = devicePixelFontSize;\n\t\tconst originY = devicePixelFontSize;\n\t\tif (decorationStyleSet?.color !== undefined) {\n\t\t\tthis._ctx.fillStyle = `#${decorationStyleSet.color.toString(16).padStart(8, '0')}`;\n\t\t} else {\n\t\t\tthis._ctx.fillStyle = colorMap[TokenMetadata.getForeground(tokenMetadata)];\n\t\t}\n\t\tthis._ctx.textBaseline = 'top';\n\n\t\tif (decorationStyleSet?.opacity !== undefined) {\n\t\t\tthis._ctx.globalAlpha = decorationStyleSet.opacity;\n\t\t}\n\n\t\tthis._ctx.fillText(chars, originX + xSubPixelXOffset, originY);\n\t\tthis._ctx.restore();\n\n\t\tconst imageData = this._ctx.getImageData(0, 0, this._canvas.width, this._canvas.height);\n\t\tif (this._antiAliasing === 'subpixel') {\n\t\t\tconst bgR = parseInt(bg.substring(1, 3), 16);\n\t\t\tconst bgG = parseInt(bg.substring(3, 5), 16);\n\t\t\tconst bgB = parseInt(bg.substring(5, 7), 16);\n\t\t\tthis._clearColor(imageData, bgR, bgG, bgB);\n\t\t\tthis._ctx.putImageData(imageData, 0, 0);\n\t\t}\n\t\tthis._findGlyphBoundingBox(imageData, this._workGlyph.boundingBox);\n\t\t// const offset = {\n\t\t// \tx: textMetrics.actualBoundingBoxLeft,\n\t\t// \ty: textMetrics.actualBoundingBoxAscent\n\t\t// };\n\t\t// const size = {\n\t\t// \tw: textMetrics.actualBoundingBoxRight + textMetrics.actualBoundingBoxLeft,\n\t\t// \ty: textMetrics.actualBoundingBoxDescent + textMetrics.actualBoundingBoxAscent,\n\t\t// \twInt: Math.ceil(textMetrics.actualBoundingBoxRight + textMetrics.actualBoundingBoxLeft),\n\t\t// \tyInt: Math.ceil(textMetrics.actualBoundingBoxDescent + textMetrics.actualBoundingBoxAscent),\n\t\t// };\n\t\t// console.log(`${chars}_${fg}`, textMetrics, boundingBox, originX, originY, { width: boundingBox.right - boundingBox.left, height: boundingBox.bottom - boundingBox.top });\n\t\tthis._workGlyph.source = this._canvas;\n\t\tthis._workGlyph.originOffset.x = this._workGlyph.boundingBox.left - originX;\n\t\tthis._workGlyph.originOffset.y = this._workGlyph.boundingBox.top - originY;\n\t\tthis._workGlyph.fontBoundingBoxAscent = this._textMetrics.fontBoundingBoxAscent;\n\t\tthis._workGlyph.fontBoundingBoxDescent = this._textMetrics.fontBoundingBoxDescent;\n\n\t\t// const result2: IRasterizedGlyph = {\n\t\t// \tsource: this._canvas,\n\t\t// \tboundingBox: {\n\t\t// \t\tleft: Math.floor(originX - textMetrics.actualBoundingBoxLeft),\n\t\t// \t\tright: Math.ceil(originX + textMetrics.actualBoundingBoxRight),\n\t\t// \t\ttop: Math.floor(originY - textMetrics.actualBoundingBoxAscent),\n\t\t// \t\tbottom: Math.ceil(originY + textMetrics.actualBoundingBoxDescent),\n\t\t// \t},\n\t\t// \toriginOffset: {\n\t\t// \t\tx: Math.floor(boundingBox.left - originX),\n\t\t// \t\ty: Math.floor(boundingBox.top - originY)\n\t\t// \t}\n\t\t// };\n\n\t\t// TODO: Verify result 1 and 2 are the same\n\n\t\t// if (result2.boundingBox.left > result.boundingBox.left) {\n\t\t// \tdebugger;\n\t\t// }\n\t\t// if (result2.boundingBox.top > result.boundingBox.top) {\n\t\t// \tdebugger;\n\t\t// }\n\t\t// if (result2.boundingBox.right < result.boundingBox.right) {\n\t\t// \tdebugger;\n\t\t// }\n\t\t// if (result2.boundingBox.bottom < result.boundingBox.bottom) {\n\t\t// \tdebugger;\n\t\t// }\n\t\t// if (JSON.stringify(result2.originOffset) !== JSON.stringify(result.originOffset)) {\n\t\t// \tdebugger;\n\t\t// }\n\n\n\n\t\treturn this._workGlyph;\n\t}\n\n\tprivate _clearColor(imageData: ImageData, r: number, g: number, b: number) {\n\t\tfor (let offset = 0; offset < imageData.data.length; offset += 4) {\n\t\t\t// Check exact match\n\t\t\tif (imageData.data[offset] === r &&\n\t\t\t\timageData.data[offset + 1] === g &&\n\t\t\t\timageData.data[offset + 2] === b) {\n\t\t\t\timageData.data[offset + 3] = 0;\n\t\t\t}\n\t\t}\n\t}\n\n\t// TODO: Does this even need to happen when measure text is used?\n\tprivate _findGlyphBoundingBox(imageData: ImageData, outBoundingBox: IBoundingBox) {\n\t\tconst height = this._canvas.height;\n\t\tconst width = this._canvas.width;\n\t\tlet found = false;\n\t\tfor (let y = 0; y < height; y++) {\n\t\t\tfor (let x = 0; x < width; x++) {\n\t\t\t\tconst alphaOffset = y * width * 4 + x * 4 + 3;\n\t\t\t\tif (imageData.data[alphaOffset] !== 0) {\n\t\t\t\t\toutBoundingBox.top = y;\n\t\t\t\t\tfound = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (found) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\toutBoundingBox.left = 0;\n\t\tfound = false;\n\t\tfor (let x = 0; x < width; x++) {\n\t\t\tfor (let y = 0; y < height; y++) {\n\t\t\t\tconst alphaOffset = y * width * 4 + x * 4 + 3;\n\t\t\t\tif (imageData.data[alphaOffset] !== 0) {\n\t\t\t\t\toutBoundingBox.left = x;\n\t\t\t\t\tfound = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (found) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\toutBoundingBox.right = width;\n\t\tfound = false;\n\t\tfor (let x = width - 1; x >= outBoundingBox.left; x--) {\n\t\t\tfor (let y = 0; y < height; y++) {\n\t\t\t\tconst alphaOffset = y * width * 4 + x * 4 + 3;\n\t\t\t\tif (imageData.data[alphaOffset] !== 0) {\n\t\t\t\t\toutBoundingBox.right = x;\n\t\t\t\t\tfound = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (found) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\toutBoundingBox.bottom = outBoundingBox.top;\n\t\tfound = false;\n\t\tfor (let y = height - 1; y >= 0; y--) {\n\t\t\tfor (let x = 0; x < width; x++) {\n\t\t\t\tconst alphaOffset = y * width * 4 + x * 4 + 3;\n\t\t\t\tif (imageData.data[alphaOffset] !== 0) {\n\t\t\t\t\toutBoundingBox.bottom = y;\n\t\t\t\t\tfound = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (found) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic getTextMetrics(text: string): TextMetrics {\n\t\treturn this._ctx.measureText(text);\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src/vs/editor/browser/gpu/raster/glyphRasterizer.ts","vs/editor/browser/gpu/raster/glyphRasterizer.ts"],"names":[],"mappings":"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","file":"glyphRasterizer.js","sourceRoot":"file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { memoize } from '../../../../base/common/decorators.js';\nimport { Disposable } from '../../../../base/common/lifecycle.js';\nimport { isMacintosh } from '../../../../base/common/platform.js';\nimport { StringBuilder } from '../../../common/core/stringBuilder.js';\nimport { FontStyle, TokenMetadata } from '../../../common/encodedTokenAttributes.js';\nimport { DecorationStyleCache } from '../css/decorationStyleCache.js';\nimport { ensureNonNullable } from '../gpuUtils.js';\nimport { type IBoundingBox, type IGlyphRasterizer, type IRasterizedGlyph } from './raster.js';\n\nlet nextId = 0;\n\nexport class GlyphRasterizer extends Disposable implements IGlyphRasterizer {\n\tpublic readonly id = nextId++;\n\n\t@memoize\n\tpublic get cacheKey(): string {\n\t\treturn `${this.fontFamily}_${this.fontSize}px`;\n\t}\n\n\tprivate _canvas: OffscreenCanvas;\n\tprivate _ctx: OffscreenCanvasRenderingContext2D;\n\n\tprivate readonly _textMetrics: TextMetrics;\n\n\tprivate _workGlyph: IRasterizedGlyph = {\n\t\tsource: null!,\n\t\tboundingBox: {\n\t\t\tleft: 0,\n\t\t\tbottom: 0,\n\t\t\tright: 0,\n\t\t\ttop: 0,\n\t\t},\n\t\toriginOffset: {\n\t\t\tx: 0,\n\t\t\ty: 0,\n\t\t},\n\t\tfontBoundingBoxAscent: 0,\n\t\tfontBoundingBoxDescent: 0,\n\t};\n\tprivate _workGlyphConfig: { chars: string | undefined; tokenMetadata: number; decorationStyleSetId: number } = { chars: undefined, tokenMetadata: 0, decorationStyleSetId: 0 };\n\n\t// TODO: Support workbench.fontAliasing correctly\n\tprivate _antiAliasing: 'subpixel' | 'greyscale' = isMacintosh ? 'greyscale' : 'subpixel';\n\n\tconstructor(\n\t\treadonly fontSize: number,\n\t\treadonly fontFamily: string,\n\t\treadonly devicePixelRatio: number,\n\t\tprivate readonly _decorationStyleCache: DecorationStyleCache,\n\t) {\n\t\tsuper();\n\n\t\tconst devicePixelFontSize = Math.ceil(this.fontSize * devicePixelRatio);\n\t\tthis._canvas = new OffscreenCanvas(devicePixelFontSize * 3, devicePixelFontSize * 3);\n\t\tthis._ctx = ensureNonNullable(this._canvas.getContext('2d', {\n\t\t\twillReadFrequently: true,\n\t\t\talpha: this._antiAliasing === 'greyscale',\n\t\t}));\n\t\tthis._ctx.textBaseline = 'top';\n\t\tthis._ctx.fillStyle = '#FFFFFF';\n\t\tthis._ctx.font = `${devicePixelFontSize}px ${this.fontFamily}`;\n\t\tthis._textMetrics = this._ctx.measureText('A');\n\t}\n\n\t/**\n\t * Rasterizes a glyph. Note that the returned object is reused across different glyphs and\n\t * therefore is only safe for synchronous access.\n\t */\n\tpublic rasterizeGlyph(\n\t\tchars: string,\n\t\ttokenMetadata: number,\n\t\tdecorationStyleSetId: number,\n\t\tcolorMap: string[],\n\t): Readonly<IRasterizedGlyph> {\n\t\tif (chars === '') {\n\t\t\treturn {\n\t\t\t\tsource: this._canvas,\n\t\t\t\tboundingBox: { top: 0, left: 0, bottom: -1, right: -1 },\n\t\t\t\toriginOffset: { x: 0, y: 0 },\n\t\t\t\tfontBoundingBoxAscent: 0,\n\t\t\t\tfontBoundingBoxDescent: 0,\n\t\t\t};\n\t\t}\n\t\t// Check if the last glyph matches the config, reuse if so. This helps avoid unnecessary\n\t\t// work when the rasterizer is called multiple times like when the glyph doesn't fit into a\n\t\t// page.\n\t\tif (this._workGlyphConfig.chars === chars && this._workGlyphConfig.tokenMetadata === tokenMetadata && this._workGlyphConfig.decorationStyleSetId === decorationStyleSetId) {\n\t\t\treturn this._workGlyph;\n\t\t}\n\t\tthis._workGlyphConfig.chars = chars;\n\t\tthis._workGlyphConfig.tokenMetadata = tokenMetadata;\n\t\tthis._workGlyphConfig.decorationStyleSetId = decorationStyleSetId;\n\t\treturn this._rasterizeGlyph(chars, tokenMetadata, decorationStyleSetId, colorMap);\n\t}\n\n\tpublic _rasterizeGlyph(\n\t\tchars: string,\n\t\ttokenMetadata: number,\n\t\tdecorationStyleSetId: number,\n\t\tcolorMap: string[],\n\t): Readonly<IRasterizedGlyph> {\n\t\tconst devicePixelFontSize = Math.ceil(this.fontSize * this.devicePixelRatio);\n\t\tconst canvasDim = devicePixelFontSize * 3;\n\t\tif (this._canvas.width !== canvasDim) {\n\t\t\tthis._canvas.width = canvasDim;\n\t\t\tthis._canvas.height = canvasDim;\n\t\t}\n\n\t\tthis._ctx.save();\n\n\t\t// The sub-pixel x offset is the fractional part of the x pixel coordinate of the cell, this\n\t\t// is used to improve the spacing between rendered characters.\n\t\tconst subPixelXOffset = (tokenMetadata & 0b1111) / 10;\n\n\t\tconst bgId = TokenMetadata.getBackground(tokenMetadata);\n\t\tconst bg = colorMap[bgId];\n\n\t\tconst decorationStyleSet = this._decorationStyleCache.getStyleSet(decorationStyleSetId);\n\n\t\t// When SPAA is used, the background color must be present to get the right glyph\n\t\tif (this._antiAliasing === 'subpixel') {\n\t\t\tthis._ctx.fillStyle = bg;\n\t\t\tthis._ctx.fillRect(0, 0, this._canvas.width, this._canvas.height);\n\t\t} else {\n\t\t\tthis._ctx.clearRect(0, 0, this._canvas.width, this._canvas.height);\n\t\t}\n\n\t\tconst fontSb = new StringBuilder(200);\n\t\tconst fontStyle = TokenMetadata.getFontStyle(tokenMetadata);\n\t\tif (fontStyle & FontStyle.Italic) {\n\t\t\tfontSb.appendString('italic ');\n\t\t}\n\t\tif (decorationStyleSet?.bold !== undefined) {\n\t\t\tif (decorationStyleSet.bold) {\n\t\t\t\tfontSb.appendString('bold ');\n\t\t\t}\n\t\t} else if (fontStyle & FontStyle.Bold) {\n\t\t\tfontSb.appendString('bold ');\n\t\t}\n\t\tfontSb.appendString(`${devicePixelFontSize}px ${this.fontFamily}`);\n\t\tthis._ctx.font = fontSb.build();\n\n\t\t// TODO: Support FontStyle.Underline text decorations, these need to be drawn manually to\n\t\t// the canvas. See xterm.js for \"dodging\" the text for underlines.\n\n\t\tconst originX = devicePixelFontSize;\n\t\tconst originY = devicePixelFontSize;\n\n\t\t// Apply text color\n\t\tif (decorationStyleSet?.color !== undefined) {\n\t\t\tthis._ctx.fillStyle = `#${decorationStyleSet.color.toString(16).padStart(8, '0')}`;\n\t\t} else {\n\t\t\tthis._ctx.fillStyle = colorMap[TokenMetadata.getForeground(tokenMetadata)];\n\t\t}\n\n\t\t// Apply opacity\n\t\tif (decorationStyleSet?.opacity !== undefined) {\n\t\t\tthis._ctx.globalAlpha = decorationStyleSet.opacity;\n\t\t}\n\n\t\t// The glyph baseline is top, meaning it's drawn at the top-left of the\n\t\t// cell. Add `TextMetrics.alphabeticBaseline` to the drawn position to\n\t\t// get the alphabetic baseline.\n\t\tthis._ctx.textBaseline = 'top';\n\n\t\t// Draw the text\n\t\tthis._ctx.fillText(chars, originX + subPixelXOffset, originY);\n\n\t\t// Draw strikethrough\n\t\tif (decorationStyleSet?.strikethrough) {\n\t\t\t// TODO: This position could be refined further by checking\n\t\t\t// TextMetrics of lowercase letters.\n\t\t\t// Position strikethrough at approximately the vertical center of\n\t\t\t// lowercase letters.\n\t\t\tconst strikethroughY = Math.round(originY - this._textMetrics.alphabeticBaseline * 0.65);\n\t\t\tconst lineWidth = decorationStyleSet?.strikethroughThickness !== undefined\n\t\t\t\t? Math.round(decorationStyleSet.strikethroughThickness * this.devicePixelRatio)\n\t\t\t\t: Math.max(1, Math.floor(devicePixelFontSize / 10));\n\t\t\t// Apply strikethrough color if specified\n\t\t\tif (decorationStyleSet?.strikethroughColor !== undefined) {\n\t\t\t\tthis._ctx.fillStyle = `#${decorationStyleSet.strikethroughColor.toString(16).padStart(8, '0')}`;\n\t\t\t}\n\t\t\t// Intentionally do not apply the sub pixel x offset to\n\t\t\t// strikethrough to ensure successive glyphs form a contiguous line.\n\t\t\tthis._ctx.fillRect(originX, strikethroughY - Math.floor(lineWidth / 2), Math.ceil(this._textMetrics.width), lineWidth);\n\t\t}\n\n\t\tthis._ctx.restore();\n\n\t\t// Extract the image data and clear the background color\n\t\tconst imageData = this._ctx.getImageData(0, 0, this._canvas.width, this._canvas.height);\n\t\tif (this._antiAliasing === 'subpixel') {\n\t\t\tconst bgR = parseInt(bg.substring(1, 3), 16);\n\t\t\tconst bgG = parseInt(bg.substring(3, 5), 16);\n\t\t\tconst bgB = parseInt(bg.substring(5, 7), 16);\n\t\t\tthis._clearColor(imageData, bgR, bgG, bgB);\n\t\t\tthis._ctx.putImageData(imageData, 0, 0);\n\t\t}\n\n\t\t// Find the bounding box\n\t\tthis._findGlyphBoundingBox(imageData, this._workGlyph.boundingBox);\n\n\t\t// const offset = {\n\t\t// \tx: textMetrics.actualBoundingBoxLeft,\n\t\t// \ty: textMetrics.actualBoundingBoxAscent\n\t\t// };\n\t\t// const size = {\n\t\t// \tw: textMetrics.actualBoundingBoxRight + textMetrics.actualBoundingBoxLeft,\n\t\t// \ty: textMetrics.actualBoundingBoxDescent + textMetrics.actualBoundingBoxAscent,\n\t\t// \twInt: Math.ceil(textMetrics.actualBoundingBoxRight + textMetrics.actualBoundingBoxLeft),\n\t\t// \tyInt: Math.ceil(textMetrics.actualBoundingBoxDescent + textMetrics.actualBoundingBoxAscent),\n\t\t// };\n\t\t// console.log(`${chars}_${fg}`, textMetrics, boundingBox, originX, originY, { width: boundingBox.right - boundingBox.left, height: boundingBox.bottom - boundingBox.top });\n\t\tthis._workGlyph.source = this._canvas;\n\t\tthis._workGlyph.originOffset.x = this._workGlyph.boundingBox.left - originX;\n\t\tthis._workGlyph.originOffset.y = this._workGlyph.boundingBox.top - originY;\n\t\tthis._workGlyph.fontBoundingBoxAscent = this._textMetrics.fontBoundingBoxAscent;\n\t\tthis._workGlyph.fontBoundingBoxDescent = this._textMetrics.fontBoundingBoxDescent;\n\n\t\t// const result2: IRasterizedGlyph = {\n\t\t// \tsource: this._canvas,\n\t\t// \tboundingBox: {\n\t\t// \t\tleft: Math.floor(originX - textMetrics.actualBoundingBoxLeft),\n\t\t// \t\tright: Math.ceil(originX + textMetrics.actualBoundingBoxRight),\n\t\t// \t\ttop: Math.floor(originY - textMetrics.actualBoundingBoxAscent),\n\t\t// \t\tbottom: Math.ceil(originY + textMetrics.actualBoundingBoxDescent),\n\t\t// \t},\n\t\t// \toriginOffset: {\n\t\t// \t\tx: Math.floor(boundingBox.left - originX),\n\t\t// \t\ty: Math.floor(boundingBox.top - originY)\n\t\t// \t}\n\t\t// };\n\n\t\t// TODO: Verify result 1 and 2 are the same\n\n\t\t// if (result2.boundingBox.left > result.boundingBox.left) {\n\t\t// \tdebugger;\n\t\t// }\n\t\t// if (result2.boundingBox.top > result.boundingBox.top) {\n\t\t// \tdebugger;\n\t\t// }\n\t\t// if (result2.boundingBox.right < result.boundingBox.right) {\n\t\t// \tdebugger;\n\t\t// }\n\t\t// if (result2.boundingBox.bottom < result.boundingBox.bottom) {\n\t\t// \tdebugger;\n\t\t// }\n\t\t// if (JSON.stringify(result2.originOffset) !== JSON.stringify(result.originOffset)) {\n\t\t// \tdebugger;\n\t\t// }\n\n\n\n\t\treturn this._workGlyph;\n\t}\n\n\tprivate _clearColor(imageData: ImageData, r: number, g: number, b: number) {\n\t\tfor (let offset = 0; offset < imageData.data.length; offset += 4) {\n\t\t\t// Check exact match\n\t\t\tif (imageData.data[offset] === r &&\n\t\t\t\timageData.data[offset + 1] === g &&\n\t\t\t\timageData.data[offset + 2] === b) {\n\t\t\t\timageData.data[offset + 3] = 0;\n\t\t\t}\n\t\t}\n\t}\n\n\t// TODO: Does this even need to happen when measure text is used?\n\tprivate _findGlyphBoundingBox(imageData: ImageData, outBoundingBox: IBoundingBox) {\n\t\tconst height = this._canvas.height;\n\t\tconst width = this._canvas.width;\n\t\tlet found = false;\n\t\tfor (let y = 0; y < height; y++) {\n\t\t\tfor (let x = 0; x < width; x++) {\n\t\t\t\tconst alphaOffset = y * width * 4 + x * 4 + 3;\n\t\t\t\tif (imageData.data[alphaOffset] !== 0) {\n\t\t\t\t\toutBoundingBox.top = y;\n\t\t\t\t\tfound = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (found) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\toutBoundingBox.left = 0;\n\t\tfound = false;\n\t\tfor (let x = 0; x < width; x++) {\n\t\t\tfor (let y = 0; y < height; y++) {\n\t\t\t\tconst alphaOffset = y * width * 4 + x * 4 + 3;\n\t\t\t\tif (imageData.data[alphaOffset] !== 0) {\n\t\t\t\t\toutBoundingBox.left = x;\n\t\t\t\t\tfound = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (found) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\toutBoundingBox.right = width;\n\t\tfound = false;\n\t\tfor (let x = width - 1; x >= outBoundingBox.left; x--) {\n\t\t\tfor (let y = 0; y < height; y++) {\n\t\t\t\tconst alphaOffset = y * width * 4 + x * 4 + 3;\n\t\t\t\tif (imageData.data[alphaOffset] !== 0) {\n\t\t\t\t\toutBoundingBox.right = x;\n\t\t\t\t\tfound = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (found) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\toutBoundingBox.bottom = outBoundingBox.top;\n\t\tfound = false;\n\t\tfor (let y = height - 1; y >= 0; y--) {\n\t\t\tfor (let x = 0; x < width; x++) {\n\t\t\t\tconst alphaOffset = y * width * 4 + x * 4 + 3;\n\t\t\t\tif (imageData.data[alphaOffset] !== 0) {\n\t\t\t\t\toutBoundingBox.bottom = y;\n\t\t\t\t\tfound = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (found) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic getTextMetrics(text: string): TextMetrics {\n\t\treturn this._ctx.measureText(text);\n\t}\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { memoize } from '../../../../base/common/decorators.js';\nimport { Disposable } from '../../../../base/common/lifecycle.js';\nimport { isMacintosh } from '../../../../base/common/platform.js';\nimport { StringBuilder } from '../../../common/core/stringBuilder.js';\nimport { FontStyle, TokenMetadata } from '../../../common/encodedTokenAttributes.js';\nimport { DecorationStyleCache } from '../css/decorationStyleCache.js';\nimport { ensureNonNullable } from '../gpuUtils.js';\nimport { type IBoundingBox, type IGlyphRasterizer, type IRasterizedGlyph } from './raster.js';\n\nlet nextId = 0;\n\nexport class GlyphRasterizer extends Disposable implements IGlyphRasterizer {\n\tpublic readonly id = nextId++;\n\n\t@memoize\n\tpublic get cacheKey(): string {\n\t\treturn `${this.fontFamily}_${this.fontSize}px`;\n\t}\n\n\tprivate _canvas: OffscreenCanvas;\n\tprivate _ctx: OffscreenCanvasRenderingContext2D;\n\n\tprivate readonly _textMetrics: TextMetrics;\n\n\tprivate _workGlyph: IRasterizedGlyph = {\n\t\tsource: null!,\n\t\tboundingBox: {\n\t\t\tleft: 0,\n\t\t\tbottom: 0,\n\t\t\tright: 0,\n\t\t\ttop: 0,\n\t\t},\n\t\toriginOffset: {\n\t\t\tx: 0,\n\t\t\ty: 0,\n\t\t},\n\t\tfontBoundingBoxAscent: 0,\n\t\tfontBoundingBoxDescent: 0,\n\t};\n\tprivate _workGlyphConfig: { chars: string | undefined; tokenMetadata: number; decorationStyleSetId: number } = { chars: undefined, tokenMetadata: 0, decorationStyleSetId: 0 };\n\n\t// TODO: Support workbench.fontAliasing correctly\n\tprivate _antiAliasing: 'subpixel' | 'greyscale' = isMacintosh ? 'greyscale' : 'subpixel';\n\n\tconstructor(\n\t\treadonly fontSize: number,\n\t\treadonly fontFamily: string,\n\t\treadonly devicePixelRatio: number,\n\t\tprivate readonly _decorationStyleCache: DecorationStyleCache,\n\t) {\n\t\tsuper();\n\n\t\tconst devicePixelFontSize = Math.ceil(this.fontSize * devicePixelRatio);\n\t\tthis._canvas = new OffscreenCanvas(devicePixelFontSize * 3, devicePixelFontSize * 3);\n\t\tthis._ctx = ensureNonNullable(this._canvas.getContext('2d', {\n\t\t\twillReadFrequently: true,\n\t\t\talpha: this._antiAliasing === 'greyscale',\n\t\t}));\n\t\tthis._ctx.textBaseline = 'top';\n\t\tthis._ctx.fillStyle = '#FFFFFF';\n\t\tthis._ctx.font = `${devicePixelFontSize}px ${this.fontFamily}`;\n\t\tthis._textMetrics = this._ctx.measureText('A');\n\t}\n\n\t/**\n\t * Rasterizes a glyph. Note that the returned object is reused across different glyphs and\n\t * therefore is only safe for synchronous access.\n\t */\n\tpublic rasterizeGlyph(\n\t\tchars: string,\n\t\ttokenMetadata: number,\n\t\tdecorationStyleSetId: number,\n\t\tcolorMap: string[],\n\t): Readonly<IRasterizedGlyph> {\n\t\tif (chars === '') {\n\t\t\treturn {\n\t\t\t\tsource: this._canvas,\n\t\t\t\tboundingBox: { top: 0, left: 0, bottom: -1, right: -1 },\n\t\t\t\toriginOffset: { x: 0, y: 0 },\n\t\t\t\tfontBoundingBoxAscent: 0,\n\t\t\t\tfontBoundingBoxDescent: 0,\n\t\t\t};\n\t\t}\n\t\t// Check if the last glyph matches the config, reuse if so. This helps avoid unnecessary\n\t\t// work when the rasterizer is called multiple times like when the glyph doesn't fit into a\n\t\t// page.\n\t\tif (this._workGlyphConfig.chars === chars && this._workGlyphConfig.tokenMetadata === tokenMetadata && this._workGlyphConfig.decorationStyleSetId === decorationStyleSetId) {\n\t\t\treturn this._workGlyph;\n\t\t}\n\t\tthis._workGlyphConfig.chars = chars;\n\t\tthis._workGlyphConfig.tokenMetadata = tokenMetadata;\n\t\tthis._workGlyphConfig.decorationStyleSetId = decorationStyleSetId;\n\t\treturn this._rasterizeGlyph(chars, tokenMetadata, decorationStyleSetId, colorMap);\n\t}\n\n\tpublic _rasterizeGlyph(\n\t\tchars: string,\n\t\ttokenMetadata: number,\n\t\tdecorationStyleSetId: number,\n\t\tcolorMap: string[],\n\t): Readonly<IRasterizedGlyph> {\n\t\tconst devicePixelFontSize = Math.ceil(this.fontSize * this.devicePixelRatio);\n\t\tconst canvasDim = devicePixelFontSize * 3;\n\t\tif (this._canvas.width !== canvasDim) {\n\t\t\tthis._canvas.width = canvasDim;\n\t\t\tthis._canvas.height = canvasDim;\n\t\t}\n\n\t\tthis._ctx.save();\n\n\t\t// The sub-pixel x offset is the fractional part of the x pixel coordinate of the cell, this\n\t\t// is used to improve the spacing between rendered characters.\n\t\tconst subPixelXOffset = (tokenMetadata & 0b1111) / 10;\n\n\t\tconst bgId = TokenMetadata.getBackground(tokenMetadata);\n\t\tconst bg = colorMap[bgId];\n\n\t\tconst decorationStyleSet = this._decorationStyleCache.getStyleSet(decorationStyleSetId);\n\n\t\t// When SPAA is used, the background color must be present to get the right glyph\n\t\tif (this._antiAliasing === 'subpixel') {\n\t\t\tthis._ctx.fillStyle = bg;\n\t\t\tthis._ctx.fillRect(0, 0, this._canvas.width, this._canvas.height);\n\t\t} else {\n\t\t\tthis._ctx.clearRect(0, 0, this._canvas.width, this._canvas.height);\n\t\t}\n\n\t\tconst fontSb = new StringBuilder(200);\n\t\tconst fontStyle = TokenMetadata.getFontStyle(tokenMetadata);\n\t\tif (fontStyle & FontStyle.Italic) {\n\t\t\tfontSb.appendString('italic ');\n\t\t}\n\t\tif (decorationStyleSet?.bold !== undefined) {\n\t\t\tif (decorationStyleSet.bold) {\n\t\t\t\tfontSb.appendString('bold ');\n\t\t\t}\n\t\t} else if (fontStyle & FontStyle.Bold) {\n\t\t\tfontSb.appendString('bold ');\n\t\t}\n\t\tfontSb.appendString(`${devicePixelFontSize}px ${this.fontFamily}`);\n\t\tthis._ctx.font = fontSb.build();\n\n\t\t// TODO: Support FontStyle.Underline text decorations, these need to be drawn manually to\n\t\t// the canvas. See xterm.js for \"dodging\" the text for underlines.\n\n\t\tconst originX = devicePixelFontSize;\n\t\tconst originY = devicePixelFontSize;\n\n\t\t// Apply text color\n\t\tif (decorationStyleSet?.color !== undefined) {\n\t\t\tthis._ctx.fillStyle = `#${decorationStyleSet.color.toString(16).padStart(8, '0')}`;\n\t\t} else {\n\t\t\tthis._ctx.fillStyle = colorMap[TokenMetadata.getForeground(tokenMetadata)];\n\t\t}\n\n\t\t// Apply opacity\n\t\tif (decorationStyleSet?.opacity !== undefined) {\n\t\t\tthis._ctx.globalAlpha = decorationStyleSet.opacity;\n\t\t}\n\n\t\t// The glyph baseline is top, meaning it's drawn at the top-left of the\n\t\t// cell. Add `TextMetrics.alphabeticBaseline` to the drawn position to\n\t\t// get the alphabetic baseline.\n\t\tthis._ctx.textBaseline = 'top';\n\n\t\t// Draw the text\n\t\tthis._ctx.fillText(chars, originX + subPixelXOffset, originY);\n\n\t\t// Draw strikethrough\n\t\tif (decorationStyleSet?.strikethrough) {\n\t\t\t// TODO: This position could be refined further by checking\n\t\t\t// TextMetrics of lowercase letters.\n\t\t\t// Position strikethrough at approximately the vertical center of\n\t\t\t// lowercase letters.\n\t\t\tconst strikethroughY = Math.round(originY - this._textMetrics.alphabeticBaseline * 0.65);\n\t\t\tconst lineWidth = decorationStyleSet?.strikethroughThickness !== undefined\n\t\t\t\t? Math.round(decorationStyleSet.strikethroughThickness * this.devicePixelRatio)\n\t\t\t\t: Math.max(1, Math.floor(devicePixelFontSize / 10));\n\t\t\t// Apply strikethrough color if specified\n\t\t\tif (decorationStyleSet?.strikethroughColor !== undefined) {\n\t\t\t\tthis._ctx.fillStyle = `#${decorationStyleSet.strikethroughColor.toString(16).padStart(8, '0')}`;\n\t\t\t}\n\t\t\t// Intentionally do not apply the sub pixel x offset to\n\t\t\t// strikethrough to ensure successive glyphs form a contiguous line.\n\t\t\tthis._ctx.fillRect(originX, strikethroughY - Math.floor(lineWidth / 2), Math.ceil(this._textMetrics.width), lineWidth);\n\t\t}\n\n\t\tthis._ctx.restore();\n\n\t\t// Extract the image data and clear the background color\n\t\tconst imageData = this._ctx.getImageData(0, 0, this._canvas.width, this._canvas.height);\n\t\tif (this._antiAliasing === 'subpixel') {\n\t\t\tconst bgR = parseInt(bg.substring(1, 3), 16);\n\t\t\tconst bgG = parseInt(bg.substring(3, 5), 16);\n\t\t\tconst bgB = parseInt(bg.substring(5, 7), 16);\n\t\t\tthis._clearColor(imageData, bgR, bgG, bgB);\n\t\t\tthis._ctx.putImageData(imageData, 0, 0);\n\t\t}\n\n\t\t// Find the bounding box\n\t\tthis._findGlyphBoundingBox(imageData, this._workGlyph.boundingBox);\n\n\t\t// const offset = {\n\t\t// \tx: textMetrics.actualBoundingBoxLeft,\n\t\t// \ty: textMetrics.actualBoundingBoxAscent\n\t\t// };\n\t\t// const size = {\n\t\t// \tw: textMetrics.actualBoundingBoxRight + textMetrics.actualBoundingBoxLeft,\n\t\t// \ty: textMetrics.actualBoundingBoxDescent + textMetrics.actualBoundingBoxAscent,\n\t\t// \twInt: Math.ceil(textMetrics.actualBoundingBoxRight + textMetrics.actualBoundingBoxLeft),\n\t\t// \tyInt: Math.ceil(textMetrics.actualBoundingBoxDescent + textMetrics.actualBoundingBoxAscent),\n\t\t// };\n\t\t// console.log(`${chars}_${fg}`, textMetrics, boundingBox, originX, originY, { width: boundingBox.right - boundingBox.left, height: boundingBox.bottom - boundingBox.top });\n\t\tthis._workGlyph.source = this._canvas;\n\t\tthis._workGlyph.originOffset.x = this._workGlyph.boundingBox.left - originX;\n\t\tthis._workGlyph.originOffset.y = this._workGlyph.boundingBox.top - originY;\n\t\tthis._workGlyph.fontBoundingBoxAscent = this._textMetrics.fontBoundingBoxAscent;\n\t\tthis._workGlyph.fontBoundingBoxDescent = this._textMetrics.fontBoundingBoxDescent;\n\n\t\t// const result2: IRasterizedGlyph = {\n\t\t// \tsource: this._canvas,\n\t\t// \tboundingBox: {\n\t\t// \t\tleft: Math.floor(originX - textMetrics.actualBoundingBoxLeft),\n\t\t// \t\tright: Math.ceil(originX + textMetrics.actualBoundingBoxRight),\n\t\t// \t\ttop: Math.floor(originY - textMetrics.actualBoundingBoxAscent),\n\t\t// \t\tbottom: Math.ceil(originY + textMetrics.actualBoundingBoxDescent),\n\t\t// \t},\n\t\t// \toriginOffset: {\n\t\t// \t\tx: Math.floor(boundingBox.left - originX),\n\t\t// \t\ty: Math.floor(boundingBox.top - originY)\n\t\t// \t}\n\t\t// };\n\n\t\t// TODO: Verify result 1 and 2 are the same\n\n\t\t// if (result2.boundingBox.left > result.boundingBox.left) {\n\t\t// \tdebugger;\n\t\t// }\n\t\t// if (result2.boundingBox.top > result.boundingBox.top) {\n\t\t// \tdebugger;\n\t\t// }\n\t\t// if (result2.boundingBox.right < result.boundingBox.right) {\n\t\t// \tdebugger;\n\t\t// }\n\t\t// if (result2.boundingBox.bottom < result.boundingBox.bottom) {\n\t\t// \tdebugger;\n\t\t// }\n\t\t// if (JSON.stringify(result2.originOffset) !== JSON.stringify(result.originOffset)) {\n\t\t// \tdebugger;\n\t\t// }\n\n\n\n\t\treturn this._workGlyph;\n\t}\n\n\tprivate _clearColor(imageData: ImageData, r: number, g: number, b: number) {\n\t\tfor (let offset = 0; offset < imageData.data.length; offset += 4) {\n\t\t\t// Check exact match\n\t\t\tif (imageData.data[offset] === r &&\n\t\t\t\timageData.data[offset + 1] === g &&\n\t\t\t\timageData.data[offset + 2] === b) {\n\t\t\t\timageData.data[offset + 3] = 0;\n\t\t\t}\n\t\t}\n\t}\n\n\t// TODO: Does this even need to happen when measure text is used?\n\tprivate _findGlyphBoundingBox(imageData: ImageData, outBoundingBox: IBoundingBox) {\n\t\tconst height = this._canvas.height;\n\t\tconst width = this._canvas.width;\n\t\tlet found = false;\n\t\tfor (let y = 0; y < height; y++) {\n\t\t\tfor (let x = 0; x < width; x++) {\n\t\t\t\tconst alphaOffset = y * width * 4 + x * 4 + 3;\n\t\t\t\tif (imageData.data[alphaOffset] !== 0) {\n\t\t\t\t\toutBoundingBox.top = y;\n\t\t\t\t\tfound = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (found) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\toutBoundingBox.left = 0;\n\t\tfound = false;\n\t\tfor (let x = 0; x < width; x++) {\n\t\t\tfor (let y = 0; y < height; y++) {\n\t\t\t\tconst alphaOffset = y * width * 4 + x * 4 + 3;\n\t\t\t\tif (imageData.data[alphaOffset] !== 0) {\n\t\t\t\t\toutBoundingBox.left = x;\n\t\t\t\t\tfound = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (found) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\toutBoundingBox.right = width;\n\t\tfound = false;\n\t\tfor (let x = width - 1; x >= outBoundingBox.left; x--) {\n\t\t\tfor (let y = 0; y < height; y++) {\n\t\t\t\tconst alphaOffset = y * width * 4 + x * 4 + 3;\n\t\t\t\tif (imageData.data[alphaOffset] !== 0) {\n\t\t\t\t\toutBoundingBox.right = x;\n\t\t\t\t\tfound = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (found) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\toutBoundingBox.bottom = outBoundingBox.top;\n\t\tfound = false;\n\t\tfor (let y = height - 1; y >= 0; y--) {\n\t\t\tfor (let x = 0; x < width; x++) {\n\t\t\t\tconst alphaOffset = y * width * 4 + x * 4 + 3;\n\t\t\t\tif (imageData.data[alphaOffset] !== 0) {\n\t\t\t\t\toutBoundingBox.bottom = y;\n\t\t\t\t\tfound = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (found) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic getTextMetrics(text: string): TextMetrics {\n\t\treturn this._ctx.measureText(text);\n\t}\n}\n"]}
|
|
@@ -176,6 +176,9 @@ export class FullFileRenderStrategy extends BaseRenderStrategy {
|
|
|
176
176
|
let decorationStyleSetBold;
|
|
177
177
|
let decorationStyleSetColor;
|
|
178
178
|
let decorationStyleSetOpacity;
|
|
179
|
+
let decorationStyleSetStrikethrough;
|
|
180
|
+
let decorationStyleSetStrikethroughThickness;
|
|
181
|
+
let decorationStyleSetStrikethroughColor;
|
|
179
182
|
let lineData;
|
|
180
183
|
let decoration;
|
|
181
184
|
let fillStartIndex = 0;
|
|
@@ -271,6 +274,9 @@ export class FullFileRenderStrategy extends BaseRenderStrategy {
|
|
|
271
274
|
decorationStyleSetColor = undefined;
|
|
272
275
|
decorationStyleSetBold = undefined;
|
|
273
276
|
decorationStyleSetOpacity = undefined;
|
|
277
|
+
decorationStyleSetStrikethrough = undefined;
|
|
278
|
+
decorationStyleSetStrikethroughThickness = undefined;
|
|
279
|
+
decorationStyleSetStrikethroughColor = undefined;
|
|
274
280
|
// Apply supported inline decoration styles to the cell metadata
|
|
275
281
|
for (decoration of lineData.inlineDecorations) {
|
|
276
282
|
// This is Range.strictContainsPosition except it works at the cell level,
|
|
@@ -312,6 +318,36 @@ export class FullFileRenderStrategy extends BaseRenderStrategy {
|
|
|
312
318
|
decorationStyleSetOpacity = parsedValue;
|
|
313
319
|
break;
|
|
314
320
|
}
|
|
321
|
+
case 'text-decoration':
|
|
322
|
+
case 'text-decoration-line': {
|
|
323
|
+
if (value === 'line-through') {
|
|
324
|
+
decorationStyleSetStrikethrough = true;
|
|
325
|
+
}
|
|
326
|
+
break;
|
|
327
|
+
}
|
|
328
|
+
case 'text-decoration-thickness': {
|
|
329
|
+
const match = value.match(/^(\d+(?:\.\d+)?)px$/);
|
|
330
|
+
if (match) {
|
|
331
|
+
decorationStyleSetStrikethroughThickness = parseFloat(match[1]);
|
|
332
|
+
}
|
|
333
|
+
break;
|
|
334
|
+
}
|
|
335
|
+
case 'text-decoration-color': {
|
|
336
|
+
let colorValue = value;
|
|
337
|
+
const varMatch = value.match(/^var\((--[^,]+),\s*(?:initial|inherit)\)$/);
|
|
338
|
+
if (varMatch) {
|
|
339
|
+
colorValue = ViewGpuContext.decorationCssRuleExtractor.resolveCssVariable(this._viewGpuContext.canvas.domNode, varMatch[1]);
|
|
340
|
+
}
|
|
341
|
+
const parsedColor = Color.Format.CSS.parse(colorValue);
|
|
342
|
+
if (parsedColor) {
|
|
343
|
+
decorationStyleSetStrikethroughColor = parsedColor.toNumber32Bit();
|
|
344
|
+
}
|
|
345
|
+
break;
|
|
346
|
+
}
|
|
347
|
+
case 'text-decoration-style': {
|
|
348
|
+
// These are validated in canRender and use default behavior
|
|
349
|
+
break;
|
|
350
|
+
}
|
|
315
351
|
default: throw new BugIndicatingError('Unexpected inline decoration style');
|
|
316
352
|
}
|
|
317
353
|
}
|
|
@@ -335,7 +371,7 @@ export class FullFileRenderStrategy extends BaseRenderStrategy {
|
|
|
335
371
|
}
|
|
336
372
|
continue;
|
|
337
373
|
}
|
|
338
|
-
const decorationStyleSetId = ViewGpuContext.decorationStyleCache.getOrCreateEntry(decorationStyleSetColor, decorationStyleSetBold, decorationStyleSetOpacity);
|
|
374
|
+
const decorationStyleSetId = ViewGpuContext.decorationStyleCache.getOrCreateEntry(decorationStyleSetColor, decorationStyleSetBold, decorationStyleSetOpacity, decorationStyleSetStrikethrough, decorationStyleSetStrikethroughThickness, decorationStyleSetStrikethroughColor);
|
|
339
375
|
glyph = this._viewGpuContext.atlas.getGlyph(this.glyphRasterizer, chars, tokenMetadata, decorationStyleSetId, absoluteOffsetX);
|
|
340
376
|
absoluteOffsetY = Math.round(
|
|
341
377
|
// Top of layout box (includes line height)
|