Skip to content

PDF: lay each day out along a rail with transport mode icons - #111

Merged
aquasolterra merged 1 commit into
mainfrom
pdf-timeline-rail
Oct 10, 2026
Merged

aquasolterra merged 1 commit into
mainfrom
pdf-timeline-rail

Conversation

@aquasolterra

Copy link
Copy Markdown
Member

The itinerary in the PDF export now reads like the app's timeline. Each day is a rail with places as dots in the trip's accent and legs as their transport mode's icon in a disc. The mode's name stays in the text.

What changed

  • Layout (trip_pdf.dart): each row draws its own piece of the rail, from a day's first node to its last. A decision's accent bar is drawn per row in the text column, so the rail runs past it unbroken.
  • Which icon: the one this database gives the mode (transportModeIconsByKey, read by the export). That includes an icon chosen for a built-in, which a bundle does not carry. pdfTransportModeIcon falls back to the bundle's custom-mode icon, then to the built-in's own.
  • Icon font: Flutter's Material Icons font is CFF (OTTO), and package:pdf parses TrueType only. It falls back to Latin-1 and throws on the code point. assets/fonts/build_pdf_icons.py therefore converts exactly the Icons.* that transport_mode.dart names out of the SDK's own font into MaterialIconsPdf.ttf (~8 KB). The font is CC BY 4.0; its attribution is registered on the license page.
  • Left side bearing fix: both icon fonts wrote lsb = 0 into hmtx, while the outlines start at xMin > 0. A TrueType renderer puts the origin at xMin − lsb, so each glyph was drawn shifted left. This affected the app too. Measured in Flutter's engine (flutter_test, Linux), the horse, gondola, chairlift and T-bar icons sat 8–15% of their size left of center; after rebuilding TransportGlyphs.ttf they are exactly centered.

Testing

  • New tests: every icon in kTransportModeIcons has a glyph in the font the PDF picks for it; lsb == xMin for both fonts (fails on the old TransportGlyphs.ttf); icon resolution order; transportModeIconsByKey; the icon font is embedded for a trip with a leg.
  • flutter analyze clean, full suite passes (1634).
  • Rendered a sample trip with places, several modes, a decision and a leg without a mode, then inspected the result.
  • TripPdfFonts.load() loads both fonts through the real asset bundle.

To check on a device (CI APK)

  • Export a trip with legs as PDF and look at the rail and icons.
  • In the timeline, the horse, gondola, chairlift and T-bar icons sit centered in their disc. Measured only on Linux so far.

No new or changed strings, so nothing is missing from app_zh.arb. SECURITY.md is unaffected: no new host, permission or parsed foreign format.

🤖 Generated with Claude Code

The itinerary in the PDF now reads like the app's timeline: a rail per day,
places as dots in the trip's accent, legs as their mode's icon in a disc.
The icon is the one this database gives the mode, so an icon chosen for a
built-in reaches the paper too; the bundle only carries custom ones.

Flutter's Material Icons font is CFF-based and package:pdf parses TrueType
only, so build_pdf_icons.py converts the transport icons out of the SDK's
own font into MaterialIconsPdf.ttf (CC BY 4.0, ~8 KB).

Both icon fonts wrote a left side bearing of 0 into hmtx, which a TrueType
renderer reads as an origin at xMin, drawing each glyph shifted left. That
also put the app's horse and lift icons up to 15% of their size off center;
TransportGlyphs.ttf is rebuilt with lsb = xMin, and a test guards both.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@codecov

codecov Bot commented Oct 10, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 83.69565% with 15 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
lib/features/sharing/trip_pdf.dart 86.90% 11 Missing ⚠️
...eatures/trips/presentation/trip_detail_screen.dart 0.00% 4 Missing ⚠️

📢 Thoughts on this report? Let us know!

@aquasolterra
aquasolterra merged commit 350be62 into main Oct 10, 2026
5 checks passed
@aquasolterra
aquasolterra deleted the pdf-timeline-rail branch October 10, 2026 20:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant