qt 6.5.1 original

This commit is contained in:
kleuter
2023-10-29 23:33:08 +01:00
parent 71d22ab6b0
commit 85d238dfda
21202 changed files with 5499099 additions and 0 deletions

View File

@ -0,0 +1,5 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
add_subdirectory(qgraphicseffect)
add_subdirectory(qpixmapfilter)

View File

@ -0,0 +1,2 @@
[draw]
wayland

View File

@ -0,0 +1,17 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qgraphicseffect Test:
#####################################################################
qt_internal_add_test(tst_qgraphicseffect
SOURCES
tst_qgraphicseffect.cpp
LIBRARIES
Qt::CorePrivate
Qt::Gui
Qt::GuiPrivate
Qt::Widgets
Qt::WidgetsPrivate
)

View File

@ -0,0 +1,719 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <QtTest/QtTestWidgets>
#include <QtWidgets/qgraphicseffect.h>
#include <QtWidgets/qgraphicsview.h>
#include <QtWidgets/qgraphicsscene.h>
#include <QtWidgets/qgraphicsitem.h>
#include <QtWidgets/qgraphicswidget.h>
#include <QtWidgets/qstyleoption.h>
#include <private/qgraphicseffect_p.h>
class tst_QGraphicsEffect : public QObject
{
Q_OBJECT
public slots:
void initTestCase();
private slots:
void setEnabled();
void source();
void boundingRectFor();
void boundingRect();
void boundingRect2();
void draw();
void opacity();
void grayscale();
void colorize();
void drawPixmapItem();
void deviceCoordinateTranslateCaching();
void inheritOpacity();
void dropShadowClipping();
void childrenVisibilityShouldInvalidateCache();
void prepareGeometryChangeInvalidateCache();
void itemHasNoContents();
};
void tst_QGraphicsEffect::initTestCase()
{}
class CustomItem : public QGraphicsRectItem
{
public:
CustomItem(qreal x, qreal y, qreal width, qreal height, QGraphicsItem *parent = nullptr)
: QGraphicsRectItem(x, y, width, height, parent), numRepaints(0),
m_painter(nullptr), m_styleOption(nullptr)
{}
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override
{
m_painter = painter;
m_styleOption = option;
++numRepaints;
QGraphicsRectItem::paint(painter, option, widget);
}
void reset()
{
numRepaints = 0;
m_painter = nullptr;
m_styleOption = nullptr;
}
int numRepaints;
QPainter *m_painter;
const QStyleOption *m_styleOption;
};
class CustomEffect : public QGraphicsEffect
{
public:
CustomEffect()
: QGraphicsEffect(), numRepaints(0), m_margin(10),
doNothingInDraw(false), m_painter(nullptr), m_styleOption(nullptr),
m_source(nullptr), m_opacity(1.0)
{}
QRectF boundingRectFor(const QRectF &rect) const override
{ return rect.adjusted(-m_margin, -m_margin, m_margin, m_margin); }
void reset()
{
numRepaints = 0;
m_sourceChangedFlags = QGraphicsEffect::ChangeFlags();
m_painter = nullptr;
m_styleOption = nullptr;
m_source = nullptr;
m_opacity = 1.0;
}
void setMargin(int margin)
{
m_margin = margin;
updateBoundingRect();
}
int margin() const
{ return m_margin; }
void draw(QPainter *painter) override
{
++numRepaints;
if (doNothingInDraw)
return;
m_source = source();
m_painter = painter;
m_styleOption = source()->styleOption();
m_opacity = painter->opacity();
drawSource(painter);
}
void sourceChanged(QGraphicsEffect::ChangeFlags flags) override
{ m_sourceChangedFlags |= flags; }
int numRepaints;
int m_margin;
QGraphicsEffect::ChangeFlags m_sourceChangedFlags;
bool doNothingInDraw;
QPainter *m_painter;
const QStyleOption *m_styleOption;
QGraphicsEffectSource *m_source;
qreal m_opacity;
};
void tst_QGraphicsEffect::setEnabled()
{
CustomEffect effect;
QVERIFY(effect.isEnabled());
effect.setEnabled(false);
QVERIFY(!effect.isEnabled());
}
void tst_QGraphicsEffect::source()
{
QPointer<CustomEffect> effect = new CustomEffect;
QVERIFY(!effect->source());
QVERIFY(!effect->m_sourceChangedFlags);
// Install effect on QGraphicsItem.
QGraphicsItem *item = new QGraphicsRectItem(0, 0, 10, 10);
item->setGraphicsEffect(effect);
QVERIFY(effect->source());
QCOMPARE(effect->source()->graphicsItem(), (const QGraphicsItem*)item);
QVERIFY(effect->m_sourceChangedFlags & QGraphicsEffect::SourceAttached);
effect->reset();
// Make sure disabling/enabling the effect doesn't change the source.
effect->setEnabled(false);
QVERIFY(effect->source());
QCOMPARE(effect->source()->graphicsItem(), (const QGraphicsItem*)item);
QVERIFY(!effect->m_sourceChangedFlags);
effect->reset();
effect->setEnabled(true);
QVERIFY(effect->source());
QCOMPARE(effect->source()->graphicsItem(), (const QGraphicsItem*)item);
QVERIFY(!effect->m_sourceChangedFlags);
effect->reset();
// Uninstall effect on QGraphicsItem.
effect->reset();
item->setGraphicsEffect(0);
QVERIFY(!effect);
effect = new CustomEffect;
// The item takes ownership and should delete the effect when destroyed.
item->setGraphicsEffect(effect);
QPointer<QGraphicsEffectSource> source = effect->source();
QVERIFY(source);
QCOMPARE(source->graphicsItem(), (const QGraphicsItem*)item);
delete item;
QVERIFY(!effect);
QVERIFY(!source);
}
void tst_QGraphicsEffect::boundingRectFor()
{
CustomEffect effect;
int margin = effect.margin();
const QRectF source(0, 0, 100, 100);
QCOMPARE(effect.boundingRectFor(source), source.adjusted(-margin, -margin, margin, margin));
effect.setMargin(margin = 20);
QCOMPARE(effect.boundingRectFor(source), source.adjusted(-margin, -margin, margin, margin));
}
void tst_QGraphicsEffect::boundingRect()
{
// No source; empty bounding rect.
CustomEffect *effect = new CustomEffect;
QCOMPARE(effect->boundingRect(), QRectF());
// Install effect on QGraphicsItem.
QRectF itemRect(0, 0, 100, 100);
QGraphicsRectItem *item = new QGraphicsRectItem;
item->setPen(QPen(Qt::black, 0));
item->setRect(itemRect);
item->setGraphicsEffect(effect);
int margin = effect->margin();
QCOMPARE(effect->boundingRect(), itemRect.adjusted(-margin, -margin, margin, margin));
QCOMPARE(effect->boundingRect(), effect->boundingRectFor(itemRect));
// Make sure disabling/enabling the effect doesn't change the bounding rect.
effect->setEnabled(false);
QCOMPARE(effect->boundingRect(), itemRect.adjusted(-margin, -margin, margin, margin));
QCOMPARE(effect->boundingRect(), effect->boundingRectFor(itemRect));
effect->setEnabled(true);
QCOMPARE(effect->boundingRect(), itemRect.adjusted(-margin, -margin, margin, margin));
QCOMPARE(effect->boundingRect(), effect->boundingRectFor(itemRect));
// Change effect margins.
effect->setMargin(margin = 20);
QCOMPARE(effect->boundingRect(), itemRect.adjusted(-margin, -margin, margin, margin));
QCOMPARE(effect->boundingRect(), effect->boundingRectFor(itemRect));
// Uninstall effect on QGraphicsItem.
QPointer<CustomEffect> ptr = effect;
item->setGraphicsEffect(0);
QVERIFY(!ptr);
delete item;
}
void tst_QGraphicsEffect::boundingRect2()
{
CustomEffect *effect = new CustomEffect;
QGraphicsRectItem *root = new QGraphicsRectItem;
root->setPen(QPen(Qt::black, 0));
root->setGraphicsEffect(effect);
QGraphicsRectItem *child = new QGraphicsRectItem;
QRectF childRect(0, 0, 100, 100);
child->setPen(QPen(Qt::black, 0));
child->setFlag(QGraphicsItem::ItemClipsChildrenToShape);
child->setRect(childRect);
child->setParentItem(root);
QGraphicsRectItem *grandChild = new QGraphicsRectItem;
QRectF grandChildRect(0, 0, 200, 200);
grandChild->setPen(QPen(Qt::black, 0));
grandChild->setRect(grandChildRect);
grandChild->setParentItem(child);
// Make sure the effect's bounding rect is clipped to the child's bounding rect.
QCOMPARE(effect->boundingRect(), effect->boundingRectFor(childRect));
// Disable ItemClipsChildrenToShape; effect's bounding rect is no longer clipped.
child->setFlag(QGraphicsItem::ItemClipsChildrenToShape, false);
QCOMPARE(effect->boundingRect(), effect->boundingRectFor(childRect | grandChildRect));
// Add root item to a scene, do the same tests as above. Results should be the same.
QGraphicsScene scene;
scene.addItem(root);
child->setFlag(QGraphicsItem::ItemClipsChildrenToShape);
QCOMPARE(effect->boundingRect(), effect->boundingRectFor(childRect));
child->setFlag(QGraphicsItem::ItemClipsChildrenToShape, false);
QCOMPARE(effect->boundingRect(), effect->boundingRectFor(childRect | grandChildRect));
// Now add the scene to a view, results should be the same.
QGraphicsView view(&scene);
child->setFlag(QGraphicsItem::ItemClipsChildrenToShape);
QCOMPARE(effect->boundingRect(), effect->boundingRectFor(childRect));
child->setFlag(QGraphicsItem::ItemClipsChildrenToShape, false);
QCOMPARE(effect->boundingRect(), effect->boundingRectFor(childRect | grandChildRect));
CustomEffect *childEffect = new CustomEffect;
child->setGraphicsEffect(childEffect);
QCOMPARE(effect->boundingRect(), effect->boundingRectFor(childEffect->boundingRectFor(childRect | grandChildRect)));
child->setGraphicsEffect(0);
QCOMPARE(effect->boundingRect(), effect->boundingRectFor(childRect | grandChildRect));
}
void tst_QGraphicsEffect::draw()
{
QGraphicsScene scene;
CustomItem *item = new CustomItem(0, 0, 100, 100);
scene.addItem(item);
QGraphicsView view(&scene);
view.show();
QVERIFY(QTest::qWaitForWindowExposed(&view));
QTRY_VERIFY(item->numRepaints > 0);
QCoreApplication::processEvents(); // Process all queued paint events
item->reset();
// Make sure installing the effect triggers a repaint.
CustomEffect *effect = new CustomEffect;
item->setGraphicsEffect(effect);
QTRY_COMPARE(effect->numRepaints, 1);
QTRY_COMPARE(item->numRepaints, 1);
// Make sure QPainter* and QStyleOptionGraphicsItem* stays persistent
// during QGraphicsEffect::draw/QGraphicsItem::paint.
QVERIFY(effect->m_painter);
QCOMPARE(effect->m_painter, item->m_painter);
QCOMPARE(effect->m_styleOption, item->m_styleOption);
// Make sure QGraphicsEffect::source is persistent.
QCOMPARE(effect->m_source, effect->source());
effect->reset();
item->reset();
// Make sure updating the source triggers a repaint.
item->update();
QTRY_COMPARE(effect->numRepaints, 1);
QTRY_COMPARE(item->numRepaints, 1);
QVERIFY(effect->m_sourceChangedFlags & QGraphicsEffect::SourceInvalidated);
effect->reset();
item->reset();
// Make sure changing the effect's bounding rect triggers a repaint.
effect->setMargin(20);
QTRY_COMPARE(effect->numRepaints, 1);
QTRY_COMPARE(item->numRepaints, 1);
effect->reset();
item->reset();
// Make sure change the item's bounding rect triggers a repaint.
item->setRect(0, 0, 50, 50);
QTRY_COMPARE(effect->numRepaints, 1);
QTRY_COMPARE(item->numRepaints, 1);
QVERIFY(effect->m_sourceChangedFlags & QGraphicsEffect::SourceBoundingRectChanged);
effect->reset();
item->reset();
// Make sure the effect is the one to issue a repaint of the item.
effect->doNothingInDraw = true;
item->update();
QTRY_COMPARE(effect->numRepaints, 1);
QCOMPARE(item->numRepaints, 0);
effect->doNothingInDraw = false;
effect->reset();
item->reset();
// Make sure we update the source when disabling/enabling the effect.
effect->setEnabled(false);
QTRY_COMPARE(item->numRepaints, 1);
QCOMPARE(effect->numRepaints, 0);
effect->reset();
item->reset();
effect->setEnabled(true);
QTRY_COMPARE(effect->numRepaints, 1);
QTRY_COMPARE(item->numRepaints, 1);
effect->reset();
item->reset();
// Effect is already enabled; nothing should happen.
effect->setEnabled(true);
QTest::qWait(50);
QCOMPARE(effect->numRepaints, 0);
QCOMPARE(item->numRepaints, 0);
// Make sure uninstalling an effect triggers a repaint.
QPointer<CustomEffect> ptr = effect;
item->setGraphicsEffect(0);
QVERIFY(!ptr);
QTRY_COMPARE(item->numRepaints, 1);
}
void tst_QGraphicsEffect::opacity()
{
// Make sure the painter's opacity is correct in QGraphicsEffect::draw.
QGraphicsScene scene;
CustomItem *item = new CustomItem(0, 0, 100, 100);
item->setOpacity(0.5);
CustomEffect *effect = new CustomEffect;
item->setGraphicsEffect(effect);
scene.addItem(item);
QGraphicsView view(&scene);
view.show();
QVERIFY(QTest::qWaitForWindowExposed(&view));
QTRY_VERIFY(effect->numRepaints > 0);
QCOMPARE(effect->m_opacity, qreal(0.5));
}
void tst_QGraphicsEffect::grayscale()
{
if (QGuiApplication::primaryScreen()->depth() < 24)
QSKIP("Test only works on 32 bit displays");
QGraphicsScene scene(0, 0, 100, 100);
QGraphicsRectItem *item = scene.addRect(0, 0, 50, 50);
item->setPen(Qt::NoPen);
item->setBrush(QColor(122, 193, 66)); // Qt light green
QGraphicsColorizeEffect *effect = new QGraphicsColorizeEffect;
effect->setColor(Qt::black);
item->setGraphicsEffect(effect);
QPainter painter;
QImage image(100, 100, QImage::Format_ARGB32_Premultiplied);
image.fill(0);
painter.begin(&image);
painter.setRenderHint(QPainter::Antialiasing);
scene.render(&painter);
painter.end();
QCOMPARE(image.pixel(10, 10), qRgb(148, 148, 148));
effect->setStrength(0.5);
image.fill(0);
painter.begin(&image);
painter.setRenderHint(QPainter::Antialiasing);
scene.render(&painter);
painter.end();
QCOMPARE(image.pixel(10, 10), qRgb(135, 171, 107));
effect->setStrength(0.0);
image.fill(0);
painter.begin(&image);
painter.setRenderHint(QPainter::Antialiasing);
scene.render(&painter);
painter.end();
QCOMPARE(image.pixel(10, 10), qRgb(122, 193, 66));
}
void tst_QGraphicsEffect::colorize()
{
if (QGuiApplication::primaryScreen()->depth() < 24)
QSKIP("Test only works on 32 bit displays");
QGraphicsScene scene(0, 0, 100, 100);
QGraphicsRectItem *item = scene.addRect(0, 0, 50, 50);
item->setPen(Qt::NoPen);
item->setBrush(QColor(122, 193, 66)); // Qt light green
QGraphicsColorizeEffect *effect = new QGraphicsColorizeEffect;
effect->setColor(QColor(102, 153, 51)); // Qt dark green
item->setGraphicsEffect(effect);
QPainter painter;
QImage image(100, 100, QImage::Format_ARGB32_Premultiplied);
image.fill(0);
painter.begin(&image);
painter.setRenderHint(QPainter::Antialiasing);
scene.render(&painter);
painter.end();
QCOMPARE(image.pixel(10, 10), qRgb(191, 212, 169));
effect->setStrength(0.5);
image.fill(0);
painter.begin(&image);
painter.setRenderHint(QPainter::Antialiasing);
scene.render(&painter);
painter.end();
QCOMPARE(image.pixel(10, 10), qRgb(156, 203, 117));
effect->setStrength(0.0);
image.fill(0);
painter.begin(&image);
painter.setRenderHint(QPainter::Antialiasing);
scene.render(&painter);
painter.end();
QCOMPARE(image.pixel(10, 10), qRgb(122, 193, 66));
}
class PixmapItemEffect : public QGraphicsEffect
{
public:
PixmapItemEffect(const QPixmap &source)
: QGraphicsEffect()
, pixmap(source)
, repaints(0)
{}
QRectF boundingRectFor(const QRectF &rect) const override
{ return rect; }
void draw(QPainter *painter) override
{
QCOMPARE(sourcePixmap(Qt::LogicalCoordinates).handle(), pixmap.handle());
QVERIFY((painter->worldTransform().type() <= QTransform::TxTranslate) == (sourcePixmap(Qt::DeviceCoordinates).handle() == pixmap.handle()));
++repaints;
}
QPixmap pixmap;
int repaints;
};
void tst_QGraphicsEffect::drawPixmapItem()
{
QImage image(32, 32, QImage::Format_RGB32);
QPainter p(&image);
p.fillRect(0, 0, 32, 16, Qt::blue);
p.fillRect(0, 16, 32, 16, Qt::red);
p.end();
QGraphicsScene scene;
QGraphicsPixmapItem *item = new QGraphicsPixmapItem(QPixmap::fromImage(image));
scene.addItem(item);
PixmapItemEffect *effect = new PixmapItemEffect(item->pixmap());
item->setGraphicsEffect(effect);
QGraphicsView view(&scene);
view.show();
QVERIFY(QTest::qWaitForWindowExposed(&view));
QTRY_VERIFY(effect->repaints >= 1);
item->setTransform(QTransform().rotate(180), true);
QTRY_VERIFY(effect->repaints >= 2);
}
class DeviceEffect : public QGraphicsEffect
{
public:
QRectF boundingRectFor(const QRectF &rect) const override
{ return rect; }
void draw(QPainter *painter) override
{
QPoint offset;
QPixmap pixmap = sourcePixmap(Qt::DeviceCoordinates, &offset, QGraphicsEffect::NoPad);
if (pixmap.isNull())
return;
painter->save();
painter->setWorldTransform(QTransform());
painter->drawPixmap(offset, pixmap);
painter->restore();
}
};
void tst_QGraphicsEffect::deviceCoordinateTranslateCaching()
{
QGraphicsScene scene;
CustomItem *item = new CustomItem(0, 0, 10, 10);
scene.addItem(item);
scene.setSceneRect(0, 0, 50, 0);
item->setGraphicsEffect(new DeviceEffect);
item->setPen(Qt::NoPen);
item->setBrush(Qt::red);
QGraphicsView view(&scene);
view.show();
QVERIFY(QTest::qWaitForWindowExposed(&view));
QTRY_VERIFY(item->numRepaints >= 1);
int numRepaints = item->numRepaints;
item->setTransform(QTransform::fromTranslate(10, 0), true);
QTRY_COMPARE(item->numRepaints, numRepaints);
}
void tst_QGraphicsEffect::inheritOpacity()
{
QGraphicsScene scene;
QGraphicsRectItem *rectItem = new QGraphicsRectItem(0, 0, 10, 10);
CustomItem *item = new CustomItem(0, 0, 10, 10, rectItem);
scene.addItem(rectItem);
item->setGraphicsEffect(new DeviceEffect);
item->setPen(Qt::NoPen);
item->setBrush(Qt::red);
rectItem->setOpacity(0.5);
QGraphicsView view(&scene);
view.show();
QVERIFY(QTest::qWaitForWindowExposed(&view));
QTRY_VERIFY(item->numRepaints >= 1);
int numRepaints = item->numRepaints;
rectItem->setOpacity(1);
// item should have been rerendered due to opacity changing
QTRY_VERIFY(item->numRepaints > numRepaints);
}
void tst_QGraphicsEffect::dropShadowClipping()
{
QImage img(128, 128, QImage::Format_ARGB32_Premultiplied);
img.fill(0xffffffff);
QGraphicsScene scene;
QGraphicsRectItem *item = new QGraphicsRectItem(-5, -500, 10, 1000);
item->setGraphicsEffect(new QGraphicsDropShadowEffect);
item->setPen(Qt::NoPen);
item->setBrush(Qt::red);
scene.addItem(item);
QPainter p(&img);
scene.render(&p, img.rect(), QRect(-64, -64, 128, 128));
p.end();
for (int y = 1; y < img.height(); ++y)
for (int x = 0; x < img.width(); ++x)
QCOMPARE(img.pixel(x, y), img.pixel(x, y-1));
}
class MyGraphicsItem : public QGraphicsWidget
{
public:
MyGraphicsItem(QGraphicsItem *parent = nullptr) :
QGraphicsWidget(parent), nbPaint(0)
{}
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override
{
nbPaint++;
QGraphicsWidget::paint(painter, option, widget);
}
int nbPaint;
};
void tst_QGraphicsEffect::childrenVisibilityShouldInvalidateCache()
{
QGraphicsScene scene;
MyGraphicsItem parent;
parent.resize(200, 200);
QGraphicsWidget child(&parent);
child.resize(200, 200);
child.setVisible(false);
scene.addItem(&parent);
QGraphicsView view(&scene);
view.show();
QVERIFY(QTest::qWaitForWindowExposed(&view));
QTRY_VERIFY(parent.nbPaint >= 1);
//we set an effect on the parent
parent.setGraphicsEffect(new QGraphicsDropShadowEffect(&parent));
//flush the events
QApplication::processEvents();
//new effect applied->repaint
QVERIFY(parent.nbPaint >= 2);
child.setVisible(true);
//flush the events
QApplication::processEvents();
//a new child appears we need to redraw the effect.
QVERIFY(parent.nbPaint >= 3);
}
void tst_QGraphicsEffect::prepareGeometryChangeInvalidateCache()
{
MyGraphicsItem *item = new MyGraphicsItem;
item->resize(200, 200);
QGraphicsScene scene;
scene.addItem(item);
QGraphicsView view(&scene);
view.show();
QVERIFY(QTest::qWaitForWindowExposed(&view));
QTRY_VERIFY(view.windowHandle()->isActive());
QTRY_VERIFY(item->nbPaint >= 1);
item->nbPaint = 0;
item->setGraphicsEffect(new QGraphicsDropShadowEffect);
QTRY_COMPARE(item->nbPaint, 1);
item->nbPaint = 0;
item->resize(300, 300);
QTRY_COMPARE(item->nbPaint, 1);
item->nbPaint = 0;
item->setPos(item->pos() + QPointF(10, 10));
QTest::qWait(50);
QCOMPARE(item->nbPaint, 0);
}
void tst_QGraphicsEffect::itemHasNoContents()
{
QGraphicsRectItem *parent = new QGraphicsRectItem;
parent->setFlag(QGraphicsItem::ItemHasNoContents);
MyGraphicsItem *child = new MyGraphicsItem;
child->setParentItem(parent);
child->resize(200, 200);
QGraphicsScene scene;
scene.addItem(parent);
QGraphicsView view(&scene);
view.show();
QVERIFY(QTest::qWaitForWindowExposed(&view));
QTRY_VERIFY(child->nbPaint >= 1);
CustomEffect *effect = new CustomEffect;
parent->setGraphicsEffect(effect);
QTRY_VERIFY(effect->numRepaints >= 1);
for (int i = 0; i < 3; ++i) {
effect->reset();
effect->update();
QTRY_VERIFY(effect->numRepaints >= 1);
}
}
QTEST_MAIN(tst_QGraphicsEffect)
#include "tst_qgraphicseffect.moc"

