From 4452b1b46b9d434054cffbff46344cdf22fe747a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Bitteur?= Date: Mon, 8 Jan 2024 10:18:31 +0100 Subject: [PATCH] Bugfix for StaffEditor: Change in staff indentation can impact sheet/score paging --- src/main/org/audiveris/omr/sheet/Sheet.java | 15 ++- .../org/audiveris/omr/sheet/SystemInfo.java | 41 +++--- .../audiveris/omr/sheet/SystemManager.java | 119 ++++++++++++------ .../audiveris/omr/sheet/ui/StaffEditor.java | 19 ++- 4 files changed, 127 insertions(+), 67 deletions(-) diff --git a/src/main/org/audiveris/omr/sheet/Sheet.java b/src/main/org/audiveris/omr/sheet/Sheet.java index eeeb14fb5..57b4dc5e1 100644 --- a/src/main/org/audiveris/omr/sheet/Sheet.java +++ b/src/main/org/audiveris/omr/sheet/Sheet.java @@ -536,9 +536,7 @@ private boolean checkShapesRenamed () case FLAG_3_UP -> modified |= inter.renameShapeAs(Shape.FLAG_3_DOWN); case FLAG_4_UP -> modified |= inter.renameShapeAs(Shape.FLAG_4_DOWN); case FLAG_5_UP -> modified |= inter.renameShapeAs(Shape.FLAG_5_DOWN); - default -> - { - } + default -> {} } } } @@ -560,6 +558,17 @@ public Rectangle clamp (Rectangle rect) return picture.clamp(rect); } + //------------// + // clearPages // + //------------// + /** + * Remove all pages in this sheet. + */ + public void clearPages () + { + pages.clear(); + } + //------------------// // createBinaryView // //------------------// diff --git a/src/main/org/audiveris/omr/sheet/SystemInfo.java b/src/main/org/audiveris/omr/sheet/SystemInfo.java index a97860c7d..ac824e769 100644 --- a/src/main/org/audiveris/omr/sheet/SystemInfo.java +++ b/src/main/org/audiveris/omr/sheet/SystemInfo.java @@ -107,10 +107,9 @@ public class SystemInfo private static final Logger logger = LoggerFactory.getLogger(SystemInfo.class); /** To sort by system id. */ - public static final Comparator byId = (SystemInfo o1, - SystemInfo o2) -> Integer.compare( - o1.id, - o2.id); + public static final Comparator byId = // + (SystemInfo o1, + SystemInfo o2) -> Integer.compare(o1.id, o2.id); //~ Instance fields ---------------------------------------------------------------------------- @@ -149,7 +148,7 @@ public class SystemInfo /** * Symbol Interpretation Graph for this system. - * NOTA: sig must be marshalled AFTER parts hierarchy to separate IDs and IDREFs handling. + * NOTA: sig must be marshaled AFTER parts hierarchy to separate IDs and IDREFs handling. */ @XmlElement(name = "sig") private SIGraph sig; @@ -1014,7 +1013,7 @@ public SystemInfo getPrecedingInPage () // getProfile // //------------// /** - * Convenient method to report the sheet processing profile based on poor switch. + * Convenient method to report the sheet processing profile based on poor-input switch. * * @return sheet processing profile */ @@ -1107,6 +1106,7 @@ public Skew getSkew () //-----------------------------// /** * Report the smallest measure-long rest shape (WHOLE_REST or BREVE_REST). + *

