musescore / MuseScore

MuseScore is an open source and free music notation software. For support, contribution, bug reports, visit MuseScore.org. Fork and make pull requests!
https://musescore.org
Other
11.91k stars 2.57k forks source link

[MU4 Issue] Accidentals in chord symbols rendered incorrectly when using custom XML file #16363

Closed MarcSabatella closed 4 days ago

MarcSabatella commented 1 year ago

Describe the bug If you use a custom XML file as your chord symbol style, then upon save/reload of your score, all accidentals get rendered as the numeric Unicode numbers (e.g., the actual string "266d" and "266f " rather than the corresponding Unicode characters

To Reproduce Steps to reproduce the behavior:

  1. Add a chord symbol "Bb7" to a score
  2. Go to Format / Style / Chord Symbols
  3. Under Appearance, select Custom and load the following file (after renaming to XML): chords_flat.ZIP
  4. Save
  5. Reload
  6. See error: the flat sign in Bb7 is now rendered as 266d

Expected behavior Ther flat sign should remain a flat sign

Screenshots image

Platform information

Additional context The XML files contain statements assigned the flat sign to that Unicode character 0x266d <sym code="0x266d" name="b">. This works normally for the built in chord description files, which are always read in anew when opening the score. But for custom XML files, we actually write the relevant contents of the XML file into the score itself. And apparently this is done in a way that somehow messes up the syntax.

Looking at the contents of the MSCZ archive, I see the file chordlist.xml is written, but it's messed up, that line has turned into <sym name="b" code="266d"/>. This worked correctly in MU3.

Jojo-Schmitz commented 1 year ago

So the 0x is being ommitted when putting it into the chordlist.xml, right?

MarcSabatella commented 1 year ago

Yes. I assume it somehow has to do with the XML read/write functions, something not being escaped that needs to be.

Meanwhile, a workaround seems to be, edit the XML file to replace the 0x266d with the more HTML-friendly &#9837;

Jojo-Schmitz commented 1 year ago

Might be related to the 'home-brew' string lib

moogly81 commented 1 year ago

Additional info

The issue happens only on the score, NOT on the parts. It's not only accidentals that are incorrectly rendered. Content inside parenthesis disappear. custom chrods file : chords_jazz_mod.xml.zip

Part

image

Score

image

Workaround (kind of ...)

step 1 : format --> style --> chord symbols --> select jazz (or standard) step 2 : format --> style --> chord symbols --> select "custom" and chose your custom xml file again. ==> chord symbols are fixed on the score ==> close and re-open the file, the issue appears again

SejoWuigui commented 1 year ago

Open *.mscz file with archiver and delete 'chordlist.xml'. Then MuseScore 4 shows chords normally. What's the reaseon?

MarcSabatella commented 1 year ago

Probably because now you’ve removed the custom chord symbol definition that caused the problem, and you are back to using the default which works.

moogly81 commented 1 year ago

Is the issue still present on your side ? On the scores I'm working on at the moment, the issue is gone on the newest version.

MarcSabatella commented 1 year ago

As mentioned, it only occurs in scores using custom chord description files, and even then, only those using a specific syntax for specifying flats. For me it's still reproducible in 4.0.2. Maybe you implemented the fix I mentioned above in your XML and that's why it is working?

SejoWuigui commented 1 year ago

I'm using MuseScore 4.02 and Windows 10(Korean language). Before, I copied 'chords_jazz.xml' to [documents] musescore folder, and edited just slash chord part(a little positioning fix). But the error like screenshot above occured.. 😥

Now, I ran into [program files] muscescore folder, and backup the 'chord_jazz.xml' and edit directrly. Set score's chord style to 'Jazz', and save it. Then I re-open the file and sharps(#) and flats(b) are shown correctly.

mattblo commented 1 year ago

I also have this issue when using an custom chord style file. Is there a fix already? I have about 350 files top render with a custom style file and this is really annoying...

Windows 11 Musescore 4.0.2

MarcSabatella commented 1 year ago

I don't think there is anyone working on a fix in the code, but the solution for now is to fix your custom XML file to use the better syntax I described above in https://github.com/musescore/MuseScore/issues/16363#issuecomment-1430235880

cbjeukendrup commented 1 year ago

I took a quick look and probably it has gone wrong either here: https://github.com/musescore/MuseScore/commit/ce2473bc80216b9af70945ef0b632f6a00ec6b13#diff-34fc1099345fb1b9e716cbe1602692db544d21858204ce45642aa36e99f779afR1794 or here: https://github.com/musescore/MuseScore/commit/0a13b86cbb35e2b20677b7f7f60427d9598b4ccc#diff-34fc1099345fb1b9e716cbe1602692db544d21858204ce45642aa36e99f779afR1792 (see the Git Blame for ChordList::write)

AlteriusOmega commented 11 months ago

I keep experiencing this issue, but I have never (intentionally) set a custom file for chord symbol styles. I didn't even know it was possible until I found this issue page. However in the past few days, my score has started exhibiting this problem a couple times. I just looked in Format --> Style --> Chord symbols and found it was set to Custom with "chords_std.xml". I don't know where this file came from so I assume its automatically built by MuseScore. The file says the version is 1.24, and it seems to be formatted correctly in terms of the XML but I don't know any of the specifics of this chord symbol style. So, I don't know why it would exhibit this problem. I had to first zip the XML to attach it since GitHub doesn't allow uploading XML files. chords_std.zip

I don't know how this got set this way as I have never opened this Style menu before. Is there some keybaord shortcut or some other action that can automatically set this? I don't know how it keeps getting set this way and I would like to avoid it since this problem is still present.

Jojo-Schmitz commented 11 months ago

Seems to happen on importing scores from older MuseScore versions

AlteriusOmega commented 11 months ago

Seems to happe on importing scores from older MuseScore versions

Ah yes you are right, this score I'm working on was originally an older MuseScore version file. I'm guessing the chords_std.xml is a sort of bridge to make the new chord style system compatible with some previous one?

Jojo-Schmitz commented 11 months ago

Which version stemmed the score from? That chords_std.xml is part of MuseScore since Mu2. Only in Mu4 there are problems reading it properly (and that's what this issue here is all about)

MarcSabatella commented 11 months ago

chords_std is the default standard style; it it is just supposed to be accompanied by a tag marking it as such rather than as Custom. So simply change the style to Standard instead of Custom to workaround this.

Jojo-Schmitz commented 3 months ago

Still an issue ILikeTheFlowersLEAD.zip

That score doesn't show any evidence having been imported from XML though not from an older version of MuseScore

Except: it does have a(n empty) Poet tag in Score properties and a mscVersion tag of "4.20", and a creation date of 11.Dec.22. so before 4.0 release, so indeed got have been imporeted ort updated somehow

Alice1667 commented 3 months ago

I had this when loading MS3 music into MS4. I went into format style - chord symbols: changed it to Jazz & it gave me the correct flat chords. Changed it back again and it was still correct.

Jojo-Schmitz commented 3 months ago

Yes, that is the workaround

Jojo-Schmitz commented 3 months ago

Came up again in https://musescore.org/en/node/363221

Jojo-Schmitz commented 3 months ago

I believe it got go wrong somehere here:

            while (e.readNextStartElement()) {
                if (e.name() == "sym") {
                    ChordSymbol cs;
                    cs.fontIdx = fontIdx;
                    cs.name    = e.attribute("name");
                    cs.value   = e.attribute("value");
                    String code = e.attribute("code");
                    String symClass = e.attribute("class");
                    if (!code.empty()) {
                        bool ok = true;
                        char32_t val = code.toUInt(&ok, 0);
                        if (!ok) {
                            cs.code = 0;
                            cs.value = code;
                        } else if (Char::requiresSurrogates(val)) {
                            cs.code = 0;
                            cs.value = String::fromUcs4(val);
                        } else {
                            cs.code = val;
                            cs.value = String(cs.code);
                        }

probably in the toUInt() method

Jojo-Schmitz commented 3 months ago

No it is not (not only though, see below), it is going wrong on write, this fixes it:

$ git diff
diff --git a/src/engraving/dom/chordlist.cpp b/src/engraving/dom/chordlist.cpp
index 8ddcd824d9..c80a218617 100644
--- a/src/engraving/dom/chordlist.cpp
+++ b/src/engraving/dom/chordlist.cpp
@@ -1780,7 +1780,7 @@ void ChordList::write(XmlWriter& xml) const
                 if (s.code.isNull()) {
                     xml.tag("sym", { { "name", s.name }, { "value", s.value } });
                 } else {
-                    xml.tag("sym", { { "name", s.name }, { "code", String::number(s.code.unicode(), 16) } });
+                    xml.tag("sym", { { "name", s.name }, { "code", u"0x" + String::number(s.code.unicode(), 16) } });
                 }
             }
         }

And indeed @cbjeukendrup was right in https://github.com/musescore/MuseScore/issues/16363#issuecomment-1553644553.

But for all scores that had been written already it is too late, so the reading needs to get fixed too, prefixing a 0x it every value not having one and not starting with & (and ending with a ;, so basically being alpha-numerical.

Like this probably:

diff --git a/src/engraving/dom/chordlist.cpp b/src/engraving/dom/chordlist.cpp
index 8ddcd824d9..72936bd543 100644
--- a/src/engraving/dom/chordlist.cpp
+++ b/src/engraving/dom/chordlist.cpp
@@ -1685,6 +1685,9 @@ void ChordList::read(XmlReader& e)
                     String code = e.attribute("code");
                     String symClass = e.attribute("class");
                     if (!code.empty()) {
+                        if (!code.startsWith(u"0x") && !code.startsWith('&') && !code.endsWith(';')) {
+                            code = u"0x" + code; // fix broken chord lists
+                        }
                         bool ok = true;
                         char32_t val = code.toUInt(&ok, 0);
                         if (!ok) {

Let me PR that...

Jojo-Schmitz commented 2 months ago

Came up again in https://musescore.org/en/node/364006

Jojo-Schmitz commented 1 month ago

Came up again in https://musescore.org/en/node/365531