diff --git a/libs/libkis/FillLayer.cpp b/libs/libkis/FillLayer.cpp index 1184182771..3640bb5cf8 100644 --- a/libs/libkis/FillLayer.cpp +++ b/libs/libkis/FillLayer.cpp @@ -1,75 +1,78 @@ /* * Copyright (c) 2017 Wolthera van Hövell tot Westerflier * * 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 "FillLayer.h" #include #include #include #include #include #include #include +#include FillLayer::FillLayer(KisImageSP image, QString name, KisFilterConfigurationSP filterConfig, Selection &selection, QObject *parent) : Node(image, new KisGeneratorLayer(image, name, filterConfig->cloneWithResourcesSnapshot(), selection.selection()), parent) { } FillLayer::FillLayer(KisGeneratorLayerSP layer, QObject *parent): Node(layer->image(), layer, parent) { } FillLayer::~FillLayer() { } QString FillLayer::generatorName() { const KisGeneratorLayer *layer = qobject_cast(this->node()); return layer->filter()->name(); } InfoObject * FillLayer::filterConfig() { const KisGeneratorLayer *layer = qobject_cast(this->node()); return new InfoObject(layer->filter()); } QString FillLayer::type() const { return "filllayer"; } bool FillLayer::setGenerator(const QString &generatorName, InfoObject *config) { KisGeneratorLayer *layer = dynamic_cast(this->node().data()); + KIS_ASSERT_RECOVER_RETURN_VALUE(layer, false); + //getting the default configuration here avoids trouble with versioning. KisGeneratorSP generator = KisGeneratorRegistry::instance()->value(generatorName); if (generator) { KisFilterConfigurationSP cfg = generator->factoryConfiguration(KisGlobalResourcesInterface::instance()); Q_FOREACH(const QString property, config->properties().keys()) { cfg->setProperty(property, config->property(property)); } layer->setFilter(cfg->cloneWithResourcesSnapshot()); return true; } return false; } diff --git a/libs/libkis/FilterMask.cpp b/libs/libkis/FilterMask.cpp index b027073194..366e8f1153 100644 --- a/libs/libkis/FilterMask.cpp +++ b/libs/libkis/FilterMask.cpp @@ -1,63 +1,69 @@ /* * Copyright (c) 2017 Wolthera van Hövell tot Westerflier * * 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 "FilterMask.h" #include #include #include #include #include FilterMask::FilterMask(KisImageSP image, QString name, Filter &filter, QObject *parent) : Node(image, new KisFilterMask(), parent) { this->node()->setName(name); KisFilterMask *mask = dynamic_cast(this->node().data()); + KIS_SAFE_ASSERT_RECOVER_RETURN(mask); + mask->setFilter(filter.filterConfig()->cloneWithResourcesSnapshot()); } FilterMask::FilterMask(KisImageSP image, KisFilterMaskSP mask, QObject *parent): Node(image, mask, parent) { } FilterMask::~FilterMask() { } QString FilterMask::type() const { return "filtermask"; } void FilterMask::setFilter(Filter &filter) { KisFilterMask *mask = dynamic_cast(this->node().data()); + KIS_SAFE_ASSERT_RECOVER_RETURN(mask); + mask->setFilter(filter.filterConfig()->cloneWithResourcesSnapshot()); } Filter * FilterMask::filter() { Filter* filter = new Filter(); const KisFilterMask *mask = qobject_cast(this->node()); + KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(mask, 0); + filter->setName(mask->filter()->name()); filter->setConfiguration(new InfoObject(mask->filter())); return filter; } diff --git a/libs/widgets/KoZoomWidget.cpp b/libs/widgets/KoZoomWidget.cpp index 886e2e9711..4cee49ba88 100644 --- a/libs/widgets/KoZoomWidget.cpp +++ b/libs/widgets/KoZoomWidget.cpp @@ -1,115 +1,115 @@ /* Copyright (C) 2004 Ariya Hidayat Copyright (C) 2006 Peter Simonsson Copyright (C) 2006-2007 C. Boemann Copyright (C) 2014 Sven Langkamp This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License version 2 as published by the Free Software Foundation. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "KoZoomWidget.h" #include #include #include #include #include "KoZoomInput.h" #include "KoIcon.h" class KoZoomWidget::Private { public: Private() : slider(0) , input(0) , aspectButton(0) {} QSlider* slider; KoZoomInput* input; QToolButton* aspectButton; - qreal effectiveZoom; + qreal effectiveZoom {1.0}; }; KoZoomWidget::KoZoomWidget(QWidget* parent, int maxZoom ) : QWidget(parent) , d(new Private) { QHBoxLayout *layout = new QHBoxLayout(this); //layout->setSizeConstraint(QLayout::SetFixedSize); layout->setMargin(0); layout->setSpacing(0); d->input = new KoZoomInput(this); connect(d->input, SIGNAL(zoomLevelChanged(QString)), this, SIGNAL(zoomLevelChanged(QString))); layout->addWidget(d->input); d->slider = new QSlider(Qt::Horizontal); d->slider->setToolTip(i18n("Zoom")); d->slider->setMinimum(0); d->slider->setMaximum(maxZoom); d->slider->setValue(0); d->slider->setSingleStep(1); d->slider->setPageStep(1); d->slider->setMinimumWidth(80); layout->addWidget(d->slider); layout->setStretch(1, 1); d->aspectButton = new QToolButton(this); d->aspectButton->setIcon(koIcon("zoom-pixels")); d->aspectButton->setIconSize(QSize(16,16)); d->aspectButton->setCheckable(true); d->aspectButton->setChecked(true); d->aspectButton->setAutoRaise(true); d->aspectButton->setToolTip(i18n("Use same aspect as pixels")); connect(d->aspectButton, SIGNAL(toggled(bool)), this, SIGNAL(aspectModeChanged(bool))); layout->addWidget(d->aspectButton); connect(d->slider, SIGNAL(valueChanged(int)), this, SIGNAL(sliderValueChanged(int))); } KoZoomWidget::~KoZoomWidget() { } void KoZoomWidget::setZoomLevels(const QStringList &values) { d->input->setZoomLevels(values); } void KoZoomWidget::setCurrentZoomLevel(const QString &valueString) { d->input->setCurrentZoomLevel(valueString); } void KoZoomWidget::setSliderValue(int value) { d->slider->blockSignals(true); d->slider->setValue(value); d->slider->blockSignals(false); } void KoZoomWidget::setAspectMode(bool status) { if(d->aspectButton && d->aspectButton->isChecked() != status) { d->aspectButton->blockSignals(true); d->aspectButton->setChecked(status); d->aspectButton->blockSignals(false); } } diff --git a/plugins/impex/xcf/kis_xcf_import.cpp b/plugins/impex/xcf/kis_xcf_import.cpp index 97f6b483a1..5325845801 100644 --- a/plugins/impex/xcf/kis_xcf_import.cpp +++ b/plugins/impex/xcf/kis_xcf_import.cpp @@ -1,331 +1,331 @@ /* * Copyright (c) 2009 Cyrille Berger * * This library 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.1 of the License, or * (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser 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 "kis_xcf_import.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "kis_iterator_ng.h" #include "kis_types.h" #include extern "C" { #include "xcftools.h" #include "pixels.h" #define GET_RED(x) (x >> RED_SHIFT) #define GET_GREEN(x) (x >> GREEN_SHIFT) #define GET_BLUE(x) (x >> BLUE_SHIFT) #define GET_ALPHA(x) (x >> ALPHA_SHIFT) } QString layerModeG2K(GimpLayerModeEffects mode) { switch (mode) { case GIMP_NORMAL_MODE: return COMPOSITE_OVER; case GIMP_DISSOLVE_MODE: return COMPOSITE_DISSOLVE; case GIMP_MULTIPLY_MODE: return COMPOSITE_MULT; case GIMP_SCREEN_MODE: return COMPOSITE_SCREEN; case GIMP_OVERLAY_MODE: case GIMP_SOFTLIGHT_MODE: return COMPOSITE_OVERLAY; case GIMP_DIFFERENCE_MODE: return COMPOSITE_DIFF; case GIMP_ADDITION_MODE: return COMPOSITE_ADD; case GIMP_SUBTRACT_MODE: return COMPOSITE_SUBTRACT; case GIMP_DARKEN_ONLY_MODE: return COMPOSITE_DARKEN; case GIMP_LIGHTEN_ONLY_MODE: return COMPOSITE_LIGHTEN; case GIMP_HUE_MODE: return COMPOSITE_HUE_HSL; case GIMP_SATURATION_MODE: return COMPOSITE_SATURATION_HSV; case GIMP_COLOR_MODE: return COMPOSITE_COLOR_HSL; case GIMP_VALUE_MODE: return COMPOSITE_VALUE; case GIMP_DIVIDE_MODE: return COMPOSITE_DIVIDE; case GIMP_DODGE_MODE: return COMPOSITE_DODGE; case GIMP_BURN_MODE: return COMPOSITE_BURN; case GIMP_ERASE_MODE: return COMPOSITE_ERASE; case GIMP_REPLACE_MODE: return COMPOSITE_COPY; case GIMP_HARDLIGHT_MODE: return COMPOSITE_HARD_LIGHT; case GIMP_COLOR_ERASE_MODE: case GIMP_NORMAL_NOPARTIAL_MODE: case GIMP_ANTI_ERASE_MODE: case GIMP_GRAIN_EXTRACT_MODE: return COMPOSITE_GRAIN_EXTRACT; case GIMP_GRAIN_MERGE_MODE: return COMPOSITE_GRAIN_MERGE; case GIMP_BEHIND_MODE: break; } dbgFile << "Unknown mode: " << mode; return COMPOSITE_OVER; } struct Layer { KisLayerSP layer; int depth; KisMaskSP mask; }; KisGroupLayerSP findGroup(const QVector &layers, const Layer& layer, int i) { for (; i < layers.size(); ++i) { KisGroupLayerSP group = dynamic_cast(const_cast(layers[i].layer.data())); if (group && (layers[i].depth == layer.depth -1)) { return group; } } return 0; } void addLayers(const QVector &layers, KisImageSP image, int depth) { for(int i = 0; i < layers.size(); i++) { const Layer &layer = layers[i]; if (layer.depth == depth) { KisGroupLayerSP group = (depth == 0 ? image->rootLayer() : findGroup(layers, layer, i)); image->addNode(layer.layer, group); if (layer.mask) { image->addNode(layer.mask, layer.layer); } } } } K_PLUGIN_FACTORY_WITH_JSON(XCFImportFactory, "krita_xcf_import.json", registerPlugin();) KisXCFImport::KisXCFImport(QObject *parent, const QVariantList &) : KisImportExportFilter(parent) { } KisXCFImport::~KisXCFImport() { } KisImportExportErrorCode KisXCFImport::convert(KisDocument *document, QIODevice *io, KisPropertiesConfigurationSP /*configuration*/) { int errorStatus; dbgFile << "Start decoding file"; QByteArray data = io->readAll(); xcf_file = (uint8_t*)data.data(); xcf_length = data.size(); io->close(); // Decode the data if (getBasicXcfInfo() != XCF_OK) { if (XCF.version < 0 || XCF.version > 3) { document->setErrorMessage(i18n("This XCF file is too new; Krita cannot support XCF files written by GIMP 2.9 or newer.")); return ImportExportCodes::FormatFeaturesUnsupported; } return ImportExportCodes::FileFormatIncorrect; } if(initColormap() != XCF_OK) { return ImportExportCodes::FileFormatIncorrect; } dbgFile << XCF.version << "width = " << XCF.width << "height = " << XCF.height << "layers = " << XCF.numLayers; // Create the image KisImageSP image = new KisImage(document->createUndoStore(), XCF.width, XCF.height, KoColorSpaceRegistry::instance()->rgb8(), "built image"); QVector layers; uint maxDepth = 0; // Read layers for (int i = 0; i < XCF.numLayers; ++i) { Layer layer; xcfLayer& xcflayer = XCF.layers[i]; dbgFile << i << " name = " << xcflayer.name << " opacity = " << xcflayer.opacity << "group:" << xcflayer.isGroup << xcflayer.pathLength; dbgFile << ppVar(xcflayer.dim.width) << ppVar(xcflayer.dim.height) << ppVar(xcflayer.dim.tilesx) << ppVar(xcflayer.dim.tilesy) << ppVar(xcflayer.dim.ntiles) << ppVar(xcflayer.dim.c.t) << ppVar(xcflayer.dim.c.l) << ppVar(xcflayer.dim.c.r) << ppVar(xcflayer.dim.c.b); maxDepth = qMax(maxDepth, xcflayer.pathLength); bool isRgbA = false; // Select the color space const KoColorSpace* colorSpace = 0; switch (xcflayer.type) { case GIMP_INDEXED_IMAGE: case GIMP_INDEXEDA_IMAGE: case GIMP_RGB_IMAGE: case GIMP_RGBA_IMAGE: colorSpace = KoColorSpaceRegistry::instance()->rgb8(); isRgbA = true; break; case GIMP_GRAY_IMAGE: case GIMP_GRAYA_IMAGE: colorSpace = KoColorSpaceRegistry::instance()->colorSpace(GrayAColorModelID.id(), Integer8BitsColorDepthID.id(), ""); isRgbA = false; break; } // Create the layer KisLayerSP kisLayer; if (xcflayer.isGroup) { kisLayer = new KisGroupLayer(image, QString::fromUtf8(xcflayer.name), xcflayer.opacity); } else { kisLayer = new KisPaintLayer(image, QString::fromUtf8(xcflayer.name), xcflayer.opacity, colorSpace); } // Set some properties kisLayer->setCompositeOpId(layerModeG2K(xcflayer.mode)); kisLayer->setVisible(xcflayer.isVisible); kisLayer->disableAlphaChannel(xcflayer.mode != GIMP_NORMAL_MODE); layer.layer = kisLayer; layer.depth = xcflayer.pathLength; // Copy the data in the image if ((errorStatus = initLayer(&xcflayer)) != XCF_OK) { return ImportExportCodes::FileFormatIncorrect; } int left = xcflayer.dim.c.l; int top = xcflayer.dim.c.t; if (!xcflayer.isGroup) { // Copy the data; for (unsigned int x = 0; x < xcflayer.dim.width; x += TILE_WIDTH) { for (unsigned int y = 0; y < xcflayer.dim.height; y += TILE_HEIGHT) { rect want; want.l = x + left; want.t = y + top; want.b = want.t + TILE_HEIGHT; want.r = want.l + TILE_WIDTH; Tile* tile = getMaskOrLayerTile(&xcflayer.dim, &xcflayer.pixels, want); if (tile == XCF_PTR_EMPTY) { return ImportExportCodes::FileFormatIncorrect; } KisHLineIteratorSP it = kisLayer->paintDevice()->createHLineIteratorNG(x, y, TILE_WIDTH); rgba* data = tile->pixels; for (int v = 0; v < TILE_HEIGHT; ++v) { if (isRgbA) { // RGB image do { KoBgrTraits::setRed(it->rawData(), GET_RED(*data)); KoBgrTraits::setGreen(it->rawData(), GET_GREEN(*data)); KoBgrTraits::setBlue(it->rawData(), GET_BLUE(*data)); KoBgrTraits::setOpacity(it->rawData(), quint8(GET_ALPHA(*data)), 1); ++data; } while (it->nextPixel()); } else { // Grayscale image do { it->rawData()[0] = GET_RED(*data); it->rawData()[1] = GET_ALPHA(*data); ++data; } while (it->nextPixel()); } it->nextRow(); } } } // Move the layer to its position kisLayer->paintDevice()->setX(left); kisLayer->paintDevice()->setY(top); } // Create the mask if (xcflayer.hasMask) { KisTransparencyMaskSP mask = new KisTransparencyMask(); layer.mask = mask; mask->initSelection(kisLayer); for (unsigned int x = 0; x < xcflayer.dim.width; x += TILE_WIDTH) { for (unsigned int y = 0; y < xcflayer.dim.height; y += TILE_HEIGHT) { rect want; want.l = x + left; want.t = y + top; want.b = want.t + TILE_HEIGHT; want.r = want.l + TILE_WIDTH; Tile* tile = getMaskOrLayerTile(&xcflayer.dim, &xcflayer.mask, want); if (tile == XCF_PTR_EMPTY) { - delete tile; + free(tile); return ImportExportCodes::FileFormatIncorrect; } KisHLineIteratorSP it = mask->paintDevice()->createHLineIteratorNG(x, y, TILE_WIDTH); rgba* data = tile->pixels; for (int v = 0; v < TILE_HEIGHT; ++v) { do { it->rawData()[0] = GET_ALPHA(*data); ++data; } while (it->nextPixel()); it->nextRow(); } - delete tile; + free(tile); } } mask->paintDevice()->setX(left); mask->paintDevice()->setY(top); } dbgFile << xcflayer.pixels.tileptrs; layers.append(layer); } for (uint i = 0; i <= maxDepth; ++i) { addLayers(layers, image, i); } document->setCurrentImage(image); return ImportExportCodes::OK; } #include "kis_xcf_import.moc"