[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-kimageshop
Subject:    Patches: Fix of smudge brush and a few other small things (sorry
From:       Silvio Heinrich <plassy () web ! de>
Date:       2010-12-31 21:12:13
Message-ID: 4D1E472D.1010302 () web ! de
[Download RAW message or body]

Here is a patch with some different changes (hopefully improvements?)

Fixed the smudge process and added color smudge feature
Added cursor option "Brush Outline and Crosshair"
Added functionality to overwrite brush presets
Sorted the brush preset list alphabetically

just ask me if i have to change something
thx :D

["various_patches.patch" (text/x-diff)]

From 951c236601bdf56097f5849464a737e0ca3f14f7 Mon Sep 17 00:00:00 2001
From: Silvio Heinrich <plassy@web.de>
Date: Sat, 25 Dec 2010 17:04:16 +0100
Subject: [PATCH 1/9] Sort the paintop preset alphabetically.

---
 krita/ui/widgets/kis_preset_chooser.cpp |   11 +++++++++--
 1 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/krita/ui/widgets/kis_preset_chooser.cpp \
b/krita/ui/widgets/kis_preset_chooser.cpp index b13d65e..f84c922 100644
--- a/krita/ui/widgets/kis_preset_chooser.cpp
+++ b/krita/ui/widgets/kis_preset_chooser.cpp
@@ -30,6 +30,7 @@
 #include <klineedit.h>
 #include <kicon.h>
 
+#include <KoResource.h>
 #include <KoResourceItemChooser.h>
 #include <KoResourceModel.h>
 #include <KoResourceServerAdapter.h>
@@ -100,6 +101,10 @@ void KisPresetDelegate::paint(QPainter * painter, const \
QStyleOptionViewItem & o  
 class KisPresetProxyAdapter : public KoResourceServerAdapter<KisPaintOpPreset>
 {
+	static bool compareKoResources(const KoResource* a, const KoResource* b){
+		return a->name() < b->name();
+	}
+	
 public:
     KisPresetProxyAdapter(KoResourceServer< KisPaintOpPreset >* resourceServer)
          : KoResourceServerAdapter<KisPaintOpPreset>(resourceServer), \
m_showAll(false){} @@ -108,7 +113,7 @@ public:
     virtual QList< KoResource* > resources() {
         if( ! resourceServer() )
             return QList<KoResource*>();
-
+		
         QList<KisPaintOpPreset*> serverResources = resourceServer()->resources();
 
         QList<KoResource*> resources;
@@ -117,7 +122,9 @@ public:
                 resources.append( resource );
             }
         }
-        return resources;      
+        
+        qSort(resources.begin(), resources.end(), \
KisPresetProxyAdapter::compareKoResources); +        return resources;
     }
 
     bool filterAcceptsPreset(KisPaintOpPreset* preset) const
-- 
1.7.1


From 4deef5ca50440b862b93113b9f1f95fc72d35eaa Mon Sep 17 00:00:00 2001
From: Silvio Heinrich <plassy@web.de>
Date: Sat, 25 Dec 2010 17:33:16 +0100
Subject: [PATCH 2/9] Removed superfluous include.

---
 krita/ui/widgets/kis_preset_chooser.cpp |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/krita/ui/widgets/kis_preset_chooser.cpp \
b/krita/ui/widgets/kis_preset_chooser.cpp index f84c922..fc29556 100644
--- a/krita/ui/widgets/kis_preset_chooser.cpp
+++ b/krita/ui/widgets/kis_preset_chooser.cpp
@@ -30,7 +30,6 @@
 #include <klineedit.h>
 #include <kicon.h>
 
-#include <KoResource.h>
 #include <KoResourceItemChooser.h>
 #include <KoResourceModel.h>
 #include <KoResourceServerAdapter.h>
-- 
1.7.1


From ceaa850e3eb3a1f3c35e9d8dec470e90a1aab671 Mon Sep 17 00:00:00 2001
From: Silvio Heinrich <plassy@web.de>
Date: Sat, 25 Dec 2010 21:50:04 +0100
Subject: [PATCH 3/9] When selecting a saved preset, the name will be loaded in the \
edit field of the PaintOpSettings popup.

---
 krita/ui/kis_paintop_box.cc                    |    3 +++
 krita/ui/widgets/kis_paintop_presets_popup.cpp |    5 +++++
 krita/ui/widgets/kis_paintop_presets_popup.h   |    3 ++-
 3 files changed, 10 insertions(+), 1 deletions(-)

diff --git a/krita/ui/kis_paintop_box.cc b/krita/ui/kis_paintop_box.cc
index 3cb6651..a200ef0 100644
--- a/krita/ui/kis_paintop_box.cc
+++ b/krita/ui/kis_paintop_box.cc
@@ -177,6 +177,9 @@ KisPaintopBox::KisPaintopBox(KisView2 * view, QWidget *parent, \
const char * name  
     connect(m_resourceProvider, SIGNAL(sigNodeChanged(const KisNodeSP)),
             this, SLOT(nodeChanged(const KisNodeSP)));
+	
+	connect(m_presetsChooserPopup, SIGNAL(resourceSelected(KoResource*)),
+			m_presetsPopup, SLOT(resourceSelected(KoResource*)));
 
     //Needed to connect canvas to favoriate resource manager
     m_view->canvasBase()->createFavoriteResourceManager(this);
diff --git a/krita/ui/widgets/kis_paintop_presets_popup.cpp \
b/krita/ui/widgets/kis_paintop_presets_popup.cpp index 6a41049..4d71b39 100644
--- a/krita/ui/widgets/kis_paintop_presets_popup.cpp
+++ b/krita/ui/widgets/kis_paintop_presets_popup.cpp
@@ -241,5 +241,10 @@ void KisPaintOpPresetsPopup::showScratchPad()
     m_d->uiWdgPaintOpPresetSettings.scratchPad->setVisible(true);
 }
 
+void KisPaintOpPresetsPopup::resourceSelected(KoResource* resource)
+{
+	m_d->uiWdgPaintOpPresetSettings.txtPreset->setText(resource->name());
+}
+
 
 #include "kis_paintop_presets_popup.moc"
diff --git a/krita/ui/widgets/kis_paintop_presets_popup.h \
b/krita/ui/widgets/kis_paintop_presets_popup.h index 71e00ac..49a242e 100644
--- a/krita/ui/widgets/kis_paintop_presets_popup.h
+++ b/krita/ui/widgets/kis_paintop_presets_popup.h
@@ -28,6 +28,7 @@ class QString;
 class KisPaintOpPreset;
 class KisPropertiesConfiguration;
 class KisCanvasResourceProvider;
+class KoResource;
 
 /**
  * Popup widget for presets with built-in functionality
@@ -59,13 +60,13 @@ public:
     QImage cutOutOverlay();
 
 protected:
-
     void contextMenuEvent(QContextMenuEvent *);
 
 public slots:
     void switchDetached();
     void hideScratchPad();
     void showScratchPad();
+	void resourceSelected(KoResource* resource);
 
 signals:
     void savePresetClicked();
-- 
1.7.1


From 6bdfe7f7c6f013487cfd12849cbf38137c0b95a0 Mon Sep 17 00:00:00 2001
From: Silvio Heinrich <plassy@web.de>
Date: Sun, 26 Dec 2010 01:40:31 +0100
Subject: [PATCH 4/9] Overwrite an existing PaintOp preset instead of creating a new \
one with the same name.

Additionally if a name is entered in the LineEdit field of the PaintOpPreset popup \
that exists already then the LineEdit field is highlighted and the save button text \
                is changed to "Overwrite Preset"
---
 krita/ui/kis_paintop_box.cc                    |   43 +++++++++++++++---------
 krita/ui/kis_paintop_box.h                     |    2 +-
 krita/ui/widgets/kis_paintop_presets_popup.cpp |   22 ++++++++++--
 krita/ui/widgets/kis_paintop_presets_popup.h   |    8 ++++
 4 files changed, 55 insertions(+), 20 deletions(-)

diff --git a/krita/ui/kis_paintop_box.cc b/krita/ui/kis_paintop_box.cc
index a200ef0..4e60f69 100644
--- a/krita/ui/kis_paintop_box.cc
+++ b/krita/ui/kis_paintop_box.cc
@@ -171,15 +171,18 @@ KisPaintopBox::KisPaintopBox(KisView2 * view, QWidget *parent, \
                const char * name
     connect(m_presetsPopup, SIGNAL(savePresetClicked()), this, \
SLOT(slotSaveActivePreset()));  
     connect(m_presetsPopup, SIGNAL(defaultPresetClicked()), this, \
SLOT(slotSetupDefaultPreset())); +    
+    connect(m_presetsPopup, SIGNAL(presetNameLineEditChanged(QString)),
+            this, SLOT(slotWatchPresetNameLineEdit(QString)));
 
     connect(m_presetsChooserPopup, SIGNAL(resourceSelected(KoResource*)),
             this, SLOT(resourceSelected(KoResource*)));
 
     connect(m_resourceProvider, SIGNAL(sigNodeChanged(const KisNodeSP)),
             this, SLOT(nodeChanged(const KisNodeSP)));
-	
-	connect(m_presetsChooserPopup, SIGNAL(resourceSelected(KoResource*)),
-			m_presetsPopup, SLOT(resourceSelected(KoResource*)));
+    
+    connect(m_presetsChooserPopup, SIGNAL(resourceSelected(KoResource*)),
+            m_presetsPopup, SLOT(resourceSelected(KoResource*)));
 
     //Needed to connect canvas to favoriate resource manager
     m_view->canvasBase()->createFavoriteResourceManager(this);
@@ -411,27 +414,28 @@ KisPaintOpPresetSP KisPaintopBox::activePreset(const KoID & \
paintop, const KoInp  
 void KisPaintopBox::slotSaveActivePreset()
 {
-    KisPaintOpPresetSP preset = m_resourceProvider->currentPreset();
-    if (!preset)
+    KisPaintOpPresetSP curPreset = m_resourceProvider->currentPreset();
+    
+    if (!curPreset)
         return;
 
-    KisPaintOpPreset* newPreset = preset->clone();
-    newPreset->setImage(m_presetsPopup->cutOutOverlay());
-
+    KisPaintOpPreset* newPreset = curPreset->clone();
     KoResourceServer<KisPaintOpPreset>* rServer = \
KisResourceServerProvider::instance()->paintOpPresetServer();  QString saveLocation = \
                rServer->saveLocation();
-
     QString name = m_presetsPopup->getPresetName();
+    QFileInfo fileInfo(saveLocation + name + newPreset->defaultFileExtension());
 
-    QFileInfo fileInfo;
-    fileInfo.setFile(saveLocation + name + newPreset->defaultFileExtension());
-
-    int i = 1;
-    while (fileInfo.exists()) {
-        fileInfo.setFile(saveLocation + name + QString("%1").arg(i) + \
                newPreset->defaultFileExtension());
-        i++;
+    if (fileInfo.exists()) {
+        rServer->removeResource(rServer->getResourceByFilename(fileInfo.fileName()));
  }
+    
+//     int i = 1;
+//     while (fileInfo.exists()) {
+//         fileInfo.setFile(saveLocation + name + QString("%1").arg(i) + \
newPreset->defaultFileExtension()); +//         i++;
+//     }
 
+    newPreset->setImage(m_presetsPopup->cutOutOverlay());
     newPreset->setFilename(fileInfo.filePath());
     newPreset->setName(name);
 
@@ -581,4 +585,11 @@ void KisPaintopBox::slotSaveToFavouriteBrushes()
     }
 }
 
+void KisPaintopBox::slotWatchPresetNameLineEdit(const QString& text)
+{
+    KoResourceServer<KisPaintOpPreset>* rServer = \
KisResourceServerProvider::instance()->paintOpPresetServer(); +    \
m_presetsPopup->changeSavePresetButtonText(rServer->getResourceByName(text) != 0); +}
+
+
 #include "kis_paintop_box.moc"
diff --git a/krita/ui/kis_paintop_box.h b/krita/ui/kis_paintop_box.h
index 85f4db2..6d17b83 100644
--- a/krita/ui/kis_paintop_box.h
+++ b/krita/ui/kis_paintop_box.h
@@ -105,7 +105,6 @@ private:
     void setEnabledInternal(bool value);
 
 private slots:
-
     void updatePaintops();
     void nodeChanged(const KisNodeSP node);
     void eraseModeToggled(bool checked);
@@ -113,6 +112,7 @@ private slots:
     void slotSetCompositeMode(const QString& compositeOp);
     void slotSetPaintop(const QString& paintOpId);
     void slotSaveToFavouriteBrushes();
+    void slotWatchPresetNameLineEdit(const QString& text);
 
 private:
 
diff --git a/krita/ui/widgets/kis_paintop_presets_popup.cpp \
b/krita/ui/widgets/kis_paintop_presets_popup.cpp index 4d71b39..3c42640 100644
--- a/krita/ui/widgets/kis_paintop_presets_popup.cpp
+++ b/krita/ui/widgets/kis_paintop_presets_popup.cpp
@@ -112,6 +112,9 @@ KisPaintOpPresetsPopup::KisPaintOpPresetsPopup(KisCanvasResourceProvider \
* resou  
     connect(m_d->uiWdgPaintOpPresetSettings.bnDefaultPreset, SIGNAL(clicked()),
             this, SIGNAL(defaultPresetClicked()));
+    
+    connect(m_d->uiWdgPaintOpPresetSettings.txtPreset, SIGNAL(textChanged(QString)),
+            this, SIGNAL(presetNameLineEditChanged(QString)));
             
     KisConfig cfg;
     m_d->detached = !cfg.paintopPopupDetached();
@@ -161,9 +164,6 @@ void KisPaintOpPresetsPopup::setPaintOpSettingsWidget(QWidget * \
widget)  }
 
     if (widget) {
-
-        
-        
         widget->setFont(m_d->smallFont);
 
         m_d->settingsWidget->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, \
QSizePolicy::Fixed)); @@ -174,6 +174,22 @@ void \
KisPaintOpPresetsPopup::setPaintOpSettingsWidget(QWidget * widget)  }
 }
 
+void KisPaintOpPresetsPopup::changeSavePresetButtonText(bool change)
+{
+    QPalette palette;
+    
+    if (change) {
+        palette.setColor(QPalette::Base, QColor(255,180,180));
+        m_d->uiWdgPaintOpPresetSettings.bnSave->setText("Overwrite Preset");
+        m_d->uiWdgPaintOpPresetSettings.txtPreset->setPalette(palette);
+    }
+    else {
+        m_d->uiWdgPaintOpPresetSettings.bnSave->setText("Save to Presets");
+        m_d->uiWdgPaintOpPresetSettings.txtPreset->setPalette(palette);
+    }
+}
+
+
 QString KisPaintOpPresetsPopup::getPresetName() const
 {
     return m_d->uiWdgPaintOpPresetSettings.txtPreset->text();
diff --git a/krita/ui/widgets/kis_paintop_presets_popup.h \
b/krita/ui/widgets/kis_paintop_presets_popup.h index 49a242e..9379ba1 100644
--- a/krita/ui/widgets/kis_paintop_presets_popup.h
+++ b/krita/ui/widgets/kis_paintop_presets_popup.h
@@ -45,6 +45,12 @@ public:
     ~KisPaintOpPresetsPopup();
 
     void setPaintOpSettingsWidget(QWidget * widget);
+    
+    /**
+     * changes the "save to preset" button text to "override preset"
+     * and highlites the preset name lineedit
+     */
+    void changeSavePresetButtonText(bool change);
 
     /**
      * @return the name entered in the preset name lineedit
@@ -71,12 +77,14 @@ public slots:
 signals:
     void savePresetClicked();
     void defaultPresetClicked();
+    void presetNameLineEditChanged(const QString& presetName);
 
 private slots:
     void fillScratchPadGradient();
     void fillScratchPadSolid();
     void fillScratchPadLayer();
     void slotCheckPresetValidity();
+    
 
 private:
 
-- 
1.7.1


From c0f8c165bb80fe1ec5dd80d340f7687ab61dfbca Mon Sep 17 00:00:00 2001
From: Silvio Heinrich <plassy@web.de>
Date: Tue, 28 Dec 2010 17:49:11 +0100
Subject: [PATCH 5/9] Used i18n function for localization of hardcoded strings.

---
 krita/ui/widgets/kis_paintop_presets_popup.cpp |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/krita/ui/widgets/kis_paintop_presets_popup.cpp \
b/krita/ui/widgets/kis_paintop_presets_popup.cpp index 3c42640..39b9af6 100644
--- a/krita/ui/widgets/kis_paintop_presets_popup.cpp
+++ b/krita/ui/widgets/kis_paintop_presets_popup.cpp
@@ -179,12 +179,12 @@ void KisPaintOpPresetsPopup::changeSavePresetButtonText(bool \
change)  QPalette palette;
     
     if (change) {
-        palette.setColor(QPalette::Base, QColor(255,180,180));
-        m_d->uiWdgPaintOpPresetSettings.bnSave->setText("Overwrite Preset");
+        palette.setColor(QPalette::Base, QColor(255,200,200));
+        m_d->uiWdgPaintOpPresetSettings.bnSave->setText(i18n("Overwrite Preset"));
         m_d->uiWdgPaintOpPresetSettings.txtPreset->setPalette(palette);
     }
     else {
-        m_d->uiWdgPaintOpPresetSettings.bnSave->setText("Save to Presets");
+        m_d->uiWdgPaintOpPresetSettings.bnSave->setText(i18n("Save to Presets"));
         m_d->uiWdgPaintOpPresetSettings.txtPreset->setPalette(palette);
     }
 }
-- 
1.7.1


From 9d3fda0f99e6e707b8ac95e76bc5825e9fce1b47 Mon Sep 17 00:00:00 2001
From: Silvio Heinrich <plassy@web.de>
Date: Tue, 28 Dec 2010 17:52:51 +0100
Subject: [PATCH 6/9] Highlight the preset name LineEdit field after saving a preset.

---
 krita/ui/kis_paintop_box.cc |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/krita/ui/kis_paintop_box.cc b/krita/ui/kis_paintop_box.cc
index 4e60f69..90cfc8c 100644
--- a/krita/ui/kis_paintop_box.cc
+++ b/krita/ui/kis_paintop_box.cc
@@ -439,6 +439,8 @@ void KisPaintopBox::slotSaveActivePreset()
     newPreset->setFilename(fileInfo.filePath());
     newPreset->setName(name);
 
+    m_presetsPopup->changeSavePresetButtonText(true);
+    
     rServer->addResource(newPreset);
 }
 
-- 
1.7.1


From 9c0f0341cb55702abde80a556f8697a279b3dc5a Mon Sep 17 00:00:00 2001
From: Silvio Heinrich <plassy@web.de>
Date: Tue, 28 Dec 2010 17:55:36 +0100
Subject: [PATCH 7/9] Add "Brush Outline and Crosshair" option to the general \
settings.

it will use the crosshair cursor and paints the brush outline simultaneously
this helps seeing the middle of the brush when using large brushes
---
 krita/image/kis_global.h             |    5 ++-
 krita/ui/forms/wdggeneralsettings.ui |    5 ++++
 krita/ui/tool/kis_tool_freehand.cc   |    6 ++--
 krita/ui/tool/kis_tool_paint.cc      |   38 ++++++++++++++++++++++++++++++++-
 4 files changed, 47 insertions(+), 7 deletions(-)

diff --git a/krita/image/kis_global.h b/krita/image/kis_global.h
index e66e806..beb8717 100644
--- a/krita/image/kis_global.h
+++ b/krita/image/kis_global.h
@@ -43,9 +43,10 @@ enum enumCursorStyle {
     CURSOR_STYLE_CROSSHAIR = 1,
     CURSOR_STYLE_POINTER = 2,
     CURSOR_STYLE_OUTLINE = 3,
-    CURSOR_STYLE_NO_CURSOR = 4
+    CURSOR_STYLE_CROSS_OUTLINE = 4,
+    CURSOR_STYLE_NO_CURSOR = 5
 #if defined(HAVE_OPENGL)
-    , CURSOR_STYLE_3D_MODEL = 5
+    , CURSOR_STYLE_3D_MODEL = 6
 #endif
 };
 
diff --git a/krita/ui/forms/wdggeneralsettings.ui \
b/krita/ui/forms/wdggeneralsettings.ui index aea9174..13e0e31 100644
--- a/krita/ui/forms/wdggeneralsettings.ui
+++ b/krita/ui/forms/wdggeneralsettings.ui
@@ -45,6 +45,11 @@
      </item>
      <item>
       <property name="text">
+       <string>Brush Outline and Crosshair</string>
+      </property>
+     </item>
+     <item>
+      <property name="text">
        <string>No Cursor</string>
       </property>
      </item>
diff --git a/krita/ui/tool/kis_tool_freehand.cc b/krita/ui/tool/kis_tool_freehand.cc
index bb50e6d..650af17 100644
--- a/krita/ui/tool/kis_tool_freehand.cc
+++ b/krita/ui/tool/kis_tool_freehand.cc
@@ -133,7 +133,7 @@ void KisToolFreehand::mousePressEvent(KoPointerEvent *e)
     m_outlineDocPoint = e->point;
 
     KisConfig cfg;
-    if(cfg.cursorStyle() == CURSOR_STYLE_OUTLINE) {
+    if(cfg.cursorStyle() == CURSOR_STYLE_OUTLINE || cfg.cursorStyle() == \
CURSOR_STYLE_CROSS_OUTLINE) {  updateOutlineRect();
     }
 
@@ -188,7 +188,7 @@ void KisToolFreehand::mouseMoveEvent(KoPointerEvent *e)
         m_outlineDocPoint = e->point;
 
         KisConfig cfg;
-        if(cfg.cursorStyle() == CURSOR_STYLE_OUTLINE) {
+        if(cfg.cursorStyle() == CURSOR_STYLE_OUTLINE || cfg.cursorStyle() == \
CURSOR_STYLE_CROSS_OUTLINE) {  updateOutlineRect();
         }
 
@@ -553,7 +553,7 @@ void KisToolFreehand::paint(QPainter& gc, const KoViewConverter \
&converter)  
         if(m_explicitShowOutline ||
            mode() == KisTool::GESTURE_MODE ||
-           (cfg.cursorStyle() == CURSOR_STYLE_OUTLINE &&
+           ((cfg.cursorStyle() == CURSOR_STYLE_OUTLINE || cfg.cursorStyle() == \
CURSOR_STYLE_CROSS_OUTLINE) &&  (mode() == HOVER_MODE ||
              (mode() == PAINT_MODE && cfg.showOutlineWhilePainting())))) {
 
diff --git a/krita/ui/tool/kis_tool_paint.cc b/krita/ui/tool/kis_tool_paint.cc
index 7e0ef4a..1121985 100644
--- a/krita/ui/tool/kis_tool_paint.cc
+++ b/krita/ui/tool/kis_tool_paint.cc
@@ -353,10 +353,44 @@ void KisToolPaint::resetCursorStyle()
 {
     KisTool::resetCursorStyle();
     KisConfig cfg;
-    if (cfg.cursorStyle() == CURSOR_STYLE_OUTLINE) {
+    
+    switch(cfg.cursorStyle())
+    {
+    case CURSOR_STYLE_OUTLINE:
+        if (m_supportOutline) {
+            useCursor(KisCursor::blankCursor());
+            break;
+        }
+        
+    case CURSOR_STYLE_CROSS_OUTLINE:
+        if (m_supportOutline) {
+            useCursor(KisCursor::crossCursor());
+            break;
+        }
+        
+#if defined(HAVE_OPENGL)
+    case CURSOR_STYLE_3D_MODEL:
+        if(isCanvasOpenGL()) {
+            if (m_supportOutline) {
+                useCursor(KisCursor::blankCursor());
+                break;
+            }
+        } else {
+            useCursor(KisCursor::arrowCursor());
+            break;
+        }
+#endif
+
+    default:
+        useCursor(cursor());
+        break;
+    }
+/*
+    if (cfg.cursorStyle() == CURSOR_STYLE_OUTLINE || cfg.cursorStyle() == \
CURSOR_STYLE_CROSS_OUTLINE) {  if (m_supportOutline) {
             // do not show cursor, tool will paint outline
             useCursor(KisCursor::blankCursor());
+            useCursor(KisCursor::crossCursor());
         } else {
             // if the tool does not support outline, use tool icon cursor
             useCursor(cursor());
@@ -377,7 +411,7 @@ void KisToolPaint::resetCursorStyle()
         }
     }
 #endif
-
+//*/
 
 }
 
-- 
1.7.1


From c4523437c5f069c89dd95c6e4829eff97512d491 Mon Sep 17 00:00:00 2001
From: Silvio Heinrich <plassy@web.de>
Date: Fri, 31 Dec 2010 00:23:07 +0100
Subject: [PATCH 8/9] Fixed (reprogrammed) smudge brush

Reprogrammed the smudge brush with a simpler algorithm.
An option to mix color into the smudge process is also introduced.
---
 .../defaultpaintops/smudge/kis_smudgeop.cpp        |  107 ++++++++++++++++----
 .../paintops/defaultpaintops/smudge/kis_smudgeop.h |    3 +-
 .../smudge/kis_smudgeop_settings_widget.cpp        |   10 +-
 krita/plugins/paintops/libpaintop/CMakeLists.txt   |    2 +
 .../libpaintop/kis_pressure_composite_option.cpp   |   76 ++++++++++++++
 .../libpaintop/kis_pressure_composite_option.h     |   58 +++++++++++
 .../kis_pressure_composite_option_widget.cpp       |  104 +++++++++++++++++++
 .../kis_pressure_composite_option_widget.h         |   46 +++++++++
 8 files changed, 380 insertions(+), 26 deletions(-)
 create mode 100644 krita/plugins/paintops/libpaintop/kis_pressure_composite_option.cpp
  create mode 100644 \
krita/plugins/paintops/libpaintop/kis_pressure_composite_option.h  create mode 100644 \
krita/plugins/paintops/libpaintop/kis_pressure_composite_option_widget.cpp  create \
mode 100644 krita/plugins/paintops/libpaintop/kis_pressure_composite_option_widget.h

diff --git a/krita/plugins/paintops/defaultpaintops/smudge/kis_smudgeop.cpp \
b/krita/plugins/paintops/defaultpaintops/smudge/kis_smudgeop.cpp index \
                ee7927f..c8dde6d 100644
--- a/krita/plugins/paintops/defaultpaintops/smudge/kis_smudgeop.cpp
+++ b/krita/plugins/paintops/defaultpaintops/smudge/kis_smudgeop.cpp
@@ -58,11 +58,11 @@ KisSmudgeOp::KisSmudgeOp(const KisBrushBasedPaintOpSettings \
*settings, KisPainte  Q_ASSERT(settings);
     Q_ASSERT(painter);
     m_sizeOption.readOptionSetting(settings);
-    m_opacityOption.readOptionSetting(settings);
     m_rateOption.readOptionSetting(settings);
+    m_compositeOption.readOptionSetting(settings);
     m_sizeOption.sensor()->reset();
-    m_opacityOption.sensor()->reset();
     m_rateOption.sensor()->reset();
+    m_compositeOption.sensor()->reset();
 
     m_tempDev = new KisPaintDevice(painter->device()->colorSpace());
     
@@ -76,9 +76,77 @@ KisSmudgeOp::~KisSmudgeOp()
 {
 }
 
-/* To smudge, one does the following:
 
- 1.- First step: initialize a temporary paint device (m_tempDev) with a copy of the \
colors below the mouse pointer. +
+qreal KisSmudgeOp::paintAt(const KisPaintInformation& info)
+{
+    // Simple error catching
+    if (!painter()->device())
+        return 1.0;
+    
+    KisBrushSP brush = m_brush;
+    
+    if(!brush || !brush->canPaintFor(info))
+        return 1.0;
+    
+    double scale = m_sizeOption.apply(info);
+    
+    if((scale*brush->width()) <= 0.01 || (scale*brush->height()) <= 0.01)
+        return 1.0;
+    
+    setCurrentScale(scale);
+    
+    QPointF point = info.pos() - brush->hotSpot(scale, scale);
+    
+    qint32 x, y;
+    qreal xFraction, yFraction;
+    splitCoordinate(point.x(), &x, &xFraction);
+    splitCoordinate(point.y(), &y, &yFraction);
+    
+    KisFixedPaintDeviceSP maskDab = cachedDab(painter()->device()->colorSpace());
+    
+    // Extract the brush mask (maskDab) from brush, and turn it into a transparency \
mask (alpha8). +    if(brush->brushType() == IMAGE || brush->brushType() == \
PIPE_IMAGE) { +        // This is for bitmap brushes
+        maskDab = brush->paintDevice(painter()->device()->colorSpace(), scale, 0.0, \
info, xFraction, yFraction); +    } else {
+        // This is for parametric brushes, those created in the Autobrush popup \
config dialogue +        maskDab = cachedDab();
+        brush->mask(maskDab, painter()->paintColor(), scale, scale, 0.0, info, \
xFraction, yFraction); +    }
+    
+    maskDab->convertTo(KoColorSpaceRegistry::instance()->alpha8());
+    
+    KisPainter copyPainter(m_tempDev);
+    
+    if(m_compositeOption.isChecked()) {
+        m_compositeOption.apply(&copyPainter, OPACITY_OPAQUE_U8, info);
+        
+        copyPainter.setFillStyle(KisPainter::FillStyleForegroundColor);
+        copyPainter.setPaintColor(painter()->paintColor());
+        copyPainter.paintRect(maskDab->bounds());
+    }
+    
+    quint8 newOpacity = m_rateOption.apply(OPACITY_OPAQUE_U8, info);
+    
+    painter()->setOpacity(newOpacity);
+    painter()->bitBltWithFixedSelection(x, y, m_tempDev, maskDab, \
maskDab->bounds().width(), maskDab->bounds().height()); +    \
//painter()->bitBlt(QPoint(x,y), m_tempDev, dab->bounds()); +    
+    m_tempDev->clear(maskDab->bounds());
+    
+    copyPainter.setCompositeOp(COMPOSITE_OVER);
+    copyPainter.setOpacity(OPACITY_OPAQUE_U8);
+    copyPainter.bitBlt(0, 0, painter()->device(), x, y, maskDab->bounds().width(), \
maskDab->bounds().height()); +    copyPainter.end();
+    
+    return spacing(scale);
+}
+
+
+/* To smudge, one does the following:
+ * 
+ 1 *.- First step: initialize a temporary paint device (m_tempDev) with a copy of \
the colors below the mouse pointer.  All other times:
  2.- Vanishing step: Reduce the transparency of the temporary paint device so as to \
let it mix gradually.  3.- Combine: Combine the temporary device with the piece the \
brush currently is 'painting', according to a ratio: @@ -93,8 +161,7 @@ \
KisSmudgeOp::~KisSmudgeOp()  temporary device is cached such that only the colored \
areas are considered.  TODO: Make this cached value dump colors that have faded \
nearly completely and lie outside of the rectangle (dab)  of the current iteration.
-*/
-    
+ *
 qreal KisSmudgeOp::paintAt(const KisPaintInformation& info)
 {
     KisBrushSP brush = m_brush;
@@ -109,14 +176,14 @@ qreal KisSmudgeOp::paintAt(const KisPaintInformation& info)
     if ((scale * brush->width()) <= 0.01 || (scale * brush->height()) <= 0.01) \
return 1.0;  setCurrentScale(scale);
     
-    /* Align a point that represents the top-left corner of the \
                brush-stroke-rendering
-    with the mouse pointer and take into account the brush mask size */
+    // Align a point that represents the top-left corner of the \
brush-stroke-rendering +    // with the mouse pointer and take into account the brush \
mask size  QPointF hotSpot = brush->hotSpot(scale, scale);
     QPointF pt = info.pos() - hotSpot;
 
-    /* Split the coordinates into integer plus fractional parts. The integer
-    is where the dab will be positioned and the fractional part determines
-    the sub-pixel positioning. */
+    // Split the coordinates into integer plus fractional parts. The integer
+    //is where the dab will be positioned and the fractional part determines
+    // the sub-pixel positioning.
     qint32 x, y;
     qreal xFraction, yFraction;
 
@@ -141,17 +208,17 @@ qreal KisSmudgeOp::paintAt(const KisPaintInformation& info)
     qint32 sw = maskDab->bounds().width();
     qint32 sh = maskDab->bounds().height();
     
-    /* Prepare the top left corner of the temporary paint device where the extracted \
color will be drawn */ +    // Prepare the top left corner of the temporary paint \
device where the extracted color will be drawn  QPoint extractionTopLeft = \
QPoint(ANCHOR_POINT.x() - sw / 2,  ANCHOR_POINT.y() - sh / 2);
                                       
-    /* In the block below, the opacity of the colors stored in m_tempDev
-    is reduced in opacity. Nothing of the color present inside it is left out */
+    // In the block below, the opacity of the colors stored in m_tempDev
+    // is reduced in opacity. Nothing of the color present inside it is left out
     quint8 opacity = OPACITY_OPAQUE_U8;
     if (!m_firstRun) {
         opacity = m_rateOption.apply(opacity, info);
-        /* Without those limits, the smudge brush doesn't smudge anymore, it either \
                makes a single
-        dropplet of color, or drags a frame indefinitely over the canvas. */
+        // Without those limits, the smudge brush doesn't smudge anymore, it either \
makes a single +        // dropplet of color, or drags a frame indefinitely over the \
                canvas.
         opacity = qBound(MIXABLE_LOWER_LIMIT, opacity, MIXABLE_UPPER_LIMIT);
                 
         // Invert the opacity value for color absorption in the next lines \
(copyPainter) @@ -162,9 +229,9 @@ qreal KisSmudgeOp::paintAt(const \
KisPaintInformation& info)  m_firstRun = false;
         m_wholeTempData = QRect(extractionTopLeft, maskDab->bounds().size());
     }
-    /* copyPainter will extract the piece of color (image) to be duplicated to \
                generate the smudge effect,
-    it extracts a simple unmasked rectangle and adds it to what was extracted before \
                in this same block of code,
-    this sometimes shows artifacts when the brush is used with stylus and high \
spacing */ +    // copyPainter will extract the piece of color (image) to be \
duplicated to generate the smudge effect, +    // it extracts a simple unmasked \
rectangle and adds it to what was extracted before in this same block of code, +    \
// this sometimes shows artifacts when the brush is used with stylus and high spacing \
KisPainter copyPainter(m_tempDev);  copyPainter.setCompositeOp(COMPOSITE_COPY);
     copyPainter.setOpacity(opacity);
@@ -179,4 +246,4 @@ qreal KisSmudgeOp::paintAt(const KisPaintInformation& info)
     renderMirrorMask(QRect(QPoint(x,y),QSize(sw,sh)),m_tempDev,extractionTopLeft.x(), \
extractionTopLeft.y(),maskDab);  
     return spacing(scale);
-}
+}//*/
diff --git a/krita/plugins/paintops/defaultpaintops/smudge/kis_smudgeop.h \
b/krita/plugins/paintops/defaultpaintops/smudge/kis_smudgeop.h index 6e3e63f..35a5b64 \
                100644
--- a/krita/plugins/paintops/defaultpaintops/smudge/kis_smudgeop.h
+++ b/krita/plugins/paintops/defaultpaintops/smudge/kis_smudgeop.h
@@ -31,6 +31,7 @@
 #include <kis_pressure_opacity_option.h>
 #include <kis_pressure_size_option.h>
 #include <kis_pressure_rate_option.h>
+#include <kis_pressure_composite_option.h>
 
 class KisBrushBasedPaintOpSettings;
 
@@ -56,8 +57,8 @@ private:
     KoColor m_color;
     
     KisPressureSizeOption m_sizeOption;
-    KisPressureOpacityOption m_opacityOption;
     KisPressureRateOption m_rateOption;
+    KisPressureCompositeOption m_compositeOption;
 };
 
 #endif // KIS_SMUDGEOP_H_
