Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/engraving/data/chords/chords_jazz.xml
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@
<sym code="0x1d12b" name="bb"/>

<sym code="0xE87C" name="dslash"/>
<sym code="0xE874" name="-"/>
<sym value="-" name="-"/>
<sym code="0xe186" name="+"/>
</font>

Expand Down Expand Up @@ -222,12 +222,12 @@

<token>
<name>o</name>
<render>sc:0.5 :push :mx circle :popy sc:2</render>
<render>sc:0.8 :push :mx circle :popy sc:1.25 m:0.1:0</render>
</token>

<token>
<name>0</name>
<render>sc:0.5 :push :mx oslash :popy sc:2</render>
<render>sc:0.8 :push :mx oslash :popy sc:1.25 m:0.1:0</render>
</token>

<token>
Expand Down
4 changes: 2 additions & 2 deletions src/engraving/data/chords/chords_std.xml
Original file line number Diff line number Diff line change
Expand Up @@ -215,12 +215,12 @@

<token>
<name>o</name>
<render>sc:0.5 :push :mx circle :popy sc:2</render>
<render>sc:0.5 :push :mx circle :popy sc:2 m:0.1:0</render>
</token>

<token>
<name>0</name>
<render>sc:0.5 :push :mx oslash :popy sc:2</render>
<render>sc:0.5 :push :mx oslash :popy sc:2 m:0.1:0</render>
</token>

<token>
Expand Down
27 changes: 24 additions & 3 deletions src/engraving/dom/edit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6397,6 +6397,23 @@
return false;
}

static bool chordHasVisibleChild(const Chord* chord)
{
for (EngravingObject* child : chord->scanChildren()) {
if (toEngravingItem(child)->visible()) {
return true;
}
}

for (const Chord* graceNote : chord->graceNotes()) {
if (chordHasVisibleChild(graceNote)) {
return true;
}
}

return false;
}

static void undoChangeOrnamentVisibility(Ornament* ornament, bool visible);

static void undoChangeNoteVisibility(Note* note, bool visible)
Expand Down Expand Up @@ -6448,9 +6465,9 @@
ElementType::LEDGER_LINE, // temporary objects, impossible to change visibility
};

for (const Chord* chord : chords) {
for (const EngravingObject* obj : chord->linkList()) {
const Chord* linkedChord = toChord(obj);
for (Chord* chord : chords) {
for (EngravingObject* obj : chord->linkList()) {
Chord* linkedChord = toChord(obj);
chordHasVisibleNote_ = chordHasVisibleNote(linkedChord);
for (EngravingObject* child : linkedChord->scanChildren()) {
const ElementType type = child->type();
Expand All @@ -6471,6 +6488,10 @@
child->undoChangeProperty(Pid::VISIBLE, chordHasVisibleNote_);
}
}
bool visible = chordHasVisibleChild(linkedChord);

Check warning on line 6491 in src/engraving/dom/edit.cpp

View workflow job for this annotation

GitHub Actions / windows_x64

declaration of 'visible' hides function parameter
if (!visible) {
linkedChord->undoChangeProperty(Pid::VISIBLE, visible);
}
}
}
}
Expand Down
66 changes: 66 additions & 0 deletions src/engraving/dom/gradualtempochange.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@

#include "gradualtempochange.h"

#include "dom/rehearsalmark.h"
#include "dom/text.h"
#include "measure.h"
#include "score.h"
#include "segment.h"
Expand Down Expand Up @@ -147,6 +149,8 @@ PropertyValue GradualTempoChange::getProperty(Pid id) const
return tempoChangeFactor();
case Pid::SNAP_AFTER:
return snapToItemAfter();
case Pid::TEMPO_ALIGN_RIGHT_OF_REHEARSAL_MARK:
return m_alignRightOfRehearsalMark;
default:
return TextLineBase::getProperty(id);
}
Expand All @@ -167,6 +171,9 @@ bool GradualTempoChange::setProperty(Pid id, const PropertyValue& val)
case Pid::SNAP_AFTER:
setSnapToItemAfter(val.toBool());
break;
case Pid::TEMPO_ALIGN_RIGHT_OF_REHEARSAL_MARK:
m_alignRightOfRehearsalMark = val.toBool();
break;
default:
if (!TextLineBase::setProperty(id, val)) {
return false;
Expand Down Expand Up @@ -221,6 +228,9 @@ PropertyValue GradualTempoChange::propertyDefault(Pid propertyId) const
case Pid::SNAP_AFTER:
return true;

case Pid::TEMPO_ALIGN_RIGHT_OF_REHEARSAL_MARK:
return true;

default:
return TextLineBase::propertyDefault(propertyId);
}
Expand Down Expand Up @@ -261,6 +271,62 @@ Sid GradualTempoChange::getPropertyStyle(Pid id) const
return TextLineBase::getPropertyStyle(id);
}

