Pārlūkot izejas kodu

fix(Container height): small scores don't significantly exceed bounding box anymore (SVG height). fix PageBottomMargin (#875) etc

remove EngravingRules.PageBottomExtraWhiteSpace, as PageBottomMargin was fixed and replaces it
fix #875 as the option isn't necessary anymore
improve solution for #788

PageBottomMargin can now be used to extend the white space below the score and extend the container (SVG) height.

fix for the SVG height is in OpenSheetMusicDisplay.createOrRefreshRenderBackend(),
where the height of the backend is now calculated from the bounding box plus margins (* 10 * zoom).

DrawingParameters default now resets EngravingRules (necessary to disable compacttight mode)

the SVGs generated by OSMD now have ids in the DOM (starting with osmdCanvasPage1)

EngravingRules.TitleTopDistance reduced to 5.0

add sample OSMD Function Test Container height, which is a small score
that had an element height of 300+ instead of the needed ~230
because of a too generous magic number.
sschmid 4 gadi atpakaļ
vecāks
revīzija
c43565c970

+ 19 - 0
demo/index.js

@@ -31,6 +31,7 @@ import * as svg2pdf from '../node_modules/svg2pdf.js/dist/svg2pdf.min';
             "OSMD Function Test - Bar lines": "OSMD_function_test_bar_lines.musicxml",
             "OSMD Function Test - Chord Symbols": "OSMD_function_test_chord_symbols.musicxml",
             "OSMD Function Test - Color (from XML)": "OSMD_function_test_color.musicxml",
+            "OSMD Function Test - Container height (compacttight mode)": "OSMD_Function_Test_Container_height.musicxml",
             "OSMD Function Test - Drumset": "OSMD_function_test_drumset.musicxml",
             "OSMD Function Test - Drums on one Line": "OSMD_Function_Test_Drums_one_line_snare_plus_piano.musicxml", 
             "OSMD Function Test - Expressions": "OSMD_function_test_expressions.musicxml",
@@ -95,6 +96,8 @@ import * as svg2pdf from '../node_modules/svg2pdf.js/dist/svg2pdf.min';
     var minMeasureToDrawStashed = 1;
     var maxMeasureToDrawStashed = Number.MAX_SAFE_INTEGER;
     var measureToDrawRangeNeedsReset = false;
+    var drawingParametersStashed = "default";
+    var drawingParametersNeedsReset = false;
     var autobeamOptionNeedsReset = false;
     var autobeamOptionStashedValue = false;
     var autoCustomColoringOptionNeedsReset = false;
@@ -512,6 +515,9 @@ import * as svg2pdf from '../node_modules/svg2pdf.js/dist/svg2pdf.min';
             // selectSampleOnChange();
         });
 
