rism-digital / verovio

🎵 Music notation engraving library for MEI with MusicXML and Humdrum support and various toolkits (JavaScript, Python)
https://www.verovio.org
GNU Lesser General Public License v3.0
687 stars 185 forks source link

Symbol clipped in SharpVectors renderer #3670

Open raiatea opened 6 months ago

raiatea commented 6 months ago

Describe the problem SVG output rendered with SharpVectors, symbols appear clipped

To Reproduce Steps to reproduce the behavior:

  1. Load accid-001.mei from the tests
  2. Convert it to accid-001.svg
  3. Render with SharpVectors WPF SVG TestBox

Expected behavior Shapes of the symbols complete

Input data The smallest example to reproduce the problem

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="2100px" height="2970px" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:mei="http://www.music-encoding.org/ns/mei" overflow="visible">
   <desc>Engraved by Verovio 4.1.0[undefined]</desc>
   <defs>
      <symbol id="E0A4-1hmocrk" viewBox="0 0 1000 1000" overflow="inherit">
         <path transform="scale(1,-1)" d="M0 -39c0 68 73 172 200 172 c66 0 114 -37 114 -95 c0 -84 -106 -171 -218 -171  c-64 0 -96 30 -96 94z" />
      </symbol>
   </defs>
   <svg class="definition-scale" color="black" viewBox="0 0 21000 29700">
      <use xlink:href="#E0A4-1hmocrk" x="1283" y="1553" height="720px" width="720px" />
   </svg>
</svg>

Verovio information See the header of SVG

Environment information (as appropriate)

Screenshots SharpVectors rendering SharpVectors

Any online browser rendering Webbrowser

Additional context It seems that the SVG viewBox declaration in <symbol id="E0A4-1hmocrk" viewBox="0 0 1000 1000" overflow="inherit"> is interpreted by SharpVectors as an instruction to clip the rendering. But the path of a symbol goes in the negative Ys, outside of the viewBox, and is clipped. If viewBox is set to "0 -200 1000 1000" for example, the full shape reappears

Is the viewBox generated by Verovio correct ?

craigsapp commented 6 months ago

This has happened before (or something similar), so there is probably an old issue for this (but I cannot find it at the moment).

rettinghaus commented 6 months ago

It is probably connected to the handling of the overflow attribute set on symbol level.
See #2380 and https://github.com/Kozea/CairoSVG/issues/300 for possible solutions to fix.

craigsapp commented 6 months ago

Yes, I am pretty sure that is what I was thinking of.

raiatea commented 6 months ago

The header of Verovio SVG ouput has overflow set to visible. <svg ... overflow="visible"> <symbol ... viewBox="0 0 1000 1000" overflow="inherit">

I tried with overflow=visible for each element, without effect.

Documentation overflow at mozilla.org

This feature is not widely implemented yet. If it has a value of visible, the attribute has no effect (i.e., a clipping rectangle is not created).

Even the example at Mozilla clips when overflow=visible, in their interactive rendering playground.

I see two possible issues:

  1. SharpVectors: the attribute should have no effect when overflow=visible.

Although the documentation is quoted in the source code before the code concerned with overflow, I'm not sure the attribute is effective. Obviously it doesn't support well SMuFL.

  1. SMufl: the paths of the symbols should not exceed the boundaries of their viewBox.

For example the definitions of the glyph E0A4, in Leipzig.xml <g c="E0A4" x="0.0" y="-133.0" w="314.0" h="266.0" h-a-x="314" n="noteheadBlack"> the bounding box is largely in the negatives.

In E0A4.xml, <symbol id="E0A4" viewBox="0 0 1000 1000" overflow="inherit"><path transform="scale(1,-1)" d="M0 -39c0 68 73 172 200 172c66 0 114 -37 114 -95c0 -84 -106 -171 -218 -171c-64 0 -96 30 -96 94z" /></symbol> the viewBox is not fitted and only in the positives.

The viewBox can only clip the path. The same happens for all the fonts.

craigsapp commented 6 months ago

Here is some CSS code that I use on VHV, probably related to this problem:

svg:not(:root) {
        overflow: inherit;
}

This implies that probably the <symbol> is not necessarily the only element to add the overflow inheriting, and the entire tree strucure of the SVG needs it as well. In other words the tree structure from the root to the location where the symbol is used, probably needs overflow inherit. (otherwise, the symbol is probably inheriting from the location where it is being used.)

raiatea commented 6 months ago

Inspecting the Leipzig font with FontForge, it appears the glyph origin is just where the path is clipped.

FontForge

I'm investigating the issue with the renderer SharpVectors.

rettinghaus commented 6 months ago

I'm working on a solution in #3673.

lpugin commented 2 months ago

@rettinghaus are you still working on this?

rettinghaus commented 2 months ago

@lpugin basically yes, but hadn't had the time recently. Will pick it up again later.