tst_QTextMarkdownWriter: test both ways of setting font characteristics

We have explicit QFont properties, and QTextFormat::setProperty().
Setting FontFixedPitch doesn't necessarily affect the view (QTextEdit or
Qt Quick Text/TextEdit); and setting the font to the one we get from
QFontDatabase::systemFont(QFontDatabase::FixedFont) is also unreliable,
because the "monospace" fallback might actually be proportional.
QTextMarkdownWriter checks for both to decide whether to use backticks;
so markdown writing works if an editor UI makes the format monospace
both ways to be safe. But in the opposite case that the main font is
actually a monospace font, it's always been broken.

The rest of the QTextCharFormat properties are generally working, to
the extent that they are applicable to Markdown. But we lacked explicit
test coverage: so far we were just reading Markdown or HTML and writing
Markdown to test the writer.

Also amend an old comment about writing underlines: writing was always
possible, and since f5c7799f59ba53c634906b11e2135190093bf87b reading is
supported too. So the underline support is symmetric (except that we
don't heed the QTextDocument::MarkdownFeatures argument to the writer
ctor: we probably should do that some day).

Task-number: QTBUG-54623
Task-number: QTBUG-75648
Task-number: QTBUG-75649
Task-number: QTBUG-79900
Task-number: QTBUG-99676
Task-number: QTBUG-103484
Change-Id: Iacb4ed0ea59030570702d4eadfdadfad872065c6
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
(cherry picked from commit bf8167c5fc513861ba9ecadf491db256de65eafd)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Shawn Rutledge 2024-02-05 22:53:22 -07:00 committed by Qt Cherry-pick Bot
parent 7fb362ab59
commit 82cc779ee6
2 changed files with 125 additions and 3 deletions

View File

@ -575,9 +575,9 @@ int QTextMarkdownWriter::writeBlock(const QTextBlock &block, bool wrap, bool ign
endingMarkers = true;
}
if (fontInfo.underline() != underline) {
// Markdown doesn't support underline, but the parser will treat a single underline
// the same as a single asterisk, and the marked fragment will be rendered in italics.
// That will have to do.
// CommonMark specifies underline as another way to get emphasis (italics):
// https://spec.commonmark.org/0.31.2/#example-148
// but md4c allows us to distinguish them; so we support underlining (in GitHub dialect).
markers += u'_';
underline = fontInfo.underline();
if (!underline)

View File

@ -38,6 +38,8 @@ private slots:
void testWriteTable();
void charFormatWrapping_data();
void charFormatWrapping();
void charFormat_data();
void charFormat();
void rewriteDocument_data();
void rewriteDocument();
void fromHtml_data();
@ -50,6 +52,8 @@ private:
private:
QTextDocument *document;
QFont m_monoFont = QFontDatabase::systemFont(QFontDatabase::FixedFont);
QFont m_defaultFont;
};
void tst_QTextMarkdownWriter::init()
@ -607,6 +611,124 @@ void tst_QTextMarkdownWriter::charFormatWrapping() // QTBUG-116927
}
}
void tst_QTextMarkdownWriter::charFormat_data()
{
QTest::addColumn<QTextFormat::Property>("property");
QTest::addColumn<QVariant>("propertyValue");
QTest::addColumn<QFont>("explicitFont");
QTest::addColumn<QString>("expectedOutput");
const QTextFormat::Property NoProperty = QTextFormat::ObjectIndex;
QTest::newRow("FontFixedPitch")
<< QTextFormat::FontFixedPitch << QVariant(true) << m_defaultFont
<< "before `formatted` after";
if (!isFixedFontProportional()) {
// QTBUG-54623 QTBUG-75649 QTBUG-79900 QTBUG-103484 etc.
QTest::newRow("mono font") << NoProperty << QVariant() << m_monoFont
<< "before `formatted` after";
}
{
QFont font;
font.setItalic(true);
QTest::newRow("italic font")
<< NoProperty << QVariant() << font
<< "before *formatted* after";
}
QTest::newRow("FontItalic")
<< QTextFormat::FontItalic << QVariant(true) << m_defaultFont
<< "before *formatted* after";
{
QFont font;
font.setUnderline(true);
QTest::newRow("underline font")
<< NoProperty << QVariant() << font
<< "before _formatted_ after";
}
QTest::newRow("FontUnderline")
<< QTextFormat::FontUnderline << QVariant(true) << m_defaultFont
<< "before _formatted_ after";
{
QFont font;
font.setStrikeOut(true);
QTest::newRow("strikeout font")
<< NoProperty << QVariant() << font
<< "before ~~formatted~~ after";
}
QTest::newRow("FontStrikeOut")
<< QTextFormat::FontStrikeOut << QVariant(true) << m_defaultFont
<< "before ~~formatted~~ after";
{
QFont font;
font.setBold(true);
QTest::newRow("bold font")
<< NoProperty << QVariant() << font
<< "before **formatted** after";
}
{
QFont font;
font.setWeight(QFont::Black);
QTest::newRow("black font")
<< NoProperty << QVariant() << font
<< "before **formatted** after";
}
QTest::newRow("FontWeight")
<< QTextFormat::FontWeight << QVariant(700) << m_defaultFont
<< "before **formatted** after";
QTest::newRow("AnchorHref")
<< QTextFormat::AnchorHref << QVariant("linky linky") << m_defaultFont
<< "before [formatted](linky linky) after";
QTest::newRow("TextToolTip") // no effect without AnchorHref
<< QTextFormat::TextToolTip << QVariant("such a tool") << m_defaultFont
<< "before formatted after";
}
void tst_QTextMarkdownWriter::charFormat()
{
if (isMainFontFixed())
QSKIP("QTextMarkdownWriter would generate bogus backticks");
QFETCH(QTextFormat::Property, property);
QFETCH(QVariant, propertyValue);
QFETCH(QFont, explicitFont);
QFETCH(QString, expectedOutput);
QTextCursor cursor(document);
cursor.insertText("before ");
QTextCharFormat fmt;
if (explicitFont != m_defaultFont)
fmt.setFont(explicitFont);
if (property != QTextFormat::ObjectIndex) // != 0
fmt.setProperty(property, propertyValue);
if (explicitFont == m_monoFont) {
QFontInfo fontInfo(fmt.font());
qCDebug(lcTests) << "mono font" << explicitFont << "fontInfo fixedPitch" << fontInfo.fixedPitch() << "fmt fixedPitch" << fmt.fontFixedPitch();
}
cursor.setCharFormat(fmt);
cursor.insertText("formatted");
cursor.setCharFormat({});
cursor.insertText(" after");
const QString output = documentToUnixMarkdown();
#ifdef DEBUG_WRITE_OUTPUT
{
QFile out(QDir::temp().filePath(QLatin1String(QTest::currentDataTag()) + ".md"));
out.open(QFile::WriteOnly);
out.write(output.toUtf8());
out.close();
}
#endif
QCOMPARE(output.trimmed(), expectedOutput);
}
void tst_QTextMarkdownWriter::rewriteDocument_data()
{
QTest::addColumn<QString>("inputFile");