diff --git a/crates/engine/src/cmd/shape.rs b/crates/engine/src/cmd/shape.rs index 08ed9be64..a447a20b9 100644 --- a/crates/engine/src/cmd/shape.rs +++ b/crates/engine/src/cmd/shape.rs @@ -103,7 +103,7 @@ pub fn specs() -> Vec { "Shape Fill", ["Shape Format", "Shape Styles"], None, - "{color? | none?: true | background?: true (the slide background shows through; shapes and text boxes only) | gradient?: {stops: [[pos 0..1, color]], kind?: linear|radial|rectangular|path, angle?: deg (linear), focus?: [l, t, r, b] fractions (radial, rectangular and path: where the first stop sits), rotateWithShape?: bool} | picture?: base64 | pattern?: {preset, fg, bg} | transparency?: 0..1 | reset?: true, ids?}; pictureProps?: {tile?: bool, offsetX?, offsetY?: pt, scaleX?, scaleY?: 0..10, align?: tl|t|tr|l|ctr|r|bl|b|br, mirror?: none|x|y|xy, stretch?: [l, t, r, b] fractions, rotateWithShape?: bool} adjusts a picture fill; a group also formats its members", + "{color? | none?: true | background?: true (the slide background shows through; shapes and text boxes only) | gradient?: {stops: [[pos 0..1, color]], kind?: linear|radial|rectangular|path, angle?: deg (linear), focus?: [l, t, r, b] fractions (radial, rectangular and path: where the first stop sits), rotateWithShape?: bool (false keeps linear and radial gradients upright on the slide; rectangular and path gradients turn with the shape when drawn)} | picture?: base64 | pattern?: {preset, fg, bg} | transparency?: 0..1 | reset?: true, ids?}; pictureProps?: {tile?: bool, offsetX?, offsetY?: pt, scaleX?, scaleY?: 0..10, align?: tl|t|tr|l|ctr|r|bl|b|br, mirror?: none|x|y|xy, stretch?: [l, t, r, b] fractions, rotateWithShape?: bool} adjusts a picture fill; a group also formats its members", has_selection, fill ), diff --git a/crates/engine/src/cmd/shape/appearance.rs b/crates/engine/src/cmd/shape/appearance.rs index 4189deaa1..c515d2b2c 100644 --- a/crates/engine/src/cmd/shape/appearance.rs +++ b/crates/engine/src/cmd/shape/appearance.rs @@ -74,7 +74,8 @@ pub(super) fn change(s: &mut Session, p: &Value) -> Result { /// `{stops: [[pos 0–1, color], …], kind?: linear|radial|rectangular|path, angle?: deg (linear), /// focus?: [l, t, r, b] fractions (radial/rectangular/path: where the first stop sits), -/// rotateWithShape?}`. +/// rotateWithShape?}`. The renderer keeps only linear and radial gradients upright when +/// `rotateWithShape` is false; rectangular and path gradients turn with the shape. pub(crate) fn gradient_param(v: &Value) -> Option { let stops: Vec = v .get("stops")? diff --git a/crates/engine/src/tests.rs b/crates/engine/src/tests.rs index e37f9d135..12fac5efc 100644 --- a/crates/engine/src/tests.rs +++ b/crates/engine/src/tests.rs @@ -4321,6 +4321,9 @@ fn shape_fill_documents_each_gradient_key_and_kind() { let params = cmd::parse_params(find_command("shape.fill").unwrap().params).unwrap(); let about = params.iter().find(|p| p.name == "gradient").unwrap().about; assert_eq!(cmd::param_keys(about).unwrap(), ["stops", "kind", "angle", "focus", "rotateWithShape"]); + // The renderer keeps only linear and radial gradients upright (`paint::fill_path`). + let rotate = cmd::parse_params(about).unwrap().into_iter().find(|p| p.name == "rotateWithShape").unwrap().about; + assert!(rotate.contains("rectangular and path gradients turn with the shape"), "{rotate}"); for kind in ["linear", "radial", "rectangular", "path"] { assert!(about.contains(kind), "{kind}: {about}"); let g = cmd::shape::gradient_param(&json!({