diff --git a/public/assets/fonts/cache/habbo-at.gif b/public/assets/fonts/cache/habbo-at.gif new file mode 100644 index 00000000..d624ae41 Binary files /dev/null and b/public/assets/fonts/cache/habbo-at.gif differ diff --git a/public/assets/fonts/cache/habbo-ato.gif b/public/assets/fonts/cache/habbo-ato.gif new file mode 100644 index 00000000..be511c2b Binary files /dev/null and b/public/assets/fonts/cache/habbo-ato.gif differ diff --git a/public/assets/images/media/logo/logo-1783095831701-q7stvw.png b/public/assets/images/media/logo/logo-1783095831701-q7stvw.png new file mode 100644 index 00000000..a241f6f5 Binary files /dev/null and b/public/assets/images/media/logo/logo-1783095831701-q7stvw.png differ diff --git a/src/components/public/logo-generator.tsx b/src/components/public/logo-generator.tsx index bc3f8eb4..62d71fdd 100644 --- a/src/components/public/logo-generator.tsx +++ b/src/components/public/logo-generator.tsx @@ -47,7 +47,7 @@ export default function LogoGenerator() { getFontInfo(styleName) .then((info) => { if (cancelled) return; - const canvas = renderToCanvas(info.chars, info.h, info.sheet, safeText, 12); + const canvas = renderToCanvas(info.chars, info.h, info.top, info.sheet, safeText, info.avgW); if (canvas && canvasRef.current) { canvasRef.current.width = canvas.width; canvasRef.current.height = canvas.height; @@ -108,7 +108,7 @@ export default function LogoGenerator() { for (const font of allFonts) { try { const info = await getFontInfo(font.styleName); - const canvas = renderToCanvas(info.chars, info.h, info.sheet, safeText, 12); + const canvas = renderToCanvas(info.chars, info.h, info.top, info.sheet, safeText, info.avgW); if (!canvas) { fail++; continue; } const blob = await new Promise((r) => canvas.toBlob((b) => r(b), "image/png")); if (blob) folder.file(`${font.styleName}.png`, blob); diff --git a/src/components/public/sprite-font.ts b/src/components/public/sprite-font.ts index 7f3e4e2b..51653ed1 100644 --- a/src/components/public/sprite-font.ts +++ b/src/components/public/sprite-font.ts @@ -6,7 +6,7 @@ interface CharInfo { w: number; } -const fontCache = new Map(); +const fontCache = new Map(); function hexPixel(data: Uint8ClampedArray, x: number, y: number, w: number): number { const i = (y * w + x) * 4; @@ -49,7 +49,7 @@ function scanCharWidths(data: Uint8ClampedArray, sw: number, sh: number): CharIn return chars; } -export async function getFontInfo(font: string): Promise<{ chars: CharInfo[]; h: number; sheet: HTMLImageElement }> { +export async function getFontInfo(font: string): Promise<{ chars: CharInfo[]; h: number; top: number; sheet: HTMLImageElement; avgW: number }> { const cached = fontCache.get(font); if (cached) return cached; @@ -83,20 +83,22 @@ export async function getFontInfo(font: string): Promise<{ chars: CharInfo[]; h: } const h = bottom - top + 1; - const result = { chars, h, sheet: img }; + const avgW = chars.length > 0 ? Math.round(chars.reduce((s, c) => s + c.w, 0) / chars.length) : 12; + + const result = { chars, h, top, sheet: img, avgW }; fontCache.set(font, result); return result; } -export function measureText(chars: CharInfo[], h: number, text: string, spaceW: number): { totalW: number } { +export function measureText(chars: CharInfo[], text: string, avgW: number): { totalW: number } { const map = new Map(chars.map((c) => [c.char, c])); let totalW = 0; for (const ch of text.toLowerCase()) { if (ch === " ") { - totalW += spaceW; + totalW += avgW; } else { const info = map.get(ch); - totalW += info?.w ?? spaceW; + totalW += info?.w ?? avgW; } } return { totalW }; @@ -105,9 +107,10 @@ export function measureText(chars: CharInfo[], h: number, text: string, spaceW: export function renderToCanvas( chars: CharInfo[], h: number, + top: number, sheet: HTMLImageElement, text: string, - spaceW: number, + avgW: number, dpr = 1, ): HTMLCanvasElement | null { const map = new Map(chars.map((c) => [c.char, c])); @@ -115,7 +118,7 @@ export function renderToCanvas( let totalW = 0; for (const ch of safeText) { - totalW += ch === " " ? spaceW : (map.get(ch)?.w ?? spaceW); + totalW += ch === " " ? avgW : (map.get(ch)?.w ?? avgW); } if (totalW === 0) return null; @@ -130,14 +133,14 @@ export function renderToCanvas( let x = 0; for (const ch of safeText) { if (ch === " ") { - x += spaceW; + x += avgW; } else { const info = map.get(ch); if (info) { - ctx.drawImage(sheet, info.x, 0, info.w, sheet.naturalHeight, x, 0, info.w, h); + ctx.drawImage(sheet, info.x, top, info.w, h, x, 0, info.w, h); x += info.w; } else { - x += spaceW; + x += avgW; } } }