resvg
resvg copied to clipboard
Incorrect dx/dy handling for RTL scripts
basically the title, the font is rendering ok but the positioning is completely off, here is how it looks when I open the svg in chrome
and this is how it renders with resvg
the relevant svg code is this
<text
filter="url(#textShadow-uy58f0o68)"
x="541"
y="1012"
font-family="BA Ziporen Plus Bold"
font-size="38"
fill="#b09554"
alignment-baseline="hanging"
text-anchor="middle"
transform="rotate(0 541 1024.8)"
>
<tspan
dy="0"
x="541"
text-anchor="middle"
letter-spacing="0.2em"
alignment-baseline="hanging"
>
מושי & חני
</tspan>
,
<tspan
dy="0.9em"
x="541"
text-anchor="middle"
letter-spacing="0.2em"
alignment-baseline="hanging"
>
גרינבוים
</tspan>
</text>
as i am looking at it now maybe the issue is the multiline, because it doesn't happen to other elements only to the multiline ones, so maybe the em syntax is not supported?
Will take a look. You have a very complicated text element. Hard to say.
But we do support all those properties. Including em
units.
It feels like dy
is handled incorrectly here.
Here is how your file is rendered using other libraries.
As you can see - it's a mess.
The first rule of SVG - never use text.
Looks like I have to invert characters positions on RTL layout as well. No idea how to do this. RTL is hard.
For now, you can simply use y
instead of dy
.
I would also suggest using separate text
for each line. tspan
support is extremely tricky and you will never get expected/reproducible results.
Sometimes it also doesn't apply the font family properly to the first tspan, so if I switch everything to use regular text instead of tspan I should get better results? also why would y
instead of dy
solve anything? I am asking because I am curious
Thanks for this wonderful library, my entire project is based on this and it's been a pleasure working with it
also why would
y
instead ofdy
solve anything?
Because they are handled in different ways. dx/dy
introduces a shift to the current baseline, which resvg
incorrectly applies only to the last character, because of RTL. But y
defines a new baseline, so it's fine.
In your case, you do have two text
elements. When a tspan
has x
or y
, it is treated as a new text chunk, which is essentially a new text
element. dx
and dy
do not.
Sometimes it also doesn't apply the font family properly to the first tspan
Probably because of RTL. Everything have to be properly inverted in the text layout. It's hard.
Also, remember that text-anchor
has no effect on tspan
without x
or y
. You can try googling about SVG text chunks for more details. It's a very advance and poorly documented topic and most SVG users are not aware of it.
Use text-anchor
only on text
if you want reproducible results.
so if I switch everything to use regular text instead of tspan I should get better results?
Yes. Not perfect, but better. Look at Safari on my screenshot - it even able to mess up lines order.
If you want reproducible results - use text
just for a single line. I.e. never use x
,y
,dx
and dy
on tspan
.
Use tspan
only for styling, not positioning.
Also, never use whitespaces. I.e. prefer
<text>a <tspan>b </tspan>c</text>
to
<text>
a
<tspan>
b
</tspan>
c
</text>
resvg and chrome are fine, but other libraries would struggle in this case. Yes, including Firefox and Safari. Especially Safari.
Thanks, that was really helpful, I refactored my entire application to never use tspan and I think it's working fine, I need to wait for feedback from my team but it looks ok