LCOV - code coverage report
Current view: top level - src/engraving/dom - textbase.h Coverage Total Hit
Test: filtered_coverage.info Lines: 87.7 % 122 107
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              : #pragma once
      24              : 
      25              : #include <variant>
      26              : 
      27              : #include "draw/fontmetrics.h"
      28              : 
      29              : #include "modularity/ioc.h"
      30              : #include "../iengravingfontsprovider.h"
      31              : 
      32              : #include "engravingitem.h"
      33              : #include "property.h"
      34              : #include "../types/types.h"
      35              : 
      36              : namespace mu::engraving {
      37              : class TextBase;
      38              : class TextBlock;
      39              : class Transaction;
      40              : 
      41              : static constexpr double SUBSCRIPT_SIZE     = 0.6;
      42              : static constexpr double SUBSCRIPT_OFFSET   = 0.5;  // of x-height
      43              : static constexpr double SUPERSCRIPT_OFFSET = -0.9; // of x-height
      44              : 
      45              : //---------------------------------------------------------
      46              : //   FrameType
      47              : //---------------------------------------------------------
      48              : 
      49              : enum class FrameType : char {
      50              :     NO_FRAME, RECTANGLE, CIRCLE
      51              : };
      52              : 
      53              : //---------------------------------------------------------
      54              : //   VerticalAlignment
      55              : //---------------------------------------------------------
      56              : 
      57              : enum class VerticalAlignment : signed char {
      58              :     AlignUndefined = -1, AlignNormal, AlignSuperScript, AlignSubScript
      59              : };
      60              : 
      61              : //---------------------------------------------------------
      62              : //   FormatId
      63              : //---------------------------------------------------------
      64              : 
      65              : enum class FormatId : char {
      66              :     Bold, Italic, Underline, Strike, Valign, FontSize, FontFamily
      67              : };
      68              : 
      69              : using FormatValue = std::variant<std::monostate, bool, int, double, String>;
      70              : 
      71              : //---------------------------------------------------------
      72              : //   MultiClick
      73              : //---------------------------------------------------------
      74              : 
      75              : enum class SelectTextType : char {
      76              :     Word, All
      77              : };
      78              : 
      79              : //---------------------------------------------------------
      80              : //   CharFormat
      81              : //---------------------------------------------------------
      82              : 
      83              : class CharFormat
      84              : {
      85              : public:
      86       164704 :     CharFormat() {}
      87        50246 :     CharFormat(const CharFormat& cf) { *this = cf; }
      88              :     bool operator==(const CharFormat& cf) const;
      89            0 :     bool operator!=(const CharFormat& cf) const { return !(*this == cf); }
      90              :     CharFormat& operator=(const CharFormat& cf);
      91              : 
      92       517774 :     FontStyle style() const { return m_style; }
      93       257379 :     void setStyle(FontStyle s) { m_style = s; }
      94       331902 :     bool bold() const { return m_style & FontStyle::Bold; }
      95       330626 :     bool italic() const { return m_style & FontStyle::Italic; }
      96       331922 :     bool underline() const { return m_style & FontStyle::Underline; }
      97       331939 :     bool strike() const { return m_style & FontStyle::Strike; }
      98        50682 :     void setBold(bool val) { m_style = val ? m_style + FontStyle::Bold : m_style - FontStyle::Bold; }
      99        50041 :     void setItalic(bool val) { m_style = val ? m_style + FontStyle::Italic : m_style - FontStyle::Italic; }
     100        49954 :     void setUnderline(bool val) { m_style = val ? m_style + FontStyle::Underline : m_style - FontStyle::Underline; }
     101        49530 :     void setStrike(bool val) { m_style = val ? m_style + FontStyle::Strike : m_style - FontStyle::Strike; }
     102              : 
     103       819624 :     VerticalAlignment valign() const { return m_valign; }
     104       780711 :     double fontSize() const { return m_fontSize; }
     105      1028688 :     String fontFamily() const { return m_fontFamily; }
     106       212084 :     void setValign(VerticalAlignment val) { m_valign = val; }
     107       256713 :     void setFontSize(double val) { m_fontSize = val; }
     108       259677 :     void setFontFamily(const String& val) { m_fontFamily = val; }
     109              : 
     110              :     FormatValue formatValue(FormatId) const;
     111              :     void setFormatValue(FormatId, const FormatValue& val);
     112              : 
     113              : private:
     114              : 
     115              :     FontStyle m_style = FontStyle::Normal;
     116              :     VerticalAlignment m_valign = VerticalAlignment::AlignNormal;
     117              :     double m_fontSize = 12.0;
     118              :     String m_fontFamily;
     119              : };
     120              : 
     121              : //---------------------------------------------------------
     122              : //   TextCursor
     123              : //    Contains current position and start of selection
     124              : //    during editing.
     125              : //---------------------------------------------------------
     126              : 
     127              : class TextCursor
     128              : {
     129              : public:
     130              :     enum class MoveOperation : unsigned char {
     131              :         Start,
     132              :         Up,
     133              :         StartOfLine,
     134              :         Left,
     135              :         WordLeft,
     136              :         End,
     137              :         Down,
     138              :         EndOfLine,
     139              :         NextWord,
     140              :         Right
     141              :     };
     142              : 
     143              :     enum class MoveMode : unsigned char {
     144              :         MoveAnchor,
     145              :         KeepAnchor
     146              :     };
     147              : 
     148        30718 :     TextCursor(TextBase* t)
     149        30718 :         : m_text(t) {}
     150              : 
     151        31857 :     TextBase* text() const { return m_text; }
     152       541145 :     bool hasSelection() const { return (m_selectLine != m_row) || (m_selectColumn != m_column); }
     153              :     void clearSelection();
     154              :     void endEdit();
     155              :     void startEdit();
     156       539952 :     bool editing() const { return m_editing; }
     157            0 :     bool visible() const { return m_visible; }
     158            0 :     void setVisible(bool val) { m_visible = val; }
     159            0 :     void toggleVisible() { setVisible(!m_visible); }
     160              : 
     161       522958 :     CharFormat* format() { return &m_format; }
     162            5 :     const CharFormat* format() const { return &m_format; }
     163         5665 :     void setFormat(const CharFormat& f) { m_format = f; }
     164              : 
     165       567244 :     size_t row() const { return m_row; }
     166       387001 :     size_t column() const { return m_column; }
     167        31768 :     size_t selectLine() const { return m_selectLine; }
     168        31771 :     size_t selectColumn() const { return m_selectColumn; }
     169        69903 :     void setRow(size_t val) { m_row = val; }
     170       247506 :     void setColumn(size_t val) { m_column = val; }
     171        31774 :     void setSelectLine(size_t val) { m_selectLine = val; }
     172        31774 :     void setSelectColumn(size_t val) { m_selectColumn = val; }
     173              :     size_t columns() const;
     174              :     void init();
     175              : 
     176              :     struct Range {
     177              :         int startPosition = 0;
     178              :         int endPosition = 0;
     179              :         String text;
     180              :     };
     181              : 
     182              :     std::pair<size_t, size_t> positionToLocalCoord(int position) const;
     183              : 
     184              :     int currentPosition() const;
     185              :     Range selectionRange() const;
     186              : 
     187              :     const TextBlock& curLine() const;
     188              :     TextBlock& curLine();
     189              : 
     190              :     RectF cursorRect() const;
     191              :     RectF cursorCanvasRect() const;
     192              :     bool movePosition(TextCursor::MoveOperation op, TextCursor::MoveMode mode = TextCursor::MoveMode::MoveAnchor, int count = 1);
     193              :     void selectWord();
     194            1 :     void moveCursorToEnd() { movePosition(TextCursor::MoveOperation::End); }
     195            1 :     void moveCursorToStart() { movePosition(TextCursor::MoveOperation::Start); }
     196              :     Char currentCharacter() const;
     197              :     bool set(const PointF& p, TextCursor::MoveMode mode = TextCursor::MoveMode::MoveAnchor);
     198              :     String selectedText(bool withFormat = false) const;
     199              :     String extractText(int r1, int c1, int r2, int c2, bool withFormat = false) const;
     200              :     void updateCursorFormat();
     201              :     void setFormat(FormatId, FormatValue val);
     202              :     void changeSelectionFormat(FormatId id, const FormatValue& val);
     203              :     const CharFormat selectedFragmentsFormat() const;
     204              : 
     205              : private:
     206              :     Range range(int start, int end) const;
     207              :     int position(int row, int column) const;
     208              : 
     209              :     TextBase* m_text = nullptr;
     210              :     CharFormat m_format;
     211              :     size_t m_row = 0;
     212              :     size_t m_column = 0;
     213              :     size_t m_selectLine = 0;           // start of selection
     214              :     size_t m_selectColumn = 0;
     215              :     bool m_editing = false;
     216              :     bool m_visible = false;
     217              : };
     218              : 
     219              : //---------------------------------------------------------
     220              : //   TextFragment
     221              : //    contains a styled text
     222              : //---------------------------------------------------------
     223              : 
     224              : class TextFragment
     225              : {
     226              : public:
     227              :     muse::GlobalInject<IEngravingFontsProvider> engravingFonts;
     228              : 
     229              : public:
     230              :     mutable CharFormat format;
     231              :     PointF pos;                    // y is relative to TextBlock->y()
     232              :     mutable String text;
     233              : 
     234         5687 :     TextFragment() = default;
     235              :     TextFragment(const String& s);
     236              :     TextFragment(TextCursor*, const String&);
     237              :     TextFragment(const TextFragment& f);
     238              : 
     239              :     TextFragment& operator =(const TextFragment& f);
     240              : 
     241              :     bool operator ==(const TextFragment& f) const;
     242              : 
     243              :     TextFragment split(int column);
     244              :     muse::draw::Font font(const TextBase*) const;
     245              :     double calculatedFontSize(const TextBase*) const;
     246              :     int columns() const;
     247              :     void changeFormat(FormatId id, const FormatValue& data);
     248              : 
     249              : private:
     250              :     void resolveFallback(muse::draw::Font::Type fontType, const muse::draw::FontMetrics& fm, String& family) const;
     251              : };
     252              : 
     253              : //---------------------------------------------------------
     254              : //   TextBlock
     255              : //    represents a block of formatted text
     256              : //---------------------------------------------------------
     257              : 
     258              : class TextBlock
     259              : {
     260              : public:
     261        43445 :     TextBlock() = default;
     262              : 
     263              :     bool operator ==(const TextBlock& x) const { return m_fragments == x.m_fragments; }
     264              :     bool operator !=(const TextBlock& x) const { return m_fragments != x.m_fragments; }
     265              : 
     266       148443 :     const std::list<TextFragment>& fragments() const { return m_fragments; }
     267       140853 :     std::list<TextFragment>& fragments() { return m_fragments; }
     268              :     std::list<TextFragment> fragmentsWithoutEmpty();
     269              :     const Shape& shape() const { return m_shape; }
     270       202197 :     Shape& shape() { return m_shape; }
     271       202827 :     const RectF& boundingRect() const { return m_shape.bbox(); }
     272              :     RectF boundingRect(int col1, int col2, const TextBase*) const;
     273              :     size_t columns() const;
     274              :     void insert(TextCursor*, const String&);
     275              :     void insertEmptyFragmentIfNeeded(TextCursor*);
     276              :     void removeEmptyFragment();
     277              :     String remove(int column, TextCursor*);
     278              :     String remove(int start, int n, TextCursor*);
     279              :     int column(double x, TextBase*) const;
     280              :     TextBlock split(int column, TextCursor* cursor);
     281              :     double xpos(size_t col, const TextBase*) const;
     282              :     const CharFormat* formatAt(int) const;
     283              :     const TextFragment* fragment(int col) const;
     284              :     std::list<TextFragment>::iterator fragment(int column, int* rcol, int* ridx);
     285       191147 :     double y() const { return m_y; }
     286       134798 :     void setY(double val) { m_y = val; }
     287       117889 :     double lineSpacing() const { return m_lineSpacing; }
     288        67399 :     void setLineSpacing(double val) { m_lineSpacing = val; }
     289              :     String text(int, int, const TextBase*, bool = false) const;
     290        43918 :     bool eol() const { return m_eol; }
     291          294 :     void setEol(bool val) { m_eol = val; }
     292              :     void changeFormat(FormatId, const FormatValue& val, int start, int n);
     293              : 
     294              : private:
     295              :     void simplify();
     296              : 
     297              :     std::list<TextFragment> m_fragments;
     298              :     double m_y = 0.0;
     299              :     double m_lineSpacing = 0.0;
     300              :     Shape m_shape;
     301              :     bool m_eol = false;
     302              : };
     303              : 
     304              : //---------------------------------------------------------
     305              : //   TextBase
     306              : //---------------------------------------------------------
     307              : 
     308              : class TextBase : public EngravingItem
     309              : {
     310           66 :     OBJECT_ALLOCATOR(engraving, TextBase)
     311              : 
     312         4328 :     M_PROPERTY2(bool, isTextLinkedToMaster, setTextLinkedToMaster, true)
     313              : 
     314              : public:
     315              : 
     316              :     ~TextBase();
     317              : 
     318              :     Text& operator=(const Text&) = delete;
     319              : 
     320       214312 :     Align align() const { return m_align; }
     321        58962 :     void setAlign(Align a) { m_align = a; }
     322        79081 :     AlignH position() const { return m_position; }
     323        56046 :     void setPosition(AlignH val) { m_position = val; }
     324              : 
     325         1326 :     static String plainToXmlText(const String& s) { return s.toXmlEscaped(); }
     326         1326 :     void setPlainText(const String& t) { setXmlText(plainToXmlText(t)); }
     327              :     virtual void setXmlText(const String&);
     328          143 :     void setXmlText(const char* str) { setXmlText(String::fromUtf8(str)); }
     329              :     void checkCustomFormatting(const String&);
     330              :     String xmlText() const;
     331              :     String plainText() const;
     332              :     void resetFormatting();
     333              : 
     334              :     void insertText(const String&);
     335              : 
     336              :     double lineSpacing() const;
     337              :     double lineHeight() const;
     338              :     virtual double baseLine() const override;
     339              : 
     340        15307 :     bool empty() const { return xmlText().isEmpty(); }
     341              :     void clear() { setXmlText(String()); }
     342              : 
     343              :     virtual FontStyle fontStyle() const;
     344              :     virtual String family() const;
     345              :     virtual double size() const;
     346              : 
     347              :     virtual void setFontStyle(const FontStyle& val);
     348              :     virtual void setFamily(const String& val);
     349              :     virtual void setSize(const double& val);
     350              : 
     351         2326 :     bool anchorToEndOfPrevious() const { return m_anchorToEndOfPrevious; }
     352            1 :     void setAnchorToEndOfPrevious(bool v) { m_anchorToEndOfPrevious = v; }
     353              : 
     354         4157 :     bool hasParentSegment() const { return ownershipParent() && parent()->isSegment(); }
     355           59 :     virtual bool allowTimeAnchor() const override { return hasParentSegment(); }
     356              :     virtual void startEdit(EditData&) override;
     357              :     virtual bool isEditAllowed(EditData&) const override;
     358              :     virtual bool edit(EditData&) override;
     359              :     virtual void editCut(EditData&) override;
     360              :     virtual void editCopy(EditData&) override;
     361              :     virtual void endEdit(EditData&) override;
     362              :     virtual RectF drag(EditData&) override;
     363              :     virtual void endDrag(EditData&) override;
     364              :     void movePosition(TextCursor::MoveOperation);
     365              : 
     366              :     bool mousePress(EditData& ed);
     367              :     void dragTo(EditData& ed);
     368              : 
     369              :     bool deleteSelectedText();
     370              : 
     371              :     void selectAll();
     372              :     void select(SelectTextType);
     373              :     bool isPrimed() const { return m_primed; }
     374            0 :     void setPrimed(bool primed) { m_primed = primed; }
     375              : 
     376              :     virtual void paste(const String& txt);
     377              : 
     378              :     RectF pageRectangle() const;
     379              : 
     380         4330 :     const Shape& highResShape() const { return ldata()->highResShape.value(); }
     381              : 
     382              :     std::vector<LineF> dragAnchorLines() const override;
     383              : 
     384              :     virtual bool acceptDrop(EditData&) const override;
     385              :     virtual EngravingItem* drop(Transaction& tx, EditData&) override;
     386              : 
     387              :     friend class TextBlock;
     388              :     friend class TextFragment;
     389              : 
     390              :     static String unEscape(String s);
     391              :     static String escape(String s);
     392              : 
     393              :     String accessibleInfo() const override;
     394              :     String screenReaderInfo() const override;
     395              : 
     396              :     int subtype() const override;
     397              :     TranslatableString subtypeUserName() const override;
     398              : 
     399              :     std::list<TextFragment> fragmentList() const;   // for MusicXML formatted export
     400              : 
     401              :     static bool validateText(String& s);
     402              :     bool inHexState() const { return m_hexState >= 0; }
     403              :     void endHexState();
     404              : 
     405              :     muse::draw::Font font() const;
     406              :     muse::draw::FontMetrics fontMetrics() const;
     407              : 
     408              :     bool isPropertyLinkedToMaster(Pid id) const override;
     409              :     bool isUnlinkedFromMaster() const override;
     410              :     PropertyValue getProperty(Pid propertyId) const override;
     411              :     bool setProperty(Pid propertyId, const PropertyValue& v) override;
     412              :     PropertyValue propertyDefault(Pid id) const override;
     413              :     void undoChangeProperty(Pid id, const PropertyValue& v, PropertyFlags ps) override;
     414              :     Sid getPropertyStyle(Pid) const override;
     415              :     void styleChanged() override;
     416              :     void editInsertText(TextCursor*, const String&);
     417              : 
     418       168619 :     TextCursor* cursor() const { return m_cursor; }
     419              : 
     420        31758 :     void setTextInvalid() { m_textInvalid = true; }
     421              :     bool isTextInvalid() const { return m_textInvalid; }
     422              : 
     423              :     // helper functions
     424        86068 :     bool hasFrame() const { return m_frameType != FrameType::NO_FRAME; }
     425           19 :     bool circle() const { return m_frameType == FrameType::CIRCLE; }
     426          144 :     bool rectangle() const { return m_frameType == FrameType::RECTANGLE; }
     427              : 
     428       596379 :     TextStyleType textStyleType() const { return m_textStyleType; }
     429        18353 :     void setTextStyleType(TextStyleType id) { m_textStyleType = id; }
     430              :     void initTextStyleType(TextStyleType id);
     431              :     void initTextStyleType(TextStyleType id, bool preserveDifferent);
     432              :     virtual void initElementStyle(const ElementStyle*) override;
     433              : 
     434              :     static const String UNDEFINED_FONT_FAMILY;
     435              :     static const double UNDEFINED_FONT_SIZE;
     436              : 
     437              :     static bool isSorted(size_t r1, size_t c1, size_t r2, size_t c2);
     438              :     static void sort(size_t& r1, size_t& c1, size_t& r2, size_t& c2);
     439              : 
     440        27173 :     bool bold() const { return fontStyle() & FontStyle::Bold; }
     441        27173 :     bool italic() const { return fontStyle() & FontStyle::Italic; }
     442        27173 :     bool underline() const { return fontStyle() & FontStyle::Underline; }
     443        27173 :     bool strike() const { return fontStyle() & FontStyle::Strike; }
     444            6 :     void setBold(bool val) { setFontStyle(val ? fontStyle() + FontStyle::Bold : fontStyle() - FontStyle::Bold); }
     445            8 :     void setItalic(bool val) { setFontStyle(val ? fontStyle() + FontStyle::Italic : fontStyle() - FontStyle::Italic); }
     446            0 :     void setUnderline(bool val)
     447              :     {
     448            0 :         setFontStyle(val ? fontStyle() + FontStyle::Underline : fontStyle() - FontStyle::Underline);
     449            0 :     }
     450              : 
     451            0 :     void setStrike(bool val)
     452              :     {
     453            0 :         setFontStyle(val ? fontStyle() + FontStyle::Strike : fontStyle() - FontStyle::Strike);
     454            0 :     }
     455              : 
     456              :     bool hasCustomFormatting() const;
     457              : 
     458              :     friend class TextCursor;
     459              :     using EngravingObject::undoChangeProperty;
     460              : 
     461              :     Color textColor(const rendering::PaintOptions& opt) const;
     462        18497 :     FrameType frameType() const { return m_frameType; }
     463        42112 :     void setFrameType(FrameType val) { m_frameType = val; }
     464        67975 :     double textLineSpacing() const { return m_textLineSpacing; }
     465        42039 :     void setTextLineSpacing(double val) { m_textLineSpacing = val; }
     466          475 :     Color bgColor() const { return m_bgColor; }
     467        42039 :     void setBgColor(const Color& val) { m_bgColor = val; }
     468        42533 :     Color frameColor() const { return m_frameColor; }
     469        84094 :     void setFrameColor(const Color& val) { m_frameColor = val; }
     470          763 :     Spatium frameWidth() const { return m_frameWidth; }
     471        42039 :     void setFrameWidth(Spatium val) { m_frameWidth = val; }
     472          619 :     Spatium paddingWidth() const { return m_paddingWidth; }
     473        42039 :     void setPaddingWidth(Spatium val) { m_paddingWidth = val; }
     474          475 :     Spatium frameRound() const { return m_frameRound; }
     475        42040 :     void setFrameRound(Spatium val) { m_frameRound = val; }
     476              : 
     477              :     struct LayoutData : public EngravingItem::LayoutData {
     478              :         std::vector<TextBlock> blocks;
     479              :         bool layoutInvalid = true;
     480              : 
     481              :         RectF frame;
     482              : 
     483        33292 :         size_t rows() const { return blocks.size(); }
     484         1705 :         const TextBlock& textBlock(size_t i) const { return blocks.at(i); }
     485            0 :         TextBlock& textBlock(size_t i) { return blocks[i]; }
     486              : 
     487              :         ld_field<Shape> highResShape = { "[TextBase] highResShape", Shape() };
     488              :     };
     489      1884401 :     DECLARE_LAYOUTDATA_METHODS(TextBase)
     490              : 
     491              :     void createBlocks();
     492              :     void createBlocks(LayoutData* ldata) const;
     493              :     void layoutFrame();
     494              :     void layoutFrame(LayoutData* ldata) const;
     495              : 
     496              :     //! NOTE It can only be set for some types of text, see who has the setter.
     497              :     //! At the moment it's: Text, Jump, Marker
     498       211301 :     bool layoutToParentWidth() const { return m_layoutToParentWidth; }
     499              : 
     500              :     virtual bool positionRelativeToNoteheadRest() const = 0;
     501              : 
     502           73 :     void setVoiceAssignment(VoiceAssignment v) { m_voiceAssignment = v; }
     503         2493 :     VoiceAssignment voiceAssignment() const { return m_voiceAssignment; }
     504          149 :     void setDirection(DirectionV v) { m_direction = v; }
     505         1895 :     DirectionV direction() const { return m_direction; }
     506           52 :     void setCenterBetweenStaves(AutoOnOff v) { m_centerBetweenStaves = v; }
     507         2814 :     AutoOnOff centerBetweenStaves() const { return m_centerBetweenStaves; }
     508              :     void genText();
     509              : 
     510         4264 :     double symbolSize() const { return m_symbolSize; }
     511        46692 :     void setSymbolSize(double v) { m_symbolSize = v; }
     512              : 
     513         7498 :     double symbolScale() const { return m_symbolScale; }
     514        44557 :     void setSymbolScale(double v) { m_symbolScale = v; }
     515              : 
     516              :     bool hasSymbolScale() const;
     517         3789 :     bool hasSymbolSize() const { return !hasSymbolScale(); }
     518              : 
     519              :     double spatiumScaling() const;
     520              : 
     521        66841 :     double textAngle() const { return m_textAngle; }
     522            0 :     void setTextAngle(double v) { m_textAngle = v; }
     523              : 
     524              :     PointF defaultPos() const override;
     525              : 
     526              : protected:
     527              :     TextBase(const ElementType& type, EngravingObject* parent = 0, TextStyleType tid = TextStyleType::DEFAULT,
     528          397 :              ElementFlags = ElementFlag::NOTHING);
     529              :     TextBase(const ElementType& type, EngravingObject* parent, ElementFlags);
     530              :     TextBase(const TextBase&);
     531              : 
     532              :     bool nudge(const EditData& ed);
     533              : 
     534              :     void insertSym(SymId id);
     535              :     void prepareFormat(const String& token, TextCursor& cursor);
     536              :     bool prepareFormat(const String& token, CharFormat& format);
     537              : 
     538              :     virtual void commitText();
     539              : 
     540              :     bool textWasEdited(EditData& ed) const;
     541              : 
     542              :     bool m_layoutToParentWidth = false;
     543              : 
     544              : private:
     545              :     void insert(TextCursor*, char32_t code, LayoutData* ldata) const;
     546              :     String genText(const LayoutData* ldata) const;
     547              : 
     548              :     virtual int getPropertyFlagsIdx(Pid id) const override;
     549              :     String stripText(bool, bool, bool) const;
     550              : 
     551              :     static String getHtmlStartTag(double, double&, const String&, String&, FontStyle, VerticalAlignment);
     552              :     static String getHtmlEndTag(FontStyle, VerticalAlignment);
     553              : 
     554              :     static void swap(size_t& r1, size_t& c1, size_t& r2, size_t& c2);
     555              : 
     556              :     Sid defaultPosSid() const override;
     557              : 
     558              : #ifndef ENGRAVING_NO_ACCESSIBILITY
     559              :     AccessibleItemPtr createAccessible() override;
     560              : #endif
     561              : 
     562              :     void notifyAboutTextCursorChanged();
     563              :     void notifyAboutTextInserted(int startPosition, int endPosition, const String& text);
     564              :     void notifyAboutTextRemoved(int startPosition, int endPosition, const String& text);
     565              : 
     566              :     Align m_align;
     567              : 
     568              :     AlignH m_position = AlignH::LEFT;
     569              : 
     570              :     FrameType m_frameType = FrameType::NO_FRAME;
     571              :     double m_textLineSpacing = 1.0;
     572              :     Color m_bgColor;
     573              :     Color m_frameColor;
     574              :     Spatium m_frameWidth;
     575              :     Spatium m_paddingWidth;
     576              :     Spatium m_frameRound;
     577              : 
     578              :     // there are two representations of text; only one
     579              :     // might be valid and the other can be constructed from it
     580              : 
     581              :     String m_text;                          // cached
     582              :     bool m_textInvalid = true;
     583              : 
     584              :     TextStyleType m_textStyleType = TextStyleType::DEFAULT;           // text style id
     585              : 
     586              :     int m_hexState = -1;
     587              :     bool m_primed = 0;
     588              : 
     589              :     double m_symbolSize = 18.0;
     590              :     double m_symbolScale = 1.0;
     591              : 
     592              :     TextCursor* m_cursor = nullptr;
     593              : 
     594              :     VoiceAssignment m_voiceAssignment = VoiceAssignment::ALL_VOICE_IN_INSTRUMENT;
     595              :     DirectionV m_direction = DirectionV::AUTO;
     596              :     AutoOnOff m_centerBetweenStaves = AutoOnOff::AUTO;
     597              :     bool m_anchorToEndOfPrevious = false;
     598              : 
     599              :     double m_textAngle = 0.0;
     600              : };
     601              : 
     602            0 : inline bool isTextNavigationKey(int key, KeyboardModifiers modifiers)
     603              : {
     604              :     // space + TextEditingControlModifier = insert nonbreaking space, so that's *not* a navigation key
     605            0 :     return (key == Key_Space && modifiers != TextEditingControlModifier) || key == Key_Tab;
     606              : }
     607              : } // namespace mu::engraving
        

Generated by: LCOV version 2.0-1