Files

148 lines
7.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ada-font-analyzer
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 (100900) 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 55110% | §703.5.4 | Canvas: rendered pixel widths. TTF: `hmtx` advance widths ÷ `sCapHeight` |
| Stroke weight 1030% of height | §703.5.7 | Canvas: thinnest ink row scan. TTF: `usWeightClass` → stroke % mapping |
| Character spacing 1035% | §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
<iframe
src="https://git.alwisp.com/jason/ada-font-analyzer/raw/branch/main/ada-font-analyzer.html"
width="100%"
height="900px"
frameborder="0"
style="border-radius:8px;">
</iframe>
```
**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. |