diff --git a/frontend/playwright/data/render-wasm/get-file-inner-strokes-artifacts.json b/frontend/playwright/data/render-wasm/get-file-inner-strokes-artifacts.json index 5987b72225..135642a0b5 100644 --- a/frontend/playwright/data/render-wasm/get-file-inner-strokes-artifacts.json +++ b/frontend/playwright/data/render-wasm/get-file-inner-strokes-artifacts.json @@ -1,814 +1,1002 @@ { - "~:features": { - "~#set": [ - "fdata/path-data", - "plugins/runtime", - "design-tokens/v1", - "variants/v1", - "layout/grid", - "styles/v2", - "fdata/pointer-map", - "fdata/objects-map", - "render-wasm/v1", - "components/v2", - "fdata/shape-data-type" - ] - }, - "~:team-id": "~ueba8fa2e-4140-8084-8005-448635d7a724", - "~: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": "gaps", - "~:revn": 79, - "~:modified-at": "~m1771855365377", - "~:vern": 0, - "~:id": "~ueffcbebc-b8c8-802f-8007-9a0b2e2c863f", - "~: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", - "0005-deprecate-image-type", - "0006-fix-old-texts-fills", - "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", - "0013-fix-component-path", - "0013-clear-invalid-strokes-and-fills", - "0014-fix-tokens-lib-duplicate-ids", - "0014-clear-components-nil-objects", - "0015-fix-text-attrs-blank-strings", - "0015-clean-shadow-color", - "0016-copy-fills-from-position-data-to-text-node" - ] - }, - "~:version": 67, - "~:project-id": "~ueba8fa2e-4140-8084-8005-448635da32b4", - "~:created-at": "~m1771591980210", - "~:backend": "legacy-db", - "~:data": { - "~:pages": [ - "~ueffcbebc-b8c8-802f-8007-9a0b2e2c8640" - ], - "~:pages-index": { - "~ueffcbebc-b8c8-802f-8007-9a0b2e2c8640": { - "~:objects": { - "~u00000000-0000-0000-0000-000000000000": { - "~#shape": { - "~:y": 0, - "~:hide-fill-on-export": false, - "~:transform": { - "~#matrix": { - "~:a": 1, - "~:b": 0, - "~:c": 0, - "~:d": 1, - "~:e": 0, - "~:f": 0 - } - }, - "~:rotation": 0, - "~:name": "Root Frame", - "~:width": 0.01, - "~:type": "~:frame", - "~:points": [ - { - "~#point": { - "~:x": 0, - "~:y": 0 - } - }, - { - "~#point": { - "~:x": 0.01, - "~:y": 0 - } - }, - { - "~#point": { - "~:x": 0.01, - "~:y": 0.01 - } - }, - { - "~#point": { - "~:x": 0, - "~:y": 0.01 - } - } - ], - "~:r2": 0, - "~:proportion-lock": false, - "~:transform-inverse": { - "~#matrix": { - "~:a": 1, - "~:b": 0, - "~:c": 0, - "~:d": 1, - "~:e": 0, - "~:f": 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, - "~:r4": 0, - "~:selrect": { - "~#rect": { + "~:features": { + "~#set": [ + "fdata/path-data", + "plugins/runtime", + "design-tokens/v1", + "variants/v1", + "layout/grid", + "styles/v2", + "fdata/pointer-map", + "fdata/objects-map", + "render-wasm/v1", + "text-editor-wasm/v1", + "components/v2", + "fdata/shape-data-type" + ] + }, + "~:team-id": "~ueba8fa2e-4140-8084-8005-448635d7a724", + "~: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": "New File 11", + "~:revn": 19, + "~:modified-at": "~m1774524674610", + "~:vern": 0, + "~:id": "~u273cd825-9673-81c2-8007-c5b6c5207a98", + "~: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", + "0005-deprecate-image-type", + "0006-fix-old-texts-fills", + "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", + "0013-fix-component-path", + "0013-clear-invalid-strokes-and-fills", + "0014-fix-tokens-lib-duplicate-ids", + "0014-clear-components-nil-objects", + "0015-fix-text-attrs-blank-strings", + "0015-clean-shadow-color", + "0016-copy-fills-from-position-data-to-text-node", + "0017-fix-layout-flex-dir" + ] + }, + "~:version": 67, + "~:project-id": "~ueba8fa2e-4140-8084-8005-448635da32b4", + "~:created-at": "~m1774522642561", + "~:backend": "legacy-db", + "~:data": { + "~:pages": [ + "~u273cd825-9673-81c2-8007-c5b6c5207a99" + ], + "~:pages-index": { + "~u273cd825-9673-81c2-8007-c5b6c5207a99": { + "~:objects": { + "~u00000000-0000-0000-0000-000000000000": { + "~#shape": { + "~:y": 0, + "~:hide-fill-on-export": false, + "~:transform": { + "~#matrix": { + "~:a": 1, + "~:b": 0, + "~:c": 0, + "~:d": 1, + "~:e": 0, + "~:f": 0 + } + }, + "~:rotation": 0, + "~:name": "Root Frame", + "~:width": 0.01, + "~:type": "~:frame", + "~:points": [ + { + "~#point": { "~:x": 0, - "~:y": 0, - "~:width": 0.01, - "~:height": 0.01, - "~:x1": 0, - "~:y1": 0, - "~:x2": 0.01, - "~:y2": 0.01 + "~:y": 0 } }, - "~:fills": [ - { - "~:fill-color": "#FFFFFF", - "~:fill-opacity": 1 - } - ], - "~:flip-x": null, - "~:height": 0.01, - "~:flip-y": null, - "~:shapes": [ - "~u36e8a3ad-2b63-8008-8007-9a0b2f24ca4e", - "~ufbc43ead-a2ce-8058-8007-9a0daf843e09", - "~ufbc43ead-a2ce-8058-8007-9a0dbe2f49b8", - "~u5bebb998-d617-801b-8007-9a3fbd5cc804", - "~u80e2fa5a-cd1c-8043-8007-9d8aaca49f40" - ] - } - }, - "~ufbc43ead-a2ce-8058-8007-9a0dbe2f49b8": { - "~#shape": { - "~:y": null, - "~:transform": { - "~#matrix": { - "~:a": 1, - "~:b": 0, - "~:c": 0, - "~:d": 1, - "~:e": 0, - "~:f": 0 + { + "~#point": { + "~:x": 0.01, + "~:y": 0 } }, - "~:rotation": 0, - "~:grow-type": "~:fixed", - "~:content": { - "~#penpot/path-data": "~bAQAAAAAAAAAAAAAAAAAAAAAAAAD/f5dEM2EsRAIAAAAAAAAAAAAAAAAAAAAAAAAAUhmnRABACkQCAAAAAAAAAAAAAAAAAAAAAAAAAP8/vET//01EAgAAAAAAAAAAAAAAAAAAAAAAAAD/f5dEM2EsRA==" - }, - "~:name": "Path", - "~:width": null, - "~:type": "~:path", - "~:points": [ - { - "~#point": { - "~:x": 1212.00003372852, - "~:y": 553.000012923003 - } - }, - { - "~#point": { - "~:x": 1506.00004755679, - "~:y": 553.000012923003 - } - }, - { - "~#point": { - "~:x": 1506.00004755679, - "~:y": 823.999993849517 - } - }, - { - "~#point": { - "~:x": 1212.00003372852, - "~:y": 823.999993849517 - } - } - ], - "~:r2": 0, - "~:proportion-lock": false, - "~:transform-inverse": { - "~#matrix": { - "~:a": 1, - "~:b": 0, - "~:c": 0, - "~:d": 1, - "~:e": 0, - "~:f": 0 + { + "~#point": { + "~:x": 0.01, + "~:y": 0.01 } }, - "~:r3": 0, - "~:r1": 0, - "~:id": "~ufbc43ead-a2ce-8058-8007-9a0dbe2f49b8", - "~:parent-id": "~u00000000-0000-0000-0000-000000000000", - "~:frame-id": "~u00000000-0000-0000-0000-000000000000", - "~:strokes": [ - { - "~:stroke-alignment": "~:inner", - "~:stroke-style": "~:solid", - "~:stroke-color": "#000000", - "~:stroke-opacity": 1, - "~:stroke-width": 10 + { + "~#point": { + "~:x": 0, + "~:y": 0.01 } - ], - "~:x": null, - "~:proportion": 1, - "~:shadow": [], - "~:r4": 0, - "~:selrect": { - "~#rect": { - "~:x": 1212.00003372852, - "~:y": 553.000012923003, - "~:width": 294.000013828278, - "~:height": 270.999980926514, - "~:x1": 1212.00003372852, - "~:y1": 553.000012923003, - "~:x2": 1506.00004755679, - "~:y2": 823.999993849517 - } - }, - "~:fills": [ - { - "~:fill-color": "#ffffff", - "~:fill-opacity": 1 - } - ], - "~:flip-x": null, - "~:height": null, - "~:flip-y": null - } - }, - "~u36e8a3ad-2b63-8008-8007-9a0b2f24ca4e": { - "~#shape": { - "~:y": 122.000001761754, - "~:transform": { - "~#matrix": { - "~:a": 1, - "~:b": 0, - "~:c": 0, - "~:d": 1, - "~:e": 0, - "~:f": 0 - } - }, - "~:rotation": 0, - "~:hide-in-viewer": false, - "~:name": "Rectangle", - "~:width": 463.999987447937, - "~:type": "~:rect", - "~:points": [ - { - "~#point": { - "~:x": 694.000014750112, - "~:y": 122.000001761754 - } - }, - { - "~#point": { - "~:x": 1158.00000219805, - "~:y": 122.000001761754 - } - }, - { - "~#point": { - "~:x": 1158.00000219805, - "~:y": 499.999980116278 - } - }, - { - "~#point": { - "~:x": 694.000014750112, - "~:y": 499.999980116278 - } - } - ], - "~:r2": 0, - "~:proportion-lock": false, - "~:transform-inverse": { - "~#matrix": { - "~:a": 1, - "~:b": 0, - "~:c": 0, - "~:d": 1, - "~:e": 0, - "~:f": 0 - } - }, - "~:r3": 0, - "~:r1": 0, - "~:id": "~u36e8a3ad-2b63-8008-8007-9a0b2f24ca4e", - "~:parent-id": "~u00000000-0000-0000-0000-000000000000", - "~:frame-id": "~u00000000-0000-0000-0000-000000000000", - "~:strokes": [ - { - "~:stroke-alignment": "~:inner", - "~:stroke-style": "~:solid", - "~:stroke-color": "#000000", - "~:stroke-opacity": 1, - "~:stroke-width": 100 - }, - { - "~:stroke-alignment": "~:outer", - "~:stroke-style": "~:solid", - "~:stroke-color": "#000000", - "~:stroke-opacity": 1, - "~:stroke-width": 100 - } - ], - "~:x": 694.000014750113, - "~:proportion": 1, - "~:shadow": [], - "~:r4": 0, - "~:selrect": { - "~#rect": { - "~:x": 694.000014750113, - "~:y": 122.000001761754, - "~:width": 463.999987447937, - "~:height": 377.999978354524, - "~:x1": 694.000014750113, - "~:y1": 122.000001761754, - "~:x2": 1158.00000219805, - "~:y2": 499.999980116278 - } - }, - "~:fills": [ - { - "~:fill-color": "#ffffff", - "~:fill-opacity": 1 - } - ], - "~:flip-x": null, - "~:height": 377.999978354524, - "~:flip-y": null - } - }, - "~ufbc43ead-a2ce-8058-8007-9a0daf843e09": { - "~#shape": { - "~:y": 262.999997589325, - "~:transform": { - "~#matrix": { - "~:a": 1, - "~:b": 0, - "~:c": 0, - "~:d": 1, - "~:e": 0, - "~:f": 0 - } - }, - "~:rotation": 0, - "~:grow-type": "~:fixed", - "~:hide-in-viewer": false, - "~:name": "Ellipse", - "~:width": 266.000036716461, - "~:type": "~:circle", - "~:points": [ - { - "~#point": { - "~:x": 1271.00000137752, - "~:y": 262.999997589325 - } - }, - { - "~#point": { - "~:x": 1537.00003809398, - "~:y": 262.999997589325 - } - }, - { - "~#point": { - "~:x": 1537.00003809398, - "~:y": 483.000033828949 - } - }, - { - "~#point": { - "~:x": 1271.00000137752, - "~:y": 483.000033828949 - } - } - ], - "~:r2": 0, - "~:proportion-lock": false, - "~:transform-inverse": { - "~#matrix": { - "~:a": 1, - "~:b": 0, - "~:c": 0, - "~:d": 1, - "~:e": 0, - "~:f": 0 - } - }, - "~:r3": 0, - "~:r1": 0, - "~:id": "~ufbc43ead-a2ce-8058-8007-9a0daf843e09", - "~:parent-id": "~u00000000-0000-0000-0000-000000000000", - "~:frame-id": "~u00000000-0000-0000-0000-000000000000", - "~:strokes": [ - { - "~:stroke-alignment": "~:inner", - "~:stroke-style": "~:solid", - "~:stroke-color": "#000000", - "~:stroke-opacity": 1, - "~:stroke-width": 10 - } - ], - "~:x": 1271.00000137752, - "~:proportion": 1, - "~:shadow": [ - { - "~:id": "~u9c6321b5-aeab-809f-8007-971f9e232191", - "~:style": "~:drop-shadow", - "~:color": { - "~:color": "#000000", - "~:opacity": 1 - }, - "~:offset-x": 4, - "~:offset-y": 4, - "~:blur": 0, - "~:spread": 0, - "~:hidden": true - } - ], - "~:r4": 0, - "~:selrect": { - "~#rect": { - "~:x": 1271.00000137752, - "~:y": 262.999997589325, - "~:width": 266.000036716461, - "~:height": 220.000036239624, - "~:x1": 1271.00000137752, - "~:y1": 262.999997589325, - "~:x2": 1537.00003809398, - "~:y2": 483.000033828949 - } - }, - "~:fills": [ - { - "~:fill-color": "#ffffff", - "~:fill-opacity": 1 - } - ], - "~:flip-x": null, - "~:height": 220.000036239624, - "~:flip-y": null - } - }, - "~u80e2fa5a-cd1c-8043-8007-9d8aaca49f40": { - "~#shape": { - "~:y": -286.999972473494, - "~:transform": { - "~#matrix": { - "~:a": 1, - "~:b": 0, - "~:c": 0, - "~:d": 1, - "~:e": 0, - "~:f": 0 - } - }, - "~:rotation": 0, - "~:grow-type": "~:auto-width", - "~:content": { - "~:type": "root", - "~:key": "1srkh8oc2vd", - "~:children": [ - { - "~:type": "paragraph-set", - "~:children": [ - { - "~:line-height": "1.2", - "~:font-style": "normal", - "~:children": [ - { - "~:line-height": "1.2", - "~:font-style": "normal", - "~:typography-ref-id": null, - "~:text-transform": "none", - "~:font-id": "sourcesanspro", - "~:key": "170uyffw5ph", - "~:font-size": "400", - "~:font-weight": "400", - "~:typography-ref-file": null, - "~:font-variant-id": "regular", - "~:text-decoration": "none", - "~:letter-spacing": "0", - "~:fills": [ - { - "~:fill-color": "#ffffff", - "~:fill-opacity": 1 - } - ], - "~:font-family": "sourcesanspro", - "~:text": "HELLO" - } - ], - "~:typography-ref-id": null, - "~:text-transform": "none", - "~:text-align": "left", - "~:font-id": "sourcesanspro", - "~:key": "psg8ayj675", - "~:font-size": "400", - "~:font-weight": "400", - "~:typography-ref-file": null, - "~:text-direction": "ltr", - "~:type": "paragraph", - "~:font-variant-id": "regular", - "~:text-decoration": "none", - "~:letter-spacing": "0", - "~:fills": [ - { - "~:fill-color": "#ffffff", - "~:fill-opacity": 1 - } - ], - "~:font-family": "sourcesanspro" - } - ] - } - ], - "~:vertical-align": "top" - }, - "~:hide-in-viewer": false, - "~:name": "HELLO", - "~:width": 1116.00003953244, - "~:type": "~:text", - "~:points": [ - { - "~#point": { - "~:x": 545.000013504691, - "~:y": -286.999972473494 - } - }, - { - "~#point": { - "~:x": 1661.00005303713, - "~:y": -286.999972473494 - } - }, - { - "~#point": { - "~:x": 1661.00005303713, - "~:y": 193.000017549648 - } - }, - { - "~#point": { - "~:x": 545.000013504691, - "~:y": 193.000017549648 - } - } - ], - "~:transform-inverse": { - "~#matrix": { - "~:a": 1, - "~:b": 0, - "~:c": 0, - "~:d": 1, - "~:e": 0, - "~:f": 0 - } - }, - "~:id": "~u80e2fa5a-cd1c-8043-8007-9d8aaca49f40", - "~:parent-id": "~u00000000-0000-0000-0000-000000000000", - "~:position-data": [ - { - "~:y": 211.980041503906, - "~:line-height": "1.2", - "~:font-style": "normal", - "~:text-transform": "none", - "~:text-align": "left", - "~:font-id": "sourcesanspro", - "~:font-size": "400", - "~:font-weight": "400", - "~:text-direction": "ltr", - "~:width": 1115.22998046875, - "~:font-variant-id": "regular", - "~:text-decoration": "none", - "~:letter-spacing": "0", - "~:x": 545, - "~:fills": [ - { - "~:fill-color": "#ffffff", - "~:fill-opacity": 1 - } - ], - "~:direction": "ltr", - "~:font-family": "sourcesanspro", - "~:height": 517.960021972656, - "~:text": "HELLO" - } - ], - "~:frame-id": "~u00000000-0000-0000-0000-000000000000", - "~:strokes": [ - { - "~:stroke-style": "~:solid", - "~:stroke-alignment": "~:inner", - "~:stroke-width": 5, - "~:stroke-color": "#000000", - "~:stroke-opacity": 1 - } - ], - "~:x": 545.000013504691, - "~:selrect": { - "~#rect": { - "~:x": 545.000013504691, - "~:y": -286.999972473494, - "~:width": 1116.00003953244, - "~:height": 479.999990023141, - "~:x1": 545.000013504691, - "~:y1": -286.999972473494, - "~:x2": 1661.00005303713, - "~:y2": 193.000017549648 - } - }, - "~:flip-x": null, - "~:height": 479.999990023141, - "~:flip-y": null - } - }, - "~u5bebb998-d617-801b-8007-9a3fbd5cc804": { - "~#shape": { - "~:y": 543.00001095581, - "~:transform": { - "~#matrix": { - "~:a": 1, - "~:b": 0, - "~:c": 0, - "~:d": 1, - "~:e": 0, - "~:f": 0 - } - }, - "~:rotation": 0, - "~:hide-in-viewer": false, - "~:name": "Rectangle", - "~:width": 463.999987447937, - "~:type": "~:rect", - "~:points": [ - { - "~#point": { - "~:x": 693.999990768432, - "~:y": 543.00001095581 - } - }, - { - "~#point": { - "~:x": 1157.99997821637, - "~:y": 543.00001095581 - } - }, - { - "~#point": { - "~:x": 1157.99997821637, - "~:y": 920.999989310334 - } - }, - { - "~#point": { - "~:x": 693.999990768432, - "~:y": 920.999989310334 - } - } - ], - "~:r2": 0, - "~:proportion-lock": false, - "~:transform-inverse": { - "~#matrix": { - "~:a": 1, - "~:b": 0, - "~:c": 0, - "~:d": 1, - "~:e": 0, - "~:f": 0 - } - }, - "~:r3": 0, - "~:r1": 0, - "~:id": "~u5bebb998-d617-801b-8007-9a3fbd5cc804", - "~:parent-id": "~u00000000-0000-0000-0000-000000000000", - "~:frame-id": "~u00000000-0000-0000-0000-000000000000", - "~:strokes": [ - { - "~:stroke-alignment": "~:inner", - "~:stroke-style": "~:solid", - "~:stroke-color": "#000000", - "~:stroke-opacity": 1, - "~:stroke-width": 100 - } - ], - "~:x": 693.999990768432, - "~:proportion": 1, - "~:shadow": [], - "~:r4": 0, - "~:selrect": { - "~#rect": { - "~:x": 693.999990768432, - "~:y": 543.00001095581, - "~:width": 463.999987447937, - "~:height": 377.999978354524, - "~:x1": 693.999990768432, - "~:y1": 543.00001095581, - "~:x2": 1157.99997821637, - "~:y2": 920.999989310334 - } - }, - "~:fills": [ - { - "~:fill-color": "#ffffff", - "~:fill-opacity": 1 - } - ], - "~:flip-x": null, - "~:height": 377.999978354524, - "~:flip-y": null - } + } + ], + "~:r2": 0, + "~:proportion-lock": false, + "~:transform-inverse": { + "~#matrix": { + "~:a": 1, + "~:b": 0, + "~:c": 0, + "~:d": 1, + "~:e": 0, + "~:f": 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, + "~:r4": 0, + "~:selrect": { + "~#rect": { + "~:x": 0, + "~:y": 0, + "~:width": 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, + "~:height": 0.01, + "~:flip-y": null, + "~:shapes": [ + "~u91d336c9-02e5-806a-8007-c5b91b180723", + "~u91d336c9-02e5-806a-8007-c5b91b180724", + "~u91d336c9-02e5-806a-8007-c5b91b180725", + "~u91d336c9-02e5-806a-8007-c5b91b185c8b", + "~u91d336c9-02e5-806a-8007-c5b91b185c8c", + "~u91d336c9-02e5-806a-8007-c5b925214f02" + ] } }, - "~:id": "~ueffcbebc-b8c8-802f-8007-9a0b2e2c8640", - "~:name": "Page 1", - "~:background": "#000000" - } - }, - "~:id": "~ueffcbebc-b8c8-802f-8007-9a0b2e2c863f", - "~:options": { - "~:components-v2": true, - "~:base-font-size": "16px" + "~u91d336c9-02e5-806a-8007-c5b94496a8b5": { + "~#shape": { + "~:y": 837.000020861669, + "~:transform": { + "~#matrix": { + "~:a": 1, + "~:b": 0, + "~:c": 0, + "~:d": 1, + "~:e": 0, + "~:f": 0 + } + }, + "~:rotation": 0, + "~:grow-type": "~:fixed", + "~:hide-in-viewer": false, + "~:name": "Rectangle", + "~:width": 384, + "~:type": "~:rect", + "~:points": [ + { + "~#point": { + "~:x": 91, + "~:y": 837.000020861669 + } + }, + { + "~#point": { + "~:x": 475, + "~:y": 837.000020861669 + } + }, + { + "~#point": { + "~:x": 475, + "~:y": 1239.99999684096 + } + }, + { + "~#point": { + "~:x": 91, + "~:y": 1239.99999684096 + } + } + ], + "~:r2": 0, + "~:proportion-lock": false, + "~:transform-inverse": { + "~#matrix": { + "~:a": 1, + "~:b": 0, + "~:c": 0, + "~:d": 1, + "~:e": 0, + "~:f": 0 + } + }, + "~:r3": 0, + "~:constraints-v": "~:top", + "~:constraints-h": "~:left", + "~:r1": 0, + "~:id": "~u91d336c9-02e5-806a-8007-c5b94496a8b5", + "~:parent-id": "~u91d336c9-02e5-806a-8007-c5b925214f02", + "~:frame-id": "~u91d336c9-02e5-806a-8007-c5b925214f02", + "~:strokes": [], + "~:x": 91, + "~:proportion": 1, + "~:r4": 0, + "~:selrect": { + "~#rect": { + "~:x": 91, + "~:y": 837.000020861669, + "~:width": 384, + "~:height": 402.999975979287, + "~:x1": 91, + "~:y1": 837.000020861669, + "~:x2": 475, + "~:y2": 1239.99999684096 + } + }, + "~:fills": [ + { + "~:fill-color": "#f7f7f7", + "~:fill-opacity": 1 + } + ], + "~:flip-x": null, + "~:height": 402.999975979287, + "~:flip-y": null + } + }, + "~u91d336c9-02e5-806a-8007-c5b91b185c8b": { + "~#shape": { + "~:y": 1213.9999834293, + "~:transform": { + "~#matrix": { + "~:a": 1, + "~:b": 0, + "~:c": 0, + "~:d": 1, + "~:e": 0, + "~:f": 0 + } + }, + "~:rotation": 0, + "~:hide-in-viewer": false, + "~:name": "Rectangle", + "~:width": 463.999987447937, + "~:type": "~:rect", + "~:points": [ + { + "~#point": { + "~:x": 449.999977263741, + "~:y": 1213.9999834293 + } + }, + { + "~#point": { + "~:x": 913.999964711679, + "~:y": 1213.9999834293 + } + }, + { + "~#point": { + "~:x": 913.999964711679, + "~:y": 1591.99996178383 + } + }, + { + "~#point": { + "~:x": 449.999977263741, + "~:y": 1591.99996178383 + } + } + ], + "~:r2": 0, + "~:proportion-lock": false, + "~:transform-inverse": { + "~#matrix": { + "~:a": 1, + "~:b": 0, + "~:c": 0, + "~:d": 1, + "~:e": 0, + "~:f": 0 + } + }, + "~:r3": 0, + "~:r1": 0, + "~:id": "~u91d336c9-02e5-806a-8007-c5b91b185c8b", + "~:parent-id": "~u00000000-0000-0000-0000-000000000000", + "~:frame-id": "~u00000000-0000-0000-0000-000000000000", + "~:strokes": [ + { + "~:stroke-alignment": "~:inner", + "~:stroke-style": "~:solid", + "~:stroke-color": "#000000", + "~:stroke-opacity": 1, + "~:stroke-width": 100 + } + ], + "~:x": 449.999977263741, + "~:proportion": 1, + "~:shadow": [], + "~:r4": 0, + "~:selrect": { + "~#rect": { + "~:x": 449.999977263741, + "~:y": 1213.9999834293, + "~:width": 463.999987447937, + "~:height": 377.999978354524, + "~:x1": 449.999977263741, + "~:y1": 1213.9999834293, + "~:x2": 913.999964711678, + "~:y2": 1591.99996178383 + } + }, + "~:fills": [ + { + "~:fill-color": "#ffffff", + "~:fill-opacity": 1 + } + ], + "~:flip-x": null, + "~:height": 377.999978354524, + "~:flip-y": null + } + }, + "~u91d336c9-02e5-806a-8007-c5b91b185c8c": { + "~#shape": { + "~:y": 384, + "~:transform": { + "~#matrix": { + "~:a": 1, + "~:b": 0, + "~:c": 0, + "~:d": 1, + "~:e": 0, + "~:f": 0 + } + }, + "~:rotation": 0, + "~:grow-type": "~:auto-width", + "~:content": { + "~:type": "root", + "~:key": "1srkh8oc2vd", + "~:children": [ + { + "~:type": "paragraph-set", + "~:children": [ + { + "~:line-height": "1.2", + "~:font-style": "normal", + "~:children": [ + { + "~:line-height": "1.2", + "~:font-style": "normal", + "~:text-transform": "none", + "~:font-id": "sourcesanspro", + "~:key": "170uyffw5ph", + "~:font-size": "400", + "~:font-weight": "400", + "~:font-variant-id": "regular", + "~:text-decoration": "none", + "~:letter-spacing": "0", + "~:fills": [ + { + "~:fill-color": "#ffffff", + "~:fill-opacity": 1 + } + ], + "~:font-family": "sourcesanspro", + "~:text": "HELLO" + } + ], + "~:text-transform": "none", + "~:text-align": "left", + "~:font-id": "sourcesanspro", + "~:key": "psg8ayj675", + "~:font-size": "400", + "~:font-weight": "400", + "~:text-direction": "ltr", + "~:type": "paragraph", + "~:font-variant-id": "regular", + "~:text-decoration": "none", + "~:letter-spacing": "0", + "~:fills": [ + { + "~:fill-color": "#ffffff", + "~:fill-opacity": 1 + } + ], + "~:font-family": "sourcesanspro" + } + ] + } + ], + "~:vertical-align": "top" + }, + "~:hide-in-viewer": false, + "~:name": "HELLO", + "~:width": 1116.00003953244, + "~:type": "~:text", + "~:points": [ + { + "~#point": { + "~:x": 301, + "~:y": 384 + } + }, + { + "~#point": { + "~:x": 1417.00003953244, + "~:y": 384 + } + }, + { + "~#point": { + "~:x": 1417.00003953244, + "~:y": 863.999990023142 + } + }, + { + "~#point": { + "~:x": 301, + "~:y": 863.999990023142 + } + } + ], + "~:transform-inverse": { + "~#matrix": { + "~:a": 1, + "~:b": 0, + "~:c": 0, + "~:d": 1, + "~:e": 0, + "~:f": 0 + } + }, + "~:id": "~u91d336c9-02e5-806a-8007-c5b91b185c8c", + "~:parent-id": "~u00000000-0000-0000-0000-000000000000", + "~:position-data": [ + { + "~:y": 882.979949951172, + "~:line-height": "1.2", + "~:font-style": "normal", + "~:text-transform": "none", + "~:text-align": "left", + "~:font-id": "sourcesanspro", + "~:font-size": "400", + "~:font-weight": "400", + "~:text-direction": "ltr", + "~:width": 1115.22998046875, + "~:font-variant-id": "regular", + "~:text-decoration": "none", + "~:letter-spacing": "0", + "~:x": 301, + "~:fills": [ + { + "~:fill-color": "#ffffff", + "~:fill-opacity": 1 + } + ], + "~:direction": "ltr", + "~:font-family": "sourcesanspro", + "~:height": 517.9599609375, + "~:text": "HELLO" + } + ], + "~:frame-id": "~u00000000-0000-0000-0000-000000000000", + "~:strokes": [ + { + "~:stroke-style": "~:solid", + "~:stroke-alignment": "~:inner", + "~:stroke-width": 5, + "~:stroke-color": "#000000", + "~:stroke-opacity": 1 + } + ], + "~:x": 301, + "~:selrect": { + "~#rect": { + "~:x": 301, + "~:y": 384, + "~:width": 1116.00003953244, + "~:height": 479.999990023141, + "~:x1": 301, + "~:y1": 384, + "~:x2": 1417.00003953244, + "~:y2": 863.999990023141 + } + }, + "~:fills": [], + "~:flip-x": null, + "~:height": 479.999990023141, + "~:flip-y": null + } + }, + "~u91d336c9-02e5-806a-8007-c5b925214f02": { + "~#shape": { + "~:y": 894.000017464198, + "~:hide-fill-on-export": false, + "~:transform": { + "~#matrix": { + "~:a": 1, + "~:b": 0, + "~:c": 0, + "~:d": 1, + "~:e": 0, + "~:f": 0 + } + }, + "~:rotation": 0, + "~:grow-type": "~:fixed", + "~:hide-in-viewer": false, + "~:name": "Board", + "~:width": 264, + "~:type": "~:frame", + "~:points": [ + { + "~#point": { + "~:x": 169, + "~:y": 894.000017464198 + } + }, + { + "~#point": { + "~:x": 433, + "~:y": 894.000017464198 + } + }, + { + "~#point": { + "~:x": 433, + "~:y": 1212.99999845028 + } + }, + { + "~#point": { + "~:x": 169, + "~:y": 1212.99999845028 + } + } + ], + "~:r2": 20, + "~:show-content": false, + "~:proportion-lock": false, + "~:transform-inverse": { + "~#matrix": { + "~:a": 1, + "~:b": 0, + "~:c": 0, + "~:d": 1, + "~:e": 0, + "~:f": 0 + } + }, + "~:r3": 20, + "~:r1": 20, + "~:id": "~u91d336c9-02e5-806a-8007-c5b925214f02", + "~:parent-id": "~u00000000-0000-0000-0000-000000000000", + "~:frame-id": "~u00000000-0000-0000-0000-000000000000", + "~:strokes": [ + { + "~:stroke-alignment": "~:inner", + "~:stroke-style": "~:solid", + "~:stroke-color": "#000000", + "~:stroke-opacity": 1, + "~:stroke-width": 10 + } + ], + "~:x": 169, + "~:proportion": 1, + "~:r4": 20, + "~:selrect": { + "~#rect": { + "~:x": 169, + "~:y": 894.000017464198, + "~:width": 264, + "~:height": 318.999980986085, + "~:x1": 169, + "~:y1": 894.000017464198, + "~:x2": 433, + "~:y2": 1212.99999845028 + } + }, + "~:fills": [], + "~:flip-x": null, + "~:height": 318.999980986085, + "~:flip-y": null, + "~:shapes": [ + "~u91d336c9-02e5-806a-8007-c5b94496a8b5" + ] + } + }, + "~u91d336c9-02e5-806a-8007-c5b91b180723": { + "~#shape": { + "~:y": 792.999974235248, + "~:transform": { + "~#matrix": { + "~:a": 1, + "~:b": 0, + "~:c": 0, + "~:d": 1, + "~:e": 0, + "~:f": 0 + } + }, + "~:rotation": 0, + "~:hide-in-viewer": false, + "~:name": "Rectangle", + "~:width": 463.999987447937, + "~:type": "~:rect", + "~:points": [ + { + "~#point": { + "~:x": 450.000001245421, + "~:y": 792.999974235248 + } + }, + { + "~#point": { + "~:x": 913.999988693359, + "~:y": 792.999974235248 + } + }, + { + "~#point": { + "~:x": 913.999988693359, + "~:y": 1170.99995258977 + } + }, + { + "~#point": { + "~:x": 450.000001245421, + "~:y": 1170.99995258977 + } + } + ], + "~:r2": 0, + "~:proportion-lock": false, + "~:transform-inverse": { + "~#matrix": { + "~:a": 1, + "~:b": 0, + "~:c": 0, + "~:d": 1, + "~:e": 0, + "~:f": 0 + } + }, + "~:r3": 0, + "~:r1": 0, + "~:id": "~u91d336c9-02e5-806a-8007-c5b91b180723", + "~:parent-id": "~u00000000-0000-0000-0000-000000000000", + "~:frame-id": "~u00000000-0000-0000-0000-000000000000", + "~:strokes": [ + { + "~:stroke-alignment": "~:inner", + "~:stroke-style": "~:solid", + "~:stroke-color": "#000000", + "~:stroke-opacity": 1, + "~:stroke-width": 100 + }, + { + "~:stroke-alignment": "~:outer", + "~:stroke-style": "~:solid", + "~:stroke-color": "#000000", + "~:stroke-opacity": 1, + "~:stroke-width": 100 + } + ], + "~:x": 450.000001245422, + "~:proportion": 1, + "~:shadow": [], + "~:r4": 0, + "~:selrect": { + "~#rect": { + "~:x": 450.000001245422, + "~:y": 792.999974235248, + "~:width": 463.999987447937, + "~:height": 377.999978354524, + "~:x1": 450.000001245422, + "~:y1": 792.999974235248, + "~:x2": 913.999988693359, + "~:y2": 1170.99995258977 + } + }, + "~:fills": [ + { + "~:fill-color": "#ffffff", + "~:fill-opacity": 1 + } + ], + "~:flip-x": null, + "~:height": 377.999978354524, + "~:flip-y": null + } + }, + "~u91d336c9-02e5-806a-8007-c5b91b180724": { + "~#shape": { + "~:y": 933.999970062819, + "~:transform": { + "~#matrix": { + "~:a": 1, + "~:b": 0, + "~:c": 0, + "~:d": 1, + "~:e": 0, + "~:f": 0 + } + }, + "~:rotation": 0, + "~:grow-type": "~:fixed", + "~:hide-in-viewer": false, + "~:name": "Ellipse", + "~:width": 266.000036716461, + "~:type": "~:circle", + "~:points": [ + { + "~#point": { + "~:x": 1026.99998787283, + "~:y": 933.999970062819 + } + }, + { + "~#point": { + "~:x": 1293.00002458929, + "~:y": 933.999970062819 + } + }, + { + "~#point": { + "~:x": 1293.00002458929, + "~:y": 1154.00000630244 + } + }, + { + "~#point": { + "~:x": 1026.99998787283, + "~:y": 1154.00000630244 + } + } + ], + "~:r2": 0, + "~:proportion-lock": false, + "~:transform-inverse": { + "~#matrix": { + "~:a": 1, + "~:b": 0, + "~:c": 0, + "~:d": 1, + "~:e": 0, + "~:f": 0 + } + }, + "~:r3": 0, + "~:r1": 0, + "~:id": "~u91d336c9-02e5-806a-8007-c5b91b180724", + "~:parent-id": "~u00000000-0000-0000-0000-000000000000", + "~:frame-id": "~u00000000-0000-0000-0000-000000000000", + "~:strokes": [ + { + "~:stroke-alignment": "~:inner", + "~:stroke-style": "~:solid", + "~:stroke-color": "#000000", + "~:stroke-opacity": 1, + "~:stroke-width": 10 + } + ], + "~:x": 1026.99998787283, + "~:proportion": 1, + "~:shadow": [ + { + "~:id": "~u9c6321b5-aeab-809f-8007-971f9e232191", + "~:style": "~:drop-shadow", + "~:color": { + "~:color": "#000000", + "~:opacity": 1 + }, + "~:offset-x": 4, + "~:offset-y": 4, + "~:blur": 0, + "~:spread": 0, + "~:hidden": true + } + ], + "~:r4": 0, + "~:selrect": { + "~#rect": { + "~:x": 1026.99998787283, + "~:y": 933.999970062819, + "~:width": 266.000036716461, + "~:height": 220.000036239624, + "~:x1": 1026.99998787283, + "~:y1": 933.999970062819, + "~:x2": 1293.00002458929, + "~:y2": 1154.00000630244 + } + }, + "~:fills": [ + { + "~:fill-color": "#ffffff", + "~:fill-opacity": 1 + } + ], + "~:flip-x": null, + "~:height": 220.000036239624, + "~:flip-y": null + } + }, + "~u91d336c9-02e5-806a-8007-c5b91b180725": { + "~#shape": { + "~:y": null, + "~:transform": { + "~#matrix": { + "~:a": 1, + "~:b": 0, + "~:c": 0, + "~:d": 1, + "~:e": 0, + "~:f": 0 + } + }, + "~:rotation": 0, + "~:grow-type": "~:fixed", + "~:content": { + "~#penpot/path-data": "~bAQAAAAAAAAAAAAAAAAAAAAAAAAD+/3FEmRCqRAIAAAAAAAAAAAAAAAAAAAAAAAAAUpmIRAAAmUQCAAAAAAAAAAAAAAAAAAAAAAAAAP+/nUT/37pEAgAAAAAAAAAAAAAAAAAAAAAAAAD+/3FEmRCqRA==" + }, + "~:name": "Path", + "~:width": null, + "~:type": "~:path", + "~:points": [ + { + "~#point": { + "~:x": 968.000020223829, + "~:y": 1223.9999853965 + } + }, + { + "~#point": { + "~:x": 1262.0000340521, + "~:y": 1223.9999853965 + } + }, + { + "~#point": { + "~:x": 1262.0000340521, + "~:y": 1494.99996632301 + } + }, + { + "~#point": { + "~:x": 968.000020223829, + "~:y": 1494.99996632301 + } + } + ], + "~:r2": 0, + "~:proportion-lock": false, + "~:transform-inverse": { + "~#matrix": { + "~:a": 1, + "~:b": 0, + "~:c": 0, + "~:d": 1, + "~:e": 0, + "~:f": 0 + } + }, + "~:r3": 0, + "~:r1": 0, + "~:id": "~u91d336c9-02e5-806a-8007-c5b91b180725", + "~:parent-id": "~u00000000-0000-0000-0000-000000000000", + "~:frame-id": "~u00000000-0000-0000-0000-000000000000", + "~:strokes": [ + { + "~:stroke-alignment": "~:inner", + "~:stroke-style": "~:solid", + "~:stroke-color": "#000000", + "~:stroke-opacity": 1, + "~:stroke-width": 10 + } + ], + "~:x": null, + "~:proportion": 1, + "~:shadow": [], + "~:r4": 0, + "~:selrect": { + "~#rect": { + "~:x": 968.000020223829, + "~:y": 1223.9999853965, + "~:width": 294.000013828278, + "~:height": 270.999980926514, + "~:x1": 968.000020223829, + "~:y1": 1223.9999853965, + "~:x2": 1262.00003405211, + "~:y2": 1494.99996632301 + } + }, + "~:fills": [ + { + "~:fill-color": "#ffffff", + "~:fill-opacity": 1 + } + ], + "~:flip-x": null, + "~:height": null, + "~:flip-y": null + } + } + }, + "~:id": "~u273cd825-9673-81c2-8007-c5b6c5207a99", + "~:name": "Page 1", + "~:background": "#000000" } + }, + "~:id": "~u273cd825-9673-81c2-8007-c5b6c5207a98", + "~:options": { + "~:components-v2": true, + "~:base-font-size": "16px" } - } \ No newline at end of file + } +} \ No newline at end of file diff --git a/frontend/playwright/ui/render-wasm-specs/shapes.spec.js-snapshots/Check-inner-stroke-artifacts-1.png b/frontend/playwright/ui/render-wasm-specs/shapes.spec.js-snapshots/Check-inner-stroke-artifacts-1.png index ed80d4675f..e74e55f39f 100644 Binary files a/frontend/playwright/ui/render-wasm-specs/shapes.spec.js-snapshots/Check-inner-stroke-artifacts-1.png and b/frontend/playwright/ui/render-wasm-specs/shapes.spec.js-snapshots/Check-inner-stroke-artifacts-1.png differ diff --git a/render-wasm/src/render.rs b/render-wasm/src/render.rs index 3b8e353213..35aaff5200 100644 --- a/render-wasm/src/render.rs +++ b/render-wasm/src/render.rs @@ -115,6 +115,7 @@ impl NodeRenderState { &self, element: &Shape, offset: Option<(f32, f32)>, + clip_inset: Option, ) -> Option { if self.id.is_nil() || !element.clip() { return self.clip_bounds.clone(); @@ -138,6 +139,10 @@ impl NodeRenderState { _ => None, }; + if let Some(clip_inset) = clip_inset.filter(|&e| e > 0.0) { + bounds.inset((clip_inset, clip_inset)); + } + Self::append_clip(self.clip_bounds.clone(), (bounds, corners, transform)) } @@ -2436,8 +2441,18 @@ impl RenderState { }); if element.is_recursive() { - let children_clip_bounds = - node_render_state.get_children_clip_bounds(element, None); + // Shrink the child clip by ~1 device px when the frame has an inner stroke, same + // epsilon as `fills::render` inset, so clipped overflow does not sit under the + // stroke band drawn later in `render_shape_exit`. + let clip_inset_for_children = (matches!(element.shape_type, Type::Frame(_)) + && element.clip() + && element.has_inner_stroke()) + .then_some(1.0 / scale); + let children_clip_bounds = node_render_state.get_children_clip_bounds( + element, + None, + clip_inset_for_children, + ); let children_ids: Vec<_> = if can_flatten { // Container was flattened: get simplified children (which skip this level) diff --git a/render-wasm/src/render/fills.rs b/render-wasm/src/render/fills.rs index 2a1968a93c..615d8b9532 100644 --- a/render-wasm/src/render/fills.rs +++ b/render-wasm/src/render/fills.rs @@ -3,15 +3,7 @@ use skia_safe::{self as skia, Paint, RRect}; use super::{filters, RenderState, SurfaceId}; use crate::error::Result; use crate::render::get_source_rect; -use crate::shapes::{merge_fills, Fill, Frame, ImageFill, Rect, Shape, StrokeKind, Type}; - -/// True when the shape has at least one visible inner stroke. -fn has_inner_stroke(shape: &Shape) -> bool { - let is_open = shape.is_open(); - shape - .visible_strokes() - .any(|s| s.render_kind(is_open) == StrokeKind::Inner) -} +use crate::shapes::{merge_fills, Fill, Frame, ImageFill, Rect, Shape, Type}; fn draw_image_fill( render_state: &mut RenderState, @@ -113,7 +105,7 @@ pub fn render( } let scale = render_state.get_scale().max(1e-6); - let inset = if has_inner_stroke(shape) { + let inset = if shape.has_inner_stroke() { Some(1.0 / scale) } else { None diff --git a/render-wasm/src/shapes.rs b/render-wasm/src/shapes.rs index dc129e8695..4e192b97bc 100644 --- a/render-wasm/src/shapes.rs +++ b/render-wasm/src/shapes.rs @@ -1605,6 +1605,13 @@ impl Shape { .count() } + /// True when the shape has at least one visible inner stroke (open paths render strokes as center). + pub fn has_inner_stroke(&self) -> bool { + let is_open = self.is_open(); + self.visible_strokes() + .any(|s| s.render_kind(is_open) == StrokeKind::Inner) + } + pub fn drop_shadow_paints(&self) -> Vec { let drop_shadows: Vec<&Shadow> = self.drop_shadows_visible().collect();