Typography improvements #2
Open
irvingpop wants to merge 9 commits into
Open
Conversation
Add seven new fields to frameOptionsSchema with backward-compatible defaults: titleWeight (800), subtitleWeight (500), titleSpacing (0), subtitleSpacing (0), fontFamily (Inter stack), titleLineHeight (1.15), autoFitTitle (false). Wire them through as CLI flags on the frame subcommand: --title-size, --subtitle-size, --title-weight, --subtitle-weight, --title-spacing, --subtitle-spacing, --title-color, --subtitle-color, --font-family, --title-line-height, --auto-fit-title. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
New src/core/fonts.ts exposes checkFont() and firstFamily().
checkFont() uses execFileSync('fc-match') to verify whether the first
family in a font stack is installed. Returns null on systems without
fc-match (Windows, minimal Linux) so callers can skip gracefully.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… multi-line Phase 1 — letter-spacing fix: - Default titleSpacing and subtitleSpacing to 0 (removes the 1.2.1 overflow bug where letter-spacing = fontSize * 0.08 caused captions to exceed canvas width with Inter installed) - Add font-kerning="normal" text-rendering="geometricPrecision" to all <text> elements in buildDeviceTextSvg and buildTextSvg Phase 2 — wire new typography opts: - buildDeviceTextSvg and buildTextSvg now use opts.titleWeight, opts.subtitleWeight, opts.fontFamily, opts.titleSpacing, opts.subtitleSpacing, opts.titleLineHeight instead of hardcoded values - buildTextSvg gains multi-line support via renderMultilineText Phase 3a — multi-line title height fix: - titleH was hardcoded to fontSize * 2 regardless of line count, pushing the device off-canvas for multi-line titles; now computed as lines.length * fontSize * lineHeight + fontSize * 0.5 Phase 3b — --auto-fit-title: - computeAutoFit() shrinks titleSize in 0.005 steps down to a 0.04 floor, then falls back to word-boundary wrap if still too wide - estimateTextWidth() heuristic: avg char ratio interpolated linearly from 0.50 (weight 400) to 0.55 (weight 800) Phase 4 — font check integration: - frameScreenshot() calls checkFont() on the resolved fontFamily; throws if an explicitly-passed --font-family is unavailable, warns once (deduped) if the default Inter stack falls back Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add "prepare": "npm run build" so that npx github:irvingpop/appshots#<ref> auto-builds dist/ on install without needing a committed dist/ directory. Bump version 1.2.1 → 1.3.0 to reflect the new typography flags, auto-fit, and multi-line fixes added in this release. Add test scripts: test, test:watch, test:goldens, test:update-goldens. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Unit tests (tests/unit.test.ts — 21 tests): - firstFamily(): quote stripping, single/multi-family stacks - estimateTextWidth(): weight interpolation math at 400/600/800 - computeAutoFit(): short title passthrough, font shrink, word wrap at floor, explicit \n passthrough, padding sensitivity, floor clamp - frameOptionsSchema: Phase 1+2 defaults (spacing=0, weights, lineHeight, fontFamily, autoFitTitle) Golden image tests (tests/golden.test.ts — 5 tests): - Device frame with title+subtitle at bottom (baseline path) - Auto-fit long title with text at top - Multi-line title via literal \n - No-device-frame path (buildTextSvg) - Custom typography flags (titleWeight, titleSize, titleSpacing) Goldens live in tests/goldens/ and are compared with pixelmatch at a 0.05% pixel-diff threshold. Regenerate with: UPDATE_GOLDENS=1 npm run test:update-goldens Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add typography example to Quick Start (--title-weight, --title-size, --auto-fit-title, multi-line \n) - Expand CLI reference table with all 11 new frame flags - Add new typography fields to the config file example - Add Typography section covering multi-line titles, auto-fit behavior, and font requirements - Update programmatic API example to show new options Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Subtitles now render multi-line via the same tspan path as titles, with layout that adjusts automatically: in textPosition=bottom the subtitle flows upward and pushes the title further up; in top it flows downward; the no-device-frame path recomputes subtitleH from line count so the screenshot area shrinks instead of getting clipped. A shared splitLines() helper accepts real \n, \r\n, and the literal backslash-n / \r\n sequences bash passes from --subtitle "Foo\nBar", so config files and programmatic callers work as well as the CLI. Subtitle line-height is hardcoded to 1.3 — no new flag. Adds 3 new golden tests (multi-line subtitle bottom, multi-line both top via real \n, no-frame multi-line subtitle) and unit tests for splitLines covering all four newline forms. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Closes #1. The hardcoded phoneScale ratios in getFrameConfig (0.775 phones, 0.88 tablets) produce inconsistent canvas-fill rhythm across devices when framing the same project. Adds an optional override at the schema, CLI, and config-file level — default behavior is unchanged when the flag is unset. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
feat: add --phone-scale flag to override per-device phoneScale
Author
|
@albertnahas any feedback? |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
hey @albertnahas thank you for this awesome project! I wanted to use it for my upcoming app release, but I ran into some issues getting the text to display just how I wanted it. Please accept the following contribution with some improvements, I added testing and took care not to break any existing functionality.
Headline fixes
fontSize × 0.08default was pushing captions past the canvas edge whenever Inter (or any properly-kerned font) was installed. SVG text now also usesfont-kerning="normal"andtext rendering="geometricPrecision".titleHwas hardcoded tofontSize × 2regardless of line count, so two-line titles shoved the device frame off-canvas. Now computed from actual line count.<text>element regardless of newlines in the input. Now they render multi-line via the sametspanpath as titles, with layout that flows in the right direction fortextPosition=topvsbottom.\n/\r\n(config files, programmatic callers) and the literal backslash-n that bash passes from--title "Foo\nBar".New knobs (all behind opt-in flags, defaults preserve existing behavior)
--title-weight,--subtitle-weight,--title-spacing,--subtitle-spacing,--title-color,--subtitle-color,--title-line-height--font-familywith anfc-match-based availability check — warns once when the default Inter stack falls back, throws when an explicit--font-familyisn't installed (silently skips on systems withoutfc-match)--auto-fit-title— shrinks title size to a floor, then falls back to balanced word-wrapTests + distribution
firstFamily,estimateTextWidth,computeAutoFit,splitLines, and schema defaultsUPDATE_GOLDENS=1"prepare": "npm run build"so consumers cannpx github:<fork>#<ref>without a committeddist/All changes are upstream-friendly: no renames, no removed flags, no changed defaults except the strict letter-spacing bug fix.