fix(print): deterministic PPD locale precedence for media labels (#181) #195

Merged
gronod merged 1 commits from feat/181-canon-media-locale into milestone/m11-print-settings 2026-09-15 19:27:48 +01:00
Owner

Refs #181

M11 Phase 3 — Canon media types displayed Thai characters because CupsParsers.ppdChoiceLabels did last-write-wins and the Canon Pro9500 PPD's th.CNIJMediaType block sits after the unqualified base block.

Changes

  • CupsParsers.ppdChoiceLabels: collect (id, qualifier, label) then resolve per id with deterministic precedence — unqualified *Key > en_US. > en. > first-qualified-seen (E3). A qualified-only id still gets its first-seen qualified label (R9). looksLikeLocale heuristic unchanged.
  • New ppdUnescape decodes <XX> hex escapes (<2F>/, <20>→space) in ids and labels; invalid pairs pass through (E2).
  • CupsService.loadPPD: UTF-8 first, .isoLatin1 only on decode failure — never Latin-1 first, so the UTF-8 Thai labels are not mojibake'd (E2/R10).
  • Canon-shaped fixture: unqualified base block early, trailing th. block — the ordering that exposed the bug.

Tests (fresh build/DerivedData-feat-181-canon-media-locale, x86_64)

xcodebuild test -scheme ICCery -destination 'platform=macOS' \
  -derivedDataPath build/DerivedData-feat-181-canon-media-locale \
  ARCHS="$(uname -m)" CODE_SIGNING_ALLOWED=YES CODE_SIGN_IDENTITY='-' \
  -only-testing:ICCeryCoreTests/CupsParserTests \
  -only-testing:ICCeryCoreTests/CupsOptionsFilterTests \
  -only-testing:ICCeryUITests/Milestone11PrintSettingsUITests \
  -only-testing:ICCeryUITests/Milestone3UITests
  • CupsParserTests: 22 executed, 0 failures
  • CupsOptionsFilterTests: 6 executed, 0 failures
  • Milestone11PrintSettingsUITests: 4 executed, 0 failures
  • Milestone3UITests: 6 executed, 0 failures

Wider core suite (-only-testing:ICCeryCoreTests): 475 executed, 0 failures.

Errata honored: E1 (no hardcoded count — every enumerated CNIJMediaType choice asserted non-Thai + 18 named spot-checks), E2 (UTF-8-first decode + hex unescape), E3 (deterministic precedence). Existing testPpdLabels goldens and Epson EPIJ_Qual labels unaffected. Panel binding/capture-return untouched (#186 scope).

Refs #181 M11 Phase 3 — Canon media types displayed Thai characters because `CupsParsers.ppdChoiceLabels` did last-write-wins and the Canon Pro9500 PPD's `th.CNIJMediaType` block sits after the unqualified base block. ## Changes - `CupsParsers.ppdChoiceLabels`: collect `(id, qualifier, label)` then resolve per id with deterministic precedence — unqualified `*Key` > `en_US.` > `en.` > first-qualified-seen (E3). A qualified-only id still gets its first-seen qualified label (R9). `looksLikeLocale` heuristic unchanged. - New `ppdUnescape` decodes `<XX>` hex escapes (`<2F>`→`/`, `<20>`→space) in ids and labels; invalid pairs pass through (E2). - `CupsService.loadPPD`: UTF-8 first, `.isoLatin1` only on decode failure — never Latin-1 first, so the UTF-8 Thai labels are not mojibake'd (E2/R10). - Canon-shaped fixture: unqualified base block early, trailing `th.` block — the ordering that exposed the bug. ## Tests (fresh `build/DerivedData-feat-181-canon-media-locale`, x86_64) ``` xcodebuild test -scheme ICCery -destination 'platform=macOS' \ -derivedDataPath build/DerivedData-feat-181-canon-media-locale \ ARCHS="$(uname -m)" CODE_SIGNING_ALLOWED=YES CODE_SIGN_IDENTITY='-' \ -only-testing:ICCeryCoreTests/CupsParserTests \ -only-testing:ICCeryCoreTests/CupsOptionsFilterTests \ -only-testing:ICCeryUITests/Milestone11PrintSettingsUITests \ -only-testing:ICCeryUITests/Milestone3UITests ``` - CupsParserTests: 22 executed, 0 failures - CupsOptionsFilterTests: 6 executed, 0 failures - Milestone11PrintSettingsUITests: 4 executed, 0 failures - Milestone3UITests: 6 executed, 0 failures Wider core suite (`-only-testing:ICCeryCoreTests`): **475 executed, 0 failures**. Errata honored: E1 (no hardcoded count — every enumerated `CNIJMediaType` choice asserted non-Thai + 18 named spot-checks), E2 (UTF-8-first decode + hex unescape), E3 (deterministic precedence). Existing `testPpdLabels` goldens and Epson `EPIJ_Qual` labels unaffected. Panel binding/capture-return untouched (#186 scope).
gronod added the Kind/Bug
Priority
Medium
3
Project/ICCery-v2Bug/Backend
labels 2026-09-15 19:27:35 +01:00
gronod added 1 commit 2026-09-15 19:27:35 +01:00
Refs #181

Co-Authored-By: Devin <devin@cognition.ai>
gronod self-assigned this 2026-09-15 19:27:44 +01:00
gronod added this to the M11 — Printer settings completeness & dialog binding milestone 2026-09-15 19:27:44 +01:00
gronod merged commit 1767792f75 into milestone/m11-print-settings 2026-09-15 19:27:48 +01:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: gronod/iccery-v2-mac#195