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
678 stars 185 forks source link

detached slurs [regression] #2770

Closed frakel closed 2 years ago

frakel commented 2 years ago

From 3.7 onwards Verovio renders slurs in certain contexts apparently worse than previous versions. Here is an example from Mozart K.475 m.144.146:

475_m144_detached-slurs_compare

Click here for the MEI code:

```xml K475 m.144.146 slur regression dime/fk

f f
```

Thank you for fixing this.

craigsapp commented 2 years ago

Potentially related to issue https://github.com/rism-digital/verovio/issues/2621

craigsapp commented 2 years ago

Here is a related example, which has the additional complication of a tuplet number:

Screen Shot 2022-04-06 at 8 07 36 AM
Click to view MEI data for above example ```xml </titleStmt> <pubStmt /> </fileDesc> <encodingDesc> <appInfo> <application isodate="2022-04-06T08:07:39" version="3.10.0-dev-4a1d799"> <name>Verovio</name> <p>Transcoded from Humdrum</p> </application> </appInfo> </encodingDesc> <workList> <work> <title /> </work> </workList> </meiHead> <music> <body> <mdiv xml:id="mez1h9d"> <score xml:id="scmx4fl"> <scoreDef xml:id="szcm13x" midi.bpm="180.000000"> <staffGrp xml:id="sny7vz3" bar.thru="true" symbol="brace"> <staffDef xml:id="s6b9drs" n="1" lines="5"> <clef xml:id="clef-L3F2" shape="G" line="2" /> <keySig xml:id="keysig-L4F2" pname="c" mode="minor" sig="3f" /> <meterSig xml:id="metersig-L6F2" count="4" sym="common" unit="4" /> </staffDef> <staffDef xml:id="sn0836z" n="2" lines="5"> <clef xml:id="clef-L3F1" shape="F" line="4" /> <keySig xml:id="keysig-L4F1" pname="c" mode="minor" sig="3f" /> <meterSig xml:id="metersig-L6F1" count="4" sym="common" unit="4" /> </staffDef> </staffGrp> </scoreDef> <section xml:id="section-L1F1"> <measure xml:id="measure-L1" n="176"> <staff xml:id="sfk5wzb" n="1"> <layer xml:id="layer-L1F2N1" n="1"> <tuplet xml:id="tuplet-L13F2-L15F2" num="3" numbase="2" bracket.place="above" bracket.visible="false" num.format="count"> <rest xml:id="rest-L13F2" dur="8" /> <beam xml:id="beam-L14F2-L15F2"> <note xml:id="note-L14F2" dur="8" oct="5" pname="c" accid.ges="n" /> <note xml:id="note-L15F2" dur="8" oct="6" pname="c" accid.ges="n" /> </beam> </tuplet> <tuplet xml:id="tuplet-L17F2-L19F2" num="3" numbase="2" bracket.place="above" bracket.visible="false" num.format="count"> <rest xml:id="rest-L17F2" dur="8" /> <beam xml:id="beam-L18F2-L19F2"> <note xml:id="note-L18F2" dur="8" oct="4" pname="b" accid="n" /> <note xml:id="note-L19F2" dur="8" oct="5" pname="b" accid="n" /> </beam> </tuplet> <tuplet xml:id="tuplet-L21F2-L23F2" num="3" numbase="2" num.visible="false" bracket.visible="false" num.format="count"> <rest xml:id="rest-L21F2" dur="8" /> <beam xml:id="beam-L22F2-L23F2"> <note xml:id="note-L22F2" dur="8" oct="5" pname="c" accid.ges="n" /> <note xml:id="note-L23F2" dur="8" oct="6" pname="c" accid.ges="n" /> </beam> </tuplet> <tuplet xml:id="tuplet-L24F2-L26F2" num="3" numbase="2" num.visible="false" bracket.visible="false" num.format="count"> <rest xml:id="rest-L24F2" dur="8" /> <beam xml:id="beam-L25F2-L26F2"> <note xml:id="note-L25F2" dur="8" oct="4" pname="g" accid.ges="n" /> <note xml:id="note-L26F2" dur="8" oct="5" pname="g" accid.ges="n" /> </beam> </tuplet> </layer> </staff> <staff xml:id="sewbl0b" n="2"> <layer xml:id="layer-L1F1N1" n="1"> <note xml:id="note-L13F1" dur="4" oct="4" pname="c" accid.ges="n" /> <note xml:id="note-L17F1" dur="4" oct="3" pname="b" accid="n" /> <note xml:id="note-L21F1" dur="4" oct="4" pname="c" accid.ges="n" /> <note xml:id="note-L24F1" dur="4" oct="3" pname="g" accid.ges="n" /> </layer> </staff> <dynam xml:id="dynam-L13F3" place="between" staff="1 2" tstamp="1.000000">p</dynam> <slur xml:id="slur-L14F2-L15F2" staff="1" startid="#note-L14F2" endid="#note-L15F2" /> <slur xml:id="slur-L18F2-L19F2" staff="1" startid="#note-L18F2" endid="#note-L19F2" /> <slur xml:id="slur-L22F2-L23F2" staff="1" startid="#note-L22F2" endid="#note-L23F2" /> <dynam xml:id="dynam-L24F3" place="between" staff="1 2" tstamp="4.000000">f</dynam> <slur xml:id="slur-L25F2-L26F2" staff="1" startid="#note-L25F2" endid="#note-L26F2" /> <slur xml:id="slur-L13F1-L50F1" staff="2" startid="#note-L13F1" endid="#note-L50F1" /> </measure> <measure xml:id="measure-L27" n="177"> <staff xml:id="staff-L27F2N1" n="1"> <layer xml:id="layer-L27F2N1" n="1"> <tuplet xml:id="tuplet-L28F2-L30F2" num="3" numbase="2" num.visible="false" bracket.visible="false" num.format="count"> <rest xml:id="rest-L28F2" dur="8" /> <beam xml:id="beam-L29F2-L30F2"> <note xml:id="note-L29F2" dur="8" oct="4" pname="a" accid.ges="f" /> <note xml:id="note-L30F2" dur="8" oct="5" pname="a" accid.ges="f" /> </beam> </tuplet> <tuplet xml:id="tuplet-L31F2-L33F2" num="3" numbase="2" num.visible="false" bracket.visible="false" num.format="count"> <rest xml:id="rest-L31F2" dur="8" /> <beam xml:id="beam-L32F2-L33F2"> <note xml:id="note-L32F2" dur="8" oct="4" pname="g" accid.ges="n" /> <note xml:id="note-L33F2" dur="8" oct="5" pname="g" accid.ges="n" /> </beam> </tuplet> <tuplet xml:id="tuplet-L34F2-L36F2" num="3" numbase="2" num.visible="false" bracket.visible="false" num.format="count"> <rest xml:id="rest-L34F2" dur="8" /> <beam xml:id="beam-L35F2-L36F2"> <note xml:id="note-L35F2" dur="8" oct="4" pname="a" accid.ges="f" /> <note xml:id="note-L36F2" dur="8" oct="5" pname="a" accid.ges="f" /> </beam> </tuplet> <tuplet xml:id="tuplet-L37F2-L39F2" num="3" numbase="2" num.visible="false" bracket.visible="false" num.format="count"> <rest xml:id="rest-L37F2" dur="8" /> <beam xml:id="beam-L38F2-L39F2"> <note xml:id="note-L38F2" type="placed" dur="8" oct="4" pname="e" stem.dir="down" accid.ges="f" /> <note xml:id="note-L39F2" type="placed" dur="8" oct="5" pname="e" stem.dir="down" accid.ges="f" /> </beam> </tuplet> </layer> </staff> <staff xml:id="staff-L27F1N1" n="2"> <layer xml:id="layer-L27F1N1" n="1"> <note xml:id="note-L28F1" dur="4" oct="3" pname="a" accid.ges="f" /> <note xml:id="note-L31F1" dur="4" oct="3" pname="g" accid.ges="n" /> <note xml:id="note-L34F1" dur="4" oct="3" pname="a" accid.ges="f" /> <note xml:id="note-L37F1" dur="4" oct="3" pname="e" accid.ges="f" /> </layer> </staff> <dynam xml:id="dynam-L28F3" place="between" staff="1 2" tstamp="1.000000">p</dynam> <slur xml:id="slur-L29F2-L30F2" staff="1" startid="#note-L29F2" endid="#note-L30F2" /> <slur xml:id="slur-L32F2-L33F2" staff="1" startid="#note-L32F2" endid="#note-L33F2" /> <slur xml:id="slur-L35F2-L36F2" staff="1" startid="#note-L35F2" endid="#note-L36F2" /> <dynam xml:id="dynam-L37F3" place="between" staff="1 2" tstamp="4.000000">f</dynam> <slur xml:id="slur-L38F2-L39F2" staff="1" startid="#note-L38F2" endid="#note-L39F2" /> </measure> <measure xml:id="measure-L40" n="178"> <staff xml:id="staff-L40F2N1" n="1"> <layer xml:id="layer-L40F2N1" n="1"> <tuplet xml:id="tuplet-L41F2-L43F2" num="3" numbase="2" num.visible="false" bracket.visible="false" num.format="count"> <rest xml:id="rest-L41F2" dur="8" /> <beam xml:id="beam-L42F2-L43F2"> <note xml:id="note-L42F2" dur="8" oct="4" pname="f" accid.ges="n" /> <note xml:id="note-L43F2" dur="8" oct="5" pname="f" accid.ges="n" /> </beam> </tuplet> <tuplet xml:id="tuplet-L44F2-L46F2" num="3" numbase="2" num.visible="false" bracket.visible="false" num.format="count"> <rest xml:id="rest-L44F2" dur="8" /> <beam xml:id="beam-L45F2-L46F2"> <note xml:id="note-L45F2" dur="8" oct="4" pname="f" accid="s" /> <note xml:id="note-L46F2" dur="8" oct="5" pname="f" accid="s" /> </beam> </tuplet> <tuplet xml:id="tuplet-L47F2-L49F2" num="3" numbase="2" num.visible="false" bracket.visible="false" num.format="count"> <rest xml:id="rest-L47F2" dur="8" /> <beam xml:id="beam-L48F2-L49F2"> <note xml:id="note-L48F2" dur="8" oct="4" pname="g" accid.ges="n" /> <note xml:id="note-L49F2" dur="8" oct="5" pname="g" accid.ges="n" /> </beam> </tuplet> <tuplet xml:id="tuplet-L50F2-L52F2" num="3" numbase="2" num.visible="false" bracket.visible="false" num.format="count"> <rest xml:id="rest-L50F2" dur="8" /> <beam xml:id="beam-L51F2-L52F2"> <note xml:id="note-L51F2" dur="8" oct="3" pname="g" accid.ges="n" /> <note xml:id="note-L52F2" dur="8" oct="4" pname="g" accid.ges="n" /> </beam> </tuplet> </layer> </staff> <staff xml:id="staff-L40F1N1" n="2"> <layer xml:id="layer-L40F1N1" n="1"> <note xml:id="note-L41F1" dur="4" oct="3" pname="f" accid.ges="n" /> <note xml:id="note-L44F1" dur="4" oct="3" pname="f" accid="s" /> <note xml:id="note-L47F1" dur="4" oct="3" pname="g" accid.ges="n" /> <note xml:id="note-L50F1" dur="4" oct="2" pname="g" accid.ges="n" /> </layer> </staff> <dynam xml:id="dynam-L41F3" place="between" staff="1 2" tstamp="1.000000">p</dynam> <slur xml:id="slur-L42F2-L43F2" staff="1" startid="#note-L42F2" endid="#note-L43F2" /> <slur xml:id="slur-L45F2-L46F2" staff="1" startid="#note-L45F2" endid="#note-L46F2" /> <slur xml:id="slur-L48F2-L49F2" staff="1" startid="#note-L48F2" endid="#note-L49F2" /> <slur xml:id="slur-L51F2-L52F2" staff="1" startid="#note-L51F2" endid="#note-L52F2" /> </measure> <measure xml:id="measure-L53" n="179"> <staff xml:id="staff-L53F2N1" n="1"> <layer xml:id="layer-L53F2N1" n="1"> <tuplet xml:id="tuplet-L54F2-L56F2" num="3" numbase="2" num.visible="false" bracket.visible="false" num.format="count"> <rest xml:id="rest-L54F2" dur="8" /> <beam xml:id="beam-L55F2-L56F2"> <note xml:id="note-L55F2" dur="8" oct="4" pname="c" accid.ges="n" /> <note xml:id="note-L56F2" dur="8" oct="5" pname="c" accid.ges="n" /> </beam> </tuplet> <tuplet xml:id="tuplet-L57F2-L59F2" num="3" numbase="2" num.visible="false" bracket.visible="false" num.format="count"> <rest xml:id="rest-L57F2" dur="8" /> <beam xml:id="beam-L58F2-L59F2"> <note xml:id="note-L58F2" dur="8" oct="3" pname="b" accid="n" /> <note xml:id="note-L59F2" dur="8" oct="4" pname="b" accid="n" /> </beam> </tuplet> <tuplet xml:id="tuplet-L60F2-L62F2" num="3" numbase="2" num.visible="false" bracket.visible="false" num.format="count"> <rest xml:id="rest-L60F2" dur="8" /> <beam xml:id="beam-L61F2-L62F2"> <note xml:id="note-L61F2" dur="8" oct="4" pname="c" accid.ges="n" /> <note xml:id="note-L62F2" dur="8" oct="5" pname="c" accid.ges="n" /> </beam> </tuplet> <tuplet xml:id="tuplet-L63F2-L65F2" num="3" numbase="2" num.visible="false" bracket.visible="false" num.format="count"> <rest xml:id="rest-L63F2" dur="8" /> <beam xml:id="beam-L64F2-L65F2"> <note xml:id="note-L64F2" dur="8" oct="3" pname="g" accid.ges="n" /> <note xml:id="note-L65F2" dur="8" oct="4" pname="g" accid.ges="n" /> </beam> </tuplet> </layer> </staff> <staff xml:id="staff-L53F1N1" n="2"> <layer xml:id="layer-L53F1N1" n="1"> <note xml:id="note-L54F1" dur="4" oct="3" pname="c" accid.ges="n" /> <note xml:id="note-L57F1" dur="4" oct="2" pname="b" accid="n" /> <note xml:id="note-L60F1" dur="4" oct="3" pname="c" accid.ges="n" /> <note xml:id="note-L63F1" dur="4" oct="2" pname="g" accid.ges="n" /> </layer> </staff> <slur xml:id="slur-L55F2-L56F2" staff="1" startid="#note-L55F2" endid="#note-L56F2" /> <slur xml:id="slur-L58F2-L59F2" staff="1" startid="#note-L58F2" endid="#note-L59F2" /> <slur xml:id="slur-L61F2-L62F2" staff="1" startid="#note-L61F2" endid="#note-L62F2" /> <dynam xml:id="dynam-L63F3" place="between" staff="1 2" tstamp="4.000000">f</dynam> <slur xml:id="slur-L64F2-L65F2" staff="1" startid="#note-L64F2" endid="#note-L65F2" /> <slur xml:id="slur-L54F1-L81F1" staff="2" startid="#note-L54F1" endid="#note-L81F1" /> </measure> <measure xml:id="measure-L66" n="180"> <staff xml:id="staff-L66F2N1" n="1"> <layer xml:id="layer-L66F2N1" n="1"> <tuplet xml:id="tuplet-L67F2-L69F2" num="3" numbase="2" num.visible="false" bracket.visible="false" num.format="count"> <rest xml:id="rest-L67F2" dur="8" /> <beam xml:id="beam-L68F2-L69F2"> <note xml:id="note-L68F2" dur="8" oct="3" pname="a" accid.ges="f" /> <note xml:id="note-L69F2" dur="8" oct="4" pname="a" accid.ges="f" /> </beam> </tuplet> <tuplet xml:id="tuplet-L70F2-L72F2" num="3" numbase="2" num.visible="false" bracket.visible="false" num.format="count"> <rest xml:id="rest-L70F2" dur="8" /> <beam xml:id="beam-L71F2-L72F2"> <note xml:id="note-L71F2" dur="8" oct="3" pname="g" accid.ges="n" /> <note xml:id="note-L72F2" dur="8" oct="4" pname="g" accid.ges="n" /> </beam> </tuplet> <tuplet xml:id="tuplet-L73F2-L75F2" num="3" numbase="2" num.visible="false" bracket.visible="false" num.format="count"> <rest xml:id="rest-L73F2" dur="8" /> <beam xml:id="beam-L74F2-L75F2"> <note xml:id="note-L74F2" dur="8" oct="3" pname="a" accid.ges="f" /> <note xml:id="note-L75F2" dur="8" oct="4" pname="a" accid.ges="f" /> </beam> </tuplet> <tuplet xml:id="tuplet-L76F2-L79F2" num="3" numbase="2" num.visible="false" bracket.visible="false" num.format="count"> <rest xml:id="rest-L76F2" dur="8" /> <clef xml:id="clef-L77F2" shape="F" line="4" /> <beam xml:id="beam-L78F2-L79F2"> <note xml:id="note-L78F2" dur="8" oct="3" pname="e" accid.ges="f" /> <note xml:id="note-L79F2" dur="8" oct="4" pname="e" accid.ges="f" /> </beam> </tuplet> </layer> </staff> <staff xml:id="staff-L66F1N1" n="2"> <layer xml:id="layer-L66F1N1" n="1"> <note xml:id="note-L67F1" dur="4" oct="2" pname="a" accid.ges="f" /> <note xml:id="note-L70F1" dur="4" oct="2" pname="g" accid.ges="n" /> <note xml:id="note-L73F1" dur="4" oct="2" pname="a" accid.ges="f" /> <note xml:id="note-L76F1" dur="4" oct="2" pname="e" accid.ges="f" /> </layer> </staff> <dynam xml:id="dynam-L68F3" place="between" staff="1 2" tstamp="1.333333">p</dynam> <slur xml:id="slur-L68F2-L69F2" staff="1" startid="#note-L68F2" endid="#note-L69F2" /> <slur xml:id="slur-L71F2-L72F2" staff="1" startid="#note-L71F2" endid="#note-L72F2" /> <slur xml:id="slur-L74F2-L75F2" staff="1" startid="#note-L74F2" endid="#note-L75F2" /> <dynam xml:id="dynam-L78F3" place="between" staff="1 2" tstamp="4.333333">f</dynam> <slur xml:id="slur-L78F2-L79F2" staff="1" startid="#note-L78F2" endid="#note-L79F2" /> </measure> <measure xml:id="measure-L80" n="181"> <staff xml:id="staff-L80F2N1" n="1"> <layer xml:id="layer-L80F2N1" n="1"> <tuplet xml:id="tuplet-L81F2-L83F2" num="3" numbase="2" num.visible="false" bracket.visible="false" num.format="count"> <rest xml:id="rest-L81F2" dur="8" /> <beam xml:id="beam-L82F2-L83F2"> <note xml:id="note-L82F2" dur="8" oct="3" pname="f" accid.ges="n" /> <note xml:id="note-L83F2" dur="8" oct="4" pname="f" accid.ges="n" /> </beam> </tuplet> <tuplet xml:id="tuplet-L84F2-L86F2" num="3" numbase="2" num.visible="false" bracket.visible="false" num.format="count"> <rest xml:id="rest-L84F2" dur="8" /> <beam xml:id="beam-L85F2-L86F2"> <note xml:id="note-L85F2" dur="8" oct="3" pname="f" accid="s" /> <note xml:id="note-L86F2" dur="8" oct="4" pname="f" accid="s" /> </beam> </tuplet> <tuplet xml:id="tuplet-L87F2-L89F2" num="3" numbase="2" num.visible="false" bracket.visible="false" num.format="count"> <rest xml:id="rest-L87F2" dur="8" /> <beam xml:id="beam-L88F2-L89F2"> <note xml:id="note-L88F2" dur="8" oct="3" pname="g" accid.ges="n" /> <note xml:id="note-L89F2" dur="8" oct="4" pname="g" accid.ges="n" /> </beam> </tuplet> <tuplet xml:id="tuplet-L90F2-L92F2" num="3" numbase="2" num.visible="false" bracket.visible="false" num.format="count"> <rest xml:id="rest-L90F2" dur="8" /> <beam xml:id="beam-L91F2-L92F2"> <note xml:id="note-L91F2" type="placed" dur="8" oct="2" pname="g" stem.dir="down" accid.ges="n" /> <note xml:id="note-L92F2" type="placed" dur="8" oct="3" pname="g" stem.dir="down" accid.ges="n" /> </beam> </tuplet> </layer> </staff> <staff xml:id="staff-L80F1N1" n="2"> <layer xml:id="layer-L80F1N1" n="1"> <note xml:id="note-L81F1" dur="4" oct="2" pname="f" accid.ges="n" /> <note xml:id="note-L84F1" dur="4" oct="2" pname="f" accid="s" /> <note xml:id="note-L87F1" dur="4" oct="2" pname="g" accid.ges="n" /> <note xml:id="note-L90F1" dur="4" oct="1" pname="g" accid.ges="n" /> </layer> </staff> <dynam xml:id="dynam-L81F3" place="between" staff="1 2" tstamp="1.000000">p</dynam> <slur xml:id="slur-L82F2-L83F2" staff="1" startid="#note-L82F2" endid="#note-L83F2" /> <slur xml:id="slur-L85F2-L86F2" staff="1" startid="#note-L85F2" endid="#note-L86F2" /> <slur xml:id="slur-L88F2-L89F2" staff="1" startid="#note-L88F2" endid="#note-L89F2" /> <slur xml:id="slur-L91F2-L92F2" staff="1" startid="#note-L91F2" endid="#note-L92F2" /> </measure> </section> </score> </mdiv> </body> </music> </mei> ``` </details> <p>Notice the <code>F#</code> slur in m. 178 which did not trigger the steep slur algorithm. There could be a "short slur" algorithm which could be implemented: in manual typesetting, short slurs are not drawn freehand but rather with a stamp (limiting the shapes of short slurs): <a href="https://www.youtube.com/watch?v=m5uPPJj_M_o&t=234s">https://www.youtube.com/watch?v=m5uPPJj_M_o&t=234s</a></p> <p>Here is the manual typesetting for the example:</p> <img width="1125" alt="Screen Shot 2022-04-06 at 8 13 50 AM" src="https://user-images.githubusercontent.com/3487289/162008081-df6fb45a-d65e-411c-b13e-b11a6f71a3c4.png"> <img width="720" alt="Screen Shot 2022-04-06 at 8 14 10 AM" src="https://user-images.githubusercontent.com/3487289/162008148-e8296d90-a673-4dcb-8799-17e83e28c9a9.png"> <p>Note that there is an exception for slurs and accidentals overlapping in difficult cases, with one given in this example:</p> <img width="75" alt="Screen Shot 2022-04-06 at 8 17 36 AM" src="https://user-images.githubusercontent.com/3487289/162009035-037fee01-e7f1-4f36-a7fc-d351ff763ee7.png"> <p>And this slur and sharp are exceptionally close (yet there is no visual merging so it is not objectionable due to the intersection angles being close to 90 degrees):</p> <img width="97" alt="Screen Shot 2022-04-06 at 8 18 56 AM" src="https://user-images.githubusercontent.com/3487289/162009378-7bd39433-8b31-4c19-8455-db8c82108fdc.png"> <p>Also note the notehead placement of the slur endpoints on these examples: the slur is lengthened horizontally by having the slur start point left justified on the notehead, and the slur end point is somewhat right justified on the notehead.</p> </div> </div> <div class="comment"> <div class="user"> <a rel="noreferrer nofollow" target="_blank" href="https://github.com/craigsapp"><img src="https://avatars.githubusercontent.com/u/3487289?v=4" />craigsapp</a> commented <strong> 2 years ago</strong> </div> <div class="markdown-body"> <p>Here is how I would manually typeset the first example above (without referring to the original edition):</p> <img width="405" alt="Screen Shot 2022-04-07 at 7 44 28 AM" src="https://user-images.githubusercontent.com/3487289/162226237-f14fabec-9dce-455c-bfe6-75ad69614d85.png"> <img width="809" alt="Screen Shot 2022-04-07 at 7 23 14 AM" src="https://user-images.githubusercontent.com/3487289/162222336-01760efd-d591-406c-8478-36265f250bfd.png"> <details> <summary> Click to view SCORE data for above example </summary> ``` 14 1 0.000 2.0 8.00 14 1 0.000 2.0 8 1 0.000 0.0 0.85 100.00 3 1 1.600 0.0 1.00 17 1 7.808 0.0 -1.00 1.00 18 1 11.008 0.0 98.00 1.00 1 1 18.688 3.0 23.00 0.00 0.2500 1.18 0 0.00 0.0 1 6 1 18.688 23.0 23.00 31.86 22.0000 5 1 22.888 25.5 28.75 26.87 1.3552 -1.00 1 1 23.888 2.0 21.00 0.00 0.2500 0.18 0 0.00 0.0 1 1 1 27.871 5.0 20.00 0.00 0.2500 3.18 0 0.00 0.0 1 5 1 30.855 27.0 30.75 35.28 1.4552 -1.00 0 0.53 1 1 31.855 3.0 20.00 0.00 0.2500 1.18 0 0.00 0.0 1 1 1 36.032 7.0 21.00 0.00 0.5000 0.00 1 0.00 0.0 1 1 1 45.718 12.0 21.00 0.00 0.5000 6.00 0 0.00 19.0 1 1 45.718 5.0 1.00 0.00 0.5000 6 1 45.718 6.0 5.00 57.48 21.0000 1 1 51.847 11.0 21.00 0.00 0.5000 5.50 0 0.00 19.0 1 1 51.847 4.0 1.00 0.00 0.5000 1 1 57.477 10.0 20.00 0.00 0.5000 5.00 0 0.00 19.0 1 1 57.477 3.0 0.00 0.00 0.5000 2 1 62.586 0.0 0.00 0.00 1.0000 2 1 78.214 0.0 1.00 0.00 0.5000 1 1 83.516 2.0 10.00 0.00 0.5000 6.00 0 0.00 19.0 1 1 83.516 9.0 0.00 0.00 0.5000 6 1 83.516 8.0 8.00 94.51 11.0000 1 1 88.626 2.0 10.00 0.00 0.5000 6.00 0 0.00 19.0 1 1 88.626 9.0 0.00 0.00 0.5000 1 1 94.505 1.0 11.00 0.00 0.5000 7.00 0 0.00 19.0 1 1 94.505 8.0 1.00 0.00 0.5000 14 1 100.000 2.0 8 2 0.000 0.0 0.85 100.00 10 2 0.000 13.0 144.00 0.75 1.0000 0.00 0 0.00 0.0 0 0 0 -2.36 3 2 1.600 17 2 7.808 0.0 -1.00 18 2 11.008 0.0 98.00 1.00 2 2 18.688 6.0 0.00 0.00 1.0000 2 2 36.032 6.0 1.00 0.00 0.5000 9 2 41.500 -4.0 56.00 1 2 45.718 10.0 23.28 0.00 0.5000 3.00 0 0.00 19.0 1 2 45.718 9.0 1.22 0.00 0.5000 0.00 0 20.00 1 2 45.718 5.0 0.00 0.00 0.5000 6 2 45.718 7.0 8.00 57.48 21.0000 1 2 51.597 11.0 20.00 0.00 0.5000 3.50 0 0.00 19.0 1 2 51.597 8.0 0.00 0.00 0.5000 1 2 51.597 6.0 1.00 0.00 0.5000 1 2 57.477 12.0 20.00 0.00 0.5000 4.00 0 0.00 19.0 1 2 57.477 10.0 0.00 0.00 0.5000 1 2 57.477 7.0 1.00 0.00 0.5000 1 2 62.086 11.0 20.00 0.00 0.2500 3.00 6 2 62.086 8.0 8.00 74.23 22.0000 5 2 64.570 10.0 15.00 69.75 1.7500 -1.00 0 0.53 1 2 66.070 8.0 20.00 0.00 0.2500 1 2 70.247 13.0 21.00 0.00 0.2500 5.00 5 2 73.231 13.0 16.75 77.71 1.4625 -1.00 1 2 74.231 11.0 20.00 0.00 0.2500 3.00 1 2 78.214 15.0 20.00 0.00 0.5000 9.00 6 2 78.214 6.0 6.00 94.51 21.0000 9 2 82.500 -5.0 56.00 1 2 83.516 8.0 20.00 0.00 0.5000 2.00 0 0.00 19.2 0 0 1 1 2 83.516 6.0 1.00 0.00 0.5000 1 2 83.516 4.0 0.00 0.00 0.5000 1 2 88.626 8.0 20.00 0.00 0.5000 2.00 0 0.00 19.2 0 0 1 1 2 88.626 6.0 0.00 0.00 0.5000 1 2 88.626 4.0 0.00 0.00 0.5000 1 2 94.505 8.0 20.00 0.00 0.5000 2.00 0 0.00 19.2 0 0 1 1 2 94.505 5.0 0.00 0.00 0.5000 ``` </details> <p>The original placement in version 3.6 is better because it almost looks like the placement here. In tight spacing, slurs are allowed to cross the stems of flats (but not to enter the lower portion of the flat as in the 3.6 rendering).</p> <p>One problem is that the kerning of the notes is being counter-productive for the placement of these two slurs. I am using a very slight kerning of the flat over the previous note so that the rhythmic spacing of the noteheads is not disturbed. In the long term the slur placement algorithm should be able to identify that kerning was done between these two notes, and it would have the ability to cancel or reduce the kerning (i.e., there would be a kerning variable that would keep track of kerning decisions, and then this value could be set to 0 by the slur rendering algorithm). </p> <p>Another thing that I did was move the first forte dynamic to the left. This make reading the first chord it applies to easier. This is something that is hard for a computer to decide to do, so ideally there would be an MEI attribute to indicate this (a boolean for placing the forte before the chord, before having to rely on a fixed horizontal offset).</p> </div> </div> <div class="page-bar-simple"> </div> <div class="footer"> <ul class="body"> <li>© <script> document.write(new Date().getFullYear()) </script> Githubissues.</li> <li>Githubissues is a development platform for aggregating issues.</li> </ul> </div> <script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.min.js"></script> <script src="/githubissues/assets/js.js"></script> <script src="/githubissues/assets/markdown.js"></script> <script src="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.4.0/build/highlight.min.js"></script> <script src="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.4.0/build/languages/go.min.js"></script> <script> hljs.highlightAll(); </script> </body> </html>