krita

kis_adjustment_layer.cc

00001 /*
00002  *  Copyright (c) 2002 Patrick Julien <freak@codepimps.org>
00003  *  Copyright (c) 2005 Casper Boemann <cbr@boemann.dk>
00004  *
00005  *  this program is free software; you can redistribute it and/or modify
00006  *  it under the terms of the gnu general public license as published by
00007  *  the free software foundation; either version 2 of the license, or
00008  *  (at your option) any later version.
00009  *
00010  *  this program is distributed in the hope that it will be useful,
00011  *  but without any warranty; without even the implied warranty of
00012  *  merchantability or fitness for a particular purpose.  see the
00013  *  gnu general public license for more details.
00014  *
00015  *  you should have received a copy of the gnu general public license
00016  *  along with this program; if not, write to the free software
00017  *  foundation, inc., 675 mass ave, cambridge, ma 02139, usa.
00018  */
00019 
00020 #include <kdebug.h>
00021 #include <qimage.h>
00022 
00023 #include "kis_debug_areas.h"
00024 #include "kis_group_layer.h"
00025 #include "kis_image.h"
00026 #include "kis_layer.h"
00027 #include "kis_adjustment_layer.h"
00028 #include "kis_painter.h"
00029 #include "kis_undo_adapter.h"
00030 #include "kis_selection.h"
00031 #include "kis_fill_painter.h"
00032 
00033 KisAdjustmentLayer::KisAdjustmentLayer(KisImageSP img, const QString &name, KisFilterConfiguration * kfc, KisSelectionSP selection)
00034     : KisLayer (img, name, OPACITY_OPAQUE)
00035 {
00036     m_filterConfig = kfc;
00037     setSelection( selection );
00038     m_cachedPaintDev = new KisPaintDevice( img->colorSpace(), name.latin1());
00039     m_showSelection = true;
00040     Q_ASSERT(m_cachedPaintDev);
00041     connect(img, SIGNAL(sigSelectionChanged(KisImageSP)),
00042             this, SLOT(slotSelectionChanged(KisImageSP)));
00043 }
00044 
00045 KisAdjustmentLayer::KisAdjustmentLayer(const KisAdjustmentLayer& rhs)
00046     : KisLayer(rhs), KisLayerSupportsIndirectPainting(rhs)
00047 {
00048     m_filterConfig = new KisFilterConfiguration(*rhs.m_filterConfig);
00049     if (rhs.m_selection) {
00050         m_selection = new KisSelection( *rhs.m_selection.data() );
00051         m_selection->setParentLayer(this);
00052         m_selection->setInterestedInDirtyness(true);
00053         connect(rhs.image(), SIGNAL(sigSelectionChanged(KisImageSP)),
00054                 this, SLOT(slotSelectionChanged(KisImageSP)));
00055     }
00056     m_cachedPaintDev = new KisPaintDevice( *rhs.m_cachedPaintDev.data() );
00057     m_showSelection = false;
00058 }
00059 
00060 
00061 KisAdjustmentLayer::~KisAdjustmentLayer()
00062 {
00063     delete m_filterConfig;
00064 }
00065 
00066 
00067 KisLayerSP KisAdjustmentLayer::clone() const
00068 {
00069     return new KisAdjustmentLayer(*this);
00070 }
00071 
00072 
00073 void KisAdjustmentLayer::resetCache()
00074 {
00075     m_cachedPaintDev = new KisPaintDevice(image()->colorSpace(), name().latin1());
00076 }
00077 
00078 KisFilterConfiguration * KisAdjustmentLayer::filter()
00079 {
00080     Q_ASSERT(m_filterConfig);
00081     return m_filterConfig;
00082 }
00083 
00084 
00085 void KisAdjustmentLayer::setFilter(KisFilterConfiguration * filterConfig)
00086 {
00087     Q_ASSERT(filterConfig);
00088     m_filterConfig = filterConfig;
00089 }
00090 
00091 
00092 KisSelectionSP KisAdjustmentLayer::selection()
00093 {
00094     return m_selection;
00095 }
00096 
00097 void KisAdjustmentLayer::setSelection(KisSelectionSP selection)
00098 {
00099     m_selection = new KisSelection();
00100     KisFillPainter gc(m_selection.data());
00101     KisColorSpace * cs = KisMetaRegistry::instance()->csRegistry()->getRGB8();
00102 
00103     if (selection) {
00104         gc.bitBlt(0, 0, COMPOSITE_COPY, selection.data(),
00105                   0, 0, image()->bounds().width(), image()->bounds().height());
00106     } else {
00107         gc.fillRect(image()->bounds(), KisColor(Qt::white, cs), MAX_SELECTED);
00108     }
00109 
00110     gc.end();
00111 
00112     m_selection->setParentLayer(this);
00113     m_selection->setInterestedInDirtyness(true);
00114 }
00115 
00116 void KisAdjustmentLayer::clearSelection()
00117 {
00118     KisFillPainter gc(m_selection.data());
00119     KisColorSpace * cs = KisMetaRegistry::instance()->csRegistry()->getRGB8();
00120 
00121     QRect bounds = extent();
00122     bounds |= image()->bounds();
00123     gc.fillRect(bounds, KisColor(Qt::white, cs), MIN_SELECTED);
00124     gc.end();
00125 }
00126 
00127 
00128 Q_INT32 KisAdjustmentLayer::x() const
00129 {
00130     if (m_selection)
00131         return m_selection->getX();
00132     else
00133         return 0;
00134 }
00135 
00136 void KisAdjustmentLayer::setX(Q_INT32 x)
00137 {
00138     if (m_selection) {
00139         m_selection->setX(x);
00140         resetCache();
00141     }
00142 
00143 }
00144 
00145 Q_INT32 KisAdjustmentLayer::y() const
00146 {
00147     if (m_selection)
00148         return m_selection->getY();
00149     else
00150         return 0;
00151 }
00152 
00153 void KisAdjustmentLayer::setY(Q_INT32 y)
00154 {
00155     if (m_selection) {
00156         m_selection->setY(y);
00157         resetCache();
00158     }
00159 }
00160 
00161 QRect KisAdjustmentLayer::extent() const
00162 {
00163     if (m_selection)
00164         return m_selection->selectedRect();
00165     else if (image())
00166         return image()->bounds();
00167     else
00168         return QRect();
00169 }
00170 
00171 QRect KisAdjustmentLayer::exactBounds() const
00172 {
00173     if (m_selection)
00174         return m_selection->selectedRect();
00175     else if (image())
00176         return image()->bounds();
00177     else
00178         return QRect();
00179 }
00180 
00181 bool KisAdjustmentLayer::accept(KisLayerVisitor & v)
00182 {
00183     return v.visit( this );
00184 }
00185 
00186 void KisAdjustmentLayer::paintSelection(QImage &img, Q_INT32 x, Q_INT32 y, Q_INT32 w, Q_INT32 h)
00187 {
00188     if (showSelection() && selection())
00189         selection()->paintSelection(img, x, y, w, h);
00190 }
00191 
00192 void KisAdjustmentLayer::paintSelection(QImage &img, const QRect& scaledImageRect, const QSize& scaledImageSize, const QSize& imageSize)
00193 {
00194     if (showSelection() && selection())
00195         selection()->paintSelection(img, scaledImageRect, scaledImageSize, imageSize);
00196 }
00197 
00198 QImage KisAdjustmentLayer::createThumbnail(Q_INT32 w, Q_INT32 h)
00199 {
00200     if (!selection())
00201         return QImage();
00202 
00203     int srcw, srch;
00204     if( image() )
00205     {
00206         srcw = image()->width();
00207         srch = image()->height();
00208     }
00209     else
00210     {
00211         const QRect e = extent();
00212         srcw = e.width();
00213         srch = e.height();
00214     }
00215 
00216     if (w > srcw)
00217     {
00218         w = srcw;
00219         h = Q_INT32(double(srcw) / w * h);
00220     }
00221     if (h > srch)
00222     {
00223         h = srch;
00224         w = Q_INT32(double(srch) / h * w);
00225     }
00226 
00227     if (srcw > srch)
00228         h = Q_INT32(double(srch) / srcw * w);
00229     else if (srch > srcw)
00230         w = Q_INT32(double(srcw) / srch * h);
00231 
00232     QColor c;
00233     Q_UINT8 opacity;
00234     QImage img(w,h,32);
00235 
00236     for (Q_INT32 y=0; y < h; ++y) {
00237         Q_INT32 iY = (y * srch ) / h;
00238         for (Q_INT32 x=0; x < w; ++x) {
00239             Q_INT32 iX = (x * srcw ) / w;
00240             m_selection->pixel(iX, iY, &c, &opacity);
00241             img.setPixel(x, y, qRgb(opacity, opacity, opacity));
00242         }
00243     }
00244 
00245     return img;
00246 }
00247 
00248 void KisAdjustmentLayer::slotSelectionChanged(KisImageSP image) {
00249     image->setModified();
00250 }
00251 
00252 #include "kis_adjustment_layer.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys