Merge pull request #7428 from penpot/elenatorro-fix-shadows-order

🐛 Fix shadows order
This commit is contained in:
Aitor Moreno
2025-10-02 17:16:58 +02:00
committed by GitHub
4 changed files with 150 additions and 2 deletions

View File

@@ -0,0 +1,130 @@
{
"~:features": {
"~#set": [
"fdata/path-data",
"plugins/runtime",
"design-tokens/v1",
"variants/v1",
"layout/grid",
"styles/v2",
"fdata/objects-map",
"render-wasm/v1",
"components/v2",
"fdata/shape-data-type"
]
},
"~:team-id": "~u6bd7c17d-4f59-815e-8006-5c1f6882469a",
"~:permissions": {
"~:type": "~:membership",
"~:is-owner": true,
"~:is-admin": true,
"~:can-edit": true,
"~:can-read": true,
"~:is-logged": true
},
"~:has-media-trimmed": false,
"~:comment-thread-seqn": 0,
"~:name": "test_shadows_order",
"~:revn": 13,
"~:modified-at": "~m1759415785228",
"~:vern": 0,
"~:id": "~u48ffa82f-6950-81b5-8006-e49a2a39657f",
"~:is-shared": false,
"~:migrations": {
"~#ordered-set": [
"legacy-2",
"legacy-3",
"legacy-5",
"legacy-6",
"legacy-7",
"legacy-8",
"legacy-9",
"legacy-10",
"legacy-11",
"legacy-12",
"legacy-13",
"legacy-14",
"legacy-16",
"legacy-17",
"legacy-18",
"legacy-19",
"legacy-25",
"legacy-26",
"legacy-27",
"legacy-28",
"legacy-29",
"legacy-31",
"legacy-32",
"legacy-33",
"legacy-34",
"legacy-36",
"legacy-37",
"legacy-38",
"legacy-39",
"legacy-40",
"legacy-41",
"legacy-42",
"legacy-43",
"legacy-44",
"legacy-45",
"legacy-46",
"legacy-47",
"legacy-48",
"legacy-49",
"legacy-50",
"legacy-51",
"legacy-52",
"legacy-53",
"legacy-54",
"legacy-55",
"legacy-56",
"legacy-57",
"legacy-59",
"legacy-62",
"legacy-65",
"legacy-66",
"legacy-67",
"0001-remove-tokens-from-groups",
"0002-normalize-bool-content-v2",
"0002-clean-shape-interactions",
"0003-fix-root-shape",
"0003-convert-path-content-v2",
"0004-clean-shadow-color",
"0005-deprecate-image-type",
"0006-fix-old-texts-fills",
"0007-clear-invalid-strokes-and-fills-v2",
"0008-fix-library-colors-v4",
"0009-clean-library-colors",
"0009-add-partial-text-touched-flags",
"0010-fix-swap-slots-pointing-non-existent-shapes",
"0011-fix-invalid-text-touched-flags",
"0012-fix-position-data"
]
},
"~:version": 67,
"~:project-id": "~u6bd7c17d-4f59-815e-8006-5c1f68846e43",
"~:created-at": "~m1759415649509",
"~:data": {
"~:pages": [
"~u48ffa82f-6950-81b5-8006-e49a2a396580"
],
"~:pages-index": {
"~u48ffa82f-6950-81b5-8006-e49a2a396580": {
"~:objects": {
"~#penpot/objects-map/v2": {
"~u00000000-0000-0000-0000-000000000000": "[\"~#shape\",[\"^ \",\"~:y\",0,\"~:hide-fill-on-export\",false,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:name\",\"Root Frame\",\"~:width\",0.01,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",0.0,\"~:y\",0.0]],[\"^:\",[\"^ \",\"~:x\",0.01,\"~:y\",0.0]],[\"^:\",[\"^ \",\"~:x\",0.01,\"~:y\",0.01]],[\"^:\",[\"^ \",\"~:x\",0.0,\"~:y\",0.01]]],\"~:r2\",0,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:r3\",0,\"~:r1\",0,\"~:id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",0,\"~:proportion\",1.0,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",0,\"~:y\",0,\"^6\",0.01,\"~:height\",0.01,\"~:x1\",0,\"~:y1\",0,\"~:x2\",0.01,\"~:y2\",0.01]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#FFFFFF\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^H\",0.01,\"~:flip-y\",null,\"~:shapes\",[\"~uae1a2ead-2994-80a4-8006-e49a2b880688\",\"~uae1a2ead-2994-80a4-8006-e49a3c230916\"]]]",
"~uae1a2ead-2994-80a4-8006-e49a2b880688": "[\"~#shape\",[\"^ \",\"~:y\",483.4820356242563,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",0.9788217705787964,\"~:b\",0.20471429222452875,\"~:c\",-0.20471415002509374,\"~:d\",0.9788218003188844,\"~:e\",0.0,\"~:f\",-9.094947017729282E-13]],\"~:rotation\",11.812776963021975,\"~:last-resize-direction\",\"horizontal\",\"~:grow-type\",\"~:fixed\",\"~:content\",[\"^ \",\"~:type\",\"root\",\"~:key\",\"1e7hxl490w2\",\"~:children\",[[\"^ \",\"^8\",\"paragraph-set\",\"^:\",[[\"^ \",\"~:line-height\",\"1.2\",\"~:font-style\",\"normal\",\"^:\",[[\"^ \",\"^;\",\"\",\"^<\",\"normal\",\"~:text-transform\",\"uppercase\",\"~:font-id\",\"gfont-seymour-one\",\"^9\",\"1q0daub9a4o\",\"~:font-size\",\"72\",\"~:font-weight\",\"400\",\"~:font-variant-id\",\"regular\",\"~:text-decoration\",\"none\",\"~:letter-spacing\",\"-10\",\"~:fills\",[[\"^ \",\"~:fill-color\",\"#80ffdb\",\"~:fill-opacity\",1]],\"~:font-family\",\"Seymour One\",\"~:text\",\"hello world\"]],\"^=\",\"uppercase\",\"~:text-align\",\"center\",\"^>\",\"gfont-seymour-one\",\"^9\",\"1njiv0webbj\",\"^?\",\"0\",\"^@\",\"400\",\"~:text-direction\",\"ltr\",\"^8\",\"paragraph\",\"^A\",\"regular\",\"^B\",\"none\",\"^C\",\"-10\",\"^D\",[[\"^ \",\"^E\",\"#80ffdb\",\"^F\",1]],\"^G\",\"Seymour One\"]]]],\"~:vertical-align\",\"top\"],\"~:hide-in-viewer\",false,\"~:name\",\"Text\",\"~:width\",696.7786469812631,\"^8\",\"^H\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",642.8707961222883,\"~:y\",415.00002146255576]],[\"^P\",[\"^ \",\"~:x\",1324.8929050619865,\"~:y\",557.6405690164898]],[\"^P\",[\"^ \",\"~:x\",1270.0221499044503,\"~:y\",820.0000167712013]],[\"^P\",[\"^ \",\"~:x\",588.0000409647498,\"~:y\",677.359469217266]]],\"~:layout-item-h-sizing\",\"~:fix\",\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",0.9788218003188955,\"~:b\",-0.20471429222453108,\"~:c\",0.20471415002509608,\"~:d\",0.9788217705788075,\"~:e\",1.8618643482577324E-13,\"~:f\",8.902332143214221E-13]],\"~:page-id\",\"~uca00b4e9-7831-806e-8006-e483daa11f18\",\"~:layout-item-v-sizing\",\"^R\",\"~:id\",\"~uae1a2ead-2994-80a4-8006-e49a2b880688\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:position-data\",[[\"~#rect\",[\"^ \",\"~:y\",550.8231760071114,\"^<\",\"normal\",\"^=\",\"uppercase\",\"^?\",\"72px\",\"^@\",\"400\",\"~:y1\",-2.3000030517578125,\"^N\",339.1499938964844,\"^B\",\"none\",\"^C\",\"-10px\",\"~:x\",689.2688958782501,\"~:x1\",69.91667175292969,\"~:y2\",88.69999694824219,\"^D\",[[\"^ \",\"^E\",\"#80ffdb\",\"^F\",1]],\"~:x2\",409.06666564941406,\"~:direction\",\"ltr\",\"^G\",\"\\\"Seymour One\\\"\",\"~:height\",91,\"^H\",\"hello \"]],[\"^Y\",[\"^ \",\"~:y\",637.2231851623849,\"^<\",\"normal\",\"^=\",\"uppercase\",\"^?\",\"72px\",\"^@\",\"400\",\"^Z\",84.10000610351562,\"^N\",380.4666748046875,\"^B\",\"none\",\"^C\",\"-10px\",\"~:x\",668.6188867229766,\"^[\",49.26666259765625,\"^10\",175.10000610351562,\"^D\",[[\"^ \",\"^E\",\"#80ffdb\",\"^F\",1]],\"^11\",429.73333740234375,\"^12\",\"ltr\",\"^G\",\"\\\"Seymour One\\\"\",\"^13\",91,\"^H\",\"world\"]]],\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",608.0571495227366,\"~:shadow\",[[\"^ \",\"^V\",\"~u68cfab5e-652d-8097-8006-e488b9656709\",\"~:style\",\"~:drop-shadow\",\"~:color\",[\"^ \",\"~:opacity\",1,\"^19\",\"#64dfdf\"],\"~:offset-x\",4,\"~:offset-y\",4,\"~:blur\",0,\"~:spread\",0,\"~:hidden\",false],[\"^ \",\"^V\",\"~u68cfab5e-652d-8097-8006-e4890c135b3b\",\"^17\",\"^18\",\"^19\",[\"^ \",\"^1:\",1,\"^19\",\"#56cfe1\"],\"^1;\",6,\"^1<\",8,\"^1=\",0,\"^1>\",0,\"^1?\",false],[\"^ \",\"^V\",\"~u68cfab5e-652d-8097-8006-e4894e9ec462\",\"^17\",\"^18\",\"^19\",[\"^ \",\"^1:\",1,\"^19\",\"#5390d9\"],\"^1;\",4,\"^1<\",12,\"^1=\",0,\"^1>\",0,\"^1?\",false],[\"^ \",\"^V\",\"~u68cfab5e-652d-8097-8006-e4898979e7f9\",\"^17\",\"^18\",\"^19\",[\"^ \",\"^1:\",1,\"^19\",\"#5e60ce\"],\"^1;\",2,\"^1<\",16,\"^1=\",0,\"^1>\",0,\"^1?\",false],[\"^ \",\"^V\",\"~u68cfab5e-652d-8097-8006-e489ba59dbd0\",\"^17\",\"^18\",\"^19\",[\"^ \",\"^1:\",1,\"^19\",\"#6930c3\"],\"^1;\",0,\"^1<\",20,\"^1=\",0,\"^1>\",0,\"^1?\",false]],\"~:selrect\",[\"^Y\",[\"^ \",\"~:x\",608.0571495227366,\"~:y\",483.4820356242563,\"^N\",696.7786469812631,\"^13\",268.03596698524456,\"^[\",608.0571495227366,\"^Z\",483.4820356242563,\"^11\",1304.8357965039997,\"^10\",751.5180026095009]],\"^D\",[],\"~:flip-x\",null,\"^13\",268.03596698524456,\"~:flip-y\",null]]",
"~uae1a2ead-2994-80a4-8006-e49a3c230916": "[\"~#shape\",[\"^ \",\"~:y\",574.6013159890737,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",0.8985240774403216,\"~:b\",-0.4389242329377807,\"~:c\",0.4389243127700668,\"~:d\",0.8985240384426714,\"~:e\",-2.5011104298755527E-12,\"~:f\",1.1937117960769683E-12]],\"~:rotation\",333.964740304884,\"~:last-resize-direction\",\"horizontal\",\"~:grow-type\",\"~:auto-height\",\"~:content\",[\"^ \",\"~:type\",\"root\",\"~:key\",\"1e7hxl490w2\",\"~:children\",[[\"^ \",\"^8\",\"paragraph-set\",\"^:\",[[\"^ \",\"~:line-height\",\"1.2\",\"~:font-style\",\"normal\",\"^:\",[[\"^ \",\"^;\",\"\",\"^<\",\"normal\",\"~:text-transform\",\"uppercase\",\"~:font-id\",\"gfont-seymour-one\",\"^9\",\"1q0daub9a4o\",\"~:font-size\",\"72\",\"~:font-weight\",\"400\",\"~:font-variant-id\",\"regular\",\"~:text-decoration\",\"none\",\"~:letter-spacing\",\"-10\",\"~:fills\",[[\"^ \",\"~:fill-color\",\"#80ffdb\",\"~:fill-opacity\",1]],\"~:font-family\",\"Seymour One\",\"~:text\",\"hello world\"]],\"^=\",\"uppercase\",\"~:text-align\",\"center\",\"^>\",\"gfont-seymour-one\",\"^9\",\"1njiv0webbj\",\"^?\",\"0\",\"^@\",\"400\",\"~:text-direction\",\"ltr\",\"^8\",\"paragraph\",\"^A\",\"regular\",\"^B\",\"none\",\"^C\",\"-10\",\"^D\",[[\"^ \",\"^E\",\"#80ffdb\",\"^F\",1]],\"^G\",\"Seymour One\"]]]],\"~:vertical-align\",\"top\"],\"~:hide-in-viewer\",false,\"~:name\",\"Text\",\"~:width\",697.0002208799245,\"^8\",\"^H\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",186.99991883808582,\"~:y\",731.9301311484297]],[\"^P\",[\"^ \",\"~:x\",813.2711110149318,\"~:y\",425.9999446754641]],[\"^P\",[\"^ \",\"~:x\",851.0186650659188,\"~:y\",503.27315214029437]],[\"^P\",[\"^ \",\"~:x\",224.74747288907042,\"~:y\",809.2033386132608]]],\"~:layout-item-h-sizing\",\"~:fix\",\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",0.8985240384426737,\"~:b\",0.4389242329377818,\"~:c\",-0.43892431277006794,\"~:d\",0.8985240774403239,\"~:e\",2.77125697378148E-12,\"~:f\",2.5219186626122624E-14]],\"~:page-id\",\"~uca00b4e9-7831-806e-8006-e483daa11f18\",\"~:layout-item-v-sizing\",\"^R\",\"~:id\",\"~uae1a2ead-2994-80a4-8006-e49a3c230916\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:position-data\",[[\"~#rect\",[\"^ \",\"~:y\",632.821684222062,\"^<\",\"normal\",\"^=\",\"uppercase\",\"^?\",\"72px\",\"^@\",\"400\",\"~:y1\",-2.3000030517578125,\"^N\",339.1499938964844,\"^B\",\"none\",\"^C\",\"-10px\",\"~:x\",291.2682359356231,\"~:x1\",69.91667175292969,\"~:y2\",88.69999694824219,\"^D\",[[\"^ \",\"^E\",\"#80ffdb\",\"^F\",1]],\"~:x2\",409.06666564941406,\"~:direction\",\"ltr\",\"^G\",\"\\\"Seymour One\\\"\",\"~:height\",91,\"^H\",\"hello \"]],[\"^Y\",[\"^ \",\"~:y\",719.2216933773354,\"^<\",\"normal\",\"^=\",\"uppercase\",\"^?\",\"72px\",\"^@\",\"400\",\"^Z\",84.10000610351562,\"^N\",380.4666748046875,\"^B\",\"none\",\"^C\",\"-10px\",\"~:x\",270.6182267803497,\"^[\",49.26666259765625,\"^10\",175.10000610351562,\"^D\",[[\"^ \",\"^E\",\"#80ffdb\",\"^F\",1]],\"^11\",429.73333740234375,\"^12\",\"ltr\",\"^G\",\"\\\"Seymour One\\\"\",\"^13\",91,\"^H\",\"world\"]]],\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",170.50918151203996,\"~:shadow\",[[\"^ \",\"^V\",\"~u68cfab5e-652d-8097-8006-e488b9656709\",\"~:style\",\"~:inner-shadow\",\"~:color\",[\"^ \",\"~:opacity\",1,\"^19\",\"#64dfdf\"],\"~:offset-x\",8,\"~:offset-y\",12,\"~:blur\",0,\"~:spread\",0,\"~:hidden\",false],[\"^ \",\"^V\",\"~u68cfab5e-652d-8097-8006-e4890c135b3b\",\"^17\",\"^18\",\"^19\",[\"^ \",\"^1:\",1,\"^19\",\"#56cfe1\"],\"^1;\",6,\"^1<\",10,\"^1=\",0,\"^1>\",0,\"^1?\",false],[\"^ \",\"^V\",\"~u68cfab5e-652d-8097-8006-e4894e9ec462\",\"^17\",\"^18\",\"^19\",[\"^ \",\"^1:\",1,\"^19\",\"#5390d9\"],\"^1;\",4,\"^1<\",12,\"^1=\",0,\"^1>\",0,\"^1?\",false],[\"^ \",\"^V\",\"~u68cfab5e-652d-8097-8006-e4898979e7f9\",\"^17\",\"^18\",\"^19\",[\"^ \",\"^1:\",1,\"^19\",\"#5e60ce\"],\"^1;\",4,\"^1<\",8,\"^1=\",0,\"^1>\",0,\"^1?\",false],[\"^ \",\"^V\",\"~u68cfab5e-652d-8097-8006-e489ba59dbd0\",\"^17\",\"^18\",\"^19\",[\"^ \",\"^1:\",1,\"^19\",\"#6930c3\"],\"^1;\",4,\"^1<\",4,\"^1=\",0,\"^1>\",0,\"^1?\",false]],\"~:selrect\",[\"^Y\",[\"^ \",\"~:x\",170.50918151203996,\"~:y\",574.6013159890737,\"^N\",697.0002208799245,\"^13\",86.00065131057738,\"^[\",170.50918151203996,\"^Z\",574.6013159890737,\"^11\",867.5094023919645,\"^10\",660.601967299651]],\"^D\",[],\"~:flip-x\",null,\"^13\",86.00065131057738,\"~:flip-y\",null]]"
}
},
"~:id": "~u48ffa82f-6950-81b5-8006-e49a2a396580",
"~:name": "Page 1"
}
},
"~:id": "~u48ffa82f-6950-81b5-8006-e49a2a39657f",
"~:options": {
"~:components-v2": true,
"~:base-font-size": "16px"
}
}
}

