mirror of
https://github.com/storytold/deckcraft.git
synced 2026-10-13 23:08:23 +00:00
Text: transparent text fills are faded once, not twice
A run's solid fill with a:alpha was resolved into the glyph colour's alpha and also kept as the run's fill opacity, and the renderer multiplied both: text at 60 % transparency drew at 16 % opacity instead of 40 %. The colour now carries the transparency alone. PowerPoint's export of "Transparent 60% text" (red) is a light red that now matches. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
9e2f7b96dc
commit
ef313b91b0
2 files changed
+17
-2
No files matched your search
@@ -54,7 +54,7 @@ pub struct GlyphRun {
|
||||
pub para: usize,
|
||||
pub chars: (usize, usize),
|
||||
pub link: bool,
|
||||
/// Alpha of the fill (0–1).
|
||||
/// Opacity of the fill on top of `color`'s own alpha (0 for no fill).
|
||||
pub alpha: f64,
|
||||
pub gradient: Option<deckcraft_model::style::Gradient>,
|
||||
/// Shadow and glow behind the glyphs (`a:rPr/a:effectLst`).
|
||||
@@ -269,7 +269,8 @@ fn make_style(ctx: &Ctx, r: &RunProps, scale: f64, prompt: Option<Rgba>) -> Styl
|
||||
let fake_italic = italic && !face.italic;
|
||||
let size = (r.size.unwrap_or(18.0) * scale).clamp(0.5, 4000.0);
|
||||
let (mut color, alpha, gradient) = match &r.fill {
|
||||
Some(Fill::Solid { color }) => (ctx.color(color, None), color.alpha(), None),
|
||||
// The resolved colour carries the fill's transparency (`a:alpha`): it is applied once.
|
||||
Some(Fill::Solid { color }) => (ctx.color(color, None), 1.0, None),
|
||||
Some(Fill::Gradient(g)) => {
|
||||
// Colours resolved here (theme, colour map), so the renderer needs no colour scheme.
|
||||
let mut g = g.clone();
|
||||
|
||||
@@ -871,3 +871,17 @@ fn capitals_keep_characters_whose_capital_is_a_sequence() {
|
||||
assert_eq!(r.glyphs[1].0, face.glyph_for('ß'), "ß is not drawn as S");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn transparent_text_is_faded_once() {
|
||||
let (p, mut sh) = setup("Faded", 2000.0, 300.0);
|
||||
let run = &mut sh.text.as_mut().unwrap().paragraphs[0].runs[0];
|
||||
run.props.fill = Some(deckcraft_model::Fill::solid(
|
||||
deckcraft_model::ColorRef::rgb(deckcraft_color::Rgba::rgb(255, 0, 0)).with(deckcraft_color::ColorTransform::Alpha(40000)),
|
||||
));
|
||||
let l = lay(&p, &sh, 2000.0, 300.0);
|
||||
let r = l.runs.iter().find(|r| !r.cells.is_empty()).unwrap();
|
||||
// 60 % transparency: 40 % opaque in all, not 40 % of 40 %.
|
||||
let opacity = r.color.a as f64 / 255.0 * r.alpha;
|
||||
assert!((opacity - 0.4).abs() < 0.01, "{opacity}");
|
||||
}
|
||||
Reference in new issue
Block a user