diff --git a/krita/plugins/paintops/defaultpaintops/smudge/kis_smudgeop_settings_widget.cpp \
b/krita/plugins/paintops/defaultpaintops/smudge/kis_smudgeop_settings_widget.cpp \
                index 07a70ca..3f01533 100644
--- a/krita/plugins/paintops/defaultpaintops/smudge/kis_smudgeop_settings_widget.cpp
+++ b/krita/plugins/paintops/defaultpaintops/smudge/kis_smudgeop_settings_widget.cpp
@@ -24,12 +24,13 @@
 #include "kis_brush_based_paintop_settings.h"
 #include <kis_properties_configuration.h>
 #include <kis_paintop_options_widget.h>
-#include <kis_pressure_darken_option.h>
-#include <kis_pressure_opacity_option.h>
 #include <kis_pressure_size_option.h>
+#include <kis_pressure_composite_option.h>
 #include <kis_pressure_rate_option.h>
 #include <kis_curve_option_widget.h>
 #include <kis_pressure_rate_option_widget.h>
+#include <kis_pressure_composite_option_widget.h>
+
 
 KisSmudgeOpSettingsWidget::KisSmudgeOpSettingsWidget(QWidget* parent)
     : KisBrushBasedPaintopOptionWidget(parent)
@@ -37,9 +38,8 @@ KisSmudgeOpSettingsWidget::KisSmudgeOpSettingsWidget(QWidget* \
parent)  setObjectName("brush option widget");
 
     addPaintOpOption(new KisCurveOptionWidget(new KisPressureSizeOption()));