* This depends on whether the 'partialWholeRests' switch is on or off for this sheet. * * @return WHOLE_REST or BREVE_REST @@ -1492,21 +1492,14 @@ public boolean isIndented () */ public boolean isMeasureRestShape (Shape shape) { - switch (shape) { - case LONG_REST: - case BREVE_REST: - return true; + final ProcessingSwitches switches = sheet.getStub().getProcessingSwitches(); - case WHOLE_REST: - { - final ProcessingSwitches switches = sheet.getStub().getProcessingSwitches(); + return switch (shape) { + case LONG_REST, BREVE_REST -> true; + case WHOLE_REST -> !switches.getValue(ProcessingSwitch.partialWholeRests); - return !switches.getValue(ProcessingSwitch.partialWholeRests); - } - - default: - return false; - } + default -> false; + }; } //--------------// @@ -1580,11 +1573,8 @@ public PageRef mergeWithBelow () vSections.addAll(systemBelow.vSections); // bottom, deltaY, left, top, width - updateCoordinates(); - // area, areaLeft, areaRight - area = null; - getArea(); + updateCoordinates(); // stacks for (int i = 0; i < stacks.size(); i++) { @@ -1971,7 +1961,7 @@ public void unmergeWith (SystemInfo systemBelow, // updateCoordinates // //-------------------// /** - * + * Update system coordinates. */ public final void updateCoordinates () { @@ -1998,6 +1988,9 @@ public final void updateCoordinates () deltaY = (int) Math.rint( lastStaff.getFirstLine().getEndPoint(LEFT).getY() - topLeft.getY()); bottom = (int) Math.rint(botLeft.getY()); + + area = null; + getArea(); } catch (Exception ex) { logger.warn("Error updating coordinates for system#{}", id, ex); } diff --git a/src/main/org/audiveris/omr/sheet/SystemManager.java b/src/main/org/audiveris/omr/sheet/SystemManager.java index d81d45099..11e2485aa 100644 --- a/src/main/org/audiveris/omr/sheet/SystemManager.java +++ b/src/main/org/audiveris/omr/sheet/SystemManager.java @@ -120,33 +120,18 @@ public SystemManager (Sheet sheet) //---------------// /** * Allocate page(s) for the sheet, as well as contained systems and parts. - *

- * Detect if an indented system starts a new movement (and thus a new score). - *

