//----------------------------------------------------------------------------//
// //
// A r t i c u l a t i o n P a t t e r n //
// //
//----------------------------------------------------------------------------//
// <editor-fold defaultstate="collapsed" desc="hdr"> //
// Copyright © Hervé Bitteur and others 2000-2013. All rights reserved. //
// This software is released under the GNU General Public License. //
// Goto http://kenai.com/projects/audiveris to report bugs or suggestions. //
//----------------------------------------------------------------------------//
// </editor-fold>
package omr.glyph.pattern;
import omr.constant.ConstantSet;
import omr.glyph.Evaluation;
import omr.glyph.Glyphs;
import omr.glyph.Shape;
import omr.glyph.ShapeSet;
import omr.glyph.facets.Glyph;
import omr.grid.StaffInfo;
import omr.sheet.NotePosition;
import omr.sheet.Scale;
import omr.sheet.SystemInfo;
import omr.util.Predicate;
import omr.util.VerticalSide;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.awt.Point;
import java.awt.Rectangle;
import java.util.List;
/**
* Class {@code ArticulationPattern} verifies that any articulation
* glyph has corresponding note(s) below or above in the staff.
*
* @author Hervé Bitteur
*/
public class ArticulationPattern
extends GlyphPattern
{
//~ Static fields/initializers ---------------------------------------------
/** Specific application parameters */
private static final Constants constants = new Constants();
/** Usual logger utility */
private static final Logger logger = LoggerFactory.getLogger(
ArticulationPattern.class);
//~ Constructors -----------------------------------------------------------
//---------------------//
// ArticulationPattern //
//---------------------//
/**
* Creates a new ArticulationPattern object.
*
* @param system the system to process
*/
public ArticulationPattern (SystemInfo system)
{
super("Articulation", system);
}
//~ Methods ----------------------------------------------------------------
//------------//
// runPattern //
//------------//
@Override
public int runPattern ()
{
int xMargin = system.getSheet()
.getScale()
.toPixels(constants.xMargin);
int nb = 0;
for (Glyph glyph : system.getGlyphs()) {
if (!ShapeSet.Articulations.contains(glyph.getShape())
|| glyph.isManualShape()) {
continue;
}
Point center = glyph.getAreaCenter();
NotePosition pos = system.getNoteStaffAt(center);
StaffInfo staff = pos.getStaff();
Rectangle box = glyph.getBounds();
// Extend height till end of staff area
double topLimit = staff.getLimitAtX(VerticalSide.TOP, center.x);
double botLimit = staff.getLimitAtX(VerticalSide.BOTTOM, center.x);
box.y = (int) Math.rint(topLimit);
box.height = (int) Math.rint(botLimit) - box.y;
box.grow(xMargin, 0);
List<Glyph> glyphs = system.lookupIntersectedGlyphs(box, glyph);
boolean hasNote = Glyphs.contains(
glyphs,
new Predicate<Glyph>()
{
@Override
public boolean check (Glyph entity)
{
Shape shape = entity.getShape();
return ShapeSet.NoteHeads.contains(shape)
|| ShapeSet.Notes.contains(shape)
|| ShapeSet.Rests.contains(shape);
}
});
if (!hasNote) {
logger.debug("Deassign articulation {}", glyph.idString());
glyph.setShape(null, Evaluation.ALGORITHM);
nb++;
}
}
return nb;
}
//~ Inner Classes ----------------------------------------------------------
//-----------//
// Constants //
//-----------//
private static final class Constants
extends ConstantSet
{
//~ Instance fields ----------------------------------------------------
Scale.Fraction xMargin = new Scale.Fraction(
0.5,
"Abscissa margin around articulation");
}
}