LCOV - code coverage report
Current view: top level - src/engraving/dom - measurerepeat.cpp Coverage Total Hit
Test: filtered_coverage.info Lines: 67.6 % 68 46
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) 2021 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 "measurerepeat.h"
      24              : 
      25              : #include "translation.h"
      26              : 
      27              : #include "style/style.h"
      28              : 
      29              : #include "measure.h"
      30              : #include "staff.h"
      31              : 
      32              : #include "log.h"
      33              : 
      34              : using namespace mu;
      35              : using namespace mu::engraving;
      36              : 
      37              : namespace mu::engraving {
      38              : //---------------------------------------------------------
      39              : //   MeasureRepeat
      40              : //---------------------------------------------------------
      41              : 
      42          134 : MeasureRepeat::MeasureRepeat(DummyParentOr<Segment> parent)
      43          134 :     : Rest(ElementType::MEASURE_REPEAT, parent), m_numMeasures(0)
      44              : {
      45              :     // however many measures the group, the element itself is always exactly the duration of its containing measure
      46          134 :     setDurationType(DurationType::V_MEASURE);
      47          134 : }
      48              : 
      49          134 : void MeasureRepeat::setNumMeasures(int n)
      50              : {
      51          134 :     IF_ASSERT_FAILED(n <= MAX_NUM_MEASURES) {
      52            0 :         m_numMeasures = MAX_NUM_MEASURES;
      53            0 :         return;
      54              :     }
      55              : 
      56          134 :     m_numMeasures = n;
      57              : }
      58              : 
      59              : //---------------------------------------------------------
      60              : //   firstMeasureOfGroup
      61              : //---------------------------------------------------------
      62              : 
      63          206 : Measure* MeasureRepeat::firstMeasureOfGroup() const
      64              : {
      65          206 :     return measure()->firstOfMeasureRepeatGroup(staffIdx());
      66              : }
      67              : 
      68          118 : const Measure* MeasureRepeat::referringMeasure(const Measure* measure) const
      69              : {
      70          118 :     IF_ASSERT_FAILED(measure) {
      71            0 :         return nullptr;
      72              :     }
      73              : 
      74          118 :     const Measure* firstMeasure = firstMeasureOfGroup();
      75          118 :     if (!firstMeasure) {
      76            0 :         return nullptr;
      77              :     }
      78              : 
      79          118 :     const Measure* referringMeasure = firstMeasure->prevMeasure();
      80              : 
      81          118 :     int measuresBack = m_numMeasures - measure->measureRepeatCount(staffIdx());
      82              : 
      83          144 :     for (int i = 0; i < measuresBack && referringMeasure; ++i) {
      84           26 :         referringMeasure = referringMeasure->prevMeasure();
      85              :     }
      86              : 
      87          118 :     return referringMeasure;
      88              : }
      89              : 
      90              : //---------------------------------------------------------
      91              : //   numberRect
      92              : ///   returns the measure repeat number's bounding rectangle
      93              : //---------------------------------------------------------
      94              : 
      95         1282 : PointF MeasureRepeat::numberPosition(const RectF& numberBbox) const
      96              : {
      97         1282 :     double x = (symBbox(ldata()->symId).width() - numberBbox.width()) * .5;
      98              :     // -pos().y(): relative to topmost staff line
      99              :     // - 0.5 * r.height(): relative to the baseline of the number symbol
     100              :     // (rather than the center)
     101         1282 :     double staffTop = -pos().y();
     102              :     // Single line staff barlines extend above top of staff
     103         1282 :     if (staffType() && staffType()->lines() == 1) {
     104            0 :         staffTop -= 2.0 * spatium();
     105              :     }
     106         1282 :     double yNumberPos = absoluteFromSpatium(style().styleS(Sid::measureRepeatNumberPos) + m_numberOffset);
     107         1282 :     double y = std::min(staffTop, -symBbox(ldata()->symId).height() / 2) + yNumberPos - 0.5 * numberBbox.height();
     108              : 
     109         1282 :     return PointF(x, y);
     110              : }
     111              : 
     112         1282 : RectF MeasureRepeat::numberRect() const
     113              : {
     114         1282 :     RectF r = symBbox(ldata()->numberSym);
     115         1282 :     r.translate(numberPosition(r));
     116         1282 :     return r;
     117              : }
     118              : 
     119              : //---------------------------------------------------------
     120              : //   propertyDefault
     121              : //---------------------------------------------------------
     122              : 
     123         1066 : PropertyValue MeasureRepeat::propertyDefault(Pid propertyId) const
     124              : {
     125         1066 :     switch (propertyId) {
     126           82 :     case Pid::MEASURE_REPEAT_NUMBER_OFFSET:
     127           82 :         return 0.0_sp;
     128          984 :     default:
     129          984 :         return Rest::propertyDefault(propertyId);
     130              :     }
     131              : }
     132              : 
     133              : //---------------------------------------------------------
     134              : //   getProperty
     135              : //---------------------------------------------------------
     136              : 
     137         1066 : PropertyValue MeasureRepeat::getProperty(Pid propertyId) const
     138              : {
     139         1066 :     switch (propertyId) {
     140           82 :     case Pid::SUBTYPE:
     141           82 :         return numMeasures();
     142           82 :     case Pid::MEASURE_REPEAT_NUMBER_OFFSET:
     143           82 :         return m_numberOffset;
     144          902 :     default:
     145          902 :         return Rest::getProperty(propertyId);
     146              :     }
     147              : }
     148              : 
     149              : //---------------------------------------------------------
     150              : //   setProperty
     151              : //---------------------------------------------------------
     152              : 
     153            0 : bool MeasureRepeat::setProperty(Pid propertyId, const PropertyValue& v)
     154              : {
     155            0 :     switch (propertyId) {
     156            0 :     case Pid::SUBTYPE:
     157            0 :         setNumMeasures(v.toInt());
     158            0 :         break;
     159            0 :     case Pid::MEASURE_REPEAT_NUMBER_OFFSET:
     160            0 :         setNumberOffset(v.value<Spatium>());
     161            0 :         triggerLayout();
     162            0 :         break;
     163            0 :     default:
     164            0 :         return Rest::setProperty(propertyId, v);
     165              :     }
     166            0 :     return true;
     167              : }
     168              : 
     169              : //---------------------------------------------------------
     170              : //   ticks
     171              : //---------------------------------------------------------
     172              : 
     173          265 : Fraction MeasureRepeat::ticks() const
     174              : {
     175          265 :     if (measure()) {
     176          265 :         return measure()->stretchedLen(staff());
     177              :     }
     178            0 :     return Fraction(0, 1);
     179              : }
     180              : 
     181              : //---------------------------------------------------------
     182              : //   accessibleInfo
     183              : //---------------------------------------------------------
     184              : 
     185            0 : String MeasureRepeat::accessibleInfo() const
     186              : {
     187            0 :     return muse::mtrc("engraving", "%1; Duration: %Ln measure(s)", nullptr, numMeasures()).arg(EngravingItem::accessibleInfo());
     188              : }
     189              : 
     190              : //---------------------------------------------------------
     191              : //   subtypeUserName
     192              : //---------------------------------------------------------
     193              : 
     194            0 : muse::TranslatableString MeasureRepeat::subtypeUserName() const
     195              : {
     196            0 :     return muse::TranslatableString("engraving", "%Ln measure(s)", nullptr, numMeasures());
     197              : }
     198              : }
        

Generated by: LCOV version 2.0-1