Support quote icon in blockquote.
This commit is contained in:
parent
6e7c4c1c4d
commit
46465fc5ce
4 changed files with 56 additions and 34 deletions
|
|
@ -19,17 +19,24 @@ TextPalette {
|
||||||
linkAlwaysActive: bool;
|
linkAlwaysActive: bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ParagraphStyle {
|
||||||
|
padding: margins;
|
||||||
|
verticalSkip: pixels;
|
||||||
|
header: pixels;
|
||||||
|
headerPosition: point;
|
||||||
|
icon: icon;
|
||||||
|
iconPosition: point;
|
||||||
|
outline: pixels;
|
||||||
|
radius: pixels;
|
||||||
|
scrollable: bool;
|
||||||
|
}
|
||||||
|
|
||||||
TextStyle {
|
TextStyle {
|
||||||
font: font;
|
font: font;
|
||||||
linkUnderline: int;
|
linkUnderline: int;
|
||||||
blockPadding: margins;
|
|
||||||
blockVerticalSkip: pixels;
|
|
||||||
blockHeader: pixels;
|
|
||||||
blockHeaderPosition: point;
|
|
||||||
blockOutline: pixels;
|
|
||||||
blockRadius: pixels;
|
|
||||||
preScrollable: bool;
|
|
||||||
lineHeight: pixels;
|
lineHeight: pixels;
|
||||||
|
blockquote: ParagraphStyle;
|
||||||
|
pre: ParagraphStyle;
|
||||||
}
|
}
|
||||||
|
|
||||||
kLinkUnderlineNever: 0;
|
kLinkUnderlineNever: 0;
|
||||||
|
|
@ -58,10 +65,14 @@ defaultTextPalette: TextPalette {
|
||||||
selectSpoilerFg: msgInDateFgSelected;
|
selectSpoilerFg: msgInDateFgSelected;
|
||||||
selectOverlay: msgSelectOverlay;
|
selectOverlay: msgSelectOverlay;
|
||||||
}
|
}
|
||||||
|
defaultParagraphStyle: ParagraphStyle {
|
||||||
|
}
|
||||||
defaultTextStyle: TextStyle {
|
defaultTextStyle: TextStyle {
|
||||||
font: normalFont;
|
font: normalFont;
|
||||||
linkUnderline: kLinkUnderlineActive;
|
linkUnderline: kLinkUnderlineActive;
|
||||||
lineHeight: 0px;
|
lineHeight: 0px;
|
||||||
|
blockquote: defaultParagraphStyle;
|
||||||
|
pre: defaultParagraphStyle;
|
||||||
}
|
}
|
||||||
semiboldTextStyle: TextStyle(defaultTextStyle) {
|
semiboldTextStyle: TextStyle(defaultTextStyle) {
|
||||||
font: semiboldFont;
|
font: semiboldFont;
|
||||||
|
|
|
||||||
|
|
@ -185,29 +185,34 @@ GeometryDescriptor SimpleGeometry(
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
void ValidateBlockPaintCache(
|
void ValidateBlockPaintCache(
|
||||||
BlockPaintCache &cache,
|
BlockPaintCache &cache,
|
||||||
const style::TextStyle &st) {
|
const style::ParagraphStyle &st) {
|
||||||
|
const auto icon = st.icon.empty() ? nullptr : &st.icon;
|
||||||
if (!cache.corners.isNull()
|
if (!cache.corners.isNull()
|
||||||
&& cache.bgCached == cache.bg
|
&& cache.bgCached == cache.bg
|
||||||
&& cache.outlineCached == cache.outline
|
&& cache.outlineCached == cache.outline
|
||||||
&& (!cache.withHeader || cache.headerCached == cache.header)
|
&& (!st.header || cache.headerCached == cache.header)
|
||||||
&& (!cache.topright || cache.iconCached == cache.icon)) {
|
&& (!icon || cache.iconCached == cache.icon)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
cache.bgCached = cache.bg;
|
cache.bgCached = cache.bg;
|
||||||
cache.outlineCached = cache.outline;
|
cache.outlineCached = cache.outline;
|
||||||
if (cache.withHeader) {
|
if (st.header) {
|
||||||
cache.headerCached = cache.header;
|
cache.headerCached = cache.header;
|
||||||
}
|
}
|
||||||
if (cache.topright) {
|
if (!st.icon.empty()) {
|
||||||
cache.iconCached = cache.icon;
|
cache.iconCached = cache.icon;
|
||||||
}
|
}
|
||||||
const auto radius = st.blockRadius;
|
const auto radius = st.radius;
|
||||||
const auto header = cache.withHeader ? st.blockHeader : 0;
|
const auto header = st.header;
|
||||||
const auto outline = st.blockOutline;
|
const auto outline = st.outline;
|
||||||
const auto corner = std::max({ header, radius, 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 middle = st::lineWidth;
|
||||||
const auto side = 2 * corner + middle;
|
const auto side = 2 * corner + middle;
|
||||||
const auto full = QSize(side, side);
|
const auto full = QSize(side, side);
|
||||||
|
|
@ -233,6 +238,11 @@ void ValidateBlockPaintCache(
|
||||||
p.setBrush(cache.bg);
|
p.setBrush(cache.bg);
|
||||||
p.setClipRect(outline, header, side - outline, side - header);
|
p.setClipRect(outline, header, side - outline, side - header);
|
||||||
p.drawRoundedRect(0, 0, side, side, radius, radius);
|
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();
|
p.end();
|
||||||
cache.corners = std::move(image);
|
cache.corners = std::move(image);
|
||||||
|
|
@ -242,7 +252,7 @@ void FillBlockPaint(
|
||||||
QPainter &p,
|
QPainter &p,
|
||||||
QRect rect,
|
QRect rect,
|
||||||
const BlockPaintCache &cache,
|
const BlockPaintCache &cache,
|
||||||
const style::TextStyle &st,
|
const style::ParagraphStyle &st,
|
||||||
SkipBlockPaintParts parts) {
|
SkipBlockPaintParts parts) {
|
||||||
const auto &image = cache.corners;
|
const auto &image = cache.corners;
|
||||||
const auto ratio = int(image.devicePixelRatio());
|
const auto ratio = int(image.devicePixelRatio());
|
||||||
|
|
@ -265,7 +275,7 @@ void FillBlockPaint(
|
||||||
image,
|
image,
|
||||||
QRect((iwidth - ihalf) * ratio, 0, ihalf * ratio, top * ratio));
|
QRect((iwidth - ihalf) * ratio, 0, ihalf * ratio, top * ratio));
|
||||||
if (const auto middle = width - 2 * ihalf) {
|
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);
|
const auto fillHeader = std::min(header, top);
|
||||||
if (fillHeader) {
|
if (fillHeader) {
|
||||||
p.fillRect(x + ihalf, y, middle, fillHeader, cache.header);
|
p.fillRect(x + ihalf, y, middle, fillHeader, cache.header);
|
||||||
|
|
@ -316,7 +326,7 @@ void FillBlockPaint(
|
||||||
}
|
}
|
||||||
rect.setHeight(height);
|
rect.setHeight(height);
|
||||||
}
|
}
|
||||||
const auto outline = st.blockOutline;
|
const auto outline = st.outline;
|
||||||
if (outline) {
|
if (outline) {
|
||||||
p.fillRect(x, y, outline, height, cache.outline);
|
p.fillRect(x, y, outline, height, cache.outline);
|
||||||
}
|
}
|
||||||
|
|
@ -1086,9 +1096,10 @@ QMargins String::paragraphPadding(ParagraphDetails *info) const {
|
||||||
if (!info) {
|
if (!info) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
const auto skip = _st->blockVerticalSkip;
|
const auto &st = info->pre ? _st->pre : _st->blockquote;
|
||||||
const auto top = info->pre ? _st->blockHeader : 0;
|
const auto skip = st.verticalSkip;
|
||||||
return _st->blockPadding + QMargins(0, top + skip, 0, skip);
|
const auto top = st.header;
|
||||||
|
return st.padding + QMargins(0, top + skip, 0, skip);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <
|
template <
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ enum class type : uchar;
|
||||||
namespace style {
|
namespace style {
|
||||||
struct TextStyle;
|
struct TextStyle;
|
||||||
struct TextPalette;
|
struct TextPalette;
|
||||||
|
struct ParagraphStyle;
|
||||||
} // namespace style
|
} // namespace style
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
|
|
@ -175,15 +176,11 @@ struct BlockPaintCache {
|
||||||
QColor bg;
|
QColor bg;
|
||||||
QColor outline;
|
QColor outline;
|
||||||
QColor icon;
|
QColor icon;
|
||||||
|
|
||||||
const style::icon *topright = nullptr;
|
|
||||||
QPoint toprightPosition;
|
|
||||||
bool withHeader = false;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void ValidateBlockPaintCache(
|
void ValidateBlockPaintCache(
|
||||||
BlockPaintCache &cache,
|
BlockPaintCache &cache,
|
||||||
const style::TextStyle &st);
|
const style::ParagraphStyle &st);
|
||||||
|
|
||||||
struct SkipBlockPaintParts {
|
struct SkipBlockPaintParts {
|
||||||
bool skipTop : 1 = false;
|
bool skipTop : 1 = false;
|
||||||
|
|
@ -193,7 +190,7 @@ void FillBlockPaint(
|
||||||
QPainter &p,
|
QPainter &p,
|
||||||
QRect rect,
|
QRect rect,
|
||||||
const BlockPaintCache &cache,
|
const BlockPaintCache &cache,
|
||||||
const style::TextStyle &st,
|
const style::ParagraphStyle &st,
|
||||||
SkipBlockPaintParts parts = {});
|
SkipBlockPaintParts parts = {});
|
||||||
|
|
||||||
struct PaintContext {
|
struct PaintContext {
|
||||||
|
|
|
||||||
|
|
@ -415,29 +415,32 @@ void Renderer::fillParagraphBg(int paddingBottom) {
|
||||||
? _blockquoteBlockCache
|
? _blockquoteBlockCache
|
||||||
: nullptr;
|
: nullptr;
|
||||||
if (cache) {
|
if (cache) {
|
||||||
|
const auto &st = _paragraph->pre
|
||||||
|
? _t->_st->pre
|
||||||
|
: _t->_st->blockquote;
|
||||||
auto &valid = _paragraph->pre
|
auto &valid = _paragraph->pre
|
||||||
? _preBlockCacheValid
|
? _preBlockCacheValid
|
||||||
: _blockquoteBlockCacheValid;
|
: _blockquoteBlockCacheValid;
|
||||||
if (!valid) {
|
if (!valid) {
|
||||||
valid = true;
|
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 isTop = (_y != _blockLineTop);
|
||||||
const auto isBottom = (paddingBottom != 0);
|
const auto isBottom = (paddingBottom != 0);
|
||||||
const auto top = _blockLineTop + (isTop ? skip : 0);
|
const auto top = _blockLineTop + (isTop ? skip : 0);
|
||||||
const auto fill = _y + _lineHeight + paddingBottom - top
|
const auto fill = _y + _lineHeight + paddingBottom - top
|
||||||
- (isBottom ? skip : 0);
|
- (isBottom ? skip : 0);
|
||||||
const auto rect = QRect(_startLeft, top, _startLineWidth, fill);
|
const auto rect = QRect(_startLeft, top, _startLineWidth, fill);
|
||||||
FillBlockPaint(*_p, rect, *cache, *_t->_st, {
|
FillBlockPaint(*_p, rect, *cache, st, {
|
||||||
.skipTop = !isTop,
|
.skipTop = !isTop,
|
||||||
.skipBottom = !isBottom,
|
.skipBottom = !isBottom,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (isTop && cache->withHeader) {
|
if (isTop && st.header > 0) {
|
||||||
const auto font = _t->_st->font->monospace();
|
const auto font = _t->_st->font->monospace();
|
||||||
const auto topleft = rect.topLeft();
|
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);
|
const auto baseline = position + QPoint(0, font->ascent);
|
||||||
_p->setFont(font);
|
_p->setFont(font);
|
||||||
_p->setPen(_palette->monoFg->p);
|
_p->setPen(_palette->monoFg->p);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue