lib

KoPictureImage.cpp

00001 /* This file is part of the KDE project
00002    Copyright (c) 2001 Simon Hausmann <hausmann@kde.org>
00003    Copyright (C) 2002, 2003 Nicolas GOUTTE <goutte@kde.org>
00004 
00005    This library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Library General Public
00007    License as published by the Free Software Foundation; either
00008    version 2 of the License, or (at your option) any later version.
00009 
00010    This library 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 GNU
00013    Library General Public License for more details.
00014 
00015    You should have received a copy of the GNU Library General Public License
00016    along with this library; see the file COPYING.LIB.  If not, write to
00017    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018  * Boston, MA 02110-1301, USA.
00019 */
00020 
00021 #include "KoPictureImage.h"
00022 #include "KoPictureKey.h"
00023 
00024 #include <kdebug.h>
00025 #include <kmimetype.h>
00026 
00027 #include <qbuffer.h>
00028 #include <qpainter.h>
00029 #include <qimage.h>
00030 #include <qpixmap.h>
00031 #include <qapplication.h>
00032 #include <qdragobject.h>
00033 
00034 KoPictureImage::KoPictureImage(void) : m_cacheIsInFastMode(true)
00035 {
00036     // Forbid QPixmap to cache the X-Window resources (Yes, it is slower!)
00037     m_cachedPixmap.setOptimization(QPixmap::MemoryOptim);
00038 }
00039 
00040 KoPictureImage::~KoPictureImage(void)
00041 {
00042 }
00043 
00044 KoPictureBase* KoPictureImage::newCopy(void) const
00045 {
00046     return new KoPictureImage(*this);
00047 }
00048 
00049 KoPictureType::Type KoPictureImage::getType(void) const
00050 {
00051     return KoPictureType::TypeImage;
00052 }
00053 
00054 bool KoPictureImage::isNull(void) const
00055 {
00056     return m_originalImage.isNull();
00057 }
00058 
00059 void KoPictureImage::scaleAndCreatePixmap(const QSize& size, bool fastMode)
00060 {
00061     if ((size==m_cachedSize)
00062         && ((fastMode) || (!m_cacheIsInFastMode)))
00063     {
00064         // The cached pixmap has already the right size
00065         // and:
00066         // - we are in fast mode (We do not care if the re-size was done slowly previously)
00067         // - the re-size was already done in slow mode
00068         return;
00069     }
00070 
00071     // Slow mode can be very slow, especially at high zoom levels -> configurable
00072     if ( !isSlowResizeModeAllowed() )
00073     {
00074         kdDebug(30003) << "User has disallowed slow mode!" << endl;
00075         fastMode = true;
00076     }
00077 
00078     // Use QImage::scale if we have fastMode==true
00079     if ( fastMode )
00080     {
00081         m_cachedPixmap.convertFromImage(m_originalImage.scale( size ), QPixmap::Color); // Always color or else B/W can be reversed
00082         m_cacheIsInFastMode=true;
00083     }
00084     else
00085     {
00086         m_cachedPixmap.convertFromImage(m_originalImage.smoothScale( size ), QPixmap::Color); // Always color or else B/W can be reversed
00087         m_cacheIsInFastMode=false;
00088     }
00089     m_cachedSize=size;
00090 }
00091 
00092 void KoPictureImage::draw(QPainter& painter, int x, int y, int width, int height, int sx, int sy, int sw, int sh, bool fastMode)
00093 {
00094     //kdDebug() << "KoImage::draw currentSize:" << currentSize.width() << "x" << currentSize.height() << endl;
00095     if ( !width || !height )
00096         return;
00097     QSize origSize = getOriginalSize();
00098     const bool scaleImage = painter.device()->isExtDev() // we are printing
00099         && ((width <= origSize.width()) || (height <= origSize.height()));
00100     if( scaleImage )
00101     {
00102         // use full resolution of image
00103         double xScale = double(width) / double(origSize.width());
00104         double yScale = double(height) / double(origSize.height());
00105 
00106         painter.save();
00107         painter.translate( x, y );
00108         painter.scale( xScale, yScale );
00109         // Note that sx, sy, sw and sh are unused in this case. Not a problem, since it's about printing.
00110         // Note 2: we do not cache the QPixmap. As we are printing, the next time we will probably
00111         //   need again the screen version.
00112         painter.drawImage(0, 0, m_originalImage);
00113         painter.restore();
00114     }
00115     else
00116     {
00117         QSize screenSize( width, height );
00118         //kdDebug() << "KoPictureImage::draw screenSize=" << screenSize.width() << "x" << screenSize.height() << endl;
00119 
00120         scaleAndCreatePixmap(screenSize, fastMode);
00121 
00122         // sx,sy,sw,sh is meant to be used as a cliprect on the pixmap, but drawPixmap
00123         // translates it to the (x,y) point -> we need (x+sx, y+sy).
00124         painter.drawPixmap( x + sx, y + sy, m_cachedPixmap, sx, sy, sw, sh );
00125     }
00126 }
00127 
00128 bool KoPictureImage::loadData(const QByteArray& array, const QString& /* extension*/ )
00129 {
00130     m_rawData=array;
00131     // Second, create the original image
00132     QBuffer buffer(m_rawData);
00133     buffer.open(IO_ReadWrite);
00134     QImageIO imageIO(&buffer,NULL);
00135 
00136     if (!imageIO.read())
00137     {
00138         buffer.close();
00139         kdError(30003) << "Image could not be loaded!" << endl;
00140         return false;
00141     }
00142     buffer.close();
00143     m_originalImage=imageIO.image();
00144 
00145     return true;
00146 }
00147 
00148 bool KoPictureImage::save(QIODevice* io) const
00149 {
00150     kdDebug() << k_funcinfo << "writing raw data. size=" << m_rawData.size() << endl;
00151     // We save the raw data, to avoid damaging the file by many load/save cycles (especially for JPEG)
00152     Q_ULONG size=io->writeBlock(m_rawData); // WARNING: writeBlock returns Q_LONG but size() Q_ULONG!
00153     return (size==m_rawData.size());
00154 }
00155 
00156 QSize KoPictureImage::getOriginalSize(void) const
00157 {
00158     return m_originalImage.size();
00159 }
00160 
00161 QPixmap KoPictureImage::generatePixmap(const QSize& size, bool smoothScale)
00162 {
00163     scaleAndCreatePixmap(size,!smoothScale);
00164     return m_cachedPixmap;
00165 }
00166 
00167 QString KoPictureImage::getMimeType(const QString& extension) const
00168 {
00169     QString fileName("/tmp/temp.");
00170     fileName+=extension;
00171     // Find the mimetype only by the extension, not by file content (as the file is empty!)
00172     const QString mimetype( KMimeType::findByPath( fileName, 0 ,true )->name() );
00173     // ### TODO: use KMimeType::findByContent (but then the mimetype probably need to be cached)
00174     kdDebug(30003) << "Image is mime type: " << mimetype << endl;
00175     return mimetype;
00176 }
00177 
00178 QDragObject* KoPictureImage::dragObject( QWidget *dragSource, const char *name )
00179 {
00180     return new QImageDrag( m_originalImage, dragSource, name );
00181 }
00182 
00183 QImage KoPictureImage::generateImage(const QSize& size)
00184 {
00185     // We do not cache the image, as we will seldom need it again.
00186     return m_originalImage.smoothScale( size );
00187 }
00188 
00189 void KoPictureImage::clearCache(void)
00190 {
00191     m_cachedPixmap.resize(0, 0);
00192     m_cacheIsInFastMode=true;
00193     m_cachedSize=QSize();
00194 }
KDE Home | KDE Accessibility Home | Description of Access Keys