fix(compositor): centrer les blocs de texte, ajuster leur plaque, et les sortir du zoom - #214
Merged
EtienneLescot merged 3 commits intoJul 30, 2026
Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
…eur plaque épouse le texte Rapport utilisateur : « il y a une énorme marge en bas » sur les blocs de sous-titres, en rendu Metal. Mesuré sur une vraie bande (1536x238 en 1080p), avant correctif : 11 px d'encre au-dessus du texte, **180 px en dessous**, et la plaque de fond couvrant la boîte ENTIÈRE. Deux causes, toutes deux dans `text_macos.rs` : * `CTFrameDraw` remplit son cadre du haut vers le bas, et le cadre couvrait toute la boîte — les lignes se collaient donc en haut. Direct2D n'avait pas le problème, il pose `DWRITE_PARAGRAPH_ALIGNMENT_CENTER`. macOS était le seul à ne pas centrer. * le fond était un `CGContextFillRect` sur la boîte entière, là où Direct2D le dessine sur `DWRITE_TEXT_METRICS`, donc ajusté au texte. Les deux se cumulent sur les sous-titres parce qu'une bande fait 22 % de la hauteur d'image (`CAPTION_BAND_HEIGHT_PCT`, volontairement généreuse pour absorber deux lignes) : la boîte est toujours bien plus haute que son texte. Les annotations texte passent par le même rastériseur, d'où le même symptôme. macOS mesure désormais le bloc (`CTFramesetterSuggestFrameSizeWithConstraints`) puis `block_layout` en déduit le cadre — centré verticalement — et la plaque qui l'habille. Un texte qui déborde de sa boîte part toujours du haut et se coupe en bas, plutôt que d'être rogné des deux côtés. Windows reçoit la même plaque : marge et coins arrondis, au lieu des métriques nues. Les trois nombres qui décident de l'allure du bloc (0.2em / 0.1em / 4px à 48px de police, le modèle de boîte du `<span>` de l'overlay DOM et de `lib/exporter/annotationRenderer.ts`) vivent dans un `text_plate.rs` partagé : recopiés, ils dériveraient en silence, puisque rien dans un rendu Windows ne signale qu'une marge macOS a bougé. Après, sur la même bande : 84 px / 84 px verticalement, 502 px / 502 px horizontalement. Vérification. macOS : `cargo test -p openscreen-compositor --lib --tests` vert (106 unitaires + 5 d'intégration, goldens de géométrie compris), dont cinq tests qui rastérisent pour de vrai sur le device Metal — non-miroir, centrage, plaque ajustée, marge autour des glyphes, débordement. Le test qui affirmait « le texte se dessine EN HAUT de sa boîte » est réécrit : il comparait les deux moitiés de la TEXTURE, ce qui ne veut plus rien dire une fois le bloc centré ; il compare maintenant les deux moitiés de la boîte englobante de l'encre, ce qui détecte le miroir sans dépendre du centrage. Windows : pas de machine sous la main, mais `text_windows.rs` type-checke pour `x86_64-pc-windows-msvc` sans warning, et les signatures `FillRoundedRectangle` / `D2D1_ROUNDED_RECT` ont été relues dans les bindings `windows-0.58`. Le rendu Windows lui-même n'est pas vérifié à l'œil.
Rapport utilisateur : « les sous-titres étaient zoomés avec le screen recording ». Ce n'est pas un bug de sous-titres — les captions sont projetées en annotations texte par `captionCuesToTextRegions` — mais une régression qui touche TOUTES les annotations, sur les deux backends. Le contrat de `SceneAnnotation` est explicite : « deliberately NOT affected by the zoom crop — the overlay is a sibling of the element carrying the zoom transform, so annotations hold still while the content zooms underneath them ». Tant que le zoom se jouait dans la coupe source, `s_dst` tenait ce rôle gratuitement : la boîte écran restait le rect paddé. L'issue #179 a rendu le zoom à la BOÎTE (pour qu'il atteigne les bords du cadre au lieu de buter sur le padding), donc `s_dst` grandit et se déplace avec lui — et les deux compositeurs continuaient d'y ancrer les annotations. `plan_frame` expose donc `s_ann` : la boîte écran AVANT le `remap_box` du zoom, c'est-à-dire le rect que l'app a résolu (`layout.screenRect`) et que l'overlay web reçoit comme conteneur. `draw_annotations` s'y ancre des deux côtés. Effet de bord utile : la poignée de sélection DOM était déjà posée sur ce `screenRect` non zoomé, donc les pixels natifs et le cadre de sélection se recollent — ils divergeaient dès qu'un zoom était actif. `the_annotation_anchor_ignores_the_zoom` épingle l'invariant sur la scène golden, avec et sans région de zoom. Il vérifie d'abord que le zoom agit bel et bien sur `s_dst` — sans cette assertion, le test passerait aussi si `remap_box` cessait de faire son travail, et ne prouverait rien. Il tourne dans le job macOS ET dans le job Windows, comme le golden `plan_frame`, qui reste inchangé au bit près : ajouter un champ ne déplace aucune des 21 valeurs épinglées. `cargo test -p openscreen-compositor --lib --tests` vert (106 + 5).
EtienneLescot
force-pushed
the
claude/text-block-padding-centering-865284
branch
from
July 30, 2026 16:05
8fface0 to
a336449
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Trois défauts de rendu sur les blocs de texte — sous-titres et annotations, qui partagent le même chemin (
captionCuesToTextRegionsprojette les captions en annotations texte). Les deux premiers étaient macOS seulement, le troisième touche les deux backends.1. Le bloc se collait en haut de sa boîte (macOS)
Rapport : « il y a une énorme marge en bas ». Mesuré sur une vraie bande de sous-titres (1536×238 en 1080p), avant correctif : 11 px d'encre au-dessus du texte, 180 px en dessous.
CTFrameDrawremplit son cadre du haut vers le bas, et le cadre couvrait toute la boîte. Direct2D n'avait pas le problème — il poseDWRITE_PARAGRAPH_ALIGNMENT_CENTER— macOS était le seul à ne pas centrer. Ça se voit surtout sur les sous-titres parce qu'une bande fait 22 % de la hauteur d'image (CAPTION_BAND_HEIGHT_PCT, volontairement généreuse pour absorber deux lignes) : la boîte est toujours bien plus haute que son texte.macOS mesure maintenant le bloc (
CTFramesetterSuggestFrameSizeWithConstraints) etblock_layouten déduit un cadre centré. Après : 84 px / 84 px.2. La plaque de fond couvrait la boîte entière (macOS)
Un
CGContextFillRectsur toute la boîte, là où Direct2D la dessine surDWRITE_TEXT_METRICS, donc ajustée au texte. Une bande de sous-titres était un pavé opaque de 22 % de la hauteur d'image.La plaque épouse désormais le bloc, avec la marge et les coins arrondis du modèle de boîte de référence de l'app — le
<span>que l'overlay DOM posait derrière le texte et son jumeau canvas (lib/exporter/annotationRenderer.ts) :padding: 0.1em 0.2em,border-radius: 4px. Windows reçoit la même plaque, au lieu des métriques nues.Les trois nombres vivent dans un
text_plate.rspartagé plutôt que recopiés de chaque côté : rien dans un rendu Windows ne signalerait qu'une marge macOS a bougé.3. Les annotations suivaient le zoom (les deux backends)
Rapport : « les sous-titres étaient zoomés avec le screen recording ». Le contrat de
SceneAnnotationest explicite :Tant que le zoom se jouait dans la coupe source,
s_dsttenait ce rôle gratuitement. L'issue #179 a rendu le zoom à la boîte — pour qu'il atteigne les bords du cadre au lieu de buter sur le padding — doncs_dstgrandit et se déplace avec lui, et les deux compositeurs continuaient d'y ancrer les annotations.plan_frameexposes_ann, la boîte écran avant leremap_boxdu zoom, c'est-à-dire le rect que l'app a résolu (layout.screenRect) et que l'overlay web reçoit comme conteneur. Effet de bord utile : la poignée de sélection DOM était déjà posée sur ce rect non zoomé, donc les pixels natifs et le cadre de sélection se recollent — ils divergeaient dès qu'un zoom était actif.Vérification
macOS —
cargo test -p openscreen-compositor --lib --testsvert : 106 unitaires + 5 d'intégration, goldens de géométrie compris. Le goldenplan_framereste inchangé au bit près (ajouter un champ ne déplace aucune des 21 valeurs épinglées). Tests ajoutés :the_annotation_anchor_ignores_the_zoom, qui vérifie d'abord que le zoom agit bel et bien surs_dst: sans cette assertion il passerait aussi siremap_boxcessait de faire son travail, et ne prouverait rien ;Le test qui affirmait « le texte se dessine EN HAUT de sa boîte » est réécrit : il comparait les deux moitiés de la texture, ce qui ne veut plus rien dire une fois le bloc centré. Il compare maintenant les deux moitiés de la boîte englobante de l'encre, ce qui détecte le miroir sans dépendre du centrage.
L'app a été lancée avec un
compositor_view.noderebuildé sur cette branche, pour valider le rendu en conditions réelles.Windows — pas de machine sous la main.
text_windows.rstype-checke pourx86_64-pc-windows-msvcsans warning, et les signaturesFillRoundedRectangle/D2D1_ROUNDED_RECTont été relues dans les bindingswindows-0.58vendorisés. Le rendu Windows lui-même n'est pas vérifié à l'œil — c'est le point à regarder en review.