UNPKG

satie

Version:

A sheet music renderer for the web

196 lines (195 loc) 9.63 kB
/** * @source: https://github.com/jnetterf/satie/ * * @license * (C) Josh Netterfield <joshua@nettek.ca> 2015. * Part of the Satie music engraver <https://github.com/jnetterf/satie>. * * This program 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. * * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. */ "use strict"; var musicxml_interfaces_1 = require("musicxml-interfaces"); var builders_1 = require("musicxml-interfaces/builders"); var lodash_1 = require("lodash"); var invariant = require("invariant"); var document_1 = require("./document"); var private_part_1 = require("./private_part"); var private_smufl_1 = require("./private_smufl"); var implAttributes_attributesModel_1 = require("./implAttributes_attributesModel"); var implAttributes_attributesData_1 = require("./implAttributes_attributesData"); var BarlineModel = (function () { /*---- Implementation -----------------------------------------------------------------------*/ function BarlineModel(spec) { var _this = this; this._class = "Barline"; lodash_1.forEach(spec, function (value, key) { _this[key] = value; }); } BarlineModel.prototype.toJSON = function () { var _a = this, _class = _a._class, segno = _a.segno, coda = _a.coda, location = _a.location, codaAttrib = _a.codaAttrib, wavyLine = _a.wavyLine, fermatas = _a.fermatas, segnoAttrib = _a.segnoAttrib, divisions = _a.divisions, barStyle = _a.barStyle, ending = _a.ending, repeat = _a.repeat, footnote = _a.footnote; return { _class: _class, segno: segno, coda: coda, location: location, codaAttrib: codaAttrib, wavyLine: wavyLine, fermatas: fermatas, segnoAttrib: segnoAttrib, divisions: divisions, barStyle: barStyle, ending: ending, repeat: repeat, footnote: footnote }; }; BarlineModel.prototype.refresh = function (cursor) { if (!this.barStyle) { cursor.patch(function (staff) { return staff .barline(function (barline) { return barline .barStyle(builders_1.buildBarStyle(function (barStyle) { return barStyle .data(musicxml_interfaces_1.BarStyleType.Regular) .color("black"); })); }); }); } if (!isFinite(this.barStyle.data) || this.barStyle.data === null) { var lastBarlineInSegment_1 = !lodash_1.some(cursor.segmentInstance.slice(cursor.segmentPosition + 1), function (model) { return cursor.factory.modelHasType(model, document_1.Type.Barline); }); cursor.patch(function (staff) { return staff .barline(function (barline) { return barline .barStyle({ data: lastBarlineInSegment_1 && cursor.measureIsLast ? musicxml_interfaces_1.BarStyleType.LightHeavy : musicxml_interfaces_1.BarStyleType.Regular, }); }); }); } if (!this.barStyle.color) { cursor.patch(function (staff) { return staff .barline(function (barline) { return barline .barStyle(function (barStyle) { return barStyle .color("black"); }); }); }); } }; BarlineModel.prototype.getLayout = function (cursor) { // mutates cursor as required. return new BarlineModel.Layout(this, cursor); }; BarlineModel.prototype.toXML = function () { return musicxml_interfaces_1.serializeBarline(this) + "\n<forward><duration>" + this.divCount + "</duration></forward>\n"; }; BarlineModel.prototype.inspect = function () { return this.toXML(); }; BarlineModel.prototype.calcWidth = function (shortest) { return 8; // TODO }; return BarlineModel; }()); BarlineModel.prototype.divCount = 0; (function (BarlineModel) { var Layout = (function () { function Layout(origModel, cursor) { var _this = this; this.division = cursor.segmentDivision; this.x = cursor.segmentX; var attributes = cursor.staffAttributes; var measureStyle = attributes.measureStyle, partSymbol = attributes.partSymbol; if (measureStyle.multipleRest && measureStyle.multipleRest.count > 1) { // TODO: removing this shows that measures are slightly misplaced return; } this.partGroups = private_part_1.groupsForPart(cursor.header.partList, cursor.segmentInstance.part); this.partSymbol = partSymbol; this.model = Object.create(origModel, { defaultX: { get: function () { return _this.overrideX; } } }); var clefOffset = 0; if (cursor.lineTotalBarsOnLine === cursor.lineBarOnLine + 1) { // TODO: Figure out a way to get this to work when the attributes on the next // line change var nextMeasure = cursor.document.measures[cursor.measureInstance.idx + 1]; var part = nextMeasure && nextMeasure.parts[cursor.segmentInstance.part]; var segment = part && part.staves[cursor.staffIdx]; var nextAttributes = void 0; if (segment) { var n = cursor.factory.search(segment, 0, document_1.Type.Attributes)[0]; if (n) { nextAttributes = n._snapshot; } } var addWarning = nextAttributes && implAttributes_attributesData_1.needsWarning(attributes, nextAttributes, cursor.staffIdx); if (addWarning) { var clefsAreEqual = implAttributes_attributesData_1.clefsEqual(attributes, nextAttributes, cursor.staffIdx); clefOffset = clefsAreEqual ? 0 : implAttributes_attributesData_1.CLEF_INDENTATION; this.model.satieAttributes = implAttributes_attributesModel_1.default.createWarningLayout(cursor, attributes, nextAttributes); } } this.model.defaultY = 0; this.yOffset = 0; // TODO this.height = 20; // TODO /*---- Geometry ---------------------------------------*/ var lineWidths = cursor.header.defaults.appearance.lineWidths; var barlineSep = private_smufl_1.bravura.engravingDefaults.barlineSeparation; var setLines = function (lines) { var x = 0; _this.lineStarts = []; _this.lineWidths = []; lodash_1.forEach(lines, function (line, idx) { if (idx > 0) { x += barlineSep * 10; } _this.lineStarts.push(x); var width = lineWidths[line].tenths; _this.lineWidths.push(width); x += width; }); _this.model.satieAttribsOffset = x + 8 + clefOffset; cursor.segmentX += x; }; switch (this.model.barStyle.data) { case musicxml_interfaces_1.BarStyleType.LightHeavy: setLines(["light barline", "heavy barline"]); break; case musicxml_interfaces_1.BarStyleType.LightLight: setLines(["light barline", "light barline"]); break; case musicxml_interfaces_1.BarStyleType.HeavyHeavy: setLines(["heavy barline", "heavy barline"]); break; case musicxml_interfaces_1.BarStyleType.HeavyLight: setLines(["heavy barline", "light barline"]); break; case musicxml_interfaces_1.BarStyleType.Regular: case musicxml_interfaces_1.BarStyleType.Dashed: case musicxml_interfaces_1.BarStyleType.Dotted: case musicxml_interfaces_1.BarStyleType.Short: case musicxml_interfaces_1.BarStyleType.Tick: setLines(["light barline"]); break; case musicxml_interfaces_1.BarStyleType.Heavy: setLines(["heavy barline"]); break; case musicxml_interfaces_1.BarStyleType.None: setLines([]); break; default: invariant(false, "Not implemented"); } this.renderedWidth = cursor.segmentX - this.x + 8; } return Layout; }()); BarlineModel.Layout = Layout; Layout.prototype.expandPolicy = "none"; Layout.prototype.renderClass = document_1.Type.Barline; Layout.prototype.boundingBoxes = []; Object.freeze(Layout.prototype.boundingBoxes); })(BarlineModel || (BarlineModel = {})); ; /** * Registers Barline in the factory structure passed in. */ function Export(constructors) { constructors[document_1.Type.Barline] = BarlineModel; } Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Export;