mirror of
https://github.com/storytold/deckcraft.git
synced 2026-10-24 10:37:03 -06:00
Chart text without a colour of its own takes the theme's text colour
A chart's title, axis labels, legend and data labels were drawn in a fixed grey (0x595959) whenever `text_color` was unset, which is near-invisible on a dark theme. The renderer now resolves the theme's tx1 instead, so a chart is readable by default on Nocturne as well as on Harbor; an explicit colour still wins. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
1b03ae95de
commit
be9bf48eb2
@@ -207,7 +207,9 @@ pub fn draw(ctx: &mut RenderContext, rctx: &Ctx, c: &Chart, m: Affine, w: f64, h
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn draw_inner(ctx: &mut RenderContext, rctx: &Ctx, c: &Chart, m: Affine, w: f64, h: f64, boxes: Option<&crate::chartex::Boxes>) {
|
||||
let text_col = c.text_color.as_ref().map(|t| rctx.color(t, None)).unwrap_or(Rgba::rgb(0x59, 0x59, 0x59));
|
||||
// Text without a colour of its own takes the theme's text colour, so a chart on a dark
|
||||
// theme is readable (a fixed grey used to vanish there).
|
||||
let text_col = rctx.color(c.text_color.as_ref().unwrap_or(&ColorRef::scheme(SchemeSlot::Tx1)), None);
|
||||
let grid_col = Rgba::rgb(0xD9, 0xD9, 0xD9);
|
||||
if let Some(f) = &c.chart_fill {
|
||||
crate::paint::fill_path(
|
||||
|
||||
@@ -2717,3 +2717,33 @@ fn empty_bullet_is_gray_only_while_editing_and_never_in_exports() {
|
||||
assert!(changed.iter().any(|(px, _)| px[0] == 179 && px[1] == 179 && px[2] == 179));
|
||||
assert!(changed.iter().all(|(px, _)| px[0] >= 179 && px[0] == px[1] && px[1] == px[2]));
|
||||
}
|
||||
|
||||
/// A chart that has no text colour of its own takes the theme's: light on Nocturne's dark slides
|
||||
/// (it used to be a fixed grey, near-invisible there), dark on Harbor's light ones.
|
||||
#[test]
|
||||
fn chart_text_follows_the_theme_when_it_has_no_colour_of_its_own() {
|
||||
let draw = |theme: &str, title: Option<&str>| {
|
||||
let mut c = Chart::sample(ChartType::Column);
|
||||
c.title = title.map(String::from);
|
||||
c.legend = None;
|
||||
c.data_labels = false;
|
||||
let sh = Shape { id: ShapeId(630), xfrm: Some(Xfrm::new(0.0, 0.0, 960.0, 540.0)), kind: ShapeKind::Chart(Box::new(c)), ..Default::default() };
|
||||
let mut p = deck_with(vec![sh]);
|
||||
let t = deckcraft_model::theme::builtin_themes().into_iter().find(|t| t.name == theme).expect("theme");
|
||||
std::sync::Arc::make_mut(&mut p.masters[0]).theme = t;
|
||||
render_slide(&p, 0, &RenderOpts { scale: 1.0, ..Default::default() })
|
||||
};
|
||||
let lum = |px: [u8; 4]| (px[0] as u32 * 299 + px[1] as u32 * 587 + px[2] as u32 * 114) / 1000;
|
||||
// Pixels in the title band that pass `f`.
|
||||
let count = |img: &Image, f: &dyn Fn(u32) -> bool| {
|
||||
(200..760u32).flat_map(|x| (4..70u32).map(move |y| (x, y))).filter(|(x, y)| f(lum(img.pixel(*x, *y)))).count()
|
||||
};
|
||||
let (dark_bare, dark_titled) = (draw("Nocturne", None), draw("Nocturne", Some("Quarterly revenue")));
|
||||
assert!(lum(dark_bare.pixel(5, 5)) < 60, "Nocturne's slide is dark: {:?}", dark_bare.pixel(5, 5));
|
||||
let light_ink = count(&dark_titled, &|l| l > 200) as i64 - count(&dark_bare, &|l| l > 200) as i64;
|
||||
assert!(light_ink > 100, "the title is light on a dark theme (light pixels added: {light_ink})");
|
||||
let (light_bare, light_titled) = (draw("Harbor", None), draw("Harbor", Some("Quarterly revenue")));
|
||||
assert!(lum(light_bare.pixel(5, 5)) > 200, "Harbor's slide is light: {:?}", light_bare.pixel(5, 5));
|
||||
let dark_ink = count(&light_titled, &|l| l < 80) as i64 - count(&light_bare, &|l| l < 80) as i64;
|
||||
assert!(dark_ink > 100, "the title is dark on a light theme (dark pixels added: {dark_ink})");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user