Skip to content

Commit

Permalink
Regression - #1799: Fix pen dabs being added to each other (#1800)
Browse files Browse the repository at this point in the history
Actually the first check in canvas painter would always return true because the blitRect and mTilledBuffer rect are in different coordinate spaces.
  • Loading branch information
MrStevns authored Dec 10, 2023
1 parent 8c3728f commit 363dcd7
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 27 deletions.
11 changes: 2 additions & 9 deletions core_lib/src/canvaspainter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -300,16 +300,9 @@ void CanvasPainter::paintCurrentBitmapFrame(QPainter& painter, const QRect& blit

if (isCurrentLayer && isDrawing)
{
// Certain tools require being painted continuously, for example, the Polyline tool.
// The tiled buffer does not update the area outside which it paints,
// so in that case, in order to see the previously laid-down polyline stroke,
// the surrounding area must be drawn again before
// applying the new tiled output on top
if (!blitRect.contains(mTiledBuffer->bounds()) || mOptions.bIgnoreCanvasBuffer) {
currentBitmapPainter.setCompositionMode(QPainter::CompositionMode_Source);
currentBitmapPainter.drawImage(paintedImage->topLeft(), *paintedImage->image());
}
currentBitmapPainter.drawImage(paintedImage->topLeft(), *paintedImage->image());

currentBitmapPainter.setCompositionMode(mOptions.cmBufferBlendMode);
const auto tiles = mTiledBuffer->tiles();
for (const Tile* tile : tiles) {
currentBitmapPainter.drawPixmap(tile->posF(), tile->pixmap());
Expand Down
3 changes: 0 additions & 3 deletions core_lib/src/canvaspainter.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,6 @@ struct CanvasPainterOptions
bool bThinLines = false;
bool bOutlines = false;

/// When using a tool that can't rely on canvas buffer,
/// for example Polyline because we're continously clearing the surface
bool bIgnoreCanvasBuffer = false;
LayerVisibility eLayerVisibility = LayerVisibility::RELATED;
float fLayerVisibilityThreshold = 0.f;
float scaling = 1.0f;
Expand Down
33 changes: 20 additions & 13 deletions core_lib/src/interface/scribblearea.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -202,16 +202,6 @@ void ScribbleArea::onTileUpdated(TiledBuffer* tiledBuffer, Tile* tile)
void ScribbleArea::onTileCreated(TiledBuffer* tiledBuffer, Tile* tile)
{
Q_UNUSED(tiledBuffer)
Layer::LAYER_TYPE layerType = mEditor->layers()->currentLayer()->type();
if (layerType == Layer::BITMAP) {
const auto& bitmapImage = currentBitmapImage(mEditor->layers()->currentLayer());
const QImage& image = *bitmapImage->image();
tile->load(image, bitmapImage->topLeft());
} else if (layerType == Layer::VECTOR) {

// Not used, we only use the buffer to paint the stroke before painting the real vector stroke
}

const QRectF& mappedRect = mEditor->view()->getView().mapRect(QRectF(tile->bounds()));
update(mappedRect.toAlignedRect());
}
Expand Down Expand Up @@ -855,7 +845,24 @@ void ScribbleArea::paintBitmapBuffer()
BitmapImage* targetImage = currentBitmapImage(layer);
if (targetImage != nullptr)
{
targetImage->paste(&mTiledBuffer, QPainter::CompositionMode_Source);
QPainter::CompositionMode cm = QPainter::CompositionMode_SourceOver;
switch (currentTool()->type())
{
case ERASER:
cm = QPainter::CompositionMode_DestinationOut;
break;
case BRUSH:
case PEN:
case PENCIL:
if (currentTool()->properties.preserveAlpha)
{
cm = QPainter::CompositionMode_SourceOver;
}
break;
default: //nothing
break;
}
targetImage->paste(&mTiledBuffer, cm);
}

QRect rect = mEditor->view()->mapCanvasToScreen(mTiledBuffer.bounds()).toRect();
Expand Down Expand Up @@ -1208,7 +1215,6 @@ void ScribbleArea::prepCanvas(int frame)
o.fLayerVisibilityThreshold = mPrefs->getFloat(SETTING::LAYER_VISIBILITY_THRESHOLD);
o.scaling = mEditor->view()->scaling();
o.cmBufferBlendMode = mEditor->tools()->currentTool()->type() == ToolType::ERASER ? QPainter::CompositionMode_DestinationOut : QPainter::CompositionMode_SourceOver;
o.bIgnoreCanvasBuffer = currentTool()->type() == POLYLINE;

OnionSkinPainterOptions onionSkinOptions;
onionSkinOptions.enabledWhilePlaying = mPrefs->getInt(SETTING::ONION_WHILE_PLAYBACK);
Expand Down Expand Up @@ -1270,7 +1276,8 @@ void ScribbleArea::drawPath(QPainterPath path, QPen pen, QBrush brush, QPainter:

void ScribbleArea::drawPen(QPointF thePoint, qreal brushWidth, QColor fillColor, bool useAA)
{
mTiledBuffer.drawBrush(thePoint, brushWidth, mEditor->view()->mapScreenToCanvas(mCursorImg.rect()).width(), Qt::NoPen, QBrush(fillColor, Qt::SolidPattern), QPainter::CompositionMode_SourceOver, useAA);
// We use Source as opposed to SourceOver here to avoid the dabs being added on top of each other
mTiledBuffer.drawBrush(thePoint, brushWidth, mEditor->view()->mapScreenToCanvas(mCursorImg.rect()).width(), Qt::NoPen, QBrush(fillColor, Qt::SolidPattern), QPainter::CompositionMode_Source, useAA);
}

void ScribbleArea::drawPencil(QPointF thePoint, qreal brushWidth, qreal fixedBrushFeather, QColor fillColor, qreal opacity)
Expand Down
4 changes: 2 additions & 2 deletions core_lib/src/tool/erasertool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ void EraserTool::paintAt(QPointF point)
brushWidth,
properties.feather,
QColor(255, 255, 255, 255),
QPainter::CompositionMode_DestinationOut,
QPainter::CompositionMode_SourceOver,
opacity,
properties.useFeather,
properties.useAA == ON);
Expand Down Expand Up @@ -240,7 +240,7 @@ void EraserTool::drawStroke()
brushWidth,
properties.feather,
Qt::white,
QPainter::CompositionMode_DestinationOut,
QPainter::CompositionMode_SourceOver,
opacity,
properties.useFeather,
properties.useAA == ON);
Expand Down

0 comments on commit 363dcd7

Please sign in to comment.