File indexing completed on 2024-05-12 16:34:16

0001 /* This file is part of the KDE project
0002  * Copyright (C) 2007 Marijn Kruisselbrink <mkruisselbrink@kde.org>
0003  *
0004  * This library is free software; you can redistribute it and/or
0005  * modify it under the terms of the GNU Library General Public
0006  * License as published by the Free Software Foundation; either
0007  * version 2 of the License, or (at your option) any later version.
0008  *
0009  * This library is distributed in the hope that it will be useful,
0010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0012  * Library General Public License for more details.
0013  *
0014  * You should have received a copy of the GNU Library General Public License
0015  * along with this library; see the file COPYING.LIB.  If not, write to
0016  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0017  * Boston, MA 02110-1301, USA.
0018  */
0019 #include "MusicStyle.h"
0020 
0021 #include <QPainterPath>
0022 
0023 using namespace MusicCore;
0024 
0025 MusicStyle::MusicStyle()
0026 #ifdef Q_WS_MAC
0027     : m_font("Emmentaler 14")
0028 #else
0029     : m_font("Emmentaler")
0030 #endif
0031     , m_textAsPath(false)
0032 {
0033     m_font.setPixelSize(20);
0034     m_staffLinePen.setWidthF(0.5);
0035     m_staffLinePen.setCapStyle(Qt::RoundCap);
0036     m_staffLinePen.setColor(Qt::black);
0037     m_stemPen.setWidthF(0.7);
0038     m_stemPen.setCapStyle(Qt::FlatCap);
0039     m_stemPen.setColor(Qt::black);
0040     m_noteDotPen.setWidthF(1.9);
0041     m_noteDotPen.setCapStyle(Qt::RoundCap);
0042     m_noteDotPen.setColor(Qt::black);
0043 }
0044 
0045 MusicStyle::~MusicStyle()
0046 {
0047 }
0048 
0049 QPen MusicStyle::staffLinePen(const QColor& color)
0050 {
0051     m_staffLinePen.setColor(color);
0052     return m_staffLinePen;
0053 }
0054 
0055 QPen MusicStyle::stemPen(const QColor& color)
0056 {
0057     m_stemPen.setColor(color);
0058     return m_stemPen;
0059 }
0060 
0061 QPen MusicStyle::noteDotPen(const QColor& color)
0062 {
0063     m_noteDotPen.setColor(color);
0064     return m_noteDotPen;
0065 }
0066 
0067 qreal MusicStyle::beamLineWidth()
0068 {
0069     return 3.0;
0070 }
0071 
0072 void MusicStyle::renderText(QPainter& painter, qreal x, qreal y, const QString& text)
0073 {
0074     QPointF p(x, y);
0075     if(m_textAsPath) {
0076         QPainterPath textPath;
0077         textPath.setFillRule(Qt::OddEvenFill);
0078         textPath.addText(p, m_font, text);
0079         painter.save();
0080         painter.setBrush(painter.pen().brush().color());
0081         painter.drawPath(textPath);
0082         painter.restore();
0083     }
0084     else {
0085         painter.drawText(p, text);
0086     }
0087 }
0088 
0089 bool MusicStyle::textAsPath() const
0090 {
0091     return m_textAsPath;
0092 }
0093 
0094 void MusicStyle::setTextAsPath(bool drawTextAsPath)
0095 {
0096     m_textAsPath = drawTextAsPath;
0097 }
0098 
0099 void MusicStyle::renderNoteHead(QPainter& painter, qreal x, qreal y, Duration duration, const QColor& color)
0100 {
0101     painter.setPen(QPen(color, 0));
0102     painter.setFont(m_font);
0103     switch (duration) {
0104         case HundredTwentyEighthNote:
0105         case SixtyFourthNote:
0106         case ThirtySecondNote:
0107         case SixteenthNote:
0108         case EighthNote:
0109         case QuarterNote:
0110             renderText(painter, x, y, QString(0xE125));
0111             break;
0112         case HalfNote:
0113             renderText(painter, x, y, QString(0xE124));
0114             break;
0115         case WholeNote:
0116             renderText(painter, x, y, QString(0xE123));
0117             break;
0118         case BreveNote:
0119             renderText(painter, x, y, QString(0xE122));
0120             break;
0121     }
0122 }
0123 
0124 void MusicStyle::renderRest(QPainter& painter, qreal x, qreal y, Duration duration, const QColor& color)
0125 {
0126     painter.setPen(QPen(color, 0));
0127     painter.setFont(m_font);
0128     QPointF p(x, y);
0129     switch (duration) {
0130         case HundredTwentyEighthNote:
0131             renderText(painter, x, y, QString(0xE10D));
0132             break;
0133         case SixtyFourthNote:
0134             renderText(painter, x, y, QString(0xE10C));
0135             break;
0136         case ThirtySecondNote:
0137             renderText(painter, x, y, QString(0xE10B));
0138             break;
0139         case SixteenthNote:
0140             renderText(painter, x, y, QString(0xE10A));
0141             break;
0142         case EighthNote:
0143             renderText(painter, x, y, QString(0xE109));
0144             break;
0145         case QuarterNote:
0146             renderText(painter, x, y, QString(0xE107));
0147             break;
0148         case HalfNote:
0149             renderText(painter, x, y, QString(0xE101));
0150             break;
0151         case WholeNote:
0152             renderText(painter, x, y, QString(0xE100));
0153             break;
0154         case BreveNote:
0155             renderText(painter, x, y, QString(0xE106));
0156             break;
0157     }
0158 }
0159 
0160 void MusicStyle::renderClef(QPainter& painter, qreal x, qreal y, Clef::ClefShape shape, const QColor& color)
0161 {
0162     painter.setPen(QPen(color, 0));
0163     painter.setFont(m_font);
0164     QPointF p(x, y);
0165     switch (shape) {
0166         case Clef::GClef:
0167             renderText(painter, x, y, QString(0xE195));
0168             break;
0169         case Clef::FClef:
0170             renderText(painter, x, y, QString(0xE193));
0171             break;
0172         case Clef::CClef:
0173             renderText(painter, x, y, QString(0xE191));
0174             break;
0175     }
0176 }
0177 
0178 void MusicStyle::renderAccidental(QPainter& painter, qreal x, qreal y, int accidental, const QColor& color)
0179 {
0180     painter.setPen(QPen(color, 0));
0181     painter.setFont(m_font);
0182     QPointF p(x, y);
0183     switch (accidental) {
0184         case 0:
0185             renderText(painter, x, y, QString(0xE111));
0186             break;
0187         case 1:
0188             renderText(painter, x, y, QString(0xE10E));
0189             break;
0190         case 2:
0191             renderText(painter, x, y, QString(0xE116));
0192             break;
0193         case -1:
0194             renderText(painter, x, y, QString(0xE112));
0195             break;
0196         case -2:
0197             renderText(painter, x, y, QString(0xE114));
0198             break;
0199     }
0200 }
0201 
0202 void MusicStyle::renderTimeSignatureNumber(QPainter& painter, qreal x, qreal y, qreal w, int number, const QColor& color)
0203 {
0204     painter.setPen(QPen(color, 0));
0205     painter.setFont(m_font);
0206     QFontMetricsF m(m_font);
0207     QString txt = QString::number(number);
0208 
0209     renderText(painter, x + (w - m.width(txt))/2, y, txt);
0210 }
0211 
0212 void MusicStyle::renderNoteFlags(QPainter& painter, qreal x, qreal y, Duration duration, bool stemsUp, const QColor& color)
0213 {
0214     painter.setPen(QPen(color, 0));
0215     painter.setFont(m_font);
0216     QPointF p(x + 0.4, y);
0217     switch (duration) {
0218         case HundredTwentyEighthNote:
0219             // no 128 flag in emmentaler, so stack 16th and 32nd on top of each other...
0220             renderText(painter, x, y, QString(stemsUp ? 0xE189 : 0xE18F));
0221             renderText(painter, p.x(), p.y() + (stemsUp ? 13 : -13), QString(stemsUp ? 0xE188 : 0xE18E));
0222             break;
0223         case SixtyFourthNote:
0224             renderText(painter, x, y, QString(stemsUp ? 0xE18A : 0xE190));
0225             break;
0226         case ThirtySecondNote:
0227             renderText(painter, x, y, QString(stemsUp ? 0xE189 : 0xE18F));
0228             break;
0229         case SixteenthNote:
0230             renderText(painter, x, y, QString(stemsUp ? 0xE188 : 0xE18E));
0231             break;
0232         case EighthNote:
0233             renderText(painter, x, y, QString(stemsUp ? 0xE187 : 0xE18B));
0234             break;
0235         default:
0236             // no flags
0237             break;
0238     }
0239 }