Fix hairline borders not visible (#11527)
This commit is contained in:
@@ -403,3 +403,25 @@ index 3e48dabc6fffc246fd0517ef5f3f2b7721115511..ea4ba5fdf359c513a5ca4f0e94492fac
|
||||
- }
|
||||
+ auto rootShadowNodeHolder = shadowTree.getCurrentRevision().rootShadowNode;
|
||||
+ const auto* rootShadowNode = rootShadowNodeHolder.get();
|
||||
diff --git a/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm b/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm
|
||||
--- a/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm
|
||||
+++ b/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm
|
||||
@@ -827,9 +827,17 @@
|
||||
} else {
|
||||
CGSize imageSize = image.size;
|
||||
UIEdgeInsets imageCapInsets = image.capInsets;
|
||||
+ // The stretchable middle is whatever lies between the cap insets. The image
|
||||
+ // may be larger than capInsets + 1 (its size is ceil'd to whole points), so
|
||||
+ // deriving the middle from the caps rather than assuming a 1pt band keeps
|
||||
+ // the bottom/right caps at their true size. A phantom cap here makes the
|
||||
+ // caps overflow sub-pixel-sized layers (e.g. hairline borders), and the
|
||||
+ // squeezed mesh + nearest-neighbor filtering drops the stroke entirely.
|
||||
CGRect contentsCenter = CGRect{
|
||||
CGPoint{imageCapInsets.left / imageSize.width, imageCapInsets.top / imageSize.height},
|
||||
- CGSize{(CGFloat)1.0 / imageSize.width, (CGFloat)1.0 / imageSize.height}};
|
||||
+ CGSize{
|
||||
+ (imageSize.width - imageCapInsets.left - imageCapInsets.right) / imageSize.width,
|
||||
+ (imageSize.height - imageCapInsets.top - imageCapInsets.bottom) / imageSize.height}};
|
||||
layer.contents = (id)image.CGImage;
|
||||
layer.contentsScale = image.scale;
|
||||
|
||||
|
||||
@@ -159,3 +159,22 @@ PR: https://github.com/facebook/react-native/pull/57483
|
||||
|
||||
Issue: https://github.com/react/react-native/issues/53450#issuecomment-3298157830
|
||||
Bandaid fix taken from: https://github.com/react/react-native/commit/581d643a9e59fd88f93757f80194e1efd11bd0e5
|
||||
|
||||
## RCTViewComponentView.mm Patch - Hairline border strokes dropped at certain subpixel Y offsets on New Arch
|
||||
|
||||
Symptom: dividers built as `borderTopWidth: hairlineWidth` vanish on some screens and not
|
||||
others, deterministically by the view's absolute subpixel Y. A background fill of the same
|
||||
geometry always renders.
|
||||
|
||||
Cause: Fabric draws borders as a stretched 9-slice image. The consumer
|
||||
(`RCTAddContourEffectToLayer`) hardcodes the stretchable middle as a 1pt band, which matched
|
||||
the image the producer built until RN 0.81. facebook/react-native#54237 changed the image
|
||||
size to `ceil(insets) + 1 + ceil(insets)` without updating that formula, so for fractional
|
||||
(hairline) insets the labels no longer match the image: transparent filler is treated as a
|
||||
rigid cap, and when squeezed into a one-pixel-tall layer the sampling can land on it instead
|
||||
of the stroke - no line.
|
||||
|
||||
Fix: compute the middle from the cap insets (`size - caps`) instead of assuming 1pt.
|
||||
|
||||
Upstream issue: https://github.com/react/react-native/issues/58054 (repro:
|
||||
https://github.com/abulenok/HairlineBorderRepro, fails identically on 0.86.0 and 0.87.0).
|
||||
|
||||
Generated
+326
-326
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,6 @@ import {createContext, useContext, useMemo} from 'react'
|
||||
import {
|
||||
type GestureResponderEvent,
|
||||
type StyleProp,
|
||||
StyleSheet,
|
||||
View,
|
||||
type ViewStyle,
|
||||
} from 'react-native'
|
||||
@@ -255,10 +254,10 @@ export function Divider({style}: ViewStyleProp) {
|
||||
return (
|
||||
<View
|
||||
style={[
|
||||
a.border_t,
|
||||
t.atoms.border_contrast_low,
|
||||
a.w_full,
|
||||
a.my_sm,
|
||||
{height: StyleSheet.hairlineWidth},
|
||||
t.atoms.bg_contrast_100,
|
||||
style,
|
||||
]}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user