35 LOG(VB_GENERAL, LOG_WARNING,
36 QString(
"MythPainter: %1 images not yet de-allocated.")
41 image->SetParent(
nullptr);
61 LOG(VB_GENERAL, LOG_ERR,
62 "Null image pointer passed to MythPainter::DrawImage()");
65 QRect
dest = QRect(x, y, im->width(), im->height());
66 QRect src = im->rect();
72 DrawImage(topLeft.x(), topLeft.y(), im, alpha);
77 int alpha,
const QRect boundRect)
83 QRect destRect(boundRect);
84 QRect srcRect(0,0,r.width(),r.height());
85 if (!boundRect.isEmpty() && boundRect != r)
89 int width = boundRect.width();
90 int height = boundRect.height();
92 if (boundRect.x() > r.x())
94 x = boundRect.x()-r.x();
96 else if (r.x() > boundRect.x())
99 width = (boundRect.x() + boundRect.width()) - r.x();
102 if (boundRect.y() > r.y())
104 y = boundRect.y()-r.y();
106 else if (r.y() > boundRect.y())
108 destRect.setY(r.y());
109 height = (boundRect.y() + boundRect.height()) - r.y();
112 if (width <= 0 || height <= 0)
115 srcRect.setRect(x,y,width,height);
126 const QRect destRect)
128 if (canvasRect.isNull())
131 QRect canvas(canvasRect);
132 QRect
dest(destRect);
138 LOG(VB_GENERAL, LOG_ERR, QString(
"MythPainter::DrawTextLayout: "
139 "Unable to create image."));
144 LOG(VB_GENERAL, LOG_DEBUG, QString(
"MythPainter::DrawTextLayout: "
145 "Rendered image is null."));
150 QRect srcRect(0, 0,
dest.width(),
dest.height());
157 const QPen &linePen,
int alpha)
162 DrawImage(area.x(), area.y(), im, alpha);
168 const QBrush &fillBrush,
const QPen &linePen,
174 DrawImage(area.x(), area.y(), im, alpha);
180 const QPen &linePen,
int alpha)
185 DrawImage(area.x(), area.y(), im, alpha);
198 int outlineAlpha = 255;
200 font.
GetOutline(outlineColor, outlineSize, outlineAlpha);
202 QPoint shadowOffset(0, 0);
204 int shadowAlpha = 255;
206 font.
GetShadow(shadowOffset, shadowColor, shadowAlpha);
208 QFontMetrics fm(font.
face());
209 int totalHeight = fm.height() + outlineSize +
210 std::max(outlineSize, std::abs(shadowOffset.y()));
215 int initialPaddingX = 0;
220 int initialPaddingY = (r.height() - totalHeight) / 2;
229 if (flags & Qt::TextWordWrap)
236 initialPaddingX + std::max(outlineSize, -shadowOffset.x());
242 initialPaddingY + std::max(outlineSize, -shadowOffset.y());
244 QImage pm(r.size(), QImage::Format_ARGB32);
245 QColor fillcolor = font.
color();
247 fillcolor = outlineColor;
248 fillcolor.setAlpha(0);
249 pm.fill(fillcolor.rgba());
252 QFont tmpfont = font.
face();
253 tmp.setFont(tmpfont);
257 path.addText(0, 0, tmpfont, msg);
261 QRect a = QRect(0, 0, r.width(), r.height());
262 a.translate(shadowOffset.x() + textOffsetX,
263 shadowOffset.y() + textOffsetY);
265 shadowColor.setAlpha(shadowAlpha);
266 tmp.setPen(shadowColor);
267 tmp.drawText(a, flags, msg);
278 int adjY = fm.ascent();
280 outlineColor.setAlpha(outlineAlpha);
281 tmp.setPen(outlineColor);
283 path.translate(adjX + textOffsetX, adjY + textOffsetY);
284 QPen pen =
tmp.pen();
285 pen.setWidth((outlineSize * 2) + 1);
286 pen.setCapStyle(Qt::RoundCap);
287 pen.setJoinStyle(Qt::RoundJoin);
291 path.translate(outlineSize, outlineSize);
296 tmp.drawText(textOffsetX, textOffsetY, r.width(), r.height(),
304 const QBrush &fillBrush,
const QPen &linePen)
309 QImage image(QSize(area.width(), area.height()), QImage::Format_ARGB32);
310 image.fill(0x00000000);
311 QPainter painter(&image);
312 painter.setRenderHint(QPainter::Antialiasing);
313 painter.setPen(linePen);
314 painter.setBrush(fillBrush);
316 radius = std::min(area.width() / 2, radius);
317 radius = std::min(area.height() / 2, radius);
319 int lineWidth = linePen.width();
320 QRect r(lineWidth, lineWidth,
321 area.width() - (lineWidth * 2), area.height() - (lineWidth * 2));
324 painter.drawEllipse(r);
325 else if (radius == 0)
328 painter.drawRoundedRect(r, (qreal)radius, qreal(radius));
335 int flags,
const QRect r,
338 QString incoming = font.
GetHash() + QString::number(r.width()) +
339 QString::number(r.height()) +
340 QString::number(flags) +
341 QString::number(font.
color().rgba()) + msg;
355 im->
SetFileName(QString(
"GetImageFromString: %1").arg(msg));
370 QRect &canvas, QRect &
dest)
372 QString incoming = QString::number(canvas.x()) +
373 QString::number(canvas.y()) +
374 QString::number(canvas.width()) +
375 QString::number(canvas.height()) +
376 QString::number(
dest.width()) +
377 QString::number(
dest.height()) +
380 for (
auto *layout : std::as_const(layouts))
381 incoming += layout->text();
397 QImage pm(canvas.size(), QImage::Format_ARGB32_Premultiplied);
400 QPainter painter(&pm);
401 if (!painter.isActive())
403 LOG(VB_GENERAL, LOG_ERR,
"MythPainter::GetImageFromTextLayout: "
409 clip.setSize(canvas.size());
411 QFont tmpfont = font.
face();
412 painter.setFont(tmpfont);
413 painter.setRenderHint(QPainter::Antialiasing);
420 int shadowAlpha = 255;
422 font.
GetShadow(shadowOffset, shadowColor, shadowAlpha);
423 shadowColor.setAlpha(shadowAlpha);
429 shadowRect.translate(shadow.x(), shadow.y());
431 painter.setPen(shadowColor);
432 for (
auto *layout : std::as_const(layouts))
433 layout->draw(&painter, shadowRect.topLeft(),
formats, clip);
436 painter.setPen(QPen(font.
GetBrush(), 0));
437 for (
auto *layout : std::as_const(layouts))
439 layout->draw(&painter, canvas.topLeft(),
440 layout->formats(), clip);
444 pm.setOffset(canvas.topLeft());
458 const QBrush &fillBrush,
461 if (area.width() <= 0 || area.height() <= 0)
464 uint64_t hash1 = ((0xfff & (uint64_t)area.width())) +
465 ((0xfff & (uint64_t)area.height()) << 12) +
466 ((0xff & (uint64_t)fillBrush.style()) << 24) +
467 ((0xff & (uint64_t)linePen.width()) << 32) +
468 ((0xff & (uint64_t)radius) << 40) +
469 ((0xff & (uint64_t)linePen.style()) << 48) +
470 ((0xff & (uint64_t)ellipse) << 56);
471 uint64_t hash2 = ((0xffffffff & (uint64_t)linePen.color().rgba())) +
472 ((0xffffffff & (uint64_t)fillBrush.color().rgba()) << 32);
474 QString incoming(
"R");
475 if (fillBrush.style() == Qt::LinearGradientPattern && fillBrush.gradient())
480 const auto *gradient =
static_cast<const QLinearGradient*
>(fillBrush.gradient());
483 incoming = QString::number(
484 ((0xfff & (uint64_t)gradient->start().x())) +
485 ((0xfff & (uint64_t)gradient->start().y()) << 12) +
486 ((0xfff & (uint64_t)gradient->finalStop().x()) << 24) +
487 ((0xfff & (uint64_t)gradient->finalStop().y()) << 36));
488 QGradientStops stops = gradient->stops();
489 for (
const auto & stop : std::as_const(stops))
491 incoming += QString::number(
492 ((0xfff * (uint64_t)(stop.first * 100))) +
493 ((uint64_t)stop.second.rgba() << 12));
498 incoming += QString::number(hash1) + QString::number(hash2);
513 DrawRectPriv(im, area, radius, ellipse, fillBrush, linePen);
552 bool recompute =
false;
561 QMap<QString, MythImage*>::iterator it =
593 static constexpr int64_t kOneMeg = 1LL * 1024 * 1024;
609 LOG((err) ? VB_GENERAL : VB_GUI, (err) ? LOG_ERR : LOG_INFO,
610 QString(
"MythPainter cache sizes: Hardware %1MB, Software %2MB")
QBrush GetBrush(void) const
bool hasOutline(void) const
bool hasShadow(void) const
void GetShadow(QPoint &offset, QColor &color, int &alpha) const
void GetOutline(QColor &color, int &size, int &alpha) const
QString GetHash(void) const
void SetFileName(QString fname)
void Assign(const QImage &img)
MythPainter * GetParent(void)
int DecrRef(void) override
Decrements reference count and deletes on 0.
int IncrRef(void) override
Increments reference count.
void SetParent(MythPainter *parent)
void DeleteFormatImage(MythImage *im)
MythImage * GetImageFromTextLayout(const LayoutVector &layouts, const FormatVector &formats, const MythFontProperties &font, QRect &canvas, QRect &dest)
static void DrawRectPriv(MythImage *im, QRect area, int radius, int ellipse, const QBrush &fillBrush, const QPen &linePen)
int64_t m_softwareCacheSize
void ExpireImages(int64_t max=0)
virtual void DeleteFormatImagePriv(MythImage *im)=0
virtual void DrawText(QRect r, const QString &msg, int flags, const MythFontProperties &font, int alpha, QRect boundRect)
virtual void DrawRect(QRect area, const QBrush &fillBrush, const QPen &linePen, int alpha)
virtual MythImage * GetFormatImagePriv(void)=0
Creates a reference counted image, call DecrRef() to delete.
QMap< QString, MythImage * > m_stringToImageMap
virtual void DrawTextLayout(QRect canvasRect, const LayoutVector &layouts, const FormatVector &formats, const MythFontProperties &font, int alpha, QRect destRect)
virtual void SetClipRect(QRect clipRect)
virtual void DrawImage(QRect dest, MythImage *im, QRect src, int alpha)=0
MythImage * GetImageFromRect(QRect area, int radius, int ellipse, const QBrush &fillBrush, const QPen &linePen)
QSet< MythImage * > m_allocatedImages
static void DrawTextPriv(MythImage *im, const QString &msg, int flags, QRect r, const MythFontProperties &font)
MythImage * GetFormatImage()
Returns a blank reference counted image in the format required for the Draw functions for this painte...
virtual void Clear(QPaintDevice *device, const QRegion ®ion)
void CheckFormatImage(MythImage *im)
std::list< QString > m_stringExpireList
void SetMaximumCacheSizes(int hardware, int software)
MythImage * GetImageFromString(const QString &msg, int flags, QRect r, const MythFontProperties &font)
virtual void DrawRoundRect(QRect area, int cornerRadius, const QBrush &fillBrush, const QPen &linePen, int alpha)
virtual void DrawEllipse(QRect area, const QBrush &fillBrush, const QPen &linePen, int alpha)
int64_t m_maxSoftwareCacheSize
virtual void SetClipRegion(const QRegion &clipRegion)
int m_maxHardwareCacheSize
virtual void Teardown(void)
Wrapper around QPoint allowing us to handle percentage and other relative values for positioning in m...
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
QVector< QTextLayout::FormatRange > FormatVector
QVector< QTextLayout * > LayoutVector
const std::array< const std::string, 8 > formats