feat: replace 2× supersampling with 1× bitmap fonts and explicit dithering#80
Open
ghcpuman902 wants to merge 9 commits into
Open
feat: replace 2× supersampling with 1× bitmap fonts and explicit dithering#80ghcpuman902 wants to merge 9 commits into
ghcpuman902 wants to merge 9 commits into
Conversation
- Introduced a new utility function `formatErrorMessage` to standardize error messages across the application. - Updated `executeSqlStatements` and database utility functions to utilize the new error formatting. - Revised README to clarify local development setup, including database configuration and initial setup instructions.
- Added new scripts for generating bitmap fonts and benchmarking font performance. - Updated package.json to include new font generation commands and dependencies. - Improved no-default-recipe error messaging and device add dialog UX. - Introduced new font styles in global CSS and updated components to utilize these styles. - Improved sign-in form with password visibility toggle for better user experience. Co-authored-by: Cursor <cursoragent@cursor.com>
TRMNL firmware calls /api/setup with MAC only (no Access-Token). Allow pre-registered devices imported from trmnl.com/devices to complete setup, add a MAC field when adding devices manually, and log incoming request headers to system logs for debugging. Co-authored-by: Cursor <cursoragent@cursor.com>
… designer - Introduced AGENTS.md to provide a comprehensive index for Next.js documentation, emphasizing the importance of consulting the docs before tasks. - Added a new script command for benchmarking font glyphs in package.json. - Enhanced bitmap font designer with new utility functions for handling font metrics and improved grid handling. - Updated bitmap font JSON files to support dynamic width and adjusted metrics for better rendering. - Introduced new generated bitmap font files for improved design consistency.
- Added new font variable `--font-pixelify-sans` to global CSS for improved typography options. - Updated `RootLayout` to suppress hydration warnings for better rendering consistency. - Enhanced `SimpleText` component to utilize `Pixelify Sans` font and added support for new bitmap font data. - Improved bitmap font designer with additional utility functions and updated editor UI for better glyph management. - Adjusted metrics and grid handling in bitmap font utilities for enhanced performance and accuracy.
- Removed supersampling settings from multiple recipe definitions to streamline rendering. - Updated global CSS to ensure proper formatting and consistency across components. - Enhanced styles in the ResponsiveExample component for better visual presentation. - Cleaned up unnecessary code and improved readability in bitmap font designer components.
- Added ditherImageToDataUrl function for converting images to dithered data URLs, improving visual quality for grayscale images. - Integrated dithering functionality into recipe rendering, allowing for dynamic image processing based on device context. - Updated recipe definitions to include prepareForDevice method for enhanced image handling. - Enhanced Wikipedia and Album components to utilize dithered images, improving overall presentation. - Introduced tests for dithering functionality to ensure reliability and performance.
- Added a new module for album city data, including city IDs, labels, timezones, and Wikipedia titles. - Updated the album component to utilize the new city data, allowing for dynamic city selection and improved presentation. - Enhanced data fetching logic to retrieve city-specific images and information from Wikipedia. - Refactored the album component to support optional custom image URLs and improved layout for better user experience. - Introduced a new utility function for resolving image URLs based on city data and custom inputs.
Apply Biome auto-fixes, align convert-legacy-font tests with defaultCharGap metrics, regenerate font packs, and remove the PR draft notes file. Co-authored-by: Cursor <cursoragent@cursor.com>
Collaborator
Author
Render pipeline — commit trailFor reviewers tracing the 2× removal vs new dithering:
What was removed (the old blanket pipeline): // lib/recipes/render/settings.ts (deleted)
export const SUPERSAMPLE_SCALE = 2;
// recipes: renderSettings: { supersample: true }
// rasterize: render 2× → sharp.resize(1×) → BMP with edge-snapWhat replaced it:
Release: merge to |
rbouteiller
requested changes
Jun 26, 2026
rbouteiller
left a comment
Collaborator
There was a problem hiding this comment.
It seems we have some scripts repeated in scripts/lib and lib/bitmap-font, maybe we want an unified surface
Collaborator
There was a problem hiding this comment.
This file seems not needed and not referenced in the code, should we delete it ?
Collaborator
There was a problem hiding this comment.
SHould we commit generated files ? Or have a generation step in readme ?
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.
Summary
This PR replaces the old 2× supersampling + blanket dither/heuristic pipeline with 1× rendering and targeted crispness tools: traced bitmap fonts for text, palette-aware photo dithering at data-fetch time, and opt-in Floyd-Steinberg only where a recipe explicitly asks for it.
Render pipeline change (important)
Before (on
main):hacker-news,calendar,simple-text, andwikipediasetrenderSettings: { supersample: true }.getRenderScale()(lib/recipes/render/settings.ts) rendered Takumi/Satori output at 2× device resolution, then downscaled with sharp back to physical pixels.applyEdgeSnap ?? true) as a global sharpness hack.After (this PR):
supersampleandlib/recipes/render/settings.tsare removed.applyEdgeSnap ?? false).BitmapText, and packs (Block Kie, Geist Pixel Grid/Square, Geneva, Pixelify Sans) for pixel-aligned text at native resolution.prepareForDevice— album and wikipedia pre-dither embedded photos with palette-aware white-noise dithering (ditherImageToDataUrl) before JSX render, using the device’s gray levels.renderSettings.dither: trueenables Floyd-Steinberg during palette quantization inrenderDeviceImage(default off). No recipe sets this yet; photos useprepareForDeviceinstead.Expected visual change: Photo recipes (album, wikipedia thumbnails) should improve. Text-heavy recipes still on Takumi/Satori vector fonts (
hacker-news,calendar,local-news, wikipedia body) may look softer until migrated toBitmapText— that is intentional; 2× downscale was masking the problem rather than fixing it.Also includes: bitmap font designer overhaul,
/api/bitmap-fonts/[packId], album city presets, TRMNL MAC setup fix, sharedformatErrorMessage, README local-setup notes, anddocs/pixel-font.mdspec.Test plan
pnpm lintpnpm typecheckpnpm test(105 tests)pnpm buildsupersample: true(e.g. hacker-news, simple-text) — expect softer vector text until bitmap font migrationBitmapTexton simple-text / device preview — baseline alignmentpnpm run generate:fontsFollow-up
wikipedia,hacker-news,calendar,local-news) to tracedBitmapTextpacks for fully crisp 1× text.fix/remove-grayscale-parameter) if both touch the render/device path.