+        // TODO after selectSampleOnChange, the resize handler triggers immediately,
+        //   so we render twice at the start of the demo.
+        //   maybe delay the first osmd render, e.g. when window ready?
         if (paramOpenUrl) {
             if (openSheetMusicDisplay.getLogLevel() < 2) { // debug or trace
                 console.log("[OSMD] selectSampleOnChange with " + paramOpenUrl);
@@ -645,6 +651,19 @@ import * as svg2pdf from '../node_modules/svg2pdf.js/dist/svg2pdf.min';
             measureToDrawRangeNeedsReset = false;
         }
 
+        if (!isCustom && str.includes("Test_Container_height")) {
+            drawingParametersStashed = openSheetMusicDisplay.drawingParameters.drawingParametersEnum;
+            openSheetMusicDisplay.setOptions({
+                drawingParameters: "compacttight"
+            });
+            drawingParametersNeedsReset = true;
+        } else if (drawingParametersNeedsReset) {
+            openSheetMusicDisplay.setOptions({
+                drawingParameters: drawingParametersStashed
+            });
+            drawingParametersNeedsReset = false;
+        }
+
         // Enable Boomwhacker-like coloring for OSMD Function Test - Auto-Coloring (Boomwhacker-like, custom color set)
         if (!isCustom && str.includes("auto-custom-coloring")) { // set options for auto coloring sample
             autoCustomColoringOptionNeedsReset = true;

+ 1 - 0
src/MusicalScore/Graphical/DrawingParameters.ts

@@ -96,6 +96,7 @@ export class DrawingParameters {
     }
 
     public setForDefault(): void {
+        this.rules.loadDefaultValues(); // this is not ideal, but it's hard to reset compactTight mode properly
         this.setForAllOn();
         this.drawHiddenNotes = false;
     }

+ 5 - 3
src/MusicalScore/Graphical/EngravingRules.ts

@@ -27,7 +27,6 @@ export class EngravingRules {
     public PageTopMargin: number;
     public PageTopMarginNarrow: number;
     public PageBottomMargin: number;
-    public PageBottomExtraWhiteSpace: number; // experimental. extra white space that wil be added below the sheet
     public PageLeftMargin: number;
     public PageRightMargin: number;
     public TitleTopDistance: number;
@@ -259,6 +258,10 @@ export class EngravingRules {
     public static FixStafflineBoundingBox: boolean; // TODO temporary workaround
 
     constructor() {
+        this.loadDefaultValues();
+    }
+
+    public loadDefaultValues(): void {
         // global variables
         this.SamplingUnit = EngravingRules.unit * 3;
 
@@ -276,10 +279,9 @@ export class EngravingRules {
         this.PageTopMargin = 5.0;
         this.PageTopMarginNarrow = 0.0; // for compact mode
         this.PageBottomMargin = 5.0;
-        this.PageBottomExtraWhiteSpace = 0.0; // experimental.
         this.PageLeftMargin = 5.0;
         this.PageRightMargin = 5.0;
-        this.TitleTopDistance = 9.0;
+        this.TitleTopDistance = 5.0;
         this.TitleBottomDistance = 1.0;
         this.StaffDistance = 7.0;
         this.BetweenStaffDistance = 5.0;

+ 0 - 19
src/MusicalScore/Graphical/MusicSystemBuilder.ts

@@ -1143,25 +1143,6 @@ export class MusicSystemBuilder {
         if (timesPageCouldntFitSingleSystem > 0) {
             console.log(`total amount of pages that couldn't fit a single music system: ${timesPageCouldntFitSingleSystem} of ${currentPage.PageNumber}`);
         }
-        if (this.rules.PageBottomExtraWhiteSpace > 0 && this.graphicalMusicSheet.MusicPages.length === 1) {
-            // experimental, not used unless the EngravingRule is set to > 0 (default 0)
-
-            // calculate last page's bounding box, otherwise it uses this.rules.PageHeight which is 10001
-            currentPage.PositionAndShape.calculateBoundingBox();
-            // TODO currently bugged with PageFormat A3. this squeezes lyrics and notes (with A3 Landscape). why?
-            //   for this reason, the extra white space should currently only be used with the Endless PageFormat,
-            //   and using EngravingRules.PageBottomExtraWhiteSpace should be considered experimental.
-
-            // add this.rules.PageBottomMargin
-            const pageBottomMarginBB: BoundingBox = new BoundingBox(currentPage, currentPage.PositionAndShape, false);
-            // pageBottomMarginBB.RelativePosition.x = 0;
-            pageBottomMarginBB.RelativePosition.y = currentPage.PositionAndShape.BorderMarginBottom;
-            // pageBottomMarginBB.BorderBottom = this.rules.PageBottomMargin;
-            pageBottomMarginBB.BorderBottom = this.rules.PageBottomExtraWhiteSpace;
-            pageBottomMarginBB.calculateBoundingBox();
-            currentPage.PositionAndShape.calculateBoundingBox();
-        }
-
     }
 
     /**

+ 1 - 0
src/MusicalScore/Graphical/VexFlow/SvgVexFlowBackend.ts

@@ -40,6 +40,7 @@ export class SvgVexFlowBackend extends VexFlowBackend {
         container.appendChild(this.inner);
         this.renderer = new Vex.Flow.Renderer(this.canvas, this.getVexflowBackendType());
         this.ctx = <Vex.Flow.SVGContext>this.renderer.getContext();
+        this.ctx.svg.id = "osmdSvgPage" + this.graphicalMusicPage.PageNumber;
     }
 
     public getContext(): Vex.Flow.SVGContext {

+ 7 - 1
src/OpenSheetMusicDisplay/OpenSheetMusicDisplay.ts

@@ -292,7 +292,13 @@ export class OpenSheetMusicDisplay {
                 height = width / this.rules.PageFormat.aspectRatio;
                 // console.log("pageformat given. height: " + page.PositionAndShape.Size.height);
             } else {
-                height = (page.PositionAndShape.Size.height + 15) * this.zoom * 10.0;
+                height = page.PositionAndShape.Size.height;
+                height += this.rules.PageBottomMargin;
+                height += this.rules.CompactMode ? this.rules.PageTopMarginNarrow : this.rules.PageTopMargin;
+                if (this.rules.RenderTitle) {
+                    height += this.rules.TitleTopDistance;
+                }
+                height *= this.zoom * 10.0;
                 // console.log("pageformat not given. height: " + page.PositionAndShape.Size.height);
             }
             if (backend.getOSMDBackendType() === BackendType.Canvas && height > canvasDimensionsLimit) {

+ 10 - 3
test/Util/generateImages_browserless.js

@@ -35,6 +35,7 @@ if (!osmdBuildDir || !sampleDir || !imageDir) {
     console.log('Error: need osmdBuildDir, sampleDir and imageDir. Exiting.')
     process.exit(1)
 }
+let pageFormat
 
 if (!mode) {
     mode = ''
@@ -62,7 +63,7 @@ async function init () {
     debug('sampleDir: ' + sampleDir, DEBUG)
     debug('imageDir: ' + imageDir, DEBUG)
 
-    let pageFormat = 'Endless'
+    pageFormat = 'Endless'
     pageWidth = Number.parseInt(pageWidth)
     pageHeight = Number.parseInt(pageHeight)
     const endlessPage = !(pageHeight > 0 && pageWidth > 0)
@@ -187,7 +188,8 @@ async function init () {
     // for more options check OSMDOptions.ts
 
     // you can set finer-grained rendering/engraving settings in EngravingRules:
-    osmdInstance.EngravingRules.TitleTopDistance = 5.0 // 9.0 is default
+    // osmdInstance.EngravingRules.TitleTopDistance = 5.0 // 5.0 is default
+    //   (unless in osmdTestingMode, these will be reset with drawingParameters default)
     // osmdInstance.EngravingRules.PageTopMargin = 5.0 // 5 is default
     // osmdInstance.EngravingRules.PageBottomMargin = 5.0 // 5 is default. <5 can cut off scores that extend in the last staffline
     // note that for now the png and canvas will still have the height given in the script argument,
@@ -242,15 +244,20 @@ async function generateSampleImage (sampleFilename, directory, osmdInstance, osm
         const isFunctionTestAutoColoring = sampleFilename.startsWith('OSMD_function_test_auto-custom-coloring')
         const isFunctionTestSystemAndPageBreaks = sampleFilename.startsWith('OSMD_Function_Test_System_and_Page_Breaks')
         const isFunctionTestDrawingRange = sampleFilename.startsWith('OSMD_function_test_measuresToDraw_')
+        const defaultOrCompactTightMode = sampleFilename.startsWith('OSMD_Function_Test_Container_height') ? 'compacttight' : 'default'
+        console.log('compacttightMode: ' + defaultOrCompactTightMode)
         osmdInstance.setOptions({
             autoBeam: isFunctionTestAutobeam, // only set to true for function test autobeam
             coloringMode: isFunctionTestAutoColoring ? 2 : 0,
             coloringSetCustom: isFunctionTestAutoColoring ? ['#d82c6b', '#F89D15', '#FFE21A', '#4dbd5c', '#009D96', '#43469d', '#76429c', '#ff0000'] : undefined,
             colorStemsLikeNoteheads: isFunctionTestAutoColoring,
+            drawingParameters: defaultOrCompactTightMode, // default resets all EngravingRules
             drawFromMeasureNumber: isFunctionTestDrawingRange ? 9 : 1,
             drawUpToMeasureNumber: isFunctionTestDrawingRange ? 12 : Number.MAX_SAFE_INTEGER,
             newSystemFromXML: isFunctionTestSystemAndPageBreaks,
-            newPageFromXML: isFunctionTestSystemAndPageBreaks
+            newPageFromXML: isFunctionTestSystemAndPageBreaks,
+            pageBackgroundColor: '#FFFFFF', // reset by drawingparameters default
+            pageFormat: pageFormat // reset by drawingparameters default
         })
         osmdInstance.drawSkyLine = includeSkyBottomLine // if includeSkyBottomLine, draw skyline and bottomline, else not
         osmdInstance.drawBottomLine = includeSkyBottomLine

+ 189 - 0
test/data/OSMD_Function_Test_Container_height.musicxml

@@ -0,0 +1,189 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE score-partwise PUBLIC "-//Recordare//DTD MusicXML 3.1 Partwise//EN" "http://www.musicxml.org/dtds/partwise.dtd">
+<score-partwise version="3.1">
+  <work>
+    <work-title>OSMD Function Test - Container Height</work-title>
+    </work>
+  <identification>
+    <encoding>
+      <software>MuseScore 3.5.0</software>
+      <encoding-date>2020-09-08</encoding-date>
+      <supports element="accidental" type="yes"/>
+      <supports element="beam" type="yes"/>
+      <supports element="print" attribute="new-page" type="yes" value="yes"/>
+      <supports element="print" attribute="new-system" type="yes" value="yes"/>
+      <supports element="stem" type="yes"/>
+      </encoding>
+    </identification>
+  <defaults>
+    <scaling>
+      <millimeters>7.05556</millimeters>
+      <tenths>40</tenths>
+      </scaling>
+    <page-layout>
+      <page-height>1683.36</page-height>
+      <page-width>1190.88</page-width>
+      <page-margins type="even">
+        <left-margin>56.6929</left-margin>
+        <right-margin>56.6929</right-margin>
+        <top-margin>56.6929</top-margin>
+        <bottom-margin>113.386</bottom-margin>
+        </page-margins>
+      <page-margins type="odd">
+        <left-margin>56.6929</left-margin>
+        <right-margin>56.6929</right-margin>
+        <top-margin>56.6929</top-margin>
+        <bottom-margin>113.386</bottom-margin>
+        </page-margins>
+      </page-layout>
+    <word-font font-family="FreeSerif" font-size="10"/>
+    <lyric-font font-family="FreeSerif" font-size="11"/>
+    </defaults>
+  <credit page="1">
+    <credit-words default-x="595.44" default-y="1626.67" justify="center" valign="top" font-size="24">height test</credit-words>
+    </credit>
+  <part-list>
+    <score-part id="P1">
+      <part-name>Piano</part-name>
+      <part-abbreviation>Pno.</part-abbreviation>
+      <score-instrument id="P1-I1">
+        <instrument-name>Piano</instrument-name>
+        </score-instrument>
+      <midi-device id="P1-I1" port="1"></midi-device>
+      <midi-instrument id="P1-I1">
+        <midi-channel>1</midi-channel>
+        <midi-program>1</midi-program>
+        <volume>78.7402</volume>
+        <pan>0</pan>
+        </midi-instrument>
+      </score-part>
+    </part-list>
+  <part id="P1">
+    <measure number="1" width="194.43">
+      <print>
+        <system-layout>
+          <system-margins>
+            <left-margin>21.00</left-margin>
+            <right-margin>434.59</right-margin>
+            </system-margins>
+          <top-system-distance>170.00</top-system-distance>
+          </system-layout>
+        <staff-layout number="2">
+          <staff-distance>65.00</staff-distance>
+          </staff-layout>
+        </print>
+      <attributes>
+        <divisions>1</divisions>
+        <key>
+          <fifths>0</fifths>
+          </key>
+        <time>
+          <beats>4</beats>
+          <beat-type>4</beat-type>
+          </time>
+        <staves>2</staves>
+        <clef number="1">
+          <sign>G</sign>
+          <line>2</line>
+          </clef>
+        <clef number="2">
+          <sign>F</sign>
+          <line>4</line>
+          </clef>
+        </attributes>
+      <note>
+        <rest measure="yes"/>
+        <duration>4</duration>
+        <voice>1</voice>
+        <staff>1</staff>
+        </note>
+      <backup>
+        <duration>4</duration>
+        </backup>
+      <note>
+        <rest measure="yes"/>
+        <duration>4</duration>
+        <voice>5</voice>
+        <staff>2</staff>
+        </note>
+      </measure>
+    <measure number="2" width="141.56">
+      <note default-x="10.00" default-y="-30.00">
+        <pitch>
+          <step>G</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>2</duration>
+        <voice>1</voice>
+        <type>half</type>
+        <stem>up</stem>
+        <staff>1</staff>
+        </note>
+      <note>
+        <rest/>
+        <duration>2</duration>
+        <voice>1</voice>
+        <type>half</type>
+        <staff>1</staff>
+        </note>
+      <backup>
+        <duration>4</duration>
+        </backup>
+      <note>
+        <rest measure="yes"/>
+        <duration>4</duration>
+        <voice>5</voice>
+        <staff>2</staff>
+        </note>
+      </measure>
+    <measure number="3" width="135.36">
+      <note>
+        <rest measure="yes"/>
+        <duration>4</duration>
+        <voice>1</voice>
+        <staff>1</staff>
+        </note>
+      <backup>
+        <duration>4</duration>
+        </backup>
+      <note>
+        <rest measure="yes"/>
+        <duration>4</duration>
+        <voice>5</voice>
+        <staff>2</staff>
+        </note>
+      </measure>
+    <measure number="4" width="150.56">
+      <note default-x="10.00" default-y="-25.00">
+        <pitch>
+          <step>A</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>2</duration>
+        <voice>1</voice>
+        <type>half</type>
+        <stem>up</stem>
+        <staff>1</staff>
+        </note>
+      <note>
+        <rest/>
+        <duration>2</duration>
+        <voice>1</voice>
+        <type>half</type>
+        <staff>1</staff>
+        </note>
+      <backup>
+        <duration>4</duration>
+        </backup>
+      <note>
+        <rest measure="yes"/>
+        <duration>4</duration>
+        <voice>5</voice>
+        <staff>2</staff>
+        </note>
+      <barline location="right">
+        <bar-style>light-heavy</bar-style>
+        </barline>
+      </measure>
+    </part>
+  </score-partwise>