Symptôme
Une annotation dont la portée tombe entièrement sous un trim ne s'affiche jamais dans la preview — quel que soit son type (texte, figure, image, flou). Aucune erreur, aucun log : elle n'existe simplement pas dans la scène envoyée au compositeur.
Repro : poser une annotation, puis trimmer le passage qu'elle recouvre. Elle disparaît de la preview.
Mécanisme
projectRegionsToSource (src/lib/ai-edition/timeline/timelineMap.ts:452) projette chaque région en n'intersectant que les segments visibles (trims retirés). Une région qui n'en recoupe aucun n'émet rien, et le seul repli existant ne couvre que le cas dégénéré « aucun segment du tout » :
if (emitted === 0 && visibleSegments.length === 0) out.push(region);
À l'export c'est correct : le passage n'est jamais joué, donc aucune image ne peut porter l'annotation.
Pourquoi ce n'est pas une ligne à changer
1. Le repli naïf a déjà été essayé et a produit pire. Le commentaire juste au-dessus le documente : ré-émettre la région lui fait porter ses startMs/endMs RAW-virtuels sans clipIndex, et belongs() (scene.rs) accepte alors une région sans clipIndex sur n'importe quel clip dont la fenêtre source recoupe numériquement ces valeurs. Résultat : l'effet se déclenchait plus tard, sur un clip sans rapport. Toute correction doit éviter de rouvrir cette classe de bug.
2. Le contrat de scène n'a pas de place où ranger l'annotation. Les régions sont adressées par clipIndex, l'indice dans le tableau des segments visibles. Une portée entièrement coupée n'a, par construction, aucun segment visible à désigner. L'exprimer suppose d'étendre le contrat (émettre des segments coupés, marqués non-joués) et de suivre côté Rust — pas un correctif local.
3. Et surtout : l'image affichée n'est pas celle qu'on croit. resolveNativePosition (timelineMap.ts:566) documente que si la tête de lecture est au-dessus d'une zone coupée, elle saute au segment gardé suivant (clampToSegmentStart) et présente sa première image. On peut donc poser la tête sur le trim — la règle RAW en garde la place — mais ce qui s'affiche est déjà le contenu d'après.
Donc « faire réapparaître l'annotation » l'incrusterait sur une image qui n'est pas la sienne. C'est un arbitrage produit, pas une correction mécanique :
- (a) garder l'état actuel : rien ne s'affiche, ce qui est cohérent avec l'image réellement présentée ;
- (b) afficher quand même l'annotation, au motif que la tête est visuellement sous son bloc dans la règle — au prix d'une incrustation sur la mauvaise image ;
- (c) traiter la cause d'inconfort en amont : signaler dans la règle que cette portion est coupée, ou empêcher la tête d'y stationner, pour que la question ne se pose plus.
Ma préférence va à (c) : (a) est correct mais déroutant, et (b) affiche sciemment quelque chose de faux.
Contexte
Relevé pendant #214 : les annotations semblaient avoir disparu, on a d'abord soupçonné le changement d'ancrage s_ann de cette PR. Ce n'est pas la cause — sans zoom, s_ann est bit-pour-bit égal à s_dst. Le diagnostic (un trim sous l'annotation) revient à @EtienneLescot.
Symptôme
Une annotation dont la portée tombe entièrement sous un trim ne s'affiche jamais dans la preview — quel que soit son type (texte, figure, image, flou). Aucune erreur, aucun log : elle n'existe simplement pas dans la scène envoyée au compositeur.
Repro : poser une annotation, puis trimmer le passage qu'elle recouvre. Elle disparaît de la preview.
Mécanisme
projectRegionsToSource(src/lib/ai-edition/timeline/timelineMap.ts:452) projette chaque région en n'intersectant que les segments visibles (trims retirés). Une région qui n'en recoupe aucun n'émet rien, et le seul repli existant ne couvre que le cas dégénéré « aucun segment du tout » :À l'export c'est correct : le passage n'est jamais joué, donc aucune image ne peut porter l'annotation.
Pourquoi ce n'est pas une ligne à changer
1. Le repli naïf a déjà été essayé et a produit pire. Le commentaire juste au-dessus le documente : ré-émettre la région lui fait porter ses
startMs/endMsRAW-virtuels sansclipIndex, etbelongs()(scene.rs) accepte alors une région sans clipIndex sur n'importe quel clip dont la fenêtre source recoupe numériquement ces valeurs. Résultat : l'effet se déclenchait plus tard, sur un clip sans rapport. Toute correction doit éviter de rouvrir cette classe de bug.2. Le contrat de scène n'a pas de place où ranger l'annotation. Les régions sont adressées par
clipIndex, l'indice dans le tableau des segments visibles. Une portée entièrement coupée n'a, par construction, aucun segment visible à désigner. L'exprimer suppose d'étendre le contrat (émettre des segments coupés, marqués non-joués) et de suivre côté Rust — pas un correctif local.3. Et surtout : l'image affichée n'est pas celle qu'on croit.
resolveNativePosition(timelineMap.ts:566) documente que si la tête de lecture est au-dessus d'une zone coupée, elle saute au segment gardé suivant (clampToSegmentStart) et présente sa première image. On peut donc poser la tête sur le trim — la règle RAW en garde la place — mais ce qui s'affiche est déjà le contenu d'après.Donc « faire réapparaître l'annotation » l'incrusterait sur une image qui n'est pas la sienne. C'est un arbitrage produit, pas une correction mécanique :
Ma préférence va à (c) : (a) est correct mais déroutant, et (b) affiche sciemment quelque chose de faux.
Contexte
Relevé pendant #214 : les annotations semblaient avoir disparu, on a d'abord soupçonné le changement d'ancrage
s_annde cette PR. Ce n'est pas la cause — sans zoom,s_annest bit-pour-bit égal às_dst. Le diagnostic (un trim sous l'annotation) revient à @EtienneLescot.