Skip to content

Commit dafacbd

Browse files
authored
Represent OSD font characters using text/SVG instead of canvas/PNG for better performance (OSD tab loads in roughly half the time on an older Chromebook). (#4497)
1 parent bbd99ea commit dafacbd

File tree

1 file changed

+27
-27
lines changed

1 file changed

+27
-27
lines changed

src/js/tabs/osd.js

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -112,15 +112,6 @@ FONT.constants = {
112112
CHAR_HEIGHT: 18,
113113
CHAR_WIDTH: 12,
114114
},
115-
COLORS: {
116-
// black
117-
0: "rgba(0, 0, 0, 1)",
118-
// also the value 3, could yield transparent according to
119-
// https://www.sparkfun.com/datasheets/BreakoutBoards/MAX7456.pdf
120-
1: "rgba(255, 255, 255, 0)",
121-
// white
122-
2: "rgba(255,255,255, 1)",
123-
},
124115
};
125116

126117
FONT.pushChar = function (fontCharacterBytes, fontCharacterBits) {
@@ -197,36 +188,45 @@ FONT.openFontFile = function () {
197188
};
198189

199190
/**
200-
* returns a canvas image with the character on it
191+
* Gets a character bitmap as a data URI.
192+
* (Uses only single quotes so it can be embedded within double quotes)
193+
* @param {number} charAddress Character index into a FONT array.
194+
* @returns {string} Data URI.
201195
*/
202-
const drawCanvas = function (charAddress) {
203-
const canvas = document.createElement("canvas");
204-
const ctx = canvas.getContext("2d");
205-
206-
const pixelSize = 1;
207-
const width = pixelSize * FONT.constants.SIZES.CHAR_WIDTH;
208-
const height = pixelSize * FONT.constants.SIZES.CHAR_HEIGHT;
196+
const characterBitmapDataUri = function (charAddress) {
197+
// Validate input
198+
if (!(charAddress in FONT.data.characters)) {
199+
console.log("charAddress", charAddress, " is not in ", FONT.data.characters.length);
200+
}
209201

210-
canvas.width = width;
211-
canvas.height = height;
202+
// Create data URI prefix and SVG wrapper
203+
const width = FONT.constants.SIZES.CHAR_WIDTH;
204+
const height = FONT.constants.SIZES.CHAR_HEIGHT;
205+
const lines = [
206+
"data:image/svg+xml;utf8,",
207+
`<svg width='${width}' height='${height}' xmlns='http://www.w3.org/2000/svg'>`,
208+
];
212209

210+
// Create a rect for each visible pixel
213211
for (let y = 0; y < height; y++) {
214212
for (let x = 0; x < width; x++) {
215-
if (!(charAddress in FONT.data.characters)) {
216-
console.log("charAddress", charAddress, " is not in ", FONT.data.characters.length);
213+
const color = FONT.data.characters[charAddress][y * width + x];
214+
const fill = color === 0 ? "black" : color === 2 ? "white" : null;
215+
if (fill) {
216+
lines.push(`<rect x='${x}' y='${y}' width='1' height='1' fill='${fill}'/>`);
217217
}
218-
const v = FONT.data.characters[charAddress][y * width + x];
219-
ctx.fillStyle = FONT.constants.COLORS[v];
220-
ctx.fillRect(x, y, pixelSize, pixelSize);
221218
}
222219
}
223-
return canvas;
220+
221+
// Close SVG wrapper and return data URI
222+
lines.push("</svg>");
223+
return lines.join("");
224224
};
225225

226226
FONT.draw = function (charAddress) {
227227
let cached = FONT.data.character_image_urls[charAddress];
228228
if (!cached) {
229-
cached = FONT.data.character_image_urls[charAddress] = drawCanvas(charAddress).toDataURL("image/png");
229+
cached = FONT.data.character_image_urls[charAddress] = characterBitmapDataUri(charAddress);
230230
}
231231
return cached;
232232
};
@@ -3410,7 +3410,7 @@ osd.initialize = function (callback) {
34103410
x = OSD.data.preview[i][2];
34113411
y = OSD.data.preview[i][3];
34123412
}
3413-
const $img = $(`<div class="char" draggable><img src=${FONT.draw(charCode)}></img></div>`)
3413+
const $img = $(`<div class="char" draggable><img src="${FONT.draw(charCode)}"></img></div>`)
34143414
.on("mouseenter", OSD.GUI.preview.onMouseEnter)
34153415
.on("mouseleave", OSD.GUI.preview.onMouseLeave)
34163416
.on("dragover", OSD.GUI.preview.onDragOver)

0 commit comments

Comments
 (0)