0xfe/vexflow — Issue #37: ModifierContext x shift computation faulty for two different clefs, or multiple keys in a StaveNote
Author: rubiety
Created: 2011-11-26 02:43:18+00:00
State: open

I discovered this when trying to build a way to consistently render a chord. The chord will consist of two StaveNotes - one for treble clef, and one for bass clef - and within each StaveNote is two keys (I'm basically showing a piano voicing for a Jazz chord).

I'm using a ModifierContext in attempting to get all four keys to line up properly, regardless of which keys have accidentals, in either of the two StaveNotes. Ideally I'd like for all four keys to share the same stem too, but really I just want to get them lined up.

In tracing through the code I found that Vex.Flow.ModifierContext.prototype.formatNotes is what attempts to set x_shifts on notes to get them to line up. The conditional that ultimately decides whether to set the x_shift at all is:

```javascript
if (top_keys[0].line <= (bottom_keys[bottom_keys.length - 1].line + 0.5)) {
```

## There are two problems with this:
### Assuming First Key
It's only considering the first key in each StaveNote, which may not make sense. It sounds like you really want the minimum or maximum line value for all keys within a StaveNote, no? I guess as long as the keys are ordered properly it doesn't necessary matter, since it's assuming the first and last respectively. There's even a TODO comment above it that seems to suggest this:

```javascript
// XXX: Do this right (by key, not whole note).
```

### Assuming Same Clef
The comparison of the line value makes sense *within* a given clef, but not across clefs. So in my case it's looking at a top_note in treble clef and a bottom_note in bass clef, yet their "line" values are only really specific to that particular clef. So my case is failing the conditional even though in reality it should be passing and setting setting that x shift on the bottom note. It sounds like we really should be comparing line values based off some sort of clef line offset.

Once I get some time and can dig more into VexFlow (and get a local development environment set up) I might try to fix this myself, but in case it's a fairly easy fix for any of the core developers I'm reporting it here. I think a fix here would do a lot to solve formatting issues with chords spanning clefs, with multiple keys each.