mirror of
https://github.com/storytold/deckcraft.git
synced 2026-10-24 10:37:03 -06:00
Conflicts: ROADMAP.md (union of rows)
This commit is contained in:
@@ -161,6 +161,7 @@ app's JSON control channel (`deckcraft --control PORT`).
|
||||
| 2026-10-16 | Symbol-font characters: a run's U+F0xx symbol code (from `<a:sym typeface="Symbol"/>`) now draws from the installed Symbol face even when it has no private-use mapping — Apple's Symbol on macOS maps the glyphs to real Unicode, so the code is remapped to that character (the Adobe Symbol encoding) instead of falling to a look-alike. Bullets and metafile text take the same remap |
|
||||
| 2026-10-15 | Native saves keep an imported chart's embedded workbook, drawings and relationships; headless PPTX → edit → native save/reopen → PPTX tests verify the payloads and stale-workbook rejection |
|
||||
| 2026-10-18 | Charts: a series' own data-label setting is honoured — numbers PowerPoint shows on a graph no longer disappear, and a bare `c:showVal` means on (#868) |
|
||||
| 2026-10-15 | Render: quick styles render on empty placeholders — the fill gate now checks for style and line overrides too (#832) |
|
||||
| 2026-10-15 | PPTX trigger sequences keep separate On Click steps, including paragraph builds; synthetic import/edit/save/reopen and headless show regressions |
|
||||
| 2026-10-16 | Export: PNG with a transparent background — the slide background is left out, only the slide's content is drawn (Export… dialog, File › Export, web download, `file.export`/`file.render` `transparentBackground`, `deckcraft-cli render --transparent`) (#784) |
|
||||
| 2026-10-16 | Arrange ▸ Align: Align to Slide and Align Selected Objects, as in PowerPoint. One object aligns to the slide and several to each other until the other choice is ticked; the choice holds for that selection and also drives Distribute |
|
||||
|
||||
@@ -1152,7 +1152,7 @@ impl Renderer {
|
||||
}
|
||||
_ => {
|
||||
if let Some(fl) = &fill
|
||||
&& !(empty_ph && f.opts.edit && s.fill.is_none())
|
||||
&& !(empty_ph && f.opts.edit && s.fill.is_none() && s.line.is_none() && s.style.is_none())
|
||||
{
|
||||
for (i, sp) in geo.paths.iter().enumerate() {
|
||||
if sp.fill == FillMode::None || fade(i).fill <= 0.0 {
|
||||
|
||||
@@ -2,7 +2,7 @@ use super::*;
|
||||
use deckcraft_model::chart::{ChartType, Trendline, TrendlineType};
|
||||
use deckcraft_model::style::ColorRef;
|
||||
use deckcraft_model::text::TextBody;
|
||||
use deckcraft_model::{Chart, Geom, Presentation, Shape, ShapeId, ShapeKind, ShapeStyle, Table, Xfrm};
|
||||
use deckcraft_model::{Chart, Geom, PhType, Placeholder, Presentation, Shape, ShapeId, ShapeKind, ShapeStyle, Table, Xfrm};
|
||||
|
||||
fn deck_with(shapes: Vec<Shape>) -> Presentation {
|
||||
let mut p = Presentation::default();
|
||||
@@ -35,6 +35,33 @@ fn shape_fill_uses_theme_accent() {
|
||||
assert_eq!(img.pixel(50, 50), [255, 255, 255, 255]);
|
||||
}
|
||||
|
||||
/// #832: a quick style on an empty placeholder paints its fill. The style reference
|
||||
/// (`s.style`) carries the fill, but the empty-placeholder gate skipped the fill whenever the
|
||||
/// shape had no local fill, so the quick style only appeared once text was added. A
|
||||
/// placeholder with no style at all still shows nothing but its dashed outline.
|
||||
#[test]
|
||||
fn a_quick_style_fills_an_empty_placeholder() {
|
||||
let placeholder = || Shape {
|
||||
id: ShapeId(910),
|
||||
xfrm: Some(Xfrm::new(100.0, 100.0, 200.0, 100.0)),
|
||||
ph: Some(Placeholder { kind: PhType::Body, idx: 1, ..Default::default() }),
|
||||
..Default::default()
|
||||
};
|
||||
let p = deck_with(vec![Shape { style: Some(ShapeStyle::accent(deckcraft_color::SchemeSlot::Accent1)), ..placeholder() }]);
|
||||
let img = render_slide(&p, 0, &RenderOpts { scale: 1.0, edit: true, ..Default::default() });
|
||||
let accent = p.masters[0].theme.colors.get(deckcraft_color::SchemeSlot::Accent1);
|
||||
// Lower right of the shape: the prompt text sits at the top of the text rect.
|
||||
let px = img.pixel(280, 185);
|
||||
assert!(
|
||||
(px[0] as i32 - accent.r as i32).abs() <= 2 && (px[1] as i32 - accent.g as i32).abs() <= 2 && (px[2] as i32 - accent.b as i32).abs() <= 2,
|
||||
"the quick style's fill is drawn on the empty placeholder: {px:?} vs {accent:?}"
|
||||
);
|
||||
// An unformatted empty placeholder stays empty: the gate is not simply gone.
|
||||
let p = deck_with(vec![placeholder()]);
|
||||
let img = render_slide(&p, 0, &RenderOpts { scale: 1.0, edit: true, ..Default::default() });
|
||||
assert_eq!(img.pixel(280, 185), [255, 255, 255, 255], "an unformatted placeholder has no fill");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn render_shapes_draws_the_selection_on_a_transparent_canvas() {
|
||||
let sh = Shape {
|
||||
|
||||
Reference in New Issue
Block a user