Skip to content

Commit

Permalink
Merge pull request microsoft#237822 from microsoft/tyriar/233990_opacity
Browse files Browse the repository at this point in the history
Support opacity in inline decorations
  • Loading branch information
Tyriar authored Jan 13, 2025
2 parents 79a7006 + c9209be commit 5bd3d12
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 3 deletions.
13 changes: 11 additions & 2 deletions src/vs/editor/browser/gpu/css/decorationStyleCache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ export interface IDecorationStyleSet {
* Whether the text should be rendered in bold.
*/
bold: boolean | undefined;
/**
* A number between 0 and 1 representing the opacity of the text.
*/
opacity: number | undefined;
}

export interface IDecorationStyleCacheEntry extends IDecorationStyleSet {
Expand All @@ -27,15 +31,20 @@ export class DecorationStyleCache {

private readonly _cache = new Map<number, IDecorationStyleSet>();

getOrCreateEntry(color: number | undefined, bold: boolean | undefined): number {
if (color === undefined && bold === undefined) {
getOrCreateEntry(
color: number | undefined,
bold: boolean | undefined,
opacity: number | undefined
): number {
if (color === undefined && bold === undefined && opacity === undefined) {
return 0;
}
const id = this._nextId++;
const entry = {
id,
color,
bold,
opacity,
};
this._cache.set(id, entry);
return id;
Expand Down
19 changes: 18 additions & 1 deletion src/vs/editor/browser/gpu/fullFileRenderStrategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,7 @@ export class FullFileRenderStrategy extends ViewEventHandler implements IGpuRend

let decorationStyleSetBold: boolean | undefined;
let decorationStyleSetColor: number | undefined;
let decorationStyleSetOpacity: number | undefined;

let lineData: ViewLineRenderingData;
let decoration: InlineDecoration;
Expand Down Expand Up @@ -363,6 +364,7 @@ export class FullFileRenderStrategy extends ViewEventHandler implements IGpuRend
chars = content.charAt(x);
decorationStyleSetColor = undefined;
decorationStyleSetBold = undefined;
decorationStyleSetOpacity = undefined;

// Apply supported inline decoration styles to the cell metadata
for (decoration of lineData.inlineDecorations) {
Expand Down Expand Up @@ -402,6 +404,11 @@ export class FullFileRenderStrategy extends ViewEventHandler implements IGpuRend
}
break;
}
case 'opacity': {
const parsedValue = parseCssOpacity(value);
decorationStyleSetOpacity = parsedValue;
break;
}
default: throw new BugIndicatingError('Unexpected inline decoration style');
}
}
Expand All @@ -419,7 +426,7 @@ export class FullFileRenderStrategy extends ViewEventHandler implements IGpuRend
continue;
}

const decorationStyleSetId = ViewGpuContext.decorationStyleCache.getOrCreateEntry(decorationStyleSetColor, decorationStyleSetBold);
const decorationStyleSetId = ViewGpuContext.decorationStyleCache.getOrCreateEntry(decorationStyleSetColor, decorationStyleSetBold, decorationStyleSetOpacity);
glyph = this._viewGpuContext.atlas.getGlyph(this._glyphRasterizer.value, chars, tokenMetadata, decorationStyleSetId);

// TODO: Support non-standard character widths
Expand Down Expand Up @@ -511,3 +518,13 @@ function parseCssFontWeight(value: string) {
}
return parseInt(value);
}

function parseCssOpacity(value: string): number {
if (value.endsWith('%')) {
return parseFloat(value.substring(0, value.length - 1)) / 100;
}
if (value.match(/^\d+(?:\.\d*)/)) {
return parseFloat(value);
}
return 1;
}
7 changes: 7 additions & 0 deletions src/vs/editor/browser/gpu/raster/glyphRasterizer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ export class GlyphRasterizer extends Disposable implements IGlyphRasterizer {
this._canvas.height = canvasDim;
}

this._ctx.save();

const decorationStyleSet = ViewGpuContext.decorationStyleCache.getStyleSet(decorationStyleSetId);

// TODO: Support workbench.fontAliasing
Expand Down Expand Up @@ -139,7 +141,12 @@ export class GlyphRasterizer extends Disposable implements IGlyphRasterizer {
}
this._ctx.textBaseline = 'top';

if (decorationStyleSet?.opacity !== undefined) {
this._ctx.globalAlpha = decorationStyleSet.opacity;
}

this._ctx.fillText(chars, originX, originY);
this._ctx.restore();

const imageData = this._ctx.getImageData(0, 0, this._canvas.width, this._canvas.height);
this._findGlyphBoundingBox(imageData, this._workGlyph.boundingBox);
Expand Down
1 change: 1 addition & 0 deletions src/vs/editor/browser/gpu/viewGpuContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,7 @@ export class ViewGpuContext extends Disposable {
const gpuSupportedDecorationCssRules = [
'color',
'font-weight',
'opacity',
];

function supportsCssRule(rule: string, style: CSSStyleDeclaration) {
Expand Down

0 comments on commit 5bd3d12

Please sign in to comment.