iOS: nested Text with mixed fonts + lineHeight paints glyphs shifted/clipped under tail truncation — while onTextLayout/onLayout report correct positions
Chưa có ai nhận issue này.
- Ngôn ngữ chính
- C++
- Star
- 127k
- Fork
- 25.3k
- Merge trung bình
- 1 ngày 23 giờ
- Pull request đã merge (30 ngày)
- 4
Mô tả
Description
A one-line (Arabic, RTL) containing nested spans where one span uses a different font/size (a fallback-font run), with an explicit lineHeight, paints its glyphs vertically shifted and bottom-clipped when the line is tail-truncated on iOS. Untruncated rows with identical structure paint correctly. The shift worsens with scroll depth in a ScrollView.
Reproduces across fonts: dramatic with a mushaf-grade face (KFGQPC Hafs — glyphs sink and bottom-clip), subtle but present with Scheherazade New (descender marks such as hamza+kasra paint slightly low). Severity scales with how far the font's ink extents diverge from its nominal metrics.
Critically: the shift is invisible to the layout APIs. onLayout and onTextLayout report identical geometry for shifted and correct rows — the repro measures both and prints the delta, which reads 0.0px while the painted output visibly diverges (the label is kept as a negative control). The defect appears to sit between text layout and rendering.
Plain single-font rows, flat rows, narrow rows, and RTL-aligned rows all paint correctly (mutations M1–M3 in the repro, all Δ 0.0 and visually clean) — the mixed-font nested run (M4) is the trigger.
Possibly related: #19653 (baseline offset computed from largest font-height in the string), #53092 (nested Text misalignment with lineHeight under the New Architecture).
Screenshots (also in the repo README): truncated rows sinking/clipping under Hafs+M4 vs their fitting pair rows.
Steps to reproduce
Reproduces across fonts: dramatic with a mushaf-grade face (KFGQPC Hafs — glyphs sink and bottom-clip), subtle but present with Scheherazade New (descender marks such as hamza+kasra paint slightly low). Severity scales with how far the font's ink extents diverge from its nominal metrics.
- Clone https://github.com/muhasabahhub/rn-arabic-seat, npm install, npx expo start, open in Expo Go on a physical iPhone.
- Select: tail (stock) + Hafs (mushaf) + M4 mixed-run.
- Scroll the list. Rows come in pairs sharing their opening words — first fits, second truncates.
- Compare pairs against the red guide: truncated rows paint shifted/bottom-clipped, worsening with scroll depth.
- Note the Δ label reads 0.0px — onLayout/onTextLayout report identical seating while the paint diverges (negative control).
- Toggle M4 off (or fonts to Amiri): all rows paint correctly, Δ 0.0 and visually clean.
React Native Version
0.86.3
Affected Platforms
Runtime - iOS
Output of npx @react-native-community/cli info
Expo SDK 57 managed project — envinfo equivalent below; full dependency table in the repo README.
System:
OS: Windows 11 10.0.26200
CPU: (22) x64 Intel(R) Core(TM) Ultra 7 155H
Memory: 3.80 GB / 15.59 GB
Binaries:
Node: 24.13.1 - C:\Program Files\nodejs\node.EXE
npm: 11.19.0 - C:\Program Files\nodejs\npm.CMD
npmPackages:
expo: ~57.0.18 => 57.0.19
expo-font: ~57.0.2 => 57.0.3
react: 19.2.3 => 19.2.3
react-native: 0.86.3 => 0.86.3
react-native-safe-area-context: ~5.7.0 => 5.7.0
Device: iPhone 15, iOS 23.3.1, physical device via Expo Go. New Architecture (Fabric), Hermes.
Stacktrace or Logs
No crash or error output — this is a silent rendering defect. Nothing is logged.
The relevant "log" is the measurement built into the repro itself: each row pair prints a Δ label computed from onLayout + onTextLayout. For visibly shifted rows, the APIs report Δ 0.0px — i.e. the layout system emits no signal that the painted output has diverged. Sample readout while the defect is visible on screen:
pair 3 (Hafs, tail, M4): reported Δ 0.0px — painted output shifted and bottom-clipped (screenshot 1)
pair 5 (Hafs, tail, M4): reported Δ 0.0px — painted output shifted, worsens with scroll depth (screenshot 2)
The absence of any discrepancy in the layout events is part of the report: the defect is undetectable programmatically from the JS layer.
MANDATORY Reproducer
https://github.com/muhasabahhub/rn-arabic-seat
Screenshots and Videos
Hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Hướng nghiên cứu
Bắt đầu với reproducer bắt buộc rn-arabic-seat, chạy nó trên iPhone vật lý và so sánh các dòng M4 tail-truncated sử dụng Hafs hoặc Scheherazade New với các dòng đối chứng tương ứng. Không có tệp nguồn hay test React Native nào được nêu tên; hoàn tất có nghĩa là các dòng RTL có font hỗn hợp không còn được render bị lệch hoặc bị cắt ở phía dưới khi tail truncation, trong khi hình học layout được báo cáo vẫn chính xác.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Đánh giá
- Công nghệ
- ios, react-native
- Lĩnh vực
- mobile
- Loại issue
- Lỗi
- Độ khó
- 4/5
- Thời gian dự kiến
- 3-5 ngày
- Mức độ hoạt động
- Sôi nổi
- Độ rõ ràng
- Khá rõ ràng
- Mức phù hợp với người mới
- 38/100