View File

@@ -281,6 +281,24 @@ test("Renders a file with different text shadows combinations", async ({
await expect(workspace.canvas).toHaveScreenshot(); await expect(workspace.canvas).toHaveScreenshot();
}); });
test("Renders a file with multiple text shadows in order", async ({
page,
}) => {
const workspace = new WasmWorkspacePage(page);
await workspace.setupEmptyFile();
await workspace.mockGetFile(
"render-wasm/get-file-text-shadows-order.json",
);
await workspace.goToWorkspace({
id: "48ffa82f-6950-81b5-8006-e49a2a39657f",
pageId: "48ffa82f-6950-81b5-8006-e49a2a396580",
});
await workspace.waitForFirstRender();
await expect(workspace.canvas).toHaveScreenshot();
});
test("Renders a file with text in frames and different strokes, shadows, and blurs", async ({ test("Renders a file with text in frames and different strokes, shadows, and blurs", async ({
page, page,
}) => { }) => {

View File

@@ -1202,7 +1202,7 @@ impl Shape {
pub fn drop_shadow_paints(&self) -> Vec<skia_safe::Paint> { pub fn drop_shadow_paints(&self) -> Vec<skia_safe::Paint> {
let drop_shadows: Vec<&crate::shapes::shadows::Shadow> = let drop_shadows: Vec<&crate::shapes::shadows::Shadow> =
self.drop_shadows().filter(|s| !s.hidden()).collect(); self.drop_shadows().rev().filter(|s| !s.hidden()).collect();
drop_shadows drop_shadows
.into_iter() .into_iter()
.map(|shadow| { .map(|shadow| {
@@ -1216,7 +1216,7 @@ impl Shape {
pub fn inner_shadow_paints(&self) -> Vec<skia_safe::Paint> { pub fn inner_shadow_paints(&self) -> Vec<skia_safe::Paint> {
let inner_shadows: Vec<&crate::shapes::shadows::Shadow> = let inner_shadows: Vec<&crate::shapes::shadows::Shadow> =
self.inner_shadows().filter(|s| !s.hidden()).collect(); self.inner_shadows().rev().filter(|s| !s.hidden()).collect();
inner_shadows inner_shadows
.into_iter() .into_iter()
.map(|shadow| { .map(|shadow| {