summaryrefslogtreecommitdiffstats
path: root/chalk/plugins/paintops
diff options
context:
space:
mode:
authortpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2011-06-26 00:41:16 +0000
committertpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2011-06-26 00:41:16 +0000
commit698569f8428ca088f764d704034a1330517b98c0 (patch)
treebf45be6946ebbbee9cce5a5bcf838f4c952d87e6 /chalk/plugins/paintops
parent2785103a6bd4de55bd26d79e34d0fdd4b329a73a (diff)
downloadkoffice-698569f8428ca088f764d704034a1330517b98c0.tar.gz
koffice-698569f8428ca088f764d704034a1330517b98c0.zip
Finish rebranding of Krita as Chalk
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/koffice@1238363 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'chalk/plugins/paintops')
-rw-r--r--chalk/plugins/paintops/Makefile.am2
-rw-r--r--chalk/plugins/paintops/defaultpaintops/Makefile.am39
-rw-r--r--chalk/plugins/paintops/defaultpaintops/README3
-rw-r--r--chalk/plugins/paintops/defaultpaintops/airbrush.pngbin0 -> 1038 bytes
-rw-r--r--chalk/plugins/paintops/defaultpaintops/chalkdefaultpaintops.desktop93
-rw-r--r--chalk/plugins/paintops/defaultpaintops/defaultpaintops_plugin.cc70
-rw-r--r--chalk/plugins/paintops/defaultpaintops/defaultpaintops_plugin.h36
-rw-r--r--chalk/plugins/paintops/defaultpaintops/eraser.pngbin0 -> 735 bytes
-rw-r--r--chalk/plugins/paintops/defaultpaintops/kis_airbrushop.cc150
-rw-r--r--chalk/plugins/paintops/defaultpaintops/kis_airbrushop.h60
-rw-r--r--chalk/plugins/paintops/defaultpaintops/kis_brushop.cc284
-rw-r--r--chalk/plugins/paintops/defaultpaintops/kis_brushop.h113
-rw-r--r--chalk/plugins/paintops/defaultpaintops/kis_convolveop.cc58
-rw-r--r--chalk/plugins/paintops/defaultpaintops/kis_convolveop.h56
-rw-r--r--chalk/plugins/paintops/defaultpaintops/kis_dlgbrushcurvecontrol.ui271
-rw-r--r--chalk/plugins/paintops/defaultpaintops/kis_duplicateop.cc341
-rw-r--r--chalk/plugins/paintops/defaultpaintops/kis_duplicateop.h62
-rw-r--r--chalk/plugins/paintops/defaultpaintops/kis_eraseop.cc140
-rw-r--r--chalk/plugins/paintops/defaultpaintops/kis_eraseop.h56
-rw-r--r--chalk/plugins/paintops/defaultpaintops/kis_penop.cc132
-rw-r--r--chalk/plugins/paintops/defaultpaintops/kis_penop.h58
-rw-r--r--chalk/plugins/paintops/defaultpaintops/kis_smudgeop.cc328
-rw-r--r--chalk/plugins/paintops/defaultpaintops/kis_smudgeop.h118
-rw-r--r--chalk/plugins/paintops/defaultpaintops/paintbrush.pngbin0 -> 770 bytes
-rw-r--r--chalk/plugins/paintops/defaultpaintops/pencil.pngbin0 -> 794 bytes
-rw-r--r--chalk/plugins/paintops/defaultpaintops/src/README2
-rw-r--r--chalk/plugins/paintops/defaultpaintops/src/pencil_01.svg637
-rw-r--r--chalk/plugins/paintops/defaultpaintops/src/pencil_jonathan_dietrich_01.svg434
-rw-r--r--chalk/plugins/paintops/defaultpaintops/src/pennello_mauro_olivo_01.svg616
29 files changed, 4159 insertions, 0 deletions
diff --git a/chalk/plugins/paintops/Makefile.am b/chalk/plugins/paintops/Makefile.am
new file mode 100644
index 00000000..328f0162
--- /dev/null
+++ b/chalk/plugins/paintops/Makefile.am
@@ -0,0 +1,2 @@
+SUBDIRS = \
+ defaultpaintops
diff --git a/chalk/plugins/paintops/defaultpaintops/Makefile.am b/chalk/plugins/paintops/defaultpaintops/Makefile.am
new file mode 100644
index 00000000..120368c6
--- /dev/null
+++ b/chalk/plugins/paintops/defaultpaintops/Makefile.am
@@ -0,0 +1,39 @@
+chalkimagesdir = $(prefix)/share/apps/chalk/images
+
+chalkimages_DATA = \
+ airbrush.png \
+ paintbrush.png \
+ eraser.png \
+ pencil.png
+
+
+kde_services_DATA = chalkdefaultpaintops.desktop
+
+# all_includes must remain last!
+INCLUDES = -I$(srcdir)/../../../sdk \
+ -I$(srcdir)/../../../core \
+ -I$(srcdir)/../../../chalkcolor/ \
+ -I$(srcdir)/../../../ui \
+ $(KOFFICE_INCLUDES) $(KOPAINTER_INCLUDES) $(all_includes)
+
+
+chalkdefaultpaintops_la_SOURCES = \
+ defaultpaintops_plugin.cc \
+ kis_airbrushop.cc \
+ kis_brushop.cc \
+ kis_duplicateop.cc \
+ kis_eraseop.cc \
+ kis_penop.cc \
+ kis_dlgbrushcurvecontrol.ui \
+ kis_smudgeop.cc
+
+noinst_HEADERS = defaultpaintops_plugin.h kis_airbrushop.h kis_brushop.h \
+ kis_duplicateop.h kis_eraseop.h kis_penop.h kis_smudgeop.h
+
+kde_module_LTLIBRARIES = chalkdefaultpaintops.la
+
+chalkdefaultpaintops_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) $(LIB_QT) -lkdecore -lkdeui -lkjs -lkdefx -lkio -lkparts -L../../../../chalk/chalkcolor/.libs -lchalkcolor -L../../../../chalk/core/.libs -lchalkimage \
+ -L../../../../chalk/ui/.libs -lchalkui
+chalkdefaultpaintops_la_LIBADD = ../../../libchalkcommon.la $(LIB_KOPAINTER) $(LIB_KOFFICECORE)
+
+chalkdefaultpaintops_la_METASOURCES = AUTO
diff --git a/chalk/plugins/paintops/defaultpaintops/README b/chalk/plugins/paintops/defaultpaintops/README
new file mode 100644
index 00000000..47b07ce7
--- /dev/null
+++ b/chalk/plugins/paintops/defaultpaintops/README
@@ -0,0 +1,3 @@
+Default implementations of the paintop interface. These may
+some day become plugins. New paintops should be created as
+plugins.
diff --git a/chalk/plugins/paintops/defaultpaintops/airbrush.png b/chalk/plugins/paintops/defaultpaintops/airbrush.png
new file mode 100644
index 00000000..36c1d707
--- /dev/null
+++ b/chalk/plugins/paintops/defaultpaintops/airbrush.png
Binary files differ
diff --git a/chalk/plugins/paintops/defaultpaintops/chalkdefaultpaintops.desktop b/chalk/plugins/paintops/defaultpaintops/chalkdefaultpaintops.desktop
new file mode 100644
index 00000000..e1c940b2
--- /dev/null
+++ b/chalk/plugins/paintops/defaultpaintops/chalkdefaultpaintops.desktop
@@ -0,0 +1,93 @@
+[Desktop Entry]
+Name=Default Paint Operations
+Name[bg]=Операции за рисуване по подразбиране
+Name[ca]=Operacions de pintura per defecte
+Name[cy]=Gweithrediadau Paent Rhagosodol
+Name[da]=Standard maleoperationer
+Name[de]=Standard Maloperation
+Name[el]=Προκαθορισμένες λειτουργίες ζωγραφικής
+Name[eo]=Aprioraj pentrooperacioj
+Name[es]=Operaciones de pintura predefinidas
+Name[et]=Vaikimisi joonistamistoimingud
+Name[eu]=Margotze-eragiketa lehenetsiak
+Name[fa]=عملیات رنگ‌آمیزی پیش‌فرض
+Name[fi]=Oletusväritystoimenpiteet
+Name[fr]=Opérations de dessin par défaut
+Name[fy]=Standertskilderaksjes
+Name[ga]=Oibríochtaí Réamhshocraithe Péinteála
+Name[gl]=Operacións de Pintura Predefinidas
+Name[he]=פעולות הצביעה המוגדרות כברירת מחדל
+Name[hu]=Alapértelmezett festési műveletek
+Name[is]=Sjálfgefnar málunaraðgerðir
+Name[it]=Operazioni predefinite di disegno
+Name[ja]=標準の描画操作
+Name[km]=ប្រតិបត្តិការ​គូរ​លំនាំដើម
+Name[ms]=Operasi Cat Piawai
+Name[nb]=Standard maleteknikker
+Name[nds]=Standard-Maalakschonen
+Name[ne]=पूर्वनिर्धारित पेन्ट सञ्चालन
+Name[nl]=Standaardschilderoperaties
+Name[nn]=Standard måleoperasjonar
+Name[pl]=Domyślne operacje na obrazkach
+Name[pt]=Operações de Pintura Predefinidas
+Name[pt_BR]=Operações de pintura padrão
+Name[ru]=Стандартные инструменты рисования
+Name[se]=Standárda málendoaimmat
+Name[sk]=Štandardné operácie kreslenia
+Name[sl]=Privzete operacije za slikanje
+Name[sr]=Подразумеване сликарске операције
+Name[sr@Latn]=Podrazumevane slikarske operacije
+Name[sv]=Förvalda målningsåtgärder
+Name[uk]=Типові дії малювання
+Name[uz]=Andoza chizish amallari
+Name[uz@cyrillic]=Андоза чизиш амаллари
+Name[zh_CN]=默认绘图操作
+Name[zh_TW]=預設繪圖操作
+Comment=Default paint operations
+Comment[bg]=Операции за рисуване по подразбиране
+Comment[ca]=Operacions de pintura per defecte
+Comment[cy]=Gweithrediadau paent rhagosodol
+Comment[da]=Standard maleoperationer
+Comment[de]=Standard Maloperation
+Comment[el]=Προκαθορισμένες λειτουργίες ζωγραφικής
+Comment[eo]=Aprioraj pentrooperacioj
+Comment[es]=Operaciones de pintado predefinidas
+Comment[et]=Vaikimisi joonistamistoimingud
+Comment[eu]=Margotze-eragiketa lehenetsiak
+Comment[fa]=عملیات رنگ‌آمیزی پیش‌فرض
+Comment[fi]=Oletusväritystoimenpiteet
+Comment[fr]=Opérations de dessin par défaut
+Comment[fy]=Standertskilderaksjes
+Comment[ga]=Oibríochtaí réamhshocraithe péinteála
+Comment[gl]=Operacións de pintura predefinidas
+Comment[he]=פעולות הצביעה המוגדרות כברירת מחדל
+Comment[hu]=Alapértelmezett festési műveletek
+Comment[is]=Sjálfgefnar málunaraðgerðir
+Comment[it]=Operazioni predefinite di disegno
+Comment[ja]=標準の描画操作
+Comment[km]=ប្រតិបត្តិកា​គូរ​លំនាំ​ដើម​
+Comment[ms]=Operasi cat piawai
+Comment[nb]=Standard maleteknikker
+Comment[nds]=Standard-Maalakschonen
+Comment[ne]=पूर्वनिर्धारित पेन्ट सञ्चालन
+Comment[nl]=Standaardschilderoperaties
+Comment[nn]=Standard måleoperasjonar
+Comment[pl]=Domyślne operacje na obrazkach
+Comment[pt]=Operações de pintura predefinidas
+Comment[pt_BR]=Operações de pintura padrão
+Comment[ru]=Инструменты рисования по умолчанию
+Comment[se]=Standárda málendoaimmat
+Comment[sk]=Štandardné operácie kreslenia
+Comment[sl]=Privzete operacije za slikanje
+Comment[sr]=Подразумеване сликарске операције
+Comment[sr@Latn]=Podrazumevane slikarske operacije
+Comment[sv]=Förvalda målningsåtgärder
+Comment[uk]=Типові дії малювання
+Comment[uz]=Andoza chizish amallari
+Comment[uz@cyrillic]=Андоза чизиш амаллари
+Comment[zh_CN]=默认绘图操作
+Comment[zh_TW]=預設繪圖操作
+ServiceTypes=Chalk/Paintop
+Type=Service
+X-KDE-Library=chalkdefaultpaintops
+X-Chalk-Version=2
diff --git a/chalk/plugins/paintops/defaultpaintops/defaultpaintops_plugin.cc b/chalk/plugins/paintops/defaultpaintops/defaultpaintops_plugin.cc
new file mode 100644
index 00000000..5a267f57
--- /dev/null
+++ b/chalk/plugins/paintops/defaultpaintops/defaultpaintops_plugin.cc
@@ -0,0 +1,70 @@
+/*
+ * defaultpaintops_plugin.cc -- Part of Chalk
+ *
+ * Copyright (c) 2004 Boudewijn Rempt ([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 <klocale.h>
+#include <kiconloader.h>
+#include <kinstance.h>
+#include <kstandarddirs.h>
+#include <ktempfile.h>
+#include <kdebug.h>
+#include <kgenericfactory.h>
+
+#include <kis_paintop_registry.h>
+
+#include "kis_airbrushop.h"
+#include "kis_brushop.h"
+#include "kis_duplicateop.h"
+#include "kis_eraseop.h"
+#include "kis_smudgeop.h"
+#include "kis_penop.h"
+#include "kis_global.h"
+#include "kis_paintop_registry.h"
+
+#include "defaultpaintops_plugin.h"
+
+typedef KGenericFactory<DefaultPaintOpsPlugin> DefaultPaintOpsPluginFactory;
+K_EXPORT_COMPONENT_FACTORY( chalkdefaultpaintops, DefaultPaintOpsPluginFactory( "chalkcore" ) )
+
+
+DefaultPaintOpsPlugin::DefaultPaintOpsPlugin(TQObject *tqparent, const char *name, const TQStringList &)
+ : KParts::Plugin(tqparent, name)
+{
+ setInstance(DefaultPaintOpsPluginFactory::instance());
+
+ // This is not a gui plugin; only load it when the doc is created.
+ if ( tqparent->inherits("KisPaintOpRegistry") )
+ {
+ KisPaintOpRegistry * r = dynamic_cast<KisPaintOpRegistry*>(tqparent);
+ // Add hard-coded paint ops. Plugin paintops will add
+ // themselves in the plugin initialization code.
+ r->add ( new KisAirbrushOpFactory );
+ r->add ( new KisBrushOpFactory );
+ r->add ( new KisDuplicateOpFactory );
+ r->add ( new KisEraseOpFactory );
+ r->add ( new KisPenOpFactory );
+ r->add ( new KisSmudgeOpFactory );
+ }
+
+}
+
+DefaultPaintOpsPlugin::~DefaultPaintOpsPlugin()
+{
+}
+
+#include "defaultpaintops_plugin.moc"
diff --git a/chalk/plugins/paintops/defaultpaintops/defaultpaintops_plugin.h b/chalk/plugins/paintops/defaultpaintops/defaultpaintops_plugin.h
new file mode 100644
index 00000000..d7afb9d0
--- /dev/null
+++ b/chalk/plugins/paintops/defaultpaintops/defaultpaintops_plugin.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2005 Boudewijn Rempt ([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 DEFAULT_PAINTOPS_PLUGIN_H_
+#define DEFAULT_PAINTOPS_PLUGIN_H_
+
+#include <kparts/plugin.h>
+
+/**
+ * A plugin wrapper that adds the paintop factories to the paintop registry.
+ */
+class DefaultPaintOpsPlugin : public KParts::Plugin
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ DefaultPaintOpsPlugin(TQObject *tqparent, const char *name, const TQStringList &);
+ virtual ~DefaultPaintOpsPlugin();
+};
+
+#endif // DEFAULT_PAINTOPSGRAY_PLUGIN_H_
diff --git a/chalk/plugins/paintops/defaultpaintops/eraser.png b/chalk/plugins/paintops/defaultpaintops/eraser.png
new file mode 100644
index 00000000..c5461aba
--- /dev/null
+++ b/chalk/plugins/paintops/defaultpaintops/eraser.png
Binary files differ
diff --git a/chalk/plugins/paintops/defaultpaintops/kis_airbrushop.cc b/chalk/plugins/paintops/defaultpaintops/kis_airbrushop.cc
new file mode 100644
index 00000000..85bef3f6
--- /dev/null
+++ b/chalk/plugins/paintops/defaultpaintops/kis_airbrushop.cc
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2002 Patrick Julien <[email protected]>
+ * Copyright (c) 2004 Boudewijn Rempt <[email protected]>
+ * Copyright (c) 2004 Clarence Dang <[email protected]>
+ * Copyright (c) 2004 Adrian Page <[email protected]>
+ * Copyright (c) 2004 Cyrille Berger <[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 <tqrect.h>
+
+#include <kdebug.h>
+
+#include "kis_vec.h"
+#include "kis_brush.h"
+#include "kis_global.h"
+#include "kis_paint_device.h"
+#include "kis_painter.h"
+#include "kis_types.h"
+#include "kis_paintop.h"
+#include "kis_layer.h"
+#include "kis_selection.h"
+#include "kis_airbrushop.h"
+
+KisPaintOp * KisAirbrushOpFactory::createOp(const KisPaintOpSettings */*settings*/, KisPainter * painter)
+{
+ KisPaintOp * op = new KisAirbrushOp(painter);
+ Q_CHECK_PTR(op);
+ return op;
+}
+
+
+KisAirbrushOp::KisAirbrushOp(KisPainter * painter)
+ : super(painter)
+{
+}
+
+KisAirbrushOp::~KisAirbrushOp()
+{
+}
+
+void KisAirbrushOp::paintAt(const KisPoint &pos, const KisPaintInformation& info)
+{
+// See: http://www.sysf.physto.se/~klere/airbrush/ for information
+// about _real_ airbrushes.
+//
+// Most graphics apps -- especially the simple ones like Kolourpaint
+// and the previous version of this routine in Chalk took a brush
+// tqshape -- often a simple ellipse -- and filled that tqshape with a
+// random 'spray' of single pixels.
+//
+// Other, more advanced graphics apps, like the Gimp or Photoshop,
+// take the brush tqshape and paint just as with the brush paint op,
+// only making the initial dab more transparent, and perhaps adding
+// extra transparence near the edges. Then, using a timer, when the
+// cursor stays in place, dab upon dab is positioned in the same
+// place, which makes the result less and less transparent.
+//
+// What I want to do here is create an airbrush that approaches a real
+// one. It won't use brush tqshapes, instead going for the old-fashioned
+// circle. Depending upon pressure, both the size of the dab and the
+// rate of paint deposition is determined. The edges of the dab are
+// more transparent than the center, with perhaps even some fully
+// transparent pixels between the near-transparent pixels.
+//
+// By pressing some to-be-determined key at the same time as pressing
+// mouse-down, one edge of the dab is made straight, to simulate
+// working with a shield.
+//
+// Tilt may be used to make the gradients more realistic, but I don't
+// have a tablet that supports tilt.
+//
+// Anyway, it's exactly twenty years ago that I have held a real
+// airbrush, for the first and up to now the last time...
+//
+
+ if (!m_painter) return;
+
+ KisPaintDeviceSP device = m_painter->device();
+
+ // For now: use the current brush tqshape -- it beats calculating
+ // ellipes and cones, and it shows the working of the timer.
+ if (!device) return;
+
+ KisBrush * brush = m_painter->brush();
+ if (! brush->canPaintFor(info) )
+ return;
+ KisPaintDeviceSP dab = m_painter->dab();
+
+ KisPoint hotSpot = brush->hotSpot(info);
+ KisPoint pt = pos - hotSpot;
+
+ TQ_INT32 x;
+ double xFraction;
+ TQ_INT32 y;
+ double yFraction;
+
+ splitCoordinate(pt.x(), &x, &xFraction);
+ splitCoordinate(pt.y(), &y, &yFraction);
+
+ if (brush->brushType() == IMAGE || brush->brushType() == PIPE_IMAGE) {
+ dab = brush->image(device->colorSpace(), info, xFraction, yFraction);
+ }
+ else {
+ KisAlphaMaskSP tqmask = brush->tqmask(info, xFraction, yFraction);
+ dab = computeDab(tqmask);
+ }
+
+ m_painter->setDab(dab); // Cache dab for future paints in the painter.
+ m_painter->setPressure(info.pressure); // Cache pressure in the current painter.
+
+ TQRect dabRect = TQRect(0, 0, brush->tqmaskWidth(info), brush->tqmaskHeight(info));
+ TQRect dstRect = TQRect(x, y, dabRect.width(), dabRect.height());
+
+ KisImage * image = device->image();
+
+ if (image != 0) {
+ dstRect &= image->bounds();
+ }
+
+ if (dstRect.isNull() || dstRect.isEmpty() || !dstRect.isValid()) return;
+
+ TQ_INT32 sx = dstRect.x() - x;
+ TQ_INT32 sy = dstRect.y() - y;
+ TQ_INT32 sw = dstRect.width();
+ TQ_INT32 sh = dstRect.height();
+
+ if (m_source->hasSelection()) {
+ m_painter->bltSelection(dstRect.x(), dstRect.y(), m_painter->compositeOp(), dab.data(),
+ m_source->selection(), m_painter->opacity(), sx, sy, sw, sh);
+ }
+ else {
+ m_painter->bitBlt(dstRect.x(), dstRect.y(), m_painter->compositeOp(), dab.data(), m_painter->opacity(), sx, sy, sw, sh);
+ }
+
+ m_painter->addDirtyRect(dstRect);
+}
diff --git a/chalk/plugins/paintops/defaultpaintops/kis_airbrushop.h b/chalk/plugins/paintops/defaultpaintops/kis_airbrushop.h
new file mode 100644
index 00000000..805664d7
--- /dev/null
+++ b/chalk/plugins/paintops/defaultpaintops/kis_airbrushop.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2002 Patrick Julien <[email protected]>
+ * Copyright (c) 2004 Boudewijn Rempt <[email protected]>
+ * Copyright (c) 2004 Clarence Dang <[email protected]>
+ * Copyright (c) 2004 Adrian Page <[email protected]>
+ * Copyright (c) 2004 Cyrille Berger <[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_AIRBRUSHOP_H_
+#define KIS_AIRBRUSHOP_H_
+
+#include "kis_paintop.h"
+
+class KisPoint;
+class KisPainter;
+
+class KisAirbrushOpFactory : public KisPaintOpFactory {
+
+public:
+ KisAirbrushOpFactory() {}
+ virtual ~KisAirbrushOpFactory() {}
+
+ virtual KisPaintOp * createOp(const KisPaintOpSettings *settings, KisPainter * painter);
+ virtual KisID id() { return KisID("airbrush", i18n("Pixel Airbrush")); }
+ virtual TQString pixmap() { return "airbrush.png"; }
+};
+
+
+
+class KisAirbrushOp : public KisPaintOp {
+
+ typedef KisPaintOp super;
+
+public:
+
+ KisAirbrushOp(KisPainter * painter);
+ virtual ~KisAirbrushOp();
+
+ // We want to spray even when the pointer doesn't move.
+ virtual bool incremental() { return true; }
+
+ void paintAt(const KisPoint &pos, const KisPaintInformation& info);
+
+};
+
+#endif // KIS_AIRBRUSHOP_H_
diff --git a/chalk/plugins/paintops/defaultpaintops/kis_brushop.cc b/chalk/plugins/paintops/defaultpaintops/kis_brushop.cc
new file mode 100644
index 00000000..360fa66e
--- /dev/null
+++ b/chalk/plugins/paintops/defaultpaintops/kis_brushop.cc
@@ -0,0 +1,284 @@
+/*
+ * Copyright (c) 2002 Patrick Julien <[email protected]>
+ * Copyright (c) 2004 Boudewijn Rempt <[email protected]>
+ * Copyright (c) 2004 Clarence Dang <[email protected]>
+ * Copyright (c) 2004 Adrian Page <[email protected]>
+ * Copyright (c) 2004 Cyrille Berger <[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 <string.h>
+
+#include <tqrect.h>
+#include <tqwidget.h>
+#include <tqlayout.h>
+#include <tqlabel.h>
+#include <tqcheckbox.h>
+#include <tqtoolbutton.h>
+
+#include <kdebug.h>
+
+#include "kcurve.h"
+#include "kis_brush.h"
+#include "kis_global.h"
+#include "kis_paint_device.h"
+#include "kis_layer.h"
+#include "kis_painter.h"
+#include "kis_types.h"
+#include "kis_paintop.h"
+#include "kis_input_device.h"
+#include "kis_selection.h"
+#include "kis_brushop.h"
+
+#include "kis_dlgbrushcurvecontrol.h"
+
+KisPaintOp * KisBrushOpFactory::createOp(const KisPaintOpSettings *settings, KisPainter * painter)
+{
+ const KisBrushOpSettings *brushopSettings = dynamic_cast<const KisBrushOpSettings *>(settings);
+ Q_ASSERT(settings == 0 || brushopSettings != 0);
+
+ KisPaintOp * op = new KisBrushOp(brushopSettings, painter);
+ Q_CHECK_PTR(op);
+ return op;
+}
+
+KisBrushOpSettings::KisBrushOpSettings(TQWidget *tqparent)
+ : super(tqparent)
+{
+ m_optionsWidget = new TQWidget(tqparent, "brush option widget");
+ TQHBoxLayout * l = new TQHBoxLayout(m_optionsWidget);
+ l->setAutoAdd(true);
+ m_pressureVariation = new TQLabel(i18n("Pressure variation: "), m_optionsWidget);
+ m_size = new TQCheckBox(i18n("Size"), m_optionsWidget);
+ m_size->setChecked(true);
+ m_opacity = new TQCheckBox(i18n("Opacity"), m_optionsWidget);
+ m_darken = new TQCheckBox(i18n("Darken"), m_optionsWidget);
+ m_curveControl = new WdgBrushCurveControl(m_optionsWidget);
+ TQToolButton* moreButton = new TQToolButton(TQt::UpArrow, m_optionsWidget);
+ moreButton->tqsetSizePolicy(TQSizePolicy::Expanding, TQSizePolicy::Expanding);
+ moreButton->setMinimumSize(TQSize(24,24)); // Bah, I had hoped the above line would make this unneeded
+ connect(moreButton, TQT_SIGNAL(clicked()), this, TQT_SLOT(slotCustomCurves()));
+
+ m_customSize = false;
+ m_customOpacity = false;
+ m_customDarken = false;
+ // the curves will get filled in when the slot gets accepted
+}
+
+void KisBrushOpSettings::slotCustomCurves() {
+ if (m_curveControl->exec() == TQDialog::Accepted) {
+ m_customSize = m_curveControl->sizeCheckbox->isChecked();
+ m_customOpacity = m_curveControl->opacityCheckbox->isChecked();
+ m_customDarken = m_curveControl->darkenCheckbox->isChecked();
+
+ if (m_customSize) {
+ transferCurve(m_curveControl->sizeCurve, m_sizeCurve);
+ }
+ if (m_customOpacity) {
+ transferCurve(m_curveControl->opacityCurve, m_opacityCurve);
+ }
+ if (m_customDarken) {
+ transferCurve(m_curveControl->darkenCurve, m_darkenCurve);
+ }
+ }
+}
+
+void KisBrushOpSettings::transferCurve(KCurve* curve, double* target) {
+ double value;
+ for (int i = 0; i < 256; i++) {
+ value = curve->getCurveValue( i / 255.0);
+ if (value < PRESSURE_MIN)
+ target[i] = PRESSURE_MIN;
+ else if (value > PRESSURE_MAX)
+ target[i] = PRESSURE_MAX;
+ else
+ target[i] = value;
+ }
+}
+
+
+bool KisBrushOpSettings::varySize() const
+{
+ return m_size->isChecked();
+}
+
+bool KisBrushOpSettings::varyOpacity() const
+{
+ return m_opacity->isChecked();
+}
+
+bool KisBrushOpSettings::varyDarken() const
+{
+ return m_darken->isChecked();
+}
+
+KisPaintOpSettings* KisBrushOpFactory::settings(TQWidget * tqparent, const KisInputDevice& inputDevice)
+{
+ if (inputDevice == KisInputDevice::mouse()) {
+ // No options for mouse, only tablet devices
+ return 0;
+ } else {
+ return new KisBrushOpSettings(tqparent);
+ }
+}
+
+KisBrushOp::KisBrushOp(const KisBrushOpSettings *settings, KisPainter *painter)
+ : super(painter)
+ , m_pressureSize(true)
+ , m_pressureOpacity(false)
+ , m_pressureDarken(false)
+ , m_customSize(false)
+ , m_customOpacity(false)
+ , m_customDarken(false)
+{
+ if (settings != 0) {
+ m_pressureSize = settings->varySize();
+ painter->setVaryBrushSpacingWithPressureWhenDrawingALine( m_pressureSize );
+
+ m_pressureOpacity = settings->varyOpacity();
+ m_pressureDarken = settings->varyDarken();
+ m_customSize = settings->customSize();
+ m_customOpacity = settings->customOpacity();
+ m_customDarken = settings->customDarken();
+ if (m_customSize) {
+ memcpy(m_sizeCurve, settings->sizeCurve(), 256 * sizeof(double));
+ }
+ if (m_customOpacity) {
+ memcpy(m_opacityCurve, settings->opacityCurve(), 256 * sizeof(double));
+ }
+ if (m_customDarken) {
+ memcpy(m_darkenCurve, settings->darkenCurve(), 256 * sizeof(double));
+ }
+ }
+}
+
+KisBrushOp::~KisBrushOp()
+{
+ m_painter->setVaryBrushSpacingWithPressureWhenDrawingALine( true );
+}
+
+void KisBrushOp::paintAt(const KisPoint &pos, const KisPaintInformation& info)
+{
+ KisPaintInformation adjustedInfo(info);
+ if (!m_pressureSize)
+ adjustedInfo.pressure = PRESSURE_DEFAULT;
+ else if (m_customSize)
+ adjustedInfo.pressure = scaleToCurve(adjustedInfo.pressure, m_sizeCurve);
+
+ // Painting should be implemented according to the following algorithm:
+ // retrieve brush
+ // if brush == tqmask
+ // retrieve tqmask
+ // else if brush == image
+ // retrieve image
+ // subsample (tqmask | image) for position -- pos should be double!
+ // apply filters to tqmask (colour | gradient | pattern | etc.
+ // composite filtered tqmask into temporary layer
+ // composite temporary layer into target layer
+ // @see: doc/brush.txt
+
+ if (!m_painter->device()) return;
+
+ KisBrush *brush = m_painter->brush();
+
+ Q_ASSERT(brush);
+ if (!brush) return;
+ if (! brush->canPaintFor(adjustedInfo) )
+ return;
+
+ KisPaintDeviceSP device = m_painter->device();
+
+ KisPoint hotSpot = brush->hotSpot(adjustedInfo);
+ KisPoint pt = 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.
+ TQ_INT32 x;
+ double xFraction;
+ TQ_INT32 y;
+ double yFraction;
+
+ splitCoordinate(pt.x(), &x, &xFraction);
+ splitCoordinate(pt.y(), &y, &yFraction);
+
+ KisPaintDeviceSP dab = 0;
+
+ TQ_UINT8 origOpacity = m_painter->opacity();
+ KisColor origColor = m_painter->paintColor();
+
+ if (m_pressureOpacity) {
+ if (!m_customOpacity)
+ m_painter->setOpacity((TQ_INT8)(origOpacity * info.pressure));
+ else
+ m_painter->setOpacity((TQ_INT8)(origOpacity * scaleToCurve(info.pressure, m_opacityCurve)));
+ }
+
+ if (m_pressureDarken) {
+ KisColor darkened = origColor;
+ // Darken docs aren't really clear about what exactly the amount param can have as value...
+ TQ_UINT32 darkenAmount;
+ if (!m_customDarken)
+ darkenAmount = (TQ_INT32)(255 - 75 * info.pressure);
+ else
+ darkenAmount = (TQ_INT32)(255 - 75 * scaleToCurve(info.pressure, m_darkenCurve));
+
+ darkened.colorSpace()->darken(origColor.data(), darkened.data(),
+ darkenAmount, false, 0.0, 1);
+ m_painter->setPaintColor(darkened);
+ }
+
+ if (brush->brushType() == IMAGE || brush->brushType() == PIPE_IMAGE) {
+ dab = brush->image(device->colorSpace(), adjustedInfo, xFraction, yFraction);
+ }
+ else {
+ KisAlphaMaskSP tqmask = brush->tqmask(adjustedInfo, xFraction, yFraction);
+ dab = computeDab(tqmask);
+ }
+
+ m_painter->setPressure(adjustedInfo.pressure);
+
+ TQRect dabRect = TQRect(0, 0, brush->tqmaskWidth(adjustedInfo),
+ brush->tqmaskHeight(adjustedInfo));
+ TQRect dstRect = TQRect(x, y, dabRect.width(), dabRect.height());
+
+ KisImage * image = device->image();
+
+ if (image != 0) {
+ dstRect &= image->bounds();
+ }
+
+ if (dstRect.isNull() || dstRect.isEmpty() || !dstRect.isValid()) return;
+
+ TQ_INT32 sx = dstRect.x() - x;
+ TQ_INT32 sy = dstRect.y() - y;
+ TQ_INT32 sw = dstRect.width();
+ TQ_INT32 sh = dstRect.height();
+
+ if (m_source->hasSelection()) {
+ m_painter->bltSelection(dstRect.x(), dstRect.y(), m_painter->compositeOp(), dab.data(),
+ m_source->selection(), m_painter->opacity(), sx, sy, sw, sh);
+ }
+ else {
+ m_painter->bitBlt(dstRect.x(), dstRect.y(), m_painter->compositeOp(), dab.data(), m_painter->opacity(), sx, sy, sw, sh);
+ }
+ m_painter->addDirtyRect(dstRect);
+
+ m_painter->setOpacity(origOpacity);
+ m_painter->setPaintColor(origColor);
+}
+
+#include "kis_brushop.moc"
diff --git a/chalk/plugins/paintops/defaultpaintops/kis_brushop.h b/chalk/plugins/paintops/defaultpaintops/kis_brushop.h
new file mode 100644
index 00000000..6475b3d7
--- /dev/null
+++ b/chalk/plugins/paintops/defaultpaintops/kis_brushop.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2002 Patrick Julien <[email protected]>
+ * Copyright (c) 2004 Boudewijn Rempt <[email protected]>
+ * Copyright (c) 2004 Clarence Dang <[email protected]>
+ * Copyright (c) 2004 Adrian Page <[email protected]>
+ * Copyright (c) 2004 Cyrille Berger <[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_BRUSHOP_H_
+#define KIS_BRUSHOP_H_
+
+#include "kis_paintop.h"
+
+class TQWidget;
+class TQCheckBox;
+class TQLabel;
+class KisPoint;
+class KisPainter;
+class KCurve;
+class WdgBrushCurveControl;
+
+class KisBrushOpFactory : public KisPaintOpFactory {
+
+public:
+ KisBrushOpFactory() {}
+ virtual ~KisBrushOpFactory() {}
+
+ virtual KisPaintOp * createOp(const KisPaintOpSettings *settings, KisPainter * painter);
+ virtual KisID id() { return KisID("paintbrush", i18n("Pixel Brush")); }
+ virtual TQString pixmap() { return "paintbrush.png"; }
+ virtual KisPaintOpSettings *settings(TQWidget * tqparent, const KisInputDevice& inputDevice);
+};
+
+class KisBrushOpSettings : public TQObject, public KisPaintOpSettings {
+ Q_OBJECT
+ TQ_OBJECT
+ typedef KisPaintOpSettings super;
+public:
+ KisBrushOpSettings(TQWidget *tqparent);
+
+ bool varySize() const;
+ bool varyOpacity() const;
+ bool varyDarken() const;
+
+ bool customSize() const { return m_customSize; }
+ bool customOpacity() const { return m_customOpacity; }
+ bool customDarken() const { return m_customDarken; }
+ const double* sizeCurve() const { return m_sizeCurve; }
+ const double* opacityCurve() const { return m_opacityCurve; }
+ const double* darkenCurve() const { return m_darkenCurve; }
+
+ virtual TQWidget *widget() const { return m_optionsWidget; }
+private slots:
+ void slotCustomCurves();
+private:
+ void transferCurve(KCurve* curve, double* target);
+ TQWidget *m_optionsWidget;
+ TQLabel * m_pressureVariation;
+ TQCheckBox * m_size;
+ TQCheckBox * m_opacity;
+ TQCheckBox * m_darken;
+ WdgBrushCurveControl* m_curveControl;
+
+ bool m_customSize;
+ bool m_customOpacity;
+ bool m_customDarken;
+ double m_sizeCurve[256];
+ double m_opacityCurve[256];
+ double m_darkenCurve[256];
+};
+
+class KisBrushOp : public KisPaintOp {
+
+ typedef KisPaintOp super;
+
+public:
+
+ KisBrushOp(const KisBrushOpSettings *settings, KisPainter * painter);
+ virtual ~KisBrushOp();
+
+ void paintAt(const KisPoint &pos, const KisPaintInformation& info);
+
+private:
+ inline double scaleToCurve(double pressure, double* curve) const {
+ int offset = CLAMP(int(255.0 * pressure), 0, 255);
+ return curve[offset];
+ }
+ bool m_pressureSize;
+ bool m_pressureOpacity;
+ bool m_pressureDarken;
+ bool m_customSize;
+ bool m_customOpacity;
+ bool m_customDarken;
+ double m_sizeCurve[256];
+ double m_opacityCurve[256];
+ double m_darkenCurve[256];
+};
+
+#endif // KIS_BRUSHOP_H_
diff --git a/chalk/plugins/paintops/defaultpaintops/kis_convolveop.cc b/chalk/plugins/paintops/defaultpaintops/kis_convolveop.cc
new file mode 100644
index 00000000..72bf9e66
--- /dev/null
+++ b/chalk/plugins/paintops/defaultpaintops/kis_convolveop.cc
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2002 Patrick Julien <[email protected]>
+ * Copyright (c) 2004 Boudewijn Rempt <[email protected]>
+ * Copyright (c) 2004 Clarence Dang <[email protected]>
+ * Copyright (c) 2004 Adrian Page <[email protected]>
+ * Copyright (c) 2004 Cyrille Berger <[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 <tqrect.h>
+
+#include <kdebug.h>
+
+#include "kis_brush.h"
+#include "kis_global.h"
+#include "kis_paint_device.h"
+#include "kis_painter.h"
+#include "kis_layer.h"
+#include "kis_types.h"
+#include "kis_paintop.h"
+#include "kis_selection.h"
+#include "kis_convolveop.h"
+
+
+KisPaintOp * KisConvolveOpFactory::createOp(const KisPaintOpSettings */*settings*/, KisPainter * painter)
+{
+ KisPaintOp * op = new KisConvolveOp(painter);
+ Q_CHECK_PTR(op);
+ return op;
+}
+
+
+KisConvolveOp::KisConvolveOp(KisPainter * painter)
+ : super(painter)
+{
+}
+
+KisConvolveOp::~KisConvolveOp()
+{
+}
+
+void KisConvolveOp::paintAt(const KisPoint &/*pos*/, const KisPaintInformation& /*info*/)
+{
+ // XXX: use convolve painter here.
+
+}
diff --git a/chalk/plugins/paintops/defaultpaintops/kis_convolveop.h b/chalk/plugins/paintops/defaultpaintops/kis_convolveop.h
new file mode 100644
index 00000000..d5dc3764
--- /dev/null
+++ b/chalk/plugins/paintops/defaultpaintops/kis_convolveop.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2002 Patrick Julien <[email protected]>
+ * Copyright (c) 2004 Boudewijn Rempt <[email protected]>
+ * Copyright (c) 2004 Clarence Dang <[email protected]>
+ * Copyright (c) 2004 Adrian Page <[email protected]>
+ * Copyright (c) 2004 Cyrille Berger <[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_CONVOLVEOP_H_
+#define KIS_CONVOLVEOP_H_
+
+#include "kis_paintop.h"
+
+class KisPoint;
+class KisPainter;
+
+
+class KisConvolveOpFactory : public KisPaintOpFactory {
+
+public:
+ KisConvolveOpFactory() {}
+ virtual ~KisConvolveOpFactory() {}
+
+ virtual KisPaintOp * createOp(const KisPaintOpSettings *settings, KisPainter * painter);
+ virtual KisID id() { return KisID("convolve", i18n("Convolve")); }
+};
+
+
+class KisConvolveOp : public KisPaintOp {
+
+ typedef KisPaintOp super;
+
+public:
+
+ KisConvolveOp(KisPainter * painter);
+ virtual ~KisConvolveOp();
+
+ void paintAt(const KisPoint &pos, const KisPaintInformation& info);
+
+};
+
+#endif // KIS_CONVOLVEOP_H_
diff --git a/chalk/plugins/paintops/defaultpaintops/kis_dlgbrushcurvecontrol.ui b/chalk/plugins/paintops/defaultpaintops/kis_dlgbrushcurvecontrol.ui
new file mode 100644
index 00000000..f6021ecc
--- /dev/null
+++ b/chalk/plugins/paintops/defaultpaintops/kis_dlgbrushcurvecontrol.ui
@@ -0,0 +1,271 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>WdgBrushCurveControl</class>
+<widget class="TQDialog">
+ <property name="name">
+ <cstring>WdgBrushCurveControl</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>477</width>
+ <height>430</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Custom Curves</string>
+ </property>
+ <property name="sizeGripEnabled">
+ <bool>true</bool>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQTabWidget">
+ <property name="name">
+ <cstring>tabWidget</cstring>
+ </property>
+ <widget class="TQWidget">
+ <property name="name">
+ <cstring>Widget8</cstring>
+ </property>
+ <attribute name="title">
+ <string>Size Curve</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLayoutWidget" row="0" column="0">
+ <property name="name">
+ <cstring>tqlayout4</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQCheckBox">
+ <property name="name">
+ <cstring>sizeCheckbox</cstring>
+ </property>
+ <property name="text">
+ <string>Use custom curve</string>
+ </property>
+ </widget>
+ <widget class="KCurve">
+ <property name="name">
+ <cstring>sizeCurve</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>7</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="TQWidget">
+ <property name="name">
+ <cstring>Widget9</cstring>
+ </property>
+ <attribute name="title">
+ <string>Opacity Curve</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLayoutWidget" row="0" column="0">
+ <property name="name">
+ <cstring>tqlayout3</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQCheckBox">
+ <property name="name">
+ <cstring>opacityCheckbox</cstring>
+ </property>
+ <property name="text">
+ <string>Use custom curve</string>
+ </property>
+ </widget>
+ <widget class="KCurve">
+ <property name="name">
+ <cstring>opacityCurve</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>7</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="TQWidget">
+ <property name="name">
+ <cstring>TabPage</cstring>
+ </property>
+ <attribute name="title">
+ <string>Darken Curve</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLayoutWidget" row="0" column="0">
+ <property name="name">
+ <cstring>tqlayout5</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQCheckBox">
+ <property name="name">
+ <cstring>darkenCheckbox</cstring>
+ </property>
+ <property name="text">
+ <string>Use custom curve</string>
+ </property>
+ </widget>
+ <widget class="KCurve">
+ <property name="name">
+ <cstring>darkenCurve</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>7</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ </grid>
+ </widget>
+ </widget>
+ <widget class="TQLayoutWidget">
+ <property name="name">
+ <cstring>Layout1</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <spacer>
+ <property name="name">
+ <cstring>Horizontal Spacing2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="tqsizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="TQPushButton">
+ <property name="name">
+ <cstring>buttonOk</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;OK</string>
+ </property>
+ <property name="accel">
+ <string></string>
+ </property>
+ <property name="autoDefault">
+ <bool>true</bool>
+ </property>
+ <property name="default">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="TQPushButton">
+ <property name="name">
+ <cstring>buttonCancel</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Cancel</string>
+ </property>
+ <property name="accel">
+ <string></string>
+ </property>
+ <property name="autoDefault">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+</widget>
+<customwidgets>
+ <customwidget>
+ <class>KCurve</class>
+ <header location="local">kcurve.h</header>
+ <sizehint>
+ <width>-1</width>
+ <height>-1</height>
+ </sizehint>
+ <container>0</container>
+ <sizepolicy>
+ <hordata>5</hordata>
+ <verdata>5</verdata>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ <pixmap>image0</pixmap>
+ </customwidget>
+</customwidgets>
+<images>
+ <image name="image0">
+ <data format="PNG" length="1002">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b000003b149444154388dad945f4c5b551cc73fe7dc4b7b4bcba0762d45c43114323599ee6192609c51d883892ce083f1718b3ebb185f8dc91e972cf39d2d2a2f1af664b6f1e0fe3863a0718969700eb0c52142da0242a1bd6d696f7bcff101585203ceb8fd9ece39f99dcff9fe7edf939f88c562ec465f5f9fe609442c161362173c3e3eae7b7a7ac8e7f36432196cdbfe4f907c3e4f2291201e8fe338cec3737357e9e8e828aded1e229d650e1f2d51754b082110124c13a4dc5ea341eb9dc284c0558a853f3ce8cb0677ef500fde7d39d2596679e326597b8e9abb85d7a770ab16ab6983ec5a05b487a70e36f0f4e10afe408d6a558310980108478dba4a1e8233990c5d474b64ed39aa3a8fe5f3317fbf81dbd70bccfeb205947632fd74f6589c1c6ea2f70d03a58ba0c1f2c9bdc1b66de3b8256a6e11cbe7e3ee1d181b590124fe2693aeee08d223c82c3a2c24b7b874bec8f26288774f7bd054504aef0dde6e99c0eb83f9fb266323cb80a27fb0958141836044605a2ee5523393371cc646fee2da37195aa35d0c0c5b4859ac03d7e91712dcaac5adab3650a3ff9d08ef7dd8404bb48869e5d958b5b87dadc4c9a1464e9f0d0326df7ebd86bd2e310cb1bf62d384d59441f2d70a070e1c60e09489929b988681bdd9cc97170bcc4c65595f71f8e0e3301337fc24a7732467831875a47f289652b0be5e4151e6d07316c1b0c0340d8ab92023e76d66a6b2840e36d2fb7a13fee632475e6edc367ea98a90fb98b7dd6310ca0328a44761582e1bab41befabcc0ec940d28bc5e93b68e064cab84e1d9beaeb48934eac1f53b01c1b000fca496aa54b61a99fcde61662a4b4b4b23d1680be9d426173e4df3602a48ea411989a4fd590f52a8fd156b05ed9d350e3defe3cfdf4b4c7ce770ea7d3fb9f520afbe1620daeee5c26735d20b9b9cfb6811a754a439e4e5c5639a4caa1e5caf586bfc0197b78702005cb9b4cae4cd3267ce8638fe964bd72b393e39d74928d242617303a756a37f284447770dcdbffc6384a05a85de1306e9a52057c7527c7131c3c42d3f475eb2303c82d4fc3276d6811db37efeb148723082d9b08f79f97c1e5729109a9a28307cc622d2d6cdf52b2b24efe548dedb00142009862cfa879ee1a71f6cec928353511472fbf4389148b0b0e0c108081412458dfe21c9f11351e67e7358595468246d1d1e5e38a6e9e851bc39d84ab502a669331dafec0d8ec7e3e8cb06e1a881d727d1ae40180a434a8c9db129a54126ad48a7358c2b4c5352c8c374bcccdab2bb37d8719cba79fab8211f9df218e0582c261e95f8bfc04f1a1e8bc5c4dfe0a190172af6a9690000000049454e44ae426082</data>
+ </image>
+</images>
+<connections>
+ <connection>
+ <sender>buttonOk</sender>
+ <signal>clicked()</signal>
+ <receiver>WdgBrushCurveControl</receiver>
+ <slot>accept()</slot>
+ </connection>
+ <connection>
+ <sender>buttonCancel</sender>
+ <signal>clicked()</signal>
+ <receiver>WdgBrushCurveControl</receiver>
+ <slot>reject()</slot>
+ </connection>
+</connections>
+<tqlayoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>kcurve.h</includehint>
+ <includehint>kcurve.h</includehint>
+ <includehint>kcurve.h</includehint>
+</includehints>
+</UI>
diff --git a/chalk/plugins/paintops/defaultpaintops/kis_duplicateop.cc b/chalk/plugins/paintops/defaultpaintops/kis_duplicateop.cc
new file mode 100644
index 00000000..139ed51d
--- /dev/null
+++ b/chalk/plugins/paintops/defaultpaintops/kis_duplicateop.cc
@@ -0,0 +1,341 @@
+/*
+ * Copyright (c) 2002 Patrick Julien <[email protected]>
+ * Copyright (c) 2004 Boudewijn Rempt <[email protected]>
+ * Copyright (c) 2004 Clarence Dang <[email protected]>
+ * Copyright (c) 2004 Adrian Page <[email protected]>
+ * Copyright (c) 2004-2006 Cyrille Berger <[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_duplicateop.h"
+
+#include <tqrect.h>
+
+#include <kdebug.h>
+
+#include "kis_brush.h"
+#include "kis_global.h"
+#include "kis_paint_device.h"
+#include "kis_layer.h"
+#include "kis_painter.h"
+#include "kis_types.h"
+#include "kis_meta_registry.h"
+#include "kis_colorspace_factory_registry.h"
+#include "kis_paintop.h"
+#include "kis_iterators_pixel.h"
+#include "kis_selection.h"
+#include "kis_perspective_grid.h"
+#include "kis_random_sub_accessor.h"
+
+KisPaintOp * KisDuplicateOpFactory::createOp(const KisPaintOpSettings */*settings*/, KisPainter * painter)
+{
+ KisPaintOp * op = new KisDuplicateOp(painter);
+ Q_CHECK_PTR(op);
+ return op;
+}
+
+
+KisDuplicateOp::KisDuplicateOp(KisPainter * painter)
+ : super(painter)
+ , m_target(0)
+ , m_srcdev(0)
+{
+}
+
+KisDuplicateOp::~KisDuplicateOp()
+{
+}
+
+double KisDuplicateOp::minimizeEnergy(const double* m, double* sol, int w, int h)
+{
+ int rowstride = 3*w;
+ double err = 0;
+ memcpy(sol, m, 3* sizeof(double) * w);
+ m+=rowstride;
+ sol+=rowstride;
+ for ( int i = 1; i < h - 1; i++)
+ {
+ memcpy(sol, m, 3* sizeof(double));
+ m+=3; sol+=3;
+ for ( int j = 3; j < rowstride-3; j++)
+ {
+ double tmp = *sol;
+ *sol = ( ( *(m - 3 ) + *(m + 3) + *(m - rowstride ) + *(m + rowstride )) + 2 * *m ) /6;
+ double diff = *sol - tmp;
+ err += diff*diff;
+ m ++; sol ++;
+ }
+ memcpy(sol, m, 3* sizeof(double));
+ m+=3; sol+=3;
+}
+ memcpy(sol, m, 3* sizeof(double) * w);
+ return err;
+}
+
+
+void KisDuplicateOp::paintAt(const KisPoint &pos, const KisPaintInformation& info)
+{
+ if (!m_painter) return;
+
+ bool heal = m_painter->duplicateHealing();
+// int healradius = m_painter->duplicateHealingRadius();
+
+ KisPaintDeviceSP device = m_painter->device();
+ if (m_source) device = m_source;
+ if (!device) return;
+
+ KisBrush * brush = m_painter->brush();
+ if (!brush) return;
+ if (! brush->canPaintFor(info) )
+ return;
+
+ KisPoint hotSpot = brush->hotSpot(info);
+ KisPoint pt = 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.
+ TQ_INT32 x;
+ double xFraction;
+ TQ_INT32 y;
+ double yFraction;
+
+ splitCoordinate(pt.x(), &x, &xFraction);
+ splitCoordinate(pt.y(), &y, &yFraction);
+ xFraction = yFraction = 0.0;
+
+ KisPaintDeviceSP dab = 0;
+
+ if (brush->brushType() == IMAGE ||
+ brush->brushType() == PIPE_IMAGE) {
+ dab = brush->image(device->colorSpace(), info, xFraction, yFraction);
+ dab->convertTo(KisMetaRegistry::instance()->csRegistry()->getAlpha8());
+ }
+ else {
+ KisAlphaMaskSP tqmask = brush->tqmask(info, xFraction, yFraction);
+ dab = computeDab(tqmask, KisMetaRegistry::instance()->csRegistry()->getAlpha8());
+ }
+
+ m_painter->setPressure(info.pressure);
+
+ KisPoint srcPointF = pt - m_painter->duplicateOffset();
+ TQPoint srcPoint = TQPoint(x - static_cast<TQ_INT32>(m_painter->duplicateOffset().x()),
+ y - static_cast<TQ_INT32>(m_painter->duplicateOffset().y()));
+
+
+ TQ_INT32 sw = dab->extent().width();
+ TQ_INT32 sh = dab->extent().height();
+
+ if (srcPoint.x() < 0 )
+ srcPoint.setX(0);
+
+ if( srcPoint.y() < 0)
+ srcPoint.setY(0);
+ if( !(m_srcdev && m_srcdev->colorSpace() != device->colorSpace()) )
+ {
+ m_srcdev = new KisPaintDevice(device->colorSpace(), "duplicate source dev");
+ m_target = new KisPaintDevice(device->colorSpace(), "duplicate target dev");
+ }
+ Q_CHECK_PTR(m_srcdev);
+
+ // Perspective correction ?
+ KisPainter copyPainter(m_srcdev);
+ if(m_painter->duplicatePerspectiveCorrection())
+ {
+ double startM[3][3];
+ double endM[3][3];
+ for(int i = 0; i < 3; i++)
+ {
+ for(int j = 0; j < 3; j++)
+ {
+ startM[i][j] = 0.;
+ endM[i][j] = 0.;
+ }
+ startM[i][i] = 1.;
+ endM[i][i] = 1.;
+ }
+ // First look for the grid corresponding to the start point
+ KisSubPerspectiveGrid* subGridStart = *device->image()->perspectiveGrid()->begin();//device->image()->perspectiveGrid()->gridAt(KisPoint(srcPoint.x() +hotSpot.x(),srcPoint.y() +hotSpot.y()));
+ TQRect r = TQRect(0,0, device->image()->width(), device->image()->height());
+
+#if 1
+ if(subGridStart)
+ {
+// kdDebug() << "fgrid" << endl;
+// kdDebug() << *subGridStart->topLeft() << " " << *subGridStart->topRight() << " " << *subGridStart->bottomLeft() << " " << *subGridStart->bottomRight() << endl;
+ double* b = KisPerspectiveMath::computeMatrixTransfoFromPerspective( r, *subGridStart->topLeft(), *subGridStart->topRight(), *subGridStart->bottomLeft(), *subGridStart->bottomRight());
+ for(int i = 0; i < 3; i++)
+ {
+ for(int j = 0; j < 3; j++)
+ {
+// kdDebug() << "sol[" << 3*i+j << "]=" << b[3*i+j] << endl;
+ startM[i][j] = b[3*i+j];
+ }
+ }
+
+ }
+#endif
+#if 1
+ // Second look for the grid corresponding to the end point
+ KisSubPerspectiveGrid* subGridEnd = *device->image()->perspectiveGrid()->begin();// device->image()->perspectiveGrid()->gridAt(pos);
+ if(subGridEnd)
+ {
+// kdDebug() << "second grid" << endl;
+ double* b = KisPerspectiveMath::computeMatrixTransfoToPerspective(*subGridEnd->topLeft(), *subGridEnd->topRight(), *subGridEnd->bottomLeft(), *subGridEnd->bottomRight(), r);
+ for(int i = 0; i < 3; i++)
+ {
+ for(int j = 0; j < 3; j++)
+ {
+// kdDebug() << "sol[" << 3*i+j << "]=" << b[3*i+j] << endl;
+ endM[i][j] = b[3*i+j];
+ }
+ }
+ }
+#endif
+// kdDebug()<< " oouuuuh" << srcPointF << KisPerspectiveMath::matProd(startM, KisPerspectiveMath::matProd(endM, srcPointF ) ) << KisPerspectiveMath::matProd(endM, KisPerspectiveMath::matProd(startM, srcPointF ) );
+
+ // Compute the translation in the perspective transformation space:
+ KisPoint positionStartPaintingT = KisPerspectiveMath::matProd(endM, m_painter->duplicateStart() );
+ KisPoint duplicateStartPoisitionT = KisPerspectiveMath::matProd(endM, m_painter->duplicateStart() - m_painter->duplicateOffset() );
+ KisPoint translat = duplicateStartPoisitionT - positionStartPaintingT;
+ KisRectIteratorPixel dstIt = m_srcdev->createRectIterator(0, 0, sw, sh, true);
+ KisRandomSubAccessorPixel srcAcc = device->createRandomSubAccessor();
+ //Action
+ while(!dstIt.isDone())
+ {
+ if(dstIt.isSelected())
+ {
+ KisPoint p = KisPerspectiveMath::matProd(startM, KisPerspectiveMath::matProd(endM, KisPoint(dstIt.x() + x, dstIt.y() + y) ) + translat );
+ srcAcc.moveTo( p );
+ srcAcc.sampledOldRawData( dstIt.rawData() );
+ }
+ ++dstIt;
+ }
+
+
+ } else {
+ // Or, copy the source data on the temporary device:
+ copyPainter.bitBlt(0, 0, COMPOSITE_COPY, device, srcPoint.x(), srcPoint.y(), sw, sh);
+ copyPainter.end();
+ }
+
+ // heal ?
+
+ if(heal)
+ {
+ TQ_UINT16 dataDevice[4];
+ TQ_UINT16 dataSrcDev[4];
+ TQMemArray<double> matrix ( 3 * sw * sh );
+ // First divide
+ KisColorSpace* deviceCs = device->colorSpace();
+ KisHLineIteratorPixel deviceIt = device->createHLineIterator(x, y, sw, false );
+ KisHLineIteratorPixel srcDevIt = m_srcdev->createHLineIterator(0, 0, sw, true );
+ double* matrixIt = &matrix[0];
+ for(int j = 0; j < sh; j++)
+ {
+ for(int i= 0; !srcDevIt.isDone(); i++)
+ {
+ deviceCs->toLabA16(deviceIt.rawData(), (TQ_UINT8*)dataDevice, 1);
+ deviceCs->toLabA16(srcDevIt.rawData(), (TQ_UINT8*)dataSrcDev, 1);
+ // Division
+ for( int k = 0; k < 3; k++)
+ {
+ matrixIt[k] = dataDevice[k] / (double)TQMAX(dataSrcDev [k], 1);
+ }
+ ++deviceIt;
+ ++srcDevIt;
+ matrixIt +=3;
+ }
+ deviceIt.nextRow();
+ srcDevIt.nextRow();
+ }
+ // Minimize energy
+ {
+ int iter = 0;
+ double err;
+ TQMemArray<double> solution ( 3 * sw * sh );
+ do {
+ err = minimizeEnergy(&matrix[0], &solution[0],sw,sh);
+ memcpy (&matrix[0], &solution[0], sw * sh * 3 * sizeof(double));
+ iter++;
+ } while( err < 0.00001 && iter < 100);
+ }
+
+ // Finaly multiply
+ deviceIt = device->createHLineIterator(x, y, sw, false );
+ srcDevIt = m_srcdev->createHLineIterator(0, 0, sw, true );
+ matrixIt = &matrix[0];
+ for(int j = 0; j < sh; j++)
+ {
+ for(int i= 0; !srcDevIt.isDone(); i++)
+ {
+ deviceCs->toLabA16(deviceIt.rawData(), (TQ_UINT8*)dataDevice, 1);
+ deviceCs->toLabA16(srcDevIt.rawData(), (TQ_UINT8*)dataSrcDev, 1);
+ // Multiplication
+ for( int k = 0; k < 3; k++)
+ {
+ dataSrcDev[k] = (int)CLAMP( matrixIt[k] * TQMAX( dataSrcDev[k], 1), 0, 65535 );
+ }
+ deviceCs->fromLabA16((TQ_UINT8*)dataSrcDev, srcDevIt.rawData(), 1);
+ ++deviceIt;
+ ++srcDevIt;
+ matrixIt +=3;
+ }
+ deviceIt.nextRow();
+ srcDevIt.nextRow();
+ }
+ }
+
+
+ // Add the dab as selection to the srcdev
+// KisPainter copySelection(srcdev->selection().data());
+// copySelection.bitBlt(0, 0, COMPOSITE_OVER, dab, 0, 0, sw, sh);
+// copySelection.end();
+
+ // copy the srcdev onto a new device, after applying the dab selection
+ copyPainter.begin(m_target);
+
+ copyPainter.bltMask(0, 0, COMPOSITE_OVER, m_srcdev, dab,
+ OPACITY_OPAQUE, 0, 0, sw, sh);
+ copyPainter.end();
+
+ TQRect dabRect = TQRect(0, 0, brush->tqmaskWidth(info), brush->tqmaskHeight(info));
+ TQRect dstRect = TQRect(x, y, dabRect.width(), dabRect.height());
+
+ KisImage * image = device->image();
+
+ if (image != 0) {
+ dstRect &= image->bounds();
+ }
+
+ if (dstRect.isNull() || dstRect.isEmpty() || !dstRect.isValid()) return;
+
+ TQ_INT32 sx = dstRect.x() - x;
+ TQ_INT32 sy = dstRect.y() - y;
+ sw = dstRect.width();
+ sh = dstRect.height();
+
+ if (m_source->hasSelection()) {
+ m_painter->bltSelection(dstRect.x(), dstRect.y(), m_painter->compositeOp(), m_target,
+ m_source->selection(), m_painter->opacity(), sx, sy, sw, sh);
+ }
+ else {
+ m_painter->bitBlt(dstRect.x(), dstRect.y(), m_painter->compositeOp(), m_target, m_painter->opacity(), sx, sy, sw, sh);
+ }
+
+
+ m_painter->addDirtyRect(dstRect);
+}
diff --git a/chalk/plugins/paintops/defaultpaintops/kis_duplicateop.h b/chalk/plugins/paintops/defaultpaintops/kis_duplicateop.h
new file mode 100644
index 00000000..965e0dc9
--- /dev/null
+++ b/chalk/plugins/paintops/defaultpaintops/kis_duplicateop.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2002 Patrick Julien <[email protected]>
+ * Copyright (c) 2004 Boudewijn Rempt <[email protected]>
+ * Copyright (c) 2004 Clarence Dang <[email protected]>
+ * Copyright (c) 2004 Adrian Page <[email protected]>
+ * Copyright (c) 2004 Cyrille Berger <[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_DUPLICATEOP_H_
+#define KIS_DUPLICATEOP_H_
+
+#include "kis_paintop.h"
+
+class KisPoint;
+class KisPainter;
+
+class KisDuplicateOpFactory : public KisPaintOpFactory {
+
+public:
+ KisDuplicateOpFactory() {}
+ virtual ~KisDuplicateOpFactory() {}
+
+ virtual KisPaintOp * createOp(const KisPaintOpSettings *settings, KisPainter * painter);
+ virtual KisID id() { return KisID("duplicate", i18n("Duplicate")); }
+ virtual bool userVisible(KisColorSpace *) { return false; }
+
+};
+
+class KisDuplicateOp : public KisPaintOp {
+
+ typedef KisPaintOp super;
+
+
+ public:
+
+ KisDuplicateOp(KisPainter * painter);
+ virtual ~KisDuplicateOp();
+
+
+ void paintAt(const KisPoint &pos, const KisPaintInformation& info);
+ private:
+ double minimizeEnergy(const double* m, double* sol, int w, int h);
+ private:
+ KisPaintDeviceSP m_target, m_srcdev;
+
+};
+
+#endif // KIS_DUPLICATEOP_H_
diff --git a/chalk/plugins/paintops/defaultpaintops/kis_eraseop.cc b/chalk/plugins/paintops/defaultpaintops/kis_eraseop.cc
new file mode 100644
index 00000000..13045139
--- /dev/null
+++ b/chalk/plugins/paintops/defaultpaintops/kis_eraseop.cc
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2002 Patrick Julien <[email protected]>
+ * Copyright (c) 2004 Boudewijn Rempt <[email protected]>
+ * Copyright (c) 2004 Clarence Dang <[email protected]>
+ * Copyright (c) 2004 Adrian Page <[email protected]>
+ * Copyright (c) 2004 Cyrille Berger <[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 <tqrect.h>
+
+#include <kdebug.h>
+
+#include "kis_brush.h"
+#include "kis_global.h"
+#include "kis_paint_device.h"
+#include "kis_layer.h"
+#include "kis_painter.h"
+#include "kis_types.h"
+#include "kis_paintop.h"
+#include "kis_iterators_pixel.h"
+#include "kis_colorspace.h"
+#include "kis_selection.h"
+#include "kis_eraseop.h"
+
+KisPaintOp * KisEraseOpFactory::createOp(const KisPaintOpSettings */*settings*/, KisPainter * painter)
+{
+ KisPaintOp * op = new KisEraseOp(painter);
+ Q_CHECK_PTR(op);
+ return op;
+}
+
+
+KisEraseOp::KisEraseOp(KisPainter * painter)
+ : super(painter)
+{
+}
+
+KisEraseOp::~KisEraseOp()
+{
+}
+
+void KisEraseOp::paintAt(const KisPoint &pos, const KisPaintInformation& info)
+{
+// Erasing is traditionally in paint applications one of two things:
+// either it is painting in the 'background' color, or it is replacing
+// all pixels with transparent (black?) pixels.
+//
+// That's what this paint op does for now; however, anyone who has
+// ever worked with paper and soft pencils knows that a sharp piece of
+// eraser rubber is a pretty useful too for making sharp to fuzzy lines
+// in the graphite layer, or equally useful: for smudging skin tones.
+//
+// A smudge tool for Chalk is in the making, but when working with
+// a tablet, the eraser tip should be at least as functional as a rubber eraser.
+// That means that only after repeated or forceful application should all the
+// 'paint' or 'graphite' be removed from the surface -- a kind of pressure
+// sensitive, incremental smudge.
+//
+// And there should be an option to not have the eraser work on certain
+// kinds of material. Layers are just a hack for this; putting your ink work
+// in one layer and your pencil in another is not the same as really working
+// with the combination.
+
+ if (!m_painter) return;
+
+ KisPaintDeviceSP device = m_painter->device();
+ if (!device) return;
+
+ KisBrush *brush = m_painter->brush();
+ if (! brush->canPaintFor(info) )
+ return;
+ KisPoint hotSpot = brush->hotSpot(info);
+ KisPoint pt = pos - hotSpot;
+
+ TQ_INT32 destX;
+ double xFraction;
+ TQ_INT32 destY;
+ double yFraction;
+
+ splitCoordinate(pt.x(), &destX, &xFraction);
+ splitCoordinate(pt.y(), &destY, &yFraction);
+
+ KisAlphaMaskSP tqmask = brush->tqmask(info, xFraction, yFraction);
+
+ KisPaintDeviceSP dab = new KisPaintDevice(device->colorSpace(), "erase op dab");
+ Q_CHECK_PTR(dab);
+
+ TQ_INT32 tqmaskWidth = tqmask->width();
+ TQ_INT32 tqmaskHeight = tqmask->height();
+
+ TQRect dstRect;
+
+ KisRectIteratorPixel it = dab->createRectIterator(0, 0, tqmaskWidth, tqmaskHeight, true);
+ KisColorSpace* cs = dab->colorSpace();
+ while (!it.isDone()) {
+ cs->setAlpha(it.rawData(), TQ_UINT8_MAX - tqmask->alphaAt(it.x(), it.y()), 1);
+ ++it;
+ }
+
+ TQRect dabRect = TQRect(0, 0, tqmaskWidth, tqmaskHeight);
+ dstRect = TQRect(destX, destY, dabRect.width(), dabRect.height());
+
+ KisImage * image = device->image();
+
+ if (image != 0) {
+ dstRect &= image->bounds();
+ }
+
+ if (dstRect.isNull() || dstRect.isEmpty() || !dstRect.isValid()) return;
+
+ TQ_INT32 sx = dstRect.x() - destX;
+ TQ_INT32 sy = dstRect.y() - destY;
+ TQ_INT32 sw = dstRect.width();
+ TQ_INT32 sh = dstRect.height();
+
+ if (m_source->hasSelection()) {
+ m_painter->bltSelection(dstRect.x(), dstRect.y(), COMPOSITE_ERASE, dab.data(),
+ m_source->selection(), m_painter->opacity(), sx, sy, sw, sh);
+ }
+ else {
+ m_painter->bitBlt(dstRect.x(), dstRect.y(), COMPOSITE_ERASE, dab.data(), m_painter->opacity(), sx, sy, sw, sh);
+ }
+
+ m_painter->addDirtyRect(dstRect);
+}
+
diff --git a/chalk/plugins/paintops/defaultpaintops/kis_eraseop.h b/chalk/plugins/paintops/defaultpaintops/kis_eraseop.h
new file mode 100644
index 00000000..8c88a122
--- /dev/null
+++ b/chalk/plugins/paintops/defaultpaintops/kis_eraseop.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2002 Patrick Julien <[email protected]>
+ * Copyright (c) 2004 Boudewijn Rempt <[email protected]>
+ * Copyright (c) 2004 Clarence Dang <[email protected]>
+ * Copyright (c) 2004 Adrian Page <[email protected]>
+ * Copyright (c) 2004 Cyrille Berger <[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_ERASEOP_H_
+#define KIS_ERASEOP_H_
+
+#include "kis_paintop.h"
+
+class KisPoint;
+class KisPainter;
+
+class KisEraseOpFactory : public KisPaintOpFactory {
+
+public:
+ KisEraseOpFactory() {}
+ virtual ~KisEraseOpFactory() {}
+
+ virtual KisPaintOp * createOp(const KisPaintOpSettings *settings, KisPainter * painter);
+ virtual KisID id() { return KisID("eraser", i18n("Pixel Eraser")); }
+ virtual TQString pixmap() { return "eraser.png"; }
+};
+
+
+class KisEraseOp : public KisPaintOp {
+
+ typedef KisPaintOp super;
+
+public:
+
+ KisEraseOp(KisPainter * painter);
+ virtual ~KisEraseOp();
+
+ void paintAt(const KisPoint &pos, const KisPaintInformation& info);
+
+};
+
+#endif // KIS_ERASEOP_H_
diff --git a/chalk/plugins/paintops/defaultpaintops/kis_penop.cc b/chalk/plugins/paintops/defaultpaintops/kis_penop.cc
new file mode 100644
index 00000000..0fcbca02
--- /dev/null
+++ b/chalk/plugins/paintops/defaultpaintops/kis_penop.cc
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2002 Patrick Julien <[email protected]>
+ * Copyright (c) 2004 Boudewijn Rempt <[email protected]>
+ * Copyright (c) 2004 Clarence Dang <[email protected]>
+ * Copyright (c) 2004 Adrian Page <[email protected]>
+ * Copyright (c) 2004 Cyrille Berger <[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 <tqrect.h>
+
+#include <kdebug.h>
+
+#include "kis_brush.h"
+#include "kis_global.h"
+#include "kis_paint_device.h"
+#include "klocale.h"
+#include "kis_layer.h"
+#include "kis_painter.h"
+#include "kis_types.h"
+#include "kis_paintop.h"
+#include "kis_iterator.h"
+#include "kis_selection.h"
+#include "kis_iterators_pixel.h"
+
+#include "kis_penop.h"
+
+
+KisPaintOp * KisPenOpFactory::createOp(const KisPaintOpSettings */*settings*/, KisPainter * painter)
+{
+ KisPaintOp * op = new KisPenOp(painter);
+ Q_CHECK_PTR(op);
+ return op;
+}
+
+
+KisPenOp::KisPenOp(KisPainter * painter)
+ : super(painter)
+{
+}
+
+KisPenOp::~KisPenOp()
+{
+}
+
+void KisPenOp::paintAt(const KisPoint &pos, const KisPaintInformation& info)
+{
+ if (!m_painter) return;
+ KisPaintDeviceSP device = m_painter->device();
+ if (!device) return;
+ KisBrush * brush = m_painter->brush();
+ if (!brush) return;
+ if (! brush->canPaintFor(info) )
+ return;
+
+ KisPoint hotSpot = brush->hotSpot(info);
+ KisPoint pt = pos - hotSpot;
+
+ TQ_INT32 x = pt.roundX();
+ TQ_INT32 y = pt.roundY();
+
+ KisPaintDeviceSP dab = 0;
+ if (brush->brushType() == IMAGE ||
+ brush->brushType() == PIPE_IMAGE) {
+ dab = brush->image(device->colorSpace(), info);
+ }
+ else {
+ // Compute tqmask without sub-pixel positioning
+ KisAlphaMaskSP tqmask = brush->tqmask(info);
+ dab = computeDab(tqmask);
+ }
+
+ m_painter->setPressure(info.pressure);
+ TQRect dabRect = TQRect(0, 0, brush->tqmaskWidth(info), brush->tqmaskHeight(info));
+ TQRect dstRect = TQRect(x, y, dabRect.width(), dabRect.height());
+
+ KisImage * image = device->image();
+
+ if (image != 0) {
+ dstRect &= image->bounds();
+ }
+
+ if (dstRect.isNull() || dstRect.isEmpty() || !dstRect.isValid()) return;
+
+ KisColorSpace * cs = dab->colorSpace();
+
+ // Set all alpha > opaque/2 to opaque, the rest to transparent.
+ // XXX: Using 4/10 as the 1x1 circle brush paints nothing with 0.5.
+
+ KisRectIteratorPixel pixelIt = dab->createRectIterator(dabRect.x(), dabRect.y(), dabRect.width(), dabRect.height(), true);
+
+ while (!pixelIt.isDone()) {
+ TQ_UINT8 alpha = cs->getAlpha(pixelIt.rawData());
+
+ if (alpha < (4 * OPACITY_OPAQUE) / 10) {
+ cs->setAlpha(pixelIt.rawData(), OPACITY_TRANSPARENT, 1);
+ } else {
+ cs->setAlpha(pixelIt.rawData(), OPACITY_OPAQUE, 1);
+ }
+
+ ++pixelIt;
+ }
+
+ TQ_INT32 sx = dstRect.x() - x;
+ TQ_INT32 sy = dstRect.y() - y;
+ TQ_INT32 sw = dstRect.width();
+ TQ_INT32 sh = dstRect.height();
+
+ if (m_source->hasSelection()) {
+ m_painter->bltSelection(dstRect.x(), dstRect.y(), m_painter->compositeOp(), dab.data(),
+ m_source->selection(), m_painter->opacity(), sx, sy, sw, sh);
+ }
+ else {
+ m_painter->bitBlt(dstRect.x(), dstRect.y(), m_painter->compositeOp(), dab.data(), m_painter->opacity(), sx, sy, sw, sh);
+ }
+
+ m_painter->addDirtyRect(dstRect);
+}
diff --git a/chalk/plugins/paintops/defaultpaintops/kis_penop.h b/chalk/plugins/paintops/defaultpaintops/kis_penop.h
new file mode 100644
index 00000000..ac03a501
--- /dev/null
+++ b/chalk/plugins/paintops/defaultpaintops/kis_penop.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2002 Patrick Julien <[email protected]>
+ * Copyright (c) 2004 Boudewijn Rempt <[email protected]>
+ * Copyright (c) 2004 Clarence Dang <[email protected]>
+ * Copyright (c) 2004 Adrian Page <[email protected]>
+ * Copyright (c) 2004 Cyrille Berger <[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_PENOP_H_
+#define KIS_PENOP_H_
+
+#include <tqlabel.h>
+#include <tqwidget.h>
+#include "kis_paintop.h"
+
+class KisPoint;
+class KisPainter;
+
+class KisPenOpFactory : public KisPaintOpFactory {
+
+public:
+ KisPenOpFactory() {}
+ virtual ~KisPenOpFactory() {}
+
+ virtual KisPaintOp * createOp(const KisPaintOpSettings *settings, KisPainter * painter);
+ virtual KisID id(){ return KisID("pen", i18n("Pixel Pencil")); }
+ virtual TQString pixmap() { return "pencil.png"; }
+};
+
+
+class KisPenOp : public KisPaintOp {
+
+ typedef KisPaintOp super;
+
+public:
+
+ KisPenOp(KisPainter * painter);
+ virtual ~KisPenOp();
+
+ void paintAt(const KisPoint &pos, const KisPaintInformation& info);
+
+};
+
+#endif // KIS_PENOP_H_
diff --git a/chalk/plugins/paintops/defaultpaintops/kis_smudgeop.cc b/chalk/plugins/paintops/defaultpaintops/kis_smudgeop.cc
new file mode 100644
index 00000000..2e50bebb
--- /dev/null
+++ b/chalk/plugins/paintops/defaultpaintops/kis_smudgeop.cc
@@ -0,0 +1,328 @@
+/*
+ * Copyright (c) 2006 Cyrille Berger <[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_smudgeop.h"
+
+#include <string.h>
+
+#include <tqrect.h>
+#include <tqwidget.h>
+#include <tqlayout.h>
+#include <tqlabel.h>
+#include <tqcheckbox.h>
+#include <tqtabwidget.h>
+#include <tqtoolbutton.h>
+#include <tqslider.h>
+
+#include <kdebug.h>
+
+#include "kis_colorspace_factory_registry.h"
+#include "kcurve.h"
+#include "kis_brush.h"
+#include "kis_global.h"
+#include "kis_paint_device.h"
+#include "kis_layer.h"
+#include "kis_meta_registry.h"
+#include "kis_painter.h"
+#include "kis_types.h"
+#include "kis_paintop.h"
+#include "kis_input_device.h"
+#include "kis_selection.h"
+
+#include "kis_dlgbrushcurvecontrol.h"
+
+KisPaintOp * KisSmudgeOpFactory::createOp(const KisPaintOpSettings *settings, KisPainter * painter)
+{
+ const KisSmudgeOpSettings *brushopSettings = dynamic_cast<const KisSmudgeOpSettings *>(settings);
+ Q_ASSERT(settings == 0 || brushopSettings != 0);
+
+ KisPaintOp * op = new KisSmudgeOp(brushopSettings, painter);
+ Q_CHECK_PTR(op);
+ return op;
+}
+
+KisSmudgeOpSettings::KisSmudgeOpSettings(TQWidget *tqparent, bool isTablet)
+ : super(tqparent)
+{
+ m_optionsWidget = new TQWidget(tqparent, "brush option widget");
+ TQHBoxLayout * l = new TQHBoxLayout(m_optionsWidget);
+ l->setAutoAdd(true);
+ m_rateLabel = new TQLabel(i18n("Rate: "), m_optionsWidget);
+ m_rateSlider = new TQSlider(0,100,1, 50, Qt::Horizontal, m_optionsWidget);
+ if(isTablet)
+ {
+ m_pressureVariation = new TQLabel(i18n("Pressure variation: "), m_optionsWidget);
+ m_size = new TQCheckBox(i18n("Size"), m_optionsWidget);
+ m_size->setChecked(true);
+ m_opacity = new TQCheckBox(i18n("Opacity"), m_optionsWidget);
+ m_rate = new TQCheckBox(i18n("Rate"), m_optionsWidget);
+ m_curveControl = new WdgBrushCurveControl(m_optionsWidget);
+ // We abuse the darken curve here for rate
+ m_curveControl->tabWidget->setTabLabel(m_curveControl->tabWidget->page(2), i18n("Rate"));
+ m_curveControl->tabWidget->setTabToolTip(m_curveControl->tabWidget->page(2),
+ i18n("Modifies the rate. Bottom is 0% of the rate top is 100% of the original rate."));
+ TQToolButton* moreButton = new TQToolButton(TQt::UpArrow, m_optionsWidget);
+ moreButton->tqsetSizePolicy(TQSizePolicy::Expanding, TQSizePolicy::Expanding);
+ moreButton->setMinimumSize(TQSize(24,24)); // Bah, I had hoped the above line would make this unneeded
+ connect(moreButton, TQT_SIGNAL(clicked()), this, TQT_SLOT(slotCustomCurves()));
+ } else {
+ m_pressureVariation = 0;
+ m_size = 0;
+ m_rate = 0;
+ m_opacity = 0;
+ m_curveControl = 0;
+ }
+
+ m_customRate = false;
+ m_customSize = false;
+ m_customOpacity = false;
+ // the curves will get filled in when the slot gets accepted
+}
+
+void KisSmudgeOpSettings::slotCustomCurves() {
+ if (m_curveControl->exec() == TQDialog::Accepted) {
+ m_customRate = m_curveControl->darkenCheckbox->isChecked();
+ m_customSize = m_curveControl->sizeCheckbox->isChecked();
+ m_customOpacity = m_curveControl->opacityCheckbox->isChecked();
+
+ if (m_customRate) {
+ transferCurve(m_curveControl->darkenCurve, m_rateCurve);
+ }
+ if (m_customSize) {
+ transferCurve(m_curveControl->sizeCurve, m_sizeCurve);
+ }
+ if (m_customOpacity) {
+ transferCurve(m_curveControl->opacityCurve, m_opacityCurve);
+ }
+ }
+}
+
+void KisSmudgeOpSettings::transferCurve(KCurve* curve, double* target) {
+ double value;
+ for (int i = 0; i < 256; i++) {
+ value = curve->getCurveValue( i / 255.0);
+ if (value < PRESSURE_MIN)
+ target[i] = PRESSURE_MIN;
+ else if (value > PRESSURE_MAX)
+ target[i] = PRESSURE_MAX;
+ else
+ target[i] = value;
+ }
+}
+
+int KisSmudgeOpSettings::rate() const
+{
+ return m_rateSlider->value();
+}
+
+bool KisSmudgeOpSettings::varyRate() const
+{
+ return m_rate ? m_rate->isChecked() : false;
+}
+
+bool KisSmudgeOpSettings::varySize() const
+{
+ return m_size ? m_size->isChecked() : true;
+}
+
+bool KisSmudgeOpSettings::varyOpacity() const
+{
+ return m_opacity ? m_opacity->isChecked() : false;
+}
+
+KisPaintOpSettings* KisSmudgeOpFactory::settings(TQWidget * tqparent, const KisInputDevice& inputDevice)
+{
+ if (inputDevice == KisInputDevice::mouse()) {
+ // No options for mouse, only tablet devices
+ return new KisSmudgeOpSettings(tqparent, false);
+ } else {
+ return new KisSmudgeOpSettings(tqparent, true);
+ }
+}
+
+KisSmudgeOp::KisSmudgeOp(const KisSmudgeOpSettings *settings, KisPainter *painter)
+ : super(painter)
+ , m_firstRun(true)
+ , m_rate(50)
+ , m_pressureSize(true)
+ , m_pressureRate(false)
+ , m_pressureOpacity(false)
+ , m_customRate(false)
+ , m_customSize(false)
+ , m_customOpacity(false)
+ , m_target(0)
+ , m_srcdev(0)
+{
+ if (settings != 0) {
+ m_rate = settings->rate();
+ m_pressureRate = settings->varyRate();
+ m_pressureSize = settings->varySize();
+ m_pressureOpacity = settings->varyOpacity();
+ m_customRate = settings->customRate();
+ m_customSize = settings->customSize();
+ m_customOpacity = settings->customOpacity();
+ if (m_customSize) {
+ memcpy(m_sizeCurve, settings->sizeCurve(), 256 * sizeof(double));
+ }
+ if (m_customOpacity) {
+ memcpy(m_opacityCurve, settings->opacityCurve(), 256 * sizeof(double));
+ }
+ if (m_customRate) {
+ memcpy(m_rateCurve, settings->rateCurve(), 256 * sizeof(double));
+ }
+ }
+ KisPaintDeviceSP device = m_painter->device();
+ m_srcdev = new KisPaintDevice(device->colorSpace(), "duplicate source dev");
+ m_target = new KisPaintDevice(device->colorSpace(), "duplicate target dev");
+}
+
+KisSmudgeOp::~KisSmudgeOp()
+{
+}
+
+void KisSmudgeOp::paintAt(const KisPoint &pos, const KisPaintInformation& info)
+{
+ KisPaintInformation adjustedInfo(info);
+ if (!m_pressureSize)
+ adjustedInfo.pressure = PRESSURE_DEFAULT;
+ else if (m_customSize)
+ adjustedInfo.pressure = scaleToCurve(adjustedInfo.pressure, m_sizeCurve);
+
+ // Painting should be implemented according to the following algorithm:
+ // retrieve brush
+ // if brush == tqmask
+ // retrieve tqmask
+ // else if brush == image
+ // retrieve image
+ // subsample (tqmask | image) for position -- pos should be double!
+ // apply filters to tqmask (colour | gradient | pattern | etc.
+ // composite filtered tqmask into temporary layer
+ // composite temporary layer into target layer
+ // @see: doc/brush.txt
+
+ if (!m_painter->device()) return;
+
+ KisBrush *brush = m_painter->brush();
+
+ Q_ASSERT(brush);
+ if (!brush) return;
+ if (! brush->canPaintFor(adjustedInfo) )
+ return;
+
+ KisPaintDeviceSP device = m_painter->device();
+
+ KisPoint hotSpot = brush->hotSpot(adjustedInfo);
+ KisPoint pt = 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.
+ TQ_INT32 x;
+ double xFraction;
+ TQ_INT32 y;
+ double yFraction;
+
+ splitCoordinate(pt.x(), &x, &xFraction);
+ splitCoordinate(pt.y(), &y, &yFraction);
+
+ KisPaintDeviceSP dab = 0;
+
+ TQ_UINT8 origOpacity = m_painter->opacity();
+
+ if (m_pressureOpacity) {
+ if (!m_customOpacity)
+ m_painter->setOpacity((TQ_INT8)(origOpacity * info.pressure));
+ else
+ m_painter->setOpacity((TQ_INT8)(origOpacity * scaleToCurve(info.pressure, m_opacityCurve)));
+ }
+
+ if (brush->brushType() == IMAGE || brush->brushType() == PIPE_IMAGE) {
+ dab = brush->image(device->colorSpace(), adjustedInfo, xFraction, yFraction);
+ dab->convertTo(KisMetaRegistry::instance()->csRegistry()->getAlpha8());
+ }
+ else {
+ KisAlphaMaskSP tqmask = brush->tqmask(adjustedInfo, xFraction, yFraction);
+ dab = computeDab(tqmask, KisMetaRegistry::instance()->csRegistry()->getAlpha8());
+ }
+
+
+ m_painter->setPressure(adjustedInfo.pressure);
+
+ TQRect dabRect = TQRect(0, 0, brush->tqmaskWidth(adjustedInfo),
+ brush->tqmaskHeight(adjustedInfo));
+ TQRect dstRect = TQRect(x, y, dabRect.width(), dabRect.height());
+
+ KisImage * image = device->image();
+
+ if (image != 0) {
+ dstRect &= image->bounds();
+ }
+
+ TQ_INT32 sw = dab->extent().width();
+ TQ_INT32 sh = dab->extent().height();
+
+ KisPainter copyPainter(m_srcdev);
+ int opacity = OPACITY_OPAQUE;
+ if(!m_firstRun)
+ {
+ opacity = rate();
+ if (m_pressureRate) {
+ if (m_customRate) {
+ opacity = CLAMP((TQ_UINT8)(double(opacity) * scaleToCurve(info.pressure, m_rateCurve)), OPACITY_TRANSPARENT, OPACITY_OPAQUE);
+ } else {
+ opacity = CLAMP((TQ_UINT8)(double(opacity) * info.pressure), OPACITY_TRANSPARENT, OPACITY_OPAQUE);
+ }
+ }
+ opacity = OPACITY_OPAQUE - opacity;
+ } else {
+ m_firstRun = false;
+ }
+ copyPainter.bitBlt(0, 0, COMPOSITE_OVER, device, opacity, pt.x(), pt.y(), sw, sh);
+ copyPainter.end();
+
+ m_target = new KisPaintDevice(device->colorSpace(), "duplicate target dev");
+
+ copyPainter.begin(m_target);
+
+ copyPainter.bltMask(0, 0, COMPOSITE_OVER, m_srcdev, dab,
+ OPACITY_OPAQUE, 0, 0, sw, sh);
+ copyPainter.end();
+
+
+ if (dstRect.isNull() || dstRect.isEmpty() || !dstRect.isValid()) return;
+
+ TQ_INT32 sx = dstRect.x() - x;
+ TQ_INT32 sy = dstRect.y() - y;
+ sw = dstRect.width();
+ sh = dstRect.height();
+
+ if (m_source->hasSelection()) {
+ m_painter->bltSelection(dstRect.x(), dstRect.y(), m_painter->compositeOp(), m_target,
+ m_source->selection(), m_painter->opacity(), sx, sy, sw, sh);
+ }
+ else {
+ m_painter->bitBlt(dstRect.x(), dstRect.y(), m_painter->compositeOp(), m_target, m_painter->opacity(), sx, sy, sw, sh);
+ }
+
+ m_painter->addDirtyRect(dstRect);
+
+ m_painter->setOpacity(origOpacity);
+
+}
+
+#include "kis_smudgeop.moc"
diff --git a/chalk/plugins/paintops/defaultpaintops/kis_smudgeop.h b/chalk/plugins/paintops/defaultpaintops/kis_smudgeop.h
new file mode 100644
index 00000000..d9c8872d
--- /dev/null
+++ b/chalk/plugins/paintops/defaultpaintops/kis_smudgeop.h
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2006 Cyrille Berger <[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_SMUDGEOP_H_
+#define KIS_SMUDGEOP_H_
+
+#include "kis_paintop.h"
+#include <tqobject.h>
+
+class TQWidget;
+class TQCheckBox;
+class TQLabel;
+class TQSlider;
+class KisPoint;
+class KisPainter;
+class KCurve;
+class WdgBrushCurveControl;
+
+class KisSmudgeOpFactory : public KisPaintOpFactory {
+
+public:
+ KisSmudgeOpFactory() {}
+ virtual ~KisSmudgeOpFactory() {}
+
+ virtual KisPaintOp * createOp(const KisPaintOpSettings *settings, KisPainter * painter);
+ virtual KisID id() { return KisID("smudge", i18n("Smudge Brush")); }
+ virtual TQString pixmap() { return "paintbrush.png"; }
+ virtual KisPaintOpSettings *settings(TQWidget * tqparent, const KisInputDevice& inputDevice);
+};
+
+class KisSmudgeOpSettings : public TQObject, public KisPaintOpSettings {
+ Q_OBJECT
+ TQ_OBJECT
+ typedef KisPaintOpSettings super;
+public:
+ KisSmudgeOpSettings(TQWidget *tqparent, bool isTablet);
+
+ int rate() const;
+ bool varyRate() const;
+ bool varySize() const;
+ bool varyOpacity() const;
+
+ bool customRate() const { return m_customRate; }
+ bool customSize() const { return m_customSize; }
+ bool customOpacity() const { return m_customOpacity; }
+ const double* rateCurve() const { return m_rateCurve; }
+ const double* sizeCurve() const { return m_sizeCurve; }
+ const double* opacityCurve() const { return m_opacityCurve; }
+
+ virtual TQWidget *widget() const { return m_optionsWidget; }
+private slots:
+ void slotCustomCurves();
+private:
+ void transferCurve(KCurve* curve, double* target);
+ TQWidget *m_optionsWidget;
+ TQLabel* m_rateLabel;
+ TQSlider* m_rateSlider;
+ TQLabel * m_pressureVariation;
+ TQCheckBox * m_rate;
+ TQCheckBox * m_size;
+ TQCheckBox * m_opacity;
+ WdgBrushCurveControl* m_curveControl;
+
+ bool m_customSize;
+ bool m_customRate;
+ bool m_customOpacity;
+ double m_rateCurve[256];
+ double m_sizeCurve[256];
+ double m_opacityCurve[256];
+};
+
+class KisSmudgeOp : public KisPaintOp {
+
+ typedef KisPaintOp super;
+
+public:
+
+ KisSmudgeOp(const KisSmudgeOpSettings *settings, KisPainter * painter);
+ virtual ~KisSmudgeOp();
+
+ void paintAt(const KisPoint &pos, const KisPaintInformation& info);
+
+ int rate() { return (m_rate * 255) / 100; }
+private:
+ KisPaintDeviceSP m_target, m_srcdev;
+ inline double scaleToCurve(double pressure, double* curve) const {
+ int offset = CLAMP(int(255.0 * pressure), 0, 255);
+ return curve[offset];
+ }
+ bool m_firstRun;
+ int m_rate;
+ bool m_pressureRate;
+ bool m_pressureSize;
+ bool m_pressureOpacity;
+ bool m_customRate;
+ bool m_customSize;
+ bool m_customOpacity;
+ double m_rateCurve[256];
+ double m_sizeCurve[256];
+ double m_opacityCurve[256];
+};
+
+#endif // KIS_BRUSHOP_H_
diff --git a/chalk/plugins/paintops/defaultpaintops/paintbrush.png b/chalk/plugins/paintops/defaultpaintops/paintbrush.png
new file mode 100644
index 00000000..accc0411
--- /dev/null
+++ b/chalk/plugins/paintops/defaultpaintops/paintbrush.png
Binary files differ
diff --git a/chalk/plugins/paintops/defaultpaintops/pencil.png b/chalk/plugins/paintops/defaultpaintops/pencil.png
new file mode 100644
index 00000000..08a2f4cf
--- /dev/null
+++ b/chalk/plugins/paintops/defaultpaintops/pencil.png
Binary files differ
diff --git a/chalk/plugins/paintops/defaultpaintops/src/README b/chalk/plugins/paintops/defaultpaintops/src/README
new file mode 100644
index 00000000..769ced65
--- /dev/null
+++ b/chalk/plugins/paintops/defaultpaintops/src/README
@@ -0,0 +1,2 @@
+These svg images are the basis of the paintop pixmaps; they were taken from
+the OpenClipArt repository and are in the public domain.
diff --git a/chalk/plugins/paintops/defaultpaintops/src/pencil_01.svg b/chalk/plugins/paintops/defaultpaintops/src/pencil_01.svg
new file mode 100644
index 00000000..40319104
--- /dev/null
+++ b/chalk/plugins/paintops/defaultpaintops/src/pencil_01.svg
@@ -0,0 +1,637 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
+"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ height="297mm"
+ id="svg1"
+ inkscape:export-filename="/home/boud/pencil.png"
+ inkscape:export-xdpi="37.290001"
+ inkscape:export-ydpi="37.290001"
+ inkscape:version="0.40"
+ sodipodi:docbase="/home/boud"
+ sodipodi:docname="pencil_01.svg"
+ sodipodi:version="0.32"
+ width="210mm"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <defs
+ id="defs3">
+ <linearGradient
+ id="linearGradient5522">
+ <stop
+ id="stop5523"
+ offset="0.0000000"
+ style="stop-color:#ffffff;stop-opacity:0.96862745;" />
+ <stop
+ id="stop5525"
+ offset="1.0000000"
+ style="stop-color:#a2a2a2;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4895">
+ <stop
+ id="stop4896"
+ offset="0.0000000"
+ style="stop-color:#bfbfbf;stop-opacity:0.96875000;" />
+ <stop
+ id="stop4898"
+ offset="0.81250000"
+ style="stop-color:#000000;stop-opacity:1.0000000;" />
+ <stop
+ id="stop4897"
+ offset="1.0000000"
+ style="stop-color:#000000;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4256">
+ <stop
+ id="stop4257"
+ offset="0.0000000"
+ style="stop-color:#000000;stop-opacity:1.0000000;" />
+ <stop
+ id="stop4260"
+ offset="0.24902344"
+ style="stop-color:#000000;stop-opacity:1.0000000;" />
+ <stop
+ id="stop4262"
+ offset="0.53125000"
+ style="stop-color:#878787;stop-opacity:0.62352943;" />
+ <stop
+ id="stop4261"
+ offset="0.67773438"
+ style="stop-color:#5a5a5a;stop-opacity:1.0000000;" />
+ <stop
+ id="stop4258"
+ offset="1.0000000"
+ style="stop-color:#070707;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2387">
+ <stop
+ id="stop2388"
+ offset="0.0000000"
+ style="stop-color:#d5d5bc;stop-opacity:1.0000000;" />
+ <stop
+ id="stop2389"
+ offset="1.0000000"
+ style="stop-color:#dfdfb9;stop-opacity:0.34117648;" />
+ <stop
+ id="stop2390"
+ offset="1.0000000"
+ style="stop-color:#c2c2b2;stop-opacity:0.60392159;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient1754">
+ <stop
+ id="stop1755"
+ offset="0.0000000"
+ style="stop-color:#fdfdc1;stop-opacity:1.0000000;" />
+ <stop
+ id="stop1761"
+ offset="1.0000000"
+ style="stop-color:#dfdfb9;stop-opacity:0.34117648;" />
+ <stop
+ id="stop1756"
+ offset="1.0000000"
+ style="stop-color:#c2c2b2;stop-opacity:0.60392159;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient9845">
+ <stop
+ id="stop9846"
+ offset="0.0000000"
+ style="stop-color:#e2e5bf;stop-opacity:1.0000000;" />
+ <stop
+ id="stop9849"
+ offset="1.0000000"
+ style="stop-color:#edde91;stop-opacity:1.0000000;" />
+ <stop
+ id="stop9850"
+ offset="1.0000000"
+ style="stop-color:#e6e7d9;stop-opacity:1.0000000;" />
+ <stop
+ id="stop10479"
+ offset="1.0000000"
+ style="stop-color:#eeefe0;stop-opacity:1.0000000;" />
+ <stop
+ id="stop9847"
+ offset="1.0000000"
+ style="stop-color:#f7f7e8;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient9215">
+ <stop
+ id="stop9216"
+ offset="0.0000000"
+ style="stop-color:#5a5a5a;stop-opacity:0.26041666;" />
+ <stop
+ id="stop9217"
+ offset="0.25000000"
+ style="stop-color:#bdbdbd;stop-opacity:0.50000000;" />
+ <stop
+ id="stop9218"
+ offset="0.50000000"
+ style="stop-color:#ffffff;stop-opacity:1.0000000;" />
+ <stop
+ id="stop9220"
+ offset="0.75000000"
+ style="stop-color:#aaaaaa;stop-opacity:0.53125000;" />
+ <stop
+ id="stop9219"
+ offset="1.0000000"
+ style="stop-color:#6a6a6a;stop-opacity:0.33333334;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient6713">
+ <stop
+ id="stop6714"
+ offset="0.0000000"
+ style="stop-color:#d5d51f;stop-opacity:0.46666667;" />
+ <stop
+ id="stop6715"
+ offset="0.25000000"
+ style="stop-color:#ffff9d;stop-opacity:0.64583331;" />
+ <stop
+ id="stop6716"
+ offset="0.50000000"
+ style="stop-color:#ffffb7;stop-opacity:0.79215688;" />
+ <stop
+ id="stop6717"
+ offset="1.0000000"
+ style="stop-color:#eaea1f;stop-opacity:0.34117648;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient5461">
+ <stop
+ id="stop5462"
+ offset="0.0000000"
+ style="stop-color:#ecd620;stop-opacity:1.0000000;" />
+ <stop
+ id="stop5466"
+ offset="0.50000000"
+ style="stop-color:#f5dd2d;stop-opacity:1.0000000;" />
+ <stop
+ id="stop5463"
+ offset="1.0000000"
+ style="stop-color:#fff01a;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3579">
+ <stop
+ id="stop3580"
+ offset="0.0000000"
+ style="stop-color:#d5d5d5;stop-opacity:0.46666667;" />
+ <stop
+ id="stop4205"
+ offset="0.25000000"
+ style="stop-color:#ffffff;stop-opacity:0.73958331;" />
+ <stop
+ id="stop3583"
+ offset="0.50000000"
+ style="stop-color:#ffffff;stop-opacity:0.79166669;" />
+ <stop
+ id="stop3581"
+ offset="1.0000000"
+ style="stop-color:#6a6a6a;stop-opacity:0.93750000;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient1706">
+ <stop
+ id="stop1707"
+ offset="0.0000000"
+ style="stop-color:#cdcdcd;stop-opacity:1.0000000;" />
+ <stop
+ id="stop1708"
+ offset="1.0000000"
+ style="stop-color:#f5f0f5;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ gradientTransform="matrix(2.820962,0.000000,6.312385e-5,2.601095e-2,298.8738,76.89546)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient3582"
+ inkscape:collect="always"
+ x1="35.424759"
+ x2="35.641914"
+ xlink:href="#linearGradient3579"
+ y1="18130.623"
+ y2="17965.547" />
+ <linearGradient
+ gradientTransform="matrix(0.202664,0.000000,0.000000,0.362058,298.8738,76.89546)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient5465"
+ inkscape:collect="always"
+ x1="1268.3737"
+ x2="1268.6208"
+ xlink:href="#linearGradient5461"
+ y1="1336.0245"
+ y2="1300.7721" />
+ <linearGradient
+ gradientTransform="matrix(6.942050e-2,0.000000,1.553402e-6,2.336613e-2,553.6438,124.8435)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient6090"
+ inkscape:collect="always"
+ x1="35.424759"
+ x2="35.641914"
+ xlink:href="#linearGradient6713"
+ y1="18130.623"
+ y2="17965.547" />
+ <linearGradient
+ gradientTransform="matrix(0.323512,0.000000,7.239130e-6,2.601095e-2,571.1883,76.96085)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient8593"
+ inkscape:collect="always"
+ x1="35.424759"
+ x2="35.641914"
+ xlink:href="#linearGradient9215"
+ y1="18130.623"
+ y2="17965.547" />
+ <linearGradient
+ gradientTransform="matrix(0.362900,0.000000,0.000000,0.202193,298.8738,76.89546)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient9857"
+ inkscape:collect="always"
+ spreadMethod="pad"
+ x1="-345.43631"
+ x2="-345.17053"
+ xlink:href="#linearGradient9845"
+ y1="2366.5361"
+ y2="2354.8115" />
+ <radialGradient
+ cx="-233.32603"
+ cy="3321.7747"
+ fx="-213.39992"
+ fy="3310.0935"
+ gradientTransform="matrix(0.517807,0.000000,0.000000,0.141706,298.8738,76.89546)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient1753"
+ inkscape:collect="always"
+ r="31.490158"
+ xlink:href="#linearGradient1754" />
+ <radialGradient
+ cx="-316.48395"
+ cy="-2710.2300"
+ fx="-290.97665"
+ fy="-2729.1069"
+ gradientTransform="matrix(0.413154,0.000000,0.000000,-0.177599,298.8738,76.89546)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient1763"
+ inkscape:collect="always"
+ r="28.744236"
+ xlink:href="#linearGradient2387" />
+ <linearGradient
+ gradientTransform="matrix(0.480053,0.000000,0.000000,0.152850,298.8738,76.89540)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient4259"
+ inkscape:collect="always"
+ x1="-328.35983"
+ x2="-328.35986"
+ xlink:href="#linearGradient4256"
+ y1="3145.9695"
+ y2="3091.0151" />
+ <radialGradient
+ cx="2255.8301"
+ cy="894.17383"
+ fx="2254.7786"
+ fy="894.33282"
+ gradientTransform="matrix(0.137506,0.000000,0.000000,0.533619,289.9911,76.13070)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient4894"
+ inkscape:collect="always"
+ r="72.563972"
+ xlink:href="#linearGradient4895" />
+ <linearGradient
+ gradientTransform="matrix(0.101819,0.000000,0.000000,0.966086,196.9883,76.89546)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient5526"
+ inkscape:collect="always"
+ x1="3950.2200"
+ x2="3970.1528"
+ xlink:href="#linearGradient5522"
+ y1="494.74939"
+ y2="494.83701" />
+ </defs>
+ <sodipodi:namedview
+ bordercolor="#666666"
+ borderopacity="1.0"
+ id="base"
+ inkscape:current-layer="layer7"
+ inkscape:cx="303.76092"
+ inkscape:cy="410.97376"
+ inkscape:grid-bbox="false"
+ inkscape:grid-points="false"
+ inkscape:guide-bbox="false"
+ inkscape:guide-points="false"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:window-height="710"
+ inkscape:window-width="1012"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:zoom="2.0000000"
+ pagecolor="#ffffff"
+ showgrid="false"
+ showguides="false">
+ <sodipodi:guide
+ id="guide6719"
+ orientation="horizontal"
+ position="-411.00582" />
+ <sodipodi:guide
+ id="guide6720"
+ orientation="horizontal"
+ position="-500.98515" />
+ <sodipodi:guide
+ id="guide6721"
+ orientation="horizontal"
+ position="-439.29009" />
+ <sodipodi:guide
+ id="guide6722"
+ orientation="horizontal"
+ position="-481.89327" />
+ <sodipodi:guide
+ id="guide8591"
+ orientation="vertical"
+ position="957.24580" />
+ </sodipodi:namedview>
+ <g
+ id="layer7"
+ inkscape:groupmode="layer"
+ inkscape:label="grafit">
+ <path
+ d="M 148.83456,547.90696 L 157.67340,548.68521 L 159.10971,555.17082 L 155.68466,557.89477 L 149.82893,558.67302 L 146.07243,559.06215 L 123.86486,553.22513 L 148.83456,547.90696 z "
+ id="path3013"
+ style="color:#000000;fill:url(#linearGradient4259);fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.067719966pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:block"
+ inkscape:export-filename="/home/boud/pencil.png"
+ inkscape:export-xdpi="37.290001"
+ inkscape:export-ydpi="25.269030" />
+ </g>
+ <g
+ id="layer5"
+ inkscape:groupmode="layer"
+ inkscape:label="sciete_drewno 0">
+ <path
+ d="M 199.81128,569.39078 C 193.61337,567.86215 187.05087,567.43411 178.71753,566.27230 C 170.53826,565.13204 173.53622,565.57447 165.90503,564.07102 C 158.30087,562.57292 152.36337,561.31943 144.96753,558.75127 C 147.51962,558.38439 151.63420,555.99968 154.18628,555.63280 C 155.07170,555.08248 157.30018,554.25609 157.30018,552.29942 C 157.30018,551.06283 156.11643,550.23527 154.87275,549.48489 C 153.54091,548.68128 149.17824,548.89390 148.18866,547.97670 C 153.68422,546.32010 168.53524,542.85318 176.53003,541.69138 C 184.47252,540.53720 191.47795,540.04042 200.90503,538.57290 C 200.17587,548.84553 200.54045,559.11815 199.81128,569.39078 z "
+ id="path9222"
+ sodipodi:nodetypes="czzcczzczcc"
+ style="fill:url(#linearGradient9857);fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:0.25000000pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
+ inkscape:export-filename="/home/boud/pencil.png"
+ inkscape:export-xdpi="37.290001"
+ inkscape:export-ydpi="25.269030" />
+ </g>
+ <g
+ id="layer6"
+ inkscape:groupmode="layer"
+ inkscape:label="polysk">
+ <path
+ d="M 193.02874,548.16636 C 193.06610,547.28902 191.47519,545.75059 190.37709,545.31274 C 187.57137,544.19402 184.34329,543.37209 181.31728,543.49678 C 175.94640,543.71802 170.45340,544.99141 165.18641,546.35045 C 163.75062,546.72091 162.18663,547.59479 161.20893,548.68521 C 160.71349,549.23782 160.14893,551.19033 160.76699,551.27943 C 164.34738,551.79565 169.47529,550.31469 173.80427,550.50118 C 177.50390,550.66061 181.20734,552.31715 184.85282,552.31715 C 186.65795,552.31715 188.48666,551.34876 190.15612,550.50118 C 191.21197,549.96512 192.99244,549.01852 193.02874,548.16636 z "
+ id="path1128"
+ sodipodi:nodetypes="csssssssss"
+ style="opacity:0.80206186;fill:url(#radialGradient1753);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.25000000pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
+ inkscape:export-filename="/home/boud/pencil.png"
+ inkscape:export-xdpi="37.290001"
+ inkscape:export-ydpi="25.269030" />
+ <path
+ d="M 179.02203,557.59082 C 179.04925,558.59448 183.19386,562.68933 182.39409,563.19022 C 180.35065,564.47001 172.69628,563.07552 170.49239,562.93294 C 166.58069,562.67982 162.58005,561.22298 158.74401,559.66824 C 157.69830,559.24448 156.55922,558.24469 155.84715,556.99724 C 155.48631,556.36509 155.07513,554.13135 155.52528,554.02939 C 158.13293,553.43886 161.86768,555.13314 165.02054,554.91976 C 167.71504,554.73738 170.41232,552.84222 173.06738,552.84222 C 174.38209,552.84222 175.71397,553.95014 176.92986,554.91976 C 177.69885,555.53301 178.99560,556.61592 179.02203,557.59082 z "
+ id="path1762"
+ sodipodi:nodetypes="csssssssss"
+ style="opacity:0.78556699;fill:url(#radialGradient1763);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.25000000pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
+ inkscape:export-filename="/home/boud/pencil.png"
+ inkscape:export-xdpi="37.290001"
+ inkscape:export-ydpi="25.269030" />
+ </g>
+ <g
+ id="layer1"
+ inkscape:groupmode="layer"
+ inkscape:label="szary_tulow 1"
+ style="display:block">
+ <path
+ d="M 200.26345,546.32445 C 316.62843,546.32445 435.09573,546.32445 551.46071,546.32445 C 551.46071,549.42291 551.46071,559.47628 551.46071,562.57480 C 550.75336,565.25801 550.75336,561.81680 550.75336,564.91526 C 434.38838,564.91526 316.62843,564.91526 200.26345,564.91526 C 200.26345,563.36603 197.40747,560.84125 192.74343,559.26561 C 188.07940,557.68996 180.41183,557.06351 179.28717,555.72548 C 180.23188,554.91565 187.89945,554.83382 192.60847,553.07333 C 197.31750,551.31283 200.26345,547.87368 200.26345,546.32445 z "
+ id="rect1061"
+ sodipodi:nodetypes="cccccscsc"
+ style="color:#000000;fill:#d2d2d2;fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:0.31228563;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.38622126;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:block"
+ inkscape:export-filename="/home/boud/pencil.png"
+ inkscape:export-xdpi="37.290001"
+ inkscape:export-ydpi="25.269030" />
+ <path
+ d="M 200.54626,538.65508 C 316.91125,538.65508 433.02176,536.56375 549.38673,536.56375 C 550.21028,540.32388 550.96053,542.46928 551.46071,546.96346 C 435.09574,546.96346 316.65677,546.96346 200.29178,546.96346 C 200.29178,546.09686 198.32960,546.16513 194.42590,545.35013 C 190.46169,544.52251 182.70217,542.01992 181.57751,541.27143 C 183.46694,540.36539 195.77770,539.43774 200.54626,538.65508 z "
+ id="path1066"
+ sodipodi:nodetypes="ccccscc"
+ style="color:#000000;fill:#bebebe;fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:0.31228563;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.38622126;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:block"
+ inkscape:export-filename="/home/boud/pencil.png"
+ inkscape:export-xdpi="37.290001"
+ inkscape:export-ydpi="25.269030" />
+ <path
+ d="M 200.03730,563.99354 C 316.40229,563.99354 435.09574,562.56306 551.46071,562.56306 C 550.72496,565.22778 550.25391,567.01986 549.40828,569.67642 C 433.04330,569.67642 315.14667,570.85172 199.78282,569.67642 C 193.83317,568.50428 190.23851,567.80163 187.98919,566.77772 C 189.87862,566.15801 200.03730,565.17912 200.03730,563.99354 z "
+ id="path1067"
+ sodipodi:nodetypes="cccccc"
+ style="color:#000000;fill:#9b9b9b;fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:0.31228563;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.38622126;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:block"
+ inkscape:export-filename="/home/boud/pencil.png"
+ inkscape:export-xdpi="37.290001"
+ inkscape:export-ydpi="25.269030" />
+ </g>
+ <g
+ id="layer2"
+ inkscape:groupmode="layer"
+ inkscape:label="blysk 2"
+ style="display:block">
+ <path
+ d="M 194.58869,545.26983 L 551.34313,545.59263 L 551.46071,548.49015 L 199.30871,548.38150 C 199.67876,547.94447 200.10935,547.12501 200.20401,546.65769 C 199.28577,546.01110 197.70842,546.05120 196.37274,545.78229 L 194.58869,545.26983 z "
+ id="rect2956"
+ sodipodi:nodetypes="ccccccc"
+ style="color:#000000;fill:url(#linearGradient3582);fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:0.31228563;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.38622126;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:block"
+ inkscape:export-filename="/home/boud/pencil.png"
+ inkscape:export-xdpi="37.290001"
+ inkscape:export-ydpi="25.269030" />
+ </g>
+ <g
+ id="layer3"
+ inkscape:groupmode="layer"
+ inkscape:label="zloto 3">
+ <path
+ d="M 549.33498,536.56375 C 552.95421,536.56375 554.44773,536.56375 558.06696,536.56375 C 558.75468,540.03032 559.50496,543.42352 560.19268,546.96346 C 556.57346,546.96346 555.07993,546.96346 551.46071,546.96346 C 550.89803,543.35008 549.96021,540.17713 549.33498,536.56375 z "
+ id="rect4209"
+ sodipodi:nodetypes="ccccc"
+ style="color:#000000;fill:#d3bc3f;fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:0.31228563;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.38622126;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:block"
+ inkscape:export-filename="/home/boud/pencil.png"
+ inkscape:export-xdpi="37.290001"
+ inkscape:export-ydpi="25.269030" />
+ <path
+ d="M 551.39818,562.56306 C 555.05911,562.56306 556.53176,562.56306 560.19268,562.56306 C 559.44243,565.21481 559.06731,566.98575 558.19198,569.63750 C 554.53108,569.63750 552.87086,569.63750 549.20993,569.63750 C 550.35413,566.11575 550.69053,565.17119 551.39818,562.56306 z "
+ id="rect4210"
+ sodipodi:nodetypes="ccccc"
+ style="color:#000000;fill:#d3bc3f;fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:0.31228563;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.38622126;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:block"
+ inkscape:export-filename="/home/boud/pencil.png"
+ inkscape:export-xdpi="37.290001"
+ inkscape:export-ydpi="25.269030" />
+ <rect
+ height="15.599600"
+ id="rect4208"
+ style="color:#000000;fill:url(#linearGradient5465);fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:0.31228563;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.38622126;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:block"
+ width="8.7319660"
+ x="551.46075"
+ y="546.96350"
+ inkscape:export-filename="/home/boud/pencil.png"
+ inkscape:export-xdpi="37.290001"
+ inkscape:export-ydpi="25.269030" />
+ <path
+ d="M 551.21196,545.59310 L 559.93478,545.60219 L 560.19013,546.96675 L 560.19158,548.48604 L 551.21131,548.38848 L 551.21643,546.28007 L 551.21196,545.59310 z "
+ id="path6089"
+ sodipodi:nodetypes="ccccccc"
+ style="opacity:0.69896907;color:#000000;fill:url(#linearGradient6090);fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:0.31228563;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.38622126;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:block"
+ inkscape:export-filename="/home/boud/pencil.png"
+ inkscape:export-xdpi="37.290001"
+ inkscape:export-ydpi="25.269030" />
+ </g>
+ <g
+ id="layer4"
+ inkscape:groupmode="layer"
+ inkscape:label="czarna_koncowka 4">
+ <rect
+ height="15.630233"
+ id="rect6723"
+ style="color:#000000;fill:#000000;fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:0.31228563;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.38622126;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:block"
+ width="39.995728"
+ x="560.11658"
+ y="546.93414"
+ inkscape:export-filename="/home/boud/pencil.png"
+ inkscape:export-xdpi="37.290001"
+ inkscape:export-ydpi="25.269030" />
+ <path
+ d="M 558.10023,536.55723 L 598.06833,536.55723 L 600.05708,546.93411 L 560.11658,546.93411 L 558.10023,536.55723 z "
+ id="rect6724"
+ sodipodi:nodetypes="ccccc"
+ style="color:#000000;fill:#000000;fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:0.31228563;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.38622126;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:block"
+ inkscape:export-filename="/home/boud/pencil.png"
+ inkscape:export-xdpi="37.290001"
+ inkscape:export-ydpi="25.269030" />
+ <path
+ d="M 560.06136,562.56435 L 600.05708,562.56435 L 598.06833,569.56876 L 558.07261,569.56876 L 560.06136,562.56435 z "
+ id="rect6725"
+ sodipodi:nodetypes="ccccc"
+ style="color:#000000;fill:#000000;fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:0.31228563;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.38622126;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:block"
+ inkscape:export-filename="/home/boud/pencil.png"
+ inkscape:export-xdpi="37.290001"
+ inkscape:export-ydpi="25.269030" />
+ <path
+ d="M 559.80053,545.49730 L 599.78261,545.62556 L 600.18986,546.96082 L 600.12756,548.42582 L 560.12901,548.47929 L 560.12531,546.97544 L 559.80053,545.49730 z "
+ id="path8592"
+ sodipodi:nodetypes="ccccccc"
+ style="color:#000000;fill:url(#linearGradient8593);fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:0.31228563;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.38622126;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:block"
+ inkscape:export-filename="/home/boud/pencil.png"
+ inkscape:export-xdpi="37.290001"
+ inkscape:export-ydpi="25.269030" />
+ </g>
+ <g
+ id="layer8"
+ inkscape:groupmode="layer"
+ inkscape:label="czarne_zakonczenie">
+ <path
+ d="M 598.01311,536.55723 C 600.20441,537.42196 600.08063,537.15475 602.54301,539.54052 C 605.03228,541.95242 606.46523,546.99904 606.46523,552.47934 C 606.46523,557.95963 604.98378,563.72181 602.21156,566.65028 C 599.46661,569.54992 600.14916,568.87697 598.01311,569.56876 C 598.69443,567.23400 599.21006,566.27195 599.55993,562.49949 C 599.90978,558.72709 599.95583,551.20377 599.61516,546.86925 C 599.27448,542.53473 598.71286,540.01617 598.01311,536.55723 z "
+ id="rect4267"
+ sodipodi:nodetypes="czzzczzc"
+ style="color:#000000;fill:#000000;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.067719966pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:block"
+ inkscape:export-filename="/home/boud/pencil.png"
+ inkscape:export-xdpi="37.290001"
+ inkscape:export-ydpi="25.269030" />
+ <path
+ d="M 598.05216,536.60308 C 600.24346,537.46780 600.11968,537.20059 602.58206,539.58637 C 605.07133,541.99826 606.50428,547.04488 606.50428,552.52518 C 606.50428,558.00548 605.02283,563.76766 602.25061,566.69612 C 599.50566,569.59576 600.18821,568.92282 598.05216,569.61460 C 598.73348,567.27984 599.13861,566.18807 599.48848,562.41566 C 599.83836,558.64320 599.55293,550.92535 599.37798,546.59083 C 599.20313,542.25889 598.75191,540.06202 598.05216,536.60308 z "
+ id="path4269"
+ sodipodi:nodetypes="czzzczzc"
+ style="color:#000000;fill:url(#radialGradient4894);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.25000000pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:block"
+ inkscape:export-filename="/home/boud/pencil.png"
+ inkscape:export-xdpi="37.290001"
+ inkscape:export-ydpi="25.269030" />
+ <path
+ d="M 598.03473,536.58259 C 599.38111,536.60420 599.36721,538.38435 599.74316,539.65763 C 600.09923,540.86358 600.43966,542.74318 600.64446,544.30814 C 600.77491,545.30499 601.05068,550.76698 601.01163,551.99376 C 600.99138,552.62961 600.81768,557.50652 600.72191,558.66757 C 600.61303,559.98727 600.46746,563.66986 599.60671,566.58394 C 598.75026,569.48358 598.76591,569.61578 598.03473,569.59418 C 598.31521,567.25935 599.18061,565.87349 599.44186,562.33037 C 599.70341,558.78297 599.71816,557.03639 599.67588,554.07746 C 599.63296,551.07251 599.45918,548.25682 599.38413,546.18128 C 599.30906,544.05989 598.91526,539.97673 598.03473,536.58259 z "
+ id="path4899"
+ sodipodi:nodetypes="czszszczszc"
+ style="color:#000000;fill:url(#linearGradient5526);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.13853176pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:block"
+ inkscape:export-filename="/home/boud/pencil.png"
+ inkscape:export-xdpi="37.290001"
+ inkscape:export-ydpi="25.269030" />
+ </g>
+ <metadata
+ id="metadata1378">
+ <rdf:RDF
+ id="RDF1379">
+ <cc:Work
+ rdf:about=""
+ id="Work1380">
+ <dc:title
+ id="title1381">pencil</dc:title>
+ <dc:description
+ id="description1383" />
+ <dc:subject
+ id="subject1384">
+ <rdf:Bag
+ id="Bag1385">
+ <rdf:li
+ id="li1386" />
+ <rdf:li
+ id="li1387">office</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ <dc:publisher
+ id="publisher1389">
+ <cc:Agent
+ rdf:about="http://www.openclipart.org"
+ id="Agent1390">
+ <dc:title
+ id="title1391">Karol Szczerba</dc:title>
+ </cc:Agent>
+ </dc:publisher>
+ <dc:creator
+ id="creator1393">
+ <cc:Agent
+ rdf:about=""
+ id="Agent1394">
+ <dc:title
+ id="title1395">Karol Szczerba</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:rights
+ id="rights1397">
+ <cc:Agent
+ rdf:about=""
+ id="Agent1398">
+ <dc:title
+ id="title1399">Karol Szczerba</dc:title>
+ </cc:Agent>
+ </dc:rights>
+ <dc:date
+ id="date1401" />
+ <dc:format
+ id="format1402">image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage"
+ id="type1404" />
+ <cc:license
+ rdf:resource="Public Domain"
+ id="license1405">
+ <dc:date
+ id="date1406" />
+ </cc:license>
+ <dc:language
+ id="language1407">en</dc:language>
+ </cc:Work>
+ <cc:License
+ rdf:about="Public Domain"
+ id="License1409">
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/Reproduction"
+ id="permits1410" />
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/Distribution"
+ id="permits1411" />
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/DerivativeWorks"
+ id="permits1412" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+</svg>
diff --git a/chalk/plugins/paintops/defaultpaintops/src/pencil_jonathan_dietrich_01.svg b/chalk/plugins/paintops/defaultpaintops/src/pencil_jonathan_dietrich_01.svg
new file mode 100644
index 00000000..4b29bb9a
--- /dev/null
+++ b/chalk/plugins/paintops/defaultpaintops/src/pencil_jonathan_dietrich_01.svg
@@ -0,0 +1,434 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
+"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ height="1.0000000in"
+ id="svg1"
+ inkscape:version="0.40"
+ sodipodi:docbase="/home/boud"
+ sodipodi:docname="pencil_jonathan_dietrich_01.svg"
+ sodipodi:version="0.32"
+ width="8.0000000in"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <metadata
+ id="metadata2">
+ <rdf:RDF
+ id="RDF3">
+ <cc:Work
+ rdf:about=""
+ id="Work4">
+ <dc:title
+ id="title5">Pencil</dc:title>
+ <dc:description
+ id="description7">HASH(0x885a0cc)</dc:description>
+ <dc:subject
+ id="subject9">
+ <rdf:Bag
+ id="Bag10">
+ <rdf:li
+ id="li11">pencil</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ <dc:publisher
+ id="publisher13">
+ <cc:Agent
+ rdf:about="http://www.openclipart.org"
+ id="Agent14">
+ <dc:title
+ id="title15">Jonathan Dietrich</dc:title>
+ </cc:Agent>
+ </dc:publisher>
+ <dc:creator
+ id="creator17">
+ <cc:Agent
+ id="Agent18">
+ <dc:title
+ id="title19">Jonathan Dietrich</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:rights
+ id="rights21">
+ <cc:Agent
+ id="Agent22">
+ <dc:title
+ id="title23">Jonathan Dietrich</dc:title>
+ </cc:Agent>
+ </dc:rights>
+ <dc:date
+ id="date25">HASH(0x846b07c)</dc:date>
+ <dc:format
+ id="format27">image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage"
+ id="type29" />
+ <cc:license
+ rdf:resource="http://web.resource.org/cc/PublicDomain"
+ id="license30" />
+ <dc:language
+ id="language31">en</dc:language>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://web.resource.org/cc/PublicDomain"
+ id="License33">
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/Reproduction"
+ id="permits34" />
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/Distribution"
+ id="permits35" />
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/DerivativeWorks"
+ id="permits36" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs3">
+ <linearGradient
+ id="linearGradient1662">
+ <stop
+ id="stop1663"
+ offset="0.0000000"
+ style="stop-color:#000000;stop-opacity:0.0000000;" />
+ <stop
+ id="stop1666"
+ offset="0.50000000"
+ style="stop-color:#000000;stop-opacity:0.15686275;" />
+ <stop
+ id="stop1664"
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient1654">
+ <stop
+ id="stop1655"
+ offset="0.0000000"
+ style="stop-color:#a27d54;stop-opacity:1.0000000;" />
+ <stop
+ id="stop1656"
+ offset="1.0000000"
+ style="stop-color:#f5bd7f;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient1650">
+ <stop
+ id="stop1651"
+ offset="0.0000000"
+ style="stop-color:#bf6663;stop-opacity:1.0000000;" />
+ <stop
+ id="stop1652"
+ offset="1.0000000"
+ style="stop-color:#ff8884;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient1646">
+ <stop
+ id="stop1647"
+ offset="0.0000000"
+ style="stop-color:#969696;stop-opacity:1.0000000;" />
+ <stop
+ id="stop1648"
+ offset="1.0000000"
+ style="stop-color:#ededed;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient1630">
+ <stop
+ id="stop1631"
+ offset="0.0000000"
+ style="stop-color:#d2b200;stop-opacity:1.0000000;" />
+ <stop
+ id="stop1658"
+ offset="0.50000000"
+ style="stop-color:#ffc300;stop-opacity:1.0000000;" />
+ <stop
+ id="stop1659"
+ offset="0.75000000"
+ style="stop-color:#ffed00;stop-opacity:1.0000000;" />
+ <stop
+ id="stop1632"
+ offset="1.0000000"
+ style="stop-color:#ffdd00;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ gradientTransform="matrix(-3.254365,0.000000,0.000000,0.316670,759.8405,-110.7512)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1633"
+ inkscape:collect="always"
+ x1="126.08783"
+ x2="126.08781"
+ xlink:href="#linearGradient1630"
+ y1="528.57239"
+ y2="377.06293" />
+ <linearGradient
+ gradientTransform="matrix(-1.364241,0.000000,0.000000,0.755408,759.8405,-110.7512)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1649"
+ inkscape:collect="always"
+ x1="505.71970"
+ x2="505.71970"
+ xlink:href="#linearGradient1646"
+ y1="221.53720"
+ y2="157.34721" />
+ <linearGradient
+ gradientTransform="matrix(-1.056744,0.000000,0.000000,0.975220,777.4291,-110.7513)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1653"
+ inkscape:collect="always"
+ x1="708.08087"
+ x2="707.66553"
+ xlink:href="#linearGradient1650"
+ y1="172.28430"
+ y2="122.22205" />
+ <linearGradient
+ gradientTransform="matrix(-1.658785,0.000000,0.000000,0.621272,750.7865,-111.0021)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1657"
+ inkscape:collect="always"
+ x1="50.804340"
+ x2="60.266266"
+ xlink:href="#linearGradient1654"
+ y1="269.75226"
+ y2="193.19295" />
+ <linearGradient
+ gradientTransform="matrix(-16.21046,0.000000,0.000000,6.357360e-2,758.2825,-106.7460)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1673"
+ inkscape:collect="always"
+ x1="25.595356"
+ x2="25.595356"
+ xlink:href="#linearGradient1662"
+ y1="2122.9712"
+ y2="2157.5330" />
+ <linearGradient
+ gradientTransform="matrix(-16.21046,0.000000,0.000000,6.357360e-2,762.2010,-121.8183)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1675"
+ inkscape:collect="always"
+ x1="25.595356"
+ x2="25.595356"
+ xlink:href="#linearGradient1662"
+ y1="2122.9712"
+ y2="2157.5330" />
+ <linearGradient
+ gradientTransform="matrix(-16.21046,0.000000,0.000000,6.357360e-2,761.1623,-89.12134)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1677"
+ inkscape:collect="always"
+ x1="25.595356"
+ x2="25.595356"
+ xlink:href="#linearGradient1662"
+ y1="2122.9712"
+ y2="2157.5330" />
+ <linearGradient
+ gradientTransform="matrix(-0.523707,0.000000,0.000000,1.946019,755.9293,-109.9526)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1681"
+ inkscape:collect="always"
+ x1="1327.0875"
+ x2="1351.4697"
+ xlink:href="#linearGradient1646"
+ y1="80.989799"
+ y2="62.197636" />
+ <linearGradient
+ gradientTransform="matrix(-0.523707,0.000000,0.000000,1.946019,761.7922,-109.9526)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1683"
+ inkscape:collect="always"
+ x1="1327.0875"
+ x2="1351.4697"
+ xlink:href="#linearGradient1646"
+ y1="80.989799"
+ y2="62.197636" />
+ <linearGradient
+ gradientTransform="matrix(-0.523707,0.000000,0.000000,1.946019,767.6551,-109.9526)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1685"
+ inkscape:collect="always"
+ x1="1327.0875"
+ x2="1351.4697"
+ xlink:href="#linearGradient1646"
+ y1="80.989799"
+ y2="62.197636" />
+ <linearGradient
+ gradientTransform="matrix(-0.523707,0.000000,0.000000,1.946019,791.1066,-109.9526)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1693"
+ inkscape:collect="always"
+ x1="1327.0875"
+ x2="1351.4697"
+ xlink:href="#linearGradient1646"
+ y1="80.989799"
+ y2="62.197636" />
+ <linearGradient
+ gradientTransform="matrix(-0.523707,0.000000,0.000000,1.946019,796.9695,-109.9526)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1697"
+ inkscape:collect="always"
+ x1="1327.0875"
+ x2="1351.4697"
+ xlink:href="#linearGradient1646"
+ y1="80.989799"
+ y2="62.197636" />
+ <linearGradient
+ gradientTransform="matrix(-0.523707,0.000000,0.000000,1.946019,802.8323,-109.9526)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1699"
+ inkscape:collect="always"
+ x1="1327.0875"
+ x2="1351.4697"
+ xlink:href="#linearGradient1646"
+ y1="80.989799"
+ y2="62.197636" />
+ </defs>
+ <sodipodi:namedview
+ bordercolor="#666666"
+ borderopacity="1.0"
+ id="base"
+ inkscape:current-layer="layer1"
+ inkscape:cx="360.00000"
+ inkscape:cy="45.000000"
+ inkscape:guide-bbox="true"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:window-height="999"
+ inkscape:window-width="1283"
+ inkscape:window-x="47"
+ inkscape:window-y="27"
+ inkscape:zoom="1.6541667"
+ pagecolor="#ffffff"
+ showguides="true" />
+ <g
+ id="layer1"
+ inkscape:groupmode="layer"
+ inkscape:label="Layer 1">
+ <path
+ d="M 592.38982,8.7978966 L 114.27426,8.2474158 C 114.27426,8.2474158 102.52077,7.7798401 102.52077,33.335829 C 102.52077,56.689895 113.53982,57.790857 113.53982,57.790857 L 594.77674,57.790857 C 594.77674,57.790857 602.71148,55.787702 601.66922,55.291203 C 600.62695,54.794711 599.23728,55.804875 597.84759,54.124745 C 596.45790,52.444617 595.06823,50.000885 594.02596,46.449979 C 592.98371,42.899074 592.41869,35.516246 592.41869,29.407432 C 592.41869,23.298620 592.84600,21.510571 593.68170,18.177576 C 594.51740,14.844590 595.63167,12.691402 596.74594,11.301822 C 597.86021,9.9122350 597.50562,10.800085 598.34131,10.521495 C 599.17702,10.242916 592.38982,8.7978966 592.38982,8.7978966 z "
+ id="path1006"
+ inkscape:export-filename="/home/boud/eraser.png"
+ inkscape:export-xdpi="25.269030"
+ inkscape:export-ydpi="25.269030"
+ sodipodi:nodetypes="cccccssscsssc"
+ style="fill:url(#linearGradient1633);fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.21643910pt;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1.0000000" />
+ <path
+ d="M 598.21122,14.439873 L 106.65310,14.245243"
+ id="path1674"
+ inkscape:export-filename="/home/boud/eraser.png"
+ inkscape:export-xdpi="25.269030"
+ inkscape:export-ydpi="25.269030"
+ sodipodi:nodetypes="cc"
+ style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:url(#linearGradient1675);stroke-width:2.1643910;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" />
+ <path
+ d="M 597.95155,46.747604 L 103.66700,46.942235"
+ id="path1676"
+ inkscape:export-filename="/home/boud/eraser.png"
+ inkscape:export-xdpi="25.269030"
+ inkscape:export-ydpi="25.269030"
+ sodipodi:nodetypes="cc"
+ style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:url(#linearGradient1677);stroke-width:2.1643910;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" />
+ <path
+ d="M 594.29274,29.414859 L 101.69598,29.317549"
+ id="path1661"
+ inkscape:export-filename="/home/boud/eraser.png"
+ inkscape:export-xdpi="25.269030"
+ inkscape:export-ydpi="25.269030"
+ sodipodi:nodetypes="cc"
+ style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:url(#linearGradient1673);stroke-width:2.1643910;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" />
+ <path
+ d="M 56.212243,8.2425325 L 14.333823,8.2474191 C 14.333823,8.2474191 2.5803330,9.4312952 2.5803330,33.335842 C 2.5803330,57.790880 13.599383,57.790880 13.599383,57.790880 L 56.196493,57.790880 C 56.196493,57.790880 45.079033,56.567471 45.079033,32.132201 C 45.079033,7.6969293 56.212243,8.2425325 56.212243,8.2425325 z "
+ id="path1640"
+ inkscape:export-filename="/home/boud/eraser.png"
+ inkscape:export-xdpi="25.269030"
+ inkscape:export-ydpi="25.269030"
+ sodipodi:nodetypes="ccccccc"
+ style="fill:url(#linearGradient1653);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.25000000pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000" />
+ <path
+ d="M 115.46247,8.2425204 L 54.419283,8.2474070 C 54.419283,8.2474070 42.665793,9.4312826 42.665793,33.335820 C 42.665793,57.790847 53.684843,57.790847 53.684843,57.790847 L 115.37718,57.790847 C 115.37718,57.790847 104.25973,56.567439 104.25973,32.132179 C 104.25973,7.6969174 115.46247,8.2425204 115.46247,8.2425204 z "
+ id="path1645"
+ inkscape:export-filename="/home/boud/eraser.png"
+ inkscape:export-xdpi="25.269030"
+ inkscape:export-ydpi="25.269030"
+ sodipodi:nodetypes="ccccccc"
+ style="fill:url(#linearGradient1649);fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.21643910pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000" />
+ <path
+ d="M 592.60935,8.8259330 L 714.80057,33.322417 L 594.72085,57.818893 C 594.72085,57.818893 594.37129,55.805894 593.04868,53.791332 C 592.02163,52.226987 587.43587,49.264318 587.53925,47.243595 C 587.64030,45.268231 593.00050,42.626259 593.00050,39.471510 C 593.00050,35.835686 583.73322,34.330639 583.73322,29.727408 C 583.73322,25.948115 591.74741,23.534144 591.74741,21.076333 C 591.74741,17.684997 586.94880,16.159860 586.82708,14.541172 C 586.70796,12.956956 592.93177,11.676165 593.26691,10.738677 C 593.50364,10.076490 592.60935,8.8259330 592.60935,8.8259330 z "
+ id="path1007"
+ inkscape:export-filename="/home/boud/eraser.png"
+ inkscape:export-xdpi="25.269030"
+ inkscape:export-ydpi="25.269030"
+ sodipodi:nodetypes="cccssscsssc"
+ style="fill:url(#linearGradient1657);fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.21643910pt;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1.0000000" />
+ <path
+ d="M 689.51035,28.508228 L 713.56524,33.327058 L 689.94377,38.145879 C 689.94377,38.145879 687.75680,37.905214 687.75680,33.098433 C 687.75680,28.291653 689.51035,28.508228 689.51035,28.508228 z "
+ id="path1008"
+ inkscape:export-filename="/home/boud/eraser.png"
+ inkscape:export-xdpi="25.269030"
+ inkscape:export-ydpi="25.269030"
+ sodipodi:nodetypes="ccccc"
+ style="fill:#000000;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.21643915pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000" />
+ <path
+ d="M 62.399193,8.3905104 L 60.827183,8.3953619 C 60.827183,8.3953619 49.138973,9.5726643 49.138973,33.344421 C 49.138973,57.663608 60.096823,57.663608 60.096823,57.663608 L 62.314383,57.663608 C 62.314383,57.663608 50.871353,57.705039 50.871353,33.405503 C 50.871353,9.1059758 62.399193,8.3905104 62.399193,8.3905104 z "
+ id="path1678"
+ inkscape:export-filename="/home/boud/eraser.png"
+ inkscape:export-xdpi="25.269030"
+ inkscape:export-ydpi="25.269030"
+ sodipodi:nodetypes="ccccccc"
+ style="fill:url(#linearGradient1681);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.25000000pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000" />
+ <path
+ d="M 68.262063,8.3905104 L 66.690053,8.3953619 C 66.690053,8.3953619 55.001843,9.5726643 55.001843,33.344421 C 55.001843,57.663608 65.959693,57.663608 65.959693,57.663608 L 68.177253,57.663608 C 68.177253,57.663608 56.734223,57.705039 56.734223,33.405503 C 56.734223,9.1059758 68.262063,8.3905104 68.262063,8.3905104 z "
+ id="path1682"
+ inkscape:export-filename="/home/boud/eraser.png"
+ inkscape:export-xdpi="25.269030"
+ inkscape:export-ydpi="25.269030"
+ sodipodi:nodetypes="ccccccc"
+ style="fill:url(#linearGradient1683);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.25000000pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000" />
+ <path
+ d="M 74.124933,8.3905104 L 72.552923,8.3953619 C 72.552923,8.3953619 60.864713,9.5726643 60.864713,33.344421 C 60.864713,57.663608 71.822563,57.663608 71.822563,57.663608 L 74.040123,57.663608 C 74.040123,57.663608 62.597103,57.705039 62.597103,33.405503 C 62.597103,9.1059758 74.124933,8.3905104 74.124933,8.3905104 z "
+ id="path1684"
+ inkscape:export-filename="/home/boud/eraser.png"
+ inkscape:export-xdpi="25.269030"
+ inkscape:export-ydpi="25.269030"
+ sodipodi:nodetypes="ccccccc"
+ style="fill:url(#linearGradient1685);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.25000000pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000" />
+ <path
+ d="M 97.576423,8.3905104 L 96.004413,8.3953619 C 96.004413,8.3953619 84.316203,9.5726643 84.316203,33.344421 C 84.316203,57.663608 95.274053,57.663608 95.274053,57.663608 L 97.491613,57.663608 C 97.491613,57.663608 86.048593,57.705039 86.048593,33.405503 C 86.048593,9.1059758 97.576423,8.3905104 97.576423,8.3905104 z "
+ id="path1692"
+ inkscape:export-filename="/home/boud/eraser.png"
+ inkscape:export-xdpi="25.269030"
+ inkscape:export-ydpi="25.269030"
+ sodipodi:nodetypes="ccccccc"
+ style="fill:url(#linearGradient1693);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.25000000pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000" />
+ <path
+ d="M 103.43930,8.3905104 L 101.86728,8.3953619 C 101.86728,8.3953619 90.179073,9.5726643 90.179073,33.344421 C 90.179073,57.663608 101.13692,57.663608 101.13692,57.663608 L 103.35448,57.663608 C 103.35448,57.663608 91.911463,57.705039 91.911463,33.405503 C 91.911463,9.1059758 103.43930,8.3905104 103.43930,8.3905104 z "
+ id="path1696"
+ inkscape:export-filename="/home/boud/eraser.png"
+ inkscape:export-xdpi="25.269030"
+ inkscape:export-ydpi="25.269030"
+ sodipodi:nodetypes="ccccccc"
+ style="fill:url(#linearGradient1697);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.25000000pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000" />
+ <path
+ d="M 109.30217,8.3905104 L 107.73016,8.3953619 C 107.73016,8.3953619 96.041953,9.5726643 96.041953,33.344421 C 96.041953,57.663608 106.99979,57.663608 106.99979,57.663608 L 109.21736,57.663608 C 109.21736,57.663608 97.774333,57.705039 97.774333,33.405503 C 97.774333,9.1059758 109.30217,8.3905104 109.30217,8.3905104 z "
+ id="path1698"
+ inkscape:export-filename="/home/boud/eraser.png"
+ inkscape:export-xdpi="25.269030"
+ inkscape:export-ydpi="25.269030"
+ sodipodi:nodetypes="ccccccc"
+ style="fill:url(#linearGradient1699);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.25000000pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000" />
+ <path
+ d="M 91.939683,8.2289912 L 76.778513,8.2911122 C 76.778513,8.2911122 65.065543,9.4709063 65.065543,33.293029 C 65.065543,57.663743 76.046613,57.663743 76.046613,57.663743 L 91.931073,57.720994 C 91.931073,57.720994 80.775573,56.444553 80.775573,32.093537 C 80.775573,7.7425207 91.939683,8.2289912 91.939683,8.2289912 z "
+ id="path1700"
+ inkscape:export-filename="/home/boud/eraser.png"
+ inkscape:export-xdpi="25.269030"
+ inkscape:export-ydpi="25.269030"
+ sodipodi:nodetypes="ccccccc"
+ style="fill:#000000;fill-opacity:0.87005651;fill-rule:evenodd;stroke:#000000;stroke-width:0.21643901pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000" />
+ </g>
+</svg>
diff --git a/chalk/plugins/paintops/defaultpaintops/src/pennello_mauro_olivo_01.svg b/chalk/plugins/paintops/defaultpaintops/src/pennello_mauro_olivo_01.svg
new file mode 100644
index 00000000..b79fcd57
--- /dev/null
+++ b/chalk/plugins/paintops/defaultpaintops/src/pennello_mauro_olivo_01.svg
@@ -0,0 +1,616 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
+"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ height="297mm"
+ id="svg1"
+ inkscape:version="0.40"
+ sodipodi:docbase="/home/boud"
+ sodipodi:docname="pennello_mauro_olivo_01.svg"
+ sodipodi:version="0.32"
+ width="210mm"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ inkscape:export-filename="/home/boud/brush.png"
+ inkscape:export-xdpi="19.260000"
+ inkscape:export-ydpi="19.260000">
+ <defs
+ id="defs3">
+ <linearGradient
+ id="linearGradient15131">
+ <stop
+ id="stop15132"
+ offset="0.0000000"
+ style="stop-color:#004800;stop-opacity:1.0000000;" />
+ <stop
+ id="stop15146"
+ offset="0.50000000"
+ style="stop-color:#7fbd7f;stop-opacity:0.49803922;" />
+ <stop
+ id="stop15147"
+ offset="0.75000000"
+ style="stop-color:#bfdebf;stop-opacity:0.24705882;" />
+ <stop
+ id="stop15148"
+ offset="0.87500000"
+ style="stop-color:#dfeedf;stop-opacity:0.12156863;" />
+ <stop
+ id="stop15149"
+ offset="0.93750000"
+ style="stop-color:#eff6ef;stop-opacity:0.058823530;" />
+ <stop
+ id="stop15150"
+ offset="0.96875000"
+ style="stop-color:#f7faf7;stop-opacity:0.027450981;" />
+ <stop
+ id="stop15151"
+ offset="0.98437500"
+ style="stop-color:#fbfcfb;stop-opacity:0.011764706;" />
+ <stop
+ id="stop15152"
+ offset="0.99000001"
+ style="stop-color:#fdfdfd;stop-opacity:0.0039215689;" />
+ <stop
+ id="stop15133"
+ offset="1.0000000"
+ style="stop-color:#ffffff;stop-opacity:0.0000000;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient1800">
+ <stop
+ id="stop1801"
+ offset="0.0000000"
+ style="stop-color:#ffffff;stop-opacity:0.62626261;" />
+ <stop
+ id="stop1802"
+ offset="1.0000000"
+ style="stop-color:#ffffff;stop-opacity:0.0000000;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient1664">
+ <stop
+ id="stop1665"
+ offset="0.0000000"
+ style="stop-color:#000000;stop-opacity:1.0000000;" />
+ <stop
+ id="stop1666"
+ offset="1.0000000"
+ style="stop-color:#ffffff;stop-opacity:0.0000000;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient1659">
+ <stop
+ id="stop1660"
+ offset="0.0000000"
+ style="stop-color:#ffffff;stop-opacity:0.77777779;" />
+ <stop
+ id="stop1661"
+ offset="1.0000000"
+ style="stop-color:#ffffff;stop-opacity:0.0000000;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient1653">
+ <stop
+ id="stop1654"
+ offset="0.0000000"
+ style="stop-color:#ffffff;stop-opacity:0.61616164;" />
+ <stop
+ id="stop1655"
+ offset="1.0000000"
+ style="stop-color:#2eff19;stop-opacity:0.0000000;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient1628">
+ <stop
+ id="stop1629"
+ offset="0.0000000"
+ style="stop-color:#717674;stop-opacity:1.0000000;" />
+ <stop
+ id="stop1630"
+ offset="1.0000000"
+ style="stop-color:#ffffff;stop-opacity:0.0000000;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient1617">
+ <stop
+ id="stop1618"
+ offset="0.0000000"
+ style="stop-color:#ffffff;stop-opacity:1.0000000;" />
+ <stop
+ id="stop1619"
+ offset="1.0000000"
+ style="stop-color:#ffffff;stop-opacity:0.0000000;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient1608">
+ <stop
+ id="stop1609"
+ offset="0.0000000"
+ style="stop-color:#004500;stop-opacity:1.0000000;" />
+ <stop
+ id="stop1611"
+ offset="0.50000000"
+ style="stop-color:#00814c;stop-opacity:1.0000000;" />
+ <stop
+ id="stop1610"
+ offset="1.0000000"
+ style="stop-color:#a54800;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient1598">
+ <stop
+ id="stop1599"
+ offset="0.0000000"
+ style="stop-color:#000000;stop-opacity:1.0000000;" />
+ <stop
+ id="stop1601"
+ offset="0.50000000"
+ style="stop-color:#7f7f7f;stop-opacity:1.0000000;" />
+ <stop
+ id="stop1600"
+ offset="1"
+ style="stop-color:#fff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient1595">
+ <stop
+ id="stop1596"
+ offset="0.0000000"
+ style="stop-color:#a25d00;stop-opacity:1.0000000;" />
+ <stop
+ id="stop1657"
+ offset="0.50000000"
+ style="stop-color:#ddae4c;stop-opacity:1.0000000;" />
+ <stop
+ id="stop1597"
+ offset="1.0000000"
+ style="stop-color:#ffe698;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient1592">
+ <stop
+ id="stop1593"
+ offset="0.0000000"
+ style="stop-color:#de8900;stop-opacity:1.0000000;" />
+ <stop
+ id="stop1594"
+ offset="1"
+ style="stop-color:#fff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient1584">
+ <stop
+ id="stop1585"
+ offset="0"
+ style="stop-color:#000;stop-opacity:1;" />
+ <stop
+ id="stop1586"
+ offset="1"
+ style="stop-color:#fff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient1588"
+ inkscape:collect="always"
+ x1="1193.5865"
+ x2="1330.3144"
+ xlink:href="#linearGradient1595"
+ y1="112.08835"
+ y2="112.08835"
+ gradientTransform="scale(0.301850,3.312902)"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ cx="556.83325"
+ cy="673.03480"
+ fx="558.31175"
+ fy="673.03480"
+ id="radialGradient1607"
+ inkscape:collect="always"
+ r="121.23903"
+ xlink:href="#linearGradient1608"
+ gradientTransform="scale(0.665788,1.501979)"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient1613"
+ inkscape:collect="always"
+ x1="511.84784"
+ x2="664.54880"
+ xlink:href="#linearGradient1598"
+ y1="462.29474"
+ y2="458.95388"
+ gradientTransform="scale(0.603506,1.656985)"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ id="radialGradient1621"
+ inkscape:collect="always"
+ xlink:href="#linearGradient1617"
+ gradientTransform="scale(0.747545,1.337712)"
+ cx="478.63759"
+ cy="683.14977"
+ fx="478.63759"
+ fy="683.14977"
+ r="17.256384"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ cx="478.63759"
+ cy="683.14977"
+ fx="478.63759"
+ fy="683.14977"
+ id="radialGradient1658"
+ inkscape:collect="always"
+ r="17.256384"
+ xlink:href="#linearGradient1659"
+ gradientTransform="scale(0.747545,1.337712)"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ cx="446.43968"
+ cy="1039.6351"
+ fx="446.79044"
+ fy="1040.7757"
+ id="radialGradient15130"
+ inkscape:collect="always"
+ r="79.796235"
+ xlink:href="#linearGradient15131"
+ gradientTransform="scale(1.083274,0.923127)"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ cx="478.63759"
+ cy="683.14977"
+ fx="478.63759"
+ fy="683.14977"
+ id="radialGradient15163"
+ inkscape:collect="always"
+ r="13.148508"
+ xlink:href="#linearGradient1659"
+ gradientTransform="scale(0.747545,1.337712)"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1617"
+ id="radialGradient1656"
+ gradientTransform="scale(0.747545,1.337712)"
+ cx="478.63759"
+ cy="683.14977"
+ fx="478.63759"
+ fy="683.14977"
+ r="17.256384"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1659"
+ id="radialGradient1657"
+ cx="478.63759"
+ cy="683.14977"
+ fx="478.63759"
+ fy="683.14977"
+ r="17.256384"
+ gradientTransform="scale(0.747545,1.337712)"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1659"
+ id="radialGradient1659"
+ cx="478.63759"
+ cy="683.14977"
+ fx="478.63759"
+ fy="683.14977"
+ r="17.256384"
+ gradientTransform="scale(0.747545,1.337712)"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1659"
+ id="radialGradient1673"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="scale(0.747545,1.337712)"
+ cx="478.63759"
+ cy="683.14977"
+ fx="478.63759"
+ fy="683.14977"
+ r="17.256384" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1617"
+ id="radialGradient1674"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="scale(0.747545,1.337712)"
+ cx="478.63759"
+ cy="683.14977"
+ fx="478.63759"
+ fy="683.14977"
+ r="17.256384" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1659"
+ id="radialGradient1675"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="scale(0.747545,1.337712)"
+ cx="478.63759"
+ cy="683.14977"
+ fx="478.63759"
+ fy="683.14977"
+ r="13.148508" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1659"
+ id="radialGradient1676"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="scale(0.747545,1.337712)"
+ cx="478.63759"
+ cy="683.14977"
+ fx="478.63759"
+ fy="683.14977"
+ r="17.256384" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1598"
+ id="linearGradient1677"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="scale(0.603506,1.656985)"
+ x1="511.84784"
+ y1="462.29474"
+ x2="664.54880"
+ y2="458.95388" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1659"
+ id="radialGradient1678"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="scale(0.747545,1.337712)"
+ cx="478.63759"
+ cy="683.14977"
+ fx="478.63759"
+ fy="683.14977"
+ r="17.256384" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1617"
+ id="radialGradient1679"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="scale(0.747545,1.337712)"
+ cx="478.63759"
+ cy="683.14977"
+ fx="478.63759"
+ fy="683.14977"
+ r="17.256384" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1608"
+ id="radialGradient1680"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(5.549835e-3,0.634975,-1.773650,1.011171e-2,1038.823,138.4314)"
+ cx="556.83325"
+ cy="673.03480"
+ fx="558.31175"
+ fy="673.03480"
+ r="121.23903" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1595"
+ id="linearGradient1681"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.841587e-3,0.305219,-2.863318,2.364665e-2,776.1582,114.7272)"
+ x1="1193.5865"
+ y1="112.08835"
+ x2="1330.3144"
+ y2="112.08835" />
+ </defs>
+ <sodipodi:namedview
+ bordercolor="#666666"
+ borderopacity="1.0"
+ id="base"
+ inkscape:cx="297.63779"
+ inkscape:cy="454.90245"
+ inkscape:guide-bbox="false"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:window-height="942"
+ inkscape:window-width="1272"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:zoom="0.92054809"
+ pagecolor="#ffffff"
+ showborder="false"
+ showguides="false">
+ <sodipodi:guide
+ id="guide918"
+ orientation="horizontal"
+ position="506.59301" />
+ <sodipodi:guide
+ id="guide919"
+ orientation="horizontal"
+ position="500.99186" />
+ <sodipodi:guide
+ id="guide922"
+ orientation="horizontal"
+ position="360.02955" />
+ <sodipodi:guide
+ id="guide923"
+ orientation="horizontal"
+ position="365.31953" />
+ <sodipodi:guide
+ id="guide1572"
+ orientation="vertical"
+ position="85.253558" />
+ <sodipodi:guide
+ id="guide1573"
+ orientation="vertical"
+ position="71.174989" />
+ <sodipodi:guide
+ id="guide1574"
+ orientation="vertical"
+ position="99.332127" />
+ </sodipodi:namedview>
+ <path
+ d="M 769.97658,486.81260 C 769.90085,474.26161 753.99967,473.66070 735.62179,471.66366 C 517.14574,458.36371 361.34879,450.03856 177.81682,469.40472 C 159.52842,469.55575 144.86624,479.78157 144.94196,492.33256 C 145.01769,504.88357 159.80181,514.86620 178.09021,514.71516 C 361.85415,533.79423 548.39498,517.77619 735.95259,501.12302 C 754.23073,499.27093 769.35872,498.56352 769.97658,486.81260 z "
+ id="rect1581"
+ sodipodi:nodetypes="ccccccc"
+ style="fill:url(#linearGradient1681);fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:1.1734303pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0.49572650" />
+ <path
+ d="M 48.073160,478.03067 C 48.087914,489.97403 48.102681,501.91738 48.117448,513.86073 C 0.85876303,531.35767 -46.500497,537.34604 -81.647766,525.45820 C -104.01644,519.50544 -131.86117,520.45766 -139.00549,501.34675 C -143.09055,490.41920 -129.73846,496.31038 -120.21496,484.29524 C -55.360244,444.22124 48.073160,478.03067 48.073160,478.03067 z "
+ id="path1576"
+ sodipodi:nodetypes="cccscc"
+ style="fill:url(#radialGradient1680);fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.58188543pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0.36752138" />
+ <path
+ d="M 370.70305 913.85773 A 12.899923 23.084074 0 1 1 344.90321,913.85773 A 12.899923 23.084074 0 1 1 370.70305 913.85773 z"
+ id="path1622"
+ sodipodi:cx="357.80313"
+ sodipodi:cy="913.85773"
+ sodipodi:rx="12.899923"
+ sodipodi:ry="23.084074"
+ sodipodi:type="arc"
+ style="fill:url(#radialGradient1679);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
+ transform="matrix(6.101001e-3,1.011162,-12.20179,0.100768,11619.90,37.23681)" />
+ <path
+ d="M 370.70305 913.85773 A 12.899923 23.084074 0 1 1 344.90321,913.85773 A 12.899923 23.084074 0 1 1 370.70305 913.85773 z"
+ id="path1668"
+ sodipodi:cx="357.80313"
+ sodipodi:cy="913.85773"
+ sodipodi:rx="12.899923"
+ sodipodi:ry="23.084074"
+ sodipodi:type="arc"
+ style="fill:url(#radialGradient1678);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
+ transform="matrix(1.392760e-2,1.633299,-4.410336,2.577152e-2,3963.448,-103.3312)" />
+ <g
+ id="g1671"
+ style="stroke:#000000;stroke-opacity:0.49572650"
+ transform="matrix(6.101001e-3,1.011162,-0.864293,7.137744e-3,776.1582,114.7272)">
+ <path
+ d="M 343.52237,671.33150 C 343.32633,673.73849 341.75770,676.43905 341.57758,678.84728 C 342.57148,679.70505 343.19413,680.92386 343.19413,682.29375 C 343.19413,683.87456 342.31922,685.22430 341.04643,686.07572 C 324.55199,705.35504 357.35073,801.15078 340.97715,833.96892 L 342.91701,837.59839 L 341.46212,840.89236 L 344.67176,849.62815 L 392.99165,849.34080 L 395.31616,840.98387 L 393.74580,837.59839 L 395.84731,833.87742 C 378.83530,791.73991 412.50569,719.52485 395.66256,686.10622 C 394.35910,685.25837 393.44558,683.89688 393.44558,682.29375 C 393.44558,680.88864 394.13863,679.67684 395.17760,678.81678 C 395.01118,676.41812 393.45882,673.73393 393.27900,671.33150 C 375.74167,671.33148 361.05969,671.33150 343.52237,671.33150 z "
+ id="rect910"
+ sodipodi:nodetypes="ccccccccccccccccc"
+ style="fill:url(#linearGradient1677);fill-opacity:1.0000000;fill-rule:evenodd;stroke-width:0.84926434pt;stroke-linecap:butt;stroke-linejoin:miter" />
+ <path
+ d="M 343.36975,682.48174 L 393.50367,682.42041"
+ id="path1649"
+ style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke-width:2.0000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000" />
+ <path
+ d="M 342.72547,837.67100 L 393.98325,837.51088 L 393.98325,837.51088 L 393.98325,837.51088"
+ id="path1650"
+ style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke-width:2.0092726;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000" />
+ </g>
+ <path
+ d="M 370.70305 913.85773 A 12.899923 23.084074 0 1 1 344.90321,913.85773 A 12.899923 23.084074 0 1 1 370.70305 913.85773 z"
+ id="path1803"
+ sodipodi:cx="357.80313"
+ sodipodi:cy="913.85773"
+ sodipodi:rx="12.899923"
+ sodipodi:ry="23.084074"
+ sodipodi:type="arc"
+ style="fill:url(#radialGradient1676);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
+ transform="matrix(8.429002e-3,1.397000,-2.669140,2.204299e-2,2565.017,-13.88688)" />
+ <path
+ d="M 370.70305 913.85773 A 12.899923 23.084074 0 1 1 344.90321,913.85773 A 12.899923 23.084074 0 1 1 370.70305 913.85773 z"
+ id="path15162"
+ sodipodi:cx="357.80313"
+ sodipodi:cy="913.85773"
+ sodipodi:rx="12.899923"
+ sodipodi:ry="23.084074"
+ sodipodi:type="arc"
+ style="fill:url(#radialGradient1675);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
+ transform="matrix(1.151647e-2,1.317638,-3.646822,2.079076e-2,3303.435,0.107690)" />
+ <path
+ d="M 370.70305 913.85773 A 12.899923 23.084074 0 1 1 344.90321,913.85773 A 12.899923 23.084074 0 1 1 370.70305 913.85773 z"
+ id="path15164"
+ sodipodi:cx="357.80313"
+ sodipodi:cy="913.85773"
+ sodipodi:rx="12.899923"
+ sodipodi:ry="23.084074"
+ sodipodi:type="arc"
+ style="fill:url(#radialGradient1674);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
+ transform="matrix(6.101001e-3,1.011162,-12.20179,0.100768,11605.82,55.08689)" />
+ <path
+ d="M 370.70305 913.85773 A 12.899923 23.084074 0 1 1 344.90321,913.85773 A 12.899923 23.084074 0 1 1 370.70305 913.85773 z"
+ id="path15165"
+ sodipodi:cx="357.80313"
+ sodipodi:cy="913.85773"
+ sodipodi:rx="12.899923"
+ sodipodi:ry="23.084074"
+ sodipodi:type="arc"
+ style="fill:url(#radialGradient1673);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
+ transform="matrix(8.429002e-3,1.397000,-2.669140,2.204299e-2,2557.975,-37.22922)" />
+ <metadata
+ id="metadata1620">
+ <rdf:RDF
+ id="RDF1621">
+ <cc:Work
+ rdf:about=""
+ id="Work1622">
+ <dc:title
+ id="title1623">pennello</dc:title>
+ <dc:description
+ id="description1625">Created with The Inkscape</dc:description>
+ <dc:subject
+ id="subject1627">
+ <rdf:Bag
+ id="Bag1628">
+ <rdf:li
+ id="li1629" />
+ <rdf:li
+ id="li1630">office</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ <dc:publisher
+ id="publisher1632">
+ <cc:Agent
+ rdf:about="http://www.openclipart.org"
+ id="Agent1633">
+ <dc:title
+ id="title1634">Mauro Olivo</dc:title>
+ </cc:Agent>
+ </dc:publisher>
+ <dc:creator
+ id="creator1636">
+ <cc:Agent
+ rdf:about=""
+ id="Agent1637">
+ <dc:title
+ id="title1638">Mauro Olivo</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:rights
+ id="rights1640">
+ <cc:Agent
+ rdf:about=""
+ id="Agent1641">
+ <dc:title
+ id="title1642">Mauro Olivo</dc:title>
+ </cc:Agent>
+ </dc:rights>
+ <dc:date
+ id="date1644" />
+ <dc:format
+ id="format1645">image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage"
+ id="type1647" />
+ <cc:license
+ rdf:resource="Public Domain"
+ id="license1648">
+ <dc:date
+ id="date1649" />
+ </cc:license>
+ <dc:language
+ id="language1650">en</dc:language>
+ </cc:Work>
+ <cc:License
+ rdf:about="Public Domain"
+ id="License1652">
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/Reproduction"
+ id="permits1653" />
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/Distribution"
+ id="permits1654" />
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/DerivativeWorks"
+ id="permits1655" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+</svg>