Count correct initial size for code blocks.

This commit is contained in:
John Preston 2023-10-13 17:27:00 +04:00
parent 46465fc5ce
commit 48012d7f4a
3 changed files with 61 additions and 10 deletions

View file

@ -434,12 +434,15 @@ void String::recountNaturalSize(
auto pindex = paragraphIndex(nullptr);
auto paragraph = paragraphByIndex(pindex);
auto ppadding = paragraphPadding(paragraph);
auto pminwidth = paragraphMinWidth(paragraph);
auto pmaxwidth = QFixed(pminwidth);
auto poldheight = 0;
_maxWidth = 0;
_minHeight = ppadding.top();
auto lineHeight = 0;
auto maxWidth = QFixed();
auto width = QFixed(ppadding.left() + ppadding.right());
auto width = QFixed(pminwidth);
auto last_rBearing = QFixed();
auto last_rPadding = QFixed();
for (auto &block : _blocks) {
@ -453,9 +456,16 @@ void String::recountNaturalSize(
const auto index = paragraphIndex(b);
if (pindex != index) {
_minHeight += ppadding.bottom();
if (paragraph) {
paragraph->maxWidth = pmaxwidth.ceil().toInt();
paragraph->minHeight = _minHeight - poldheight;
}
poldheight = _minHeight;
pindex = index;
paragraph = paragraphByIndex(pindex);
ppadding = paragraphPadding(paragraph);
pminwidth = paragraphMinWidth(paragraph);
pmaxwidth = pminwidth;
_minHeight += ppadding.top();
ppadding.setTop(0);
}
@ -471,7 +481,8 @@ void String::recountNaturalSize(
last_rPadding = 0;// b->f_rpadding(); (0 for newline)
accumulate_max(maxWidth, width);
width = ppadding.left() + ppadding.right();
accumulate_max(pmaxwidth, width);
width = pminwidth;
// + (b->f_width() - last_rBearing); (0 for newline)
continue;
}
@ -486,6 +497,7 @@ void String::recountNaturalSize(
// for all the blocks to fit on their line we check each block, even the
// intermediate one with a large negative right bearing.
accumulate_max(maxWidth, width);
accumulate_max(pmaxwidth, width);
width += last_rBearing + (last_rPadding + b->f_width() - b__f_rbearing);
lineHeight = qMax(lineHeight, blockHeight);
@ -503,9 +515,16 @@ void String::recountNaturalSize(
}
_minHeight += ppadding.top() + lineHeight + ppadding.bottom();
accumulate_max(maxWidth, width);
accumulate_max(pmaxwidth, width);
}
_maxWidth = maxWidth.ceil().toInt();
_endsWithParagraphDetails = (pindex != 0);
if (paragraph) {
paragraph->maxWidth = pmaxwidth.ceil().toInt();
paragraph->minHeight = _minHeight - poldheight;
_endsWithParagraphDetails = true;
} else {
_endsWithParagraphDetails = false;
}
}
int String::countMaxMonospaceWidth() const {
@ -1092,16 +1111,47 @@ int String::paragraphIndex(const AbstractBlock *block) const {
: _startParagraphIndex;
}
const style::ParagraphStyle &String::paragraphStyle(
not_null<ParagraphDetails*> info) const {
return info->pre ? _st->pre : _st->blockquote;
}
QMargins String::paragraphPadding(ParagraphDetails *info) const {
if (!info) {
return {};
}
const auto &st = info->pre ? _st->pre : _st->blockquote;
const auto &st = paragraphStyle(info);
const auto skip = st.verticalSkip;
const auto top = st.header;
return st.padding + QMargins(0, top + skip, 0, skip);
}
int String::paragraphMinWidth(ParagraphDetails *info) const {
if (!info) {
return 0;
}
const auto ppadding = paragraphPadding(info);
const auto &pheader = paragraphHeaderText(info);
const auto pst = info ? &paragraphStyle(info) : nullptr;
return ppadding.left()
+ (pheader.isEmpty() ? 0 : _st->font->monospace()->width(pheader))
+ std::max(
ppadding.right(),
((pst && !pst->icon.empty())
? (pst->iconPosition.x() + pst->icon.width())
: 0));
}
const QString &String::paragraphHeaderText(ParagraphDetails *info) const {
static const auto kEmptyHeader = QString();
static const auto kDefaultHeader = u"code"_q;
return (!info || !info->pre)
? kEmptyHeader
: info->language.isEmpty()
? kDefaultHeader
: info->language;
}
template <
typename AppendPartCallback,
typename ClickHandlerStartCallback,

View file

@ -376,7 +376,12 @@ private:
const TextBlocks::const_iterator &i,
const TextBlocks::const_iterator &e) const;
[[nodiscard]] ParagraphDetails *paragraphByIndex(int index) const;
[[nodiscard]] const style::ParagraphStyle &paragraphStyle(
not_null<ParagraphDetails*> info) const;
[[nodiscard]] QMargins paragraphPadding(ParagraphDetails *info) const;
[[nodiscard]] int paragraphMinWidth(ParagraphDetails *info) const;
[[nodiscard]] const QString &paragraphHeaderText(
ParagraphDetails *info) const;
// block must be either nullptr or a pointer to a NewlineBlock.
[[nodiscard]] int paragraphIndex(const AbstractBlock *block) const;

View file

@ -415,9 +415,7 @@ void Renderer::fillParagraphBg(int paddingBottom) {
? _blockquoteBlockCache
: nullptr;
if (cache) {
const auto &st = _paragraph->pre
? _t->_st->pre
: _t->_st->blockquote;
const auto &st = _t->paragraphStyle(_paragraph);
auto &valid = _paragraph->pre
? _preBlockCacheValid
: _blockquoteBlockCacheValid;
@ -444,9 +442,7 @@ void Renderer::fillParagraphBg(int paddingBottom) {
const auto baseline = position + QPoint(0, font->ascent);
_p->setFont(font);
_p->setPen(_palette->monoFg->p);
_p->drawText(baseline, _paragraph->language.isEmpty()
? u"code"_q
: _paragraph->language);
_p->drawText(baseline, _t->paragraphHeaderText(_paragraph));
}
}
_blockLineTop = _y + _lineHeight + paddingBottom;