All Classes Namespaces Functions Variables Enumerations Properties Pages
canvaspainter.cpp
1 /*
2 
3 Pencil2D - Traditional Animation Software
4 Copyright (C) 2012-2020 Matthew Chiawen Chang
5 
6 This program is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License
8 as published by the Free Software Foundation; version 2 of the License.
9 
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14 
15 */
16 
17 #include "canvaspainter.h"
18 
19 #include <QtMath>
20 #include <QSettings>
21 
22 #include "object.h"
23 #include "layerbitmap.h"
24 #include "layervector.h"
25 #include "bitmapimage.h"
26 #include "layercamera.h"
27 #include "vectorimage.h"
28 #include "util.h"
29 #include <QDebug>
30 
31 CanvasPainter::CanvasPainter()
32 {
33 }
34 
35 CanvasPainter::~CanvasPainter()
36 {
37 }
38 
39 void CanvasPainter::setCanvas(QPixmap* canvas)
40 {
41  Q_ASSERT(canvas);
42  mCanvas = canvas;
43 }
44 
45 void CanvasPainter::setViewTransform(const QTransform view, const QTransform viewInverse)
46 {
47  if (mViewTransform != view || mViewInverse != viewInverse) {
48  mViewTransform = view;
49  mViewInverse = viewInverse;
50  }
51 }
52 
53 void CanvasPainter::setTransformedSelection(QRect selection, QTransform transform)
54 {
55  // Make sure that the selection is not empty
56  if (selection.width() > 0 && selection.height() > 0)
57  {
58  mSelection = selection;
59  mSelectionTransform = transform;
60  mRenderTransform = true;
61  }
62  else
63  {
64  // Otherwise we shouldn't be in transformation mode
65  ignoreTransformedSelection();
66  }
67 }
68 
69 void CanvasPainter::ignoreTransformedSelection()
70 {
71  mRenderTransform = false;
72 }
73 
74 void CanvasPainter::paintCached()
75 {
76  QPixmap tempPixmap(mCanvas->size());
77  tempPixmap.fill(Qt::transparent);
78  mCanvas->fill(Qt::transparent);
79  QPainter tempPainter;
80  QPainter painter;
81  initializePainter(tempPainter, tempPixmap);
82  initializePainter(painter, *mCanvas);
83 
84  if (!mPreLayersCache)
85  {
86  renderPreLayers(painter);
87  mPreLayersCache.reset(new QPixmap(*mCanvas));
88  }
89  else
90  {
91  painter.setWorldMatrixEnabled(false);
92  painter.drawPixmap(0, 0, *(mPreLayersCache.get()));
93  painter.setWorldMatrixEnabled(true);
94  }
95 
96  renderCurLayer(painter);
97 
98  if (!mPostLayersCache)
99  {
100  renderPostLayers(tempPainter);
101  mPostLayersCache.reset(new QPixmap(tempPixmap));
102  painter.setWorldMatrixEnabled(false);
103  painter.drawPixmap(0, 0, tempPixmap);
104  painter.setWorldMatrixEnabled(true);
105  }
106  else
107  {
108  painter.setWorldMatrixEnabled(false);
109  painter.drawPixmap(0, 0, *(mPostLayersCache.get()));
110  painter.setWorldMatrixEnabled(true);
111  }
112 }
113 
114 void CanvasPainter::resetLayerCache()
115 {
116  mPreLayersCache.reset();
117  mPostLayersCache.reset();
118 }
119 
121 {
122  painter.begin(&pixmap);
123  painter.setWorldMatrixEnabled(true);
124  painter.setWorldTransform(mViewTransform);
125 }
126 
127 void CanvasPainter::renderPreLayers(QPixmap* pixmap)
128 {
129  QPainter painter;
130  initializePainter(painter, *pixmap);
131  renderPreLayers(painter);
132 }
133 
134 void CanvasPainter::renderPreLayers(QPainter& painter)
135 {
136  if (mOptions.eLayerVisibility != LayerVisibility::CURRENTONLY || mObject->getLayer(mCurrentLayerIndex)->type() == Layer::CAMERA)
137  {
138  paintCurrentFrame(painter, 0, mCurrentLayerIndex - 1);
139  }
140 
141  paintOnionSkin(painter);
142  painter.setOpacity(1.0);
143 }
144 
145 void CanvasPainter::renderCurLayer(QPixmap* pixmap)
146 {
147  QPainter painter;
148  initializePainter(painter, *pixmap);
149  renderCurLayer(painter);
150 }
151 
152 void CanvasPainter::renderCurLayer(QPainter& painter)
153 {
154  paintCurrentFrame(painter, mCurrentLayerIndex, mCurrentLayerIndex);
155 }
156 
157 void CanvasPainter::renderPostLayers(QPixmap* pixmap)
158 {
159  QPainter painter;
160  initializePainter(painter, *pixmap);
161  renderPostLayers(painter);
162 }
163 
164 void CanvasPainter::renderPostLayers(QPainter& painter)
165 {
166  if (mOptions.eLayerVisibility != LayerVisibility::CURRENTONLY || mObject->getLayer(mCurrentLayerIndex)->type() == Layer::CAMERA)
167  {
168  paintCurrentFrame(painter, mCurrentLayerIndex + 1, mObject->getLayerCount() - 1);
169  }
170 
171  paintCameraBorder(painter);
172 
173  // post effects
174  if (mOptions.bAxis)
175  {
176  paintAxis(painter);
177  }
178 }
179 
180 void CanvasPainter::setPaintSettings(const Object* object, int currentLayer, int frame, QRect rect, BitmapImage* buffer)
181 {
182  Q_UNUSED(rect);
183  Q_ASSERT(object);
184  mObject = object;
185 
186  CANVASPAINTER_LOG("Set CurrentLayerIndex = %d", currentLayer);
187  mCurrentLayerIndex = currentLayer;
188  mFrameNumber = frame;
189  mBuffer = buffer;
190 }
191 
192 void CanvasPainter::paint()
193 {
194  QPainter painter;
195  initializePainter(painter, *mCanvas);
196 
197  renderPreLayers(painter);
198  renderCurLayer(painter);
199  renderPostLayers(painter);
200 }
201 
202 void CanvasPainter::paintBackground()
203 {
204  mCanvas->fill(Qt::transparent);
205 }
206 
207 void CanvasPainter::paintOnionSkin(QPainter& painter)
208 {
209  if (!mOptions.onionWhilePlayback && mOptions.isPlaying) { return; }
210 
211  Layer* layer = mObject->getLayer(mCurrentLayerIndex);
212 
213  if (layer->visible() == false)
214  return;
215 
216  if (layer->keyFrameCount() == 0)
217  return;
218 
219  qreal minOpacity = static_cast<qreal>(mOptions.fOnionSkinMinOpacity / 100);
220  qreal maxOpacity = static_cast<qreal>(mOptions.fOnionSkinMaxOpacity / 100);
221 
222  if (mOptions.bPrevOnionSkin && mFrameNumber > 1)
223  {
224  // Paint onion skin before current frame.
225  qreal prevOpacityIncrement = (maxOpacity - minOpacity) / mOptions.nPrevOnionSkinCount;
226  qreal opacity = maxOpacity;
227 
228  int onionFrameNumber = mFrameNumber;
229  if (mOptions.bIsOnionAbsolute)
230  {
231  onionFrameNumber = layer->getPreviousFrameNumber(onionFrameNumber + 1, true);
232  }
233  onionFrameNumber = layer->getPreviousFrameNumber(onionFrameNumber, mOptions.bIsOnionAbsolute);
234 
235  int onionPosition = 0;
236 
237  while (onionPosition < mOptions.nPrevOnionSkinCount && onionFrameNumber > 0)
238  {
239  painter.setOpacity(opacity);
240 
241  switch (layer->type())
242  {
243  case Layer::BITMAP: { paintBitmapFrame(painter, layer, onionFrameNumber, mOptions.bColorizePrevOnion, false, false); break; }
244  case Layer::VECTOR: { paintVectorFrame(painter, layer, onionFrameNumber, mOptions.bColorizePrevOnion, false, false); break; }
245  default: break;
246  }
247  opacity = opacity - prevOpacityIncrement;
248 
249  onionFrameNumber = layer->getPreviousFrameNumber(onionFrameNumber, mOptions.bIsOnionAbsolute);
250  onionPosition++;
251  }
252  }
253 
254  if (mOptions.bNextOnionSkin)
255  {
256  // Paint onion skin after current frame.
257  qreal nextOpacityIncrement = (maxOpacity - minOpacity) / mOptions.nNextOnionSkinCount;
258  qreal opacity = maxOpacity;
259 
260  int onionFrameNumber = layer->getNextFrameNumber(mFrameNumber, mOptions.bIsOnionAbsolute);
261  int onionPosition = 0;
262 
263  while (onionPosition < mOptions.nNextOnionSkinCount && onionFrameNumber > 0)
264  {
265  painter.setOpacity(opacity);
266 
267  switch (layer->type())
268  {
269  case Layer::BITMAP: { paintBitmapFrame(painter, layer, onionFrameNumber, mOptions.bColorizeNextOnion, false, false); break; }
270  case Layer::VECTOR: { paintVectorFrame(painter, layer, onionFrameNumber, mOptions.bColorizeNextOnion, false, false); break; }
271  default: break;
272  }
273  opacity = opacity - nextOpacityIncrement;
274 
275  onionFrameNumber = layer->getNextFrameNumber(onionFrameNumber, mOptions.bIsOnionAbsolute);
276  onionPosition++;
277  }
278  }
279 }
280 
281 void CanvasPainter::paintBitmapFrame(QPainter& painter,
282  Layer* layer,
283  int nFrame,
284  bool colorize,
285  bool useLastKeyFrame,
286  bool isCurrentFrame)
287 {
288 #ifdef _DEBUG
289  LayerBitmap* bitmapLayer = dynamic_cast<LayerBitmap*>(layer);
290  Q_ASSERT(bitmapLayer);
291 #else
292  LayerBitmap* bitmapLayer = static_cast<LayerBitmap*>(layer);
293 #endif
294 
295  CANVASPAINTER_LOG(" Paint Bitmap Frame = %d, UseLastKeyFrame = %d", nFrame, useLastKeyFrame);
296  BitmapImage* paintedImage = nullptr;
297  if (useLastKeyFrame)
298  {
299  paintedImage = bitmapLayer->getLastBitmapImageAtFrame(nFrame, 0);
300  CANVASPAINTER_LOG(" Actual frame = %d", paintedImage->pos());
301  }
302  else
303  {
304  paintedImage = bitmapLayer->getBitmapImageAtFrame(nFrame);
305  }
306 
307  if (paintedImage == nullptr) { return; }
308  paintedImage->loadFile(); // Critical! force the BitmapImage to load the image
309  CANVASPAINTER_LOG(" Paint Image Size: %dx%d", paintedImage->image()->width(), paintedImage->image()->height());
310 
311  const bool frameIsEmpty = (paintedImage == nullptr || paintedImage->bounds().isEmpty());
312  const bool isDrawing = isCurrentFrame && mBuffer && !mBuffer->bounds().isEmpty();
313  if (frameIsEmpty && !isDrawing)
314  {
315  CANVASPAINTER_LOG(" Early return frame %d, %d", frameIsEmpty, isDrawing);
316  return;
317  }
318 
319  BitmapImage paintToImage;
320  paintToImage.paste(paintedImage);
321 
322  painter.setOpacity(paintedImage->getOpacity() - (1.0-painter.opacity()));
323  if (isCurrentFrame)
324  {
325  paintToImage.paste(mBuffer, mOptions.cmBufferBlendMode);
326  }
327 
328  if (colorize)
329  {
330  QBrush colorBrush = QBrush(Qt::transparent); //no color for the current frame
331 
332  if (nFrame < mFrameNumber)
333  {
334  colorBrush = QBrush(Qt::red);
335  }
336  else if (nFrame > mFrameNumber)
337  {
338  colorBrush = QBrush(Qt::blue);
339  }
340 
341  paintToImage.drawRect(paintedImage->bounds(),
342  Qt::NoPen,
343  colorBrush,
345  false);
346  }
347 
348  // If the current frame on the current layer has a transformation, we apply it.
349  bool shouldPaintTransform = mRenderTransform && nFrame == mFrameNumber && layer == mObject->getLayer(mCurrentLayerIndex);
350  if (shouldPaintTransform)
351  {
352  paintToImage.clear(mSelection);
353  }
354 
355  painter.setWorldMatrixEnabled(true);
356  prescale(&paintToImage);
357  paintToImage.paintImage(painter, mScaledBitmap, mScaledBitmap.rect(), paintToImage.bounds());
358 
359  if (shouldPaintTransform)
360  {
361  paintTransformedSelection(painter);
362  }
363 // static int cc = 0;
364 // QString path = QString("C:/Temp/pencil2d/canvas-%1-%2-%3.png")
365 // .arg(cc++, 3, 10, QChar('0'))
366 // .arg(layer->name())
367 // .arg(mFrameNumber);
368 // Q_ASSERT(mCanvas->save(path));
369 
370 }
371 
372 void CanvasPainter::prescale(BitmapImage* bitmapImage)
373 {
374  QImage origImage = bitmapImage->image()->copy();
375 
376  // copy content of our unmodified qimage
377  // to our (not yet) scaled bitmap
378  mScaledBitmap = origImage.copy();
379 
380  if (mOptions.scaling >= 1.0f)
381  {
382  // TODO: Qt doesn't handle huge upscaled qimages well...
383  // possible solution, myPaintLib canvas renderer splits its canvas up in chunks.
384  }
385  else
386  {
387  // map to correct matrix
388  QRect mappedOrigImage = mViewTransform.mapRect(bitmapImage->bounds());
389  mScaledBitmap = mScaledBitmap.scaled(mappedOrigImage.size(),
391  }
392 }
393 
394 void CanvasPainter::paintVectorFrame(QPainter& painter,
395  Layer* layer,
396  int nFrame,
397  bool colorize,
398  bool useLastKeyFrame,
399  bool isCurrentFrame)
400 {
401 #ifdef _DEBUG
402  LayerVector* vectorLayer = dynamic_cast<LayerVector*>(layer);
403  Q_ASSERT(vectorLayer);
404 #else
405  LayerVector* vectorLayer = static_cast<LayerVector*>(layer);
406 #endif
407 
408  CANVASPAINTER_LOG("Paint Onion skin vector, Frame = %d", nFrame);
409  VectorImage* vectorImage = nullptr;
410  if (useLastKeyFrame)
411  {
412  vectorImage = vectorLayer->getLastVectorImageAtFrame(nFrame, 0);
413  }
414  else
415  {
416  vectorImage = vectorLayer->getVectorImageAtFrame(nFrame);
417  }
418  if (vectorImage == nullptr)
419  {
420  return;
421  }
422 
423  QImage* strokeImage = new QImage(mCanvas->size(), QImage::Format_ARGB32_Premultiplied);
424  vectorImage->outputImage(strokeImage, mViewTransform, mOptions.bOutlines, mOptions.bThinLines, mOptions.bAntiAlias);
425 
426  // Go through a Bitmap image to paint the onion skin colour
427  BitmapImage rasterizedVectorImage;
428  rasterizedVectorImage.setImage(strokeImage);
429 
430  if (colorize)
431  {
432  QBrush colorBrush = QBrush(Qt::transparent); //no color for the current frame
433 
434  if (nFrame < mFrameNumber)
435  {
436  colorBrush = QBrush(Qt::red);
437  }
438  else if (nFrame > mFrameNumber)
439  {
440  colorBrush = QBrush(Qt::blue);
441  }
442  rasterizedVectorImage.drawRect(strokeImage->rect(),
443  Qt::NoPen, colorBrush,
445  }
446 
447  // Don't transform the image here as we used the viewTransform in the image output
448  painter.setWorldMatrixEnabled(false);
449 
450  painter.setOpacity(vectorImage->getOpacity() - (1.0-painter.opacity()));
451  if (isCurrentFrame)
452  {
453  // Paste buffer onto image to see stroke in realtime
454  rasterizedVectorImage.paste(mBuffer, mOptions.cmBufferBlendMode);
455  }
456 
457  // Paint buffer pasted on top of vector image:
458  // fixes polyline not being rendered properly
459  rasterizedVectorImage.paintImage(painter);
460 }
461 
462 void CanvasPainter::paintTransformedSelection(QPainter& painter)
463 {
464  // Make sure there is something selected
465  if (mSelection.width() == 0 || mSelection.height() == 0)
466  return;
467 
468  Layer* layer = mObject->getLayer(mCurrentLayerIndex);
469 
470  if (layer->type() == Layer::BITMAP)
471  {
472  // Get the transformed image
473  BitmapImage* bitmapImage = static_cast<LayerBitmap*>(layer)->getLastBitmapImageAtFrame(mFrameNumber, 0);
474  if (bitmapImage == nullptr) { return; };
475  BitmapImage transformedImage = bitmapImage->transformed(mSelection, mSelectionTransform, mOptions.bAntiAlias);
476 
477  // Paint the transformation output
478  painter.setWorldMatrixEnabled(true);
479  transformedImage.paintImage(painter);
480  }
481 }
482 
489 void CanvasPainter::paintCurrentFrame(QPainter& painter, int startLayer, int endLayer)
490 {
491  painter.setOpacity(1.0);
492 
493 
494  bool isCameraLayer = mObject->getLayer(mCurrentLayerIndex)->type() == Layer::CAMERA;
495 
496  for (int i = startLayer; i <= endLayer; ++i)
497  {
498  Layer* layer = mObject->getLayer(i);
499 
500  if (layer->visible() == false)
501  continue;
502 
503  if (mOptions.eLayerVisibility == LayerVisibility::RELATED && !isCameraLayer)
504  {
506  }
507 
508  CANVASPAINTER_LOG(" Render Layer[%d] %s", i, layer->name());
509  switch (layer->type())
510  {
511  case Layer::BITMAP: { paintBitmapFrame(painter, layer, mFrameNumber, false, true, i == mCurrentLayerIndex); break; }
512  case Layer::VECTOR: { paintVectorFrame(painter, layer, mFrameNumber, false, true, i == mCurrentLayerIndex); break; }
513  default: break;
514  }
515  }
516 }
517 
519 {
520  int layerOffset = mCurrentLayerIndex - layerIndex;
521  int absoluteOffset = qAbs(layerOffset);
522  qreal newOpacity = 1.0;
523  if (absoluteOffset != 0)
524  {
525  newOpacity = qPow(static_cast<qreal>(mOptions.fLayerVisibilityThreshold), absoluteOffset);
526  }
527  return newOpacity;
528 }
529 
530 void CanvasPainter::paintAxis(QPainter& painter)
531 {
532  painter.setPen(Qt::green);
533  painter.drawLine(QLineF(0, -500, 0, 500));
534 
535  painter.setPen(Qt::red);
536  painter.drawLine(QLineF(-500, 0, 500, 0));
537 }
538 
539 int round100(double f, int gridSize)
540 {
541  return static_cast<int>(f) / gridSize * gridSize;
542 }
543 
544 void CanvasPainter::paintGrid(QPainter& painter)
545 {
546  int gridSizeW = mOptions.nGridSizeW;
547  int gridSizeH = mOptions.nGridSizeH;
548 
549  QRectF rect = painter.viewport();
550  QRectF boundingRect = mViewTransform.inverted().mapRect(rect);
551 
552  int left = round100(boundingRect.left(), gridSizeW) - gridSizeW;
553  int right = round100(boundingRect.right(), gridSizeW) + gridSizeW;
554  int top = round100(boundingRect.top(), gridSizeH) - gridSizeH;
555  int bottom = round100(boundingRect.bottom(), gridSizeH) + gridSizeH;
556 
557  QPen pen(Qt::lightGray);
558  pen.setCosmetic(true);
559  painter.setPen(pen);
560  painter.setWorldMatrixEnabled(true);
561  painter.setBrush(Qt::NoBrush);
562  QPainter::RenderHints previous_renderhints = painter.renderHints();
563  painter.setRenderHint(QPainter::Antialiasing, false);
564  // draw vertical grid lines
565  for (int x = left; x < right; x += gridSizeW)
566  {
567  painter.drawLine(x, top, x, bottom);
568  }
569 
570  // draw horizontal grid lines
571  for (int y = top; y < bottom; y += gridSizeH)
572  {
573  painter.drawLine(left, y, right, y);
574  }
575  painter.setRenderHints(previous_renderhints);
576 }
577 
578 void CanvasPainter::renderGrid(QPainter& painter)
579 {
580  if (mOptions.bGrid)
581  {
582  painter.save();
583  painter.setWorldTransform(mViewTransform);
584  paintGrid(painter);
585  painter.restore();
586  }
587 }
588 
589 void CanvasPainter::paintCameraBorder(QPainter& painter)
590 {
591  LayerCamera* cameraLayer = nullptr;
592  bool isCameraMode = false;
593 
594  // Find the first visible camera layers
595  for (int i = 0; i < mObject->getLayerCount(); ++i)
596  {
597  Layer* layer = mObject->getLayer(i);
598  if (layer->type() == Layer::CAMERA && layer->visible())
599  {
600  cameraLayer = static_cast<LayerCamera*>(layer);
601  isCameraMode = (i == mCurrentLayerIndex);
602  break;
603  }
604  }
605 
606  if (cameraLayer == nullptr) { return; }
607 
608  QRectF viewRect = painter.viewport();
609  QRect boundingRect;
610  mCameraRect = cameraLayer->getViewRect();
611 
612  QRegion rg2(mCameraRect);
613  if (isCameraMode)
614  {
615  painter.setWorldMatrixEnabled(false);
616  QTransform center = QTransform::fromTranslate(viewRect.width() / 2.0, viewRect.height() / 2.0);
617  boundingRect = viewRect.toAlignedRect();
618  mCameraRect = center.mapRect(mCameraRect);
619  rg2 = center.map(rg2);
620  }
621  else
622  {
623  painter.setWorldMatrixEnabled(true);
624  QTransform viewInverse = mViewTransform.inverted();
625  boundingRect = viewInverse.mapRect(viewRect).toAlignedRect();
626 
627  QTransform camTransform = cameraLayer->getViewAtFrame(mFrameNumber);
628  mCameraRect = camTransform.inverted().mapRect(mCameraRect);
629  rg2 = camTransform.inverted().map(rg2);
630  }
631 
632  painter.setOpacity(1.0);
633  painter.setPen(Qt::NoPen);
634  painter.setBrush(QColor(0, 0, 0, 80));
635 
636  QRegion rg1(boundingRect);
637  QRegion rg3 = rg1.subtracted(rg2);
638 
639  painter.setClipRegion(rg3);
640  painter.drawRect(boundingRect);
641 
642  /*
643  painter.setClipping(false);
644 
645  QPen pen( Qt::black,
646  2,
647  Qt::SolidLine,
648  Qt::FlatCap,
649  Qt::MiterJoin );
650  painter.setPen( pen );
651  painter.setBrush( Qt::NoBrush );
652  painter.drawRect( mCameraRect.adjusted( -1, -1, 1, 1) );
653  */
654 }
655 
656 QRect CanvasPainter::getCameraRect()
657 {
658  return mCameraRect;
659 }
QTransform fromTranslate(qreal dx, qreal dy)
void setOpacity(qreal opacity)
QSize size() const const
QSize size() const const
void paintCurrentFrame(QPainter &painter, int startLayer, int endLayer)
Paints layers within the specified range for the current frame.
void setRenderHint(QPainter::RenderHint hint, bool on)
Format_ARGB32_Premultiplied
void fill(const QColor &color)
QPainter::RenderHints renderHints() const const
QPoint map(const QPoint &point) const const
QTextStream & right(QTextStream &stream)
void save()
qreal top() const const
int height() const const
void setClipRegion(const QRegion &region, Qt::ClipOperation operation)
void drawLine(const QLineF &line)
QImage copy(const QRect &rectangle) const const
qreal left() const const
QTransform inverted(bool *invertible) const const
QTextStream & left(QTextStream &stream)
qreal bottom() const const
void drawRect(const QRectF &rectangle)
QRegion subtracted(const QRegion &r) const const
void setPen(const QColor &color)
void setWorldTransform(const QTransform &matrix, bool combine)
int width() const const
void drawPixmap(const QRectF &target, const QPixmap &pixmap, const QRectF &source)
QRect rect() const const
Definition: layer.h:38
QTextStream & center(QTextStream &stream)
void setBrush(const QBrush &brush)
qreal right() const const
CompositionMode_SourceIn
bool isEmpty() const const
void initializePainter(QPainter &painter, QPixmap &pixmap)
CanvasPainter::initializePainter Enriches the painter with a context and sets it's initial matrix...
qreal calculateRelativeOpacityForLayer(int layerIndex) const
Calculate layer opacity based on current layer offset.
QRect viewport() const const
void setRenderHints(QPainter::RenderHints hints, bool on)
void restore()
int width() const const
qreal width() const const
IgnoreAspectRatio
void setWorldMatrixEnabled(bool enable)
QRect toAlignedRect() const const
qreal height() const const
int height() const const
Definition: object.h:41
transparent
typedef RenderHints
bool begin(QPaintDevice *device)
SmoothTransformation
QRect mapRect(const QRect &rectangle) const const
void outputImage(QImage *image, QTransform myView, bool simplified, bool showThinCurves, bool antialiasing)
VectorImage::outputImage.
QImage scaled(int width, int height, Qt::AspectRatioMode aspectRatioMode, Qt::TransformationMode transformMode) const const
qreal opacity() const const