bool GradualTempoChange::adjustForRehearsalMark(bool start) const
{
const Segment* segment = start ? startSegment() : endSegment();
if (!m_alignRightOfRehearsalMark || !segment) {
return false;
}

const RehearsalMark* rehearsalMark = toRehearsalMark(segment->findAnnotation(ElementType::REHEARSAL_MARK, track(), track()));
if (!rehearsalMark) {
return false;
}
RectF thisBbox = ldata()->bbox().translated(pos());
RectF rehearsalMarkBbox = rehearsalMark ? rehearsalMark->ldata()->bbox().translated(rehearsalMark->pos()) : RectF();

const bool sameSide = placeAbove() == rehearsalMark->placeAbove();
const bool collision = placeAbove() ? muse::RealIsEqualOrMore(rehearsalMarkBbox.bottom(), thisBbox.top()) : muse::RealIsEqualOrLess(
rehearsalMarkBbox.top(), thisBbox.bottom());

return sameSide && collision;
}

PointF GradualTempoChange::linePos(Grip grip, System** system) const
{
bool start = grip == Grip::START;
PointF defaultPos = TextLineBase::linePos(grip, system);
if (!adjustForRehearsalMark(start)) {
return defaultPos;
}

const Segment* segment = start ? startSegment() : endSegment();
const RehearsalMark* rehearsalMark = toRehearsalMark(segment->findAnnotation(ElementType::REHEARSAL_MARK, track(), track()));
RectF rehearsalMarkBbox = rehearsalMark ? rehearsalMark->ldata()->bbox().translated(rehearsalMark->pos()) : RectF();

PointF rehearsalMarkPos = segment->pos() + segment->measure()->pos();
rehearsalMarkBbox.translate(rehearsalMarkPos);

Text* text = start ? toGradualTempoChangeSegment(frontSegment())->text() : toGradualTempoChangeSegment(backSegment())->endText();

const double sp = spatium();

double padding = sp;
if (text) {
const double fontSizeScaleFactor = text->size() / 10.0;
padding = 0.5 * sp * fontSizeScaleFactor;
}

padding *= start ? 1.0 : -1.0;
double x = (start ? rehearsalMarkBbox.right() : rehearsalMarkBbox.left()) + padding;

*system = segment->measure()->system();

x = start ? std::max(x, defaultPos.x()) : x;

return PointF(x, 0.0);
}

void GradualTempoChange::added()
{
requestToRebuildTempo();
Expand Down
5 changes: 5 additions & 0 deletions src/engraving/dom/gradualtempochange.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ class GradualTempoChange : public TextLineBase
bool snapToItemAfter() const { return m_snapToItemAfter; }
void setSnapToItemAfter(bool v) { m_snapToItemAfter = v; }

bool adjustForRehearsalMark(bool start) const;
PointF linePos(Grip grip, System** system) const override;

protected:
void added() override;
void removed() override;
Expand All @@ -69,6 +72,8 @@ class GradualTempoChange : public TextLineBase

bool m_snapToItemAfter = true;

bool m_alignRightOfRehearsalMark = true;

friend class GradualTempoChangeSegment;
};

Expand Down
3 changes: 2 additions & 1 deletion src/engraving/dom/score.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1612,7 +1612,8 @@ void Score::addElement(EngravingItem* element)
break;
}

