|
|
|
/* This file is part of the KDE project
|
|
|
|
Copyright (c) 2001 Simon Hausmann <hausmann@kde.org>
|
|
|
|
Copyright (C) 2002, 2003 Nicolas GOUTTE <goutte@kde.org>
|
|
|
|
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU Library General Public
|
|
|
|
License as published by the Free Software Foundation; either
|
|
|
|
version 2 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
|
|
|
|
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 "KoPictureImage.h"
|
|
|
|
#include "KoPictureKey.h"
|
|
|
|
|
|
|
|
#include <kdebug.h>
|
|
|
|
#include <kmimetype.h>
|
|
|
|
|
|
|
|
#include <tqbuffer.h>
|
|
|
|
#include <tqpainter.h>
|
|
|
|
#include <tqimage.h>
|
|
|
|
#include <tqpixmap.h>
|
|
|
|
#include <tqapplication.h>
|
|
|
|
#include <tqdragobject.h>
|
|
|
|
|
|
|
|
KoPictureImage::KoPictureImage(void) : m_cacheIsInFastMode(true)
|
|
|
|
{
|
|
|
|
// Forbid TQPixmap to cache the X-Window resources (Yes, it is slower!)
|
|
|
|
m_cachedPixmap.setOptimization(TQPixmap::MemoryOptim);
|
|
|
|
}
|
|
|
|
|
|
|
|
KoPictureImage::~KoPictureImage(void)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
KoPictureBase* KoPictureImage::newCopy(void) const
|
|
|
|
{
|
|
|
|
return new KoPictureImage(*this);
|
|
|
|
}
|
|
|
|
|
|
|
|
KoPictureType::Type KoPictureImage::getType(void) const
|
|
|
|
{
|
|
|
|
return KoPictureType::TypeImage;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool KoPictureImage::isNull(void) const
|
|
|
|
{
|
|
|
|
return m_originalImage.isNull();
|
|
|
|
}
|
|
|
|
|
|
|
|
void KoPictureImage::scaleAndCreatePixmap(const TQSize& size, bool fastMode)
|
|
|
|
{
|
|
|
|
if ((size==m_cachedSize)
|
|
|
|
&& ((fastMode) || (!m_cacheIsInFastMode)))
|
|
|
|
{
|
|
|
|
// The cached pixmap has already the right size
|
|
|
|
// and:
|
|
|
|
// - we are in fast mode (We do not care if the re-size was done slowly previously)
|
|
|
|
// - the re-size was already done in slow mode
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Slow mode can be very slow, especially at high zoom levels -> configurable
|
|
|
|
if ( !isSlowResizeModeAllowed() )
|
|
|
|
{
|
|
|
|
kdDebug(30003) << "User has disallowed slow mode!" << endl;
|
|
|
|
fastMode = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Use TQImage::scale if we have fastMode==true
|
|
|
|
if ( fastMode )
|
|
|
|
{
|
|
|
|
m_cachedPixmap.convertFromImage(m_originalImage.scale( size ), TQPixmap::Color); // Always color or else B/W can be reversed
|
|
|
|
m_cacheIsInFastMode=true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_cachedPixmap.convertFromImage(m_originalImage.smoothScale( size ), TQPixmap::Color); // Always color or else B/W can be reversed
|
|
|
|
m_cacheIsInFastMode=false;
|
|
|
|
}
|
|
|
|
m_cachedSize=size;
|
|
|
|
}
|
|
|
|
|
|
|
|
void KoPictureImage::draw(TQPainter& painter, int x, int y, int width, int height, int sx, int sy, int sw, int sh, bool fastMode)
|
|
|
|
{
|
|
|
|
//kdDebug() << "KoImage::draw currentSize:" << currentSize.width() << "x" << currentSize.height() << endl;
|
|
|
|
if ( !width || !height )
|
|
|
|
return;
|
|
|
|
TQSize origSize = getOriginalSize();
|
|
|
|
const bool scaleImage = painter.device()->isExtDev() // we are printing
|
|
|
|
&& ((width <= origSize.width()) || (height <= origSize.height()));
|
|
|
|
if( scaleImage )
|
|
|
|
{
|
|
|
|
// use full resolution of image
|
|
|
|
double xScale = double(width) / double(origSize.width());
|
|
|
|
double yScale = double(height) / double(origSize.height());
|
|
|
|
|
|
|
|
painter.save();
|
|
|
|
painter.translate( x, y );
|
|
|
|
painter.scale( xScale, yScale );
|
|
|
|
// Note that sx, sy, sw and sh are unused in this case. Not a problem, since it's about printing.
|
|
|
|
// Note 2: we do not cache the TQPixmap. As we are printing, the next time we will probably
|
|
|
|
// need again the screen version.
|
|
|
|
painter.drawImage(0, 0, m_originalImage);
|
|
|
|
painter.restore();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
TQSize screenSize( width, height );
|
|
|
|
//kdDebug() << "KoPictureImage::draw screenSize=" << screenSize.width() << "x" << screenSize.height() << endl;
|
|
|
|
|
|
|
|
scaleAndCreatePixmap(screenSize, fastMode);
|
|
|
|
|
|
|
|
// sx,sy,sw,sh is meant to be used as a cliprect on the pixmap, but drawPixmap
|
|
|
|
// translates it to the (x,y) point -> we need (x+sx, y+sy).
|
|
|
|
painter.drawPixmap( x + sx, y + sy, m_cachedPixmap, sx, sy, sw, sh );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool KoPictureImage::loadData(const TQByteArray& array, const TQString& /* extension*/ )
|
|
|
|
{
|
|
|
|
m_rawData=array;
|
|
|
|
// Second, create the original image
|
|
|
|
TQBuffer buffer(m_rawData);
|
|
|
|
buffer.open(IO_ReadWrite);
|
|
|
|
TQImageIO imageIO(&buffer,NULL);
|
|
|
|
|
|
|
|
if (!imageIO.read())
|
|
|
|
{
|
|
|
|
buffer.close();
|
|
|
|
kdError(30003) << "Image could not be loaded!" << endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
buffer.close();
|
|
|
|
m_originalImage=imageIO.image();
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool KoPictureImage::save(TQIODevice* io) const
|
|
|
|
{
|
|
|
|
kdDebug() << k_funcinfo << "writing raw data. size=" << m_rawData.size() << endl;
|
|
|
|
// We save the raw data, to avoid damaging the file by many load/save cycles (especially for JPEG)
|
|
|
|
TQ_ULONG size=io->writeBlock(m_rawData); // WARNING: writeBlock returns TQ_LONG but size() TQ_ULONG!
|
|
|
|
return (size==m_rawData.size());
|
|
|
|
}
|
|
|
|
|
|
|
|
TQSize KoPictureImage::getOriginalSize(void) const
|
|
|
|
{
|
|
|
|
return m_originalImage.size();
|
|
|
|
}
|
|
|
|
|
|
|
|
TQPixmap KoPictureImage::generatePixmap(const TQSize& size, bool smoothScale)
|
|
|
|
{
|
|
|
|
scaleAndCreatePixmap(size,!smoothScale);
|
|
|
|
return m_cachedPixmap;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString KoPictureImage::getMimeType(const TQString& extension) const
|
|
|
|
{
|
|
|
|
TQString fileName("/tmp/temp.");
|
|
|
|
fileName+=extension;
|
|
|
|
// Find the mimetype only by the extension, not by file content (as the file is empty!)
|
|
|
|
const TQString mimetype( KMimeType::findByPath( fileName, 0 ,true )->name() );
|
|
|
|
// ### TODO: use KMimeType::findByContent (but then the mimetype probably need to be cached)
|
|
|
|
kdDebug(30003) << "Image is mime type: " << mimetype << endl;
|
|
|
|
return mimetype;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQDragObject* KoPictureImage::dragObject( TQWidget *dragSource, const char *name )
|
|
|
|
{
|
|
|
|
return new TQImageDrag( m_originalImage, dragSource, name );
|
|
|
|
}
|
|
|
|
|
|
|
|
TQImage KoPictureImage::generateImage(const TQSize& size)
|
|
|
|
{
|
|
|
|
// We do not cache the image, as we will seldom need it again.
|
|
|
|
return m_originalImage.smoothScale( size );
|
|
|
|
}
|
|
|
|
|
|
|
|
void KoPictureImage::clearCache(void)
|
|
|
|
{
|
|
|
|
m_cachedPixmap.resize(0, 0);
|
|
|
|
m_cacheIsInFastMode=true;
|
|
|
|
m_cachedSize=TQSize();
|
|
|
|
}
|