From 6e28ffa93bdc570937c01139d03489aca2c08a52 Mon Sep 17 00:00:00 2001 From: Anton Afanasyeu Date: Sat, 30 May 2026 18:22:59 +0200 Subject: [PATCH] font struggling --- build.config.yml | 57 +++++ .../app_hub/assets/build_ttf_lcd_alphabet.py | 196 ++++++++++++++++++ .../assets/digital-7-mono-italic-alphabet.svg | 129 ++++++++++++ .../app_hub/assets/ds-digital-alphabet.svg | 129 ++++++++++++ .../assets/dseg14-classic-alphabet.svg | 129 ++++++++++++ .../app_hub/assets/dseg14-modern-alphabet.svg | 129 ++++++++++++ examples/app_hub/assets/fonts/DS-Digital.ttf | Bin 0 -> 24448 bytes .../assets/fonts/DSEG14Classic-Regular.ttf | Bin 0 -> 65224 bytes .../assets/fonts/DSEG14Modern-Regular.ttf | Bin 0 -> 65176 bytes .../assets/fonts/digital-7-mono-italic.ttf | Bin 0 -> 17888 bytes examples/app_hub/hub.css | 69 +++++- examples/app_hub/index.html | 181 ++++++++++++++-- 12 files changed, 997 insertions(+), 22 deletions(-) create mode 100644 build.config.yml create mode 100644 examples/app_hub/assets/build_ttf_lcd_alphabet.py create mode 100644 examples/app_hub/assets/digital-7-mono-italic-alphabet.svg create mode 100644 examples/app_hub/assets/ds-digital-alphabet.svg create mode 100644 examples/app_hub/assets/dseg14-classic-alphabet.svg create mode 100644 examples/app_hub/assets/dseg14-modern-alphabet.svg create mode 100644 examples/app_hub/assets/fonts/DS-Digital.ttf create mode 100644 examples/app_hub/assets/fonts/DSEG14Classic-Regular.ttf create mode 100644 examples/app_hub/assets/fonts/DSEG14Modern-Regular.ttf create mode 100644 examples/app_hub/assets/fonts/digital-7-mono-italic.ttf diff --git a/build.config.yml b/build.config.yml new file mode 100644 index 0000000..78e4ff4 --- /dev/null +++ b/build.config.yml @@ -0,0 +1,57 @@ +# Android Cast build pipeline (CircleCI-compatible shape) +version: 2.1 + +parameters: + git_ref: + type: string + default: next + gradle_task: + type: string + default: assembleDebug + run_tests: + type: boolean + default: true + run_native: + type: boolean + default: true + run_apk: + type: boolean + default: true + auto_ota: + type: boolean + default: false + ota_channel: + type: string + default: staging + +jobs: + android-build: + docker: + - image: androidcast-ci:00.01.00.1000 + steps: + - checkout + - run: + name: Native codecs + command: | + if [ "<< pipeline.parameters.run_native >>" = "true" ]; then + ./scripts/ci-build-and-publish-ota.sh + fi + - run: + name: Gradle + tests + command: | + export GRADLE_TASK="<< pipeline.parameters.gradle_task >>" + export RUN_UNIT_TESTS="<< pipeline.parameters.run_tests >>" + export RUN_APK="<< pipeline.parameters.run_apk >>" + export AUTO_OTA="<< pipeline.parameters.auto_ota >>" + export OTA_CHANNEL="<< pipeline.parameters.ota_channel >>" + ./scripts/ci-build-and-publish-ota.sh + - store_artifacts: + path: out/builds + +workflows: + build: + jobs: + - android-build: + filters: + branches: + only: [next, master] diff --git a/examples/app_hub/assets/build_ttf_lcd_alphabet.py b/examples/app_hub/assets/build_ttf_lcd_alphabet.py new file mode 100644 index 0000000..e139269 --- /dev/null +++ b/examples/app_hub/assets/build_ttf_lcd_alphabet.py @@ -0,0 +1,196 @@ +#!/usr/bin/env python3 +"""Vectorize LCD TTF fonts into SVG symbol sets for the hub clock widget.""" + +from __future__ import annotations + +import argparse +import re +from dataclasses import dataclass +from pathlib import Path + +from fontTools.pens.boundsPen import BoundsPen +from fontTools.pens.svgPathPen import SVGPathPen +from fontTools.ttLib import TTFont + +CHARS = ( + [" "] + + [str(d) for d in range(10)] + + [chr(c) for c in range(ord("A"), ord("Z") + 1)] + + [":", "+", "-", "/", "."] +) + +TARGET_HEIGHT = 32.0 +PADDING_X = 1.5 +PADDING_Y = 1.0 + + +@dataclass(frozen=True) +class FontSpec: + ttf: str + prefix: str + outfile: str + comment: str + + +FONTS: dict[str, FontSpec] = { + "dseg14-classic": FontSpec( + ttf="DSEG14Classic-Regular.ttf", + prefix="d14c", + outfile="dseg14-classic-alphabet.svg", + comment="DSEG14 Classic (OFL) — vectorized for hub clock", + ), + "dseg14-modern": FontSpec( + ttf="DSEG14Modern-Regular.ttf", + prefix="d14m", + outfile="dseg14-modern-alphabet.svg", + comment="DSEG14 Modern (OFL) — vectorized for hub clock", + ), + "ds-digital": FontSpec( + ttf="DS-Digital.ttf", + prefix="dsd", + outfile="ds-digital-alphabet.svg", + comment="DS-Digital by Dusit Supasawat (shareware) — vectorized for hub clock", + ), + "digital-7-mono-italic": FontSpec( + ttf="digital-7-mono-italic.ttf", + prefix="d7mi", + outfile="digital-7-mono-italic-alphabet.svg", + comment="Digital-7 Mono Italic by Style-7 (personal use) — vectorized for hub clock", + ), +} + + +def symbol_id(prefix: str, ch: str) -> str: + if ch == " ": + return f"{prefix}-space" + if ch == ":": + return f"{prefix}-colon" + if ch == "+": + return f"{prefix}-plus" + if ch == "-": + return f"{prefix}-minus" + if ch == "/": + return f"{prefix}-slash" + if ch == ".": + return f"{prefix}-dot" + if len(ch) == 1 and "0" <= ch <= "9": + return f"{prefix}-{ch}" + if len(ch) == 1 and "A" <= ch <= "Z": + return f"{prefix}-{ch}" + return f"{prefix}-u{ord(ch):04x}" + + +def glyph_path(font: TTFont, ch: str) -> tuple[str, float, float, float, float] | None: + cmap = font.getBestCmap() + code = ord(ch) + if code not in cmap: + return None + glyph_name = cmap[code] + glyph_set = font.getGlyphSet() + if glyph_name not in glyph_set: + return None + glyph = glyph_set[glyph_name] + + pen = SVGPathPen(glyph_set) + bounds_pen = BoundsPen(glyph_set) + glyph.draw(bounds_pen) + if bounds_pen.bounds is None: + return None + x_min, y_min, x_max, y_max = bounds_pen.bounds + glyph.draw(pen) + path = pen.getCommands() + if not path.strip(): + return None + return path, x_min, y_min, x_max, y_max + + +def char_width(font: TTFont, ch: str, fallback: float) -> float: + cmap = font.getBestCmap() + code = ord(ch) + if code not in cmap: + return fallback + glyph_name = cmap[code] + if glyph_name in font["hmtx"].metrics: + adv, _ = font["hmtx"].metrics[glyph_name] + return float(adv) + return fallback + + +def build_alphabet(spec: FontSpec, fonts_dir: Path, out_dir: Path) -> None: + ttf_path = fonts_dir / spec.ttf + font = TTFont(ttf_path) + units_per_em = float(font["head"].unitsPerEm or 1000) + + lines = [ + '", ""]) + out_path = out_dir / spec.outfile + out_path.write_text("\n".join(lines), encoding="utf-8") + print(f"Wrote {out_path}") + + +def main() -> None: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument( + "--fonts-dir", + type=Path, + default=Path(__file__).resolve().parent / "fonts", + ) + parser.add_argument( + "--out-dir", + type=Path, + default=Path(__file__).resolve().parent, + ) + parser.add_argument( + "--only", + choices=sorted(FONTS.keys()), + action="append", + help="Build one font (repeatable). Default: all.", + ) + args = parser.parse_args() + + selected = args.only or sorted(FONTS.keys()) + for key in selected: + build_alphabet(FONTS[key], args.fonts_dir, args.out_dir) + + +if __name__ == "__main__": + main() diff --git a/examples/app_hub/assets/digital-7-mono-italic-alphabet.svg b/examples/app_hub/assets/digital-7-mono-italic-alphabet.svg new file mode 100644 index 0000000..40ac039 --- /dev/null +++ b/examples/app_hub/assets/digital-7-mono-italic-alphabet.svg @@ -0,0 +1,129 @@ + diff --git a/examples/app_hub/assets/ds-digital-alphabet.svg b/examples/app_hub/assets/ds-digital-alphabet.svg new file mode 100644 index 0000000..e4f9ee8 --- /dev/null +++ b/examples/app_hub/assets/ds-digital-alphabet.svg @@ -0,0 +1,129 @@ + diff --git a/examples/app_hub/assets/dseg14-classic-alphabet.svg b/examples/app_hub/assets/dseg14-classic-alphabet.svg new file mode 100644 index 0000000..525f2f2 --- /dev/null +++ b/examples/app_hub/assets/dseg14-classic-alphabet.svg @@ -0,0 +1,129 @@ + diff --git a/examples/app_hub/assets/dseg14-modern-alphabet.svg b/examples/app_hub/assets/dseg14-modern-alphabet.svg new file mode 100644 index 0000000..cb52047 --- /dev/null +++ b/examples/app_hub/assets/dseg14-modern-alphabet.svg @@ -0,0 +1,129 @@ + diff --git a/examples/app_hub/assets/fonts/DS-Digital.ttf b/examples/app_hub/assets/fonts/DS-Digital.ttf new file mode 100644 index 0000000000000000000000000000000000000000..09258773c7219ad9e60b92b918e3c50b58f43c9e GIT binary patch literal 24448 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 literal 0 HcmV?d00001 diff --git a/examples/app_hub/assets/fonts/digital-7-mono-italic.ttf b/examples/app_hub/assets/fonts/digital-7-mono-italic.ttf new file mode 100644 index 0000000000000000000000000000000000000000..ddbd3f7523170de919fc03258999b9de230e5581 GIT binary patch literal 17888 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 - + @@ -11,12 +11,13 @@ })(); - + + @@ -151,14 +152,52 @@ } var stage = document.getElementById('hub-logo-stage'); - if (!stage) return; var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); var supportsSvg = !!(svg && svg.createSVGRect); var supportsLayout = !!(window.CSS && CSS.supports && CSS.supports('object-fit', 'cover')); - if (!supportsSvg || !supportsLayout) return; + var logoEnabled = !!(stage && supportsSvg && supportsLayout); - var logoBuild = '20260530i'; + var logoBuild = '20260530k'; + + function hubAsset(rel) { + var link = document.querySelector('link[href*="hub.css"]'); + if (link) { + var href = link.getAttribute('href') || ''; + return href.replace(/[^/]*$/, '') + rel; + } + return rel; + } + + var LCD_FONT_CATALOG = { + 'dseg14-classic': { + url: 'assets/dseg14-classic-alphabet.svg', + prefix: 'd14c', + css: '"DSEG14 Classic", "Consolas", monospace' + }, + 'dseg14-modern': { + url: 'assets/dseg14-modern-alphabet.svg', + prefix: 'd14m', + css: '"DSEG14 Modern", "Consolas", monospace' + }, + 'ds-digital': { + url: 'assets/ds-digital-alphabet.svg', + prefix: 'dsd', + css: '"DS-Digital", "Consolas", monospace' + }, + 'digital-7-mono-italic': { + url: 'assets/digital-7-mono-italic-alphabet.svg', + prefix: 'd7mi', + css: '"Digital-7 Mono Italic", "Consolas", monospace' + } + }; + + var clockFontParams = new URLSearchParams(window.location.search); + var clockFontKey = (clockFontParams.get('clockFont') || 'dseg14-classic').toLowerCase(); + if (!LCD_FONT_CATALOG[clockFontKey]) clockFontKey = 'dseg14-classic'; + var lcdFontReady = false; + var lcdSymbolIds = {}; + var lcdFontPrefix = LCD_FONT_CATALOG[clockFontKey].prefix; var fragments = { space: 'assets/hub-logo-fragment-space.svg', globe: 'assets/hub-logo-fragment-globe.svg', @@ -185,6 +224,7 @@ return base + '?v=' + logoBuild; } + if (logoEnabled) { list.forEach(function (name) { var img = document.createElement('img'); img.className = 'hub-logo-layer hub-logo-layer--' + name; @@ -208,6 +248,7 @@ stage.hidden = false; stage.setAttribute('aria-hidden', 'true'); + } /* Nav dock overlaps globe left hemisphere; stack top → bottom. */ var GLOBE_VIEW = { imgW: 1920, imgH: 1080, cx: 720, cy: 560, r: 330 }; @@ -443,7 +484,7 @@ } function bindCompassOpen() { - if (!compassLayer) return; + if (!logoEnabled || !compassLayer) return; var open = function () { openDeploymentModel(); }; compassLayer.addEventListener('click', open); compassLayer.addEventListener('keydown', function (ev) { @@ -586,6 +627,113 @@ return null; } + function lcdSymbolId(ch) { + var p = lcdFontPrefix; + if (ch >= '0' && ch <= '9') return p + '-' + ch; + if (ch === ':') return p + '-colon'; + if (ch === '+') return p + '-plus'; + if (ch === '-') return p + '-minus'; + if (ch === '/') return p + '-slash'; + if (ch === '.') return p + '-dot'; + if (ch === ' ') return p + '-space'; + if (ch >= 'A' && ch <= 'Z') return p + '-' + ch; + if (ch >= 'a' && ch <= 'z') return p + '-' + ch.toUpperCase(); + return null; + } + + function loadLcdAlphabet(done) { + var host = document.getElementById('lcd-alphabet-host'); + var spec = LCD_FONT_CATALOG[clockFontKey]; + if (!host || !spec) { done(false); return; } + fetch(hubAsset(spec.url) + '?v=' + logoBuild) + .then(function (res) { + if (!res.ok) throw new Error('alphabet fetch failed'); + return res.text(); + }) + .then(function (svgText) { + host.replaceChildren(); + var parser = new DOMParser(); + var doc = parser.parseFromString(svgText, 'image/svg+xml'); + var sprite = doc.documentElement; + if (sprite.querySelector('parsererror')) throw new Error('alphabet parse failed'); + sprite.setAttribute('aria-hidden', 'true'); + sprite.style.cssText = 'position:absolute;width:0;height:0;overflow:hidden;pointer-events:none'; + host.appendChild(sprite); + lcdSymbolIds = {}; + sprite.querySelectorAll('symbol').forEach(function (sym) { + if (sym.id) lcdSymbolIds[sym.id] = sym; + }); + lcdFontReady = Object.keys(lcdSymbolIds).length > 0; + document.documentElement.setAttribute('data-clock-font', clockFontKey); + var widget = document.getElementById('hub-clock-widget'); + if (widget) widget.setAttribute('data-lcd-mode', lcdFontReady ? 'svg' : 'text'); + done(lcdFontReady); + }) + .catch(function () { + lcdFontReady = false; + var widget = document.getElementById('hub-clock-widget'); + if (widget) widget.setAttribute('data-lcd-mode', 'text'); + done(false); + }); + } + + function cloneLcdSymbolContent(svg, sym) { + sym.childNodes.forEach(function (node) { + if (node.nodeType !== 1) return; + svg.appendChild(node.cloneNode(true)); + }); + } + + function renderLcdText(el, text, opts) { + opts = opts || {}; + if (!el) return; + el.innerHTML = ''; + el.classList.add('cw-lcd-text'); + var fontCss = LCD_FONT_CATALOG[clockFontKey].css; + if (!lcdFontReady) { + el.textContent = text; + el.style.fontFamily = fontCss; + return; + } + var renderedSvg = false; + String(text).split('').forEach(function (ch) { + var up = ch.toUpperCase(); + var sid = lcdSymbolId(up === ch ? ch : up); + if (!sid || !lcdSymbolIds[sid]) { + var fb = document.createElement('span'); + fb.className = 'ot-fallback-char' + (opts.bold ? ' ot-fallback-char--bold' : ''); + fb.style.fontFamily = fontCss; + fb.textContent = ch === ' ' ? '\u00A0' : ch; + el.appendChild(fb); + return; + } + var sym = lcdSymbolIds[sid]; + if (!sym.childNodes.length) { + var emptyFb = document.createElement('span'); + emptyFb.className = 'ot-fallback-char'; + emptyFb.style.fontFamily = fontCss; + emptyFb.textContent = ch === ' ' ? '\u00A0' : ch; + el.appendChild(emptyFb); + return; + } + renderedSvg = true; + var wrap = document.createElement('span'); + wrap.className = 'ot-glyph-wrap' + (opts.bold ? ' ot-glyph-wrap--bold' : ''); + if (opts.blinkColon && ch === ':') wrap.className += ' ot-colon-blink'; + var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); + svg.setAttribute('viewBox', sym.getAttribute('viewBox') || '0 0 20 32'); + svg.setAttribute('class', 'ot-glyph'); + svg.setAttribute('aria-hidden', 'true'); + cloneLcdSymbolContent(svg, sym); + wrap.appendChild(svg); + el.appendChild(wrap); + }); + if (!renderedSvg) { + el.textContent = text; + el.style.fontFamily = fontCss; + } + } + function loadQuartzAlphabet(done) { var host = document.getElementById('quartz-alphabet-host'); if (!host) { done(false); return; } @@ -817,19 +965,18 @@ }); function setClockopiaText(el, text) { - if (!el) return; - el.textContent = text; + renderLcdText(el, text, {}); } function updateClockWidget() { var now = new Date(); var p = timeParts(now, primaryTz); - setClockopiaText(document.getElementById('cw-hm-lcd'), p.hh + ':' + p.mm); - setClockopiaText(document.getElementById('cw-colon-lcd'), ':'); - setClockopiaText(document.getElementById('cw-ss-lcd'), p.ss); - setClockopiaText(document.getElementById('cw-tz-text'), gmtOffsetLabel(now, primaryTz)); - setClockopiaText(document.getElementById('cw-region'), regionLabel(primaryTz)); - setClockopiaText(document.getElementById('cw-date-line'), formatDateLine(now, primaryTz)); + renderLcdText(document.getElementById('cw-hm-lcd'), p.hh + ':' + p.mm, { bold: true }); + renderLcdText(document.getElementById('cw-colon-lcd'), ':', { blinkColon: true }); + renderLcdText(document.getElementById('cw-ss-lcd'), p.ss, {}); + renderLcdText(document.getElementById('cw-tz-text'), gmtOffsetLabel(now, primaryTz), {}); + renderLcdText(document.getElementById('cw-region'), regionLabel(primaryTz), {}); + renderLcdText(document.getElementById('cw-date-line'), formatDateLine(now, primaryTz), {}); secondary.forEach(function (clock) { var t = timeParts(now, clock.tz); @@ -920,8 +1067,10 @@ widget.releasePointerCapture(ev.pointerId); }); })(); - updateClockWidget(); - setInterval(updateClockWidget, 1000); + loadLcdAlphabet(function () { + updateClockWidget(); + setInterval(updateClockWidget, 1000); + }); })();