Improve very small quote areas with icons.
This commit is contained in:
		
							parent
							
								
									611224c52f
								
							
						
					
					
						commit
						272a23e9bc
					
				
					 1 changed files with 45 additions and 41 deletions
				
			
		| 
						 | 
					@ -207,15 +207,18 @@ void ValidateQuotePaintCache(
 | 
				
			||||||
	const auto radius = st.radius;
 | 
						const auto radius = st.radius;
 | 
				
			||||||
	const auto header = st.header;
 | 
						const auto header = st.header;
 | 
				
			||||||
	const auto outline = st.outline;
 | 
						const auto outline = st.outline;
 | 
				
			||||||
	const auto iconsize = icon
 | 
						const auto wiconsize = icon
 | 
				
			||||||
		? std::max(
 | 
							? (icon->width() + st.iconPosition.x())
 | 
				
			||||||
			icon->width() + st.iconPosition.x(),
 | 
					 | 
				
			||||||
			icon->height() + st.iconPosition.y())
 | 
					 | 
				
			||||||
		: 0;
 | 
							: 0;
 | 
				
			||||||
	const auto corner = std::max({ header, radius, outline, iconsize });
 | 
						const auto hiconsize = icon
 | 
				
			||||||
 | 
							? (icon->height() + st.iconPosition.y())
 | 
				
			||||||
 | 
							: 0;
 | 
				
			||||||
 | 
						const auto wcorner = std::max({ radius, outline, wiconsize });
 | 
				
			||||||
 | 
						const auto hcorner = std::max({ header, radius, hiconsize });
 | 
				
			||||||
	const auto middle = st::lineWidth;
 | 
						const auto middle = st::lineWidth;
 | 
				
			||||||
	const auto side = 2 * corner + middle;
 | 
						const auto wside = 2 * wcorner + middle;
 | 
				
			||||||
	const auto full = QSize(side, side);
 | 
						const auto hside = 2 * hcorner + middle;
 | 
				
			||||||
 | 
						const auto full = QSize(wside, hside);
 | 
				
			||||||
	const auto ratio = style::DevicePixelRatio();
 | 
						const auto ratio = style::DevicePixelRatio();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!cache.outlines[1].alpha()) {
 | 
						if (!cache.outlines[1].alpha()) {
 | 
				
			||||||
| 
						 | 
					@ -258,32 +261,32 @@ void ValidateQuotePaintCache(
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (header) {
 | 
						if (header) {
 | 
				
			||||||
		p.setBrush(cache.header);
 | 
							p.setBrush(cache.header);
 | 
				
			||||||
		p.setClipRect(outline, 0, side - outline, header);
 | 
							p.setClipRect(outline, 0, wside - outline, header);
 | 
				
			||||||
		p.drawRoundedRect(0, 0, side, corner + radius, radius, radius);
 | 
							p.drawRoundedRect(0, 0, wside, hcorner + radius, radius, radius);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (outline) {
 | 
						if (outline) {
 | 
				
			||||||
		const auto rect = QRect(0, 0, outline + radius * 2, side);
 | 
							const auto rect = QRect(0, 0, outline + radius * 2, hside);
 | 
				
			||||||
		if (!cache.outline.isNull()) {
 | 
							if (!cache.outline.isNull()) {
 | 
				
			||||||
			const auto shift = QPoint(0, st.outlineShift);
 | 
								const auto shift = QPoint(0, st.outlineShift);
 | 
				
			||||||
			p.translate(shift);
 | 
								p.translate(shift);
 | 
				
			||||||
			p.setBrush(cache.outline);
 | 
								p.setBrush(cache.outline);
 | 
				
			||||||
			p.setClipRect(QRect(-shift, QSize(outline, side)));
 | 
								p.setClipRect(QRect(-shift, QSize(outline, hside)));
 | 
				
			||||||
			p.drawRoundedRect(rect.translated(-shift), radius, radius);
 | 
								p.drawRoundedRect(rect.translated(-shift), radius, radius);
 | 
				
			||||||
			p.translate(-shift);
 | 
								p.translate(-shift);
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			p.setBrush(cache.outlines[0]);
 | 
								p.setBrush(cache.outlines[0]);
 | 
				
			||||||
			p.setClipRect(0, 0, outline, side);
 | 
								p.setClipRect(0, 0, outline, hside);
 | 
				
			||||||
			p.drawRoundedRect(rect, radius, radius);
 | 
								p.drawRoundedRect(rect, radius, radius);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	p.setBrush(cache.bg);
 | 
						p.setBrush(cache.bg);
 | 
				
			||||||
	p.setClipRect(outline, header, side - outline, side - header);
 | 
						p.setClipRect(outline, header, wside - outline, hside - header);
 | 
				
			||||||
	p.drawRoundedRect(0, 0, side, side, radius, radius);
 | 
						p.drawRoundedRect(0, 0, wside, hside, radius, radius);
 | 
				
			||||||
	if (icon) {
 | 
						if (icon) {
 | 
				
			||||||
		p.setClipping(false);
 | 
							p.setClipping(false);
 | 
				
			||||||
		const auto left = side - icon->width() - st.iconPosition.x();
 | 
							const auto left = wside - icon->width() - st.iconPosition.x();
 | 
				
			||||||
		const auto top = st.iconPosition.y();
 | 
							const auto top = st.iconPosition.y();
 | 
				
			||||||
		icon->paint(p, left, top, side, cache.icon);
 | 
							icon->paint(p, left, top, wside, cache.icon);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	p.end();
 | 
						p.end();
 | 
				
			||||||
| 
						 | 
					@ -301,30 +304,31 @@ void FillQuotePaint(
 | 
				
			||||||
	const auto iwidth = image.width() / ratio;
 | 
						const auto iwidth = image.width() / ratio;
 | 
				
			||||||
	const auto iheight = image.height() / ratio;
 | 
						const auto iheight = image.height() / ratio;
 | 
				
			||||||
	const auto imiddle = st::lineWidth;
 | 
						const auto imiddle = st::lineWidth;
 | 
				
			||||||
	const auto ihalf = (iheight - imiddle) / 2;
 | 
						const auto whalf = (iwidth - imiddle) / 2;
 | 
				
			||||||
 | 
						const auto hhalf = (iheight - imiddle) / 2;
 | 
				
			||||||
	const auto x = rect.left();
 | 
						const auto x = rect.left();
 | 
				
			||||||
	const auto width = rect.width();
 | 
						const auto width = rect.width();
 | 
				
			||||||
	auto y = rect.top();
 | 
						auto y = rect.top();
 | 
				
			||||||
	auto height = rect.height();
 | 
						auto height = rect.height();
 | 
				
			||||||
	if (!parts.skippedTop) {
 | 
						if (!parts.skippedTop) {
 | 
				
			||||||
		const auto top = std::min(height, ihalf);
 | 
							const auto top = std::min(height, hhalf);
 | 
				
			||||||
		p.drawImage(
 | 
							p.drawImage(
 | 
				
			||||||
			QRect(x, y, ihalf, top),
 | 
								QRect(x, y, whalf, top),
 | 
				
			||||||
			image,
 | 
								image,
 | 
				
			||||||
			QRect(0, 0, ihalf * ratio, top * ratio));
 | 
								QRect(0, 0, whalf * ratio, top * ratio));
 | 
				
			||||||
		p.drawImage(
 | 
							p.drawImage(
 | 
				
			||||||
			QRect(x + width - ihalf, y, ihalf, top),
 | 
								QRect(x + width - whalf, y, whalf, top),
 | 
				
			||||||
			image,
 | 
								image,
 | 
				
			||||||
			QRect((iwidth - ihalf) * ratio, 0, ihalf * ratio, top * ratio));
 | 
								QRect((iwidth - whalf) * ratio, 0, whalf * ratio, top * ratio));
 | 
				
			||||||
		if (const auto middle = width - 2 * ihalf) {
 | 
							if (const auto middle = width - 2 * whalf) {
 | 
				
			||||||
			const auto header = st.header;
 | 
								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 + whalf, y, middle, fillHeader, cache.header);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if (const auto fillBody = top - fillHeader) {
 | 
								if (const auto fillBody = top - fillHeader) {
 | 
				
			||||||
				p.fillRect(
 | 
									p.fillRect(
 | 
				
			||||||
					QRect(x + ihalf, y + fillHeader, middle, fillBody),
 | 
										QRect(x + whalf, y + fillHeader, middle, fillBody),
 | 
				
			||||||
					cache.bg);
 | 
										cache.bg);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -337,43 +341,43 @@ void FillQuotePaint(
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	const auto outline = st.outline;
 | 
						const auto outline = st.outline;
 | 
				
			||||||
	if (!parts.skipBottom) {
 | 
						if (!parts.skipBottom) {
 | 
				
			||||||
		const auto bottom = std::min(height, ihalf);
 | 
							const auto bottom = std::min(height, hhalf);
 | 
				
			||||||
		const auto skip = !cache.outline.isNull() ? outline : 0;
 | 
							const auto skip = !cache.outline.isNull() ? outline : 0;
 | 
				
			||||||
		p.drawImage(
 | 
							p.drawImage(
 | 
				
			||||||
			QRect(x + skip, y + height - bottom, ihalf - skip, bottom),
 | 
								QRect(x + skip, y + height - bottom, whalf - skip, bottom),
 | 
				
			||||||
			image,
 | 
								image,
 | 
				
			||||||
			QRect(
 | 
								QRect(
 | 
				
			||||||
				skip * ratio,
 | 
									skip * ratio,
 | 
				
			||||||
				(iheight - bottom) * ratio,
 | 
									(iheight - bottom) * ratio,
 | 
				
			||||||
				(ihalf - skip) * ratio,
 | 
									(whalf - skip) * ratio,
 | 
				
			||||||
				bottom * ratio));
 | 
									bottom * ratio));
 | 
				
			||||||
		p.drawImage(
 | 
							p.drawImage(
 | 
				
			||||||
			QRect(
 | 
								QRect(
 | 
				
			||||||
				x + width - ihalf,
 | 
									x + width - whalf,
 | 
				
			||||||
				y + height - bottom,
 | 
									y + height - bottom,
 | 
				
			||||||
				ihalf,
 | 
									whalf,
 | 
				
			||||||
				bottom),
 | 
									bottom),
 | 
				
			||||||
			image,
 | 
								image,
 | 
				
			||||||
			QRect(
 | 
								QRect(
 | 
				
			||||||
				(iwidth - ihalf) * ratio,
 | 
									(iwidth - whalf) * ratio,
 | 
				
			||||||
				(iheight - bottom) * ratio,
 | 
									(iheight - bottom) * ratio,
 | 
				
			||||||
				ihalf * ratio,
 | 
									whalf * ratio,
 | 
				
			||||||
				bottom * ratio));
 | 
									bottom * ratio));
 | 
				
			||||||
		if (const auto middle = width - 2 * ihalf) {
 | 
							if (const auto middle = width - 2 * whalf) {
 | 
				
			||||||
			p.fillRect(
 | 
								p.fillRect(
 | 
				
			||||||
				QRect(x + ihalf, y + height - bottom, middle, bottom),
 | 
									QRect(x + whalf, y + height - bottom, middle, bottom),
 | 
				
			||||||
				cache.bg);
 | 
									cache.bg);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if (skip) {
 | 
							if (skip) {
 | 
				
			||||||
			if (cache.bottomCorner.size() != QSize(skip, ihalf)) {
 | 
								if (cache.bottomCorner.size() != QSize(skip, whalf)) {
 | 
				
			||||||
				cache.bottomCorner = QImage(
 | 
									cache.bottomCorner = QImage(
 | 
				
			||||||
					QSize(skip, ihalf) * ratio,
 | 
										QSize(skip, hhalf) * ratio,
 | 
				
			||||||
					QImage::Format_ARGB32_Premultiplied);
 | 
										QImage::Format_ARGB32_Premultiplied);
 | 
				
			||||||
				cache.bottomCorner.setDevicePixelRatio(ratio);
 | 
									cache.bottomCorner.setDevicePixelRatio(ratio);
 | 
				
			||||||
				cache.bottomCorner.fill(Qt::transparent);
 | 
									cache.bottomCorner.fill(Qt::transparent);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				cache.bottomRounding = QImage(
 | 
									cache.bottomRounding = QImage(
 | 
				
			||||||
					QSize(skip, ihalf) * ratio,
 | 
										QSize(skip, hhalf) * ratio,
 | 
				
			||||||
					QImage::Format_ARGB32_Premultiplied);
 | 
										QImage::Format_ARGB32_Premultiplied);
 | 
				
			||||||
				cache.bottomRounding.setDevicePixelRatio(ratio);
 | 
									cache.bottomRounding.setDevicePixelRatio(ratio);
 | 
				
			||||||
				cache.bottomRounding.fill(Qt::transparent);
 | 
									cache.bottomRounding.fill(Qt::transparent);
 | 
				
			||||||
| 
						 | 
					@ -386,18 +390,18 @@ void FillQuotePaint(
 | 
				
			||||||
					0,
 | 
										0,
 | 
				
			||||||
					-2 * radius,
 | 
										-2 * radius,
 | 
				
			||||||
					skip + 2 * radius,
 | 
										skip + 2 * radius,
 | 
				
			||||||
					ihalf + 2 * radius,
 | 
										hhalf + 2 * radius,
 | 
				
			||||||
					radius,
 | 
										radius,
 | 
				
			||||||
					radius);
 | 
										radius);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			auto q = QPainter(&cache.bottomCorner);
 | 
								auto q = QPainter(&cache.bottomCorner);
 | 
				
			||||||
			const auto skipped = (height - bottom)
 | 
								const auto skipped = (height - bottom)
 | 
				
			||||||
				+ (parts.skippedTop ? int(parts.skippedTop) : ihalf)
 | 
									+ (parts.skippedTop ? int(parts.skippedTop) : hhalf)
 | 
				
			||||||
				- st.outlineShift;
 | 
									- st.outlineShift;
 | 
				
			||||||
			q.translate(0, -skipped);
 | 
								q.translate(0, -skipped);
 | 
				
			||||||
			q.fillRect(0, skipped, skip, bottom, cache.outline);
 | 
								q.fillRect(0, skipped, skip, bottom, cache.outline);
 | 
				
			||||||
			q.setCompositionMode(QPainter::CompositionMode_DestinationIn);
 | 
								q.setCompositionMode(QPainter::CompositionMode_DestinationIn);
 | 
				
			||||||
			q.drawImage(0, skipped + bottom - ihalf, cache.bottomRounding);
 | 
								q.drawImage(0, skipped + bottom - hhalf, cache.bottomRounding);
 | 
				
			||||||
			q.end();
 | 
								q.end();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			p.drawImage(
 | 
								p.drawImage(
 | 
				
			||||||
| 
						 | 
					@ -414,7 +418,7 @@ void FillQuotePaint(
 | 
				
			||||||
	if (outline) {
 | 
						if (outline) {
 | 
				
			||||||
		if (!cache.outline.isNull()) {
 | 
							if (!cache.outline.isNull()) {
 | 
				
			||||||
			const auto skipped = st.outlineShift
 | 
								const auto skipped = st.outlineShift
 | 
				
			||||||
				- (parts.skippedTop ? int(parts.skippedTop) : ihalf);
 | 
									- (parts.skippedTop ? int(parts.skippedTop) : hhalf);
 | 
				
			||||||
			const auto top = y + skipped;
 | 
								const auto top = y + skipped;
 | 
				
			||||||
			p.translate(x, top);
 | 
								p.translate(x, top);
 | 
				
			||||||
			p.fillRect(0, -skipped, outline, height, cache.outline);
 | 
								p.fillRect(0, -skipped, outline, height, cache.outline);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue