// ------------------// // isCompatibleWith // // ------------------// private boolean isCompatibleWith(SystemPoint point) { // Check x-proximity and y-alignment Scale scale = getSystem().getScale(); int dx = scale.toUnits(constants.maxDx); int dy = scale.toUnits(constants.maxDy); // Horizontal distance int xDist = Math.min(Math.abs(getBox().x - point.x), Math.abs((getBox().x + getBox().width) - point.x)); // Vertical distance int yDist = Math.abs(getReferencePoint().y - point.y); return (xDist <= dx) && (yDist <= dy); }
/** * Try to infer the role of this textual item. For the time being, this is a simple algorithm * based on sentence location within the page, augmented by valid chord name, etc. * * @param line the sentence * @param systemInfo the containing system * @return the role information inferred for the provided sentence glyph */ public static TextRoleInfo guessRole(TextLine line, SystemInfo systemInfo) { if (line == null) { return null; } if (line.isVip()) { logger.info("TextRoleInfo. guessRole for {}", line.getValue()); } int chordCount = 0; for (TextWord word : line.getWords()) { // At least one word/glyph with a role manually assigned Glyph glyph = word.getGlyph(); if (glyph != null) { if (glyph.getManualRole() != null) { return glyph.getManualRole(); } } // Word that could be a chord symbol? if (word.guessChordInfo() != null) { chordCount++; } } // Is line made entirely of potential chord symbols? boolean isAllChord = chordCount == line.getWords().size(); Rectangle box = line.getBounds(); if (box == null) { return null; } // Is line mainly in italic? boolean isMainlyItalic = systemInfo.getTextBuilder().isMainlyItalic(line); Sheet sheet = systemInfo.getSheet(); ScoreSystem system = systemInfo.getScoreSystem(); Scale scale = system.getScale(); Point left = new Point(box.x, box.y + (box.height / 2)); Point right = new Point(box.x + box.width, box.y + (box.height / 2)); // First system in page? boolean firstSystem = system.getId() == 1; // Last system in page? boolean lastSystem = sheet.getSystems().size() == system.getId(); // Vertical position wrt (system) staves StaffPosition systemPosition = system.getStaffPosition(left); // Vertical position wrt (part) staves SystemPart part = system.getPartAbove(left); StaffPosition partPosition = part.getStaffPosition(left); // Vertical distance from staff? Staff staff = system.getStaffAt(left); int staffDy = Math.abs(staff.getTopLeft().y - box.y); boolean closeToStaff = staffDy <= scale.toPixels(constants.maxStaffDy); // Begins on left side of the part? boolean leftOfStaves = system.isLeftOfStaves(left); // At the center of page width? int maxCenterDx = scale.toPixels(constants.maxCenterDx); int pageCenter = sheet.getWidth() / 2; boolean pageCentered = Math.abs((box.x + (box.width / 2)) - pageCenter) <= maxCenterDx; // Right aligned with staves? int maxRightDx = scale.toPixels(constants.maxRightDx); boolean rightAligned = Math.abs(right.x - system.getTopLeft().x - system.getDimension().width) <= maxRightDx; // Short Sentence? int maxShortLength = scale.toPixels(constants.maxShortLength); boolean shortSentence = box.width <= maxShortLength; // Tiny Sentence? int maxTinyLength = scale.toPixels(constants.maxTinyLength); boolean tinySentence = box.width <= maxTinyLength; // High text? int minTitleHeight = scale.toPixels(constants.minTitleHeight); boolean highText = box.height >= minTitleHeight; logger.debug( "{} firstSystem={} lastSystem={} systemPosition={}" + " partPosition={} closeToStaff={} leftOfStaves={}" + " pageCentered={} rightAligned={} shortSentence={}" + " highText={10}", box, firstSystem, lastSystem, systemPosition, partPosition, closeToStaff, leftOfStaves, pageCentered, rightAligned, shortSentence, highText); // Decisions ... switch (systemPosition) { case ABOVE_STAVES: // Title, Number, Creator, Direction, Chord if (tinySentence) { if (isAllChord) { return new TextRoleInfo(TextRole.Chord); } else { return new TextRoleInfo(TextRole.UnknownRole); } } if (firstSystem) { if (leftOfStaves) { return new TextRoleInfo(TextRole.Creator, Text.CreatorText.CreatorType.lyricist); } else if (rightAligned) { return new TextRoleInfo(TextRole.Creator, Text.CreatorText.CreatorType.composer); } else if (closeToStaff) { if (isAllChord) { return new TextRoleInfo(TextRole.Chord); } else { return new TextRoleInfo(TextRole.Direction); } } else if (pageCentered) { // Title, Number if (highText) { return new TextRoleInfo(TextRole.Title); } else { return new TextRoleInfo(TextRole.Number); } } } else { if (isAllChord) { return new TextRoleInfo(TextRole.Chord); } else { return new TextRoleInfo(TextRole.Direction); } } break; case WITHIN_STAVES: // Name, Lyrics, Direction if (leftOfStaves) { return new TextRoleInfo(TextRole.Name); } else if ((partPosition == StaffPosition.BELOW_STAVES) && !isMainlyItalic) { return new TextRoleInfo(TextRole.Lyrics); } else { return new TextRoleInfo(TextRole.Direction); } case BELOW_STAVES: // Copyright, Lyrics for single-staff part if (tinySentence) { return new TextRoleInfo(TextRole.UnknownRole); } if (pageCentered && shortSentence && lastSystem) { return new TextRoleInfo(TextRole.Rights); } if (part.getStaves().size() == 1) { if ((partPosition == StaffPosition.BELOW_STAVES) && !isMainlyItalic) { return new TextRoleInfo(TextRole.Lyrics); } } } // Default return new TextRoleInfo(TextRole.UnknownRole); }