summaryrefslogtreecommitdiffstats
path: root/krita/plugins/viewplugins/histogram_docker
diff options
context:
space:
mode:
authortpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-01-20 01:29:50 +0000
committertpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-01-20 01:29:50 +0000
commit8362bf63dea22bbf6736609b0f49c152f975eb63 (patch)
tree0eea3928e39e50fae91d4e68b21b1e6cbae25604 /krita/plugins/viewplugins/histogram_docker
downloadkoffice-8362bf63dea22bbf6736609b0f49c152f975eb63.tar.gz
koffice-8362bf63dea22bbf6736609b0f49c152f975eb63.zip
Added old abandoned KDE3 version of koffice
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/koffice@1077364 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'krita/plugins/viewplugins/histogram_docker')
-rw-r--r--krita/plugins/viewplugins/histogram_docker/Makefile.am21
-rw-r--r--krita/plugins/viewplugins/histogram_docker/histogramdocker.cc192
-rw-r--r--krita/plugins/viewplugins/histogram_docker/histogramdocker.h79
-rw-r--r--krita/plugins/viewplugins/histogram_docker/kis_accumulating_producer.cc102
-rw-r--r--krita/plugins/viewplugins/histogram_docker/kis_accumulating_producer.h76
-rw-r--r--krita/plugins/viewplugins/histogram_docker/kis_cachedhistogram.cc37
-rw-r--r--krita/plugins/viewplugins/histogram_docker/kis_cachedhistogram.h53
-rw-r--r--krita/plugins/viewplugins/histogram_docker/kis_imagerasteredcache.cc162
-rw-r--r--krita/plugins/viewplugins/histogram_docker/kis_imagerasteredcache.h80
-rw-r--r--krita/plugins/viewplugins/histogram_docker/kritahistogramdocker.desktop40
-rw-r--r--krita/plugins/viewplugins/histogram_docker/kritahistogramdocker.rc3
11 files changed, 845 insertions, 0 deletions
diff --git a/krita/plugins/viewplugins/histogram_docker/Makefile.am b/krita/plugins/viewplugins/histogram_docker/Makefile.am
new file mode 100644
index 00000000..6d116358
--- /dev/null
+++ b/krita/plugins/viewplugins/histogram_docker/Makefile.am
@@ -0,0 +1,21 @@
+kde_services_DATA = kritahistogramdocker.desktop
+kritarcdir = $(kde_datadir)/kritaplugins
+kritarc_DATA = kritahistogramdocker.rc
+
+INCLUDES = -I$(srcdir)/../../../sdk \
+ -I$(srcdir)/../../../core \
+ -I$(srcdir)/../../../kritacolor/ \
+ -I$(srcdir)/../../../ui \
+ -I$/../../../ui \
+ $(KOFFICE_INCLUDES) \
+ $(all_includes)
+
+kritahistogramdocker_la_SOURCES = histogramdocker.cc kis_imagerasteredcache.cc kis_cachedhistogram.cc kis_accumulating_producer.cc
+
+kde_module_LTLIBRARIES = kritahistogramdocker.la
+noinst_HEADERS = histogramdocker.h kis_imagerasteredcache.h kis_cachedhistogram.h kis_accumulating_producer.h
+
+kritahistogramdocker_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN)
+kritahistogramdocker_la_LIBADD = ../../../libkritacommon.la
+
+kritahistogramdocker_la_METASOURCES = AUTO
diff --git a/krita/plugins/viewplugins/histogram_docker/histogramdocker.cc b/krita/plugins/viewplugins/histogram_docker/histogramdocker.cc
new file mode 100644
index 00000000..93d77bfb
--- /dev/null
+++ b/krita/plugins/viewplugins/histogram_docker/histogramdocker.cc
@@ -0,0 +1,192 @@
+/*
+ * This file is part of the KDE project
+ *
+ * Copyright (c) 2005 Bart Coppens <[email protected]>
+ *
+ * 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 <qtooltip.h>
+
+#include <klocale.h>
+#include <kiconloader.h>
+#include <kinstance.h>
+#include <kmessagebox.h>
+#include <kstandarddirs.h>
+#include <ktempfile.h>
+#include <kdebug.h>
+#include <kgenericfactory.h>
+
+#include <kopalettemanager.h>
+
+#include "kis_meta_registry.h"
+#include <kis_doc.h>
+#include <kis_global.h>
+#include <kis_types.h>
+#include <kis_view.h>
+
+#include <kis_basic_histogram_producers.h>
+#include <kis_colorspace_factory_registry.h>
+
+#include "histogramdocker.h"
+#include "kis_imagerasteredcache.h"
+#include "kis_accumulating_producer.h"
+
+typedef KGenericFactory<KritaHistogramDocker> KritaHistogramDockerFactory;
+K_EXPORT_COMPONENT_FACTORY( kritahistogramdocker, KritaHistogramDockerFactory( "krita" ) )
+
+KritaHistogramDocker::KritaHistogramDocker(QObject *parent, const char *name, const QStringList&)
+ : KParts::Plugin(parent, name)
+{
+
+ if ( parent->inherits("KisView") ) {
+ m_view = dynamic_cast<KisView*>(parent);
+
+ setInstance(KritaHistogramDockerFactory::instance());
+ setXMLFile(locate("data","kritaplugins/kritahistogramdocker.rc"), true);
+
+ KisImageSP img = m_view->canvasSubject()->currentImg();
+ if (!img) {
+ m_cache = 0;
+ return;
+ }
+
+ m_hview = 0; // producerChanged wants to setCurrentChannels, prevent that here
+ m_cache = 0; // we try to delete it in producerChanged
+ colorSpaceChanged(img->colorSpace()); // calls producerChanged(0)
+
+
+ m_hview = new KisHistogramView(m_view);
+ QToolTip::add(m_hview, i18n("Right-click to select histogram type"));
+ m_hview->setHistogram(m_histogram);
+ m_hview->setColor(true);
+ m_hview->setCurrentChannels(m_producer, m_producer->channels());
+ m_hview->setFixedSize(256, 100); // XXX if not it keeps expanding
+ m_hview->setCaption(i18n("Histogram"));
+
+
+ connect(m_hview, SIGNAL(rightClicked(const QPoint&)),
+ this, SLOT(popupMenu(const QPoint&)));
+ connect(m_cache, SIGNAL(cacheUpdated()),
+ new HistogramDockerUpdater(this, m_histogram, m_hview, m_producer), SLOT(updated()));
+ connect(&m_popup, SIGNAL(activated(int)),
+ this, SLOT(producerChanged(int)));
+ connect(img, SIGNAL(sigColorSpaceChanged(KisColorSpace*)),
+ this, SLOT(colorSpaceChanged(KisColorSpace*))); // No need to force updates here
+
+ // Add it to the control palette
+ m_view->canvasSubject()->paletteManager()->addWidget(
+ m_hview, "histodocker", krita::CONTROL_PALETTE);
+ } else {
+ m_cache = 0;
+ }
+}
+
+KritaHistogramDocker::~KritaHistogramDocker()
+{
+ uint count = m_producers . count();
+ for (uint i = 0; i < count; i++) {
+ delete m_producers . at(i);
+ }
+
+ if (m_cache)
+ m_cache->deleteLater();
+}
+
+void KritaHistogramDocker::producerChanged(int pos)
+{
+ if (m_cache)
+ m_cache->deleteLater();
+ m_cache = 0;
+
+ if (m_currentProducerPos < m_popup.count())
+ m_popup.setItemChecked(m_currentProducerPos, false);
+ m_currentProducerPos = pos;
+ m_popup.setItemChecked(m_currentProducerPos, true);
+
+ uint count = m_producers . count();
+ for (uint i = 0; i < count; i++) {
+ delete m_producers . at(i);
+ }
+ m_producers.clear();
+
+ KisIDList keys = KisHistogramProducerFactoryRegistry::instance() ->
+ listKeysCompatibleWith(m_cs);
+
+ m_factory = KisHistogramProducerFactoryRegistry::instance()->get(*(keys.at(pos)));
+
+ KisCachedHistogramObserver observer(&m_producers, m_factory, 0, 0, 0, 0, false);
+
+ // We can reference observer because it will be only used as a factory to create new
+ // instances
+ m_cache = new KisImageRasteredCache(m_view, &observer);
+
+ m_producer = new KisAccumulatingHistogramProducer(&m_producers);
+
+ // use dummy layer as a source; we are not going to actually use or need it
+ // All of these are SP, no need to delete them afterwards
+ m_histogram = new KisHistogram( new KisPaintDevice(KisMetaRegistry::instance()->csRegistry()->getAlpha8(), "dummy histogram"), m_producer, LOGARITHMIC);
+
+ if (m_hview) {
+ m_hview->setHistogram(m_histogram);
+ m_hview->setColor(true);
+ m_hview->setCurrentChannels(m_producer, m_producer->channels());
+
+ connect(m_cache, SIGNAL(cacheUpdated()),
+ new HistogramDockerUpdater(this, m_histogram, m_hview, m_producer), SLOT(updated()));
+ }
+}
+
+void KritaHistogramDocker::popupMenu(const QPoint& pos)
+{
+ m_popup.popup(pos, m_currentProducerPos);
+}
+
+void KritaHistogramDocker::colorSpaceChanged(KisColorSpace* cs)
+{
+ m_cs = cs;
+
+ KisIDList keys = KisHistogramProducerFactoryRegistry::instance() ->
+ listKeysCompatibleWith(m_cs);
+
+ m_popup.clear();
+ m_currentProducerPos = 0;
+
+ for (uint i = 0; i < keys.count(); i++) {
+ KisID id(*(keys.at(i)));
+ m_popup . insertItem(id.name(), static_cast<int>(i));
+ }
+
+ producerChanged(0);
+}
+
+HistogramDockerUpdater::HistogramDockerUpdater(QObject* /*parent*/, KisHistogramSP h, KisHistogramView* v,
+ KisAccumulatingHistogramProducer* p)
+ : m_histogram(h), m_view(v), m_producer(p)
+{
+ connect(p, SIGNAL(completed()), this, SLOT(completed()));
+}
+
+void HistogramDockerUpdater::updated() {
+ // We don't [!] do m_histogram->updateHistogram();, because that will try to compute
+ // the histogram synchronously, while we want it asynchronously.
+ m_producer->addRegionsToBinAsync();
+}
+
+void HistogramDockerUpdater::completed() {
+ m_histogram->computeHistogram();
+ m_view->updateHistogram();
+}
+
+#include "histogramdocker.moc"
diff --git a/krita/plugins/viewplugins/histogram_docker/histogramdocker.h b/krita/plugins/viewplugins/histogram_docker/histogramdocker.h
new file mode 100644
index 00000000..5cc57e18
--- /dev/null
+++ b/krita/plugins/viewplugins/histogram_docker/histogramdocker.h
@@ -0,0 +1,79 @@
+/*
+ * This file is part of Krita
+ *
+ * Copyright (c) 2005 Bart Coppens <[email protected]>
+ *
+ * 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 _HISTOGRAMDOCKER_H_
+#define _HISTOGRAMDOCKER_H_
+
+#include <qobject.h>
+#include <qpopupmenu.h>
+
+#include <kparts/plugin.h>
+#include <kis_histogram_view.h>
+#include <kis_histogram.h>
+
+#include "kis_cachedhistogram.h"
+
+class KisAccumulatingHistogramProducer;
+class KisColorSpace;
+class KisHistogramView;
+class KisView;
+class KisColorSpace;
+
+class KritaHistogramDocker : public KParts::Plugin
+{
+Q_OBJECT
+public:
+ KritaHistogramDocker(QObject *parent, const char *name, const QStringList &);
+ virtual ~KritaHistogramDocker();
+private slots:
+ void producerChanged(int pos);
+ void popupMenu(const QPoint & pos);
+ void colorSpaceChanged(KisColorSpace* cs);
+private:
+ KisHistogramProducerFactory* m_factory;
+ KisCachedHistogramObserver::Producers m_producers;
+ KisAccumulatingHistogramProducer* m_producer;
+ KisColorSpace* m_cs;
+ KisView* m_view;
+ KisHistogramView* m_hview;
+ KisImageRasteredCache* m_cache;
+ QPopupMenu m_popup;
+ KisHistogramSP m_histogram;
+ uint m_currentProducerPos;
+};
+
+class KisGenericRGBHistogramProducerFactory;
+
+class HistogramDockerUpdater : public QObject {
+Q_OBJECT
+public:
+ HistogramDockerUpdater(QObject* parent, KisHistogramSP h, KisHistogramView* v,
+ KisAccumulatingHistogramProducer* p);
+public slots:
+ void updated();
+private slots:
+ void completed();
+private:
+ KisHistogramSP m_histogram;
+ KisHistogramView* m_view;
+ KisAccumulatingHistogramProducer* m_producer;
+};
+
+#endif //_HISTOGRAMDOCKER_H_
diff --git a/krita/plugins/viewplugins/histogram_docker/kis_accumulating_producer.cc b/krita/plugins/viewplugins/histogram_docker/kis_accumulating_producer.cc
new file mode 100644
index 00000000..f899f2af
--- /dev/null
+++ b/krita/plugins/viewplugins/histogram_docker/kis_accumulating_producer.cc
@@ -0,0 +1,102 @@
+/*
+ * This file is part of Krita
+ *
+ * Copyright (c) 2005 Bart Coppens <[email protected]>
+ *
+ * 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 <qthread.h>
+#include <qapplication.h>
+#include <qevent.h>
+
+#include "kis_accumulating_producer.h"
+
+static const int EmitCompletedType = QEvent::User + 1;
+
+/**
+ * The threaded producer definition in c++ file because this is really an internal affair.
+ * Note that since we _know_ that we'll only have a single instance of it running, at most,
+ * we don't care too much about locking and synchronization
+ **/
+class KisAccumulatingHistogramProducer::ThreadedProducer : public QThread {
+ KisAccumulatingHistogramProducer* m_source;
+ bool m_stop;
+protected:
+ virtual void run();
+public:
+ ThreadedProducer(KisAccumulatingHistogramProducer* source)
+ : m_source(source), m_stop(false) {}
+ void cancel() { m_stop = true; }
+};
+
+KisAccumulatingHistogramProducer::KisAccumulatingHistogramProducer(KisCachedHistogramObserver::Producers* source)
+ : KisBasicHistogramProducer(
+ KisID("ACCHISTO", ""),
+ source->at(0)->channels().count(),
+ source->at(0)->numberOfBins(),
+ 0),
+ m_source(source)
+{
+ m_thread = new ThreadedProducer(this);
+}
+
+KisAccumulatingHistogramProducer::~KisAccumulatingHistogramProducer() {
+ m_thread->cancel();
+ m_thread->wait();
+ delete m_thread;
+}
+
+void KisAccumulatingHistogramProducer::addRegionsToBinAsync() {
+ m_thread->cancel();
+ m_thread->wait();
+ clear();
+ m_thread->start();
+}
+
+void KisAccumulatingHistogramProducer::ThreadedProducer::run() {
+ m_stop = false;
+
+ uint count = m_source->m_source->count(); // Talk about bad naming schemes...
+ KisCachedHistogramObserver::Producers* source = m_source->m_source;
+ QValueVector<vBins>& bins = m_source->m_bins;
+ int channels = m_source->m_channels;
+ int nrOfBins = m_source->m_nrOfBins;
+
+ for (uint i = 0; i < count && !m_stop; i++) {
+ KisHistogramProducer* p = source->at(i);
+ m_source->m_count += p->count();
+
+ for (int j = 0; j < channels && !m_stop; j++) {
+ for (int k = 0; k < nrOfBins; k++) {
+ bins.at(j).at(k) += p->getBinAt(j, k);
+ }
+ }
+ }
+
+ if (!m_stop) {
+ // This function is thread-safe; and it takes ownership of the event
+ QApplication::postEvent(m_source, new QCustomEvent(EmitCompletedType));
+ }
+}
+
+void KisAccumulatingHistogramProducer::customEvent(QCustomEvent* e) {
+ if (e->type() == EmitCompletedType) {
+ emit completed();
+ }
+}
+
+#include "kis_accumulating_producer.moc"
+
diff --git a/krita/plugins/viewplugins/histogram_docker/kis_accumulating_producer.h b/krita/plugins/viewplugins/histogram_docker/kis_accumulating_producer.h
new file mode 100644
index 00000000..4ef9f02a
--- /dev/null
+++ b/krita/plugins/viewplugins/histogram_docker/kis_accumulating_producer.h
@@ -0,0 +1,76 @@
+/*
+ * This file is part of Krita
+ *
+ * Copyright (c) 2005 Bart Coppens <[email protected]>
+ *
+ * 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_ACCUMULATING_PRODUCER_H_
+#define _KIS_ACCUMULATING_PRODUCER_H_
+
+#include <qobject.h>
+
+#include <kis_basic_histogram_producers.h>
+#include "kis_cachedhistogram.h"
+
+/**
+ * Kept very minimalistic because all options would require much reiterating which we don't want.
+ * This class is multithreading! Don't expect it to contain the right data after an
+ * addRegionsToBinAsync call, but await it's completed() signal. Also beware! This function
+ * _does_ clear() before addRegionsToBinAsync! (hence not conforming to the regular semantics
+ * of HistogramProducers if you'd take addRegionsToBinAsync = addRegionToBin, but since that is
+ * already violated with the asynchronousity of it that is not really an issue anymore, I think)
+ **/
+class KisAccumulatingHistogramProducer : public QObject, public KisBasicHistogramProducer {
+Q_OBJECT
+public:
+ KisAccumulatingHistogramProducer(KisCachedHistogramObserver::Producers* source);
+ ~KisAccumulatingHistogramProducer();
+ /// Does _nothing_, use addRegionsToBinAsync
+ virtual void addRegionToBin(Q_UINT8 *, Q_UINT8*, Q_UINT32, KisColorSpace *) {}
+ virtual void addRegionsToBinAsync();
+ virtual QString positionToString(double pos) const
+ { return m_source->at(0)->positionToString(pos); }
+
+ virtual void setView(double, double) {} // No view support
+ virtual double maximalZoom() const { return 1.0; }
+
+ virtual Q_INT32 numberOfBins() { return m_source->at(0)->numberOfBins(); }
+
+ virtual QValueVector<KisChannelInfo *> channels() { return m_source->at(0)->channels(); }
+
+ /// Call this when the 'source' list has changed colorspace
+ virtual void changedSourceProducer() {
+ m_count = m_source->at(0)->channels().count();
+ m_external.clear();
+ makeExternalToInternal();
+ }
+
+signals:
+ void completed();
+
+protected:
+ virtual void customEvent(QCustomEvent* e);
+ /// source already converts external to internal
+ virtual int externalToInternal(int ext) { return ext; }
+ KisCachedHistogramObserver::Producers* m_source;
+
+ class ThreadedProducer;
+ friend class ThreadedProducer;
+ ThreadedProducer* m_thread;
+};
+
+#endif // _KIS_ACCUMULATING_PRODUCER_H_
diff --git a/krita/plugins/viewplugins/histogram_docker/kis_cachedhistogram.cc b/krita/plugins/viewplugins/histogram_docker/kis_cachedhistogram.cc
new file mode 100644
index 00000000..2b0c9b85
--- /dev/null
+++ b/krita/plugins/viewplugins/histogram_docker/kis_cachedhistogram.cc
@@ -0,0 +1,37 @@
+/*
+ * This file is part of Krita
+ *
+ * Copyright (c) 2005 Bart Coppens <[email protected]>
+ *
+ * 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_paint_device.h>
+#include <kis_iterators_pixel.h>
+
+#include "kis_cachedhistogram.h"
+
+void KisCachedHistogramObserver::regionUpdated(KisPaintDeviceSP dev) {
+ m_producer->clear();
+ KisRectIteratorPixel srcIt = dev->createRectIterator(m_x, m_y, m_w, m_h, false);
+ int i;
+ while ( !srcIt.isDone() ) {
+ i = srcIt.nConseqPixels();
+ m_producer->addRegionToBin(srcIt.rawData(), srcIt.selectionMask(), i, dev->colorSpace());
+ srcIt += i;
+ if (i == 0)
+ ++srcIt;
+ }
+}
diff --git a/krita/plugins/viewplugins/histogram_docker/kis_cachedhistogram.h b/krita/plugins/viewplugins/histogram_docker/kis_cachedhistogram.h
new file mode 100644
index 00000000..dfe7a05e
--- /dev/null
+++ b/krita/plugins/viewplugins/histogram_docker/kis_cachedhistogram.h
@@ -0,0 +1,53 @@
+/*
+ * This file is part of Krita
+ *
+ * Copyright (c) 2005 Bart Coppens <[email protected]>
+ *
+ * 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 _CACHED_HISTOGRAM_H_
+#define _CACHED_HISTOGRAM_H_
+
+#include <qvaluevector.h>
+#include <kis_histogram_producer.h>
+
+#include "kis_imagerasteredcache.h"
+
+class KisCachedHistogramObserver : public KisImageRasteredCache::Observer {
+public:
+ typedef QValueVector<KisHistogramProducer*> Producers;
+ KisCachedHistogramObserver(Producers* p, KisHistogramProducerFactory* f,
+ int x, int y, int w, int h, bool add = true)
+ : m_producers(p), m_factory(f), m_x(x), m_y(y), m_w(w), m_h(h)
+ {
+ m_producer = m_factory->generate();
+ if (add)
+ m_producers->append(m_producer);
+ }
+ virtual ~KisCachedHistogramObserver() {}
+
+ virtual Observer* createNew(int x, int y, int w, int h)
+ { return new KisCachedHistogramObserver(m_producers, m_factory, x, y, w, h); }
+
+ virtual void regionUpdated(KisPaintDeviceSP dev);
+private:
+ Producers* m_producers;
+ KisHistogramProducerFactory* m_factory;
+ KisHistogramProducerSP m_producer;
+ int m_x, m_y, m_w, m_h;
+};
+
+#endif // _CACHED_HISTOGRAM_H_
diff --git a/krita/plugins/viewplugins/histogram_docker/kis_imagerasteredcache.cc b/krita/plugins/viewplugins/histogram_docker/kis_imagerasteredcache.cc
new file mode 100644
index 00000000..2c6562df
--- /dev/null
+++ b/krita/plugins/viewplugins/histogram_docker/kis_imagerasteredcache.cc
@@ -0,0 +1,162 @@
+/*
+ * This file is part of the KDE project
+ *
+ * Copyright (c) 2005 Bart Coppens <[email protected]>
+ *
+ * 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 <cmath>
+
+#include <qapplication.h>
+
+#include <kdebug.h>
+
+#include <kis_doc.h>
+#include <kis_global.h>
+#include <kis_types.h>
+#include <kis_view.h>
+
+#include "kis_imagerasteredcache.h"
+
+KisImageRasteredCache::KisImageRasteredCache(KisView* view, Observer* o)
+ : m_observer(o->createNew(0, 0, 0, 0)), m_view(view)
+{
+ m_busy = false;
+ m_imageProjection = 0;
+ m_rasterSize = 64*4;
+ m_timeOutMSec = 1000;
+
+ KisImageSP img = view->canvasSubject()->currentImg();
+
+ if (!img) {
+ return;
+ }
+
+ imageSizeChanged(img->width(), img->height());
+
+ connect(img, SIGNAL(sigImageUpdated(QRect)),
+ this, SLOT(imageUpdated(QRect)));
+ connect(img, SIGNAL(sigSizeChanged(Q_INT32, Q_INT32)),
+ this, SLOT(imageSizeChanged(Q_INT32, Q_INT32)));
+ connect(&m_timer, SIGNAL(timeout()), this, SLOT(timeOut()));
+}
+
+KisImageRasteredCache::~KisImageRasteredCache() {
+ cleanUpElements();
+}
+
+void KisImageRasteredCache::imageUpdated(QRect rc) {
+
+ if (rc.isValid()) {
+ QRect r(0, 0, m_width * m_rasterSize, m_height * m_rasterSize);
+ r &= rc;
+
+ uint x = static_cast<int>(r.x() / m_rasterSize);
+ uint y = static_cast<int>(r.y() / m_rasterSize);
+ uint x2 = static_cast<int>(ceil(float(r.x() + r.width()) / float(m_rasterSize)));
+ uint y2 = static_cast<int>(ceil(float(r.y() + r.height()) / float(m_rasterSize)));
+
+ if (!m_raster.empty()) {
+ for ( ; x < x2; x++) {
+ for (uint i = y; i < y2; i++) {
+ if (x < m_raster.size()) {
+ if (i < m_raster.at(x).size()) {
+ Element* e = m_raster.at(x).at(i);
+ if (e && e->valid) {
+ e->valid = false;
+ m_queue.push_back(e);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (!m_busy) {
+ // If the timer is already started, this resets it. That way, we update always
+ // m_timeOutMSec milliseconds after the lastly monitored activity
+ m_timer.start(m_timeOutMSec, true); // true->singleshot
+ }
+}
+
+void KisImageRasteredCache::imageSizeChanged(Q_INT32 w, Q_INT32 h) {
+
+ KisImageSP image = m_view->canvasSubject()->currentImg();
+
+ cleanUpElements();
+ m_busy = false;
+
+ m_width = static_cast<int>(ceil(float(w) / float(m_rasterSize)));
+ m_height = static_cast<int>(ceil(float(h) / float(m_rasterSize)));
+
+ m_raster.resize(m_width);
+
+ int rasterX = 0;
+
+ for (int i = 0; i < m_width * m_rasterSize; i += m_rasterSize) {
+ int rasterY = 0;
+
+ m_raster.at(rasterX).resize(m_height + 1);
+
+ for (int j = 0; j < m_height * m_rasterSize; j += m_rasterSize) {
+ Element* e = new Element(m_observer->createNew(i, j, m_rasterSize, m_rasterSize));
+ m_raster.at(rasterX).at(rasterY) = e;
+ rasterY++;
+ }
+ rasterX++;
+ }
+
+ imageUpdated(QRect(0,0, image->width(), image->height()));
+}
+
+void KisImageRasteredCache::timeOut() {
+ m_busy = true;
+ KisImageSP img = m_view->canvasSubject()->currentImg();
+
+ // Temporary cache: while we are busy, we won't get the mergeImage time and again.
+ if (!m_imageProjection)
+ m_imageProjection = img->mergedImage();
+
+ // Pick one element of the cache, and update it
+ if (!m_queue.isEmpty()) {
+ m_queue.front()->observer->regionUpdated(m_imageProjection);
+ m_queue.front()->valid = true;
+ m_queue.pop_front();
+ }
+
+ // If there are still elements, we need to be called again (this emulates processEvents)
+ if (!m_queue.isEmpty()) {
+ QTimer::singleShot(0, this, SLOT(timeOut()));
+ } else {
+ emit cacheUpdated();
+ m_imageProjection = 0;
+ m_busy = false;
+ }
+}
+
+void KisImageRasteredCache::cleanUpElements() {
+ for (uint i = 0; i < m_raster.count(); i++) {
+ for (uint j = 0; j < m_raster.at(i).count(); j++) {
+ delete m_raster.at(i).at(j);
+ }
+ m_raster.at(i).clear();
+ }
+ m_raster.clear();
+ m_queue.clear();
+}
+
+#include "kis_imagerasteredcache.moc"
diff --git a/krita/plugins/viewplugins/histogram_docker/kis_imagerasteredcache.h b/krita/plugins/viewplugins/histogram_docker/kis_imagerasteredcache.h
new file mode 100644
index 00000000..6335eadb
--- /dev/null
+++ b/krita/plugins/viewplugins/histogram_docker/kis_imagerasteredcache.h
@@ -0,0 +1,80 @@
+/*
+ * This file is part of the KDE project
+ *
+ * Copyright (c) 2005 Bart Coppens <[email protected]>
+ *
+ * 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_IMAGE_RASTERED_CACHE_H_
+#define _KIS_IMAGE_RASTERED_CACHE_H_
+
+#include <qobject.h>
+#include <qvaluevector.h>
+#include <qvaluelist.h>
+#include <qtimer.h>
+
+#include <kis_paint_device.h>
+
+class KisView;
+
+class KisImageRasteredCache : public QObject {
+Q_OBJECT
+
+public:
+ class Observer {
+ public:
+ virtual Observer* createNew(int x, int y, int w, int h) = 0;
+ virtual void regionUpdated(KisPaintDeviceSP dev) = 0;
+ virtual ~Observer() {}
+ };
+
+ KisImageRasteredCache(KisView* view, Observer* o);
+ virtual ~KisImageRasteredCache();
+
+signals:
+ void cacheUpdated();
+
+private slots:
+ void imageUpdated(QRect rc);
+ void imageSizeChanged(Q_INT32 w, Q_INT32 h);
+ void timeOut();
+
+private:
+ class Element {
+ public:
+ Element(Observer* o) : observer(o), valid(true) {}
+ Observer* observer;
+ bool valid;
+ };
+ typedef QValueVector< QValueVector<Element*> > Raster;
+ typedef QValueList<Element*> Queue;
+
+ void cleanUpElements();
+
+ Observer* m_observer;
+ Raster m_raster;
+ Queue m_queue;
+ QTimer m_timer;
+ int m_timeOutMSec;
+ int m_rasterSize;
+ int m_width, m_height;
+ KisView * m_view;
+ bool m_busy;
+
+ KisPaintDeviceSP m_imageProjection;
+};
+
+#endif // _KIS_IMAGE_RASTERED_CACHE_H_
diff --git a/krita/plugins/viewplugins/histogram_docker/kritahistogramdocker.desktop b/krita/plugins/viewplugins/histogram_docker/kritahistogramdocker.desktop
new file mode 100644
index 00000000..1603058d
--- /dev/null
+++ b/krita/plugins/viewplugins/histogram_docker/kritahistogramdocker.desktop
@@ -0,0 +1,40 @@
+[Desktop Entry]
+Name=Histogram Docker
+Name[ca]=Amarrador de l'histograma
+Name[cy]=Bachydd Histogram
+Name[da]=Histogramdokning
+Name[de]=Histogramm-Docker
+Name[el]=Προσάρτηση ιστογράμματος
+Name[eo]=Histogramdokilo
+Name[es]=Anclaje del histograma
+Name[et]=Histogrammi dokk
+Name[fa]=پیونددهندۀ سابقه‌نما
+Name[fr]=Ancrage d'histogramme
+Name[fy]=Histogramkomponint
+Name[gl]=Acoplador de Histogramas
+Name[hu]=Hisztogramdokkoló
+Name[is]=Súluritsspjald
+Name[it]=Aggancia-istogrammi
+Name[ja]=ヒストグラムドッカー
+Name[km]=កន្លែង​ចត​អ៊ីស្តូក្រាម
+Name[nb]=Histogramdokker
+Name[nds]=Histogramm-Docker
+Name[ne]=हिस्टोग्राम डकर
+Name[nl]=Histogramcomponent
+Name[pl]=Doker histogramu
+Name[pt]=Acoplador de Histogramas
+Name[pt_BR]=Acoplador de Histogramas
+Name[ru]=Панель гистограммы
+Name[sk]=Histogram
+Name[sl]=Histogram
+Name[sr]=Сидраш хистограма
+Name[sr@Latn]=Sidraš histograma
+Name[sv]=Histogramdockning
+Name[uk]=Швартувальник гістограм
+Name[uz]=Gistogramma paneli
+Name[uz@cyrillic]=Гистограмма панели
+Name[zh_TW]=直方圖停駐點
+ServiceTypes=Krita/ViewPlugin
+Type=Service
+X-KDE-Library=kritahistogramdocker
+X-Krita-Version=2
diff --git a/krita/plugins/viewplugins/histogram_docker/kritahistogramdocker.rc b/krita/plugins/viewplugins/histogram_docker/kritahistogramdocker.rc
new file mode 100644
index 00000000..525fd65b
--- /dev/null
+++ b/krita/plugins/viewplugins/histogram_docker/kritahistogramdocker.rc
@@ -0,0 +1,3 @@
+<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
+<kpartgui library="kritahistogramdocker" version="1">
+</kpartgui> \ No newline at end of file