Example #1
0
void Ambitus::draw(QPainter* p) const
      {
      qreal _spatium = spatium();
      qreal lw = lineWidth().val() * _spatium;
      p->setPen(QPen(curColor(), lw, Qt::SolidLine, Qt::RoundCap));
      drawSymbol(noteHead(), p, _topPos);
      drawSymbol(noteHead(), p, _bottomPos);
      if (_hasLine)
            p->drawLine(_line);

      // draw ledger lines (if not in a palette)
      if (segment() && track() > -1) {
            int tick          = segment()->tick();
            Staff* stf        = score()->staff(staffIdx());
            qreal lineDist    = stf->lineDistance(tick);
            int numOfLines    = stf->lines(tick);
            qreal step        = lineDist * _spatium;
            qreal stepTolerance = step * 0.1;
            qreal ledgerOffset = score()->styleS(Sid::ledgerLineLength).val() * 0.5 * _spatium;
            p->setPen(QPen(curColor(), score()->styleS(Sid::ledgerLineWidth).val() * _spatium,
                        Qt::SolidLine, Qt::RoundCap) );
            if (_topPos.y()-stepTolerance <= -step) {
                  qreal xMin = _topPos.x() - ledgerOffset;
                  qreal xMax = _topPos.x() + headWidth() + ledgerOffset;
                  for (qreal y = -step; y >= _topPos.y()-stepTolerance; y -= step)
                        p->drawLine(QPointF(xMin, y), QPointF(xMax, y));
                  }
            if (_bottomPos.y()+stepTolerance >= numOfLines * step) {
                  qreal xMin = _bottomPos.x() - ledgerOffset;
                  qreal xMax = _bottomPos.x() + headWidth() + ledgerOffset;
                  for (qreal y = numOfLines*step; y <= _bottomPos.y()+stepTolerance; y += step)
                        p->drawLine(QPointF(xMin, y), QPointF(xMax, y));
                  }
            }
      }
