1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ 2 3 /* 4 Rosegarden 5 A MIDI and audio sequencer and musical notation editor. 6 Copyright 2000-2021 the Rosegarden development team. 7 8 Other copyrights also apply to some parts of this work. Please 9 see the AUTHORS file and individual file headers for details. 10 11 This program is free software; you can redistribute it and/or 12 modify it under the terms of the GNU General Public License as 13 published by the Free Software Foundation; either version 2 of the 14 License, or (at your option) any later version. See the file 15 COPYING included with this distribution for more information. 16 */ 17 18 #ifndef RG_NOTEPIXMAPFACTORY_H 19 #define RG_NOTEPIXMAPFACTORY_H 20 21 #include <QGraphicsPixmapItem> 22 23 #include "base/NotationTypes.h" 24 #include "NoteCharacter.h" 25 #include "NoteItem.h" 26 #include "base/Event.h" 27 #include "gui/editors/notation/NoteCharacterNames.h" 28 #include <map> 29 #include <string> 30 31 #include <QFont> 32 #include <QFontMetrics> 33 #include <QPixmap> 34 #include <QPoint> 35 #include <QCoreApplication> // for Q_DECLARE_TR_FUNCTIONS 36 #include <QSharedPointer> 37 38 class QPainter; 39 class QBitmap; 40 class QString; 41 42 43 namespace Rosegarden 44 { 45 46 namespace Guitar { class Fingering; } 47 48 class TimeSignature; 49 class Text; 50 class NoteStyle; 51 class NotePixmapParameters; 52 class NoteFont; 53 class NotePixmapPainter; 54 class Clef; 55 class StaffHeader; 56 57 /** 58 * Generates pixmaps and graphics items for various notation items. 59 * This class is not re-entrant. 60 */ 61 class NotePixmapFactory 62 { 63 Q_DECLARE_TR_FUNCTIONS(Rosegarden::NotePixmapFactory) 64 65 public: 66 static const int NO_GRACE_SIZE = -1; 67 68 NotePixmapFactory(QString fontName = "", int size = -1, int graceSize = NO_GRACE_SIZE); 69 NotePixmapFactory(const NotePixmapFactory &); 70 NotePixmapFactory &operator=(const NotePixmapFactory &); 71 ~NotePixmapFactory(); 72 73 QString getFontName() const; 74 int getSize() const; 75 76 /** 77 \enum ColourType 78 79 This enum describes the different colours that may be used to draw 80 notation-related glyphs. This aspect of drawing is handled through this 81 enum, rather than by specifying a colour explicitly. If you have some 82 occasion to add more colours for some new purpose, do so through this enum 83 (realising that you have to hook it all up somewhere to make use of the new 84 values defined!) 85 86 \sa GUIPalette, TrackParameterBox, PresetHandlerDialog 87 */ 88 enum ColourType { 89 PlainColour, /**< The default basic Qt::black (hard coded) */ 90 QuantizedColour, /**< Defined in GUIPalette; used when quantized notes are indicated */ 91 HighlightedColour, /**< Defined in GUIPalette; used when notes (&c.) are shown in the selected state */ 92 TriggerColour, /**< Defined in GUIPalette; used when trigger notes are indicated */ 93 TriggerSkipColour, /**< Defined in GUIPalette; used when masked-out trigger notes within ties are indicated */ 94 OutRangeColour, /**< Defined in GUIPalette; used when out-of-range notes are indicated */ 95 PlainColourLight, /**< The default basic Qt::white (hard coded) used when drawing on a black background */ 96 ConflictColour, /**< Qt::red (hard coded) used by track headers to indicate, eg. a clef conflict */ 97 MemberOfParallelColour /**< for members of parallels */ 98 }; 99 100 /** Used to notify the drawing code that the character is selected, and 101 * should therefore be drawn with a blue foreground 102 */ setSelected(bool selected)103 void setSelected(bool selected) { m_selected = selected; } 104 105 /** Returns true if the character is in the selected state 106 */ isSelected()107 bool isSelected() const { return m_selected; } 108 getGraceSize()109 int getGraceSize() const { return m_graceSize; } 110 111 /** Used to notify the drawing code that the character is shaded, and should 112 * therefore be drawn with a gray foreground. This is used for "invisible" 113 * items 114 */ setShaded(bool shaded)115 void setShaded(bool shaded) { m_shaded = shaded; } 116 117 /** Returns true if the character is in the shaded (ie. "invisible") state 118 */ isShaded()119 bool isShaded() const { return m_shaded; } 120 setNoteStyle(QSharedPointer<NoteStyle> style)121 void setNoteStyle(QSharedPointer<NoteStyle> style) { m_style = style; } getNoteStyle()122 const QSharedPointer<NoteStyle> getNoteStyle() const { return m_style; } 123 124 // Display methods -- create graphics items: 125 126 QGraphicsItem *makeNote(const NotePixmapParameters ¶meters); 127 QGraphicsItem *makeRest(const NotePixmapParameters ¶meters); 128 129 QGraphicsPixmapItem *makeNotePixmapItem(const NotePixmapParameters ¶meters); 130 131 void getNoteDimensions(const NotePixmapParameters ¶meters, 132 NoteItemDimensions &dimensions); 133 134 void drawNoteForItem(const NotePixmapParameters ¶meters, 135 const NoteItemDimensions &dimensions, 136 NoteItem::DrawMode mode, 137 QPainter *painter); 138 139 /** Make a clef pixmap from Clef &clef. The optional colourType parameter 140 * is used to pass a ColourType through makeClef() into drawCharacter() for 141 * certain special situations requiring external control of the glyph colour 142 * (eg. track headers) 143 */ 144 QGraphicsPixmapItem *makeClef(const Clef &clef, const ColourType colourType = PlainColour); 145 146 /** Make a symbol pixmap from Symbol &symbol. 147 * 148 * \sa makeClef 149 */ 150 QGraphicsPixmapItem *makeSymbol(const Symbol &symbol, const ColourType colourType = PlainColour); 151 152 QGraphicsPixmapItem *makeKey(const Key &key, 153 const Clef &clef, 154 Key previousKey = 155 Key::DefaultKey, 156 const ColourType colourType = PlainColour); 157 QGraphicsPixmapItem *makeTimeSig(const TimeSignature& sig); 158 QGraphicsPixmapItem *makeHairpin(int length, bool isCrescendo); 159 QGraphicsPixmapItem *makeSlur(int length, int dy, bool above, bool phrasing); 160 QGraphicsPixmapItem *makeOttava(int length, int octavesUp); 161 QGraphicsPixmapItem *makePedalDown(); 162 QGraphicsPixmapItem *makePedalUp(); 163 QGraphicsPixmapItem *makeUnknown(); 164 QGraphicsPixmapItem *makeText(const Text &text); 165 QGraphicsPixmapItem *makeGuitarChord(const Guitar::Fingering &fingering, 166 int x, int y); 167 QGraphicsPixmapItem *makeTrillLine(int length); 168 169 QGraphicsPixmapItem *makeNoteHalo(const NotePixmapParameters ¶meters); 170 171 // Printing methods -- draw direct to a paint device: 172 173 void drawNote(const NotePixmapParameters ¶meters, 174 QPainter &painter, int x, int y); 175 void drawRest(const NotePixmapParameters ¶meters, 176 QPainter &painter, int x, int y); 177 void drawHairpin(int length, bool isCrescendo, 178 QPainter &painter, int x, int y); 179 void drawSlur(int length, int dy, bool above, bool phrasing, 180 QPainter &painter, int x, int y); 181 void drawOttava(int length, int octavesUp, 182 QPainter &painter, int x, int y); 183 void drawText(const Text &text, 184 QPainter &painter, int x, int y); 185 186 // Other support methods for producing pixmaps for other contexts: 187 188 static QPixmap makeToolbarPixmap(QString name, bool menuSize = false); 189 static QPixmap makeNoteMenuPixmap(timeT duration, timeT &errorReturn); 190 static QPixmap makeMarkMenuPixmap(Mark); 191 192 QPixmap makePitchDisplayPixmap(int pitch, 193 const Clef &clef, 194 bool useSharps, 195 const ColourType = PlainColour); 196 QPixmap makePitchDisplayPixmap(int pitch, 197 const Clef &clef, 198 int octave, 199 int step, 200 const ColourType = PlainColour); 201 QPixmap makeClefDisplayPixmap(const Clef &clef, const ColourType colourType = PlainColour); 202 QPixmap makeKeyDisplayPixmap(const Key &key, 203 const Clef &clef, 204 const ColourType colourType = PlainColour); 205 QPixmap makeTextPixmap(const Text &text); 206 207 // Bounding box and other geometry methods: 208 209 int getNoteBodyWidth (Note::Type = 210 Note::Crotchet) const; 211 212 int getNoteBodyHeight(Note::Type = 213 Note::Crotchet) const; 214 215 int getAccidentalWidth (const Accidental &, 216 int shift = 0, bool extra = false) const; 217 int getAccidentalHeight(const Accidental &) const; 218 219 int getLineSpacing() const; 220 int getStemLength() const; 221 int getStemThickness() const; 222 int getStaffLineThickness() const; 223 int getLegerLineThickness() const; 224 int getDotWidth() const; 225 int getBarMargin() const; 226 227 int getClefWidth(const Clef &clef) const; 228 int getTimeSigWidth(const TimeSignature ×ig) const; 229 int getRestWidth(const Note &restType) const; 230 int getKeyWidth(const Key &key, 231 Key previousKey = Key::DefaultKey) const; 232 int getTextWidth(const Text &text) const; 233 234 /** 235 * Returns the width of clef and key signature drawn in a track header. 236 */ 237 int getClefAndKeyWidth(const Key &key, const Clef &clef); 238 239 /** 240 * Returns the Number of Text Lines that can be written at top and bottom 241 * of a track header. 242 * The parameter is the track header height. 243 * Always returns a value >= 1. 244 */ 245 int getTrackHeaderNTL(int height); 246 247 /** 248 * Returns the width of a text string written in a track header. 249 */ 250 int getTrackHeaderTextWidth(QString str); 251 252 /** 253 * Returns the spacing of a text lines written in a track header. 254 */ 255 int getTrackHeaderTextLineSpacing(); 256 257 /** 258 * Returns from the beginning of "text" a string of horizontal size 259 * "width" (when written with m_trackHeaderFont) and removes it 260 * from "text". 261 */ 262 QString getOneLine(QString &text, int width); 263 getTrackHeaderFont()264 QFont getTrackHeaderFont() { return m_trackHeaderFont; } getTrackHeaderFontMetrics()265 QFontMetrics getTrackHeaderFontMetrics() { return m_trackHeaderFontMetrics; } 266 getTrackHeaderBoldFont()267 QFont getTrackHeaderBoldFont() { return m_trackHeaderBoldFont; } getTrackHeaderBoldFontMetrics()268 QFontMetrics getTrackHeaderBoldFontMetrics() { 269 return m_trackHeaderBoldFontMetrics; 270 } 271 272 static void dumpStats(std::ostream &); 273 274 275 static const char* const defaultSerifFontFamily; 276 static const char* const defaultSansSerifFontFamily; 277 static const char* const defaultTimeSigFontFamily; 278 279 protected: 280 void init(QString fontName, int size); initMaybe()281 void initMaybe() { if (!m_font) init("", -1); } 282 283 void calculateNoteDimensions(const NotePixmapParameters ¶meters); 284 void sketchNoteTiny(const NotePixmapParameters ¶meters, 285 const NoteItemDimensions &dimensions, 286 QPainter *painter); 287 void drawNoteAux(const NotePixmapParameters ¶meters, 288 QPainter *painter, int x, int y); 289 void drawRestAux(const NotePixmapParameters ¶meters, QPoint &hotspot, 290 QPainter *painter, int x, int y); 291 void drawHairpinAux(int length, bool isCrescendo, 292 QPainter *painter, int x, int y); 293 void drawSlurAux(int length, int dy, bool above, bool smooth, bool tie, bool phrasing, 294 QPoint &hotspot, 295 QPainter *painter, int x, int y); 296 void drawOttavaAux(int length, int octavesUp, 297 QPainter *painter, int x, int y); 298 void drawTextAux(const Text &text, 299 QPainter *painter, int x, int y); 300 void drawTrillLineAux(int length, QPainter *painter, int x, int y); 301 302 int getStemLength(const NotePixmapParameters &) const; 303 304 void makeRoomForAccidental(Accidental, bool cautionary, int shift, bool extra); 305 void drawAccidental(const NotePixmapParameters ¶ms); 306 307 void makeRoomForMarks(bool isStemmed, const NotePixmapParameters ¶ms, int stemLength); 308 void drawMarks(bool isStemmed, const NotePixmapParameters ¶ms, int stemLength, bool overRestHack = false); 309 310 void makeRoomForLegerLines(const NotePixmapParameters ¶ms); 311 void drawLegerLines(const NotePixmapParameters ¶ms); 312 313 void makeRoomForStemAndFlags(int flagCount, int stemLength, 314 const NotePixmapParameters ¶ms, 315 QPoint &startPoint, QPoint &endPoint); 316 void drawFlags(int flagCount, const NotePixmapParameters ¶ms, 317 const QPoint &startPoint, const QPoint &endPoint); 318 void drawStem(const NotePixmapParameters ¶ms, 319 const QPoint &startPoint, const QPoint &endPoint, 320 int shortening); 321 322 void makeRoomForBeams(const NotePixmapParameters ¶ms); 323 void drawBeams(const QPoint &, const NotePixmapParameters ¶ms, 324 int beamCount); 325 326 void drawSlashes(const QPoint &, const NotePixmapParameters ¶ms, 327 int slashCount); 328 329 void makeRoomForTuplingLine(const NotePixmapParameters ¶ms); 330 void drawTuplingLine(const NotePixmapParameters ¶ms); 331 332 void drawShallowLine(float x0, float y0, float x1, float y1, float thickness); 333 void drawTie(bool above, int length, int shift); 334 335 /// Draw a parenthesis for cautionary (courtesy) accidentals. 336 void drawBracket(int length, bool left, bool curly, int x, int y); 337 338 QFont getTextFont(const Text &text) const; 339 340 QGraphicsPixmapItem *makeAnnotation(const Text &text); 341 QGraphicsPixmapItem *makeAnnotation(const Text &text, 342 const bool isLilyPondDirective); 343 344 void createPixmap(int width, int height); 345 QGraphicsPixmapItem *makeItem(QPoint hotspot); 346 QPixmap makePixmap(); 347 348 /// draws selected/shaded status from m_selected/m_shaded: 349 NoteCharacter getCharacter(CharName name, ColourType type, bool inverted); 350 351 /// draws selected/shaded status from m_selected/m_shaded: 352 bool getCharacter(CharName name, NoteCharacter &ch, ColourType type, bool inverted); 353 354 /// Draw character with a specified QColor 355 // This is a first step to a simpler use of colors 356 NoteCharacter getCharacter(CharName name, QColor color, bool inverted); 357 358 /// Draw character with a specified QColor 359 // This is a first step to a simpler use of colors 360 bool getCharacter(CharName name, NoteCharacter &ch, QColor color, bool inverted); 361 362 void drawNoteHalo(int x, int y, int w, int h); 363 364 //--------------- Data members --------------------------------- 365 366 NoteFont *m_font; 367 NoteFont *m_graceFont; 368 QSharedPointer<NoteStyle> m_style; 369 bool m_selected; 370 bool m_shaded; 371 bool m_haveGrace; 372 373 int m_graceSize; 374 375 NoteItemDimensions m_nd; 376 377 QFont m_tupletCountFont; 378 QFontMetrics m_tupletCountFontMetrics; 379 380 QFont m_textMarkFont; 381 QFontMetrics m_textMarkFontMetrics; 382 383 QFont m_fingeringFont; 384 QFontMetrics m_fingeringFontMetrics; 385 386 QFont m_timeSigFont; 387 QFontMetrics m_timeSigFontMetrics; 388 389 QFont m_bigTimeSigFont; 390 QFontMetrics m_bigTimeSigFontMetrics; 391 392 QFont m_ottavaFont; 393 QFontMetrics m_ottavaFontMetrics; 394 395 QFont m_clefOttavaFont; 396 QFontMetrics m_clefOttavaFontMetrics; 397 398 QFont m_trackHeaderFont; 399 QFontMetrics m_trackHeaderFontMetrics; 400 401 QFont m_trackHeaderBoldFont; 402 QFontMetrics m_trackHeaderBoldFontMetrics; 403 404 QPixmap *m_generatedPixmap; 405 406 int m_generatedWidth; 407 int m_generatedHeight; 408 bool m_inPrinterMethod; 409 410 NotePixmapPainter *m_p; 411 412 typedef std::map<const char *, QFont> TextFontCache; 413 mutable TextFontCache m_textFontCache; 414 }; 415 416 417 418 } 419 420 #endif 421