if (element->isTextBase() && toTextBase(element)->hasParentSegment()) {
if (element->isTextBase() && toTextBase(element)->hasParentSegment()
&& toSegment(element->parent())->isType(Segment::CHORD_REST_OR_TIME_TICK_TYPE)) {
MoveElementAnchors::checkMeasureBoundariesAndMoveIfNeed(element);
}

Expand Down
7 changes: 5 additions & 2 deletions src/engraving/dom/volta.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -331,12 +331,15 @@ PointF Volta::linePos(Grip grip, System** system) const
bool isAtSystemStart = segment->rtick().isZero() && measure && measure->system() && measure->isFirstInSystem();
bool searchForPrevBarline = start ? segment->rtick().isZero() && (measure->repeatStart() || !isAtSystemStart) : true;

SegmentType barlineType = start ? (SegmentType::StartRepeatBarLine | SegmentType::EndBarLine) : SegmentType::EndBarLine;

if (searchForPrevBarline) {
Segment* prev = segment;
while (prev && !prev->isType(SegmentType::BarLineType) && prev->tick() == segment->tick()) {
while (prev && !prev->isType(barlineType) && prev->tick() == segment->tick()) {
prev = prev->prev1MMenabled();
}
if (prev && prev->isType(SegmentType::BarLineType)) {

if (prev && prev->isType(barlineType)) {
segment = prev;
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/engraving/rendering/score/dynamicslayout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ void DynamicsLayout::doLayoutDynamic(Dynamic* item, Dynamic::LayoutData* ldata,
}

bool centerOnNote = item->centerOnNotehead() || (!item->centerOnNotehead() && item->align().horizontal == AlignH::HCENTER);
double noteHeadWidth = item->score()->noteHeadWidth();
double mag = item->staff()->staffMag(item);
double noteHeadWidth = item->score()->noteHeadWidth() * mag;

ldata->moveX(noteHeadWidth * (centerOnNote ? 0.5 : 1));

Expand Down
37 changes: 37 additions & 0 deletions src/engraving/rendering/score/harmonylayout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -774,6 +774,41 @@ void HarmonyLayout::renderActionParen(Harmony* item, const RenderActionParenPtr&
harmonyCtx.renderItemList.push_back(parenItem);
}

void HarmonyLayout::kernCharacters(const Harmony* item, const String& text, HarmonyRenderCtx& harmonyCtx)
{
if (harmonyCtx.renderItemList.empty()) {
return;
}
// Character pair and distance to move the second
static const std::map<std::pair<String, String>, double> KERNED_CHARACTERS {
{ { u"A", u"\uE870" }, -0.4 }, // dim
{ { u"A", u"\uE871" }, -0.3 }, // half-dim
{ { u"\uE873", u"\uE870" }, -0.4 }, // triangle - dim
{ { u"\uE873", u"\uE871" }, -0.3 }, // triangle - half-dim

{ { u"A", u"\uE18E" }, -0.15 }, // dim JAZZ
{ { u"A", u"\uE18F" }, -0.15 }, // hal-dim JAZZ
{ { u"\uE18A", u"\uE18E" }, -0.15 }, // triangle - dim JAZZ
{ { u"\uE18A", u"\uE18F" }, -0.15 }, // triangle - half-dim JAZZ
};

HarmonyRenderItem* prevSeg = harmonyCtx.renderItemList.back();
TextSegment* ts = dynamic_cast<TextSegment*>(prevSeg);
if (!ts) {
return;
}

for (auto& kernInfo : KERNED_CHARACTERS) {
const std::pair<String, String> kernPair = kernInfo.first;
if (ts->text().endsWith(kernPair.first) && text.startsWith(kernPair.second)) {
const FontMetrics fm = FontMetrics(item->font());
const double scale = harmonyCtx.scale * item->mag();
harmonyCtx.pos = harmonyCtx.pos + PointF(kernInfo.second, 0.0) * FontMetrics::capHeight(item->font()) * scale;
break;
}
}
}

void HarmonyLayout::renderActionSet(Harmony* item, Harmony::LayoutData* ldata, const RenderActionSetPtr& a, HarmonyRenderCtx& harmonyCtx)
{
const ChordList* chordList = item->score()->chordList();
Expand All @@ -786,6 +821,8 @@ void HarmonyLayout::renderActionSet(Harmony* item, Harmony::LayoutData* ldata, c
font.setPointSizeF(font.pointSizeF() * nmag);
}

kernCharacters(item, text, harmonyCtx);

TextSegment* ts = new TextSegment(text, font, harmonyCtx.x(), harmonyCtx.y(), harmonyCtx.hAlign);
harmonyCtx.movex(ts->width());

Expand Down
2 changes: 2 additions & 0 deletions src/engraving/rendering/score/harmonylayout.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,5 +86,7 @@ class HarmonyLayout
static void renderActionAlign(HarmonyRenderCtx& harmonyCtx);
static void renderActionScale(const RenderActionScalePtr& a, HarmonyRenderCtx& harmonyCtx);
static void renderActionParen(Harmony* item, const RenderActionParenPtr& a, HarmonyRenderCtx& harmonyCtx);

static void kernCharacters(const Harmony* item, const String& text, HarmonyRenderCtx& harmonyCtx);
};
}
6 changes: 5 additions & 1 deletion src/engraving/rendering/score/restlayout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -497,7 +497,11 @@ InterruptionPoints RestLayout::computeInterruptionPoints(const Measure* measure,
for (const Segment* segment = measure->first(SegmentType::ChordRest); segment; segment = segment->next(SegmentType::ChordRest)) {
for (track_idx_t track = sTrack; track < eTrack; ++track) {
EngravingItem* item = segment->element(track);
if (item && item->isRest() && toRest(item)->isGap()) {
if (!item) {
continue;
}
const bool gapRest = item->isRest() && toRest(item)->isGap();
if (gapRest || !item->visible()) {
for (voice_idx_t voice = 0; voice < VOICES; ++voice) {
interruptionPointSets[voice].insert(segment->rtick());
interruptionPointSets[voice].insert(segment->rtick() + segment->ticks());
Expand Down
Loading
Loading