diff --git a/libs/image/filter/kis_filter.cc b/libs/image/filter/kis_filter.cc index 8dd5bec546..266001ddd9 100644 --- a/libs/image/filter/kis_filter.cc +++ b/libs/image/filter/kis_filter.cc @@ -1,133 +1,144 @@ /* * Copyright (c) 2004,2006-2007 Cyrille Berger * * 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-1301, USA. */ #include "filter/kis_filter.h" #include #include #include "kis_bookmarked_configuration_manager.h" #include "filter/kis_filter_configuration.h" #include "kis_processing_information.h" #include "kis_transaction.h" #include "kis_paint_device.h" #include "kis_selection.h" #include "kis_types.h" #include #include KisFilter::KisFilter(const KoID& _id, const KoID & category, const QString & entry) : KisBaseProcessor(_id, category, entry), m_supportsLevelOfDetail(false) { init(id() + "_filter_bookmarks"); } KisFilter::~KisFilter() { } void KisFilter::process(KisPaintDeviceSP device, const QRect& applyRect, const KisFilterConfigurationSP config, KoUpdater* progressUpdater) const { process(device, device, KisSelectionSP(), applyRect, config, progressUpdater); } void KisFilter::process(const KisPaintDeviceSP src, KisPaintDeviceSP dst, KisSelectionSP selection, const QRect& applyRect, const KisFilterConfigurationSP config, KoUpdater* progressUpdater ) const { if (applyRect.isEmpty()) return; QRect needRect = neededRect(applyRect, config, src->defaultBounds()->currentLevelOfDetail()); KisPaintDeviceSP temporary; KisTransaction *transaction = 0; bool weirdDstColorSpace = dst->colorSpace() != dst->compositionSourceColorSpace() && *dst->colorSpace() != *dst->compositionSourceColorSpace(); if(src == dst && !selection && !weirdDstColorSpace) { temporary = src; } else { temporary = dst->createCompositionSourceDevice(src, needRect); transaction = new KisTransaction(temporary); } try { QScopedPointer fakeUpdater; if (!progressUpdater) { // TODO: remove dependency on KoUpdater, depend on KoProgressProxy, // it is more lightweight fakeUpdater.reset(new KoDummyUpdater()); progressUpdater = fakeUpdater.data(); } processImpl(temporary, applyRect, config, progressUpdater); } catch (const std::bad_alloc&) { warnKrita << "Filter" << name() << "failed to allocate enough memory to run."; } if(transaction) { delete transaction; KisPainter::copyAreaOptimized(applyRect.topLeft(), temporary, dst, applyRect, selection); } } QRect KisFilter::neededRect(const QRect & rect, const KisFilterConfigurationSP c, int lod) const { Q_UNUSED(c); Q_UNUSED(lod); return rect; } QRect KisFilter::changedRect(const QRect & rect, const KisFilterConfigurationSP c, int lod) const { Q_UNUSED(c); Q_UNUSED(lod); return rect; } bool KisFilter::supportsLevelOfDetail(const KisFilterConfigurationSP config, int lod) const { Q_UNUSED(config); Q_UNUSED(lod); return m_supportsLevelOfDetail; } void KisFilter::setSupportsLevelOfDetail(bool value) { m_supportsLevelOfDetail = value; } bool KisFilter::needsTransparentPixels(const KisFilterConfigurationSP config, const KoColorSpace *cs) const { Q_UNUSED(config); Q_UNUSED(cs); return false; } + +bool KisFilter::configurationAllowedForMask(KisFilterConfigurationSP config) const +{ + Q_UNUSED(config); + return supportsAdjustmentLayers(); +} + +void KisFilter::fixLoadedFilterConfigurationForMasks(KisFilterConfigurationSP config) const +{ + Q_UNUSED(config); +} diff --git a/libs/image/filter/kis_filter.h b/libs/image/filter/kis_filter.h index 3e8ed01dd6..ba738825c7 100644 --- a/libs/image/filter/kis_filter.h +++ b/libs/image/filter/kis_filter.h @@ -1,126 +1,129 @@ /* * Copyright (c) 2004,2006-2007 Cyrille Berger * * 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-1301, USA. */ #ifndef _KIS_FILTER_H_ #define _KIS_FILTER_H_ #include #include #include #include "KoID.h" #include "KoColorSpace.h" #include "kis_types.h" #include "kis_base_processor.h" #include "kritaimage_export.h" /** * Basic interface of a Krita filter. */ class KRITAIMAGE_EXPORT KisFilter : public KisBaseProcessor { public: /** * Construct a Krita filter */ KisFilter(const KoID& id, const KoID & category, const QString & entry); ~KisFilter() override; /** * Override this function with the implementation of your filter. * * This is a low level function that expects all the conditions * for the @param device be met. Use usual process() methods * instead. * * @param device the paint device to filter * @param applyRect the rectangle where the filter is applied * @param config the parameters of the filter * @param progressUpdater to pass on the progress the filter is making */ virtual void processImpl(KisPaintDeviceSP device, const QRect& applyRect, const KisFilterConfigurationSP config, KoUpdater* progressUpdater = 0 ) const = 0; /** * Filter \p src device and write the result into \p dst device. * If \p dst is an alpha color space device, it will get special * treatment. * * @param src the source paint device * @param dst the destination paint device * @param selection the selection * @param applyRect the rectangle where the filter is applied * @param config the parameters of the filter * @param progressUpdater to pass on the progress the filter is making */ void process(const KisPaintDeviceSP src, KisPaintDeviceSP dst, KisSelectionSP selection, const QRect& applyRect, const KisFilterConfigurationSP config, KoUpdater* progressUpdater = 0 ) const; /** * A convenience method for a two-device process() function */ void process(KisPaintDeviceSP device, const QRect& applyRect, const KisFilterConfigurationSP config, KoUpdater* progressUpdater = 0 ) const; /** * Some filters need pixels outside the current processing rect to compute the new * value (for instance, convolution filters) */ virtual QRect neededRect(const QRect & rect, const KisFilterConfigurationSP config, int lod) const; /** * Similar to @ref neededRect : some filters will alter a lot of pixels that are * near to each other at the same time. So when you changed a single rectangle * in a device, the actual rectangle that will feel the influence of this change * might be bigger. Use this function to determine that rect. */ virtual QRect changedRect(const QRect & rect, const KisFilterConfigurationSP config, int lod) const; /** * Returns true if the filter is capable of handling LoD scaled planes * when generating preview. */ virtual bool supportsLevelOfDetail(const KisFilterConfigurationSP config, int lod) const; virtual bool needsTransparentPixels(const KisFilterConfigurationSP config, const KoColorSpace *cs) const; + virtual bool configurationAllowedForMask(KisFilterConfigurationSP config) const; + virtual void fixLoadedFilterConfigurationForMasks(KisFilterConfigurationSP config) const; + protected: QString configEntryGroup() const; void setSupportsLevelOfDetail(bool value); private: bool m_supportsLevelOfDetail; }; #endif diff --git a/libs/image/kis_base_processor.cpp b/libs/image/kis_base_processor.cpp index 8390b707f2..af11c9b738 100644 --- a/libs/image/kis_base_processor.cpp +++ b/libs/image/kis_base_processor.cpp @@ -1,191 +1,191 @@ /* * Copyright (c) 2004,2006-2007 Cyrille Berger * * 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-1301, USA. */ #include "kis_base_processor.h" #include #include "kis_bookmarked_configuration_manager.h" #include "filter/kis_filter_configuration.h" #include "kis_paint_device.h" #include "kis_selection.h" class KisBaseProcessorConfigurationFactory : public KisSerializableConfigurationFactory { public: KisBaseProcessorConfigurationFactory(KisBaseProcessor* _generator) : m_generator(_generator) {} ~KisBaseProcessorConfigurationFactory() override {} KisSerializableConfigurationSP createDefault() override { return m_generator->factoryConfiguration(); } KisSerializableConfigurationSP create(const QDomElement& e) override { KisSerializableConfigurationSP config = m_generator->factoryConfiguration(); config->fromXML(e); return config; } private: KisBaseProcessor* m_generator; }; struct Q_DECL_HIDDEN KisBaseProcessor::Private { Private() : bookmarkManager(0) , supportsPainting(false) , supportsAdjustmentLayers(true) , supportsThreading(true) , showConfigurationWidget(true) , colorSpaceIndependence(FULLY_INDEPENDENT) { } KisBookmarkedConfigurationManager* bookmarkManager; KoID id; KoID category; // The category in the filter menu this filter fits QString entry; // the i18n'ed accelerated menu text QKeySequence shortcut; bool supportsPainting; bool supportsAdjustmentLayers; bool supportsThreading; bool showConfigurationWidget; ColorSpaceIndependence colorSpaceIndependence; }; KisBaseProcessor::KisBaseProcessor(const KoID& id, const KoID & category, const QString & entry) : d(new Private) { d->id = id; d->category = category; d->entry = entry; } void KisBaseProcessor::init(const QString& configEntryGroup) { d->bookmarkManager = new KisBookmarkedConfigurationManager(configEntryGroup, new KisBaseProcessorConfigurationFactory(this)); } KisBaseProcessor::~KisBaseProcessor() { delete d->bookmarkManager; delete d; } KisFilterConfigurationSP KisBaseProcessor::factoryConfiguration() const { return new KisFilterConfiguration(id(), 0); } KisFilterConfigurationSP KisBaseProcessor::defaultConfiguration() const { return factoryConfiguration(); } -KisConfigWidget * KisBaseProcessor::createConfigurationWidget(QWidget *, const KisPaintDeviceSP) const +KisConfigWidget * KisBaseProcessor::createConfigurationWidget(QWidget *, const KisPaintDeviceSP, bool) const { return 0; } KisBookmarkedConfigurationManager* KisBaseProcessor::bookmarkManager() { return d->bookmarkManager; } const KisBookmarkedConfigurationManager* KisBaseProcessor::bookmarkManager() const { return d->bookmarkManager; } QString KisBaseProcessor::id() const { return d->id.id(); } QString KisBaseProcessor::name() const { return d->id.name(); } KoID KisBaseProcessor::menuCategory() const { return d->category; } QString KisBaseProcessor::menuEntry() const { return d->entry; } QKeySequence KisBaseProcessor::shortcut() const { return d->shortcut; } void KisBaseProcessor::setShortcut(const QKeySequence & shortcut) { d->shortcut = shortcut; } bool KisBaseProcessor::supportsPainting() const { return d->supportsPainting; } bool KisBaseProcessor::supportsAdjustmentLayers() const { return d->supportsAdjustmentLayers; } bool KisBaseProcessor::supportsThreading() const { return d->supportsThreading; } ColorSpaceIndependence KisBaseProcessor::colorSpaceIndependence() const { return d->colorSpaceIndependence; } void KisBaseProcessor::setSupportsPainting(bool v) { d->supportsPainting = v; } void KisBaseProcessor::setSupportsAdjustmentLayers(bool v) { d->supportsAdjustmentLayers = v; } void KisBaseProcessor::setSupportsThreading(bool v) { d->supportsThreading = v; } void KisBaseProcessor::setColorSpaceIndependence(ColorSpaceIndependence v) { d->colorSpaceIndependence = v; } bool KisBaseProcessor::showConfigurationWidget() { return d->showConfigurationWidget; } void KisBaseProcessor::setShowConfigurationWidget(bool v) { d->showConfigurationWidget = v; } diff --git a/libs/image/kis_base_processor.h b/libs/image/kis_base_processor.h index ebd614fbdb..d391cd0c98 100644 --- a/libs/image/kis_base_processor.h +++ b/libs/image/kis_base_processor.h @@ -1,167 +1,169 @@ /* * Copyright (c) 2008 Boudewijn Rempt * * 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-1301, USA. */ #ifndef _KIS_BASE_PROCESSOR_H_ #define _KIS_BASE_PROCESSOR_H_ #include #include #include #include #include "KoID.h" #include "KoColorSpace.h" #include "kis_types.h" #include "kis_shared.h" #include "kis_image.h" #include "kritaimage_export.h" class QWidget; class KisBookmarkedConfigurationManager; class KisFilterConfiguration; class KisConfigWidget; /** * Base class for classes that process areas of pixels. * Processors can either read in pixels and write out pixels * or just write out pixels, using a certain set of configuration * pixels. * * in-out processing is typically filtering: @see KisFilter. * out-only processing is typically generating: @see KisGenerator. * * Information about the area that needs to be processed is contained * @see KisProcessingInformation and @see KisConstProcessingInformation. */ class KRITAIMAGE_EXPORT KisBaseProcessor : public KisShared { friend class KisBaseProcessorConfigurationFactory; public: KisBaseProcessor(const KoID& id, const KoID & category, const QString & entry); virtual ~KisBaseProcessor(); /** * Return the configuration set as the default by the user or the default * configuration from the filter writer as returned by factoryConfiguration. * * This configuration is used by default for the configuration widget and * given to the process function if there is no configuration widget. * * @return the default configuration of this widget */ KisFilterConfigurationSP defaultConfiguration() const; /** * @return the bookmark manager for this processor */ KisBookmarkedConfigurationManager* bookmarkManager(); /** * @return the bookmark manager for this processor */ const KisBookmarkedConfigurationManager* bookmarkManager() const; /// @return Unique identification for this processor QString id() const; /// @return User-visible identification for this processor QString name() const; /// @return the submenu in the filters menu does processor want to go? KoID menuCategory() const; /// @return the i18n'ed string this filter wants to show itself in the menu QString menuEntry() const; /** * Return the default keyboard shortcut for activation of this filter * * @return the shortcut */ QKeySequence shortcut() const; /** * Create the configuration widget for this processor. * * @param parent the Qt owner widget of this widget * @param dev the paintdevice this filter will act on + * @param useForMasks shown if the filer is going to be used in a mask. Some filters + * may provide limited options when applied as a mask (e.g. Gaussian Blur) */ - virtual KisConfigWidget * createConfigurationWidget(QWidget * parent, const KisPaintDeviceSP dev) const; + virtual KisConfigWidget * createConfigurationWidget(QWidget * parent, const KisPaintDeviceSP dev, bool useForMasks) const; // "Support" functions public: /** * If true, this filter can be used in painting tools as a paint operation */ bool supportsPainting() const; /// This filter can be used in adjustment layers bool supportsAdjustmentLayers() const; /** * This filter supports cutting up the work area and filtering * each chunk in a separate thread. Filters that need access to the * whole area for correct computations should return false. */ bool supportsThreading() const; /// If true, the filter wants to show a configuration widget bool showConfigurationWidget(); /** * Determine the colorspace independence of this filter. * @see ColorSpaceIndependence * * @return the degree of independence */ ColorSpaceIndependence colorSpaceIndependence() const; /// @return the default configuration as defined by whoever wrote the plugin virtual KisFilterConfigurationSP factoryConfiguration() const; protected: void setSupportsPainting(bool v); void setSupportsAdjustmentLayers(bool v); void setSupportsThreading(bool v); void setColorSpaceIndependence(ColorSpaceIndependence v); void setShowConfigurationWidget(bool v); /** * Set the default shortcut for activation of this filter. */ void setShortcut(const QKeySequence & shortcut); protected: void init(const QString& configEntryGroup); private: struct Private; Private* const d; }; #endif diff --git a/libs/image/kis_node_filter_interface.cpp b/libs/image/kis_node_filter_interface.cpp index 7f385c5cba..091579f235 100644 --- a/libs/image/kis_node_filter_interface.cpp +++ b/libs/image/kis_node_filter_interface.cpp @@ -1,92 +1,92 @@ /* * Copyright (c) 2008 Cyrille Berger * Copyright (c) 2012 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-1301, USA. */ #include "kis_node_filter_interface.h" #include "filter/kis_filter.h" #include "generator/kis_generator.h" #include "filter/kis_filter_registry.h" #include "filter/kis_filter_configuration.h" #include "generator/kis_generator_registry.h" #ifdef SANITY_CHECK_FILTER_CONFIGURATION_OWNER #define SANITY_ACQUIRE_FILTER(filter) \ do { \ if ((filter)) { \ (filter)->sanityRefUsageCounter(); \ } \ } while (0) #define SANITY_RELEASE_FILTER(filter) \ do { \ if (m_filter && m_filter->sanityDerefUsageCounter()) { \ warnKrita; \ warnKrita << "WARNING: filter configuration has more than one user! Krita will probably crash soon!"; \ warnKrita << "WARNING:" << ppVar(this); \ warnKrita << "WARNING:" << ppVar(filter.data()); \ warnKrita; \ } \ } while (0) #else /* SANITY_CHECK_FILTER_CONFIGURATION_OWNER */ #define SANITY_ACQUIRE_FILTER(filter) #define SANITY_RELEASE_FILTER(filter) #endif /* SANITY_CHECK_FILTER_CONFIGURATION_OWNER*/ KisNodeFilterInterface::KisNodeFilterInterface(KisFilterConfigurationSP filterConfig, bool useGeneratorRegistry) : m_filter(filterConfig), m_useGeneratorRegistry(useGeneratorRegistry) { SANITY_ACQUIRE_FILTER(m_filter); } KisNodeFilterInterface::KisNodeFilterInterface(const KisNodeFilterInterface &rhs) : m_useGeneratorRegistry(rhs.m_useGeneratorRegistry) { if (m_useGeneratorRegistry) { m_filter = KisGeneratorRegistry::instance()->cloneConfiguration(const_cast(rhs.m_filter.data())); } else { m_filter = KisFilterRegistry::instance()->cloneConfiguration(const_cast(rhs.m_filter.data())); } SANITY_ACQUIRE_FILTER(m_filter); } KisNodeFilterInterface::~KisNodeFilterInterface() { SANITY_RELEASE_FILTER(m_filter); } KisFilterConfigurationSP KisNodeFilterInterface::filter() const { return m_filter; } void KisNodeFilterInterface::setFilter(KisFilterConfigurationSP filterConfig) { SANITY_RELEASE_FILTER(m_filter); - Q_ASSERT(filterConfig); + KIS_SAFE_ASSERT_RECOVER_RETURN(filterConfig); m_filter = filterConfig; SANITY_ACQUIRE_FILTER(m_filter); } diff --git a/libs/libqml/plugins/kritasketchplugin/models/FiltersCategoryModel.cpp b/libs/libqml/plugins/kritasketchplugin/models/FiltersCategoryModel.cpp index cd425b7122..6b156a4249 100644 --- a/libs/libqml/plugins/kritasketchplugin/models/FiltersCategoryModel.cpp +++ b/libs/libqml/plugins/kritasketchplugin/models/FiltersCategoryModel.cpp @@ -1,316 +1,316 @@ /* This file is part of the KDE project * Copyright (C) 2012 Dan Leinir Turthra Jensen * * 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-1301, USA. */ #include "FiltersCategoryModel.h" #include "FiltersModel.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include bool categoryLessThan(const FiltersModel* s1, const FiltersModel* s2) { return s1->categoryName.toLower() < s2->categoryName.toLower(); } class FiltersCategoryModel::Private { public: Private(FiltersCategoryModel* qq) : q(qq) , currentCategory(-1) , view(0) , previewEnabled(false) , previewFilterID(-1) , previewTimer(new QTimer()) { previewTimer->setInterval(150); previewTimer->setSingleShot(true); connect(previewTimer, SIGNAL(timeout()), q, SLOT(updatePreview())); } FiltersCategoryModel* q; int currentCategory; KisViewManager* view; QList categories; FiltersModel* categoryByName(const QString& name) { FiltersModel* category = 0; for(int i = 0; i < categories.count(); ++i) { if (categories.at(i)->categoryId == name) { category = categories[i]; break; } } return category; } void refreshContents() { q->beginResetModel(); qDeleteAll(categories); categories.clear(); QList filters = KisFilterRegistry::instance()->values(); QList tmpCategoryIDs; Q_FOREACH (const KisFilterSP filter, filters) { Q_ASSERT(filter); FiltersModel* cat = 0; if (!tmpCategoryIDs.contains(filter->menuCategory().id())) { cat = new FiltersModel(q); cat->categoryId = filter->menuCategory().id(); cat->categoryName = filter->menuCategory().name(); cat->setView(view); categories << cat; tmpCategoryIDs << filter->menuCategory().id(); connect(cat, SIGNAL(configurationChanged(int)), q, SLOT(filterConfigurationChanged(int))); connect(cat, SIGNAL(filterActivated(int)), q, SLOT(filterActivated(int))); } else cat = categoryByName(filter->menuCategory().id()); cat->addFilter(filter); qApp->processEvents(); } std::sort(categories.begin(), categories.end(), categoryLessThan); q->endResetModel(); } bool previewEnabled; KisFilterMaskSP mask; KisNodeSP node; int previewFilterID; KisFilterConfigurationSP newConfig; QTimer* previewTimer; }; FiltersCategoryModel::FiltersCategoryModel(QObject* parent) : QAbstractListModel(parent) , d(new Private(this)) { } FiltersCategoryModel::~FiltersCategoryModel() { delete d; } QHash FiltersCategoryModel::roleNames() const { QHash roles; roles[TextRole] = "text"; return roles; } QVariant FiltersCategoryModel::data(const QModelIndex& index, int role) const { QVariant data; if (index.isValid()) { switch(role) { case TextRole: data = d->categories[index.row()]->categoryName; break; default: break; } } return data; } int FiltersCategoryModel::rowCount(const QModelIndex& parent) const { if (parent.isValid()) return 0; return d->categories.count(); } QObject* FiltersCategoryModel::filterModel() const { if (d->currentCategory == -1) return 0; return d->categories[d->currentCategory]; } void FiltersCategoryModel::activateItem(int index) { if (index > -1 && index < d->categories.count()) { d->currentCategory = index; emit filterModelChanged(); } } QObject* FiltersCategoryModel::view() const { return d->view; } void FiltersCategoryModel::setView(QObject* newView) { if (d->view) { setPreviewEnabled(false); d->view->nodeManager()->disconnect(this); d->view->selectionManager()->disconnect(this); } d->view = qobject_cast( newView ); if (d->view) { d->refreshContents(); connect(d->view->nodeManager(), SIGNAL(sigLayerActivated(KisLayerSP)), this, SLOT(activeLayerChanged(KisLayerSP))); connect(d->view->selectionManager(), SIGNAL(currentSelectionChanged()), this, SLOT(activeSelectionChanged())); } emit viewChanged(); } void FiltersCategoryModel::activeLayerChanged(KisLayerSP layer) { Q_UNUSED(layer); setPreviewEnabled(false); } void FiltersCategoryModel::activeSelectionChanged() { setPreviewEnabled(false); } void FiltersCategoryModel::filterActivated(int index) { Q_UNUSED(index); setPreviewEnabled(false); } void FiltersCategoryModel::filterConfigurationChanged(int index, FiltersModel* model) { d->previewFilterID = index; if (d->previewEnabled && index > -1) { if (!model) { model = qobject_cast(sender()); } if (!model) { return; } KisFilterConfigurationSP config; KisFilter* filter = model->filter(index); if (filter->showConfigurationWidget() && filter->id() != QLatin1String("colortransfer")) { - KisConfigWidget* wdg = filter->createConfigurationWidget(0, d->view->activeNode()->original()); + KisConfigWidget* wdg = filter->createConfigurationWidget(0, d->view->activeNode()->original(), false); wdg->deleteLater(); config = KisFilterConfigurationSP(KisFilterRegistry::instance()->cloneConfiguration(dynamic_cast(wdg->configuration().data()))); } else { config = KisFilterConfigurationSP(KisFilterRegistry::instance()->cloneConfiguration(filter->defaultConfiguration())); } QObject* configuration = d->categories[d->currentCategory]->configuration(index); Q_FOREACH (const QByteArray& propName, configuration->dynamicPropertyNames()) { config->setProperty(QString(propName), configuration->property(propName)); } config->setCurve(qobject_cast(configuration)->curve()); config->setCurves(qobject_cast(configuration)->curves()); configuration->deleteLater(); d->newConfig = config; d->previewTimer->start(); } } void FiltersCategoryModel::updatePreview() { d->view->filterManager()->apply(d->newConfig); } bool FiltersCategoryModel::previewEnabled() const { return d->previewEnabled; } void FiltersCategoryModel::filterSelected(int index) { if (d->previewEnabled) filterConfigurationChanged(index, d->categories[d->currentCategory]); } void FiltersCategoryModel::setPreviewEnabled(bool enabled) { if (d->previewEnabled != enabled) { d->previewEnabled = enabled; emit previewEnabledChanged(); if (enabled) filterConfigurationChanged(d->previewFilterID, d->categories[d->currentCategory]); else d->view->filterManager()->cancel(); } } int FiltersCategoryModel::categoryIndexForConfig(QObject* config) { PropertyContainer* configuration = qobject_cast(config); if (!configuration) return -1; FiltersModel* model = 0; int i = 0; while(model == 0 && i < d->categories.count()) { FiltersModel* cat = d->categories.at(i); // i know there's no check here - but a category is not created unless there // is something to put in it for(int j = 0; j < cat->rowCount(); ++j) { if (cat->filter(j)->id() == configuration->name()) return i; } ++i; } return -1; } int FiltersCategoryModel::filterIndexForConfig(int categoryIndex, QObject* filterConfig) { PropertyContainer* configuration = qobject_cast(filterConfig); if (!configuration) return -1; if (categoryIndex < 0 || categoryIndex > d->categories.count() - 1) return -1; FiltersModel* cat = d->categories.at(categoryIndex); // i know there's no check here - but a category is not created unless there // is something to put in it for(int j = 0; j < cat->rowCount(); ++j) { if (cat->filter(j)->id() == configuration->name()) return j; } return -1; } diff --git a/libs/libqml/plugins/kritasketchplugin/models/FiltersModel.cpp b/libs/libqml/plugins/kritasketchplugin/models/FiltersModel.cpp index 42c685cd91..b12eba8730 100644 --- a/libs/libqml/plugins/kritasketchplugin/models/FiltersModel.cpp +++ b/libs/libqml/plugins/kritasketchplugin/models/FiltersModel.cpp @@ -1,207 +1,207 @@ /* This file is part of the KDE project * Copyright (C) 2012 Dan Leinir Turthra Jensen * * 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-1301, USA. */ #include "FiltersModel.h" #include #include #include #include #include #include class FiltersModel::Private { public: Private() : view(0) {}; KisViewManager* view; QList filters; QList configurations; }; FiltersModel::FiltersModel(QObject* parent) : QAbstractListModel(parent) , d(new Private) { } FiltersModel::~FiltersModel() { delete d; } QHash FiltersModel::roleNames() const { QHash roles; roles[TextRole] = "text"; return roles; } QVariant FiltersModel::data(const QModelIndex& index, int role) const { QVariant data; if (index.isValid()) { switch(role) { case TextRole: data = d->filters[index.row()]->name(); break; default: break; } } return data; } int FiltersModel::rowCount(const QModelIndex& parent) const { if (parent.isValid()) return 0; return d->filters.count(); } bool FiltersModel::filterRequiresConfiguration(int index) { if (index > -1 && index < d->filters.count()) { return d->filters[index]->showConfigurationWidget(); } return false; } QString FiltersModel::filterID(int index) { if (index > -1 && index < d->filters.count()) { return d->filters[index]->id(); } return QLatin1String(""); } void FiltersModel::activateFilter(int index) { if (index > -1 && index < d->filters.count()) { if (d->configurations[index]) { d->view->filterManager()->apply(d->configurations[index]); } else { d->view->filterManager()->apply(KisFilterConfigurationSP(d->filters[index]->defaultConfiguration())); } d->view->filterManager()->finish(); emit filterActivated(index); } } KisFilter* FiltersModel::filter(int index) { if (index > -1 && index < d->filters.count()) { return d->filters[index].data(); } return 0; } void FiltersModel::addFilter(KisFilterSP filter) { if (!d->view || !d->view->activeNode()) return; if (!filter.isNull()) { int newRow = d->filters.count(); beginInsertRows(QModelIndex(), newRow, newRow); d->filters << filter; // We're not asking for the config widget config for color transfer // The reason for this is that the completion widget is VERY slow to destruct on // Windows. This can be removed once that bug has been alleviated at some later // point in time, but for now it has no side effects, as this filter's default // config is fine anyway. if (filter->showConfigurationWidget() && filter->id() != QLatin1String("colortransfer")) { - KisConfigWidget* wdg = filter->createConfigurationWidget(0, d->view->activeNode()->original()); + KisConfigWidget* wdg = filter->createConfigurationWidget(0, d->view->activeNode()->original(), false); wdg->deleteLater(); d->configurations << KisFilterConfigurationSP(dynamic_cast(wdg->configuration().data())); } else { d->configurations << KisFilterConfigurationSP(filter->defaultConfiguration()); } endInsertRows(); } } QObject* FiltersModel::view() const { return d->view; } void FiltersModel::setView(QObject* newView) { d->view = qobject_cast( newView ); emit viewChanged(); } QObject* FiltersModel::configuration(int index) { // If index is out of bounds, return /something/ for the object work on at least. if (index < 0 || index > d->configurations.count() - 1) return new PropertyContainer("", this); PropertyContainer* config = new PropertyContainer(d->filters[index]->id(), this); if (!d->configurations[index]) { // if we have a config widget to show, reinitialise the configuration, just in case if(d->filters[index]->showConfigurationWidget() && d->filters[index]->id() != QLatin1String("colortransfer")) { - KisConfigWidget* wdg = d->filters[index]->createConfigurationWidget(0, d->view->activeNode()->original()); + KisConfigWidget* wdg = d->filters[index]->createConfigurationWidget(0, d->view->activeNode()->original(), false); wdg->deleteLater(); d->configurations[index] = KisFilterConfigurationSP(dynamic_cast(wdg->configuration().data())); } // If we've not got one already, assign the default configuration to the cache else { d->configurations[index] = KisFilterConfigurationSP(d->filters[index]->defaultConfiguration()); } } QMap props = d->configurations[index]->getProperties(); QMap::const_iterator i; for(i = props.constBegin(); i != props.constEnd(); ++i) { config->setProperty(i.key().toLatin1(), i.value()); } config->setCurve(d->configurations[index]->curve()); config->setCurves(d->configurations[index]->curves()); return config; } void FiltersModel::setConfiguration(int index, QObject* configuration) { if (qobject_cast< PropertyContainer* >(configuration) && index > -1 && index < d->configurations.count() - 1) { KisFilterConfigurationSP config = d->configurations[index]; Q_FOREACH (const QByteArray& propName, configuration->dynamicPropertyNames()) { config->setProperty(QString(propName), configuration->property(propName)); } config->setCurve(qobject_cast< PropertyContainer* >(configuration)->curve()); config->setCurves(qobject_cast< PropertyContainer* >(configuration)->curves()); d->configurations[index] = config; emit configurationChanged(index); } } diff --git a/libs/ui/dialogs/kis_dlg_adj_layer_props.cc b/libs/ui/dialogs/kis_dlg_adj_layer_props.cc index e6e91cd286..c5f8b4abc3 100644 --- a/libs/ui/dialogs/kis_dlg_adj_layer_props.cc +++ b/libs/ui/dialogs/kis_dlg_adj_layer_props.cc @@ -1,144 +1,144 @@ /* * Copyright (c) 2006 Boudewijn Rempt * * 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-1301, USA. */ #include "kis_dlg_adj_layer_props.h" #include #include #include #include #include #include "kis_config_widget.h" #include "kis_transaction.h" #include "filter/kis_filter.h" #include "filter/kis_filter_configuration.h" #include "filter/kis_filter_registry.h" #include "kis_layer.h" #include "kis_adjustment_layer.h" #include "kis_paint_device.h" #include "kis_paint_layer.h" #include "kis_group_layer.h" #include "kis_node_filter_interface.h" KisDlgAdjLayerProps::KisDlgAdjLayerProps(KisNodeSP node, KisNodeFilterInterface* nfi, KisPaintDeviceSP paintDevice, KisViewManager *view, KisFilterConfigurationSP configuration, const QString & layerName, const QString & caption, QWidget *parent, const char *name) : KoDialog(parent) , m_node(node) , m_paintDevice(paintDevice) , m_currentConfigWidget(0) , m_currentFilter(0) , m_currentConfiguration(0) , m_nodeFilterInterface(nfi) { setButtons(Ok | Cancel); setDefaultButton(Ok); setObjectName(name); m_currentConfiguration = configuration; if (m_currentConfiguration) { m_currentFilter = KisFilterRegistry::instance()->get(m_currentConfiguration->name()).data(); } setCaption(caption); QWidget * page = new QWidget(this); page->setObjectName("page widget"); QHBoxLayout * layout = new QHBoxLayout(page); layout->setMargin(0); setMainWidget(page); QVBoxLayout *v1 = new QVBoxLayout(); layout->addLayout(v1); QHBoxLayout *hl = new QHBoxLayout(); v1->addLayout(hl); QLabel * lblName = new QLabel(i18n("Layer name:"), page); lblName->setObjectName("lblName"); hl->addWidget(lblName, 0); m_layerName = new KLineEdit(page); m_layerName->setObjectName("m_layerName"); m_layerName->setText(layerName); m_layerName->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); hl->addWidget(m_layerName, 10); connect(m_layerName, SIGNAL(textChanged(QString)), this, SLOT(slotNameChanged(QString))); if (m_currentFilter) { - m_currentConfigWidget = m_currentFilter->createConfigurationWidget(page, paintDevice); + m_currentConfigWidget = m_currentFilter->createConfigurationWidget(page, paintDevice, true); if (m_currentConfigWidget) { m_currentConfigWidget->setView(view); m_currentConfigWidget->setConfiguration(m_currentConfiguration); } } if (m_currentFilter == 0 || m_currentConfigWidget == 0) { QLabel * labelNoConfigWidget = new QLabel(i18n("No configuration options are available for this filter"), page); v1->addWidget(labelNoConfigWidget); } else { v1->addWidget(m_currentConfigWidget); connect(m_currentConfigWidget, SIGNAL(sigConfigurationUpdated()), SLOT(slotConfigChanged())); } enableButtonOk(!m_layerName->text().isEmpty()); } void KisDlgAdjLayerProps::slotNameChanged(const QString & text) { enableButtonOk(!text.isEmpty()); } KisFilterConfigurationSP KisDlgAdjLayerProps::filterConfiguration() const { if (m_currentConfigWidget) { KisFilterConfigurationSP config = dynamic_cast(m_currentConfigWidget->configuration().data()); if (config) { return config; } } return m_currentFilter->defaultConfiguration(); } QString KisDlgAdjLayerProps::layerName() const { return m_layerName->text(); } void KisDlgAdjLayerProps::slotConfigChanged() { enableButtonOk(true); KisFilterConfigurationSP config = filterConfiguration(); if (config) { m_nodeFilterInterface->setFilter(config); } m_node->setDirty(); } diff --git a/libs/ui/dialogs/kis_dlg_filter.cpp b/libs/ui/dialogs/kis_dlg_filter.cpp index 87c300c516..fab63a1f18 100644 --- a/libs/ui/dialogs/kis_dlg_filter.cpp +++ b/libs/ui/dialogs/kis_dlg_filter.cpp @@ -1,245 +1,248 @@ /* * Copyright (c) 2007 Cyrille Berger * Copyright (c) 2008 Boudewijn Rempt * * 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-1301, USA. */ #include "kis_dlg_filter.h" #include #include #include #include #include #include #include #include #include #include "kis_selection.h" #include "kis_node_commands_adapter.h" #include "kis_filter_manager.h" #include "ui_wdgfilterdialog.h" #include "kis_canvas2.h" struct KisDlgFilter::Private { Private(KisFilterManager *_filterManager, KisViewManager *_view) : currentFilter(0) , resizeCount(0) , view(_view) , filterManager(_filterManager) , blockModifyingActionsGuard(new KisInputActionGroupsMaskGuard(view->canvasBase(), ViewTransformActionGroup)) { } KisFilterSP currentFilter; Ui_FilterDialog uiFilterDialog; KisNodeSP node; int resizeCount; KisViewManager *view; KisFilterManager *filterManager; // a special guard object that blocks all the painting input actions while the // dialog is open QScopedPointer blockModifyingActionsGuard; }; KisDlgFilter::KisDlgFilter(KisViewManager *view, KisNodeSP node, KisFilterManager *filterManager, QWidget *parent) : QDialog(parent), d(new Private(filterManager, view)) { setModal(false); d->uiFilterDialog.setupUi(this); d->node = node; d->uiFilterDialog.filterSelection->setView(view); d->uiFilterDialog.filterSelection->showFilterGallery(KisConfig(true).showFilterGallery()); d->uiFilterDialog.pushButtonCreateMaskEffect->show(); connect(d->uiFilterDialog.pushButtonCreateMaskEffect, SIGNAL(pressed()), SLOT(createMask())); connect(d->uiFilterDialog.pushButtonCreateMaskEffect,SIGNAL(pressed()),SLOT(close())); d->uiFilterDialog.filterGalleryToggle->setChecked(d->uiFilterDialog.filterSelection->isFilterGalleryVisible()); d->uiFilterDialog.filterGalleryToggle->setIcon(QPixmap(":/pics/sidebaricon.png")); d->uiFilterDialog.filterGalleryToggle->setMaximumWidth(d->uiFilterDialog.filterGalleryToggle->height()); connect(d->uiFilterDialog.filterSelection, SIGNAL(sigFilterGalleryToggled(bool)), d->uiFilterDialog.filterGalleryToggle, SLOT(setChecked(bool))); connect(d->uiFilterDialog.filterGalleryToggle, SIGNAL(toggled(bool)), d->uiFilterDialog.filterSelection, SLOT(showFilterGallery(bool))); connect(d->uiFilterDialog.filterSelection, SIGNAL(sigSizeChanged()), this, SLOT(slotFilterWidgetSizeChanged())); if (node->inherits("KisMask")) { d->uiFilterDialog.pushButtonCreateMaskEffect->setVisible(false); } d->uiFilterDialog.filterSelection->setPaintDevice(true, d->node->original()); connect(d->uiFilterDialog.buttonBox, SIGNAL(accepted()), SLOT(accept())); connect(d->uiFilterDialog.buttonBox, SIGNAL(rejected()), SLOT(reject())); connect(d->uiFilterDialog.checkBoxPreview, SIGNAL(toggled(bool)), SLOT(enablePreviewToggled(bool))); connect(d->uiFilterDialog.filterSelection, SIGNAL(configurationChanged()), SLOT(filterSelectionChanged())); connect(this, SIGNAL(accepted()), SLOT(slotOnAccept())); connect(this, SIGNAL(rejected()), SLOT(slotOnReject())); KConfigGroup group( KSharedConfig::openConfig(), "filterdialog"); d->uiFilterDialog.checkBoxPreview->setChecked(group.readEntry("showPreview", true)); restoreGeometry(KisConfig(true).readEntry("filterdialog/geometry", QByteArray())); } KisDlgFilter::~KisDlgFilter() { KisConfig(false).writeEntry("filterdialog/geometry", saveGeometry()); delete d; } void KisDlgFilter::setFilter(KisFilterSP f) { Q_ASSERT(f); setDialogTitle(f); d->uiFilterDialog.filterSelection->setFilter(f); d->uiFilterDialog.pushButtonCreateMaskEffect->setEnabled(f->supportsAdjustmentLayers()); d->currentFilter = f; updatePreview(); } void KisDlgFilter::setDialogTitle(KisFilterSP filter) { setWindowTitle(filter.isNull() ? i18nc("@title:window", "Filter") : i18nc("@title:window", "Filter: %1", filter->name())); } void KisDlgFilter::startApplyingFilter(KisFilterConfigurationSP config) { if (!d->uiFilterDialog.filterSelection->configuration()) return; if (d->node->inherits("KisLayer")) { config->setChannelFlags(qobject_cast(d->node.data())->channelFlags()); } d->filterManager->apply(config); } void KisDlgFilter::updatePreview() { - if (!d->uiFilterDialog.filterSelection->configuration()) return; + KisFilterConfigurationSP config = d->uiFilterDialog.filterSelection->configuration(); + if (!config) return; + bool maskCreationAllowed = !d->currentFilter || d->currentFilter->configurationAllowedForMask(config); + d->uiFilterDialog.pushButtonCreateMaskEffect->setEnabled(maskCreationAllowed); if (d->uiFilterDialog.checkBoxPreview->isChecked()) { KisFilterConfigurationSP config(d->uiFilterDialog.filterSelection->configuration()); startApplyingFilter(config); } d->uiFilterDialog.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true); } void KisDlgFilter::adjustSize() { QWidget::adjustSize(); } void KisDlgFilter::slotFilterWidgetSizeChanged() { QMetaObject::invokeMethod(this, "adjustSize", Qt::QueuedConnection); } void KisDlgFilter::slotOnAccept() { if (!d->filterManager->isStrokeRunning()) { KisFilterConfigurationSP config(d->uiFilterDialog.filterSelection->configuration()); startApplyingFilter(config); } d->filterManager->finish(); d->uiFilterDialog.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); KisConfig(false).setShowFilterGallery(d->uiFilterDialog.filterSelection->isFilterGalleryVisible()); } void KisDlgFilter::slotOnReject() { if (d->filterManager->isStrokeRunning()) { d->filterManager->cancel(); } KisConfig(false).setShowFilterGallery(d->uiFilterDialog.filterSelection->isFilterGalleryVisible()); } void KisDlgFilter::createMask() { if (d->node->inherits("KisMask")) return; if (d->filterManager->isStrokeRunning()) { d->filterManager->cancel(); } KisLayer *layer = qobject_cast(d->node.data()); KisFilterMaskSP mask = new KisFilterMask(); mask->setName(d->currentFilter->name()); mask->initSelection(d->view->selection(), layer); mask->setFilter(d->uiFilterDialog.filterSelection->configuration()); Q_ASSERT(layer->allowAsChild(mask)); KisNodeCommandsAdapter adapter(d->view); adapter.addNode(mask, layer, layer->lastChild()); } void KisDlgFilter::enablePreviewToggled(bool state) { if (state) { updatePreview(); } else if (d->filterManager->isStrokeRunning()) { d->filterManager->cancel(); } KConfigGroup group( KSharedConfig::openConfig(), "filterdialog"); group.writeEntry("showPreview", d->uiFilterDialog.checkBoxPreview->isChecked()); group.config()->sync(); } void KisDlgFilter::filterSelectionChanged() { KisFilterSP filter = d->uiFilterDialog.filterSelection->currentFilter(); setDialogTitle(filter); d->uiFilterDialog.pushButtonCreateMaskEffect->setEnabled(filter.isNull() ? false : filter->supportsAdjustmentLayers()); updatePreview(); } void KisDlgFilter::resizeEvent(QResizeEvent* event) { QDialog::resizeEvent(event); // // Workaround, after the initialisation don't center the dialog anymore // if(d->resizeCount < 2) { // QWidget* canvas = d->view->canvas(); // QRect rect(canvas->mapToGlobal(canvas->geometry().topLeft()), size()); // int deltaX = (canvas->geometry().width() - geometry().width())/2; // int deltaY = (canvas->geometry().height() - geometry().height())/2; // rect.translate(deltaX, deltaY); // setGeometry(rect); // d->resizeCount++; // } } diff --git a/libs/ui/widgets/kis_filter_selector_widget.cc b/libs/ui/widgets/kis_filter_selector_widget.cc index b83a1050c1..dcf73c9f14 100644 --- a/libs/ui/widgets/kis_filter_selector_widget.cc +++ b/libs/ui/widgets/kis_filter_selector_widget.cc @@ -1,361 +1,363 @@ /* * Copyright (c) 2007-2008 Cyrille Berger * Copyright (c) 2009 Boudewijn Rempt * * 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-1301, USA. */ #include "kis_filter_selector_widget.h" #include #include #include #include #include #include #include #include #include #include #include #include "ui_wdgfilterselector.h" #include #include #include #include #include #include "kis_default_bounds.h" #include // From krita/ui #include "kis_bookmarked_configurations_editor.h" #include "kis_bookmarked_filter_configurations_model.h" #include "kis_filters_model.h" #include "kis_config.h" class ThumbnailBounds : public KisDefaultBounds { public: ThumbnailBounds() : KisDefaultBounds() {} ~ThumbnailBounds() override {} QRect bounds() const override { return QRect(0, 0, 100, 100); } private: Q_DISABLE_COPY(ThumbnailBounds) }; struct KisFilterSelectorWidget::Private { QWidget *currentCentralWidget {0}; KisConfigWidget *currentFilterConfigurationWidget {0}; KisFilterSP currentFilter; KisPaintDeviceSP paintDevice; Ui_FilterSelector uiFilterSelector; KisPaintDeviceSP thumb; KisBookmarkedFilterConfigurationsModel *currentBookmarkedFilterConfigurationsModel {0}; KisFiltersModel *filtersModel {}; QGridLayout *widgetLayout {}; KisViewManager *view{}; bool showFilterGallery {true}; + bool usedForMask {false}; }; KisFilterSelectorWidget::KisFilterSelectorWidget(QWidget* parent) : d(new Private) { Q_UNUSED(parent); setObjectName("KisFilterSelectorWidget"); d->uiFilterSelector.setupUi(this); d->widgetLayout = new QGridLayout(d->uiFilterSelector.centralWidgetHolder); d->widgetLayout->setContentsMargins(0,0,0,0); d->widgetLayout->setHorizontalSpacing(0); showFilterGallery(false); connect(d->uiFilterSelector.filtersSelector, SIGNAL(clicked(QModelIndex)), SLOT(setFilterIndex(QModelIndex))); connect(d->uiFilterSelector.filtersSelector, SIGNAL(activated(QModelIndex)), SLOT(setFilterIndex(QModelIndex))); connect(d->uiFilterSelector.comboBoxPresets, SIGNAL(activated(int)),SLOT(slotBookmarkedFilterConfigurationSelected(int))); connect(d->uiFilterSelector.pushButtonEditPressets, SIGNAL(pressed()), SLOT(editConfigurations())); connect(d->uiFilterSelector.btnXML, SIGNAL(clicked()), this, SLOT(showXMLdialog())); KisConfig cfg(true); d->uiFilterSelector.chkRememberPreset->setChecked(cfg.readEntry("filterdialog/rememberlastpreset", false)); } KisFilterSelectorWidget::~KisFilterSelectorWidget() { KisConfig cfg(false); cfg.writeEntry("filterdialog/rememberlastpreset", d->uiFilterSelector.chkRememberPreset->isChecked()); delete d->filtersModel; delete d->currentBookmarkedFilterConfigurationsModel; delete d->currentCentralWidget; delete d->widgetLayout; delete d; } void KisFilterSelectorWidget::setView(KisViewManager *view) { d->view = view; } void KisFilterSelectorWidget::setPaintDevice(bool showAll, KisPaintDeviceSP _paintDevice) { if (!_paintDevice) return; if (d->filtersModel) delete d->filtersModel; + d->usedForMask = !showAll; d->paintDevice = _paintDevice; d->thumb = d->paintDevice->createThumbnailDevice(100, 100); d->thumb->setDefaultBounds(new ThumbnailBounds()); d->filtersModel = new KisFiltersModel(showAll, d->thumb); d->uiFilterSelector.filtersSelector->setFilterModel(d->filtersModel); d->uiFilterSelector.filtersSelector->header()->setVisible(false); KisConfig cfg(true); QModelIndex idx = d->filtersModel->indexForFilter(cfg.readEntry("FilterSelector/LastUsedFilter", "levels")); if (!idx.isValid()) { idx = d->filtersModel->indexForFilter("levels"); } if (isFilterGalleryVisible()) { d->uiFilterSelector.filtersSelector->activateFilter(idx); } } void KisFilterSelectorWidget::showFilterGallery(bool visible) { if (d->showFilterGallery == visible) { return; } d->showFilterGallery = visible; update(); emit sigFilterGalleryToggled(visible); emit sigSizeChanged(); } void KisFilterSelectorWidget::showXMLdialog() { if (currentFilter()->showConfigurationWidget()) { QDialog *xmlDialog = new QDialog(); xmlDialog->setMinimumWidth(500); xmlDialog->setWindowTitle(i18n("Filter configuration XML")); QVBoxLayout *xmllayout = new QVBoxLayout(xmlDialog); QPlainTextEdit *text = new QPlainTextEdit(xmlDialog); KisFilterConfigurationSP config = configuration(); text->setPlainText(config->toXML()); xmllayout->addWidget(text); QDialogButtonBox *buttons = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel, xmlDialog); connect(buttons, SIGNAL(accepted()), xmlDialog, SLOT(accept())); connect(buttons, SIGNAL(rejected()), xmlDialog, SLOT(reject())); xmllayout->addWidget(buttons); if (xmlDialog->exec()==QDialog::Accepted) { QDomDocument doc; doc.setContent(text->toPlainText()); config->fromXML(doc.documentElement()); if (config) { d->currentFilterConfigurationWidget->setConfiguration(config); } } } } bool KisFilterSelectorWidget::isFilterGalleryVisible() const { return d->showFilterGallery; } KisFilterSP KisFilterSelectorWidget::currentFilter() const { return d->currentFilter; } void KisFilterSelectorWidget::setFilter(KisFilterSP f) { Q_ASSERT(f); Q_ASSERT(d->filtersModel); setWindowTitle(f->name()); dbgKrita << "setFilter: " << f; d->currentFilter = f; delete d->currentCentralWidget; { bool v = d->uiFilterSelector.filtersSelector->blockSignals(true); d->uiFilterSelector.filtersSelector->setCurrentIndex(d->filtersModel->indexForFilter(f->id())); d->uiFilterSelector.filtersSelector->blockSignals(v); } KisConfigWidget* widget = - d->currentFilter->createConfigurationWidget(d->uiFilterSelector.centralWidgetHolder, d->paintDevice); + d->currentFilter->createConfigurationWidget(d->uiFilterSelector.centralWidgetHolder, d->paintDevice, d->usedForMask); if (!widget) { // No widget, so display a label instead d->uiFilterSelector.comboBoxPresets->setEnabled(false); d->uiFilterSelector.pushButtonEditPressets->setEnabled(false); d->uiFilterSelector.btnXML->setEnabled(false); d->currentFilterConfigurationWidget = 0; d->currentCentralWidget = new QLabel(i18n("No configuration options"), d->uiFilterSelector.centralWidgetHolder); d->uiFilterSelector.scrollArea->setMinimumSize(d->currentCentralWidget->sizeHint()); qobject_cast(d->currentCentralWidget)->setAlignment(Qt::AlignCenter); } else { d->uiFilterSelector.comboBoxPresets->setEnabled(true); d->uiFilterSelector.pushButtonEditPressets->setEnabled(true); d->uiFilterSelector.btnXML->setEnabled(true); d->currentFilterConfigurationWidget = widget; d->currentCentralWidget = widget; widget->layout()->setContentsMargins(0,0,0,0); d->currentFilterConfigurationWidget->setView(d->view); d->currentFilterConfigurationWidget->blockSignals(true); d->currentFilterConfigurationWidget->setConfiguration(d->currentFilter->defaultConfiguration()); d->currentFilterConfigurationWidget->blockSignals(false); d->uiFilterSelector.scrollArea->setContentsMargins(0,0,0,0); d->uiFilterSelector.scrollArea->setMinimumWidth(widget->sizeHint().width() + 18); connect(d->currentFilterConfigurationWidget, SIGNAL(sigConfigurationUpdated()), this, SIGNAL(configurationChanged())); } // Change the list of presets delete d->currentBookmarkedFilterConfigurationsModel; d->currentBookmarkedFilterConfigurationsModel = new KisBookmarkedFilterConfigurationsModel(d->thumb, f); d->uiFilterSelector.comboBoxPresets->setModel(d->currentBookmarkedFilterConfigurationsModel); // Add the widget to the layout d->currentCentralWidget->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); d->widgetLayout->addWidget(d->currentCentralWidget, 0 , 0); if (d->uiFilterSelector.chkRememberPreset->isChecked()) { int lastBookmarkedFilterConfiguration = KisConfig(true).readEntry("lastBookmarkedFilterConfiguration/" + f->id(), 0); if (d->uiFilterSelector.comboBoxPresets->count() > lastBookmarkedFilterConfiguration) { d->uiFilterSelector.comboBoxPresets->setCurrentIndex(lastBookmarkedFilterConfiguration); slotBookmarkedFilterConfigurationSelected(lastBookmarkedFilterConfiguration); } } update(); } void KisFilterSelectorWidget::setFilterIndex(const QModelIndex& idx) { if (!idx.isValid()) return; Q_ASSERT(d->filtersModel); KisFilter* filter = const_cast(d->filtersModel->indexToFilter(idx)); if (filter) { setFilter(filter); } else { if (d->currentFilter) { bool v = d->uiFilterSelector.filtersSelector->blockSignals(true); QModelIndex idx = d->filtersModel->indexForFilter(d->currentFilter->id()); d->uiFilterSelector.filtersSelector->setCurrentIndex(idx); d->uiFilterSelector.filtersSelector->scrollTo(idx); d->uiFilterSelector.filtersSelector->blockSignals(v); } } KisConfig cfg(false); cfg.writeEntry("FilterSelector/LastUsedFilter", d->currentFilter->id()); emit(configurationChanged()); } void KisFilterSelectorWidget::slotBookmarkedFilterConfigurationSelected(int index) { if (d->currentFilterConfigurationWidget) { QModelIndex modelIndex = d->currentBookmarkedFilterConfigurationsModel->index(index, 0); KisFilterConfigurationSP config = d->currentBookmarkedFilterConfigurationsModel->configuration(modelIndex); d->currentFilterConfigurationWidget->setConfiguration(config); if (d->currentFilter && index != KisConfig(true).readEntry("lastBookmarkedFilterConfiguration/" + d->currentFilter->id(), 0)) { KisConfig(false).writeEntry("lastBookmarkedFilterConfiguration/" + d->currentFilter->id(), index); } } } void KisFilterSelectorWidget::editConfigurations() { KisSerializableConfigurationSP config = d->currentFilterConfigurationWidget ? d->currentFilterConfigurationWidget->configuration() : 0; KisBookmarkedConfigurationsEditor editor(this, d->currentBookmarkedFilterConfigurationsModel, config); editor.exec(); } void KisFilterSelectorWidget::update() { d->uiFilterSelector.filtersSelector->setVisible(d->showFilterGallery); if (d->showFilterGallery) { setMinimumWidth(qMax(sizeHint().width(), 700)); d->uiFilterSelector.scrollArea->setMinimumHeight(400); setMinimumHeight(d->uiFilterSelector.verticalLayout->sizeHint().height()); if (d->currentFilter) { bool v = d->uiFilterSelector.filtersSelector->blockSignals(true); d->uiFilterSelector.filtersSelector->setCurrentIndex(d->filtersModel->indexForFilter(d->currentFilter->id())); d->uiFilterSelector.filtersSelector->blockSignals(v); } } else { if (d->currentCentralWidget) { d->uiFilterSelector.scrollArea->setMinimumHeight(qMin(400, d->currentCentralWidget->sizeHint().height())); } setMinimumSize(d->uiFilterSelector.verticalLayout->sizeHint()); } } KisFilterConfigurationSP KisFilterSelectorWidget::configuration() { if (d->currentFilterConfigurationWidget) { KisFilterConfigurationSP config = dynamic_cast(d->currentFilterConfigurationWidget->configuration().data()); if (config) { return config; } } else if (d->currentFilter) { return d->currentFilter->defaultConfiguration(); } return 0; } void KisFilterTree::setFilterModel(QAbstractItemModel *model) { m_model = model; } void KisFilterTree::activateFilter(QModelIndex idx) { setModel(m_model); selectionModel()->select(idx, QItemSelectionModel::SelectCurrent); expand(idx); scrollTo(idx); emit activated(idx); } void KisFilterSelectorWidget::setVisible(bool visible) { QWidget::setVisible(visible); if (visible) { update(); } } diff --git a/libs/ui/widgets/kis_wdg_generator.cpp b/libs/ui/widgets/kis_wdg_generator.cpp index 39f38d2309..7c0d5d429a 100644 --- a/libs/ui/widgets/kis_wdg_generator.cpp +++ b/libs/ui/widgets/kis_wdg_generator.cpp @@ -1,174 +1,174 @@ /* This file is part of the KDE project * Copyright (C) Boudewijn Rempt , (C) 2008 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "widgets/kis_wdg_generator.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include "ui_wdggenerators.h" class KisGeneratorItem : public QListWidgetItem { public: KisGeneratorItem(const QString & text, QListWidget * parent = 0, int type = Type) : QListWidgetItem(text, parent, type) { } KisGeneratorSP generator; }; struct KisWdgGenerator::Private { public: Private() : centralWidget(0), view(0) { } QWidget * centralWidget; // Active generator settings widget KisGeneratorSP currentGenerator; Ui_WdgGenerators uiWdgGenerators; KisPaintDeviceSP dev; QGridLayout *widgetLayout; KisViewManager *view; }; KisWdgGenerator::KisWdgGenerator(QWidget * parent) : QWidget(parent) , d(new Private()) { KisPaintDeviceSP dev = new KisPaintDevice(KoColorSpaceRegistry::instance()->rgb8(0)); } KisWdgGenerator::~KisWdgGenerator() { delete d; } void KisWdgGenerator::initialize(KisViewManager *view) { d->view = view; d->uiWdgGenerators.setupUi(this); d->widgetLayout = new QGridLayout(d->uiWdgGenerators.centralWidgetHolder); QStringList generatorNames = KisGeneratorRegistry::instance()->keys(); generatorNames.sort(); Q_FOREACH (const QString &generatorName, generatorNames) { KisGeneratorSP generator = KisGeneratorRegistry::instance()->get(generatorName); Q_ASSERT(generator); KisGeneratorItem * item = new KisGeneratorItem(generator->name(), d->uiWdgGenerators.lstGenerators, QListWidgetItem::UserType + 1); item->generator = generator; } connect(d->uiWdgGenerators.lstGenerators, SIGNAL(currentRowChanged(int)), this, SLOT(slotGeneratorActivated(int))); if (d->uiWdgGenerators.lstGenerators->count() > 0) { d->uiWdgGenerators.lstGenerators->setCurrentRow(0); } } void KisWdgGenerator::setConfiguration(const KisFilterConfigurationSP config) { for (int i = 0; i < d->uiWdgGenerators.lstGenerators->count(); ++i) { KisGeneratorItem * item = static_cast(d->uiWdgGenerators.lstGenerators->item(i)); if (item->generator->id() == config->name()) { // match! slotGeneratorActivated(i); d->uiWdgGenerators.lstGenerators->setCurrentRow(i); KisConfigWidget * wdg = dynamic_cast(d->centralWidget); if (wdg) { wdg->setConfiguration(config); } return; } } } KisFilterConfigurationSP KisWdgGenerator::configuration() { KisConfigWidget * wdg = dynamic_cast(d->centralWidget); if (wdg) { KisFilterConfigurationSP config = dynamic_cast(wdg->configuration().data()); if (config) { return config; } } else { return d->currentGenerator->defaultConfiguration(); } return 0; } void KisWdgGenerator::slotGeneratorActivated(int row) { KisGeneratorItem *item = dynamic_cast(d->uiWdgGenerators.lstGenerators->item(row)); if (!item) { d->centralWidget = new QLabel(i18n("No configuration options."), d->uiWdgGenerators.centralWidgetHolder); } else { d->currentGenerator = item->generator; delete d->centralWidget; KisConfigWidget* widget = - d->currentGenerator->createConfigurationWidget(d->uiWdgGenerators.centralWidgetHolder, d->dev); + d->currentGenerator->createConfigurationWidget(d->uiWdgGenerators.centralWidgetHolder, d->dev, true); if (!widget) { // No widget, so display a label instead d->centralWidget = new QLabel(i18n("No configuration options."), d->uiWdgGenerators.centralWidgetHolder); } else { d->centralWidget = widget; connect( widget, SIGNAL(sigConfigurationUpdated()), this, SIGNAL(previewConfiguration())); widget->setView(d->view); widget->setConfiguration(d->currentGenerator->defaultConfiguration()); } } d->widgetLayout->addWidget(d->centralWidget, 0 , 0); d->uiWdgGenerators.centralWidgetHolder->setMinimumSize(d->centralWidget->minimumSize()); } diff --git a/plugins/filters/asccdl/kis_asccdl_filter.cpp b/plugins/filters/asccdl/kis_asccdl_filter.cpp index 12e0000b6c..d0ba94eff3 100644 --- a/plugins/filters/asccdl/kis_asccdl_filter.cpp +++ b/plugins/filters/asccdl/kis_asccdl_filter.cpp @@ -1,130 +1,130 @@ /* * Copyright (c) 2017 Wolthera van Hövell tot Westerflier * * 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-1301, USA. */ #include "kis_asccdl_filter.h" #include "kis_wdg_asccdl.h" #include #include #include #include #include #include K_PLUGIN_FACTORY_WITH_JSON(KritaASCCDLFactory, "kritaasccdl.json", registerPlugin();) KritaASCCDL::KritaASCCDL(QObject *parent, const QVariantList &) : QObject(parent) { KisFilterRegistry::instance()->add(KisFilterSP(new KisFilterASCCDL())); } KritaASCCDL::~KritaASCCDL() { } KisFilterASCCDL::KisFilterASCCDL(): KisColorTransformationFilter(id(), FiltersCategoryAdjustId, i18n("&Slope, Offset, Power...")) { setSupportsPainting(true); setSupportsAdjustmentLayers(true); setSupportsLevelOfDetail(true); setSupportsThreading(true); setColorSpaceIndependence(FULLY_INDEPENDENT); setShowConfigurationWidget(true); } KoColorTransformation *KisFilterASCCDL::createTransformation(const KoColorSpace *cs, const KisFilterConfigurationSP config) const { KoColor black(Qt::black, cs); return new KisASCCDLTransformation(cs, config->getColor("slope", black), config->getColor("offset", black), config->getColor("power", black)); } -KisConfigWidget *KisFilterASCCDL::createConfigurationWidget(QWidget *parent, const KisPaintDeviceSP dev) const +KisConfigWidget *KisFilterASCCDL::createConfigurationWidget(QWidget *parent, const KisPaintDeviceSP dev, bool) const { return new KisASCCDLConfigWidget(parent, dev->colorSpace()); } bool KisFilterASCCDL::needsTransparentPixels(const KisFilterConfigurationSP config, const KoColorSpace *cs) const { KoColor black(Qt::black, cs); KoColor offset = config->getColor("offset", black); offset.convertTo(cs); if (cs->difference(black.data(), offset.data())>0) { return true; } return false; } KisFilterConfigurationSP KisFilterASCCDL::factoryConfiguration() const { KisColorTransformationConfigurationSP config = new KisColorTransformationConfiguration(id().id(), 0); QVariant colorVariant("KoColor"); KoColor black; black.fromQColor(QColor(Qt::black)); KoColor white; white.fromQColor(QColor(Qt::white)); colorVariant.setValue(white); config->setProperty( "slope", colorVariant); config->setProperty( "power", colorVariant); colorVariant.setValue(black); config->setProperty("offset", colorVariant); return config; } KisASCCDLTransformation::KisASCCDLTransformation(const KoColorSpace *cs, KoColor slope, KoColor offset, KoColor power) { QVector slopeN(cs->channelCount()); slope.convertTo(cs); slope.colorSpace()->normalisedChannelsValue(slope.data(), slopeN); m_slope = slopeN; offset.convertTo(cs); QVector offsetN(cs->channelCount()); offset.colorSpace()->normalisedChannelsValue(offset.data(), offsetN); m_offset = offsetN; power.convertTo(cs); QVector powerN(cs->channelCount()); power.colorSpace()->normalisedChannelsValue(power.data(), powerN); m_power = powerN; m_cs = cs; } void KisASCCDLTransformation::transform(const quint8 *src, quint8 *dst, qint32 nPixels) const { QVector normalised(m_cs->channelCount()); const int pixelSize = m_cs->pixelSize(); while (nPixels--) { m_cs->normalisedChannelsValue(src, normalised); for (uint c=0; cchannelCount(); c++){ if (m_cs->channels().at(c)->channelType()!=KoChannelInfo::ALPHA) { normalised[c] = qPow( (normalised.at(c)*m_slope.at(c))+m_offset.at(c), m_power.at(c)); } } m_cs->fromNormalisedChannelsValue(dst, normalised); src += pixelSize; dst += pixelSize; } } #include "kis_asccdl_filter.moc" diff --git a/plugins/filters/asccdl/kis_asccdl_filter.h b/plugins/filters/asccdl/kis_asccdl_filter.h index a7eb26a7b6..5e818f9812 100644 --- a/plugins/filters/asccdl/kis_asccdl_filter.h +++ b/plugins/filters/asccdl/kis_asccdl_filter.h @@ -1,61 +1,61 @@ /* * Copyright (c) 2017 Wolthera van Hövell tot Westerflier * * 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-1301, USA. */ #ifndef KIS_ASCCDL_FILTER_H #define KIS_ASCCDL_FILTER_H #include #include "filter/kis_color_transformation_filter.h" class KritaASCCDL : public QObject { Q_OBJECT public: KritaASCCDL(QObject *parent, const QVariantList &); ~KritaASCCDL() override; }; class KisFilterASCCDL: public KisColorTransformationFilter { public: KisFilterASCCDL(); public: static inline KoID id() { return KoID("asc-cdl", i18n("Slope, Offset, Power(ASC-CDL)")); } KoColorTransformation *createTransformation(const KoColorSpace* cs, const KisFilterConfigurationSP config) const override; - KisConfigWidget *createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev) const override; + KisConfigWidget *createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev, bool useForMasks) const override; bool needsTransparentPixels(const KisFilterConfigurationSP config, const KoColorSpace *cs) const override; protected: KisFilterConfigurationSP factoryConfiguration() const override; }; class KisASCCDLTransformation : public KoColorTransformation { public: KisASCCDLTransformation(const KoColorSpace *cs, KoColor slope, KoColor offset, KoColor power); void transform(const quint8* src, quint8* dst, qint32 nPixels) const override; private: QVector m_slope; QVector m_offset; QVector m_power; const KoColorSpace *m_cs; }; #endif // KIS_ASCCDL_H diff --git a/plugins/filters/blur/kis_blur_filter.cpp b/plugins/filters/blur/kis_blur_filter.cpp index 553a134070..2dc522a7ec 100644 --- a/plugins/filters/blur/kis_blur_filter.cpp +++ b/plugins/filters/blur/kis_blur_filter.cpp @@ -1,139 +1,139 @@ /* * This file is part of Krita * * Copyright (c) 2006 Cyrille Berger * * 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-1301, USA. */ #include //MSVC requires that Vc come first #include "kis_blur_filter.h" #include #include #include #include "kis_wdg_blur.h" #include "ui_wdgblur.h" #include #include #include #include #include #include "kis_mask_generator.h" #include "kis_lod_transform.h" KisBlurFilter::KisBlurFilter() : KisFilter(id(), FiltersCategoryBlurId, i18n("&Blur...")) { setSupportsPainting(true); setSupportsAdjustmentLayers(true); setSupportsLevelOfDetail(true); setColorSpaceIndependence(FULLY_INDEPENDENT); } -KisConfigWidget * KisBlurFilter::createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP) const +KisConfigWidget * KisBlurFilter::createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP, bool) const { return new KisWdgBlur(parent); } KisFilterConfigurationSP KisBlurFilter::factoryConfiguration() const { KisFilterConfigurationSP config = new KisFilterConfiguration(id().id(), 1); config->setProperty("halfWidth", 5); config->setProperty("halfHeight", 5); config->setProperty("rotate", 0); config->setProperty("strength", 0); config->setProperty("shape", 0); return config; } void KisBlurFilter::processImpl(KisPaintDeviceSP device, const QRect& rect, const KisFilterConfigurationSP _config, KoUpdater* progressUpdater ) const { QPoint srcTopLeft = rect.topLeft(); Q_ASSERT(device != 0); KisFilterConfigurationSP config = _config ? _config : new KisFilterConfiguration(id().id(), 1); KisLodTransformScalar t(device); QVariant value; const uint halfWidth = t.scale((config->getProperty("halfWidth", value)) ? value.toUInt() : 5); const uint halfHeight = t.scale((config->getProperty("halfHeight", value)) ? value.toUInt() : 5); int shape = (config->getProperty("shape", value)) ? value.toInt() : 0; uint width = 2 * halfWidth + 1; uint height = 2 * halfHeight + 1; float aspectRatio = (float) width / height; int rotate = (config->getProperty("rotate", value)) ? value.toInt() : 0; int strength = 100 - (config->getProperty("strength", value) ? value.toUInt() : 0); int hFade = (halfWidth * strength) / 100; int vFade = (halfHeight * strength) / 100; KisMaskGenerator* kas; dbgKrita << width << "" << height << "" << hFade << "" << vFade; switch (shape) { case 1: kas = new KisRectangleMaskGenerator(width, aspectRatio, hFade, vFade, 2, true); break; case 0: default: kas = new KisCircleMaskGenerator(width, aspectRatio, hFade, vFade, 2, true); break; } QBitArray channelFlags; if (config) { channelFlags = config->channelFlags(); } if (channelFlags.isEmpty() || !config) { channelFlags = QBitArray(device->colorSpace()->channelCount(), true); } KisConvolutionKernelSP kernel = KisConvolutionKernel::fromMaskGenerator(kas, rotate * M_PI / 180.0); delete kas; KisConvolutionPainter painter(device); painter.setChannelFlags(channelFlags); painter.setProgress(progressUpdater); painter.applyMatrix(kernel, device, srcTopLeft, srcTopLeft, rect.size(), BORDER_REPEAT); } QRect KisBlurFilter::neededRect(const QRect & rect, const KisFilterConfigurationSP _config, int lod) const { KisLodTransformScalar t(lod); QVariant value; const int halfWidth = t.scale(_config->getProperty("halfWidth", value) ? value.toUInt() : 5); const int halfHeight = t.scale(_config->getProperty("halfHeight", value) ? value.toUInt() : 5); return rect.adjusted(-halfWidth * 2, -halfHeight * 2, halfWidth * 2, halfHeight * 2); } QRect KisBlurFilter::changedRect(const QRect & rect, const KisFilterConfigurationSP _config, int lod) const { KisLodTransformScalar t(lod); QVariant value; const int halfWidth = t.scale(_config->getProperty("halfWidth", value) ? value.toUInt() : 5); const int halfHeight = t.scale(_config->getProperty("halfHeight", value) ? value.toUInt() : 5); return rect.adjusted(-halfWidth, -halfHeight, halfWidth, halfHeight); } diff --git a/plugins/filters/blur/kis_blur_filter.h b/plugins/filters/blur/kis_blur_filter.h index aee3bd80d6..14097419c9 100644 --- a/plugins/filters/blur/kis_blur_filter.h +++ b/plugins/filters/blur/kis_blur_filter.h @@ -1,48 +1,48 @@ /* * This file is part of Krita * * Copyright (c) 2006 Cyrille Berger * * 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-1301, USA. */ #ifndef KIS_BLUR_FILTER_H #define KIS_BLUR_FILTER_H #include "filter/kis_filter.h" class KisBlurFilter : public KisFilter { public: KisBlurFilter(); public: void processImpl(KisPaintDeviceSP device, const QRect& size, const KisFilterConfigurationSP config, KoUpdater* progressUpdater ) const override; static inline KoID id() { return KoID("blur", i18n("Blur")); } KisFilterConfigurationSP factoryConfiguration() const override; public: - KisConfigWidget * createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev) const override; + KisConfigWidget * createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev, bool useForMasks) const override; QRect neededRect(const QRect & rect, const KisFilterConfigurationSP _config, int lod) const override; QRect changedRect(const QRect & rect, const KisFilterConfigurationSP _config, int lod) const override; }; #endif diff --git a/plugins/filters/blur/kis_gaussian_blur_filter.cpp b/plugins/filters/blur/kis_gaussian_blur_filter.cpp index 008e14daaa..81386c4054 100644 --- a/plugins/filters/blur/kis_gaussian_blur_filter.cpp +++ b/plugins/filters/blur/kis_gaussian_blur_filter.cpp @@ -1,123 +1,148 @@ /* * This file is part of Krita * * Copyright (c) 2009 Edward Apap * * 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-1301, USA. */ #include "kis_gaussian_blur_filter.h" #include "kis_wdg_gaussian_blur.h" #include #include #include #include #include "ui_wdg_gaussian_blur.h" #include #include #include #include #include #include "kis_lod_transform.h" #include KisGaussianBlurFilter::KisGaussianBlurFilter() : KisFilter(id(), FiltersCategoryBlurId, i18n("&Gaussian Blur...")) { setSupportsPainting(true); setSupportsAdjustmentLayers(true); setSupportsLevelOfDetail(true); setColorSpaceIndependence(FULLY_INDEPENDENT); } -KisConfigWidget * KisGaussianBlurFilter::createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP) const +KisConfigWidget * KisGaussianBlurFilter::createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP, bool usedForMasks) const { - return new KisWdgGaussianBlur(parent); + return new KisWdgGaussianBlur(usedForMasks, parent); } KisFilterConfigurationSP KisGaussianBlurFilter::factoryConfiguration() const { KisFilterConfigurationSP config = new KisFilterConfiguration(id().id(), 1); config->setProperty("horizRadius", 5); config->setProperty("vertRadius", 5); config->setProperty("lockAspect", true); return config; } void KisGaussianBlurFilter::processImpl(KisPaintDeviceSP device, const QRect& rect, const KisFilterConfigurationSP _config, KoUpdater* progressUpdater ) const { Q_ASSERT(device != 0); KisFilterConfigurationSP config = _config ? _config : new KisFilterConfiguration(id().id(), 1); KisLodTransformScalar t(device); QVariant value; config->getProperty("horizRadius", value); float horizontalRadius = t.scale(value.toFloat()); config->getProperty("vertRadius", value); float verticalRadius = t.scale(value.toFloat()); QBitArray channelFlags; if (config) { channelFlags = config->channelFlags(); } if (channelFlags.isEmpty() || !config) { channelFlags = QBitArray(device->colorSpace()->channelCount(), true); } KisGaussianKernel::applyGaussian(device, rect, horizontalRadius, verticalRadius, channelFlags, progressUpdater); } QRect KisGaussianBlurFilter::neededRect(const QRect & rect, const KisFilterConfigurationSP _config, int lod) const { KisLodTransformScalar t(lod); QVariant value; /** * NOTE: integer division by two is done on purpose, * because the kernel size is always odd */ const int halfWidth = _config->getProperty("horizRadius", value) ? KisGaussianKernel::kernelSizeFromRadius(t.scale(value.toFloat())) / 2 : 5; const int halfHeight = _config->getProperty("vertRadius", value) ? KisGaussianKernel::kernelSizeFromRadius(t.scale(value.toFloat())) / 2 : 5; return rect.adjusted(-halfWidth * 2, -halfHeight * 2, halfWidth * 2, halfHeight * 2); } QRect KisGaussianBlurFilter::changedRect(const QRect & rect, const KisFilterConfigurationSP _config, int lod) const { KisLodTransformScalar t(lod); QVariant value; const int halfWidth = _config->getProperty("horizRadius", value) ? KisGaussianKernel::kernelSizeFromRadius(t.scale(value.toFloat())) / 2 : 5; const int halfHeight = _config->getProperty("vertRadius", value) ? KisGaussianKernel::kernelSizeFromRadius(t.scale(value.toFloat())) / 2 : 5; return rect.adjusted( -halfWidth, -halfHeight, halfWidth, halfHeight); } + +bool KisGaussianBlurFilter::configurationAllowedForMask(KisFilterConfigurationSP config) const +{ + ENTER_FUNCTION() << config->getFloat("horizRadius", 5.0) << config->getFloat("vertRadius", 5.0); + + const float maxRadiusForMask = 100.0; + + return config->getFloat("horizRadius", 5.0) <= maxRadiusForMask && + config->getFloat("vertRadius", 5.0) <= maxRadiusForMask; +} + +void KisGaussianBlurFilter::fixLoadedFilterConfigurationForMasks(KisFilterConfigurationSP config) const +{ + ENTER_FUNCTION(); + + const float maxRadiusForMask = 100.0; + + if (config->getFloat("horizRadius", 5.0) > maxRadiusForMask) { + config->setProperty("horizRadius", maxRadiusForMask); + } + + if (config->getFloat("vertRadius", 5.0) > maxRadiusForMask) { + config->setProperty("vertRadius", maxRadiusForMask); + } +} diff --git a/plugins/filters/blur/kis_gaussian_blur_filter.h b/plugins/filters/blur/kis_gaussian_blur_filter.h index 770123f345..c7ec27f318 100644 --- a/plugins/filters/blur/kis_gaussian_blur_filter.h +++ b/plugins/filters/blur/kis_gaussian_blur_filter.h @@ -1,50 +1,53 @@ /* This file is part of Krita * * Copyright (c) 2009 Edward Apap * * 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-1301, USA. */ #ifndef KIS_GAUSSIAN_BLUR_FILTER_H #define KIS_GAUSSIAN_BLUR_FILTER_H #include "filter/kis_filter.h" #include "ui_wdg_gaussian_blur.h" #include class KisGaussianBlurFilter : public KisFilter { public: KisGaussianBlurFilter(); public: void processImpl(KisPaintDeviceSP device, const QRect& rect, const KisFilterConfigurationSP config, KoUpdater* progressUpdater ) const override; static inline KoID id() { return KoID("gaussian blur", i18n("Gaussian Blur")); } KisFilterConfigurationSP factoryConfiguration() const override; public: - KisConfigWidget * createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev) const override; + KisConfigWidget * createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev, bool useForMasks) const override; QRect neededRect(const QRect & rect, const KisFilterConfigurationSP _config, int lod) const override; QRect changedRect(const QRect & rect, const KisFilterConfigurationSP _config, int lod) const override; + + bool configurationAllowedForMask(KisFilterConfigurationSP config) const override; + void fixLoadedFilterConfigurationForMasks(KisFilterConfigurationSP config) const override; }; #endif diff --git a/plugins/filters/blur/kis_lens_blur_filter.cpp b/plugins/filters/blur/kis_lens_blur_filter.cpp index b7d7e6c4cf..dd786047ac 100644 --- a/plugins/filters/blur/kis_lens_blur_filter.cpp +++ b/plugins/filters/blur/kis_lens_blur_filter.cpp @@ -1,205 +1,205 @@ /* * This file is part of Krita * * Copyright (c) 2010 Edward Apap * * 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-1301, USA. */ #include "kis_lens_blur_filter.h" #include "kis_wdg_lens_blur.h" #include #include #include #include "ui_wdg_lens_blur.h" #include #include #include #include #include #include "kis_lod_transform.h" #include #include KisLensBlurFilter::KisLensBlurFilter() : KisFilter(id(), FiltersCategoryBlurId, i18n("&Lens Blur...")) { setSupportsPainting(true); setSupportsAdjustmentLayers(true); setSupportsLevelOfDetail(true); setColorSpaceIndependence(FULLY_INDEPENDENT); } -KisConfigWidget * KisLensBlurFilter::createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP) const +KisConfigWidget * KisLensBlurFilter::createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP, bool) const { return new KisWdgLensBlur(parent); } QSize KisLensBlurFilter::getKernelHalfSize(const KisFilterConfigurationSP config, int lod) { QPolygonF iris = getIrisPolygon(config, lod); QRect rect = iris.boundingRect().toAlignedRect(); int w = std::ceil(qreal(rect.width()) / 2.0); int h = std::ceil(qreal(rect.height()) / 2.0); return QSize(w, h); } KisFilterConfigurationSP KisLensBlurFilter::factoryConfiguration() const { KisFilterConfigurationSP config = new KisFilterConfiguration(id().id(), 1); config->setProperty("irisShape", "Pentagon (5)"); config->setProperty("irisRadius", 5); config->setProperty("irisRotation", 0); QSize halfSize = getKernelHalfSize(config, 0); config->setProperty("halfWidth", halfSize.width()); config->setProperty("halfHeight", halfSize.height()); return config; } QPolygonF KisLensBlurFilter::getIrisPolygon(const KisFilterConfigurationSP config, int lod) { KIS_ASSERT_RECOVER(config) { return QPolygonF(); } KisLodTransformScalar t(lod); QVariant value; config->getProperty("irisShape", value); QString irisShape = value.toString(); config->getProperty("irisRadius", value); uint irisRadius = t.scale(value.toUInt()); config->getProperty("irisRotation", value); uint irisRotation = value.toUInt(); if (irisRadius < 1) return QPolygon(); QPolygonF irisShapePoly; int sides = 1; qreal angle = 0; if (irisShape == "Triangle") sides = 3; else if (irisShape == "Quadrilateral (4)") sides = 4; else if (irisShape == "Pentagon (5)") sides = 5; else if (irisShape == "Hexagon (6)") sides = 6; else if (irisShape == "Heptagon (7)") sides = 7; else if (irisShape == "Octagon (8)") sides = 8; else return QPolygonF(); for (int i = 0; i < sides; ++i) { irisShapePoly << QPointF(0.5 * cos(angle), 0.5 * sin(angle)); angle += 2 * M_PI / sides; } QTransform transform; transform.rotate(irisRotation); transform.scale(irisRadius * 2, irisRadius * 2); QPolygonF transformedIris = transform.map(irisShapePoly); return transformedIris; } void KisLensBlurFilter::processImpl(KisPaintDeviceSP device, const QRect& rect, const KisFilterConfigurationSP _config, KoUpdater* progressUpdater ) const { QPoint srcTopLeft = rect.topLeft(); Q_ASSERT(device != 0); KisFilterConfigurationSP config = _config ? _config : new KisFilterConfiguration(id().id(), 1); QBitArray channelFlags; if (config) { channelFlags = config->channelFlags(); } if (channelFlags.isEmpty() || !config) { channelFlags = QBitArray(device->colorSpace()->channelCount(), true); } const int lod = device->defaultBounds()->currentLevelOfDetail(); QPolygonF transformedIris = getIrisPolygon(config, lod); if (transformedIris.isEmpty()) return; QRectF boundingRect = transformedIris.boundingRect(); int kernelWidth = boundingRect.toAlignedRect().width(); int kernelHeight = boundingRect.toAlignedRect().height(); QImage kernelRepresentation(kernelWidth, kernelHeight, QImage::Format_RGB32); kernelRepresentation.fill(0); QPainter imagePainter(&kernelRepresentation); imagePainter.setRenderHint(QPainter::Antialiasing); imagePainter.setBrush(QColor::fromRgb(255, 255, 255)); QTransform offsetTransform; offsetTransform.translate(-boundingRect.x(), -boundingRect.y()); imagePainter.setTransform(offsetTransform); imagePainter.drawPolygon(transformedIris, Qt::WindingFill); // construct kernel from image Eigen::Matrix irisKernel(kernelHeight, kernelWidth); for (int j = 0; j < kernelHeight; ++j) { for (int i = 0; i < kernelWidth; ++i) { irisKernel(j, i) = qRed(kernelRepresentation.pixel(i, j)); } } // apply convolution KisConvolutionPainter painter(device); painter.setChannelFlags(channelFlags); painter.setProgress(progressUpdater); KisConvolutionKernelSP kernel = KisConvolutionKernel::fromMatrix(irisKernel, 0, irisKernel.sum()); painter.applyMatrix(kernel, device, srcTopLeft, srcTopLeft, rect.size(), BORDER_REPEAT); } QRect KisLensBlurFilter::neededRect(const QRect & rect, const KisFilterConfigurationSP _config, int lod) const { KisLodTransformScalar t(lod); QVariant value; const int halfWidth = t.scale(_config->getProperty("halfWidth", value) ? value.toUInt() : 5); const int halfHeight = t.scale(_config->getProperty("halfHeight", value) ? value.toUInt() : 5); return rect.adjusted(-halfWidth * 2, -halfHeight * 2, halfWidth * 2, halfHeight * 2); } QRect KisLensBlurFilter::changedRect(const QRect & rect, const KisFilterConfigurationSP _config, int lod) const { KisLodTransformScalar t(lod); QVariant value; const int halfWidth = t.scale(_config->getProperty("halfWidth", value) ? value.toUInt() : 5); const int halfHeight = t.scale(_config->getProperty("halfHeight", value) ? value.toUInt() : 5); return rect.adjusted(-halfWidth, -halfHeight, halfWidth, halfHeight); } diff --git a/plugins/filters/blur/kis_lens_blur_filter.h b/plugins/filters/blur/kis_lens_blur_filter.h index f3d330b0bb..f072bf2ebe 100644 --- a/plugins/filters/blur/kis_lens_blur_filter.h +++ b/plugins/filters/blur/kis_lens_blur_filter.h @@ -1,59 +1,59 @@ /* * This file is part of Krita * * Copyright (c) 2010 Edward Apap * * 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-1301, USA. */ #ifndef KIS_LENS_BLUR_FILTER_H #define KIS_LENS_BLUR_FILTER_H #include "filter/kis_filter.h" #include "ui_wdg_lens_blur.h" #include class KisLensBlurFilter : public KisFilter { public: KisLensBlurFilter(); public: void processImpl(KisPaintDeviceSP src, const QRect& size, const KisFilterConfigurationSP config, KoUpdater* progressUpdater ) const override; static inline KoID id() { return KoID("lens blur", i18n("Lens Blur")); } KisFilterConfigurationSP factoryConfiguration() const override; static QSize getKernelHalfSize(const KisFilterConfigurationSP config, int lod); QRect neededRect(const QRect & rect, const KisFilterConfigurationSP _config, int lod) const override; QRect changedRect(const QRect & rect, const KisFilterConfigurationSP _config, int lod) const override; public: - KisConfigWidget * createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev) const override; + KisConfigWidget * createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev, bool useForMasks) const override; private: static QPolygonF getIrisPolygon(const KisFilterConfigurationSP config, int lod); }; #endif diff --git a/plugins/filters/blur/kis_motion_blur_filter.cpp b/plugins/filters/blur/kis_motion_blur_filter.cpp index fa09173036..ac8a1ed952 100644 --- a/plugins/filters/blur/kis_motion_blur_filter.cpp +++ b/plugins/filters/blur/kis_motion_blur_filter.cpp @@ -1,167 +1,167 @@ /* * This file is part of Krita * * Copyright (c) 2010 Edward Apap * * 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-1301, USA. */ #include "kis_motion_blur_filter.h" #include "kis_wdg_motion_blur.h" #include #include #include #include "ui_wdg_motion_blur.h" #include #include #include #include #include #include "kis_lod_transform.h" #include #include KisMotionBlurFilter::KisMotionBlurFilter() : KisFilter(id(), FiltersCategoryBlurId, i18n("&Motion Blur...")) { setSupportsPainting(true); setSupportsAdjustmentLayers(true); setSupportsLevelOfDetail(true); setColorSpaceIndependence(FULLY_INDEPENDENT); } -KisConfigWidget * KisMotionBlurFilter::createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP) const +KisConfigWidget * KisMotionBlurFilter::createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP, bool) const { return new KisWdgMotionBlur(parent); } KisFilterConfigurationSP KisMotionBlurFilter::factoryConfiguration() const { KisFilterConfigurationSP config = new KisFilterConfiguration(id().id(), 1); config->setProperty("blurAngle", 0); config->setProperty("blurLength", 5); return config; } void KisMotionBlurFilter::processImpl(KisPaintDeviceSP device, const QRect& rect, const KisFilterConfigurationSP _config, KoUpdater* progressUpdater ) const { QPoint srcTopLeft = rect.topLeft(); Q_ASSERT(device != 0); KisFilterConfigurationSP config = _config ? _config : new KisFilterConfiguration(id().id(), 1); QVariant value; config->getProperty("blurAngle", value); uint blurAngle = value.toUInt(); KisLodTransformScalar t(device); config->getProperty("blurLength", value); uint blurLength = t.scale(value.toUInt()); if (blurLength == 0) return; QBitArray channelFlags; if (config) { channelFlags = config->channelFlags(); } if (channelFlags.isEmpty() || !config) { channelFlags = QBitArray(device->colorSpace()->channelCount(), true); } // convert angle to radians qreal angleRadians = blurAngle / 360.0 * 2 * M_PI; // construct image qreal halfWidth = blurLength / 2.0 * cos(angleRadians); qreal halfHeight = blurLength / 2.0 * sin(angleRadians); int kernelWidth = ceil(fabs(halfWidth)) * 2; int kernelHeight = ceil(fabs(halfHeight)) * 2; // check for zero dimensions (vertical/horizontal motion vectors) kernelWidth = (kernelWidth == 0) ? 1 : kernelWidth; kernelHeight = (kernelHeight == 0) ? 1 : kernelHeight; QImage kernelRepresentation(kernelWidth, kernelHeight, QImage::Format_RGB32); kernelRepresentation.fill(0); QPainter imagePainter(&kernelRepresentation); imagePainter.setRenderHint(QPainter::Antialiasing); imagePainter.setPen(QPen(QColor::fromRgb(255, 255, 255), 1.0)); imagePainter.drawLine(QPointF(kernelWidth / 2 - halfWidth, kernelHeight / 2 + halfHeight), QPointF(kernelWidth / 2 + halfWidth, kernelHeight / 2 - halfHeight)); // construct kernel from image Eigen::Matrix motionBlurKernel(kernelHeight, kernelWidth); for (int j = 0; j < kernelHeight; ++j) { for (int i = 0; i < kernelWidth; ++i) { motionBlurKernel(j, i) = qRed(kernelRepresentation.pixel(i, j)); } } // apply convolution KisConvolutionPainter painter(device); painter.setChannelFlags(channelFlags); painter.setProgress(progressUpdater); KisConvolutionKernelSP kernel = KisConvolutionKernel::fromMatrix(motionBlurKernel, 0, motionBlurKernel.sum()); painter.applyMatrix(kernel, device, srcTopLeft, srcTopLeft, rect.size(), BORDER_REPEAT); } QRect KisMotionBlurFilter::neededRect(const QRect & rect, const KisFilterConfigurationSP _config, int lod) const { KisLodTransformScalar t(lod); QVariant value; uint blurAngle = _config->getProperty("blurAngle", value) ? value.toUInt() : 0; uint blurLength = t.scale(_config->getProperty("blurLength", value) ? value.toUInt() : 5); qreal angleRadians = blurAngle / 360.0 * 2 * M_PI; const int halfWidth = ceil(fabs(blurLength / 2.0 * cos(angleRadians))); const int halfHeight = ceil(fabs(blurLength / 2.0 * cos(angleRadians))); return rect.adjusted(-halfWidth * 2, -halfHeight * 2, halfWidth * 2, halfHeight * 2); } QRect KisMotionBlurFilter::changedRect(const QRect & rect, const KisFilterConfigurationSP _config, int lod) const { KisLodTransformScalar t(lod); QVariant value; uint blurAngle = _config->getProperty("blurAngle", value) ? value.toUInt() : 0; uint blurLength = t.scale(_config->getProperty("blurLength", value) ? value.toUInt() : 5); qreal angleRadians = blurAngle / 360.0 * 2 * M_PI; const int halfWidth = ceil(fabs(blurLength * cos(angleRadians))); const int halfHeight = ceil(fabs(blurLength * cos(angleRadians))); return rect.adjusted(-halfWidth * 2, -halfHeight * 2, halfWidth * 2, halfHeight * 2); } diff --git a/plugins/filters/blur/kis_motion_blur_filter.h b/plugins/filters/blur/kis_motion_blur_filter.h index ce6c878d72..d455d50c4f 100644 --- a/plugins/filters/blur/kis_motion_blur_filter.h +++ b/plugins/filters/blur/kis_motion_blur_filter.h @@ -1,52 +1,52 @@ /* * This file is part of Krita * * Copyright (c) 2010 Edward Apap * * 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-1301, USA. */ #ifndef KIS_MOTION_BLUR_FILTER_H #define KIS_MOTION_BLUR_FILTER_H #include "filter/kis_filter.h" #include "ui_wdg_motion_blur.h" #include class KisMotionBlurFilter : public KisFilter { public: KisMotionBlurFilter(); public: void processImpl(KisPaintDeviceSP src, const QRect& size, const KisFilterConfigurationSP config, KoUpdater* progressUpdater ) const override; static inline KoID id() { return KoID("motion blur", i18n("Motion Blur")); } KisFilterConfigurationSP factoryConfiguration() const override; public: - KisConfigWidget * createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev) const override; + KisConfigWidget * createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev, bool useForMasks) const override; QRect neededRect(const QRect & rect, const KisFilterConfigurationSP _config, int lod) const override; QRect changedRect(const QRect & rect, const KisFilterConfigurationSP _config, int lod) const override; }; #endif diff --git a/plugins/filters/blur/kis_wdg_gaussian_blur.cpp b/plugins/filters/blur/kis_wdg_gaussian_blur.cpp index 2b106f8b52..99ed865e38 100644 --- a/plugins/filters/blur/kis_wdg_gaussian_blur.cpp +++ b/plugins/filters/blur/kis_wdg_gaussian_blur.cpp @@ -1,121 +1,123 @@ /* * This file is part of Krita * * Copyright (c) 2009 Edward Apap * * 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-1301, USA. */ #include "kis_wdg_gaussian_blur.h" #include #include #include #include #include #include #include #include #include "ui_wdg_gaussian_blur.h" -KisWdgGaussianBlur::KisWdgGaussianBlur(QWidget * parent) : KisConfigWidget(parent) +KisWdgGaussianBlur::KisWdgGaussianBlur(bool usedForMasks, QWidget * parent) : KisConfigWidget(parent) { m_widget = new Ui_WdgGaussianBlur(); m_widget->setupUi(this); m_widget->aspectButton->setKeepAspectRatio(false); - m_widget->horizontalRadius->setRange(0.0, 1000.0, 2); + const qreal maxRadius = usedForMasks ? 100.0 : 1000.0; + + m_widget->horizontalRadius->setRange(0.0, maxRadius, 2); m_widget->horizontalRadius->setSingleStep(0.2); m_widget->horizontalRadius->setValue(0.5); m_widget->horizontalRadius->setExponentRatio(3.0); m_widget->horizontalRadius->setSuffix(i18n(" px")); connect(m_widget->horizontalRadius, SIGNAL(valueChanged(qreal)), this, SLOT(horizontalRadiusChanged(qreal))); - m_widget->verticalRadius->setRange(0.0, 1000.0, 2); + m_widget->verticalRadius->setRange(0.0, maxRadius, 2); m_widget->verticalRadius->setSingleStep(0.2); m_widget->verticalRadius->setValue(0.5); m_widget->verticalRadius->setExponentRatio(3.0); m_widget->verticalRadius->setSuffix(i18n(" px")); connect(m_widget->verticalRadius, SIGNAL(valueChanged(qreal)), this, SLOT(verticalRadiusChanged(qreal))); connect(m_widget->aspectButton, SIGNAL(keepAspectRatioChanged(bool)), this, SLOT(aspectLockChanged(bool))); connect(m_widget->horizontalRadius, SIGNAL(valueChanged(qreal)), SIGNAL(sigConfigurationItemChanged())); connect(m_widget->verticalRadius, SIGNAL(valueChanged(qreal)), SIGNAL(sigConfigurationItemChanged())); } KisWdgGaussianBlur::~KisWdgGaussianBlur() { delete m_widget; } KisPropertiesConfigurationSP KisWdgGaussianBlur::configuration() const { KisFilterConfigurationSP config = new KisFilterConfiguration("gaussian blur", 1); config->setProperty("horizRadius", m_widget->horizontalRadius->value()); config->setProperty("vertRadius", m_widget->verticalRadius->value()); config->setProperty("lockAspect", m_widget->aspectButton->keepAspectRatio()); return config; } void KisWdgGaussianBlur::setConfiguration(const KisPropertiesConfigurationSP config) { QVariant value; if (config->getProperty("horizRadius", value)) { m_widget->horizontalRadius->setValue(value.toFloat()); } if (config->getProperty("vertRadius", value)) { m_widget->verticalRadius->setValue(value.toFloat()); } if (config->getProperty("lockAspect", value)) { m_widget->aspectButton->setKeepAspectRatio(value.toBool()); } } void KisWdgGaussianBlur::horizontalRadiusChanged(qreal v) { m_widget->horizontalRadius->blockSignals(true); m_widget->horizontalRadius->setValue(v); m_widget->horizontalRadius->blockSignals(false); if (m_widget->aspectButton->keepAspectRatio()) { m_widget->verticalRadius->blockSignals(true); m_widget->verticalRadius->setValue(v); m_widget->verticalRadius->blockSignals(false); } } void KisWdgGaussianBlur::verticalRadiusChanged(qreal v) { m_widget->verticalRadius->blockSignals(true); m_widget->verticalRadius->setValue(v); m_widget->verticalRadius->blockSignals(false); if (m_widget->aspectButton->keepAspectRatio()) { m_widget->horizontalRadius->blockSignals(true); m_widget->horizontalRadius->setValue(v); m_widget->horizontalRadius->blockSignals(false); } } void KisWdgGaussianBlur::aspectLockChanged(bool v) { if (v) { m_widget->verticalRadius->setValue( m_widget->horizontalRadius->value() ); } } diff --git a/plugins/filters/blur/kis_wdg_gaussian_blur.h b/plugins/filters/blur/kis_wdg_gaussian_blur.h index de4d0be4ee..185775b851 100644 --- a/plugins/filters/blur/kis_wdg_gaussian_blur.h +++ b/plugins/filters/blur/kis_wdg_gaussian_blur.h @@ -1,49 +1,49 @@ /* * This file is part of Krita * * Copyright (c) 2009 Edward Apap * * 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-1301, USA. */ #ifndef _KIS_WDG_GAUSSIAN_BLUR_H_ #define _KIS_WDG_GAUSSIAN_BLUR_H_ #include class Ui_WdgGaussianBlur; class KisWdgGaussianBlur : public KisConfigWidget { Q_OBJECT public: - KisWdgGaussianBlur(QWidget * parent); + KisWdgGaussianBlur(bool useForMasks, QWidget * parent); ~KisWdgGaussianBlur() override; inline const Ui_WdgGaussianBlur* widget() const { return m_widget; } void setConfiguration(const KisPropertiesConfigurationSP) override; KisPropertiesConfigurationSP configuration() const override; private Q_SLOTS: void horizontalRadiusChanged(qreal); void verticalRadiusChanged(qreal); void aspectLockChanged(bool); private: Ui_WdgGaussianBlur* m_widget; }; #endif diff --git a/plugins/filters/colors/kis_color_to_alpha.cpp b/plugins/filters/colors/kis_color_to_alpha.cpp index b5fdafe079..b6d8b12b34 100644 --- a/plugins/filters/colors/kis_color_to_alpha.cpp +++ b/plugins/filters/colors/kis_color_to_alpha.cpp @@ -1,189 +1,189 @@ /* * This file is part of Krita * * Copyright (c) 2006 Cyrille Berger * * 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-1301, USA. */ #include "kis_color_to_alpha.h" #include #include #include #include #include #include "kis_progress_update_helper.h" #include #include #include #include #include #include "ui_wdgcolortoalphabase.h" #include "kis_wdg_color_to_alpha.h" #include #include KisFilterColorToAlpha::KisFilterColorToAlpha() : KisFilter(id(), FiltersCategoryColorId, i18n("&Color to Alpha...")) { setSupportsPainting(true); setSupportsAdjustmentLayers(true); setSupportsLevelOfDetail(true); setColorSpaceIndependence(FULLY_INDEPENDENT); } -KisConfigWidget * KisFilterColorToAlpha::createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP) const +KisConfigWidget * KisFilterColorToAlpha::createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP, bool) const { return new KisWdgColorToAlpha(parent); } KisFilterConfigurationSP KisFilterColorToAlpha::factoryConfiguration() const { KisFilterConfigurationSP config = new KisFilterConfiguration("colortoalpha", 1); config->setProperty("targetcolor", QColor(255, 255, 255)); config->setProperty("threshold", 100); return config; } template inline void inverseOver(const int numChannels, const int *channelIndex, channel_type *dst, const channel_type *baseColor, qreal dstOpacity) { for (int i = 0; i < numChannels; i++) { const int idx = channelIndex[i]; dst[idx] = KoColorSpaceMaths::clamp( (static_cast(dst[idx]) - baseColor[idx]) / dstOpacity + baseColor[idx]); } } template void applyToIterator(const int numChannels, const int *channelIndex, KisSequentialIteratorProgress &it, KoColor baseColor, int threshold, const KoColorSpace *cs) { qreal thresholdF = threshold; quint8 *baseColorData_uint8 = baseColor.data(); channel_type *baseColorData = reinterpret_cast(baseColorData_uint8); while (it.nextPixel()) { channel_type *dst = reinterpret_cast(it.rawData()); quint8 *dst_uint8 = it.rawData(); quint8 diff = cs->difference(baseColorData_uint8, dst_uint8); qreal newOpacity = diff >= threshold ? 1.0 : diff / thresholdF; if(newOpacity < cs->opacityF(dst_uint8)) { cs->setOpacity(dst_uint8, newOpacity, 1); } inverseOver(numChannels, channelIndex, dst, baseColorData, newOpacity); } } void KisFilterColorToAlpha::processImpl(KisPaintDeviceSP device, const QRect& rect, const KisFilterConfigurationSP _config, KoUpdater* progressUpdater ) const { Q_ASSERT(device != 0); KisFilterConfigurationSP config = _config ? _config : new KisFilterConfiguration("colortoalpha", 1); QVariant value; QColor cTA = (config->getProperty("targetcolor", value)) ? value.value() : QColor(255, 255, 255); int threshold = (config->getProperty("threshold", value)) ? value.toInt() : 1; const KoColorSpace * cs = device->colorSpace(); KisSequentialIteratorProgress it(device, rect, progressUpdater); KoColor baseColor(cTA, cs); QVector channelIndex; KoChannelInfo::enumChannelValueType valueType = KoChannelInfo::OTHER; QList channels = cs->channels(); for (int i = 0; i < channels.size(); i++) { const KoChannelInfo *info = channels[i]; if (info->channelType() != KoChannelInfo::COLOR) continue; KoChannelInfo::enumChannelValueType currentValueType = info->channelValueType(); if (valueType != KoChannelInfo::OTHER && valueType != currentValueType) { warnKrita << "Cannot apply a Color-to-Alpha filter to a heterogeneous colorspace"; return; } else { valueType = currentValueType; } channelIndex.append(i); } switch (valueType) { case KoChannelInfo::UINT8: applyToIterator(channelIndex.size(), channelIndex.data(), it, baseColor, threshold, cs); break; case KoChannelInfo::UINT16: applyToIterator(channelIndex.size(), channelIndex.data(), it, baseColor, threshold, cs); break; case KoChannelInfo::UINT32: applyToIterator(channelIndex.size(), channelIndex.data(), it, baseColor, threshold, cs); break; case KoChannelInfo::FLOAT32: applyToIterator(channelIndex.size(), channelIndex.data(), it, baseColor, threshold, cs); break; case KoChannelInfo::FLOAT64: applyToIterator(channelIndex.size(), channelIndex.data(), it, baseColor, threshold, cs); break; case KoChannelInfo::FLOAT16: #ifdef HAVE_OPENEXR #include applyToIterator(channelIndex.size(), channelIndex.data(), it, baseColor, threshold, cs); break; #endif case KoChannelInfo::INT8: /* !UNSUPPORTED! */ case KoChannelInfo::INT16: /* !UNSUPPORTED! */ case KoChannelInfo::OTHER: warnKrita << "Color To Alpha: Unsupported channel type:" << valueType; } } diff --git a/plugins/filters/colors/kis_color_to_alpha.h b/plugins/filters/colors/kis_color_to_alpha.h index c0048bd1d8..b313069669 100644 --- a/plugins/filters/colors/kis_color_to_alpha.h +++ b/plugins/filters/colors/kis_color_to_alpha.h @@ -1,49 +1,49 @@ /* * This file is part of Krita * * Copyright (c) 2006 Cyrille Berger * * 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-1301, USA. */ #ifndef KIS_COLOR_TO_ALPHA_H_ #define KIS_COLOR_TO_ALPHA_H_ #include "filter/kis_filter.h" class KisFilterColorToAlpha : public KisFilter { public: KisFilterColorToAlpha(); void processImpl(KisPaintDeviceSP device, const QRect& rect, const KisFilterConfigurationSP config, KoUpdater* progressUpdater ) const override; static inline KoID id() { return KoID("colortoalpha", i18n("Color to Alpha")); } public: - KisConfigWidget * createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev) const override; + KisConfigWidget * createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev, bool useForMasks) const override; KisFilterConfigurationSP factoryConfiguration() const override; }; #endif diff --git a/plugins/filters/colorsfilters/kis_color_balance_filter.cpp b/plugins/filters/colorsfilters/kis_color_balance_filter.cpp index e8ec5bbb3d..6a999bf2d9 100644 --- a/plugins/filters/colorsfilters/kis_color_balance_filter.cpp +++ b/plugins/filters/colorsfilters/kis_color_balance_filter.cpp @@ -1,206 +1,206 @@ /* * Copyright (c) 2013 Sahil Nagpal * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "kis_color_balance_filter.h" #include #include "filter/kis_color_transformation_configuration.h" #include "kis_selection.h" #include "kis_paint_device.h" #include "kis_processing_information.h" KisColorBalanceFilter::KisColorBalanceFilter() : KisColorTransformationFilter(id(), FiltersCategoryAdjustId, i18n("&Color Balance...")) { setShortcut(QKeySequence(Qt::CTRL + Qt::Key_B)); setSupportsPainting(true); } -KisConfigWidget * KisColorBalanceFilter::createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev) const +KisConfigWidget * KisColorBalanceFilter::createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev, bool) const { Q_UNUSED(dev); return new KisColorBalanceConfigWidget(parent); } KoColorTransformation * KisColorBalanceFilter::createTransformation(const KoColorSpace* cs, const KisFilterConfigurationSP config) const { QHash params; if (config) { params["cyan_red_midtones"] = config->getInt("cyan_red_midtones", 0) * 0.01; params["magenta_green_midtones"] = config->getInt("magenta_green_midtones", 0) * 0.01; params["yellow_blue_midtones"] = config->getInt("yellow_blue_midtones", 0) * 0.01; params["cyan_red_shadows"] = config->getInt("cyan_red_shadows", 0) * 0.01; params["magenta_green_shadows"] = config->getInt("magenta_green_shadows", 0) * 0.01; params["yellow_blue_shadows"] = config->getInt("yellow_blue_shadows", 0) * 0.01; params["cyan_red_highlights"] = config->getInt("cyan_red_highlights", 0) * 0.01; params["magenta_green_highlights"] = config->getInt("magenta_green_highlights", 0) * 0.01; params["yellow_blue_highlights"] = config->getInt("yellow_blue_highlights", 0) * 0.01; params["preserve_luminosity"] = config->getBool("preserve_luminosity", true); } return cs->createColorTransformation("ColorBalance" , params); } KisFilterConfigurationSP KisColorBalanceFilter::factoryConfiguration() const { KisColorTransformationConfigurationSP config = new KisColorTransformationConfiguration(id().id(), 0); config->setProperty("cyan_red_midtones", 0); config->setProperty("yellow_green_midtones", 0); config->setProperty("magenta_blue_midtones", 0); config->setProperty("cyan_red_shadows", 0); config->setProperty("yellow_green_shadows", 0); config->setProperty("magenta_blue_shadows", 0); config->setProperty("cyan_red_highlights", 0); config->setProperty("yellow_green_highlights", 0); config->setProperty("magenta_blue_highlights", 0); config->setProperty("preserve_luminosity", true); return config; } KisColorBalanceConfigWidget::KisColorBalanceConfigWidget(QWidget* parent) : KisConfigWidget(parent) { m_page = new Ui_Form(); m_page->setupUi(this); m_page->cyanRedShadowsSlider->setMaximum(100); m_page->cyanRedShadowsSlider->setMinimum(-100); m_page->yellowBlueShadowsSlider->setMaximum(100); m_page->yellowBlueShadowsSlider->setMinimum(-100); m_page->magentaGreenShadowsSlider->setMaximum(100); m_page->magentaGreenShadowsSlider->setMinimum(-100); m_page->cyanRedMidtonesSlider->setMaximum(100); m_page->cyanRedMidtonesSlider->setMinimum(-100); m_page->yellowBlueMidtonesSlider->setMaximum(100); m_page->yellowBlueMidtonesSlider->setMinimum(-100); m_page->magentaGreenMidtonesSlider->setMaximum(100); m_page->magentaGreenMidtonesSlider->setMinimum(-100); m_page->cyanRedHighlightsSlider->setMaximum(100); m_page->cyanRedHighlightsSlider->setMinimum(-100); m_page->yellowBlueHighlightsSlider->setMaximum(100); m_page->yellowBlueHighlightsSlider->setMinimum(-100); m_page->magentaGreenHighlightsSlider->setMaximum(100); m_page->magentaGreenHighlightsSlider->setMinimum(-100); connect(m_page->cyanRedShadowsSlider, SIGNAL(valueChanged(int)), SIGNAL(sigConfigurationItemChanged())); connect(m_page->magentaGreenShadowsSlider, SIGNAL(valueChanged(int)), SIGNAL(sigConfigurationItemChanged())); connect(m_page->yellowBlueShadowsSlider, SIGNAL(valueChanged(int)), SIGNAL(sigConfigurationItemChanged())); connect(m_page->cyanRedMidtonesSlider, SIGNAL(valueChanged(int)), SIGNAL(sigConfigurationItemChanged())); connect(m_page->magentaGreenMidtonesSlider, SIGNAL(valueChanged(int)), SIGNAL(sigConfigurationItemChanged())); connect(m_page->yellowBlueMidtonesSlider, SIGNAL(valueChanged(int)), SIGNAL(sigConfigurationItemChanged())); connect(m_page->cyanRedHighlightsSlider, SIGNAL(valueChanged(int)), SIGNAL(sigConfigurationItemChanged())); connect(m_page->magentaGreenHighlightsSlider, SIGNAL(valueChanged(int)), SIGNAL(sigConfigurationItemChanged())); connect(m_page->yellowBlueHighlightsSlider, SIGNAL(valueChanged(int)), SIGNAL(sigConfigurationItemChanged())); connect(m_page->chkPreserveLuminosity, SIGNAL(toggled(bool)), SIGNAL(sigConfigurationItemChanged())); connect(m_page->pushResetShadows, SIGNAL(clicked()), SLOT(slotShadowsClear())); connect(m_page->pushResetMidtones, SIGNAL(clicked()), SLOT(slotMidtonesClear())); connect(m_page->pushResetHighlights, SIGNAL(clicked()), SLOT(slotHighlightsClear())); m_page->cyanRedShadowsSpinbox->setMaximum(100); m_page->cyanRedShadowsSpinbox->setMinimum(-100); m_page->yellowBlueShadowsSpinbox->setMaximum(100); m_page->yellowBlueShadowsSpinbox->setMinimum(-100); m_page->magentaGreenShadowsSpinbox->setMaximum(100); m_page->magentaGreenShadowsSpinbox->setMinimum(-100); m_page->cyanRedMidtonesSpinbox->setMaximum(100); m_page->cyanRedMidtonesSpinbox->setMinimum(-100); m_page->yellowBlueMidtonesSpinbox->setMaximum(100); m_page->yellowBlueMidtonesSpinbox->setMinimum(-100); m_page->magentaGreenMidtonesSpinbox->setMaximum(100); m_page->magentaGreenMidtonesSpinbox->setMinimum(-100); m_page->cyanRedHighlightsSpinbox->setMaximum(100); m_page->cyanRedHighlightsSpinbox->setMinimum(-100); m_page->yellowBlueHighlightsSpinbox->setMaximum(100); m_page->yellowBlueHighlightsSpinbox->setMinimum(-100); m_page->magentaGreenHighlightsSpinbox->setMaximum(100); m_page->magentaGreenHighlightsSpinbox->setMinimum(-100); } KisColorBalanceConfigWidget::~KisColorBalanceConfigWidget() { delete m_page; } KisPropertiesConfigurationSP KisColorBalanceConfigWidget::configuration() const { KisColorTransformationConfigurationSP c = new KisColorTransformationConfiguration(KisColorBalanceFilter::id().id(), 0); c->setProperty("cyan_red_shadows", m_page->cyanRedShadowsSlider->value()); c->setProperty("magenta_green_shadows", m_page->magentaGreenShadowsSlider->value()); c->setProperty("yellow_blue_shadows", m_page->yellowBlueShadowsSlider->value()); c->setProperty("cyan_red_midtones", m_page->cyanRedMidtonesSlider->value()); c->setProperty("magenta_green_midtones", m_page->magentaGreenMidtonesSlider->value()); c->setProperty("yellow_blue_midtones", m_page->yellowBlueMidtonesSlider->value()); c->setProperty("cyan_red_highlights", m_page->cyanRedHighlightsSlider->value()); c->setProperty("magenta_green_highlights", m_page->magentaGreenHighlightsSlider->value()); c->setProperty("yellow_blue_highlights", m_page->yellowBlueHighlightsSlider->value()); c->setProperty("preserve_luminosity", m_page->chkPreserveLuminosity->isChecked()); return c; } void KisColorBalanceConfigWidget::setConfiguration(const KisPropertiesConfigurationSP config) { m_page->cyanRedMidtonesSlider->setValue( config->getDouble("cyan_red_midtones", 0)); m_page->magentaGreenMidtonesSlider->setValue( config->getDouble("magenta_green_midtones", 0)); m_page->yellowBlueMidtonesSlider->setValue( config->getDouble("yellow_blue_midtones", 0)); m_page->cyanRedShadowsSlider->setValue( config->getDouble("cyan_red_shadows", 0)); m_page->magentaGreenShadowsSlider->setValue( config->getDouble("magenta_green_shadows", 0)); m_page->yellowBlueShadowsSlider->setValue( config->getDouble("yellow_blue_shadows", 0)); m_page->cyanRedHighlightsSlider->setValue( config->getDouble("cyan_red_highlights", 0)); m_page->magentaGreenHighlightsSlider->setValue( config->getDouble("magenta_green_highlights", 0)); m_page->yellowBlueHighlightsSlider->setValue( config->getDouble("yellow_blue_highlights", 0)); m_page->chkPreserveLuminosity->setChecked(config->getBool("preserve_luminosity", true)); } void KisColorBalanceConfigWidget::slotMidtonesClear() { m_page->cyanRedMidtonesSlider->setValue(0); m_page->magentaGreenMidtonesSlider->setValue(0); m_page->yellowBlueMidtonesSlider->setValue(0); } void KisColorBalanceConfigWidget::slotHighlightsClear() { m_page->cyanRedHighlightsSlider->setValue(0); m_page->magentaGreenHighlightsSlider->setValue(0); m_page->yellowBlueHighlightsSlider->setValue(0); } void KisColorBalanceConfigWidget::slotShadowsClear() { m_page->cyanRedShadowsSlider->setValue(0); m_page->magentaGreenShadowsSlider->setValue(0); m_page->yellowBlueShadowsSlider->setValue(0); } diff --git a/plugins/filters/colorsfilters/kis_color_balance_filter.h b/plugins/filters/colorsfilters/kis_color_balance_filter.h index 57ff681f3c..21474cd5fb 100644 --- a/plugins/filters/colorsfilters/kis_color_balance_filter.h +++ b/plugins/filters/colorsfilters/kis_color_balance_filter.h @@ -1,80 +1,80 @@ /* * Copyright (c) 2013 Sahil Nagpal * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef _KIS_COLOR_BALANCE_FILTER_H_ #define _KIS_COLOR_BALANCE_FILTER_H_ #include #include "filter/kis_filter.h" #include "kis_config_widget.h" #include "ui_wdg_color_balance.h" #include "filter/kis_color_transformation_filter.h" class QWidget; class KoColorTransformation; class KisColorBalanceFilter : public KisColorTransformationFilter { public: KisColorBalanceFilter(); public: enum Type { SHADOWS, MIDTONES, HIGHLIGHTS }; public: - KisConfigWidget * createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev) const override; + KisConfigWidget * createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev, bool useForMasks) const override; KoColorTransformation* createTransformation(const KoColorSpace* cs, const KisFilterConfigurationSP config) const override; static inline KoID id() { return KoID("colorbalance", i18n("Color Balance")); } KisFilterConfigurationSP factoryConfiguration() const override; }; class KisColorBalanceConfigWidget : public KisConfigWidget { Q_OBJECT public: KisColorBalanceConfigWidget(QWidget * parent); ~KisColorBalanceConfigWidget() override; KisPropertiesConfigurationSP configuration() const override; void setConfiguration(const KisPropertiesConfigurationSP config) override; Ui_Form * m_page; QString m_id; public Q_SLOTS: void slotShadowsClear(); void slotMidtonesClear(); void slotHighlightsClear(); }; #endif diff --git a/plugins/filters/colorsfilters/kis_cross_channel_filter.cpp b/plugins/filters/colorsfilters/kis_cross_channel_filter.cpp index 510eaef5cb..db93504a3c 100644 --- a/plugins/filters/colorsfilters/kis_cross_channel_filter.cpp +++ b/plugins/filters/colorsfilters/kis_cross_channel_filter.cpp @@ -1,293 +1,293 @@ /* * This file is part of Krita * * Copyright (c) 2018 Jouni Pentikainen * * 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-1301, USA. */ #include "kis_cross_channel_filter.h" #include #include #include #include #include #include #include #include #include "KoChannelInfo.h" #include "KoBasicHistogramProducers.h" #include "KoColorModelStandardIds.h" #include "KoColorSpace.h" #include "KoColorTransformation.h" #include "KoCompositeColorTransformation.h" #include "KoCompositeOp.h" #include "KoID.h" #include "kis_signals_blocker.h" #include "kis_bookmarked_configuration_manager.h" #include "kis_config_widget.h" #include #include #include #include #include #include "kis_histogram.h" #include "kis_painter.h" #include "widgets/kis_curve_widget.h" #include "../../color/colorspaceextensions/kis_hsv_adjustment.h" // KisCrossChannelFilterConfiguration KisCrossChannelFilterConfiguration::KisCrossChannelFilterConfiguration(int channelCount, const KoColorSpace *cs) : KisMultiChannelFilterConfiguration(channelCount, "crosschannel", 1) { init(); int defaultDriver = 0; if (cs) { QVector virtualChannels = KisMultiChannelFilter::getVirtualChannels(cs); defaultDriver = qMax(0, KisMultiChannelFilter::findChannel(virtualChannels, VirtualChannelInfo::LIGHTNESS)); } m_driverChannels.fill(defaultDriver, channelCount); } KisCrossChannelFilterConfiguration::~KisCrossChannelFilterConfiguration() {} const QVector KisCrossChannelFilterConfiguration::driverChannels() const { return m_driverChannels; } void KisCrossChannelFilterConfiguration::setDriverChannels(QVector driverChannels) { KIS_SAFE_ASSERT_RECOVER_RETURN(driverChannels.size() == m_curves.size()); m_driverChannels = driverChannels; } void KisCrossChannelFilterConfiguration::fromXML(const QDomElement& root) { KisMultiChannelFilterConfiguration::fromXML(root); m_driverChannels.resize(m_curves.size()); QRegExp rx("driver(\\d+)"); for (QDomElement e = root.firstChildElement(); !e.isNull(); e = e.nextSiblingElement()) { const QString attributeName = e.attribute("name"); if (rx.exactMatch(attributeName)) { int channel = rx.cap(1).toUShort(); int driver = KisDomUtils::toInt(e.text()); if (0 <= channel && channel < m_driverChannels.size()) { m_driverChannels[channel] = driver; } } } } void KisCrossChannelFilterConfiguration::toXML(QDomDocument& doc, QDomElement& root) const { KisMultiChannelFilterConfiguration::toXML(doc, root); for (int i = 0; i < m_driverChannels.size(); i++) { QDomElement param = doc.createElement("param"); param.setAttribute("name", QString("driver%1").arg(i)); QDomText text = doc.createTextNode(KisDomUtils::toString(m_driverChannels[i])); param.appendChild(text); root.appendChild(param); } } KisCubicCurve KisCrossChannelFilterConfiguration::getDefaultCurve() { const QList points { QPointF(0.0f, 0.5f), QPointF(1.0f, 0.5f) }; return KisCubicCurve(points); } KisCrossChannelConfigWidget::KisCrossChannelConfigWidget(QWidget * parent, KisPaintDeviceSP dev, Qt::WindowFlags f) : KisMultiChannelConfigWidget(parent, dev, f) { const int virtualChannelCount = m_virtualChannels.size(); m_driverChannels.resize(virtualChannelCount); init(); for (int i = 0; i < virtualChannelCount; i++) { const VirtualChannelInfo &info = m_virtualChannels[i]; if (info.type() == VirtualChannelInfo::ALL_COLORS) { continue; } m_page->cmbDriverChannel->addItem(info.name(), i); } connect(m_page->cmbDriverChannel, SIGNAL(activated(int)), this, SLOT(slotDriverChannelSelected(int))); } // KisCrossChannelConfigWidget KisCrossChannelConfigWidget::~KisCrossChannelConfigWidget() {} void KisCrossChannelConfigWidget::setConfiguration(const KisPropertiesConfigurationSP config) { const auto *cfg = dynamic_cast(config.data()); m_driverChannels = cfg->driverChannels(); KisMultiChannelConfigWidget::setConfiguration(config); // Show the first channel with a curve, or saturation by default int initialChannel = -1; for (int i = 0; i < m_virtualChannels.size(); i++) { if (!m_curves[i].isConstant(0.5)) { initialChannel = i; break; } } if (initialChannel < 0) { initialChannel = qMax(0, KisMultiChannelFilter::findChannel(m_virtualChannels, VirtualChannelInfo::SATURATION)); } setActiveChannel(initialChannel); } KisPropertiesConfigurationSP KisCrossChannelConfigWidget::configuration() const { auto *cfg = new KisCrossChannelFilterConfiguration(m_virtualChannels.count(), m_dev->colorSpace()); KisPropertiesConfigurationSP cfgSP = cfg; m_curves[m_activeVChannel] = m_page->curveWidget->curve(); cfg->setCurves(m_curves); cfg->setDriverChannels(m_driverChannels); return cfgSP; } void KisCrossChannelConfigWidget::updateChannelControls() { m_page->curveWidget->setupInOutControls(m_page->intIn, m_page->intOut, 0, 100, -100, 100); const int index = m_page->cmbDriverChannel->findData(m_driverChannels[m_activeVChannel]); m_page->cmbDriverChannel->setCurrentIndex(index); } KisPropertiesConfigurationSP KisCrossChannelConfigWidget::getDefaultConfiguration() { return new KisCrossChannelFilterConfiguration(m_virtualChannels.size(), m_dev->colorSpace()); } void KisCrossChannelConfigWidget::slotDriverChannelSelected(int index) { const int channel = m_page->cmbDriverChannel->itemData(index).toInt(); KIS_SAFE_ASSERT_RECOVER_RETURN(0 <= channel && channel < m_virtualChannels.size()); m_driverChannels[m_activeVChannel] = channel; updateChannelControls(); } // KisCrossChannelFilter KisCrossChannelFilter::KisCrossChannelFilter() : KisMultiChannelFilter(id(), i18n("&Cross-channel adjustment curves...")) {} KisCrossChannelFilter::~KisCrossChannelFilter() {} -KisConfigWidget * KisCrossChannelFilter::createConfigurationWidget(QWidget *parent, const KisPaintDeviceSP dev) const +KisConfigWidget * KisCrossChannelFilter::createConfigurationWidget(QWidget *parent, const KisPaintDeviceSP dev, bool) const { return new KisCrossChannelConfigWidget(parent, dev); } KisFilterConfigurationSP KisCrossChannelFilter::factoryConfiguration() const { return new KisCrossChannelFilterConfiguration(0, nullptr); } int mapChannel(const VirtualChannelInfo &channel) { switch (channel.type()) { case VirtualChannelInfo::REAL: { int pixelIndex = channel.pixelIndex(); KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(0 <= pixelIndex && pixelIndex < 4, 0); return pixelIndex; } case VirtualChannelInfo::ALL_COLORS: return KisHSVCurve::AllColors; case VirtualChannelInfo::HUE: return KisHSVCurve::Hue; case VirtualChannelInfo::SATURATION: return KisHSVCurve::Saturation; case VirtualChannelInfo::LIGHTNESS: return KisHSVCurve::Value; }; KIS_SAFE_ASSERT_RECOVER_NOOP(false); return 0; } KoColorTransformation* KisCrossChannelFilter::createTransformation(const KoColorSpace* cs, const KisFilterConfigurationSP config) const { const KisCrossChannelFilterConfiguration* configBC = dynamic_cast(config.data()); Q_ASSERT(configBC); const QVector > &originalTransfers = configBC->transfers(); const QList &curves = configBC->curves(); const QVector &drivers = configBC->driverChannels(); const QVector virtualChannels = KisMultiChannelFilter::getVirtualChannels(cs, originalTransfers.size()); if (originalTransfers.size() > int(virtualChannels.size())) { // We got an illegal number of colorchannels :( return 0; } QVector transforms; // Channel order reversed in order to adjust saturation before hue. This allows mapping grays to colors. for (int i = virtualChannels.size() - 1; i >= 0; i--) { if (!curves[i].isConstant(0.5)) { int channel = mapChannel(virtualChannels[i]); int driverChannel = mapChannel(virtualChannels[drivers[i]]); QHash params; params["channel"] = channel; params["driverChannel"] = driverChannel; params["curve"] = QVariant::fromValue(originalTransfers[i]); params["relative"] = true; params["lumaRed"] = cs->lumaCoefficients()[0]; params["lumaGreen"] = cs->lumaCoefficients()[1]; params["lumaBlue"] = cs->lumaCoefficients()[2]; transforms << cs->createColorTransformation("hsv_curve_adjustment", params); } } return KoCompositeColorTransformation::createOptimizedCompositeTransform(transforms); } diff --git a/plugins/filters/colorsfilters/kis_cross_channel_filter.h b/plugins/filters/colorsfilters/kis_cross_channel_filter.h index 37da142778..98d22e451b 100644 --- a/plugins/filters/colorsfilters/kis_cross_channel_filter.h +++ b/plugins/filters/colorsfilters/kis_cross_channel_filter.h @@ -1,102 +1,102 @@ /* * This file is part of Krita * * Copyright (c) 2018 Jouni Pentikainen * * 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-1301, USA. */ #ifndef _KIS_CROSSCHANNEL_FILTER_H_ #define _KIS_CROSSCHANNEL_FILTER_H_ #include #include #include #include #include #include #include "ui_wdg_perchannel.h" #include "virtual_channel_info.h" #include "kis_multichannel_filter_base.h" /** * Filter which applies a relative adjustment to a (virtual) color channel based on the value of another. * The amount of adjustment for a given input is controlled by a user-defined curve. */ class KisCrossChannelFilter : public KisMultiChannelFilter { public: KisCrossChannelFilter(); ~KisCrossChannelFilter() override; - KisConfigWidget * createConfigurationWidget(QWidget *parent, const KisPaintDeviceSP dev) const override; + KisConfigWidget * createConfigurationWidget(QWidget *parent, const KisPaintDeviceSP dev, bool useForMasks) const override; KisFilterConfigurationSP factoryConfiguration() const override; KoColorTransformation* createTransformation(const KoColorSpace *cs, const KisFilterConfigurationSP config) const override; static inline KoID id() { return KoID("crosschannel", i18n("Cross-channel color adjustment")); } }; class KisCrossChannelFilterConfiguration : public KisMultiChannelFilterConfiguration { public: KisCrossChannelFilterConfiguration(int channelCount, const KoColorSpace *cs); ~KisCrossChannelFilterConfiguration() override; const QVector driverChannels() const; void setDriverChannels(QVector driverChannels); using KisFilterConfiguration::fromXML; using KisFilterConfiguration::toXML; void fromXML(const QDomElement& e) override; void toXML(QDomDocument& doc, QDomElement& root) const override; KisCubicCurve getDefaultCurve() override; private: QVector m_driverChannels; }; class KisCrossChannelConfigWidget : public KisMultiChannelConfigWidget { Q_OBJECT public: KisCrossChannelConfigWidget(QWidget * parent, KisPaintDeviceSP dev, Qt::WindowFlags f = 0); ~KisCrossChannelConfigWidget() override; void setConfiguration(const KisPropertiesConfigurationSP config) override; KisPropertiesConfigurationSP configuration() const override; protected: void updateChannelControls() override; virtual KisPropertiesConfigurationSP getDefaultConfiguration() override; private Q_SLOTS: void slotDriverChannelSelected(int index); private: QVector m_driverChannels; }; #endif diff --git a/plugins/filters/colorsfilters/kis_desaturate_filter.cpp b/plugins/filters/colorsfilters/kis_desaturate_filter.cpp index b72f1e5179..e910c3e988 100644 --- a/plugins/filters/colorsfilters/kis_desaturate_filter.cpp +++ b/plugins/filters/colorsfilters/kis_desaturate_filter.cpp @@ -1,123 +1,123 @@ /* * This file is part of Krita * * Copyright (c) 2004 Cyrille Berger * * 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-1301, USA. */ #include "kis_desaturate_filter.h" #include #include #include #include #include #include #include #include #include #include #include "KoBasicHistogramProducers.h" #include #include #include #include #include #include #include #include #include #include #include #include #include "filter/kis_filter_registry.h" #include #include #include #include KisDesaturateFilter::KisDesaturateFilter() : KisColorTransformationFilter(id(), FiltersCategoryAdjustId, i18n("&Desaturate...")) { setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_U)); setSupportsPainting(true); } KisDesaturateFilter::~KisDesaturateFilter() { } -KisConfigWidget *KisDesaturateFilter::createConfigurationWidget(QWidget *parent, const KisPaintDeviceSP dev) const +KisConfigWidget *KisDesaturateFilter::createConfigurationWidget(QWidget *parent, const KisPaintDeviceSP dev, bool) const { Q_UNUSED(dev); return new KisDesaturateConfigWidget(parent); } KoColorTransformation* KisDesaturateFilter::createTransformation(const KoColorSpace* cs, const KisFilterConfigurationSP config) const { QHash params; if (config) { params["type"] = config->getInt("type", 0); } return cs->createColorTransformation("desaturate_adjustment", params); } KisFilterConfigurationSP KisDesaturateFilter::factoryConfiguration() const { KisColorTransformationConfigurationSP config = new KisColorTransformationConfiguration(id().id(), 1); config->setProperty("type", 0); return config; } KisDesaturateConfigWidget::KisDesaturateConfigWidget(QWidget * parent, Qt::WindowFlags f) : KisConfigWidget(parent, f) { m_page = new Ui_WdgDesaturate(); m_page->setupUi(this); m_group = new QButtonGroup(this); m_group->addButton(m_page->radioLightness, 0); m_group->addButton(m_page->radioLuminosityBT709, 1); m_group->addButton(m_page->radioLuminosityBT601, 2); m_group->addButton(m_page->radioAverage, 3); m_group->addButton(m_page->radioMin, 4); m_group->addButton(m_page->radioMax, 5); m_group->setExclusive(true); connect(m_group, SIGNAL(buttonClicked(int)), SIGNAL(sigConfigurationItemChanged())); } KisDesaturateConfigWidget::~KisDesaturateConfigWidget() { delete m_page; } KisPropertiesConfigurationSP KisDesaturateConfigWidget::configuration() const { KisColorTransformationConfigurationSP c = new KisColorTransformationConfiguration(KisDesaturateFilter::id().id(), 0); c->setProperty("type", m_group->checkedId()); return c; } void KisDesaturateConfigWidget::setConfiguration(const KisPropertiesConfigurationSP config) { m_group->button(config->getInt("type", 0))->setChecked(true); emit sigConfigurationItemChanged(); } diff --git a/plugins/filters/colorsfilters/kis_desaturate_filter.h b/plugins/filters/colorsfilters/kis_desaturate_filter.h index 59bf312011..9ab8a3626d 100644 --- a/plugins/filters/colorsfilters/kis_desaturate_filter.h +++ b/plugins/filters/colorsfilters/kis_desaturate_filter.h @@ -1,70 +1,70 @@ /* * This file is part of Krita * * Copyright (c) 2004 Cyrille Berger * * 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-1301, USA. */ #ifndef KIS_DESATURATE_FILTER_H #define KIS_DESATURATE_FILTER_H #include #include #include #include #include "ui_wdg_desaturate.h" class KoColorSpace; class KoColorTransformation; class KisDesaturateFilter : public KisColorTransformationFilter { public: KisDesaturateFilter(); ~KisDesaturateFilter() override; public: - KisConfigWidget * createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev) const override; + KisConfigWidget * createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev, bool useForMasks) const override; KoColorTransformation* createTransformation(const KoColorSpace* cs, const KisFilterConfigurationSP config) const override; static inline KoID id() { return KoID("desaturate", i18n("Desaturate")); } KisFilterConfigurationSP factoryConfiguration() const override; }; class KisDesaturateConfigWidget : public KisConfigWidget { Q_OBJECT public: KisDesaturateConfigWidget(QWidget * parent, Qt::WindowFlags f = 0); ~KisDesaturateConfigWidget() override; KisPropertiesConfigurationSP configuration() const override; void setConfiguration(const KisPropertiesConfigurationSP config) override; Ui_WdgDesaturate *m_page; QButtonGroup *m_group; }; #endif diff --git a/plugins/filters/colorsfilters/kis_hsv_adjustment_filter.cpp b/plugins/filters/colorsfilters/kis_hsv_adjustment_filter.cpp index a9ae138370..4cc5d12ac2 100644 --- a/plugins/filters/colorsfilters/kis_hsv_adjustment_filter.cpp +++ b/plugins/filters/colorsfilters/kis_hsv_adjustment_filter.cpp @@ -1,208 +1,208 @@ /* * Copyright (c) 2007 Cyrille Berger * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; version 2 * of the License. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "kis_hsv_adjustment_filter.h" #include #include #include #include #include #include namespace { struct SliderConfig { QString m_text; int m_minimum; int m_maximum; inline void apply(QSpinBox* spinBox, QSlider* slider, QLabel* label) const { label->setText(m_text); slider->setMinimum(m_minimum); slider->setMaximum(m_maximum); spinBox->setMinimum(m_minimum); spinBox->setMaximum(m_maximum); int sliderValue = slider->value(); if (sliderValue < m_minimum || sliderValue > m_maximum) { slider->setValue((m_minimum + m_maximum) / 2); } } inline double normalize(int value) const { return (double)value / (double)m_maximum; } inline void resetSlider( QSlider* slider) const { slider->setValue(0); } }; struct WidgetSlidersConfig { SliderConfig m_sliders[3]; }; #define PERCENT_FIELD_REL(x) {x, -100, 100} #define PERCENT_FIELD_ABS(x) {x, 0, 100} #define DEGREES_FIELD_REL(x) {x, -180, 180} #define DEGREES_FIELD_ABS(x) {x, 0, 360} #define HSX_CONFIGS(x) { \ { {DEGREES_FIELD_REL(i18n("Hue:")), PERCENT_FIELD_REL(i18n("Saturation:")), PERCENT_FIELD_REL(x)} }, \ { {DEGREES_FIELD_ABS(i18n("Hue:")), PERCENT_FIELD_ABS(i18n("Saturation:")), PERCENT_FIELD_REL(x)} } \ } const WidgetSlidersConfig WIDGET_CONFIGS[][2] = { // Hue/Saturation/Value HSX_CONFIGS(i18n("Value:")), // Hue/Saturation/Lightness HSX_CONFIGS(i18n("Lightness:")), // Hue/Saturation/Intensity HSX_CONFIGS(i18n("Intensity:")), // Hue/Saturation/Luminosity HSX_CONFIGS(i18n("Luma:")), // Blue Chroma/Red Chroma/Luma {{ {PERCENT_FIELD_REL(i18n("Yellow-Blue:")), PERCENT_FIELD_REL(i18n("Green-Red:")), PERCENT_FIELD_REL(i18n("Luma:"))} }, { {PERCENT_FIELD_ABS(i18n("Yellow-Blue:")), PERCENT_FIELD_ABS(i18n("Green-Red:")), PERCENT_FIELD_REL(i18n("Luma:"))} }} }; inline const WidgetSlidersConfig& getCurrentWidgetConfig(int type, bool colorize) { return WIDGET_CONFIGS[type][colorize ? 1 : 0]; } } KisHSVAdjustmentFilter::KisHSVAdjustmentFilter() : KisColorTransformationFilter(id(), FiltersCategoryAdjustId, i18n("&HSV Adjustment...")) { setShortcut(QKeySequence(Qt::CTRL + Qt::Key_U)); setSupportsPainting(true); } -KisConfigWidget * KisHSVAdjustmentFilter::createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev) const +KisConfigWidget * KisHSVAdjustmentFilter::createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev, bool) const { Q_UNUSED(dev); return new KisHSVConfigWidget(parent); } KoColorTransformation* KisHSVAdjustmentFilter::createTransformation(const KoColorSpace* cs, const KisFilterConfigurationSP config) const { QHash params; if (config) { int type = config->getInt("type", 1); bool colorize = config->getBool("colorize", false); const WidgetSlidersConfig& widgetConfig = getCurrentWidgetConfig(type, colorize); params["h"] = widgetConfig.m_sliders[0].normalize(config->getInt("h", 0)); params["s"] = widgetConfig.m_sliders[1].normalize(config->getInt("s", 0)); params["v"] = widgetConfig.m_sliders[2].normalize(config->getInt("v", 0)); params["type"] = type; params["colorize"] = colorize; params["lumaRed"] = cs->lumaCoefficients()[0]; params["lumaGreen"] = cs->lumaCoefficients()[1]; params["lumaBlue"] = cs->lumaCoefficients()[2]; } return cs->createColorTransformation("hsv_adjustment", params); } KisFilterConfigurationSP KisHSVAdjustmentFilter::factoryConfiguration() const { KisColorTransformationConfigurationSP config = new KisColorTransformationConfiguration(id().id(), 1); config->setProperty("h", 0); config->setProperty("s", 0); config->setProperty("v", 0); config->setProperty("type", 1); config->setProperty("colorize", false); return config; } KisHSVConfigWidget::KisHSVConfigWidget(QWidget * parent, Qt::WindowFlags f) : KisConfigWidget(parent, f) { m_page = new Ui_WdgHSVAdjustment(); m_page->setupUi(this); connect(m_page->cmbType, SIGNAL(activated(int)), this, SLOT(configureSliderLimitsAndLabels())); connect(m_page->chkColorize, SIGNAL(toggled(bool)), this, SLOT(configureSliderLimitsAndLabels())); connect(m_page->reset,SIGNAL(clicked(bool)),this,SLOT(resetFilter())); // connect horizontal sliders connect(m_page->hueSlider, SIGNAL(valueChanged(int)), SIGNAL(sigConfigurationItemChanged())); connect(m_page->saturationSlider, SIGNAL(valueChanged(int)), SIGNAL(sigConfigurationItemChanged())); connect(m_page->valueSlider, SIGNAL(valueChanged(int)), SIGNAL(sigConfigurationItemChanged())); connect(m_page->hueSpinBox, SIGNAL(valueChanged(int)), m_page->hueSlider, SLOT(setValue(int))); connect(m_page->saturationSpinBox, SIGNAL(valueChanged(int)), m_page->saturationSlider, SLOT(setValue(int))); connect(m_page->valueSpinBox, SIGNAL(valueChanged(int)), m_page->valueSlider, SLOT(setValue(int))); connect(m_page->hueSlider, SIGNAL(valueChanged(int)), m_page->hueSpinBox, SLOT(setValue(int))); connect(m_page->saturationSlider, SIGNAL(valueChanged(int)), m_page->saturationSpinBox, SLOT(setValue(int))); connect(m_page->valueSlider, SIGNAL(valueChanged(int)), m_page->valueSpinBox, SLOT(setValue(int))); } KisHSVConfigWidget::~KisHSVConfigWidget() { delete m_page; } KisPropertiesConfigurationSP KisHSVConfigWidget::configuration() const { KisColorTransformationConfigurationSP c = new KisColorTransformationConfiguration(KisHSVAdjustmentFilter::id().id(), 0); c->setProperty("h", m_page->hueSlider->value()); c->setProperty("s", m_page->saturationSlider->value()); c->setProperty("v", m_page->valueSlider->value()); c->setProperty("type", m_page->cmbType->currentIndex()); c->setProperty("colorize", m_page->chkColorize->isChecked()); return c; } void KisHSVConfigWidget::setConfiguration(const KisPropertiesConfigurationSP config) { m_page->cmbType->setCurrentIndex(config->getInt("type", 1)); m_page->chkColorize->setChecked(config->getBool("colorize", false)); m_page->hueSlider->setValue(config->getInt("h", 0)); m_page->saturationSlider->setValue(config->getInt("s", 0)); m_page->valueSlider->setValue(config->getInt("v", 0)); configureSliderLimitsAndLabels(); } void KisHSVConfigWidget::configureSliderLimitsAndLabels() { const WidgetSlidersConfig& widget = getCurrentWidgetConfig(m_page->cmbType->currentIndex(), m_page->chkColorize->isChecked()); widget.m_sliders[0].apply(m_page->hueSpinBox, m_page->hueSlider, m_page->label); widget.m_sliders[1].apply(m_page->saturationSpinBox, m_page->saturationSlider, m_page->label_2); widget.m_sliders[2].apply(m_page->valueSpinBox, m_page->valueSlider, m_page->label_3); emit sigConfigurationItemChanged(); } void KisHSVConfigWidget::resetFilter() { const WidgetSlidersConfig& widget = getCurrentWidgetConfig(m_page->cmbType->currentIndex(), m_page->chkColorize->isChecked()); widget.m_sliders[0].resetSlider(m_page->hueSlider); widget.m_sliders[1].resetSlider(m_page->saturationSlider); widget.m_sliders[2].resetSlider(m_page->valueSlider); } diff --git a/plugins/filters/colorsfilters/kis_hsv_adjustment_filter.h b/plugins/filters/colorsfilters/kis_hsv_adjustment_filter.h index 2e007d42df..2b19fb8753 100644 --- a/plugins/filters/colorsfilters/kis_hsv_adjustment_filter.h +++ b/plugins/filters/colorsfilters/kis_hsv_adjustment_filter.h @@ -1,78 +1,78 @@ /* * Copyright (c) 2007 Cyrille Berger * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; version 2 * of the License. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef _KIS_HSV_ADJUSTMENT_FILTER_H_ #define _KIS_HSV_ADJUSTMENT_FILTER_H_ #include #include "filter/kis_filter.h" #include "kis_config_widget.h" #include "ui_wdg_hsv_adjustment.h" #include "filter/kis_color_transformation_filter.h" class QWidget; class KoColorTransformation; /** * This class affect Intensity Y of the image */ class KisHSVAdjustmentFilter : public KisColorTransformationFilter { public: KisHSVAdjustmentFilter(); public: - KisConfigWidget * createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev) const override; + KisConfigWidget * createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev, bool useForMasks) const override; KoColorTransformation* createTransformation(const KoColorSpace* cs, const KisFilterConfigurationSP config) const override; static inline KoID id() { return KoID("hsvadjustment", i18n("HSV/HSL Adjustment")); } KisFilterConfigurationSP factoryConfiguration() const override; }; class KisHSVConfigWidget : public KisConfigWidget { Q_OBJECT public: KisHSVConfigWidget(QWidget * parent, Qt::WindowFlags f = 0); ~KisHSVConfigWidget() override; KisPropertiesConfigurationSP configuration() const override; void setConfiguration(const KisPropertiesConfigurationSP config) override; Ui_WdgHSVAdjustment * m_page; private Q_SLOTS: void configureSliderLimitsAndLabels(); void resetFilter(); }; #endif diff --git a/plugins/filters/colorsfilters/kis_perchannel_filter.cpp b/plugins/filters/colorsfilters/kis_perchannel_filter.cpp index 106f5f83a8..084df0e451 100644 --- a/plugins/filters/colorsfilters/kis_perchannel_filter.cpp +++ b/plugins/filters/colorsfilters/kis_perchannel_filter.cpp @@ -1,318 +1,318 @@ /* * This file is part of Krita * * Copyright (c) 2005 C. Boemann * * 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-1301, USA. */ #include "kis_perchannel_filter.h" #include #include #include #include #include #include #include #include #include "KoChannelInfo.h" #include "KoBasicHistogramProducers.h" #include "KoColorModelStandardIds.h" #include "KoColorSpace.h" #include "KoColorTransformation.h" #include "KoCompositeColorTransformation.h" #include "KoCompositeOp.h" #include "KoID.h" #include "kis_signals_blocker.h" #include "kis_bookmarked_configuration_manager.h" #include "kis_config_widget.h" #include #include #include #include #include "kis_histogram.h" #include "kis_painter.h" #include "widgets/kis_curve_widget.h" #include "../../color/colorspaceextensions/kis_hsv_adjustment.h" KisPerChannelConfigWidget::KisPerChannelConfigWidget(QWidget * parent, KisPaintDeviceSP dev, Qt::WindowFlags f) : KisMultiChannelConfigWidget(parent, dev, f) { init(); // These are not used by this filter, // but the dialog is shared with KisCrossChannelFilter m_page->lblDriverChannel->hide(); m_page->cmbDriverChannel->hide(); } KisPerChannelConfigWidget::~KisPerChannelConfigWidget() {} #define BITS_PER_BYTE 8 #define pwr2(p) (1<curveWidget->dropInOutControls(); switch (valueType) { case KoChannelInfo::UINT8: case KoChannelInfo::UINT16: case KoChannelInfo::UINT32: min = 0; max = maxValue - 1; break; case KoChannelInfo::INT8: case KoChannelInfo::INT16: min = -maxValue / 2; max = maxValue / 2 - 1; break; case KoChannelInfo::FLOAT16: case KoChannelInfo::FLOAT32: case KoChannelInfo::FLOAT64: default: //Hack Alert: should be changed to float min = 0; max = 100; break; } m_page->curveWidget->setupInOutControls(m_page->intIn, m_page->intOut, min, max, min, max); } KisPropertiesConfigurationSP KisPerChannelConfigWidget::configuration() const { int numChannels = m_virtualChannels.size(); KisPropertiesConfigurationSP cfg = new KisPerChannelFilterConfiguration(numChannels); KIS_ASSERT_RECOVER(m_activeVChannel < m_curves.size()) { return cfg; } m_curves[m_activeVChannel] = m_page->curveWidget->curve(); static_cast(cfg.data())->setCurves(m_curves); return cfg; } KisPropertiesConfigurationSP KisPerChannelConfigWidget::getDefaultConfiguration() { return new KisPerChannelFilterConfiguration(m_virtualChannels.size()); } KisPerChannelFilterConfiguration::KisPerChannelFilterConfiguration(int channelCount) : KisMultiChannelFilterConfiguration(channelCount, "perchannel", 1) { init(); } KisPerChannelFilterConfiguration::~KisPerChannelFilterConfiguration() { } KisCubicCurve KisPerChannelFilterConfiguration::getDefaultCurve() { return KisCubicCurve(); } // KisPerChannelFilter KisPerChannelFilter::KisPerChannelFilter() : KisMultiChannelFilter(id(), i18n("&Color Adjustment curves...")) { setShortcut(QKeySequence(Qt::CTRL + Qt::Key_M)); } -KisConfigWidget * KisPerChannelFilter::createConfigurationWidget(QWidget *parent, const KisPaintDeviceSP dev) const +KisConfigWidget * KisPerChannelFilter::createConfigurationWidget(QWidget *parent, const KisPaintDeviceSP dev, bool) const { return new KisPerChannelConfigWidget(parent, dev); } KisFilterConfigurationSP KisPerChannelFilter::factoryConfiguration() const { return new KisPerChannelFilterConfiguration(0); } KoColorTransformation* KisPerChannelFilter::createTransformation(const KoColorSpace* cs, const KisFilterConfigurationSP config) const { const KisPerChannelFilterConfiguration* configBC = dynamic_cast(config.data()); // Somehow, this shouldn't happen Q_ASSERT(configBC); const QVector > &originalTransfers = configBC->transfers(); const QList &originalCurves = configBC->curves(); /** * TODO: What about the order of channels? (DK) * * Virtual channels are sorted in display order, does Lcms accepts * transforms in display order? Why on Earth it works?! Is it * documented anywhere? */ const QVector virtualChannels = KisMultiChannelFilter::getVirtualChannels(cs, originalTransfers.size()); if (originalTransfers.size() > int(virtualChannels.size())) { // We got an illegal number of colorchannels :( return 0; } bool colorsNull = true; bool hueNull = true; bool saturationNull = true; bool lightnessNull = true; bool allColorsNull = true; int alphaIndexInReal = -1; QVector > realTransfers; QVector hueTransfer; QVector saturationTransfer; QVector lightnessTransfer; QVector allColorsTransfer; for (int i = 0; i < virtualChannels.size(); i++) { if (virtualChannels[i].type() == VirtualChannelInfo::REAL) { realTransfers << originalTransfers[i]; if (virtualChannels[i].isAlpha()) { alphaIndexInReal = realTransfers.size() - 1; } if (colorsNull && !originalCurves[i].isIdentity()) { colorsNull = false; } } else if (virtualChannels[i].type() == VirtualChannelInfo::HUE) { KIS_ASSERT_RECOVER_NOOP(hueTransfer.isEmpty()); hueTransfer = originalTransfers[i]; if (hueNull && !originalCurves[i].isIdentity()) { hueNull = false; } } else if (virtualChannels[i].type() == VirtualChannelInfo::SATURATION) { KIS_ASSERT_RECOVER_NOOP(saturationTransfer.isEmpty()); saturationTransfer = originalTransfers[i]; if (saturationNull && !originalCurves[i].isIdentity()) { saturationNull = false; } } else if (virtualChannels[i].type() == VirtualChannelInfo::LIGHTNESS) { KIS_ASSERT_RECOVER_NOOP(lightnessTransfer.isEmpty()); lightnessTransfer = originalTransfers[i]; if (lightnessNull && !originalCurves[i].isIdentity()) { lightnessNull = false; } } else if (virtualChannels[i].type() == VirtualChannelInfo::ALL_COLORS) { KIS_ASSERT_RECOVER_NOOP(allColorsTransfer.isEmpty()); allColorsTransfer = originalTransfers[i]; if (allColorsNull && !originalCurves[i].isIdentity()) { allColorsNull = false; } } } KoColorTransformation *hueTransform = 0; KoColorTransformation *saturationTransform = 0; KoColorTransformation *lightnessTransform = 0; KoColorTransformation *allColorsTransform = 0; KoColorTransformation *colorTransform = 0; if (!colorsNull) { const quint16** transfers = new const quint16*[realTransfers.size()]; for(int i = 0; i < realTransfers.size(); ++i) { transfers[i] = realTransfers[i].constData(); /** * createPerChannelAdjustment() expects alpha channel to * be the last channel in the list, so just it here */ KIS_ASSERT_RECOVER_NOOP(i != alphaIndexInReal || alphaIndexInReal == (realTransfers.size() - 1)); } colorTransform = cs->createPerChannelAdjustment(transfers); delete [] transfers; } if (!hueNull) { QHash params; params["curve"] = QVariant::fromValue(hueTransfer); params["channel"] = KisHSVCurve::Hue; params["relative"] = false; params["lumaRed"] = cs->lumaCoefficients()[0]; params["lumaGreen"] = cs->lumaCoefficients()[1]; params["lumaBlue"] = cs->lumaCoefficients()[2]; hueTransform = cs->createColorTransformation("hsv_curve_adjustment", params); } if (!saturationNull) { QHash params; params["curve"] = QVariant::fromValue(saturationTransfer); params["channel"] = KisHSVCurve::Saturation; params["relative"] = false; params["lumaRed"] = cs->lumaCoefficients()[0]; params["lumaGreen"] = cs->lumaCoefficients()[1]; params["lumaBlue"] = cs->lumaCoefficients()[2]; saturationTransform = cs->createColorTransformation("hsv_curve_adjustment", params); } if (!lightnessNull) { lightnessTransform = cs->createBrightnessContrastAdjustment(lightnessTransfer.constData()); } if (!allColorsNull) { const quint16** allColorsTransfers = new const quint16*[realTransfers.size()]; for(int i = 0; i < realTransfers.size(); ++i) { allColorsTransfers[i] = (i != alphaIndexInReal) ? allColorsTransfer.constData() : 0; /** * createPerChannelAdjustment() expects alpha channel to * be the last channel in the list, so just it here */ KIS_ASSERT_RECOVER_NOOP(i != alphaIndexInReal || alphaIndexInReal == (realTransfers.size() - 1)); } allColorsTransform = cs->createPerChannelAdjustment(allColorsTransfers); delete[] allColorsTransfers; } QVector allTransforms; allTransforms << colorTransform; allTransforms << allColorsTransform; allTransforms << hueTransform; allTransforms << saturationTransform; allTransforms << lightnessTransform; return KoCompositeColorTransformation::createOptimizedCompositeTransform(allTransforms); } diff --git a/plugins/filters/colorsfilters/kis_perchannel_filter.h b/plugins/filters/colorsfilters/kis_perchannel_filter.h index 829d6862b0..279e26b044 100644 --- a/plugins/filters/colorsfilters/kis_perchannel_filter.h +++ b/plugins/filters/colorsfilters/kis_perchannel_filter.h @@ -1,81 +1,81 @@ /* * This file is part of Krita * * Copyright (c) 2004 Cyrille Berger * * 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-1301, USA. */ #ifndef _KIS_PERCHANNEL_FILTER_H_ #define _KIS_PERCHANNEL_FILTER_H_ #include #include #include #include #include #include #include "virtual_channel_info.h" #include "kis_multichannel_filter_base.h" class KisPerChannelFilterConfiguration : public KisMultiChannelFilterConfiguration { public: KisPerChannelFilterConfiguration(int channelCount); ~KisPerChannelFilterConfiguration() override; KisCubicCurve getDefaultCurve() override; }; /** * This class is a filter to adjust channels independently */ class KisPerChannelFilter : public KisMultiChannelFilter { public: KisPerChannelFilter(); - KisConfigWidget * createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev) const override; + KisConfigWidget * createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev, bool useForMasks) const override; KisFilterConfigurationSP factoryConfiguration() const override; KoColorTransformation* createTransformation(const KoColorSpace* cs, const KisFilterConfigurationSP config) const override; static inline KoID id() { return KoID("perchannel", i18n("Color Adjustment")); } }; class KisPerChannelConfigWidget : public KisMultiChannelConfigWidget { Q_OBJECT public: KisPerChannelConfigWidget(QWidget * parent, KisPaintDeviceSP dev, Qt::WindowFlags f = 0); ~KisPerChannelConfigWidget() override; KisPropertiesConfigurationSP configuration() const override; protected: void updateChannelControls() override; virtual KisPropertiesConfigurationSP getDefaultConfiguration() override; }; #endif diff --git a/plugins/filters/convertheightnormalmap/kis_convert_height_to_normal_map_filter.cpp b/plugins/filters/convertheightnormalmap/kis_convert_height_to_normal_map_filter.cpp index f5678cd6c2..b2dce21a6b 100644 --- a/plugins/filters/convertheightnormalmap/kis_convert_height_to_normal_map_filter.cpp +++ b/plugins/filters/convertheightnormalmap/kis_convert_height_to_normal_map_filter.cpp @@ -1,170 +1,170 @@ /* * Copyright (c) 2017 Wolthera van Hövell tot Westerflier * * 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-1301, USA. */ #include "kis_convert_height_to_normal_map_filter.h" #include "kis_wdg_convert_height_to_normal_map.h" #include #include #include #include #include #include "kis_lod_transform.h" #include K_PLUGIN_FACTORY_WITH_JSON(KritaConvertHeightToNormalMapFilterFactory, "kritaconvertheighttonormalmap.json", registerPlugin();) KritaConvertHeightToNormalMapFilter::KritaConvertHeightToNormalMapFilter(QObject *parent, const QVariantList &) : QObject(parent) { KisFilterRegistry::instance()->add(KisFilterSP(new KisConvertHeightToNormalMapFilter())); } KritaConvertHeightToNormalMapFilter::~KritaConvertHeightToNormalMapFilter() { } KisConvertHeightToNormalMapFilter::KisConvertHeightToNormalMapFilter(): KisFilter(id(), FiltersCategoryEdgeDetectionId, i18n("&Height to Normal Map...")) { setSupportsPainting(true); setSupportsAdjustmentLayers(true); setSupportsLevelOfDetail(true); setColorSpaceIndependence(FULLY_INDEPENDENT); setShowConfigurationWidget(true); } void KisConvertHeightToNormalMapFilter::processImpl(KisPaintDeviceSP device, const QRect &rect, const KisFilterConfigurationSP config, KoUpdater *progressUpdater) const { Q_ASSERT(device != 0); KisFilterConfigurationSP configuration = config ? config : new KisFilterConfiguration(id().id(), 1); KisLodTransformScalar t(device); QVariant value; configuration->getProperty("horizRadius", value); float horizontalRadius = t.scale(value.toFloat()); configuration->getProperty("vertRadius", value); float verticalRadius = t.scale(value.toFloat()); QBitArray channelFlags; if (configuration) { channelFlags = configuration->channelFlags(); } if (channelFlags.isEmpty() || !configuration) { channelFlags = device->colorSpace()->channelFlags(); } KisEdgeDetectionKernel::FilterType type = KisEdgeDetectionKernel::SobelVector; if (configuration->getString("type") == "prewitt") { type = KisEdgeDetectionKernel::Prewit; } else if (configuration->getString("type") == "simple") { type = KisEdgeDetectionKernel::Simple; } int channelToConvert = configuration->getInt("channelToConvert", 0); QVector channelOrder(3); QVector channelFlip(3); channelFlip.fill(false); int i = config->getInt("redSwizzle", 0); if (i%2==1 || i==2) { channelFlip[0] = true; } if (i==3) { channelFlip[0] = false; } channelOrder[device->colorSpace()->channels().at(0)->displayPosition()] = qMax(i/2,0); i = config->getInt("greenSwizzle", 2); if (i%2==1 || i==2) { channelFlip[1] = true; } if (i==3) { channelFlip[1] = false; } channelOrder[device->colorSpace()->channels().at(1)->displayPosition()] = qMax(i/2,0); i = config->getInt("blueSwizzle", 4); if (i%2==1 || i==2) { channelFlip[2] = true; } if (i==3) { channelFlip[2] = false; } channelOrder[device->colorSpace()->channels().at(2)->displayPosition()] = qMax(i/2,0); KisEdgeDetectionKernel::convertToNormalMap(device, rect, horizontalRadius, verticalRadius, type, channelToConvert, channelOrder, channelFlip, channelFlags, progressUpdater); } KisFilterConfigurationSP KisConvertHeightToNormalMapFilter::factoryConfiguration() const { KisFilterConfigurationSP config = new KisFilterConfiguration(id().id(), 1); config->setProperty("horizRadius", 1); config->setProperty("vertRadius", 1); config->setProperty("type", "sobol"); config->setProperty("channelToConvert", 0); config->setProperty("lockAspect", true); config->setProperty("redSwizzle", KisWdgConvertHeightToNormalMap::xPlus); config->setProperty("greenSwizzle", KisWdgConvertHeightToNormalMap::yPlus); config->setProperty("blueSwizzle", KisWdgConvertHeightToNormalMap::zPlus); return config; } -KisConfigWidget *KisConvertHeightToNormalMapFilter::createConfigurationWidget(QWidget *parent, const KisPaintDeviceSP dev) const +KisConfigWidget *KisConvertHeightToNormalMapFilter::createConfigurationWidget(QWidget *parent, const KisPaintDeviceSP dev, bool) const { return new KisWdgConvertHeightToNormalMap(parent, dev->colorSpace()); } QRect KisConvertHeightToNormalMapFilter::neededRect(const QRect &rect, const KisFilterConfigurationSP _config, int lod) const { KisLodTransformScalar t(lod); QVariant value; /** * NOTE: integer division by two is done on purpose, * because the kernel size is always odd */ const int halfWidth = _config->getProperty("horizRadius", value) ? KisEdgeDetectionKernel::kernelSizeFromRadius(t.scale(value.toFloat())) / 2 : 5; const int halfHeight = _config->getProperty("vertRadius", value) ? KisEdgeDetectionKernel::kernelSizeFromRadius(t.scale(value.toFloat())) / 2 : 5; return rect.adjusted(-halfWidth * 2, -halfHeight * 2, halfWidth * 2, halfHeight * 2); } QRect KisConvertHeightToNormalMapFilter::changedRect(const QRect &rect, const KisFilterConfigurationSP _config, int lod) const { KisLodTransformScalar t(lod); QVariant value; const int halfWidth = _config->getProperty("horizRadius", value) ? KisEdgeDetectionKernel::kernelSizeFromRadius(t.scale(value.toFloat())) / 2 : 5; const int halfHeight = _config->getProperty("vertRadius", value) ? KisEdgeDetectionKernel::kernelSizeFromRadius(t.scale(value.toFloat())) / 2 : 5; return rect.adjusted( -halfWidth, -halfHeight, halfWidth, halfHeight); } #include "kis_convert_height_to_normal_map_filter.moc" diff --git a/plugins/filters/convertheightnormalmap/kis_convert_height_to_normal_map_filter.h b/plugins/filters/convertheightnormalmap/kis_convert_height_to_normal_map_filter.h index 082c38f734..203e0a0b05 100644 --- a/plugins/filters/convertheightnormalmap/kis_convert_height_to_normal_map_filter.h +++ b/plugins/filters/convertheightnormalmap/kis_convert_height_to_normal_map_filter.h @@ -1,52 +1,52 @@ /* * Copyright (c) 2017 Wolthera van Hövell tot Westerflier * * 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-1301, USA. */ #ifndef KIS_CONVERT_HEIGHT_TO_NORMAL_MAP_FILTER_H #define KIS_CONVERT_HEIGHT_TO_NORMAL_MAP_FILTER_H #include "filter/kis_filter.h" class KritaConvertHeightToNormalMapFilter : public QObject { Q_OBJECT public: KritaConvertHeightToNormalMapFilter(QObject *parent, const QVariantList &); ~KritaConvertHeightToNormalMapFilter() override; }; class KisConvertHeightToNormalMapFilter : public KisFilter { public: KisConvertHeightToNormalMapFilter(); void processImpl(KisPaintDeviceSP device, const QRect& rect, const KisFilterConfigurationSP config, KoUpdater* progressUpdater ) const override; static inline KoID id() { return KoID("height to normal", i18n("Height to Normal Map")); } KisFilterConfigurationSP factoryConfiguration() const override; public: - KisConfigWidget * createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev) const override; + KisConfigWidget * createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev, bool useForMasks) const override; QRect neededRect(const QRect & rect, const KisFilterConfigurationSP _config, int lod) const override; QRect changedRect(const QRect & rect, const KisFilterConfigurationSP _config, int lod) const override; }; #endif // KIS_CONVERT_HEIGHT_TO_NORMAL_MAP_FILTER_H diff --git a/plugins/filters/dodgeburn/DodgeBurn.cpp b/plugins/filters/dodgeburn/DodgeBurn.cpp index 3b286320e7..322f767ba4 100644 --- a/plugins/filters/dodgeburn/DodgeBurn.cpp +++ b/plugins/filters/dodgeburn/DodgeBurn.cpp @@ -1,112 +1,112 @@ /* * Copyright (c) 2009 Cyrille Berger * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 2.1 of the License. * * This library 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "DodgeBurn.h" #include #include #include #include "ui_DodgeBurnConfigurationBaseWidget.h" KisFilterDodgeBurn::KisFilterDodgeBurn(const QString& id, const QString& prefix, const QString& name ) : KisColorTransformationFilter(KoID(id, name), FiltersCategoryAdjustId, name), m_prefix(prefix) { setColorSpaceIndependence(FULLY_INDEPENDENT); setSupportsPainting(true); } -KisConfigWidget * KisFilterDodgeBurn::createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev) const +KisConfigWidget * KisFilterDodgeBurn::createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev, bool) const { Q_UNUSED(dev); return new KisDodgeBurnConfigWidget(parent, id()); } KoColorTransformation* KisFilterDodgeBurn::createTransformation(const KoColorSpace* cs, const KisFilterConfigurationSP config) const { QHash params; QString suffix = "Midtones"; if (config) { params["exposure"] = config->getDouble("exposure", 0.5); int type = config->getInt("type", KisFilterDodgeBurn::MIDTONES); switch(type) { case KisFilterDodgeBurn::HIGHLIGHTS: suffix = "Highlights"; break; case KisFilterDodgeBurn::SHADOWS: suffix = "Shadows"; break; default: break; } } return cs->createColorTransformation(m_prefix + suffix, params); } KisDodgeBurnConfigWidget::KisDodgeBurnConfigWidget(QWidget * parent, const QString& id) : KisConfigWidget(parent), m_id(id) { m_page = new Ui_DodgeBurnConfigurationBaseWidget(); m_page->setupUi(this); connect(m_page->radioButtonHighlights, SIGNAL(toggled(bool)), SIGNAL(sigConfigurationItemChanged())); connect(m_page->radioButtonMidtones, SIGNAL(toggled(bool)), SIGNAL(sigConfigurationItemChanged())); connect(m_page->radioButtonShadows, SIGNAL(toggled(bool)), SIGNAL(sigConfigurationItemChanged())); connect(m_page->sliderExposure, SIGNAL(valueChanged(int)), SIGNAL(sigConfigurationItemChanged())); } KisDodgeBurnConfigWidget::~KisDodgeBurnConfigWidget() { delete m_page; } KisPropertiesConfigurationSP KisDodgeBurnConfigWidget::configuration() const { KisColorTransformationConfigurationSP c = new KisColorTransformationConfiguration(m_id, 0); int type = 0; if(m_page->radioButtonHighlights->isChecked()) { type = KisFilterDodgeBurn::HIGHLIGHTS; } else if(m_page->radioButtonShadows->isChecked()) { type = KisFilterDodgeBurn::SHADOWS; } else { type = KisFilterDodgeBurn::MIDTONES; } c->setProperty("type", type); c->setProperty("exposure", m_page->sliderExposure->value() / 100.0); return c; } void KisDodgeBurnConfigWidget::setConfiguration(const KisPropertiesConfigurationSP config) { int type = config->getInt("type", KisFilterDodgeBurn::MIDTONES); switch(type) { case KisFilterDodgeBurn::HIGHLIGHTS: m_page->radioButtonHighlights->setChecked(true); break; case KisFilterDodgeBurn::SHADOWS: m_page->radioButtonShadows->setChecked(true); break; default: case KisFilterDodgeBurn::MIDTONES: m_page->radioButtonMidtones->setChecked(true); break; } m_page->sliderExposure->setValue(config->getDouble("exposure", 0.5) * 100); } diff --git a/plugins/filters/dodgeburn/DodgeBurn.h b/plugins/filters/dodgeburn/DodgeBurn.h index 2acc751eb3..06dc1fa757 100644 --- a/plugins/filters/dodgeburn/DodgeBurn.h +++ b/plugins/filters/dodgeburn/DodgeBurn.h @@ -1,58 +1,58 @@ /* * Copyright (c) 2009 Cyrille Berger * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 2.1 of the License. * * This library 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef DODGE_BURN_H #define DODGE_BURN_H #include "filter/kis_color_transformation_filter.h" #include "kis_config_widget.h" class KisFilterDodgeBurn : public KisColorTransformationFilter { public: enum Type { SHADOWS, MIDTONES, HIGHLIGHTS }; public: KisFilterDodgeBurn(const QString& id, const QString& prefix, const QString& name ); public: KoColorTransformation* createTransformation(const KoColorSpace* cs, const KisFilterConfigurationSP config) const override; - KisConfigWidget * createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev) const override; + KisConfigWidget * createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev, bool useForMasks) const override; private: QString m_prefix; }; class Ui_DodgeBurnConfigurationBaseWidget; class KisDodgeBurnConfigWidget : public KisConfigWidget { public: KisDodgeBurnConfigWidget(QWidget * parent, const QString& id); ~KisDodgeBurnConfigWidget() override; KisPropertiesConfigurationSP configuration() const override; void setConfiguration(const KisPropertiesConfigurationSP config) override; QString m_id; Ui_DodgeBurnConfigurationBaseWidget * m_page; }; #endif diff --git a/plugins/filters/edgedetection/kis_edge_detection_filter.cpp b/plugins/filters/edgedetection/kis_edge_detection_filter.cpp index 42c1e8ff68..1bb977c52a 100644 --- a/plugins/filters/edgedetection/kis_edge_detection_filter.cpp +++ b/plugins/filters/edgedetection/kis_edge_detection_filter.cpp @@ -1,159 +1,159 @@ /* * Copyright (c) 2017 Wolthera van Hövell tot Westerflier * * 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-1301, USA. */ #include "kis_edge_detection_filter.h" #include "kis_wdg_edge_detection.h" #include #include #include #include #include #include #include #include #include #include #include "kis_lod_transform.h" #include #include #include K_PLUGIN_FACTORY_WITH_JSON(KritaEdgeDetectionFilterFactory, "kritaedgedetection.json", registerPlugin();) KritaEdgeDetectionFilter::KritaEdgeDetectionFilter(QObject *parent, const QVariantList &) : QObject(parent) { KisFilterRegistry::instance()->add(KisFilterSP(new KisEdgeDetectionFilter())); } KritaEdgeDetectionFilter::~KritaEdgeDetectionFilter() { } KisEdgeDetectionFilter::KisEdgeDetectionFilter(): KisFilter(id(), FiltersCategoryEdgeDetectionId, i18n("&Edge Detection...")) { setSupportsPainting(true); setSupportsAdjustmentLayers(true); setSupportsLevelOfDetail(true); setColorSpaceIndependence(FULLY_INDEPENDENT); setShowConfigurationWidget(true); } void KisEdgeDetectionFilter::processImpl(KisPaintDeviceSP device, const QRect &rect, const KisFilterConfigurationSP config, KoUpdater *progressUpdater) const { Q_ASSERT(device != 0); KisFilterConfigurationSP configuration = config ? config : new KisFilterConfiguration(id().id(), 1); KisLodTransformScalar t(device); QVariant value; configuration->getProperty("horizRadius", value); float horizontalRadius = t.scale(value.toFloat()); configuration->getProperty("vertRadius", value); float verticalRadius = t.scale(value.toFloat()); QBitArray channelFlags; if (configuration) { channelFlags = configuration->channelFlags(); } if (channelFlags.isEmpty() || !configuration) { channelFlags = device->colorSpace()->channelFlags(); } KisEdgeDetectionKernel::FilterType type = KisEdgeDetectionKernel::SobelVector; if (config->getString("type") == "prewitt") { type = KisEdgeDetectionKernel::Prewit; } else if (config->getString("type") == "simple") { type = KisEdgeDetectionKernel::Simple; } KisEdgeDetectionKernel::FilterOutput output = KisEdgeDetectionKernel::pythagorean; if (config->getString("output") == "xGrowth") { output = KisEdgeDetectionKernel::xGrowth; } else if (config->getString("output") == "xFall") { output = KisEdgeDetectionKernel::xFall; } else if (config->getString("output") == "yGrowth") { output = KisEdgeDetectionKernel::yGrowth; } else if (config->getString("output") == "yFall") { output = KisEdgeDetectionKernel::yFall; } else if (config->getString("output") == "radian") { output = KisEdgeDetectionKernel::radian; } KisEdgeDetectionKernel::applyEdgeDetection(device, rect, horizontalRadius, verticalRadius, type, channelFlags, progressUpdater, output, config->getBool("transparency", false)); } KisFilterConfigurationSP KisEdgeDetectionFilter::factoryConfiguration() const { KisFilterConfigurationSP config = new KisFilterConfiguration(id().id(), 1); config->setProperty("horizRadius", 1); config->setProperty("vertRadius", 1); config->setProperty("type", "prewitt"); config->setProperty("output", "pythagorean"); config->setProperty("lockAspect", true); config->setProperty("transparency", false); return config; } -KisConfigWidget *KisEdgeDetectionFilter::createConfigurationWidget(QWidget *parent, const KisPaintDeviceSP dev) const +KisConfigWidget *KisEdgeDetectionFilter::createConfigurationWidget(QWidget *parent, const KisPaintDeviceSP dev, bool) const { Q_UNUSED(dev); return new KisWdgEdgeDetection(parent); } QRect KisEdgeDetectionFilter::neededRect(const QRect &rect, const KisFilterConfigurationSP _config, int lod) const { KisLodTransformScalar t(lod); QVariant value; /** * NOTE: integer division by two is done on purpose, * because the kernel size is always odd */ const int halfWidth = _config->getProperty("horizRadius", value) ? KisEdgeDetectionKernel::kernelSizeFromRadius(t.scale(value.toFloat())) / 2 : 5; const int halfHeight = _config->getProperty("vertRadius", value) ? KisEdgeDetectionKernel::kernelSizeFromRadius(t.scale(value.toFloat())) / 2 : 5; return rect.adjusted(-halfWidth * 2, -halfHeight * 2, halfWidth * 2, halfHeight * 2); } QRect KisEdgeDetectionFilter::changedRect(const QRect &rect, const KisFilterConfigurationSP _config, int lod) const { KisLodTransformScalar t(lod); QVariant value; const int halfWidth = _config->getProperty("horizRadius", value) ? KisEdgeDetectionKernel::kernelSizeFromRadius(t.scale(value.toFloat())) / 2 : 5; const int halfHeight = _config->getProperty("vertRadius", value) ? KisEdgeDetectionKernel::kernelSizeFromRadius(t.scale(value.toFloat())) / 2 : 5; return rect.adjusted( -halfWidth, -halfHeight, halfWidth, halfHeight); } #include "kis_edge_detection_filter.moc" diff --git a/plugins/filters/edgedetection/kis_edge_detection_filter.h b/plugins/filters/edgedetection/kis_edge_detection_filter.h index 626cfd2c99..a9fc3c8255 100644 --- a/plugins/filters/edgedetection/kis_edge_detection_filter.h +++ b/plugins/filters/edgedetection/kis_edge_detection_filter.h @@ -1,53 +1,53 @@ /* * Copyright (c) 2017 Wolthera van Hövell tot Westerflier * * 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-1301, USA. */ #ifndef KIS_EDGE_DETECTION_FILTER_H #define KIS_EDGE_DETECTION_FILTER_H #include "filter/kis_filter.h" #include class KritaEdgeDetectionFilter : public QObject { Q_OBJECT public: KritaEdgeDetectionFilter(QObject *parent, const QVariantList &); ~KritaEdgeDetectionFilter() override; }; class KisEdgeDetectionFilter : public KisFilter { public: KisEdgeDetectionFilter(); void processImpl(KisPaintDeviceSP device, const QRect& rect, const KisFilterConfigurationSP config, KoUpdater* progressUpdater ) const override; static inline KoID id() { return KoID("edge detection", i18n("Edge Detection")); } KisFilterConfigurationSP factoryConfiguration() const override; public: - KisConfigWidget * createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev) const override; + KisConfigWidget * createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev, bool useForMasks) const override; QRect neededRect(const QRect & rect, const KisFilterConfigurationSP _config, int lod) const override; QRect changedRect(const QRect & rect, const KisFilterConfigurationSP _config, int lod) const override; }; #endif // KIS_EDGE_DETECTION_FILTER_H diff --git a/plugins/filters/embossfilter/kis_emboss_filter.cpp b/plugins/filters/embossfilter/kis_emboss_filter.cpp index 385dafd01a..f408955e00 100644 --- a/plugins/filters/embossfilter/kis_emboss_filter.cpp +++ b/plugins/filters/embossfilter/kis_emboss_filter.cpp @@ -1,160 +1,160 @@ /* * This file is part of Krita * * Copyright (c) 2004 Michael Thaler * * ported from digikam, Copyrighted 2004 Gilles Caulier, * Original Emboss algorithm copyrighted 2004 by * Pieter Z. Voloshyn . * * 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-1301, USA. */ #include "kis_emboss_filter.h" #include #include #include #include #include #include #include #include "KoIntegerMaths.h" #include #include #include #include #include #include #include #include #include #include #include "widgets/kis_multi_integer_filter_widget.h" #include KisEmbossFilter::KisEmbossFilter() : KisFilter(id(), FiltersCategoryEmbossId, i18n("&Emboss with Variable Depth...")) { setSupportsPainting(false); setColorSpaceIndependence(TO_RGBA8); setSupportsThreading(false); setSupportsAdjustmentLayers(false); } KisFilterConfigurationSP KisEmbossFilter::factoryConfiguration() const { KisFilterConfigurationSP config = new KisFilterConfiguration(id().id(), 0); config->setProperty("depth", 30); return config; } // This method have been ported from Pieter Z. Voloshyn algorithm code. /* Function to apply the Emboss effect * * data => The image data in RGBA mode. * Width => Width of image. * Height => Height of image. * d => Emboss value * * Theory => This is an amazing effect. And the theory is very simple to * understand. You get the difference between the colors and * increase it. After this, get the gray tone */ void KisEmbossFilter::processImpl(KisPaintDeviceSP device, const QRect& applyRect, const KisFilterConfigurationSP config, KoUpdater* progressUpdater ) const { QPoint srcTopLeft = applyRect.topLeft(); Q_ASSERT(device); //read the filter configuration values from the KisFilterConfiguration object quint32 embossdepth = config ? config->getInt("depth", 30) : 30; //the actual filter function from digikam. It needs a pointer to a quint8 array //with the actual pixel data. float Depth = embossdepth / 10.0; int R = 0, G = 0, B = 0; uchar Gray = 0; int Width = applyRect.width(); int Height = applyRect.height(); KisSequentialIteratorProgress it(device, applyRect, progressUpdater); QColor color1; QColor color2; KisRandomConstAccessorSP acc = device->createRandomAccessorNG(srcTopLeft.x(), srcTopLeft.y()); while (it.nextPixel()) { // XXX: COLORSPACE_INDEPENDENCE or at least work IN RGB16A device->colorSpace()->toQColor(it.oldRawData(), &color1); acc->moveTo(srcTopLeft.x() + it.x() + Lim_Max(it.x(), 1, Width), srcTopLeft.y() + it.y() + Lim_Max(it.y(), 1, Height)); device->colorSpace()->toQColor(acc->oldRawData(), &color2); R = abs((int)((color1.red() - color2.red()) * Depth + (quint8_MAX / 2))); G = abs((int)((color1.green() - color2.green()) * Depth + (quint8_MAX / 2))); B = abs((int)((color1.blue() - color2.blue()) * Depth + (quint8_MAX / 2))); Gray = CLAMP((R + G + B) / 3, 0, quint8_MAX); device->colorSpace()->fromQColor(QColor(Gray, Gray, Gray, color1.alpha()), it.rawData()); } } // This method have been ported from Pieter Z. Voloshyn algorithm code. /* This function limits the max and min values * defined by the developer * * Now => Original value * Up => Increments * Max => Maximum value * * Theory => This function is used in some functions to limit the * "for step". E.g. I have a picture with 309 pixels (width), and * my "for step" is 5. All the code goes alright until it reaches the * w = 305, because in the next step we will go to 310, but we want * to analyze all the pixels. So, this function will reduce the * "for step", when necessary, until we reach the last possible value */ int KisEmbossFilter::Lim_Max(int Now, int Up, int Max) const { --Max; while (Now > Max - Up) --Up; return (Up); } -KisConfigWidget * KisEmbossFilter::createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev) const +KisConfigWidget * KisEmbossFilter::createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev, bool) const { Q_UNUSED(dev); vKisIntegerWidgetParam param; param.push_back(KisIntegerWidgetParam(10, 300, 30, i18nc("Emboss depth", "Depth"), "depth")); KisConfigWidget * w = new KisMultiIntegerFilterWidget(id().id(), parent, id().id(), param); Q_CHECK_PTR(w); return w; } diff --git a/plugins/filters/embossfilter/kis_emboss_filter.h b/plugins/filters/embossfilter/kis_emboss_filter.h index 67fe340cb5..6248dfb5ae 100644 --- a/plugins/filters/embossfilter/kis_emboss_filter.h +++ b/plugins/filters/embossfilter/kis_emboss_filter.h @@ -1,51 +1,51 @@ /* * This file is part of the KDE project * * Copyright (c) Michael Thaler * * 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-1301, USA. */ #ifndef _KIS_EMBOSS_FILTER_H_ #define _KIS_EMBOSS_FILTER_H_ #include "filter/kis_filter.h" #include "kis_config_widget.h" class KisEmbossFilter : public KisFilter { public: KisEmbossFilter(); public: void processImpl(KisPaintDeviceSP device, const QRect& applyRect, const KisFilterConfigurationSP config, KoUpdater* progressUpdater ) const override; static inline KoID id() { return KoID("emboss", i18n("Emboss with Variable Depth")); } public: - KisConfigWidget * createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev) const override; + KisConfigWidget * createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev, bool useForMasks) const override; protected: KisFilterConfigurationSP factoryConfiguration() const override; private: inline int Lim_Max(int Now, int Up, int Max) const; }; #endif diff --git a/plugins/filters/fastcolortransfer/fastcolortransfer.cpp b/plugins/filters/fastcolortransfer/fastcolortransfer.cpp index e08986abb7..dde61044eb 100644 --- a/plugins/filters/fastcolortransfer/fastcolortransfer.cpp +++ b/plugins/filters/fastcolortransfer/fastcolortransfer.cpp @@ -1,171 +1,171 @@ /* * This file is part of Krita * * Copyright (c) 2006 Cyrille Berger * * 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-1301, USA. */ #include "fastcolortransfer.h" #include #include #include #include #include #include #include #include #include #include #include #include #include "kis_wdg_fastcolortransfer.h" #include "ui_wdgfastcolortransfer.h" #include #include K_PLUGIN_FACTORY_WITH_JSON(KritaFastColorTransferFactory, "kritafastcolortransfer.json", registerPlugin();) FastColorTransferPlugin::FastColorTransferPlugin(QObject *parent, const QVariantList &) : QObject(parent) { KisFilterRegistry::instance()->add(new KisFilterFastColorTransfer()); } FastColorTransferPlugin::~FastColorTransferPlugin() { } KisFilterFastColorTransfer::KisFilterFastColorTransfer() : KisFilter(id(), FiltersCategoryColorId, i18n("&Color Transfer...")) { setColorSpaceIndependence(FULLY_INDEPENDENT); setSupportsThreading(false); setSupportsPainting(false); setSupportsAdjustmentLayers(false); } -KisConfigWidget * KisFilterFastColorTransfer::createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev) const +KisConfigWidget * KisFilterFastColorTransfer::createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev, bool) const { Q_UNUSED(dev); return new KisWdgFastColorTransfer(parent); } KisFilterConfigurationSP KisFilterFastColorTransfer::factoryConfiguration() const { KisFilterConfigurationSP config = new KisFilterConfiguration(id().id(), 1); config->setProperty("filename", ""); return config; } #define CLAMP(x,l,u) ((x)<(l)?(l):((x)>(u)?(u):(x))) void KisFilterFastColorTransfer::processImpl(KisPaintDeviceSP device, const QRect& applyRect, const KisFilterConfigurationSP config, KoUpdater* progressUpdater) const { Q_ASSERT(device != 0); dbgPlugins << "Start transferring color"; // Convert ref and src to LAB const KoColorSpace* labCS = KoColorSpaceRegistry::instance()->lab16(); if (!labCS) { dbgPlugins << "The LAB colorspace is not available."; return; } dbgPlugins << "convert a copy of src to lab"; const KoColorSpace* oldCS = device->colorSpace(); KisPaintDeviceSP srcLAB = new KisPaintDevice(*device.data()); dbgPlugins << "srcLab : " << srcLAB->extent(); srcLAB->convertTo(labCS, KoColorConversionTransformation::internalRenderingIntent(), KoColorConversionTransformation::internalConversionFlags()); KoProgressUpdater compositeUpdater(progressUpdater, KoProgressUpdater::Unthreaded); KoUpdater *updaterStats = compositeUpdater.startSubtask(1); KoUpdater *updaterMap = compositeUpdater.startSubtask(2); // Compute the means and sigmas of src dbgPlugins << "Compute the means and sigmas of src"; double meanL_src = 0., meanA_src = 0., meanB_src = 0.; double sigmaL_src = 0., sigmaA_src = 0., sigmaB_src = 0.; { KisSequentialConstIteratorProgress srcIt(srcLAB, applyRect, updaterStats); while (srcIt.nextPixel()) { const quint16* data = reinterpret_cast(srcIt.oldRawData()); quint32 L = data[0]; quint32 A = data[1]; quint32 B = data[2]; meanL_src += L; meanA_src += A; meanB_src += B; sigmaL_src += L * L; sigmaA_src += A * A; sigmaB_src += B * B; } } double totalSize = 1. / (applyRect.width() * applyRect.height()); meanL_src *= totalSize; meanA_src *= totalSize; meanB_src *= totalSize; sigmaL_src *= totalSize; sigmaA_src *= totalSize; sigmaB_src *= totalSize; dbgPlugins << totalSize << "" << meanL_src << "" << meanA_src << "" << meanB_src << "" << sigmaL_src << "" << sigmaA_src << "" << sigmaB_src; double meanL_ref = config->getDouble("meanL"); double meanA_ref = config->getDouble("meanA"); double meanB_ref = config->getDouble("meanB"); double sigmaL_ref = config->getDouble("sigmaL"); double sigmaA_ref = config->getDouble("sigmaA"); double sigmaB_ref = config->getDouble("sigmaB"); // Transfer colors dbgPlugins << "Transfer colors"; { double coefL = sqrt((sigmaL_ref - meanL_ref * meanL_ref) / (sigmaL_src - meanL_src * meanL_src)); double coefA = sqrt((sigmaA_ref - meanA_ref * meanA_ref) / (sigmaA_src - meanA_src * meanA_src)); double coefB = sqrt((sigmaB_ref - meanB_ref * meanB_ref) / (sigmaB_src - meanB_src * meanB_src)); quint16 labPixel[4]; KisSequentialConstIteratorProgress srcLabIt(srcLAB, applyRect, updaterMap); KisSequentialIterator dstIt(device, applyRect); while (srcLabIt.nextPixel() && dstIt.nextPixel()) { const quint16* data = reinterpret_cast(srcLabIt.oldRawData()); labPixel[0] = (quint16)CLAMP(((double)data[0] - meanL_src) * coefL + meanL_ref, 0., 65535.); labPixel[1] = (quint16)CLAMP(((double)data[1] - meanA_src) * coefA + meanA_ref, 0., 65535.); labPixel[2] = (quint16)CLAMP(((double)data[2] - meanB_src) * coefB + meanB_ref, 0., 65535.); labPixel[3] = data[3]; oldCS->fromLabA16(reinterpret_cast(labPixel), dstIt.rawData(), 1); } } } #include "fastcolortransfer.moc" diff --git a/plugins/filters/fastcolortransfer/fastcolortransfer.h b/plugins/filters/fastcolortransfer/fastcolortransfer.h index 61755c3368..aeb12b4667 100644 --- a/plugins/filters/fastcolortransfer/fastcolortransfer.h +++ b/plugins/filters/fastcolortransfer/fastcolortransfer.h @@ -1,55 +1,55 @@ /* * This file is part of Krita * * Copyright (c) 2006 Cyrille Berger * * 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-1301, USA. */ #ifndef COLORTRANSFER_H #define COLORTRANSFER_H #include #include #include class FastColorTransferPlugin : public QObject { Q_OBJECT public: FastColorTransferPlugin(QObject *parent, const QVariantList &); ~FastColorTransferPlugin() override; }; class KisFilterFastColorTransfer : public KisFilter { public: KisFilterFastColorTransfer(); public: void processImpl(KisPaintDeviceSP device, const QRect& applyRect, const KisFilterConfigurationSP config, KoUpdater* progressUpdater) const override; static inline KoID id() { return KoID("colortransfer", i18n("Color Transfer")); } public: - KisConfigWidget * createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev) const override; + KisConfigWidget * createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev, bool useForMasks) const override; KisFilterConfigurationSP factoryConfiguration() const override; }; #endif diff --git a/plugins/filters/gradientmap/krita_filter_gradient_map.cpp b/plugins/filters/gradientmap/krita_filter_gradient_map.cpp index 614dea90db..ae5dc8f7c0 100644 --- a/plugins/filters/gradientmap/krita_filter_gradient_map.cpp +++ b/plugins/filters/gradientmap/krita_filter_gradient_map.cpp @@ -1,104 +1,104 @@ /* * This file is part of the KDE project * * Copyright (c) 2016 Spencer Brown * 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-1301, USA. */ #include "krita_filter_gradient_map.h" #include #include #include #include #include #include #include "kis_config_widget.h" #include #include #include #include #include #include "gradientmap.h" #include KritaFilterGradientMap::KritaFilterGradientMap() : KisFilter(id(), FiltersCategoryMapId, i18n("&Gradient Map...")) { setColorSpaceIndependence(FULLY_INDEPENDENT); setShowConfigurationWidget(true); setSupportsLevelOfDetail(true); setSupportsPainting(true); setSupportsAdjustmentLayers(true); setSupportsThreading(true); } void KritaFilterGradientMap::processImpl(KisPaintDeviceSP device, const QRect& applyRect, const KisFilterConfigurationSP config, KoUpdater *progressUpdater) const { Q_ASSERT(!device.isNull()); QDomDocument doc; if (config->version()==1) { QDomElement elt = doc.createElement("gradient"); KoAbstractGradient *gradientAb = KoResourceServerProvider::instance()->gradientServer()->resourceByName(config->getString("gradientName")); if (!gradientAb) { qWarning() << "Could not find gradient" << config->getString("gradientName"); } gradientAb = KoResourceServerProvider::instance()->gradientServer()->resources().first(); KoStopGradient::fromQGradient(gradientAb->toQGradient())->toXML(doc, elt); doc.appendChild(elt); } else { doc.setContent(config->getString("gradientXML", "")); } KoStopGradient gradient = KoStopGradient::fromXML(doc.firstChildElement()); KoColor outColor(Qt::white, device->colorSpace()); KisSequentialIteratorProgress it(device, applyRect, progressUpdater); quint8 grey; const int pixelSize = device->colorSpace()->pixelSize(); while (it.nextPixel()) { grey = device->colorSpace()->intensity8(it.oldRawData()); gradient.colorAt(outColor,(qreal)grey/255); outColor.setOpacity(qMin(KoColor(it.oldRawData(), device->colorSpace()).opacityF(), outColor.opacityF())); outColor.convertTo(device->colorSpace()); memcpy(it.rawData(), outColor.data(), pixelSize); } } KisFilterConfigurationSP KritaFilterGradientMap::factoryConfiguration() const { KisFilterConfigurationSP config = new KisFilterConfiguration("gradientmap", 2); KoAbstractGradient *gradient = KoResourceServerProvider::instance()->gradientServer()->resources().first(); KoStopGradient stopGradient; stopGradient.fromQGradient(gradient->toQGradient()); QDomDocument doc; QDomElement elt = doc.createElement("gradient"); stopGradient.toXML(doc, elt); doc.appendChild(elt); config->setProperty("gradientXML", doc.toString()); return config; } -KisConfigWidget * KritaFilterGradientMap::createConfigurationWidget(QWidget * parent, const KisPaintDeviceSP dev) const +KisConfigWidget * KritaFilterGradientMap::createConfigurationWidget(QWidget * parent, const KisPaintDeviceSP dev, bool) const { return new KritaGradientMapConfigWidget(parent, dev); } diff --git a/plugins/filters/gradientmap/krita_filter_gradient_map.h b/plugins/filters/gradientmap/krita_filter_gradient_map.h index d54b2abc32..8171030845 100644 --- a/plugins/filters/gradientmap/krita_filter_gradient_map.h +++ b/plugins/filters/gradientmap/krita_filter_gradient_map.h @@ -1,52 +1,52 @@ /* * This file is part of Krita * * Copyright (c) 2016 Spencer Brown * * 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-1301, USA. */ #ifndef KIS_GRADIENT_MAP_H #define KIS_GRADIENT_MAP_H #include #include #include #include #include #include #include class KritaFilterGradientMap : public KisFilter { public: KritaFilterGradientMap(); public: static inline KoID id() { return KoID("gradientmap", i18n("Gradient Map")); } void processImpl(KisPaintDeviceSP device, const QRect& applyRect, const KisFilterConfigurationSP config, KoUpdater *progressUpdater) const override; KisFilterConfigurationSP factoryConfiguration() const override; - KisConfigWidget* createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev) const override; + KisConfigWidget* createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev, bool useForMasks) const override; }; #endif diff --git a/plugins/filters/halftone/kis_halftone_filter.cpp b/plugins/filters/halftone/kis_halftone_filter.cpp index 9cf1eb5584..9c4d2b94fa 100644 --- a/plugins/filters/halftone/kis_halftone_filter.cpp +++ b/plugins/filters/halftone/kis_halftone_filter.cpp @@ -1,270 +1,270 @@ /* * This file is part of Krita * * Copyright (c) 2016 Wolthera van Hövell tot Westerflier * * 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-1301, USA. */ #include #include #include #include #include #include #include #include "kis_filter_configuration.h" #include #include #include #include #include #include #include #include "kis_halftone_filter.h" K_PLUGIN_FACTORY_WITH_JSON(KritaHalftoneFactory, "kritahalftone.json", registerPlugin();) KritaHalftone::KritaHalftone(QObject *parent, const QVariantList &) : QObject(parent) { KisFilterRegistry::instance()->add(new KisHalftoneFilter()); } KritaHalftone::~KritaHalftone() { } KisHalftoneFilter::KisHalftoneFilter() : KisFilter(id(), FiltersCategoryArtisticId, i18n("&Halftone...")) { setColorSpaceIndependence(FULLY_INDEPENDENT); setSupportsPainting(false); setShowConfigurationWidget(true); setSupportsLevelOfDetail(false); setSupportsAdjustmentLayers(false); setSupportsThreading(false); } //I am pretty terrible at trigonometry, hence all the comments. void KisHalftoneFilter::processImpl(KisPaintDeviceSP device, const QRect &applyRect, const KisFilterConfigurationSP config, KoUpdater *progressUpdater) const { qreal cellSize = (qreal)config->getInt("cellSize", 8); qreal angle = fmod((qreal)config->getInt("patternAngle", 45), 90.0); KoColor foregroundC(Qt::black, device->colorSpace()); foregroundC.fromKoColor(config->getColor("foreGroundColor", KoColor(Qt::black, device->colorSpace()) ) ); KoColor backgroundC(Qt::white, device->colorSpace()); backgroundC.fromKoColor(config->getColor("backGroundColor", KoColor(Qt::white, device->colorSpace()) ) ); //First calculate the full diameter, using pythagoras theorem. qreal diameter = qSqrt((cellSize*cellSize)*2); qreal cellSpacingH = cellSize; qreal cellSpacingV = cellSize; qreal cellOffsetV = 0; if (angle>0.0){ //2/3=0.6 sin=o/h //0.6*3=2 sin*h=o //2/0.6=3 o/sin=h qreal angleRad = qDegreesToRadians(angle); //Horizontal cellspacing is the hypotenuse of the Angle and the cellSize(opposite). cellSpacingH = cellSize/qSin(angleRad); //Vertical cellspacing is the opposite of the Angle and the cellSize(hypotenuse). cellSpacingV = cellSize*qSin(angleRad); //cellSpacingoffset is the oppose of the (90-angle) and the vertical cellspacing(adjectant) toa t=o/a, t*a=o. cellOffsetV = qTan(qDegreesToRadians(90-angle))*cellSpacingV; } QPolygonF gridPoints; QRect totalRect(QPoint(0,0), applyRect.bottomRight()); if (gridPoints.size()<1) { int rows = (totalRect.height()/cellSpacingV)+3; for (int r=0; rexactBounds(); if (progressUpdater) { progressUpdater->setRange(0, (applyRect.height()/cellSpacingV+3)*(applyRect.width()/cellSpacingH+3)); } KisRandomConstAccessorSP itterator = device->createRandomConstAccessorNG( 0, 0); //itterator->numContiguousColumns(qCeil(cellSize)); //itterator->numContiguousRows(qCeil(cellSize)); KisPainter painter(device); painter.setCompositeOp(device->colorSpace()->compositeOp(COMPOSITE_OVER)); KisPaintDeviceSP dab = device->createCompositionSourceDevice(); KisPainter dbPainter(dab); KisSelectionSP alpha = new KisSelection(new KisSelectionEmptyBounds(0)); alpha->pixelSelection()->copyAlphaFrom(device, applyRect); device->fill(applyRect, backgroundC); dbPainter.setAntiAliasPolygonFill(config->getBool("antiAliasing", true)); dbPainter.setPaintColor(foregroundC); dbPainter.setFillStyle(KisPainter::FillStyleForegroundColor); dbPainter.setCompositeOp(device->colorSpace()->compositeOp(COMPOSITE_OVER)); quint8 eightbit = 255; if (config->getBool("invert", false)) { eightbit = 0; } QRect cellRect(applyRect.topLeft()-QPoint(qFloor(cellSpacingH), qFloor(qMax(cellSpacingV, diameter))), applyRect.bottomRight()+QPoint(qCeil(cellSpacingH), qCeil(qMax(cellSpacingV, diameter)))); for (int i=0; imoveTo(center.x(), center.y()); quint8 intensity = device->colorSpace()->intensity8(itterator->oldRawData()); qreal size = diameter*((qAbs(intensity-eightbit))/255.0); QPoint sPoint(qMax(qFloor(samplePoint.x()), applyRect.left()), qMax(qFloor(samplePoint.y()), applyRect.top())); dbPainter.bitBlt(0, 0, device, sPoint.x(), sPoint.y(), diameter, diameter); dbPainter.paintEllipse((samplePoint.x()-qFloor(samplePoint.x()))+qCeil(size)-size, (samplePoint.y()-qFloor(samplePoint.y()))+qCeil(size)-size, size, size); dab->crop(qAbs(qMin(0, xdifference)), qAbs(qMin(0, ydifference)), diameter, diameter); //we only want to paint the bits actually in the apply rect...) painter.bitBlt(sPoint, dab, dab->exactBounds()); if (progressUpdater) { progressUpdater->setValue(i); } } } alpha->pixelSelection()->invert(); device->clearSelection(alpha); } KisFilterConfigurationSP KisHalftoneFilter::factoryConfiguration() const { KisFilterConfigurationSP config = new KisFilterConfiguration("halftone", 1); config->setProperty("cellSize", 8.0); config->setProperty("patternAngle", 45.0); QVariant v; KoColor black; black.fromQColor(QColor(Qt::black)); v.setValue(black); config->setProperty("foreGroundColor", v); KoColor white; white.fromQColor(QColor(Qt::white)); v.setValue(white); config->setProperty("backGroundColor", v); config->setProperty("antiAliasing", true); config->setProperty("invert", false); return config; } -KisConfigWidget *KisHalftoneFilter::createConfigurationWidget(QWidget *parent, const KisPaintDeviceSP dev) const +KisConfigWidget *KisHalftoneFilter::createConfigurationWidget(QWidget *parent, const KisPaintDeviceSP dev, bool) const { return new KisHalftoneConfigWidget(parent, dev); } //----------config---------// KisHalftoneConfigWidget::KisHalftoneConfigWidget(QWidget *parent, KisPaintDeviceSP dev) : KisConfigWidget(parent) { Q_ASSERT(dev); m_page.setupUi(this); KoColor white(Qt::white, dev->colorSpace()); KoColor black(Qt::black, dev->colorSpace()); m_page.bnforeground->setColor(white); m_page.bnbackground->setColor(black); m_page.bnforeground->setDefaultColor(white); m_page.bnbackground->setDefaultColor(black); m_page.sld_cellSize->setRange(3, 90); connect(m_page.sld_cellSize, SIGNAL(valueChanged(int)), SLOT(slotConfigChanged())); connect(m_page.dial_angle, SIGNAL(valueChanged(int)), m_page.spb_angle, SLOT(setValue(int))); connect(m_page.dial_angle, SIGNAL(valueChanged(int)), SLOT(slotConfigChanged())); connect(m_page.spb_angle, SIGNAL(valueChanged(int)), SLOT(slotConfigChanged())); connect(m_page.bnforeground, SIGNAL(changed(KoColor)), SLOT(slotConfigChanged())); connect(m_page.bnbackground, SIGNAL(changed(KoColor)), SLOT(slotConfigChanged())); connect(m_page.ckbAntialiasing, SIGNAL(toggled(bool)), SLOT(slotConfigChanged())); connect(m_page.ckbInvert, SIGNAL(toggled(bool)), SLOT(slotConfigChanged())); } KisHalftoneConfigWidget::~KisHalftoneConfigWidget() { } KisPropertiesConfigurationSP KisHalftoneConfigWidget::configuration() const { KisFilterConfiguration *config = new KisFilterConfiguration("halftone", 1); config->setProperty("cellSize", m_page.sld_cellSize->value()); config->setProperty("patternAngle", m_page.spb_angle->value()); QVariant v; v.setValue(m_page.bnforeground->color()); config->setProperty("foreGroundColor", v); v.setValue(m_page.bnbackground->color()); config->setProperty("backGroundColor", v); config->setProperty("antiAliasing", m_page.ckbAntialiasing->isChecked()); config->setProperty("invert", m_page.ckbInvert->isChecked()); return config; } void KisHalftoneConfigWidget::setConfiguration(const KisPropertiesConfigurationSP config) { QVariant value; if (config->getProperty("cellSize", value)) { m_page.sld_cellSize->setValue(value.toUInt()); } if (config->getProperty("patternAngle", value)) { m_page.dial_angle->setValue(value.toUInt()); m_page.spb_angle->setValue(value.toUInt()); } if (config->getProperty("antiAliasing", value)) { m_page.ckbAntialiasing->setChecked(value.toBool()); } if (config->getProperty("invert", value)) { m_page.ckbInvert->setChecked(value.toBool()); } m_page.bnforeground->setColor(config->getColor("foreGroundColor",m_page.bnforeground->defaultColor())); m_page.bnbackground->setColor(config->getColor("backGroundColor",m_page.bnbackground->defaultColor())); } #include "kis_halftone_filter.moc" diff --git a/plugins/filters/halftone/kis_halftone_filter.h b/plugins/filters/halftone/kis_halftone_filter.h index e54a558d65..6fe36b2f61 100644 --- a/plugins/filters/halftone/kis_halftone_filter.h +++ b/plugins/filters/halftone/kis_halftone_filter.h @@ -1,101 +1,101 @@ /* * This file is part of Krita * * Copyright (c) 2016 Wolthera van Hövell tot Westerflier * * 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-1301, USA. */ #ifndef KISHALFTONEFILTER_H #define KISHALFTONEFILTER_H #include #include #include #include #include "ui_wdg_halftone_filter.h" class WdgHalftone; class KritaHalftone : public QObject { Q_OBJECT public: KritaHalftone(QObject *parent, const QVariantList &); ~KritaHalftone() override; }; /** * @brief The kisHalftoneFilter class * This filter will allow the user to input an image and have it be approximated with * a halftone pattern. https://en.wikipedia.org/wiki/Halftone * * The primary usecase of such a filter is for specialized printing techniques, but for * many people the half-tone pattern also serves as a neutral pattern that is more pleasant * than plain flat look. The half tone in this case also becomes a stylistic technique. * * Based on that, there's a few ways a user could want to use this technique: * 1. Per-component. Per patch, each component will have a halftone approximated. * 2. Intensity only. The relative luminosity of the patch is determined and will be used * for the approximation, resulting in a black/white pattern. * 3. Intensity and then two colors mapped to the black/white pattern. * * On top of that, the pattern can be rotated, the shape can be chosen, and the user will want to * decide whether or not to use antialiasing(as printers themselves give * inefficient results with anti-aliasing). * * As of currently, 2 and 3 can be done. 1 is not impossible to code with some creative usage of composite * modes, but might be a little slow. */ class KisHalftoneFilter : public KisFilter { public: KisHalftoneFilter(); static inline KoID id() { return KoID("halftone", i18n("Halftone")); } void processImpl(KisPaintDeviceSP device, const QRect& applyRect, const KisFilterConfigurationSP config, KoUpdater *progressUpdater) const override; KisFilterConfigurationSP factoryConfiguration() const override; - KisConfigWidget *createConfigurationWidget(QWidget *parent, const KisPaintDeviceSP dev) const override; + KisConfigWidget *createConfigurationWidget(QWidget *parent, const KisPaintDeviceSP dev, bool useForMasks) const override; private: QPolygonF m_gridPoints; }; class KisHalftoneConfigWidget : public KisConfigWidget { Q_OBJECT public: KisHalftoneConfigWidget(QWidget *parent, KisPaintDeviceSP dev); ~KisHalftoneConfigWidget() override; KisPropertiesConfigurationSP configuration() const override; void setConfiguration(const KisPropertiesConfigurationSP config) override; Ui::WdgHalftone m_page; }; #endif // KISHALFTONEFILTER_H diff --git a/plugins/filters/imageenhancement/kis_simple_noise_reducer.cpp b/plugins/filters/imageenhancement/kis_simple_noise_reducer.cpp index 3cfa603622..fccafd3542 100644 --- a/plugins/filters/imageenhancement/kis_simple_noise_reducer.cpp +++ b/plugins/filters/imageenhancement/kis_simple_noise_reducer.cpp @@ -1,113 +1,113 @@ /* * Copyright (c) 2005 Cyrille Berger * * 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-1301, USA. */ #include //MSVC requires that Vc come first #include "kis_simple_noise_reducer.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include KisSimpleNoiseReducer::KisSimpleNoiseReducer() : KisFilter(id(), FiltersCategoryEnhanceId, i18n("&Gaussian Noise Reduction...")) { setSupportsPainting(false); } KisSimpleNoiseReducer::~KisSimpleNoiseReducer() { } -KisConfigWidget * KisSimpleNoiseReducer::createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev) const +KisConfigWidget * KisSimpleNoiseReducer::createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev, bool) const { Q_UNUSED(dev); vKisIntegerWidgetParam param; param.push_back(KisIntegerWidgetParam(0, 255, 15, i18n("Threshold"), "threshold")); param.push_back(KisIntegerWidgetParam(0, 10, 1, i18n("Window size"), "windowsize")); return new KisMultiIntegerFilterWidget(id().id(), parent, id().id(), param); } KisFilterConfigurationSP KisSimpleNoiseReducer::factoryConfiguration() const { KisFilterConfigurationSP config = new KisFilterConfiguration(id().id(), 0); config->setProperty("threshold", 15); config->setProperty("windowsize", 1); return config; } inline int ABS(int v) { if (v < 0) return -v; return v; } void KisSimpleNoiseReducer::processImpl(KisPaintDeviceSP device, const QRect& applyRect, const KisFilterConfigurationSP _config, KoUpdater* progressUpdater ) const { QPoint srcTopLeft = applyRect.topLeft(); Q_ASSERT(device); KisFilterConfigurationSP config = _config ? _config : defaultConfiguration(); const int threshold = config->getInt("threshold", 15); const int windowsize = config->getInt("windowsize", 1); const KoColorSpace* cs = device->colorSpace(); // Compute the blur mask KisCircleMaskGenerator* kas = new KisCircleMaskGenerator(2*windowsize + 1, 1, windowsize, windowsize, 2, true); KisConvolutionKernelSP kernel = KisConvolutionKernel::fromMaskGenerator(kas); delete kas; KisPaintDeviceSP interm = new KisPaintDevice(*device); // TODO no need for a full copy and then a transaction KisConvolutionPainter painter(interm); painter.beginTransaction(); painter.applyMatrix(kernel, interm, srcTopLeft, srcTopLeft, applyRect.size(), BORDER_REPEAT); painter.deleteTransaction(); KisSequentialConstIteratorProgress intermIt(interm, applyRect, progressUpdater); KisSequentialIterator dstIt(device, applyRect); while (dstIt.nextPixel() && intermIt.nextPixel()) { const quint8 diff = cs->difference(dstIt.oldRawData(), intermIt.oldRawData()); if (diff > threshold) { memcpy(dstIt.rawData(), intermIt.oldRawData(), cs->pixelSize()); } } } diff --git a/plugins/filters/imageenhancement/kis_simple_noise_reducer.h b/plugins/filters/imageenhancement/kis_simple_noise_reducer.h index 6ceb3e27b3..2766507f16 100644 --- a/plugins/filters/imageenhancement/kis_simple_noise_reducer.h +++ b/plugins/filters/imageenhancement/kis_simple_noise_reducer.h @@ -1,48 +1,48 @@ /* a * Copyright (c) 2005 Cyrille Berger * * 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-1301, USA. */ #ifndef KISSIMPLENOISEREDUCER_H #define KISSIMPLENOISEREDUCER_H #include #include "kis_config_widget.h" /** @author Cyrille Berger */ class KisSimpleNoiseReducer : public KisFilter { public: KisSimpleNoiseReducer(); ~KisSimpleNoiseReducer() override; public: void processImpl(KisPaintDeviceSP device, const QRect& applyRect, const KisFilterConfigurationSP config, KoUpdater* progressUpdater ) const override; - KisConfigWidget * createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev) const override; + KisConfigWidget * createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev, bool useForMasks) const override; static inline KoID id() { return KoID("gaussiannoisereducer", i18n("Gaussian Noise Reducer")); } protected: KisFilterConfigurationSP factoryConfiguration() const override; }; #endif diff --git a/plugins/filters/imageenhancement/kis_wavelet_noise_reduction.cpp b/plugins/filters/imageenhancement/kis_wavelet_noise_reduction.cpp index 639e146a37..14df748383 100644 --- a/plugins/filters/imageenhancement/kis_wavelet_noise_reduction.cpp +++ b/plugins/filters/imageenhancement/kis_wavelet_noise_reduction.cpp @@ -1,125 +1,125 @@ /* * This file is part of the KDE project * * Copyright (c) 2005 Cyrille Berger * 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-1301, USA. */ #include "kis_wavelet_noise_reduction.h" #include #include #include #include #include #include #include #include #include #include #include "kis_global.h" KisWaveletNoiseReduction::KisWaveletNoiseReduction() : KisFilter(id(), FiltersCategoryEnhanceId, i18n("&Wavelet Noise Reducer...")) { setSupportsPainting(false); setSupportsThreading(false); } KisWaveletNoiseReduction::~KisWaveletNoiseReduction() { } -KisConfigWidget * KisWaveletNoiseReduction::createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP) const +KisConfigWidget * KisWaveletNoiseReduction::createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP, bool) const { vKisDoubleWidgetParam param; param.push_back(KisDoubleWidgetParam(0.0, 256.0, BEST_WAVELET_THRESHOLD_VALUE, i18n("Threshold"), "threshold")); return new KisMultiDoubleFilterWidget(id().id(), parent, id().id(), param); } KisFilterConfigurationSP KisWaveletNoiseReduction::factoryConfiguration() const { KisFilterConfigurationSP config = new KisFilterConfiguration(id().id(), 0); config->setProperty("threshold", BEST_WAVELET_THRESHOLD_VALUE); return config; } void KisWaveletNoiseReduction::processImpl(KisPaintDeviceSP device, const QRect& applyRect, const KisFilterConfigurationSP _config, KoUpdater* progressUpdater ) const { Q_ASSERT(device); KisFilterConfigurationSP config = _config ? _config : defaultConfiguration(); const float threshold = config->getDouble("threshold", BEST_WAVELET_THRESHOLD_VALUE); KisMathToolbox mathToolbox; // dbgFilters << size <<"" << maxrectsize <<"" << srcTopLeft.x() <<"" << srcTopLeft.y(); // dbgFilters <<"Transforming..."; KisMathToolbox::KisWavelet* buff = 0; KisMathToolbox::KisWavelet* wav = 0; try { buff = mathToolbox.initWavelet(device, applyRect); } catch (const std::bad_alloc&) { if (buff) delete buff; return; } try { wav = mathToolbox.fastWaveletTransformation(device, applyRect, buff); } catch (const std::bad_alloc&) { if (wav) delete wav; return; } float* const fin = wav->coeffs + wav->depth * pow2(wav->size); float* const begin = wav->coeffs + wav->depth; const int size = fin - begin; const int progressOffset = int(std::ceil(std::log2(size / 100))); const int progressMask = (1 << progressOffset) - 1; const int numProgressSteps = size >> progressOffset; int pointsProcessed = 0; progressUpdater->setRange(0, numProgressSteps); for (float* it = begin; it < fin; it++) { if (*it > threshold) { *it -= threshold; } else if (*it < -threshold) { *it += threshold; } else { *it = 0.; } if (!(pointsProcessed & progressMask)) { progressUpdater->setValue(pointsProcessed >> progressOffset); } pointsProcessed++; } mathToolbox.fastWaveletUntransformation(device, applyRect, wav, buff); delete wav; delete buff; } diff --git a/plugins/filters/imageenhancement/kis_wavelet_noise_reduction.h b/plugins/filters/imageenhancement/kis_wavelet_noise_reduction.h index 9657d4329b..76665787cf 100644 --- a/plugins/filters/imageenhancement/kis_wavelet_noise_reduction.h +++ b/plugins/filters/imageenhancement/kis_wavelet_noise_reduction.h @@ -1,57 +1,57 @@ /* * This file is part of the KDE project * * Copyright (c) 2005 Cyrille Berger * 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-1301, USA. */ #ifndef KIS_WAVELET_NOISE_REDUCTION_H #define KIS_WAVELET_NOISE_REDUCTION_H #include #include #define BEST_WAVELET_THRESHOLD_VALUE 7.0 /** @author Cyrille Berger */ class KisWaveletNoiseReduction : public KisFilter { public: KisWaveletNoiseReduction(); ~KisWaveletNoiseReduction() override; public: void processImpl(KisPaintDeviceSP device, const QRect& applyRect, const KisFilterConfigurationSP config, KoUpdater* progressUpdater ) const override; - KisConfigWidget * createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev) const override; + KisConfigWidget * createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev, bool useForMasks) const override; static inline KoID id() { return KoID("waveletnoisereducer", i18n("Wavelet Noise Reducer")); } private: KisFilterConfigurationSP factoryConfiguration() const override; }; #endif diff --git a/plugins/filters/indexcolors/indexcolors.cpp b/plugins/filters/indexcolors/indexcolors.cpp index 6ab5a6f1eb..67d532ed24 100644 --- a/plugins/filters/indexcolors/indexcolors.cpp +++ b/plugins/filters/indexcolors/indexcolors.cpp @@ -1,145 +1,145 @@ /* * Copyright 2014 Manuel Riecke * * Permission to use, copy, modify, and distribute this software * and its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice appear in all * copies and that both that the copyright notice and this * permission notice and warranty disclaimer appear in supporting * documentation, and that the name of the author not be used in * advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * * The author disclaim all warranties with regard to this * software, including all implied warranties of merchantability * and fitness. In no event shall the author be liable for any * special, indirect or consequential damages or any damages * whatsoever resulting from loss of use, data or profits, whether * in an action of contract, negligence or other tortious action, * arising out of or in connection with the use or performance of * this software. */ #include "indexcolors.h" #include #include #include #include #include #include #include #include #include "kiswdgindexcolors.h" #include "palettegeneratorconfig.h" K_PLUGIN_FACTORY_WITH_JSON(IndexColorsFactory, "kritaindexcolors.json", registerPlugin();) IndexColors::IndexColors(QObject *parent, const QVariantList &) : QObject(parent) { KisFilterRegistry::instance()->add(KisFilterSP(new KisFilterIndexColors())); } IndexColors::~IndexColors() { } KisFilterIndexColors::KisFilterIndexColors() : KisColorTransformationFilter(id(), FiltersCategoryArtisticId, i18n("&Index Colors...")) { setColorSpaceIndependence(FULLY_INDEPENDENT); // Technically it is TO_LAB16 but that would only display a warning we don't want // This filter will always degrade the color space, that is it's purpose setSupportsPainting(true); setShowConfigurationWidget(true); } KoColorTransformation* KisFilterIndexColors::createTransformation(const KoColorSpace* cs, const KisFilterConfigurationSP config) const { IndexColorPalette pal; PaletteGeneratorConfig palCfg; palCfg.fromByteArray(config->getProperty("paletteGen").toByteArray()); pal = palCfg.generate(); if(config->getBool("reduceColorsEnabled")) { int maxClrs = config->getInt("colorLimit"); while(pal.numColors() > maxClrs) pal.mergeMostReduantColors(); } pal.similarityFactors.L = config->getFloat("LFactor"); pal.similarityFactors.a = config->getFloat("aFactor"); pal.similarityFactors.b = config->getFloat("bFactor"); return new KisIndexColorTransformation(pal, cs, config->getInt("alphaSteps")); } -KisConfigWidget* KisFilterIndexColors::createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev) const +KisConfigWidget* KisFilterIndexColors::createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev, bool) const { Q_UNUSED(dev); KisWdgIndexColors* w = new KisWdgIndexColors(parent); w->setup( QStringList() << i18nc("Color palette shade", "Bright") << i18nc("Color palette shade", "Light") << i18nc("Color palette shade", "Base") << i18nc("Color palette shade", "Shadow") , 4 ); return w; } KisFilterConfigurationSP KisFilterIndexColors::factoryConfiguration() const { KisColorTransformationConfigurationSP config = new KisColorTransformationConfiguration(id().id(), 0); PaletteGeneratorConfig palCfg; // Default constructor is factory config config->setProperty("paletteGen", palCfg.toByteArray()); config->setProperty("LFactor", 1.f); config->setProperty("aFactor", 1.f); config->setProperty("bFactor", 1.f); config->setProperty("reduceColorsEnabled", false); config->setProperty("colorLimit", 32); config->setProperty("alphaSteps", 1); return config; } KisIndexColorTransformation::KisIndexColorTransformation(IndexColorPalette palette, const KoColorSpace* cs, int alphaSteps) : m_colorSpace(cs), m_psize(cs->pixelSize()) { m_palette = palette; static const qreal max = KoColorSpaceMathsTraits::max; if(alphaSteps > 0) { m_alphaStep = max / alphaSteps; m_alphaHalfStep = m_alphaStep / 2; } else { m_alphaStep = 0; m_alphaHalfStep = 0; } } void KisIndexColorTransformation::transform(const quint8* src, quint8* dst, qint32 nPixels) const { union { quint16 laba[4]; LabColor lab; } clr; while (nPixels--) { m_colorSpace->toLabA16(src, reinterpret_cast(clr.laba), 1); clr.lab = m_palette.getNearestIndex(clr.lab); if(m_alphaStep) { quint16 amod = clr.laba[3] % m_alphaStep; clr.laba[3] = clr.laba[3] + (amod > m_alphaHalfStep ? m_alphaStep - amod : -amod); } m_colorSpace->fromLabA16(reinterpret_cast(clr.laba), dst, 1); src += m_psize; dst += m_psize; } } #include "indexcolors.moc" diff --git a/plugins/filters/indexcolors/indexcolors.h b/plugins/filters/indexcolors/indexcolors.h index 316382ff91..dae51d49cf 100644 --- a/plugins/filters/indexcolors/indexcolors.h +++ b/plugins/filters/indexcolors/indexcolors.h @@ -1,69 +1,69 @@ /* * Copyright 2014 Manuel Riecke * * Permission to use, copy, modify, and distribute this software * and its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice appear in all * copies and that both that the copyright notice and this * permission notice and warranty disclaimer appear in supporting * documentation, and that the name of the author not be used in * advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * * The author disclaim all warranties with regard to this * software, including all implied warranties of merchantability * and fitness. In no event shall the author be liable for any * special, indirect or consequential damages or any damages * whatsoever resulting from loss of use, data or profits, whether * in an action of contract, negligence or other tortious action, * arising out of or in connection with the use or performance of * this software. */ #ifndef INDEXCOLORS_H #define INDEXCOLORS_H #include #include #include "filter/kis_color_transformation_filter.h" #include "kis_config_widget.h" #include #include "indexcolorpalette.h" class IndexColors : public QObject { Q_OBJECT public: IndexColors(QObject *parent, const QVariantList &); ~IndexColors() override; }; class KisFilterIndexColors : public KisColorTransformationFilter { public: KisFilterIndexColors(); public: KoColorTransformation* createTransformation(const KoColorSpace* cs, const KisFilterConfigurationSP config) const override; - KisConfigWidget* createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev) const override; + KisConfigWidget* createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev, bool useForMasks) const override; static inline KoID id() { return KoID("indexcolors", i18n("Index Colors")); } protected: KisFilterConfigurationSP factoryConfiguration() const override; }; class KisIndexColorTransformation : public KoColorTransformation { public: KisIndexColorTransformation(IndexColorPalette palette, const KoColorSpace* cs, int alphaSteps); void transform(const quint8* src, quint8* dst, qint32 nPixels) const override; private: const KoColorSpace* m_colorSpace; quint32 m_psize; IndexColorPalette m_palette; quint16 m_alphaStep; quint16 m_alphaHalfStep; }; #endif diff --git a/plugins/filters/levelfilter/kis_level_filter.cpp b/plugins/filters/levelfilter/kis_level_filter.cpp index 4c6ff36a40..4e37018236 100644 --- a/plugins/filters/levelfilter/kis_level_filter.cpp +++ b/plugins/filters/levelfilter/kis_level_filter.cpp @@ -1,345 +1,345 @@ /* * This file is part of Krita * * Copyright (c) 2006 Frederic Coiffier * * 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-1301, USA. */ #include "kis_level_filter.h" #include #include #include #include #include #include #include #include #include #include #include #include "kis_paint_device.h" #include "kis_histogram.h" #include "kis_painter.h" #include "KisGradientSlider.h" #include "kis_processing_information.h" #include "kis_selection.h" #include "kis_types.h" #include #include "filter/kis_color_transformation_configuration.h" KisLevelFilter::KisLevelFilter() : KisColorTransformationFilter(id(), FiltersCategoryAdjustId, i18n("&Levels...")) { setShortcut(QKeySequence(Qt::CTRL + Qt::Key_L)); setSupportsPainting(false); setColorSpaceIndependence(TO_LAB16); } KisLevelFilter::~KisLevelFilter() { } -KisConfigWidget * KisLevelFilter::createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev) const +KisConfigWidget * KisLevelFilter::createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev, bool) const { return new KisLevelConfigWidget(parent, dev); } KoColorTransformation* KisLevelFilter::createTransformation(const KoColorSpace* cs, const KisFilterConfigurationSP config) const { if (!config) { warnKrita << "No configuration object for level filter\n"; return 0; } Q_ASSERT(config); int blackvalue = config->getInt("blackvalue"); int whitevalue = config->getInt("whitevalue", 255); double gammavalue = config->getDouble("gammavalue", 1.0); int outblackvalue = config->getInt("outblackvalue"); int outwhitevalue = config->getInt("outwhitevalue", 255); quint16 transfer[256]; for (int i = 0; i < 256; i++) { if (i <= blackvalue) transfer[i] = outblackvalue; else if (i < whitevalue) { double a = (double)(i - blackvalue) / (double)(whitevalue - blackvalue); a = (double)(outwhitevalue - outblackvalue) * pow(a, (1.0 / gammavalue)); transfer[i] = int(outblackvalue + a); } else transfer[i] = outwhitevalue; // TODO use floats instead of integer in the configuration transfer[i] = ((int)transfer[i] * 0xFFFF) / 0xFF ; } return cs->createBrightnessContrastAdjustment(transfer); } KisLevelConfigWidget::KisLevelConfigWidget(QWidget * parent, KisPaintDeviceSP dev) : KisConfigWidget(parent) { Q_ASSERT(dev); m_page.setupUi(this); m_page.ingradient->enableGamma(true); m_page.blackspin->setValue(0); m_page.whitespin->setValue(255); m_page.gammaspin->setValue(1.0); m_page.ingradient->slotModifyGamma(1.0); m_page.outblackspin->setValue(0); m_page.outwhitespin->setValue(255); connect(m_page.blackspin, SIGNAL(valueChanged(int)), SIGNAL(sigConfigurationItemChanged())); connect(m_page.whitespin, SIGNAL(valueChanged(int)), SIGNAL(sigConfigurationItemChanged())); connect(m_page.ingradient, SIGNAL(sigModifiedGamma(double)), SIGNAL(sigConfigurationItemChanged())); connect(m_page.blackspin, SIGNAL(valueChanged(int)), m_page.ingradient, SLOT(slotModifyBlack(int))); connect(m_page.whitespin, SIGNAL(valueChanged(int)), m_page.ingradient, SLOT(slotModifyWhite(int))); connect(m_page.gammaspin, SIGNAL(valueChanged(double)), m_page.ingradient, SLOT(slotModifyGamma(double))); connect(m_page.blackspin, SIGNAL(valueChanged(int)), this, SLOT(slotModifyInWhiteLimit(int))); connect(m_page.whitespin, SIGNAL(valueChanged(int)), this, SLOT(slotModifyInBlackLimit(int))); connect(m_page.ingradient, SIGNAL(sigModifiedBlack(int)), m_page.blackspin, SLOT(setValue(int))); connect(m_page.ingradient, SIGNAL(sigModifiedWhite(int)), m_page.whitespin, SLOT(setValue(int))); connect(m_page.ingradient, SIGNAL(sigModifiedGamma(double)), m_page.gammaspin, SLOT(setValue(double))); connect(m_page.outblackspin, SIGNAL(valueChanged(int)), SIGNAL(sigConfigurationItemChanged())); connect(m_page.outwhitespin, SIGNAL(valueChanged(int)), SIGNAL(sigConfigurationItemChanged())); connect(m_page.outblackspin, SIGNAL(valueChanged(int)), m_page.outgradient, SLOT(slotModifyBlack(int))); connect(m_page.outwhitespin, SIGNAL(valueChanged(int)), m_page.outgradient, SLOT(slotModifyWhite(int))); connect(m_page.outblackspin, SIGNAL(valueChanged(int)), this, SLOT(slotModifyOutWhiteLimit(int))); connect(m_page.outwhitespin, SIGNAL(valueChanged(int)), this, SLOT(slotModifyOutBlackLimit(int))); connect(m_page.outgradient, SIGNAL(sigModifiedBlack(int)), m_page.outblackspin, SLOT(setValue(int))); connect(m_page.outgradient, SIGNAL(sigModifiedWhite(int)), m_page.outwhitespin, SLOT(setValue(int))); connect(m_page.butauto, SIGNAL(clicked(bool)), this, SLOT(slotAutoLevel())); connect(m_page.butinvert, SIGNAL(clicked(bool)), this, SLOT(slotInvert())); connect((QObject*)(m_page.chkLogarithmic), SIGNAL(toggled(bool)), this, SLOT(slotDrawHistogram(bool))); KoHistogramProducer *producer = new KoGenericLabHistogramProducer(); m_histogram.reset( new KisHistogram(dev, dev->exactBounds(), producer, LINEAR) ); m_isLogarithmic = false; //m_page.histview->resize(288,100); m_inverted = false; slotDrawHistogram(m_page.chkLogarithmic->isChecked()); } KisLevelConfigWidget::~KisLevelConfigWidget() { } void KisLevelConfigWidget::slotDrawHistogram(bool isLogarithmic) { int wHeight = m_page.histview->height(); int wHeightMinusOne = wHeight - 1; int wWidth = m_page.histview->width(); if (m_isLogarithmic != isLogarithmic) { // Update the m_histogram if (isLogarithmic) m_histogram->setHistogramType(LOGARITHMIC); else m_histogram->setHistogramType(LINEAR); m_isLogarithmic = isLogarithmic; } QPalette appPalette = QApplication::palette(); QPixmap pix(wWidth, wHeight); pix.fill(QColor(appPalette.color(QPalette::Base))); QPainter p(&pix); p.setPen(QPen(Qt::gray, 1, Qt::SolidLine)); double highest = (double)m_histogram->calculations().getHighest(); qint32 bins = m_histogram->producer()->numberOfBins(); // use nearest neighbour interpolation if (m_histogram->getHistogramType() == LINEAR) { double factor = (double)(wHeight - wHeight / 5.0) / highest; for (int i = 0; i < wWidth; i++) { int binNo = qRound((double)i / wWidth * (bins - 1)); if ((int)m_histogram->getValue(binNo) != 0) p.drawLine(i, wHeightMinusOne, i, wHeightMinusOne - (int)m_histogram->getValue(binNo) * factor); } } else { double factor = (double)(wHeight - wHeight / 5.0) / (double)log(highest); for (int i = 0; i < wWidth; i++) { int binNo = qRound((double)i / wWidth * (bins - 1)) ; if ((int)m_histogram->getValue(binNo) != 0) p.drawLine(i, wHeightMinusOne, i, wHeightMinusOne - log((double)m_histogram->getValue(binNo)) * factor); } } m_page.histview->setPixmap(pix); } void KisLevelConfigWidget::slotModifyInBlackLimit(int limit) { m_page.blackspin->setMaximum(limit - 1); } void KisLevelConfigWidget::slotModifyInWhiteLimit(int limit) { m_page.whitespin->setMinimum(limit + 1); } void KisLevelConfigWidget::slotModifyOutBlackLimit(int limit) { if (m_inverted) { m_page.outblackspin->setMinimum(limit + 1); } else { m_page.outblackspin->setMaximum(limit - 1); } } void KisLevelConfigWidget::slotModifyOutWhiteLimit(int limit) { if (m_inverted) { m_page.outwhitespin->setMaximum(limit - 1); } else { m_page.outwhitespin->setMinimum(limit + 1); } } void KisLevelConfigWidget::slotAutoLevel(void) { Q_ASSERT(m_histogram); qint32 num_bins = m_histogram->producer()->numberOfBins(); Q_ASSERT(num_bins > 1); int chosen_low_bin = 0, chosen_high_bin = num_bins-1; int count_thus_far = m_histogram->getValue(0); const int total_count = m_histogram->producer()->count(); const double threshold = 0.006; // find the low and hi point/bins based on summing count percentages // // this implementation is a port of GIMP's auto level implementation // (use a GPLv2 version as reference, specifically commit 51bfd07f18ef045a3e43632218fd92cae9ff1e48) for (int bin=0; bin<(num_bins-1); ++bin) { int next_count_thus_far = count_thus_far + m_histogram->getValue(bin+1); double this_percentage = static_cast(count_thus_far) / total_count; double next_percentage = static_cast(next_count_thus_far) / total_count; //dbgKrita << "bin" << bin << "this_percentage" << this_percentage << "next_percentage" << next_percentage; if (fabs(this_percentage - threshold) < fabs(next_percentage - threshold)) { chosen_low_bin = bin; break; } count_thus_far = next_count_thus_far; } count_thus_far = m_histogram->getValue(num_bins-1); for (int bin=(num_bins-1); bin>0; --bin) { int next_count_thus_far = count_thus_far + m_histogram->getValue(bin-1); double this_percentage = static_cast(count_thus_far) / total_count; double next_percentage = static_cast(next_count_thus_far) / total_count; //dbgKrita << "hi-bin" << bin << "this_percentage" << this_percentage << "next_percentage" << next_percentage; if (fabs(this_percentage - threshold) < fabs(next_percentage - threshold)) { chosen_high_bin = bin; break; } count_thus_far = next_count_thus_far; } if (chosen_low_bin < chosen_high_bin) { m_page.blackspin->setValue(chosen_low_bin); m_page.ingradient->slotModifyBlack(chosen_low_bin); m_page.whitespin->setValue(chosen_high_bin); m_page.ingradient->slotModifyWhite(chosen_high_bin); } } void KisLevelConfigWidget::slotInvert(void) { m_inverted = !m_inverted; int white = m_page.outwhitespin->value(); int black = m_page.outblackspin->value(); resetOutSpinLimit(); m_page.outgradient->setInverted(m_inverted); m_page.outwhitespin->setValue(black); m_page.outblackspin->setValue(white); } KisPropertiesConfigurationSP KisLevelConfigWidget::configuration() const { KisColorTransformationConfiguration * config = new KisColorTransformationConfiguration(KisLevelFilter::id().id(), 1); config->setProperty("blackvalue", m_page.blackspin->value()); config->setProperty("whitevalue", m_page.whitespin->value()); config->setProperty("gammavalue", m_page.gammaspin->value()); config->setProperty("outblackvalue", m_page.outblackspin->value()); config->setProperty("outwhitevalue", m_page.outwhitespin->value()); return config; } void KisLevelConfigWidget::setConfiguration(const KisPropertiesConfigurationSP config) { QVariant value; if (config->getProperty("blackvalue", value)) { m_page.blackspin->setValue(value.toUInt()); m_page.ingradient->slotModifyBlack(value.toUInt()); } if (config->getProperty("whitevalue", value)) { m_page.whitespin->setValue(value.toUInt()); m_page.ingradient->slotModifyWhite(value.toUInt()); } if (config->getProperty("gammavalue", value)) { m_page.gammaspin->setValue(value.toUInt()); m_page.ingradient->slotModifyGamma(value.toDouble()); } if (config->getProperty("outblackvalue", value)) { m_page.outblackspin->setValue(value.toUInt()); m_page.outgradient->slotModifyBlack(value.toUInt()); } if (config->getProperty("outwhitevalue", value)) { m_page.outwhitespin->setValue(value.toUInt()); m_page.outgradient->slotModifyWhite(value.toUInt()); } } void KisLevelConfigWidget::resetOutSpinLimit() { if (m_inverted) { m_page.outblackspin->setMaximum(255); m_page.outwhitespin->setMinimum(0); } else { m_page.outblackspin->setMinimum(0); m_page.outwhitespin->setMaximum(255); } } diff --git a/plugins/filters/levelfilter/kis_level_filter.h b/plugins/filters/levelfilter/kis_level_filter.h index ce0dd3ef54..b7a6a269ef 100644 --- a/plugins/filters/levelfilter/kis_level_filter.h +++ b/plugins/filters/levelfilter/kis_level_filter.h @@ -1,88 +1,88 @@ /* * This file is part of Krita * * Copyright (c) 2006 Frederic Coiffier * * 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-1301, USA. */ #ifndef _KIS_LEVEL_FILTER_H_ #define _KIS_LEVEL_FILTER_H_ #include "filter/kis_color_transformation_filter.h" #include "kis_config_widget.h" #include "ui_wdg_level.h" class WdgLevel; class QWidget; class KisHistogram; /** * This class affect Intensity Y of the image */ class KisLevelFilter : public KisColorTransformationFilter { public: KisLevelFilter(); ~KisLevelFilter() override; public: // virtual KisFilterConfigurationSP factoryConfiguration() const; - KisConfigWidget * createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev) const override; + KisConfigWidget * createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev, bool useForMasks) const override; KoColorTransformation* createTransformation(const KoColorSpace* cs, const KisFilterConfigurationSP config) const override; static inline KoID id() { return KoID("levels", i18n("Levels")); } }; class KisLevelConfigWidget : public KisConfigWidget { Q_OBJECT public: KisLevelConfigWidget(QWidget * parent, KisPaintDeviceSP dev); ~KisLevelConfigWidget() override; KisPropertiesConfigurationSP configuration() const override; void setConfiguration(const KisPropertiesConfigurationSP config) override; Ui::WdgLevel m_page; protected Q_SLOTS: void slotDrawHistogram(bool isLogarithmic); void slotModifyInBlackLimit(int); void slotModifyInWhiteLimit(int); void slotModifyOutBlackLimit(int); void slotModifyOutWhiteLimit(int); void slotAutoLevel(void); void slotInvert(void); void resetOutSpinLimit(); protected: QScopedPointer m_histogram; bool m_isLogarithmic; bool m_inverted; }; #endif diff --git a/plugins/filters/noisefilter/noisefilter.cpp b/plugins/filters/noisefilter/noisefilter.cpp index 2dd29c3e05..78cd05028d 100644 --- a/plugins/filters/noisefilter/noisefilter.cpp +++ b/plugins/filters/noisefilter/noisefilter.cpp @@ -1,149 +1,149 @@ /* * This file is part of the KDE project * * Copyright (c) 2005 Cyrille Berger * * 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-1301, USA. */ #include "noisefilter.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "kis_wdg_noise.h" #include "ui_wdgnoiseoptions.h" #include K_PLUGIN_FACTORY_WITH_JSON(KritaNoiseFilterFactory, "kritanoisefilter.json", registerPlugin();) KritaNoiseFilter::KritaNoiseFilter(QObject *parent, const QVariantList &) : QObject(parent) { KisFilterRegistry::instance()->add(new KisFilterNoise()); } KritaNoiseFilter::~KritaNoiseFilter() { } KisFilterNoise::KisFilterNoise() : KisFilter(id(), FiltersCategoryOtherId, i18n("&Random Noise...")) { setColorSpaceIndependence(FULLY_INDEPENDENT); setSupportsPainting(true); } KisFilterConfigurationSP KisFilterNoise::factoryConfiguration() const { KisFilterConfigurationSP config = new KisFilterConfiguration("noise", 1); config->setProperty("level", 50); config->setProperty("opacity", 100); config->setProperty("seedThreshold", rand()); config->setProperty("seedRed", rand()); config->setProperty("seedGreen", rand()); config->setProperty("seedBlue", rand()); return config; } -KisConfigWidget * KisFilterNoise::createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev) const +KisConfigWidget * KisFilterNoise::createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev, bool) const { Q_UNUSED(dev); return new KisWdgNoise((KisFilter*)this, (QWidget*)parent); } void KisFilterNoise::processImpl(KisPaintDeviceSP device, const QRect& applyRect, const KisFilterConfigurationSP config, KoUpdater* progressUpdater ) const { Q_ASSERT(!device.isNull()); const KoColorSpace * cs = device->colorSpace(); QVariant value; const int level = (config && config->getProperty("level", value)) ? value.toInt() : 50; const int opacity = (config && config->getProperty("opacity", value)) ? value.toInt() : 100; quint8* interm = new quint8[cs->pixelSize()]; const double threshold = (100.0 - level) * 0.01; qint16 weights[2]; weights[0] = (255 * opacity) / 100; weights[1] = 255 - weights[0]; const quint8* pixels[2]; pixels[0] = interm; KoMixColorsOp * mixOp = cs->mixColorsOp(); int seedThreshold = rand(); int seedRed = rand(); int seedGreen = rand(); int seedBlue = rand(); if (config) { seedThreshold = config->getInt("seedThreshold", seedThreshold); seedRed = config->getInt("seedRed", seedRed); seedGreen = config->getInt("seedGreen", seedGreen); seedBlue = config->getInt("seedBlue", seedBlue); } KisRandomGenerator randt(seedThreshold); KisRandomGenerator randr(seedRed); KisRandomGenerator randg(seedGreen); KisRandomGenerator randb(seedBlue); KisSequentialIteratorProgress it(device, applyRect, progressUpdater); while (it.nextPixel()) { if (randt.doubleRandomAt(it.x(), it.y()) > threshold) { // XXX: Added static_cast to get rid of warnings QColor c = qRgb(static_cast((double)randr.doubleRandomAt(it.x(), it.y()) * 255), static_cast((double)randg.doubleRandomAt(it.x(), it.y()) * 255), static_cast((double)randb.doubleRandomAt(it.x(), it.y()) * 255)); cs->fromQColor(c, interm, 0); pixels[1] = it.oldRawData(); mixOp->mixColors(pixels, weights, 2, it.rawData()); } } delete [] interm; } #include "noisefilter.moc" diff --git a/plugins/filters/noisefilter/noisefilter.h b/plugins/filters/noisefilter/noisefilter.h index 53f6fad158..217c237ea7 100644 --- a/plugins/filters/noisefilter/noisefilter.h +++ b/plugins/filters/noisefilter/noisefilter.h @@ -1,56 +1,56 @@ /* * This file is part of Krita * * Copyright (c) 2006 Cyrille Berger * * 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-1301, USA. */ #ifndef NOISEFILTER_H #define NOISEFILTER_H #include #include #include "filter/kis_filter.h" class KisConfigWidget; class KritaNoiseFilter : public QObject { Q_OBJECT public: KritaNoiseFilter(QObject *parent, const QVariantList &); ~KritaNoiseFilter() override; }; class KisFilterNoise : public KisFilter { public: KisFilterNoise(); public: void processImpl(KisPaintDeviceSP device, const QRect& applyRect, const KisFilterConfigurationSP config, KoUpdater* progressUpdater ) const override; static inline KoID id() { return KoID("noise", i18n("Noise")); } KisFilterConfigurationSP factoryConfiguration() const override; - KisConfigWidget * createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev) const override; + KisConfigWidget * createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev, bool useForMasks) const override; }; #endif diff --git a/plugins/filters/oilpaintfilter/kis_oilpaint_filter.cpp b/plugins/filters/oilpaintfilter/kis_oilpaint_filter.cpp index 8e2bb0d81b..fa6108937b 100644 --- a/plugins/filters/oilpaintfilter/kis_oilpaint_filter.cpp +++ b/plugins/filters/oilpaintfilter/kis_oilpaint_filter.cpp @@ -1,204 +1,204 @@ /* * This file is part of Krita * * Copyright (c) 2004 Michael Thaler * Copyright (c) 2008 Cyrille Berger * * ported from digikam, Copyrighted by Gilles Caulier, * Original Oilpaint algorithm copyrighted 2004 by * Pieter Z. Voloshyn . * * 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-1301, USA. */ #include "kis_oilpaint_filter.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "widgets/kis_multi_integer_filter_widget.h" KisOilPaintFilter::KisOilPaintFilter() : KisFilter(id(), FiltersCategoryArtisticId, i18n("&Oilpaint...")) { setSupportsPainting(true); setSupportsThreading(false); setSupportsAdjustmentLayers(true); } void KisOilPaintFilter::processImpl(KisPaintDeviceSP device, const QRect& applyRect, const KisFilterConfigurationSP config, KoUpdater* progressUpdater ) const { Q_ASSERT(!device.isNull()); //read the filter configuration values from the KisFilterConfiguration object const quint32 brushSize = config ? config->getInt("brushSize", 1) : 1; const quint32 smooth = config ? config->getInt("smooth", 30) : 30; OilPaint(device, device, applyRect, brushSize, smooth, progressUpdater); } // This method have been ported from Pieter Z. Voloshyn algorithm code. /* Function to apply the OilPaint effect. * * data => The image data in RGBA mode. * w => Width of image. * h => Height of image. * BrushSize => Brush size. * Smoothness => Smooth value. * * Theory => Using MostFrequentColor function we take the main color in * a matrix and simply write at the original position. */ void KisOilPaintFilter::OilPaint(const KisPaintDeviceSP src, KisPaintDeviceSP dst, const QRect &applyRect, int BrushSize, int Smoothness, KoUpdater* progressUpdater) const { KisSequentialConstIteratorProgress it(src, applyRect, progressUpdater); KisSequentialIterator dstIt(dst, applyRect); while (it.nextPixel() && dstIt.nextPixel()) { MostFrequentColor(src, dstIt.rawData(), applyRect, it.x(), it.y(), BrushSize, Smoothness); } } // This method has been ported from Pieter Z. Voloshyn's algorithm code in Digikam. /* Function to determine the most frequent color in a matrix * * Bits => Bits array * Width => Image width * Height => Image height * X => Position horizontal * Y => Position vertical * Radius => Is the radius of the matrix to be analyzed * Intensity => Intensity to calculate * * Theory => This function creates a matrix with the analyzed pixel in * the center of this matrix and find the most frequenty color */ void KisOilPaintFilter::MostFrequentColor(KisPaintDeviceSP src, quint8* dst, const QRect& bounds, int X, int Y, int Radius, int Intensity) const { uint I; double Scale = Intensity / 255.0; // Alloc some arrays to be used uchar *IntensityCount = new uchar[(Intensity + 1) * sizeof(uchar)]; const KoColorSpace* cs = src->colorSpace(); QVector channel(cs->channelCount()); QVector* AverageChannels = new QVector[(Intensity + 1)]; // Erase the array memset(IntensityCount, 0, (Intensity + 1) * sizeof(uchar)); int startx = qMax(X - Radius, bounds.left()); int starty = qMax(Y - Radius, bounds.top()); int width = (2 * Radius) + 1; if ((startx + width - 1) > bounds.right()) width = bounds.right() - startx + 1; Q_ASSERT((startx + width - 1) <= bounds.right()); int height = (2 * Radius) + 1; if ((starty + height) > bounds.bottom()) height = bounds.bottom() - starty + 1; Q_ASSERT((starty + height - 1) <= bounds.bottom()); KisSequentialConstIterator srcIt(src, QRect(startx, starty, width, height)); while (srcIt.nextPixel()) { cs->normalisedChannelsValue(srcIt.rawDataConst(), channel); I = (uint)(cs->intensity8(srcIt.rawDataConst()) * Scale); IntensityCount[I]++; if (IntensityCount[I] == 1) { AverageChannels[I] = channel; } else { for (int i = 0; i < channel.size(); i++) { AverageChannels[I][i] += channel[i]; } } } I = 0; int MaxInstance = 0; for (int i = 0 ; i <= Intensity ; ++i) { if (IntensityCount[i] > MaxInstance) { I = i; MaxInstance = IntensityCount[i]; } } if (MaxInstance != 0) { channel = AverageChannels[I]; for (int i = 0; i < channel.size(); i++) { channel[i] /= MaxInstance; } cs->fromNormalisedChannelsValue(dst, channel); } else { memset(dst, 0, cs->pixelSize()); cs->setOpacity(dst, OPACITY_OPAQUE_U8, 1); } delete [] IntensityCount; // free all the arrays delete [] AverageChannels; } -KisConfigWidget * KisOilPaintFilter::createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP) const +KisConfigWidget * KisOilPaintFilter::createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP, bool) const { vKisIntegerWidgetParam param; param.push_back(KisIntegerWidgetParam(1, 5, 1, i18n("Brush size"), "brushSize")); param.push_back(KisIntegerWidgetParam(10, 255, 30, i18nc("smooth out the painting strokes the filter creates", "Smooth"), "smooth")); KisMultiIntegerFilterWidget * w = new KisMultiIntegerFilterWidget(id().id(), parent, id().id(), param); w->setConfiguration(factoryConfiguration()); return w; } KisFilterConfigurationSP KisOilPaintFilter::factoryConfiguration() const { KisFilterConfigurationSP config = new KisFilterConfiguration("oilpaint", 1); config->setProperty("brushSize", 1); config->setProperty("smooth", 30); return config; } diff --git a/plugins/filters/oilpaintfilter/kis_oilpaint_filter.h b/plugins/filters/oilpaintfilter/kis_oilpaint_filter.h index 6dd5134041..758dd7086a 100644 --- a/plugins/filters/oilpaintfilter/kis_oilpaint_filter.h +++ b/plugins/filters/oilpaintfilter/kis_oilpaint_filter.h @@ -1,51 +1,51 @@ /* * This file is part of the KDE project * * Copyright (c) Michael Thaler * * 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-1301, USA. */ #ifndef _KIS_OILPAINT_FILTER_H_ #define _KIS_OILPAINT_FILTER_H_ #include "filter/kis_filter.h" #include "kis_config_widget.h" class KisOilPaintFilter : public KisFilter { public: KisOilPaintFilter(); public: void processImpl(KisPaintDeviceSP device, const QRect& applyRect, const KisFilterConfigurationSP config, KoUpdater* progressUpdater ) const override; static inline KoID id() { return KoID("oilpaint", i18n("Oilpaint")); } KisFilterConfigurationSP factoryConfiguration() const override; public: - KisConfigWidget * createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev) const override; + KisConfigWidget * createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev, bool useForMasks) const override; private: void OilPaint(const KisPaintDeviceSP src, KisPaintDeviceSP dst, const QRect &applyRect, int BrushSize, int Smoothness, KoUpdater* progressUpdater) const; void MostFrequentColor(KisPaintDeviceSP src, quint8* dst, const QRect& bounds, int X, int Y, int Radius, int Intensity) const; }; #endif diff --git a/plugins/filters/phongbumpmap/kis_phong_bumpmap_filter.cpp b/plugins/filters/phongbumpmap/kis_phong_bumpmap_filter.cpp index 3c2b42c272..3ec63ea454 100644 --- a/plugins/filters/phongbumpmap/kis_phong_bumpmap_filter.cpp +++ b/plugins/filters/phongbumpmap/kis_phong_bumpmap_filter.cpp @@ -1,238 +1,238 @@ /* * Copyright (c) 2010-2011 José Luis Vergara * * 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-1301, USA. */ #include "kis_phong_bumpmap_filter.h" #include "kis_phong_bumpmap_config_widget.h" #include "phong_pixel_processor.h" #include "kis_debug.h" #include "kis_paint_device.h" #include "kis_config_widget.h" #include "KoUpdater.h" #include "kis_math_toolbox.h" #include "KoColorSpaceRegistry.h" #include #include #include #include "kis_iterator_ng.h" #include "kundo2command.h" #include "kis_painter.h" KisFilterPhongBumpmap::KisFilterPhongBumpmap() : KisFilter(KoID("phongbumpmap", i18n("Phong Bumpmap")), FiltersCategoryMapId, i18n("&Phong Bumpmap...")) { setColorSpaceIndependence(TO_LAB16); setSupportsPainting(true); setSupportsLevelOfDetail(true); } void KisFilterPhongBumpmap::processImpl(KisPaintDeviceSP device, const QRect& applyRect, const KisFilterConfigurationSP config, KoUpdater *progressUpdater ) const { if (!config) return; if (progressUpdater) progressUpdater->setProgress(0); QString userChosenHeightChannel = config->getString(PHONG_HEIGHT_CHANNEL, "FAIL"); bool m_usenormalmap = config->getBool(USE_NORMALMAP_IS_ENABLED); if (userChosenHeightChannel == "FAIL") { qDebug("FIX YOUR FILTER"); return; } KoChannelInfo *m_heightChannel = 0; Q_FOREACH (KoChannelInfo* channel, device->colorSpace()->channels()) { if (userChosenHeightChannel == channel->name()) { m_heightChannel = channel; } } if (!m_heightChannel) { m_heightChannel = device->colorSpace()->channels().first(); } KIS_ASSERT_RECOVER_RETURN(m_heightChannel); QRect inputArea = applyRect; QRect outputArea = applyRect; if (m_usenormalmap==false) { inputArea.adjust(-1, -1, 1, 1); } quint32 posup; quint32 posdown; quint32 posleft; quint32 posright; QColor I; //Reflected light if (progressUpdater) progressUpdater->setProgress(1); //======Preparation paraphlenalia======= //Hardcoded facts about Phong Bumpmap: it _will_ generate an RGBA16 bumpmap const quint8 BYTE_DEPTH_OF_BUMPMAP = 2; // 16 bits per channel const quint8 CHANNEL_COUNT_OF_BUMPMAP = 4; // RGBA const quint32 pixelsOfInputArea = abs(inputArea.width() * inputArea.height()); const quint32 pixelsOfOutputArea = abs(outputArea.width() * outputArea.height()); const quint8 pixelSize = BYTE_DEPTH_OF_BUMPMAP * CHANNEL_COUNT_OF_BUMPMAP; const quint32 bytesToFillBumpmapArea = pixelsOfOutputArea * pixelSize; QVector bumpmap(bytesToFillBumpmapArea); quint8 *bumpmapDataPointer = bumpmap.data(); quint32 ki = KoChannelInfo::displayPositionToChannelIndex(m_heightChannel->displayPosition(), device->colorSpace()->channels()); PhongPixelProcessor tileRenderer(pixelsOfInputArea, config); if (progressUpdater) progressUpdater->setProgress(2); //===============RENDER================= QVector toDoubleFuncPtr(device->colorSpace()->channels().count()); KisMathToolbox mathToolbox; if (!mathToolbox.getToDoubleChannelPtr(device->colorSpace()->channels(), toDoubleFuncPtr)) { return; } KisHLineConstIteratorSP iterator; quint32 curPixel = 0; iterator = device->createHLineConstIteratorNG(inputArea.x(), inputArea.y(), inputArea.width() ); if (m_usenormalmap==false) { for (qint32 srcRow = 0; srcRow < inputArea.height(); ++srcRow) { do { const quint8 *data = iterator->oldRawData(); tileRenderer.realheightmap[curPixel] = toDoubleFuncPtr[ki](data, device->colorSpace()->channels()[ki]->pos()); curPixel++; } while (iterator->nextPixel()); iterator->nextRow(); } if (progressUpdater) progressUpdater->setProgress(50); const int tileHeightMinus1 = inputArea.height() - 1; const int tileWidthMinus1 = inputArea.width() - 1; // Foreach INNER pixel in tile for (int y = 1; y < tileHeightMinus1; ++y) { for (int x = 1; x < tileWidthMinus1; ++x) { posup = (y + 1) * inputArea.width() + x; posdown = (y - 1) * inputArea.width() + x; posleft = y * inputArea.width() + x - 1; posright = y * inputArea.width() + x + 1; memcpy(bumpmapDataPointer, tileRenderer.IlluminatePixelFromHeightmap(posup, posdown, posleft, posright).data(), pixelSize); bumpmapDataPointer += pixelSize; } } } else { for (qint32 srcRow = 0; srcRow < inputArea.height(); ++srcRow) { do { const quint8 *data = iterator->oldRawData(); tileRenderer.realheightmap[curPixel] = toDoubleFuncPtr[ki](data, device->colorSpace()->channels()[ki]->pos()); QVector current_pixel_values(4); device->colorSpace()->normalisedChannelsValue(data, current_pixel_values ); //dbgKrita<< "Vector:" << current_pixel_values[2] << "," << current_pixel_values[1] << "," << current_pixel_values[0]; memcpy(bumpmapDataPointer, tileRenderer.IlluminatePixelFromNormalmap(current_pixel_values[2], current_pixel_values[1], current_pixel_values[0]).data(), pixelSize); curPixel++; //pointer that crashes here, but not in the other if statement. bumpmapDataPointer += pixelSize; } while (iterator->nextPixel()); iterator->nextRow(); } } if (progressUpdater) progressUpdater->setProgress(90); KisPaintDeviceSP bumpmapPaintDevice = new KisPaintDevice(KoColorSpaceRegistry::instance()->rgb16()); bumpmapPaintDevice->writeBytes(bumpmap.data(), outputArea.x(), outputArea.y(), outputArea.width(), outputArea.height()); bumpmapPaintDevice->convertTo(device->colorSpace(), KoColorConversionTransformation::internalRenderingIntent(), KoColorConversionTransformation::internalConversionFlags()); KisPainter copier(device); copier.bitBlt(outputArea.x(), outputArea.y(), bumpmapPaintDevice, outputArea.x(), outputArea.y(), outputArea.width(), outputArea.height()); //device->prepareClone(bumpmapPaintDevice); //device->makeCloneFrom(bumpmapPaintDevice, bumpmapPaintDevice->extent()); // THIS COULD BE BUG GY if (progressUpdater) progressUpdater->setProgress(100); } KisFilterConfigurationSP KisFilterPhongBumpmap::factoryConfiguration() const { KisFilterConfigurationSP config = new KisFilterConfiguration(id(), 2); config->setProperty(PHONG_AMBIENT_REFLECTIVITY, 0.2); config->setProperty(PHONG_DIFFUSE_REFLECTIVITY, 0.5); config->setProperty(PHONG_SPECULAR_REFLECTIVITY, 0.3); config->setProperty(PHONG_SHINYNESS_EXPONENT, 2); config->setProperty(USE_NORMALMAP_IS_ENABLED, false); config->setProperty(PHONG_DIFFUSE_REFLECTIVITY_IS_ENABLED, true); config->setProperty(PHONG_SPECULAR_REFLECTIVITY_IS_ENABLED, true); // Indexes are off by 1 simply because arrays start at 0 and the GUI naming scheme started at 1 config->setProperty(PHONG_ILLUMINANT_IS_ENABLED[0], true); config->setProperty(PHONG_ILLUMINANT_IS_ENABLED[1], true); config->setProperty(PHONG_ILLUMINANT_IS_ENABLED[2], false); config->setProperty(PHONG_ILLUMINANT_IS_ENABLED[3], false); config->setProperty(PHONG_ILLUMINANT_COLOR[0], QColor(255, 255, 0)); config->setProperty(PHONG_ILLUMINANT_COLOR[1], QColor(255, 0, 0)); config->setProperty(PHONG_ILLUMINANT_COLOR[2], QColor(0, 0, 255)); config->setProperty(PHONG_ILLUMINANT_COLOR[3], QColor(0, 255, 0)); config->setProperty(PHONG_ILLUMINANT_AZIMUTH[0], 50); config->setProperty(PHONG_ILLUMINANT_AZIMUTH[1], 100); config->setProperty(PHONG_ILLUMINANT_AZIMUTH[2], 150); config->setProperty(PHONG_ILLUMINANT_AZIMUTH[3], 200); config->setProperty(PHONG_ILLUMINANT_INCLINATION[0], 25); config->setProperty(PHONG_ILLUMINANT_INCLINATION[1], 20); config->setProperty(PHONG_ILLUMINANT_INCLINATION[2], 30); config->setProperty(PHONG_ILLUMINANT_INCLINATION[3], 40); return config; } QRect KisFilterPhongBumpmap::neededRect(const QRect &rect, const KisFilterConfigurationSP /*config*/, int /*lod*/) const { return rect.adjusted(-1, -1, 1, 1); } QRect KisFilterPhongBumpmap::changedRect(const QRect &rect, const KisFilterConfigurationSP /*config*/, int /*lod*/) const { return rect; } -KisConfigWidget *KisFilterPhongBumpmap::createConfigurationWidget(QWidget *parent, const KisPaintDeviceSP dev) const +KisConfigWidget *KisFilterPhongBumpmap::createConfigurationWidget(QWidget *parent, const KisPaintDeviceSP dev, bool) const { KisPhongBumpmapConfigWidget *w = new KisPhongBumpmapConfigWidget(dev, parent); return w; } diff --git a/plugins/filters/phongbumpmap/kis_phong_bumpmap_filter.h b/plugins/filters/phongbumpmap/kis_phong_bumpmap_filter.h index 8de0c9664e..56152a9183 100644 --- a/plugins/filters/phongbumpmap/kis_phong_bumpmap_filter.h +++ b/plugins/filters/phongbumpmap/kis_phong_bumpmap_filter.h @@ -1,54 +1,54 @@ /* * Copyright (c) 2010 Dmitry Kazakov * Copyright (c) 2010-2011 José Luis Vergara * * 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-1301, USA. */ #ifndef KIS_PHONG_BUMPMAP_FILTER_H #define KIS_PHONG_BUMPMAP_FILTER_H #include #include /** * This class is an implementation of the phong illumination model. * It uses a heightmap as an input mesh (normally taken from 1 * channel of a colorspace) to achieve a bumpmapping effect with * multiple illumination sources. */ class KisFilterPhongBumpmap : public KisFilter { public: KisFilterPhongBumpmap(); public: void processImpl(KisPaintDeviceSP device, const QRect& applyRect, const KisFilterConfigurationSP config, KoUpdater *progressUpdater ) const override; QRect neededRect(const QRect &rect, const KisFilterConfigurationSP config, int lod) const override; QRect changedRect(const QRect &rect, const KisFilterConfigurationSP config, int lod) const override; - KisConfigWidget *createConfigurationWidget(QWidget *parent, const KisPaintDeviceSP dev) const override; + KisConfigWidget *createConfigurationWidget(QWidget *parent, const KisPaintDeviceSP dev, bool useForMasks) const override; KisFilterConfigurationSP factoryConfiguration() const override; private: //bool m_usenormalmap; }; #endif //KIS_PHONG_BUMPMAP_FILTER_H diff --git a/plugins/filters/pixelizefilter/kis_pixelize_filter.cpp b/plugins/filters/pixelizefilter/kis_pixelize_filter.cpp index 704fab4ef1..4d2294249d 100644 --- a/plugins/filters/pixelizefilter/kis_pixelize_filter.cpp +++ b/plugins/filters/pixelizefilter/kis_pixelize_filter.cpp @@ -1,163 +1,163 @@ /* * This file is part of Krita * * Copyright (c) 2005 Michael Thaler * * ported from Gimp, Copyright (C) 1997 Eiichi Takamori * original pixelize.c for GIMP 0.54 by Tracy Scott * * 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-1301, USA. */ #include "kis_pixelize_filter.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "widgets/kis_multi_integer_filter_widget.h" #include #include #include "kis_algebra_2d.h" #include "kis_lod_transform.h" KisPixelizeFilter::KisPixelizeFilter() : KisFilter(id(), FiltersCategoryArtisticId, i18n("&Pixelize...")) { setSupportsPainting(true); setSupportsThreading(true); setSupportsAdjustmentLayers(true); setSupportsLevelOfDetail(true); setColorSpaceIndependence(FULLY_INDEPENDENT); } void KisPixelizeFilter::processImpl(KisPaintDeviceSP device, const QRect& applyRect, const KisFilterConfigurationSP config, KoUpdater* progressUpdater ) const { Q_ASSERT(device); KisLodTransformScalar t(device); const int pixelWidth = qCeil(t.scale(config ? qMax(1, config->getInt("pixelWidth", 10)) : 10)); const int pixelHeight = qCeil(t.scale(config ? qMax(1, config->getInt("pixelHeight", 10)) : 10)); const qint32 pixelSize = device->pixelSize(); const QRect deviceBounds = device->defaultBounds()->bounds(); const int bufferSize = pixelSize * pixelWidth * pixelHeight; QScopedArrayPointer buffer(new quint8[bufferSize]); KoColor pixelColor(Qt::black, device->colorSpace()); KoMixColorsOp *mixOp = device->colorSpace()->mixColorsOp(); using namespace KisAlgebra2D; const qint32 firstCol = divideFloor(applyRect.x(), pixelWidth); const qint32 firstRow = divideFloor(applyRect.y(), pixelHeight); const qint32 lastCol = divideFloor(applyRect.x() + applyRect.width() - 1, pixelWidth); const qint32 lastRow = divideFloor(applyRect.y() + applyRect.height() - 1, pixelHeight); progressUpdater->setRange(firstRow, lastRow); for(qint32 i = firstRow; i <= lastRow; i++) { for(qint32 j = firstCol; j <= lastCol; j++) { const QRect maxPatchRect(j * pixelWidth, i * pixelHeight, pixelWidth, pixelHeight); const QRect pixelRect = maxPatchRect & deviceBounds; const int numColors = pixelRect.width() * pixelRect.height(); //read KisSequentialConstIterator srcIt(device, pixelRect); memset(buffer.data(), 0, bufferSize); quint8 *bufferPtr = buffer.data(); while (srcIt.nextPixel()) { memcpy(bufferPtr, srcIt.oldRawData(), pixelSize); bufferPtr += pixelSize; } // mix all the colors mixOp->mixColors(buffer.data(), numColors, pixelColor.data()); // write only colors in applyRect const QRect writeRect = pixelRect & applyRect; KisSequentialIterator dstIt(device, writeRect); while (dstIt.nextPixel()) { memcpy(dstIt.rawData(), pixelColor.data(), pixelSize); } } progressUpdater->setValue(i); } } QRect KisPixelizeFilter::neededRect(const QRect &rect, const KisFilterConfigurationSP config, int lod) const { KisLodTransformScalar t(lod); const int pixelWidth = qCeil(t.scale(config ? qMax(1, config->getInt("pixelWidth", 10)) : 10)); const int pixelHeight = qCeil(t.scale(config ? qMax(1, config->getInt("pixelHeight", 10)) : 10)); // TODO: make more precise calculation of the rect, including the alignment return rect.adjusted(-2*pixelWidth, -2*pixelHeight, 2*pixelWidth, 2*pixelHeight); } QRect KisPixelizeFilter::changedRect(const QRect &rect, const KisFilterConfigurationSP config, int lod) const { return neededRect(rect, config, lod); } -KisConfigWidget * KisPixelizeFilter::createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP) const +KisConfigWidget * KisPixelizeFilter::createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP, bool) const { vKisIntegerWidgetParam param; param.push_back(KisIntegerWidgetParam(2, 512, 10, i18n("Pixel width"), "pixelWidth")); param.push_back(KisIntegerWidgetParam(2, 512, 10, i18n("Pixel height"), "pixelHeight")); return new KisMultiIntegerFilterWidget(id().id(), parent, id().id(), param); } KisFilterConfigurationSP KisPixelizeFilter::factoryConfiguration() const { KisFilterConfigurationSP config = new KisFilterConfiguration("pixelize", 1); config->setProperty("pixelWidth", 10); config->setProperty("pixelHeight", 10); return config; } diff --git a/plugins/filters/pixelizefilter/kis_pixelize_filter.h b/plugins/filters/pixelizefilter/kis_pixelize_filter.h index 11a7248c3b..d1023251dc 100644 --- a/plugins/filters/pixelizefilter/kis_pixelize_filter.h +++ b/plugins/filters/pixelizefilter/kis_pixelize_filter.h @@ -1,50 +1,50 @@ /* * This file is part of the KDE project * * Copyright (c) Michael Thaler * * 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-1301, USA. */ #ifndef _KIS_PIXELIZE_FILTER_H_ #define _KIS_PIXELIZE_FILTER_H_ #include "filter/kis_filter.h" #include "kis_config_widget.h" class KisPixelizeFilter : public KisFilter { public: KisPixelizeFilter(); public: void processImpl(KisPaintDeviceSP device, const QRect& applyRect, const KisFilterConfigurationSP config, KoUpdater* progressUpdater) const override; static inline KoID id() { return KoID("pixelize", i18n("Pixelize")); } QRect neededRect(const QRect & rect, const KisFilterConfigurationSP config, int lod) const override; QRect changedRect(const QRect & rect, const KisFilterConfigurationSP config, int lod) const override; public: - KisConfigWidget * createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev) const override; + KisConfigWidget * createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev, bool useForMasks) const override; KisFilterConfigurationSP factoryConfiguration() const override; }; #endif diff --git a/plugins/filters/posterize/posterize.cpp b/plugins/filters/posterize/posterize.cpp index f62bdded0e..93da26c2e0 100644 --- a/plugins/filters/posterize/posterize.cpp +++ b/plugins/filters/posterize/posterize.cpp @@ -1,111 +1,111 @@ /* * Copyright (c) 2014 Manuel Riecke * * 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-1301, USA. */ #include "posterize.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include K_PLUGIN_FACTORY_WITH_JSON(PosterizeFactory, "kritaposterize.json", registerPlugin();) Posterize::Posterize(QObject *parent, const QVariantList &) : QObject(parent) { KisFilterRegistry::instance()->add(KisFilterSP(new KisFilterPosterize())); } Posterize::~Posterize() { } KisFilterPosterize::KisFilterPosterize() : KisColorTransformationFilter(id(), FiltersCategoryArtisticId, i18n("&Posterize...")) { setColorSpaceIndependence(FULLY_INDEPENDENT); setSupportsPainting(true); setShowConfigurationWidget(true); } KoColorTransformation* KisFilterPosterize::createTransformation(const KoColorSpace* cs, const KisFilterConfigurationSP config) const { return new KisPosterizeColorTransformation(config->getInt("steps", 16), cs); } KisPosterizeColorTransformation::KisPosterizeColorTransformation(int steps, const KoColorSpace* cs) : m_colorSpace(cs), m_psize(cs->pixelSize()) { m_step = KoColorSpaceMathsTraits::max / steps; m_halfStep = m_step / 2; } -KisConfigWidget* KisFilterPosterize::createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev) const +KisConfigWidget* KisFilterPosterize::createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev, bool) const { Q_UNUSED(dev); vKisIntegerWidgetParam param; param.push_back(KisIntegerWidgetParam(2, 128, 16, i18n("Steps"), "steps")); return new KisMultiIntegerFilterWidget(id().id(), parent, id().id(), param); } KisFilterConfigurationSP KisFilterPosterize::factoryConfiguration() const { KisColorTransformationConfigurationSP config = new KisColorTransformationConfiguration(id().id(), 0); config->setProperty("steps", 16); return config; } void KisPosterizeColorTransformation::transform(const quint8* src, quint8* dst, qint32 nPixels) const { quint16 m_rgba[4]; quint16 m_mod[4]; while (nPixels--) { m_colorSpace->toRgbA16(src, reinterpret_cast(m_rgba), 1); m_mod[0] = m_rgba[0] % m_step; m_mod[1] = m_rgba[1] % m_step; m_mod[2] = m_rgba[2] % m_step; m_mod[3] = m_rgba[3] % m_step; m_rgba[0] = m_rgba[0] + (m_mod[0] > m_halfStep ? m_step - m_mod[0] : -m_mod[0]); m_rgba[1] = m_rgba[1] + (m_mod[1] > m_halfStep ? m_step - m_mod[1] : -m_mod[1]); m_rgba[2] = m_rgba[2] + (m_mod[2] > m_halfStep ? m_step - m_mod[2] : -m_mod[2]); m_rgba[3] = m_rgba[3] + (m_mod[3] > m_halfStep ? m_step - m_mod[3] : -m_mod[3]); m_colorSpace->fromRgbA16(reinterpret_cast(m_rgba), dst, 1); src += m_psize; dst += m_psize; } } #include "posterize.moc" diff --git a/plugins/filters/posterize/posterize.h b/plugins/filters/posterize/posterize.h index 5271b6ba26..88f7b69922 100644 --- a/plugins/filters/posterize/posterize.h +++ b/plugins/filters/posterize/posterize.h @@ -1,61 +1,61 @@ /* * Copyright (c) 2014 Manuel Riecke * * 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-1301, USA. */ #ifndef POSTERIZE_H #define POSTERIZE_H #include #include #include "filter/kis_color_transformation_filter.h" #include "kis_config_widget.h" class Posterize : public QObject { Q_OBJECT public: Posterize(QObject *parent, const QVariantList &); ~Posterize() override; }; class KisFilterPosterize : public KisColorTransformationFilter { public: KisFilterPosterize(); public: KoColorTransformation* createTransformation(const KoColorSpace* cs, const KisFilterConfigurationSP config) const override; - KisConfigWidget* createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev) const override; + KisConfigWidget* createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev, bool useForMasks) const override; static inline KoID id() { return KoID("posterize", i18n("Posterize")); } protected: KisFilterConfigurationSP factoryConfiguration() const override; }; class KisPosterizeColorTransformation : public KoColorTransformation { public: KisPosterizeColorTransformation(int steps, const KoColorSpace* cs); void transform(const quint8* src, quint8* dst, qint32 nPixels) const override; private: const KoColorSpace* m_colorSpace; quint32 m_psize; quint16 m_step; quint16 m_halfStep; }; #endif diff --git a/plugins/filters/raindropsfilter/kis_raindrops_filter.cpp b/plugins/filters/raindropsfilter/kis_raindrops_filter.cpp index 6a4a61d61d..519e82373d 100644 --- a/plugins/filters/raindropsfilter/kis_raindrops_filter.cpp +++ b/plugins/filters/raindropsfilter/kis_raindrops_filter.cpp @@ -1,397 +1,397 @@ /* * This file is part of the KDE project * * Copyright (c) 2004 Michael Thaler * * ported from digikam, copyrighted 2004 by Gilles Caulier, * Original RainDrops algorithm copyrighted 2004 by * Pieter Z. Voloshyn . * * 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-1301, USA. */ #include "kis_raindrops_filter.h" #include #include #include #include #include #include #include #include #include #include "KoIntegerMaths.h" #include #include #include #include #include #include #include #include #include #include #include #include "widgets/kis_multi_integer_filter_widget.h" KisRainDropsFilter::KisRainDropsFilter() : KisFilter(id(), FiltersCategoryArtisticId, i18n("&Raindrops...")) { setSupportsPainting(false); setSupportsThreading(false); setSupportsAdjustmentLayers(true); } // This method have been ported from Pieter Z. Voloshyn algorithm code. /* Function to apply the RainDrops effect (inspired from Jason Waltman code) * * data => The image data in RGBA mode. * Width => Width of image. * Height => Height of image. * DropSize => Raindrop size * number => Maximum number of raindrops * fishEyes => FishEye coefficient * * Theory => This functions does several math's functions and the engine * is simple to understand, but a little hard to implement. A * control will indicate if there is or not a raindrop in that * area, if not, a fisheye effect with a random size (max=DropSize) * will be applied, after this, a shadow will be applied too. * and after this, a blur function will finish the effect. */ void KisRainDropsFilter::processImpl(KisPaintDeviceSP device, const QRect& applyRect, const KisFilterConfigurationSP config, KoUpdater* progressUpdater ) const { QPoint srcTopLeft = applyRect.topLeft(); Q_ASSERT(device); //read the filter configuration values from the KisFilterConfiguration object quint32 DropSize = config->getInt("dropSize", 80); quint32 number = config->getInt("number", 80); quint32 fishEyes = config->getInt("fishEyes", 30); qsrand(config->getInt("seed")); if (fishEyes <= 0) fishEyes = 1; if (fishEyes > 100) fishEyes = 100; int Width = applyRect.width(); int Height = applyRect.height(); bool** BoolMatrix = CreateBoolArray(Width, Height); int i, j, k, l, m, n; // loop variables int Bright; // Bright value for shadows and highlights int x, y; // center coordinates int Counter = 0; // Counter (duh !) int NewSize; // Size of current raindrop int halfSize; // Half of the current raindrop int Radius; // Maximum radius for raindrop int BlurRadius; // Blur Radius int BlurPixels; double r, a; // polar coordinates double OldRadius; // Radius before processing double NewfishEyes = (double)fishEyes * 0.01; // FishEye fishEyesicients double s; double R, G, B; bool FindAnother = false; // To search for good coordinates const KoColorSpace * cs = device->colorSpace(); // Init boolean Matrix. for (i = 0 ; i < Width; ++i) { for (j = 0 ; j < Height; ++j) { BoolMatrix[i][j] = false; } } progressUpdater->setRange(0, number); KisRandomAccessorSP dstAccessor = device->createRandomAccessorNG(srcTopLeft.x(), srcTopLeft.y()); for (uint NumBlurs = 0; NumBlurs <= number; ++NumBlurs) { NewSize = (int)(qrand() * ((double)(DropSize - 5) / RAND_MAX) + 5); halfSize = NewSize / 2; Radius = halfSize; s = Radius / log(NewfishEyes * Radius + 1); Counter = 0; do { FindAnother = false; y = (int)(qrand() * ((double)(Width - 1) / RAND_MAX)); x = (int)(qrand() * ((double)(Height - 1) / RAND_MAX)); if (BoolMatrix[y][x]) FindAnother = true; else for (i = x - halfSize ; i <= x + halfSize; i++) for (j = y - halfSize ; j <= y + halfSize; j++) if ((i >= 0) && (i < Height) && (j >= 0) && (j < Width)) if (BoolMatrix[j][i]) FindAnother = true; Counter++; } while (FindAnother && Counter < 10000); if (Counter >= 10000) { NumBlurs = number; break; } for (i = -1 * halfSize ; i < NewSize - halfSize; i++) { for (j = -1 * halfSize ; j < NewSize - halfSize; j++) { r = sqrt((double)i * i + j * j); a = atan2(static_cast(i), static_cast(j)); if (r <= Radius) { OldRadius = r; r = (exp(r / s) - 1) / NewfishEyes; k = x + (int)(r * sin(a)); l = y + (int)(r * cos(a)); m = x + i; n = y + j; if ((k >= 0) && (k < Height) && (l >= 0) && (l < Width)) { if ((m >= 0) && (m < Height) && (n >= 0) && (n < Width)) { Bright = 0; if (OldRadius >= 0.9 * Radius) { if ((a <= 0) && (a > -2.25)) Bright = -80; else if ((a <= -2.25) && (a > -2.5)) Bright = -40; else if ((a <= 0.25) && (a > 0)) Bright = -40; } else if (OldRadius >= 0.8 * Radius) { if ((a <= -0.75) && (a > -1.50)) Bright = -40; else if ((a <= 0.10) && (a > -0.75)) Bright = -30; else if ((a <= -1.50) && (a > -2.35)) Bright = -30; } else if (OldRadius >= 0.7 * Radius) { if ((a <= -0.10) && (a > -2.0)) Bright = -20; else if ((a <= 2.50) && (a > 1.90)) Bright = 60; } else if (OldRadius >= 0.6 * Radius) { if ((a <= -0.50) && (a > -1.75)) Bright = -20; else if ((a <= 0) && (a > -0.25)) Bright = 20; else if ((a <= -2.0) && (a > -2.25)) Bright = 20; } else if (OldRadius >= 0.5 * Radius) { if ((a <= -0.25) && (a > -0.50)) Bright = 30; else if ((a <= -1.75) && (a > -2.0)) Bright = 30; } else if (OldRadius >= 0.4 * Radius) { if ((a <= -0.5) && (a > -1.75)) Bright = 40; } else if (OldRadius >= 0.3 * Radius) { if ((a <= 0) && (a > -2.25)) Bright = 30; } else if (OldRadius >= 0.2 * Radius) { if ((a <= -0.5) && (a > -1.75)) Bright = 20; } BoolMatrix[n][m] = true; QColor originalColor; dstAccessor->moveTo(srcTopLeft.x() + l, srcTopLeft.y() + k); cs->toQColor(dstAccessor->oldRawData(), &originalColor); int newRed = CLAMP(originalColor.red() + Bright, 0, quint8_MAX); int newGreen = CLAMP(originalColor.green() + Bright, 0, quint8_MAX); int newBlue = CLAMP(originalColor.blue() + Bright, 0, quint8_MAX); QColor newColor; newColor.setRgb(newRed, newGreen, newBlue); dstAccessor->moveTo(srcTopLeft.x() + n, srcTopLeft.y() + m); cs->fromQColor(newColor, dstAccessor->rawData()); } } } } } BlurRadius = NewSize / 25 + 1; for (i = -1 * halfSize - BlurRadius ; i < NewSize - halfSize + BlurRadius; i++) { for (j = -1 * halfSize - BlurRadius; j < NewSize - halfSize + BlurRadius; ++j) { r = sqrt((double)i * i + j * j); if (r <= Radius * 1.1) { R = G = B = 0; BlurPixels = 0; for (k = -1 * BlurRadius; k < BlurRadius + 1; k++) for (l = -1 * BlurRadius; l < BlurRadius + 1; l++) { m = x + i + k; n = y + j + l; if ((m >= 0) && (m < Height) && (n >= 0) && (n < Width)) { QColor color; dstAccessor->moveTo(srcTopLeft.x() + n, srcTopLeft.y() + m); cs->toQColor(dstAccessor->rawData(), &color); R += color.red(); G += color.green(); B += color.blue(); BlurPixels++; } } m = x + i; n = y + j; if ((m >= 0) && (m < Height) && (n >= 0) && (n < Width)) { QColor color; color.setRgb((int)(R / BlurPixels), (int)(G / BlurPixels), (int)(B / BlurPixels)); dstAccessor->moveTo(srcTopLeft.x() + n, srcTopLeft.y() + m); cs->fromQColor(color, dstAccessor->rawData()); } } } } progressUpdater->setValue(NumBlurs); } FreeBoolArray(BoolMatrix, Width); } // This method have been ported from Pieter Z. Voloshyn algorithm code. /* Function to free a dynamic boolean array * * lpbArray => Dynamic boolean array * Columns => The array bidimension value * * Theory => An easy to understand 'for' statement */ void KisRainDropsFilter::FreeBoolArray(bool** lpbArray, uint Columns) const { for (uint i = 0; i < Columns; ++i) free(lpbArray[i]); free(lpbArray); } /* Function to create a bidimentional dynamic boolean array * * Columns => Number of columns * Rows => Number of rows * * Theory => Using 'for' statement, we can alloc multiple dynamic arrays * To create more dimensions, just add some 'for's, ok? */ bool** KisRainDropsFilter::CreateBoolArray(uint Columns, uint Rows) const { bool** lpbArray = 0; lpbArray = (bool**) malloc(Columns * sizeof(bool*)); if (lpbArray == 0) return (0); for (uint i = 0; i < Columns; ++i) { lpbArray[i] = (bool*) malloc(Rows * sizeof(bool)); if (lpbArray[i] == 0) { FreeBoolArray(lpbArray, Columns); return (0); } } return (lpbArray); } // This method have been ported from Pieter Z. Voloshyn algorithm code. /* This function limits the RGB values * * ColorValue => Here, is an RGB value to be analyzed * * Theory => A color is represented in RGB value (e.g. 0xFFFFFF is * white color). But R, G and B values have 256 values to be used * so, this function analyzes the value and limits to this range */ uchar KisRainDropsFilter::LimitValues(int ColorValue) const { if (ColorValue > 255) // MAX = 255 ColorValue = 255; if (ColorValue < 0) // MIN = 0 ColorValue = 0; return ((uchar) ColorValue); } -KisConfigWidget * KisRainDropsFilter::createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP) const +KisConfigWidget * KisRainDropsFilter::createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP, bool) const { vKisIntegerWidgetParam param; param.push_back(KisIntegerWidgetParam(1, 200, 80, i18n("Drop size"), "dropsize")); param.push_back(KisIntegerWidgetParam(1, 500, 80, i18n("Number"), "number")); param.push_back(KisIntegerWidgetParam(1, 100, 30, i18n("Fish eyes"), "fishEyes")); KisMultiIntegerFilterWidget * w = new KisMultiIntegerFilterWidget(id().id(), parent, id().id(), param); w->setConfiguration(factoryConfiguration()); return w; } KisFilterConfigurationSP KisRainDropsFilter::factoryConfiguration() const { KisFilterConfigurationSP config = new KisFilterConfiguration("raindrops", 2); config->setProperty("dropsize", 80); config->setProperty("number", 80); config->setProperty("fishEyes", 30); config->setProperty("seed", QTime::currentTime().msec()); return config; } diff --git a/plugins/filters/raindropsfilter/kis_raindrops_filter.h b/plugins/filters/raindropsfilter/kis_raindrops_filter.h index ff77c381d1..c394a3e992 100644 --- a/plugins/filters/raindropsfilter/kis_raindrops_filter.h +++ b/plugins/filters/raindropsfilter/kis_raindrops_filter.h @@ -1,51 +1,51 @@ /* * This file is part of Krita * * Copyright (c) Michael Thaler * * 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-1301, USA. */ #ifndef _KIS_RAINDROPS_FILTER_H_ #define _KIS_RAINDROPS_FILTER_H_ #include "filter/kis_filter.h" #include "kis_config_widget.h" #include "kis_paint_device.h" class KisRainDropsFilter : public KisFilter { public: KisRainDropsFilter(); public: void processImpl(KisPaintDeviceSP device, const QRect& applyRect, const KisFilterConfigurationSP config, KoUpdater* progressUpdater) const override; static inline KoID id() { return KoID("raindrops", i18n("Raindrops")); } KisFilterConfigurationSP factoryConfiguration() const override; public: - KisConfigWidget * createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev) const override; + KisConfigWidget * createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev, bool useForMasks) const override; private: bool** CreateBoolArray(uint Columns, uint Rows) const; void FreeBoolArray(bool** lpbArray, uint Columns) const; uchar LimitValues(int ColorValue) const; }; #endif diff --git a/plugins/filters/randompickfilter/randompickfilter.cpp b/plugins/filters/randompickfilter/randompickfilter.cpp index 3d612485a9..d98df1bfb5 100644 --- a/plugins/filters/randompickfilter/randompickfilter.cpp +++ b/plugins/filters/randompickfilter/randompickfilter.cpp @@ -1,157 +1,157 @@ /* * This file is part of the KDE project * * Copyright (c) 2005 Cyrille Berger * * 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-1301, USA. */ #include "randompickfilter.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "kis_wdg_random_pick.h" #include "ui_wdgrandompickoptions.h" #include #include K_PLUGIN_FACTORY_WITH_JSON(KritaRandomPickFilterFactory, "kritarandompickfilter.json", registerPlugin();) KritaRandomPickFilter::KritaRandomPickFilter(QObject *parent, const QVariantList &) : QObject(parent) { KisFilterRegistry::instance()->add(new KisFilterRandomPick()); } KritaRandomPickFilter::~KritaRandomPickFilter() { } KisFilterRandomPick::KisFilterRandomPick() : KisFilter(id(), FiltersCategoryOtherId, i18n("&Random Pick...")) { setColorSpaceIndependence(FULLY_INDEPENDENT); setSupportsPainting(true); } void KisFilterRandomPick::processImpl(KisPaintDeviceSP device, const QRect& applyRect, const KisFilterConfigurationSP config, KoUpdater* progressUpdater ) const { Q_UNUSED(config); Q_ASSERT(!device.isNull()); const KoColorSpace * cs = device->colorSpace(); QVariant value; int level = (config && config->getProperty("level", value)) ? value.toInt() : 50; int opacity = (config && config->getProperty("opacity", value)) ? value.toInt() : 100; double windowsize = (config && config->getProperty("windowsize", value)) ? value.toDouble() : 2.5; int seedThreshold = rand(); int seedH = rand(); int seedV = rand(); if (config) { seedThreshold = config->getInt("seedThreshold", seedThreshold); seedH = config->getInt("seedH", seedH); seedV = config->getInt("seedV", seedV); } KisRandomGenerator randT(seedThreshold); KisRandomGenerator randH(seedH); KisRandomGenerator randV(seedV); KisSequentialIteratorProgress dstIt(device, applyRect, progressUpdater); KisRandomConstAccessorSP srcRA = device->createRandomConstAccessorNG(0, 0); double threshold = (100 - level) / 100.0; qint16 weights[2]; weights[0] = (255 * opacity) / 100; weights[1] = 255 - weights[0]; const quint8* pixels[2]; KoMixColorsOp * mixOp = cs->mixColorsOp(); while (dstIt.nextPixel()) { if (randT.doubleRandomAt(dstIt.x(), dstIt.y()) > threshold) { int x = static_cast(dstIt.x() + windowsize * (randH.doubleRandomAt(dstIt.x(), dstIt.y()) - 0.5)); int y = static_cast(dstIt.y() + windowsize * (randV.doubleRandomAt(dstIt.x(), dstIt.y()) -0.5)); srcRA->moveTo(x, y); pixels[0] = srcRA->oldRawData(); pixels[1] = dstIt.oldRawData(); mixOp->mixColors(pixels, weights, 2, dstIt.rawData()); } } } -KisConfigWidget * KisFilterRandomPick::createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev) const +KisConfigWidget * KisFilterRandomPick::createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev, bool) const { Q_UNUSED(dev); return new KisWdgRandomPick((KisFilter*)this, (QWidget*)parent); } KisFilterConfigurationSP KisFilterRandomPick::factoryConfiguration() const { KisFilterConfigurationSP config = new KisFilterConfiguration("randompick", 1); config->setProperty("level", 50); config->setProperty("windowsize", 2.5); config->setProperty("opacity", 100); config->setProperty("seedThreshold", rand()); config->setProperty("seedH", rand()); config->setProperty("seedV", rand()); return config; } QRect KisFilterRandomPick::neededRect(const QRect& rect, const KisFilterConfigurationSP config, int lod) const { Q_UNUSED(lod); QVariant value; int windowsize = ceil((config && config->getProperty("windowsize", value)) ? value.toDouble() : 2.5); return rect.adjusted(-windowsize, -windowsize, windowsize, windowsize); } QRect KisFilterRandomPick::changedRect(const QRect &rect, const KisFilterConfigurationSP config, int lod) const { return neededRect(rect, config, lod); } #include "randompickfilter.moc" diff --git a/plugins/filters/randompickfilter/randompickfilter.h b/plugins/filters/randompickfilter/randompickfilter.h index daeb0208c9..63487b060b 100644 --- a/plugins/filters/randompickfilter/randompickfilter.h +++ b/plugins/filters/randompickfilter/randompickfilter.h @@ -1,60 +1,60 @@ /* * This file is part of Krita * * Copyright (c) 2006 Cyrille Berger * * 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-1301, USA. */ #ifndef RANDOMPICKFILTER_H #define RANDOMPICKFILTER_H #include #include #include "filter/kis_filter.h" class KisConfigWidget; class KritaRandomPickFilter : public QObject { Q_OBJECT public: KritaRandomPickFilter(QObject *parent, const QVariantList &); ~KritaRandomPickFilter() override; }; class KisFilterRandomPick : public KisFilter { public: KisFilterRandomPick(); public: void processImpl(KisPaintDeviceSP device, const QRect& applyRect, const KisFilterConfigurationSP config, KoUpdater* progressUpdater ) const override; static inline KoID id() { return KoID("randompick", i18n("Random Pick")); } KisFilterConfigurationSP factoryConfiguration() const override; public: - KisConfigWidget * createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev) const override; + KisConfigWidget * createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev, bool useForMasks) const override; QRect neededRect(const QRect& rect, const KisFilterConfigurationSP config, int lod = 0) const override; QRect changedRect(const QRect& rect, const KisFilterConfigurationSP config, int lod = 0) const override; }; #endif diff --git a/plugins/filters/roundcorners/kis_round_corners_filter.cpp b/plugins/filters/roundcorners/kis_round_corners_filter.cpp index f0843fde5a..04b3827acf 100644 --- a/plugins/filters/roundcorners/kis_round_corners_filter.cpp +++ b/plugins/filters/roundcorners/kis_round_corners_filter.cpp @@ -1,155 +1,155 @@ /* * This file is part of Krita * * Copyright (c) 2005 Michael Thaler * * ported from Gimp, Copyright (C) 1997 Eiichi Takamori * original pixelize.c for GIMP 0.54 by Tracy Scott * * 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-1301, USA. */ #include "kis_round_corners_filter.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include KisRoundCornersFilter::KisRoundCornersFilter() : KisFilter(id(), FiltersCategoryMapId, i18n("&Round Corners...")) { setSupportsPainting(false); } void fadeOneCorner(KisPaintDeviceSP device, const QPoint &basePoint, const QRect &processRect, const qreal thresholdSq, KoUpdater* progressUpdater) { const KoColorSpace *cs = device->colorSpace(); KisSequentialIteratorProgress dstIt(device, processRect, progressUpdater); while (dstIt.nextPixel()) { const QPointF point(dstIt.x(), dstIt.y()); const qreal distanceSq = kisSquareDistance(point, basePoint); if (distanceSq >= thresholdSq) { cs->setOpacity(dstIt.rawData(), OPACITY_TRANSPARENT_U8, 1); } } } void KisRoundCornersFilter::processImpl(KisPaintDeviceSP device, const QRect& applyRect, const KisFilterConfigurationSP config, KoUpdater* progressUpdater ) const { Q_UNUSED(config); Q_ASSERT(!device.isNull()); if (!device || !config) { warnKrita << "Invalid parameters for round corner filter"; dbgPlugins << device << " " << config; return; } const QRect bounds = device->defaultBounds()->bounds(); const qint32 radius = qMin(KisAlgebra2D::minDimension(bounds) / 2, qMax(1, config->getInt("radius" , 30))); const qreal radiusSq = pow2(radius); struct CornerJob { QRect rc; QPoint pt; KoUpdater *progressUpdater; }; QVector jobs; KoProgressUpdater compositeUpdater(progressUpdater, KoProgressUpdater::Unthreaded); { QRect rc(bounds.x(), bounds.y(), radius, radius); QPoint pt(rc.bottomRight()); jobs << CornerJob({rc, pt, compositeUpdater.startSubtask()}); } { QRect rc(bounds.x() + bounds.width() - radius, bounds.y(), radius, radius); QPoint pt(rc.bottomLeft()); jobs << CornerJob({rc, pt, compositeUpdater.startSubtask()}); } { QRect rc(bounds.x(), bounds.y() + bounds.height() - radius, radius, radius); QPoint pt(rc.topRight()); jobs << CornerJob({rc, pt, compositeUpdater.startSubtask()}); } { QRect rc(bounds.x() + bounds.width() - radius, bounds.y() + bounds.height() - radius, radius, radius); QPoint pt(rc.topLeft()); jobs << CornerJob({rc, pt, compositeUpdater.startSubtask()}); } Q_FOREACH (const CornerJob &job, jobs) { const QRect processRect = job.rc & applyRect; if (!processRect.isEmpty()) { fadeOneCorner(device, job.pt, processRect, radiusSq, job.progressUpdater); } } } -KisConfigWidget * KisRoundCornersFilter::createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP) const +KisConfigWidget * KisRoundCornersFilter::createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP, bool) const { vKisIntegerWidgetParam param; param.push_back(KisIntegerWidgetParam(2, 100, 30, i18n("Radius"), "radius")); return new KisMultiIntegerFilterWidget(id().id(), parent, id().id(), param); } KisFilterConfigurationSP KisRoundCornersFilter::factoryConfiguration() const { KisFilterConfigurationSP config = new KisFilterConfiguration("roundcorners", 1); config->setProperty("radius", 30); return config; } diff --git a/plugins/filters/roundcorners/kis_round_corners_filter.h b/plugins/filters/roundcorners/kis_round_corners_filter.h index 30ad806e8e..ae6d8e5ed6 100644 --- a/plugins/filters/roundcorners/kis_round_corners_filter.h +++ b/plugins/filters/roundcorners/kis_round_corners_filter.h @@ -1,47 +1,47 @@ /* * This file is part of the KDE project * * Copyright (c) Michael Thaler * * 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-1301, USA. */ #ifndef _KIS_ROUND_CORNERS_FILTER_H_ #define _KIS_ROUND_CORNERS_FILTER_H_ #include "kis_paint_device.h" #include "filter/kis_filter.h" #include "kis_config_widget.h" class KisRoundCornersFilter : public KisFilter { public: KisRoundCornersFilter(); public: void processImpl(KisPaintDeviceSP device, const QRect& applyRect, const KisFilterConfigurationSP config, KoUpdater* progressUpdater ) const override; static inline KoID id() { return KoID("roundcorners", i18n("Round Corners")); } KisFilterConfigurationSP factoryConfiguration() const override; public: - KisConfigWidget * createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev) const override; + KisConfigWidget * createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev, bool useForMasks) const override; private: }; #endif diff --git a/plugins/filters/smalltilesfilter/kis_small_tiles_filter.cpp b/plugins/filters/smalltilesfilter/kis_small_tiles_filter.cpp index 3de792466c..673b15964d 100644 --- a/plugins/filters/smalltilesfilter/kis_small_tiles_filter.cpp +++ b/plugins/filters/smalltilesfilter/kis_small_tiles_filter.cpp @@ -1,115 +1,115 @@ /* * This file is part of Krita * * Copyright (c) 2005 Michael Thaler * * ported from Gimp, Copyright (C) 1997 Eiichi Takamori * original pixelize.c for GIMP 0.54 by Tracy Scott * * 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-1301, USA. */ #include "kis_small_tiles_filter.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "widgets/kis_multi_integer_filter_widget.h" KisSmallTilesFilter::KisSmallTilesFilter() : KisFilter(id(), FiltersCategoryMapId, i18n("&Small Tiles...")) { setSupportsPainting(true); setSupportsThreading(false); setSupportsAdjustmentLayers(false); } void KisSmallTilesFilter::processImpl(KisPaintDeviceSP device, const QRect& applyRect, const KisFilterConfigurationSP config, KoUpdater* progressUpdater ) const { Q_ASSERT(!device.isNull()); //read the filter configuration values from the KisFilterConfiguration object const quint32 numberOfTiles = config->getInt("numberOfTiles", 2); const QRect srcRect = applyRect; const int w = static_cast(srcRect.width() / numberOfTiles); const int h = static_cast(srcRect.height() / numberOfTiles); KisPaintDeviceSP tile = device->createThumbnailDevice(w, h); if (tile.isNull()) return; device->clear(applyRect); KisPainter gc(device); gc.setCompositeOp(COMPOSITE_COPY); if (progressUpdater) { progressUpdater->setRange(0, numberOfTiles); } for (uint y = 0; y < numberOfTiles; ++y) { for (uint x = 0; x < numberOfTiles; ++x) { gc.bitBlt(w * x, h * y, tile, 0, 0, w, h); } if (progressUpdater) progressUpdater->setValue(y); } gc.end(); } -KisConfigWidget * KisSmallTilesFilter::createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP) const +KisConfigWidget * KisSmallTilesFilter::createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP, bool) const { vKisIntegerWidgetParam param; param.push_back(KisIntegerWidgetParam(2, 5, 1, i18n("Number of tiles"), "numberOfTiles")); return new KisMultiIntegerFilterWidget(id().id(), parent, id().id(), param); } KisFilterConfigurationSP KisSmallTilesFilter::factoryConfiguration() const { KisFilterConfigurationSP config = new KisFilterConfiguration("smalltiles", 1); config->setProperty("numberOfTiles", 2); return config; } diff --git a/plugins/filters/smalltilesfilter/kis_small_tiles_filter.h b/plugins/filters/smalltilesfilter/kis_small_tiles_filter.h index e29dc15fe0..309171ab6f 100644 --- a/plugins/filters/smalltilesfilter/kis_small_tiles_filter.h +++ b/plugins/filters/smalltilesfilter/kis_small_tiles_filter.h @@ -1,51 +1,51 @@ /* * This file is part of the KDE project * * Copyright (c) Michael Thaler * * 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-1301, USA. */ #ifndef _KIS_SMALL_TILES_FILTER_H_ #define _KIS_SMALL_TILES_FILTER_H_ #include "kis_paint_device.h" #include "filter/kis_filter.h" #include "kis_config_widget.h" class KisSmallTilesFilter : public KisFilter { public: KisSmallTilesFilter(); public: void processImpl(KisPaintDeviceSP device, const QRect& applyRect, const KisFilterConfigurationSP config, KoUpdater* progressUpdater ) const override; static inline KoID id() { return KoID("smalltiles", i18n("Small Tiles")); } KisFilterConfigurationSP factoryConfiguration() const override; public: - KisConfigWidget * createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev) const override; + KisConfigWidget * createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev, bool useForMasks) const override; }; #endif diff --git a/plugins/filters/threshold/threshold.cpp b/plugins/filters/threshold/threshold.cpp index 9c4fefbeeb..8fe991fd07 100644 --- a/plugins/filters/threshold/threshold.cpp +++ b/plugins/filters/threshold/threshold.cpp @@ -1,216 +1,216 @@ /* * This file is part of the KDE project * * Copyright (c) 2016 Boudewijn Rempt * * 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-1301, USA. */ #include "threshold.h" #include #include #include #include #include #include #include #include #include #include #include "KisGradientSlider.h" #include "kis_histogram.h" #include #include "kis_paint_device.h" #include "kis_painter.h" #include #include #include #include #include #include "KoColorModelStandardIds.h" #include #include #include K_PLUGIN_FACTORY_WITH_JSON(KritaThresholdFactory, "kritathreshold.json", registerPlugin();) KritaThreshold::KritaThreshold(QObject *parent, const QVariantList &) : QObject(parent) { KisFilterRegistry::instance()->add(new KisFilterThreshold()); } KritaThreshold::~KritaThreshold() { } KisFilterThreshold::KisFilterThreshold() : KisFilter(id(), FiltersCategoryAdjustId, i18n("&Threshold...")) { setColorSpaceIndependence(FULLY_INDEPENDENT); setSupportsPainting(false); setShowConfigurationWidget(true); setSupportsLevelOfDetail(true); setSupportsAdjustmentLayers(true); setSupportsThreading(true); } void KisFilterThreshold::processImpl(KisPaintDeviceSP device, const QRect& applyRect, const KisFilterConfigurationSP config, KoUpdater *progressUpdater) const { Q_ASSERT(!device.isNull()); const int threshold = config->getInt("threshold"); KoColor white(Qt::white, device->colorSpace()); KoColor black(Qt::black, device->colorSpace()); KisSequentialIteratorProgress it(device, applyRect, progressUpdater); const int pixelSize = device->colorSpace()->pixelSize(); while (it.nextPixel()) { if (device->colorSpace()->intensity8(it.oldRawData()) > threshold) { white.setOpacity(device->colorSpace()->opacityU8(it.oldRawData())); memcpy(it.rawData(), white.data(), pixelSize); } else { black.setOpacity(device->colorSpace()->opacityU8(it.oldRawData())); memcpy(it.rawData(), black.data(), pixelSize); } } } KisFilterConfigurationSP KisFilterThreshold::factoryConfiguration() const { KisFilterConfigurationSP config = new KisFilterConfiguration("threshold", 1); config->setProperty("threshold", 128); return config; } -KisConfigWidget *KisFilterThreshold::createConfigurationWidget(QWidget *parent, const KisPaintDeviceSP dev) const +KisConfigWidget *KisFilterThreshold::createConfigurationWidget(QWidget *parent, const KisPaintDeviceSP dev, bool) const { return new KisThresholdConfigWidget(parent, dev); } KisThresholdConfigWidget::KisThresholdConfigWidget(QWidget * parent, KisPaintDeviceSP dev) : KisConfigWidget(parent) { Q_ASSERT(dev); m_page.setupUi(this); m_page.thresholdGradient->enableGamma(false); m_page.thresholdGradient->enableWhite(false); m_page.intThreshold->setValue(128); connect(m_page.intThreshold, SIGNAL(valueChanged(int)), SIGNAL(sigConfigurationItemChanged())); connect(m_page.thresholdGradient, SIGNAL(sigModifiedGamma(double)), SIGNAL(sigConfigurationItemChanged())); connect(m_page.intThreshold, SIGNAL(valueChanged(int)), m_page.thresholdGradient, SLOT(slotModifyBlack(int))); connect(m_page.thresholdGradient, SIGNAL(sigModifiedBlack(int)), m_page.intThreshold, SLOT(setValue(int))); connect((QObject*)(m_page.chkLogarithmic), SIGNAL(toggled(bool)), this, SLOT(slotDrawHistogram(bool))); KoHistogramProducer *producer = new KoGenericLabHistogramProducer(); m_histogram.reset( new KisHistogram(dev, dev->exactBounds(), producer, LINEAR) ); m_histlog = false; m_page.histview->resize(288,100); slotDrawHistogram(); } KisThresholdConfigWidget::~KisThresholdConfigWidget() { } void KisThresholdConfigWidget::slotDrawHistogram(bool logarithmic) { int wHeight = m_page.histview->height(); int wHeightMinusOne = wHeight - 1; int wWidth = m_page.histview->width(); if (m_histlog != logarithmic) { // Update the m_histogram if (logarithmic) m_histogram->setHistogramType(LOGARITHMIC); else m_histogram->setHistogramType(LINEAR); m_histlog = logarithmic; } QPalette appPalette = QApplication::palette(); QPixmap pix(wWidth-100, wHeight); pix.fill(QColor(appPalette.color(QPalette::Base))); QPainter p(&pix); p.setPen(QPen(Qt::gray, 1, Qt::SolidLine)); double highest = (double)m_histogram->calculations().getHighest(); qint32 bins = m_histogram->producer()->numberOfBins(); // use nearest neighbour interpolation if (m_histogram->getHistogramType() == LINEAR) { double factor = (double)(wHeight - wHeight / 5.0) / highest; for (int i = 0; i < wWidth; i++) { int binNo = qRound((double)i / wWidth * (bins - 1)); if ((int)m_histogram->getValue(binNo) != 0) p.drawLine(i, wHeightMinusOne, i, wHeightMinusOne - (int)m_histogram->getValue(binNo) * factor); } } else { double factor = (double)(wHeight - wHeight / 5.0) / (double)log(highest); for (int i = 0; i < wWidth; i++) { int binNo = qRound((double)i / wWidth * (bins - 1)) ; if ((int)m_histogram->getValue(binNo) != 0) p.drawLine(i, wHeightMinusOne, i, wHeightMinusOne - log((double)m_histogram->getValue(binNo)) * factor); } } m_page.histview->setPixmap(pix); } void KisThresholdConfigWidget::slotSetThreshold(int limit) { m_page.intThreshold->setMaximum(limit - 1); } KisPropertiesConfigurationSP KisThresholdConfigWidget::configuration() const { KisFilterConfigurationSP config = new KisFilterConfiguration("threshold", 1); config->setProperty("threshold", m_page.intThreshold->value()); return config; } void KisThresholdConfigWidget::setConfiguration(const KisPropertiesConfigurationSP config) { QVariant value; if (config->getProperty("threshold", value)) { m_page.intThreshold->setValue(value.toUInt()); m_page.thresholdGradient->slotModifyBlack(value.toUInt()); } } #include "threshold.moc" diff --git a/plugins/filters/threshold/threshold.h b/plugins/filters/threshold/threshold.h index 8b5ae80ff9..c6e0eae930 100644 --- a/plugins/filters/threshold/threshold.h +++ b/plugins/filters/threshold/threshold.h @@ -1,91 +1,91 @@ /* * This file is part of Krita * * Copyright (c) 2016 Boudewijn Rempt * * 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-1301, USA. */ #ifndef THRESHOLD_H #define THRESHOLD_H #include #include #include #include #include #include "ui_wdg_threshold.h" class WdgThreshold; class QWidget; class KisHistogram; class KritaThreshold : public QObject { Q_OBJECT public: KritaThreshold(QObject *parent, const QVariantList &); ~KritaThreshold() override; }; class KisFilterThreshold : public KisFilter { public: KisFilterThreshold(); public: static inline KoID id() { return KoID("threshold", i18n("Threshold")); } void processImpl(KisPaintDeviceSP device, const QRect& applyRect, const KisFilterConfigurationSP config, KoUpdater *progressUpdater) const override; KisFilterConfigurationSP factoryConfiguration() const override; - KisConfigWidget *createConfigurationWidget(QWidget *parent, const KisPaintDeviceSP dev) const override; + KisConfigWidget *createConfigurationWidget(QWidget *parent, const KisPaintDeviceSP dev, bool useForMasks) const override; }; class KisThresholdConfigWidget : public KisConfigWidget { Q_OBJECT public: KisThresholdConfigWidget(QWidget *parent, KisPaintDeviceSP dev); ~KisThresholdConfigWidget() override; KisPropertiesConfigurationSP configuration() const override; void setConfiguration(const KisPropertiesConfigurationSP config) override; Ui::WdgThreshold m_page; private Q_SLOTS: void slotDrawHistogram(bool logarithmic = false); void slotSetThreshold(int); protected: QScopedPointer m_histogram; bool m_histlog; }; #endif diff --git a/plugins/filters/unsharp/kis_unsharp_filter.cpp b/plugins/filters/unsharp/kis_unsharp_filter.cpp index e860a0d522..f782e5ba6f 100644 --- a/plugins/filters/unsharp/kis_unsharp_filter.cpp +++ b/plugins/filters/unsharp/kis_unsharp_filter.cpp @@ -1,229 +1,229 @@ /* * This file is part of Krita * * Copyright (c) 2006 Cyrille Berger * * 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-1301, USA. */ #include //MSVC requires that Vc come first #include "kis_unsharp_filter.h" #include #include #include #include #include #include #include #include #include #include #include #include #include "kis_lod_transform.h" #include "kis_wdg_unsharp.h" #include "ui_wdgunsharp.h" #include "KoColorSpaceTraits.h" #include KisUnsharpFilter::KisUnsharpFilter() : KisFilter(id(), FiltersCategoryEnhanceId, i18n("&Unsharp Mask...")) { setSupportsPainting(true); setSupportsAdjustmentLayers(true); setSupportsThreading(true); /** * Officially Unsharp Mask doesn't support LoD, because it * generates subtle artifacts when the unsharp radius is smaller * than current zoom level. But LoD devices can still appear when * the filter is used in Adjustment Layer. So the actual LoD is * still counted on. */ setSupportsLevelOfDetail(false); setColorSpaceIndependence(FULLY_INDEPENDENT); } -KisConfigWidget * KisUnsharpFilter::createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP) const +KisConfigWidget * KisUnsharpFilter::createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP, bool) const { return new KisWdgUnsharp(parent); } KisFilterConfigurationSP KisUnsharpFilter::factoryConfiguration() const { KisFilterConfigurationSP config = new KisFilterConfiguration(id().id(), 1); config->setProperty("halfSize", 1); config->setProperty("amount", 0.5); config->setProperty("threshold", 0); config->setProperty("lightnessOnly", true); return config; } void KisUnsharpFilter::processImpl(KisPaintDeviceSP device, const QRect& applyRect, const KisFilterConfigurationSP _config, KoUpdater* progressUpdater ) const { QPointer filterUpdater = 0; QPointer convolutionUpdater = 0; QScopedPointer updater; if (progressUpdater) { updater.reset(new KoProgressUpdater(progressUpdater)); updater->start(100, i18n("Unsharp Mask")); // Two sub-sub tasks that each go from 0 to 100. convolutionUpdater = updater->startSubtask(); filterUpdater = updater->startSubtask(); } KisFilterConfigurationSP config = _config ? _config : new KisFilterConfiguration(id().id(), 1); QVariant value; KisLodTransformScalar t(device); const qreal halfSize = t.scale(config->getProperty("halfSize", value) ? value.toDouble() : 1.0); const qreal amount = (config->getProperty("amount", value)) ? value.toDouble() : 0.5; const uint threshold = (config->getProperty("threshold", value)) ? value.toUInt() : 0; const uint lightnessOnly = (config->getProperty("lightnessOnly", value)) ? value.toBool() : true; QBitArray channelFlags = config->channelFlags(); KisGaussianKernel::applyGaussian(device, applyRect, halfSize, halfSize, channelFlags, convolutionUpdater); qreal weights[2]; qreal factor = 128; weights[0] = factor * (1. + amount); weights[1] = -factor * amount; if (lightnessOnly) { processLightnessOnly(device, applyRect, threshold, weights, factor, channelFlags, filterUpdater); } else { processRaw(device, applyRect, threshold, weights, factor, channelFlags, filterUpdater); } } void KisUnsharpFilter::processRaw(KisPaintDeviceSP device, const QRect &rect, quint8 threshold, qreal weights[2], qreal factor, const QBitArray &channelFlags, KoUpdater *progressUpdater) const { const KoColorSpace *cs = device->colorSpace(); const int pixelSize = cs->pixelSize(); KoConvolutionOp * convolutionOp = cs->convolutionOp(); quint8 *colors[2]; colors[0] = new quint8[pixelSize]; colors[1] = new quint8[pixelSize]; KisSequentialIteratorProgress dstIt(device, rect, progressUpdater); while (dstIt.nextPixel()) { quint8 diff = 0; if (threshold == 1) { if (memcmp(dstIt.oldRawData(), dstIt.rawDataConst(), cs->pixelSize()) == 0) { diff = 1; } } else { diff = cs->difference(dstIt.oldRawData(), dstIt.rawDataConst()); } if (diff >= threshold) { memcpy(colors[0], dstIt.oldRawData(), pixelSize); memcpy(colors[1], dstIt.rawDataConst(), pixelSize); convolutionOp->convolveColors(colors, weights, dstIt.rawData(), factor, 0, 2, channelFlags); } else { memcpy(dstIt.rawData(), dstIt.oldRawData(), pixelSize); } } delete[] colors[0]; delete[] colors[1]; } void KisUnsharpFilter::processLightnessOnly(KisPaintDeviceSP device, const QRect &rect, quint8 threshold, qreal weights[2], qreal factor, const QBitArray & /*channelFlags*/, KoUpdater *progressUpdater) const { const KoColorSpace *cs = device->colorSpace(); const int pixelSize = cs->pixelSize(); quint16 labColorSrc[4]; quint16 labColorDst[4]; const int posL = 0; const int posAplha = 3; const qreal factorInv = 1.0 / factor; KisSequentialIteratorProgress dstIt(device, rect, progressUpdater); while (dstIt.nextPixel()) { quint8 diff = cs->differenceA(dstIt.oldRawData(), dstIt.rawDataConst()); if (diff >= threshold) { cs->toLabA16(dstIt.oldRawData(), (quint8*)labColorSrc, 1); cs->toLabA16(dstIt.rawDataConst(), (quint8*)labColorDst, 1); qint32 valueL = (labColorSrc[posL] * weights[0] + labColorDst[posL] * weights[1]) * factorInv; labColorSrc[posL] = CLAMP(valueL, KoColorSpaceMathsTraits::min, KoColorSpaceMathsTraits::max); qint32 valueAlpha = (labColorSrc[posAplha] * weights[0] + labColorDst[posAplha] * weights[1]) * factorInv; labColorSrc[posAplha] = CLAMP(valueAlpha, KoColorSpaceMathsTraits::min, KoColorSpaceMathsTraits::max); cs->fromLabA16((quint8*)labColorSrc, dstIt.rawData(), 1); } else { memcpy(dstIt.rawData(), dstIt.oldRawData(), pixelSize); } } } QRect KisUnsharpFilter::neededRect(const QRect & rect, const KisFilterConfigurationSP config, int lod) const { KisLodTransformScalar t(lod); QVariant value; const qreal halfSize = t.scale(config->getProperty("halfSize", value) ? value.toDouble() : 1.0); return rect.adjusted(-halfSize * 2, -halfSize * 2, halfSize * 2, halfSize * 2); } QRect KisUnsharpFilter::changedRect(const QRect & rect, const KisFilterConfigurationSP config, int lod) const { KisLodTransformScalar t(lod); QVariant value; const qreal halfSize = t.scale(config->getProperty("halfSize", value) ? value.toDouble() : 1.0); return rect.adjusted( -halfSize, -halfSize, halfSize, halfSize); } diff --git a/plugins/filters/unsharp/kis_unsharp_filter.h b/plugins/filters/unsharp/kis_unsharp_filter.h index abd8573c43..2395e673c3 100644 --- a/plugins/filters/unsharp/kis_unsharp_filter.h +++ b/plugins/filters/unsharp/kis_unsharp_filter.h @@ -1,64 +1,64 @@ /* * This file is part of Krita * * Copyright (c) 2006 Cyrille Berger * * 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-1301, USA. */ #ifndef KIS_UNSHARP_FILTER_H #define KIS_UNSHARP_FILTER_H #include "filter/kis_filter.h" class KisUnsharpFilter : public KisFilter { public: KisUnsharpFilter(); void processImpl(KisPaintDeviceSP device, const QRect& applyRect, const KisFilterConfigurationSP config, KoUpdater* progressUpdater ) const override; static inline KoID id() { return KoID("unsharp", i18n("Unsharp Mask")); } - KisConfigWidget * createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev) const override; + KisConfigWidget * createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev, bool useForMasks) const override; KisFilterConfigurationSP factoryConfiguration() const override; QRect changedRect(const QRect & rect, const KisFilterConfigurationSP _config, int lod) const override; QRect neededRect(const QRect & rect, const KisFilterConfigurationSP _config, int lod) const override; private: void processLightnessOnly(KisPaintDeviceSP device, const QRect &rect, quint8 threshold, qreal weights[2], qreal factor, const QBitArray &channelFlags, KoUpdater *progressUpdater) const; void processRaw(KisPaintDeviceSP device, const QRect &rect, quint8 threshold, qreal weights[2], qreal factor, const QBitArray &channelFlags, KoUpdater *progressUpdater) const; }; #endif diff --git a/plugins/filters/wavefilter/wavefilter.cpp b/plugins/filters/wavefilter/wavefilter.cpp index d074187b84..10996d155e 100644 --- a/plugins/filters/wavefilter/wavefilter.cpp +++ b/plugins/filters/wavefilter/wavefilter.cpp @@ -1,177 +1,177 @@ /* * This file is part of the KDE project * * Copyright (c) 2005 Cyrille Berger * * 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-1301, USA. */ #include "wavefilter.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "kis_wdg_wave.h" #include "ui_wdgwaveoptions.h" #include #include K_PLUGIN_FACTORY_WITH_JSON(KritaWaveFilterFactory, "kritawavefilter.json", registerPlugin();) class KisWaveCurve { public: virtual ~KisWaveCurve() {} virtual double valueAt(int x, int y) = 0; }; class KisSinusoidalWaveCurve : public KisWaveCurve { public: KisSinusoidalWaveCurve(int amplitude, int wavelength, int shift) : m_amplitude(amplitude), m_wavelength(wavelength), m_shift(shift) { } ~KisSinusoidalWaveCurve() override {} double valueAt(int x, int y) override { return y + m_amplitude * cos((double)(m_shift + x) / m_wavelength); } private: int m_amplitude, m_wavelength, m_shift; }; class KisTriangleWaveCurve : public KisWaveCurve { public: KisTriangleWaveCurve(int amplitude, int wavelength, int shift) : m_amplitude(amplitude), m_wavelength(wavelength), m_shift(shift) { } ~KisTriangleWaveCurve() override {} double valueAt(int x, int y) override { return y + m_amplitude * pow(-1.0, (m_shift + x) / m_wavelength) *(0.5 - (double)((m_shift + x) % m_wavelength) / m_wavelength); } private: int m_amplitude, m_wavelength, m_shift; }; KritaWaveFilter::KritaWaveFilter(QObject *parent, const QVariantList &) : QObject(parent) { KisFilterRegistry::instance()->add(new KisFilterWave()); } KritaWaveFilter::~KritaWaveFilter() { } KisFilterWave::KisFilterWave() : KisFilter(id(), FiltersCategoryOtherId, i18n("&Wave...")) { setColorSpaceIndependence(FULLY_INDEPENDENT); setSupportsPainting(false); setSupportsAdjustmentLayers(false); } KisFilterConfigurationSP KisFilterWave::factoryConfiguration() const { KisFilterConfigurationSP config = new KisFilterConfiguration("wave", 1); config->setProperty("horizontalwavelength", 50); config->setProperty("horizontalshift", 50); config->setProperty("horizontalamplitude", 4); config->setProperty("horizontalshape", 0); config->setProperty("verticalwavelength", 50); config->setProperty("verticalshift", 50); config->setProperty("verticalamplitude", 4); config->setProperty("verticalshape", 0); return config; } -KisConfigWidget * KisFilterWave::createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP) const +KisConfigWidget * KisFilterWave::createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP, bool) const { return new KisWdgWave((KisFilter*)this, (QWidget*)parent); } void KisFilterWave::processImpl(KisPaintDeviceSP device, const QRect& applyRect, const KisFilterConfigurationSP config, KoUpdater* progressUpdater ) const { Q_ASSERT(device.data() != 0); QVariant value; int horizontalwavelength = (config && config->getProperty("horizontalwavelength", value)) ? value.toInt() : 50; int horizontalshift = (config && config->getProperty("horizontalshift", value)) ? value.toInt() : 50; int horizontalamplitude = (config && config->getProperty("horizontalamplitude", value)) ? value.toInt() : 4; int horizontalshape = (config && config->getProperty("horizontalshape", value)) ? value.toInt() : 0; int verticalwavelength = (config && config->getProperty("verticalwavelength", value)) ? value.toInt() : 50; int verticalshift = (config && config->getProperty("verticalshift", value)) ? value.toInt() : 50; int verticalamplitude = (config && config->getProperty("verticalamplitude", value)) ? value.toInt() : 4; int verticalshape = (config && config->getProperty("verticalshape", value)) ? value.toInt() : 0; KisWaveCurve* verticalcurve; if (verticalshape == 1) verticalcurve = new KisTriangleWaveCurve(verticalamplitude, verticalwavelength, verticalshift); else verticalcurve = new KisSinusoidalWaveCurve(verticalamplitude, verticalwavelength, verticalshift); KisWaveCurve* horizontalcurve; if (horizontalshape == 1) horizontalcurve = new KisTriangleWaveCurve(horizontalamplitude, horizontalwavelength, horizontalshift); else horizontalcurve = new KisSinusoidalWaveCurve(horizontalamplitude, horizontalwavelength, horizontalshift); KisSequentialIteratorProgress dstIt(device, applyRect, progressUpdater); KisRandomSubAccessorSP srcRSA = device->createRandomSubAccessor(); while (dstIt.nextPixel()) { double xv = horizontalcurve->valueAt(dstIt.y(), dstIt.x()); double yv = verticalcurve->valueAt(dstIt.x(), dstIt.y()); srcRSA->moveTo(QPointF(xv, yv)); srcRSA->sampledOldRawData(dstIt.rawData()); } delete horizontalcurve; delete verticalcurve; } QRect KisFilterWave::neededRect(const QRect& rect, const KisFilterConfigurationSP config, int lod) const { Q_UNUSED(lod); QVariant value; int horizontalamplitude = (config && config->getProperty("horizontalamplitude", value)) ? value.toInt() : 4; int verticalamplitude = (config && config->getProperty("verticalamplitude", value)) ? value.toInt() : 4; return rect.adjusted(-horizontalamplitude, -verticalamplitude, horizontalamplitude, verticalamplitude); } #include "wavefilter.moc" diff --git a/plugins/filters/wavefilter/wavefilter.h b/plugins/filters/wavefilter/wavefilter.h index cc2921f766..1465fa0003 100644 --- a/plugins/filters/wavefilter/wavefilter.h +++ b/plugins/filters/wavefilter/wavefilter.h @@ -1,61 +1,61 @@ /* * This file is part of Krita * * Copyright (c) 2006 Cyrille Berger * * 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-1301, USA. */ #ifndef WAVEFILTER_H #define WAVEFILTER_H #include #include #include "filter/kis_filter.h" class KisConfigWidget; class KritaWaveFilter : public QObject { Q_OBJECT public: KritaWaveFilter(QObject *parent, const QVariantList &); ~KritaWaveFilter() override; }; class KisFilterWave : public KisFilter { public: KisFilterWave(); public: void processImpl(KisPaintDeviceSP device, const QRect& applyRect, const KisFilterConfigurationSP config, KoUpdater* progressUpdater) const override; static inline KoID id() { return KoID("wave", i18n("Wave")); } KisFilterConfigurationSP factoryConfiguration() const override; public: QRect neededRect(const QRect& rect, const KisFilterConfigurationSP config = 0, int lod = 0) const override; - KisConfigWidget * createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev) const override; + KisConfigWidget * createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev, bool useForMasks) const override; }; #endif diff --git a/plugins/generators/pattern/patterngenerator.cpp b/plugins/generators/pattern/patterngenerator.cpp index 09dffd5cec..61d20f5875 100644 --- a/plugins/generators/pattern/patterngenerator.cpp +++ b/plugins/generators/pattern/patterngenerator.cpp @@ -1,121 +1,121 @@ /* * This file is part of the KDE project * * Copyright (c) 2008 Boudewijn Rempt * * 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-1301, USA. */ #include "patterngenerator.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "kis_wdg_pattern.h" #include "ui_wdgpatternoptions.h" K_PLUGIN_FACTORY_WITH_JSON(KritaPatternGeneratorFactory, "kritapatterngenerator.json", registerPlugin();) KritaPatternGenerator::KritaPatternGenerator(QObject *parent, const QVariantList &) : QObject(parent) { KisGeneratorRegistry::instance()->add(new KoPatternGenerator()); } KritaPatternGenerator::~KritaPatternGenerator() { } KoPatternGenerator::KoPatternGenerator() : KisGenerator(id(), KoID("basic"), i18n("&Pattern...")) { setColorSpaceIndependence(FULLY_INDEPENDENT); setSupportsPainting(true); } KisFilterConfigurationSP KoPatternGenerator::factoryConfiguration() const { KisFilterConfigurationSP config = new KisFilterConfiguration("pattern", 1); QVariant v; v.setValue(QString("Grid01.pat")); config->setProperty("pattern", v); // v.setValue(KoColor()); // config->setProperty("color", v); return config; } -KisConfigWidget * KoPatternGenerator::createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev) const +KisConfigWidget * KoPatternGenerator::createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev, bool) const { Q_UNUSED(dev); return new KisWdgPattern(parent); } void KoPatternGenerator::generate(KisProcessingInformation dstInfo, const QSize& size, const KisFilterConfigurationSP config, KoUpdater* progressUpdater) const { KisPaintDeviceSP dst = dstInfo.paintDevice(); Q_ASSERT(!dst.isNull()); Q_ASSERT(config); if (!config) return; QString patternName = config->getString("pattern", "Grid01.pat"); KoResourceServer *rserver = KoResourceServerProvider::instance()->patternServer(); KoPattern *pattern = rserver->resourceByName(patternName); // KoColor c = config->getColor("color"); KisFillPainter gc(dst); gc.setPattern(pattern); // gc.setPaintColor(c); gc.setProgress(progressUpdater); gc.setChannelFlags(config->channelFlags()); gc.setOpacity(OPACITY_OPAQUE_U8); gc.setSelection(dstInfo.selection()); gc.setWidth(size.width()); gc.setHeight(size.height()); gc.setFillStyle(KisFillPainter::FillStylePattern); gc.fillRect(QRect(dstInfo.topLeft(), size), pattern); gc.end(); } #include "patterngenerator.moc" diff --git a/plugins/generators/pattern/patterngenerator.h b/plugins/generators/pattern/patterngenerator.h index 806e71d574..063edbe0d6 100644 --- a/plugins/generators/pattern/patterngenerator.h +++ b/plugins/generators/pattern/patterngenerator.h @@ -1,59 +1,59 @@ /* * This file is part of Krita * * Copyright (c) 2006 Cyrille Berger * * 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-1301, USA. */ #ifndef PATTERN_GENERATOR_H #define PATTERN_GENERATOR_H #include #include #include "generator/kis_generator.h" class KisConfigWidget; class KritaPatternGenerator : public QObject { Q_OBJECT public: KritaPatternGenerator(QObject *parent, const QVariantList &); ~KritaPatternGenerator() override; }; class KoPatternGenerator : public KisGenerator { public: KoPatternGenerator(); using KisGenerator::generate; void generate(KisProcessingInformation dst, const QSize& size, const KisFilterConfigurationSP config, KoUpdater* progressUpdater ) const override; static inline KoID id() { return KoID("pattern", i18n("Pattern")); } KisFilterConfigurationSP factoryConfiguration() const override; - KisConfigWidget * createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev) const override; + KisConfigWidget * createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev, bool useForMasks) const override; }; #endif diff --git a/plugins/generators/simplexnoise/simplexnoisegenerator.cpp b/plugins/generators/simplexnoise/simplexnoisegenerator.cpp index 6cf2635a57..67499910e3 100644 --- a/plugins/generators/simplexnoise/simplexnoisegenerator.cpp +++ b/plugins/generators/simplexnoise/simplexnoisegenerator.cpp @@ -1,149 +1,149 @@ /* * KDE. Krita Project. * * Copyright (c) 2019 Eoin O'Neill * Copyright (c) 2019 Emmet O'Neill * * 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-1301, USA. */ #include "simplexnoisegenerator.h" #include "ui_wdgsimplexnoiseoptions.h" #include "kis_wdg_simplex_noise.h" #include "3rdparty/c-open-simplex/open-simplex-noise.h" #include #include #include #include #include #include #include K_PLUGIN_FACTORY_WITH_JSON(KritaSimplexNoiseGeneratorFactory, "kritasimplexnoisegenerator.json", registerPlugin();) KisSimplexNoiseGeneratorHandle::KisSimplexNoiseGeneratorHandle(QObject *parent, const QVariantList &) : QObject(parent) { KisGeneratorRegistry::instance()->add(new KisSimplexNoiseGenerator()); } KisSimplexNoiseGeneratorHandle::~KisSimplexNoiseGeneratorHandle() { } KisSimplexNoiseGenerator::KisSimplexNoiseGenerator() : KisGenerator(id(), KoID("basic"), i18n("&Simplex Noise...")) { setColorSpaceIndependence(FULLY_INDEPENDENT); setSupportsPainting(true); } void KisSimplexNoiseGenerator::generate(KisProcessingInformation dst, const QSize &size, const KisFilterConfigurationSP config, KoUpdater *progressUpdater) const { KisPaintDeviceSP device = dst.paintDevice(); Q_ASSERT(!device.isNull()); osn_context *noise_context; QRect bounds = QRect(dst.topLeft(), size); const KoColorSpace * cs = device->colorSpace(); KisSequentialIteratorProgress it(device, bounds, progressUpdater); QVariant property; const uint default_seed = (config->getProperty("seed", property)) ? property.toUInt() : 0; const QString custom_seed_string = (config->getProperty("custom_seed_string", property)) ? property.toString() : ""; const bool use_custom_seed = !custom_seed_string.trimmed().isEmpty(); const uint seed = use_custom_seed ? seedFromString(custom_seed_string) : default_seed; open_simplex_noise(seed, &noise_context); double frequency = (config && config->getProperty("frequency", property)) ? property.toDouble() : 25.0; double ratio_x = (config && config->getProperty("ratio_x", property)) ? property.toDouble() : 1.0; double ratio_y = (config && config->getProperty("ratio_y", property)) ? property.toDouble() : 1.0; bool looping = (config && config->getProperty("looping", property)) ? property.toBool() : false; if( looping ){ float major_radius = 0.5f * frequency * ratio_x; float minor_radius = 0.5f * frequency * ratio_y; while(it.nextPixel()){ double x_phase = (double)it.x() / (double)bounds.width() * M_PI * 2; double y_phase = (double)it.y() / (double)(bounds.height()) * M_PI * 2; double x_coordinate = major_radius * map_range(cos(x_phase), -1.0, 1.0, 0.0, 1.0); double y_coordinate = major_radius * map_range(sin(x_phase), -1.0, 1.0, 0.0, 1.0); double z_coordinate = minor_radius * map_range(cos(y_phase), -1.0, 1.0, 0.0, 1.0); double w_coordinate = minor_radius * map_range(sin(y_phase), -1.0, 1.0, 0.0, 1.0); double value = open_simplex_noise4(noise_context, x_coordinate, y_coordinate, z_coordinate, w_coordinate); value = map_range(value, -1.0, 1.0, 0.0, 255.0); QColor color = qRgb(static_cast(value), static_cast(value), static_cast(value)); cs->fromQColor(color, it.rawData()); } } else { while(it.nextPixel()){ double x_phase = (double)it.x() / (double)(bounds.width()) * ratio_x; double y_phase = (double)it.y() / (double)(bounds.height()) * ratio_y; double value = open_simplex_noise4(noise_context, x_phase * frequency, y_phase * frequency, x_phase * frequency, y_phase * frequency); value = map_range(value, -1.0, 1.0, 0.0, 255.0); QColor color = qRgb(static_cast(value), static_cast(value), static_cast(value)); cs->fromQColor(color, it.rawData()); } } open_simplex_noise_free(noise_context); } KisFilterConfigurationSP KisSimplexNoiseGenerator::factoryConfiguration() const { KisFilterConfigurationSP config = new KisFilterConfiguration("simplex_noise", 1); config->setProperty("looping", false); config->setProperty("frequency", 25.0); uint seed = static_cast(rand()); config->setProperty("seed", seed); config->setProperty("custom_seed_string", ""); config->setProperty("ratio_x", 1.0f); config->setProperty("ratio_y", 1.0f); return config; } -KisConfigWidget * KisSimplexNoiseGenerator::createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev) const +KisConfigWidget * KisSimplexNoiseGenerator::createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev, bool) const { Q_UNUSED(dev); return new KisWdgSimplexNoise((KisFilter*)this, (QWidget*)parent); } uint KisSimplexNoiseGenerator::seedFromString(const QString &string) const { QByteArray bytes = QCryptographicHash::hash(string.toUtf8(),QCryptographicHash::Md5); uint hash = 0; for( int index = 0; index < bytes.length(); index++){ hash += rotateLeft(bytes[index], index % 32); } return hash; } quint64 KisSimplexNoiseGenerator::rotateLeft(const quint64 input, uint shift) const { return (input << shift)|(input >> (64 - shift)); } #include "simplexnoisegenerator.moc" diff --git a/plugins/generators/simplexnoise/simplexnoisegenerator.h b/plugins/generators/simplexnoise/simplexnoisegenerator.h index 1f3ff2eae1..a10afa84c4 100644 --- a/plugins/generators/simplexnoise/simplexnoisegenerator.h +++ b/plugins/generators/simplexnoise/simplexnoisegenerator.h @@ -1,65 +1,65 @@ /* * KDE. Krita Project. * * Copyright (c) 2019 Eoin O'Neill * Copyright (c) 2019 Emmet O'Neill * * 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-1301, USA. */ #ifndef NOISEFILTER_H #define NOISEFILTER_H #include #include "generator/kis_generator.h" class KisConfigWidget; class KisSimplexNoiseGeneratorHandle : public QObject { Q_OBJECT public: KisSimplexNoiseGeneratorHandle(QObject *parent, const QVariantList &); ~KisSimplexNoiseGeneratorHandle() override; }; class KisSimplexNoiseGenerator : public KisGenerator { public: KisSimplexNoiseGenerator(); using KisGenerator::generate; virtual void generate(KisProcessingInformation dst, const QSize& size, const KisFilterConfigurationSP config, KoUpdater* progressUpdater ) const override; static inline KoID id() { return KoID("simplex_noise", i18n("Simplex Noise")); } KisFilterConfigurationSP factoryConfiguration() const override; - KisConfigWidget * createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev) const override; + KisConfigWidget * createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev, bool useForMasks) const override; uint seedFromString(const QString &string) const; quint64 rotateLeft(const quint64 input, uint d) const; static inline double map_range(double value, double curr_min, double curr_max, double new_min, double new_max ) { return (value - curr_min) * (new_max - new_min) / (curr_max - curr_min) + new_min; } }; #endif diff --git a/plugins/generators/solid/colorgenerator.cpp b/plugins/generators/solid/colorgenerator.cpp index b0631e0bb3..f5df6bd65d 100644 --- a/plugins/generators/solid/colorgenerator.cpp +++ b/plugins/generators/solid/colorgenerator.cpp @@ -1,103 +1,103 @@ /* * This file is part of the KDE project * * Copyright (c) 2008 Boudewijn Rempt * * 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-1301, USA. */ #include "colorgenerator.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "kis_wdg_color.h" #include "ui_wdgcoloroptions.h" K_PLUGIN_FACTORY_WITH_JSON(KritaColorGeneratorFactory, "kritacolorgenerator.json", registerPlugin();) KritaColorGenerator::KritaColorGenerator(QObject *parent, const QVariantList &) : QObject(parent) { KisGeneratorRegistry::instance()->add(new KisColorGenerator()); } KritaColorGenerator::~KritaColorGenerator() { } KisColorGenerator::KisColorGenerator() : KisGenerator(id(), KoID("basic"), i18n("&Solid Color...")) { setColorSpaceIndependence(FULLY_INDEPENDENT); setSupportsPainting(true); } KisFilterConfigurationSP KisColorGenerator::factoryConfiguration() const { KisFilterConfigurationSP config = new KisFilterConfiguration("color", 1); QVariant v; v.setValue(KoColor()); config->setProperty("color", v); return config; } -KisConfigWidget * KisColorGenerator::createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev) const +KisConfigWidget * KisColorGenerator::createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev, bool) const { Q_UNUSED(dev); return new KisWdgColor(parent); } void KisColorGenerator::generate(KisProcessingInformation dstInfo, const QSize& size, const KisFilterConfigurationSP config, KoUpdater* progressUpdater) const { KisPaintDeviceSP dst = dstInfo.paintDevice(); Q_ASSERT(!dst.isNull()); Q_ASSERT(config); KoColor c; if (config) { c = config->getColor("color"); KisFillPainter gc(dst); gc.setProgress(progressUpdater); gc.setChannelFlags(config->channelFlags()); gc.setOpacity(100); gc.setSelection(dstInfo.selection()); gc.fillRect(QRect(dstInfo.topLeft(), size), c); gc.end(); } } #include "colorgenerator.moc" diff --git a/plugins/generators/solid/colorgenerator.h b/plugins/generators/solid/colorgenerator.h index f8d6b4763c..e9c8c0759f 100644 --- a/plugins/generators/solid/colorgenerator.h +++ b/plugins/generators/solid/colorgenerator.h @@ -1,59 +1,59 @@ /* * This file is part of Krita * * Copyright (c) 2006 Cyrille Berger * * 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-1301, USA. */ #ifndef COLOR_GENERATOR_H #define COLOR_GENERATOR_H #include #include #include "generator/kis_generator.h" class KisConfigWidget; class KritaColorGenerator : public QObject { Q_OBJECT public: KritaColorGenerator(QObject *parent, const QVariantList &); ~KritaColorGenerator() override; }; class KisColorGenerator : public KisGenerator { public: KisColorGenerator(); using KisGenerator::generate; void generate(KisProcessingInformation dst, const QSize& size, const KisFilterConfigurationSP config, KoUpdater* progressUpdater ) const override; static inline KoID id() { return KoID("color", i18n("Color")); } KisFilterConfigurationSP factoryConfiguration() const override; - KisConfigWidget * createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev) const override; + KisConfigWidget * createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev, bool useForMasks) const override; }; #endif diff --git a/plugins/impex/libkra/kis_kra_load_visitor.cpp b/plugins/impex/libkra/kis_kra_load_visitor.cpp index 1e3e8494d1..1739d04177 100644 --- a/plugins/impex/libkra/kis_kra_load_visitor.cpp +++ b/plugins/impex/libkra/kis_kra_load_visitor.cpp @@ -1,753 +1,769 @@ /* * Copyright (c) 2002 Patrick Julien * Copyright (c) 2005 C. Boemann * * 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-1301, USA. */ #include "kis_kra_load_visitor.h" #include "kis_kra_tags.h" #include "flake/kis_shape_layer.h" #include "flake/KisReferenceImagesLayer.h" #include "KisReferenceImage.h" #include #include #include #include #include #include #include #include #include #include #include // kritaimage #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "kis_transform_mask_params_factory_registry.h" #include #include #include #include #include "kis_shape_selection.h" #include "kis_colorize_dom_utils.h" #include "kis_dom_utils.h" #include "kis_raster_keyframe_channel.h" #include "kis_paint_device_frames_interface.h" +#include "kis_filter_registry.h" + using namespace KRA; QString expandEncodedDirectory(const QString& _intern) { QString intern = _intern; QString result; int pos; while ((pos = intern.indexOf('/')) != -1) { if (QChar(intern.at(0)).isDigit()) result += "part"; result += intern.left(pos + 1); // copy numbers (or "pictures") + "/" intern = intern.mid(pos + 1); // remove the dir we just processed } if (!intern.isEmpty() && QChar(intern.at(0)).isDigit()) result += "part"; result += intern; return result; } KisKraLoadVisitor::KisKraLoadVisitor(KisImageSP image, KoStore *store, KoShapeControllerBase *shapeController, QMap &layerFilenames, QMap &keyframeFilenames, const QString & name, int syntaxVersion) : KisNodeVisitor() , m_image(image) , m_store(store) , m_external(false) , m_layerFilenames(layerFilenames) , m_keyframeFilenames(keyframeFilenames) , m_name(name) , m_shapeController(shapeController) { m_store->pushDirectory(); if (!m_store->enterDirectory(m_name)) { QStringList directories = m_store->directoryList(); dbgKrita << directories; if (directories.size() > 0) { dbgFile << "Could not locate the directory, maybe some encoding issue? Grab the first directory, that'll be the image one." << m_name << directories; m_name = directories.first(); } else { dbgFile << "Could not enter directory" << m_name << ", probably an old-style file with 'part' added."; m_name = expandEncodedDirectory(m_name); } } else { m_store->popDirectory(); } m_syntaxVersion = syntaxVersion; } void KisKraLoadVisitor::setExternalUri(const QString &uri) { m_external = true; m_uri = uri; } bool KisKraLoadVisitor::visit(KisExternalLayer * layer) { bool result = false; if (auto *referencesLayer = dynamic_cast(layer)) { Q_FOREACH(KoShape *shape, referencesLayer->shapes()) { auto *reference = dynamic_cast(shape); KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(reference, false); while (!reference->loadImage(m_store)) { if (reference->embed()) { m_errorMessages << i18n("Could not load embedded reference image %1 ", reference->internalFile()); break; } else { QString msg = i18nc( "@info", "A reference image linked to an external file could not be loaded.\n\n" "Path: %1\n\n" "Do you want to select another location?", reference->filename()); int locateManually = QMessageBox::warning(0, i18nc("@title:window", "File not found"), msg, QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); QString url; if (locateManually == QMessageBox::Yes) { KoFileDialog dialog(0, KoFileDialog::OpenFile, "OpenDocument"); dialog.setMimeTypeFilters(KisImportExportManager::supportedMimeTypes(KisImportExportManager::Import)); url = dialog.filename(); } if (url.isEmpty()) { break; } else { reference->setFilename(url); } } } } } else if (KisShapeLayer *shapeLayer = dynamic_cast(layer)) { if (!loadMetaData(layer)) { return false; } m_store->pushDirectory(); m_store->enterDirectory(getLocation(layer, DOT_SHAPE_LAYER)) ; result = shapeLayer->loadLayer(m_store); m_store->popDirectory(); } result = visitAll(layer) && result; return result; } bool KisKraLoadVisitor::visit(KisPaintLayer *layer) { loadNodeKeyframes(layer); if (!loadPaintDevice(layer->paintDevice(), getLocation(layer))) { return false; } if (!loadProfile(layer->paintDevice(), getLocation(layer, DOT_ICC))) { return false; } if (!loadMetaData(layer)) { return false; } if (m_syntaxVersion == 1) { // Check whether there is a file with a .mask extension in the // layer directory, if so, it's an old-style transparency mask // that should be converted. QString location = getLocation(layer, ".mask"); if (m_store->open(location)) { KisSelectionSP selection = KisSelectionSP(new KisSelection()); KisPixelSelectionSP pixelSelection = selection->pixelSelection(); if (!pixelSelection->read(m_store->device())) { pixelSelection->disconnect(); } else { KisTransparencyMask* mask = new KisTransparencyMask(); mask->setSelection(selection); m_image->addNode(mask, layer, layer->firstChild()); } m_store->close(); } } bool result = visitAll(layer); return result; } bool KisKraLoadVisitor::visit(KisGroupLayer *layer) { if (*layer->colorSpace() != *m_image->colorSpace()) { layer->resetCache(m_image->colorSpace()); } if (!loadMetaData(layer)) { return false; } bool result = visitAll(layer); return result; } bool KisKraLoadVisitor::visit(KisAdjustmentLayer* layer) { loadNodeKeyframes(layer); // Adjustmentlayers are tricky: there's the 1.x style and the 2.x // style, which has selections with selection components bool result = true; if (m_syntaxVersion == 1) { KisSelectionSP selection = new KisSelection(); KisPixelSelectionSP pixelSelection = selection->pixelSelection(); result = loadPaintDevice(pixelSelection, getLocation(layer, ".selection")); layer->setInternalSelection(selection); } else if (m_syntaxVersion == 2) { result = loadSelection(getLocation(layer), layer->internalSelection()); } else { // We use the default, empty selection } if (!loadMetaData(layer)) { return false; } - loadFilterConfiguration(layer->filter().data(), getLocation(layer, DOT_FILTERCONFIG)); + loadFilterConfiguration(layer->filter(), getLocation(layer, DOT_FILTERCONFIG)); + fixOldFilterConfigurations(layer->filter()); result = visitAll(layer); return result; } bool KisKraLoadVisitor::visit(KisGeneratorLayer *layer) { if (!loadMetaData(layer)) { return false; } bool result = true; loadNodeKeyframes(layer); result = loadSelection(getLocation(layer), layer->internalSelection()); // HACK ALERT: we set the same filter again to ensure the layer // is correctly updated KisFilterConfigurationSP filter = layer->filter(); result = loadFilterConfiguration(filter.data(), getLocation(layer, DOT_FILTERCONFIG)); layer->setFilter(filter); result = visitAll(layer); return result; } bool KisKraLoadVisitor::visit(KisCloneLayer *layer) { if (!loadMetaData(layer)) { return false; } // the layer might have already been lazily initialized // from the mask loading code if (layer->copyFrom()) { return true; } KisNodeSP srcNode = layer->copyFromInfo().findNode(m_image->rootLayer()); KisLayerSP srcLayer = qobject_cast(srcNode.data()); Q_ASSERT(srcLayer); layer->setCopyFrom(srcLayer); // Clone layers have no data except for their masks bool result = visitAll(layer); return result; } void KisKraLoadVisitor::initSelectionForMask(KisMask *mask) { KisLayer *cloneLayer = dynamic_cast(mask->parent().data()); if (cloneLayer) { // the clone layers should be initialized out of order // and lazily, because their original() is still not // initialized cloneLayer->accept(*this); } KisLayer *parentLayer = qobject_cast(mask->parent().data()); // the KisKraLoader must have already set the parent for us Q_ASSERT(parentLayer); mask->initSelection(parentLayer); } bool KisKraLoadVisitor::visit(KisFilterMask *mask) { initSelectionForMask(mask); loadNodeKeyframes(mask); bool result = true; result = loadSelection(getLocation(mask), mask->selection()); - result = loadFilterConfiguration(mask->filter().data(), getLocation(mask, DOT_FILTERCONFIG)); + result = loadFilterConfiguration(mask->filter(), getLocation(mask, DOT_FILTERCONFIG)); + fixOldFilterConfigurations(mask->filter()); return result; } bool KisKraLoadVisitor::visit(KisTransformMask *mask) { QString location = getLocation(mask, DOT_TRANSFORMCONFIG); if (m_store->hasFile(location)) { QByteArray data; m_store->open(location); data = m_store->read(m_store->size()); m_store->close(); if (!data.isEmpty()) { QDomDocument doc; doc.setContent(data); QDomElement rootElement = doc.documentElement(); QDomElement main; if (!KisDomUtils::findOnlyElement(rootElement, "main", &main/*, &m_errorMessages*/)) { return false; } QString id = main.attribute("id", "not-valid"); if (id == "not-valid") { m_errorMessages << i18n("Could not load \"id\" of the transform mask"); return false; } QDomElement data; if (!KisDomUtils::findOnlyElement(rootElement, "data", &data, &m_errorMessages)) { return false; } KisTransformMaskParamsInterfaceSP params = KisTransformMaskParamsFactoryRegistry::instance()->createParams(id, data); if (!params) { m_errorMessages << i18n("Could not create transform mask params"); return false; } mask->setTransformParams(params); loadNodeKeyframes(mask); params->clearChangedFlag(); return true; } } return false; } bool KisKraLoadVisitor::visit(KisTransparencyMask *mask) { initSelectionForMask(mask); loadNodeKeyframes(mask); return loadSelection(getLocation(mask), mask->selection()); } bool KisKraLoadVisitor::visit(KisSelectionMask *mask) { initSelectionForMask(mask); return loadSelection(getLocation(mask), mask->selection()); } bool KisKraLoadVisitor::visit(KisColorizeMask *mask) { m_store->pushDirectory(); QString location = getLocation(mask, DOT_COLORIZE_MASK); m_store->enterDirectory(location) ; QByteArray data; if (!m_store->extractFile("content.xml", data)) return false; QDomDocument doc; if (!doc.setContent(data)) return false; QVector strokes; if (!KisDomUtils::loadValue(doc.documentElement(), COLORIZE_KEYSTROKES_SECTION, &strokes, mask->colorSpace())) return false; int i = 0; Q_FOREACH (const KisLazyFillTools::KeyStroke &stroke, strokes) { const QString fileName = QString("%1_%2").arg(COLORIZE_KEYSTROKE).arg(i++); loadPaintDevice(stroke.dev, fileName); } mask->setKeyStrokesDirect(QList::fromVector(strokes)); loadPaintDevice(mask->coloringProjection(), COLORIZE_COLORING_DEVICE); mask->resetCache(); m_store->popDirectory(); return true; } QStringList KisKraLoadVisitor::errorMessages() const { return m_errorMessages; } QStringList KisKraLoadVisitor::warningMessages() const { return m_warningMessages; } struct SimpleDevicePolicy { bool read(KisPaintDeviceSP dev, QIODevice *stream) { return dev->read(stream); } void setDefaultPixel(KisPaintDeviceSP dev, const KoColor &defaultPixel) const { return dev->setDefaultPixel(defaultPixel); } }; struct FramedDevicePolicy { FramedDevicePolicy(int frameId) : m_frameId(frameId) {} bool read(KisPaintDeviceSP dev, QIODevice *stream) { return dev->framesInterface()->readFrame(stream, m_frameId); } void setDefaultPixel(KisPaintDeviceSP dev, const KoColor &defaultPixel) const { return dev->framesInterface()->setFrameDefaultPixel(defaultPixel, m_frameId); } int m_frameId; }; bool KisKraLoadVisitor::loadPaintDevice(KisPaintDeviceSP device, const QString& location) { // Layer data KisPaintDeviceFramesInterface *frameInterface = device->framesInterface(); QList frames; if (frameInterface) { frames = device->framesInterface()->frames(); } if (!frameInterface || frames.count() <= 1) { return loadPaintDeviceFrame(device, location, SimpleDevicePolicy()); } else { KisRasterKeyframeChannel *keyframeChannel = device->keyframeChannel(); for (int i = 0; i < frames.count(); i++) { int id = frames[i]; if (keyframeChannel->frameFilename(id).isEmpty()) { m_warningMessages << i18n("Could not find keyframe pixel data for frame %1 in %2.", id, location); } else { Q_ASSERT(!keyframeChannel->frameFilename(id).isEmpty()); QString frameFilename = getLocation(keyframeChannel->frameFilename(id)); Q_ASSERT(!frameFilename.isEmpty()); if (!loadPaintDeviceFrame(device, frameFilename, FramedDevicePolicy(id))) { m_warningMessages << i18n("Could not load keyframe pixel data for frame %1 in %2.", id, location); } } } } return true; } template bool KisKraLoadVisitor::loadPaintDeviceFrame(KisPaintDeviceSP device, const QString &location, DevicePolicy policy) { { const int pixelSize = device->colorSpace()->pixelSize(); KoColor color(Qt::transparent, device->colorSpace()); if (m_store->open(location + ".defaultpixel")) { if (m_store->size() == pixelSize) { m_store->read((char*)color.data(), pixelSize); } m_store->close(); } policy.setDefaultPixel(device, color); } if (m_store->open(location)) { if (!policy.read(device, m_store->device())) { m_warningMessages << i18n("Could not read pixel data: %1.", location); device->disconnect(); m_store->close(); return true; } m_store->close(); } else { m_warningMessages << i18n("Could not load pixel data: %1.", location); return true; } return true; } bool KisKraLoadVisitor::loadProfile(KisPaintDeviceSP device, const QString& location) { if (m_store->hasFile(location)) { m_store->open(location); QByteArray data; data.resize(m_store->size()); dbgFile << "Data to load: " << m_store->size() << " from " << location << " with color space " << device->colorSpace()->id(); int read = m_store->read(data.data(), m_store->size()); dbgFile << "Profile size: " << data.size() << " " << m_store->atEnd() << " " << m_store->device()->bytesAvailable() << " " << read; m_store->close(); // Create a colorspace with the embedded profile const KoColorProfile *profile = KoColorSpaceRegistry::instance()->createColorProfile(device->colorSpace()->colorModelId().id(), device->colorSpace()->colorDepthId().id(), data); if (device->setProfile(profile)) { return true; } } m_warningMessages << i18n("Could not load profile: %1.", location); return true; } bool KisKraLoadVisitor::loadFilterConfiguration(KisFilterConfigurationSP kfc, const QString& location) { if (m_store->hasFile(location)) { QByteArray data; m_store->open(location); data = m_store->read(m_store->size()); m_store->close(); if (!data.isEmpty()) { QDomDocument doc; doc.setContent(data); QDomElement e = doc.documentElement(); if (e.tagName() == "filterconfig") { kfc->fromLegacyXML(e); } else { kfc->fromXML(e); } loadDeprecatedFilter(kfc); return true; } } m_warningMessages << i18n("Could not filter configuration %1.", location); return true; } +void KisKraLoadVisitor::fixOldFilterConfigurations(KisFilterConfigurationSP kfc) +{ + KisFilterSP filter = KisFilterRegistry::instance()->value(kfc->name()); + KIS_SAFE_ASSERT_RECOVER_RETURN(filter); + + if (!filter->configurationAllowedForMask(kfc)) { + filter->fixLoadedFilterConfigurationForMasks(kfc); + } + + KIS_SAFE_ASSERT_RECOVER_NOOP(filter->configurationAllowedForMask(kfc)); +} + bool KisKraLoadVisitor::loadMetaData(KisNode* node) { KisLayer* layer = qobject_cast(node); if (!layer) return true; KisMetaData::IOBackend* backend = KisMetaData::IOBackendRegistry::instance()->get("xmp"); if (!backend || !backend->supportLoading()) { if (backend) dbgFile << "Backend " << backend->id() << " does not support loading."; else dbgFile << "Could not load the XMP backend at all"; return true; } QString location = getLocation(node, QString(".") + backend->id() + DOT_METADATA); dbgFile << "going to load " << backend->id() << ", " << backend->name() << " from " << location; if (m_store->hasFile(location)) { QByteArray data; m_store->open(location); data = m_store->read(m_store->size()); m_store->close(); QBuffer buffer(&data); if (!backend->loadFrom(layer->metaData(), &buffer)) { m_warningMessages << i18n("Could not load metadata for layer %1.", layer->name()); } } return true; } bool KisKraLoadVisitor::loadSelection(const QString& location, KisSelectionSP dstSelection) { // by default the selection is expected to be fully transparent { KisPixelSelectionSP pixelSelection = dstSelection->pixelSelection(); KoColor transparent(Qt::transparent, pixelSelection->colorSpace()); pixelSelection->setDefaultPixel(transparent); } // Pixel selection bool result = true; QString pixelSelectionLocation = location + DOT_PIXEL_SELECTION; if (m_store->hasFile(pixelSelectionLocation)) { KisPixelSelectionSP pixelSelection = dstSelection->pixelSelection(); result = loadPaintDevice(pixelSelection, pixelSelectionLocation); if (!result) { m_warningMessages << i18n("Could not load raster selection %1.", location); } pixelSelection->invalidateOutlineCache(); } // Shape selection QString shapeSelectionLocation = location + DOT_SHAPE_SELECTION; if (m_store->hasFile(shapeSelectionLocation + "/content.svg") || m_store->hasFile(shapeSelectionLocation + "/content.xml")) { m_store->pushDirectory(); m_store->enterDirectory(shapeSelectionLocation) ; KisShapeSelection* shapeSelection = new KisShapeSelection(m_shapeController, m_image, dstSelection); dstSelection->setShapeSelection(shapeSelection); result = shapeSelection->loadSelection(m_store); m_store->popDirectory(); if (!result) { m_warningMessages << i18n("Could not load vector selection %1.", location); } } return true; } QString KisKraLoadVisitor::getLocation(KisNode* node, const QString& suffix) { return getLocation(m_layerFilenames[node], suffix); } QString KisKraLoadVisitor::getLocation(const QString &filename, const QString& suffix) { QString location = m_external ? QString() : m_uri; location += m_name + LAYER_PATH + filename + suffix; return location; } void KisKraLoadVisitor::loadNodeKeyframes(KisNode *node) { if (!m_keyframeFilenames.contains(node)) return; node->enableAnimation(); const QString &location = getLocation(m_keyframeFilenames[node]); if (!m_store->open(location)) { m_errorMessages << i18n("Could not load keyframes from %1.", location); return; } QString errorMsg; int errorLine; int errorColumn; QDomDocument dom; bool ok = dom.setContent(m_store->device(), &errorMsg, &errorLine, &errorColumn); m_store->close(); if (!ok) { m_errorMessages << i18n("parsing error in the keyframe file %1 at line %2, column %3\nError message: %4", location, errorLine, errorColumn, i18n(errorMsg.toUtf8())); return; } QDomElement root = dom.firstChildElement(); for (QDomElement child = root.firstChildElement(); !child.isNull(); child = child.nextSiblingElement()) { if (child.nodeName().toUpper() == "CHANNEL") { QString id = child.attribute("name"); KisKeyframeChannel *channel = node->getKeyframeChannel(id, true); if (!channel) { m_warningMessages << i18n("unknown keyframe channel type: %1 in %2", id, location); continue; } channel->loadXML(child); } } } void KisKraLoadVisitor::loadDeprecatedFilter(KisFilterConfigurationSP cfg) { if (cfg->getString("legacy") == "left edge detections") { cfg->setProperty("horizRadius", 1); cfg->setProperty("vertRadius", 1); cfg->setProperty("type", "prewitt"); cfg->setProperty("output", "yFall"); cfg->setProperty("lockAspect", true); cfg->setProperty("transparency", false); } else if (cfg->getString("legacy") == "right edge detections") { cfg->setProperty("horizRadius", 1); cfg->setProperty("vertRadius", 1); cfg->setProperty("type", "prewitt"); cfg->setProperty("output", "yGrowth"); cfg->setProperty("lockAspect", true); cfg->setProperty("transparency", false); } else if (cfg->getString("legacy") == "top edge detections") { cfg->setProperty("horizRadius", 1); cfg->setProperty("vertRadius", 1); cfg->setProperty("type", "prewitt"); cfg->setProperty("output", "xGrowth"); cfg->setProperty("lockAspect", true); cfg->setProperty("transparency", false); } else if (cfg->getString("legacy") == "bottom edge detections") { cfg->setProperty("horizRadius", 1); cfg->setProperty("vertRadius", 1); cfg->setProperty("type", "prewitt"); cfg->setProperty("output", "xFall"); cfg->setProperty("lockAspect", true); cfg->setProperty("transparency", false); } } diff --git a/plugins/impex/libkra/kis_kra_load_visitor.h b/plugins/impex/libkra/kis_kra_load_visitor.h index f88b63b78d..3cf33cc129 100644 --- a/plugins/impex/libkra/kis_kra_load_visitor.h +++ b/plugins/impex/libkra/kis_kra_load_visitor.h @@ -1,109 +1,110 @@ /* * Copyright (c) 2002 Patrick Julien * Copyright (c) 2005 C. Boemann * Copyright (c) 2007 Boudewijn Rempt * * 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-1301, USA. */ #ifndef KIS_KRA_LOAD_VISITOR_H_ #define KIS_KRA_LOAD_VISITOR_H_ #include #include // kritaimage #include "kis_types.h" #include "kis_node_visitor.h" #include "kritalibkra_export.h" class KisFilterConfiguration; class KoStore; class KoShapeControllerBase; class KRITALIBKRA_EXPORT KisKraLoadVisitor : public KisNodeVisitor { public: KisKraLoadVisitor(KisImageSP image, KoStore *store, KoShapeControllerBase *shapeController, QMap &layerFilenames, QMap &keyframeFilenames, const QString & name, int syntaxVersion); public: void setExternalUri(const QString &uri); bool visit(KisNode*) override { return true; } bool visit(KisExternalLayer *) override; bool visit(KisPaintLayer *layer) override; bool visit(KisGroupLayer *layer) override; bool visit(KisAdjustmentLayer* layer) override; bool visit(KisGeneratorLayer* layer) override; bool visit(KisCloneLayer *layer) override; bool visit(KisFilterMask *mask) override; bool visit(KisTransformMask *mask) override; bool visit(KisTransparencyMask *mask) override; bool visit(KisSelectionMask *mask) override; bool visit(KisColorizeMask *mask) override; QStringList errorMessages() const; QStringList warningMessages() const; private: bool loadPaintDevice(KisPaintDeviceSP device, const QString& location); template bool loadPaintDeviceFrame(KisPaintDeviceSP device, const QString &location, DevicePolicy policy); bool loadProfile(KisPaintDeviceSP device, const QString& location); bool loadFilterConfiguration(KisFilterConfigurationSP kfc, const QString& location); + void fixOldFilterConfigurations(KisFilterConfigurationSP kfc); bool loadMetaData(KisNode* node); void initSelectionForMask(KisMask *mask); bool loadSelection(const QString& location, KisSelectionSP dstSelection); QString getLocation(KisNode* node, const QString& suffix = QString()); QString getLocation(const QString &filename, const QString &suffix = QString()); void loadNodeKeyframes(KisNode *node); /** * Load deprecated filters. * Most deprecated filters can be handled by this, but the brightnesscontact to perchannels * conversion needs to be handled in the perchannel class because those filters * have their own xml loading functionality. */ void loadDeprecatedFilter(KisFilterConfigurationSP cfg); private: KisImageSP m_image; KoStore *m_store; bool m_external; QString m_uri; QMap m_layerFilenames; QMap m_keyframeFilenames; QString m_name; int m_syntaxVersion; QStringList m_errorMessages; QStringList m_warningMessages; KoShapeControllerBase *m_shapeController; }; #endif // KIS_KRA_LOAD_VISITOR_H_ diff --git a/plugins/paintops/libpaintop/kis_filter_option.cpp b/plugins/paintops/libpaintop/kis_filter_option.cpp index 7d915abe8f..b9f89953a4 100644 --- a/plugins/paintops/libpaintop/kis_filter_option.cpp +++ b/plugins/paintops/libpaintop/kis_filter_option.cpp @@ -1,215 +1,215 @@ /* This file is part of the KDE project * Copyright (C) Boudewijn Rempt , (C) 2008 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "kis_filter_option.h" #include #include #include #include #include #include #include #include #include #include #include #include #include "ui_wdgfilteroption.h" #include class KisFilterOptionWidget : public QWidget, public Ui::FilterOpOptions { public: KisFilterOptionWidget(QWidget* parent = 0) : QWidget(parent) { setupUi(this); } }; KisFilterOption::KisFilterOption() : KisPaintOpOption(KisPaintOpOption::FILTER, true) { setObjectName("KisFilterOption"); m_checkable = false; m_filterOptionWidget = new KisFilterOptionWidget(); m_filterOptionWidget->hide(); setConfigurationPage(m_filterOptionWidget); m_layout = new QGridLayout(m_filterOptionWidget->grpFilterOptions); // Check which filters support painting QList l = KisFilterRegistry::instance()->keys(); QList l2; QList::iterator it; for (it = l.begin(); it != l.end(); ++it) { KisFilterSP f = KisFilterRegistry::instance()->value((*it)); if (f->supportsPainting()) { l2.push_back(KoID(*it, f->name())); } } m_filterOptionWidget->filtersList->setIDList(l2); connect(m_filterOptionWidget->filtersList, SIGNAL(activated(KoID)), SLOT(setCurrentFilter(KoID))); if (!l2.empty()) { setCurrentFilter(l2.first()); } connect(m_filterOptionWidget->checkBoxSmudgeMode, SIGNAL(stateChanged(int)), this, SLOT(emitSettingChanged())); } KisFilterOption::~KisFilterOption() { } const KisFilterSP KisFilterOption::filter() const { return m_currentFilter; } KisFilterConfigurationSP KisFilterOption::filterConfig() const { if (!m_currentFilterConfigWidget) return 0; return static_cast(m_currentFilterConfigWidget->configuration().data()); } bool KisFilterOption::smudgeMode() const { return m_filterOptionWidget->checkBoxSmudgeMode->isChecked(); } void KisFilterOption::setNode(KisNodeWSP node) { if (node && node->paintDevice()) { m_paintDevice = node->paintDevice(); // The "not m_currentFilterConfigWidget" is a corner case // which happens because the first configuration settings is // created before any layer is selected in the view if (!m_currentFilterConfigWidget || (m_currentFilterConfigWidget && static_cast(m_currentFilterConfigWidget->configuration().data())->isCompatible(m_paintDevice) ) ) { if (m_currentFilter) { KisPropertiesConfigurationSP configuration = 0; if (m_currentFilterConfigWidget) { configuration = m_currentFilterConfigWidget->configuration(); } setCurrentFilter(KoID(m_currentFilter->id())); if (configuration) { m_currentFilterConfigWidget->setConfiguration(configuration); } } } } else { m_paintDevice = 0; } } void KisFilterOption::setImage(KisImageWSP image) { m_image = image; if (!m_currentFilterConfigWidget) { updateFilterConfigWidget(); } } void KisFilterOption::setCurrentFilter(const KoID& id) { m_currentFilter = KisFilterRegistry::instance()->get(id.id()); m_filterOptionWidget->filtersList->setCurrent(id); updateFilterConfigWidget(); emitSettingChanged(); } void KisFilterOption::updateFilterConfigWidget() { if (m_currentFilterConfigWidget) { m_currentFilterConfigWidget->hide(); m_layout->removeWidget(m_currentFilterConfigWidget); m_layout->invalidate(); delete m_currentFilterConfigWidget; } m_currentFilterConfigWidget = 0; if (m_currentFilter && m_image && m_paintDevice) { m_currentFilterConfigWidget = - m_currentFilter->createConfigurationWidget(m_filterOptionWidget->grpFilterOptions, m_paintDevice); + m_currentFilter->createConfigurationWidget(m_filterOptionWidget->grpFilterOptions, m_paintDevice, true); if (m_currentFilterConfigWidget) { m_layout->addWidget(m_currentFilterConfigWidget); m_filterOptionWidget->grpFilterOptions->updateGeometry(); m_currentFilterConfigWidget->show(); connect(m_currentFilterConfigWidget, SIGNAL(sigConfigurationUpdated()), this, SLOT(emitSettingChanged())); } } m_layout->update(); } void KisFilterOption::writeOptionSetting(KisPropertiesConfigurationSP setting) const { if (!m_currentFilter) return; setting->setProperty(FILTER_ID, m_currentFilter->id()); setting->setProperty(FILTER_SMUDGE_MODE, smudgeMode()); if (filterConfig()) { setting->setProperty(FILTER_CONFIGURATION, filterConfig()->toXML()); } } void KisFilterOption::readOptionSetting(const KisPropertiesConfigurationSP setting) { KoID id(setting->getString(FILTER_ID), QString()); if (id.id() != m_currentFilter->id()) { setCurrentFilter(id); } m_filterOptionWidget->checkBoxSmudgeMode->setChecked(setting->getBool(FILTER_SMUDGE_MODE)); KisFilterConfigurationSP configuration = filterConfig(); if (configuration && m_currentFilterConfigWidget) { configuration->fromXML(setting->getString(FILTER_CONFIGURATION)); m_currentFilterConfigWidget->blockSignals(true); m_currentFilterConfigWidget->setConfiguration(configuration); m_currentFilterConfigWidget->blockSignals(false); } } void KisFilterOption::lodLimitations(KisPaintopLodLimitations *l) const { KisFilterConfigurationSP config = filterConfig(); if (m_currentFilter && config) { QRect testRect(0,0,100,100); if (m_currentFilter->neededRect(testRect, config, 0) != testRect || m_currentFilter->changedRect(testRect, config, 0) != testRect) { l->blockers << KoID("filter-nonlinear", i18nc("PaintOp instant preview limitation", "\"%1\" does not support scaled preview (non-linear filter)", config->name())); } } } #include "moc_kis_filter_option.cpp"