示例#1
0
void Glissando::draw(QPainter* painter) const
      {
      painter->save();
      qreal _spatium = spatium();

      QPen pen(curColor());
      pen.setWidthF(_spatium * .15);
      pen.setCapStyle(Qt::RoundCap);
      painter->setPen(pen);

      qreal w = line.dx();
      qreal h = line.dy();

      qreal l = sqrt(w * w + h * h);
      painter->translate(line.p1());
      qreal wi = asin(-h / l) * 180.0 / M_PI;
      painter->rotate(-wi);

      if (glissandoType() == Type::STRAIGHT) {
            painter->drawLine(QLineF(0.0, 0.0, l, 0.0));
            }
      else if (glissandoType() == Type::WAVY) {
            QRectF b = symBbox(SymId::wiggleTrill);
            qreal w  = symWidth(SymId::wiggleTrill);
            int n    = (int)(l / w);      // always round down (truncate) to avoid overlap
            qreal x  = (l - n*w) * 0.5;   // centre line in available space
            drawSymbol(SymId::wiggleTrill, painter, QPointF(x, b.height()*.5), n);
            }
      if (_showText) {
            const TextStyle& st = score()->textStyle(TextStyleType::GLISSANDO);
            QFont f = st.fontPx(_spatium);
            QRectF r = QFontMetricsF(f).boundingRect(_text);
            // if text longer than available space, skip it
            if (r.width() < l) {
                  qreal yOffset = r.height() + r.y();       // find text descender height
                  // raise text slightly above line and slightly more with WAVY than with STRAIGHT
                  yOffset += _spatium * (glissandoType() == Type::WAVY ? 0.75 : 0.05);
                  painter->setFont(f);
                  qreal x = (l - r.width()) * 0.5;
                  painter->drawText(QPointF(x, -yOffset), _text);
                  }
            }
      painter->restore();
      }
示例#2
0
void ShadowNote::draw(QPainter* painter) const
      {
      if (!visible() || sym == SymId::noSym)
            return;

      QPointF ap(pagePos());
#if 0 // yet(?) unused
      QRect r(abbox().toRect());
#endif

      painter->translate(ap);
      qreal lw = point(score()->styleS(StyleIdx::ledgerLineWidth));
      InputState ps = score()->inputState();
      int voice;
      if (ps.drumNote() != -1 && ps.drumset() && ps.drumset()->isValid(ps.drumNote()))
            voice = ps.drumset()->voice(ps.drumNote());
      else
            voice = ps.voice();

      QPen pen(MScore::selectColor[voice].lighter(140), lw);
      painter->setPen(pen);

      drawSymbol(sym, painter);

      qreal ms = spatium();

      qreal x1 = symWidth(sym) * .5 - (ms * mag());
      qreal x2 = x1 + 2 * ms * mag();

      ms *= .5;
      if (_line < 100 && _line > -100 && !ps.rest()) {
            for (int i = -2; i >= _line; i -= 2) {
                  qreal y = ms * mag() * (i - _line);
                  painter->drawLine(QLineF(x1, y, x2, y));
                  }
            for (int i = 10; i <= _line; i += 2) {
                  qreal y = ms * mag() * (i - _line);
                  painter->drawLine(QLineF(x1, y, x2, y));
                  }
            }
      painter->translate(-ap);
      }
示例#3
0
void ShadowNote::layout()
      {
      if (sym == SymId::noSym) {
            setbbox(QRectF());
            return;
            }
      QRectF b(symBbox(sym));
      qreal _spatium = spatium();
      qreal lw = point(score()->styleS(StyleIdx::ledgerLineWidth));

      qreal x1 = symWidth(sym) * .5 - (_spatium * mag()) - lw * .5;
      qreal x2 = x1 + 2 * _spatium * mag() + lw * .5;

      InputState ps = score()->inputState();
      QRectF r(x1, -lw * .5, x2 - x1, lw);
      if (_line < 100 && _line > -100 && !ps.rest()) {
            for (int i = -2; i >= _line; i -= 2)
                  b |= r.translated(QPointF(0, _spatium * .5 * (i - _line)));
            for (int i = 10; i <= _line; i += 2)
                  b |= r.translated(QPointF(0, _spatium * .5 * (i - _line)));
            }
      setbbox(b);
      }
