Bug 872078 - Allow multi-line font previews. r=jdescottes

This change prepares the font preview generation for the display within the Network Monitor's Response view.
In there, the preview is meant to contain all the letters of the Latin alphabet in upper and lower case plus the numbers from 0 to 9 and different characters in other alphabets.
As those are too long to be displayed in a single line, they will be split into several ones.

For this to work, the getFontPreviewData() method now splits the given preview text at new-line characters into several lines.
This also means that for the existing single-line preview texts within the Inspector there is no change.

Differential Revision: https://phabricator.services.mozilla.com/D110167
This commit is contained in:
Sebastian Zartner 2021-04-08 21:39:56 +00:00
Родитель bb90b740d2
Коммит 86a324602a
1 изменённых файлов: 35 добавлений и 9 удалений

Просмотреть файл

@ -12,6 +12,8 @@ const FONT_PREVIEW_FONT_SIZE = 40;
const FONT_PREVIEW_FILLSTYLE = "black";
// Offset (in px) to avoid cutting off text edges of italic fonts.
const FONT_PREVIEW_OFFSET = 4;
// Factor used to resize the canvas in order to get better text quality.
const FONT_PREVIEW_OVERSAMPLING_FACTOR = 2;
/**
* Helper function for getting an image preview of the given font.
@ -29,6 +31,7 @@ const FONT_PREVIEW_OFFSET = 4;
function getFontPreviewData(font, doc, options) {
options = options || {};
const previewText = options.previewText || FONT_PREVIEW_TEXT;
const previewTextLines = previewText.split("\n");
const previewFontSize = options.previewFontSize || FONT_PREVIEW_FONT_SIZE;
const fillStyle = options.fillStyle || FONT_PREVIEW_FILLSTYLE;
const fontStyle = options.fontStyle || "";
@ -41,23 +44,46 @@ function getFontPreviewData(font, doc, options) {
// Get the correct preview text measurements and set the canvas dimensions
ctx.font = fontValue;
ctx.fillStyle = fillStyle;
const textWidth = Math.round(ctx.measureText(previewText).width);
const previewTextLinesWidths = previewTextLines.map(
previewTextLine => ctx.measureText(previewTextLine).width
);
const textWidth = Math.round(Math.max(...previewTextLinesWidths));
canvas.width = textWidth * 2 + FONT_PREVIEW_OFFSET * 4;
canvas.height = previewFontSize * 3;
// The canvas width is calculated as the width of the longest line plus
// an offset at the left and right of it.
// The canvas height is calculated as the font size multiplied by the
// number of lines plus an offset at the top and bottom.
//
// In order to get better text quality, we oversample the canvas.
// That means, after the width and height are calculated, we increase
// both sizes by some factor.
const simpleCanvasWidth = textWidth + FONT_PREVIEW_OFFSET * 2;
canvas.width = simpleCanvasWidth * FONT_PREVIEW_OVERSAMPLING_FACTOR;
canvas.height =
(previewFontSize * previewTextLines.length + FONT_PREVIEW_OFFSET * 2) *
FONT_PREVIEW_OVERSAMPLING_FACTOR;
// we have to reset these after changing the canvas size
ctx.font = fontValue;
ctx.fillStyle = fillStyle;
// Oversample the canvas for better text quality
ctx.scale(FONT_PREVIEW_OVERSAMPLING_FACTOR, FONT_PREVIEW_OVERSAMPLING_FACTOR);
ctx.textBaseline = "top";
ctx.scale(2, 2);
ctx.fillText(
previewText,
FONT_PREVIEW_OFFSET,
Math.round(previewFontSize / 3)
);
ctx.textAlign = "center";
const horizontalTextPosition = simpleCanvasWidth / 2;
let verticalTextPosition = FONT_PREVIEW_OFFSET;
for (let i = 0; i < previewTextLines.length; i++) {
ctx.fillText(
previewTextLines[i],
horizontalTextPosition,
verticalTextPosition
);
// Move vertical text position one line down
verticalTextPosition += previewFontSize;
}
const dataURL = canvas.toDataURL("image/png");