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