Skip to content

Commit

Permalink
Merge pull request #4526 from Tyriar/4499_overline
Browse files Browse the repository at this point in the history
Add support for SGR 53 overline and SGR 55 not overline
  • Loading branch information
Tyriar committed May 20, 2023
2 parents e9b0593 + eb56356 commit cdec1e5
Show file tree
Hide file tree
Showing 9 changed files with 57 additions and 4 deletions.
10 changes: 10 additions & 0 deletions css/xterm.css
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,16 @@
.xterm-underline-4 { text-decoration: dotted underline; }
.xterm-underline-5 { text-decoration: dashed underline; }

.xterm-overline {
text-decoration: overline;
}

.xterm-overline.xterm-underline-1 { text-decoration: overline underline; }
.xterm-overline.xterm-underline-2 { text-decoration: overline double underline; }
.xterm-overline.xterm-underline-3 { text-decoration: overline wavy underline; }
.xterm-overline.xterm-underline-4 { text-decoration: overline dotted underline; }
.xterm-overline.xterm-underline-5 { text-decoration: overline dashed underline; }

.xterm-strikethrough {
text-decoration: line-through;
}
Expand Down
7 changes: 5 additions & 2 deletions demo/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -976,7 +976,9 @@ function sgrTest(): void {
{ ps: 45, name: 'Background Magenta' },
{ ps: 46, name: 'Background Cyan' },
{ ps: 47, name: 'Background White' },
{ ps: 49, name: 'Background default' }
{ ps: 49, name: 'Background default' },
{ ps: 53, name: 'Overlined' },
{ ps: 55, name: 'Not overlined' }
];
const maxNameLength = entries.reduce<number>((p, c) => Math.max(c.name.length, p), 0);
for (const e of entries) {
Expand All @@ -988,7 +990,8 @@ function sgrTest(): void {
}
const comboEntries: { ps: number[] }[] = [
{ ps: [1, 2, 3, 4, 5, 6, 7, 9] },
{ ps: [2, 41] }
{ ps: [2, 41] },
{ ps: [4, 53] }
];
term.write('\n\n\r');
term.writeln(`Combinations`);
Expand Down
10 changes: 10 additions & 0 deletions src/browser/renderer/dom/DomRendererRowFactory.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,16 @@ describe('DomRendererRowFactory', () => {
});
});

it('should add class for overline', () => {
const cell = CellData.fromCharData([0, 'a', 1, 'a'.charCodeAt(0)]);
cell.bg = DEFAULT_ATTR_DATA.bg | BgFlags.OVERLINE;
lineData.setCell(0, cell);
const fragment = rowFactory.createRow(lineData, 0, false, undefined, 0, false, 5, 20, EMPTY_ELEM_MAPPING);
assert.equal(getFragmentHtml(fragment),
'<span class="xterm-overline">a</span>'
);
});

