LCOV - code coverage report
Current view: top level - src/engraving/playback/renderers - chordarticulationsrenderer.cpp Coverage Total Hit
Test: filtered_coverage.info Lines: 74.0 % 50 37
Test Date: 2026-11-05 04:07:02

            Line data    Source code
       1              : /*
       2              :  * SPDX-License-Identifier: GPL-3.0-only
       3              :  * MuseScore-Studio-CLA-applies
       4              :  *
       5              :  * MuseScore Studio
       6              :  * Music Composition & Notation
       7              :  *
       8              :  * Copyright (C) 2022 MuseScore Limited and others
       9              :  *
      10              :  * This program is free software: you can redistribute it and/or modify
      11              :  * it under the terms of the GNU General Public License version 3 as
      12              :  * published by the Free Software Foundation.
      13              :  *
      14              :  * This program is distributed in the hope that it will be useful,
      15              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      16              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17              :  * GNU General Public License for more details.
      18              :  *
      19              :  * You should have received a copy of the GNU General Public License
      20              :  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
      21              :  */
      22              : 
      23              : #include "chordarticulationsrenderer.h"
      24              : 
      25              : #include "bendsrenderer.h"
      26              : #include "noterenderer.h"
      27              : #include "gracechordcontext.h"
      28              : #include "ornamentsrenderer.h"
      29              : #include "tremolorenderer.h"
      30              : #include "arpeggiorenderer.h"
      31              : 
      32              : #include "playback/utils/expressionutils.h"
      33              : 
      34              : using namespace mu::engraving;
      35              : using namespace muse;
      36              : using namespace muse::mpe;
      37              : 
      38            0 : const mpe::ArticulationTypeSet& ChordArticulationsRenderer::supportedTypes()
      39              : {
      40            0 :     static mpe::ArticulationTypeSet SUPPORTED_TYPES;
      41              : 
      42            0 :     if (SUPPORTED_TYPES.empty()) {
      43            0 :         SUPPORTED_TYPES = GRACE_NOTE_ARTICULATION_TYPES;
      44              : 
      45            0 :         SUPPORTED_TYPES.insert(OrnamentsRenderer::supportedTypes().cbegin(),
      46            0 :                                OrnamentsRenderer::supportedTypes().cend());
      47            0 :         SUPPORTED_TYPES.insert(TremoloRenderer::supportedTypes().cbegin(),
      48            0 :                                TremoloRenderer::supportedTypes().cend());
      49            0 :         SUPPORTED_TYPES.insert(ArpeggioRenderer::supportedTypes().cbegin(),
      50            0 :                                ArpeggioRenderer::supportedTypes().cend());
      51              :     }
      52              : 
      53            0 :     return SUPPORTED_TYPES;
      54              : }
      55              : 
      56         1071 : void ChordArticulationsRenderer::doRender(const EngravingItem* item, const mpe::ArticulationType /*type*/, const RenderingContext& ctx,
      57              :                                           mpe::PlaybackEventList& result)
      58              : {
      59         1071 :     IF_ASSERT_FAILED(item->isChord()) {
      60            0 :         return;
      61              :     }
      62              : 
      63         1136 :     for (const auto& type : ctx.commonArticulations) {
      64           72 :         if (muse::contains(GRACE_NOTE_ARTICULATION_TYPES, type.first)) {
      65            7 :             renderChordWithGraceChords(toChord(item), type.first, ctx, result);
      66            7 :             return;
      67              :         }
      68              :     }
      69              : 
      70         1064 :     renderChord(toChord(item), ctx, result);
      71              : }
      72              : 
      73         1080 : void ChordArticulationsRenderer::renderChord(const Chord* chord, const RenderingContext& ctx, muse::mpe::PlaybackEventList& result)
      74              : {
      75         1080 :     if (renderChordArticulations(chord, ctx, result)) {
      76           52 :         return;
      77              :     }
      78              : 
      79         1028 :     const bool supportsMultibend = ctx.profile->contains(ArticulationType::Multibend);
      80              : 
      81         2066 :     for (const Note* note: chord->notes()) {
      82         1038 :         if (supportsMultibend && BendsRenderer::isMultibendPart(note)) {
      83            0 :             BendsRenderer::render(note, ctx, result);
      84              :         } else {
      85         1038 :             NoteRenderer::render(note, ctx, result);
      86              :         }
      87              :     }
      88              : }
      89              : 
      90            7 : void ChordArticulationsRenderer::renderChordWithGraceChords(const Chord* chord, const muse::mpe::ArticulationType type,
      91              :                                                             const RenderingContext& ctx,
      92              :                                                             muse::mpe::PlaybackEventList& result)
      93              : {
      94            7 :     const GraceChordCtx graceChordCtx = GraceChordCtx::buildCtx(chord, type, ctx);
      95              : 
      96            7 :     if (isGraceNotePlacedBeforePrincipalNote(type)) {
      97            9 :         for (const auto& pair : graceChordCtx.graceChordCtxList) {
      98            5 :             renderChord(pair.first, pair.second, result);
      99              :         }
     100            4 :         renderChord(chord, graceChordCtx.principalChordCtx, result);
     101              :     } else {
     102            3 :         renderChord(chord, graceChordCtx.principalChordCtx, result);
     103            7 :         for (const auto& pair : graceChordCtx.graceChordCtxList) {
     104            4 :             renderChord(pair.first, pair.second, result);
     105              :         }
     106              :     }
     107            7 : }
     108              : 
     109         1080 : bool ChordArticulationsRenderer::renderChordArticulations(const Chord* chord, const RenderingContext& ctx,
     110              :                                                           mpe::PlaybackEventList& result)
     111              : {
     112         1102 :     for (const auto& pair : ctx.commonArticulations) {
     113           74 :         const mpe::ArticulationType type = pair.first;
     114              : 
     115           74 :         if (OrnamentsRenderer::isAbleToRender(type)) {
     116           14 :             OrnamentsRenderer::render(chord, type, ctx, result);
     117           52 :             return true;
     118              :         }
     119              : 
     120           60 :         if (TremoloRenderer::isAbleToRender(type)) {
     121           28 :             TremoloRenderer::render(chord, type, ctx, result);
     122           28 :             return true;
     123              :         }
     124              : 
     125           32 :         if (ArpeggioRenderer::isAbleToRender(type)) {
     126           10 :             ArpeggioRenderer::render(chord, type, ctx, result);
     127           10 :             return true;
     128              :         }
     129              :     }
     130              : 
     131         1028 :     return false;
     132              : }
        

Generated by: LCOV version 2.0-1