示例#4
0
void BarLine::layout()
      {
      qreal y1, y2;
      getY(&y1, &y2);

      // if bar line does not belong to a system, has a staff and staff is set to hide bar lines, set null bbox
      if (parent() && parent()->type() != Element::Type::SYSTEM && staff() && !staff()->staffType()->showBarlines())
            setbbox(QRectF());

      // bar lines not hidden
      else {
            qreal dw = layoutWidth(score(), barLineType(), magS());
            QRectF r(0.0, y1, dw, y2-y1);

            if (score()->styleB(StyleIdx::repeatBarTips)) {
                  switch (barLineType()) {
                        case BarLineType::START_REPEAT:
                              r |= symBbox(SymId::bracketTop).translated(0, y1);
                              r |= symBbox(SymId::bracketBottom).translated(0, y2);
                              break;
                        case BarLineType::END_REPEAT:
                              {
                              qreal w1 = symBbox(SymId::reversedBracketTop).width();
                              r |= symBbox(SymId::reversedBracketTop).translated(dw - w1, y1);
                              r |= symBbox(SymId::reversedBracketBottom).translated(dw - w1, y2);
                              break;
                              }

                        case BarLineType::END_START_REPEAT:
                              {
                              qreal lw   = point(score()->styleS(StyleIdx::barWidth));
                              qreal lw2  = point(score()->styleS(StyleIdx::endBarWidth));
                              qreal d1   = point(score()->styleS(StyleIdx::endBarDistance));
                              qreal dotw = symWidth(SymId::repeatDot);
                              qreal x   =  dotw + 2 * d1 + lw + lw2 * .5;                     // thick bar
                              qreal w1 = symBbox(SymId::reversedBracketTop).width();
                              r |= symBbox(SymId::bracketTop).translated(x, y1);
                              r |= symBbox(SymId::bracketBottom).translated(x, y2);
                              r |= symBbox(SymId::reversedBracketTop).translated(x - w1 , y1);
                              r |= symBbox(SymId::reversedBracketBottom).translated(x - w1, y2);
                              }
                              break;

                        default:
                              break;
                        }
                  }
            setbbox(r);
            }

      // in any case, lay out attached elements
      foreach(Element* e, _el) {
            e->layout();
            if (e->type() == Element::Type::ARTICULATION) {
                  Articulation* a       = static_cast<Articulation*>(e);
                  MScore::Direction dir = a->direction();
                  qreal distance        = 0.5 * spatium();
                  qreal x               = width() * .5;
                  if (dir == MScore::Direction::DOWN) {
                        qreal botY = y2 + distance;
                        a->setPos(QPointF(x, botY));
                        }
                  else {
                        qreal topY = y1 - distance;
                        a->setPos(QPointF(x, topY));
                        }
                  }
            }
示例#5
0
void BarLine::draw(QPainter* painter) const
      {
      // get line length and do nothing if 0 (or near enough)
      qreal y1, y2;
      getY(&y1, &y2);
      if (y2-y1 < 0.1)
            return;

      qreal _spatium = score()->spatium();
      qreal lw = score()->styleS(StyleIdx::barWidth).val() * _spatium;

      QPen pen(curColor(), lw, Qt::SolidLine, Qt::FlatCap);
      painter->setPen(pen);

      switch(barLineType()) {
            case BarLineType::BROKEN:
                  pen.setStyle(Qt::DashLine);
                  painter->setPen(pen);
                  painter->drawLine(QLineF(lw * .5, y1, lw * .5, y2));
                  break;

            case BarLineType::DOTTED:
                  pen.setStyle(Qt::DotLine);
                  painter->setPen(pen);

            case BarLineType::NORMAL:
                  painter->drawLine(QLineF(lw * .5, y1, lw * .5, y2));
                  break;

            case BarLineType::END:
                  {
                  qreal lw2 = score()->styleS(StyleIdx::endBarWidth).val() * _spatium;
                  qreal d   = score()->styleS(StyleIdx::endBarDistance).val() * _spatium;

                  painter->drawLine(QLineF(lw * .5, y1, lw * .5, y2));
                  pen.setWidthF(lw2);
                  painter->setPen(pen);
                  qreal x = d + lw2 * .5 + lw;
                  painter->drawLine(QLineF(x, y1, x, y2));
                  }
                  break;

            case BarLineType::DOUBLE:
                  {
                  lw      = point(score()->styleS(StyleIdx::doubleBarWidth));
                  qreal d = point(score()->styleS(StyleIdx::doubleBarDistance));

                  pen.setWidthF(lw);
                  painter->setPen(pen);
                  qreal x = lw * .5;
                  painter->drawLine(QLineF(x, y1, x, y2));
                  x += d + lw;
                  painter->drawLine(QLineF(x, y1, x, y2));
                  }
                  break;

            case BarLineType::START_REPEAT:
                  {
                  qreal lw2 = point(score()->styleS(StyleIdx::endBarWidth));
                  qreal d1  = point(score()->styleS(StyleIdx::endBarDistance));

                  qreal x2   =  lw2 * .5;                               // thick line (lw2)
                  qreal x1   =  lw2 + d1 + lw * .5;                     // thin line (lw)
                  qreal x0   =  lw2 + d1 + lw + d1;                     // dot position

                  drawDots(painter, x0);

                  painter->drawLine(QLineF(x1, y1, x1, y2));

                  pen.setWidthF(lw2);
                  painter->setPen(pen);
                  painter->drawLine(QLineF(x2, y1, x2, y2));

                  if (score()->styleB(StyleIdx::repeatBarTips)) {
                        drawSymbol(SymId::bracketTop, painter, QPointF(0.0, y1));
                        drawSymbol(SymId::bracketBottom, painter, QPointF(0.0, y2));
                        }
                  }
                  break;

            case BarLineType::END_REPEAT:
                  {
                  qreal lw2  = point(score()->styleS(StyleIdx::endBarWidth));
                  qreal d1   = point(score()->styleS(StyleIdx::endBarDistance));
                  qreal dotw = symWidth(SymId::repeatDot);
                  qreal x1   =  dotw + d1 + lw * .5;
                  qreal x2   =  dotw + d1 + lw + d1 + lw2 * .5;

                  drawDots(painter, 0.0);
                  painter->drawLine(QLineF(x1, y1, x1, y2));
                  pen.setWidthF(lw2);
                  painter->setPen(pen);
                  painter->drawLine(QLineF(x2, y1, x2, y2));

                  if (score()->styleB(StyleIdx::repeatBarTips)) {
                        qreal x = x2 + lw2 * .5;
                        qreal w1 = symBbox(SymId::reversedBracketTop).width();
                        drawSymbol(SymId::reversedBracketTop, painter, QPointF(x - w1, y1));
                        drawSymbol(SymId::reversedBracketBottom, painter, QPointF(x - w1, y2));
                        }
                  }
                  break;

            case BarLineType::END_START_REPEAT:
                  {
                  qreal lw2  = point(score()->styleS(StyleIdx::endBarWidth));
                  qreal d1   = point(score()->styleS(StyleIdx::endBarDistance));
                  qreal dotw = symWidth(SymId::repeatDot);

                  qreal x1   =  dotw + d1 + lw * .5;                                // thin bar
                  qreal x2   =  dotw + d1 + lw + d1 + lw2 * .5;                     // thick bar
                  qreal x3   =  dotw + d1 + lw + d1 + lw2 + d1 + lw * .5;           // thin bar
                  qreal x4   =  dotw + d1 + lw + d1 + lw2 + d1 + lw + d1;           // dot position

                  drawDots(painter, .0);
                  drawDots(painter, x4);
                  painter->drawLine(QLineF(x1, y1, x1, y2));

                  pen.setWidthF(lw2);
                  painter->setPen(pen);
                  painter->drawLine(QLineF(x2, y1, x2, y2));

                  pen.setWidthF(lw);
                  painter->setPen(pen);
                  painter->drawLine(QLineF(x3, y1, x3, y2));

                  if (score()->styleB(StyleIdx::repeatBarTips)) {
                        qreal x = x2;
                        qreal w1 = symBbox(SymId::reversedBracketTop).width();
                        drawSymbol(SymId::bracketTop, painter, QPointF(x, y1));
                        drawSymbol(SymId::bracketBottom, painter, QPointF(x, y2));
                        drawSymbol(SymId::reversedBracketTop, painter, QPointF(x - w1, y1));
                        drawSymbol(SymId::reversedBracketBottom, painter, QPointF(x - w1, y2));
                        }
                  }
                  break;
            }
      }
示例#6
0
void Bracket::layout()
{
    path = QPainterPath();
    if (h2 == 0.0)
        return;

    if (bracketType() == BRACKET_BRACE) {
        qreal w = point(score()->styleS(ST_akkoladeWidth));

#define XM(a) (a+700)*w/700
#define YM(a) (a+7100)*h2/7100

        path.moveTo( XM(   -8), YM(-2048));
        path.cubicTo(XM(   -8), YM(-3192), XM(-360), YM(-4304), XM( -360), YM(-5400)); // c 0
        path.cubicTo(XM( -360), YM(-5952), XM(-264), YM(-6488), XM(   32), YM(-6968)); // c 1
        path.cubicTo(XM(   40), YM(-6976), XM(  40), YM(-6976), XM(   40), YM(-6984)); // c 0
        path.cubicTo(XM(   40), YM(-7000), XM(  16), YM(-7024), XM(    0), YM(-7024)); // c 0
        path.cubicTo(XM(   -8), YM(-7024), XM( -24), YM(-7024), XM(  -32), YM(-7008)); // c 1
        path.cubicTo(XM( -416), YM(-6392), XM(-544), YM(-5680), XM( -544), YM(-4960)); // c 0
        path.cubicTo(XM( -544), YM(-3800), XM(-168), YM(-2680), XM( -168), YM(-1568)); // c 0
        path.cubicTo(XM( -168), YM(-1016), XM(-264), YM( -496), XM( -560), YM(  -16)); // c 1
        path.lineTo( XM( -560), YM(    0));  //  l 1
        path.lineTo( XM( -560), YM(   16));  //  l 1
        path.cubicTo(XM( -264), YM(  496), XM(-168), YM( 1016), XM( -168), YM( 1568)); // c 0
        path.cubicTo(XM( -168), YM( 2680), XM(-544), YM( 3800), XM( -544), YM( 4960)); // c 0
        path.cubicTo(XM( -544), YM( 5680), XM(-416), YM( 6392), XM(  -32), YM( 7008)); // c 1
        path.cubicTo(XM(  -24), YM( 7024), XM(  -8), YM( 7024), XM(    0), YM( 7024)); // c 0
        path.cubicTo(XM(   16), YM( 7024), XM(  40), YM( 7000), XM(   40), YM( 6984)); // c 0
        path.cubicTo(XM(   40), YM( 6976), XM(  40), YM( 6976), XM(   32), YM( 6968)); // c 1
        path.cubicTo(XM( -264), YM( 6488), XM(-360), YM( 5952), XM( -360), YM( 5400)); // c 0
        path.cubicTo(XM( -360), YM( 4304), XM(  -8), YM( 3192), XM(   -8), YM( 2048)); // c 0
        path.cubicTo(XM( -  8), YM( 1320), XM(-136), YM(  624), XM( -512), YM(    0)); // c 1
        path.cubicTo(XM( -136), YM( -624), XM(  -8), YM(-1320), XM(   -8), YM(-2048)); // c 0
        setbbox(path.boundingRect());
    }
    else if (bracketType() == BRACKET_NORMAL) {
        qreal _spatium = spatium();
        qreal w = score()->styleS(ST_bracketWidth).val() * _spatium * .5;
        qreal x = -w;
        w      += symWidth(SymId::bracketTop);
        qreal bd = _spatium * .25;
        qreal y = - symHeight(SymId::bracketTop) - bd;
        qreal h = (-y + h2) * 2;
        bbox().setRect(x, y, w, h);
    }
    else if (bracketType() == BRACKET_SQUARE) {
        qreal _spatium = spatium();
        qreal w = score()->styleS(ST_staffLineWidth).val() * _spatium * .5;
        qreal x = -w;
        qreal y = -w;
        qreal h = (h2 + w) * 2 ;
        w      += (.5 * spatium() + 3* w);
        bbox().setRect(x, y, w, h);
    }
    else if (bracketType() == BRACKET_LINE) {
        qreal _spatium = spatium();
        qreal w = 0.67 * score()->styleS(ST_bracketWidth).val() * _spatium * .5;
        qreal x = -w;
        qreal bd = _spatium * .25;
        qreal y = -bd;
        qreal h = (-y + h2) * 2;
        bbox().setRect(x, y, w, h);
    }
}
示例#7
0
void TrillSegment::draw(QPainter* painter) const
      {
      QRectF b2(symBbox(SymId::wiggleTrill));
      qreal w2   = symWidth(SymId::wiggleTrill);

      qreal x2   = pos2().x();

      QColor color;
      if (flag(ELEMENT_DROP_TARGET))
            color = MScore::dropColor;
      else if (selected() && !(score() && score()->printing()))
            color = MScore::selectColor[0];
      else if (!visible())
            color = Qt::gray;
      else {
            color = trill()->curColor();
            }

      painter->setPen(color);
      if (spannerSegmentType() == SEGMENT_SINGLE || spannerSegmentType() == SEGMENT_BEGIN) {
            SymId sym = SymId::noSym;
            qreal x0 = 0.0, x1 = 0.0, y = 0.0;
            int n = 0;
            QRectF b1;

            switch(trill()->trillType()) {
                  case Trill::TRILL_LINE:
                        sym  = SymId::ornamentTrill;
                        b1   = symBbox(sym);
                        x0   = -b1.x();
                        x1   = x0 + b1.width();
                        n    = int(floor((x2-x1) / w2));
                        y    = 0.0;
                        break;
#if 0 // TODO-smufl
                  case Trill::UPPRALL_LINE:
                        sym  = SymId(upprallSym);
                        b1   = score()->sym(sym).bbox(mag);
                        x0   = -b1.x();
                        x1   = b1.width();
                        n    = int(floor((x2-x1) / w2));
                        y    = -b1.height();
                        break;
                  case Trill::DOWNPRALL_LINE:
                        sym  = SymId(downprallSym);
                        b1   = score()->sym(sym).bbox(mag);
                        x0   = -b1.x();
                        x1   = b1.width();
                        n    = int(floor((x2-x1) / w2));
                        y    = -b1.height();
                        break;
                  case Trill::PRALLPRALL_LINE:
                        sym  = SymId(prallprallSym);
                        b1   = score()->sym(sym).bbox(mag);
                        x0   = -b1.x();
                        x1   = b1.width();
                        n    = int(floor((x2-x1) / w2));
                        y    = -b1.height();
                        break;
#endif
                  case Trill::PURE_LINE:
                        sym = SymId::noSym;
                        x0 = 0;
                        x1 = 0;
                        n    = int(floor((x2-x1) / w2));
                        y = 0.0;
                  }
            if (n <= 0)
                  n = 1;
            if (sym != SymId::noSym)
                  drawSymbol(sym, painter, QPointF(x0, y));
            drawSymbol(SymId::wiggleTrill, painter, QPointF(x1, b2.y() * .9), n);
            }
      else {
            qreal x1 = 0.0;
            int n = int(floor((x2-x1) / w2));
            drawSymbol(SymId::wiggleTrill, painter, QPointF(x1, b2.y() * .9), n);
            }
      }
示例#8
0
void Lyrics::layout1()
      {
      setPos(textStyle().offset(spatium()));
      Text::layout1();
      if (!parent()) // palette & clone trick
          return;

      ChordRest* cr = chordRest();
      const QList<Lyrics*>* ll = &(cr->lyricsList());

      qreal lh = lineSpacing() * score()->styleD(StyleIdx::lyricsLineHeight);
      int line = ll->indexOf(this);
      qreal y  = lh * line + point(score()->styleS(StyleIdx::lyricsDistance));
      qreal x  = 0.0;

      //
      // parse leading verse number and/or punctuation, so we can factor it into layout separately
      // TODO: provide a way to disable this
      //
      bool hasNumber = false; // _verseNumber;
      qreal adjust = 0.0;
      QString s = plainText(true);
      // find:
      // 1) string of numbers and non-word characters at start of syllable
      // 2) at least one other character (indicating start of actual lyric)
      QRegularExpression leadingPattern("(^[\\d\\W]+)([^\\d\\W]+)");
      QRegularExpressionMatch leadingMatch = leadingPattern.match(s);
      if (leadingMatch.hasMatch()) {
            // leading string
            QString s1 = leadingMatch.captured(1);
            // actual lyric
            //QString s2 = leadingMatch.captured(2);
            Text leading(*this);
            leading.setPlainText(s1);
            leading.layout1();
            adjust = leading.width();
            if (!s1.isEmpty() && s1[0].isDigit())
                  hasNumber = true;
            }

      if (textStyle().align() & AlignmentFlags::HCENTER) {
            //
            // center under notehead, not origin
            // however, lyrics that are melismas or have verse numbers will be forced to left alignment
            // TODO: provide a way to disable the automatic left alignment
            //
            qreal maxWidth;
            if (cr->type() == Element::Type::CHORD)
                  maxWidth = static_cast<Chord*>(cr)->maxHeadWidth();
            else
                  maxWidth = cr->width();       // TODO: exclude ledger line for multivoice rest?
            qreal nominalWidth = symWidth(SymId::noteheadBlack);
            if (!isMelisma() && !hasNumber)     // center under notehead
                  x +=  nominalWidth * .5 - cr->x() - adjust * 0.5;
            else                                // force left alignment
                  x += (width() + nominalWidth - maxWidth) * .5 - cr->x() - adjust;
            }
      else {
            // even for left aligned syllables, ignore leading verse numbers and/or punctuation
            x -= adjust;
            }

      rxpos() += x;
      rypos() += y;

      if (_ticks > 0 || _syllabic == Syllabic::BEGIN || _syllabic == Syllabic::MIDDLE) {
            if (_separator == nullptr) {
                  _separator = new LyricsLine(score());
                  _separator->setTick(cr->tick());
                  score()->addUnmanagedSpanner(_separator);
                  }
            _separator->setParent(this);
            _separator->setTick(cr->tick());
            _separator->setTrack(track());
            _separator->setTrack2(track());
#if defined(USE_FONT_DASH_METRIC)
            // if font parameters different from font cached values, compute new dash values from font metrics
            if (textStyle().family() != g_fontFamily && textStyle().size() != g_fontSize) {
                  QFontMetricsF     fm    = textStyle().fontMetrics(spatium());
                  QRectF            r     = fm.tightBoundingRect("\u2013");   // U+2013 EN DASH
                  g_cachedDashY           = _dashY          = r.y() + (r.height() * HALF);
                  g_cachedDashLength      = _dashLength     = r.width();
   #if defined(USE_FONT_DASH_TICKNESS)
                  g_cachedDashThickness   = _dashThickness  = r.height();
   #endif
                  g_fontFamily            = textStyle().family();
                  g_fontSize              = textStyle().size();
                  }
            // if same font, use cached values
            else {
                  _dashY                  = g_cachedDashY;
                  _dashLength             = g_cachedDashLength;
   #if defined(USE_FONT_DASH_TICKNESS)
                  _dashThickness          = g_cachedDashThickness;
   #endif
                  }
#endif
            }
      else
            if (_separator != nullptr) {
                  _separator->unchain();
                  delete _separator;
                  _separator = nullptr;
                  }
      }
示例#9
0
qreal Rest::centerX() const
      {
      return symWidth(_sym) * .5;
      }