8 #include <QPainterPath>
36 LOG(VB_GENERAL, LOG_WARNING,
37 QString(
"MythPainter: %1 images not yet de-allocated.")
42 image->SetParent(
nullptr);
62 LOG(VB_GENERAL, LOG_ERR,
63 "Null image pointer passed to MythPainter::DrawImage()");
66 QRect
dest = QRect(x, y, im->width(), im->height());
67 QRect src = im->rect();
73 DrawImage(topLeft.x(), topLeft.y(), im, alpha);
78 int alpha,
const QRect boundRect)
84 QRect destRect(boundRect);
85 QRect srcRect(0,0,r.width(),r.height());
86 if (!boundRect.isEmpty() && boundRect != r)
90 int width = boundRect.width();
91 int height = boundRect.height();
93 if (boundRect.x() > r.x())
95 x = boundRect.x()-r.x();
97 else if (r.x() > boundRect.x())
100 width = (boundRect.x() + boundRect.width()) - r.x();
103 if (boundRect.y() > r.y())
105 y = boundRect.y()-r.y();
107 else if (r.y() > boundRect.y())
109 destRect.setY(r.y());
110 height = (boundRect.y() + boundRect.height()) - r.y();
113 if (width <= 0 || height <= 0)
116 srcRect.setRect(x,y,width,height);
127 const QRect destRect)
129 if (canvasRect.isNull())
132 QRect canvas(canvasRect);
133 QRect
dest(destRect);
139 LOG(VB_GENERAL, LOG_ERR, QString(
"MythPainter::DrawTextLayout: "
140 "Unable to create image."));
145 LOG(VB_GENERAL, LOG_DEBUG, QString(
"MythPainter::DrawTextLayout: "
146 "Rendered image is null."));
151 QRect srcRect(0, 0,
dest.width(),
dest.height());
158 const QPen &linePen,
int alpha)
163 DrawImage(area.x(), area.y(), im, alpha);
169 const QBrush &fillBrush,
const QPen &linePen,
175 DrawImage(area.x(), area.y(), im, alpha);
181 const QPen &linePen,
int alpha)
186 DrawImage(area.x(), area.y(), im, alpha);
199 int outlineAlpha = 255;
201 font.
GetOutline(outlineColor, outlineSize, outlineAlpha);
203 QPoint shadowOffset(0, 0);
205 int shadowAlpha = 255;
207 font.
GetShadow(shadowOffset, shadowColor, shadowAlpha);
209 QFontMetrics fm(font.
face());
210 int totalHeight = fm.height() + outlineSize +
211 std::max(outlineSize, std::abs(shadowOffset.y()));
216 int initialPaddingX = 0;
221 int initialPaddingY = (r.height() - totalHeight) / 2;
230 if (flags & Qt::TextWordWrap)
237 initialPaddingX + std::max(outlineSize, -shadowOffset.x());
243 initialPaddingY + std::max(outlineSize, -shadowOffset.y());
245 QImage pm(r.size(), QImage::Format_ARGB32);
246 QColor fillcolor = font.
color();
248 fillcolor = outlineColor;
249 fillcolor.setAlpha(0);
250 pm.fill(fillcolor.rgba());
253 QFont tmpfont = font.
face();
254 tmp.setFont(tmpfont);
258 path.addText(0, 0, tmpfont, msg);
262 QRect a = QRect(0, 0, r.width(), r.height());
263 a.translate(shadowOffset.x() + textOffsetX,
264 shadowOffset.y() + textOffsetY);
266 shadowColor.setAlpha(shadowAlpha);
267 tmp.setPen(shadowColor);
268 tmp.drawText(a, flags, msg);
279 int adjY = fm.ascent();
281 outlineColor.setAlpha(outlineAlpha);
282 tmp.setPen(outlineColor);
284 path.translate(adjX + textOffsetX, adjY + textOffsetY);
285 QPen pen =
tmp.pen();
286 pen.setWidth((outlineSize * 2) + 1);
287 pen.setCapStyle(Qt::RoundCap);
288 pen.setJoinStyle(Qt::RoundJoin);
292 path.translate(outlineSize, outlineSize);
297 tmp.drawText(textOffsetX, textOffsetY, r.width(), r.height(),
305 const QBrush &fillBrush,
const QPen &linePen)
310 QImage image(QSize(area.width(), area.height()), QImage::Format_ARGB32);
311 image.fill(0x00000000);
312 QPainter painter(&image);
313 painter.setRenderHint(QPainter::Antialiasing);
314 painter.setPen(linePen);
315 painter.setBrush(fillBrush);
317 radius = std::min(area.width() / 2, radius);
318 radius = std::min(area.height() / 2, radius);
320 int lineWidth = linePen.width();
321 QRect r(lineWidth, lineWidth,
322 area.width() - (lineWidth * 2), area.height() - (lineWidth * 2));
325 painter.drawEllipse(r);
326 else if (radius == 0)
329 painter.drawRoundedRect(r, (qreal)radius, qreal(radius));
336 int flags,
const QRect r,
339 QString incoming = font.
GetHash() + QString::number(r.width()) +
340 QString::number(r.height()) +
341 QString::number(flags) +
342 QString::number(font.
color().rgba()) + msg;
356 im->
SetFileName(QString(
"GetImageFromString: %1").arg(msg));
371 QRect &canvas, QRect &
dest)
373 QString incoming = QString::number(canvas.x()) +
374 QString::number(canvas.y()) +
375 QString::number(canvas.width()) +
376 QString::number(canvas.height()) +
377 QString::number(
dest.width()) +
378 QString::number(
dest.height()) +
381 for (
auto *layout : std::as_const(layouts))
382 incoming += layout->text();
398 QImage pm(canvas.size(), QImage::Format_ARGB32_Premultiplied);
401 QPainter painter(&pm);
402 if (!painter.isActive())
404 LOG(VB_GENERAL, LOG_ERR,
"MythPainter::GetImageFromTextLayout: "
410 clip.setSize(canvas.size());
412 QFont tmpfont = font.
face();
413 painter.setFont(tmpfont);
414 painter.setRenderHint(QPainter::Antialiasing);
421 int shadowAlpha = 255;
423 font.
GetShadow(shadowOffset, shadowColor, shadowAlpha);
424 shadowColor.setAlpha(shadowAlpha);
430 shadowRect.translate(shadow.x(), shadow.y());
432 painter.setPen(shadowColor);
433 for (
auto *layout : std::as_const(layouts))
434 layout->draw(&painter, shadowRect.topLeft(),
formats, clip);
437 painter.setPen(QPen(font.
GetBrush(), 0));
438 for (
auto *layout : std::as_const(layouts))
440 layout->draw(&painter, canvas.topLeft(),
441 layout->formats(), clip);
445 pm.setOffset(canvas.topLeft());
459 const QBrush &fillBrush,
462 if (area.width() <= 0 || area.height() <= 0)
465 uint64_t hash1 = ((0xfff & (uint64_t)area.width())) +
466 ((0xfff & (uint64_t)area.height()) << 12) +
467 ((0xff & (uint64_t)fillBrush.style()) << 24) +
468 ((0xff & (uint64_t)linePen.width()) << 32) +
469 ((0xff & (uint64_t)radius) << 40) +
470 ((0xff & (uint64_t)linePen.style()) << 48) +
471 ((0xff & (uint64_t)ellipse) << 56);
472 uint64_t hash2 = ((0xffffffff & (uint64_t)linePen.color().rgba())) +
473 ((0xffffffff & (uint64_t)fillBrush.color().rgba()) << 32);
475 QString incoming(
"R");
476 if (fillBrush.style() == Qt::LinearGradientPattern && fillBrush.gradient())
481 const auto *gradient =
static_cast<const QLinearGradient*
>(fillBrush.gradient());
484 incoming = QString::number(
485 ((0xfff & (uint64_t)gradient->start().x())) +
486 ((0xfff & (uint64_t)gradient->start().y()) << 12) +
487 ((0xfff & (uint64_t)gradient->finalStop().x()) << 24) +
488 ((0xfff & (uint64_t)gradient->finalStop().y()) << 36));
489 QGradientStops stops = gradient->stops();
490 for (
const auto & stop : std::as_const(stops))
492 incoming += QString::number(
493 ((0xfff * (uint64_t)(stop.first * 100))) +
494 ((uint64_t)stop.second.rgba() << 12));
499 incoming += QString::number(hash1) + QString::number(hash2);
514 DrawRectPriv(im, area, radius, ellipse, fillBrush, linePen);
553 bool recompute =
false;
562 QMap<QString, MythImage*>::iterator it =
594 static constexpr int64_t kOneMeg = 1LL * 1024 * 1024;
610 LOG((err) ? VB_GENERAL : VB_GUI, (err) ? LOG_ERR : LOG_INFO,
611 QString(
"MythPainter cache sizes: Hardware %1MB, Software %2MB")