-    addPaintOpOption(new KisCurveOptionWidget(new KisPressureOpacityOption()));
-    addPaintOpOption(new KisCurveOptionWidget(new KisPressureDarkenOption));
     addPaintOpOption(new KisPressureRateOptionWidget());
+    addPaintOpOption(new KisPressureCompositeOptionWidget());
 
 }
 
@@ -51,7 +51,7 @@ KisPropertiesConfiguration* \
KisSmudgeOpSettingsWidget::configuration() const  {
     KisBrushBasedPaintOpSettings *config = new KisBrushBasedPaintOpSettings();
     config->setOptionsWidget(const_cast<KisSmudgeOpSettingsWidget*>(this));
-    config->setProperty("paintop", "smudge"); // XXX: make this a const id string
+    config->setProperty("paintop", "smudge"); // TODO: make this a const id string
     writeConfiguration(config);
     return config;
 }
diff --git a/krita/plugins/paintops/libpaintop/CMakeLists.txt \
b/krita/plugins/paintops/libpaintop/CMakeLists.txt index 996cafc..b0bc55d 100644
--- a/krita/plugins/paintops/libpaintop/CMakeLists.txt
+++ b/krita/plugins/paintops/libpaintop/CMakeLists.txt
@@ -38,6 +38,8 @@ set(kritalibpaintop_LIB_SRCS
     kis_pressure_size_option.cpp
     kis_pressure_softness_option.cpp
     kis_pressure_mix_option.cpp
+    kis_pressure_composite_option.cpp
+    kis_pressure_composite_option_widget.cpp
     kis_sensor_selector.cc
     kis_text_brush_chooser.cpp
     kis_brush_based_paintop_options_widget.cpp
diff --git a/krita/plugins/paintops/libpaintop/kis_pressure_composite_option.cpp \
b/krita/plugins/paintops/libpaintop/kis_pressure_composite_option.cpp new file mode \
100644 index 0000000..18a9882
--- /dev/null
+++ b/krita/plugins/paintops/libpaintop/kis_pressure_composite_option.cpp
@@ -0,0 +1,76 @@
+/* This file is part of the KDE project
+ * Copyright (C) Boudewijn Rempt <boud@valdyas.org>, (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_pressure_composite_option.h"
+
+
+#include <klocale.h>
+
+#include <kis_painter.h>
+#include <widgets/kis_curve_widget.h>
+
+#include <KoColor.h>
+#include <KoColorSpace.h>
+#include <KoCompositeOp.h>
+
+KisPressureCompositeOption::KisPressureCompositeOption()
+        : KisCurveOption(i18n("Color"), "Color", KisPaintOpOption::brushCategory(), \
false) +{
+    setMinimumLabel(i18n("Full Color"));
+    setMaximumLabel(i18n("No Color"));
+}
+
+void KisPressureCompositeOption::writeOptionSetting(KisPropertiesConfiguration* \
setting) const +{
+    KisCurveOption::writeOptionSetting(setting);
+    setting->setProperty("CompositeOp", m_compositeOp);
+    setting->setProperty("CompositeRateValue", m_rate);
+}
+
+void KisPressureCompositeOption::readOptionSetting(const KisPropertiesConfiguration* \
setting) +{
+    KisCurveOption::readOptionSetting(setting);
+    m_compositeOp = setting->getString("CompositeOp");
+    m_rate        = setting->getInt("CompositeRateValue");
+    
+    if(m_compositeOp == "") //TODO: test if compositeOp is valid instead of just \
testing for an empty string +        m_compositeOp = COMPOSITE_OVER;
+}
+
+QString KisPressureCompositeOption::apply(KisPainter* painter, qint8 opacity, const \
KisPaintInformation& info) const +{
+    if(!isChecked())
+        return painter->compositeOp()->id();
+    
+    QString oldCompositeOp = painter->compositeOp()->id();
+    
+    opacity = (m_rate * 255) / 100;
+    opacity = qBound((qint32)OPACITY_TRANSPARENT_U8,
+                     (qint32)(double(opacity) * computeValue(info) / \
PRESSURE_DEFAULT), +                     (qint32)OPACITY_OPAQUE_U8);
+    
+    //qreal  opacity1 = (qreal)(painter->opacity() * computeValue(info));
+    //quint8 opacity2 = (quint8)qRound(qBound<qreal>(OPACITY_TRANSPARENT_U8, \
opacity1, OPACITY_OPAQUE_U8)); +    
+    painter->setCompositeOp(m_compositeOp);
+    painter->setOpacity(opacity);
+
+    return oldCompositeOp;
+}
+
diff --git a/krita/plugins/paintops/libpaintop/kis_pressure_composite_option.h \
b/krita/plugins/paintops/libpaintop/kis_pressure_composite_option.h new file mode \
100644 index 0000000..f05642a
--- /dev/null
+++ b/krita/plugins/paintops/libpaintop/kis_pressure_composite_option.h
@@ -0,0 +1,58 @@
+/* This file is part of the KDE project
+ * Copyright (C) Boudewijn Rempt <boud@valdyas.org>, (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.
+ */
+
+#ifndef KIS_PRESSURE_COMPOSITE_OPTION_H
+#define KIS_PRESSURE_COMPOSITE_OPTION_H
+
+#include "kis_curve_option.h"
+#include <kis_paint_information.h>
+#include <krita_export.h>
+#include <kis_types.h>
+
+class QSlider;
+class KisPropertiesConfiguration;
+class KisPainter;
+
+class PAINTOP_EXPORT KisPressureCompositeOption : public KisCurveOption
+{
+public:
+    KisPressureCompositeOption();
+
+    /**
+     * Set the composite mode and opacity of the painter based on the pressure
+     * and the curve (if checked) and return the old composite mode
+     * of the painter.
+     */
+    QString apply(KisPainter* painter, qint8 opacity, const KisPaintInformation& \
info) const; +
+    void writeOptionSetting(KisPropertiesConfiguration* setting) const;
+    void readOptionSetting(const KisPropertiesConfiguration* setting);
+    
+    void setCompositeOp(const QString& compositeOp) { m_compositeOp = compositeOp; }
+    QString getCompositeOp() { return m_compositeOp; }
+    
+    void setRate(int rate) { m_rate = rate; }
+    int getRate() { return m_rate; }
+    
+private:
+    QString m_compositeOp;
+    int     m_rate;
+};
+
+#endif // KIS_PRESSURE_COMPOSITE_OPTION_H
diff --git a/krita/plugins/paintops/libpaintop/kis_pressure_composite_option_widget.cpp \
b/krita/plugins/paintops/libpaintop/kis_pressure_composite_option_widget.cpp new file \
mode 100644 index 0000000..140c628
--- /dev/null
+++ b/krita/plugins/paintops/libpaintop/kis_pressure_composite_option_widget.cpp
@@ -0,0 +1,104 @@
+/* This file is part of the KDE project
+ * Copyright (C) Boudewijn Rempt <boud@valdyas.org>, (C) 2008
+ * Copyright (C) Sven Langkamp <sven.langkamp@gmail.com>, (C) 2009
+ *
+ * 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_pressure_composite_option_widget.h"
+#include "kis_pressure_composite_option.h"
+
+#include <KoCompositeOp.h>
+
+#include <QWidget>
+#include <QCheckBox>
+#include <QLabel>
+#include <QComboBox>
+#include <QSlider>
+#include <QVBoxLayout>
+#include <QGridLayout>
+
+#include <klocale.h>
+
+KisPressureCompositeOptionWidget::KisPressureCompositeOptionWidget()
+    : KisCurveOptionWidget(new KisPressureCompositeOption())
+{
+    QWidget* widget    = new QWidget;
+    QLabel*  modeLabel = new QLabel(i18n("Mode: "));
+    QLabel*  rateLabel = new QLabel(i18n("Rate: "));
+    
+    m_compositeOpBox = new QComboBox();
+    m_compositeOpBox->addItem(COMPOSITE_OVER);
+    m_compositeOpBox->addItem(COMPOSITE_OVERLAY);
+    m_compositeOpBox->addItem(COMPOSITE_SCREEN);
+    m_compositeOpBox->addItem(COMPOSITE_ADD);
+    m_compositeOpBox->addItem(COMPOSITE_SUBTRACT);
+    
+    m_rateSlider = new QSlider();
+    m_rateSlider->setMinimum(0);
+    m_rateSlider->setMaximum(100);
+    m_rateSlider->setPageStep(1);
+    m_rateSlider->setValue(90);
+    m_rateSlider->setOrientation(Qt::Horizontal);
+    
+    connect(m_compositeOpBox, SIGNAL(activated(QString)), this, \
SLOT(compositeOpChanged(QString))); +    connect(m_rateSlider, \
SIGNAL(valueChanged(int)), this, SLOT(rateChanged(int))); +    
+    QGridLayout* gridLayout = new QGridLayout();
+    gridLayout->addWidget(modeLabel, 0, 0);
+    gridLayout->addWidget(m_compositeOpBox, 0, 1);
+    gridLayout->addWidget(rateLabel, 1, 0);
+    gridLayout->addWidget(m_rateSlider, 1, 1);
+
+    QVBoxLayout* vBoxLayout = new QVBoxLayout;
+    vBoxLayout->addLayout(gridLayout);
+    vBoxLayout->addWidget(curveWidget());
+
+    widget->setLayout(vBoxLayout);
+    
+    setConfigurationPage(widget);
+    
+    compositeOpChanged(COMPOSITE_OVER);
+    rateChanged(m_rateSlider->value());
+}
+
+void KisPressureCompositeOptionWidget::readOptionSetting(const \
KisPropertiesConfiguration* setting) +{
+    KisCurveOptionWidget::readOptionSetting(setting);
+    
+    QString compositeOp = \
static_cast<KisPressureCompositeOption*>(curveOption())->getCompositeOp(); +    
+    for(int i=0; i<m_compositeOpBox->count(); ++i) {
+        if(m_compositeOpBox->itemText(i) == compositeOp) {
+            m_compositeOpBox->setCurrentIndex(i);
+            break;
+        }
+    }
+    
+    m_rateSlider->setValue(static_cast<KisPressureCompositeOption*>(curveOption())->getRate());
 +}
+
+void KisPressureCompositeOptionWidget::compositeOpChanged(const QString& \
compositeOp) +{
+    static_cast<KisPressureCompositeOption*>(curveOption())->setCompositeOp(compositeOp);
 +    emit sigSettingChanged();
+}
+
+void KisPressureCompositeOptionWidget::rateChanged(int rate)
+{
+    static_cast<KisPressureCompositeOption*>(curveOption())->setRate(rate);
+    emit sigSettingChanged();
+}
diff --git a/krita/plugins/paintops/libpaintop/kis_pressure_composite_option_widget.h \
b/krita/plugins/paintops/libpaintop/kis_pressure_composite_option_widget.h new file \
mode 100644 index 0000000..6660f72
--- /dev/null
+++ b/krita/plugins/paintops/libpaintop/kis_pressure_composite_option_widget.h
@@ -0,0 +1,46 @@
+/* This file is part of the KDE project
+ * Copyright (C) Sven Langkamp <sven.langkamp@gmail.com>, (C) 2009
+ *
+ * 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_PRESSURE_COMPOSITE_OPTION_WIDGET_H
+#define KIS_PRESSURE_COMPOSITE_OPTION_WIDGET_H
+
+#include "kis_curve_option_widget.h"
+
+class QComboBox;
+class QSlider;
+
+class PAINTOP_EXPORT KisPressureCompositeOptionWidget : public KisCurveOptionWidget
+{
+    Q_OBJECT
+    
+public:
+    KisPressureCompositeOptionWidget();
+
+    void readOptionSetting(const KisPropertiesConfiguration* setting);
+    
+private slots:
+     void compositeOpChanged(const QString& compositeOp);
+     void rateChanged(int rate);
+    
+private:
+    QComboBox* m_compositeOpBox;
+    QSlider*   m_rateSlider;
+};
+
+#endif // KIS_PRESSURE_COMPOSITE_OPTION_WIDGET_H
-- 
1.7.1


From ae5627cd172be0a333e30f74aed5249dfbea8f17 Mon Sep 17 00:00:00 2001
From: Silvio Heinrich <plassy@web.de>
Date: Fri, 31 Dec 2010 21:28:09 +0100
Subject: [PATCH 9/9] Some cleanup and documentation and added more composite modes to \
KisPressureCompositeOptionWidget.

---
 .../defaultpaintops/smudge/kis_smudgeop.cpp        |  163 ++++----------------
 .../paintops/defaultpaintops/smudge/kis_smudgeop.h |    8 +-
 .../libpaintop/kis_pressure_composite_option.cpp   |    7 +-
 .../libpaintop/kis_pressure_composite_option.h     |    7 +-
 .../kis_pressure_composite_option_widget.cpp       |    6 +
 5 files changed, 42 insertions(+), 149 deletions(-)

diff --git a/krita/plugins/paintops/defaultpaintops/smudge/kis_smudgeop.cpp \
b/krita/plugins/paintops/defaultpaintops/smudge/kis_smudgeop.cpp index \
                c8dde6d..372a1b7 100644
--- a/krita/plugins/paintops/defaultpaintops/smudge/kis_smudgeop.cpp
+++ b/krita/plugins/paintops/defaultpaintops/smudge/kis_smudgeop.cpp
@@ -40,19 +40,8 @@
 #include <kis_selection.h>
 #include <kis_brush_based_paintop_settings.h>
 
-
-// Both limits defined to be 15 units away from the min (0) or max (255) to allow \
                actual mixing of colors
-const quint8 MIXABLE_UPPER_LIMIT = 240;
-const quint8 MIXABLE_LOWER_LIMIT = 15;
-
-// All pieces of color extracted from the canvas will be centered around \
                ANCHOR_POINT
-const QPoint ANCHOR_POINT = QPoint(0, 0);
-
-
 KisSmudgeOp::KisSmudgeOp(const KisBrushBasedPaintOpSettings *settings, KisPainter \
                *painter, KisImageWSP image)
-        : KisBrushBasedPaintOp(settings, painter)
-        , m_firstRun(true)
-        , m_tempDev(0)
+        : KisBrushBasedPaintOp(settings, painter), m_tempDev(0)
 {
     Q_UNUSED(image);
     Q_ASSERT(settings);
@@ -65,11 +54,6 @@ KisSmudgeOp::KisSmudgeOp(const KisBrushBasedPaintOpSettings \
*settings, KisPainte  m_compositeOption.sensor()->reset();
 
     m_tempDev = new KisPaintDevice(painter->device()->colorSpace());
-    
-    // Initializing to a valid value to avoid weird errors during modifications
-    m_wholeTempData = QRect(0, 0, 0, 0);
-    
-    m_color = painter->paintColor();
 }
 
 KisSmudgeOp::~KisSmudgeOp()
@@ -89,8 +73,10 @@ qreal KisSmudgeOp::paintAt(const KisPaintInformation& info)
     if(!brush || !brush->canPaintFor(info))
         return 1.0;
     
+    // get the scaling factor calculated by the size option
     double scale = m_sizeOption.apply(info);
     
+    // don't paint anything if the brush is too samll
     if((scale*brush->width()) <= 0.01 || (scale*brush->height()) <= 0.01)
         return 1.0;
     
@@ -105,7 +91,7 @@ qreal KisSmudgeOp::paintAt(const KisPaintInformation& info)
     
     KisFixedPaintDeviceSP maskDab = cachedDab(painter()->device()->colorSpace());
     
-    // Extract the brush mask (maskDab) from brush, and turn it into a transparency \
mask (alpha8). +    // Extract the brush mask (maskDab) from brush with the correct \
scaled size  if(brush->brushType() == IMAGE || brush->brushType() == PIPE_IMAGE) {
         // This is for bitmap brushes
         maskDab = brush->paintDevice(painter()->device()->colorSpace(), scale, 0.0, \
info, xFraction, yFraction); @@ -115,135 +101,46 @@ qreal KisSmudgeOp::paintAt(const \
                KisPaintInformation& info)
         brush->mask(maskDab, painter()->paintColor(), scale, scale, 0.0, info, \
xFraction, yFraction);  }
     
+    // transforms the fixed paint device with the current brush to alpha color space \
(to use it as alpha/transparency mask)  \
maskDab->convertTo(KoColorSpaceRegistry::instance()->alpha8());  
-    KisPainter copyPainter(m_tempDev);
-    
-    if(m_compositeOption.isChecked()) {
-        m_compositeOption.apply(&copyPainter, OPACITY_OPAQUE_U8, info);
-        
-        copyPainter.setFillStyle(KisPainter::FillStyleForegroundColor);
-        copyPainter.setPaintColor(painter()->paintColor());
-        copyPainter.paintRect(maskDab->bounds());
-    }
-    
+    // GET the opacy calculated by the rate option (apply is misleading because the \
opacy will not be applied)  quint8 newOpacity = m_rateOption.apply(OPACITY_OPAQUE_U8, \
info);  
+    // set opacity calculated by the rate option
+    // then blit the temporary painting device on the canvas at the current brush \
position +    // the alpha mask (maskDab) will be used here to only blit the pixels \
that lie in the area (shape) of the brush  painter()->setOpacity(newOpacity);
     painter()->bitBltWithFixedSelection(x, y, m_tempDev, maskDab, \
                maskDab->bounds().width(), maskDab->bounds().height());
-    //painter()->bitBlt(QPoint(x,y), m_tempDev, dab->bounds());
     
+    // IMPORTANT: clear the temporary painting device to color black with zero \
opacity +    //            it will only clear the extents of the brush
     m_tempDev->clear(maskDab->bounds());
     
+    KisPainter copyPainter(m_tempDev);
+    
+    // reset composite mode and opacity
+    // then cut out the area from the canvas under the brush
+    // and blit it to the temporary painting device
     copyPainter.setCompositeOp(COMPOSITE_OVER);
     copyPainter.setOpacity(OPACITY_OPAQUE_U8);
     copyPainter.bitBlt(0, 0, painter()->device(), x, y, maskDab->bounds().width(), \
                maskDab->bounds().height());
-    copyPainter.end();
-    
-    return spacing(scale);
-}
-
-
-/* To smudge, one does the following:
- * 
- 1 *.- First step: initialize a temporary paint device (m_tempDev) with a copy of \
                the colors below the mouse pointer.
- All other times:
- 2.- Vanishing step: Reduce the transparency of the temporary paint device so as to \
                let it mix gradually.
- 3.- Combine: Combine the temporary device with the piece the brush currently is \
                'painting', according to a ratio:
- in this case, opacity. (This is what in the first step does the copying of the \
                data).
- 4.- Blit to screen: This combination is then composited upon the actual image.
- 5.- Special case: If the size of the dab (brush mask) changes during the stroke \
                (for example, when
- using a stylus sensitive to pressure), align the colors extracted to the center of \
                the previously absorbed colors,
- and in the vanishing step, ensure that all the colors have their opacity slowly \
                reduced, not just the ones below
- the current brush mask.
- 
- For the sake of speed optimization, the extent of the largest area of color \
                contained in the
- temporary device is cached such that only the colored areas are considered.
- TODO: Make this cached value dump colors that have faded nearly completely and lie \
                outside of the rectangle (dab)
- of the current iteration.
- *
-qreal KisSmudgeOp::paintAt(const KisPaintInformation& info)
-{
-    KisBrushSP brush = m_brush;
     
-    // Simple error catching
-    if (!painter()->device()) return 1.0;
-    if (!brush) return 1.0;
-    if (!brush->canPaintFor(info)) return 1.0;
-
-    // Grow the brush (this includes the mask) according to pressure or other \
                parameters
-    double scale = m_sizeOption.apply(info);
-    if ((scale * brush->width()) <= 0.01 || (scale * brush->height()) <= 0.01) \
                return 1.0;
-    setCurrentScale(scale);
-    
-    // Align a point that represents the top-left corner of the \
                brush-stroke-rendering
-    // with the mouse pointer and take into account the brush mask size
-    QPointF hotSpot = brush->hotSpot(scale, scale);
-    QPointF pt = info.pos() - hotSpot;
-
-    // Split the coordinates into integer plus fractional parts. The integer
-    //is where the dab will be positioned and the fractional part determines
-    // the sub-pixel positioning.
-    qint32 x, y;
-    qreal xFraction, yFraction;
-
-    splitCoordinate(pt.x(), &x, &xFraction);
-    splitCoordinate(pt.y(), &y, &yFraction);
-
-    KisFixedPaintDeviceSP maskDab = 0;
-
-    // Extract the brush mask (maskDab) from brush, and turn it into a transparency \
                mask (alpha8).
-    if (brush->brushType() == IMAGE || brush->brushType() == PIPE_IMAGE) {
-        // This is for bitmap brushes
-        maskDab = brush->paintDevice(painter()->device()->colorSpace(), scale, 0.0, \
                info, xFraction, yFraction);
-        maskDab->convertTo(KoColorSpaceRegistry::instance()->alpha8());
-    } else {
-        // This is for parametric brushes, those created in the Autobrush popup \
                config dialogue
-        maskDab = cachedDab();
-        brush->mask(maskDab, m_color, scale, scale, 0.0, info, xFraction, \
                yFraction);
-        maskDab->convertTo(KoColorSpaceRegistry::instance()->alpha8());
-    }
-
-    // Convenient renaming for the limits of the maskDab
-    qint32 sw = maskDab->bounds().width();
-    qint32 sh = maskDab->bounds().height();
-    
-    // Prepare the top left corner of the temporary paint device where the extracted \
                color will be drawn
-    QPoint extractionTopLeft = QPoint(ANCHOR_POINT.x() - sw / 2,
-                                      ANCHOR_POINT.y() - sh / 2);
-                                      
-    // In the block below, the opacity of the colors stored in m_tempDev
-    // is reduced in opacity. Nothing of the color present inside it is left out
-    quint8 opacity = OPACITY_OPAQUE_U8;
-    if (!m_firstRun) {
-        opacity = m_rateOption.apply(opacity, info);
-        // Without those limits, the smudge brush doesn't smudge anymore, it either \
                makes a single
-        // dropplet of color, or drags a frame indefinitely over the canvas.
-        opacity = qBound(MIXABLE_LOWER_LIMIT, opacity, MIXABLE_UPPER_LIMIT);
-                
-        // Invert the opacity value for color absorption in the next lines \
                (copyPainter)
-        opacity = OPACITY_OPAQUE_U8 - opacity;
-        m_wholeTempData |= QRect(extractionTopLeft, maskDab->bounds().size());
-    }
-    else {
-        m_firstRun = false;
-        m_wholeTempData = QRect(extractionTopLeft, maskDab->bounds().size());
+    // if the user selected the color smudge option
+    // we will mix some color into the temorary painting device (m_tempDev)
+    if(m_compositeOption.isChecked()) {
+        // this will apply the composite mode and the opacy (selected by the user)
+        // to copyPainter
+        m_compositeOption.apply(&copyPainter, OPACITY_OPAQUE_U8, info);
+        
+        // paint a rectangle with the current color (foreground color)
+        // into the temporary painting device
+        copyPainter.setFillStyle(KisPainter::FillStyleForegroundColor);
+        copyPainter.setPaintColor(painter()->paintColor());
+        copyPainter.paintRect(maskDab->bounds());
     }
-    // copyPainter will extract the piece of color (image) to be duplicated to \
                generate the smudge effect,
-    // it extracts a simple unmasked rectangle and adds it to what was extracted \
                before in this same block of code,
-    // this sometimes shows artifacts when the brush is used with stylus and high \
                spacing
-    KisPainter copyPainter(m_tempDev);
-    copyPainter.setCompositeOp(COMPOSITE_COPY);
-    copyPainter.setOpacity(opacity);
-    copyPainter.bitBlt(m_wholeTempData.x(), m_wholeTempData.y(), \
                painter()->device(),
-                       x - m_wholeTempData.x() + extractionTopLeft.x(),
-                       y - m_wholeTempData.y() + extractionTopLeft.y(),
-                       m_wholeTempData.width(), m_wholeTempData.height());
-    copyPainter.end();
     
-    // This is the line that renders the extracted colors to the screen, with \
                maskDab giving it the brush shape
-    painter()->bitBltWithFixedSelection(x, y, m_tempDev, maskDab, 0, 0, \
                extractionTopLeft.x(), extractionTopLeft.y(), sw, sh);
-    renderMirrorMask(QRect(QPoint(x,y),QSize(sw,sh)),m_tempDev,extractionTopLeft.x(), \
extractionTopLeft.y(),maskDab); +    copyPainter.end();
     
     return spacing(scale);
-}//*/
+}
diff --git a/krita/plugins/paintops/defaultpaintops/smudge/kis_smudgeop.h \
b/krita/plugins/paintops/defaultpaintops/smudge/kis_smudgeop.h index 35a5b64..5948e04 \
                100644
