void tst_QQuickTextMetrics::functionsWithArguments() { QFETCH(QString, text); QFETCH(Qt::TextElideMode, mode); QFETCH(qreal, width); QQuickTextMetrics metrics; // Ensures that the values actually change. metrics.setText(text + "extra"); metrics.setElideWidth(width + 1); switch (mode) { case Qt::ElideNone: metrics.setElide(Qt::ElideMiddle); break; case Qt::ElideLeft: metrics.setElide(Qt::ElideRight); break; case Qt::ElideMiddle: metrics.setElide(Qt::ElideNone); break; case Qt::ElideRight: metrics.setElide(Qt::ElideLeft); break; } QSignalSpy textSpy(&metrics, SIGNAL(textChanged())); QSignalSpy metricsSpy(&metrics, SIGNAL(metricsChanged())); metrics.setText(text); QCOMPARE(textSpy.count(), 1); QCOMPARE(metricsSpy.count(), 1); QSignalSpy elideSpy(&metrics, SIGNAL(elideChanged())); metrics.setElide(mode); QCOMPARE(elideSpy.count(), 1); QCOMPARE(metricsSpy.count(), 2); QSignalSpy elideWidthSpy(&metrics, SIGNAL(elideWidthChanged())); metrics.setElideWidth(width); QCOMPARE(elideWidthSpy.count(), 1); QCOMPARE(metricsSpy.count(), 3); QFontMetricsF expected = QFontMetricsF(QFont()); QCOMPARE(metrics.elidedText(), expected.elidedText(text, mode, width, 0)); QCOMPARE(metrics.advanceWidth(), expected.width(text)); QCOMPARE(metrics.boundingRect(), expected.boundingRect(text)); QCOMPARE(metrics.width(), expected.boundingRect(text).width()); QCOMPARE(metrics.height(), expected.boundingRect(text).height()); QCOMPARE(metrics.tightBoundingRect(), expected.tightBoundingRect(text)); }
void Lyrics::layout1() { setPos(textStyle().offset(spatium())); Text::layout1(); if (!parent()) // palette & clone trick return; ChordRest* cr = chordRest(); const QList<Lyrics*>* ll = &(cr->lyricsList()); qreal lh = lineSpacing() * score()->styleD(StyleIdx::lyricsLineHeight); int line = ll->indexOf(this); qreal y = lh * line + point(score()->styleS(StyleIdx::lyricsDistance)); qreal x = 0.0; // // parse leading verse number and/or punctuation, so we can factor it into layout separately // TODO: provide a way to disable this // bool hasNumber = false; // _verseNumber; qreal adjust = 0.0; QString s = plainText(true); // find: // 1) string of numbers and non-word characters at start of syllable // 2) at least one other character (indicating start of actual lyric) QRegularExpression leadingPattern("(^[\\d\\W]+)([^\\d\\W]+)"); QRegularExpressionMatch leadingMatch = leadingPattern.match(s); if (leadingMatch.hasMatch()) { // leading string QString s1 = leadingMatch.captured(1); // actual lyric //QString s2 = leadingMatch.captured(2); Text leading(*this); leading.setPlainText(s1); leading.layout1(); adjust = leading.width(); if (!s1.isEmpty() && s1[0].isDigit()) hasNumber = true; } if (textStyle().align() & AlignmentFlags::HCENTER) { // // center under notehead, not origin // however, lyrics that are melismas or have verse numbers will be forced to left alignment // TODO: provide a way to disable the automatic left alignment // qreal maxWidth; if (cr->type() == Element::Type::CHORD) maxWidth = static_cast<Chord*>(cr)->maxHeadWidth(); else maxWidth = cr->width(); // TODO: exclude ledger line for multivoice rest? qreal nominalWidth = symWidth(SymId::noteheadBlack); if (!isMelisma() && !hasNumber) // center under notehead x += nominalWidth * .5 - cr->x() - adjust * 0.5; else // force left alignment x += (width() + nominalWidth - maxWidth) * .5 - cr->x() - adjust; } else { // even for left aligned syllables, ignore leading verse numbers and/or punctuation x -= adjust; } rxpos() += x; rypos() += y; if (_ticks > 0 || _syllabic == Syllabic::BEGIN || _syllabic == Syllabic::MIDDLE) { if (_separator == nullptr) { _separator = new LyricsLine(score()); _separator->setTick(cr->tick()); score()->addUnmanagedSpanner(_separator); } _separator->setParent(this); _separator->setTick(cr->tick()); _separator->setTrack(track()); _separator->setTrack2(track()); #if defined(USE_FONT_DASH_METRIC) // if font parameters different from font cached values, compute new dash values from font metrics if (textStyle().family() != g_fontFamily && textStyle().size() != g_fontSize) { QFontMetricsF fm = textStyle().fontMetrics(spatium()); QRectF r = fm.tightBoundingRect("\u2013"); // U+2013 EN DASH g_cachedDashY = _dashY = r.y() + (r.height() * HALF); g_cachedDashLength = _dashLength = r.width(); #if defined(USE_FONT_DASH_TICKNESS) g_cachedDashThickness = _dashThickness = r.height(); #endif g_fontFamily = textStyle().family(); g_fontSize = textStyle().size(); } // if same font, use cached values else { _dashY = g_cachedDashY; _dashLength = g_cachedDashLength; #if defined(USE_FONT_DASH_TICKNESS) _dashThickness = g_cachedDashThickness; #endif } #endif } else if (_separator != nullptr) { _separator->unchain(); delete _separator; _separator = nullptr; } }