285 Commits

Author SHA1 Message Date
Alejandro Alonso
b62512e459 Add basic WASM SVG export path
Introduce a minimal vector SVG exporter via render-wasm: solid fills,
native opacity/blend wrappers, frame clip-content, FFI/frontend wiring,
insta snapshots, and a visual preview gallery. Defer save_layer
workarounds (shadows, blur, masks, special strokes) to follow-up PRs.
2026-08-27 07:20:14 +02:00
Alejandro Alonso
7419bc7007
🐛 Evict multi-scale tile cache on shape edits (#11337)
those textures across zoom for progressive previews, and invalidate
by old∪new document coverage so rotate/move edits do not leave
stale fragments on zoom-out.
2026-08-26 08:25:23 +02:00
Alejandro Alonso
5dab689a6e 🐛 Pack tile atlas and clamp HiDPI surfaces under GPU limits
HQ tiles are 512px and the atlas stays at 4096² (64 full-size
slots). Browser zoom plus a forced ?dpr= can need more visible
tiles than that, and a framebuffer larger than the GPU allows.

Pack interest tiles into smaller atlas cells, blit at 512 then
scale, and inset Linear samples so seams do not bleed. Clamp the
canvas backing store and DPR together, wrap Skia at the real
drawingBuffer size, and wait one frame after DPR changes so CSS
client size and overlays stay aligned.
2026-08-21 11:17:16 +02:00
Alejandro Alonso
689d506788 Render eligible frame drop shadows via direct geometry path
Add a direct container-geometry path for eligible frames: inline blur
when the kernel fits the tile margin, otherwise a cached filter-surface
pass reused across tiles via DropShadowFilterCache on both the direct
and slow render_shape paths.

Move frame shadow logic into shadows.rs. Fix nested/clipped frame
shadows by deferring parent clip to composite time, apply negative
spread via inset, and allow rotated/transformed frames on the direct
path. Skip descendant extrect walks for clipped frames when only
nested drop shadows matter, and skip child silhouettes when the
container fill already covers shadow descendants.
2026-08-21 11:17:16 +02:00
Elena Torró
ed588d4500
Disable ReduceOpsTaskSplitting Skia flag (#11280) 2026-08-19 17:27:50 +02:00
Belén Albeza
b6c4cb48d7
🐛 Fix not being able to select right or center-aligned text in v3 (#11258) 2026-08-18 18:13:47 +02:00
Alejandro Alonso
cb57fd9dfa
Skip save_layer for plain image fills (#11230)
Avoid an offscreen buffer per Fill::Image during tile walks: only use
save_layer when a shape image filter is present; axis-aligned rects and
frames without corner radii also skip the redundant container clip.
2026-08-13 12:12:43 +02:00
Alejandro Alonso
43b12bc4b9
Soft-drain GPU mid-walk on progressive Partials (#11127)
Release packs far more cheap Current draws (e.g. fills_none paths)
into one Partial than debug; a single end-of-Partial
flush_and_submit then stalls the browser. Soft-flush every N walker
nodes (and on Partial yield) keeps ops buffers bounded while Full
still submits via present_frame.
2026-08-07 09:45:39 +02:00
Elena Torró
38b990ef90
🔧 Add exporter headless backend (#10875)
*  Add headless wasm render backend to the exporter

* ♻️ Move render-wasm bridge to common and split wasm builds

* 🔧 Upload builtin font variants in the wasm exporter

* ♻️ Move shared font and resources utils out of render_wasm

*  Fetch only the exported roots in the wasm exporter

*  Bound save_layer rects in the vector export path
2026-08-06 16:13:06 +02:00
Alejandro Alonso
a76401596e
Skip imperceptible shadows and simplify low-scale strokes (#11102)
*  Skip drop shadows that are imperceptible at current scale

Filter drop shadows by on-screen footprint (stricter for recursive
shapes) so overview HQ avoids expensive blur passes that barely show.

*  Simplify Path and Bool strokes at low scale

At overview zooms, Inner/Outer strokes fall back to Center and
dash/dotted styles become solid when the pattern is subpixel.
Strokes are never skipped so stroke-only icons stay visible.

*  Drain GPU work on partial render frames

Partial frames only flushed the Backbuffer, so tile GPU commands
queued until present_frame's flush_and_submit and stalled the
browser on large files. Submit the context each partial frame
without presenting Target or re-composing the tile atlas.

*  Prefer direct painting when effects are imperceptible

Skip the Fills/Strokes layered path when drop/inner shadows would
not paint at the current scale, and allow stroke-only shapes
(fills_none) on the direct path. Apply the same footprint LOD to
inner-shadow painting.
2026-08-06 15:58:11 +02:00
Elena Torró
10a2c19f92
🔧 Improve text editor selection and tab conversion (#11071) 2026-08-06 09:43:02 +02:00
Alejandro Alonso
4b413299c2
Clear dirty flags after tile surface reset (#11095)
Marking intermediate surfaces dirty after clearing them on tile
context switch made the first stack composite blit empty
Fills/Strokes/shadows into Current. Dirty means content to
composite, so clear the flags after the clear instead.
2026-08-06 09:09:09 +02:00
Alejandro Alonso
35bdcde183
Avoid per-tile image_snapshot when filling atlases (#11093)
Copy Current into DocAtlas and the tile atlas with Surface::draw
instead of image_snapshot_with_bounds, matching the interactive
path and removing a GPU sync stall on every completed tile.
2026-08-05 17:12:09 +02:00
Elena Torró
0fed63eeb3
🐛 Fix text replacement on selection and text offsets (#10983)
* 🐛 Fix text not being replaced when there is a selection

* 🐛 Fix text editor offsets on transformed text
2026-08-03 15:22:49 +02:00
Elena Torró
a722a33503
🐛 Fix gradients and text selection (#10941)
* 🐛 Add missing text fills

*  Keep text leaf selected while editing
2026-07-30 12:11:53 +02:00
Belén Albeza
704cd40182
🐛 Fix caret not mimicking text color (#10866) 2026-07-28 16:25:47 +02:00
Elena Torró
d4d22ff1a4
🔧 Prepare wasm render for headless exporter (#10795)
* 🔧 Support background blur on PDF render for strokes and text shapes

*  Add LRU eviction to the wasm image store

*  Add RasterFormat to encode png, jpeg and webp from wasm

* 🐛 Fix client-side wasm export encoding jpeg and webp as png
2026-07-28 11:54:22 +02:00
Belén Albeza
4f46700c94
🐛 Fix text editor v3 blinks (#10654) 2026-07-24 09:14:59 +02:00
Elena Torró
4383cf183a
Add background blur to strokes (#10716) 2026-07-22 17:07:16 +02:00
Elena Torró
ef3511e519
Add basic individual strokes implementation (#10648) 2026-07-22 16:13:38 +02:00
Elena Torró
08e42687d1
♻️ Extract GPU-free RenderResources; add headless wasm exports (#10653) 2026-07-22 09:56:21 +02:00
Alejandro Alonso
6c5618025d
Merge pull request #10712 from penpot/elenatorro-10706-apply-background-blur-to-text-shapes
 Add background blur to text shapes
2026-07-21 09:53:01 +02:00
Elena Torró
8d98877ba7
🐛 Fix using SVG image file as shape fill (#10707) 2026-07-20 10:41:07 +02:00
Elena Torro
001dba1bef Add background blur to text shapes 2026-07-16 08:33:36 +02:00
Belén Albeza
2e32a8743e
♻️ Refactor rulers into ui modules (#10461)
* ♻️ Move rulers rendering to ui submodule

* ♻️ Refactor RulerState into UIState
2026-07-03 08:37:22 +02:00
Alejandro Alonso
b82ab0c830 Merge remote-tracking branch 'origin/staging' into develop 2026-07-02 13:52:25 +02:00
Elena Torró
28b5371901
🔧 Improve text strokes in texts with emoji (#10519) 2026-07-01 18:10:46 +02:00
Alejandro Alonso
f25317ac47
🐛 Fix text inner stroke fill seam by compositing fill inside SrcIn (#10509)
* 🐛 Fix text inner stroke fill seam by compositing fill inside SrcIn

* 🔧 Update e2e Playwright screenshots
2026-07-01 16:24:23 +02:00
Belén Albeza
51877c4bca
🐛 Fix text editor cursor being too thin on dpr > 1 (#10501) 2026-07-01 10:43:59 +02:00
Elena Torró
21f646aeee
🐛 Fix decimal rounding and format in WebGL rulers (#10487) 2026-06-30 10:35:03 +02:00
Belén Albeza
d323aa9693
🐛 Fix guides not clipping (#10423) 2026-06-25 11:50:58 +02:00
Elena Torró
149caaf292
🐛 Fix rulers values visibility (#10408) 2026-06-25 07:20:41 +02:00
Alejandro Alonso
9b22d96553 🐛 Fix render from cache 2026-06-24 14:00:57 +02:00
Elena Torró
07de0e92d5
Fix slow zoom/edit on Firefox+NVIDIA WebGL renderer (#10371) 2026-06-23 10:58:14 +02:00
Elena Torró
8e548c8c54
🐛 Fix blank tiles and atlas crash on render-wasm zoom/pan (#10367)
* 🐛 Fix missing tiles on page switch and pan/zoom end

* 🐛 Fix blank tiles and atlas crash on render-wasm zoom/pan
2026-06-23 10:25:45 +02:00
Alejandro Alonso
2a5c29421f
🐛 Cap GPU max texture size at 4096 2026-06-19 09:38:38 +02:00
Alejandro Alonso
f6f716de3a 🐛 Fix performance regression 2026-06-18 18:30:51 +02:00
Alejandro Alonso
61cd9fe886
🐛 Fix performance regression
* 🔧 Preserve atlas on zoom interaction 

Co-authored-by: Elena Torro <elenatorro@gmail.com>
2026-06-17 14:52:12 +02:00
Elena Torro
82cd11a1ad 🐛 Fix DocAtlas cap 2026-06-17 09:52:57 +02:00
Belén Albeza
d1dd5d9016
🎉 Render guides in wasm (#10014)
*  Remove guides from svg overlay

* 🎉 Draw guides in wasm

* 🎉 Serialize guides to wasm

*  Store separate and sorted horizontal and vertical guides

* 🎉 Implement collision detection with guides

* 🎉 Right click on guides to change color or remove

*  Implement dragging guides

* 🎉 Edit wasm guides by double clicking them

* 🎉 Implement changing mouse cursor on hovering a guide

*  Show guide pill on hover

* 🎉 Implement removing guide on hovering + Del

* 🔧 Fix lint + fmt errors

* 🎉 Clip out outer board guide lines

* ♻️ Extract common code into guide-pill* component

* 🎉 Draw dotted lines on hovering board guides

* 🐛 Fix board rotation when it has guides

* 🎉 Make foreign guides not visible in focus mode
2026-06-16 09:19:58 +02:00
Elena Torró
6ebefa2c16
Add single-file export to PDF using the WebGL render (#9860) 2026-06-11 10:41:21 +02:00
Alejandro Alonso
9f5e89d5f8 🎉 Basic viewer with wasm 2026-06-05 16:41:30 +02:00
Elena Torró
60d3c81450
Add wasm rulers (#9858)
*  Add wasm rulers

* 🔧 Fix dpr on page zoom

Co-authored-by: Alejandro Alonso <alejandroalonsofernandez@gmail.com>
Co-authored-by: Elena Torro <elenatorro@gmail.com>

* 🔧 Change page-switch behavior to refresh rulers and keep blurred snapshot

* 🐛 Restore WASM rulers after WebGL context recovery

Co-Authored-By: Elena Torro <elenatorro@gmail.com>
Co-Authored-By: Alejandro Alonso <alejandroalonsofernandez@gmail.com>

---------

Co-authored-by: Alejandro Alonso <alejandroalonsofernandez@gmail.com>
2026-06-05 07:51:35 +02:00
Andrey Antukh
7ddc93a4df Merge remote-tracking branch 'origin/staging' into develop 2026-06-03 14:19:47 +02:00
Elena Torró
0fe4337359
🐛 Fix webgl thumbnail label (#10009) 2026-06-03 14:06:05 +02:00
Aitor Moreno
ff3587ca2d
Merge pull request #9997 from penpot/elenatorro-fix-background-clear
🐛 Fix clear canvas
2026-06-03 12:02:48 +02:00
Andrey Antukh
feca7cef41 Merge remote-tracking branch 'origin/staging' into develop 2026-06-02 17:50:45 +02:00
Elena Torro
d9fea603f8 🐛 Fix clear canvas 2026-06-02 17:14:25 +02:00
Belén Albeza
d5fe5f82f3
🐛 Fix wasm info label positioning (#9981) 2026-06-02 15:18:37 +02:00
Aitor Moreno
d0f6d5b3a1
♻️ Refactor render pipeline (#9891)
* ♻️ Refactor viewbox

* 🎉 Add draw_atlas alternative to draw tiles

* 🐛 Fix minor glitches

* ♻️ Change how process_animation_frame works

* ♻️ Refactor document atlas

* ♻️ Refactor max texture size

* ♻️ Refactor entrypoints and dead_code
2026-06-02 09:38:52 +02:00