Differences between PNG and SVG outputs, for unicode char with size

+1 vote
asked Dec 2, 2020 in Bug by The-Lu (63,920 points)

Hello PlantUML,

We observe (on current version V1.2020.21) a difference between PNG and SVG outputs, about Unicode char, when we change the size.

@startuml
test: text <U+1F610>
test_size25: text <size:25><U+1F610>
test_size75: text <size:75><U+1F610>
test_size100: text <size:100><U+1F610>
@enduml

Displays correctly in PNG (the face is proportional):

but not in SVG (the face is compressed like an anamorphosis):

Hints or causes: https://forum.plantuml.net/3182/differently-produced-building-different-platforms-consistent?show=3183#a3183

Thank for your support,
Regards,
Th.

1 Answer

0 votes
answered Dec 4, 2020 by plantuml (294,960 points)
selected Dec 5, 2020 by The-Lu
 
Best answer

The situation is complex and this issue is related to
https://forum.plantuml.net/3182/differently-produced-building-different-platforms-consistent

We are first going to explain you why we cannot fix this issue.
Then we are going to propose you a workaround :-)

To fully understand this issue, you should know more about text rendering is done on SVG.
For regular geometric elements (that is line, circle, box...), the full characteristics of the elements are
encoded in the SVG file. So position and size are clearly specified in the SVG, with no possible ambiguity.
For text, it's somehow different because you specify in the SVG the font to be used and the position of the text.
But you don't specify the precise length of the text in pixels.

So the text rendering completely depends on the fonts available on the system that displays the SVG file.

It's a big issue because when the SVG file is generated be PlantUML, there is absolutely no way of knowing what will the actual size used by this text.
And by the way, there is no unique answer for this size: it really depends on the future SVG reader that will be used.

It's really an issue because PlantUML needs to know the real precise space. It need this information to be able to draw the box around the text and to position this box exactly in the picture.

So here PlantUML makes a wild guess (which is always wrong): it supposes that the text will take the very same space as if it were generated for a PNG image.
Fortunately, there are a "textLength" setting in the <text> element to enforce the SVG reader to use the space specified by PlantUML, along with a "lengthAdjust" attribute set to "spacingAndGlyphs". This way, the SVG reader renders the text with the space expected by PlantUML, but at a price of an anamorphic change on glyphs.

Usually, it gives good result, but not always, like in your example.

Once again, it's impossible to solve because there is absolutely no way for PlantUML to know exactly how <U+1F610>
will be rendered in SVG. (In PNG, this is completely different because we know which size <U+1F610> will be: we compute
it before positioning elements. In that case we know exactly which font is going to be used.).


So now, the workaround :-)

Since we agree that is this an issue, so we propose you a hack for this:

!pragma svgSize <U+1F610> XX

This directive tells to PlantUML: "assume that the size of <U+1F610> is the same as 'XX' "

You can play with this directive:

!pragma svgSize <U+1F610> XX
or
!pragma svgSize <U+1F610> I

to find the best setting for you.

As I said, this is really an hack. We think this is acceptable. You tell us !
And if anyone has a better solution, please post it here !

Thanks

commented Dec 5, 2020 by The-Lu (63,920 points)

Hello PlantUML team,

Without comment: It's perfect wink
Especially with the clear explanation of the text management on SVG output.

Now remains to make a large configuration file with all the Emoji...

Regards,
Th.

commented Dec 6, 2020 by Martin
Sorry if this is a naive idea, but could PlantUML, for each piece of text, generate a tiny SVG containing just the text, render it using a standard SVG engine and work out the size and then fit that into the full picture?  (Caveat: It sounds like an SVG could render differently on different machines based on fonts installed; but at least the SVG would render perfectly on the machine that generated it).  Just curious if this is a viable option.
...