package com.xenoage.zong.renderer.stamping;
import com.xenoage.utils.color.Color;
import com.xenoage.utils.math.geom.Point2f;
import com.xenoage.zong.core.music.group.BracketGroup;
import com.xenoage.zong.musiclayout.stampings.BracketStamping;
import com.xenoage.zong.musiclayout.stampings.StaffStamping;
import com.xenoage.zong.musiclayout.stampings.Stamping;
import com.xenoage.zong.musiclayout.stampings.bitmap.BitmapStaff;
import com.xenoage.zong.renderer.RendererArgs;
import com.xenoage.zong.renderer.canvas.Canvas;
import com.xenoage.zong.renderer.canvas.CanvasFormat;
import com.xenoage.zong.renderer.symbol.SymbolsRenderer;
import com.xenoage.zong.symbols.Symbol;
import com.xenoage.zong.symbols.common.CommonSymbol;
import static com.xenoage.utils.math.geom.Point2f.p;
/**
* Renderer for a bracket stamping.
*
* At the moment braces and square brackets
* are supported.
*
* @author Andreas Wenger
*/
public class BracketRenderer
extends StampingRenderer {
/**
* Draws the given {@link BracketStamping} on the given {@link Canvas},
* using the given {@link RendererArgs}.
*/
@Override public void draw(Stamping stamping, Canvas canvas, RendererArgs args) {
BracketStamping bracket = (BracketStamping) stamping;
BracketGroup.Style style = bracket.groupStyle;
if (style == null || style == BracketGroup.Style.Brace) {
paintBrace(bracket, canvas, args);
}
else if (style == BracketGroup.Style.Bracket) {
paintBracket(bracket, canvas, args);
}
}
/**
* Draws a brace, using the given bracket stamping and rendering parameters.
*/
private static void paintBrace(BracketStamping bracket, Canvas canvas, RendererArgs args) {
float interlineSpace = bracket.firstStaff.is;
float y1 = getStaffTopY(bracket.firstStaff, canvas, args);
float y2 = getStaffBottomY(bracket.lastStaff, canvas, args);
Point2f pCenter = new Point2f(bracket.xMm, (y1 + y2) / 2);
Symbol braceSymbol = args.symbolPool.getSymbol(CommonSymbol.BracketBrace);
float symbolScaling = (y2 - y1) / braceSymbol.boundingRect.size.height;
SymbolsRenderer.draw(braceSymbol, canvas, Color.black, pCenter,
new Point2f(interlineSpace * 1.2f, symbolScaling));
}
/**
* Draws a bracket, using the given bracket stamping and rendering parameters.
*/
private static void paintBracket(BracketStamping bracket, Canvas canvas, RendererArgs args) {
float interlineSpace = bracket.firstStaff.is;
float y1 = getStaffTopY(bracket.firstStaff, canvas, args);
float y2 = getStaffBottomY(bracket.lastStaff, canvas, args);
Point2f p1Mm = new Point2f(bracket.xMm, y1);
Symbol bracketLineSymbol = args.symbolPool.getSymbol(CommonSymbol.BracketBracketLine);
Symbol bracketEndSymbol = args.symbolPool.getSymbol(CommonSymbol.BracketBracketEnd);
float lineYCorrection = bracketEndSymbol.boundingRect.size.height / 2; //to avoid gaps
float lineYScaling = (y2 - y1 + lineYCorrection) / bracketLineSymbol.boundingRect.size.height;
SymbolsRenderer.draw(bracketLineSymbol, canvas, Color.black, p(p1Mm.x, p1Mm.y - lineYCorrection / 2),
new Point2f(interlineSpace, lineYScaling));
SymbolsRenderer.draw(bracketEndSymbol, canvas, Color.black, p1Mm, new Point2f(interlineSpace,
-interlineSpace));
p1Mm = new Point2f(p1Mm.x, y2);
SymbolsRenderer.draw(bracketEndSymbol, canvas, Color.black, p1Mm, new Point2f(interlineSpace,
interlineSpace));
}
/**
* Gets the vertical position in px of the topmost line
* of the given staff.
* TIDY: move into other class?
*/
private static float getStaffTopY(StaffStamping staff, Canvas canvas, RendererArgs args) {
float scaling = args.targetScaling;
float ret = staff.positionMm.y;
if (canvas.getFormat() == CanvasFormat.Raster) {
//render on screen
BitmapStaff screenStaff = staff.getBitmapInfo().getBitmapStaff(scaling);
ret += screenStaff.yOffsetMm;
}
return ret;
}
/**
* Gets the vertical position in px of the lowest line
* of the given staff.
* TIDY: move into other class?
*/
private static float getStaffBottomY(StaffStamping staff, Canvas canvas, RendererArgs args) {
float scaling = args.targetScaling;
if (canvas.getFormat() == CanvasFormat.Raster) {
//render on screen
BitmapStaff screenStaff = staff.getBitmapInfo().getBitmapStaff(scaling);
return staff.positionMm.y + screenStaff.lp0Mm;
}
else if (canvas.getFormat() == CanvasFormat.Vector) {
//render with high quality
return staff.positionMm.y + staff.is * (staff.linesCount - 1) + staff.getLineWidthMm();
}
return 0;
}
}