diff --git a/plugins/extensions/pykrita/libkis/Channel.cpp b/plugins/extensions/pykrita/libkis/Channel.cpp index 6f74cca33e..8627e08b6c 100644 --- a/plugins/extensions/pykrita/libkis/Channel.cpp +++ b/plugins/extensions/pykrita/libkis/Channel.cpp @@ -1,196 +1,223 @@ /* * Copyright (c) 2016 Boudewijn Rempt * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; 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 Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "Channel.h" #include #include #include #include #include #include #include +#include #ifdef HAVE_OPENEXR #include #endif struct Channel::Private { Private() {} KisNodeSP node; KoChannelInfo *channel; }; Channel::Channel(KisNodeSP node, KoChannelInfo *channel, QObject *parent) : QObject(parent) , d(new Private) { d->node = node; d->channel = channel; } Channel::~Channel() { delete d; } bool Channel::visible() const { + if (!d->node || !d->channel) return false; + if (!d->node->inherits("KisLayer")) return false; + for (int i = 0; i < d->node->colorSpace()->channelCount(); ++i) { + if (d->node->colorSpace()->channels()[i] == d->channel) { + KisLayerSP layer = qobject_cast(d->node.data()); + if (!layer) return false; + + QBitArray flags = layer->channelFlags(); + return flags.testBit(i); + break; + } + } return false; } void Channel::setvisible(bool value) { + if (!d->node || !d->channel) return; + if (!d->node->inherits("KisLayer")) return; + + for (int i = 0; i < d->node->colorSpace()->channelCount(); ++i) { + if (d->node->colorSpace()->channels()[i] == d->channel) { + QBitArray flags = d->node->colorSpace()->channelFlags(true, true); + flags.setBit(i, value); + KisLayerSP layer = qobject_cast(d->node.data()); + if (!layer) return; + layer->setChannelFlags(flags); + break; + } + } + } QString Channel::name() const { return d->channel->name(); } int Channel::position() const { return d->channel->pos(); } int Channel::channelSize() const { return d->channel->size(); } QRect Channel::bounds() const { if (!d->node || !d->channel) return QRect(); QRect rect = d->node->exactBounds(); KisPaintDeviceSP dev; if (d->node->colorSpace()->colorDepthId() == Integer8BitsColorDepthID) { dev = new KisPaintDevice(KoColorSpaceRegistry::instance()->alpha8()); } else if (d->node->colorSpace()->colorDepthId() == Integer16BitsColorDepthID) { dev = new KisPaintDevice(KoColorSpaceRegistry::instance()->alpha16()); } #ifdef HAVE_OPENEXR else if (d->node->colorSpace()->colorDepthId() == Float16BitsColorDepthID) { dev = new KisPaintDevice(KoColorSpaceRegistry::instance()->alpha16f()); } #endif else if (d->node->colorSpace()->colorDepthId() == Float32BitsColorDepthID) { dev = new KisPaintDevice(KoColorSpaceRegistry::instance()->alpha32f()); } KisSequentialConstIterator srcIt(d->node->projection(), rect); KisSequentialIterator dstIt(dev, rect); do { const quint8 *srcPtr = srcIt.rawDataConst(); memcpy(dstIt.rawData(), srcPtr + d->channel->pos(), d->channel->size()); } while(srcIt.nextPixel() && dstIt.nextPixel()); if (dev) { return dev->exactBounds(); } return QRect(); } QByteArray Channel::pixelData(const QRect &rect) const { QByteArray ba; if (!d->node || !d->channel) return ba; QDataStream stream(&ba, QIODevice::WriteOnly); KisSequentialConstIterator srcIt(d->node->projection(), rect); if (d->node->colorSpace()->colorDepthId() == Integer8BitsColorDepthID) { do { stream << (quint8) *srcIt.rawDataConst(); } while(srcIt.nextPixel()); } else if (d->node->colorSpace()->colorDepthId() == Integer16BitsColorDepthID) { do { stream << (quint16) *srcIt.rawDataConst(); } while(srcIt.nextPixel()); } #ifdef HAVE_OPENEXR else if (d->node->colorSpace()->colorDepthId() == Float16BitsColorDepthID) { do { half h = (half)*srcIt.rawDataConst(); stream << (float)h; } while(srcIt.nextPixel()); } #endif else if (d->node->colorSpace()->colorDepthId() == Float32BitsColorDepthID) { do { stream << (float) *srcIt.rawDataConst(); } while(srcIt.nextPixel()); } return ba; } void Channel::setPixelData(QByteArray value, const QRect &rect) { if (!d->node || !d->channel || d->node->paintDevice() == 0) return; QDataStream stream(&value, QIODevice::ReadOnly); KisSequentialIterator dstIt(d->node->paintDevice(), rect); if (d->node->colorSpace()->colorDepthId() == Integer8BitsColorDepthID) { do { quint8 v; stream >> v; *dstIt.rawData() = v ; } while(dstIt.nextPixel()); } else if (d->node->colorSpace()->colorDepthId() == Integer16BitsColorDepthID) { do { quint16 v; stream >> v; *dstIt.rawData() = v ; } while(dstIt.nextPixel()); } #ifdef HAVE_OPENEXR else if (d->node->colorSpace()->colorDepthId() == Float16BitsColorDepthID) { do { float f; stream >> f; half v = f; *dstIt.rawData() = v ; } while(dstIt.nextPixel()); } #endif else if (d->node->colorSpace()->colorDepthId() == Float32BitsColorDepthID) { do { float v; stream >> v; *dstIt.rawData() = v ; } while(dstIt.nextPixel()); } } diff --git a/plugins/extensions/pykrita/libkis/Channel.h b/plugins/extensions/pykrita/libkis/Channel.h index eec2ef330c..73930378c6 100644 --- a/plugins/extensions/pykrita/libkis/Channel.h +++ b/plugins/extensions/pykrita/libkis/Channel.h @@ -1,88 +1,96 @@ /* * Copyright (c) 2016 Boudewijn Rempt * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; 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 Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef LIBKIS_CHANNEL_H #define LIBKIS_CHANNEL_H #include #include "kritalibkis_export.h" #include "libkis.h" #include #include /** * A Channel represents a singel channel in a Node. Krita does not * use channels to store local selections: these are strictly the * color and alpha channels. */ class KRITALIBKIS_EXPORT Channel : public QObject { Q_OBJECT Q_DISABLE_COPY(Channel) Q_PROPERTY(bool visible READ visible WRITE setvisible) public: explicit Channel(KisNodeSP node, KoChannelInfo *channel, QObject *parent = 0); virtual ~Channel(); + /** + * @brief visible checks whether this channel is visible in the node + * @return the status of this channel + */ bool visible() const; + + /** + * @brief setvisible set the visibility of the channel to the given value. + */ void setvisible(bool value); /** * @return the name of the channel */ QString name() const; /** * @returns the position of the first byte of the channel in the pixel */ int position() const; /** * @return the number of bytes this channel takes */ int channelSize() const; /** * @return the exact bounds of the channel. This can be smaller than the bounds of the Node this channel is part of. */ QRect bounds() const; /** * Read the values of the channel into the a byte array for each pixel in the rect from the Node this channel is part of, and returns it, */ QByteArray pixelData(const QRect &rect) const; /** * @brief setPixelData writes the given data to the relevant channel in the Node. This is only possible for Nodes * that have a paintDevice, so nothing will happen when trying to write to e.g. a group layer. * @param value a byte array with exactly enough bytes. * @param rect the rectangle to write the bytes into */ void setPixelData(QByteArray value, const QRect &rect); private: struct Private; Private *const d; }; #endif // LIBKIS_CHANNEL_H diff --git a/plugins/extensions/pykrita/libkis/Node.h b/plugins/extensions/pykrita/libkis/Node.h index 46391283f9..1d308c324f 100644 --- a/plugins/extensions/pykrita/libkis/Node.h +++ b/plugins/extensions/pykrita/libkis/Node.h @@ -1,163 +1,167 @@ /* * Copyright (c) 2016 Boudewijn Rempt * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; 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 Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef LIBKIS_NODE_H #define LIBKIS_NODE_H #include #include #include "kritalibkis_export.h" #include "libkis.h" /** * Node */ class KRITALIBKIS_EXPORT Node : public QObject { Q_OBJECT Q_DISABLE_COPY(Node) public: explicit Node(KisNodeSP node, QObject *parent = 0); virtual ~Node(); /** * @brief alphaLocked checks whether the node is a paint layer and returns whether it is alpha locked * @return whether the paint layer is alpha locked, or false if the node is not a paint layer */ bool alphaLocked() const; /** * @brief setAlphaLocked set the layer to value if the the node is paint layer. */ void setAlphaLocked(bool value); /** * @return the blending mode of the layer. The values of the blending modes are defined in @see KoCompositeOpRegistry.h */ QString blendingMode() const; /** * @brief setBlendingMode set the blending mode of the node to the given value * @param value one of the string values from @see KoCompositeOpRegistry.h */ void setBlendingMode(QString value); /** * @brief channels creates a list of Channel objects that can be used individually to * show or hide certain channels, and to retrieve the contents of each channel in a * node separately. * * Only layers have channels, masks do not, and calling channels on a Node that is a mask * will return an empty list. * * @return the list of channels ordered in by position of the channels in pixel position */ QList channels() const; + /** + * Return a list of child nodes of the current node. The nodes are ordered from the bottommost up. + * The function is not recursive. + */ QList childNodes() const; void setChildNodes(QList value); ColorDepth* colorDepth() const; void setColorDepth(ColorDepth* value); QString colorLabel() const; void setColorLabel(QString value); ColorModel* colorModel() const; void setColorModel(ColorModel* value); ColorProfile* colorProfile() const; void setColorProfile(ColorProfile* value); bool inheritAlpha() const; void setInheritAlpha(bool value); bool locked() const; void setLocked(bool value); QString name() const; void setName(QString value); int opacity() const; void setOpacity(int value); Node* parentNode() const; void setParentNode(Node* value); QString type() const; void setType(QString value); bool visible() const; void setVisible(bool value); InfoObject* metaDataInfo() const; void setMetaDataInfo(InfoObject* value); Generator* generator() const; void setGenerator(Generator* value); Filter* filter() const; void setFilter(Filter* value); Transformation* transformation() const; void setTransformation(Transformation* value); Selection* selection() const; void setSelection(Selection* value); QString fileName() const; void setFileName(QString value); QByteArray pixelData() const; void setPixelData(QByteArray value); QRect bounds() const; public Q_SLOTS: void move(int x, int y); void moveToParent(Node *parent); void remove(); Node* duplicate(); /** * @brief save exports the given node with this filename. The extension of the filename determins the filetype. * @param filename the filename including extension * @param xRes the horizontal resolution in pixels per pt (there are 72 pts in an inch) * @param yRes the horizontal resolution in pixels per pt (there are 72 pts in an inch) * @return true if saving succeeded, false if it failed. */ bool save(const QString &filename, double xRes, double yRes); Q_SIGNALS: private: struct Private; Private *d; }; #endif // LIBKIS_NODE_H