Who would have thought I'd stumble upon a new challenge on Stack Overflow? But here we are. If there's already a solution out there, please guide me in the right direction. I'm currently developing an interactive desktop environment inspired by the Amiga Workbench, and naturally, I want to include a recreation of the iconic Topaz font. However, I've encountered an issue. While basic text like hyphens, commas, and periods display correctly when drawn using the Canvas API, symbols like the copyright sign or backslash do not.
Amiga Workbench screen where the copyright sign isn't displayed correctly
I initially thought that the font I'm using may be missing these symbols, but it seemed unlikely. Why create a font only to omit certain characters, right? Upon inspecting the font with Font Forge, I can see that the symbols are indeed included along with a variety of other characters.
Font Forge displaying a set of symbols saved in the font data
Examining the complete set rules out any Unicode mix-ups. Moreover, when I used the same font in Gimp for a visual mockup, the copyright symbol displayed without any issues. So keyboard layouts shouldn't be causing this problem, right?
Screenshot from Gimp showing correct display of the copyright sign
The only remaining factor is my code, which I believe is free of issues. Here's how I integrate the font and draw text:
const amigaFont = new FontFace(
'Topaz A1200',
'url(./media/font/Topaz_a1200_v1.0.ttf)'
);
amigaFont.load().then(function (font) {
document.fonts.add(amigaFont);
});
// Additional code here ensures all media, including images and fonts, are loaded before drawing on the canvas
const splashScreenText = [
'AMIGA ROM Operating System and Libraries',
'Copyright © 1985-1992 Commodore-Amiga, Inc.',
'All Rights Reserved.',
'1>'
];
let fontSize = Math.round(amigaDOSwindow.bottom * (24 / 356));
ctx.font = fontSize.toString() + 'px Topaz A1200';
textCursor.x = amigaDOSinput.left;
textCursor.y = amigaDOSinput.top + fontSize;
for (let index = 0; index < splashScreenText.length; index++) {
ctx.fillText(splashScreenText[index], textCursor.x, textCursor.y);
textCursor.y += fontSize;
}
Edit: Requested to provide runnable code replicating the issue:
const mediaCount = 1;
const mediaArray = [];
const mediaManager = setInterval(checkArray, 15);
function checkArray() {
switch (true) {
case mediaArray.length == mediaCount:
clearInterval(mediaManager);
initCanvas();
break;
default:
break;
}
}
const amigaFont = new FontFace(
'Topaz A1200',
'url(https://cdn.jsdelivr.net/gh/rewtnull/amigafonts@master/ttf/Topaz_a1200_v1.0.ttf)'
);
amigaFont.load().then(function (font) {
document.fonts.add(amigaFont);
mediaArray.push(amigaFont);
});
const splashScreenText = [
'AMIGA ROM Operating System and Libraries',
'Copyright © 1985-1992 Commodore-Amiga, Inc.',
'All Rights Reserved.',
'1>'
];
const textCursor = {
x: 0,
y: 0,
};
function initCanvas() {
let canvas = document.createElement('canvas');
canvas.id = 'canvas';
document.body.appendChild(canvas);
processCanvas();
}
function processCanvas() {
let canvas = document.getElementById('canvas');
canvas.width = 320;
canvas.height = 180;
drawText();
}
function drawText() {
let canvas = document.getElementById('canvas');
let ctx = canvas.getContext('2d');
let fontSize = 32;
ctx.font = fontSize.toString() + 'px Topaz A1200';
textCursor.x = 0;
textCursor.y = 0 + fontSize;
for (let i = 0; i < splashScreenText.length; i++) {
ctx.fillText(splashScreenText[i], textCursor.x, textCursor.y);
textCursor.y += fontSize;
}
}
<canvas id="canvas"></canvas>
Surprisingly, everything seems to work fine in this setup...
Could there be something unknown about fonts and the Canvas API contributing to this anomaly?