Skip to content

Commit

Permalink
Fix path preview and selection mask bounds
Browse files Browse the repository at this point in the history
They now add a margin depending on the zoom level, which fixes rendering
glitches on some systems.
  • Loading branch information
askmeaboutlo0m committed Aug 12, 2024
1 parent b1847b9 commit 4a0d110
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 11 deletions.
1 change: 1 addition & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
Unreleased Version 2.2.2-pre
* Fix: Solve rendering glitches with selection outlines that happen on some systems. Thanks xxxx for reporting.

2024-08-09 Version 2.2.2-beta.3
* Fix: Use more accurate timers for performance profiles if the platform supports it.
Expand Down
10 changes: 8 additions & 2 deletions src/desktop/scene/canvasscene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,12 @@ void CanvasScene::setZoom(qreal zoom)
{
if(zoom != m_zoom) {
m_zoom = zoom;
if(m_pathPreview) {
m_pathPreview->setZoom(zoom);
}
if(m_selection) {
m_selection->setZoom(zoom);
}
if(m_transform) {
m_transform->setZoom(zoom);
}
Expand Down Expand Up @@ -441,7 +447,7 @@ void CanvasScene::setSelection(
if(valid) {
if(!m_selection) {
m_selection = new SelectionItem(
m_selectionIgnored, m_showSelectionMask, m_group);
m_selectionIgnored, m_showSelectionMask, m_zoom, m_group);
m_selection->setUpdateSceneOnRefresh(true);
}
m_selection->setModel(bounds, mask);
Expand Down Expand Up @@ -779,7 +785,7 @@ void CanvasScene::setPathPreview(const QPainterPath &path)
} else if(m_pathPreview) {
m_pathPreview->setPath(path);
} else {
m_pathPreview = new PathPreviewItem(path, m_group);
m_pathPreview = new PathPreviewItem(path, m_zoom, m_group);
}
}

Expand Down
15 changes: 13 additions & 2 deletions src/desktop/scene/pathpreviewitem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,22 @@
#include <QMarginsF>
#include <QPaintEngine>
#include <QPainter>
#include <cmath>

namespace drawingboard {

PathPreviewItem::PathPreviewItem(
const QPainterPath &path, QGraphicsItem *parent)
const QPainterPath &path, qreal zoom, QGraphicsItem *parent)
: BaseItem(parent)
, m_path(path)
, m_zoom(zoom)
{
}

QRectF PathPreviewItem::boundingRect() const
{
return m_path.boundingRect().marginsAdded(QMarginsF(1.0, 1.0, 1.0, 1.0));
qreal m = m_zoom > 0.0 ? std::ceil(1.0 / m_zoom) : 1.0;
return m_path.boundingRect().marginsAdded(QMarginsF(m, m, m, m));
}

void PathPreviewItem::setPath(const QPainterPath &path)
Expand All @@ -24,6 +27,14 @@ void PathPreviewItem::setPath(const QPainterPath &path)
m_path = path;
}

void PathPreviewItem::setZoom(qreal zoom)
{
if(zoom != m_zoom) {
refreshGeometry();
m_zoom = zoom;
}
}

void PathPreviewItem::paint(
QPainter *painter, const QStyleOptionGraphicsItem *options, QWidget *widget)
{
Expand Down
5 changes: 4 additions & 1 deletion src/desktop/scene/pathpreviewitem.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@ class PathPreviewItem final : public BaseItem {
public:
enum { Type = PathPreviewType };

PathPreviewItem(const QPainterPath &path, QGraphicsItem *parent = nullptr);
PathPreviewItem(
const QPainterPath &path, qreal zoom, QGraphicsItem *parent = nullptr);

QRectF boundingRect() const override;

int type() const override { return Type; }

void setPath(const QPainterPath &path);
void setZoom(qreal zoom);

protected:
void paint(
Expand All @@ -25,6 +27,7 @@ class PathPreviewItem final : public BaseItem {

private:
QPainterPath m_path;
qreal m_zoom;
};

}
Expand Down
19 changes: 16 additions & 3 deletions src/desktop/scene/selectionitem.cpp
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
// SPDX-License-Identifier: GPL-3.0-or-later
#include "desktop/scene/selectionitem.h"
#include "libclient/utils/selectionoutlinegenerator.h"
#include <QMarginsF>
#include <QPainter>
#include <QThreadPool>
#include <cmath>

namespace drawingboard {

SelectionItem::SelectionItem(bool ignored, bool showMask, QGraphicsItem *parent)
SelectionItem::SelectionItem(
bool ignored, bool showMask, qreal zoom, QGraphicsItem *parent)
: BaseObject(parent)
, m_zoom(zoom)
, m_ignored(ignored)
, m_showMask(showMask)
{
Expand All @@ -29,6 +32,7 @@ void SelectionItem::setModel(const QRect &bounds, const QImage &mask)
m_maskOpacity = 0.0;
m_haveTemporaryMask = true;
updateBoundingRectFromBounds();
setPos(m_bounds.topLeft());
if(m_bounds.isEmpty()) {
qWarning("Selection mask is empty");
} else if(canShowOutline()) {
Expand Down Expand Up @@ -69,6 +73,14 @@ void SelectionItem::setShowMask(bool showMask)
}
}

void SelectionItem::setZoom(qreal zoom)
{
if(zoom != m_zoom) {
m_zoom = zoom;
updateBoundingRectFromBounds();
}
}

void SelectionItem::animationStep(qreal dt)
{
bool havePath = !m_path.isEmpty();
Expand Down Expand Up @@ -173,8 +185,9 @@ void SelectionItem::setOutline(
void SelectionItem::updateBoundingRectFromBounds()
{
refreshGeometry();
m_boundingRect = QRectF(QPointF(0.0, 0.0), QSizeF(m_bounds.size()));
setPos(m_bounds.topLeft());
qreal m = m_zoom > 0.0 ? std::ceil(1.0 / m_zoom) : 1.0;
m_boundingRect = QRectF(QPointF(0.0, 0.0), QSizeF(m_bounds.size()))
.marginsAdded(QMarginsF(m, m, m, m));
}

}
6 changes: 5 additions & 1 deletion src/desktop/scene/selectionitem.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ class SelectionItem final : public BaseObject {
public:
enum { Type = SelectionType };

SelectionItem(bool ignored, bool showMask, QGraphicsItem *parent = nullptr);
SelectionItem(
bool ignored, bool showMask, qreal zoom,
QGraphicsItem *parent = nullptr);

int type() const override { return Type; }

Expand All @@ -30,6 +32,7 @@ class SelectionItem final : public BaseObject {

void setIgnored(bool ignored);
void setShowMask(bool showMask);
void setZoom(qreal zoom);

void animationStep(qreal dt);

Expand All @@ -50,6 +53,7 @@ class SelectionItem final : public BaseObject {
QRect m_bounds;
QPainterPath m_path;
QImage m_mask;
qreal m_zoom;
qreal m_marchingAnts = 0.0;
qreal m_maskOpacity = 0.0;
qreal m_transparentDelay = 0.0;
Expand Down
10 changes: 8 additions & 2 deletions src/desktop/view/canvasscene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,12 @@ void CanvasScene::setZoom(qreal zoom)
{
if(zoom != m_zoom) {
m_zoom = zoom;
if(m_pathPreview) {
m_pathPreview->setZoom(zoom);
}
if(m_selection) {
m_selection->setZoom(zoom);
}
if(m_transform) {
m_transform->setZoom(zoom);
}
Expand Down Expand Up @@ -304,7 +310,7 @@ void CanvasScene::setPathPreview(const QPainterPath &path)
} else if(m_pathPreview) {
m_pathPreview->setPath(path);
} else {
m_pathPreview = new PathPreviewItem(path, m_canvasGroup);
m_pathPreview = new PathPreviewItem(path, m_zoom, m_canvasGroup);
m_pathPreview->setUpdateSceneOnRefresh(true);
}
}
Expand Down Expand Up @@ -625,7 +631,7 @@ void CanvasScene::setSelection(
if(valid) {
if(!m_selection) {
m_selection = new SelectionItem(
m_selectionIgnored, m_showSelectionMask, m_canvasGroup);
m_selectionIgnored, m_showSelectionMask, m_zoom, m_canvasGroup);
m_selection->setUpdateSceneOnRefresh(true);
}
m_selection->setModel(bounds, mask);
Expand Down

0 comments on commit 4a0d110

Please sign in to comment.