UNPKG

satie

Version:

A sheet music renderer for the web

349 lines (348 loc) 14.4 kB
/** * This file is part of Satie music engraver <https://github.com/jnetterf/satie>. * Copyright (C) Joshua Netterfield <joshua.ca> 2015 - present. * * Satie is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * Satie is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Satie. If not, see <http://www.gnu.org/licenses/>. */ "use strict"; /** * @file engine/scoreHeader.ts holds default header information as well * as convienience utilites for score headers. */ var musicxml_interfaces_1 = require("musicxml-interfaces"); var lodash_1 = require("lodash"); var private_print_1 = require("./private_print"); var private_smufl_1 = require("./private_smufl"); var private_renderUtil_1 = require("./private_renderUtil"); /** * A header is a child of parts, and includes the title and other basic * information. */ var ScoreHeaderModel = (function () { /*---- Extensions ---------------------------------------------------------------------------*/ function ScoreHeaderModel(spec) { /*---- ScoreHeader --------------------------------------------------------------------------*/ this.credits = []; this.identification = { creators: [], encoding: { encodingDescriptions: [], encodingDate: null, supports: {}, encoders: [], softwares: [] }, miscellaneous: null, relations: [], rights: [], source: null }; this.defaults = { appearance: { distances: { hyphen: { tenths: 10 * private_smufl_1.distances.hyphen, type: "hyphen" }, beam: { tenths: 10 * private_smufl_1.distances.beam, type: "beam" } }, lineWidths: { staff: { "tenths": 10 * private_smufl_1.bravura.engravingDefaults.staffLineThickness, "type": "staff" }, wedge: { "tenths": 10 * private_smufl_1.bravura.engravingDefaults.hairpinThickness, "type": "wedge" }, ending: { "tenths": 10 * private_smufl_1.bravura.engravingDefaults.repeatEndingLineThickness, "type": "ending" }, "heavy barline": { "tenths": 10 * private_smufl_1.bravura.engravingDefaults.thickBarlineThickness, "type": "heavy barline" }, leger: { "tenths": 10 * private_smufl_1.bravura.engravingDefaults.legerLineThickness, "type": "leger" }, stem: { "tenths": 10 * private_smufl_1.bravura.engravingDefaults.stemThickness, "type": "stem" }, "tuplet bracket": { "tenths": 10 * private_smufl_1.bravura.engravingDefaults.tupletBracketThickness, "type": "tuplet bracket" }, beam: { "tenths": 10 * private_smufl_1.bravura.engravingDefaults.beamThickness, "type": "beam" }, "light barline": { "tenths": 10 * private_smufl_1.bravura.engravingDefaults.thinBarlineThickness, "type": "light barline" }, enclosure: { "tenths": 10 * private_smufl_1.bravura.engravingDefaults.textEnclosureThickness, "type": "enclosure" } }, noteSizes: { 1: { "type": 1, "size": 60 // Not sure what 60 refers to. Our grace notes are 1.9 spaces }, 0: { "type": 0, "size": 60 // Not sure what 60 refers to. Our cue notes are 1.9 spaces. } }, otherAppearances: [] }, lyricFonts: [], lyricLanguages: [], musicFont: { fontSize: "20.5", fontFamily: "Bravura, Maestro, engraved", fontStyle: musicxml_interfaces_1.NormalItalic.Normal, fontWeight: musicxml_interfaces_1.NormalBold.Normal }, pageLayout: { pageHeight: private_renderUtil_1.mmToTenths(private_renderUtil_1.defaultStaveHeight, private_renderUtil_1.defaultPageSize().height), pageWidth: private_renderUtil_1.mmToTenths(private_renderUtil_1.defaultStaveHeight, private_renderUtil_1.defaultPageSize().width), pageMargins: [ { bottomMargin: private_renderUtil_1.mmToTenths(private_renderUtil_1.defaultStaveHeight, private_renderUtil_1.defaultMargins.bottom), leftMargin: private_renderUtil_1.mmToTenths(private_renderUtil_1.defaultStaveHeight, private_renderUtil_1.defaultMargins.left), rightMargin: private_renderUtil_1.mmToTenths(private_renderUtil_1.defaultStaveHeight, private_renderUtil_1.defaultMargins.right), topMargin: private_renderUtil_1.mmToTenths(private_renderUtil_1.defaultStaveHeight, private_renderUtil_1.defaultMargins.top), type: musicxml_interfaces_1.OddEvenBoth.Both } ] }, scaling: { millimeters: private_renderUtil_1.defaultStaveHeight, tenths: 40 }, staffLayouts: [], systemLayout: { systemDistance: 131, systemDividers: null, systemMargins: { leftMargin: 0, rightMargin: 0 }, topSystemDistance: 70 }, wordFont: { fontSize: "12", fontFamily: "Alegreya, Times New Roman, serif", fontStyle: musicxml_interfaces_1.NormalItalic.Normal, fontWeight: musicxml_interfaces_1.NormalBold.Normal } }; this.work = { opus: null, workNumber: "", workTitle: "" }; this.movementTitle = ""; this.movementNumber = ""; this.partList = []; if (spec) { lodash_1.defaultsDeep(spec, this); } for (var key in spec) { if (spec.hasOwnProperty(key) && typeof key === "string" && !!spec[key]) { this[key] = spec[key]; } } } Object.defineProperty(ScoreHeaderModel.prototype, "composer", { get: function () { return this._getIdentificationOrCredit("composer"); }, set: function (composer) { this._setIdentification("composer", composer); this._setCredits("composer", composer, musicxml_interfaces_1.LeftCenterRight.Right, "12px", 20); }, enumerable: true, configurable: true }); Object.defineProperty(ScoreHeaderModel.prototype, "arranger", { get: function () { return this._getIdentificationOrCredit("arranger"); }, set: function (arranger) { this._setIdentification("arranger", arranger); this._setCredits("arranger", arranger, musicxml_interfaces_1.LeftCenterRight.Right, "12px", 35); }, enumerable: true, configurable: true }); Object.defineProperty(ScoreHeaderModel.prototype, "lyricist", { get: function () { return this._getIdentificationOrCredit("lyricist"); }, set: function (lyricist) { this._setIdentification("lyricist", lyricist); this._setCredits("lyricist", lyricist, musicxml_interfaces_1.LeftCenterRight.Right, "12px", 50); }, enumerable: true, configurable: true }); Object.defineProperty(ScoreHeaderModel.prototype, "title", { get: function () { return this.movementTitle; }, set: function (title) { // Set meta-data this.movementTitle = title; this._setCredits("title", title, musicxml_interfaces_1.LeftCenterRight.Center, "18px", 10); }, enumerable: true, configurable: true }); ScoreHeaderModel.prototype.toXML = function () { return musicxml_interfaces_1.serializeScoreHeader(this); }; ScoreHeaderModel.prototype.inspect = function () { return this.toXML(); }; ScoreHeaderModel.prototype.overwriteEncoding = function () { var date = new Date; this.identification = this.identification || (new ScoreHeaderModel(null)).identification; this.identification.encoding = { encodingDescriptions: [], encodingDate: { month: date.getMonth() + 1, day: date.getDate(), year: date.getFullYear() }, supports: { "satie-collaboration": { element: "satie-collaboration", value: null, type: true, attribute: null } }, encoders: [], softwares: [ "Songhaus Satie" ] }; }; ScoreHeaderModel.prototype._getIdentificationOrCredit = function (type) { if (this.identification && (this.identification.creators || []).length) { var idComposer = this.identification.creators .filter(function (c) { return c.type === type; }) .map(function (c) { return c.creator; }) .join(", "); if (idComposer) { return idComposer; } } return this.credits.filter(function (c) { return c.creditTypes.indexOf(type) !== -1; }) .map(function (m) { return m.creditWords; }) .map(function (w) { return w.map(function (w) { return w.words; }).join(", "); }) .join(", "); }; ScoreHeaderModel.prototype._setIdentification = function (type, val) { this.identification = this.identification || { miscellaneous: [], creators: [], encoding: [], relations: [], rights: [], source: null }; this.identification.creators = this.identification.creators || []; lodash_1.forEach(this.identification.creators, function (c) { if (c.type === type) { c.creator = val; } }); if (!lodash_1.some(this.identification.creators, function (c) { return c.type === type; })) { // ...or add a val this.identification.creators.push({ creator: val, type: type }); } }; ScoreHeaderModel.prototype._setCredits = function (type, val, justification, fontSize, top) { var _this = this; var mm = this.defaults.scaling.millimeters; var pageLayout = this.defaults.pageLayout; this.credits = this.credits || []; lodash_1.forEach(this.credits, function (c, idx) { if (!c.creditWords) { return false; } // Replace a credit... var isComposer = c.creditTypes.indexOf(type) !== -1; if (isComposer) { if (!c.creditWords.length) { delete _this.credits[idx]; } else { c.creditWords.length = 1; c.creditWords[0].words = val; } } }); if (!lodash_1.some(this.credits, function (c) { return Boolean(c.creditWords) && c.creditTypes.indexOf(type) !== -1; })) { var defaultX = NaN; var margins = private_print_1.getPageMargins(this.defaults.pageLayout.pageMargins, 1); // TODO: Throughout this file, use own instead of default values switch (justification) { case musicxml_interfaces_1.LeftCenterRight.Center: defaultX = (margins.leftMargin - margins.rightMargin + pageLayout.pageWidth) / 2; break; case musicxml_interfaces_1.LeftCenterRight.Right: defaultX = pageLayout.pageWidth - margins.rightMargin; break; case musicxml_interfaces_1.LeftCenterRight.Left: defaultX = margins.leftMargin; break; default: defaultX = margins.leftMargin; break; } ; this.credits.push({ // ... or add a credit creditImage: null, creditTypes: [type], creditWords: [{ words: val, defaultX: defaultX, justify: justification, defaultY: pageLayout.pageHeight - private_renderUtil_1.mmToTenths(mm, top), fontSize: fontSize }], page: 1 }); } }; return ScoreHeaderModel; }()); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ScoreHeaderModel;