forked from qt-creator/qt-creator
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:
@@ -406,19 +406,35 @@ void MarkdownBrowser::setBasePath(const FilePath &filePath)
|
|||||||
void MarkdownBrowser::setMarkdown(const QString &markdown)
|
void MarkdownBrowser::setMarkdown(const QString &markdown)
|
||||||
{
|
{
|
||||||
document()->setMarkdown(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()) {
|
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.
|
// Leave images as they are.
|
||||||
if (block.text().contains(QChar::ObjectReplacementCharacter))
|
if (block.text().contains(QChar::ObjectReplacementCharacter))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (blockFormat.hasProperty(QTextFormat::HeadingLevel)) {
|
// Convert code blocks to highlighted frames
|
||||||
blockFormat.setTopMargin(SpacingTokens::ExVPaddingGapXl);
|
if (blockFormat.hasProperty(QTextFormat::BlockCodeLanguage)) {
|
||||||
blockFormat.setBottomMargin(SpacingTokens::VGapL);
|
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
|
// Add anchors to headings. This should actually be done by Qt QTBUG-120518
|
||||||
|
if (blockFormat.hasProperty(QTextFormat::HeadingLevel)) {
|
||||||
QTextCharFormat cFormat = block.charFormat();
|
QTextCharFormat cFormat = block.charFormat();
|
||||||
QString anchor;
|
QString anchor;
|
||||||
const QString text = block.text();
|
const QString text = block.text();
|
||||||
@@ -432,35 +448,42 @@ void MarkdownBrowser::setMarkdown(const QString &markdown)
|
|||||||
cFormat.setAnchorNames({anchor});
|
cFormat.setAnchorNames({anchor});
|
||||||
QTextCursor cursor(block);
|
QTextCursor cursor(block);
|
||||||
cursor.setBlockCharFormat(cFormat);
|
cursor.setBlockCharFormat(cFormat);
|
||||||
} else
|
}
|
||||||
blockFormat.setLineHeight(lineHeight(contentTF), QTextBlockFormat::FixedHeight);
|
}
|
||||||
|
|
||||||
|
// Update fonts
|
||||||
QTextCursor cursor(block);
|
QTextCursor cursor(block);
|
||||||
if (blockFormat.hasProperty(QTextFormat::BlockCodeLanguage)) {
|
auto blockFormat = block.blockFormat();
|
||||||
QString language = blockFormat.stringProperty(QTextFormat::BlockCodeLanguage);
|
|
||||||
highlightCodeBlock(document(), block, language);
|
const auto scaledFont = [fontScale](QFont f) {
|
||||||
continue;
|
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);
|
cursor.mergeBlockFormat(blockFormat);
|
||||||
|
|
||||||
const TextFormat &headingTf
|
const TextFormat &headingTf
|
||||||
= markdownHeadingFormats[qBound(0, blockFormat.headingLevel() - 1, 5)];
|
= 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) {
|
for (auto it = block.begin(); !(it.atEnd()); ++it) {
|
||||||
QTextFragment fragment = it.fragment();
|
const QTextFragment fragment = it.fragment();
|
||||||
if (fragment.isValid()) {
|
if (fragment.isValid()) {
|
||||||
QTextCharFormat charFormat = fragment.charFormat();
|
QTextCharFormat charFormat = fragment.charFormat();
|
||||||
cursor.setPosition(fragment.position());
|
cursor.setPosition(fragment.position());
|
||||||
cursor.setPosition(fragment.position() + fragment.length(), QTextCursor::KeepAnchor);
|
cursor.setPosition(fragment.position() + fragment.length(), QTextCursor::KeepAnchor);
|
||||||
if (blockFormat.hasProperty(QTextFormat::HeadingLevel)) {
|
if (blockFormat.hasProperty(QTextFormat::HeadingLevel)) {
|
||||||
// Change font size adjustment to resemble the heading font size
|
// We don't use font size adjustment for headings
|
||||||
// (We want the font size to be relative to the default font size,
|
charFormat.clearProperty(QTextFormat::FontSizeAdjustment);
|
||||||
// otherwise the heading size won't respect the font scale factor)
|
charFormat.setFontPointSize(headingFont.pointSizeF());
|
||||||
charFormat.setProperty(
|
|
||||||
QTextFormat::FontSizeAdjustment,
|
|
||||||
headingFont.pointSizeF() / document()->defaultFont().pointSizeF());
|
|
||||||
|
|
||||||
charFormat.setFontCapitalization(headingFont.capitalization());
|
charFormat.setFontCapitalization(headingFont.capitalization());
|
||||||
charFormat.setFontFamilies(headingFont.families());
|
charFormat.setFontFamilies(headingFont.families());
|
||||||
charFormat.setFontWeight(headingFont.weight());
|
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
|
} // namespace Utils
|
||||||
|
|
||||||
#include "markdownbrowser.moc"
|
#include "markdownbrowser.moc"
|
||||||
|
@@ -24,6 +24,12 @@ public:
|
|||||||
|
|
||||||
QSize sizeHint() const override;
|
QSize sizeHint() const override;
|
||||||
QSize minimumSizeHint() const override;
|
QSize minimumSizeHint() const override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void changeEvent(QEvent *event) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void postProcessDocument(bool firstTime) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Utils
|
} // namespace Utils
|
||||||
|
Reference in New Issue
Block a user