Support quote icon in blockquote.

This commit is contained in:
John Preston 2023-10-13 16:13:08 +04:00
parent 6e7c4c1c4d
commit 46465fc5ce
4 changed files with 56 additions and 34 deletions

View file

@ -19,17 +19,24 @@ TextPalette {
linkAlwaysActive: bool;
}
ParagraphStyle {
padding: margins;
verticalSkip: pixels;
header: pixels;
headerPosition: point;
icon: icon;
iconPosition: point;
outline: pixels;
radius: pixels;
scrollable: bool;
}
TextStyle {
font: font;
linkUnderline: int;
blockPadding: margins;
blockVerticalSkip: pixels;
blockHeader: pixels;
blockHeaderPosition: point;
blockOutline: pixels;
blockRadius: pixels;
preScrollable: bool;
lineHeight: pixels;
blockquote: ParagraphStyle;
pre: ParagraphStyle;
}
kLinkUnderlineNever: 0;
@ -58,10 +65,14 @@ defaultTextPalette: TextPalette {
selectSpoilerFg: msgInDateFgSelected;
selectOverlay: msgSelectOverlay;
}
defaultParagraphStyle: ParagraphStyle {
}
defaultTextStyle: TextStyle {
font: normalFont;
linkUnderline: kLinkUnderlineActive;
lineHeight: 0px;
blockquote: defaultParagraphStyle;
pre: defaultParagraphStyle;
}
semiboldTextStyle: TextStyle(defaultTextStyle) {
font: semiboldFont;

View file

@ -185,29 +185,34 @@ GeometryDescriptor SimpleGeometry(
}
};
void ValidateBlockPaintCache(
BlockPaintCache &cache,
const style::TextStyle &st) {
const style::ParagraphStyle &st) {
const auto icon = st.icon.empty() ? nullptr : &st.icon;
if (!cache.corners.isNull()
&& cache.bgCached == cache.bg
&& cache.outlineCached == cache.outline
&& (!cache.withHeader || cache.headerCached == cache.header)
&& (!cache.topright || cache.iconCached == cache.icon)) {
&& (!st.header || cache.headerCached == cache.header)
&& (!icon || cache.iconCached == cache.icon)) {
return;
}
cache.bgCached = cache.bg;
cache.outlineCached = cache.outline;
if (cache.withHeader) {
if (st.header) {
cache.headerCached = cache.header;
}
if (cache.topright) {
if (!st.icon.empty()) {
cache.iconCached = cache.icon;
}
const auto radius = st.blockRadius;
const auto header = cache.withHeader ? st.blockHeader : 0;
const auto outline = st.blockOutline;
const auto corner = std::max({ header, radius, outline });
const auto radius = st.radius;
const auto header = st.header;
const auto outline = st.outline;
const auto iconsize = icon
? std::max(
icon->width() + st.iconPosition.x(),
icon->height() + st.iconPosition.y())
: 0;
const auto corner = std::max({ header, radius, outline, iconsize });
const auto middle = st::lineWidth;
const auto side = 2 * corner + middle;
const auto full = QSize(side, side);
@ -233,6 +238,11 @@ void ValidateBlockPaintCache(
p.setBrush(cache.bg);
p.setClipRect(outline, header, side - outline, side - header);
p.drawRoundedRect(0, 0, side, side, radius, radius);
if (icon) {
const auto left = side - icon->width() - st.iconPosition.x();
const auto top = st.iconPosition.y();
icon->paint(p, left, top, side, cache.icon);
}
p.end();
cache.corners = std::move(image);
@ -242,7 +252,7 @@ void FillBlockPaint(
QPainter &p,
QRect rect,
const BlockPaintCache &cache,
const style::TextStyle &st,
const style::ParagraphStyle &st,
SkipBlockPaintParts parts) {
const auto &image = cache.corners;
const auto ratio = int(image.devicePixelRatio());
@ -265,7 +275,7 @@ void FillBlockPaint(
image,
QRect((iwidth - ihalf) * ratio, 0, ihalf * ratio, top * ratio));
if (const auto middle = width - 2 * ihalf) {
const auto header = cache.withHeader ? st.blockHeader : 0;
const auto header = st.header;
const auto fillHeader = std::min(header, top);
if (fillHeader) {
p.fillRect(x + ihalf, y, middle, fillHeader, cache.header);
@ -316,7 +326,7 @@ void FillBlockPaint(
}
rect.setHeight(height);
}
const auto outline = st.blockOutline;
const auto outline = st.outline;
if (outline) {
p.fillRect(x, y, outline, height, cache.outline);
}
@ -1086,9 +1096,10 @@ QMargins String::paragraphPadding(ParagraphDetails *info) const {
if (!info) {
return {};
}
const auto skip = _st->blockVerticalSkip;
const auto top = info->pre ? _st->blockHeader : 0;
return _st->blockPadding + QMargins(0, top + skip, 0, skip);
const auto &st = info->pre ? _st->pre : _st->blockquote;
const auto skip = st.verticalSkip;
const auto top = st.header;
return st.padding + QMargins(0, top + skip, 0, skip);
}
template <

View file

@ -24,6 +24,7 @@ enum class type : uchar;
namespace style {
struct TextStyle;
struct TextPalette;
struct ParagraphStyle;
} // namespace style
namespace Ui {
@ -175,15 +176,11 @@ struct BlockPaintCache {
QColor bg;
QColor outline;
QColor icon;
const style::icon *topright = nullptr;
QPoint toprightPosition;
bool withHeader = false;
};
void ValidateBlockPaintCache(
BlockPaintCache &cache,
const style::TextStyle &st);
const style::ParagraphStyle &st);
struct SkipBlockPaintParts {
bool skipTop : 1 = false;
@ -193,7 +190,7 @@ void FillBlockPaint(
QPainter &p,
QRect rect,
const BlockPaintCache &cache,
const style::TextStyle &st,
const style::ParagraphStyle &st,
SkipBlockPaintParts parts = {});
struct PaintContext {

View file

@ -415,29 +415,32 @@ void Renderer::fillParagraphBg(int paddingBottom) {
? _blockquoteBlockCache
: nullptr;
if (cache) {
const auto &st = _paragraph->pre
? _t->_st->pre
: _t->_st->blockquote;
auto &valid = _paragraph->pre
? _preBlockCacheValid
: _blockquoteBlockCacheValid;
if (!valid) {
valid = true;
ValidateBlockPaintCache(*cache, *_t->_st);
ValidateBlockPaintCache(*cache, st);
}
const auto skip = _t->_st->blockVerticalSkip;
const auto skip = st.verticalSkip;
const auto isTop = (_y != _blockLineTop);
const auto isBottom = (paddingBottom != 0);
const auto top = _blockLineTop + (isTop ? skip : 0);
const auto fill = _y + _lineHeight + paddingBottom - top
- (isBottom ? skip : 0);
const auto rect = QRect(_startLeft, top, _startLineWidth, fill);
FillBlockPaint(*_p, rect, *cache, *_t->_st, {
FillBlockPaint(*_p, rect, *cache, st, {
.skipTop = !isTop,
.skipBottom = !isBottom,
});
if (isTop && cache->withHeader) {
if (isTop && st.header > 0) {
const auto font = _t->_st->font->monospace();
const auto topleft = rect.topLeft();
const auto position = topleft + _t->_st->blockHeaderPosition;
const auto position = topleft + st.headerPosition;
const auto baseline = position + QPoint(0, font->ascent);
_p->setFont(font);
_p->setPen(_palette->monoFg->p);