Review 1 fixes for 13.9a and 13.9b: the rounded move, effects while moving and dragging a gradient, a draft in a clipping stack pinned; stale Soft Light, nine-mode and 12.7a lines corrected
This commit is contained in:
1 parent
81894f744a
commit
382c9c20ad
5 files changed
+116
-8
No files matched your search
@@ -187,7 +187,7 @@ void AdjustmentLayerTests::adjustmentBlendAndSoftMaskPreserveCoverage()
|
||||
s.updateAdjustment(id, value);
|
||||
s.setLayerBlendMode(LayerBlendMode::multiply);
|
||||
QVERIFY((rendered(s) == std::vector<int>{0, 0, 0, 255, 0, 0, 0, 128, 0, 0, 0, 32, 0, 0, 0, 0}));
|
||||
// Green over red adds to yellow; Swift adjusts as Normal.
|
||||
// Green over red adds to yellow, as Swift 1.4.
|
||||
s.setLayerBlendMode(LayerBlendMode::linearDodge);
|
||||
QVERIFY((part(rendered(s), 0, 4) == std::vector<int>{255, 255, 0, 255}));
|
||||
QCOMPARE(rendered(s)[7], 128);
|
||||
|
||||
@@ -34,6 +34,7 @@ private slots:
|
||||
void aGradientInASelectionShowsAsItsCommit();
|
||||
void aGradientThatCannotFillCancels();
|
||||
void aLiveMaskFromFurtherDownShowsAsTheExport();
|
||||
void aDraftOnAStacksBaseSitsInsideTheStack();
|
||||
};
|
||||
|
||||
void CanvasEditContractTests::aNewMaskRevealsTheWholeLayer_data()
|
||||
@@ -173,5 +174,29 @@ void CanvasEditContractTests::aLiveMaskFromFurtherDownShowsAsTheExport()
|
||||
QVERIFY2(scene.gapToExport() <= 1, qPrintable(QString::number(scene.gapToExport())));
|
||||
}
|
||||
|
||||
// The draft follows its active base into the stack's group.
|
||||
void CanvasEditContractTests::aDraftOnAStacksBaseSitsInsideTheStack()
|
||||
{
|
||||
ContractScene scene(60, 40, 60, 40);
|
||||
const QImage white = solid(30, 40, qRgba(255, 255, 255, 255));
|
||||
scene.session.insert(ImportedImage(white, white, QStringLiteral("Base")), QPointF(15, 20));
|
||||
const QUuid base = scene.session.activeLayerID().value();
|
||||
const QImage red = solid(10, 40, qRgba(255, 0, 0, 255));
|
||||
scene.session.insert(ImportedImage(red, red, QStringLiteral("Clipped")), QPointF(5, 20));
|
||||
QVERIFY(scene.session.linkMask(base, scene.session.activeLayerID().value()));
|
||||
scene.session.zoom(1);
|
||||
scene.session.selectLayer(base);
|
||||
scene.session.selectTool(NavigationTool::shape);
|
||||
scene.session.beginShape(QPointF(5, 10));
|
||||
scene.session.dragShape(QPointF(55, 30), false, false);
|
||||
const QImage shown = scene.documentShot();
|
||||
// The draft joins the base, its alpha included, as Swift's.
|
||||
QCOMPARE(shown.pixel(20, 20), qRgb(0, 0, 0));
|
||||
QCOMPARE(shown.pixel(45, 20), qRgb(0, 0, 0));
|
||||
// The clipped layer stays over it.
|
||||
QCOMPARE(shown.pixel(5, 20), qRgb(255, 0, 0));
|
||||
scene.session.cancelShape();
|
||||
}
|
||||
|
||||
QTEST_MAIN(CanvasEditContractTests)
|
||||
#include "CanvasEditContractTests.moc"
|
||||
@@ -3,7 +3,9 @@
|
||||
#include "Rendering/EditorCanvas.h"
|
||||
#include "RenderFixtures.h"
|
||||
#include "EffectsCanvasFixtures.h"
|
||||
#include "SelectionFixtures.h"
|
||||
#include "SessionFixtures.h"
|
||||
#include <QPainterPathStroker>
|
||||
#include <QtTest>
|
||||
|
||||
// Swift's effects on the canvas: previews, the paint's surface, distortions.
|
||||
@@ -61,6 +63,8 @@ private slots:
|
||||
void paintPastTheSurfacesBudgetShowsTheLastEffects();
|
||||
void invalidEffectsShowNothing();
|
||||
void effectsDrawAheadOfAColourEditsPreview();
|
||||
void movingPixelsKeepTheEffects();
|
||||
void aGradientKeepsTheEffects();
|
||||
};
|
||||
|
||||
void EffectsCanvasTests::theCanvasDrawsALayersEffectsOnceTheyLand()
|
||||
@@ -354,5 +358,84 @@ void EffectsCanvasTests::effectsDrawAheadOfAColourEditsPreview()
|
||||
QCOMPARE(scene.at(QPoint(23, 20)), yellow);
|
||||
}
|
||||
|
||||
// A band round a path, where overlays draw.
|
||||
QPainterPath band(const QPainterPath &path, double width)
|
||||
{
|
||||
QPainterPathStroker stroker;
|
||||
stroker.setWidth(width);
|
||||
return stroker.createStroke(path);
|
||||
}
|
||||
|
||||
// The document as shown, pixel by pixel, overlays' bands aside.
|
||||
int gapBetween(Scene &scene, const QImage &one, const QImage &other, const QPainterPath &skip)
|
||||
{
|
||||
int worst = 0;
|
||||
for (int y = 0; y < 40; ++y) {
|
||||
for (int x = 0; x < 60; ++x) {
|
||||
if (skip.contains(QPointF(x + 0.5, y + 0.5)))
|
||||
continue;
|
||||
const QRgb a = one.pixel(scene.shown(QPointF(x + 0.5, y + 0.5))), b = other.pixel(scene.shown(QPointF(x + 0.5, y + 0.5)));
|
||||
worst = std::max({worst, std::abs(qRed(a) - qRed(b)), std::abs(qGreen(a) - qGreen(b)), std::abs(qBlue(a) - qBlue(b))});
|
||||
}
|
||||
}
|
||||
return worst;
|
||||
}
|
||||
|
||||
// Swift's movingWithEffects: the stroke follows the lifted pixels.
|
||||
void EffectsCanvasTests::movingPixelsKeepTheEffects()
|
||||
{
|
||||
Scene scene;
|
||||
EditorSession &session = scene.session;
|
||||
session.setEffects(outline(2));
|
||||
scene.landed();
|
||||
session.applySelection(rectPath(QRectF(25, 15, 10, 10)), SelectionMode::replace, QStringLiteral("Select"));
|
||||
QVERIFY(session.beginPixelMove());
|
||||
// 5.6 rounds to 6: the square moves to 31..41.
|
||||
session.movePixels(QSizeF(5.6, 0));
|
||||
scene.canvas.synchronizeDisplay();
|
||||
QCOMPARE(scene.at(QPoint(42, 20)), yellow);
|
||||
QCOMPARE(scene.at(QPoint(24, 20)), QColor(Qt::white));
|
||||
const QImage moving = scene.shot();
|
||||
bool done = false;
|
||||
session.finishPixelMove([&done] { done = true; });
|
||||
QTRY_VERIFY(done);
|
||||
QCOMPARE(session.selection().value().path.boundingRect(), QRectF(31, 15, 10, 10));
|
||||
scene.canvas.synchronizeDisplay();
|
||||
QCOMPARE(gapBetween(scene, moving, scene.shot(), band(rectPath(QRectF(31, 15, 10, 10)), 4)), 0);
|
||||
session.deselect();
|
||||
QTRY_COMPARE(scene.gapToExport(), 0);
|
||||
}
|
||||
|
||||
// Swift's gradientWithEffects: the pending fill shows its effects.
|
||||
void EffectsCanvasTests::aGradientKeepsTheEffects()
|
||||
{
|
||||
Scene scene;
|
||||
EditorSession &session = scene.session;
|
||||
session.setEffects(outline(2));
|
||||
scene.landed();
|
||||
// Black fading to clear across the square's left half.
|
||||
session.applySelection(rectPath(QRectF(10, 5, 20, 30)), SelectionMode::replace, QStringLiteral("Select"));
|
||||
session.selectTool(NavigationTool::gradient);
|
||||
session.beginGradient(QPointF(15, 20));
|
||||
session.moveGradient(std::nullopt, QPointF(30, 20));
|
||||
session.endGradientDrag();
|
||||
scene.canvas.synchronizeDisplay();
|
||||
// The stroke rings the new paint at once.
|
||||
QVERIFY(scene.at(QPoint(8, 20)).red() > 100 && scene.at(QPoint(8, 20)).blue() < 30);
|
||||
const QImage pending = scene.shot();
|
||||
bool done = false;
|
||||
session.commitGradient([&done] { done = true; });
|
||||
QTRY_VERIFY(done);
|
||||
scene.canvas.synchronizeDisplay();
|
||||
// The line, its ends and the ants aside.
|
||||
QPainterPath line;
|
||||
line.moveTo(15, 20);
|
||||
line.lineTo(30, 20);
|
||||
const QPainterPath overlays = band(rectPath(QRectF(10, 5, 20, 30)), 4).united(band(line, 24));
|
||||
QTRY_VERIFY(gapBetween(scene, pending, scene.shot(), overlays) <= 1);
|
||||
session.deselect();
|
||||
QTRY_COMPARE(scene.gapToExport(), 0);
|
||||
}
|
||||
|
||||
QTEST_MAIN(EffectsCanvasTests)
|
||||
#include "EffectsCanvasTests.moc"
|
||||
Reference in new issue
Block a user