fix: bundle consistent fonts for share card rendering

This commit is contained in:
syntaxbullet
2026-09-07 11:57:23 +02:00
parent e6002ad619
commit 1721ee469d
12 changed files with 245 additions and 10 deletions

View File

@@ -10,9 +10,18 @@ import { cardDate } from "../lib/progress-card";
import { calendarTimeline } from "../components/design-system/calendar-model";
import { themedHabitShade } from "../lib/habit-palette";
const sourceFont = new URL('../assets/fonts/InstrumentSerif-Regular.ttf', import.meta.url);
const builtFont = new URL('./fonts/InstrumentSerif-Regular.ttf', import.meta.url);
GlobalFonts.registerFromPath((existsSync(sourceFont) ? sourceFont : builtFont).pathname, 'Instrument Serif');
for (const [file, family] of [
['InstrumentSerif-Regular.ttf', 'Instrument Serif'],
['NotoSans-Regular.ttf', 'Mina Sans'],
['NotoSans-Medium.ttf', 'Mina Sans'],
['NotoSans-SemiBold.ttf', 'Mina Sans'],
]) {
const sourceFont = new URL(`../assets/fonts/${file}`, import.meta.url);
const builtFont = new URL(`./fonts/${file}`, import.meta.url);
if (!GlobalFonts.registerFromPath((existsSync(sourceFont) ? sourceFont : builtFont).pathname, family)) {
throw new Error(`Could not load bundled font: ${file}`);
}
}
export function liveCardData(db: AppDatabase, userId: string, now: number) {
const user = db.select().from(users).where(eq(users.id, userId)).get();
@@ -54,7 +63,7 @@ export async function renderLiveCard(data: LiveImageData, theme: Theme) {
ctx.fillStyle = color; ctx.beginPath(); ctx.roundRect(x, y, Math.max(0, w), Math.max(0, h), radius); ctx.fill();
};
const text = (value: string, x: number, y: number, size: number, width: number, color: string = colors.ink, serif = false, weight = '400') => {
ctx.font = `${weight} ${size}px ${serif ? '"Instrument Serif"' : 'sans-serif'}`; ctx.fillStyle = color;
ctx.font = `${weight} ${size}px ${serif ? '"Instrument Serif"' : '"Mina Sans"'}`; ctx.fillStyle = color;
const chars = Array.from(value); let fitted = value;
while (chars.length && ctx.measureText(fitted).width > width) { chars.pop(); fitted = chars.join('') + '…'; }
ctx.fillText(fitted, x, y);