- * This behavior is driven by the "indentations" processing switch. - * - * @see PR of Vladimir Buyanov */ - public void allocatePages () + private void allocatePages () { final SheetStub stub = sheet.getStub(); - final ProcessingSwitches switches = stub.getProcessingSwitches(); - final boolean useIndentation = switches.getValue(ProcessingSwitch.indentations); Page page = null; PageRef pageRef = null; - - if (useIndentation) { - // Look at left indentation of (deskewed) systems - checkIndentations(); - } - - // Allocate systems and pages for (SystemInfo system : systems) { final int pageId = 1 + sheet.getPages().size(); if (system.isIndented()) { final int systId = system.getId(); - logger.info("Indentation detected for system#{}", systId); + logger.info("Indentation detected for system #{}", systId); // We have a movement start if (page != null) { @@ -177,36 +162,91 @@ public void allocatePages () // checkIndentations // //-------------------// /** - * Check all (de-skewed) systems for left-indentation that would signal a new movement. + * Check all systems for left-indentation that would signal a new movement, + * and flag them as such. + *

+ * This behavior is driven by the "indentations" processing switch. + * + * @see PR of Vladimir Buyanov */ private void checkIndentations () { + if (sheet.getStub().getProcessingSwitches().getValue(ProcessingSwitch.indentations)) { + systems.forEach(system -> system.setIndented(checkIndentation(system))); + } + } + + //------------------// + // checkIndentation // + //------------------// + /** + * Check whether the provided system is left-indented with respect to its neighboring + * systems above and below. + * + * @param system the system to check + * @return true if system is indeed indented + */ + public boolean checkIndentation (SystemInfo system) + { + // For side by side systems, only the leftmost one is concerned + if (system.getAreaEnd(LEFT) != 0) { + return false; + } + final Skew skew = sheet.getSkew(); final double minIndentation = sheet.getScale().toPixels(constants.minIndentation); + final Point2D ul = skew.deskewed(new Point(system.getLeft(), system.getTop())); - for (SystemInfo system : systems) { - // For side by side systems, only the leftmost one is concerned - if (system.getAreaEnd(LEFT) != 0) { - continue; - } + for (VerticalSide side : VerticalSide.values()) { + final List others = verticalNeighbors(system, side); - final Point2D ul = skew.deskewed(new Point(system.getLeft(), system.getTop())); + if (!others.isEmpty()) { + final SystemInfo other = others.get(0); + final Point2D ulOther = skew.deskewed(new Point(other.getLeft(), other.getTop())); - for (VerticalSide side : VerticalSide.values()) { - final List others = verticalNeighbors(system, side); + if ((ul.getX() - ulOther.getX()) >= minIndentation) { + return true; + } + } + } - if (!others.isEmpty()) { - SystemInfo other = others.get(0); - Point2D ulOther = skew.deskewed(new Point(other.getLeft(), other.getTop())); + return false; + } - if ((ul.getX() - ulOther.getX()) >= minIndentation) { - system.setIndented(true); + //---------------------// + // checkNewIndentation // + //---------------------// + /** + * If indentation is used and has changed for the provided system, + * reorganize the containing page(s) and score(s) accordingly. + * + * @param system the system to check + * @return true if changed + */ + public boolean checkNewIndentation (SystemInfo system) + { + final SheetStub stub = sheet.getStub(); + if (!stub.getProcessingSwitches().getValue(ProcessingSwitch.indentations)) { + return false; + } - break; - } - } - } + final boolean newIndent = checkIndentation(system); + if (newIndent == system.isIndented()) { + return false; } + + logger.info("Indentation changed for system #{}", system.getId()); + system.setIndented(newIndent); + + // Rebuild pages, pageRefs and scores + stub.clearPageRefs(); + sheet.clearPages(); + allocatePages(); + stub.getBook().updateScores(stub); + + reportResults(); + + return true; } //-------------------// @@ -620,6 +660,9 @@ public void populateSystems () dispatchHorizontalSections(); dispatchVerticalSections(); + // Check systems indentation + checkIndentations(); + // Allocate one (or several) page instances for the sheet allocatePages(); @@ -681,7 +724,7 @@ private void reportResults () } for (Page page : sheet.getPages()) { - StringBuilder sb = new StringBuilder(); + final StringBuilder sb = new StringBuilder(); if (pageNb > 1) { sb.append("Page #").append(1 + sheet.getPages().indexOf(page)).append(": "); @@ -712,7 +755,7 @@ private void reportResults () sb.append("no part found"); } - int sysNb = page.getSystems().size(); + final int sysNb = page.getSystems().size(); if (sysNb > 0) { sb.append(" along ").append(sysNb).append(" system"); @@ -749,7 +792,7 @@ public void reset () } //------------// - // setSystemsFrom // + // setSystems // //------------// /** * Assign the whole sequence of systems diff --git a/src/main/org/audiveris/omr/sheet/ui/StaffEditor.java b/src/main/org/audiveris/omr/sheet/ui/StaffEditor.java index f3805914d..4da9140bb 100644 --- a/src/main/org/audiveris/omr/sheet/ui/StaffEditor.java +++ b/src/main/org/audiveris/omr/sheet/ui/StaffEditor.java @@ -39,7 +39,9 @@ import org.audiveris.omr.run.RunTable; import org.audiveris.omr.run.RunTableFactory; import org.audiveris.omr.sheet.Picture; +import org.audiveris.omr.sheet.ProcessingSwitch; import org.audiveris.omr.sheet.Sheet; +import org.audiveris.omr.sheet.SheetStub; import org.audiveris.omr.sheet.Staff; import org.audiveris.omr.sheet.StaffLine; import org.audiveris.omr.sheet.grid.LineInfo; @@ -286,12 +288,16 @@ public void endProcess () //-----------// // finalDoit // //-----------// + @Override public void finalDoit () { super.finalDoit(); + final Staff staff = getStaff(); + final Sheet sheet = system.getSheet(); + // Register staff lines glyphs - final GlyphIndex glyphIndex = system.getSheet().getGlyphIndex(); + final GlyphIndex glyphIndex = sheet.getGlyphIndex(); lines.forEach(line -> { final StaffLine staffLine = (StaffLine) line; Glyph glyph = staffLine.getGlyph(); @@ -299,7 +305,16 @@ public void finalDoit () staffLine.setGlyph(glyph); }); - // Check if system indentation has changed + staff.getSystem().updateCoordinates(); + + // Check for potential change in system indentation + if (staff == system.getFirstStaff()) { + final SheetStub stub = sheet.getStub(); + + if (stub.getProcessingSwitches().getValue(ProcessingSwitch.indentations)) { + sheet.getSystemManager().checkNewIndentation(system); + } + } } //--------------//