Members of the KDE Community are recommended to subscribe to the kde-community mailing list at https://mail.kde.org/mailman/listinfo/kde-community to allow them to participate in important discussions and receive other important announcements

Commit ddb5c23f authored by Boudewijn Rempt's avatar Boudewijn Rempt

* Make plugins from paintops

* Refactor all code to distinguish between depths-as-in-bytes-per-pixel and
depth as in channels-per-pixel.
* Move filter tool to its own plugin
* Add the base for a wet+sticky paint model plugin
* Add a toolbox for paint ops, filters etc.

svn path=/trunk/koffice/; revision=390558
parent 97dd551e
......@@ -4,7 +4,7 @@ INCLUDES = $(KOFFICE_INCLUDES) -I$(interfacedir) $(KOPAINTER_INCLUDES) $(all_in
lib_LTLIBRARIES = libkritacommon.la
libkritacommon_la_SOURCES = dummycommon.cc
libkritacommon_la_LDFLAGS = $(all_libraries) -version-info 1:0 -no-undefined
libkritacommon_la_LIBADD = core/libkritacore.la ui/libkisui.la paintops/libkispaintops.la $(LCMS_LIBS) $(LIB_KOFFICEUI) $(LIB_KOPAINTER) $(LIB_XINPUTEXT)
libkritacommon_la_LIBADD = core/libkritacore.la ui/libkisui.la $(LCMS_LIBS) $(LIB_KOFFICEUI) $(LIB_KOPAINTER) $(LIB_XINPUTEXT)
## The part
kde_module_LTLIBRARIES = libkritapart.la
......@@ -30,7 +30,7 @@ kdemimedir = $(kde_mimedir)/application
rcdir = $(kde_datadir)/krita
rc_DATA = krita.rc krita_readonly.rc
SUBDIRS = ui core paintops . dtd tools modules plugins data pics
SUBDIRS = ui core . dtd paintops tools modules plugins data pics
# Needed to compile libkritacommon.la, which has no source files to itself
# but everything in static libs.
......
......@@ -58,7 +58,8 @@ User Interface
* Create templates for often-used image formats. Add save-as-template
* Check OASIS file saving.
* Fix gimp XCF import/export (ImageMagick hacking...)
* Fix imports to import metadata and image files in non-rgb encodings.
* Fix imports to import metadata and image files in non-rgb encodings -> move import
export code to color strategies.
Dockers
* Tabs in dockers drag-and-droppable (vector of docker
......
......@@ -45,11 +45,6 @@ int KIsImageIface::width() const
return m_img->width();
}
bool KIsImageIface::alpha() const
{
return m_img->alpha();
}
bool KIsImageIface::empty() const
{
return m_img->empty();
......
......@@ -35,7 +35,6 @@ k_dcop:
QString name()const;
int height() const;
int width() const;
bool alpha() const;
bool empty() const;
void setName(const QString& name);
......
......@@ -2,10 +2,10 @@
INCLUDES = -I$(srcdir)/builder \
-I$(srcdir)/resources \
-I$(srcdir)/visitors \
-I$(srcdir)/tool \
-I$(srcdir)/paintop \
-I$(srcdir)/tiles \
-I$(srcdir)/../ui \
-I$(srcdir)/tool \
-I../ui \
-I$(srcdir)/../ui/dialogs \
-I../ui/dialogs \
......@@ -31,86 +31,29 @@ libkritacore_la_LIBADD = tiles/libkistile.la \
tool/libkistool.la \
$(LIB_KOPAINTER)
libkritacore_la_SOURCES = kis_paint_device.cc \
kis_layer.cc \
kis_image.cc \
kis_doc.cc \
kis_view.cc \
kis_factory.cc \
kis_nameserver.cc \
kis_painter.cc \
kis_fill_painter.cc \
kis_gradient_painter.cc \
kis_convolution_painter.cc \
kis_cursor.cc \
kis_selection.cc \
kis_command.cc \
kis_background.cc \
kis_global.cc \
kis_config.cc \
kis_guide.cc \
kis_canvas_subject.cc \
kis_canvas_controller.cc \
kis_canvas_observer.cc \
kis_tile_command.cc \
kis_vec.cc \
kis_rect.cc \
kis_iterators_pixel.cc \
kis_histogram.cc \
KRayonViewIface.cc \
KRayonViewIface.skel \
KIsDocIface.cc \
KIsDocIface.skel \
KIsImageIface.cc \
KIsImageIface.skel \
kis_filter.cc \
kis_plugin_registry.cc \
kis_filter_registry.cc \
kis_selection_manager.cc \
kis_scale_visitor.cc \
kis_rotate_visitor.cc \
kis_cms.cc \
kis_quantum_operations.cc \
kis_clipboard.cc \
kis_pixel.cc
libkritacore_la_SOURCES = kis_paint_device.cc kis_layer.cc kis_image.cc \
kis_doc.cc kis_view.cc kis_factory.cc kis_nameserver.cc kis_painter.cc \
kis_fill_painter.cc kis_gradient_painter.cc kis_convolution_painter.cc kis_cursor.cc \
kis_selection.cc kis_command.cc kis_background.cc kis_global.cc kis_config.cc \
kis_guide.cc kis_canvas_subject.cc kis_canvas_controller.cc kis_canvas_observer.cc \
kis_tile_command.cc kis_vec.cc kis_rect.cc kis_iterators_pixel.cc kis_histogram.cc \
KRayonViewIface.cc KRayonViewIface.skel KIsDocIface.cc KIsDocIface.skel KIsImageIface.cc \
KIsImageIface.skel kis_selection_manager.cc kis_scale_visitor.cc kis_rotate_visitor.cc \
kis_cms.cc kis_quantum_operations.cc kis_clipboard.cc kis_pixel.cc kis_filter.cc \
kis_filter_registry.cc kis_plugin_loader.cc
noinst_HEADERS = kis_paint_device.h kis_layer.h kis_image.h kis_doc.h \
kis_view.h kis_factory.h kis_nameserver.h kis_cursor.h kis_selection.h \
kis_command.h kis_background.h kis_global.h kis_config.h kis_guide.h \
kis_canvas_subject.h kis_canvas_controller.h kis_canvas_observer.h kis_tile_command.h \
kis_vec.h kis_rect.h kis_iteratorpixeltrait.h kis_iterators_pixel.h \
kis_histogram.h KRayonViewIface.h KIsDocIface.h KIsImageIface.h \
kis_matrix.h kis_selection_manager.h kis_scale_visitor.h kis_rotate_visitor.h \
kis_cms.h kis_quantum_operations.h kis_filter.h kis_filter_registry.h
noinst_HEADERS = kis_paint_device.h \
kis_layer.h \
kis_image.h \
kis_doc.h \
kis_view.h \
kis_factory.h \
kis_nameserver.h \
kis_cursor.h \
kis_selection.h \
kis_command.h \
kis_background.h \
kis_global.h \
kis_config.h \
kis_guide.h \
kis_canvas_subject.h \
kis_canvas_controller.h \
kis_canvas_observer.h \
kis_tile_command.h \
kis_vec.h \
kis_rect.h \
kis_iteratorpixeltrait.h \
kis_iterators_pixel.h \
kis_histogram.h \
kis_plugin_registry.h \
KRayonViewIface.h \
KIsDocIface.h \
KIsImageIface.h \
kis_matrix.h \
kis_filter.h \
kis_filter_registry.h \
kis_selection_manager.h \
kis_scale_visitor.h \
kis_rotate_visitor.h \
kis_cms.h \
kis_quantum_operations.h
libkritacore_la_METASOURCES = AUTO
libkritacore_la_LDFLAGS = $(all_libraries)
SUBDIRS = tiles builder strategy color_strategy paintop resources tool
SUBDIRS = tiles builder strategy color_strategy paintop resources tool
KDE_OPTIONS = nofinal
......@@ -205,7 +205,7 @@ KisImageBuilder_Result KisImageMagickConverter::decode(const KURL& uri, bool isB
emit notifyProgressStage(this, i18n("Importing..."), 0);
m_img = 0;
while ((image = RemoveFirstImageFromList(&images))) {
ViewInfo *vi = OpenCacheView(image);
......@@ -218,7 +218,7 @@ KisImageBuilder_Result KisImageMagickConverter::decode(const KURL& uri, bool isB
m_img->add(layer, 0);
for (Q_INT32 y = 0; y < image->rows; y ++)
for (Q_UINT32 y = 0; y < image->rows; y ++)
{
const PixelPacket *pp = AcquireCacheView(vi, 0, y, image->columns, 1, &ei);
......@@ -241,11 +241,11 @@ KisImageBuilder_Result KisImageMagickConverter::decode(const KURL& uri, bool isB
*(ptr++) = pp->green;
*(ptr++) = pp->red;
*(ptr++) = OPACITY_OPAQUE - pp->opacity;
pp++;
pp++;
hiter++;
}
emit notifyProgress(this, y * 100 / image->rows);
if (m_stop) {
......@@ -258,7 +258,7 @@ KisImageBuilder_Result KisImageMagickConverter::decode(const KURL& uri, bool isB
}
}
}
emit notifyProgressDone(this);
CloseCacheView(vi);
DestroyImage(image);
......@@ -368,7 +368,7 @@ KisImageBuilder_Result KisImageMagickConverter::buildFile(const KURL& uri, KisLa
image -> matte = MagickTrue;
else
image -> matte = MagickFalse;
#else
#else
image -> matte = layer -> alpha();
#endif
w = TILE_WIDTH;
......@@ -531,6 +531,7 @@ QString KisImageMagickConverter::writeFilters()
mi = GetMagickInfo("*", &ei);
if (!mi)
kdDebug() << "Eek, no magick info!\n";
return s;
for (; mi; mi = reinterpret_cast<const MagickInfo*>(mi -> next)) {
......@@ -539,6 +540,7 @@ QString KisImageMagickConverter::writeFilters()
if (mi -> encoder) {
name = mi -> name;
kdDebug() << "Found: " << name << "\n";
description = mi -> description;
if (!description.isEmpty() && !description.contains('/')) {
......
......@@ -35,7 +35,6 @@
#include "kis_types.h"
namespace {
const Q_INT32 MAX_CHANNEL_ALPHA = 1;
const PIXELTYPE PIXEL_MASK = 0;
}
......@@ -87,16 +86,11 @@ bool KisColorSpaceAlpha::alpha() const
return true; // Of course!
}
Q_INT32 KisColorSpaceAlpha::depth() const
{
return MAX_CHANNEL_ALPHA;
}
// XXX: We convert the alpha space to create a mask for display in selection previews
// etc. No need to actually use the profiles here to create a mask image -- they don't
// need to be true color.
QImage KisColorSpaceAlpha::convertToQImage(const QUANTUM *data, Q_INT32 width, Q_INT32 height,
KisProfileSP /*srcProfile*/, KisProfileSP /*dstProfile*/,
QImage KisColorSpaceAlpha::convertToQImage(const QUANTUM *data, Q_INT32 width, Q_INT32 height,
KisProfileSP /*srcProfile*/, KisProfileSP /*dstProfile*/,
Q_INT32 /*renderingIntent*/)
{
......@@ -105,10 +99,10 @@ QImage KisColorSpaceAlpha::convertToQImage(const QUANTUM *data, Q_INT32 width, Q
Q_INT32 i = 0;
uchar *j = img.bits();
while ( i < width * height * depth()) {
while ( i < width * height * pixelSize()) {
// Temporary copy until I figure out something better
PIXELTYPE PIXEL_BLUE = 0;
PIXELTYPE PIXEL_GREEN = 1;
PIXELTYPE PIXEL_RED = 2;
......@@ -121,49 +115,49 @@ QImage KisColorSpaceAlpha::convertToQImage(const QUANTUM *data, Q_INT32 width, Q
*( j + PIXEL_GREEN ) = 0;
*( j + PIXEL_BLUE ) = 0;
*( j + PIXEL_ALPHA ) = *( data + i );
i += MAX_CHANNEL_ALPHA;
i += 1;
j += 4; // Because we're hard-coded 32 bits deep, 4 bytes
}
return img;
}
bool KisColorSpaceAlpha::convertPixelsTo(QUANTUM * src, KisProfileSP /*srcProfile*/,
QUANTUM * dst, KisStrategyColorSpaceSP dstColorStrategy, KisProfileSP dstProfile,
Q_UINT32 length,
QUANTUM * dst, KisStrategyColorSpaceSP dstColorStrategy, KisProfileSP dstProfile,
Q_UINT32 length,
Q_INT32 /*renderingIntent*/)
{
// kdDebug() << "KisColorSpaceAlpha:: convertPixels for " << length << " pixels from " << name() << " to " << dstColorStrategy -> name() << "\n";
// No lcms trickery here, we are a QColor + opacity channel
Q_INT32 size = dstColorStrategy -> size();
Q_INT32 size = dstColorStrategy -> pixelSize();
Q_UINT32 j = 0;
Q_UINT32 i = 0;
while ( i < length ) {
dstColorStrategy -> nativeColor(m_maskColor, OPACITY_OPAQUE - *(src + i), (dst + j), dstProfile);
i += 1;
j += size;
}
return true;
}
void KisColorSpaceAlpha::bitBlt(Q_INT32 stride,
QUANTUM *dst,
QUANTUM *dst,
Q_INT32 dststride,
QUANTUM *src,
QUANTUM *src,
Q_INT32 srcstride,
QUANTUM opacity,
Q_INT32 rows,
Q_INT32 cols,
Q_INT32 rows,
Q_INT32 cols,
CompositeOp op)
{
// kdDebug() << "KisColorSpaceAlpha::bitBlt. stride: " << stride
......@@ -203,7 +197,7 @@ void KisColorSpaceAlpha::bitBlt(Q_INT32 stride,
while (rows-- > 0) {
d = dst;
s = src;
for (i = cols; i > 0; i--, d += stride, s += stride) {
if (d[PIXEL_MASK] < s[PIXEL_MASK]) {
continue;
......@@ -211,16 +205,16 @@ void KisColorSpaceAlpha::bitBlt(Q_INT32 stride,
else {
d[PIXEL_MASK] = s[PIXEL_MASK];
}
}
dst += dststride;
src += srcstride;
}
return;
case COMPOSITE_OVER:
default:
if (opacity == OPACITY_TRANSPARENT)
if (opacity == OPACITY_TRANSPARENT)
return;
if (opacity != OPACITY_OPAQUE) {
while (rows-- > 0) {
......
......@@ -27,7 +27,7 @@
#include "kis_pixel.h"
/**
* The alpha mask is a special color strategy that treats all pixels as
* The alpha mask is a special color strategy that treats all pixels as
* alpha value with a colour common to the mask. The default color is white.
*/
class KisColorSpaceAlpha : public KisStrategyColorSpace {
......@@ -38,7 +38,7 @@ public:
public:
virtual void nativeColor(const QColor& c, QUANTUM *dst, KisProfileSP profile = 0);
virtual void nativeColor(const QColor& c, QUANTUM opacity, QUANTUM *dst, KisProfileSP profile = 0);
virtual void toQColor(const QUANTUM *src, QColor *c, KisProfileSP profile = 0);
virtual void toQColor(const QUANTUM *src, QColor *c, QUANTUM *opacity, KisProfileSP profile = 0);
......@@ -47,12 +47,12 @@ public:
virtual vKisChannelInfoSP channels() const;
virtual bool alpha() const;
virtual Q_INT32 depth() const;
virtual Q_INT32 nChannels() const { return 1; };
virtual Q_INT32 nColorChannels() const { return 0; };
virtual Q_INT32 size() const { return 1; };
virtual Q_INT32 pixelSize() const { return 1; };
virtual QImage convertToQImage(const QUANTUM *data, Q_INT32 width, Q_INT32 height,
KisProfileSP srcProfile, KisProfileSP dstProfile,
virtual QImage convertToQImage(const QUANTUM *data, Q_INT32 width, Q_INT32 height,
KisProfileSP srcProfile, KisProfileSP dstProfile,
Q_INT32 renderingIntent = INTENT_PERCEPTUAL);
virtual void setMaskColor(QColor c) { m_maskColor = c; }
......@@ -67,20 +67,20 @@ protected:
* Returns false if the conversion failed, true if it succeeded
*/
virtual bool convertPixelsTo(QUANTUM * src, KisProfileSP srcProfile,
QUANTUM * dst, KisStrategyColorSpaceSP dstColorStrategy, KisProfileSP dstProfile,
QUANTUM * dst, KisStrategyColorSpaceSP dstColorStrategy, KisProfileSP dstProfile,
Q_UINT32 length,
Q_INT32 renderingIntent = INTENT_PERCEPTUAL);
virtual void bitBlt(Q_INT32 stride,
QUANTUM *dst,
QUANTUM *dst,
Q_INT32 dststride,
QUANTUM *src,
QUANTUM *src,
Q_INT32 srcstride,
QUANTUM opacity,
Q_INT32 rows,
Q_INT32 cols,
Q_INT32 rows,
Q_INT32 cols,
CompositeOp op);
private:
......
......@@ -67,8 +67,6 @@ void rgb_to_hls(Q_UINT8 r, Q_UINT8 g, Q_UINT8 b, float * h, float * l, float * s
}
kdDebug() << " Converted rgb (" << r << ", " << g << ", " << b
<< ") to hls (" << *h << ", " << *l << ", " << *s << ")\n";
};
float hue_value(float n1, float n2, float hue)
......
......@@ -29,12 +29,12 @@
#include "kis_profile.h"
#include "kis_config.h"
KisStrategyColorSpace::KisStrategyColorSpace(const QString& name, const QString& description, Q_UINT32 cmType, icColorSpaceSignature colorSpaceSignature)
KisStrategyColorSpace::KisStrategyColorSpace(const QString& name, const QString& description, Q_UINT32 cmType, icColorSpaceSignature colorSpaceSignature)
: m_name(name),
m_description(description),
m_cmType(cmType),
m_colorSpaceSignature(colorSpaceSignature)
{
{
// Load all profiles that are suitable for this colorspace signature
resetProfiles();
}
......@@ -57,14 +57,14 @@ bool KisStrategyColorSpace::convertTo(KisPixel& src, KisPixel& dst, Q_INT32 rend
}
bool KisStrategyColorSpace::convertPixelsTo(QUANTUM * src, KisProfileSP srcProfile,
QUANTUM * dst, KisStrategyColorSpaceSP dstColorStrategy, KisProfileSP dstProfile,
Q_UINT32 length,
QUANTUM * dst, KisStrategyColorSpaceSP dstColorStrategy, KisProfileSP dstProfile,
Q_UINT32 length,
Q_INT32 renderingIntent)
{
// kdDebug() << "convertPixels for " << length << " pixels from " << name() << " to " << dstColorStrategy -> name() << "\n";
// kdDebug() << " src profile: " << srcProfile << ", dst profile: " << dstProfile << "\n";
cmsHTRANSFORM tf = 0;
if (!m_transforms.contains(KisProfilePair(srcProfile, dstProfile))) {
// kdDebug() << "Create new transform\n";
tf = createTransform(dstColorStrategy,
......@@ -72,7 +72,7 @@ bool KisStrategyColorSpace::convertPixelsTo(QUANTUM * src, KisProfileSP srcProfi
dstProfile,
renderingIntent);
m_transforms[KisProfilePair(srcProfile, dstProfile)] = tf;
m_transforms[KisProfilePair(srcProfile, dstProfile)] = tf;
}
else {
// kdDebug() << "Use cached transform\n";
......@@ -83,23 +83,23 @@ bool KisStrategyColorSpace::convertPixelsTo(QUANTUM * src, KisProfileSP srcProfi
cmsDoTransform(tf, src, dst, length);
return true;
}
kdDebug() << "No transform from "
<< srcProfile -> productName() << " to " << dstProfile -> productName()
<< ", so cannot convert pixels!\n";
return false;
}
void KisStrategyColorSpace::bitBlt(Q_INT32 stride,
QUANTUM *dst,
QUANTUM *dst,
Q_INT32 dststride,
KisStrategyColorSpaceSP srcSpace,
QUANTUM *src,
QUANTUM *src,
Q_INT32 srcstride,
QUANTUM opacity,
Q_INT32 rows,
Q_INT32 cols,
Q_INT32 rows,
Q_INT32 cols,
CompositeOp op,
KisProfileSP srcProfile,
KisProfileSP dstProfile)
......@@ -111,7 +111,7 @@ void KisStrategyColorSpace::bitBlt(Q_INT32 stride,
if (m_name != srcSpace -> name()) {
// kdDebug() << "compositing heterogenous color spaces: src = " << srcSpace -> name() << ", dst = " << m_name << "\n";
int len = depth() * rows * cols;
int len = pixelSize() * rows * cols;
QUANTUM * convertedSrcPixels = new QUANTUM[len];
memset(convertedSrcPixels, 0, len * sizeof(QUANTUM));
......@@ -119,35 +119,35 @@ void KisStrategyColorSpace::bitBlt(Q_INT32 stride,
srcSpace -> convertPixelsTo(src, 0,
convertedSrcPixels, this, 0,
rows * cols);
srcstride = (srcstride / srcSpace -> depth()) * depth();
srcstride = (srcstride / srcSpace -> pixelSize()) * pixelSize();
bitBlt(stride,
dst,
dst,
dststride,
convertedSrcPixels,
convertedSrcPixels,
srcstride,
opacity,
rows,
cols,
rows,
cols,
op);
delete[] convertedSrcPixels;
}
else {
bitBlt(stride,
dst,
dst,
dststride,
src,
src,
srcstride,
opacity,
rows,
cols,
rows,
cols,
op);
}
}
void KisStrategyColorSpace::resetProfiles()
void KisStrategyColorSpace::resetProfiles()
{
// XXX: Should find a way to make sure not all profiles are read for all color strategies
m_profiles.clear();
......@@ -168,7 +168,7 @@ void KisStrategyColorSpace::resetProfiles()
KisProfileSP KisStrategyColorSpace::getProfileByName(const QString & name)
{
vKisProfileSP::iterator it;
for ( it = m_profiles.begin(); it != m_profiles.end(); ++it ) {
if ((*it) -> productName() == name) {
return *it;
......@@ -185,12 +185,12 @@ cmsHTRANSFORM KisStrategyColorSpace::createTransform(KisStrategyColorSpaceSP dst
{
KisConfig cfg;
int flags = 0;
if (cfg.useBlackPointCompensation()) {
flags = cmsFLAGS_BLACKPOINTCOMPENSATION;
}
if (dstProfile != 0
if (dstProfile != 0
&& dstColorStrategy != 0
&& dstColorStrategy != 0
&& dstProfile -> colorSpaceSignature() == dstColorStrategy -> colorSpaceSignature()
......
......@@ -59,7 +59,7 @@ public:
/**
* Create a new colorspace strategy.
*
*