/* * Copyright (c) 2002 Patrick Julien * Copyright (c) 2005 Casper Boemann * * 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., 675 mass ave, cambridge, ma 02139, usa. */ #include #include #include "kis_debug_areas.h" #include "kis_group_layer.h" #include "kis_image.h" #include "kis_layer.h" #include "kis_adjustment_layer.h" #include "kis_painter.h" #include "kis_undo_adapter.h" #include "kis_selection.h" #include "kis_fill_painter.h" KisAdjustmentLayer::KisAdjustmentLayer(KisImageSP img, const QString &name, KisFilterConfiguration * kfc, KisSelectionSP selection) : KisLayer (img, name, OPACITY_OPAQUE) { m_filterConfig = kfc; setSelection( selection ); m_cachedPaintDev = new KisPaintDevice( img->colorSpace(), name.latin1()); m_showSelection = true; Q_ASSERT(m_cachedPaintDev); connect(img, SIGNAL(sigSelectionChanged(KisImageSP)), this, SLOT(slotSelectionChanged(KisImageSP))); } KisAdjustmentLayer::KisAdjustmentLayer(const KisAdjustmentLayer& rhs) : KisLayer(rhs), KisLayerSupportsIndirectPainting(rhs) { m_filterConfig = new KisFilterConfiguration(*rhs.m_filterConfig); if (rhs.m_selection) { m_selection = new KisSelection( *rhs.m_selection.data() ); m_selection->setParentLayer(this); m_selection->setInterestedInDirtyness(true); connect(rhs.image(), SIGNAL(sigSelectionChanged(KisImageSP)), this, SLOT(slotSelectionChanged(KisImageSP))); } m_cachedPaintDev = new KisPaintDevice( *rhs.m_cachedPaintDev.data() ); m_showSelection = false; } KisAdjustmentLayer::~KisAdjustmentLayer() { delete m_filterConfig; } KisLayerSP KisAdjustmentLayer::clone() const { return new KisAdjustmentLayer(*this); } void KisAdjustmentLayer::resetCache() { m_cachedPaintDev = new KisPaintDevice(image()->colorSpace(), name().latin1()); } KisFilterConfiguration * KisAdjustmentLayer::filter() { Q_ASSERT(m_filterConfig); return m_filterConfig; } void KisAdjustmentLayer::setFilter(KisFilterConfiguration * filterConfig) { Q_ASSERT(filterConfig); m_filterConfig = filterConfig; } KisSelectionSP KisAdjustmentLayer::selection() { return m_selection; } void KisAdjustmentLayer::setSelection(KisSelectionSP selection) { m_selection = new KisSelection(); KisFillPainter gc(m_selection.data()); KisColorSpace * cs = KisMetaRegistry::instance()->csRegistry()->getRGB8(); if (selection) { gc.bitBlt(0, 0, COMPOSITE_COPY, selection.data(), 0, 0, image()->bounds().width(), image()->bounds().height()); } else { gc.fillRect(image()->bounds(), KisColor(Qt::white, cs), MAX_SELECTED); } gc.end(); m_selection->setParentLayer(this); m_selection->setInterestedInDirtyness(true); } void KisAdjustmentLayer::clearSelection() { KisFillPainter gc(m_selection.data()); KisColorSpace * cs = KisMetaRegistry::instance()->csRegistry()->getRGB8(); QRect bounds = extent(); bounds |= image()->bounds(); gc.fillRect(bounds, KisColor(Qt::white, cs), MIN_SELECTED); gc.end(); } Q_INT32 KisAdjustmentLayer::x() const { if (m_selection) return m_selection->getX(); else return 0; } void KisAdjustmentLayer::setX(Q_INT32 x) { if (m_selection) { m_selection->setX(x); resetCache(); } } Q_INT32 KisAdjustmentLayer::y() const { if (m_selection) return m_selection->getY(); else return 0; } void KisAdjustmentLayer::setY(Q_INT32 y) { if (m_selection) { m_selection->setY(y); resetCache(); } } QRect KisAdjustmentLayer::extent() const { if (m_selection) return m_selection->selectedRect(); else if (image()) return image()->bounds(); else return QRect(); } QRect KisAdjustmentLayer::exactBounds() const { if (m_selection) return m_selection->selectedRect(); else if (image()) return image()->bounds(); else return QRect(); } bool KisAdjustmentLayer::accept(KisLayerVisitor & v) { return v.visit( this ); } void KisAdjustmentLayer::paintSelection(QImage &img, Q_INT32 x, Q_INT32 y, Q_INT32 w, Q_INT32 h) { if (showSelection() && selection()) selection()->paintSelection(img, x, y, w, h); } void KisAdjustmentLayer::paintSelection(QImage &img, const QRect& scaledImageRect, const QSize& scaledImageSize, const QSize& imageSize) { if (showSelection() && selection()) selection()->paintSelection(img, scaledImageRect, scaledImageSize, imageSize); } QImage KisAdjustmentLayer::createThumbnail(Q_INT32 w, Q_INT32 h) { if (!selection()) return QImage(); int srcw, srch; if( image() ) { srcw = image()->width(); srch = image()->height(); } else { const QRect e = extent(); srcw = e.width(); srch = e.height(); } if (w > srcw) { w = srcw; h = Q_INT32(double(srcw) / w * h); } if (h > srch) { h = srch; w = Q_INT32(double(srch) / h * w); } if (srcw > srch) h = Q_INT32(double(srch) / srcw * w); else if (srch > srcw) w = Q_INT32(double(srcw) / srch * h); QColor c; Q_UINT8 opacity; QImage img(w,h,32); for (Q_INT32 y=0; y < h; ++y) { Q_INT32 iY = (y * srch ) / h; for (Q_INT32 x=0; x < w; ++x) { Q_INT32 iX = (x * srcw ) / w; m_selection->pixel(iX, iY, &c, &opacity); img.setPixel(x, y, qRgb(opacity, opacity, opacity)); } } return img; } void KisAdjustmentLayer::slotSelectionChanged(KisImageSP image) { image->setModified(); } #include "kis_adjustment_layer.moc"