Example #2
0
QgsStringMap QgsArrowSymbolLayer::properties() const
{
  QgsStringMap map;

  map["arrow_width"] = QString::number( arrowWidth() );
  map["arrow_width_unit"] = QgsSymbolLayerV2Utils::encodeOutputUnit( arrowWidthUnit() );
  map["arrow_width_unit_scale"] = QgsSymbolLayerV2Utils::encodeMapUnitScale( arrowWidthUnitScale() );

  map["arrow_start_width"] = QString::number( arrowStartWidth() );
  map["arrow_start_width_unit"] = QgsSymbolLayerV2Utils::encodeOutputUnit( arrowStartWidthUnit() );
  map["arrow_start_width_unit_scale"] = QgsSymbolLayerV2Utils::encodeMapUnitScale( arrowStartWidthUnitScale() );

  map["is_curved"] = QString::number( isCurved() ? 1 : 0 );
  map["is_repeated"] = QString::number( isRepeated() ? 1 : 0 );

  map["head_width"] = QString::number( headWidth() );
  map["head_width_unit"] = QgsSymbolLayerV2Utils::encodeOutputUnit( headWidthUnit() );
  map["head_width_unit_scale"] = QgsSymbolLayerV2Utils::encodeMapUnitScale( headWidthUnitScale() );

  map["head_height"] = QString::number( headHeight() );
  map["head_height_unit"] = QgsSymbolLayerV2Utils::encodeOutputUnit( headHeightUnit() );
  map["head_height_unit_scale"] = QgsSymbolLayerV2Utils::encodeMapUnitScale( headHeightUnitScale() );

  map["head_type"] = QString::number( headType() );
  map["arrow_type"] = QString::number( arrowType() );

  map["offset"] = QString::number( offset() );
  map["offset_unit"] = QgsSymbolLayerV2Utils::encodeOutputUnit( offsetUnit() );
  map["offset_unit_scale"] = QgsSymbolLayerV2Utils::encodeMapUnitScale( offsetMapUnitScale() );

  saveDataDefinedProperties( map );
  return map;
}
Example #3
0
void Ambitus::layout()
      {
      int         bottomLine, topLine;
      ClefType    clf;
      qreal       headWdt     = headWidth();
      Key         key;
      qreal       lineDist;
      int         numOfLines;
      Segment*    segm        = segment();
      qreal       _spatium    = spatium();
      Staff*      stf         = nullptr;
      if (segm && track() > -1) {
            int tick    = segm->tick();
            stf         = score()->staff(staffIdx());
            lineDist    = stf->lineDistance(tick) * _spatium;
            numOfLines  = stf->lines(tick);
            clf         = stf->clef(tick);
            }
      else {                              // for use in palettes
            lineDist    = _spatium;
            numOfLines  = 3;
            clf         = ClefType::G;
            }

      //
      // NOTEHEADS Y POS
      //
      // if pitch == INVALID_PITCH oor tpc == INALID_TPC, set to some default:
      // for use in palettes and when actual range cannot be calculated (new ambitus or no notes in staff)
      //
      qreal xAccidOffTop    = 0;
      qreal xAccidOffBottom = 0;
      if (stf)
            key = stf->key(segm->tick());
      else
            key = Key::C;

      // top notehead
      if (_topPitch == INVALID_PITCH || _topTpc == Tpc::TPC_INVALID)
            _topPos.setY(0);                          // if uninitialized, set to top staff line
      else {
            topLine  = absStep(_topTpc, _topPitch);
            topLine  = relStep(topLine, clf);
            _topPos.setY(topLine * lineDist * 0.5);
            // compute accidental
            AccidentalType accidType;
            // if (13 <= (tpc - key) <= 19) there is no accidental)
            if (_topTpc - int(key) >= 13 && _topTpc - int(key) <= 19)
                  accidType = AccidentalType::NONE;
            else {
                  AccidentalVal accidVal = AccidentalVal( (_topTpc - Tpc::TPC_MIN) / TPC_DELTA_SEMITONE - 2 );
                  accidType = Accidental::value2subtype(accidVal);
                  if (accidType == AccidentalType::NONE)
                        accidType = AccidentalType::NATURAL;
                  }
            _topAccid.setAccidentalType(accidType);
            if (accidType != AccidentalType::NONE)
                  _topAccid.layout();
            else
                  _topAccid.setbbox(QRect());
            _topAccid.rypos() = _topPos.y();
            }

      // bottom notehead
      if (_bottomPitch == INVALID_PITCH || _bottomTpc == Tpc::TPC_INVALID)
            _bottomPos.setY( (numOfLines-1) * lineDist);          // if uninitialized, set to last staff line
      else {
            bottomLine  = absStep(_bottomTpc, _bottomPitch);
            bottomLine  = relStep(bottomLine, clf);
            _bottomPos.setY(bottomLine * lineDist * 0.5);
            // compute accidental
            AccidentalType accidType;
            if (_bottomTpc - int(key) >= 13 && _bottomTpc - int(key) <= 19)
                  accidType = AccidentalType::NONE;
            else {
                  AccidentalVal accidVal = AccidentalVal( (_bottomTpc - Tpc::TPC_MIN) / TPC_DELTA_SEMITONE - 2 );
                  accidType = Accidental::value2subtype(accidVal);
                  if (accidType == AccidentalType::NONE)
                        accidType = AccidentalType::NATURAL;
                  }
            _bottomAccid.setAccidentalType(accidType);
            if (accidType != AccidentalType::NONE)
                  _bottomAccid.layout();
            else
                  _bottomAccid.setbbox(QRect());
            _bottomAccid.rypos() = _bottomPos.y();
            }

      //
      // NOTEHEAD X POS
      //
      // Note: manages colliding accidentals
      //
      qreal accNoteDist = point(score()->styleS(Sid::accidentalNoteDistance));
      xAccidOffTop      = _topAccid.width() + accNoteDist;
      xAccidOffBottom   = _bottomAccid.width() + accNoteDist;

      // if top accidental extends down more than bottom accidental extends up,
      // AND ambitus is not leaning right, bottom accidental needs to be displaced
      bool collision =
            (_topAccid.ipos().y() + _topAccid.bbox().y() + _topAccid.height()
                   > _bottomAccid.ipos().y() + _bottomAccid.bbox().y() )
            && _dir != MScore::DirectionH::RIGHT;
      if (collision) {
            // displace bottom accidental (also attempting to 'undercut' flats)
            xAccidOffBottom = xAccidOffTop +
                  ((_bottomAccid.accidentalType() == AccidentalType::FLAT
                        || _bottomAccid.accidentalType() == AccidentalType::FLAT2
                        || _bottomAccid.accidentalType() == AccidentalType::NATURAL)
                  ? _bottomAccid.width() * 0.5 : _bottomAccid.width());
            }

      switch (_dir) {
            case MScore::DirectionH::AUTO:               // noteheads one above the other
                  // left align noteheads and right align accidentals 'hanging' on the left
                  _topPos.setX(0.0);
                  _bottomPos.setX(0.0);
                  _topAccid.rxpos()       = - xAccidOffTop;
                  _bottomAccid.rxpos()    = - xAccidOffBottom;
                  break;
            case MScore::DirectionH::LEFT:               // top notehead at the left of bottom notehead
                  // place top notehead at left margin; bottom notehead at right of top head;
                  // top accid. 'hanging' on left of top head and bottom accid. 'hanging' at left of bottom head
                  _topPos.setX(0.0);
                  _bottomPos.setX(headWdt);
                  _topAccid.rxpos() = - xAccidOffTop;
                  _bottomAccid.rxpos() = collision ? - xAccidOffBottom : headWdt - xAccidOffBottom;
                  break;
            case MScore::DirectionH::RIGHT:              // top notehead at the right of bottom notehead
                  // bottom notehead at left margin; top notehead at right of bottomnotehead
                  // top accid. 'hanging' on left of top head and bottom accid. 'hanging' at left of bottom head
                  _bottomPos.setX(0.0);
                  _topPos.setX(headWdt);
                  _bottomAccid.rxpos() = - xAccidOffBottom;
                  _topAccid.rxpos() = headWdt - xAccidOffTop;
                  break;
            }

      // compute line from top note centre to bottom note centre
      QLineF fullLine(_topPos.x() + headWdt*0.5, _topPos.y(),
            _bottomPos.x() + headWdt*0.5, _bottomPos.y());
      // shorten line on each side by offsets
      qreal yDelta = _bottomPos.y() - _topPos.y();
      if (yDelta != 0.0) {
            qreal off = _spatium * LINEOFFSET_DEFAULT;
            QPointF p1 = fullLine.pointAt(off / yDelta);
            QPointF p2 = fullLine.pointAt(1 - (off / yDelta));
            _line = QLineF(p1, p2);
            }
      else
            _line = fullLine;

      QRectF headRect = QRectF(0, -0.5*_spatium, headWdt, 1*_spatium);
      setbbox(headRect.translated(_topPos).united(headRect.translated(_bottomPos))
            .united(_topAccid.bbox().translated(_topAccid.ipos()))
            .united(_bottomAccid.bbox().translated(_bottomAccid.ipos()))
            );
      }
