add another prerequisite patch (also a bugfix so still good)
[alioth/musescore.git] / debian / patches / backports / 59-blank-lines.diff
1 Origin: vendor, commit:25f92afae6374e1d610efd5b43b8effab36cf21b
2 Author: SKefalidis <megistios@gmail.com>
3 Description: fix #307721: blank lines ignored at top of text elements
4
5 --- a/libmscore/textbase.cpp
6 +++ b/libmscore/textbase.cpp
7 @@ -705,11 +705,33 @@ void TextBlock::layout(TextBase* t)
8                          break;
9                    }
10              }
11 +
12        if (_fragments.empty()) {
13              QFontMetricsF fm = t->fontMetrics();
14              _bbox.setRect(0.0, -fm.ascent(), 1.0, fm.descent());
15              _lineSpacing = fm.lineSpacing();
16              }
17 +      else if (_fragments.size() == 1 && _fragments.at(0).text.isEmpty()) {
18 +            auto fi = _fragments.begin();
19 +            TextFragment& f = *fi;
20 +            f.pos.setX(x);
21 +            QFontMetricsF fm(f.font(t), MScore::paintDevice());
22 +            if (f.format.valign() != VerticalAlignment::AlignNormal) {
23 +                  qreal voffset = fm.xHeight() / subScriptSize;   // use original height
24 +                  if (f.format.valign() == VerticalAlignment::AlignSubScript)
25 +                        voffset *= subScriptOffset;
26 +                  else
27 +                        voffset *= superScriptOffset;
28 +                  f.pos.setY(voffset);
29 +                  }
30 +            else {
31 +                  f.pos.setY(0.0);
32 +                  }
33 +
34 +            QRectF temp(0.0, -fm.ascent(), 1.0, fm.descent());
35 +            _bbox |= temp;
36 +            _lineSpacing = qMax(_lineSpacing, fm.lineSpacing());
37 +            }
38        else {
39              for (TextFragment& f : _fragments) {
40                    f.pos.setX(x);
41 @@ -744,6 +766,24 @@ void TextBlock::layout(TextBase* t)
42        }
43  
44  //---------------------------------------------------------
45 +//   fragmentsWithoutEmpty
46 +//---------------------------------------------------------
47 +
48 +QList<TextFragment>* TextBlock::fragmentsWithoutEmpty()
49 +      {
50 +      QList<TextFragment>* list = new QList<TextFragment>();
51 +      for (auto x :_fragments) {
52 +            if (x.text.isEmpty()) {
53 +                  continue;
54 +                  }
55 +            else {
56 +                  list->append(x);
57 +                  }
58 +            }
59 +      return list;
60 +      }
61 +
62 +//---------------------------------------------------------
63  //   xpos
64  //---------------------------------------------------------
65  
66 @@ -899,8 +939,9 @@ void TextBlock::insert(TextCursor* curso
67  
68  void TextBlock::insertEmptyFragmentIfNeeded(TextCursor* cursor)
69        {
70 -      if (_fragments.size() == 0 || _fragments.at(0).text != "")
71 +      if (_fragments.size() == 0 || _fragments.at(0).text.isEmpty()) {
72              _fragments.insert(0, TextFragment(cursor, ""));
73 +            }
74        }
75  
76  //---------------------------------------------------------
77 @@ -1136,7 +1177,7 @@ void TextFragment::changeFormat(FormatId
78  //   split
79  //---------------------------------------------------------
80  
81 -TextBlock TextBlock::split(int column)
82 +TextBlock TextBlock::split(int column, Ms::TextCursor* cursor)
83        {
84        TextBlock tl;
85  
86 @@ -1156,6 +1197,8 @@ TextBlock TextBlock::split(int column)
87                                }
88                          for (; i != _fragments.end(); i = _fragments.erase(i))
89                                tl._fragments.append(*i);
90 +                        if (_fragments.size() == 0)
91 +                              insertEmptyFragmentIfNeeded(cursor);
92                          return tl;
93                          }
94                    ++idx;
95 @@ -1167,6 +1210,8 @@ TextBlock TextBlock::split(int column)
96        TextFragment tf("");
97        if (_fragments.size() > 0)
98              tf.format = _fragments.last().format;
99 +      else if (_fragments.size() == 0)
100 +            insertEmptyFragmentIfNeeded(cursor);
101        tl._fragments.append(tf);
102        return tl;
103        }
104 @@ -1327,7 +1372,7 @@ static qreal parseNumProperty(const QStr
105  
106  void TextBase::createLayout()
107        {
108 -      _layout.clear();
109 +      _layout.clear();  // deletes the text fragments so we lose all formatting information
110        TextCursor cursor((Text*)this);
111        cursor.init();
112  
113 @@ -1716,8 +1761,9 @@ void TextBase::genText() const
114  
115        for (const TextBlock& block : _layout) {
116              for (const TextFragment& f : block.fragments()) {
117 -                  if (f.text.isEmpty())                     // skip empty fragments, not to
118 -                        continue;                           // insert extra HTML formatting
119 +                  // don't skip, empty text fragments hold information for empty lines
120 +//                  if (f.text.isEmpty())                     // skip empty fragments, not to
121 +//                        continue;                           // insert extra HTML formatting
122                    const CharFormat& format = f.format;
123                    if (fmt.bold() != format.bold()) {
124                          if (format.bold())
125 --- a/libmscore/textbase.h
126 +++ b/libmscore/textbase.h
127 @@ -189,6 +189,7 @@ class TextBlock {
128        void layout(TextBase*);
129        const QList<TextFragment>& fragments() const { return _fragments; }
130        QList<TextFragment>& fragments()             { return _fragments; }
131 +      QList<TextFragment>* fragmentsWithoutEmpty();
132        const QRectF& boundingRect() const           { return _bbox; }
133        QRectF boundingRect(int col1, int col2, const TextBase*) const;
134        int columns() const;
135 @@ -198,7 +199,7 @@ class TextBlock {
136        QString remove(int column, TextCursor*);
137        QString remove(int start, int n, TextCursor*);
138        int column(qreal x, TextBase*) const;
139 -      TextBlock split(int column);
140 +      TextBlock split(int column, TextCursor* cursor);
141        qreal xpos(int col, const TextBase*) const;
142        const CharFormat* formatAt(int) const;
143        const TextFragment* fragment(int col) const;
144 --- a/libmscore/textedit.cpp
145 +++ b/libmscore/textedit.cpp
146 @@ -448,15 +448,21 @@ void SplitJoinText::join(EditData* ed)
147        CharFormat* charFmt = c.format();         // take current format
148        int col             = t->textBlock(line-1).columns();
149        int eol             = t->textBlock(line).eol();
150 -      t->textBlock(line-1).fragments().append(t->textBlock(line).fragments());
151 +      auto fragmentsList = t->textBlock(line).fragmentsWithoutEmpty();
152 +      if (fragmentsList->size() > 0)
153 +            t->textBlock(line-1).removeEmptyFragment();
154 +      t->textBlock(line-1).fragments().append(*fragmentsList);
155 +      delete fragmentsList;
156        int lines = t->rows();
157        if (line < lines)
158              t->textBlock(line).setEol(eol);
159        t->textBlockList().removeAt(line);
160 +
161        c.setRow(line-1);
162        c.setColumn(col);
163        c.setFormat(*charFmt);             // restore orig. format at new line
164        c.clearSelection();
165 +
166        if (ed)
167              *t->cursor(*ed) = c;
168        c.text()->setTextInvalid();
169 @@ -470,7 +476,7 @@ void SplitJoinText::split(EditData* ed)
170        t->triggerLayout();
171  
172        CharFormat* charFmt = c.format();         // take current format
173 -      t->textBlockList().insert(line + 1, c.curLine().split(c.column()));
174 +      t->textBlockList().insert(line + 1, c.curLine().split(c.column(), t->cursor(*ed)));
175        c.curLine().setEol(true);
176  
177        c.setRow(line+1);