64 Commits

Author SHA1 Message Date
alonso.torres
e66e507002 ✨ Add Chinese emphasis and underline positions
Carry optional span positions through the schema, WASM header, editor,
Plugin API and CSS output. Expose Chinese controls with language defaults
and independent overrides for horizontal and vertical text.

Reserve automatic clearance per side and stack underlines, ruby and
emphasis. Preserve reading groups during decoration edits and retain
canonical position values in DOM editor style data.

Add protocol, geometry, editing and API tests, including the prior Japanese
mixed-font gutter behavior. Verify both WASM targets and live exports.

AI-assisted-by: GPT-6
2026-11-03 17:36:40 +01:00
alonso.torres
2eb1fe946a ✨ Add a CJK text layout proof of concept
Choose paragraph layout rules from an optional language tag. Pass language
to horizontal and vertical shaping, add basic Chinese punctuation rules,
and add experimental Korean spaces-only wrapping.

Keep text boundaries grapheme-safe and preserve paragraph profiles across
editor splits and merges. Add reproducible font fixtures for localized
glyphs and regression tests for the shared WASM protocol and layout paths.

Validation: renderer, common JVM/JS, frontend and exporter tests pass.
Both WASM targets build. Full CI still reports baseline lint and format
errors and one backend multipart-upload test failure.

