Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
nginx \
# Chrome headless shell dependencies
wget ca-certificates openssl unzip \
fonts-liberation fonts-noto-color-emoji fonts-noto-cjk fontconfig \
fonts-liberation fonts-symbola fonts-noto-cjk fontconfig \
libnss3 libatk-bridge2.0-0t64 libdrm2 libxkbcommon0 \
libgbm1 libxcomposite1 libxdamage1 libxfixes3 libxrandr2 \
libasound2t64 libcups2t64 libatk1.0-0t64 libnspr4 libdbus-1-3 \
Expand Down
19 changes: 11 additions & 8 deletions backend/src/screen-designer/services/screen-renderer.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,16 +149,19 @@ export class ScreenRendererService implements OnModuleDestroy, OnModuleInit {
* This ensures the loaded woff2 fonts are actually used
*/
private mapFontFamily(fontFamily: string): string {
// 'Symbola' is a monochrome symbol/emoji font (installed in the image). It is
// listed as a per-glyph fallback so emoji render as black glyphs that survive
// the grayscale + Floyd-Steinberg dithering for e-ink (color emoji turn white).
switch (fontFamily) {
case 'sans-serif':
return "'Inter', sans-serif";
return "'Inter', 'Symbola', sans-serif";
case 'monospace':
return "'Roboto Mono', monospace";
return "'Roboto Mono', 'Symbola', monospace";
case 'serif':
return "'Merriweather', serif";
return "'Merriweather', 'Symbola', serif";
default:
// If already a specific font or unknown, return with fallback
return fontFamily.includes(',') ? fontFamily : `${fontFamily}, sans-serif`;
return fontFamily.includes(',') ? fontFamily : `${fontFamily}, 'Symbola', sans-serif`;
}
}

Expand Down Expand Up @@ -776,9 +779,9 @@ export class ScreenRendererService implements OnModuleDestroy, OnModuleInit {
<ellipse cx="${cx - 5}" cy="${cy - 5}" rx="${r * 0.7}" ry="${r * 0.5}" fill="${color}"/>
<ellipse cx="${cx + 6}" cy="${cy - 5}" rx="${r * 0.6}" ry="${r * 0.45}" fill="${color}"/>
<ellipse cx="${cx}" cy="${cy - 10}" rx="${r * 0.85}" ry="${r * 0.6}" fill="${color}"/>
<text x="${cx - 8}" y="${cy + 12}" font-size="12" fill="${color}">*</text>
<text x="${cx}" y="${cy + 16}" font-size="12" fill="${color}">*</text>
<text x="${cx + 8}" y="${cy + 10}" font-size="12" fill="${color}">*</text>
<text x="${cx - 8}" y="${cy + 12}" font-size="12" font-family="sans-serif" fill="${color}">*</text>
<text x="${cx}" y="${cy + 16}" font-size="12" font-family="sans-serif" fill="${color}">*</text>
<text x="${cx + 8}" y="${cy + 10}" font-size="12" font-family="sans-serif" fill="${color}">*</text>
`;
case 'thunder':
return `
Expand Down Expand Up @@ -2961,7 +2964,7 @@ export class ScreenRendererService implements OnModuleDestroy, OnModuleInit {

html += '<div style="display: flex; align-items: center; gap: 8px;">';
if (showIcon) {
html += `<div style="color: currentColor;">${this.getWeatherIconSvg(condition.icon, iconSize, 'currentColor')}</div>`;
html += `<svg width="${iconSize}" height="${iconSize}" viewBox="0 0 ${iconSize} ${iconSize}" xmlns="http://www.w3.org/2000/svg" style="color: currentColor;">${this.getWeatherIconSvg(condition.icon, iconSize, 'currentColor')}</svg>`;
}
html += '<div style="display: flex; flex-direction: column;">';
if (showTemperature) {
Expand Down