Path: blob/main/src/vs/editor/browser/config/charWidthReader.ts
3294 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { applyFontInfo } from './domFontInfo.js';6import { BareFontInfo } from '../../common/config/fontInfo.js';78export const enum CharWidthRequestType {9Regular = 0,10Italic = 1,11Bold = 212}1314export class CharWidthRequest {1516public readonly chr: string;17public readonly type: CharWidthRequestType;18public width: number;1920constructor(chr: string, type: CharWidthRequestType) {21this.chr = chr;22this.type = type;23this.width = 0;24}2526public fulfill(width: number) {27this.width = width;28}29}3031class DomCharWidthReader {3233private readonly _bareFontInfo: BareFontInfo;34private readonly _requests: CharWidthRequest[];3536private _container: HTMLElement | null;37private _testElements: HTMLSpanElement[] | null;3839constructor(bareFontInfo: BareFontInfo, requests: CharWidthRequest[]) {40this._bareFontInfo = bareFontInfo;41this._requests = requests;4243this._container = null;44this._testElements = null;45}4647public read(targetWindow: Window): void {48// Create a test container with all these test elements49this._createDomElements();5051// Add the container to the DOM52targetWindow.document.body.appendChild(this._container!);5354// Read character widths55this._readFromDomElements();5657// Remove the container from the DOM58this._container?.remove();5960this._container = null;61this._testElements = null;62}6364private _createDomElements(): void {65const container = document.createElement('div');66container.style.position = 'absolute';67container.style.top = '-50000px';68container.style.width = '50000px';6970const regularDomNode = document.createElement('div');71applyFontInfo(regularDomNode, this._bareFontInfo);72container.appendChild(regularDomNode);7374const boldDomNode = document.createElement('div');75applyFontInfo(boldDomNode, this._bareFontInfo);76boldDomNode.style.fontWeight = 'bold';77container.appendChild(boldDomNode);7879const italicDomNode = document.createElement('div');80applyFontInfo(italicDomNode, this._bareFontInfo);81italicDomNode.style.fontStyle = 'italic';82container.appendChild(italicDomNode);8384const testElements: HTMLSpanElement[] = [];85for (const request of this._requests) {8687let parent: HTMLElement;88if (request.type === CharWidthRequestType.Regular) {89parent = regularDomNode;90}91if (request.type === CharWidthRequestType.Bold) {92parent = boldDomNode;93}94if (request.type === CharWidthRequestType.Italic) {95parent = italicDomNode;96}9798parent!.appendChild(document.createElement('br'));99100const testElement = document.createElement('span');101DomCharWidthReader._render(testElement, request);102parent!.appendChild(testElement);103104testElements.push(testElement);105}106107this._container = container;108this._testElements = testElements;109}110111private static _render(testElement: HTMLElement, request: CharWidthRequest): void {112if (request.chr === ' ') {113let htmlString = '\u00a0';114// Repeat character 256 (2^8) times115for (let i = 0; i < 8; i++) {116htmlString += htmlString;117}118testElement.innerText = htmlString;119} else {120let testString = request.chr;121// Repeat character 256 (2^8) times122for (let i = 0; i < 8; i++) {123testString += testString;124}125testElement.textContent = testString;126}127}128129private _readFromDomElements(): void {130for (let i = 0, len = this._requests.length; i < len; i++) {131const request = this._requests[i];132const testElement = this._testElements![i];133134request.fulfill(testElement.offsetWidth / 256);135}136}137}138139export function readCharWidths(targetWindow: Window, bareFontInfo: BareFontInfo, requests: CharWidthRequest[]): void {140const reader = new DomCharWidthReader(bareFontInfo, requests);141reader.read(targetWindow);142}143144145