fontInfo.js 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. /*---------------------------------------------------------------------------------------------
  2. * Copyright (c) Microsoft Corporation. All rights reserved.
  3. * Licensed under the MIT License. See License.txt in the project root for license information.
  4. *--------------------------------------------------------------------------------------------*/
  5. import * as platform from '../../../base/common/platform.js';
  6. import { EditorZoom } from './editorZoom.js';
  7. /**
  8. * Determined from empirical observations.
  9. * @internal
  10. */
  11. const GOLDEN_LINE_HEIGHT_RATIO = platform.isMacintosh ? 1.5 : 1.35;
  12. /**
  13. * @internal
  14. */
  15. const MINIMUM_LINE_HEIGHT = 8;
  16. export class BareFontInfo {
  17. /**
  18. * @internal
  19. */
  20. constructor(opts) {
  21. this._bareFontInfoBrand = undefined;
  22. this.zoomLevel = opts.zoomLevel;
  23. this.pixelRatio = opts.pixelRatio;
  24. this.fontFamily = String(opts.fontFamily);
  25. this.fontWeight = String(opts.fontWeight);
  26. this.fontSize = opts.fontSize;
  27. this.fontFeatureSettings = opts.fontFeatureSettings;
  28. this.lineHeight = opts.lineHeight | 0;
  29. this.letterSpacing = opts.letterSpacing;
  30. }
  31. /**
  32. * @internal
  33. */
  34. static createFromValidatedSettings(options, zoomLevel, pixelRatio, ignoreEditorZoom) {
  35. const fontFamily = options.get(42 /* fontFamily */);
  36. const fontWeight = options.get(46 /* fontWeight */);
  37. const fontSize = options.get(45 /* fontSize */);
  38. const fontFeatureSettings = options.get(44 /* fontLigatures */);
  39. const lineHeight = options.get(58 /* lineHeight */);
  40. const letterSpacing = options.get(55 /* letterSpacing */);
  41. return BareFontInfo._create(fontFamily, fontWeight, fontSize, fontFeatureSettings, lineHeight, letterSpacing, zoomLevel, pixelRatio, ignoreEditorZoom);
  42. }
  43. /**
  44. * @internal
  45. */
  46. static _create(fontFamily, fontWeight, fontSize, fontFeatureSettings, lineHeight, letterSpacing, zoomLevel, pixelRatio, ignoreEditorZoom) {
  47. if (lineHeight === 0) {
  48. lineHeight = GOLDEN_LINE_HEIGHT_RATIO * fontSize;
  49. }
  50. else if (lineHeight < MINIMUM_LINE_HEIGHT) {
  51. // Values too small to be line heights in pixels are probably in ems. Accept them gracefully.
  52. lineHeight = lineHeight * fontSize;
  53. }
  54. // Enforce integer, minimum constraints
  55. lineHeight = Math.round(lineHeight);
  56. if (lineHeight < MINIMUM_LINE_HEIGHT) {
  57. lineHeight = MINIMUM_LINE_HEIGHT;
  58. }
  59. const editorZoomLevelMultiplier = 1 + (ignoreEditorZoom ? 0 : EditorZoom.getZoomLevel() * 0.1);
  60. fontSize *= editorZoomLevelMultiplier;
  61. lineHeight *= editorZoomLevelMultiplier;
  62. return new BareFontInfo({
  63. zoomLevel: zoomLevel,
  64. pixelRatio: pixelRatio,
  65. fontFamily: fontFamily,
  66. fontWeight: fontWeight,
  67. fontSize: fontSize,
  68. fontFeatureSettings: fontFeatureSettings,
  69. lineHeight: lineHeight,
  70. letterSpacing: letterSpacing
  71. });
  72. }
  73. /**
  74. * @internal
  75. */
  76. getId() {
  77. return this.zoomLevel + '-' + this.pixelRatio + '-' + this.fontFamily + '-' + this.fontWeight + '-' + this.fontSize + '-' + this.fontFeatureSettings + '-' + this.lineHeight + '-' + this.letterSpacing;
  78. }
  79. /**
  80. * @internal
  81. */
  82. getMassagedFontFamily(fallbackFontFamily) {
  83. const fontFamily = BareFontInfo._wrapInQuotes(this.fontFamily);
  84. if (fallbackFontFamily && this.fontFamily !== fallbackFontFamily) {
  85. return `${fontFamily}, ${fallbackFontFamily}`;
  86. }
  87. return fontFamily;
  88. }
  89. static _wrapInQuotes(fontFamily) {
  90. if (/[,"']/.test(fontFamily)) {
  91. // Looks like the font family might be already escaped
  92. return fontFamily;
  93. }
  94. if (/[+ ]/.test(fontFamily)) {
  95. // Wrap a font family using + or <space> with quotes
  96. return `"${fontFamily}"`;
  97. }
  98. return fontFamily;
  99. }
  100. }
  101. // change this whenever `FontInfo` members are changed
  102. export const SERIALIZED_FONT_INFO_VERSION = 1;
  103. export class FontInfo extends BareFontInfo {
  104. /**
  105. * @internal
  106. */
  107. constructor(opts, isTrusted) {
  108. super(opts);
  109. this._editorStylingBrand = undefined;
  110. this.version = SERIALIZED_FONT_INFO_VERSION;
  111. this.isTrusted = isTrusted;
  112. this.isMonospace = opts.isMonospace;
  113. this.typicalHalfwidthCharacterWidth = opts.typicalHalfwidthCharacterWidth;
  114. this.typicalFullwidthCharacterWidth = opts.typicalFullwidthCharacterWidth;
  115. this.canUseHalfwidthRightwardsArrow = opts.canUseHalfwidthRightwardsArrow;
  116. this.spaceWidth = opts.spaceWidth;
  117. this.middotWidth = opts.middotWidth;
  118. this.wsmiddotWidth = opts.wsmiddotWidth;
  119. this.maxDigitWidth = opts.maxDigitWidth;
  120. }
  121. /**
  122. * @internal
  123. */
  124. equals(other) {
  125. return (this.fontFamily === other.fontFamily
  126. && this.fontWeight === other.fontWeight
  127. && this.fontSize === other.fontSize
  128. && this.fontFeatureSettings === other.fontFeatureSettings
  129. && this.lineHeight === other.lineHeight
  130. && this.letterSpacing === other.letterSpacing
  131. && this.typicalHalfwidthCharacterWidth === other.typicalHalfwidthCharacterWidth
  132. && this.typicalFullwidthCharacterWidth === other.typicalFullwidthCharacterWidth
  133. && this.canUseHalfwidthRightwardsArrow === other.canUseHalfwidthRightwardsArrow
  134. && this.spaceWidth === other.spaceWidth
  135. && this.middotWidth === other.middotWidth
  136. && this.wsmiddotWidth === other.wsmiddotWidth
  137. && this.maxDigitWidth === other.maxDigitWidth);
  138. }
  139. }