--- a/krita/plugins/paintops/defaultpaintops/smudge/kis_smudgeop.h
+++ b/krita/plugins/paintops/defaultpaintops/smudge/kis_smudgeop.h
@@ -49,13 +49,7 @@ public:
     qreal paintAt(const KisPaintInformation& info);
 
 private:
-    bool m_firstRun;
-    // The "temporary paint device"
-    KisPaintDeviceSP m_tempDev;
-    // The size of the rectangle encompassing the whole data in the temporary device \
                needs to be cached for speed
-    QRect m_wholeTempData;
-    KoColor m_color;
-    
+    KisPaintDeviceSP m_tempDev; // The temporary paint device
     KisPressureSizeOption m_sizeOption;
     KisPressureRateOption m_rateOption;
     KisPressureCompositeOption m_compositeOption;
diff --git a/krita/plugins/paintops/libpaintop/kis_pressure_composite_option.cpp \
b/krita/plugins/paintops/libpaintop/kis_pressure_composite_option.cpp index \
                18a9882..ca09eb6 100644
--- a/krita/plugins/paintops/libpaintop/kis_pressure_composite_option.cpp
+++ b/krita/plugins/paintops/libpaintop/kis_pressure_composite_option.cpp
@@ -30,7 +30,7 @@
 #include <KoCompositeOp.h>
 
 KisPressureCompositeOption::KisPressureCompositeOption()
