LCOV - code coverage report
Current view: top level - src/engraving/rw/read400 - readcontext.cpp Coverage Total Hit
Test: filtered_coverage.info Lines: 76.9 % 324 249
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 "readcontext.h"
      24              : 
      25              : #include "global/containers.h"
      26              : 
      27              : #include "engraving/dom/beam.h"
      28              : #include "engraving/dom/linkedobjects.h"
      29              : #include "engraving/dom/measure.h"
      30              : #include "engraving/dom/score.h"
      31              : #include "engraving/dom/staff.h"
      32              : #include "engraving/dom/tuplet.h"
      33              : #include "engraving/editing/transaction/undostack.h"
      34              : #include "engraving/types/types.h"
      35              : 
      36              : #include "connectorinforeader.h"
      37              : 
      38              : #include "log.h"
      39              : 
      40              : using namespace mu;
      41              : using namespace mu::engraving;
      42              : using namespace mu::engraving::read400;
      43              : 
      44            0 : ReadContext::ReadContext(const muse::modularity::ContextPtr& iocCtx)
      45            0 :     : muse::Contextable(iocCtx)
      46              : {
      47            0 : }
      48              : 
      49        12968 : ReadContext::ReadContext(Score* score)
      50        12968 :     : muse::Contextable(score ? score->iocContext() : muse::modularity::globalCtx()), m_score(score)
      51              : {
      52        12968 : }
      53              : 
      54        12968 : ReadContext::~ReadContext()
      55              : {
      56        12968 :     if (!_connectors.empty() || !_pendingConnectors.empty()) {
      57            0 :         LOGD("XmlReader::~XmlReader: there are unpaired connectors left");
      58            0 :         for (auto& c : _connectors) {
      59            0 :             EngravingItem* conn = c->releaseConnector();
      60            0 :             if (conn && !conn->isTuplet()) { // tuplets are added to score even when not finished
      61            0 :                 delete conn;
      62              :             }
      63              :         }
      64            0 :         for (auto& c : _pendingConnectors) {
      65            0 :             delete c->releaseConnector();
      66              :         }
      67              :     }
      68        12968 : }
      69              : 
      70           32 : void ReadContext::setScore(Score* score)
      71              : {
      72           32 :     m_score = score;
      73           32 : }
      74              : 
      75        10463 : Score* ReadContext::score() const
      76              : {
      77        10463 :     return m_score;
      78              : }
      79              : 
      80          785 : const MStyle& ReadContext::style() const
      81              : {
      82          785 :     return score()->style();
      83              : }
      84              : 
      85          156 : String ReadContext::mscoreVersion() const
      86              : {
      87          156 :     return m_score->mscoreVersion();
      88              : }
      89              : 
      90         4248 : int ReadContext::mscVersion() const
      91              : {
      92         4248 :     return m_score->mscVersion();
      93              : }
      94              : 
      95           26 : int ReadContext::fileDivision() const
      96              : {
      97           26 :     return m_score->fileDivision();
      98              : }
      99              : 
     100          127 : int ReadContext::fileDivision(int t) const
     101              : {
     102          127 :     return m_score->fileDivision(t);
     103              : }
     104              : 
     105         2660 : double ReadContext::spatium() const
     106              : {
     107         2660 :     return m_score->style().spatium();
     108              : }
     109              : 
     110            0 : void ReadContext::setSpatium(double v)
     111              : {
     112            0 :     m_score->style().set(Sid::spatium, v);
     113            0 : }
     114              : 
     115        10388 : DummyParent* ReadContext::dummy() const
     116              : {
     117        10388 :     return m_score->dummy();
     118              : }
     119              : 
     120         6213 : Staff* ReadContext::staff(staff_idx_t n)
     121              : {
     122         6213 :     return m_score->staff(n);
     123              : }
     124              : 
     125           93 : void ReadContext::appendStaff(Staff* staff)
     126              : {
     127           93 :     m_score->appendStaff(staff);
     128           93 : }
     129              : 
     130           22 : void ReadContext::addSpanner(Spanner* s)
     131              : {
     132           22 :     m_score->addSpanner(s);
     133           22 : }
     134              : 
     135          136 : bool ReadContext::undoStackActive() const
     136              : {
     137          136 :     return m_score->undoStack()->hasActiveTransaction();
     138              : }
     139              : 
     140         5112 : bool ReadContext::isSameScore(const EngravingObject* obj) const
     141              : {
     142         5112 :     return obj->score() == m_score;
     143              : }
     144              : 
     145           73 : rw::ReadLinks ReadContext::readLinks() const
     146              : {
     147           73 :     rw::ReadLinks l;
     148           73 :     l.linksIndexer = m_linksIndexer;
     149           73 :     l.staffLinkedElements = m_staffLinkedElements;
     150           73 :     return l;
     151            0 : }
     152              : 
     153            0 : void ReadContext::initLinks(const rw::ReadLinks& l)
     154              : {
     155            0 :     m_linksIndexer = l.linksIndexer;
     156            0 :     m_staffLinkedElements = l.staffLinkedElements;
     157            0 : }
     158              : 
     159          546 : void ReadContext::addLink(Staff* staff, LinkedObjects* link, const Location& location)
     160              : {
     161          546 :     int staffIndex = static_cast<int>(staff->idx());
     162          546 :     const bool isMasterScore = staff->score()->isMaster();
     163          546 :     if (!isMasterScore) {
     164            3 :         staffIndex *= -1;
     165              :     }
     166              : 
     167          546 :     std::vector<std::pair<LinkedObjects*, Location> >& staffLinks = m_staffLinkedElements[staffIndex];
     168          546 :     if (!isMasterScore) {
     169            3 :         if (!staffLinks.empty()
     170            3 :             && (link->mainElement()->score() != staffLinks.front().first->mainElement()->score())
     171              :             ) {
     172            3 :             staffLinks.clear();
     173              :         }
     174              :     }
     175              : 
     176          546 :     m_linksIndexer.assignLocalIndex(location);
     177          546 :     staffLinks.push_back(std::make_pair(link, location));
     178          546 : }
     179              : 
     180          547 : LinkedObjects* ReadContext::getLink(bool isMasterScore, const Location& location, int localIndexDiff)
     181              : {
     182          547 :     int staffIndex = location.staff();
     183          547 :     if (!isMasterScore) {
     184           10 :         staffIndex *= -1;
     185              :     }
     186              : 
     187          547 :     const int localIndex = m_linksIndexer.assignLocalIndex(location) + localIndexDiff;
     188          547 :     std::vector<std::pair<LinkedObjects*, Location> >& staffLinks = m_staffLinkedElements[staffIndex];
     189              : 
     190          547 :     if (!staffLinks.empty() && staffLinks.back().second == location) {
     191              :         // This element potentially affects local index for "main"
     192              :         // elements that may go afterwards at the same tick, so
     193              :         // append it to staffLinks as well.
     194           42 :         staffLinks.push_back(staffLinks.back()); // nothing should reference exactly this local index, so it shouldn't matter what to append
     195              :     }
     196              : 
     197        12061 :     for (size_t i = 0; i < staffLinks.size(); ++i) {
     198        12061 :         if (staffLinks[i].second == location) {
     199          547 :             if (localIndex == 0) {
     200          239 :                 return staffLinks[i].first;
     201              :             }
     202              : 
     203          308 :             i += localIndex;
     204          308 :             if (i >= staffLinks.size()) {
     205            0 :                 return nullptr;
     206              :             }
     207              : 
     208          308 :             if (staffLinks[i].second == location) {
     209          308 :                 return staffLinks[i].first;
     210              :             }
     211              : 
     212            0 :             return nullptr;
     213              :         }
     214              :     }
     215              : 
     216            0 :     return nullptr;
     217              : }
     218              : 
     219         3143 : Fraction ReadContext::rtick() const
     220              : {
     221         3143 :     return _curMeasure ? _tick - _curMeasure->tick() : _tick;
     222              : }
     223              : 
     224        12438 : void ReadContext::setTick(const Fraction& f)
     225              : {
     226        12438 :     _tick = f.reduced();
     227        12438 :     _intTick = _tick.ticks();
     228        12438 : }
     229              : 
     230        13593 : void ReadContext::incTick(const Fraction& f)
     231              : {
     232        13593 :     _tick += f;
     233        13593 :     _tick.reduce();
     234        13593 :     _intTick += f.ticks();
     235        13593 : }
     236              : 
     237         1174 : Location ReadContext::location(bool forceAbsFrac) const
     238              : {
     239         1174 :     Location l = Location::absolute();
     240         1174 :     fillLocation(l, forceAbsFrac);
     241         1174 :     return l;
     242              : }
     243              : 
     244              : //---------------------------------------------------------
     245              : //   fillLocation
     246              : //    fills location fields which have default values with
     247              : //    values relevant for the current reader's position.
     248              : //    When in paste mode (or forceAbsFrac is true) absolute
     249              : //    fraction values are used and measure number is set to
     250              : //    zero.
     251              : //---------------------------------------------------------
     252              : 
     253         4236 : void ReadContext::fillLocation(Location& l, bool forceAbsFrac) const
     254              : {
     255         4236 :     constexpr Location defaults = Location::absolute();
     256         4236 :     const bool absFrac = (pasteMode() || forceAbsFrac);
     257         4236 :     if (l.track() == defaults.track()) {
     258         1174 :         l.setTrack(static_cast<int>(track()));
     259              :     }
     260         4236 :     if (l.frac() == defaults.frac()) {
     261         4236 :         l.setFrac(absFrac ? tick() : rtick());
     262              :     }
     263         4236 :     if (l.measure() == defaults.measure()) {
     264         4236 :         l.setMeasure(absFrac ? 0 : currentMeasureIndex());
     265              :     }
     266         4236 : }
     267              : 
     268              : //---------------------------------------------------------
     269              : //   setLocation
     270              : //    sets a new reading location, taking into account its
     271              : //    type (absolute or relative).
     272              : //---------------------------------------------------------
     273              : 
     274          162 : void ReadContext::setLocation(const Location& l)
     275              : {
     276          162 :     if (l.isRelative()) {
     277           81 :         Location newLoc = l;
     278           81 :         newLoc.toAbsolute(location());
     279           81 :         int intTicks = l.frac().ticks();
     280           81 :         if (_tick == Fraction::fromTicks(_intTick + intTicks)) {
     281            0 :             _intTick += intTicks;
     282            0 :             setTrack(newLoc.track() - _trackOffset);
     283            0 :             return;
     284              :         }
     285           81 :         setLocation(newLoc); // recursion
     286           81 :         return;
     287              :     }
     288           81 :     setTrack(l.track() - _trackOffset);
     289           81 :     setTick(l.frac() - _tickOffset);
     290           81 :     if (!pasteMode()) {
     291           81 :         assert(l.measure() == currentMeasureIndex());
     292           81 :         incTick(currentMeasure()->tick());
     293              :     }
     294              : }
     295              : 
     296           87 : size_t ReadContext::getStaffBarLineSpan(const staff_idx_t staffIdx) const
     297              : {
     298           87 :     return muse::value(m_staffBarLineSpanValues, staffIdx, 0);
     299              : }
     300              : 
     301            9 : void ReadContext::setStaffBarLineSpan(const staff_idx_t staffIdx, const size_t barLineSpan)
     302              : {
     303            9 :     const auto [it, didInsert] = m_staffBarLineSpanValues.emplace(staffIdx, barLineSpan);
     304            9 :     DO_ASSERT(didInsert)
     305            9 : }
     306              : 
     307           55 : std::optional<size_t> ReadContext::getBarLineSpan(const BarLine* barLine)
     308              : {
     309           55 :     if (!muse::contains(m_barLineSpanValues, barLine)) {
     310            0 :         return std::nullopt;
     311              :     }
     312              : 
     313           55 :     return muse::value(m_barLineSpanValues, barLine);
     314              : }
     315              : 
     316           64 : void ReadContext::setBarLineSpan(const BarLine* barLine, const size_t barLineSpan)
     317              : {
     318           64 :     const auto [it, didInsert] = m_barLineSpanValues.emplace(barLine, barLineSpan);
     319           64 :     DO_ASSERT(didInsert)
     320           64 : }
     321              : 
     322           22 : void ReadContext::addBeam(int beamId, Beam* s)
     323              : {
     324           22 :     _beams.insert_or_assign(beamId, s);
     325           22 : }
     326              : 
     327           27 : void ReadContext::addTuplet(int tupletId, Tuplet* s)
     328              : {
     329           27 :     _tuplets.insert_or_assign(tupletId, s);
     330           27 : }
     331              : 
     332          887 : void ReadContext::checkTuplets()
     333              : {
     334          914 :     for (auto& p : tuplets()) {
     335           27 :         Tuplet* tuplet = p.second;
     336           27 :         if (tuplet->elements().empty()) {
     337              :             // this should not happen and is a sign of input file corruption
     338            0 :             LOGD("Measure:read(): empty tuplet id %d (%p), input file corrupted?", p.first, tuplet);
     339            0 :             delete tuplet;
     340              :         } else {
     341              :             //sort tuplet elements. Needed for nested tuplets #22537
     342           27 :             tuplet->sortElements();
     343           27 :             tuplet->sanitizeTuplet();
     344              :         }
     345              :     }
     346              :     // This requires a separate pass in case of nested tuplets that required sanitizing
     347          914 :     for (auto& p : tuplets()) {
     348           27 :         Tuplet* tuplet = p.second;
     349           27 :         tuplet->addMissingElements();
     350              :     }
     351          887 : }
     352              : 
     353           22 : void ReadContext::addSpanner(int id, Spanner* s)
     354              : {
     355           22 :     _spanner.push_back(std::pair<int, Spanner*>(id, s));
     356           22 : }
     357              : 
     358            0 : void ReadContext::removeSpanner(const Spanner* s)
     359              : {
     360            0 :     for (auto i : _spanner) {
     361            0 :         if (i.second == s) {
     362            0 :             muse::remove(_spanner, i);
     363            0 :             return;
     364              :         }
     365              :     }
     366              : }
     367              : 
     368           38 : Spanner* ReadContext::findSpanner(int id)
     369              : {
     370          284 :     for (auto i : _spanner) {
     371          284 :         if (i.first == id) {
     372           38 :             return i.second;
     373              :         }
     374              :     }
     375            0 :     return nullptr;
     376              : }
     377              : 
     378            6 : int ReadContext::spannerId(const Spanner* s)
     379              : {
     380           12 :     for (auto i : _spanner) {
     381           12 :         if (i.second == s) {
     382            6 :             return i.first;
     383              :         }
     384              :     }
     385            0 :     LOGD() << "spannerId not found";
     386            0 :     return -1;
     387              : }
     388              : 
     389            6 : const SpannerValues* ReadContext::spannerValues(int id) const
     390              : {
     391            6 :     for (const SpannerValues& v : _spannerValues) {
     392            0 :         if (v.spannerId == id) {
     393            0 :             return &v;
     394              :         }
     395              :     }
     396            6 :     return 0;
     397              : }
     398              : 
     399         1531 : void ReadContext::removeConnector(const ConnectorInfoReader* c)
     400              : {
     401         1540 :     while (c->prev()) {
     402            9 :         c = c->prev();
     403              :     }
     404         4593 :     while (c) {
     405         3062 :         ConnectorInfoReader* next = c->next();
     406         3936 :         for (auto it = _connectors.begin(); it != _connectors.end(); ++it) {
     407         3936 :             if (it->get() == c) {
     408         3062 :                 _connectors.erase(it);
     409         3062 :                 break;
     410              :             }
     411              :         }
     412         3062 :         c = next;
     413              :     }
     414         1531 : }
     415              : 
     416         3062 : void ReadContext::addConnectorInfoLater(std::shared_ptr<read400::ConnectorInfoReader> c)
     417              : {
     418         3062 :     _pendingConnectors.push_back(c);
     419         3062 : }
     420              : 
     421         5112 : void ReadContext::checkConnectors()
     422              : {
     423         8174 :     for (std::shared_ptr<ConnectorInfoReader>& c : _pendingConnectors) {
     424         3062 :         addConnectorInfo(c);
     425              :     }
     426         5112 :     _pendingConnectors.clear();
     427         5112 : }
     428              : 
     429         3062 : void ReadContext::addConnectorInfo(std::shared_ptr<ConnectorInfoReader> c)
     430              : {
     431         3062 :     _connectors.push_back(std::move(c));
     432         3062 :     ConnectorInfoReader* c1 = _connectors.back().get();
     433         3062 :     c1->update();
     434         5462 :     for (std::shared_ptr<ConnectorInfoReader>& c2 : _connectors) {
     435         3929 :         if (c2->connect(c1)) {
     436         1529 :             if (c2->finished()) {
     437         1529 :                 c2->addToScore(pasteMode());
     438         1529 :                 removeConnector(c2.get());
     439              :             }
     440         1529 :             break;
     441              :         }
     442              :     }
     443         3062 : }
     444              : 
     445           14 : static bool distanceSort(const std::pair<int, std::pair<ConnectorInfoReader*, ConnectorInfoReader*> >& p1,
     446              :                          const std::pair<int, std::pair<ConnectorInfoReader*, ConnectorInfoReader*> >& p2)
     447              : {
     448           14 :     return p1.first < p2.first;
     449              : }
     450              : 
     451              : //---------------------------------------------------------
     452              : //   reconnectBrokenConnectors
     453              : //---------------------------------------------------------
     454              : 
     455          503 : void ReadContext::reconnectBrokenConnectors()
     456              : {
     457          503 :     if (_connectors.empty()) {
     458          502 :         return;
     459              :     }
     460            1 :     LOGD("Reconnecting broken connectors (%d nodes)", int(_connectors.size()));
     461            1 :     std::vector<std::pair<int, std::pair<ConnectorInfoReader*, ConnectorInfoReader*> > > brokenPairs;
     462            4 :     for (size_t i = 1; i < _connectors.size(); ++i) {
     463            9 :         for (size_t j = 0; j < i; ++j) {
     464            6 :             ConnectorInfoReader* c1 = _connectors[i].get();
     465            6 :             ConnectorInfoReader* c2 = _connectors[j].get();
     466            6 :             int d = c1->connectionDistance(*c2);
     467            6 :             if (d >= 0) {
     468            4 :                 brokenPairs.push_back(std::make_pair(d, std::make_pair(c1, c2)));
     469              :             } else {
     470            2 :                 brokenPairs.push_back(std::make_pair(-d, std::make_pair(c2, c1)));
     471              :             }
     472              :         }
     473              :     }
     474            1 :     std::sort(brokenPairs.begin(), brokenPairs.end(), distanceSort);
     475            7 :     for (auto& distPair : brokenPairs) {
     476            6 :         if (distPair.first == INT_MAX) {
     477            4 :             continue;
     478              :         }
     479            2 :         auto& pair = distPair.second;
     480            2 :         if (pair.first->next() || pair.second->prev()) {
     481            0 :             continue;
     482              :         }
     483            2 :         pair.first->forceConnect(pair.second);
     484              :     }
     485            1 :     std::set<ConnectorInfoReader*> reconnected;
     486            5 :     for (auto& conn : _connectors) {
     487            4 :         ConnectorInfoReader* c = conn.get();
     488            4 :         if (c->finished()) {
     489            4 :             reconnected.insert(static_cast<ConnectorInfoReader*>(c->start()));
     490              :         }
     491              :     }
     492            3 :     for (ConnectorInfoReader* cptr : reconnected) {
     493            2 :         cptr->addToScore(pasteMode());
     494            2 :         removeConnector(cptr);
     495              :     }
     496            1 :     LOGD() << "reconnected broken connectors: " << reconnected.size();
     497            1 : }
     498              : 
     499           73 : void ReadContext::clearOrphanedConnectors()
     500              : {
     501           73 :     if (_connectors.empty() && _pendingConnectors.empty()) {
     502           73 :         return;
     503              :     }
     504              : 
     505            0 :     LOGD("XmlReader::~XmlReader: there are unpaired connectors left");
     506              : 
     507            0 :     std::set<LinkedObjects*> deletedLinks;
     508              : 
     509            0 :     auto deleteConnectors = [&deletedLinks](std::shared_ptr<ConnectorInfoReader> c) {
     510            0 :         EngravingItem* conn = c ? c->releaseConnector() : nullptr;
     511            0 :         if (!conn) {
     512            0 :             return;
     513              :         }
     514              : 
     515            0 :         LinkedObjects* links = conn->links();
     516            0 :         bool linksWillBeDeleted = links && links->size() == 1;
     517              : 
     518            0 :         if (!conn->isTuplet()) {     // tuplets are added to score even when not finished
     519            0 :             if (linksWillBeDeleted) {
     520            0 :                 deletedLinks.insert(links);
     521              :             }
     522              : 
     523            0 :             delete conn;
     524              :         }
     525            0 :     };
     526              : 
     527            0 :     if (!_connectors.empty()) {
     528            0 :         for (auto& c : _connectors) {
     529            0 :             deleteConnectors(c);
     530              :         }
     531            0 :         _connectors.clear();
     532              :     }
     533              : 
     534            0 :     if (!_pendingConnectors.empty()) {
     535            0 :         for (auto& c : _pendingConnectors) {
     536            0 :             deleteConnectors(c);
     537              :         }
     538            0 :         _pendingConnectors.clear();
     539              :     }
     540              : 
     541            0 :     for (auto& it : m_staffLinkedElements) {
     542            0 :         std::vector<std::pair<LinkedObjects*, Location> >& vector = it.second;
     543            0 :         muse::remove_if(vector, [&deletedLinks](std::pair<LinkedObjects*, Location>& pair){
     544            0 :             return deletedLinks.count(pair.first);
     545              :         });
     546              :     }
     547            0 : }
     548              : 
     549              : //---------------------------------------------------------
     550              : //   addUserTextStyle
     551              : //    return false if mapping is not possible
     552              : //      (too many user text styles)
     553              : //---------------------------------------------------------
     554              : 
     555           30 : TextStyleType ReadContext::addUserTextStyle(const String& name)
     556              : {
     557           30 :     LOGD() << name;
     558           30 :     TextStyleType id = TextStyleType::TEXT_TYPES;
     559           30 :     if (userTextStyles.size() == 0) {
     560            5 :         id = TextStyleType::USER1;
     561           25 :     } else if (userTextStyles.size() == 1) {
     562            5 :         id = TextStyleType::USER2;
     563           20 :     } else if (userTextStyles.size() == 2) {
     564            4 :         id = TextStyleType::USER3;
     565           16 :     } else if (userTextStyles.size() == 3) {
     566            4 :         id = TextStyleType::USER4;
     567           12 :     } else if (userTextStyles.size() == 4) {
     568            4 :         id = TextStyleType::USER5;
     569            8 :     } else if (userTextStyles.size() == 5) {
     570            4 :         id = TextStyleType::USER6;
     571            4 :     } else if (userTextStyles.size() == 6) {
     572            4 :         id = TextStyleType::USER7;
     573            0 :     } else if (userTextStyles.size() == 7) {
     574            0 :         id = TextStyleType::USER8;
     575            0 :     } else if (userTextStyles.size() == 8) {
     576            0 :         id = TextStyleType::USER9;
     577            0 :     } else if (userTextStyles.size() == 9) {
     578            0 :         id = TextStyleType::USER10;
     579            0 :     } else if (userTextStyles.size() == 10) {
     580            0 :         id = TextStyleType::USER11;
     581            0 :     } else if (userTextStyles.size() == 11) {
     582            0 :         id = TextStyleType::USER12;
     583              :     } else {
     584            0 :         LOGD() << "too many user defined textstyles";
     585              :     }
     586           30 :     if (id != TextStyleType::TEXT_TYPES) {
     587           30 :         userTextStyles.push_back({ name, id });
     588              :     }
     589           30 :     return id;
     590           30 : }
     591              : 
     592           73 : TextStyleType ReadContext::lookupUserTextStyle(const String& name) const
     593              : {
     594          186 :     for (const auto& i : userTextStyles) {
     595          141 :         if (i.name == name) {
     596           28 :             return i.ss;
     597              :         }
     598              :     }
     599           45 :     return TextStyleType::TEXT_TYPES;         // not found
     600              : }
     601              : 
     602        13444 : void ReadContext::addPartAudioSettingCompat(PartAudioSettingsCompat partAudioSetting)
     603              : {
     604        13444 :     if (_settingsCompat.audioSettings.count(partAudioSetting.instrumentId.partId) == 0) {
     605        13267 :         _settingsCompat.audioSettings.insert({ partAudioSetting.instrumentId.partId, partAudioSetting });
     606              :     }
     607        13444 : }
     608              : 
     609          177 : TimeSigMap* ReadContext::compatTimeSigMap()
     610              : {
     611          177 :     return &m_compatTimeSigMap;
     612              : }
        

Generated by: LCOV version 2.0-1