Merge pull request #12253 from alexpavlov96/gp_bend

implemented stretched bends for correct import from guitar pro
This commit is contained in:
Alexander Pavlov 2022-07-11 14:45:50 +03:00 committed by GitHub
commit b0a2e290f8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 670 additions and 14 deletions

View file

@ -86,8 +86,8 @@ static const PitchValues PREBEND_RELEASE_CURVE = { PitchValue(0, 100),
// Bend
//---------------------------------------------------------
Bend::Bend(Note* parent)
: EngravingItem(ElementType::BEND, parent, ElementFlag::MOVABLE)
Bend::Bend(Note* parent, ElementType type)
: EngravingItem(type, parent, ElementFlag::MOVABLE)
{
initElementStyle(&bendStyle);
}

View file

@ -45,7 +45,7 @@ enum class BendType {
CUSTOM
};
class Bend final : public EngravingItem
class Bend : public EngravingItem // TODO: bring back "final" keyword
{
M_PROPERTY(String, fontFace, setFontFace)
M_PROPERTY(double, fontSize, setFontSize)
@ -70,9 +70,9 @@ public:
bool setProperty(Pid propertyId, const PropertyValue&) override;
PropertyValue propertyDefault(Pid) const override;
private:
protected: /// TODO: bring back "private" keyword after removing StretchedBend class
friend class Factory;
Bend(Note* parent);
Bend(Note* parent, ElementType type = ElementType::BEND);
mu::draw::Font font(double) const;
BendType parseBendTypeFromCurve() const;
@ -82,7 +82,8 @@ private:
PitchValues m_points;
mu::PointF m_notePos;
double m_noteWidth;
double m_noteWidth = 0;
double m_noteHeight = 0;
};
} // namespace mu::engraving
#endif

View file

@ -106,6 +106,7 @@ class TextBase;
class Hairpin;
class HairpinSegment;
class Bend;
class StretchedBend;
class TremoloBar;
class MeasureRepeat;
class Tuplet;
@ -351,6 +352,7 @@ public:
CONVERT(Hairpin, HAIRPIN)
CONVERT(HairpinSegment, HAIRPIN_SEGMENT)
CONVERT(Bend, BEND)
CONVERT(StretchedBend, STRETCHED_BEND)
CONVERT(TremoloBar, TREMOLOBAR)
CONVERT(MeasureRepeat, MEASURE_REPEAT)
CONVERT(Tuplet, TUPLET)
@ -680,6 +682,7 @@ CONVERT(MMRestRange)
CONVERT(Hairpin)
CONVERT(HairpinSegment)
CONVERT(Bend)
CONVERT(StretchedBend)
CONVERT(TremoloBar)
CONVERT(MeasureRepeat)
CONVERT(MMRest)

View file

@ -81,6 +81,7 @@
#include "tremolobar.h"
#include "fret.h"
#include "bend.h"
#include "stretchedbend.h"
#include "lyrics.h"
#include "figuredbass.h"
#include "slur.h"
@ -178,6 +179,7 @@ EngravingItem* Factory::doCreateItem(ElementType type, EngravingItem* parent)
case ElementType::HARMONY: return new Harmony(parent->isSegment() ? toSegment(parent) : dummy->segment());
case ElementType::FRET_DIAGRAM: return new FretDiagram(parent->isSegment() ? toSegment(parent) : dummy->segment());
case ElementType::BEND: return new Bend(parent->isNote() ? toNote(parent) : dummy->note());
case ElementType::STRETCHED_BEND: return new StretchedBend(parent->isNote() ? toNote(parent) : dummy->note());
case ElementType::TREMOLOBAR: return new TremoloBar(parent);
case ElementType::LYRICS: return new Lyrics(parent->isChordRest() ? toChordRest(parent) : dummy->chord());
case ElementType::FIGURED_BASS: return new FiguredBass(parent->isSegment() ? toSegment(parent) : dummy->segment());
@ -308,7 +310,17 @@ std::shared_ptr<Beam> Factory::makeBeam(System* parent)
return std::shared_ptr<Beam>(createBeam(parent));
}
CREATE_ITEM_IMPL(Bend, ElementType::BEND, Note, isAccessibleEnabled)
//CREATE_ITEM_IMPL(Bend, ElementType::BEND, Note, isAccessibleEnabled)
CREATE_ITEM_IMPL(StretchedBend, ElementType::STRETCHED_BEND, Note, isAccessibleEnabled)
Bend* Factory::createBend(Note * parent, ElementType type, bool isAccessibleEnabled)
{
Bend* b = new Bend(parent, type);
b->setAccessibleEnabled(isAccessibleEnabled);
return b;
}
MAKE_ITEM_IMPL(Bend, Note)
CREATE_ITEM_IMPL(Bracket, ElementType::BRACKET, EngravingItem, isAccessibleEnabled)

View file

@ -59,9 +59,11 @@ public:
static Beam* createBeam(System* parent, bool isAccessibleEnabled = true);
static std::shared_ptr<Beam> makeBeam(System* parent);
static Bend* createBend(Note* parent, bool isAccessibleEnabled = true);
static Bend* createBend(Note* parent, ElementType type = ElementType::BEND, bool isAccessibleEnabled = true);
static std::shared_ptr<Bend> makeBend(Note* parent);
static StretchedBend* createStretchedBend(Note* parent, bool isAccessibleEnabled = true);
static Bracket* createBracket(EngravingItem* parent, bool isAccessibleEnabled = true);
static std::shared_ptr<Bracket> makeBracket(EngravingItem* parent);
static BracketItem* createBracketItem(EngravingItem* parent);

View file

@ -39,6 +39,8 @@ set(LIBMSCORE_SRC
${CMAKE_CURRENT_LIST_DIR}/beam.h
${CMAKE_CURRENT_LIST_DIR}/bend.cpp
${CMAKE_CURRENT_LIST_DIR}/bend.h
${CMAKE_CURRENT_LIST_DIR}/stretchedbend.cpp
${CMAKE_CURRENT_LIST_DIR}/stretchedbend.h
${CMAKE_CURRENT_LIST_DIR}/box.cpp
${CMAKE_CURRENT_LIST_DIR}/box.h
${CMAKE_CURRENT_LIST_DIR}/bracket.cpp

View file

@ -1207,6 +1207,9 @@ void Note::add(EngravingItem* e)
case ElementType::NOTEDOT:
_dots.push_back(toNoteDot(e));
break;
case ElementType::STRETCHED_BEND:
m_bend = toStretchedBend(e);
// fallthrough
case ElementType::FINGERING:
case ElementType::SYMBOL:
case ElementType::IMAGE:
@ -1252,6 +1255,9 @@ void Note::remove(EngravingItem* e)
_dots.pop_back();
break;
case ElementType::STRETCHED_BEND:
m_bend = nullptr;
// fallthrough
case ElementType::TEXT:
case ElementType::SYMBOL:
case ElementType::IMAGE:

View file

@ -195,6 +195,7 @@ private:
bool _play = true; ///< note is not played if false
mutable bool _mark = false; ///< for use in sequencer
bool _fixed = false; ///< for slash notation
StretchedBend* m_bend = nullptr;
DirectionH _userMirror = DirectionH::AUTO; ///< user override of mirror
DirectionV _userDotPosition = DirectionV::AUTO; ///< user override of dot position
@ -537,6 +538,8 @@ public:
void relateSlide(Note& start) { _relatedSlide = &start._attachedSlide; }
StretchedBend* bend() const { return m_bend; }
bool isHammerOn() const { return _isHammerOn; }
void setIsHammerOn(bool hammerOn) { _isHammerOn = hammerOn; }

View file

@ -0,0 +1,494 @@
/*
* SPDX-License-Identifier: GPL-3.0-only
* MuseScore-CLA-applies
*
* MuseScore
* Music Composition & Notation
*
* Copyright (C) 2021 MuseScore BVBA and others
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "stretchedbend.h"
#include "staff.h"
#include "score.h"
#include "chord.h"
#include "draw/fontmetrics.h"
#include "log.h"
using namespace mu;
using namespace mu::draw;
using namespace mu::engraving;
namespace mu::engraving {
//---------------------------------------------------------
// label
//---------------------------------------------------------
static const char* label[] = {
"", "\u00BC", "\u00BD", "\u00BE", /// 0, 1/4, 1/2, 3/4
"full", "1\u00BC", "1\u00BD", "1\u00BE", /// 1, 1+1/4...
"2", "2\u00BC", "2\u00BD", "2\u00BE", /// 2, ...
"3" /// 3
};
//---------------------------------------------------------
// textFlags
//---------------------------------------------------------
static int textFlags = Qt::AlignHCenter | Qt::AlignBottom | Qt::TextDontClip;
//---------------------------------------------------------
// forward declarations of static functions
//---------------------------------------------------------
static void drawText(mu::draw::Painter* painter, const PointF& pos, const String& text);
static RectF textBoundingRect(const mu::draw::FontMetrics& fm, const PointF& pos, const String& text);
static PainterPath bendCurveFromPoints(const PointF& p1, const PointF& p2);
static int bendTone(int notePitch);
//---------------------------------------------------------
// static values
//---------------------------------------------------------
static constexpr double s_bendHeightMultiplier = .2; /// how much height differs for bend pitches
//---------------------------------------------------------
// StretchedBend
//---------------------------------------------------------
StretchedBend::StretchedBend(Note* parent)
: Bend(parent, ElementType::STRETCHED_BEND)
{
}
//---------------------------------------------------------
// fillSegments
//---------------------------------------------------------
void StretchedBend::fillSegments()
{
m_bendSegments.clear();
size_t n = m_points.size();
if (n < 2) {
return;
}
PointF src = (m_points[0].pitch == 0)
? PointF(m_noteWidth + m_spatium * .8, 0)
: PointF(m_noteWidth * .5, -m_noteHeight * .5 - m_spatium * .2);
PointF dest(0, 0);
int firstPointPitch = m_points.front().pitch;
int lastPointPitch = m_points.back().pitch;
m_releasedToInitial = (0 == lastPointPitch);
double baseBendHeight = m_spatium * 1.5;
bool skipNext = false; // need to skip some points
for (size_t pt = 0; pt < n - 1; pt++) {
if (skipNext) {
skipNext = false;
continue;
}
int pitch = m_points[pt].pitch;
int nextPitch = m_points[pt + 1].pitch;
BendSegmentType type = BendSegmentType::NO_TYPE;
int tone = bendTone(nextPitch);
bool untilNextSegment = false;
/// PRE-BEND (+BEND, +RELEASE)
if (pt == 0 && pitch != 0) {
int prebendTone = bendTone(pitch);
double minY = std::min(-m_notePos.y(), src.y());
dest = PointF(src.x(), minY - bendHeight(prebendTone) - baseBendHeight);
m_bendSegments.push_back({ src, dest, BendSegmentType::LINE_UP, prebendTone });
src.ry() = dest.y();
}
/// PRE-BEND - - -
if (pitch == nextPitch) {
if (pt == (n - 2)) {
break;
}
if (pt == 0) {
type = BendSegmentType::LINE_STROKED;
}
} else {
bool bendUp = pitch < nextPitch;
if (pt < n - 2) {
double nextNextPitch = m_points[pt + 2].pitch;
bool nextBendUp = nextPitch < nextNextPitch;
if (bendUp == nextBendUp) {
nextPitch = nextNextPitch;
skipNext = true;
}
}
if (bendUp) {
double minY = std::min(-m_notePos.y(), src.y());
dest.ry() = minY - bendHeight(tone) - baseBendHeight;
type = BendSegmentType::CURVE_UP;
} else {
if (m_releasedToInitial) {
dest.ry() = 0;
} else {
dest.ry() = src.y() + baseBendHeight;
}
type = BendSegmentType::CURVE_DOWN;
}
}
if (type != BendSegmentType::NO_TYPE) {
m_bendSegments.push_back({ src, dest, type, tone });
}
src = dest;
}
}
//---------------------------------------------------------
// stretchSegments
//---------------------------------------------------------
void StretchedBend::stretchSegments()
{
if (m_bendSegments.empty()) {
return;
}
/// find end of the whole bend
double bendEnd = nextSegmentX();
for (BendSegment& seg : m_bendSegments) {
if (seg.type != BendSegmentType::LINE_UP) {
seg.dest.rx() = bendEnd;
}
}
if (m_bendSegments.size() == 1) {
return;
}
size_t segsSize = m_bendSegments.size();
auto& lastSeg = m_bendSegments[segsSize - 1];
auto& prevSeg = m_bendSegments[segsSize - 2];
if (lastSeg.type != BendSegmentType::LINE_UP && prevSeg.type != BendSegmentType::LINE_UP) {
lastSeg.dest.rx() = bendEnd;
double newCoord = prevSeg.src.x() + (bendEnd - prevSeg.src.x()) / 2;
prevSeg.dest.rx() = newCoord;
lastSeg.src.rx() = newCoord;
}
}
//---------------------------------------------------------
// layout
//---------------------------------------------------------
void StretchedBend::layout()
{
preLayout();
layoutDraw(true);
postLayout();
}
//---------------------------------------------------------
// draw
//---------------------------------------------------------
void StretchedBend::draw(mu::draw::Painter* painter) const
{
TRACE_OBJ_DRAW;
setupPainter(painter);
layoutDraw(false, painter);
}
//---------------------------------------------------------
// layoutDraw
//---------------------------------------------------------
void StretchedBend::layoutDraw(const bool layoutMode, mu::draw::Painter* painter) const
{
if (!layoutMode && !painter) {
return;
}
double prebendStrokeLength = m_spatium * .5;
for (const BendSegment& bendSegment : m_bendSegments) {
const PointF& src = bendSegment.src;
const PointF& dest = bendSegment.dest;
const String& text = String(label[bendSegment.tone]);
switch (bendSegment.type) {
case BendSegmentType::LINE_UP:
{
if (layoutMode) {
m_boundingRect.unite(RectF(src.x(), src.y(), dest.x() - src.x(), dest.y() - src.y()));
m_boundingRect.unite(m_arrowUp.translated(dest).boundingRect());
mu::draw::FontMetrics fm(font(m_spatium));
m_boundingRect.unite(textBoundingRect(fm, dest, text));
} else {
painter->drawLine(LineF(src, dest));
painter->setBrush(curColor());
painter->drawPolygon(m_arrowUp.translated(dest));
drawText(painter, dest, text);
}
break;
}
case BendSegmentType::CURVE_UP:
case BendSegmentType::CURVE_DOWN:
{
bool bendUp = (bendSegment.type == BendSegmentType::CURVE_UP);
double endY = dest.y() + m_bendArrowWidth * (bendUp ? 1 : -1);
PainterPath path = bendCurveFromPoints(src, PointF(dest.x(), endY));
const auto& arrowPath = (bendUp ? m_arrowUp : m_arrowDown);
if (layoutMode) {
m_boundingRect.unite(path.boundingRect());
m_boundingRect.unite(arrowPath.translated(dest).boundingRect());
} else {
painter->setBrush(BrushStyle::NoBrush);
painter->drawPath(path);
painter->setBrush(curColor());
painter->drawPolygon(arrowPath.translated(dest));
}
if (bendUp || !m_releasedToInitial) {
if (layoutMode) {
mu::draw::FontMetrics fm(font(m_spatium));
m_boundingRect.unite(textBoundingRect(fm, dest - PointF(m_spatium, 0), text));
} else {
double textLabelOffset = (!bendUp && !m_releasedToInitial ? m_spatium : 0);
PointF textPoint = dest + PointF(textLabelOffset, -textLabelOffset);
drawText(painter, textPoint, text);
}
}
break;
}
case BendSegmentType::LINE_STROKED:
{
if (layoutMode) {
m_boundingRect.unite(RectF(src.x(), src.y(), dest.x() - src.x(), dest.y() - src.y()));
} else {
PainterPath path;
path.moveTo(src + PointF(m_bendArrowWidth, 0));
path.lineTo(dest);
Pen p(painter->pen());
p.setStyle(PenStyle::DashLine);
painter->strokePath(path, p);
}
break;
}
default:
break;
}
}
}
//---------------------------------------------------------
// preLayout
//---------------------------------------------------------
void StretchedBend::preLayout()
{
m_spatium = spatium();
m_boundingRect = RectF();
Note* note = toNote(explicitParent());
m_notePos = note->pos();
m_noteWidth = note->width();
m_noteHeight = note->height();
fillArrows();
fillSegments();
stretchSegments();
}
//---------------------------------------------------------
// postLayout
//---------------------------------------------------------
void StretchedBend::postLayout()
{
double lw = lineWidth();
m_boundingRect.adjust(-lw, -lw, lw, lw);
setbbox(m_boundingRect);
setPos(0.0, 0.0);
}
//---------------------------------------------------------
// setupPainter
//---------------------------------------------------------
void StretchedBend::setupPainter(mu::draw::Painter* painter) const
{
Pen pen(curColor(), lineWidth(), PenStyle::SolidLine, PenCapStyle::RoundCap, PenJoinStyle::RoundJoin);
painter->setPen(pen);
painter->setBrush(Brush(curColor()));
mu::draw::Font f = font(spatium() * MScore::pixelRatio);
painter->setFont(f);
}
//---------------------------------------------------------
// glueNeighbor
//---------------------------------------------------------
void StretchedBend::prepareBends(std::vector<StretchedBend*>& bends)
{
/// glueing extra bends together
for (StretchedBend* bend : bends) {
bend->glueNeighbor();
}
/// deleting reduntant bends
auto reduntantIt = std::partition(bends.begin(), bends.end(), [](StretchedBend* bend) { return bend->m_reduntant; });
for (auto bendIt = bends.begin(); bendIt != reduntantIt; bendIt++) {
StretchedBend* bendToRemove = *bendIt;
EngravingObject* parentObj = bendToRemove->parent();
if (Note* note = dynamic_cast<Note*>(parentObj)) {
note->remove(bendToRemove);
}
delete bendToRemove;
bendToRemove = nullptr;
}
}
//---------------------------------------------------------
// glueNeighbor
//---------------------------------------------------------
void StretchedBend::glueNeighbor()
{
if (m_reduntant) {
return;
}
std::vector<Note*> ties = toNote(parent())->tiedNotes();
for (Note* t : ties) {
assert(!!t);
if (t->bend() && t != parent()) {
auto bend = t->bend();
auto& lastPoints = bend->points();
for (int i = 1; i < lastPoints.size(); ++i) {
m_points.push_back(lastPoints[i]);
}
t->remove(bend);
bend->m_reduntant = true;
}
}
}
//---------------------------------------------------------
// fillArrows
//---------------------------------------------------------
void StretchedBend::fillArrows()
{
double aw = 0;
m_bendArrowWidth = aw = score()->styleMM(Sid::bendArrowWidth);
m_arrowUp.clear();
m_arrowDown.clear();
m_arrowUp << PointF(0, 0) << PointF(aw * .5, aw) << PointF(-aw * .5, aw);
m_arrowDown << PointF(0, 0) << PointF(aw * .5, -aw) << PointF(-aw * .5, -aw);
}
//---------------------------------------------------------
// drawText
//---------------------------------------------------------
void drawText(mu::draw::Painter* painter, const PointF& pos, const String& text)
{
painter->drawText(RectF(pos.x(), pos.y(), .0, .0), textFlags, text);
}
//---------------------------------------------------------
// textBoundingRect
//---------------------------------------------------------
RectF textBoundingRect(const mu::draw::FontMetrics& fm, const PointF& pos, const String& text)
{
return fm.boundingRect(RectF(pos.x(), pos.y(), 0, 0), textFlags, text);
}
//---------------------------------------------------------
// bendCurveFromPoints
//---------------------------------------------------------
PainterPath bendCurveFromPoints(const PointF& p1, const PointF& p2)
{
PainterPath path;
path.moveTo(p1.x(), p1.y());
path.cubicTo(p1.x() + (p2.x() - p1.x()) / 2, p1.y(), p2.x(), p1.y() + (p2.y() - p1.y()) / 4, p2.x(), p2.y());
return path;
}
//---------------------------------------------------------
// nextSegmentX
//---------------------------------------------------------
double StretchedBend::nextSegmentX() const
{
Segment* nextSeg = toNote(parent())->chord()->segment()->nextInStaff(
staffIdx(), SegmentType::ChordRest | SegmentType::BarLine | SegmentType::EndBarLine);
if (!nextSeg) {
return 0;
}
return nextSeg->pagePos().x() - pagePos().x() - m_spatium;
}
//---------------------------------------------------------
// bendPitch
//---------------------------------------------------------
int bendTone(int notePitch)
{
return (notePitch + 12) / 25;
}
//---------------------------------------------------------
// bendHeight
//---------------------------------------------------------
double StretchedBend::bendHeight(int bendIdx) const
{
return m_spatium * (bendIdx + 1) * s_bendHeightMultiplier;
}
}

View file

@ -0,0 +1,90 @@
/*
* SPDX-License-Identifier: GPL-3.0-only
* MuseScore-CLA-applies
*
* MuseScore
* Music Composition & Notation
*
* Copyright (C) 2021 MuseScore BVBA and others
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef __STRETCHED_BEND_H__
#define __STRETCHED_BEND_H__
#include "bend.h"
namespace mu::engraving {
class Factory;
//---------------------------------------------------------
// @@ StretchedBend
//---------------------------------------------------------
class StretchedBend final : public Bend
{
public:
StretchedBend* clone() const override { return new StretchedBend(*this); }
void layout() override;
void draw(mu::draw::Painter*) const override;
static void prepareBends(std::vector<StretchedBend*>& bends);
private:
friend class mu::engraving::Factory;
StretchedBend(Note* parent);
void fillSegments(); // converting points from file to bend segments
void stretchSegments(); // stretching until end of chord duration
void glueNeighbor(); // fixing the double appearance of some bends
void layoutDraw(const bool layoutMode, mu::draw::Painter* painter = nullptr) const; /// loop for both layout and draw logic
void preLayout();
void postLayout();
void setupPainter(mu::draw::Painter* painter) const;
void fillArrows();
double nextSegmentX() const;
double bendHeight(int bendIdx) const;
bool m_reduntant = false; // marks that the bend was 'glued' to neighbour and is now unnecessary
enum class BendSegmentType {
NO_TYPE = -1,
LINE_UP,
CURVE_UP,
CURVE_DOWN,
LINE_STROKED
};
struct BendSegment {
PointF src;
PointF dest;
BendSegmentType type = BendSegmentType::NO_TYPE;
int tone = -1;
};
std::vector<BendSegment> m_bendSegments;
PolygonF m_arrowUp;
PolygonF m_arrowDown;
double m_spatium = 0;
double m_bendArrowWidth = 0;
mutable RectF m_boundingRect;
bool m_releasedToInitial = false;
};
} // namespace mu::engraving
#endif

View file

@ -113,6 +113,7 @@ enum class ElementType {
HARMONY,
FRET_DIAGRAM,
BEND,
STRETCHED_BEND,
TREMOLOBAR,
VOLTA,
HAIRPIN_SEGMENT,

View file

@ -187,6 +187,7 @@ static const std::vector<Item<ElementType> > ELEMENT_TYPES = {
{ ElementType::HARMONY, "Harmony", QT_TRANSLATE_NOOP("engraving", "Chord symbol") },
{ ElementType::FRET_DIAGRAM, "FretDiagram", QT_TRANSLATE_NOOP("engraving", "Fretboard diagram") },
{ ElementType::BEND, "Bend", QT_TRANSLATE_NOOP("engraving", "Bend") },
{ ElementType::STRETCHED_BEND, "Bend", QT_TRANSLATE_NOOP("engraving", "Bend") },
{ ElementType::TREMOLOBAR, "TremoloBar", QT_TRANSLATE_NOOP("engraving", "Tremolo bar") },
{ ElementType::VOLTA, "Volta", QT_TRANSLATE_NOOP("engraving", "Volta") },
{ ElementType::HAIRPIN_SEGMENT, "HairpinSegment", QT_TRANSLATE_NOOP("engraving", "Hairpin segment") },

View file

@ -7,7 +7,6 @@
#include "libmscore/factory.h"
#include "libmscore/arpeggio.h"
#include "libmscore/box.h"
#include "libmscore/bend.h"
#include "libmscore/bracketItem.h"
#include "libmscore/clef.h"
#include "libmscore/chord.h"
@ -49,7 +48,7 @@
#include "libmscore/tuplet.h"
#include "libmscore/volta.h"
#include "libmscore/harmonicmark.h"
#include "libmscore/excerpt.h"
#include "libmscore/stretchedbend.h"
#include "../importgtp.h"
@ -329,6 +328,11 @@ void GPConverter::convert(const std::vector<std::unique_ptr<GPMasterBar> >& mast
}
addTempoMap();
#ifdef ENGRAVING_USE_STRETCHED_BENDS
StretchedBend::prepareBends(m_bends);
#endif
addFermatas();
addContinuousSlideHammerOn();
}
@ -1676,7 +1680,12 @@ void GPConverter::addBend(const GPNote* gpnote, Note* note)
return;
}
#ifdef ENGRAVING_USE_STRETCHED_BENDS
StretchedBend* bend = mu::engraving::Factory::createStretchedBend(note);
#else
Bend* bend = mu::engraving::Factory::createBend(note);
#endif
auto gpBend = gpnote->bend();
bool bendHasMiddleValue{ true };
@ -1719,6 +1728,7 @@ void GPConverter::addBend(const GPNote* gpnote, Note* note)
bend->setTrack(note->track());
note->add(bend);
m_bends.push_back(bend);
}
void GPConverter::addLineElement(ChordRest* cr, std::vector<TextLineBase*>& elements, ElementType muType, TextLineImportType importType,

View file

@ -34,6 +34,7 @@ class LetRing;
class PalmMute;
class Vibrato;
class Ottava;
class Bend;
class GPConverter
{
@ -217,6 +218,13 @@ private:
Hairpin* _lastHairpin = nullptr;
std::vector<Ottava*> m_lastOttavas;
#ifdef ENGRAVING_USE_STRETCHED_BENDS
std::vector<StretchedBend*> m_bends;
#else
std::vector<Bend*> m_bends;
#endif
Measure* _lastMeasure = nullptr;
bool m_showCapo = true; // TODO-gp : settings
};

View file

@ -26,7 +26,6 @@
#include "libmscore/arpeggio.h"
#include "libmscore/articulation.h"
#include "libmscore/barline.h"
#include "libmscore/bend.h"
#include "libmscore/box.h"
#include "libmscore/bracket.h"
#include "libmscore/chord.h"
@ -1136,6 +1135,10 @@ bool GuitarPro4::read(IODevice* io)
}
}
#ifdef ENGRAVING_USE_STRETCHED_BENDS
StretchedBend::prepareBends(m_bends);
#endif
return true;
}
}

View file

@ -26,7 +26,6 @@
#include "libmscore/arpeggio.h"
#include "libmscore/articulation.h"
#include "libmscore/barline.h"
#include "libmscore/bend.h"
#include "libmscore/box.h"
#include "libmscore/bracket.h"
#include "libmscore/chord.h"
@ -954,6 +953,10 @@ bool GuitarPro5::read(IODevice* io)
}
}
#ifdef ENGRAVING_USE_STRETCHED_BENDS
StretchedBend::prepareBends(m_bends);
#endif
return true;
}

View file

@ -32,7 +32,6 @@
#include "libmscore/arpeggio.h"
#include "libmscore/articulation.h"
#include "libmscore/barline.h"
#include "libmscore/bend.h"
#include "libmscore/box.h"
#include "libmscore/bracket.h"
#include "libmscore/bracketItem.h"

View file

@ -59,7 +59,7 @@
#include <libmscore/articulation.h>
#include <libmscore/keysig.h>
#include <libmscore/harmony.h>
#include <libmscore/bend.h>
#include "libmscore/stretchedbend.h"
#include <libmscore/tremolobar.h>
#include <libmscore/segment.h>
#include <libmscore/rehearsalmark.h>
@ -759,7 +759,13 @@ void GuitarPro::readBend(Note* note)
if (numPoints == 0) {
return;
}
#ifdef ENGRAVING_USE_STRETCHED_BENDS
StretchedBend* bend = Factory::createStretchedBend(note);
#else
Bend* bend = Factory::createBend(note);
#endif
//TODO-ws bend->setNote(note);
for (int i = 0; i < numPoints; ++i) {
int bendTime = readInt();
@ -770,6 +776,7 @@ void GuitarPro::readBend(Note* note)
//TODO-ws bend->setAmplitude(amplitude);
bend->setTrack(note->track());
note->add(bend);
m_bends.push_back(bend);
}
//---------------------------------------------------------
@ -2741,6 +2748,11 @@ bool GuitarPro3::read(IODevice* io)
break;
}
}
#ifdef ENGRAVING_USE_STRETCHED_BENDS
StretchedBend::prepareBends(m_bends);
#endif
return true;
}

View file

@ -229,6 +229,12 @@ protected:
QTextCodec* _codec { 0 };
Slur** slurs { nullptr };
#ifdef ENGRAVING_USE_STRETCHED_BENDS
std::vector<StretchedBend*> m_bends;
#else
std::vector<Bend*> m_bends;
#endif
void skip(qint64 len);
void read(void* p, qint64 len);
int readUChar();