-        : KisCurveOption(i18n("Color"), "Color", KisPaintOpOption::brushCategory(), \
false) +    : KisCurveOption(i18n("Color"), "Color", \
KisPaintOpOption::brushCategory(), false)  {
     setMinimumLabel(i18n("Full Color"));
     setMaximumLabel(i18n("No Color"));
@@ -53,7 +53,7 @@ void KisPressureCompositeOption::readOptionSetting(const \
KisPropertiesConfigurat  m_compositeOp = COMPOSITE_OVER;
 }
 
-QString KisPressureCompositeOption::apply(KisPainter* painter, qint8 opacity, const \
KisPaintInformation& info) const +void KisPressureCompositeOption::apply(KisPainter* \
painter, qint8 opacity, const KisPaintInformation& info) const  {
     if(!isChecked())
         return painter->compositeOp()->id();
@@ -65,9 +65,6 @@ QString KisPressureCompositeOption::apply(KisPainter* painter, \
                qint8 opacity, co
                      (qint32)(double(opacity) * computeValue(info) / \
PRESSURE_DEFAULT),  (qint32)OPACITY_OPAQUE_U8);
     
-    //qreal  opacity1 = (qreal)(painter->opacity() * computeValue(info));
-    //quint8 opacity2 = (quint8)qRound(qBound<qreal>(OPACITY_TRANSPARENT_U8, \
                opacity1, OPACITY_OPAQUE_U8));
