SVG regression : Invisible measure appears in SVG output

• Jan 5, 2016 - 16:02
S4 - Minor

MuseScore d08e14cc36

  • Create a score with one invisible measure (via measure properties) or via the cutaway property in Staff Properties.
  • Export to SVG.
  • Actual result
    The invisible measures are not invisible in the SVG

    Expected result
    The invisible measures should not be visible in the SVG

    Let's see if we can fix this bug properly. If not, let's revert to staff lines per measure.


The fix looks good. I will test them further. Sure, please do a PR. Two things though.

However, you got a problem in your git history... You have 3 commits, not two. You might be able to recover as follow if you have the git repo setup as explained here

$ git checkout master
$ git fetch upstream
$ git merge upstream/master
$ git checkout -b 92901-SVG-Invisible-Measure2
$ git cherry-pick a1cfc3d
$ git cherry-pick 724ac20
$ git push origin 92901-SVG-Invisible-Measure2

The new branch 92901-SVG-Invisible-Measure2 should now have only two commits on top of master.
Thank you for having "fix #XXXX" in the commit message. Feel free to make the commit message a bit longer in the future like "fix #92901: SVG regression : Invisible measure appears in SVG output" so it's self explanatory but people can check the issue if necessary.

2/ I see that you draw the staff lines per measure if you have a single invisible measure. I thought you would stop lines and start again until the next invisible one.

final edit - it's not the simplest set of concepts to explain verbally, and I might be mildly OCD when it comes to clarity on such topics
1) Yes, I'll start a new branch again... I only committed twice, after creating this branch, so I don't know what happened, but I'm obviously still clumsy with github. I think the creation of the branch somehow created the first commit.

2) Part of my approach to this is based on my perception that invisible measures are not a common occurrence. Combine this with how often SVG Export is used. Combine that with this particular enhancement, which matters primarily for horizontally scrolling, single-page scores. The result is a sub-feature that affects a tiny portion of a tiny percentage of scores. To me, invisible measures in this context is a clear exception to otherwise basic concepts in the code flow.

Being probably the current #1 user of both SVG Export and horizontally scrolling, single-page scores, I don't imagine any scores of mine that will use invisible measures, for example. Most of them will be parts, not full scores, so the concept of invisible measures becomes even more confusing - do you really use invisible measures in a part? Just empty space at some default width? That could actually be confusing in a horizontally scrolling score, if the viewport becomes completely empty at some point in time because it's displaying 100% invisible measures.

In order to draw staff lines once per system, the code loops this way:
for each Page
> for each System
> > for each Staff

So staff/system/page is the basic unit of operation. In order to handle invisible measures, the new code simply checks for the existence of any invisible measure in each staff/system/page. If it finds one invisible measure, then it considers that entire staff/system/page to be exceptional, and it draws the staff lines by measure. If it doesn't find an invisible measure, there is no exception, and it draws those staff lines only once.

Yes, if you have a horizontally scrolling, single-page score with an invisible measure in it, the SVG export for that score will be inefficient. But I find it hard to justify more complexity in the code for what I see as an extremely obscure case, less than 1 in 10,000, a basis point (0.01%) in financial reporting terminology. In order to function that way the code needs to keep track of variable start and end points within a staff/system/page. This alters the basic paradigm/flow of the core code and makes it more complicated, IMO. Imagine all the various possible cases, multiple contiguous invisible measures, multiple discontiguous invisible measures, the first measure is invisible, the last measure is invisible, etc. I only deal with one case, and I can exit my search loop early if I find an invisible measure prior to the end of the staff/system/page.

That is my justification for coding it this way. If you feel that invisible measures are more common that I imagine, and that others will be following in my animation footsteps with all kinds of horizontally scrolling, single-page scores, then I can write the code to be ultimately efficient in that regard. Otherwise I don't think it's worth it.

Thank you for the thorough explanation. I'm fine with your current implementation.

If you need live help on git, don't hesitate to join IRC #musescore on
Looking forward to review your PR.

OK, I backed up my 2 currently pending branches and then completely deleted my MuseScore fork/repo. Then I forked MuseScore from scratch, all over again. Am I going to have to do that every time I go through this process?

Anyway, now I have a new branch with only two commits, for this and the other pending issue: The branch is called 01-16-SVG-fixes, and here is a link:

oops - I forgot to mention that the pull request is here (2338):

Please let me know if there are any further issues.

No, you should never normally need to delete a fork. If you follow the Git Workflow document to a "T", everything works smoothly,. Things go wrong only when you deviate from it, whether on accident or because you were trying to outsmart the system. I've screwed my repo up both ways, and sometimes indeed needed to resort to deleting the fork and starting over, although I'm getting better at figuring out how to repair the damage I caused. But when I follow the instructions literally, everything goes smooth as silk.

