17 #include "canvaspainter.h"
21 #include "layerbitmap.h"
22 #include "layervector.h"
23 #include "bitmapimage.h"
24 #include "layercamera.h"
25 #include "vectorimage.h"
29 CanvasPainter::CanvasPainter()
33 CanvasPainter::~CanvasPainter()
37 void CanvasPainter::setCanvas(
QPixmap* canvas)
45 if (mViewTransform != view || mViewInverse != viewInverse) {
46 mViewTransform = view;
47 mViewInverse = viewInverse;
51 void CanvasPainter::setTransformedSelection(
QRect selection,
QTransform transform)
54 if (selection.
width() > 0 && selection.
height() > 0)
56 mSelection = selection;
57 mSelectionTransform = transform;
58 mRenderTransform =
true;
63 ignoreTransformedSelection();
67 void CanvasPainter::ignoreTransformedSelection()
69 mRenderTransform =
false;
72 void CanvasPainter::paintCached()
84 renderPreLayers(painter);
85 mPreLayersCache.reset(
new QPixmap(*mCanvas));
90 painter.
drawPixmap(0, 0, *(mPreLayersCache.get()));
94 renderCurLayer(painter);
96 if (!mPostLayersCache)
98 renderPostLayers(tempPainter);
99 mPostLayersCache.reset(
new QPixmap(tempPixmap));
107 painter.
drawPixmap(0, 0, *(mPostLayersCache.get()));
112 void CanvasPainter::resetLayerCache()
114 mPreLayersCache.reset();
115 mPostLayersCache.reset();
120 painter.
begin(&pixmap);
125 void CanvasPainter::renderPreLayers(
QPixmap* pixmap)
129 renderPreLayers(painter);
132 void CanvasPainter::renderPreLayers(
QPainter& painter)
134 if (mOptions.eLayerVisibility != LayerVisibility::CURRENTONLY || mObject->getLayer(mCurrentLayerIndex)->type() == Layer::CAMERA)
139 paintOnionSkin(painter);
143 void CanvasPainter::renderCurLayer(
QPixmap* pixmap)
147 renderCurLayer(painter);
150 void CanvasPainter::renderCurLayer(
QPainter& painter)
155 void CanvasPainter::renderPostLayers(
QPixmap* pixmap)
159 renderPostLayers(painter);
162 void CanvasPainter::renderPostLayers(
QPainter& painter)
164 if (mOptions.eLayerVisibility != LayerVisibility::CURRENTONLY || mObject->getLayer(mCurrentLayerIndex)->type() == Layer::CAMERA)
166 paintCurrentFrame(painter, mCurrentLayerIndex + 1, mObject->getLayerCount() - 1);
169 paintCameraBorder(painter);
178 void CanvasPainter::setPaintSettings(
const Object*
object,
int currentLayer,
int frame,
QRect rect,
BitmapImage* buffer)
184 CANVASPAINTER_LOG(
"Set CurrentLayerIndex = %d", currentLayer);
185 mCurrentLayerIndex = currentLayer;
186 mFrameNumber = frame;
190 void CanvasPainter::paint()
195 renderPreLayers(painter);
196 renderCurLayer(painter);
197 renderPostLayers(painter);
200 void CanvasPainter::paintBackground()
205 void CanvasPainter::paintOnionSkin(
QPainter& painter)
207 if (!mOptions.onionWhilePlayback && mOptions.isPlaying) {
return; }
209 Layer* layer = mObject->getLayer(mCurrentLayerIndex);
211 if (layer->visible() ==
false)
214 if (layer->keyFrameCount() == 0)
217 qreal minOpacity =
static_cast<qreal
>(mOptions.fOnionSkinMinOpacity / 100);
218 qreal maxOpacity =
static_cast<qreal
>(mOptions.fOnionSkinMaxOpacity / 100);
220 if (mOptions.bPrevOnionSkin && mFrameNumber > 1)
223 qreal prevOpacityIncrement = (maxOpacity - minOpacity) / mOptions.nPrevOnionSkinCount;
224 qreal opacity = maxOpacity;
226 int onionFrameNumber = mFrameNumber;
227 if (mOptions.bIsOnionAbsolute)
229 onionFrameNumber = layer->getPreviousFrameNumber(onionFrameNumber + 1,
true);
231 onionFrameNumber = layer->getPreviousFrameNumber(onionFrameNumber, mOptions.bIsOnionAbsolute);
233 int onionPosition = 0;
235 while (onionPosition < mOptions.nPrevOnionSkinCount && onionFrameNumber > 0)
239 switch (layer->type())
241 case Layer::BITMAP: { paintBitmapFrame(painter, layer, onionFrameNumber, mOptions.bColorizePrevOnion,
false,
false);
break; }
242 case Layer::VECTOR: { paintVectorFrame(painter, layer, onionFrameNumber, mOptions.bColorizePrevOnion,
false,
false);
break; }
245 opacity = opacity - prevOpacityIncrement;
247 onionFrameNumber = layer->getPreviousFrameNumber(onionFrameNumber, mOptions.bIsOnionAbsolute);
252 if (mOptions.bNextOnionSkin)
255 qreal nextOpacityIncrement = (maxOpacity - minOpacity) / mOptions.nNextOnionSkinCount;
256 qreal opacity = maxOpacity;
258 int onionFrameNumber = layer->getNextFrameNumber(mFrameNumber, mOptions.bIsOnionAbsolute);
259 int onionPosition = 0;
261 while (onionPosition < mOptions.nNextOnionSkinCount && onionFrameNumber > 0)
265 switch (layer->type())
267 case Layer::BITMAP: { paintBitmapFrame(painter, layer, onionFrameNumber, mOptions.bColorizeNextOnion,
false,
false);
break; }
268 case Layer::VECTOR: { paintVectorFrame(painter, layer, onionFrameNumber, mOptions.bColorizeNextOnion,
false,
false);
break; }
271 opacity = opacity - nextOpacityIncrement;
273 onionFrameNumber = layer->getNextFrameNumber(onionFrameNumber, mOptions.bIsOnionAbsolute);
279 void CanvasPainter::paintBitmapFrame(
QPainter& painter,
283 bool useLastKeyFrame,
288 Q_ASSERT(bitmapLayer);
293 CANVASPAINTER_LOG(
" Paint Bitmap Frame = %d, UseLastKeyFrame = %d", nFrame, useLastKeyFrame);
297 paintedImage = bitmapLayer->getLastBitmapImageAtFrame(nFrame, 0);
298 CANVASPAINTER_LOG(
" Actual frame = %d", paintedImage->pos());
302 paintedImage = bitmapLayer->getBitmapImageAtFrame(nFrame);
305 if (paintedImage ==
nullptr) {
return; }
306 paintedImage->loadFile();
307 CANVASPAINTER_LOG(
" Paint Image Size: %dx%d", paintedImage->image()->
width(), paintedImage->image()->
height());
309 const bool frameIsEmpty = (paintedImage ==
nullptr || paintedImage->bounds().
isEmpty());
310 const bool isDrawing = isCurrentFrame && mBuffer && !mBuffer->bounds().
isEmpty();
311 if (frameIsEmpty && !isDrawing)
313 CANVASPAINTER_LOG(
" Early return frame %d, %d", frameIsEmpty, isDrawing);
318 paintToImage.paste(paintedImage);
322 paintToImage.paste(mBuffer, mOptions.cmBufferBlendMode);
329 if (nFrame < mFrameNumber)
333 else if (nFrame > mFrameNumber)
338 paintToImage.drawRect(paintedImage->bounds(),
346 bool shouldPaintTransform = mRenderTransform && nFrame == mFrameNumber && layer == mObject->getLayer(mCurrentLayerIndex);
347 if (shouldPaintTransform)
349 paintToImage.clear(mSelection);
354 prescale(&paintToImage);
355 paintToImage.paintImage(painter, mScaledBitmap, mScaledBitmap.
rect(), paintToImage.bounds());
357 if (shouldPaintTransform)
359 paintTransformedSelection(painter);
370 void CanvasPainter::prescale(
BitmapImage* bitmapImage)
372 QImage origImage = bitmapImage->image()->
copy();
376 mScaledBitmap = origImage.
copy();
378 if (mOptions.scaling >= 1.0f)
386 QRect mappedOrigImage = mViewTransform.
mapRect(bitmapImage->bounds());
387 mScaledBitmap = mScaledBitmap.
scaled(mappedOrigImage.
size(),
392 void CanvasPainter::paintVectorFrame(
QPainter& painter,
396 bool useLastKeyFrame,
401 Q_ASSERT(vectorLayer);
406 CANVASPAINTER_LOG(
"Paint Onion skin vector, Frame = %d", nFrame);
410 vectorImage = vectorLayer->getLastVectorImageAtFrame(nFrame, 0);
414 vectorImage = vectorLayer->getVectorImageAtFrame(nFrame);
416 if (vectorImage ==
nullptr)
422 vectorImage->
outputImage(strokeImage, mViewTransform, mOptions.bOutlines, mOptions.bThinLines, mOptions.bAntiAlias);
426 rasterizedVectorImage.setImage(strokeImage);
432 if (nFrame < mFrameNumber)
436 else if (nFrame > mFrameNumber)
440 rasterizedVectorImage.drawRect(strokeImage->
rect(),
449 rasterizedVectorImage.paintImage(painter);
453 rasterizedVectorImage.paste(mBuffer, mOptions.cmBufferBlendMode);
458 rasterizedVectorImage.paintImage(painter);
461 void CanvasPainter::paintTransformedSelection(
QPainter& painter)
464 if (mSelection.
width() == 0 || mSelection.
height() == 0)
467 Layer* layer = mObject->getLayer(mCurrentLayerIndex);
469 if (layer->type() == Layer::BITMAP)
473 if (bitmapImage ==
nullptr) {
return; };
474 BitmapImage transformedImage = bitmapImage->transformed(mSelection, mSelectionTransform, mOptions.bAntiAlias);
478 transformedImage.paintImage(painter);
493 bool isCameraLayer = mObject->getLayer(mCurrentLayerIndex)->type() == Layer::CAMERA;
495 for (
int i = startLayer; i <= endLayer; ++i)
497 Layer* layer = mObject->getLayer(i);
499 if (layer->visible() ==
false)
502 if (mOptions.eLayerVisibility == LayerVisibility::RELATED && !isCameraLayer)
507 CANVASPAINTER_LOG(
" Render Layer[%d] %s", i, layer->name());
508 switch (layer->type())
510 case Layer::BITMAP: { paintBitmapFrame(painter, layer, mFrameNumber,
false,
true, i == mCurrentLayerIndex);
break; }
511 case Layer::VECTOR: { paintVectorFrame(painter, layer, mFrameNumber,
false,
true, i == mCurrentLayerIndex);
break; }
519 int layerOffset = mCurrentLayerIndex - layerIndex;
520 int absoluteOffset = qAbs(layerOffset);
521 qreal newOpacity = 1.0;
522 if (absoluteOffset != 0)
524 newOpacity = qPow(static_cast<qreal>(mOptions.fLayerVisibilityThreshold), absoluteOffset);
529 void CanvasPainter::paintAxis(
QPainter& painter)
538 int round100(
double f,
int gridSize)
540 return static_cast<int>(f) / gridSize * gridSize;
543 void CanvasPainter::paintGrid(
QPainter& painter)
545 int gridSizeW = mOptions.nGridSizeW;
546 int gridSizeH = mOptions.nGridSizeH;
551 int left = round100(boundingRect.
left(), gridSizeW) - gridSizeW;
552 int right = round100(boundingRect.
right(), gridSizeW) + gridSizeW;
553 int top = round100(boundingRect.
top(), gridSizeH) - gridSizeH;
554 int bottom = round100(boundingRect.
bottom(), gridSizeH) + gridSizeH;
557 pen.setCosmetic(
true);
564 for (
int x = left; x < right; x += gridSizeW)
566 painter.
drawLine(x, top, x, bottom);
570 for (
int y = top; y < bottom; y += gridSizeH)
572 painter.
drawLine(left, y, right, y);
577 void CanvasPainter::paintOverlayCenter(
QPainter& painter)
579 QRect rect = getCameraRect();
581 Layer* layer = mObject->getLayer(mCurrentLayerIndex);
582 bool isCameraMode = (layer->type() == Layer::CAMERA);
590 dashes << 10 << space << 10 << space << 10 << space;
591 pen.setDashPattern(dashes);
592 pen.setCosmetic(
true);
598 QPoint offsetX(OVERLAY_SAFE_CENTER_CROSS_SIZE, 0), offsetY(0, OVERLAY_SAFE_CENTER_CROSS_SIZE);
607 void CanvasPainter::paintOverlayThirds(
QPainter& painter)
609 QRect rect = getCameraRect();
613 Layer* layer = mObject->getLayer(mCurrentLayerIndex);
614 bool isCameraMode = (layer->type() == Layer::CAMERA);
619 dashes << 10 << space << 10 << space << 10 << space;
620 pen.setDashPattern(dashes);
621 pen.setCosmetic(
true);
637 void CanvasPainter::paintOverlayGolden(
QPainter& painter)
639 QRect rect = getCameraRect();
643 Layer* layer = mObject->getLayer(mCurrentLayerIndex);
644 bool isCameraMode = (layer->type() == Layer::CAMERA);
649 dashes << 10 << space << 10 << space << 10 << space;
650 pen.setDashPattern(dashes);
651 pen.setCosmetic(
true);
658 painter.
drawLine(rect.
x(),
static_cast<int>(rect.
y() + (rect.
height() * 0.38)), rect.
right(),
static_cast<int>(rect.
y() + (rect.
height() * 0.38)));
659 painter.
drawLine(rect.
x(),
static_cast<int>(rect.
y() + (rect.
height() * 0.62)), rect.
x() + rect.
width(),
static_cast<int>(rect.
y() + (rect.
height() * 0.62)));
660 painter.
drawLine(static_cast<int>(rect.
x() + rect.
width() * 0.38), rect.
y(),
static_cast<int>(rect.
x() + rect.
width() * 0.38), rect.
bottom());
661 painter.
drawLine(static_cast<int>(rect.
x() + rect.
width() * 0.62), rect.
y(),
static_cast<int>(rect.
x() + rect.
width() * 0.62), rect.
bottom());
667 void CanvasPainter::paintOverlaySafeAreas(
QPainter& painter)
669 QRect rect = getCameraRect();
671 Layer* layer = mObject->getLayer(mCurrentLayerIndex);
672 bool isCameraMode = (layer->type() == Layer::CAMERA);
679 dashes << 10 << space << 10 << space << 10 << space;
680 pen.setDashPattern(dashes);
681 pen.setCosmetic(
true);
688 if (mOptions.bActionSafe)
690 int action = mOptions.nActionSafe;
692 rect.
y() + rect.
height() * action / 200,
693 rect.
width() * (100 - action) / 100,
694 rect.
height() * (100 - action) / 100);
697 if (mOptions.bShowSafeAreaHelperText)
702 if (mOptions.bTitleSafe)
704 int title = mOptions.nTitleSafe;
706 rect.
y() + rect.
height() * title / 200,
707 rect.
width() * (100 - title) / 100,
708 rect.
height() * (100 - title) / 100);
711 if (mOptions.bShowSafeAreaHelperText)
721 void CanvasPainter::renderGrid(
QPainter& painter)
732 void CanvasPainter::renderOverlays(
QPainter& painter)
734 if (mOptions.bCenter)
738 paintOverlayCenter(painter);
741 if (mOptions.bThirds)
745 paintOverlayThirds(painter);
748 if (mOptions.bGoldenRatio)
752 paintOverlayGolden(painter);
755 if (mOptions.bSafeArea)
759 paintOverlaySafeAreas(painter);
765 void CanvasPainter::paintCameraBorder(
QPainter& painter)
768 bool isCameraMode =
false;
771 for (
int i = 0; i < mObject->getLayerCount(); ++i)
773 Layer* layer = mObject->getLayer(i);
774 if (layer->type() == Layer::CAMERA && layer->visible())
777 isCameraMode = (i == mCurrentLayerIndex);
782 if (cameraLayer ==
nullptr) {
return; }
786 mCameraRect = cameraLayer->getViewRect();
794 mCameraRect = center.
mapRect(mCameraRect);
795 rg2 = center.
map(rg2);
801 boundingRect = viewInverse.
mapRect(viewRect).toAlignedRect();
803 QTransform camTransform = cameraLayer->getViewAtFrame(mFrameNumber);
832 QRect CanvasPainter::getCameraRect()
void setOpacity(qreal opacity)
void setCompositionMode(QPainter::CompositionMode mode)
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)
void fill(const QColor &color)
QPainter::RenderHints renderHints() const const
QTextStream & right(QTextStream &stream)
void setClipRegion(const QRegion ®ion, Qt::ClipOperation operation)
void drawLine(const QLineF &line)
QImage copy(const QRect &rectangle) const const
QString tr(const char *sourceText, const char *disambiguation, int n)
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 drawPixmap(const QRectF &target, const QPixmap &pixmap, const QRectF &source)
QTextStream & center(QTextStream &stream)
void setBrush(const QBrush &brush)
void drawText(const QPointF &position, const QString &text)
QPoint center() const const
qreal right() const const
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)
qreal width() const const
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
void setWorldMatrixEnabled(bool enable)
QRect toAlignedRect() const const
qreal height() const const
bool begin(QPaintDevice *device)
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