-    
     painter->setCompositeOp(m_compositeOp);
     painter->setOpacity(opacity);
 
diff --git a/krita/plugins/paintops/libpaintop/kis_pressure_composite_option.h \
b/krita/plugins/paintops/libpaintop/kis_pressure_composite_option.h index \
                f05642a..2ba3d8b 100644
--- a/krita/plugins/paintops/libpaintop/kis_pressure_composite_option.h
+++ b/krita/plugins/paintops/libpaintop/kis_pressure_composite_option.h
@@ -35,11 +35,10 @@ public:
     KisPressureCompositeOption();
 
     /**
-     * Set the composite mode and opacity of the painter based on the pressure
-     * and the curve (if checked) and return the old composite mode
-     * of the painter.
+     * Set the composite mode and opacity of the painter based on the user selection
+     * and the pressure curve (if checked)
      */
-    QString apply(KisPainter* painter, qint8 opacity, const KisPaintInformation& \
info) const; +    void apply(KisPainter* painter, qint8 opacity, const \
KisPaintInformation& info) const;  
     void writeOptionSetting(KisPropertiesConfiguration* setting) const;
     void readOptionSetting(const KisPropertiesConfiguration* setting);
diff --git a/krita/plugins/paintops/libpaintop/kis_pressure_composite_option_widget.cpp \
b/krita/plugins/paintops/libpaintop/kis_pressure_composite_option_widget.cpp index \
                140c628..6f17544 100644
