MUSX Document Model
Loading...
Searching...
No Matches
CommonClasses.h
1/*
2 * Copyright (C) 2025, Robert Patterson
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 * THE SOFTWARE.
21 */
22#pragma once
23
24#include <numeric>
25#include <filesystem>
26#include <array>
27
28#include "musx/util/Fraction.h"
29#include "BaseClasses.h"
30
31namespace music_theory {
32class Transposer;
33} // namespace music_theory
34
35namespace musx {
36namespace dom {
37
38// This file contains common classes that are shared among Options, Others, and Details.
39
45enum class NoteType : Edu
46{
47 Maxima = 0x8000,
48 Longa = 0x4000,
49 Breve = 0x2000,
50 Whole = 0x1000,
51 Half = 0x0800,
52 Quarter = 0x0400,
53 Eighth = 0x0200,
54 Note16th = 0x0100,
55 Note32nd = 0x0080,
56 Note64th = 0x0040,
57 Note128th = 0x0020,
58 Note256th = 0x0010,
59 Note512th = 0x0008,
60 Note1024th = 0x0004,
61 Note2048th = 0x0002,
62 Note4096th = 0x0001
63};
64
68enum class ShowClefMode
69{
71 Never,
72 Always
73};
74
83{
84public:
86 int fontSize{};
87 bool bold{};
88 bool italic{};
89 bool underline{};
90 bool strikeout{};
91 bool absolute{};
92 bool hidden{};
93
95
100 std::string getName() const;
101
107 void setFontIdByName(const std::string& name);
108
115 void setEnigmaStyles(uint16_t efx)
116 {
117 bold = efx & 0x01; // FONT_EFX_BOLD
118 italic = efx & 0x02; // FONT_EFX_ITALIC
119 underline = efx & 0x04; // FONT_EFX_UNDERLINE
120 strikeout = efx & 0x20; // FONT_EFX_STRIKEOUT
121 absolute = efx & 0x40; // FONT_EFX_ABSOLUTE
122 hidden = efx & 0x80; // FONT_EFX_HIDDEN
123 }
124
127 { return fontId == 0; }
128
130 bool calcIsSymbolFont() const;
131
133 std::optional<std::filesystem::path> calcSMuFLMetaDataPath() const;
134
138 bool calcIsSMuFL() const { return calcSMuFLMetaDataPath().has_value(); }
139
145 static std::vector<std::filesystem::path> calcSMuFLPaths();
146
148};
149
155{
156private:
157 std::vector<unsigned> calcTonalCenterArrayForSharps() const;
158 std::vector<unsigned> calcTonalCenterArrayForFlats() const;
159 std::vector<unsigned> calcTonalCenterArray() const;
160 std::vector<int> calcAcciAmountsArray() const;
161 std::vector<unsigned> calcAcciOrderArray() const;
162
163 int m_octaveDisplacement{};
164 int m_alterationOffset{};
165
166public:
168
175 uint16_t key{};
176 bool keyless{};
178
193 Cmper getKeyMode() const { return isLinear() ? key >> 8 : key; }
194
197 int getAlteration() const { return isLinear() ? int(int8_t(key & 0xff)) + m_alterationOffset : 0; }
198
199 bool isLinear() const { return (key & 0xC000) == 0; }
200 bool isNonLinear() const { return (key & 0xC000) != 0; }
201 bool isBuiltIn() const { return isLinear() && getKeyMode() <= 1; }
202 bool isMajor() const { return getKeyMode() == 0; }
203 bool isMinor() const { return getKeyMode() == 1; }
204
206 bool isSame(const KeySignature& src)
207 {
208 return key == src.key && keyless == src.keyless && hideKeySigShowAccis == src.hideKeySigShowAccis;
209 }
210
227 void setTransposition(int interval, int keyAdjustment, bool simplify);
228
232 int calcTonalCenterIndex() const;
233
237 { return m_octaveDisplacement; }
238
241 int calcAlterationOnNote(unsigned noteIndex) const;
242
244 int calcEDODivisions() const;
245
247 std::optional<std::vector<int>> calcKeyMap() const;
248
253 std::unique_ptr<music_theory::Transposer> createTransposer(int displacement, int alteration) const;
254
255 void integrityCheck() override
256 {
258 if (key >= 0x8000) {
259 MUSX_INTEGRITY_ERROR("Key signature has invalid key value: " + std::to_string(key));
260 }
261 }
262
264};
265
266namespace texts {
267class LyricsTextBase; // forward delcaration
268} // namespace texts
269
275{
276public:
277
278 std::string syllable;
281
282private:
288 LyricsSyllableInfo(const DocumentWeakPtr& document, const std::string text, bool before, bool after)
289 : CommonClassBase(document), syllable(text), hasHyphenBefore(before), hasHyphenAfter(after)
290 {
291 }
292
293 friend class texts::LyricsTextBase;
294};
295
296namespace details {
297class IndependentStaffDetails; // forward delcaration
298} // namespace details
299
300namespace others {
301 class Measure; // forward delcaration
302 } // namespace others
303
309{
310public:
311
314 {
315 std::vector<util::Fraction> counts;
317 std::vector<Edu> units;
320
322 bool operator==(const TimeSigComponent& src) const
323 { return counts == src.counts && units == src.units; }
324
327 { return std::accumulate(counts.begin(), counts.end(), util::Fraction{}); }
328
330 Edu sumUnits() const
331 { return std::accumulate(units.begin(), units.end(), Edu{}); }
332 };
333
334 std::vector<TimeSigComponent> components;
335
340 std::pair<util::Fraction, NoteType> calcSimplified() const;
341
344 {
345 util::Fraction result = std::accumulate(components.begin(), components.end(), util::Fraction{},
346 [](const util::Fraction& acc, const TimeSigComponent& comp)
347 { return acc + (comp.sumCounts() * comp.sumUnits()); }
348 );
349 return result / Edu(NoteType::Whole);
350 }
351
353 bool isSame(const TimeSignature& src)
354 {
355 return components == src.components && m_abbreviate == src.m_abbreviate;
356 }
357
361 std::shared_ptr<TimeSignature> createComponent(size_t index) const
362 {
363 checkIndex(index);
364 return std::shared_ptr<TimeSignature>(new TimeSignature(getDocument(), components[index], m_abbreviate));
365 }
366
371 std::optional<char32_t> getAbbreviatedSymbol() const;
372
374 bool isCommonTime() const;
376 bool isCutTime() const;
377
378private:
379 void checkIndex(size_t index) const
380 {
381 if (index > components.size()) {
382 throw std::invalid_argument("Index out of range. The time signature has " + std::to_string(components.size())
383 + " elements. The index requested was " + std::to_string(index) + ".");
384 }
385 }
386
391 explicit TimeSignature(const DocumentWeakPtr& document, int beats, Edu unit, bool hasCompositeTop, bool hasCompositeBottom,
392 std::optional<bool> abbreviate = std::nullopt);
393
398 explicit TimeSignature(const DocumentWeakPtr& document, const TimeSigComponent& timeSigUnit, std::optional<bool> abbreviate)
399 : CommonClassBase(document), m_abbreviate(abbreviate)
400 {
401 components.push_back(timeSigUnit);
402 }
403
404 std::optional<bool> m_abbreviate;
405
406 friend class others::Measure;
407 friend class details::IndependentStaffDetails;
408};
409
410namespace others {
411
412// The following classes are defined here because they are shared by multiple subclasses and container classes.
413
418class Enclosure : public OthersBase
419{
420public:
425 enum class Shape : uint8_t
426 {
427 NoEnclosure = 0,
428 Rectangle = 1,
429 Ellipse = 2,
430 Triangle = 3,
431 Diamond = 4,
432 Pentagon = 5,
433 Hexagon = 6,
434 Heptagon = 7,
435 Octogon = 8
436 };
437
445 explicit Enclosure(const DocumentWeakPtr& document, Cmper partId = 0, ShareMode shareMode = ShareMode::All, Cmper cmper = 0)
446 : OthersBase(document, partId, shareMode, cmper) {}
447
455 bool fixedSize{};
456 bool equalAspect{};
457 bool notTall{};
458 bool opaque{};
460
462};
463
471class MusicRange : public OthersBase
472{
473public:
482 explicit MusicRange(const DocumentWeakPtr& document, Cmper partId = SCORE_PARTID, ShareMode shareMode = ShareMode::All,
483 Cmper cmper = 0, std::optional<Inci> inci = std::nullopt)
484 : OthersBase(document, partId, shareMode, cmper, inci)
485 {
486 }
487
492
496 bool contains(MeasCmper measId, Edu eduPosition) const
497 {
498 return (startMeas < measId || (startMeas == measId && startEdu <= eduPosition)) &&
499 (endMeas > measId || (endMeas == measId && endEdu >= eduPosition));
500 }
501
503};
504
513{
514public:
515
523 explicit NamePositioning(const DocumentWeakPtr& document, Cmper partId = SCORE_PARTID, ShareMode shareMode = ShareMode::All, Cmper cmper = 0)
524 : OthersBase(document, partId, shareMode, cmper) {}
525
527 enum class AlignJustify
528 {
529 Left,
530 Right,
531 Center
532 };
533
537 bool indivPos{};
539 bool expand{};
540
542};
543
544} // namespace others
545} // namespace dom
546} // namespace mux
DocumentPtr getDocument() const
Gets a reference to the Document.
Definition BaseClasses.h:89
virtual void integrityCheck()
Allows a class to determine if it has been properly contructed by the factory and fix issues that it ...
Definition BaseClasses.h:133
ShareMode
Describes how this instance is shared between part and score.
Definition BaseClasses.h:72
Base class for classes that are commonly used among others, details, entries, and/or texts....
Definition BaseClasses.h:174
CommonClassBase(const DocumentWeakPtr &document)
Constructs a CommonClassBase object.
Definition BaseClasses.h:181
Represents the default font settings for a particular element type.
Definition CommonClasses.h:83
bool calcIsSymbolFont() const
Calculates if this is a symbol font. (See others::FontDefinition::calcIsSymbolFont....
Definition Implementations.cpp:707
bool strikeout
Strikeout effect.
Definition CommonClasses.h:90
void setFontIdByName(const std::string &name)
Sets the id of the font from a string name.
Definition Implementations.cpp:679
Cmper fontId
Font identifier. This is a Cmper for others::FontDefinition.
Definition CommonClasses.h:85
static std::vector< std::filesystem::path > calcSMuFLPaths()
Returns the standard SMuFL font folder.
Definition Implementations.cpp:715
bool calcIsSMuFL() const
Calculates whether this is a SMuFL font.
Definition CommonClasses.h:138
std::string getName() const
Get the name of the font.
Definition Implementations.cpp:671
static const xml::XmlElementArray< FontInfo > & xmlMappingArray()
Required for musx::factory::FieldPopulator.
void setEnigmaStyles(uint16_t efx)
Set style effects based on a bitmask. This is mainly useful for capturing text styles from enigma str...
Definition CommonClasses.h:115
bool italic
Italic effect.
Definition CommonClasses.h:88
bool hidden
Hidden effect.
Definition CommonClasses.h:92
bool calcIsDefaultMusic() const
Calculates if this is the default music font.
Definition CommonClasses.h:126
int fontSize
Font size.
Definition CommonClasses.h:86
bool underline
Underline effect.
Definition CommonClasses.h:89
bool absolute
Fixed size effect.
Definition CommonClasses.h:91
std::optional< std::filesystem::path > calcSMuFLMetaDataPath() const
Returns the filepath of the SMuFL font's metadata json file, if any.
Definition Implementations.cpp:691
bool bold
Bold effect.
Definition CommonClasses.h:87
Shared key signature class that is contained in other classes. (See others::Measure)
Definition CommonClasses.h:155
Cmper getKeyMode() const
Returns the key mode.
Definition CommonClasses.h:193
bool hideKeySigShowAccis
Instead of a key signature, show accidentals for the key on the notes where they occur.
Definition CommonClasses.h:177
int getAlteration() const
For linear keys, returns the number of sharps or flats from -7..7.
Definition CommonClasses.h:197
bool isLinear() const
whether this is a linear key
Definition CommonClasses.h:199
int calcEDODivisions() const
Calculates the number of EDO division for the key. (The standard value is 12.)
Definition Implementations.cpp:1275
bool isBuiltIn() const
whether this is a built-in key
Definition CommonClasses.h:201
int calcAlterationOnNote(unsigned noteIndex) const
Calculates the amount of alteration on a note int the key.
Definition Implementations.cpp:1178
uint16_t key
16-bit value intepreted as follows:
Definition CommonClasses.h:175
std::unique_ptr< music_theory::Transposer > createTransposer(int displacement, int alteration) const
Creates a transposer for this KeySignature instance.
Definition Implementations.cpp:1283
void setTransposition(int interval, int keyAdjustment, bool simplify)
Transposes the key by the specified amounts. Set them to zero to remove transposition.
Definition Implementations.cpp:1210
bool isMinor() const
whether this is a built-in minor key
Definition CommonClasses.h:203
int getOctaveDisplacement() const
The octave displacement if this key is a transposed key.
Definition CommonClasses.h:236
void integrityCheck() override
Allows a class to determine if it has been properly contructed by the factory and fix issues that it ...
Definition CommonClasses.h:255
bool isSame(const KeySignature &src)
returns whether the two key signatures represent the same key signature. Does not take into account t...
Definition CommonClasses.h:206
bool isNonLinear() const
whether this is a non-linear key
Definition CommonClasses.h:200
static const xml::XmlElementArray< KeySignature > & xmlMappingArray()
Required for musx::factory::FieldPopulator.
bool isMajor() const
whether this is a built-in major key
Definition CommonClasses.h:202
std::optional< std::vector< int > > calcKeyMap() const
Calculates the key's diatonic key map.
Definition Implementations.cpp:1237
int calcTonalCenterIndex() const
Calculates the tonal center index for the key, where C=0, D=1, E=2, ...
Definition Implementations.cpp:1167
bool keyless
Indicates the absence of a key signature.
Definition CommonClasses.h:176
Contains the syllable information for a single syllable. (See texts::LyricsTextBase)
Definition CommonClasses.h:275
bool hasHyphenAfter
indicates the syllable if followed by a hyphen.
Definition CommonClasses.h:280
std::string syllable
the syllable text with no hyphenation or font information.
Definition CommonClasses.h:278
bool hasHyphenBefore
indicates the syllable is preceded by a hyphen.
Definition CommonClasses.h:279
Base class for all "others" types.
Definition BaseClasses.h:220
Shared time signature class that is derived from other classes. (See others::Measure)
Definition CommonClasses.h:309
bool isCutTime() const
Returns if this time signature is cut time.
Definition Implementations.cpp:2548
std::vector< TimeSigComponent > components
the components in the time signature
Definition CommonClasses.h:334
bool isSame(const TimeSignature &src)
returns whether the two time signatures represent the same time signature
Definition CommonClasses.h:353
util::Fraction calcTotalDuration() const
Calculates the total duration of the time signature as a fraction of a whole note.
Definition CommonClasses.h:343
std::optional< char32_t > getAbbreviatedSymbol() const
Returns the abbreviated symbol (code point) for this time signature, or std::nullopt if none.
Definition Implementations.cpp:2517
bool isCommonTime() const
Returns if this time signature is common time.
Definition Implementations.cpp:2540
std::pair< util::Fraction, NoteType > calcSimplified() const
Calculates the simplest form of of this time signature, expressed as a fractional count of NoteType u...
Definition Implementations.cpp:2556
std::shared_ptr< TimeSignature > createComponent(size_t index) const
Creates a time signature corresponding to the component at index.
Definition CommonClasses.h:361
Represents independent time and key signature overrides for a staff.
Definition Details.h:366
Represents the enclosure settings for text expressions.
Definition CommonClasses.h:419
bool notTall
"Enforce Minimum Width": don't let shape get taller than it is wide
Definition CommonClasses.h:457
Evpu yAdd
Center Y offset - offsets text from center (in EVPU).
Definition CommonClasses.h:449
Enclosure(const DocumentWeakPtr &document, Cmper partId=0, ShareMode shareMode=ShareMode::All, Cmper cmper=0)
Constructs an Enclosure object.
Definition CommonClasses.h:445
bool roundCorners
Whether the enclosure has rounded corners.
Definition CommonClasses.h:459
Efix lineWidth
Line thickness in 64ths of an EVPU (EFIX).
Definition CommonClasses.h:452
static const xml::XmlElementArray< Enclosure > & xmlMappingArray()
Required for musx::factory::FieldPopulator.
bool opaque
Whether the enclosure is opaque.
Definition CommonClasses.h:458
Shape
Enumeration for enclosure shapes.
Definition CommonClasses.h:426
Evpu yMargin
Half height - extra space on top/bottom sides (in EVPU).
Definition CommonClasses.h:451
Shape shape
Enclosure shape (default: NoEnclosure).
Definition CommonClasses.h:453
bool fixedSize
Whether the enclosure is fixed size (ignore text bounding box)
Definition CommonClasses.h:455
bool equalAspect
"Match Height and Width"
Definition CommonClasses.h:456
Efix cornerRadius
Corner radius (in EFIX).
Definition CommonClasses.h:454
Evpu xMargin
Half width - extra space on left/right sides (in EVPU).
Definition CommonClasses.h:450
Evpu xAdd
Center X offset - offsets text from center (in EVPU).
Definition CommonClasses.h:448
Represents a range of music using measure and EDUs.
Definition CommonClasses.h:472
Edu startEdu
Starting EDU (Elapsed Durational Unit) in the range.
Definition CommonClasses.h:489
MeasCmper endMeas
Ending measure in the range.
Definition CommonClasses.h:490
static const xml::XmlElementArray< MusicRange > & xmlMappingArray()
Required for musx::factory::FieldPopulator.
Edu endEdu
Ending EDU (Elapsed Durational Unit) in the range.
Definition CommonClasses.h:491
MusicRange(const DocumentWeakPtr &document, Cmper partId=SCORE_PARTID, ShareMode shareMode=ShareMode::All, Cmper cmper=0, std::optional< Inci > inci=std::nullopt)
Constructs a MusicRange object.
Definition CommonClasses.h:482
MeasCmper startMeas
Starting measure in the range.
Definition CommonClasses.h:488
bool contains(MeasCmper measId, Edu eduPosition) const
Returns true of the given metric location is contained in this MusicRange instance.
Definition CommonClasses.h:496
Contains horizontal and vertical offsets, alignment, and expansion settings for name positioning.
Definition CommonClasses.h:513
bool indivPos
Indicates that this positioning overrides the default positioning. (Not used by options::StaffOptions...
Definition CommonClasses.h:537
NamePositioning(const DocumentWeakPtr &document, Cmper partId=SCORE_PARTID, ShareMode shareMode=ShareMode::All, Cmper cmper=0)
Constructs an NamePositioning object.
Definition CommonClasses.h:523
bool expand
"Expand Single Word"
Definition CommonClasses.h:539
AlignJustify
Alignment and justification options for staff and group names.
Definition CommonClasses.h:528
@ Left
Left alignment or justification (the default value.)
Evpu horzOff
Horizontal distance from staff in Evpu.
Definition CommonClasses.h:534
AlignJustify hAlign
Horizontal alignment for the name text. (xml node is <halign>)
Definition CommonClasses.h:538
AlignJustify justify
Justification for the name text.
Definition CommonClasses.h:536
Evpu vertOff
Vertical offset from staff in Evpu.
Definition CommonClasses.h:535
static const xml::XmlElementArray< NamePositioning > & xmlMappingArray()
Required for musx::factory::FieldPopulator.
Base class for lyrics text.
Definition Texts.h:118
A class to represent fractions with integer m_numerator and m_denominator, automatically reduced to s...
Definition Fraction.h:37
A dependency-free, header-only collection of useful functions for music theory.
ShowClefMode
Enum representing the clef display mode for a frame.
Definition CommonClasses.h:69
@ WhenNeeded
Clef is displayed only when needed (the default).
@ Always
Clef is always displayed. (xml value is "forced")
@ Never
Clef is never displayed. (xml value is "hidden")
NoteType
Enum class representing note types based on EDU values.
Definition CommonClasses.h:46
int16_t MeasCmper
Enigma meas Cmper (may be negative when not applicable)
Definition Fundamentals.h:64
int32_t Efix
EFIX value (64 per EVPU, 64*288=18432 per inch)
Definition Fundamentals.h:60
constexpr Cmper SCORE_PARTID
The part id of the score.
Definition Fundamentals.h:75
int32_t Evpu
EVPU value (288 per inch)
Definition Fundamentals.h:57
uint16_t Cmper
Enigma "comperator" key type.
Definition Fundamentals.h:55
int32_t Edu
"Enigma Durational Units" value (1024 per quarter note)
Definition Fundamentals.h:61
std::weak_ptr< Document > DocumentWeakPtr
Shared weak Document pointer.
Definition BaseClasses.h:57
std::vector< XmlElementDescriptor< T > > XmlElementArray
an array type for XmlElementDescriptor instances.
Definition XmlInterface.h:127
object model for musx file (enigmaxml)
Definition BaseClasses.h:32
A single time signature component.
Definition CommonClasses.h:314
std::vector< util::Fraction > counts
Definition CommonClasses.h:315
std::vector< Edu > units
Definition CommonClasses.h:317
util::Fraction sumCounts() const
Compute the sum of all counts.
Definition CommonClasses.h:326
Edu sumUnits() const
Compute the sum of all units.
Definition CommonClasses.h:330
bool operator==(const TimeSigComponent &src) const
Test if two TimeSigComponent values are the same.
Definition CommonClasses.h:322