Fabric text is drawn with ClearType onto transparent composition surfaces, fringing thin glyphs
维护者通常 2 天内回复
还没有人认领这个 Issue。
评估
调研方向
从 TextDrawing.cpp 开始,重点查看 RenderText 以及其中现有的 GetAntialiasMode/SetAntialiasMode/restore 惯用模式;检查 ParagraphComponentView.cpp、ScrollViewComponentView.cpp 和 TextInput/WindowsTextInputComponentView.cpp 中列出的 DrawTextLayout 位置。运行可用的 RNW 构建或检查,并在透明表面上的文本使用显式灰度抗锯齿且不改变周围设备上下文状态时,视为工作完成。
由索引模型根据 Issue 内容生成。
描述
Problem Description
On the new architecture, RenderText — the single function every <Text> render goes through —
calls ID2D1RenderTarget::DrawTextLayout without ever setting a text antialias mode, so the draw
inherits the device context's default. On a normal Windows machine that default is ClearType
subpixel antialiasing.
The surface it draws onto is transparent:
ParagraphComponentView::updateVisualBrushcreates it as
CreateDrawingSurfaceBrush(surfaceSize, DirectXPixelFormat::B8G8R8A8UIntNormalized, DirectXAlphaMode::Premultiplied)
(vnext/Microsoft.ReactNative/Fabric/Composition/ParagraphComponentView.cpp, ~L367-370).ParagraphComponentView::DrawTextclears it toD2D1::ColorF(D2D1::ColorF::Black, 0.0f)—
transparent black — whenever the view has nobackgroundColor(same file, ~L521-523).- The surface is composited by the visual tree afterwards, possibly under an opacity or a transform.
ClearType computes independent R/G/B coverage and needs an opaque, known background to filter
against. There is none here, so that per-channel coverage lands in the surface's colour channels and
shows up as dark or colour-tinted fringes along thin glyph stems once the surface is composited.
D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE is the documented mode for transparent render targets.
The gap is repo-wide, not local: at c69cf55f67f9b03f467502dac1007ac2d9ebe209, neither
SetTextAntialiasMode nor D2D1_TEXT_ANTIALIAS_MODE appears anywhere in the tree. The other two
DrawTextLayout call sites have the same omission —
ScrollViewComponentView.cpp ~L529 (scrollbar arrow glyphs) and
TextInput/WindowsTextInputComponentView.cpp ~L1870 (placeholder text).
Confidence, stated honestly. The missing call is a fact — the source is quoted above and the
repo-wide search returned zero hits. The visual claim is a source-level diagnosis that I have not
captured as before/after pixels: I have not built or run RNW main, and I cannot rule out that D2D
already coerces toward grayscale on some premultiplied targets, in which case the practical effect
of setting it explicitly is determinism (no dependence on the user's font-smoothing setting) rather
than a pixel change. I did not want to file a "verified" claim I had not measured.
Steps To Reproduce
- New-arch RNW app, default
<Text>(nobackgroundColor), light background behind it. - Use thin glyph strokes — a light font weight, a small icon font, or hairline separators — at a
fractional/high display scale (we see it clearly at 250%). - Zoom a screenshot to the pixel level along vertical stems.
- Observe coloured/dark fringing rather than clean grayscale edges.
Control: set D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE on the device context immediately before the
DrawTextLayout in RenderText and repeat.
Expected Results
Text on the new architecture is antialiased in grayscale, matching what other frameworks do for text
on transparent composition surfaces, and does not depend on the machine's ClearType setting.
Fix
PR attached: save / set D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE / restore around the DrawTextLayout
call in RenderText, matching the GetAntialiasMode/SetAntialiasMode/restore and
GetDpi/SetDpi/restore idioms already present in that same function. One file, twelve added
lines, no signature or header changes. Not compiled and not run — lint/format/build gates are unrun.
CLI version
18.0.0
Environment
System:
OS: Windows 11 10.0.26200 (ARM64 device; app builds and runs ARM64)
CPU: (6) x64 Apple Silicon (Windows-on-ARM)
Memory: 6.49 GB / 15.99 GB
Binaries:
Node: 22.15.0
Yarn: 4.5.1
npm: 10.9.2
SDKs:
Windows SDK versions: 10.0.19041.0, 10.0.22621.0, 10.0.26100.0
IDEs:
Visual Studio: 18.6.11822.322 (Community 2026), 17.14.37314.3 (Community 2022)
npmPackages (yarn 4 workspaces — `cli info` reports Not Found in-workspace):
react-native: 0.83.2
react-native-windows: 0.83.2 (New Architecture / Fabric composition)
Microsoft.WindowsAppSDK: 1.8
Source analysis above is against main at c69cf55f67f9b03f467502dac1007ac2d9ebe209, not 0.83.2 —
the code in question is unchanged between them as far as this function is concerned.
Community Modules
None involved. Core <Text> on the Composition/Fabric path.
Target React Native Architecture
New Architecture (WinAppSDK) Only
Target Platform Version
10.0.22621
Visual Studio Version
Visual Studio 2026
Build Configuration
Debug
Snack, code example, screenshot, or link to a repository
The decisive artifact is the source itself — TextDrawing.cpp L171-172 has no antialias-mode call
and D2D1_TEXT_ANTIALIAS_MODE occurs nowhere in the repo. Happy to produce zoomed before/after
captures from our app once we have the patched build, and to test any alternative the team prefers
(e.g. conditional grayscale only when the paragraph has no opaque background).
Context: found during a Windows hardening pass of a production RNW app (Facilitron FIT — RNW 0.83.2
new-arch, Windows 11 ARM64, WinAppSDK 1.8, 250% display scale). Related font-path issues from the
same investigation: #16306, #16308. Sibling PRs: #16302, #16303, #16304.
- 主要语言
- C++
- 星标
- 17.4k
- 派生
- 1.2k
- 平均合并
- 2 天 23 小时
- 30 天内合并 PR
- 16
环境准备
- 没有 Dockerfile 或 Docker Compose 文件
- 有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
microsoft/react-native-windows 的其他 Issue
-
bug Needs: Triage :mag:
难度 2/5 1-3 小时 新手友好度 68/100
microsoft/react-native-windows#16321 · 1 条评论 ·
维护者通常 2 天内回复
-
bug Needs: Triage :mag:
难度 3/5 1-2 天 新手友好度 48/100
microsoft/react-native-windows#16479 ·
维护者通常 2 天内回复
-
Needs: Triage :mag:
难度 5/5 一周以上 新手友好度 30/100
microsoft/react-native-windows#16442 · 2 条评论 ·
维护者通常 2 天内回复
-
Fabric: activating the window doesn't announce the window or the focused control to a screen reader未关闭Needs: Triage :mag:
难度 4/5 3-5 天 新手友好度 48/100
microsoft/react-native-windows#16435 ·
维护者通常 2 天内回复
-
bug Needs: Triage :mag:
难度 4/5 3-5 天 新手友好度 48/100
microsoft/react-native-windows#16410 ·
维护者通常 2 天内回复
查看 microsoft/react-native-windows 的全部 Issue
相似的 Issue
-
[Docs] CONTRIBUTING still says FreeType 2.14.3 and TabLabel.h says ImGui 1.92.9b after the bumps可能已有人在做 @mgradwohl 今天认领。 未关闭agent:WSL documentation LOW
难度 1/5 1-3 小时 新手友好度 83/100
维护者通常 1 天内回复
-
cudf-polars feature request
难度 2/5 1-3 小时 新手友好度 77/100
维护者通常 2 天内回复
-
(S1 - Need confirmation)
难度 2/5 1-3 小时 新手友好度 68/100
CleverRaven/Cataclysm-DDA#89212 ·
维护者通常 1 天内回复
-
Status: Needs confirmation Status: Needs triage
难度 2/5 1-3 小时 新手友好度 70/100
维护者通常 1 天内回复
-
a byte order mark at the start of a migration makes dbmate miss the up block可能已有人在做 @Dem1241 今天认领。 未关闭
难度 2/5 1-3 小时 新手友好度 70/100
维护者通常 2 天内回复