--- a/krita/plugins/paintops/libpaintop/kis_pressure_composite_option_widget.cpp
+++ b/krita/plugins/paintops/libpaintop/kis_pressure_composite_option_widget.cpp
@@ -46,6 +46,12 @@ KisPressureCompositeOptionWidget::KisPressureCompositeOptionWidget()
  m_compositeOpBox->addItem(COMPOSITE_SCREEN);
     m_compositeOpBox->addItem(COMPOSITE_ADD);
     m_compositeOpBox->addItem(COMPOSITE_SUBTRACT);
+    m_compositeOpBox->addItem(COMPOSITE_DIVIDE);
+    m_compositeOpBox->addItem(COMPOSITE_BURN);
+    m_compositeOpBox->addItem(COMPOSITE_DODGE);
+    m_compositeOpBox->addItem(COMPOSITE_COLOR);
+    m_compositeOpBox->addItem(COMPOSITE_HARD_LIGHT);
+    m_compositeOpBox->addItem(COMPOSITE_SOFT_LIGHT);
     
     m_rateSlider = new QSlider();
     m_rateSlider->setMinimum(0);
-- 
1.7.1



_______________________________________________
kimageshop mailing list
kimageshop@kde.org
https://mail.kde.org/mailman/listinfo/kimageshop


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic