|
@@ -19,8 +19,6 @@ import { AbstractExpression } from "../MusicalScore/VoiceData/Expressions/Abstra
|
|
|
import { Dictionary } from "typescript-collections";
|
|
|
import { NoteEnum } from "..";
|
|
|
import { AutoColorSet, GraphicalMusicPage } from "../MusicalScore";
|
|
|
-import jspdf = require("jspdf-yworks/dist/jspdf.min");
|
|
|
-import svg2pdf = require("svg2pdf.js/dist/svg2pdf.min");
|
|
|
import { MusicPartManagerIterator } from "../MusicalScore/MusicParts";
|
|
|
import { ITransposeCalculator } from "../MusicalScore/Interfaces";
|
|
|
/**
|
|
@@ -29,7 +27,7 @@ import { ITransposeCalculator } from "../MusicalScore/Interfaces";
|
|
|
* After the constructor, use load() and render() to load and render a MusicXML file.
|
|
|
*/
|
|
|
export class OpenSheetMusicDisplay {
|
|
|
- private version: string = "0.8.1-release"; // getter: this.Version
|
|
|
+ private version: string = "0.8.2-release"; // getter: this.Version
|
|
|
// at release, bump version and change to -release, afterwards to -dev again
|
|
|
|
|
|
/**
|
|
@@ -112,21 +110,25 @@ export class OpenSheetMusicDisplay {
|
|
|
// UTF with BOM detected, truncate first three bytes and pass along
|
|
|
return self.load(str.substr(3));
|
|
|
}
|
|
|
- if (str.substr(0, 6).includes("<?xml")) { // first character is sometimes null, making first five characters '<?xm'.
|
|
|
- log.debug("[OSMD] Finally parsing XML content, length: " + str.length);
|
|
|
+ let trimmedStr: string = str;
|
|
|
+ if (/^\s/.test(trimmedStr)) { // only trim if we need to. (end of string is irrelevant)
|
|
|
+ trimmedStr = trimmedStr.trim(); // trim away empty lines at beginning etc
|
|
|
+ }
|
|
|
+ if (trimmedStr.substr(0, 6).includes("<?xml")) { // first character is sometimes null, making first five characters '<?xm'.
|
|
|
+ log.debug("[OSMD] Finally parsing XML content, length: " + trimmedStr.length);
|
|
|
// Parse the string representing an xml file
|
|
|
const parser: DOMParser = new DOMParser();
|
|
|
- content = parser.parseFromString(str, "application/xml");
|
|
|
- } else if (str.length < 2083) { // TODO do proper URL format check
|
|
|
- log.debug("[OSMD] Retrieve the file at the given URL: " + str);
|
|
|
+ content = parser.parseFromString(trimmedStr, "application/xml");
|
|
|
+ } else if (trimmedStr.length < 2083) { // TODO do proper URL format check
|
|
|
+ log.debug("[OSMD] Retrieve the file at the given URL: " + trimmedStr);
|
|
|
// Assume now "str" is a URL
|
|
|
// Retrieve the file at the given URL
|
|
|
- return AJAX.ajax(str).then(
|
|
|
+ return AJAX.ajax(trimmedStr).then(
|
|
|
(s: string) => { return self.load(s); },
|
|
|
(exc: Error) => { throw exc; }
|
|
|
);
|
|
|
} else {
|
|
|
- console.error("[OSMD] osmd.load(string): Could not process string. Missing else branch?");
|
|
|
+ console.error("[OSMD] osmd.load(string): Could not process string. Did not find <?xml at beginning.");
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -779,59 +781,6 @@ export class OpenSheetMusicDisplay {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * Creates a Pdf of the currently rendered MusicXML
|
|
|
- * @param pdfName if no name is given, the composer and title of the piece will be used
|
|
|
- */
|
|
|
- public createPdf(pdfName: string = undefined): void {
|
|
|
- if (this.backendType !== BackendType.SVG) {
|
|
|
- console.log("[OSMD] osmd.createPdf(): Warning: createPDF is only supported for SVG background for now, not for Canvas." +
|
|
|
- " Please use osmd.setOptions({backendType: SVG}).");
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- if (pdfName === undefined) {
|
|
|
- pdfName = this.sheet.FullNameString + ".pdf";
|
|
|
- }
|
|
|
-
|
|
|
- const backends: VexFlowBackend[] = this.drawer.Backends;
|
|
|
- let svgElement: SVGElement = (<SvgVexFlowBackend>backends[0]).getSvgElement();
|
|
|
-
|
|
|
- let pageWidth: number = 210;
|
|
|
- let pageHeight: number = 297;
|
|
|
- const engravingRulesPageFormat: PageFormat = this.rules.PageFormat;
|
|
|
- if (engravingRulesPageFormat && !engravingRulesPageFormat.IsUndefined) {
|
|
|
- pageWidth = engravingRulesPageFormat.width;
|
|
|
- pageHeight = engravingRulesPageFormat.height;
|
|
|
- } else {
|
|
|
- pageHeight = pageWidth * svgElement.clientHeight / svgElement.clientWidth;
|
|
|
- }
|
|
|
-
|
|
|
- const orientation: string = pageHeight > pageWidth ? "p" : "l";
|
|
|
- // create a new jsPDF instance
|
|
|
- const pdf: any = new jspdf(orientation, "mm", [pageWidth, pageHeight]);
|
|
|
- const scale: number = pageWidth / svgElement.clientWidth;
|
|
|
- for (let idx: number = 0, len: number = backends.length; idx < len; ++idx) {
|
|
|
- if (idx > 0) {
|
|
|
- pdf.addPage();
|
|
|
- }
|
|
|
- svgElement = (<SvgVexFlowBackend>backends[idx]).getSvgElement();
|
|
|
-
|
|
|
- // render the svg element
|
|
|
- svg2pdf(svgElement, pdf, {
|
|
|
- scale: scale,
|
|
|
- xOffset: 0,
|
|
|
- yOffset: 0
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
- // simply save the created pdf
|
|
|
- pdf.save(pdfName);
|
|
|
-
|
|
|
- // note that using jspdf with svg2pdf creates unnecessary console warnings "AcroForm-Classes are not populated into global-namespace..."
|
|
|
- // this will hopefully be fixed with a new jspdf release, see https://github.com/yWorks/jsPDF/pull/32
|
|
|
- }
|
|
|
-
|
|
|
//#region GETTER / SETTER
|
|
|
public set DrawSkyLine(value: boolean) {
|
|
|
this.drawSkyLine = value;
|