Android text oversized glyph clipping #45364
Open
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:
Android TextView native implementation clips oversized font glyphs due to padding box clipping. This can be found in TextView sources:
https://android.googlesource.com/platform/frameworks/base/+/jb-mr0-release/core/java/android/widget/TextView.java#4852
https://android.googlesource.com/platform/frameworks/base/+/jb-mr0-release/core/java/android/widget/TextView.java#4838
This causes dense fonts to be clipped. Example of such clipping in Android built-in 'notoserif' font, with 'italic' style and weight '900' (see top row):
![image](https://private-user-images.githubusercontent.com/21238529/347543161-9b109ba9-ce46-4aeb-89ce-d69f32cdb5b2.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MzkwNzkxOTUsIm5iZiI6MTczOTA3ODg5NSwicGF0aCI6Ii8yMTIzODUyOS8zNDc1NDMxNjEtOWIxMDliYTktY2U0Ni00YWViLTg5Y2UtZDY5ZjMyY2RiNWIyLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAyMDklMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMjA5VDA1MjgxNVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWY3YjQ0NWYwZGRjNDc0NmEwYjk4NGQ4ZmQ1OTM4ZmJkZDE5N2IxMDcyZDY2M2U2MWIwMWJjYzA2OTMzZGU5OWUmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.pBoWKTCqMjbleYnWAwhrCufcbqK-GXk2OP955PqCntQ)
More zoomed in:
![image](https://private-user-images.githubusercontent.com/21238529/347690275-384c93d1-8ccc-4d66-9184-026846424dc5.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MzkwNzkxOTUsIm5iZiI6MTczOTA3ODg5NSwicGF0aCI6Ii8yMTIzODUyOS8zNDc2OTAyNzUtMzg0YzkzZDEtOGNjYy00ZDY2LTkxODQtMDI2ODQ2NDI0ZGM1LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAyMDklMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMjA5VDA1MjgxNVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTM4MjgyMDM3ODU1NjkyZTM4NWY2MzhjMDRkN2Y4OWE2NjYyNTk5ZTE0NTA2M2UwMmY4NTdmNWFjMjIyYTg1NGImWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.qFnauAD8ZpvX8o4Bnnjr4qDBwHx3F-9rswaJ9MpB3zs)
Bottom row "E is not cut" is the one with fix applied.
This is just an example, on some dense and (very) bold fonts, the effect is much worse and noticable.
To follow an idea of expanding
overflow
styling support: #44734 I decided to bind this behavior withoverflow: visible
style. I'm not certain if this is desired though, in my own project, I've created a dedicatedclipRect
prop.The solution idea is to make TextView draw on custom OverflowingCanvas, and then apply custom canvas bitmap to TextView's canvas. This should not be too memory heavy - the same bitmap is used in both canvases.
Changelog:
Test Plan: