LCOV - code coverage report
Current view: top level - src/engraving/dom - textline.cpp Coverage Total Hit
Test: filtered_coverage.info Lines: 84.1 % 107 90
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              : #include "textline.h"
      23              : 
      24              : #include "score.h"
      25              : #include "system.h"
      26              : #include "text.h"
      27              : #include "../editing/editproperty.h"
      28              : 
      29              : using namespace mu;
      30              : 
      31              : namespace mu::engraving {
      32              : //---------------------------------------------------------
      33              : //   textLineSegmentStyle
      34              : //---------------------------------------------------------
      35              : 
      36              : static const ElementStyle textLineSegmentStyle {
      37              :     { Sid::textLineMinDistance,   Pid::MIN_DISTANCE },
      38              : };
      39              : 
      40              : //---------------------------------------------------------
      41              : //   systemTextLineSegmentStyle
      42              : //---------------------------------------------------------
      43              : 
      44              : static const ElementStyle systemTextLineSegmentStyle {
      45              :     { Sid::systemTextLineMinDistance,   Pid::MIN_DISTANCE },
      46              : };
      47              : 
      48              : //---------------------------------------------------------
      49              : //   textLineStyle
      50              : //---------------------------------------------------------
      51              : 
      52              : static const ElementStyle textLineStyle {
      53              :     { Sid::textLineFontFace,                   Pid::BEGIN_FONT_FACE },
      54              :     { Sid::textLineFontFace,                   Pid::CONTINUE_FONT_FACE },
      55              :     { Sid::textLineFontFace,                   Pid::END_FONT_FACE },
      56              :     { Sid::textLineFontSize,                   Pid::BEGIN_FONT_SIZE },
      57              :     { Sid::textLineFontSize,                   Pid::CONTINUE_FONT_SIZE },
      58              :     { Sid::textLineFontSize,                   Pid::END_FONT_SIZE },
      59              :     { Sid::textLineFontStyle,                  Pid::BEGIN_FONT_STYLE },
      60              :     { Sid::textLineFontStyle,                  Pid::CONTINUE_FONT_STYLE },
      61              :     { Sid::textLineFontStyle,                  Pid::END_FONT_STYLE },
      62              :     { Sid::textLineTextAlign,                  Pid::BEGIN_TEXT_ALIGN },
      63              :     { Sid::textLineTextAlign,                  Pid::CONTINUE_TEXT_ALIGN },
      64              :     { Sid::textLineTextAlign,                  Pid::END_TEXT_ALIGN },
      65              :     { Sid::textLinePosition,                   Pid::BEGIN_TEXT_POSITION },
      66              :     { Sid::textLinePosition,                   Pid::CONTINUE_TEXT_POSITION },
      67              :     { Sid::textLinePosition,                   Pid::END_TEXT_POSITION },
      68              :     { Sid::textLineHookHeight,                 Pid::BEGIN_HOOK_HEIGHT },
      69              :     { Sid::textLineHookHeight,                 Pid::END_HOOK_HEIGHT },
      70              :     { Sid::textLineLineWidth,                  Pid::LINE_WIDTH },
      71              :     { Sid::textLineDashLineLen,                Pid::DASH_LINE_LEN },
      72              :     { Sid::textLineDashGapLen,                 Pid::DASH_GAP_LEN },
      73              :     { Sid::textLinePlacement,                  Pid::PLACEMENT },
      74              :     { Sid::textLineLineStyle,                  Pid::LINE_STYLE },
      75              :     { Sid::textLineFontSpatiumDependent,       Pid::TEXT_SIZE_SPATIUM_DEPENDENT },
      76              :     { Sid::textLineEndLineArrowHeight,         Pid::END_LINE_ARROW_HEIGHT },
      77              :     { Sid::textLineEndLineArrowWidth,          Pid::END_LINE_ARROW_WIDTH },
      78              :     { Sid::textLineBeginLineArrowHeight,       Pid::BEGIN_LINE_ARROW_HEIGHT },
      79              :     { Sid::textLineBeginLineArrowWidth,        Pid::BEGIN_LINE_ARROW_WIDTH },
      80              :     { Sid::textLineEndFilledArrowHeight,       Pid::END_FILLED_ARROW_HEIGHT },
      81              :     { Sid::textLineEndFilledArrowWidth,        Pid::END_FILLED_ARROW_WIDTH },
      82              :     { Sid::textLineBeginFilledArrowHeight,     Pid::BEGIN_FILLED_ARROW_HEIGHT },
      83              :     { Sid::textLineBeginFilledArrowWidth,      Pid::BEGIN_FILLED_ARROW_WIDTH },
      84              :     { Sid::textLineMusicalSymbolSize,          Pid::BEGIN_TEXT_MUSIC_SYMBOLS_SIZE },
      85              :     { Sid::textLineMusicalSymbolSize,          Pid::CONTINUE_TEXT_MUSIC_SYMBOLS_SIZE },
      86              :     { Sid::textLineMusicalSymbolSize,          Pid::END_TEXT_MUSIC_SYMBOLS_SIZE },
      87              :     { Sid::dummyMusicalSymbolsScale,           Pid::BEGIN_TEXT_MUSICAL_SYMBOLS_SCALE },
      88              :     { Sid::dummyMusicalSymbolsScale,           Pid::CONTINUE_TEXT_MUSICAL_SYMBOLS_SCALE },
      89              :     { Sid::dummyMusicalSymbolsScale,           Pid::END_TEXT_MUSICAL_SYMBOLS_SCALE },
      90              : };
      91              : 
      92              : //---------------------------------------------------------
      93              : //   systemTextLineStyle
      94              : //---------------------------------------------------------
      95              : 
      96              : static const ElementStyle systemTextLineStyle {
      97              :     { Sid::systemTextLineFontFace,             Pid::BEGIN_FONT_FACE },
      98              :     { Sid::systemTextLineFontFace,             Pid::CONTINUE_FONT_FACE },
      99              :     { Sid::systemTextLineFontFace,             Pid::END_FONT_FACE },
     100              :     { Sid::systemTextLineFontSize,             Pid::BEGIN_FONT_SIZE },
     101              :     { Sid::systemTextLineFontSize,             Pid::CONTINUE_FONT_SIZE },
     102              :     { Sid::systemTextLineFontSize,             Pid::END_FONT_SIZE },
     103              :     { Sid::systemTextLineFontStyle,            Pid::BEGIN_FONT_STYLE },
     104              :     { Sid::systemTextLineFontStyle,            Pid::CONTINUE_FONT_STYLE },
     105              :     { Sid::systemTextLineFontStyle,            Pid::END_FONT_STYLE },
     106              :     { Sid::systemTextLineTextAlign,            Pid::BEGIN_TEXT_ALIGN },
     107              :     { Sid::systemTextLineTextAlign,            Pid::CONTINUE_TEXT_ALIGN },
     108              :     { Sid::systemTextLineTextAlign,            Pid::END_TEXT_ALIGN },
     109              :     { Sid::systemTextLineHookHeight,           Pid::BEGIN_HOOK_HEIGHT },
     110              :     { Sid::systemTextLineHookHeight,           Pid::END_HOOK_HEIGHT },
     111              :     { Sid::systemTextLineLineWidth,            Pid::LINE_WIDTH },
     112              :     { Sid::systemTextLineDashLineLen,          Pid::DASH_LINE_LEN },
     113              :     { Sid::systemTextLineDashGapLen,           Pid::DASH_GAP_LEN },
     114              :     { Sid::systemTextLinePlacement,            Pid::PLACEMENT },
     115              :     { Sid::systemTextLineLineStyle,            Pid::LINE_STYLE },
     116              :     { Sid::systemTextLineMusicalSymbolSize,    Pid::BEGIN_TEXT_MUSIC_SYMBOLS_SIZE },
     117              :     { Sid::systemTextLineMusicalSymbolSize,    Pid::CONTINUE_TEXT_MUSIC_SYMBOLS_SIZE },
     118              :     { Sid::systemTextLineMusicalSymbolSize,    Pid::END_TEXT_MUSIC_SYMBOLS_SIZE },
     119              :     { Sid::dummyMusicalSymbolsScale,           Pid::BEGIN_TEXT_MUSICAL_SYMBOLS_SCALE },
     120              :     { Sid::dummyMusicalSymbolsScale,           Pid::CONTINUE_TEXT_MUSICAL_SYMBOLS_SCALE },
     121              :     { Sid::dummyMusicalSymbolsScale,           Pid::END_TEXT_MUSICAL_SYMBOLS_SCALE },
     122              :     { Sid::systemTextLineFontSpatiumDependent, Pid::TEXT_SIZE_SPATIUM_DEPENDENT },
     123              : };
     124              : 
     125              : //---------------------------------------------------------
     126              : //   TextLineSegment
     127              : //---------------------------------------------------------
     128              : 
     129           34 : TextLineSegment::TextLineSegment(TextLine* sp, bool system)
     130           34 :     : TextLineBaseSegment(ElementType::TEXTLINE_SEGMENT, sp, ElementFlag::MOVABLE | ElementFlag::ON_STAFF)
     131              : {
     132           34 :     setSystemFlag(system);
     133           34 :     initStyle();
     134              : 
     135           34 :     m_text->setTextStyleType(propertyDefault(Pid::TEXT_STYLE).value<TextStyleType>());
     136           34 :     m_endText->setTextStyleType(propertyDefault(Pid::TEXT_STYLE).value<TextStyleType>());
     137           34 : }
     138              : 
     139              : //---------------------------------------------------------
     140              : //   propertyDelegate
     141              : //---------------------------------------------------------
     142              : 
     143          322 : EngravingObject* TextLineSegment::propertyDelegate(Pid pid) const
     144              : {
     145          322 :     if (pid == Pid::SYSTEM_FLAG) {
     146            0 :         return static_cast<TextLine*>(spanner());
     147              :     }
     148          322 :     return TextLineBaseSegment::propertyDelegate(pid);
     149              : }
     150              : 
     151              : //---------------------------------------------------------
     152              : //   TextLine
     153              : //---------------------------------------------------------
     154              : 
     155          113 : TextLine::TextLine(DummyParentOr<EngravingItem> parent, bool system)
     156          113 :     : TextLineBase(ElementType::TEXTLINE, parent)
     157              : {
     158          113 :     setSystemFlag(system);
     159              : 
     160          113 :     initStyle();
     161              : 
     162          113 :     setBeginText(u"");
     163          113 :     setContinueText(u"");
     164          113 :     setEndText(u"");
     165          113 :     setBeginTextOffset(PointF(0, 0));
     166          113 :     setContinueTextOffset(PointF(0, 0));
     167          113 :     setEndTextOffset(PointF(0, 0));
     168          113 :     setLineVisible(true);
     169              : 
     170          113 :     setBeginHookType(HookType::NONE);
     171          113 :     setEndHookType(HookType::NONE);
     172          113 :     setBeginHookHeight(1.5_sp);
     173          113 :     setEndHookHeight(1.5_sp);
     174          113 :     setGapBetweenTextAndLine(0.5_sp);
     175              : 
     176          113 :     setBeginFilledArrowHeight(1.0_sp);
     177          113 :     setBeginFilledArrowWidth(0.85_sp);
     178          113 :     setEndFilledArrowHeight(1.0_sp);
     179          113 :     setEndFilledArrowWidth(0.85_sp);
     180              : 
     181          113 :     setBeginLineArrowHeight(1.0_sp);
     182          113 :     setBeginLineArrowWidth(0.5_sp);
     183          113 :     setEndLineArrowHeight(1.0_sp);
     184          113 :     setEndLineArrowWidth(0.5_sp);
     185              : 
     186          113 :     resetProperty(Pid::BEGIN_TEXT_PLACE);
     187          113 :     resetProperty(Pid::CONTINUE_TEXT_PLACE);
     188          113 :     resetProperty(Pid::END_TEXT_PLACE);
     189          113 : }
     190              : 
     191            0 : TextLine::TextLine(const TextLine& tl)
     192            0 :     : TextLineBase(tl)
     193              : {
     194            0 : }
     195              : 
     196              : //---------------------------------------------------------
     197              : //   initStyle
     198              : //---------------------------------------------------------
     199              : 
     200          167 : void TextLine::initStyle()
     201              : {
     202          167 :     if (systemFlag()) {
     203            1 :         initElementStyle(&systemTextLineStyle);
     204              :     } else {
     205          166 :         initElementStyle(&textLineStyle);
     206              :     }
     207          167 : }
     208              : 
     209           68 : void TextLineSegment::initStyle()
     210              : {
     211           68 :     if (systemFlag()) {
     212            4 :         initElementStyle(&systemTextLineSegmentStyle);
     213              :     } else {
     214           64 :         initElementStyle(&textLineSegmentStyle);
     215              :     }
     216           68 : }
     217              : 
     218              : //---------------------------------------------------------
     219              : //   createLineSegment
     220              : //---------------------------------------------------------
     221              : 
     222           34 : LineSegment* TextLine::createLineSegment()
     223              : {
     224           34 :     TextLineSegment* seg = new TextLineSegment(this, systemFlag());
     225           34 :     seg->setTrack(track());
     226              :     // note-anchored line segments are relative to system not to staff
     227           34 :     if (anchor() == Spanner::Anchor::NOTE) {
     228            0 :         seg->setFlag(ElementFlag::ON_STAFF, false);
     229              :     }
     230           34 :     seg->initStyle();
     231              : 
     232           34 :     return seg;
     233              : }
     234              : 
     235              : //---------------------------------------------------------
     236              : //   propertyDefault
     237              : //---------------------------------------------------------
     238              : 
     239         1508 : PropertyValue TextLine::propertyDefault(Pid propertyId) const
     240              : {
     241         1508 :     switch (propertyId) {
     242          135 :     case Pid::BEGIN_TEXT:
     243              :     case Pid::CONTINUE_TEXT:
     244              :     case Pid::END_TEXT:
     245          135 :         return "";
     246           45 :     case Pid::LINE_VISIBLE:
     247           45 :         return true;
     248          135 :     case Pid::BEGIN_TEXT_OFFSET:
     249              :     case Pid::CONTINUE_TEXT_OFFSET:
     250              :     case Pid::END_TEXT_OFFSET:
     251          270 :         return PointF(0, 0);
     252           90 :     case Pid::BEGIN_HOOK_TYPE:
     253              :     case Pid::END_HOOK_TYPE:
     254           90 :         return HookType::NONE;
     255          474 :     case Pid::BEGIN_TEXT_PLACE:
     256              :     case Pid::CONTINUE_TEXT_PLACE:
     257              :     case Pid::END_TEXT_PLACE:
     258          474 :         return TextPlace::LEFT;
     259           68 :     case Pid::TEXT_STYLE:
     260           68 :         return systemFlag() ? TextStyleType::SYSTEM_TEXTLINE : TextStyleType::TEXTLINE;
     261          561 :     default:
     262          561 :         return TextLineBase::propertyDefault(propertyId);
     263              :     }
     264              : }
     265              : 
     266              : //---------------------------------------------------------
     267              : //   allowTimeAnchor
     268              : //---------------------------------------------------------
     269            0 : bool TextLine::allowTimeAnchor() const
     270              : {
     271            0 :     return !(anchor() == Spanner::Anchor::NOTE);
     272              : }
     273              : 
     274              : //---------------------------------------------------------
     275              : //   setProperty
     276              : //---------------------------------------------------------
     277              : 
     278         6692 : bool TextLine::setProperty(Pid id, const engraving::PropertyValue& v)
     279              : {
     280         6692 :     switch (id) {
     281            0 :     case Pid::PLAY:
     282            0 :         break;
     283          170 :     case Pid::PLACEMENT:
     284          170 :         setPlacement(v.value<PlacementV>());
     285          170 :         break;
     286         6522 :     default:
     287         6522 :         return TextLineBase::setProperty(id, v);
     288              :     }
     289          170 :     triggerLayout();
     290          170 :     return true;
     291              : }
     292              : 
     293              : //---------------------------------------------------------
     294              : //   getProperty
     295              : //---------------------------------------------------------
     296              : 
     297         1283 : PropertyValue TextLine::getProperty(Pid id) const
     298              : {
     299         1283 :     switch (id) {
     300           45 :     case Pid::PLAY:
     301           45 :         return PropertyValue();
     302         1238 :     default:
     303         1238 :         break;
     304              :     }
     305         1238 :     return TextLineBase::getProperty(id);
     306              : }
     307              : 
     308              : //---------------------------------------------------------
     309              : //   undoChangeProperty
     310              : //---------------------------------------------------------
     311              : 
     312            0 : void TextLine::undoChangeProperty(Pid id, const engraving::PropertyValue& v, PropertyFlags ps)
     313              : {
     314            0 :     if (id == Pid::SYSTEM_FLAG) {
     315            0 :         score()->undo(new ChangeTextLineProperty(this, v));
     316            0 :         for (SpannerSegment* s : spannerSegments()) {
     317            0 :             score()->undo(new ChangeTextLineProperty(s, v));
     318            0 :             triggerLayout();
     319              :         }
     320            0 :         return;
     321              :     }
     322            0 :     TextLineBase::undoChangeProperty(id, v, ps);
     323              : }
     324              : 
     325           56 : Sid TextLine::defaultPosSid() const
     326              : {
     327           56 :     if (systemFlag()) {
     328            4 :         return placeAbove() ? Sid::systemTextLinePosAbove : Sid::systemTextLinePosBelow;
     329              :     }
     330           52 :     return placeAbove() ? Sid::textLinePosAbove : Sid::textLinePosBelow;
     331              : }
     332              : } // namespace mu::engraving
        

Generated by: LCOV version 2.0-1