Example #4
0
void QgsArrowSymbolLayer::_resolveDataDefined( QgsSymbolV2RenderContext& context )
{
  if ( !hasDataDefinedProperties() )
    return; // shortcut if case there is no data defined properties at all

  bool ok;
  if ( hasDataDefinedProperty( "arrow_width" ) )
  {
    context.setOriginalValueVariable( arrowWidth() );
    double w = evaluateDataDefinedProperty( "arrow_width", context, QVariant(), &ok ).toDouble();
    if ( ok )
    {
      mScaledArrowWidth = QgsSymbolLayerV2Utils::convertToPainterUnits( context.renderContext(), w, arrowWidthUnit(), arrowWidthUnitScale() );
    }
  }
  if ( hasDataDefinedProperty( "arrow_start_width" ) )
  {
    context.setOriginalValueVariable( arrowStartWidth() );
    double w = evaluateDataDefinedProperty( "arrow_start_width", context, QVariant(), &ok ).toDouble();
    if ( ok )
    {
      mScaledArrowStartWidth = QgsSymbolLayerV2Utils::convertToPainterUnits( context.renderContext(), w, arrowStartWidthUnit(), arrowStartWidthUnitScale() );
    }
  }
  if ( hasDataDefinedProperty( "head_width" ) )
  {
    context.setOriginalValueVariable( headWidth() );
    double w = evaluateDataDefinedProperty( "head_width", context, QVariant(), &ok ).toDouble();
    if ( ok )
    {
      mScaledHeadWidth = QgsSymbolLayerV2Utils::convertToPainterUnits( context.renderContext(), w, headWidthUnit(), headWidthUnitScale() );
    }
  }
  if ( hasDataDefinedProperty( "head_height" ) )
  {
    context.setOriginalValueVariable( headHeight() );
    double w = evaluateDataDefinedProperty( "head_height", context, QVariant(), &ok ).toDouble();
    if ( ok )
    {
      mScaledHeadHeight = QgsSymbolLayerV2Utils::convertToPainterUnits( context.renderContext(), w, headHeightUnit(), headHeightUnitScale() );
    }
  }
  if ( hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_OFFSET ) )
  {
    context.setOriginalValueVariable( offset() );
    double w = evaluateDataDefinedProperty( QgsSymbolLayerV2::EXPR_OFFSET, context, QVariant(), &ok ).toDouble();
    if ( ok )
    {
      mScaledOffset = QgsSymbolLayerV2Utils::convertToPainterUnits( context.renderContext(), w, offsetUnit(), offsetMapUnitScale() );
    }
  }

  if ( hasDataDefinedProperty( "head_type" ) )
  {
    context.setOriginalValueVariable( headType() );
    int h = evaluateDataDefinedProperty( "head_type", context, QVariant(), &ok ).toInt();
    if ( ok )
    {
      mComputedHeadType = static_cast<HeadType>( h );
    }
  }

  if ( hasDataDefinedProperty( "arrow_type" ) )
  {
    context.setOriginalValueVariable( arrowType() );
    int h = evaluateDataDefinedProperty( "arrow_type", context, QVariant(), &ok ).toInt();
    if ( ok )
    {
      mComputedArrowType = static_cast<ArrowType>( h );
    }
  }
}
Example #5
0
void QgsArrowSymbolLayer::startRender( QgsSymbolV2RenderContext& context )
{
  mExpressionScope.reset( new QgsExpressionContextScope() );
  mScaledArrowWidth = QgsSymbolLayerV2Utils::convertToPainterUnits( context.renderContext(), arrowWidth(), arrowWidthUnit(), arrowWidthUnitScale() );
  mScaledArrowStartWidth = QgsSymbolLayerV2Utils::convertToPainterUnits( context.renderContext(), arrowStartWidth(), arrowStartWidthUnit(), arrowStartWidthUnitScale() );
  mScaledHeadWidth = QgsSymbolLayerV2Utils::convertToPainterUnits( context.renderContext(), headWidth(), headWidthUnit(), headWidthUnitScale() );
  mScaledHeadHeight = QgsSymbolLayerV2Utils::convertToPainterUnits( context.renderContext(), headHeight(), headHeightUnit(), headHeightUnitScale() );
  mScaledOffset = QgsSymbolLayerV2Utils::convertToPainterUnits( context.renderContext(), offset(), offsetUnit(), offsetMapUnitScale() );
  mComputedHeadType = headType();
  mComputedArrowType = arrowType();

  mSymbol->startRender( context.renderContext() );
}