use of com.xenoage.utils.math.geom.Point2f in project Zong by Xenoage.
the class WedgeRenderer method draw.
/**
* Draws the given {@link WedgeStamping} on the given {@link Canvas},
* using the given {@link RendererArgs}.
*/
@Override
public void draw(Stamping stamping, Canvas canvas, RendererArgs args) {
WedgeStamping wedge = (WedgeStamping) stamping;
StaffStamping parentStaff = wedge.parentStaff;
float scaling = args.scaling;
// horizontal position
float x1Mm = wedge.leftXMm + parentStaff.positionMm.x;
float x2Mm = wedge.rightXMm + parentStaff.positionMm.x;
// compute vertical distances at the start and end point
float d1Mm = wedge.leftDistanceIs * parentStaff.is;
float d2Mm = wedge.rightDistanceIs * parentStaff.is;
// width and color of the line
Color color = Color.Companion.getBlack();
// like staff line
float width = parentStaff.getLineWidthMm();
float paintWidth;
// compute the horizontal line and color
float yMm;
Color paintColor;
if (canvas.getFormat() == CanvasFormat.Raster) {
BitmapStaff ss = parentStaff.getBitmapInfo().getBitmapStaff(scaling);
yMm = parentStaff.positionMm.y + ss.getYMm(wedge.lp);
BitmapLine screenLine = parentStaff.getBitmapInfo().getBitmapLine(scaling, width, color);
paintColor = screenLine.color;
paintWidth = screenLine.widthMm;
} else {
yMm = parentStaff.computeYMm(wedge.lp);
paintColor = color;
paintWidth = width;
}
// draw lines
canvas.drawLine(new Point2f(x1Mm, yMm - d1Mm / 2), new Point2f(x2Mm, yMm - d2Mm / 2), paintColor, paintWidth);
canvas.drawLine(new Point2f(x1Mm, yMm + d1Mm / 2), new Point2f(x2Mm, yMm + d2Mm / 2), paintColor, paintWidth);
}
use of com.xenoage.utils.math.geom.Point2f in project Zong by Xenoage.
the class GwtCanvas method drawText.
/**
* {@inheritDoc}
* The text selection is ignored.
*/
@Override
public void drawText(FormattedText text, TextSelection selection, Point2f position, boolean yIsBaseline, float frameWidth) {
context.save();
context.translate(position.x, position.y);
// print the text frame paragraph for paragraph
float offsetX = 0;
float offsetY = 0;
for (FormattedTextParagraph p : text.getParagraphs()) {
TextMetrics pMetrics = p.getMetrics();
if (!yIsBaseline)
offsetY += pMetrics.getAscent();
// adjustment
if (p.getAlignment() == Alignment.Center)
offsetX = (frameWidth - pMetrics.getWidth()) / 2;
else if (p.getAlignment() == Alignment.Right)
offsetX = frameWidth - pMetrics.getWidth();
else
offsetX = 0;
// draw elements
for (FormattedTextElement e : p.getElements()) {
if (e instanceof FormattedTextString) {
FormattedTextString t = (FormattedTextString) e;
context.setFillStyle(GwtColorUtils.createColor(t.getStyle().getColor()));
context.save();
context.scale(Units.pxToMm_1_1, Units.pxToMm_1_1);
context.setFont(GwtFontUtils.getCssFont(t.getStyle().getFont()));
context.fillText(t.getText(), offsetX / Units.pxToMm_1_1, offsetY / Units.pxToMm_1_1);
// Debug: Paint dot at text offset
// context.fillRect(offsetX / Units.pxToMm_1_1, offsetY / Units.pxToMm_1_1, 2, 2);
context.restore();
} else {
// symbol
FormattedTextSymbol fts = (FormattedTextSymbol) e;
float scaling = fts.getScaling();
SymbolsRenderer.draw(fts.getSymbol(), this, Color.black, new Point2f(offsetX + fts.getOffsetX(), offsetY + fts.getSymbol().baselineOffset * scaling), new Point2f(scaling, scaling));
}
offsetX += e.getMetrics().getWidth();
}
// next line
offsetY += p.getMetrics().getAscent() + p.getMetrics().getDescent() + p.getMetrics().getLeading();
}
context.restore();
}
use of com.xenoage.utils.math.geom.Point2f in project Zong by Xenoage.
the class CursorOutput method write.
public JsonObject write(ScoreDoc doc) {
JsonObject ret = new JsonObject();
// create midi sequence and mp mappings
Score score = doc.getScore();
val seq = MidiConverter.convertToSequence(score, optionsForFileExport, new JseMidiSequenceWriter());
// save time map
JsonArray jsonMPs = new JsonArray();
val timeMap = seq.getTimeMap();
for (int iRep : range(timeMap.getRepetitionsCount())) {
for (val time : timeMap.getTimesSorted(iRep)) {
val midiTime = timeMap.getByRepTime(iRep, time);
JsonObject jsonMP = new JsonObject();
jsonMP.addProperty("measure", time.measure);
jsonMP.addProperty("beat", "" + time.beat);
jsonMP.addProperty("ms", midiTime.ms);
jsonMPs.add(jsonMP);
}
}
ret.add("mps", jsonMPs);
// collect data
int measuresCount = score.getMeasuresCount();
ArrayList<System> systems = new ArrayList<>();
ArrayList<Measure> measures = new ArrayList<>();
for (int i = 0; i < measuresCount; i++) {
measures.add(new Measure());
}
int systemCount = 0;
Layout layout = doc.getLayout();
for (int iPage : range(layout.getPages())) {
Page page = layout.getPages().get(iPage);
Size2f pageSize = page.getFormat().getSize();
for (Frame frame : page.getFrames()) {
if (frame instanceof ScoreFrame) {
Point2f absPos = frame.getAbsolutePosition();
float offsetX = absPos.x - frame.getSize().width / 2;
float offsetY = absPos.y - frame.getSize().height / 2;
ScoreFrameLayout sfl = ((ScoreFrame) frame).getScoreFrameLayout();
for (SystemSpacing systemSpacing : sfl.getFrameSpacing().getSystems()) {
// read system data
int systemIndex = systemCount + systemSpacing.getSystemIndexInFrame();
while (systems.size() - 1 < systemIndex) systems.add(new System());
System system = systems.get(systemIndex);
system.page = iPage;
system.top = (offsetY + systemSpacing.offsetYMm) / pageSize.height;
system.bottom = (offsetY + systemSpacing.offsetYMm + systemSpacing.getHeightMm()) / pageSize.height;
// read measure beats
float systemOffsetX = systemSpacing.marginLeftMm;
for (int iMeasure : systemSpacing.getMeasures()) {
Measure measure = measures.get(iMeasure);
measure.system = systemIndex;
measure.left = (offsetX + systemOffsetX + systemSpacing.getMeasureStartMm(iMeasure)) / pageSize.width;
measure.right = (offsetX + systemOffsetX + systemSpacing.getMeasureEndMm(iMeasure)) / pageSize.width;
for (BeatOffset bo : systemSpacing.getColumn(iMeasure).getBeatOffsets()) {
measure.beats.put(bo.getBeat(), (offsetX + systemOffsetX + bo.getOffsetMm()) / pageSize.width);
}
}
}
systemCount += sfl.getFrameSpacing().getSystems().size();
}
}
}
// save systems
JsonArray jsonSystems = new JsonArray();
for (int i = 0; i < systems.size(); i++) {
System system = systems.get(i);
JsonObject jsonSystem = new JsonObject();
jsonSystem.addProperty("number", i);
jsonSystem.addProperty("page", system.page);
jsonSystem.addProperty("top", system.top);
jsonSystem.addProperty("bottom", system.bottom);
jsonSystems.add(jsonSystem);
}
ret.add("systems", jsonSystems);
// save measures
JsonArray jsonMeasures = new JsonArray();
for (int i = 0; i < measuresCount; i++) {
Measure measure = measures.get(i);
JsonObject jsonMeasure = new JsonObject();
jsonMeasure.addProperty("number", i);
jsonMeasure.addProperty("system", measure.system);
jsonMeasure.addProperty("left", measure.left);
jsonMeasure.addProperty("right", measure.right);
// beats
JsonArray jsonBeats = new JsonArray();
ArrayList<Fraction> sortedBeats = new ArrayList<>(measure.beats.keySet());
Collections.sort(sortedBeats);
for (Fraction beat : sortedBeats) {
JsonObject jsonBeat = new JsonObject();
jsonBeat.addProperty("at", "" + beat);
jsonBeat.addProperty("x", measure.beats.get(beat));
jsonBeats.add(jsonBeat);
}
jsonMeasure.add("beats", jsonBeats);
jsonMeasures.add(jsonMeasure);
}
ret.add("measures", jsonMeasures);
// save time cursors
JsonArray jsonTCs = new JsonArray();
for (int iRep : range(timeMap.getRepetitionsCount())) {
for (val time : timeMap.getTimesSorted(iRep)) {
val midiTime = timeMap.getByRepTime(iRep, time);
JsonObject jsonTC = new JsonObject();
jsonTC.addProperty("time", midiTime.ms);
Measure measure = measures.get(time.measure);
System system = systems.get(measure.system);
jsonTC.addProperty("page", system.page);
jsonTC.addProperty("top", system.top);
jsonTC.addProperty("left", measure.beats.get(time.beat));
jsonTC.addProperty("bottom", system.bottom);
jsonTCs.add(jsonTC);
}
}
ret.add("timecursors", jsonTCs);
return ret;
}
use of com.xenoage.utils.math.geom.Point2f in project Zong by Xenoage.
the class ScoreDocFactory method read.
/**
* Creates a {@link ScoreDoc} instance from the given score.
* TIDY: move elsewhere, e.g. in a ScoreDocFactory class
*/
public ScoreDoc read(Score score) throws InvalidFormatException, IOException {
// page format
LayoutFormat layoutFormat = Companion.getDefaultLayoutFormat();
Object oLayoutFormat = score.getMetaData().get("layoutformat");
if (oLayoutFormat instanceof LayoutFormat) {
layoutFormat = (LayoutFormat) oLayoutFormat;
}
LayoutDefaults layoutDefaults = new LayoutDefaults(layoutFormat);
// create the document
ScoreDoc ret = new ScoreDoc(score, layoutDefaults);
Layout layout = ret.getLayout();
// layout basics
PageFormat pageFormat = layoutFormat.getPageFormat(0);
Size2f frameSize = new Size2f(pageFormat.getUseableWidth(), pageFormat.getUseableHeight());
Point2f framePos = new Point2f(pageFormat.getMargins().getLeft() + frameSize.width / 2, pageFormat.getMargins().getTop() + frameSize.height / 2);
// layout the score to find out the needed space
Target target = Target.completeLayoutTarget(new ScoreLayoutArea(frameSize));
ScoreLayouter layouter = new ScoreLayouter(ret, target);
ScoreLayout scoreLayout = isErrorLayoutEnabled ? layouter.createScoreLayout() : layouter.createLayoutWithExceptions();
// create and fill at least one page
if (scoreLayout.frames.size() > 0) {
// normal layout: one frame per page
ScoreFrameChain chain = null;
for (int i = 0; i < scoreLayout.frames.size(); i++) {
Page page = new Page(pageFormat);
layout.addPage(page);
ScoreFrame frame = new ScoreFrame();
frame.setPosition(framePos);
frame.setSize(frameSize);
// TEST frame = frame.withHFill(NoHorizontalSystemFillingStrategy.getInstance());
page.addFrame(frame);
if (chain == null) {
chain = new ScoreFrameChain(score);
chain.setScoreLayout(scoreLayout);
}
chain.add(frame);
}
} else {
// no frames: create a single empty page
Page page = new Page(pageFormat);
layout.addPage(page);
}
return ret;
}
use of com.xenoage.utils.math.geom.Point2f in project Zong by Xenoage.
the class SvgPathReader method read.
/**
* Creates a path from the given d attribute value of a SVG path element.
* The type of the path is implementation dependent.
* The path and its bounding rect is returned.
*/
public Path read() {
// parse commands
char tokenChar = '?';
String token = getNextToken();
Point2f p, cp1, cp2;
float x, y;
while (token != null) {
char nextTokenChar = token.charAt(0);
if (Character.isDigit(nextTokenChar) || nextTokenChar == '-' || nextTokenChar == '+') {
// number. reuse last command (if not 'M' or 'm' - then it is 'L' or 'l'. see SVG spec)
pos -= token.length();
if (tokenChar == 'M')
tokenChar = 'L';
else if (tokenChar == 'm')
tokenChar = 'l';
} else {
// next command
tokenChar = nextTokenChar;
}
switch(tokenChar) {
// MoveTo (absolute)
case 'M':
p = readPointAbs();
moveTo(p);
break;
// MoveTo (relative)
case 'm':
p = readPointRel();
moveTo(pCurrent.add(p));
break;
// ClosePath
case 'Z':
case 'z':
closePath();
break;
// LineTo (absolute)
case 'L':
p = readPointAbs();
lineTo(p);
break;
// LineTo (relative)
case 'l':
p = readPointRel();
lineTo(pCurrent.add(p));
break;
// Horizontal LineTo (absolute)
case 'H':
x = readCoordAbs();
lineTo(p(x, pCurrent.y));
break;
// Horizontal LineTo (relative)
case 'h':
x = readCoordRel();
lineTo(p(pCurrent.x + x, pCurrent.y));
break;
// Vertical LineTo (absolute)
case 'V':
y = readCoordAbs();
lineTo(p(pCurrent.x, y));
break;
// Vertical LineTo (relative)
case 'v':
y = readCoordRel();
lineTo(p(pCurrent.x, pCurrent.y + y));
break;
// Cubic CurveTo (absolute)
case 'C':
cp1 = readPointAbs();
cp2 = readPointAbs();
p = readPointAbs();
cubicCurveTo(cp1, cp2, p);
break;
// Cubic CurveTo (relative)
case 'c':
cp1 = readPointRel();
cp2 = readPointRel();
p = readPointRel();
cubicCurveTo(pCurrent.add(cp1), pCurrent.add(cp2), pCurrent.add(p));
break;
// Quadratic CurveTo (absolute)
case 'Q':
cp1 = readPointAbs();
p = readPointAbs();
quadraticCurveTo(cp1, p);
break;
// Quadratic CurveTo (relative)
case 'q':
cp1 = readPointRel();
p = readPointRel();
quadraticCurveTo(pCurrent.add(cp1), pCurrent.add(p));
break;
// not implemented commands
case 'T':
case 't':
case 'S':
case 's':
case 'A':
case 'a':
throw new IllegalStateException("SVG command \"" + token + "\" not implemented yet.");
// unknown command
default:
throw new IllegalStateException("Unknown SVG command: \"" + token + "\"");
}
token = getNextToken();
}
return new Path(elements);
}
Aggregations