Repository navigation
SVG import: <textPath> comes back as type on a path - #6
Merged
Merged
Conversation
VectorCraft exports type on a path as <text><textPath href="#text-path-N" startOffset="…%"> with the path in <defs>, but the XML text fallback read every <text> as point type at the text element's x/y. Text on a path therefore re-imported as a straight line at (0, 0), above the artboard and mostly out of view, and lost its path. Resolve the textPath's href (SVG 2 href or xlink:href) to the <path>, bake the text's user-space transform (and the path's own transform) into it, and read startOffset (a percentage, or a length along the path) into TextKind::OnPath. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Member
|
Thanks @storybored379, merged! Type on a path now survives an SVG round trip. Handling both If you're not already there, come say hi in our Discord, we'd love to have you: https://discord.gg/artcraft |
apexmiguel9-hub
pushed a commit
to apexmiguel9-hub/vectorcraft-android
that referenced
this pull request
Oct 6, 2026
…lar shaders
MEDIDO, con la cadena de 35 frames del tombstone. Se lee de abajo arriba:
storytold#15 egui_wgpu::Painter::set_window
storytold#14 egui_wgpu::renderer::Renderer::new
storytold#13 wgpu_core::...::CoreDevice::<dispatch>::DeviceInterface::create_render_pipeline
storytold#12 wgpu_core::device::global::Global::device_create_render_pipeline
storytold#11 wgpu_core::device::global::Global::device_create_general_render_pipeline
storytold#10 wgpu_core::device::resource::Device::create_render_pipeline
storytold#9 wgpu_core::device::resource::Device::create_render_pipeline_inner
storytold#8 wgpu_hal::dynamic::device::vulkan::DynDevice::create_render_pipeline
storytold#7 wgpu_hal::vulkan::device::Device::create_render_pipeline
storytold#6 vulkan.mtk.so (FragmentShaderCompileState::CompileUF()+1272)
storytold#4 vulkan.mtk.so
storytold#3 libufwriter.so (BILParseStream+164)
#00 libc.so (abort+156)
**Los seis frames interiores no son de Rust, son del driver.** `egui_wgpu` pide su
primer pipeline, `wgpu` lo pasa a Vulkan, y `vulkan.mtk.so` aborta mientras compila
el fragment shader, dentro de `libufwriter.so` — el escritor de binarios del
compilador propietario, porque `BIL` es su IR.
## Y no es que a Vulkan le falte nada
Es lo que mas confunde, y conviene dejarlo escrito con numeros. Del perfil
`vp_gpuinfo` del Moto G56 5G (Android 16) y del informe de la base de datos de
Sascha Willems:
| | |
|---|---|
| `apiVersion` | **1.3.1023** (la base de datos lo da como 1.3.303) |
| extensiones | **129**, 61 de ellas `VK_KHR` |
| `VK_ANDROID_external_memory_android_hardware_buffer` | si |
| `driverID` | `VK_DRIVER_ID_IMAGINATION_PROPRIETARY`, PowerVR B-Series 25.1 |
| subgroup | 128, todas las operaciones |
| todas las versiones core 1.0-1.3 | soportadas |
O sea: **no falta ninguna feature, es un driver que conforms pero aborta.** Ni
siquiera hay mensaje: `PVR_ASSERT` viene compilado en release y es un `abort()` a
peloso, asi que el logcat no dice que construccion del SPIR-V le molesta. No hay
forma de averiguarlo desde aqui.
## Por que OpenGL no cuesta nada
Porque VectorCraft **rasteriza en CPU** con `vello_cpu`. La GPU solo presenta
pixeles que ya estan pintados. Toda la parte de Vulkan que de verdad importa —
compute shaders, para rasterizar en GPU— es justo la que este proyecto no usa, y lo
hizo a proposito para no depender del driver. Aqui el coste de GL es cero.
## Como queda
Una funcion, `wgpu_solo_opengl()`, que parte de
`WgpuSetupCreateNew::without_display_handle()` y cambia `instance_descriptor.backends`
a `Backends::GL`. Se escribe asi, modificando el campo, y no con sintaxis de
actualizacion de structs, porque no depende de que campos existan los que no se
nombran.
`eframe` reexporta `egui_wgpu` y `egui_wgpu::wgpu` (su `lib.rs:162`), asi que no
hacen falta dependencias nuevas.
**Queda anotado como una linea si el driver deja de abortar**, y el propio egui-wgpu
tiene ademas el interruptor `WGPU_BACKEND=opengl` para probarlo sin recompilar.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
VectorCraft exports type on a path as
<text><textPath href="#text-path-N" startOffset="…%">with thepath in
<defs>, but the XML text fallback read every<text>as point type at the text element'sx/y. Text on a path therefore re-imported from VectorCraft's own SVG as a straight line of point type
at (0, 0), above the artboard and mostly out of view, and lost its path.
What changed
crates/svg/src/import.rs: a<textPath>child resolves itshref(SVG 2hreforxlink:href) to thereferenced
<path>, bakes the text's user-space transform (and the path's owntransform) into it, andreads
startOffset(a percentage, or a length along the path) intoTextKind::OnPath.How it was found and tested
vectorcraft-cli mcp --headless): type on a path → export SVG → open_file.text_on_path_roundtrip(crates/svg/tests/roundtrip.rs): exports type on a curve, imports it and checkskind, text, start offset and the path's placement. Verified it fails on current
mainwithout the change(
not type on a path: Point) and passes with it.cargo test -p vectorcraft-svg,cargo clippy -p vectorcraft-svg --all-targets(no new warnings),cargo fmt --check,cargo xtask layers,cargo xtask wasmon currentmain.crates/svg/src/import.rs,crates/svg/src/lib.rs,crates/svg/tests/roundtrip.rstextPathspecification only.Found and fixed with Claude Code (AI-assisted).
🤖 Generated with Claude Code