View File

@ -0,0 +1,16 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qpixmapfilter Test:
#####################################################################
qt_internal_add_test(tst_qpixmapfilter
SOURCES
tst_qpixmapfilter.cpp
LIBRARIES
Qt::Gui
Qt::GuiPrivate
Qt::Widgets
Qt::WidgetsPrivate
)

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

View File

@ -0,0 +1,390 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <QTest>
#include <qpixmap.h>
#include <private/qpixmapfilter_p.h>
#include <qpainter.h>
class tst_QPixmapFilter : public QObject
{
Q_OBJECT
private slots:
void colorizeSetColor();
void colorizeSetStrength();
void colorizeProcess();
void colorizeDraw();
void colorizeDrawStrength();
void colorizeDrawSubRect();
void colorizeProcessSubRect();
void convolutionBoundingRectFor();
void convolutionDrawSubRect();
void dropShadowBoundingRectFor();
void blurIndexed8();
void testDefaultImplementations();
};
class CustomFilter : public QPixmapFilter
{
public:
enum { Type = QPixmapFilter::UserFilter + 1 };
CustomFilter() : QPixmapFilter((QPixmapFilter::FilterType) Type, 0) { };
void draw(QPainter *p, const QPointF &pt, const QPixmap &src, const QRectF &srcRect = QRectF()) const override
{
p->drawPixmap(QRectF(pt, srcRect.size()), src, srcRect);
}
};
void tst_QPixmapFilter::testDefaultImplementations()
{
CustomFilter filter;
QCOMPARE(filter.type(), (QPixmapFilter::FilterType) CustomFilter::Type);
QCOMPARE(filter.boundingRectFor(QRectF(1, 2, 4, 8)), QRectF(1, 2, 4, 8));
QPixmap src(10, 10);
src.fill(Qt::blue);
QPixmap test(src.size());
QPainter p(&test);
filter.draw(&p, QPointF(0, 0), src, src.rect());
p.end();
QCOMPARE(test.toImage().pixel(0, 0), 0xff0000ff);
}
void tst_QPixmapFilter::colorizeSetColor()
{
QPixmapColorizeFilter filter;
filter.setColor(QColor(50, 100, 200));
QCOMPARE(filter.color(), QColor(50, 100, 200));
}
void tst_QPixmapFilter::colorizeSetStrength()
{
QPixmapColorizeFilter filter;
QCOMPARE(filter.strength(), qreal(1));
filter.setStrength(0.5);
QCOMPARE(filter.strength(), qreal(0.5));
filter.setStrength(0.0);
QCOMPARE(filter.strength(), qreal(0.0));
}
void tst_QPixmapFilter::colorizeProcess()
{
QPixmapColorizeFilter filter;
filter.setColor(QColor(100, 100, 100));
QCOMPARE(filter.boundingRectFor(QRectF(0, 0, 50, 50)), QRectF(0, 0, 50, 50));
QCOMPARE(filter.boundingRectFor(QRectF(30, 20, 10, 40)), QRectF(30, 20, 10, 40));
QCOMPARE(filter.boundingRectFor(QRectF(2.2, 6.3, 11.4, 47.5)), QRectF(2.2, 6.3, 11.4, 47.5));
QPixmap source("noise.png");
QImage result(source.size(), QImage::Format_ARGB32_Premultiplied);
result.fill(0);
QPainter p(&result);
filter.draw(&p, QPointF(0, 0), source);
p.end();
QImage resultImg = result;
for(int y = 0; y < resultImg.height(); y++)
{
for(int x = 0; x < resultImg.width(); x++)
{
QRgb pixel = resultImg.pixel(x,y);
QCOMPARE(qRed(pixel), qGreen(pixel));
QCOMPARE(qGreen(pixel), qBlue(pixel));
}
}
}
void tst_QPixmapFilter::colorizeDraw()
{
QPixmapColorizeFilter filter;
filter.setColor(QColor(100, 100, 100));
QPixmap pixmap("noise.png");
QImage result(pixmap.size(), QImage::Format_ARGB32_Premultiplied);
QPainter painter(&result);
painter.setCompositionMode(QPainter::CompositionMode_Source);
painter.fillRect(result.rect(), QColor(128, 0, 0, 0));
painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
filter.draw(&painter, QPointF(0, 0), pixmap);
painter.end();
QImage resultImg = result;
for(int y = 0; y < resultImg.height(); y++)
{
for(int x = 0; x < resultImg.width(); x++)
{
QRgb pixel = resultImg.pixel(x,y);
QCOMPARE(qRed(pixel), qGreen(pixel));
QCOMPARE(qGreen(pixel), qBlue(pixel));
}
}
}
void tst_QPixmapFilter::colorizeDrawStrength()
{
QPixmapColorizeFilter filter;
filter.setColor(Qt::blue);
filter.setStrength(0.3);
QImage source(256, 128, QImage::Format_ARGB32);
source.fill(qRgb(255, 0, 0));
QPixmap pixmap = QPixmap::fromImage(source);
QImage result(pixmap.size(), QImage::Format_ARGB32_Premultiplied);
QPainter painter(&result);
painter.setCompositionMode(QPainter::CompositionMode_Source);
filter.draw(&painter, QPointF(0, 0), pixmap);
painter.end();
QImage resultImg = result;
for(int y = 0; y < resultImg.height(); y++)
{
for(int x = 0; x < resultImg.width(); x++)
{
QRgb pixel = resultImg.pixel(x,y);
QCOMPARE(qRed(pixel), 206);
QCOMPARE(qGreen(pixel), 26);
QCOMPARE(qBlue(pixel), 75);
}
}
}
void tst_QPixmapFilter::colorizeDrawSubRect()
{
QPixmapColorizeFilter filter;
filter.setColor(QColor(255, 255, 255));
QPixmap pixmap("noise.png");
QImage result(pixmap.size(), QImage::Format_ARGB32_Premultiplied);
QPainter painter(&result);
painter.setCompositionMode(QPainter::CompositionMode_Source);
painter.fillRect(result.rect(), QColor(128, 0, 0, 255));
painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
filter.draw(&painter, QPointF(16, 16), pixmap, QRectF(16, 16, 16, 16));
painter.end();
QImage resultImg = result;
QImage sourceImg = pixmap.toImage();
for(int y = 0; y < resultImg.height(); y++)
{
for(int x = 0; x < resultImg.width(); x++)
{
QRgb pixel = resultImg.pixel(x,y);
if(x>=16 && x<32 && y>=16 && y<32) {
QCOMPARE(qRed(pixel), qGreen(pixel));
QCOMPARE(qGreen(pixel), qBlue(pixel));
} else {
QCOMPARE(qRed(pixel), 128);
QCOMPARE(qGreen(pixel), 0);
QCOMPARE(qBlue(pixel), 0);
QCOMPARE(qAlpha(pixel), 255);
}
}
}
}
void tst_QPixmapFilter::colorizeProcessSubRect()
{
QPixmapColorizeFilter filter;
filter.setColor(QColor(200, 200, 200));
QPixmap source("noise.png");
QImage result(QSize(16, 16), QImage::Format_ARGB32_Premultiplied);
result.fill(0);
QPainter p(&result);
filter.draw(&p, QPointF(0, 0), source, QRectF(16, 16, 16, 16));
p.end();
QImage resultImg = result;
for(int y = 0; y < resultImg.height(); y++)
{
for(int x = 0; x < resultImg.width(); x++)
{
QRgb pixel = resultImg.pixel(x,y);
QCOMPARE(qRed(pixel), qGreen(pixel));
QCOMPARE(qGreen(pixel), qBlue(pixel));
}
}
}
void tst_QPixmapFilter::convolutionBoundingRectFor()
{
QPixmapConvolutionFilter filter;
QCOMPARE(filter.boundingRectFor(QRectF(0, 0, 50, 50)), QRectF(0, 0, 50, 50));
QCOMPARE(filter.boundingRectFor(QRectF(30, 20, 10, 40)), QRectF(30, 20, 10, 40));
QCOMPARE(filter.boundingRectFor(QRectF(2.2, 6.3, 11.4, 47.5)), QRectF(2.2, 6.3, 11.4, 47.5));
qreal kernel[] = {
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0
};
filter.setConvolutionKernel(kernel, 2, 2);
QCOMPARE(filter.boundingRectFor(QRectF(0, 0, 50, 50)), QRectF(-1, -1, 51, 51));
QCOMPARE(filter.boundingRectFor(QRectF(30, 20, 10, 40)), QRectF(29, 19, 11, 41));
QCOMPARE(filter.boundingRectFor(QRectF(2.2, 6.3, 11.4, 47.5)), QRectF(1.2, 5.3, 12.4, 48.5));
filter.setConvolutionKernel(kernel, 3, 3);
QCOMPARE(filter.boundingRectFor(QRectF(0, 0, 50, 50)), QRectF(-1, -1, 52, 52));
QCOMPARE(filter.boundingRectFor(QRectF(30, 20, 10, 40)), QRectF(29, 19, 12, 42));
QCOMPARE(filter.boundingRectFor(QRectF(2.2, 6.3, 11.4, 47.5)), QRectF(1.2, 5.3, 13.4, 49.5));
filter.setConvolutionKernel(kernel, 4, 4);
QCOMPARE(filter.boundingRectFor(QRectF(0, 0, 50, 50)), QRectF(-2, -2, 53, 53));
QCOMPARE(filter.boundingRectFor(QRectF(30, 20, 10, 40)), QRectF(28, 18, 13, 43));
QCOMPARE(filter.boundingRectFor(QRectF(2.2, 6.3, 11.4, 47.5)), QRectF(0.2, 4.3, 14.4, 50.5));
}
void tst_QPixmapFilter::convolutionDrawSubRect()
{
QPixmapConvolutionFilter filter;
qreal kernel[] = {
0, 0, 0,
0, 0, 0,
0, 0, 1
};
filter.setConvolutionKernel(kernel, 3, 3);
QPixmap pixmap("noise.png");
QImage result(pixmap.size(), QImage::Format_ARGB32_Premultiplied);
QPainter painter(&result);
painter.setCompositionMode(QPainter::CompositionMode_Source);
painter.fillRect(result.rect(), QColor(128, 0, 0, 255));
painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
filter.draw(&painter, QPointF(16, 16), pixmap, QRectF(16, 16, 16, 16));
painter.end();
QImage resultImg = result;
QImage sourceImg = pixmap.toImage();
for(int y = 0; y < resultImg.height()-1; y++)
{
for(int x = 0; x < resultImg.width()-1; x++)
{
QRgb pixel = resultImg.pixel(x,y);
QRgb srcPixel = sourceImg.pixel(x+1,y+1);
if(x>=15 && x<33 && y>=15 && y<33) {
QCOMPARE(pixel, srcPixel);
} else {
QCOMPARE(qRed(pixel), 128);
QCOMPARE(qGreen(pixel), 0);
QCOMPARE(qBlue(pixel), 0);
QCOMPARE(qAlpha(pixel), 255);
}
}
}
kernel[2] = 1;
kernel[8] = 0;
filter.setConvolutionKernel(kernel, 3, 3);
QPainter painter2(&result);
painter2.setCompositionMode(QPainter::CompositionMode_Source);
painter2.fillRect(result.rect(), QColor(128, 0, 0, 255));
painter2.setCompositionMode(QPainter::CompositionMode_SourceOver);
filter.draw(&painter2, QPointF(16, 16), pixmap, QRectF(16, 16, 16, 16));
painter2.end();
resultImg = result;
sourceImg = pixmap.toImage();
for(int y = 1; y < resultImg.height(); y++)
{
for(int x = 0; x < resultImg.width()-1; x++)
{
QRgb pixel = resultImg.pixel(x,y);
QRgb srcPixel = sourceImg.pixel(x+1,y-1);
if(x>=15 && x<33 && y>=15 && y<33) {
QCOMPARE(pixel, srcPixel);
} else {
QCOMPARE(qRed(pixel), 128);
QCOMPARE(qGreen(pixel), 0);
QCOMPARE(qBlue(pixel), 0);
QCOMPARE(qAlpha(pixel), 255);
}
}
}
}
void tst_QPixmapFilter::dropShadowBoundingRectFor()
{
QPixmapDropShadowFilter filter;
filter.setBlurRadius(0);
QCOMPARE(filter.blurRadius(), 0.);
const QRectF rect1(0, 0, 50, 50);
const QRectF rect2(30, 20, 10, 40);
const QRectF rect3(2.2, 6.3, 11.4, 47.5);
filter.setOffset(QPointF(0,0));
QCOMPARE(filter.boundingRectFor(rect1), rect1);
QCOMPARE(filter.boundingRectFor(rect2), rect2);
QCOMPARE(filter.boundingRectFor(rect3), rect3);
filter.setOffset(QPointF(1,1));
QCOMPARE(filter.offset(), QPointF(1, 1));
QCOMPARE(filter.boundingRectFor(rect1), rect1.adjusted(0, 0, 1, 1));
QCOMPARE(filter.boundingRectFor(rect2), rect2.adjusted(0, 0, 1, 1));
QCOMPARE(filter.boundingRectFor(rect3), rect3.adjusted(0, 0, 1, 1));
filter.setOffset(QPointF(-1,-1));
QCOMPARE(filter.boundingRectFor(rect1), rect1.adjusted(-1, -1, 0, 0));
QCOMPARE(filter.boundingRectFor(rect2), rect2.adjusted(-1, -1, 0, 0));
QCOMPARE(filter.boundingRectFor(rect3), rect3.adjusted(-1, -1, 0, 0));
filter.setBlurRadius(2);
filter.setOffset(QPointF(0,0));
qreal delta = 2;
QCOMPARE(filter.boundingRectFor(rect1), rect1.adjusted(-delta, -delta, delta, delta));
QCOMPARE(filter.boundingRectFor(rect2), rect2.adjusted(-delta, -delta, delta, delta));
QCOMPARE(filter.boundingRectFor(rect3), rect3.adjusted(-delta, -delta, delta, delta));
filter.setOffset(QPointF(1,1));
QCOMPARE(filter.boundingRectFor(rect1), rect1.adjusted(-delta + 1, -delta + 1, delta + 1, delta + 1));
QCOMPARE(filter.boundingRectFor(rect2), rect2.adjusted(-delta + 1, -delta + 1, delta + 1, delta + 1));
QCOMPARE(filter.boundingRectFor(rect3), rect3.adjusted(-delta + 1, -delta + 1, delta + 1, delta + 1));
filter.setOffset(QPointF(-10,-10));
QCOMPARE(filter.boundingRectFor(rect1), rect1.adjusted(-delta - 10, -delta - 10, 0, 0));
QCOMPARE(filter.boundingRectFor(rect2), rect2.adjusted(-delta - 10, -delta - 10, 0, 0));
QCOMPARE(filter.boundingRectFor(rect3), rect3.adjusted(-delta - 10, -delta - 10, 0, 0));
}
QT_BEGIN_NAMESPACE
void qt_blurImage(QImage &blurImage, qreal radius, bool quality, int transposed);
QT_END_NAMESPACE
void tst_QPixmapFilter::blurIndexed8()
{
QImage img(16, 32, QImage::Format_Indexed8);
img.setDevicePixelRatio(2);
img.setColorCount(256);
for (int i = 0; i < 256; ++i)
img.setColor(i, qRgb(i, i, i));
img.fill(255);
QImage original = img;
qt_blurImage(img, 10, true, false);
QCOMPARE(original.size(), img.size());
QVERIFY2(qFuzzyCompare(img.devicePixelRatio(), qreal(2)),
QByteArray::number(img.devicePixelRatio()).constData());
original = img;
qt_blurImage(img, 10, true, true);
QVERIFY2(qFuzzyCompare(img.devicePixelRatio(), qreal(2)),
QByteArray::number(img.devicePixelRatio()).constData());
QCOMPARE(original.size(), QSize(img.height(), img.width()));
}
QTEST_MAIN(tst_QPixmapFilter)
#include "tst_qpixmapfilter.moc"