use of com.xenoage.zong.core.music.beam.Beam in project Zong by Xenoage.
the class ScoreLayouter method createLayoutWithExceptions.
/**
* Computes the whole layout and returns it.
* If something fails, an exception is thrown.
*/
public ScoreLayout createLayoutWithExceptions() {
// notations of elements
Notations notations = notator.computeAll(context);
// compute optimal measure column spacings
List<ColumnSpacing> columns = columnsSpacer.compute(notations, context);
// break columns into systems and frames
FramesSpacing frames = framesSpacer.compute(columns, target, context, notations);
// system stretching (horizontal)
fillSystemsHorizontally(frames, target);
// frame filling (vertical)
fillFramesVertically(frames, target, context.score);
// compute beam spacings. these are computed only now, after the horizontal
// and vertical spacing of the score is fixed, since the beam slants depend on the
// exact spacings
Map<Beam, BeamSpacing> beams = beamsSpacer.compute(context.score, notations, frames);
// create score frame layouts from the collected information
List<ScoreFrameLayout> scoreFrameLayouts = createScoreFrameLayouts(frames, notations, context, beams);
// create score layout
return new ScoreLayout(context.score, scoreFrameLayouts, context.symbols, context.settings);
}
use of com.xenoage.zong.core.music.beam.Beam in project Zong by Xenoage.
the class ChordStamper method stampCore.
/**
* Draws the given chord, including noteheads, stem, flags, accidentals, dots,
* articulations and leger lines.
*/
public ChordStampings stampCore(ChordNotation chord, float chordXMm, StamperContext context) {
val staff = context.getCurrentStaffStamping();
Chord element = chord.element;
boolean grace = element.isGrace();
LayoutSettings settings = context.getSettings();
float scaling = (grace ? settings.scalingGrace : 1);
ChordWidths chordWidths = (grace ? settings.graceChordWidths : settings.chordWidths);
float leftNoteXMm = getLeftNoteXMm(chordXMm, chord.notes, staff.is);
// stem
StemStamping stem = stampStem(chord, leftNoteXMm, context);
// type of notehead
CommonSymbol noteheadSymbol = CommonSymbol.NoteWhole;
Duration.Type symbolType = Duration.INSTANCE.getNoteheadSymbolType(element.getDisplayedDuration());
if (symbolType == Duration.INSTANCE.Type.Half)
noteheadSymbol = CommonSymbol.NoteHalf;
else if (symbolType == Duration.INSTANCE.Type.Quarter)
noteheadSymbol = CommonSymbol.NoteQuarter;
// noteheads
NotesNotation notes = chord.notes;
NoteheadStamping[] noteheads = new NoteheadStamping[notes.getNotesCount()];
for (int iNote : range(noteheads)) {
NoteDisplacement note = notes.getNote(iNote);
Symbol noteSymbol = context.getSymbol(noteheadSymbol);
float noteXMm = getNoteheadXMm(leftNoteXMm + note.xIs * staff.is, scaling, staff, noteSymbol);
NoteheadStamping noteSt = new NoteheadStamping(chord, iNote, noteSymbol, Color.Companion.getBlack(), staff, sp(noteXMm, note.lp), scaling);
noteheads[iNote] = noteSt;
}
// flags (only drawn if there is no beam)
int flagsCount = Duration.INSTANCE.getFlagsCount(element.getDisplayedDuration());
Beam beam = element.getBeam();
StemDirection stemDir = chord.stemDirection;
FlagsStamping flags = null;
if (beam == null && flagsCount > 0 && chord.stem != null) /* can happen when no stem is used */
{
FlagsStamping.FlagsDirection flag = (stemDir == StemDirection.Up ? FlagsStamping.FlagsDirection.Down : FlagsStamping.FlagsDirection.Up);
Symbol flagSymbol = context.getSymbol(CommonSymbol.NoteFlag);
flags = new FlagsStamping(chord, staff, flag, flagsCount, flagSymbol, scaling, sp(leftNoteXMm + notes.stemOffsetIs * staff.is, chord.stem.endSlp.lp));
}
// accidentals
AccidentalsNotation accs = chord.accidentals;
AccidentalStamping[] accsSt = new AccidentalStamping[0];
if (accs != null) {
accsSt = new AccidentalStamping[accs.accidentals.length];
for (int iAcc : range(accsSt)) {
AccidentalDisplacement acc = accs.accidentals[iAcc];
AccidentalStamping accSt = new AccidentalStamping(chord, iAcc, staff, sp(chordXMm + (acc.xIs - chord.width.frontGap + 0.5f) * staff.is, acc.yLp), 1, context.getSymbol(CommonSymbol.getAccidental(acc.accidental)));
accsSt[iAcc] = accSt;
}
}
// dots
int[] dotPositions = notes.dotsLp;
int dotsPerNote = notes.getDotsPerNoteCount();
ProlongationDotStamping[] dots = new ProlongationDotStamping[dotPositions.length * dotsPerNote];
Symbol dotSymbol = context.getSymbol(CommonSymbol.NoteDot);
for (int iNote : range(dotPositions)) {
for (int iDot : range(dotsPerNote)) {
ProlongationDotStamping dotSt = new ProlongationDotStamping(chord, staff, dotSymbol, sp(leftNoteXMm + notes.getDotsOffsetIs(iDot) * staff.is, dotPositions[iNote]));
dots[iNote * dotsPerNote + iDot] = dotSt;
}
}
// articulations
ArticulationsNotation arts = chord.articulations;
ArticulationStamping[] artsSt = new ArticulationStamping[0];
if (arts != null) {
artsSt = new ArticulationStamping[arts.articulations.length];
float noteheadWidth = chordWidths.get(element.getDuration());
for (int iArt : range(artsSt)) {
ArticulationDisplacement art = arts.articulations[iArt];
ArticulationStamping artSt = new ArticulationStamping(chord, iArt, staff, sp(leftNoteXMm + (art.xIs + (noteheadWidth / 2)) * staff.is, art.yLp), 1, context.getSymbol(CommonSymbol.getArticulation(art.articulation)));
artsSt[iArt] = artSt;
}
}
// leger lines
LegerLineStamping[] legerLines = legerLinesStamper.stamp(chord, chordXMm, staff);
return new ChordStampings(element, chordXMm, staff, noteheads, dots, accsSt, legerLines, artsSt, flags, stem);
}
use of com.xenoage.zong.core.music.beam.Beam in project Zong by Xenoage.
the class BeamFragmenterTest method computeTest.
@Test
public void computeTest() {
ChlapikBeamFragments source = new ChlapikBeamFragments();
Beam b;
// example of row 1, column 1
b = source.exampleRow1Col1();
try {
// not working for 8th lines
testee.compute(b, 0, null);
fail();
} catch (IllegalArgumentException ex) {
// ok
}
Fragments wp = testee.compute(b, 2, null);
// 32th
assertEqualsList(wp, None, None, None);
// 16th
assertEqualsList(testee.compute(b, 1, wp), HookRight, None, HookLeft);
// example of row 1, column 2
b = source.exampleRow1Col2();
// 16th
assertEqualsList(testee.compute(b, 1, null), HookRight, None, HookLeft);
// example of row 1, column 3
b = source.exampleRow1Col3();
// 16th
assertEqualsList(testee.compute(b, 1, null), HookRight, None, None, HookLeft);
// example of row 1, column 4
b = source.exampleRow1Col4();
// 16th
assertEqualsList(testee.compute(b, 1, null), HookRight, None, None, HookLeft);
// example of row 2, column 1
b = source.exampleRow2Col1();
// 16th
assertEqualsList(testee.compute(b, 1, null), None, HookLeft);
// example of row 2, column 2
b = source.exampleRow2Col2();
// 16th
assertEqualsList(testee.compute(b, 1, null), None, HookLeft);
// example of row 2, column 3
b = source.exampleRow2Col3();
wp = testee.compute(b, 2, null);
// 32th
assertEqualsList(wp, None, HookLeft, None, HookLeft);
// 16th
assertEqualsList(testee.compute(b, 1, wp), Start, None, None, Stop);
// example of row 2, column 4
b = source.exampleRow2Col4();
wp = testee.compute(b, 2, null);
// 32th
assertEqualsList(wp, None, HookLeft, None, HookLeft);
// 16th
assertEqualsList(testee.compute(b, 1, wp), Start, None, None, Stop);
// example of row 3, column 2
b = source.exampleRow3Col2();
// 16th
assertEqualsList(testee.compute(b, 1, null), HookRight, None, HookLeft, None);
// example of row 3, column 4
b = source.exampleRow3Col4();
// 16th
assertEqualsList(testee.compute(b, 1, null), None, HookRight, None);
// example of row 3, column 6
b = source.exampleRow3Col6();
wp = testee.compute(b, 2, null);
// 32th
assertEqualsList(wp, None, HookLeft, None, HookLeft);
// 16th
assertEqualsList(testee.compute(b, 1, wp), None, HookLeft, Start, Stop);
}
use of com.xenoage.zong.core.music.beam.Beam in project Zong by Xenoage.
the class Test24a method testBeams.
@Test
public void testBeams() {
Staff staff = getFirstStaff();
int iChord = 0;
Beam currentBeam = null;
for (int iM = 0; iM < staff.getMeasures().size(); iM++) {
Voice voice = staff.getMeasure(iM).getVoice(0);
for (VoiceElement e : voice.getElements()) {
Chord expectedChord = expectedChords[iChord];
// beams between chord 2 and 3 and between 11 and 12
if (iChord == 2 || iChord == 11) {
assertNotNull("chord " + iChord + " unbeamed", expectedChord.getBeam());
assertEquals("chord " + iChord, WaypointPosition.Start, expectedChord.getBeam().getWaypointPosition(expectedChord));
currentBeam = expectedChord.getBeam();
} else if (iChord == 3 || iChord == 12) {
assertNotNull("chord " + iChord + " unbeamed", expectedChord.getBeam());
assertEquals("wrong beam", currentBeam, expectedChord.getBeam());
assertEquals("chord " + iChord, WaypointPosition.Stop, expectedChord.getBeam().getWaypointPosition(expectedChord));
currentBeam = null;
} else {
assertNull("chord " + iChord + " beamed", expectedChord.getBeam());
}
iChord++;
}
}
assertEquals("not all chords found", expectedChords.length, iChord);
}
use of com.xenoage.zong.core.music.beam.Beam in project Zong by Xenoage.
the class StemDirector method compute.
/**
* Computes the {@link StemDirection} of the given chord (and maybe connected
* ones) and returns them. The chord must be part of a score.
*/
public Map<Chord, StemDirection> compute(Chord chord) {
Map<Chord, StemDirection> ret = map();
Beam beam = chord.getBeam();
Score score = chord.getScore();
if (beam != null) {
// compute stem directions for all chords of the beam
StemDirection[] beamedStems = beamedStemDirector.compute(beam, score);
for (int iChord : range(beam.size())) ret.put(beam.getChord(iChord), beamedStems[iChord]);
} else {
// compute stem direction for single chord
MP mp = MP.getMP(chord);
StemDirection stem = singleStemDirector.compute(chord, score.getMusicContext(mp, BeforeOrAt, Before));
ret.put(chord, stem);
}
// but it was bad and outdated, so we removed it.
return ret;
}
Aggregations