it('should add class for strikethrough', () => {
const cell = CellData.fromCharData([0, 'a', 1, 'a'.charCodeAt(0)]);
cell.fg = DEFAULT_ATTR_DATA.fg | FgFlags.STRIKETHROUGH;
Expand Down
8 changes: 8 additions & 0 deletions src/browser/renderer/dom/DomRendererRowFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export const BOLD_CLASS = 'xterm-bold';
export const DIM_CLASS = 'xterm-dim';
export const ITALIC_CLASS = 'xterm-italic';
export const UNDERLINE_CLASS = 'xterm-underline';
export const OVERLINE_CLASS = 'xterm-overline';
export const STRIKETHROUGH_CLASS = 'xterm-strikethrough';
export const CURSOR_CLASS = 'xterm-cursor';
export const CURSOR_BLINK_CLASS = 'xterm-cursor-blink';
Expand Down Expand Up @@ -185,6 +186,13 @@ export class DomRendererRowFactory {
}
}

if (cell.isOverline()) {
charElement.classList.add(OVERLINE_CLASS);
if (charElement.textContent === ' ') {
charElement.textContent = '\xa0'; // = &nbsp;
}
}

if (cell.isStrikethrough()) {
charElement.classList.add(STRIKETHROUGH_CLASS);
}
Expand Down
15 changes: 14 additions & 1 deletion src/browser/renderer/shared/TextureAtlas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,7 @@ export class TextureAtlas implements ITextureAtlas {
const italic = !!this._workAttributeData.isItalic();
const underline = !!this._workAttributeData.isUnderline();
const strikethrough = !!this._workAttributeData.isStrikethrough();
const overline = !!this._workAttributeData.isOverline();
let fgColor = this._workAttributeData.getFgColor();
let fgColorMode = this._workAttributeData.getFgColorMode();
let bgColor = this._workAttributeData.getBgColor();
Expand Down Expand Up @@ -632,12 +633,24 @@ export class TextureAtlas implements ITextureAtlas {
}
}

// Overline
if (overline) {
const lineWidth = Math.max(1, Math.floor(this._config.fontSize * this._config.devicePixelRatio / 15));
const yOffset = lineWidth % 2 === 1 ? 0.5 : 0;
this._tmpCtx.lineWidth = lineWidth;
this._tmpCtx.strokeStyle = this._tmpCtx.fillStyle;
this._tmpCtx.beginPath();
this._tmpCtx.moveTo(padding, padding + yOffset);
this._tmpCtx.lineTo(padding + this._config.deviceCharWidth * chWidth, padding + yOffset);
this._tmpCtx.stroke();
}

// Draw the character
if (!customGlyph) {
this._tmpCtx.fillText(chars, padding, padding + this._config.deviceCharHeight);
}

// If this charcater is underscore and beyond the cell bounds, shift it up until it is visible
// If this character is underscore and beyond the cell bounds, shift it up until it is visible
// even on the bottom row, try for a maximum of 5 pixels.
if (chars === '_' && !this._config.allowTransparency) {
let isBeyondCellBounds = clearColor(this._tmpCtx.getImageData(padding, padding, this._config.deviceCellWidth, this._config.deviceCellHeight), backgroundColor, foregroundColor, enableClearThresholdCheck);
Expand Down
6 changes: 6 additions & 0 deletions src/common/InputHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2551,6 +2551,12 @@ export class InputHandler extends Disposable implements IInputHandler {
} else if (p === 38 || p === 48 || p === 58) {
// fg color 256 and RGB
i += this._extractColor(params, i, attr);
} else if (p === 53) {
// overline
attr.bg |= BgFlags.OVERLINE;
} else if (p === 55) {
// not overline
attr.bg &= ~BgFlags.OVERLINE;
} else if (p === 59) {
attr.extended = attr.extended.clone();
attr.extended.underlineColor = -1;
Expand Down
1 change: 1 addition & 0 deletions src/common/Types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ export interface IAttributeData {
isDim(): number;
isStrikethrough(): number;
isProtected(): number;
isOverline(): number;

/**
* The color mode of the foreground color which determines how to decode {@link getFgColor},
Expand Down
1 change: 1 addition & 0 deletions src/common/buffer/AttributeData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export class AttributeData implements IAttributeData {
public isDim(): number { return this.bg & BgFlags.DIM; }
public isStrikethrough(): number { return this.fg & FgFlags.STRIKETHROUGH; }
public isProtected(): number { return this.bg & BgFlags.PROTECTED; }
public isOverline(): number { return this.bg & BgFlags.OVERLINE; }

// color modes
public getFgColorMode(): number { return this.fg & Attributes.CM_MASK; }
Expand Down
3 changes: 2 additions & 1 deletion src/common/buffer/Constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,8 @@ export const enum BgFlags {
ITALIC = 0x4000000,
DIM = 0x8000000,
HAS_EXTENDED = 0x10000000,
PROTECTED = 0x20000000
PROTECTED = 0x20000000,
OVERLINE = 0x40000000
}

export const enum ExtFlags {
Expand Down

0 comments on commit cdec1e5

Please sign in to comment.