2012-05-26 14:26:10 +02:00
//=============================================================================
// MuseScore
// Music Composition & Notation
//
// Copyright (C) 2002-2011 Werner Schweer
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2
// as published by the Free Software Foundation and appearing in
// the file LICENCE.GPL
//=============================================================================
# ifndef __FIGUREDBASS_H__
# define __FIGUREDBASS_H__
# include "text.h"
2013-05-13 18:49:17 +02:00
namespace Ms {
2017-03-08 13:12:26 +01:00
class Segment ;
2012-05-26 14:26:10 +02:00
/*---------------------------------------------------------
NOTE ON ARCHITECTURE
FiguredBass elements are stored in the annotations of a Segment ( like for instance Harmony )
FiguredBass is rather simple : it contains only _ticks , telling the duration of the element ,
and a list of FiguredBassItem elements which do most of the job . It also maintains a text with the
normalized ( made uniform ) version of the text , which is used during editing .
2012-08-14 14:58:43 +02:00
Normally , a FiguredBass element is assumed to be styled with an internally maintained text style
( based on the parameters of the general style " Figured Bass " ) FIGURED_BASS style and it is set
in this way upon creation and upon layout ( ) .
2012-05-26 14:26:10 +02:00
- - - -
FiguredBassItem contains the actually f . b . info ; it is made of 4 parts ( in this order ) :
2013-02-10 07:01:31 +01:00
1 ) prefix : one of [ nothing , doubleflat , flat , natural , sharp , doublesharp , cross ]
2012-05-26 14:26:10 +02:00
2 ) digit : one digit from 1 to 9
2013-02-10 07:01:31 +01:00
3 ) suffix : one of [ nothing , doubleflat , flat , natural , sharp , doublesharp , cross , backslash , slash ]
2012-05-26 14:26:10 +02:00
4 ) contLine : true if the item has a continuation line ( whose length is determined by parent ' s _ticks )
and 5 parenthesis flags , one for each position before , between and after the four parts above :
each of them may contain one of [ nothing , roundOpen , roundClosed , squaredOpen , squaredClosed ] .
There is a number of restrictions , implemented at the end of FiguredBassItem : : parse ( ) .
Currently , no attempt is made to ensure that , if multiple parentheses are present , they are consistent
( matching open and closed parentheses is left to the user ) .
If an item cannot be parsed , the whole FiguredBass element is kept as entered , possibly un - styled .
If all items can be parsed , each item generates a display text from its properties ,
lays it out so that it properly aligns under the chord , draws it at its proper location
and provides its FiguredBass parent with a normalized text for future editing .
FiguredBassItem has not use for formats ( italics , bold , . . . ) and it is never edited directly ;
more generally , it is never accessed directly , only via its FiguredBass parent ;
2012-08-01 19:06:20 +02:00
so it is directly derived from Element and returns INVALID as type .
2012-05-26 14:26:10 +02:00
FiguredBass might require formatting ( discouraged , but might be necessary for very uncommon cases )
and it is edited ( via the normalized text ) ; so it is derived from Text .
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2013-02-10 07:01:31 +01:00
# define FBIDigitNone -1
2013-01-17 11:33:11 +01:00
2012-05-26 14:26:10 +02:00
//---------------------------------------------------------
2012-07-25 11:49:34 +02:00
// @@ FiguredBassItem
2012-08-10 20:50:27 +02:00
/// One line of a figured bass indication
//
2015-04-24 00:55:46 +02:00
// @P continuationLine enum (FiguredBassItem.NONE, .SIMPLE, .EXTENDED) whether item has continuation line or not, and of which type
// @P digit int main digit(s) (0 - 9)
// @P displayText string text displayed (depends on configured fonts) (read only)
fix various typos
* Found via `codespell -q 3 -S ./share/locale,./thirdparty -L ba,cann,clas,dur,foto,iff,nd,ois,ot,pres,possibile,snaped,strack,tage,te,uint,thru,valu`
* Some revisions made per feedback given during review.
* Follow-up typos for review
* Add revisions per feedback
2019-12-17 21:06:10 +01:00
// @P normalizedText string conventional textual representation of item properties (= text used during input) (read only)
// @P parenthesis1 enum (FiguredBassItem.NONE, .ROUNDOPEN, .ROUNDCLOSED, .SQUAREDOPEN, .SQUAREDCLOSED) parenthesis before the prefix
// @P parenthesis2 enum (FiguredBassItem.NONE, .ROUNDOPEN, .ROUNDCLOSED, .SQUAREDOPEN, .SQUAREDCLOSED) parenthesis after the prefix / before the digit
// @P parenthesis3 enum (FiguredBassItem.NONE, .ROUNDOPEN, .ROUNDCLOSED, .SQUAREDOPEN, .SQUAREDCLOSED) parenthesis after the digit / before the suffix
// @P parenthesis4 enum (FiguredBassItem.NONE, .ROUNDOPEN, .ROUNDCLOSED, .SQUAREDOPEN, .SQUAREDCLOSED) parenthesis after the suffix / before the cont. line
// @P parenthesis5 enum (FiguredBassItem.NONE, .ROUNDOPEN, .ROUNDCLOSED, .SQUAREDOPEN, .SQUAREDCLOSED) parenthesis after the cont. line
2015-04-24 00:55:46 +02:00
// @P prefix enum (FiguredBassItem.NONE, .DOUBLEFLAT, .FLAT, .NATURAL, .SHARP, .DOUBLESHARP, .PLUS, .BACKSLASH, .SLASH) accidental before the digit
// @P suffix enum (FiguredBassItem.NONE, .DOUBLEFLAT, .FLAT, .NATURAL, .SHARP, .DOUBLESHARP, .PLUS, .BACKSLASH, .SLASH) accidental/diacritic after the digit
2012-05-26 14:26:10 +02:00
//---------------------------------------------------------
class FiguredBass ;
2017-12-21 14:03:45 +01:00
class FiguredBassItem final : public Element {
2012-08-10 20:50:27 +02:00
public :
2014-05-22 22:21:56 +02:00
enum class Modifier : char {
NONE = 0 ,
DOUBLEFLAT ,
FLAT ,
NATURAL ,
SHARP ,
DOUBLESHARP ,
CROSS ,
BACKSLASH ,
SLASH ,
NUMOF
2016-10-20 11:32:07 +02:00
} ;
2014-05-23 08:24:41 +02:00
enum class Parenthesis : char {
NONE = 0 ,
ROUNDOPEN ,
ROUNDCLOSED ,
SQUAREDOPEN ,
SQUAREDCLOSED ,
NUMOF
2016-10-20 11:32:07 +02:00
} ;
2014-05-23 09:49:22 +02:00
enum class ContLine : char {
NONE = 0 ,
SIMPLE , // cont. line stops at f.b. element end
EXTENDED // cont. line joins with next element, if possible
2016-10-20 11:32:07 +02:00
} ;
2013-02-12 16:00:05 +01:00
2014-05-23 10:06:55 +02:00
enum class Style : char {
MODERN = 0 ,
HISTORIC ,
NUMOF
2013-02-10 07:01:31 +01:00
} ;
2014-05-23 11:45:32 +02:00
enum class Combination : char {
SIMPLE = 0 ,
CROSSED ,
BACKSLASHED ,
SLASHED ,
NUMOF
2013-02-10 07:01:31 +01:00
} ;
2012-05-26 14:26:10 +02:00
2012-08-10 20:50:27 +02:00
private :
2014-05-23 08:24:41 +02:00
static const QChar normParenthToChar [ int ( Parenthesis : : NUMOF ) ] ;
2012-05-26 14:26:10 +02:00
2012-08-01 19:06:20 +02:00
QString _displayText ; // the constructed display text (read-only)
2012-05-26 14:26:10 +02:00
int ord ; // the line ordinal of this element in the FB stack
// the parts making a FiguredBassItem up
2012-08-11 01:15:22 +02:00
Modifier _prefix ; // the accidental coming before the body
2012-08-10 20:50:27 +02:00
int _digit ; // the main digit (if present)
2012-08-11 01:15:22 +02:00
Modifier _suffix ; // the accidental coming after the body
2013-02-12 16:00:05 +01:00
ContLine _contLine ; // whether the item has continuation line or not
2012-08-11 01:15:22 +02:00
Parenthesis parenth [ 5 ] ; // each of the parenthesis: before, between and after parts
2012-05-26 14:26:10 +02:00
qreal textWidth ; // the text width (in raster units), set during layout()
// used by draw()
// part parsing
int parseDigit ( QString & str ) ;
int parseParenthesis ( QString & str , int parenthIdx ) ;
int parsePrefixSuffix ( QString & str , bool bPrefix ) ;
2012-08-01 19:06:20 +02:00
void setDisplayText ( const QString & s ) { _displayText = s ; }
2012-08-10 20:50:27 +02:00
// read / write MusicXML support
2012-08-11 01:15:22 +02:00
QString Modifier2MusicXML ( FiguredBassItem : : Modifier prefix ) const ;
2012-08-01 19:06:20 +02:00
2012-05-26 14:26:10 +02:00
public :
2012-08-10 20:50:27 +02:00
FiguredBassItem ( Score * s = 0 , int line = 0 ) ;
2012-05-26 14:26:10 +02:00
FiguredBassItem ( const FiguredBassItem & ) ;
~ FiguredBassItem ( ) ;
2014-06-27 13:41:49 +02:00
FiguredBassItem & operator = ( const FiguredBassItem & ) = delete ;
2012-05-26 14:26:10 +02:00
2013-01-17 11:33:11 +01:00
FiguredBassItem : : Modifier MusicXML2Modifier ( const QString prefix ) const ;
2012-05-26 14:26:10 +02:00
// standard re-implemented virtual functions
2015-01-19 12:37:17 +01:00
virtual FiguredBassItem * clone ( ) const override { return new FiguredBassItem ( * this ) ; }
2017-01-18 14:16:33 +01:00
virtual ElementType type ( ) const override { return ElementType : : INVALID ; }
2015-01-19 12:37:17 +01:00
virtual void draw ( QPainter * painter ) const override ;
virtual void layout ( ) override ;
virtual void read ( XmlReader & ) override ;
2016-11-19 11:51:21 +01:00
virtual void write ( XmlWriter & xml ) const override ;
2012-05-26 14:26:10 +02:00
// read / write MusicXML
2016-11-19 11:51:21 +01:00
void writeMusicXML ( XmlWriter & xml , bool isOriginalFigure , int crEndTick , int fbEndTick ) const ;
2012-05-26 14:26:10 +02:00
bool startsWithParenthesis ( ) const ;
// specific API
const FiguredBass * figuredBass ( ) const { return ( FiguredBass * ) ( parent ( ) ) ; }
bool parse ( QString & text ) ;
2012-08-10 20:50:27 +02:00
// getters / setters
2012-08-11 01:15:22 +02:00
Modifier prefix ( ) const { return _prefix ; }
2013-01-17 11:33:11 +01:00
void setPrefix ( const Modifier & v ) { _prefix = v ; }
2012-08-11 01:15:22 +02:00
void undoSetPrefix ( Modifier pref ) ;
2012-08-10 20:50:27 +02:00
int digit ( ) const { return _digit ; }
2013-01-17 11:33:11 +01:00
void setDigit ( int val ) { _digit = val ; }
2012-08-10 20:50:27 +02:00
void undoSetDigit ( int digit ) ;
2012-08-11 01:15:22 +02:00
Modifier suffix ( ) const { return _suffix ; }
2013-01-17 11:33:11 +01:00
void setSuffix ( const Modifier & v ) { _suffix = v ; }
2012-08-11 01:15:22 +02:00
void undoSetSuffix ( Modifier suff ) ;
2013-02-12 16:00:05 +01:00
ContLine contLine ( ) const { return _contLine ; }
2015-01-03 10:58:53 +01:00
void setContLine ( const ContLine & v ) { _contLine = v ; }
2014-05-23 09:49:22 +02:00
void undoSetContLine ( ContLine val ) ;
2012-08-14 14:58:43 +02:00
Parenthesis parenth1 ( ) { return parenth [ 0 ] ; }
Parenthesis parenth2 ( ) { return parenth [ 1 ] ; }
Parenthesis parenth3 ( ) { return parenth [ 2 ] ; }
Parenthesis parenth4 ( ) { return parenth [ 3 ] ; }
Parenthesis parenth5 ( ) { return parenth [ 4 ] ; }
2013-01-17 11:33:11 +01:00
void setParenth1 ( Parenthesis v ) { parenth [ 0 ] = v ; }
void setParenth2 ( Parenthesis v ) { parenth [ 1 ] = v ; }
void setParenth3 ( Parenthesis v ) { parenth [ 2 ] = v ; }
void setParenth4 ( Parenthesis v ) { parenth [ 3 ] = v ; }
void setParenth5 ( Parenthesis v ) { parenth [ 4 ] = v ; }
2012-08-14 14:58:43 +02:00
void undoSetParenth1 ( Parenthesis par ) ;
void undoSetParenth2 ( Parenthesis par ) ;
void undoSetParenth3 ( Parenthesis par ) ;
void undoSetParenth4 ( Parenthesis par ) ;
void undoSetParenth5 ( Parenthesis par ) ;
2012-08-10 20:50:27 +02:00
QString normalizedText ( ) const ;
QString displayText ( ) const { return _displayText ; }
2012-05-26 14:26:10 +02:00
2018-03-27 15:36:00 +02:00
virtual QVariant getProperty ( Pid propertyId ) const override ;
virtual bool setProperty ( Pid propertyId , const QVariant & ) override ;
virtual QVariant propertyDefault ( Pid ) const override ;
2016-10-20 11:32:07 +02:00
} ;
2012-05-26 14:26:10 +02:00
//---------------------------------------------------------
// FiguredBassFont
//---------------------------------------------------------
struct FiguredBassFont {
QString family ;
QString displayName ;
qreal defPitch ;
qreal defLineHeight ;
2014-05-22 22:21:56 +02:00
QChar displayAccidental [ int ( FiguredBassItem : : Modifier : : NUMOF ) ] ;
2014-05-23 08:24:41 +02:00
QChar displayParenthesis [ int ( FiguredBassItem : : Parenthesis : : NUMOF ) ] ;
2014-05-23 11:45:32 +02:00
QChar displayDigit [ int ( FiguredBassItem : : Style : : NUMOF ) ] [ 10 ] [ int ( FiguredBassItem : : Combination : : NUMOF ) ] ;
2012-05-26 14:26:10 +02:00
2013-01-11 18:10:18 +01:00
bool read ( XmlReader & ) ;
2016-10-20 11:32:07 +02:00
} ;
2012-05-26 14:26:10 +02:00
//---------------------------------------------------------
2012-07-25 11:49:34 +02:00
// @@ FiguredBass
2014-05-16 13:44:32 +02:00
/// A complete figured bass indication
2012-08-10 00:11:42 +02:00
//
2014-05-16 13:44:32 +02:00
// @P onNote bool whether it is placed on a note beginning or between notes (read only)
// @P ticks int duration in ticks
2012-05-26 14:26:10 +02:00
//---------------------------------------------------------
2017-12-27 11:51:00 +01:00
class FiguredBass final : public TextBase {
2014-04-21 00:46:40 +02:00
std : : vector < FiguredBassItem * > items ; // the individual lines of the F.B.
2018-11-27 22:49:18 +01:00
QVector < qreal > _lineLengths ; // lengths of duration indicator lines (in raster units)
2012-05-26 14:26:10 +02:00
bool _onNote ; // true if this element is on a staff note | false if it is betweee notes
2019-01-30 15:13:54 +01:00
Fraction _ticks ; // the duration (used for cont. lines and for multiple F.B.
2012-05-26 14:26:10 +02:00
// under the same note)
2013-03-01 13:42:05 +01:00
qreal _printedLineLength ; // the length of lines actually printed (i.e. continuation lines)
2012-05-26 14:26:10 +02:00
void layoutLines ( ) ;
2012-08-10 20:50:27 +02:00
bool hasParentheses ( ) const ; // read / write MusicXML support
2012-08-01 19:06:20 +02:00
2019-05-17 03:45:27 +02:00
virtual Sid getPropertyStyle ( Pid ) const override ;
2012-05-26 14:26:10 +02:00
public :
2012-08-10 20:50:27 +02:00
FiguredBass ( Score * s = 0 ) ;
2012-05-26 14:26:10 +02:00
FiguredBass ( const FiguredBass & ) ;
~ FiguredBass ( ) ;
// a convenience static function to create/retrieve a new FiguredBass into/from its intended parent
2019-01-30 15:13:54 +01:00
static FiguredBass * addFiguredBassToSegment ( Segment * seg , int track , const Fraction & extTicks , bool * pNew ) ;
2012-05-26 14:26:10 +02:00
// static functions for font config files
static bool readConfigFile ( const QString & fileName ) ;
static QList < QString > fontNames ( ) ;
static bool fontData ( int nIdx , QString * pFamily , QString * pDisplayName ,
qreal * pSize , qreal * pLineHeight ) ;
// standard re-implemented virtual functions
2017-12-21 14:03:45 +01:00
virtual FiguredBass * clone ( ) const override { return new FiguredBass ( * this ) ; }
2017-01-18 14:16:33 +01:00
virtual ElementType type ( ) const override { return ElementType : : FIGURED_BASS ; }
2015-01-19 12:37:17 +01:00
virtual void draw ( QPainter * painter ) const override ;
2017-03-31 13:03:15 +02:00
virtual void endEdit ( EditData & ) override ;
2015-01-19 12:37:17 +01:00
virtual void layout ( ) override ;
virtual void read ( XmlReader & ) override ;
virtual void setSelected ( bool f ) override ;
virtual void setVisible ( bool f ) override ;
2017-03-31 13:03:15 +02:00
virtual void startEdit ( EditData & ) override ;
2016-11-19 11:51:21 +01:00
virtual void write ( XmlWriter & xml ) const override ;
2012-05-26 14:26:10 +02:00
// read / write MusicXML
2016-11-19 11:51:21 +01:00
void writeMusicXML ( XmlWriter & xml , bool isOriginalFigure , int crEndTick , int fbEndTick , bool writeDuration , int divisions ) const ;
2012-05-26 14:26:10 +02:00
2012-08-10 20:50:27 +02:00
//DEBUG
2014-07-06 01:56:30 +02:00
//Q_INVOKABLE Ms::FiguredBassItem* addItem();
2012-08-10 20:50:27 +02:00
2012-08-11 01:15:22 +02:00
// getters / setters / properties
2012-08-10 00:11:42 +02:00
// void qmlItemsAppend(QDeclarativeListProperty<FiguredBassItem> *list, FiguredBassItem * pItem)
// { list->append(pItem);
// items.append(&pItem);
// }
// QDeclarativeListProperty<FiguredBassItem> qmlItems()
// { QList<FiguredBassItem*> list;
// foreach(FiguredBassItem item, items)
// list.append(&item);
// return QDeclarativeListProperty<FiguredBassItem>(this, &items, qmlItemsAppend);
// }
2018-11-27 22:49:18 +01:00
qreal lineLength ( int idx ) const { if ( _lineLengths . size ( ) > idx )
return _lineLengths . at ( idx ) ;
2012-08-10 00:11:42 +02:00
return 0 ; }
2013-03-01 13:42:05 +01:00
qreal printedLineLength ( ) const { return _printedLineLength ; }
2012-05-26 14:26:10 +02:00
bool onNote ( ) const { return _onNote ; }
2018-09-11 16:56:50 +02:00
size_t numOfItems ( ) const { return items . size ( ) ; }
2012-05-26 14:26:10 +02:00
void setOnNote ( bool val ) { _onNote = val ; }
2017-03-08 13:12:26 +01:00
Segment * segment ( ) const { return ( Segment * ) ( parent ( ) ) ; }
2019-01-30 15:13:54 +01:00
Fraction ticks ( ) const { return _ticks ; }
void setTicks ( const Fraction & v ) { _ticks = v ; }
2012-05-26 14:26:10 +02:00
2013-02-12 16:00:05 +01:00
qreal additionalContLineX ( qreal pagePosY ) const ; // returns the X coord (in page coord) of cont. line at pagePosY, if any
FiguredBass * nextFiguredBass ( ) const ; // returns next *adjacent* f.b. item, if any
2018-03-27 15:36:00 +02:00
virtual QVariant getProperty ( Pid propertyId ) const override ;
virtual bool setProperty ( Pid propertyId , const QVariant & ) override ;
virtual QVariant propertyDefault ( Pid ) const override ;
2013-01-17 11:33:11 +01:00
2014-04-21 00:46:40 +02:00
void appendItem ( FiguredBassItem * item ) { items . push_back ( item ) ; }
2012-05-26 14:26:10 +02:00
} ;
2013-05-13 18:49:17 +02:00
} // namespace Ms
Q_DECLARE_METATYPE ( Ms : : FiguredBassItem : : Modifier ) ;
Q_DECLARE_METATYPE ( Ms : : FiguredBassItem : : Parenthesis ) ;
2014-05-12 11:12:56 +02:00
Q_DECLARE_METATYPE ( Ms : : FiguredBassItem : : ContLine ) ;
2013-05-13 18:49:17 +02:00
2012-05-26 14:26:10 +02:00
# endif