From 62dcf5d7ae62d5f9b6fb39ac62710200ecff944e Mon Sep 17 00:00:00 2001 From: jason Date: Tue, 5 May 2026 16:05:52 -0500 Subject: [PATCH] =?UTF-8?q?docs:=20update=20README=20to=20v1.0=20=E2=80=94?= =?UTF-8?q?=20full=20documentation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 146 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 145 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e0bd9a9..7f0c16f 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,147 @@ # ada-font-analyzer -Standalone browser tool for evaluating fonts against ADA §703.5 signage compliance standards. Used by MPM's design team to validate fonts before deployment to the ~2,000-display installed base. \ No newline at end of file +Standalone browser tool for evaluating fonts against ADA §703.5 digital signage compliance standards. + +**Version:** 1.0 +**Author:** Bryan Gilliom — Message Point Media +**Repo:** https://git.alwisp.com/jason/ada-font-analyzer +**CoWork Project:** CW-005 — ADA Font Analyzer + +--- + +## Overview + +A single-file, browser-based tool built for MPM's design and content team to evaluate fonts against the 2010 ADA Standards for Accessible Design, Chapter 7 (Signs), Section §703.5 — the governing standard for digital signage character legibility. Used to select and validate fonts before deploying to MPM's ~2,000-display RDMC/OnSign.tv installed base. Runs entirely in the browser with no backend, no API keys, and no external dependencies beyond Google Fonts CDN. Embedded via iframe in the ADA Signage Guidelines Knowledge article in MPM's Odoo portal at `https://portal.mpmedia.tv/knowledge/article/4638`. + +--- + +## Tabs & Capabilities + +| Tab | What It Does | +|---|---| +| **Tab 1 — Browse Curated Fonts** | 25 hand-curated Google Fonts pre-evaluated against all five §703.5 criteria. Filter by compliance tier (Fully compliant / Transit-tested / Use with caution). Per-card: Select, View on Google Fonts, Download TTF/OTF ZIP. Sidebar with bulk "Download all selected." | +| **Tab 2 — Test a Google Font** | Type any Google Fonts family name; loads via CSS2 API and measures O:I ratio and stroke weight via HTML5 canvas (~±5% accuracy). Weight selector (100–900) re-scores live. Light-on-dark preview panel. | +| **Tab 3 — Upload TTF / OTF** | Drag-and-drop or file picker for TTF, OTF, WOFF, WOFF2. For TTF/OTF: parses binary font tables directly via custom JS DataView parser (no library). Full §703.5 scoring with higher accuracy than canvas. Raw metrics table with source attribution. | + +--- + +## ADA §703.5 Criteria Implemented + +| Criterion | Standard | How Measured | +|---|---|---| +| Sans-serif, conventional form | §703.5.3 | Name heuristics + OS/2 `panose bFamilyType` + `fsSelection` | +| O:I width ratio 55–110% | §703.5.4 | Canvas: rendered pixel widths. TTF: `hmtx` advance widths ÷ `sCapHeight` | +| Stroke weight 10–30% of height | §703.5.7 | Canvas: thinnest ink row scan. TTF: `usWeightClass` → stroke % mapping | +| Character spacing 10–35% | §703.5.8 | Condensed-variant name detection (proxy) | +| No italic/script/decorative | §703.5.3 | `fsSelection` italic/oblique bits + `panose` family type + name table | + +§703.5.9 (line spacing) not yet implemented — flagged as a planned improvement. + +--- + +## TTF Binary Parser — Tables Read + +The Tab 3 `parseTTF()` function reads these tables directly from the binary: + +| Table | Fields Extracted | +|---|---| +| `head` | `unitsPerEm` | +| `OS/2` | `usWeightClass`, `fsSelection`, `panose[10]`, `sCapHeight` (ver≥2) | +| `hhea` | `ascender`, `lineGap` | +| `cmap` | Format 4 Unicode map → glyph IDs for U+0049 (I) and U+004F (O) | +| `hmtx` | Advance widths for glyphs I and O | +| `name` | `nameID=1` (family), `nameID=2` (subfamily) — platform 3 (UTF-16BE) and platform 1 | + +--- + +## Architecture + +- **Single-file, no build step.** All HTML, CSS, JS, data, and the TTF parser live in one `ada-font-analyzer.html` (~970 lines). Required for Odoo iframe embedding (stable URL to a single file). +- **No external JS libraries.** TTF parsing uses native JS DataView. Font preview uses Google Fonts CSS2 API and FontFace API. +- **No localStorage, no cookies.** Privacy-safe for Odoo embedding. +- **WOFF/WOFF2:** Falls back to canvas-only measurement (Brotli/DEFLATE decompression not implemented). + +--- + +## Key Functions + +| Function | Purpose | +|---|---| +| `parseTTF(buffer)` | Binary font table parser → `{tables, metrics, errors}` | +| `canvasMeasure(fontName, weight)` | Canvas pixel scan → `{oiRatio, strokePct}` | +| `renderScoreUI(...)` | Shared scoring renderer used by Tab 2 and Tab 3 | +| `FONTS[]` | Curated font data array (25 entries) | +| `renderGrid()` | Re-renders Tab 1 grid from current filter/search state | + +--- + +## Embedding in Odoo Knowledge + +```html + +``` + +**Hosting options (priority order):** +1. Gitea raw file URL — `https://git.alwisp.com/jason/ada-font-analyzer/raw/branch/main/ada-font-analyzer.html` (CoWork-native, recommended) +2. Odoo attachment with direct URL +3. MPM web server / CDN + +**Note:** Odoo CSP compatibility with `fonts.googleapis.com` has not been tested. If blocked, Tab 2 preview will fail silently (tool remains functional, fonts won't render in preview panel). + +--- + +## Curated Font List — Maintenance + +Fonts are defined in the `FONTS[]` array in the JS. Use Tab 2 or Tab 3 to measure a font before adding it. Each entry: `name`, `style`, `cat`, `tags`, `compliance` (per-criterion pass/fail), `notes`, `gf` (URL-encoded family name for GF API/download links). + +**Filter tags:** `"best"` = fully compliant, `"transit"` = transit-tested, `"caution"` = use with caution. + +**Transit-tested badge:** Applied to fonts with known real-world transit deployment (Roboto, Open Sans, Inter, Work Sans, Noto Sans, Atkinson Hyperlegible, Montserrat). Heuristic, not a formal registry — update based on documented deployments. + +--- + +## Known Limitations + +| Item | Status | +|---|---| +| WOFF/WOFF2 binary parsing | Not implemented — falls back to canvas. Future: pako.js for WOFF, Brotli WASM for WOFF2. | +| §703.5.9 line spacing | Not implemented. `hhea.lineGap` already parsed — straightforward add. | +| Full GF catalog scan | 25 curated fonts are a training-knowledge subset of ~1,500+ GF fonts. Full scan needs separate CoWork tool + GF Developer API key. | +| Weight-specific compliance | `compliance` object is worst-case only. Per-weight table is a planned enhancement. | +| OTF CFF table support | CFF-flavored OTFs fall back to canvas gracefully. | +| Odoo iframe sizing | Narrow viewport collapses to single column — test at your iframe width. | + +--- + +## Troubleshooting + +| Symptom | Fix | +|---|---| +| Tab 2 fonts don't render | Check if `fonts.googleapis.com` is blocked by browser or Odoo CSP | +| "Download all selected" only opens first tab | Allow pop-ups from the tool's origin domain (700ms stagger between opens requires pop-up permission) | +| Tab 3 OTF shows canvas-only metrics | CFF-flavored OTF — metrics from canvas, not binary tables. Expected behavior. | +| Tab 3 WOFF/WOFF2 canvas only | WOFF decompression not implemented — use TTF/OTF files instead | + +--- + +## Files in This Repo + +| File | Purpose | +|---|---| +| `ada-font-analyzer.html` | The tool — all HTML, CSS, JS, data, and TTF parser in one file | +| `ada_tool_context.md` | Session handoff doc — architecture, API notes, maintenance guide, change log | +| `ada_tool_decisions.md` | Decision trail — why each design choice was made, what was considered and rejected | + +--- + +## Changelog + +| Date | Version | Change | +|---|---|---| +| 2026-05-05 | 1.0 | Initial build — three tabs: Browse curated fonts, Test Google Font, Upload TTF/OTF. Binary TTF parser, canvas cross-check, GF download links, light-on-dark preview. |