20 Commits

Author SHA1 Message Date
alonso.torres
a641cbab5d ✨ Render Japanese text layouts in WASM
Lay out horizontal and vertical Japanese text with kinsoku, ruby,
emphasis, warichu, tate-chu-yoko and proportional font features.
Carry the layout through glyph paths, SVG export and text selection.

Update the Rust and ClojureScript binary formats together, including
the editor bridge and headless exporter. Resolve CJK fallback fonts
and add renderer tests and font fixtures.
2026-11-03 17:36:40 +01:00
Elena Torró
b48d163f5f
⚡ Fix slow drop shadow spread in CPU exports (#12718)
* ⚡ Fix slow drop shadow spread in CPU exports

* 🐛 Fix text opacity in board drop shadows on CPU exports
2026-10-29 18:27:19 +01:00
Belén Albeza
ef68304cb8
🐛 Draw masked group inner shadows in PDF and multi-element export (#12468)
* 🐛 Fix render_to_pdf call in the ToUnicode test

The test passed a scale argument that render_to_pdf does not take, so
the render-wasm test build failed to compile.


* 🐛 Draw masked group inner shadows in PDF and multi-element export

The CPU renderer behind PDF and multi-element raster export drew a
masked group's drop shadow but never its inner shadow, so the masked
content came out flat. Wrap the masked content in a layer that draws
the inner shadows over it, as the GPU single export does.


* 🐛 Export every visible inner shadow of a masked group

The workspace skips shadows too small to see at the current zoom, to
render faster. Export has no such need, so draw every visible inner
shadow instead of filtering by scale.
2026-10-20 15:04:54 +02:00
Elena Torró
0801674af2
🐛 Ignore export scale in render-wasm PDF export (#12447) 2026-10-19 18:21:02 +02:00
Elena Torró
c401151541
🐛 Fix mask group drop shadow in PDF export (#12362) 2026-10-19 12:07:51 +02:00
Elena Torró
b3a62eeb4b
🐛 Paint layout children in canvas z-order in vector exports (#12171) 2026-10-08 09:07:33 +02:00
Elena Torró
c44484a1e5
🐛 Fix SVG filter shadows and inherited group fills in render-wasm: (#11925)
* 🐛 Fix shadows derived from imported SVG filters

* 🐛 Fix inherited group fills in exports and group drop shadows

* 🔧 Run exporter tests on render-wasm changes
2026-09-28 07:29:25 +02:00
Belén Albeza
a34b4011cf
🎉 Render different stroke styles per side (#11883)
* 🎉 Render different stroke styles per side

* 🔧 Stabilise per-side stroke snapshots against clip id churn

SVG clip ids come from a counter that lives for the whole test
process, so a snapshot holding one depends on how many clips other
tests emitted first. The masked-group export tests that landed on
develop shifted that count and broke two per-side snapshots, whose
only diff was the id.

Route the remaining per-side snapshots through with_stable_clip_ids,
which renumbers ids in order of appearance. No snapshot in the suite
now carries a generated id.

AI-assisted-by: claude-opus-5
2026-09-24 13:20:33 +02:00
Shreyash
76e9289fcf
🐛 Fix stroke to path dropping caps and markers (#11614)
* 🐛 Fix stroke to path dropping caps and markers

Caps and markers (round ends, arrows, square/diamond/circle markers) are
painted separately by `handle_stroke_caps` after the stroke itself, so
`stroke_to_path` — which only outlines the shape path — dropped them.
Converting a stroke to a path lost every end decoration except the
Round/Round and Square/Square pairs Skia draws natively, and even those
were missing because the outline paint kept the default butt cap.

Cap geometry now lives in `shapes/stroke_paths.rs` as plain path
builders, shared by the canvas renderer and by `stroke_to_path`, which
unions the caps into the outline for open paths and honors
`to_skia_linecap`. The SVG export no longer overlays the caps a second
time on top of the expanded outline, which would double the alpha of
translucent strokes; the clip silhouette for image strokes gets them
from the outline too.

Co-authored-by: Shreyash Agare <agareshreyash26@gmail.com>
2026-09-16 12:46:00 +02:00
Alejandro Alonso
dbe5941a23
✨ Export layer blur to WASM SVG (#11580)
SkSVGDevice drops paint image-filters, so re-emit visible layer blur as a
native feGaussianBlur filter on the composite <g>. Match canvas sigma via
radius_to_sigma(value * scale), and skip Skia blur filters on the SVG
VectorRenderer path so shapes do not vanish.

Closes #11380
2026-09-10 14:25:47 +02:00
Alejandro Alonso
dc12f1db91
✨ Export image-filled strokes to WASM SVG as linked images (#11559)
Closes #11384

Skia's SVG backend drops save_layer+SrcIn, so image strokes are re-emitted
as a linked <image> clipped to an opaque stroke silhouette (filled outline,
clip-rule evenodd). Open-path caps join the silhouette and grow the image
dest by cap_bounds_margin so markers stay textured.
2026-09-10 13:29:14 +02:00
Elena Torró
61caefbcf3
🔧 Support independent image bounds on wasm export (#11590) 2026-09-09 18:27:22 +02:00
Alejandro Alonso
269aa36f82
✨ Export solid and patterned strokes to WASM SVG (#11513)
* ✨ Export solid inner and outer strokes to WASM SVG

SkSVGDevice drops save_layer+Clear used for path Outer strokes, so
solid Inner/Outer strokes on closed shapes are expanded to filled
outlines via stroke_to_path. Center and open paths stay on the shared
stroke path.

Closes #11381

* ✨ Export dotted, dashed, and mixed strokes to WASM SVG

PathEffects do not survive SkSVGDevice, so dotted/dashed/mixed strokes
expand via stroke_to_path with the effect kept, producing filled
outline geometry for all alignments including Center.

Closes #11382

* 🐛 Fix WASM SVG stroke export edge cases

Keep expanded stroke outlines in local space under the leaf CTM so
rotated rects/paths are not double-transformed; overlay open-path caps
after dotted expansion; draw frame strokes outside the content clip;
and route per-side rect/frame strokes through the evenodd band path.
2026-09-07 13:50:58 +02:00
Alejandro Alonso
b92112da54
🐛 Export multiple solid fills to WASM SVG (#11467)
Shapes and text with stacked solid fills were exported without fill
attributes because merge_fills builds a Skia shader that SkSVGDevice
does not serialize. Draw each fill layer separately for SVG export,
bottom to top, matching the classic exporter.

Closes #11466
2026-09-02 13:40:05 +02:00
Alejandro Alonso
89a17df403
✨ Add basic WASM SVG export path (#10891)
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-31 16:06:38 +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
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
Elena Torró
08e42687d1
♻️ Extract GPU-free RenderResources; add headless wasm exports (#10653) 2026-07-22 09:56:21 +02:00
Elena Torró
28b5371901
🔧 Improve text strokes in texts with emoji (#10519) 2026-07-01 18:10:46 +02:00
Elena Torró
6ebefa2c16
✨ Add single-file export to PDF using the WebGL render (#9860) 2026-06-11 10:41:21 +02:00