KoPictureImage.cpp
1/* This file is part of the KDE project
2 Copyright (c) 2001 Simon Hausmann <hausmann@kde.org>
3 Copyright (C) 2002, 2003 Nicolas GOUTTE <goutte@kde.org>
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19*/
20
21#include "KoPictureImage.h"
22#include "KoPictureKey.h"
23
24#include <kdebug.h>
25#include <kmimetype.h>
26
27#include <tqbuffer.h>
28#include <tqpainter.h>
29#include <tqimage.h>
30#include <tqpixmap.h>
31#include <tqapplication.h>
32#include <tqdragobject.h>
33
34KoPictureImage::KoPictureImage(void) : m_cacheIsInFastMode(true)
35{
36 // Forbid TQPixmap to cache the X-Window resources (Yes, it is slower!)
37 m_cachedPixmap.setOptimization(TQPixmap::MemoryOptim);
38}
39
40KoPictureImage::~KoPictureImage(void)
41{
42}
43
44KoPictureBase* KoPictureImage::newCopy(void) const
45{
46 return new KoPictureImage(*this);
47}
48
49KoPictureType::Type KoPictureImage::getType(void) const
50{
51 return KoPictureType::TypeImage;
52}
53
54bool KoPictureImage::isNull(void) const
55{
56 return m_originalImage.isNull();
57}
58
59void KoPictureImage::scaleAndCreatePixmap(const TQSize& size, bool fastMode)
60{
61 if ((size==m_cachedSize)
62 && ((fastMode) || (!m_cacheIsInFastMode)))
63 {
64 // The cached pixmap has already the right size
65 // and:
66 // - we are in fast mode (We do not care if the re-size was done slowly previously)
67 // - the re-size was already done in slow mode
68 return;
69 }
70
71 // Slow mode can be very slow, especially at high zoom levels -> configurable
72 if ( !isSlowResizeModeAllowed() )
73 {
74 kdDebug(30003) << "User has disallowed slow mode!" << endl;
75 fastMode = true;
76 }
77
78 // Use TQImage::scale if we have fastMode==true
79 if ( fastMode )
80 {
81 m_cachedPixmap.convertFromImage(m_originalImage.scale( size ), TQPixmap::Color); // Always color or else B/W can be reversed
82 m_cacheIsInFastMode=true;
83 }
84 else
85 {
86 m_cachedPixmap.convertFromImage(m_originalImage.smoothScale( size ), TQPixmap::Color); // Always color or else B/W can be reversed
87 m_cacheIsInFastMode=false;
88 }
89 m_cachedSize=size;
90}
91
92void KoPictureImage::draw(TQPainter& painter, int x, int y, int width, int height, int sx, int sy, int sw, int sh, bool fastMode)
93{
94 //kdDebug() << "KoImage::draw currentSize:" << currentSize.width() << "x" << currentSize.height() << endl;
95 if ( !width || !height )
96 return;
97 TQSize origSize = getOriginalSize();
98 const bool scaleImage = painter.device()->isExtDev() // we are printing
99 && ((width <= origSize.width()) || (height <= origSize.height()));
100 if( scaleImage )
101 {
102 // use full resolution of image
103 double xScale = double(width) / double(origSize.width());
104 double yScale = double(height) / double(origSize.height());
105
106 painter.save();
107 painter.translate( x, y );
108 painter.scale( xScale, yScale );
109 // Note that sx, sy, sw and sh are unused in this case. Not a problem, since it's about printing.
110 // Note 2: we do not cache the TQPixmap. As we are printing, the next time we will probably
111 // need again the screen version.
112 painter.drawImage(0, 0, m_originalImage);
113 painter.restore();
114 }
115 else
116 {
117 TQSize screenSize( width, height );
118 //kdDebug() << "KoPictureImage::draw screenSize=" << screenSize.width() << "x" << screenSize.height() << endl;
119
120 scaleAndCreatePixmap(screenSize, fastMode);
121
122 // sx,sy,sw,sh is meant to be used as a cliprect on the pixmap, but drawPixmap
123 // translates it to the (x,y) point -> we need (x+sx, y+sy).
124 painter.drawPixmap( x + sx, y + sy, m_cachedPixmap, sx, sy, sw, sh );
125 }
126}
127
128bool KoPictureImage::loadData(const TQByteArray& array, const TQString& /* extension*/ )
129{
130 m_rawData=array;
131 // Second, create the original image
132 TQBuffer buffer(m_rawData);
133 buffer.open(IO_ReadWrite);
134 TQImageIO imageIO(&buffer,NULL);
135
136 if (!imageIO.read())
137 {
138 buffer.close();
139 kdError(30003) << "Image could not be loaded!" << endl;
140 return false;
141 }
142 buffer.close();
143 m_originalImage=imageIO.image();
144
145 return true;
146}
147
148bool KoPictureImage::save(TQIODevice* io) const
149{
150 kdDebug() << k_funcinfo << "writing raw data. size=" << m_rawData.size() << endl;
151 // We save the raw data, to avoid damaging the file by many load/save cycles (especially for JPEG)
152 TQ_ULONG size=io->writeBlock(m_rawData); // WARNING: writeBlock returns TQ_LONG but size() TQ_ULONG!
153 return (size==m_rawData.size());
154}
155
156TQSize KoPictureImage::getOriginalSize(void) const
157{
158 return m_originalImage.size();
159}
160
161TQPixmap KoPictureImage::generatePixmap(const TQSize& size, bool smoothScale)
162{
163 scaleAndCreatePixmap(size,!smoothScale);
164 return m_cachedPixmap;
165}
166
167TQString KoPictureImage::getMimeType(const TQString& extension) const
168{
169 TQString fileName("/tmp/temp.");
170 fileName+=extension;
171 // Find the mimetype only by the extension, not by file content (as the file is empty!)
172 const TQString mimetype( KMimeType::findByPath( fileName, 0 ,true )->name() );
173 // ### TODO: use KMimeType::findByContent (but then the mimetype probably need to be cached)
174 kdDebug(30003) << "Image is mime type: " << mimetype << endl;
175 return mimetype;
176}
177
178TQDragObject* KoPictureImage::dragObject( TQWidget *dragSource, const char *name )
179{
180 return new TQImageDrag( m_originalImage, dragSource, name );
181}
182
183TQImage KoPictureImage::generateImage(const TQSize& size)
184{
185 // We do not cache the image, as we will seldom need it again.
186 return m_originalImage.smoothScale( size );
187}
188
189void KoPictureImage::clearCache(void)
190{
191 m_cachedPixmap.resize(0, 0);
192 m_cacheIsInFastMode=true;
193 m_cachedSize=TQSize();
194}
const char * name(StdAction id)