From 85de6ca5d76356ebaf3367ad319bd2fdbb0c0155 Mon Sep 17 00:00:00 2001 From: ".CooCoo" Date: Wed, 4 Nov 2026 15:11:29 -0800 Subject: [PATCH] Shape Fill: the gradient help says which kinds rotateWithShape keeps upright (#1843) With rotateWithShape false, the renderer lays linear and radial gradients out upright on the slide, while rectangular and path gradients still turn with the shape. The shape.fill params doc now says so. --- crates/engine/src/cmd/shape.rs | 2 +- crates/engine/src/cmd/shape/appearance.rs | 3 ++- crates/engine/src/tests.rs | 3 +++ 3 files changed, 6 insertions(+), 2 deletions(-) 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!({