AI-assisted-by: GPT-6
2026-11-03 17:36:40 +01:00
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ó
0913545b41
🐛 Fix letter spacing and position when flattening text to path (#11555)
* 🐛 Fix letter spacing and position when flattening text to path

* ♻️ Simplify text to path conversion and add flatten tests
2026-09-11 08:20:22 +02:00
Alejandro Alonso
aa78ca0be8
🐛 Keep text image fills aligned during drag (#11610)
Cached Skia paragraphs bake absolute image/gradient shaders at layout
time. On move, clones reuse those paragraphs while painting at the new
selrect, so glyphs move and the fill stays put. Record the paint origin
when layout is built and translate the canvas when painting from cache
so shaders track the text. Also sync bounds before update_layout so
fills bake against the current container.
2026-09-10 16:55:45 +02:00
Elena Torró
9b24907992
🐛 Fix render text-decoration on spans and update regression tests (#11583) 2026-09-10 09:42:09 +02:00
Alejandro Alonso
2e5157e6aa
✨ Export image fills to WASM SVG as linked images (#11529)
Emit clipped `<image href>` for fills with a registered media URL instead
of Skia base64 embeds. Register URLs from the frontend and exporter via
store_image_url. Cover rect, path, frame, and text (glyph clip) cases in
SVG export tests.

Closes #11383
2026-09-08 17:30:53 +02:00
Alejandro Alonso
c5897bc50a
⚡ Paint plain text directly onto Current (#11355)
* ♻️ Share text layout paragraphs across modifier clones

Store Skia paragraphs in Rc so TextContentLayout::clone keeps the
cached layout for rotate/pan modifiers. Add layout.clear() and treat
needs_update as paragraphs-empty only.

* ⚡ Reuse cached Skia paragraphs when painting text

Add try_paint_from_layout_cache to paint from TextContent.layout when
versions match, skipping ParagraphBuilder rebuild and layout on each
frame. Wire into the layered text path for plain fills without strokes
or effects.

* ⚡ Paint plain text directly onto Current

Extend can_render_directly for stroke-free text and skip the empty
save_layer in draw_text when no stroke-group opacity is set. Plain text
paints into Current without the Fills/Strokes blit.
2026-09-02 16:17:06 +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
d1a54134bb
✨ Add text and @font-face to WASM SVG export (#11442)
* ✨ Add text and @font-face to WASM SVG export

Emit selectable <text> elements and inject @font-face rules that
reference the font URLs registered at load time. Text fill bypasses
save_layer wrappers that SkSVGDevice drops. Text strokes are deferred
to a follow-up PR.

* 🐛 Strip trailing commas from Skia SVG text positions

Skia's SVG backend appends a trailing comma to per-glyph x/y lists.
Firefox rejects the malformed attribute and drops glyph positioning,
making exported text vanish or mis-render.
2026-09-01 17:06:50 +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ó
10a2c19f92
🔧 Improve text editor selection and tab conversion (#11071) 2026-08-06 09:43:02 +02:00
Elena Torró
4383cf183a
✨ Add background blur to strokes (#10716) 2026-07-22 17:07:16 +02:00
Elena Torro
001dba1bef ✨ Add background blur to text shapes 2026-07-16 08:33:36 +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
Elena Torró
6ebefa2c16
✨ Add single-file export to PDF using the WebGL render (#9860) 2026-06-11 10:41:21 +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
Elena Torro
68760c8e26 🎉 Improve text inner stroke rendering 2026-04-02 12:00:08 +02:00
Elena Torro
e630be1509 🎉 Add background blur for wasm render 2026-03-18 18:05:30 +01:00
Alejandro Alonso
024f779cab 🐛 Fix text stroke opacity causing different colors on overlapping glyphs 2026-03-10 12:36:53 +01:00
Alejandro Alonso
e2b5f936f5 🐛 Fix stroke artifacts 2026-02-25 11:27:05 +01:00
Alejandro Alonso
0dda7bd9ee 🐛 Fix text stroke bounds 2026-02-17 12:25:32 +01:00
Alejandro Alonso
ee766e85a0 🎉 Wasm render dirty surfaces 2026-01-14 11:10:03 +01:00
alonso.torres
ea4d0e1238 ✨ Calculate position data in wasm 2025-12-11 16:00:03 +01:00
Elena Torro
2c3732f3f4 🔧 Fix line height calculation 2025-12-10 10:59:27 +01:00
Alejandro Alonso
24745bed40 🐛 Fix shadows and blurs for high levels of zoom 2025-11-20 11:25:23 +01:00
Elena Torro
127fa931c7 🐛 Fix new lines spacing between paragraphs 2025-11-14 12:00:39 +01:00
Belén Albeza
d048a251f1 🐛 Fix render of text baseline (wasm) 2025-11-12 14:59:57 +01:00
Elena Torro
b76bfa2197 🐛 Fix width on rotation 2025-11-03 16:37:17 +01:00
Belén Albeza
4ab6ecec21 🔧 Fix rust linter errors 2025-11-03 10:43:35 +01:00
Elena Torro
9dfb0ebe84 🐛 Fix default font size in text spans 2025-10-29 17:23:29 +01:00
Elena Torro
2c37c5c8ed 🔧 Add support for text spans of different sizes 2025-10-27 12:43:41 +01:00
Aitor Moreno
247c5c3700
Merge pull request #7588 from penpot/elenatorro-fix-text-tests
🔧 Fix text align selrect
2025-10-23 15:04:48 +02:00
Aitor Moreno
eb088c31c1 🔧 Rename textleafs and inlines to keep coherence between render and editor 2025-10-23 13:04:21 +02:00
Elena Torro
a30315c91c 🔧 Fix text align selrect and update regression tests 2025-10-23 11:44:40 +02:00
Elena Torró
140290cd60
Merge pull request #7556 from penpot/ladybenko-12362-fix-underline-spacing
🐛 Fix underline not matching spacing/thickness
2025-10-22 10:21:48 +02:00
Belén Albeza
87221eb7db 🐛 Fix underline not matching spacing/thickness 2025-10-21 16:57:02 +02:00
Elena Torro
dc689f9756 🐛 Fix texts offset-y calculation when there are multiple lines and stroke paints 2025-10-21 16:13:40 +02:00
Elena Torro
a51fd009bc 🔧 Improve text tiles intersection on changes 2025-10-21 13:21:02 +02:00
Aitor Moreno
7ca8bf32b2 🎉 Set DOM text editor element caret 2025-10-16 12:59:24 +02:00
Aitor Moreno
732c79b7b5 🎉 Add function to retrieve caret position 2025-10-01 09:18:46 +02:00
Aitor Moreno
f505fcfa0d 🎉 Add internal TextContent layout data 2025-09-22 16:01:23 +02:00
Elena Torro
4bd2eba573 🐛 Fix text shadows and blur and refactor text rendering 2025-09-10 14:20:24 +02:00
Belén Albeza
50b9e8c6e6 ♻️ Rename TextContent::get_width to TextContent::width 2025-09-02 15:07:13 +02:00
Elena Torró
5f37601122
🐛 Fix different fonts on texts shadows (#7214)
* 🐛 Fix different fonts on texts shadows

* 🔧 Refactor text rendering and move text-decoration logic outside

* 🔧 Use transparency correctly
2025-09-02 12:56:07 +02:00
Elena Torro
025423a75e 🐛 Fix line height on texts and improve text decoration rendering 2025-08-28 12:40:23 +02:00
Elena Torro
46b3e174ed 🐛 Fix paragraph layout width on autowidth 2025-08-22 13:55:24 +02:00
Elena Torro
82d2889e96 🔧 Improve text strokes blending 2025-08-13 11:50:09 +02:00
Alejandro Alonso
e473f45048 🐛 Fix visible 0 width strokes in wasm render 2025-07-28 08:46:47 +02:00