use of com.xenoage.zong.musiclayout.stampings.BeamStamping in project Zong by Xenoage.
the class BeamStamper method stamp.
/**
* Computes the stampings for the given beam and returns them.
* @param beam the beam to stamp
* @param staff the staff stamping of the first chord of the beam
*/
public List<BeamStamping> stamp(BeamSpacing beam, StaffStamping staff) {
int beamSize = beam.chords.size();
val leftEndSp = beam.getLeftSp();
val rightEndSp = beam.getRightSp();
val primaryStemDir = beam.getStemDirection(0);
// number of beam lines
int linesCount = beam.notation.getLinesCount();
// first guess of the size (is correct for simple beams)
List<BeamStamping> ret = alist(linesCount);
// first line (8th line) is always continuous
val beam8th = new BeamStamping(beam, staff, leftEndSp, rightEndSp, primaryStemDir);
ret.add(beam8th);
// this is stored in the notation
for (int i : range(beam.notation.linesFragments)) {
int line = i + 1;
float lineLp = -1 * primaryStemDir.getSign() * (lineHeightIs + beam.notation.gapIs) * 2 * line;
val beamLinePoints = new LinearInterpolationPoints(leftEndSp.lp + lineLp, rightEndSp.lp + lineLp, leftEndSp.xMm, rightEndSp.xMm);
// create the line stampings
float startXMm = 0;
Fragments fragments = beam.notation.linesFragments.get(i);
for (int iChord : range(fragments)) {
Fragment fragment = fragments.get(iChord);
float stemXMm = beam.getStemEndSp(iChord).xMm;
if (fragment == Start) {
// begin a new beam line
startXMm = stemXMm;
} else if (fragment == Stop) {
// end the beam line and stem it
float stopXMm = stemXMm;
SP leftSp = sp(startXMm, INSTANCE.interpolateLinear(beamLinePoints, startXMm));
SP rightSp = sp(stopXMm, INSTANCE.interpolateLinear(beamLinePoints, stopXMm));
val stamping = new BeamStamping(beam, staff, leftSp, rightSp, primaryStemDir);
ret.add(stamping);
} else if (fragment == HookLeft || fragment == HookRight) {
// left or right hook
float lengthMm = hookLengthIs * staff.is;
float x1Mm = (fragment == HookLeft ? stemXMm - lengthMm : stemXMm);
float x2Mm = (fragment == HookLeft ? stemXMm : stemXMm + lengthMm);
SP leftSp = sp(x1Mm, INSTANCE.interpolateLinear(beamLinePoints, x1Mm));
SP rightSp = sp(x2Mm, INSTANCE.interpolateLinear(beamLinePoints, x2Mm));
val stamping = new BeamStamping(beam, staff, leftSp, rightSp, primaryStemDir);
ret.add(stamping);
}
}
}
return ret;
}
use of com.xenoage.zong.musiclayout.stampings.BeamStamping in project Zong by Xenoage.
the class BeamRenderer method draw.
/**
* Draws the given {@link BeamStamping} on the given {@link Canvas},
* using the given {@link RendererArgs}.
*/
@Override
public void draw(Stamping stamping, Canvas canvas, RendererArgs args) {
BeamStamping beam = (BeamStamping) stamping;
StaffStamping staff = beam.staff;
float scaling = args.targetScaling;
// TODO: stem should be thinner than lineWidth?
float stemWidthMm = staff.getLineWidthMm();
float x1Mm = staff.positionMm.x + beam.sp1.xMm - stemWidthMm / 2f;
float x2Mm = staff.positionMm.x + beam.sp2.xMm + stemWidthMm / 2f;
Color color = Color.Companion.getBlack();
float leftYStart, rightYStart, beamHeightMm;
if (canvas.getFormat() == CanvasFormat.Raster) {
// render on screen
float staffYPos = staff.positionMm.y;
BitmapStaff screenStaff = staff.getBitmapInfo().getBitmapStaff(scaling);
leftYStart = staffYPos + screenStaff.getYMm(beam.sp1.lp);
rightYStart = staffYPos + screenStaff.getYMm(beam.sp2.lp);
beamHeightMm = BeamNotation.lineHeightIs * screenStaff.interlineSpaceMm;
} else {
leftYStart = staff.computeYMm(beam.sp1.lp);
rightYStart = staff.computeYMm(beam.sp2.lp);
beamHeightMm = BeamNotation.lineHeightIs * staff.is;
}
// TODO: avoid edges at the stem end points
// beam sits on or hangs from the vertical position, dependent on stem direction
float vAdd = (beam.stemDir.getSign() - 1) / 2f * beamHeightMm;
Point2f sw = new Point2f(x1Mm, leftYStart + vAdd);
Point2f nw = new Point2f(x1Mm, sw.y + beamHeightMm);
Point2f se = new Point2f(x2Mm, rightYStart + vAdd);
Point2f ne = new Point2f(x2Mm, se.y + beamHeightMm);
List<PathElement> elements = alist(4);
elements.add(new MoveTo(sw));
elements.add(new LineTo(nw));
elements.add(new LineTo(ne));
elements.add(new LineTo(se));
elements.add(new ClosePath());
Path path = new Path(elements);
canvas.fillPath(path, color);
}
Aggregations