MythTV  master
mythpainter.cpp
Go to the documentation of this file.
1 #include <algorithm>
2 #include <complex>
3 #include <cstdint>
4 
5 // QT headers
6 #include <QRect>
7 #include <QPainter>
8 
9 // libmythbase headers
10 #include "mythlogging.h"
11 #include "compat.h"
12 #include "mythcorecontext.h"
13 
14 // libmythui headers
15 #include "mythfontproperties.h"
16 #include "mythimage.h"
17 #include "mythuianimation.h" // UIEffects
18 
19 // Own header
20 #include "mythpainter.h"
21 
23 {
25  gCoreContext->GetNumSetting("UIPainterMaxCacheHW",64),
26  gCoreContext->GetNumSetting("UIPainterMaxCacheSW",48) );
27 }
28 
30 {
31  ExpireImages(0);
32 
33  QMutexLocker locker(&m_allocationLock);
34 
35  if (!m_allocatedImages.isEmpty())
36  {
37  LOG(VB_GENERAL, LOG_WARNING,
38  QString("MythPainter: %1 images not yet de-allocated.")
39  .arg(m_allocatedImages.size()));
40  }
41 
42  QSet<MythImage*>::iterator it = m_allocatedImages.begin();
43  for (; it != m_allocatedImages.end(); ++it)
44  (*it)->SetParent(nullptr);
45  m_allocatedImages.clear();
46 }
47 
48 void MythPainter::SetClipRect(const QRect & /*clipRect*/)
49 {
50 }
51 
52 void MythPainter::SetClipRegion(const QRegion & /*clipRegion*/)
53 {
54 }
55 
56 void MythPainter::Clear(QPaintDevice */*device*/, const QRegion &/*region*/)
57 {
58 }
59 
60 void MythPainter::DrawImage(int x, int y, MythImage *im, int alpha)
61 {
62  if (!im)
63  {
64  LOG(VB_GENERAL, LOG_ERR,
65  "Null image pointer passed to MythPainter::DrawImage()");
66  return;
67  }
68  QRect dest = QRect(x, y, im->width(), im->height());
69  QRect src = im->rect();
70  DrawImage(dest, im, src, alpha);
71 }
72 
73 void MythPainter::DrawImage(const QPoint &topLeft, MythImage *im, int alpha)
74 {
75  DrawImage(topLeft.x(), topLeft.y(), im, alpha);
76 }
77 
78 void MythPainter::DrawText(const QRect &r, const QString &msg,
79  int flags, const MythFontProperties &font,
80  int alpha, const QRect &boundRect)
81 {
82  MythImage *im = GetImageFromString(msg, flags, r, font);
83  if (!im)
84  return;
85 
86  QRect destRect(boundRect);
87  QRect srcRect(0,0,r.width(),r.height());
88  if (!boundRect.isEmpty() && boundRect != r)
89  {
90  int x = 0;
91  int y = 0;
92  int width = boundRect.width();
93  int height = boundRect.height();
94 
95  if (boundRect.x() > r.x())
96  {
97  x = boundRect.x()-r.x();
98  }
99  else if (r.x() > boundRect.x())
100  {
101  destRect.setX(r.x());
102  width = (boundRect.x() + boundRect.width()) - r.x();
103  }
104 
105  if (boundRect.y() > r.y())
106  {
107  y = boundRect.y()-r.y();
108  }
109  else if (r.y() > boundRect.y())
110  {
111  destRect.setY(r.y());
112  height = (boundRect.y() + boundRect.height()) - r.y();
113  }
114 
115  if (width <= 0 || height <= 0)
116  return;
117 
118  srcRect.setRect(x,y,width,height);
119  }
120 
121  DrawImage(destRect, im, srcRect, alpha);
122  im->DecrRef();
123 }
124 
125 void MythPainter::DrawTextLayout(const QRect & canvasRect,
126  const LayoutVector & layouts,
127  const FormatVector & formats,
128  const MythFontProperties & font, int alpha,
129  const QRect & destRect)
130 {
131  if (canvasRect.isNull())
132  return;
133 
134  QRect canvas(canvasRect);
135  QRect dest(destRect);
136 
137  MythImage *im = GetImageFromTextLayout(layouts, formats, font,
138  canvas, dest);
139  if (!im)
140  {
141  LOG(VB_GENERAL, LOG_ERR, QString("MythPainter::DrawTextLayout: "
142  "Unable to create image."));
143  return;
144  }
145  if (im->isNull())
146  {
147  LOG(VB_GENERAL, LOG_DEBUG, QString("MythPainter::DrawTextLayout: "
148  "Rendered image is null."));
149  im->DecrRef();
150  return;
151  }
152 
153  QRect srcRect(0, 0, dest.width(), dest.height());
154  DrawImage(dest, im, srcRect, alpha);
155 
156  im->DecrRef();
157 }
158 
159 void MythPainter::DrawRect(const QRect &area, const QBrush &fillBrush,
160  const QPen &linePen, int alpha)
161 {
162  MythImage *im = GetImageFromRect(area, 0, 0, fillBrush, linePen);
163  if (im)
164  {
165  DrawImage(area.x(), area.y(), im, alpha);
166  im->DecrRef();
167  }
168 }
169 
170 void MythPainter::DrawRoundRect(const QRect &area, int cornerRadius,
171  const QBrush &fillBrush, const QPen &linePen,
172  int alpha)
173 {
174  MythImage *im = GetImageFromRect(area, cornerRadius, 0, fillBrush, linePen);
175  if (im)
176  {
177  DrawImage(area.x(), area.y(), im, alpha);
178  im->DecrRef();
179  }
180 }
181 
182 void MythPainter::DrawEllipse(const QRect &area, const QBrush &fillBrush,
183  const QPen &linePen, int alpha)
184 {
185  MythImage *im = GetImageFromRect(area, 0, 1, fillBrush, linePen);
186  if (im)
187  {
188  DrawImage(area.x(), area.y(), im, alpha);
189  im->DecrRef();
190  }
191 }
192 
193 void MythPainter::PushTransformation(const UIEffects &zoom, QPointF center)
194 {
195  (void)zoom;
196  (void)center;
197 }
198 
199 void MythPainter::DrawTextPriv(MythImage *im, const QString &msg, int flags,
200  const QRect &r, const MythFontProperties &font)
201 {
202  if (!im)
203  return;
204 
205  QColor outlineColor;
206  int outlineSize = 0;
207  int outlineAlpha;
208  if (font.hasOutline())
209  font.GetOutline(outlineColor, outlineSize, outlineAlpha);
210 
211  QPoint shadowOffset(0, 0);
212  QColor shadowColor;
213  int shadowAlpha;
214  if (font.hasShadow())
215  font.GetShadow(shadowOffset, shadowColor, shadowAlpha);
216 
217  QFontMetrics fm(font.face());
218  int totalHeight = fm.height() + outlineSize +
219  std::max(outlineSize, std::abs(shadowOffset.y()));
220 
221  // initialPaddingX is the number of pixels from the left of the
222  // input QRect to the left of the actual text. It is always 0
223  // because we don't add padding to the text rectangle.
224  int initialPaddingX = 0;
225 
226  // initialPaddingY is the number of pixels from the top of the
227  // input QRect to the top of the actual text. It may be nonzero
228  // because of extra vertical padding.
229  int initialPaddingY = (r.height() - totalHeight) / 2;
230  // Hack. Normally we vertically center the text due to some
231  // (solvable) issues in the SubtitleScreen code - the text rect
232  // and the background rect are both created with PAD_WIDTH extra
233  // padding, and to honor Qt::AlignTop, the text rect needs to be
234  // without padding. This doesn't work for Qt::TextWordWrap, since
235  // the first line will be vertically centered with subsequence
236  // lines below. So if Qt::TextWordWrap is set, we do top
237  // alignment.
238  if (flags & Qt::TextWordWrap)
239  initialPaddingY = 0;
240 
241  // textOffsetX is the number of pixels from r.left() to the left
242  // edge of the core text. This assumes that flags contains
243  // Qt::AlignLeft.
244  int textOffsetX =
245  initialPaddingX + std::max(outlineSize, -shadowOffset.x());
246 
247  // textOffsetY is the number of pixels from r.top() to the top
248  // edge of the core text. This assumes that flags contains
249  // Qt::AlignTop.
250  int textOffsetY =
251  initialPaddingY + std::max(outlineSize, -shadowOffset.y());
252 
253  QImage pm(r.size(), QImage::Format_ARGB32);
254  QColor fillcolor = font.color();
255  if (font.hasOutline())
256  fillcolor = outlineColor;
257  fillcolor.setAlpha(0);
258  pm.fill(fillcolor.rgba());
259 
260  QPainter tmp(&pm);
261  QFont tmpfont = font.face();
262  tmpfont.setStyleStrategy(QFont::OpenGLCompatible);
263  tmp.setFont(tmpfont);
264 
265  QPainterPath path;
266  if (font.hasOutline())
267  path.addText(0, 0, tmpfont, msg);
268 
269  if (font.hasShadow())
270  {
271  QRect a = QRect(0, 0, r.width(), r.height());
272  a.translate(shadowOffset.x() + textOffsetX,
273  shadowOffset.y() + textOffsetY);
274 
275  shadowColor.setAlpha(shadowAlpha);
276  tmp.setPen(shadowColor);
277  tmp.drawText(a, flags, msg);
278  }
279 
280  if (font.hasOutline())
281  {
282  // QPainter::drawText() treats the Y coordinate as the top of
283  // the text (when Qt::AlignTop is used). However,
284  // QPainterPath::addText() treats the Y coordinate as the base
285  // line of the text. To translate from the top to the base
286  // line, we need to add QFontMetrics::ascent().
287  int adjX = 0;
288  int adjY = fm.ascent();
289 
290  outlineColor.setAlpha(outlineAlpha);
291  tmp.setPen(outlineColor);
292 
293  path.translate(adjX + textOffsetX, adjY + textOffsetY);
294  QPen pen = tmp.pen();
295  pen.setWidth(outlineSize * 2 + 1);
296  pen.setCapStyle(Qt::RoundCap);
297  pen.setJoinStyle(Qt::RoundJoin);
298  tmp.setPen(pen);
299  tmp.drawPath(path);
300 
301  path.translate(outlineSize, outlineSize);
302  }
303 
304  tmp.setPen(QPen(font.GetBrush(), 0));
305  tmp.setBrush(font.GetBrush());
306  tmp.drawText(textOffsetX, textOffsetY, r.width(), r.height(),
307  flags, msg);
308  tmp.end();
309  im->Assign(pm);
310 }
311 
312 void MythPainter::DrawRectPriv(MythImage *im, const QRect &area, int radius,
313  int ellipse,
314  const QBrush &fillBrush, const QPen &linePen)
315 {
316  if (!im)
317  return;
318 
319  QImage image(QSize(area.width(), area.height()), QImage::Format_ARGB32);
320  image.fill(0x00000000);
321  QPainter painter(&image);
322  painter.setRenderHint(QPainter::Antialiasing);
323  painter.setPen(linePen);
324  painter.setBrush(fillBrush);
325 
326  if ((area.width() / 2) < radius)
327  radius = area.width() / 2;
328 
329  if ((area.height() / 2) < radius)
330  radius = area.height() / 2;
331 
332  int lineWidth = linePen.width();
333  QRect r(lineWidth, lineWidth,
334  area.width() - (lineWidth * 2), area.height() - (lineWidth * 2));
335 
336  if (ellipse)
337  painter.drawEllipse(r);
338  else if (radius == 0)
339  painter.drawRect(r);
340  else
341  painter.drawRoundedRect(r, (qreal)radius, qreal(radius));
342 
343  painter.end();
344  im->Assign(image);
345 }
346 
348  int flags, const QRect &r,
349  const MythFontProperties &font)
350 {
351  QString incoming = font.GetHash() + QString::number(r.width()) +
352  QString::number(r.height()) +
353  QString::number(flags) +
354  QString::number(font.color().rgba()) + msg;
355 
356  MythImage *im = nullptr;
357  if (m_StringToImageMap.contains(incoming))
358  {
359  m_StringExpireList.remove(incoming);
360  m_StringExpireList.push_back(incoming);
361  im = m_StringToImageMap[incoming];
362  if (im)
363  im->IncrRef();
364  }
365  else
366  {
367  im = GetFormatImage();
368  im->SetFileName(QString("GetImageFromString: %1").arg(msg));
369  DrawTextPriv(im, msg, flags, r, font);
370 
371  im->IncrRef();
372  m_SoftwareCacheSize += im->bytesPerLine() * im->height();
373  m_StringToImageMap[incoming] = im;
374  m_StringExpireList.push_back(incoming);
376  }
377  return im;
378 }
379 
381  const FormatVector &formats,
382  const MythFontProperties &font,
383  QRect &canvas, QRect &dest)
384 {
385  LayoutVector::const_iterator Ipara;
386 
387  QString incoming = QString::number(canvas.x()) +
388  QString::number(canvas.y()) +
389  QString::number(canvas.width()) +
390  QString::number(canvas.height()) +
391  QString::number(dest.width()) +
392  QString::number(dest.height()) +
393  font.GetHash();
394 
395  for (Ipara = layouts.begin(); Ipara != layouts.end(); ++Ipara)
396  incoming += (*Ipara)->text();
397 
398  MythImage *im = nullptr;
399  if (m_StringToImageMap.contains(incoming))
400  {
401  m_StringExpireList.remove(incoming);
402  m_StringExpireList.push_back(incoming);
403  im = m_StringToImageMap[incoming];
404  if (im)
405  im->IncrRef();
406  }
407  else
408  {
409  im = GetFormatImage();
410  im->SetFileName("GetImageFromTextLayout");
411 
412  QImage pm(canvas.size(), QImage::Format_ARGB32_Premultiplied);
413  pm.fill(0);
414 
415  QPainter painter(&pm);
416  if (!painter.isActive())
417  {
418  LOG(VB_GENERAL, LOG_ERR, "MythPainter::GetImageFromTextLayout: "
419  "Invalid canvas.");
420  return im;
421  }
422 
423  QRect clip;
424  clip.setSize(canvas.size());
425 
426  QFont tmpfont = font.face();
427  tmpfont.setStyleStrategy(QFont::OpenGLCompatible);
428  painter.setFont(tmpfont);
429  painter.setRenderHint(QPainter::Antialiasing);
430 
431  if (font.hasShadow())
432  {
433  QRect shadowRect;
434  QPoint shadowOffset;
435  QColor shadowColor;
436  int shadowAlpha;
437 
438  font.GetShadow(shadowOffset, shadowColor, shadowAlpha);
439  shadowColor.setAlpha(shadowAlpha);
440 
441  MythPoint shadow(shadowOffset);
442  shadow.NormPoint(); // scale it to screen resolution
443 
444  shadowRect = canvas;
445  shadowRect.translate(shadow.x(), shadow.y());
446 
447  painter.setPen(shadowColor);
448  for (Ipara = layouts.begin(); Ipara != layouts.end(); ++Ipara)
449  (*Ipara)->draw(&painter, shadowRect.topLeft(), formats, clip);
450  }
451 
452  painter.setPen(QPen(font.GetBrush(), 0));
453  for (Ipara = layouts.begin(); Ipara != layouts.end(); ++Ipara)
454  {
455 #if QT_VERSION >= QT_VERSION_CHECK(5,6,0)
456  (*Ipara)->draw(&painter, canvas.topLeft(),
457  (*Ipara)->formats(), clip);
458 #else
459  (*Ipara)->draw(&painter, canvas.topLeft(), formats, clip);
460 #endif
461  }
462  painter.end();
463 
464  pm.setOffset(canvas.topLeft());
465  im->Assign(pm.copy(0, 0, dest.width(), dest.height()));
466 
467  im->IncrRef();
468  m_SoftwareCacheSize += im->bytesPerLine() * im->height();
469  m_StringToImageMap[incoming] = im;
470  m_StringExpireList.push_back(incoming);
472  }
473  return im;
474 }
475 
476 MythImage* MythPainter::GetImageFromRect(const QRect &area, int radius,
477  int ellipse,
478  const QBrush &fillBrush,
479  const QPen &linePen)
480 {
481  if (area.width() <= 0 || area.height() <= 0)
482  return nullptr;
483 
484  uint64_t hash1 = ((0xfff & (uint64_t)area.width())) +
485  ((0xfff & (uint64_t)area.height()) << 12) +
486  ((0xff & (uint64_t)fillBrush.style()) << 24) +
487  ((0xff & (uint64_t)linePen.width()) << 32) +
488  ((0xff & (uint64_t)radius) << 40) +
489  ((0xff & (uint64_t)linePen.style()) << 48) +
490  ((0xff & (uint64_t)ellipse) << 56);
491  uint64_t hash2 = ((0xffffffff & (uint64_t)linePen.color().rgba())) +
492  ((0xffffffff & (uint64_t)fillBrush.color().rgba()) << 32);
493 
494  QString incoming("R");
495  if (fillBrush.style() == Qt::LinearGradientPattern && fillBrush.gradient())
496  {
497  const QLinearGradient *gradient = static_cast<const QLinearGradient*>(fillBrush.gradient());
498  if (gradient)
499  {
500  incoming = QString::number(
501  ((0xfff & (uint64_t)gradient->start().x())) +
502  ((0xfff & (uint64_t)gradient->start().y()) << 12) +
503  ((0xfff & (uint64_t)gradient->finalStop().x()) << 24) +
504  ((0xfff & (uint64_t)gradient->finalStop().y()) << 36));
505  QGradientStops stops = gradient->stops();
506  for (int i = 0; i < stops.size(); i++)
507  {
508  incoming += QString::number(
509  ((0xfff * (uint64_t)(stops[i].first * 100))) +
510  ((uint64_t)stops[i].second.rgba() << 12));
511  }
512  }
513  }
514 
515  incoming += QString::number(hash1) + QString::number(hash2);
516 
517  MythImage *im = nullptr;
518  if (m_StringToImageMap.contains(incoming))
519  {
520  m_StringExpireList.remove(incoming);
521  m_StringExpireList.push_back(incoming);
522  im = m_StringToImageMap[incoming];
523  if (im)
524  im->IncrRef();
525  }
526  else
527  {
528  im = GetFormatImage();
529  im->SetFileName("GetImageFromRect");
530  DrawRectPriv(im, area, radius, ellipse, fillBrush, linePen);
531 
532  im->IncrRef();
533  m_SoftwareCacheSize += (im->bytesPerLine() * im->height());
534  m_StringToImageMap[incoming] = im;
535  m_StringExpireList.push_back(incoming);
537  }
538  return im;
539 }
540 
542 {
543  QMutexLocker locker(&m_allocationLock);
544  MythImage *result = GetFormatImagePriv();
545  result->SetFileName("GetFormatImage");
546  m_allocatedImages.insert(result);
547  return result;
548 }
549 
551 {
552  QMutexLocker locker(&m_allocationLock);
554  m_allocatedImages.remove(im);
555 }
556 
558 {
559  if (im && !im->GetParent())
560  {
561  QMutexLocker locker(&m_allocationLock);
562  m_allocatedImages.insert(im);
563  im->SetParent(this);
564  }
565 }
566 
567 void MythPainter::ExpireImages(int64_t max)
568 {
569  bool recompute = false;
570  while (!m_StringExpireList.empty())
571  {
572  if (m_SoftwareCacheSize < max)
573  break;
574 
575  QString oldmsg = m_StringExpireList.front();
576  m_StringExpireList.pop_front();
577 
578  QMap<QString, MythImage*>::iterator it =
579  m_StringToImageMap.find(oldmsg);
580  if (it == m_StringToImageMap.end())
581  {
582  recompute = true;
583  continue;
584  }
585  MythImage *oldim = *it;
586  it = m_StringToImageMap.erase(it);
587 
588  if (oldim)
589  {
590  m_SoftwareCacheSize -= oldim->bytesPerLine() * oldim->height();
591  if (m_SoftwareCacheSize < 0)
592  {
594  recompute = true;
595  }
596  oldim->DecrRef();
597  }
598  }
599  if (recompute)
600  {
602  QMap<QString, MythImage*>::iterator it = m_StringToImageMap.begin();
603  for (; it != m_StringToImageMap.end(); ++it)
604  m_SoftwareCacheSize += (*it)->bytesPerLine() * (*it)->height();
605  }
606 }
607 
608 // the following assume graphics hardware operates natively at 32bpp
609 void MythPainter::SetMaximumCacheSizes(int hardware, int software)
610 {
611  const int64_t kOneMeg = 1024 * 1024;
612  m_MaxHardwareCacheSize = kOneMeg * hardware;
613  m_MaxSoftwareCacheSize = kOneMeg * software;
614 
615  bool err = false;
616  if (m_MaxHardwareCacheSize < 0)
617  {
619  err = true;
620  }
621  if (m_MaxSoftwareCacheSize < 0)
622  {
623  m_MaxSoftwareCacheSize = kOneMeg * 48;
624  err = true;
625  }
626 
627  LOG((err) ? VB_GENERAL : VB_GUI, (err) ? LOG_ERR : LOG_INFO,
628  QString("MythPainter cache sizes: Hardware %1 MB, Software %2 MB")
629  .arg(m_MaxHardwareCacheSize / kOneMeg)
630  .arg(m_MaxSoftwareCacheSize / kOneMeg));
631 }
virtual void Teardown(void)
Definition: mythpainter.cpp:29
QColor color(void) const
MythImage * GetImageFromTextLayout(const LayoutVector &layouts, const FormatVector &formats, const MythFontProperties &font, QRect &canvas, QRect &dest)
void DrawRectPriv(MythImage *im, const QRect &area, int radius, int ellipse, const QBrush &fillBrush, const QPen &linePen)
QMap< QString, MythImage * > m_StringToImageMap
Definition: mythpainter.h:139
void DeleteFormatImage(MythImage *im)
int DecrRef(void) override
Decrements reference count and deletes on 0.
Definition: mythimage.cpp:55
QSet< MythImage * > m_allocatedImages
Definition: mythpainter.h:137
virtual void DrawEllipse(const QRect &area, const QBrush &fillBrush, const QPen &linePen, int alpha)
QVector< QTextLayout * > LayoutVector
Definition: mythpainter.h:27
void GetShadow(QPoint &offset, QColor &color, int &alpha) const
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
QString GetHash(void) const
virtual MythImage * GetFormatImagePriv(void)=0
Creates a reference counted image, call DecrRef() to delete.
virtual void DrawRoundRect(const QRect &area, int cornerRadius, const QBrush &fillBrush, const QPen &linePen, int alpha)
const char * formats[8]
Definition: vbilut.cpp:190
static guint32 * tmp
Definition: goom_core.c:35
QMutex m_allocationLock
Definition: mythpainter.h:136
unsigned char r
Definition: ParseText.cpp:329
void DrawTextPriv(MythImage *im, const QString &msg, int flags, const QRect &r, const MythFontProperties &font)
MythPainter * GetParent(void)
Definition: mythimage.h:39
MythImage * GetImageFromRect(const QRect &area, int radius, int ellipse, const QBrush &fillBrush, const QPen &linePen)
std::list< QString > m_StringExpireList
Definition: mythpainter.h:140
QFont face(void) const
virtual void PushTransformation(const UIEffects &zoom, QPointF center=QPointF())
virtual void SetClipRegion(const QRegion &clipRegion)
Definition: mythpainter.cpp:52
int IncrRef(void) override
Increments reference count.
Definition: mythimage.cpp:47
virtual void DrawRect(const QRect &area, const QBrush &fillBrush, const QPen &linePen, int alpha)
void ExpireImages(int64_t max=0)
virtual void Clear(QPaintDevice *device, const QRegion &region)
Definition: mythpainter.cpp:56
virtual void DrawText(const QRect &r, const QString &msg, int flags, const MythFontProperties &font, int alpha, const QRect &boundRect)
Definition: mythpainter.cpp:78
virtual void DeleteFormatImagePriv(MythImage *im)=0
MythImage * GetImageFromString(const QString &msg, int flags, const QRect &r, const MythFontProperties &font)
void SetFileName(QString fname)
Definition: mythimage.h:85
void GetOutline(QColor &color, int &size, int &alpha) const
virtual void DrawImage(const QRect &dest, MythImage *im, const QRect &src, int alpha)=0
int64_t m_MaxSoftwareCacheSize
Definition: mythpainter.h:134
int GetNumSetting(const QString &key, int defaultval=0)
bool hasOutline(void) const
#define LOG(_MASK_, _LEVEL_, _STRING_)
Definition: mythlogging.h:41
QVector< QTextLayout::FormatRange > FormatVector
Definition: mythpainter.h:30
virtual void DrawTextLayout(const QRect &canvasRect, const LayoutVector &layouts, const FormatVector &formats, const MythFontProperties &font, int alpha, const QRect &destRect)
void CheckFormatImage(MythImage *im)
QBrush GetBrush(void) const
Wrapper around QPoint allowing us to handle percentage and other relative values for positioning in m...
Definition: mythrect.h:86
int64_t m_SoftwareCacheSize
Definition: mythpainter.h:133
void Assign(const QImage &img)
Definition: mythimage.cpp:80
bool hasShadow(void) const
void SetParent(MythPainter *parent)
Definition: mythimage.h:40
MythImage * GetFormatImage()
Returns a blank reference counted image in the format required for the Draw functions for this painte...
void NormPoint(void)
Definition: mythrect.cpp:391
virtual void SetClipRect(const QRect &clipRect)
Definition: mythpainter.cpp:48
void SetMaximumCacheSizes(int hardware, int software)
int m_MaxHardwareCacheSize
Definition: mythpainter.h:130