Yes, I'm trying to be 100% in the GitHub client for Windows, which in and of itself appears to violate the "to the letter" concept of the instructions. I'm not good with super detailed, super strict instructions, but not many people are. Once I do it again, and subsequently memorize it I'll be fine.

Glad to hear this won't be a regular occurrence. It was the only way I could easily start over completely. The key word being "easily", i.e. not following too many detailed instructions. My error appears to be in the rebasing of the master before I start a new branch. I'll read the instructions again...

... Marc, do you care to comment on my question about invisible measures in an instrument's part, as opposed to the full score? To me, the concept of an invisible measure, and even the cutaway, only really apply in a multi-part score. But I'm not a real user of the feature. Maybe you can comment on the standard reason(s) for invisible measures. thx., of course, I have come up with my own invisible measure in a part example. How plausible/normal is this scenario:
The score is a concatenation of multiple pieces or movements with titles. The invisible measure (which would be in every staff in the full score) serves as an inline title space. For playback, you could create a preset duration of silence for the invisible measure with an invisible tempo change. It works as a fixed duration of space between "sections" of the piece. It sounds a bit odd to me, but I could imagine a set of micro-songs based on haiku or whatever. Is it intended for that kind of cut/pasty desktop publishing trick, or is there generally a musical intent behind it?

Rebasing the master before creating a brnch is actually a good idea, it's right there in the instructions. I think trying to use the Windows client is just asking for trouble, as who knows what it is doing behind your back. The command line interface is very straightforward, just a short series of comamnds you do every time that work reliably.


I see no reason to assume an invisible measure would apply only to a score and not to a part. I guess for *certain* use cases, I could imagine that being the case, but for others, perhaps not. One reason fro cutaway scores is to make entrances and exists clearer to the conductor, and in that case, sure, it's for score only. But invisible measures might also be used to replace a section of notated music with, say, a graphic, or some text - and in that case, it would need to be in the parts as well. These are just two examples off the top of my head, I'm sure there are others, some that should be score only, others score and parts. Probably others still might be parts only, who knows. Your particular example seems contrived - it's really just someone using an invisible measure where a section break plus a frame is the better choice

So to me, the ability to have these independent seems useful, but I have no particular opinion on what the default should be or on a GUI for overriding the default.

That generally answers my question and confirms my basic idea of it. Cutaway, as I imagine it, is full-score only. And I also imagine that the invisible measure is otherwise rarely left as empty space, there is a graphic or text in the revealed space.

The one scenario where I can now imagine doing it myself, because I haven't seen a way to do it, is this, and it only applies to a full-score:
~ I am hiding empty staves.
~ I have a part that is only in the first half of the score
~ I have a part that is only in the second half of the score
~ There is at least one empty measure between those two parts
So I create an invisible set of measures in the middle, and use a single staff for two different instruments. In the empty space revealed by the invisible measures, I put text with the new instrument name.

There isn't any other way to do an instrument change within a staff/system, is there? You'd have to display both staves unless there was a page break during the empty measures, right?

i) Another positive aspect of this code is that adding the feature to accommodate changing staff-lines within a staff will be super simple. Add a new case to the initial, by measure, search loop checking to check for changed staff lines, something like:
if (!static_cast<Measure*>(mb)->visible(i) || mb.staffLines.count <> prevMB.staffLines.count)
if (!static_cast<Measure*>(mb)->visible(i) || staff.lines( <> staff.lines( - 1))

That's it. Simply drawing the staff lines by measure will handle it all automatically. And given that the feature doesn't even exist yet, I'm pretty sure that it falls into the ''not used very often" category along with invisible measures, so it's a good fit all around.

ii) a) OK, now I see the Text palette. I'm such a Windows user now that I assume all the functionality will be available in the menus, one way or another. I also see that the Staff Properties dialog has a Change Instrument... button. Here's what happens when I use them in 2.0.2 and the latest master:
~ I drag an "Instrument" from the Text palette to the whole note rest in bar 20, Voice staff.
~ I right-click on the "Instrument" text, then click Change Instrument...
~ I choose a new instrument (Voice becomes Tuba)
>> Problem 1: The short instrument name displayed to the left of each system remains unchanged for the remaining systems. If I change the primary instrument to Flute in Staff properties, all the short instrument name text changes, and the recently added Instrument from the Text palette remains Tuba. So the entire problem is that after an instrument change mid-score, the displayed short instrument name does not change.
>>Problem 2: I need to be able to edit all the instrument properties for this part of the staff. There is no option to do that, though reusing the Staff properties dialog makes sense here. It would have to be adapted to be sensitive to the measure or even chordrest selected. btw - changing the default text inserted by the palette from "Instrument" does not have any effect elsewhere in the program. That text, however it is inserted, must be connected to the long/short instrument names in the dialog box, or it must not be editable in-place, the same way instrument names are generally not editable in-place.
>>Problem 3: The Mixer does provide me with two channels, but both have the long instrument name Flute. In 2.0.2 the correct default sounds are selected, in the master no default sounds are selected for any staff - an entirely separate issue.
b) If I want to position the instrument name inline with the staff lines, as is normal for instrument names, I do need an empty measure within the staff to create the empty space for the text.

