From kde-kimageshop Wed Dec 27 09:13:49 2017 From: Dmitry Kazakov Date: Wed, 27 Dec 2017 09:13:49 +0000 To: kde-kimageshop Subject: [krita/kazakov/masking-brush] /: Implement dependent size changes for the Masking Brush Message-Id: X-MARC-Message: https://marc.info/?l=kde-kimageshop&m=151437923024363 Git commit a641fec91cba9f024286088f7c2ae622f94e5516 by Dmitry Kazakov. Committed on 27/12/2017 at 09:10. Pushed by dkazakov into branch 'kazakov/masking-brush'. Implement dependent size changes for the Masking Brush Now the masking brush changes according to these requirements: 1) When the brush size is changed in the brush editor, masking brush size is kept unchanged 2) When the brush size is changed using quick-controls, that is toolbox slider, shift+gesture, HUD display, the masking brush size is changed proportionally. 3) Technically, the masking brush supports disabling this "dependent size" functionality, but I'm not sure if it should be visible in GUI. It is already overcomplicated. Technical changes: 1) Now the brushes are always **copied** when fetched from the brushes registry. That is, if you load the brush using KisBrush::fromXML(), you will always have your own copy of the brush object, not shared with the one in the server. 2) For the efficiency reasons, the brush tip QImage will be lazily shared with the one on the server using the Qt's internal algorithm. If you change the brush tip in you copy of the brush, Qt will deep- copy the corresponding QImage. 3) For the efficiency reasons, brush mipmap pyramid (KisQImagePyramid) is also shared among all the instances of the brush with the same brush tip QImage. Every time one changes the instance of the brush, the pyramid object is detached and reset. This basic lazy copying algorithm is implemented in KisSharedQImagePyramid. CC:kimageshop@kde.org M +1 -0 libs/brush/CMakeLists.txt C +32 -19 libs/brush/KisSharedQImagePyramid.cpp [from: plugins/paintop= s/libpaintop/KisMaskingBrushOption.h - 050% similarity] A +61 -0 libs/brush/KisSharedQImagePyramid.h [License: GPL (v2+)] M +1 -3 libs/brush/kis_auto_brush_factory.cpp M +1 -1 libs/brush/kis_auto_brush_factory.h M +7 -16 libs/brush/kis_brush.cpp M +10 -9 libs/brush/kis_brush.h M +1 -1 libs/brush/kis_brush_factory.h M +2 -2 libs/brush/kis_brush_registry.cpp M +1 -1 libs/brush/kis_brush_registry.h M +0 -1 libs/brush/kis_gbr_brush.cpp M +0 -1 libs/brush/kis_png_brush.cpp M +4 -5 libs/brush/kis_predefined_brush_factory.cpp M +1 -1 libs/brush/kis_predefined_brush_factory.h M +1 -3 libs/brush/kis_text_brush_factory.cpp M +1 -1 libs/brush/kis_text_brush_factory.h M +1 -1 libs/brush/tests/kis_auto_brush_factory_test.cpp M +13 -8 libs/brush/tests/kis_gbr_brush_test.cpp M +2 -0 libs/image/brushengine/KisPaintopSettingsIds.cpp M +2 -0 libs/image/brushengine/KisPaintopSettingsIds.h M +6 -0 libs/image/brushengine/kis_paintop_settings.cpp M +3 -1 plugins/paintops/defaultpaintops/brush/kis_brushop_settings_= widget.cpp M +1 -1 plugins/paintops/hairy/kis_hairy_paintop.cpp M +6 -3 plugins/paintops/libpaintop/KisMaskingBrushOption.cpp M +4 -1 plugins/paintops/libpaintop/KisMaskingBrushOption.h M +16 -4 plugins/paintops/libpaintop/KisMaskingBrushOptionProperties.= cpp M +3 -2 plugins/paintops/libpaintop/KisMaskingBrushOptionProperties.h M +2 -2 plugins/paintops/libpaintop/kis_brush_based_paintop.cpp M +1 -1 plugins/paintops/libpaintop/kis_brush_based_paintop_settings= .cpp M +71 -60 plugins/paintops/libpaintop/kis_brush_chooser.cpp M +2 -5 plugins/paintops/libpaintop/kis_brush_chooser.h M +2 -17 plugins/paintops/libpaintop/kis_brush_option.cpp M +0 -5 plugins/paintops/libpaintop/kis_brush_option.h M +1 -1 plugins/paintops/sketch/kis_sketch_paintop.cpp M +1 -1 plugins/paintops/spray/kis_spray_paintop.cpp https://commits.kde.org/krita/a641fec91cba9f024286088f7c2ae622f94e5516 diff --git a/libs/brush/CMakeLists.txt b/libs/brush/CMakeLists.txt index 88e61fe6074..e2ca732025d 100644 --- a/libs/brush/CMakeLists.txt +++ b/libs/brush/CMakeLists.txt @@ -20,6 +20,7 @@ set(kritalibbrush_LIB_SRCS kis_png_brush.cpp kis_svg_brush.cpp kis_qimage_pyramid.cpp + KisSharedQImagePyramid.cpp kis_text_brush.cpp kis_auto_brush_factory.cpp kis_text_brush_factory.cpp diff --git a/plugins/paintops/libpaintop/KisMaskingBrushOption.h b/libs/bru= sh/KisSharedQImagePyramid.cpp similarity index 50% copy from plugins/paintops/libpaintop/KisMaskingBrushOption.h copy to libs/brush/KisSharedQImagePyramid.cpp index f35dcd57d35..75e86f42087 100644 --- a/plugins/paintops/libpaintop/KisMaskingBrushOption.h +++ b/libs/brush/KisSharedQImagePyramid.cpp @@ -16,34 +16,47 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-13= 01, USA. */ = -#ifndef KISMASKINGBRUSHOPTION_H -#define KISMASKINGBRUSHOPTION_H +#include "KisSharedQImagePyramid.h" = -#include -#include +#include = -#include -#include "kis_paintop_option.h" +#include "kis_qimage_pyramid.h" +#include "kis_brush.h" = = -class PAINTOP_EXPORT KisMaskingBrushOption : public KisPaintOpOption +KisSharedQImagePyramid::KisSharedQImagePyramid() { -public: - KisMaskingBrushOption(); - ~KisMaskingBrushOption() override; +} = - void writeOptionSetting(KisPropertiesConfigurationSP setting) const ov= erride; - void readOptionSetting(const KisPropertiesConfigurationSP setting) ove= rride; +KisSharedQImagePyramid::~KisSharedQImagePyramid() +{ +} + +const KisQImagePyramid *KisSharedQImagePyramid::pyramid(const KisBrush *br= ush) const +{ + const KisQImagePyramid * result =3D 0; = - void setImage(KisImageWSP image) override; + if (m_cachedPyramidPointer) { + result =3D m_cachedPyramidPointer; + } else { + QMutexLocker l(&m_mutex); = - void lodLimitations(KisPaintopLodLimitations *l) const override; + if (!m_pyramid) { + m_pyramid.reset(new KisQImagePyramid(brush->brushTipImage())); + } = -private: - struct Private; - const QScopedPointer m_d; -}; + m_cachedPyramidPointer =3D m_pyramid.data(); + result =3D m_pyramid.data(); + } = + return result; +} = = -#endif // KISMASKINGBRUSHOPTION_H + +bool KisSharedQImagePyramid::isNull() const +{ + QMutexLocker l(&m_mutex); + return bool(m_pyramid); +} + diff --git a/libs/brush/KisSharedQImagePyramid.h b/libs/brush/KisSharedQIma= gePyramid.h new file mode 100644 index 00000000000..bc3d9b5cbe9 --- /dev/null +++ b/libs/brush/KisSharedQImagePyramid.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2017 Dmitry Kazakov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-13= 01, USA. + */ + +#ifndef KISSHAREDQIMAGEPYRAMID_H +#define KISSHAREDQIMAGEPYRAMID_H + +#include "kritabrush_export.h" + +#include +#include +#include + + +class KisQImagePyramid; +class KisBrush; + +/** + * A special class for storing the shared brushes pyramid among different = brushes, + * which can be used by different threads. All the calls to pyramid() are = thread-safe. + * + * Please note, that one cannot alter the pyramid. If the brush alters the= pyramid, + * it should just detach from this object and create a new, unshared one. + */ + +class BRUSH_EXPORT KisSharedQImagePyramid +{ +public: + KisSharedQImagePyramid(); + ~KisSharedQImagePyramid(); + +public: + + // lazy create and return the pyramid + const KisQImagePyramid* pyramid(const KisBrush *brush) const; + + // return true if the pyramid is already prepared + bool isNull() const; + +private: + mutable QMutex m_mutex; + + mutable QSharedPointer m_pyramid; + mutable QAtomicPointer m_cachedPyramidPointer; +}; + +#endif // KISSHAREDQIMAGEPYRAMID_H diff --git a/libs/brush/kis_auto_brush_factory.cpp b/libs/brush/kis_auto_br= ush_factory.cpp index d597c469303..ec0a697a136 100644 --- a/libs/brush/kis_auto_brush_factory.cpp +++ b/libs/brush/kis_auto_brush_factory.cpp @@ -26,10 +26,8 @@ #include "kis_mask_generator.h" #include = -KisBrushSP KisAutoBrushFactory::getOrCreateBrush(const QDomElement& brushD= efinition, bool forceCopy) +KisBrushSP KisAutoBrushFactory::createBrush(const QDomElement &brushDefini= tion) { - Q_UNUSED(forceCopy); - KisMaskGenerator* mask =3D KisMaskGenerator::fromXML(brushDefinition.f= irstChildElement("MaskGenerator")); double angle =3D KisDomUtils::toDouble(brushDefinition.attribute("angl= e", "0.0")); double randomness =3D KisDomUtils::toDouble(brushDefinition.attribute(= "randomness", "0.0")); diff --git a/libs/brush/kis_auto_brush_factory.h b/libs/brush/kis_auto_brus= h_factory.h index 719bd29b2af..e52385b4ca1 100644 --- a/libs/brush/kis_auto_brush_factory.h +++ b/libs/brush/kis_auto_brush_factory.h @@ -50,7 +50,7 @@ public: * object. If this call leads to the creation of a resource, it should= be * added to the resource provider, too. */ - KisBrushSP getOrCreateBrush(const QDomElement& brushDefinition, bool f= orceCopy) override; + KisBrushSP createBrush(const QDomElement& brushDefinition) override; = }; = diff --git a/libs/brush/kis_brush.cpp b/libs/brush/kis_brush.cpp index 5fc231b1453..0a8c45ff1b3 100644 --- a/libs/brush/kis_brush.cpp +++ b/libs/brush/kis_brush.cpp @@ -46,6 +46,7 @@ #include #include #include +#include #include = = @@ -126,7 +127,7 @@ struct KisBrush::Private { double spacing; QPointF hotSpot; = - mutable QSharedPointer brushPyramid; + mutable QSharedPointer brushPyramid; = QImage brushTipImage; = @@ -179,7 +180,6 @@ KisBrush::KisBrush(const KisBrush& rhs) = KisBrush::~KisBrush() { - clearBrushPyramid(); delete d; } = @@ -348,9 +348,9 @@ void KisBrush::toXML(QDomDocument& /*document*/ , QDomE= lement& element) const element.setAttribute("BrushVersion", "2"); } = -KisBrushSP KisBrush::fromXML(const QDomElement& element, bool forceCopy) +KisBrushSP KisBrush::fromXML(const QDomElement& element) { - KisBrushSP brush =3D KisBrushRegistry::instance()->getOrCreateBrush(el= ement, forceCopy); + KisBrushSP brush =3D KisBrushRegistry::instance()->createBrush(element= ); if (brush && element.attribute("BrushVersion", "1") =3D=3D "1") { brush->setScale(brush->scale() * 2.0); } @@ -454,16 +454,9 @@ bool KisBrush::threadingAllowed() const return d->threadingAllowed; } = -void KisBrush::prepareBrushPyramid() const -{ - if (!d->brushPyramid) { - d->brushPyramid =3D toQShared(new KisQImagePyramid(brushTipImage()= )); - } -} - void KisBrush::clearBrushPyramid() { - d->brushPyramid.clear(); + d->brushPyramid.reset(new KisSharedQImagePyramid()); } = void KisBrush::mask(KisFixedPaintDeviceSP dst, const KoColor& color, KisDa= bShape const& shape, const KisPaintInformation& info, double subPixelX, dou= ble subPixelY, qreal softnessFactor) const @@ -489,8 +482,7 @@ void KisBrush::generateMaskAndApplyMaskOrCreateDab(KisF= ixedPaintDeviceSP dst, Q_UNUSED(info_); Q_UNUSED(softnessFactor); = - prepareBrushPyramid(); - QImage outputImage =3D d->brushPyramid->createImage(KisDabShape( + QImage outputImage =3D d->brushPyramid->pyramid(this)->createImage(Kis= DabShape( shape.scale() * d->scale, shape.ratio(), -normalizeAngle(shape.rotation() + d->angle)), subPixelX, subPixelY); @@ -576,8 +568,7 @@ KisFixedPaintDeviceSP KisBrush::paintDevice(const KoCol= orSpace * colorSpace, double angle =3D normalizeAngle(shape.rotation() + d->angle); double scale =3D shape.scale() * d->scale; = - prepareBrushPyramid(); - QImage outputImage =3D d->brushPyramid->createImage( + QImage outputImage =3D d->brushPyramid->pyramid(this)->createImage( KisDabShape(scale, shape.ratio(), -angle), subPixelX, subPixelY); = KisFixedPaintDeviceSP dab =3D new KisFixedPaintDevice(colorSpace); diff --git a/libs/brush/kis_brush.h b/libs/brush/kis_brush.h index c336216c592..42935fe01b0 100644 --- a/libs/brush/kis_brush.h +++ b/libs/brush/kis_brush.h @@ -325,7 +325,7 @@ public: */ virtual void toXML(QDomDocument& , QDomElement&) const; = - static KisBrushSP fromXML(const QDomElement& element, bool forceCopy = =3D false); + static KisBrushSP fromXML(const QDomElement& element); = virtual const KisBoundary* boundary() const; virtual QPainterPath outline() const; @@ -335,14 +335,13 @@ public: virtual void setAngle(qreal _angle); qreal angle() const; = - void prepareBrushPyramid() const; void clearBrushPyramid(); = virtual void lodLimitations(KisPaintopLodLimitations *l) const; = virtual KisBrush* clone() const =3D 0; = -//protected: +protected: = KisBrush(const KisBrush& rhs); = @@ -352,12 +351,6 @@ public: = void setHotSpot(QPointF); = - /** - * The image is used to represent the brush in the gui, and may also, = depending on the brush type - * be used to define the actual brush instance. - */ - virtual void setBrushTipImage(const QImage& image); - /** * XXX */ @@ -365,6 +358,14 @@ public: = virtual void setHasColor(bool hasColor); = +public: + + /** + * The image is used to represent the brush in the gui, and may also, = depending on the brush type + * be used to define the actual brush instance. + */ + virtual void setBrushTipImage(const QImage& image); + /** * Returns true if the brush has a bunch of pixels almost * fully transparent in the very center. If the brush is pierced, diff --git a/libs/brush/kis_brush_factory.h b/libs/brush/kis_brush_factory.h index f6d694159ac..ca1b3299594 100644 --- a/libs/brush/kis_brush_factory.h +++ b/libs/brush/kis_brush_factory.h @@ -47,7 +47,7 @@ public: * object. If this call leads to the creation of a resource, it should= be * added to the resource provider, too. */ - virtual KisBrushSP getOrCreateBrush(const QDomElement& element, bool f= orceCopy) =3D 0; + virtual KisBrushSP createBrush(const QDomElement& element) =3D 0; = }; = diff --git a/libs/brush/kis_brush_registry.cpp b/libs/brush/kis_brush_regis= try.cpp index f64cb5d1d99..e832974f35b 100644 --- a/libs/brush/kis_brush_registry.cpp +++ b/libs/brush/kis_brush_registry.cpp @@ -62,7 +62,7 @@ KisBrushRegistry* KisBrushRegistry::instance() } = = -KisBrushSP KisBrushRegistry::getOrCreateBrush(const QDomElement& element, = bool forceCopy) +KisBrushSP KisBrushRegistry::createBrush(const QDomElement& element) { QString brushType =3D element.attribute("type"); = @@ -71,6 +71,6 @@ KisBrushSP KisBrushRegistry::getOrCreateBrush(const QDomE= lement& element, bool f KisBrushFactory* factory =3D get(brushType); if (!factory) return 0; = - return factory->getOrCreateBrush(element, forceCopy); + return factory->createBrush(element); } = diff --git a/libs/brush/kis_brush_registry.h b/libs/brush/kis_brush_registr= y.h index 82066fcb8ca..1713cc067ba 100644 --- a/libs/brush/kis_brush_registry.h +++ b/libs/brush/kis_brush_registry.h @@ -42,7 +42,7 @@ public: = static KisBrushRegistry* instance(); = - KisBrushSP getOrCreateBrush(const QDomElement& element, bool forceCopy= =3D false); + KisBrushSP createBrush(const QDomElement& element); = private: KisBrushRegistry(const KisBrushRegistry&); diff --git a/libs/brush/kis_gbr_brush.cpp b/libs/brush/kis_gbr_brush.cpp index 77a9beedddd..d25aa1d341a 100644 --- a/libs/brush/kis_gbr_brush.cpp +++ b/libs/brush/kis_gbr_brush.cpp @@ -139,7 +139,6 @@ KisGbrBrush::KisGbrBrush(const KisGbrBrush& rhs) , d(new Private(*rhs.d)) { setName(rhs.name()); - setBrushTipImage(rhs.brushTipImage()); d->data =3D QByteArray(); setValid(rhs.valid()); } diff --git a/libs/brush/kis_png_brush.cpp b/libs/brush/kis_png_brush.cpp index 879b28fa570..4c1b95cb3b8 100644 --- a/libs/brush/kis_png_brush.cpp +++ b/libs/brush/kis_png_brush.cpp @@ -38,7 +38,6 @@ KisPngBrush::KisPngBrush(const KisPngBrush &rhs) : KisScalingSizeBrush(rhs) { setSpacing(rhs.spacing()); - setBrushTipImage(rhs.brushTipImage()); if (brushTipImage().isGrayscale()) { setBrushType(MASK); setHasColor(false); diff --git a/libs/brush/kis_predefined_brush_factory.cpp b/libs/brush/kis_p= redefined_brush_factory.cpp index 4a2d32aa0ad..e232c3e595f 100644 --- a/libs/brush/kis_predefined_brush_factory.cpp +++ b/libs/brush/kis_predefined_brush_factory.cpp @@ -33,7 +33,7 @@ QString KisPredefinedBrushFactory::id() const return m_id; } = -KisBrushSP KisPredefinedBrushFactory::getOrCreateBrush(const QDomElement& = brushDefinition, bool forceCopy) +KisBrushSP KisPredefinedBrushFactory::createBrush(const QDomElement& brush= Definition) { KisBrushResourceServer *rServer =3D KisBrushServer::instance()->brushS= erver(); QString brushFileName =3D brushDefinition.attribute("filename", ""); @@ -49,11 +49,10 @@ KisBrushSP KisPredefinedBrushFactory::getOrCreateBrush(= const QDomElement& brushD brush =3D rServer->resources().first(); } = - Q_ASSERT(brush); + KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(brush, 0); = - if (forceCopy) { - brush =3D brush->clone(); - } + // we always return a copy of the brush! + brush =3D brush->clone(); = double spacing =3D KisDomUtils::toDouble(brushDefinition.attribute("sp= acing", "0.25")); brush->setSpacing(spacing); diff --git a/libs/brush/kis_predefined_brush_factory.h b/libs/brush/kis_pre= defined_brush_factory.h index af5fc50d6d9..5c3cc188995 100644 --- a/libs/brush/kis_predefined_brush_factory.h +++ b/libs/brush/kis_predefined_brush_factory.h @@ -32,7 +32,7 @@ public: KisPredefinedBrushFactory(const QString &brushType); = QString id() const override; - KisBrushSP getOrCreateBrush(const QDomElement& brushDefinition, bool f= orceCopy) override; + KisBrushSP createBrush(const QDomElement& brushDefinition) override; = private: const QString m_id; diff --git a/libs/brush/kis_text_brush_factory.cpp b/libs/brush/kis_text_br= ush_factory.cpp index 6ae80550710..1d7fad257f7 100644 --- a/libs/brush/kis_text_brush_factory.cpp +++ b/libs/brush/kis_text_brush_factory.cpp @@ -22,10 +22,8 @@ #include #include "kis_text_brush.h" = -KisBrushSP KisTextBrushFactory::getOrCreateBrush(const QDomElement& brushD= efinition, bool forceCopy) +KisBrushSP KisTextBrushFactory::createBrush(const QDomElement& brushDefini= tion) { - Q_UNUSED(forceCopy); - QString text =3D brushDefinition.attribute("text", "The quick brown fo= x ate your text"); QFont font; font.fromString(brushDefinition.attribute("font")); diff --git a/libs/brush/kis_text_brush_factory.h b/libs/brush/kis_text_brus= h_factory.h index e854bcc053b..0ee25012533 100644 --- a/libs/brush/kis_text_brush_factory.h +++ b/libs/brush/kis_text_brush_factory.h @@ -46,7 +46,7 @@ public: * object. If this call leads to the creation of a resource, it should= be * added to the resource provider, too. */ - KisBrushSP getOrCreateBrush(const QDomElement& brushDefinition, bool f= orceCopy) override; + KisBrushSP createBrush(const QDomElement& brushDefinition) override; = = }; diff --git a/libs/brush/tests/kis_auto_brush_factory_test.cpp b/libs/brush/= tests/kis_auto_brush_factory_test.cpp index 0b9930b46b4..724d027f3fb 100644 --- a/libs/brush/tests/kis_auto_brush_factory_test.cpp +++ b/libs/brush/tests/kis_auto_brush_factory_test.cpp @@ -20,7 +20,7 @@ void KisAutoBrushFactoryTest::testXMLClone() QDomDocument d; QDomElement e =3D d.createElement("Brush"); brush->toXML(d, e); - KisBrushSP clone =3D KisAutoBrushFactory().getOrCreateBrush(e, false); + KisBrushSP clone =3D KisAutoBrushFactory().createBrush(e); = // Test that the clone has the same settings as the original brush. QCOMPARE(brush->width(), clone->width()); diff --git a/libs/brush/tests/kis_gbr_brush_test.cpp b/libs/brush/tests/kis= _gbr_brush_test.cpp index e5994faef51..75c31904a67 100644 --- a/libs/brush/tests/kis_gbr_brush_test.cpp +++ b/libs/brush/tests/kis_gbr_brush_test.cpp @@ -101,7 +101,6 @@ void KisGbrBrushTest::testImageGeneration() Q_UNUSED(res); Q_ASSERT(res); QVERIFY(!brush->brushTipImage().isNull()); - brush->prepareBrushPyramid(); qsrand(1); = const KoColorSpace* cs =3D KoColorSpaceRegistry::instance()->rgb8(); @@ -128,30 +127,38 @@ void KisGbrBrushTest::testImageGeneration() } } = +#include "KisSharedQImagePyramid.h" + void KisGbrBrushTest::benchmarkPyramidCreation() { - KisGbrBrush* brush =3D new KisGbrBrush(QString(FILES_DATA_DIR) + QDir:= :separator() + "testing_brush_512_bars.gbr"); + QScopedPointer brush(new KisGbrBrush(QString(FILES_DATA_D= IR) + QDir::separator() + "testing_brush_512_bars.gbr")); brush->load(); QVERIFY(!brush->brushTipImage().isNull()); = QBENCHMARK { - brush->prepareBrushPyramid(); - brush->clearBrushPyramid(); + KisSharedQImagePyramid sharedPyramid; + QVERIFY(sharedPyramid.pyramid(brush.data())); // avoid compiler el= imination of unused code! } } = void KisGbrBrushTest::benchmarkScaling() { - KisGbrBrush* brush =3D new KisGbrBrush(QString(FILES_DATA_DIR) + QDir:= :separator() + "testing_brush_512_bars.gbr"); + QScopedPointer brush(new KisGbrBrush(QString(FILES_DATA_D= IR) + QDir::separator() + "testing_brush_512_bars.gbr")); brush->load(); QVERIFY(!brush->brushTipImage().isNull()); - brush->prepareBrushPyramid(); qsrand(1); = const KoColorSpace* cs =3D KoColorSpaceRegistry::instance()->rgb8(); KisPaintInformation info(QPointF(100.0, 100.0), 0.5); KisFixedPaintDeviceSP dab; = + { + // warm up the pyramid! + dab =3D brush->paintDevice(cs, KisDabShape(qreal(qrand()) / RAND_M= AX * 2.0, 1.0, 0.0), info); + QVERIFY(dab); // avoid compiler elimination of unused code! + dab.clear(); + } + QBENCHMARK { dab =3D brush->paintDevice(cs, KisDabShape(qreal(qrand()) / RAND_M= AX * 2.0, 1.0, 0.0), info); //dab->convertToQImage(0).save(QString("dab_%1_new_smooth.png").ar= g(i++)); @@ -163,7 +170,6 @@ void KisGbrBrushTest::benchmarkRotation() KisGbrBrush* brush =3D new KisGbrBrush(QString(FILES_DATA_DIR) + QDir:= :separator() + "testing_brush_512_bars.gbr"); brush->load(); QVERIFY(!brush->brushTipImage().isNull()); - brush->prepareBrushPyramid(); qsrand(1); = const KoColorSpace* cs =3D KoColorSpaceRegistry::instance()->rgb8(); @@ -180,7 +186,6 @@ void KisGbrBrushTest::benchmarkMaskScaling() KisGbrBrush* brush =3D new KisGbrBrush(QString(FILES_DATA_DIR) + QDir:= :separator() + "testing_brush_512_bars.gbr"); brush->load(); QVERIFY(!brush->brushTipImage().isNull()); - brush->prepareBrushPyramid(); qsrand(1); = const KoColorSpace* cs =3D KoColorSpaceRegistry::instance()->rgb8(); diff --git a/libs/image/brushengine/KisPaintopSettingsIds.cpp b/libs/image/= brushengine/KisPaintopSettingsIds.cpp index d078d63a9c8..1edb0cb3303 100644 --- a/libs/image/brushengine/KisPaintopSettingsIds.cpp +++ b/libs/image/brushengine/KisPaintopSettingsIds.cpp @@ -23,6 +23,8 @@ namespace KisPaintOpUtils { const char MaskingBrushPaintOpId[] =3D "paintbrush"; const char MaskingBrushEnabledTag[] =3D "MaskingBrush/Enabled"; const char MaskingBrushCompositeOpTag[] =3D "MaskingBrush/MaskingComposite= Op"; +const char MaskingBrushUseMasterSizeTag[] =3D "MaskingBrush/UseMasterSize"; +const char MaskingBrushMasterSizeCoeffTag[] =3D "MaskingBrush/MasterSizeCo= eff"; const char MaskingBrushPresetPrefix[] =3D "MaskingBrush/Preset/"; = } diff --git a/libs/image/brushengine/KisPaintopSettingsIds.h b/libs/image/br= ushengine/KisPaintopSettingsIds.h index bc50c8f4a05..2b8014edf54 100644 --- a/libs/image/brushengine/KisPaintopSettingsIds.h +++ b/libs/image/brushengine/KisPaintopSettingsIds.h @@ -26,6 +26,8 @@ namespace KisPaintOpUtils { KRITAIMAGE_EXPORT extern const char MaskingBrushPaintOpId[]; KRITAIMAGE_EXPORT extern const char MaskingBrushEnabledTag[]; KRITAIMAGE_EXPORT extern const char MaskingBrushCompositeOpTag[]; +KRITAIMAGE_EXPORT extern const char MaskingBrushUseMasterSizeTag[]; +KRITAIMAGE_EXPORT extern const char MaskingBrushMasterSizeCoeffTag[]; KRITAIMAGE_EXPORT extern const char MaskingBrushPresetPrefix[]; = } diff --git a/libs/image/brushengine/kis_paintop_settings.cpp b/libs/image/b= rushengine/kis_paintop_settings.cpp index 8b80a4965c7..1ed78ea6e62 100644 --- a/libs/image/brushengine/kis_paintop_settings.cpp +++ b/libs/image/brushengine/kis_paintop_settings.cpp @@ -161,6 +161,12 @@ KisPaintOpSettingsSP KisPaintOpSettings::createMasking= Settings() const KisPaintOpSettingsSP maskingSettings =3D KisPaintOpRegistry::instance(= )->settings(pixelBrushId); this->getPrefixedProperties(KisPaintOpUtils::MaskingBrushPresetPrefix,= maskingSettings); = + const bool useMasterSize =3D this->getBool(KisPaintOpUtils::MaskingBru= shUseMasterSizeTag, true); + if (useMasterSize) { + const qreal masterSizeCoeff =3D getDouble(KisPaintOpUtils::Masking= BrushMasterSizeCoeffTag, 1.0); + maskingSettings->setPaintOpSize(masterSizeCoeff * paintOpSize()); + } + return maskingSettings; } = diff --git a/plugins/paintops/defaultpaintops/brush/kis_brushop_settings_wi= dget.cpp b/plugins/paintops/defaultpaintops/brush/kis_brushop_settings_widg= et.cpp index 9b687fced21..41c69534c02 100644 --- a/plugins/paintops/defaultpaintops/brush/kis_brushop_settings_widget.cpp +++ b/plugins/paintops/defaultpaintops/brush/kis_brushop_settings_widget.cpp @@ -85,8 +85,10 @@ KisBrushOpSettingsWidget::KisBrushOpSettingsWidget(QWidg= et* parent) addPaintOpOption(new KisTextureOption(), i18n("Pattern")); addPaintOpOption(new KisCurveOptionWidget(new KisPressureTextureStreng= thOption(), i18n("Weak"), i18n("Strong")), i18n("Strength")); = + KisMaskingBrushOption::MasterBrushSizeAdapter sizeAdapter =3D + [this] () { return this->brush()->userEffectiveSize(); }; = - addPaintOpOption(new KisMaskingBrushOption(), i18n("Brush Tip")); + addPaintOpOption(new KisMaskingBrushOption(sizeAdapter), i18n("Brush T= ip")); = = { diff --git a/plugins/paintops/hairy/kis_hairy_paintop.cpp b/plugins/paintop= s/hairy/kis_hairy_paintop.cpp index ad592f3a244..6811707089d 100644 --- a/plugins/paintops/hairy/kis_hairy_paintop.cpp +++ b/plugins/paintops/hairy/kis_hairy_paintop.cpp @@ -49,7 +49,7 @@ KisHairyPaintOp::KisHairyPaintOp(const KisPaintOpSettings= SP settings, KisPainter m_dev =3D node ? node->paintDevice() : 0; = KisBrushOption brushOption; - brushOption.readOptionSettingForceCopy(settings); + brushOption.readOptionSetting(settings); KisBrushSP brush =3D brushOption.brush(); KisFixedPaintDeviceSP dab =3D cachedDab(painter->device()->composition= SourceColorSpace()); if (brush->brushType() =3D=3D IMAGE || brush->brushType() =3D=3D PIPE_= IMAGE) { diff --git a/plugins/paintops/libpaintop/KisMaskingBrushOption.cpp b/plugin= s/paintops/libpaintop/KisMaskingBrushOption.cpp index df703fdb022..8cd1121a2f2 100644 --- a/plugins/paintops/libpaintop/KisMaskingBrushOption.cpp +++ b/plugins/paintops/libpaintop/KisMaskingBrushOption.cpp @@ -65,12 +65,15 @@ struct KisMaskingBrushOption::Private QScopedPointer ui; KisPredefinedBrushChooser *brushChooser =3D 0; QComboBox *compositeSelector =3D 0; + MasterBrushSizeAdapter masterBrushSizeAdapter; }; = -KisMaskingBrushOption::KisMaskingBrushOption() +KisMaskingBrushOption::KisMaskingBrushOption(MasterBrushSizeAdapter master= BrushSizeAdapter) : KisPaintOpOption(KisPaintOpOption::MASKING_BRUSH, false), m_d(new Private()) { + m_d->masterBrushSizeAdapter =3D masterBrushSizeAdapter; + setObjectName("KisMaskingBrushOption"); setConfigurationPage(m_d->ui.data()); = @@ -91,13 +94,13 @@ void KisMaskingBrushOption::writeOptionSetting(KisPrope= rtiesConfigurationSP sett props.brush =3D m_d->brushChooser->brush(); props.compositeOpId =3D m_d->compositeSelector->currentData().toString= (); = - props.write(setting.data()); + props.write(setting.data(), m_d->masterBrushSizeAdapter()); } = void KisMaskingBrushOption::readOptionSetting(const KisPropertiesConfigura= tionSP setting) { KisMaskingBrushOptionProperties props; - props.read(setting.data()); + props.read(setting.data(), m_d->masterBrushSizeAdapter()); = setChecked(props.isEnabled); = diff --git a/plugins/paintops/libpaintop/KisMaskingBrushOption.h b/plugins/= paintops/libpaintop/KisMaskingBrushOption.h index f35dcd57d35..a583b09768e 100644 --- a/plugins/paintops/libpaintop/KisMaskingBrushOption.h +++ b/plugins/paintops/libpaintop/KisMaskingBrushOption.h @@ -29,7 +29,10 @@ class PAINTOP_EXPORT KisMaskingBrushOption : public KisPaintOpOption { public: - KisMaskingBrushOption(); + typedef std::function MasterBrushSizeAdapter; + +public: + KisMaskingBrushOption(MasterBrushSizeAdapter masterBrushSizeAdapter); ~KisMaskingBrushOption() override; = void writeOptionSetting(KisPropertiesConfigurationSP setting) const ov= erride; diff --git a/plugins/paintops/libpaintop/KisMaskingBrushOptionProperties.cp= p b/plugins/paintops/libpaintop/KisMaskingBrushOptionProperties.cpp index ec395c59897..bf45b61b6af 100644 --- a/plugins/paintops/libpaintop/KisMaskingBrushOptionProperties.cpp +++ b/plugins/paintops/libpaintop/KisMaskingBrushOptionProperties.cpp @@ -25,15 +25,21 @@ = = KisMaskingBrushOptionProperties::KisMaskingBrushOptionProperties() - : isEnabled(false), - compositeOpId(COMPOSITE_MULT) + : compositeOpId(COMPOSITE_MULT) + { } = -void KisMaskingBrushOptionProperties::write(KisPropertiesConfiguration *se= tting) const +void KisMaskingBrushOptionProperties::write(KisPropertiesConfiguration *se= tting, qreal masterBrushSize) const { setting->setProperty(KisPaintOpUtils::MaskingBrushEnabledTag, isEnable= d); setting->setProperty(KisPaintOpUtils::MaskingBrushCompositeOpTag, comp= ositeOpId); + setting->setProperty(KisPaintOpUtils::MaskingBrushUseMasterSizeTag, us= eMasterSize); + + const qreal masterSizeCoeff =3D + brush && masterBrushSize > 0 ? brush->userEffectiveSize() / master= BrushSize : 1.0; + + setting->setProperty(KisPaintOpUtils::MaskingBrushMasterSizeCoeffTag, = masterSizeCoeff); = // TODO: skip saving in some cases? // if (!isEnabled) return; @@ -60,10 +66,11 @@ void KisMaskingBrushOptionProperties::write(KisProperti= esConfiguration *setting) } } = -void KisMaskingBrushOptionProperties::read(const KisPropertiesConfiguratio= n *setting) +void KisMaskingBrushOptionProperties::read(const KisPropertiesConfiguratio= n *setting, qreal masterBrushSize) { isEnabled =3D setting->getBool(KisPaintOpUtils::MaskingBrushEnabledTag= ); compositeOpId =3D setting->getString(KisPaintOpUtils::MaskingBrushComp= ositeOpTag, COMPOSITE_MULT); + useMasterSize =3D setting->getBool(KisPaintOpUtils::MaskingBrushUseMas= terSizeTag, true); = KisPropertiesConfigurationSP embeddedConfig =3D new KisPropertiesConfi= guration(); setting->getPrefixedProperties(KisPaintOpUtils::MaskingBrushPresetPref= ix, embeddedConfig); @@ -72,4 +79,9 @@ void KisMaskingBrushOptionProperties::read(const KisPrope= rtiesConfiguration *set option.readOptionSetting(embeddedConfig); = brush =3D option.brush(); + + if (brush && useMasterSize) { + const qreal masterSizeCoeff =3D setting->getDouble(KisPaintOpUtils= ::MaskingBrushMasterSizeCoeffTag, 1.0); + brush->setUserEffectiveSize(masterSizeCoeff * masterBrushSize); + } } diff --git a/plugins/paintops/libpaintop/KisMaskingBrushOptionProperties.h = b/plugins/paintops/libpaintop/KisMaskingBrushOptionProperties.h index 5fae6690917..8ad9ff1a1a3 100644 --- a/plugins/paintops/libpaintop/KisMaskingBrushOptionProperties.h +++ b/plugins/paintops/libpaintop/KisMaskingBrushOptionProperties.h @@ -33,9 +33,10 @@ struct PAINTOP_EXPORT KisMaskingBrushOptionProperties bool isEnabled =3D false; KisBrushSP brush; QString compositeOpId; + bool useMasterSize =3D true; = - void write(KisPropertiesConfiguration *setting) const; - void read(const KisPropertiesConfiguration *setting); + void write(KisPropertiesConfiguration *setting, qreal masterBrushSize)= const; + void read(const KisPropertiesConfiguration *setting, qreal masterBrush= Size); }; = #endif // KISMASKINGBRUSHOPTIONPROPERTIES_H diff --git a/plugins/paintops/libpaintop/kis_brush_based_paintop.cpp b/plug= ins/paintops/libpaintop/kis_brush_based_paintop.cpp index a119ae5348f..f81d876b72c 100644 --- a/plugins/paintops/libpaintop/kis_brush_based_paintop.cpp +++ b/plugins/paintops/libpaintop/kis_brush_based_paintop.cpp @@ -45,7 +45,7 @@ void TextBrushInitializationWorkaround::preinitialize(Kis= PropertiesConfiguration { if (KisBrushOption::isTextBrush(settings.data())) { KisBrushOption brushOption; - brushOption.readOptionSettingForceCopy(settings); + brushOption.readOptionSetting(settings); m_brush =3D brushOption.brush(); m_settings =3D settings; } @@ -90,7 +90,7 @@ KisBrushBasedPaintOp::KisBrushBasedPaintOp(const KisPrope= rtiesConfigurationSP se = if (!m_brush) { KisBrushOption brushOption; - brushOption.readOptionSettingForceCopy(settings); + brushOption.readOptionSetting(settings); m_brush =3D brushOption.brush(); } = diff --git a/plugins/paintops/libpaintop/kis_brush_based_paintop_settings.c= pp b/plugins/paintops/libpaintop/kis_brush_based_paintop_settings.cpp index 97b9a7dddac..51ff8abbb57 100644 --- a/plugins/paintops/libpaintop/kis_brush_based_paintop_settings.cpp +++ b/plugins/paintops/libpaintop/kis_brush_based_paintop_settings.cpp @@ -81,7 +81,7 @@ KisPaintOpSettingsSP KisBrushBasedPaintOpSettings::clone(= ) const { KisPaintOpSettingsSP _settings =3D KisOutlineGenerationPolicy::clone(); KisBrushBasedPaintOpSettingsSP settings =3D dynamic_cast(_settings.data()); - settings->m_savedBrush =3D this->brush(); + settings->m_savedBrush =3D 0; return settings; } = diff --git a/plugins/paintops/libpaintop/kis_brush_chooser.cpp b/plugins/pa= intops/libpaintop/kis_brush_chooser.cpp index 8db32f1d86f..3607f976dae 100644 --- a/plugins/paintops/libpaintop/kis_brush_chooser.cpp +++ b/plugins/paintops/libpaintop/kis_brush_chooser.cpp @@ -40,7 +40,6 @@ #include = #include -#include "kis_brush_registry.h" #include "kis_brush_server.h" #include "widgets/kis_slider_spin_box.h" #include "widgets/kis_multipliers_double_slider_spinbox.h" @@ -133,8 +132,8 @@ KisPredefinedBrushChooser::KisPredefinedBrushChooser(QW= idget *parent, const char KisBrushResourceServer* rServer =3D KisBrushServer::instance()->brushS= erver(); QSharedPointer adapter(new KisBrushReso= urceServerAdapter(rServer)); = - m_itemChooser =3D new KoResourceItemChooser(adapter, this); + m_itemChooser->setObjectName("brush_selector"); = m_itemChooser->showTaggingBar(true); m_itemChooser->setColumnCount(10); @@ -184,21 +183,52 @@ KisPredefinedBrushChooser::~KisPredefinedBrushChooser= () { } = -void KisPredefinedBrushChooser::setBrush(KisBrushSP _brush) +void KisPredefinedBrushChooser::setBrush(KisBrushSP brush) { - m_itemChooser->setCurrentResource(_brush.data()); - update(_brush.data()); + /** + * Warning: since the brushes are always cloned after loading from XML= or + * fetching from the server, we cannot just ask for that brush explici= tly. + * Instead, we should search for the brush with the same filename and/= or name + * and load it. Please take it into account that after selecting the b= rush + * explicitly in the chooser, m_itemChooser->currentResource() might be + * **not** the same as the value in m_brush. + * + * Ideally, if the resource is not found on the server, we should add = it, but + * it might lead to a set of weird consequences. So for now we just + * select nothing. + */ + + KisBrushResourceServer* server =3D KisBrushServer::instance()->brushSe= rver(); + KoResource *resource =3D server->resourceByFilename(brush->shortFilena= me()).data(); + + if (!resource) { + resource =3D server->resourceByName(brush->name()).data(); + } + + if (!resource) { + resource =3D brush.data(); + } + + m_itemChooser->setCurrentResource(resource); + update(brush.data()); } = void KisPredefinedBrushChooser::slotResetBrush() { + /** + * The slot also resets the brush on the server + * + * TODO: technically, after we refactored all the brushes to be forked, + * we can just re-update the brush from the server without reloa= ding. + * But it needs testing. + */ + KisBrush *brush =3D dynamic_cast(m_itemChooser->currentRes= ource()); if (brush) { brush->load(); brush->setScale(1.0); brush->setAngle(0.0); = - slotActivatedBrush(brush); update(brush); emit sigBrushChanged(); } @@ -206,35 +236,33 @@ void KisPredefinedBrushChooser::slotResetBrush() = void KisPredefinedBrushChooser::slotSetItemSize(qreal sizeValue) { - KisBrush *brush =3D dynamic_cast(m_itemChooser->currentRes= ource()); + KIS_SAFE_ASSERT_RECOVER_RETURN(m_brush); = - if (brush) { - int brushWidth =3D brush->width(); + if (m_brush) { + int brushWidth =3D m_brush->width(); = - brush->setScale(sizeValue / qreal(brushWidth)); - slotActivatedBrush(brush); + m_brush->setScale(sizeValue / qreal(brushWidth)); emit sigBrushChanged(); } } = void KisPredefinedBrushChooser::slotSetItemRotation(qreal rotationValue) { - KisBrush *brush =3D dynamic_cast(m_itemChooser->currentRes= ource()); - if (brush) { - brush->setAngle(rotationValue / 180.0 * M_PI); - slotActivatedBrush(brush); + KIS_SAFE_ASSERT_RECOVER_RETURN(m_brush); = + if (m_brush) { + m_brush->setAngle(rotationValue / 180.0 * M_PI); emit sigBrushChanged(); } } = void KisPredefinedBrushChooser::slotSpacingChanged() { - KisBrush *brush =3D dynamic_cast(m_itemChooser->currentRes= ource()); - if (brush) { - brush->setSpacing(brushSpacingSelectionWidget->spacing()); - brush->setAutoSpacing(brushSpacingSelectionWidget->autoSpacingActi= ve(), brushSpacingSelectionWidget->autoSpacingCoeff()); - slotActivatedBrush(brush); + KIS_SAFE_ASSERT_RECOVER_RETURN(m_brush); + + if (m_brush) { + m_brush->setSpacing(brushSpacingSelectionWidget->spacing()); + m_brush->setAutoSpacing(brushSpacingSelectionWidget->autoSpacingAc= tive(), brushSpacingSelectionWidget->autoSpacingCoeff()); = emit sigBrushChanged(); } @@ -242,11 +270,11 @@ void KisPredefinedBrushChooser::slotSpacingChanged() = void KisPredefinedBrushChooser::slotSetItemUseColorAsMask(bool useColorAsM= ask) { - KisGbrBrush *brush =3D dynamic_cast(m_itemChooser->curr= entResource()); + KIS_SAFE_ASSERT_RECOVER_RETURN(m_brush); + + KisGbrBrush *brush =3D dynamic_cast(m_brush.data()); if (brush) { brush->setUseColorAsMask(useColorAsMask); - slotActivatedBrush(brush); - emit sigBrushChanged(); } } @@ -284,72 +312,55 @@ void KisPredefinedBrushChooser::slotOpenClipboardBrus= h() = void KisPredefinedBrushChooser::update(KoResource * resource) { - KisBrush* brush =3D dynamic_cast(resource); - - if (brush) { - + { + KisBrush* brush =3D dynamic_cast(resource); + m_brush =3D brush ? brush->clone() : 0; + } = - brushTipNameLabel->setText(i18n(brush->name().toUtf8().data())); + if (m_brush) { + brushTipNameLabel->setText(i18n(m_brush->name().toUtf8().data())); = QString brushTypeString =3D ""; = - if (brush->brushType() =3D=3D INVALID) { + if (m_brush->brushType() =3D=3D INVALID) { brushTypeString =3D i18n("Invalid"); - } else if (brush->brushType() =3D=3D MASK) { + } else if (m_brush->brushType() =3D=3D MASK) { brushTypeString =3D i18n("Mask"); - } else if (brush->brushType() =3D=3D IMAGE) { + } else if (m_brush->brushType() =3D=3D IMAGE) { brushTypeString =3D i18n("GBR"); - } else if (brush->brushType() =3D=3D PIPE_MASK ) { + } else if (m_brush->brushType() =3D=3D PIPE_MASK ) { brushTypeString =3D i18n("Animated Mask"); - } else if (brush->brushType() =3D=3D PIPE_IMAGE ) { + } else if (m_brush->brushType() =3D=3D PIPE_IMAGE ) { brushTypeString =3D i18n("Animated Image"); } = = QString brushDetailsText =3D QString("%1 (%2 x %3)") .arg(brushTypeString) - .arg(brush->width()) - .arg(brush->height()); + .arg(m_brush->width()) + .arg(m_brush->height()); = brushDetailsLabel->setText(brushDetailsText); = = - brushSpacingSelectionWidget->setSpacing(brush->autoSpacingActive(), - brush->autoSpacingActive() ? - brush->autoSpacingCoeff() : brush->spacing= ()); + brushSpacingSelectionWidget->setSpacing(m_brush->autoSpacingActive= (), + m_brush->autoSpacingActive() ? + m_brush->autoSpacingCoeff() : m_brush->spa= cing()); = - brushRotationSpinBox->setValue(brush->angle() * 180 / M_PI); - brushSizeSpinBox->setValue(brush->width() * brush->scale()); + brushRotationSpinBox->setValue(m_brush->angle() * 180 / M_PI); + brushSizeSpinBox->setValue(m_brush->width() * m_brush->scale()); = // useColorAsMask support is only in gimp brush so far - KisGbrBrush *gimpBrush =3D dynamic_cast(resource); + KisGbrBrush *gimpBrush =3D dynamic_cast(m_brush.data= ()); if (gimpBrush) { useColorAsMaskCheckbox->setChecked(gimpBrush->useColorAsMask()= ); } - useColorAsMaskCheckbox->setEnabled(brush->hasColor() && gimpBrush); + useColorAsMaskCheckbox->setEnabled(m_brush->hasColor() && gimpBrus= h); = - slotActivatedBrush(brush); emit sigBrushChanged(); } } = -void KisPredefinedBrushChooser::slotActivatedBrush(KoResource * resource) -{ - KisBrush* brush =3D dynamic_cast(resource); - - if (m_brush !=3D brush) { - if (m_brush) { - m_brush->clearBrushPyramid(); - } - - m_brush =3D brush; - - if (m_brush) { - m_brush->prepareBrushPyramid(); - } - } -} - void KisPredefinedBrushChooser::slotNewPredefinedBrush(KoResource *resourc= e) { m_itemChooser->setCurrentResource(resource); diff --git a/plugins/paintops/libpaintop/kis_brush_chooser.h b/plugins/pain= tops/libpaintop/kis_brush_chooser.h index f87a311e14a..644481695f3 100644 --- a/plugins/paintops/libpaintop/kis_brush_chooser.h +++ b/plugins/paintops/libpaintop/kis_brush_chooser.h @@ -38,6 +38,7 @@ class KisClipboardBrushWidget; class KoResourceItemChooser; class KoResource; = + class PAINTOP_EXPORT KisPredefinedBrushChooser : public QWidget, Ui::WdgPr= edefinedBrushChooser { = @@ -51,7 +52,7 @@ public: return m_brush; }; = - void setBrush(KisBrushSP _brush); + void setBrush(KisBrushSP brush); void setBrushSize(qreal xPixels, qreal yPixels); void setImage(KisImageWSP image); = @@ -62,7 +63,6 @@ private Q_SLOTS: void slotSetItemRotation(qreal); void slotSpacingChanged(); void slotSetItemUseColorAsMask(bool); - void slotActivatedBrush(KoResource *); void slotOpenStampBrush(); void slotOpenClipboardBrush(); void slotImportNewBrushResource(); @@ -70,8 +70,6 @@ private Q_SLOTS: void slotNewPredefinedBrush(KoResource *); void update(KoResource *); = - - Q_SIGNALS: = void sigBrushChanged(); @@ -82,7 +80,6 @@ private: KisImageWSP m_image; KisCustomBrushWidget* m_stampBrushWidget; KisClipboardBrushWidget* m_clipboardBrushWidget; - }; = #endif // KIS_PREDEFINED_BRUSH_CHOOSER_H_ diff --git a/plugins/paintops/libpaintop/kis_brush_option.cpp b/plugins/pai= ntops/libpaintop/kis_brush_option.cpp index 2d800f823ee..e0432072d69 100644 --- a/plugins/paintops/libpaintop/kis_brush_option.cpp +++ b/plugins/paintops/libpaintop/kis_brush_option.cpp @@ -56,30 +56,15 @@ QDomElement getBrushXMLElement(const KisPropertiesConfi= guration *setting) return element; } = -void KisBrushOption::readOptionSettingInternal(const KisPropertiesConfigur= ation *setting, bool forceCopy) +void KisBrushOption::readOptionSettingImpl(const KisPropertiesConfiguratio= n *setting) { QDomElement element =3D getBrushXMLElement(setting); = if (!element.isNull()) { - m_brush =3D KisBrush::fromXML(element, forceCopy); + m_brush =3D KisBrush::fromXML(element); } } = -void KisBrushOption::readOptionSettingForceCopy(KisPropertiesConfiguration= SP setting) -{ - readOptionSettingInternal(setting.data(), true); -} - -void KisBrushOption::readOptionSettingForceCopy(const KisPropertiesConfigu= ration *setting) -{ - readOptionSettingInternal(setting, true); -} - -void KisBrushOption::readOptionSettingImpl(const KisPropertiesConfiguratio= n *setting) -{ - readOptionSettingInternal(setting, false); -} - #ifdef HAVE_THREADED_TEXT_RENDERING_WORKAROUND = #include "kis_text_brush_factory.h" diff --git a/plugins/paintops/libpaintop/kis_brush_option.h b/plugins/paint= ops/libpaintop/kis_brush_option.h index b36b58ab782..26df674e765 100644 --- a/plugins/paintops/libpaintop/kis_brush_option.h +++ b/plugins/paintops/libpaintop/kis_brush_option.h @@ -35,8 +35,6 @@ public: = void writeOptionSettingImpl(KisPropertiesConfiguration *setting) const= override; void readOptionSettingImpl(const KisPropertiesConfiguration *setting) = override; - void readOptionSettingForceCopy(KisPropertiesConfigurationSP setting); - void readOptionSettingForceCopy(const KisPropertiesConfiguration *sett= ing); = KisBrushSP brush() const; void setBrush(KisBrushSP brush); @@ -45,9 +43,6 @@ public: static bool isTextBrush(const KisPropertiesConfiguration *setting); #endif /* HAVE_THREADED_TEXT_RENDERING_WORKAROUND */ = -private: - void readOptionSettingInternal(const KisPropertiesConfiguration *setti= ng, bool forceCopy); - private: KisBrushSP m_brush; }; diff --git a/plugins/paintops/sketch/kis_sketch_paintop.cpp b/plugins/paint= ops/sketch/kis_sketch_paintop.cpp index 26461d555bf..46be473fe34 100644 --- a/plugins/paintops/sketch/kis_sketch_paintop.cpp +++ b/plugins/paintops/sketch/kis_sketch_paintop.cpp @@ -75,7 +75,7 @@ KisSketchPaintOp::KisSketchPaintOp(const KisPaintOpSettin= gsSP settings, KisPaint m_rotationOption.readOptionSetting(settings); m_rateOption.readOptionSetting(settings); m_sketchProperties.readOptionSetting(settings); - m_brushOption.readOptionSettingForceCopy(settings); + m_brushOption.readOptionSetting(settings); m_densityOption.readOptionSetting(settings); m_lineWidthOption.readOptionSetting(settings); m_offsetScaleOption.readOptionSetting(settings); diff --git a/plugins/paintops/spray/kis_spray_paintop.cpp b/plugins/paintop= s/spray/kis_spray_paintop.cpp index 6e3d353610f..ff833550075 100644 --- a/plugins/paintops/spray/kis_spray_paintop.cpp +++ b/plugins/paintops/spray/kis_spray_paintop.cpp @@ -62,7 +62,7 @@ KisSprayPaintOp::KisSprayPaintOp(const KisPaintOpSettings= SP settings, KisPainter m_sizeOption.resetAllSensors(); m_rateOption.resetAllSensors(); = - m_brushOption.readOptionSettingForceCopy(settings); + m_brushOption.readOptionSetting(settings); = m_colorProperties.fillProperties(settings); m_properties.readOptionSetting(settings);