Utils: Implement correct font scaling

Since QTextFormat::FontSizeAdjustment is pretty useless as it only
allows setting 6 distinct values (-2 to 3), which correspond to some
predefined scale factors, we need to implement our own font scaling.

Change-Id: Id8df65632ef2af78d46d1e92a58f45a0d15dcca0
Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
This commit is contained in:
Marcus Tillmanns
2024-11-01 13:45:15 +01:00
parent 121bb13cf0
commit ad914c9e62
2 changed files with 71 additions and 35 deletions

View File

@@ -406,19 +406,35 @@ void MarkdownBrowser::setBasePath(const FilePath &filePath)
void MarkdownBrowser::setMarkdown(const QString &markdown)
{
document()->setMarkdown(markdown);
document()->setDefaultFont(Utils::font(contentTF));
postProcessDocument(true);
}
void MarkdownBrowser::postProcessDocument(bool firstTime) const
{
const QFont contentFont = Utils::font(contentTF);
const float fontScale = font().pointSizeF() / qApp->font().pointSizeF();
const auto scaledFont = [fontScale](QFont f) {
f.setPointSizeF(f.pointSizeF() * fontScale);
return f;
};
document()->setDefaultFont(scaledFont(contentFont));
for (QTextBlock block = document()->begin(); block != document()->end(); block = block.next()) {
QTextBlockFormat blockFormat = block.blockFormat();
if (firstTime) {
const QTextBlockFormat blockFormat = block.blockFormat();
// Leave images as they are.
if (block.text().contains(QChar::ObjectReplacementCharacter))
continue;
if (blockFormat.hasProperty(QTextFormat::HeadingLevel)) {
blockFormat.setTopMargin(SpacingTokens::ExVPaddingGapXl);
blockFormat.setBottomMargin(SpacingTokens::VGapL);
// Convert code blocks to highlighted frames
if (blockFormat.hasProperty(QTextFormat::BlockCodeLanguage)) {
const QString language = blockFormat.stringProperty(QTextFormat::BlockCodeLanguage);
highlightCodeBlock(document(), block, language);
continue;
}
// Add anchors to headings. This should actually be done by Qt QTBUG-120518
if (blockFormat.hasProperty(QTextFormat::HeadingLevel)) {
QTextCharFormat cFormat = block.charFormat();
QString anchor;
const QString text = block.text();
@@ -432,35 +448,42 @@ void MarkdownBrowser::setMarkdown(const QString &markdown)
cFormat.setAnchorNames({anchor});
QTextCursor cursor(block);
cursor.setBlockCharFormat(cFormat);
} else
blockFormat.setLineHeight(lineHeight(contentTF), QTextBlockFormat::FixedHeight);
}
}
// Update fonts
QTextCursor cursor(block);
if (blockFormat.hasProperty(QTextFormat::BlockCodeLanguage)) {
QString language = blockFormat.stringProperty(QTextFormat::BlockCodeLanguage);
highlightCodeBlock(document(), block, language);
continue;
auto blockFormat = block.blockFormat();
const auto scaledFont = [fontScale](QFont f) {
f.setPointSizeF(f.pointSizeF() * fontScale);
return f;
};
if (blockFormat.hasProperty(QTextFormat::HeadingLevel)) {
blockFormat.setTopMargin(SpacingTokens::ExVPaddingGapXl * fontScale);
blockFormat.setBottomMargin(SpacingTokens::VGapL * fontScale);
} else {
blockFormat
.setLineHeight(lineHeight(contentTF) * fontScale, QTextBlockFormat::FixedHeight);
}
cursor.mergeBlockFormat(blockFormat);
const TextFormat &headingTf
= markdownHeadingFormats[qBound(0, blockFormat.headingLevel() - 1, 5)];
const QFont headingFont = Utils::font(headingTf);
const QFont headingFont = scaledFont(Utils::font(headingTf));
for (auto it = block.begin(); !(it.atEnd()); ++it) {
QTextFragment fragment = it.fragment();
const QTextFragment fragment = it.fragment();
if (fragment.isValid()) {
QTextCharFormat charFormat = fragment.charFormat();
cursor.setPosition(fragment.position());
cursor.setPosition(fragment.position() + fragment.length(), QTextCursor::KeepAnchor);
if (blockFormat.hasProperty(QTextFormat::HeadingLevel)) {
// Change font size adjustment to resemble the heading font size
// (We want the font size to be relative to the default font size,
// otherwise the heading size won't respect the font scale factor)
charFormat.setProperty(
QTextFormat::FontSizeAdjustment,
headingFont.pointSizeF() / document()->defaultFont().pointSizeF());
// We don't use font size adjustment for headings
charFormat.clearProperty(QTextFormat::FontSizeAdjustment);
charFormat.setFontPointSize(headingFont.pointSizeF());
charFormat.setFontCapitalization(headingFont.capitalization());
charFormat.setFontFamilies(headingFont.families());
charFormat.setFontWeight(headingFont.weight());
@@ -476,6 +499,13 @@ void MarkdownBrowser::setMarkdown(const QString &markdown)
}
}
void MarkdownBrowser::changeEvent(QEvent *event)
{
if (event->type() == QEvent::FontChange)
postProcessDocument(false);
QTextBrowser::changeEvent(event);
}
} // namespace Utils
#include "markdownbrowser.moc"

View File

@@ -24,6 +24,12 @@ public:
QSize sizeHint() const override;
QSize minimumSizeHint() const override;
protected:
void changeEvent(QEvent *event) override;
private:
void postProcessDocument(bool firstTime) const;
};
} // namespace Utils