iii) Communicating in formatted text with people I have just met online and never met in person is not easy, for either of us. It's can be technically precise, yet horribly unsubtle and lacking in nuance - the opposite of music. A few things about me and code: a) I would never suggest that you limit functionality. In this case I'm simply trying to understand the reason why someone might use an invisible measure. I've truly never given it any thought, even though, now that you mention it, I have seen scores that have graphics blended into the pages. b) Simplicity is always a top priority for me when writing code, as is c) facilitating future maintenance. All my previous development projects have been, from the start, under the premise that once I had gotten the product up to spec, I would hand it off 100% to other people for maintenance and enhancements - we literally never speak again and I never see the source again. Open Source seems to have that concept built into the name, so I'm hoping to feel at home in that regard, even though this is my first contribution ever to an open source project. I've used gnu in the distant past, but never contributed. I should probably learn to use the system I've seen in some of the modules for documenting code, but I've had my hands full just getting this far. So I've resorted to relatively heavy commenting inside the code.

This kind of discussion s better suited to the forum, but yes, the short name not changing is a known issue, it hinges on how systems are laid out. And as I said before, making other staff properties change mid-score would be a much larger change. I got lucky in that the necessary framework for transposition was already in place. As for changing number of staff lines mid-score, I think you are greatly underestimating what it involved. It isn't just drawing the staff that needs to change, it is everywhere we use the number of staff lines in a calculation, such as to determine which notes need ledger lines and how many, calculating stem directions and lengths, beam calculations, etc. It's not impossible, but hardly "super simple".

For invisible measures, I thought I gave a couple of use cases already, but one is to have a space in the music where you will replace the notation with a graphic. GTo get more feedbakc on other use cases, it is better to start a new thread in the forum.

ii) Sorry, I didn't realize it was a known issue. You recommended that I use it, and spoke of it as if I could actually get proper results on the page.
i) + iii) I assume it's excessively entangled or you would have made the changes along with the transposition. That's why I put iii) in there, because of an exchange such as this. By "super simple" i was speaking entirely within the context of this particular bit of SVG code relating to this issue #92901. I meant that the ripple effect of the gnarly overall change would be super simple to accommodate here within this code. And I provided an example of the type of modification to a single line of code.
And I bring up the issue of changing staff lines mid-staff because @lasconic brought it up clearly when reporting this bug (#92901) initially in this issue's "parent" #86686, and we have been discussing it. See here and below:
Context can be difficult to express and/or understand properly in formatted text with a relative stranger, and I am definitely having some difficulty achieving clarity here at times. And the concept of a sub-issue and resulting hierarchy is implicit here, not explicitly implemented, so the two issues (92901 and 86686) are separate, yet related. These forums are also sometimes multiple 1-to-1 conversations happening simultaneously, which is why I often use outline numbering to keep thoughts separated. It's a difficult medium all around.

Well, sometimes you'd want the short name to change, other times you might not, depending on your use case. I didn't know which result you intended. I was just pointing out the instrument change feature *does* exist, since you said you knew of know way to do it.

Anyhow, yes, I did look at getting the short name to change when I did the transposition changes, but ran into a roadblock: at the point where we are contructing the staff names to place at the beginning of a system, we have not yet actually added any measures to the system. So there is no way to get the tick of the first measure of system without doing some re-architecting of the code. Not impossible to solve, but since it wasn't relevant to the changes I was making, I decided not to try to combine these unrelated fixes.

Sorry, it's kind of hard to follow all the different threads of discussion here and kjeep track of the history of the discussion, so sometimes I am just responding to what I read at face value. hence my comment about staff lines.

Status (old) active fixed

Fixed in branch master, commit 0c01f64438

fix #92901

fix #92901
SVG Export: Invisible measures not supported. Changes affect one block
of code in mscore/file.cpp. Now if there is an invisible measure within
a system/staff, that system/staff paints its staff lines by measure.

Fixed in branch master, commit 0c01f64438

fix #92901

fix #92901
SVG Export: Invisible measures not supported. Changes affect one block
of code in mscore/file.cpp. Now if there is an invisible measure within
a system/staff, that system/staff paints its staff lines by measure.

Fixed in branch 2.0.3, commit baf92bc699

fix #92901

fix #92901
SVG Export: Invisible measures not supported. Changes affect one block
of code in mscore/file.cpp. Now if there is an invisible measure within
a system/staff, that system/staff paints its staff lines by measure.

Fixed in branch 2.0.3, commit baf92bc699

fix #92901

fix #92901
SVG Export: Invisible measures not supported. Changes affect one block
of code in mscore/file.cpp. Now if there is an invisible measure within
a system/staff, that system/staff paints its staff lines by measure.