# Native range-display truncation evidence ## Reported symptom On the target 1920x1080 television, a batch that called tickets `00010` and `00011` rendered the main current-call field as only `00010 至`; the latest-ticket metric at the right still showed `00011`. ## Boundary verification The production public snapshot was read on 2026-08-12 from `GET https://queue.nianxx.cn/api/display/YYHHC/snapshot`. It contained: - `latest_ticket_number: "00011"` - `current_batch.ticket_count: 2` - `current_batch.tickets[0].display_number: "00010"` - `current_batch.tickets[1].display_number: "00011"` `DisplayFormatting.currentBatchNumbers` therefore produces the complete string `00010 至 00011`. This rules out the server response, JSON parser, and range formatter as the cause. ## Root cause The original native current-number `TextView` started at 74sp, allowed one line, and called `NativeDisplayUi.autoSize`. That helper only activated Android platform auto-size on API 26 and later, although the APK supports API 23. On API 23-25, long range text stayed at 74sp and could be silently clipped by the half-width current-call panel. Platform behavior and display density also made the guarantee device-dependent on newer releases. An API-25 Robolectric regression using a full `ProjectDisplayView`, 1920x1080 exact layout, and the real two-ticket snapshot was run before the fix. Its red signal confirmed the legacy view retained the initial 74sp rather than applying a fitting policy. ## Fix and invariant `SingleLineFitTextView` now owns current-call fitting on API 23 and later. On text, size, or padding changes it: - computes actual content width and height after compound padding; - measures the real text and font metrics with a copy of the active `TextPaint`; - binary-searches for the largest whole-sp size that fits both dimensions; - enforces a single line and never ellipsizes; - falls below the normal 30sp readability floor only when necessary to preserve the complete ticket range. Short single numbers still receive the largest fitting size, up to 74sp. ## Verification - `gradlew.bat clean testDebugUnitTest lintDebug assembleDebug`: PASS. - JVM tests: 56 across 12 suites, 0 failures, 0 errors, 0 skipped. - Lint: 0 errors, 24 warnings. - `ProjectDisplayViewTest` locks the full `00010 至 00011` string, one-line behavior, and no ellipsis on API 25. - A narrow ASCII control asserts the fitted `TextPaint` width and font height are within actual content bounds; deterministic sizing tests call the production two-stage decision and lock largest-fitting selection, full-size selection, below-floor fallback, and the 1sp terminal boundary. - APK: versionCode 9, versionName 1.5.2; Android Debug v1/v2 signatures verified. - Build and deliverable SHA-256: `0D56C10B8CE706893F3EA8E59B21329847517F56F7347ABEA127AB30C6C71D77`. ## Remaining acceptance Robolectric's host font metrics are not the target television's font metrics. The production code uses the device's real `TextPaint`, but final acceptance still requires installing 1.5.2 on the target television and visually confirming both endpoints for `00010 至 00011` and at least one wider representative range.