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         if (!m_selection->hasSelection())
00054             m_selection->setSelection(m_selection);
00055         connect(rhs.image(), SIGNAL(sigSelectionChanged(KisImageSP)),
00056                 this, SLOT(slotSelectionChanged(KisImageSP)));
00057     }
00058     m_cachedPaintDev = new KisPaintDevice( *rhs.m_cachedPaintDev.data() );
00059     m_showSelection = false;
00060 }
00061 
00062 
00063 KisAdjustmentLayer::~KisAdjustmentLayer()
00064 {
00065     delete m_filterConfig;
00066 }
00067 
00068 
00069 KisLayerSP KisAdjustmentLayer::clone() const
00070 {
00071     return new KisAdjustmentLayer(*this);
00072 }
00073 
00074 
00075 void KisAdjustmentLayer::resetCache()
00076 {
00077     m_cachedPaintDev = new KisPaintDevice(image()->colorSpace(), name().latin1());
00078 }
00079 
00080 KisFilterConfiguration * KisAdjustmentLayer::filter()
00081 {
00082     Q_ASSERT(m_filterConfig);
00083     return m_filterConfig;
00084 }
00085 
00086 
00087 void KisAdjustmentLayer::setFilter(KisFilterConfiguration * filterConfig)
00088 {
00089     Q_ASSERT(filterConfig);
00090     m_filterConfig = filterConfig;
00091 }
00092 
00093 
00094 KisSelectionSP KisAdjustmentLayer::selection()
00095 {
00096     return m_selection;
00097 }
00098 
00099 void KisAdjustmentLayer::setSelection(KisSelectionSP selection)
00100 {
00101     m_selection = new KisSelection();
00102     KisFillPainter gc(m_selection.data());
00103     KisColorSpace * cs = KisMetaRegistry::instance()->csRegistry()->getRGB8();
00104 
00105     if (selection) {
00106         gc.bitBlt(0, 0, COMPOSITE_COPY, selection.data(),
00107                   0, 0, image()->bounds().width(), image()->bounds().height());
00108     } else {
00109         gc.fillRect(image()->bounds(), KisColor(Qt::white, cs), MAX_SELECTED);
00110     }
00111 
00112     gc.end();
00113 
00114     m_selection->setParentLayer(this);
00115     m_selection->setInterestedInDirtyness(true);
00116 
00117     if (!m_selection->hasSelection())
00118         m_selection->setSelection(m_selection);
00119 }
00120 
00121 void KisAdjustmentLayer::clearSelection()
00122 {
00123     KisFillPainter gc(m_selection.data());
00124     KisColorSpace * cs = KisMetaRegistry::instance()->csRegistry()->getRGB8();
00125 
00126     QRect bounds = extent();
00127     bounds |= image()->bounds();
00128     gc.fillRect(bounds, KisColor(Qt::white, cs), MIN_SELECTED);
00129     gc.end();
00130 }
00131 
00132 
00133 Q_INT32 KisAdjustmentLayer::x() const
00134 {
00135     if (m_selection)
00136         return m_selection->getX();
00137     else
00138         return 0;
00139 }
00140 
00141 void KisAdjustmentLayer::setX(Q_INT32 x)
00142 {
00143     if (m_selection) {
00144         m_selection->setX(x);
00145         resetCache();
00146     }
00147 
00148 }
00149 
00150 Q_INT32 KisAdjustmentLayer::y() const
00151 {
00152     if (m_selection)
00153         return m_selection->getY();
00154     else
00155         return 0;
00156 }
00157 
00158 void KisAdjustmentLayer::setY(Q_INT32 y)
00159 {
00160     if (m_selection) {
00161         m_selection->setY(y);
00162         resetCache();
00163     }
00164 }
00165 
00166 QRect KisAdjustmentLayer::extent() const
00167 {
00168     if (m_selection)
00169         return m_selection->selectedRect();
00170     else if (image())
00171         return image()->bounds();
00172     else
00173         return QRect();
00174 }
00175 
00176 QRect KisAdjustmentLayer::exactBounds() const
00177 {
00178     if (m_selection)
00179         return m_selection->selectedRect();
00180     else if (image())
00181         return image()->bounds();
00182     else
00183         return QRect();
00184 }
00185 
00186 bool KisAdjustmentLayer::accept(KisLayerVisitor & v)
00187 {
00188     return v.visit( this );
00189 }
00190 
00191 void KisAdjustmentLayer::paintSelection(QImage &img, Q_INT32 x, Q_INT32 y, Q_INT32 w, Q_INT32 h)
00192 {
00193     if (showSelection() && selection())
00194         selection()->paintSelection(img, x, y, w, h);
00195 }
00196 
00197 void KisAdjustmentLayer::paintSelection(QImage &img, const QRect& scaledImageRect, const QSize& scaledImageSize, const QSize& imageSize)
00198 {
00199     if (showSelection() && selection())
00200         selection()->paintSelection(img, scaledImageRect, scaledImageSize, imageSize);
00201 }
00202 
00203 QImage KisAdjustmentLayer::createThumbnail(Q_INT32 w, Q_INT32 h)
00204 {
00205     if (!selection())
00206         return QImage();
00207 
00208     int srcw, srch;
00209     if( image() )
00210     {
00211         srcw = image()->width();
00212         srch = image()->height();
00213     }
00214     else
00215     {
00216         const QRect e = extent();
00217         srcw = e.width();
00218         srch = e.height();
00219     }
00220 
00221     if (w > srcw)
00222     {
00223         w = srcw;
00224         h = Q_INT32(double(srcw) / w * h);
00225     }
00226     if (h > srch)
00227     {
00228         h = srch;
00229         w = Q_INT32(double(srch) / h * w);
00230     }
00231 
00232     if (srcw > srch)
00233         h = Q_INT32(double(srch) / srcw * w);
00234     else if (srch > srcw)
00235         w = Q_INT32(double(srcw) / srch * h);
00236 
00237     QColor c;
00238     Q_UINT8 opacity;
00239     QImage img(w,h,32);
00240 
00241     for (Q_INT32 y=0; y < h; ++y) {
00242         Q_INT32 iY = (y * srch ) / h;
00243         for (Q_INT32 x=0; x < w; ++x) {
00244             Q_INT32 iX = (x * srcw ) / w;
00245             m_selection->pixel(iX, iY, &c, &opacity);
00246             img.setPixel(x, y, qRgb(opacity, opacity, opacity));
00247         }
00248     }
00249 
00250     return img;
00251 }
00252 
00253 void KisAdjustmentLayer::slotSelectionChanged(KisImageSP image) {
00254     image->setModified();
00255 }
00256 
00257 #include "kis_adjustment_layer.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys