All Classes Namespaces Functions Variables Enumerations Properties Pages
test_bitmapbucket.cpp
1 #include "catch.hpp"
2 
3 #include "layermanager.h"
4 #include "filemanager.h"
5 #include "scribblearea.h"
6 
7 #include <QDir>
8 
9 #include "layerbitmap.h"
10 
11 #include "object.h"
12 #include "editor.h"
13 #include "bitmapbucket.h"
14 #include "bitmapimage.h"
15 
16 #include "basetool.h"
17 
18 void dragAndFill(QPointF movePoint, Editor* editor, QColor color, QRect bounds, Properties properties) {
19  int moveX = 0;
20 
21  BitmapBucket bucket = BitmapBucket(editor, color, bounds, movePoint, properties);
22  QPointF movingPoint = movePoint;
23 
24  int fillCount = 0;
25  while (moveX < 40) {
26  moveX++;
27  movingPoint.setX(movingPoint.x()+1);
28 
29  bucket.paint(movingPoint, [&fillCount] (BucketState state, int, int ) {
30 
31  if (state == BucketState::DidFillTarget) {
32  fillCount++;
33  }
34  });
35  }
36 
37  // Make sure that only 4 fills has been applied
38  // otherwise we're spilling onto unwanted pixels
39  REQUIRE(fillCount == 4);
40 }
41 
42 void verifyPixels(QPoint referencePoint, const BitmapImage* image, QRgb fillColor)
43 {
44  REQUIRE(image->constScanLine(referencePoint.x(), referencePoint.y()) == fillColor);
45 
46  // pixels that are not transparent nor the given fill color, should be left untouched
47  REQUIRE(image->constScanLine(referencePoint.x()+4, referencePoint.y()) != fillColor);
48  REQUIRE(image->constScanLine(referencePoint.x()+5, referencePoint.y()) != fillColor);
49  REQUIRE(image->constScanLine(referencePoint.x()+6, referencePoint.y()) != fillColor);
50 }
51 
52 TEST_CASE("BitmapBucket - Fill drag logic")
53 {
54  FileManager fm;
55  Object* obj = fm.load(":/fill-drag-test/fill-drag-test.pcl");
56  Editor* editor = new Editor;
57  ScribbleArea* scribbleArea = new ScribbleArea(nullptr);
58  editor->setScribbleArea(scribbleArea);
59  editor->setObject(obj);
60  editor->init();
61 
62  Properties properties;
63 
64  QDir dir;
65  QString resultsPath = dir.currentPath() + "/fill-drag-test/";
66 
67  dir.mkpath(resultsPath);
68 
69  properties.bucketFillReferenceMode = 0;
70  properties.bucketFillToLayerMode = 0;
71  properties.bucketFillExpandEnabled = false;
72  properties.fillMode = 0;
73 
74  QColor fillColor = QColor(255,255,0,100);
75 
76  BitmapImage beforeFill = *static_cast<LayerBitmap*>(editor->layers()->currentLayer())->getBitmapImageAtFrame(1);
77 
78  QPoint pressPoint = beforeFill.bounds().topLeft();
79 
80  pressPoint.setX(pressPoint.x()+3);
81  pressPoint.setY(pressPoint.y()+7);
82 
83  REQUIRE(beforeFill.constScanLine(pressPoint.x(), pressPoint.y()) == 0);
84 
85  SECTION("FillTo: CurrentLayer - Reference: Current Layer")
86  {
87  dragAndFill(pressPoint, editor, fillColor, beforeFill.bounds(), properties);
88 
89  BitmapImage* image = static_cast<LayerBitmap*>(editor->layers()->currentLayer())->getLastBitmapImageAtFrame(1);
90 
91  image->writeFile(resultsPath + "test1.png");
92 
93  verifyPixels(pressPoint, image, fillColor.rgba());
94  }
95 
96  SECTION("FillTo: Layer below - reference: current layer")
97  {
98  properties.bucketFillToLayerMode = 1;
99 
100  dragAndFill(pressPoint, editor, fillColor, beforeFill.bounds(), properties);
101 
102  // Verify that colors are correct on layer below
103  BitmapImage* image = static_cast<LayerBitmap*>(editor->layers()->getLayer(editor->currentLayerIndex()-1))->getLastBitmapImageAtFrame(1);
104 
105  image->writeFile(resultsPath + "test2.png");
106 
107  verifyPixels(pressPoint, image, qPremultiply(fillColor.rgba()));
108  }
109 
110 
111  SECTION("FillTo: Layer below - reference: all layers")
112  {
113  properties.bucketFillToLayerMode = 1;
114  properties.bucketFillReferenceMode = 1;
115 
116  dragAndFill(pressPoint, editor, fillColor, beforeFill.bounds(), properties);
117 
118  BitmapImage* image = static_cast<LayerBitmap*>(editor->layers()->getLayer(editor->currentLayerIndex()-1))->getLastBitmapImageAtFrame(1);
119 
120  image->writeFile(resultsPath + "test3.png");
121 
122  verifyPixels(pressPoint, image, qPremultiply(fillColor.rgba()));
123  }
124 
125  SECTION("FillTo: Current layer - reference: all layers")
126  {
127  properties.bucketFillToLayerMode = 0;
128  properties.bucketFillReferenceMode = 1;
129 
130  dragAndFill(pressPoint, editor, fillColor, beforeFill.bounds(), properties);
131 
132  BitmapImage* image = static_cast<LayerBitmap*>(editor->layers()->currentLayer())->getLastBitmapImageAtFrame(1);
133 
134  image->writeFile(resultsPath + "test4.png");
135 
136  verifyPixels(pressPoint, image, fillColor.rgba());
137  }
138 }
QString currentPath()
int x() const const
int y() const const
qreal x() const const
void paint(const QPointF updatedPoint, std::function< void(BucketState, int, int)> progress)
Will paint at the given point, given that it makes sense.
void setX(qreal x)
QPoint topLeft() const const
void setX(int x)
void setY(int y)
Definition: object.h:41
Definition: editor.h:55
bool mkpath(const QString &dirPath) const const
QRgb rgba() const const