kpresenter

KPrPixmapObject.cpp
1/* This file is part of the KDE project
2 Copyright (C) 1998, 1999 Reginald Stadlbauer <reggie@kde.org>
3 Copyright (C) 2005 Thorsten Zachmann <zachmann@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// ### TODO: fix copyright date/authors
22
23// for getenv ()
24#include <stdlib.h>
25#include <float.h>
26
27#include <tqbuffer.h>
28#include <tqpainter.h>
29#include <tqwmatrix.h>
30#include <tqfileinfo.h>
31#include <tqpixmap.h>
32#include <tqdom.h>
33#include <tqimage.h>
34#include <tqbitmap.h>
35
36#include <kdebug.h>
37#include <kimageeffect.h>
38#include <KoSize.h>
39#include <KoTextZoomHandler.h>
40#include <KoStore.h>
41#include <KoStoreDevice.h>
42#include <KoOasisContext.h>
43#include <KoXmlNS.h>
44#include <KoDom.h>
45
46#include "KPrPixmapObject.h"
47#include "KPrGradient.h"
48#include "KPrPixmapObjectIface.h"
49
50
51KPrPixmapObject::KPrPixmapObject( KoPictureCollection *_imageCollection )
52 : KPr2DObject()
53{
54 imageCollection = _imageCollection;
55 pen = KoPen( TQt::black, 1.0, TQt::NoPen );
56 mirrorType = PM_NORMAL;
57 depth = 0;
58 swapRGB = false;
59 grayscal = false;
60 bright = 0;
61 m_effect = IE_NONE;
62 m_ie_par1 = TQVariant();
63 m_ie_par2 = TQVariant();
64 m_ie_par3 = TQVariant();
65 // Forbid TQPixmap to cache the X-Window resources (Yes, it is slower!)
66 m_cachedPixmap.setOptimization(TQPixmap::MemoryOptim);
67 keepRatio = true;
68}
69
70KPrPixmapObject::KPrPixmapObject( KoPictureCollection *_imageCollection, const KoPictureKey & key )
71 : KPr2DObject()
72{
73 imageCollection = _imageCollection;
74
75 ext = KoSize(); // invalid size means unset
76 pen = KoPen( TQt::black, 1.0, TQt::NoPen );
77 mirrorType = PM_NORMAL;
78 depth = 0;
79 swapRGB = false;
80 grayscal = false;
81 bright = 0;
82 m_effect = IE_NONE;
83 m_ie_par1 = TQVariant();
84 m_ie_par2 = TQVariant();
85 m_ie_par3 = TQVariant();
86 // Forbid TQPixmap to cache the X-Window resources (Yes, it is slower!)
87 m_cachedPixmap.setOptimization(TQPixmap::MemoryOptim);
88
89 setPicture( key );
90}
91
92DCOPObject* KPrPixmapObject::dcopObject()
93{
94 if ( !dcop )
95 dcop = new KPrPixmapObjectIface( this );
96 return dcop;
97}
98
99TQString KPrPixmapObject::convertValueToPercent( int val ) const
100{
101 return TQString::number( val )+"%";
102}
103
104void KPrPixmapObject::saveOasisPictureElement( KoGenStyle &styleobjectauto ) const
105{
106
107 if ( bright != 0 )
108 {
109 styleobjectauto.addProperty( "draw:luminance", convertValueToPercent( bright ) );
110 }
111 if ( grayscal )
112 {
113 styleobjectauto.addProperty( "draw:color-mode","greyscale" );
114 }
115
116 switch (m_effect)
117 {
118 case IE_NONE:
119 //nothing
120 break;
121 case IE_CHANNEL_INTENSITY:
122 {
123 //for the moment kpresenter support just one channel
124 TQString percent = convertValueToPercent( m_ie_par1.toInt() );
125 KImageEffect::RGBComponent channel = static_cast<KImageEffect::RGBComponent>( m_ie_par2.toInt() );
126 switch( channel )
127 {
128 case KImageEffect::Red:
129 styleobjectauto.addProperty( "draw:red", percent );
130 styleobjectauto.addProperty( "draw:blue", "0%" );
131 styleobjectauto.addProperty( "draw:green", "0%" );
132 break;
133 case KImageEffect::Green:
134 styleobjectauto.addProperty( "draw:green", percent );
135 styleobjectauto.addProperty( "draw:red", "0%" );
136 styleobjectauto.addProperty( "draw:blue", "0%" );
137 break;
138 case KImageEffect::Blue:
139 styleobjectauto.addProperty( "draw:blue", percent );
140 styleobjectauto.addProperty( "draw:red", "0%" );
141 styleobjectauto.addProperty( "draw:green", "0%" );
142 break;
143 case KImageEffect::Gray:
144 break;
145 case KImageEffect::All:
146 break;
147 }
148 }
149 break;
150 case IE_FADE:
151 break;
152 case IE_FLATTEN:
153 break;
154 case IE_INTENSITY:
155 break;
156 case IE_DESATURATE:
157 break;
158 case IE_CONTRAST:
159 {
160 //kpresenter use value between -255 and 255
161 //oo impress between -100% and 100%
162 int val = m_ie_par1.toInt();
163 val = ( int )( ( double )val*100.0/255.0 );
164 styleobjectauto.addProperty( "draw:contrast", convertValueToPercent( val ) );
165 }
166 break;
167 case IE_NORMALIZE:
168 break;
169 case IE_EQUALIZE:
170 break;
171 case IE_THRESHOLD:
172 break;
173 case IE_SOLARIZE:
174 break;
175 case IE_EMBOSS:
176 break;
177 case IE_DESPECKLE:
178 break;
179 case IE_CHARCOAL:
180 break;
181 case IE_NOISE:
182 break;
183 case IE_BLUR:
184 break;
185 case IE_EDGE:
186 break;
187 case IE_IMPLODE:
188 break;
189 case IE_OIL_PAINT:
190 break;
191 case IE_SHARPEN:
192 break;
193 case IE_SPREAD:
194 break;
195 case IE_SHADE:
196 break;
197 case IE_SWIRL:
198 break;
199 case IE_WAVE:
200 break;
201 }
202}
203
204bool KPrPixmapObject::saveOasisObjectAttributes( KPOasisSaveContext &sc ) const
205{
206 sc.xmlWriter.startElement( "draw:image" );
207 sc.xmlWriter.addAttribute( "xlink:type", "simple" );
208 sc.xmlWriter.addAttribute( "xlink:show", "embed" );
209 sc.xmlWriter.addAttribute( "xlink:actuate", "onLoad" );
210 sc.xmlWriter.addAttribute( "xlink:href", imageCollection->getOasisFileName( image ) );
211 sc.xmlWriter.endElement();
212
213 return true;
214}
215
216const char * KPrPixmapObject::getOasisElementName() const
217{
218 return "draw:frame";
219}
220
221
222// Deprecated, same as KPrPixmapObject::loadPicture
223void KPrPixmapObject::loadImage( const TQString & fileName )
224{
225 loadPicture( fileName );
226}
227
228void KPrPixmapObject::loadPicture( const TQString & fileName )
229{
230 image = imageCollection->loadPicture( fileName );
231}
232
233KPrPixmapObject &KPrPixmapObject::operator=( const KPrPixmapObject & )
234{
235 return *this;
236}
237
238// Deprecated, same as KPrPixmapObject::setPicture
239void KPrPixmapObject::setPixmap( const KoPictureKey & key )
240{
241 setPicture( key );
242}
243
244void KPrPixmapObject::setPicture( const KoPictureKey & key )
245{
246 image = imageCollection->findPicture( key );
247}
248
249void KPrPixmapObject::reload( void )
250{
251 // ### FIXME: this seems wrong, KoPictureCollection will never reload it (or perhaps it is the function name that is wrong)
252 setPicture( image.getKey() );
253 if (image.isNull()) {
254 // this happens for example when doing copy&paste from a different KPresenter instance
255 image = imageCollection->loadPicture( image.getKey().filename() );
256 }
257}
258
259TQDomDocumentFragment KPrPixmapObject::save( TQDomDocument& doc, double offset )
260{
261 TQDomDocumentFragment fragment=KPr2DObject::save(doc, offset);
262 TQDomElement elem=doc.createElement("KEY");
263 image.getKey().saveAttributes(elem);
264 fragment.appendChild(elem);
265
266 TQDomElement elemSettings = doc.createElement( "PICTURESETTINGS" );
267
268 elemSettings.setAttribute( "mirrorType", static_cast<int>( mirrorType ) );
269 elemSettings.setAttribute( "depth", depth );
270 elemSettings.setAttribute( "swapRGB", static_cast<int>( swapRGB ) );
271 elemSettings.setAttribute( "grayscal", static_cast<int>( grayscal ) );
272 elemSettings.setAttribute( "bright", bright );
273 fragment.appendChild( elemSettings );
274
275 if (m_effect!=IE_NONE) {
276 TQDomElement imageEffects = doc.createElement("EFFECTS");
277 imageEffects.setAttribute("type", static_cast<int>(m_effect));
278 if (m_ie_par1.isValid())
279 imageEffects.setAttribute("param1", m_ie_par1.toString());
280 if (m_ie_par2.isValid())
281 imageEffects.setAttribute("param2", m_ie_par2.toString());
282 if (m_ie_par3.isValid())
283 imageEffects.setAttribute("param3", m_ie_par3.toString());
284 fragment.appendChild( imageEffects );
285 }
286
287 return fragment;
288}
289
290void KPrPixmapObject::loadOasisPictureEffect(KoOasisContext & context )
291{
292 KoStyleStack &styleStack = context.styleStack();
293 styleStack.setTypeProperties( "graphic" );
294 if ( styleStack.hasAttributeNS( KoXmlNS::draw, "color-mode" ) && ( styleStack.attributeNS( KoXmlNS::draw, "color-mode" )=="greyscale" ) )
295 {
296 grayscal = true;
297 }
298
299 if ( styleStack.hasAttributeNS( KoXmlNS::draw, "contrast" ) )
300 {
301 TQString str( styleStack.attributeNS( KoXmlNS::draw, "contrast" ) );
302 str = str.remove( '%' );
303 int val = str.toInt();
304 m_effect = IE_CONTRAST;
305 val = ( int )( 255.0 *val/100.0 );
306 m_ie_par1 = TQVariant(val);
307 }
308 if ( styleStack.hasAttributeNS( KoXmlNS::draw, "red" ) && styleStack.attributeNS( KoXmlNS::draw, "red" ) != "0%" )
309 {
310 TQString str( styleStack.attributeNS( KoXmlNS::draw, "red" ) );
311 str = str.remove( '%' );
312 int val = str.toInt();
313 m_effect = IE_CHANNEL_INTENSITY;
314 m_ie_par1 = TQVariant(val);
315 m_ie_par2 = TQVariant( ( int )KImageEffect::Red );
316 }
317 if ( styleStack.hasAttributeNS( KoXmlNS::draw, "green" ) && styleStack.attributeNS( KoXmlNS::draw, "green" ) != "0%" )
318 {
319 TQString str( styleStack.attributeNS( KoXmlNS::draw, "green" ) );
320 str = str.remove( '%' );
321 int val = str.toInt();
322 m_effect = IE_CHANNEL_INTENSITY;
323 m_ie_par1 = TQVariant(val);
324 m_ie_par2 = TQVariant( ( int )KImageEffect::Green );
325 }
326 if ( styleStack.hasAttributeNS( KoXmlNS::draw, "blue" ) && styleStack.attributeNS( KoXmlNS::draw, "blue" ) != "0%" )
327 {
328 TQString str( styleStack.attributeNS( KoXmlNS::draw, "blue" ) );
329 str = str.remove( '%' );
330 int val = str.toInt();
331 m_effect = IE_CHANNEL_INTENSITY;
332 m_ie_par1 = TQVariant(val);
333 m_ie_par2 = TQVariant( ( int )KImageEffect::Blue );
334 }
335 if ( styleStack.hasAttributeNS( KoXmlNS::draw, "luminance" ) )
336 {
337 TQString str( styleStack.attributeNS( KoXmlNS::draw, "luminance" ) );
338 str = str.remove( '%' );
339 bright = str.toInt();
340 }
341
342}
343
344void KPrPixmapObject::fillStyle( KoGenStyle& styleObjectAuto, KoGenStyles& mainStyles ) const
345{
346 KPr2DObject::fillStyle( styleObjectAuto, mainStyles );
347 saveOasisPictureElement( styleObjectAuto );
348}
349
350void KPrPixmapObject::loadOasis(const TQDomElement &element, KoOasisContext & context, KPrLoadingInfo *info)
351{
352 //load it into kpresenter_doc
353 KPr2DObject::loadOasis( element, context, info );
354 loadOasisPictureEffect( context );
355 TQDomNode imageBox = KoDom::namedItemNS( element, KoXmlNS::draw, "image" );
356 const TQString href( imageBox.toElement().attributeNS( KoXmlNS::xlink, "href", TQString()) );
357 kdDebug()<<" href: "<<href<<endl;
358 if ( !href.isEmpty() /*&& href[0] == '#'*/ )
359 {
360 TQString strExtension;
361 const int result=href.findRev(".");
362 if (result>=0)
363 {
364 strExtension=href.mid(result+1); // As we are using KoPicture, the extension should be without the dot.
365 }
366 TQString filename(href/*.mid(1)*/);
367 const KoPictureKey key(filename, TQDateTime::currentDateTime(TQt::UTC));
368 image.setKey(key);
369
370 KoStore* store = context.store();
371 if ( store->open( filename ) )
372 {
373 KoStoreDevice dev(store);
374 if ( !image.load( &dev, strExtension ) )
375 kdWarning() << "Cannot load picture: " << filename << " " << href << endl;
376 store->close();
377 }
378 imageCollection->insertPicture( key, image );
379 }
380 // ### TODO: load remote file
381}
382
383
384double KPrPixmapObject::load(const TQDomElement &element)
385{
386 double offset=KPr2DObject::load(element);
387 TQDomElement e=element.namedItem("KEY").toElement();
388 if(!e.isNull()) {
389 KoPictureKey key;
390 key.loadAttributes( e );
391 image.clear();
392 image.setKey(key);
393 }
394 else {
395 // try to find a PIXMAP tag if the KEY is not available...
396 e=element.namedItem("PIXMAP").toElement();
397 if (e.isNull()) {
398 // try to find a FILENAME tag (old cliparts...)
399 e=element.namedItem("FILENAME").toElement();
400 if(!e.isNull()) {
401 // Loads from the disk directly (unless it's in the collection already?)
402 image = imageCollection->loadPicture( e.attribute("filename") );
403 }
404 } else {
405 bool openPic = true;
406 TQString _data;
407 TQString _fileName;
408 if(e.hasAttribute("data"))
409 _data=e.attribute("data");
410 if ( _data.isEmpty() )
411 openPic = true;
412 else
413 openPic = false;
414 if(e.hasAttribute("filename"))
415 _fileName=e.attribute("filename");
416 if ( !_fileName.isEmpty() )
417 {
418 if ( int _envVarB = _fileName.find( '$' ) >= 0 )
419 {
420 int _envVarE = _fileName.find( '/', _envVarB );
421 // ### FIXME: it should be TQString::local8Bit instead of TQFile::encodeName, shouldn't it?
422 TQString path = getenv( TQFile::encodeName(_fileName.mid( _envVarB, _envVarE-_envVarB )) );
423 _fileName.replace( _envVarB-1, _envVarE-_envVarB+1, path );
424 }
425 }
426
427 if ( openPic )
428 // !! this loads it from the disk (unless it's in the image collection already)
429 image = imageCollection->loadPicture( _fileName );
430 else
431 {
432 KoPictureKey key( _fileName );
433 image.clear();
434 image.setKey(key);
435 TQByteArray rawData=_data.utf8(); // XPM is normally ASCII, therefore UTF-8
436 rawData[rawData.size()-1]=char(10); // Replace the NULL character by a LINE FEED
437 TQBuffer buffer(rawData); // ### TODO: open?
438 image.loadXpm(&buffer);
439 }
440 }
441 }
442
443 e = element.namedItem( "PICTURESETTINGS" ).toElement();
444 if ( !e.isNull() ) {
445 PictureMirrorType _mirrorType = PM_NORMAL;
446 int _depth = 0;
447 bool _swapRGB = false;
448 bool _grayscal = false;
449 int _bright = 0;
450
451 if ( e.hasAttribute( "mirrorType" ) )
452 _mirrorType = static_cast<PictureMirrorType>( e.attribute( "mirrorType" ).toInt() );
453 if ( e.hasAttribute( "depth" ) )
454 _depth = e.attribute( "depth" ).toInt();
455 if ( e.hasAttribute( "swapRGB" ) )
456 _swapRGB = static_cast<bool>( e.attribute( "swapRGB" ).toInt() );
457 if ( e.hasAttribute( "grayscal" ) )
458 _grayscal = static_cast<bool>( e.attribute( "grayscal" ).toInt() );
459 if ( e.hasAttribute( "bright" ) )
460 _bright = e.attribute( "bright" ).toInt();
461
462 mirrorType = _mirrorType;
463 depth = _depth;
464 swapRGB = _swapRGB;
465 grayscal = _grayscal;
466 bright = _bright;
467 }
468 else {
469 mirrorType = PM_NORMAL;
470 depth = 0;
471 swapRGB = false;
472 grayscal = false;
473 bright = 0;
474 }
475
476 e = element.namedItem( "EFFECTS" ).toElement();
477 if (!e.isNull()) {
478 if (e.hasAttribute("type"))
479 m_effect = static_cast<ImageEffect>(e.attribute("type").toInt());
480 if (e.hasAttribute("param1"))
481 m_ie_par1 = TQVariant(e.attribute("param1"));
482 else
483 m_ie_par1 = TQVariant();
484 if (e.hasAttribute("param2"))
485 m_ie_par2 = TQVariant(e.attribute("param2"));
486 else
487 m_ie_par2 = TQVariant();
488 if (e.hasAttribute("param3"))
489 m_ie_par3 = TQVariant(e.attribute("param3"));
490 else
491 m_ie_par3 = TQVariant();
492 }
493 else
494 m_effect = IE_NONE;
495
496 return offset;
497}
498
499void KPrPixmapObject::drawShadow( TQPainter* _painter, KoZoomHandler* _zoomHandler)
500{
501 const double ox = orig.x();
502 const double oy = orig.y();
503 const double ow = ext.width();
504 const double oh = ext.height();
505
506 _painter->save();
507
508 TQPen pen2 = pen.zoomedPen( _zoomHandler );
509 _painter->setPen( pen2 );
510 _painter->setBrush( getBrush() );
511
512 double sx = 0;
513 double sy = 0;
514
515 getShadowCoords( sx, sy );
516
517 _painter->translate( _zoomHandler->zoomItX( ox ), _zoomHandler->zoomItY( oy ) );
518 _painter->setPen( TQPen( shadowColor ) );
519 _painter->setBrush( shadowColor );
520 if ( kAbs(angle) <= DBL_EPSILON )
521 _painter->drawRect( _zoomHandler->zoomItX( sx ), _zoomHandler->zoomItY( sy ),
522 _zoomHandler->zoomItX( ext.width() ), _zoomHandler->zoomItY( ext.height() ) );
523 else
524 {
525 TQSize bs = TQSize( _zoomHandler->zoomItX( ow ), _zoomHandler->zoomItY( oh ) );
526 TQRect br = TQRect( 0, 0, bs.width(), bs.height() );
527 int pw = br.width();
528 int ph = br.height();
529 TQRect rr = br;
530 int pixYPos = -rr.y();
531 int pixXPos = -rr.x();
532 br.moveTopLeft( TQPoint( -br.width() / 2, -br.height() / 2 ) );
533 rr.moveTopLeft( TQPoint( -rr.width() / 2, -rr.height() / 2 ) );
534
535 TQWMatrix m;
536 m.translate( pw / 2, ph / 2 );
537 m.rotate( angle );
538 m.translate( rr.left() + pixXPos + _zoomHandler->zoomItX( sx ),
539 rr.top() + pixYPos + _zoomHandler->zoomItY( sy ) );
540
541 _painter->setWorldMatrix( m, true );
542
543 _painter->drawRect( 0, 0, bs.width(), bs.height() );
544 }
545
546 _painter->restore();
547}
548
549TQPixmap KPrPixmapObject::generatePixmap(KoZoomHandler*_zoomHandler)
550{
551 const double penw = _zoomHandler->zoomItX( ( ( pen.style() == TQt::NoPen ) ? 1 : pen.width() ) / 2.0 );
552
553 TQSize size( _zoomHandler->zoomSize( ext ) );
554 //kdDebug(33001) << "KPrPixmapObject::generatePixmap size= " << size << endl;
555 TQPixmap pixmap(size);
556 TQPainter paint;
557
558 paint.begin( &pixmap );
559 pixmap.fill( TQt::white );
560
561 // Draw background
562 paint.setPen( TQt::NoPen );
563 paint.setBrush( getBrush() );
564
565 TQRect rect( (int)( penw ), (int)( penw ),
566 (int)( _zoomHandler->zoomItX( ext.width() ) - 2.0 * penw ),
567 (int)( _zoomHandler->zoomItY( ext.height() ) - 2.0 * penw ) );
568
569 if ( getFillType() == FT_BRUSH || !gradient )
570 paint.drawRect( rect );
571 else {
572 // ### TODO: this was also drawn for drawContour==true, but why?
573 gradient->setSize( size );
574 paint.drawPixmap( (int)( penw ), (int)( penw ),
575 gradient->pixmap(), 0, 0,
576 (int)( _zoomHandler->zoomItX( ext.width() ) - 2 * penw ),
577 (int)( _zoomHandler->zoomItY( ext.height() ) - 2 * penw ) );
578 }
579
580
581 image.draw(paint, 0, 0, size.width(), size.height(), 0, 0, -1, -1, false); // Always slow mode!
582 image.clearCache(); // Release the memoy of the picture cache
583
584 image.setAlphaBuffer(true);
585 TQBitmap tmpMask;
586 tmpMask = image.createAlphaMask().scale(size);
587 pixmap.setMask(tmpMask);
588
589 paint.end();
590 return pixmap;
591}
592
593void KPrPixmapObject::draw( TQPainter *_painter, KoTextZoomHandler*_zoomHandler,
594 int pageNum, SelectionMode selectionMode, bool drawContour )
595{
596 if ( image.isNull() ) return;
597
598 if ( shadowDistance > 0 && !drawContour )
599 drawShadow(_painter, _zoomHandler);
600
601 const double ox = orig.x();
602 const double oy = orig.y();
603 const double ow = ext.width();
604 const double oh = ext.height();
605 const double penw = _zoomHandler->zoomItX( ( ( pen.style() == TQt::NoPen ) ? 1.0 : pen.width() ) / 2.0 );
606
607 _painter->save();
608
609 _painter->translate( _zoomHandler->zoomItX( ox ), _zoomHandler->zoomItY( oy ) );
610
611 if ( kAbs(angle)> DBL_EPSILON ) {
612 TQSize bs = TQSize( _zoomHandler->zoomItX( ow ), _zoomHandler->zoomItY( oh ) );
613 TQRect br = TQRect( 0, 0, bs.width(), bs.height() );
614 int pw = br.width();
615 int ph = br.height();
616 TQRect rr = br;
617 int pixYPos = -rr.y();
618 int pixXPos = -rr.x();
619 br.moveTopLeft( TQPoint( -br.width() / 2, -br.height() / 2 ) );
620 rr.moveTopLeft( TQPoint( -rr.width() / 2, -rr.height() / 2 ) );
621
622 TQWMatrix m;
623 m.translate( pw / 2, ph / 2 );
624 m.rotate( angle );
625 m.translate( rr.left() + pixXPos, rr.top() + pixYPos );
626 _painter->setWorldMatrix( m, true );
627 }
628
629 if ( !drawContour )
630 {
631 TQRect rect( 0, 0, (int)( _zoomHandler->zoomItX( ow ) ),
632 (int)( _zoomHandler->zoomItY( oh ) ) );
633 // ### HACK TQt seems not to be able to correctly compare TQVariant
634 bool variants1;
635 if (m_ie_par1.isNull())
636 variants1=m_cachedPar1.isNull();
637 else
638 variants1=(m_ie_par1 == m_cachedPar1);
639 bool variants2;
640 if (m_ie_par2.isNull())
641 variants2=m_cachedPar2.isNull();
642 else
643 variants2=(m_ie_par2 == m_cachedPar2);
644 bool variants3;
645 if (m_ie_par3.isNull())
646 variants3=m_cachedPar3.isNull();
647 else
648 variants3=(m_ie_par3 == m_cachedPar3);
649
650 if (m_cachedRect == rect
651 // All what KPrPixmapObject::changePictureSettings needs
652 && m_cachedMirrorType == mirrorType && m_cachedSwapRGB == swapRGB && m_cachedGrayscal == grayscal
653 && m_cachedBright == bright && m_cachedEffect == m_effect
654 // Who needs it?
655 && m_cachedDepth == depth
656#if 0
657 && m_ie_par1 == m_cachedPar1 && m_ie_par2 == m_cachedPar2 && m_ie_par3 == m_cachedPar3
658#else
659 && variants1 && variants2 && variants3
660#endif
661 )
662 {
663 //kdDebug(33001) << "Drawing cached pixmap " << (void*) this << " " << k_funcinfo << endl;
664 }
665 else
666 {
667 if (mirrorType != PM_NORMAL || depth != 0 || swapRGB || grayscal || bright != 0 || m_effect!=IE_NONE)
668 m_cachedPixmap = changePictureSettings( generatePixmap( _zoomHandler ) );
669 else
670 m_cachedPixmap = generatePixmap( _zoomHandler );
671 m_cachedRect = rect;
672 m_cachedMirrorType = mirrorType;
673 m_cachedSwapRGB = swapRGB;
674 m_cachedGrayscal = grayscal;
675 m_cachedBright = bright;
676 m_cachedEffect = m_effect;
677 m_cachedDepth = depth;
678 m_cachedPar1 = m_ie_par1;
679 m_cachedPar2 = m_ie_par2;
680 m_cachedPar3 = m_ie_par3;
681 //kdDebug(33001) << "Drawing non-cached pixmap " << (void*) this << " " << k_funcinfo << endl;
682 }
683 _painter->drawPixmap( rect, m_cachedPixmap);
684 }
685
686 // Draw border
687 // ### TODO port to KoBorder::drawBorders() (after writing a simplified version of it, that takes the same border on each size)
688 TQPen pen2;
689 if ( drawContour ) {
690 pen2 = TQPen( TQt::black, 1, TQt::DotLine );
691 _painter->setRasterOp( TQt::NotXorROP );
692 }
693 else {
694 pen2 = pen;
695 pen2.setWidth( _zoomHandler->zoomItX( ( pen.style() == TQt::NoPen ) ? 1.0 : (double)pen.width() ) );
696 }
697 _painter->setPen( pen2 );
698 _painter->setBrush( TQt::NoBrush );
699 _painter->drawRect( (int)( penw ), (int)( penw ),
700 (int)( _zoomHandler->zoomItX( ow ) - 2.0 * penw ),
701 (int)( _zoomHandler->zoomItY( oh ) - 2.0 * penw ) );
702
703 _painter->restore();
704
705 KPrObject::draw( _painter, _zoomHandler, pageNum, selectionMode, drawContour );
706}
707
708TQPixmap KPrPixmapObject::getOriginalPixmap()
709{
710 TQSize _pixSize = image.getOriginalSize();
711 kdDebug(33001) << "KPrPixmapObject::getOriginalPixmap size= " << _pixSize << endl;
712 TQPixmap _pixmap = image.generatePixmap( _pixSize, true );
713 image.clearCache(); // Release the memoy of the picture cache
714
715 return _pixmap;
716}
717
718TQPixmap KPrPixmapObject::changePictureSettings( TQPixmap _tmpPixmap )
719{
720 TQImage _tmpImage = _tmpPixmap.convertToImage();
721
722 if (_tmpImage.isNull())
723 return _tmpPixmap;
724
725 bool _horizontal = false;
726 bool _vertical = false;
727 if ( mirrorType == PM_HORIZONTAL )
728 _horizontal = true;
729 else if ( mirrorType == PM_VERTICAL )
730 _vertical = true;
731 else if ( mirrorType == PM_HORIZONTALANDVERTICAL ) {
732 _horizontal = true;
733 _vertical = true;
734 }
735
736 _tmpImage = _tmpImage.mirror( _horizontal, _vertical );
737
738 if ( depth != 0 ) {
739 TQImage tmpImg = _tmpImage.convertDepth( depth );
740 if ( !tmpImg.isNull() )
741 _tmpImage = tmpImg;
742 }
743
744 if ( swapRGB )
745 _tmpImage = _tmpImage.swapRGB();
746
747 if ( grayscal ) {
748 if ( depth == 1 || depth == 8 ) {
749 for ( int i = 0; i < _tmpImage.numColors(); ++i ) {
750 TQRgb rgb = _tmpImage.color( i );
751 int gray = tqGray( rgb );
752 rgb = tqRgb( gray, gray, gray );
753 _tmpImage.setColor( i, rgb );
754 }
755 }
756 else {
757 int _width = _tmpImage.width();
758 int _height = _tmpImage.height();
759 int _x = 0;
760 int _y = 0;
761
762 for ( _x = 0; _x < _width; ++_x ) {
763 for ( _y = 0; _y < _height; ++_y ) {
764 if ( _tmpImage.valid( _x, _y ) ) {
765 TQRgb rgb = _tmpImage.pixel( _x, _y );
766 int gray = tqGray( rgb );
767 rgb = tqRgb( gray, gray, gray );
768 _tmpImage.setPixel( _x, _y, rgb );
769 }
770 }
771 }
772 }
773 }
774
775 if ( bright != 0 ) {
776 if ( depth == 1 || depth == 8 ) {
777 for ( int i = 0; i < _tmpImage.numColors(); ++i ) {
778 TQRgb rgb = _tmpImage.color( i );
779 TQColor c( rgb );
780
781 if ( bright > 0 )
782 rgb = c.light( 100 + bright ).rgb();
783 else
784 rgb = c.dark( 100 + abs( bright ) ).rgb();
785
786 _tmpImage.setColor( i, rgb );
787 }
788 }
789 else {
790 int _width = _tmpImage.width();
791 int _height = _tmpImage.height();
792 int _x = 0;
793 int _y = 0;
794
795 for ( _x = 0; _x < _width; ++_x ) {
796 for ( _y = 0; _y < _height; ++_y ) {
797 if ( _tmpImage.valid( _x, _y ) ) {
798 TQRgb rgb = _tmpImage.pixel( _x, _y );
799 TQColor c( rgb );
800
801 if ( bright > 0 )
802 rgb = c.light( 100 + bright ).rgb();
803 else
804 rgb = c.dark( 100 + abs( bright ) ).rgb();
805
806 _tmpImage.setPixel( _x, _y, rgb );
807 }
808 }
809 }
810 }
811 }
812
813 switch (m_effect) {
814 case IE_CHANNEL_INTENSITY: {
815 _tmpImage = KImageEffect::channelIntensity(_tmpImage, m_ie_par1.toDouble()/100.0,
816 static_cast<KImageEffect::RGBComponent>(m_ie_par2.toInt()));
817 break;
818 }
819 case IE_FADE: {
820 _tmpImage = KImageEffect::fade(_tmpImage, m_ie_par1.toDouble(), m_ie_par2.toColor());
821 break;
822 }
823 case IE_FLATTEN: {
824 _tmpImage = KImageEffect::flatten(_tmpImage, m_ie_par1.toColor(), m_ie_par2.toColor());
825 break;
826 }
827 case IE_INTENSITY: {
828 _tmpImage = KImageEffect::intensity(_tmpImage, m_ie_par1.toDouble()/100.0);
829 break;
830 }
831 case IE_DESATURATE: {
832 _tmpImage = KImageEffect::desaturate(_tmpImage, m_ie_par1.toDouble());
833 break;
834 }
835 case IE_CONTRAST: {
836 _tmpImage = KImageEffect::contrast(_tmpImage, m_ie_par1.toInt());
837 break;
838 }
839 case IE_NORMALIZE: {
840 KImageEffect::normalize(_tmpImage);
841 break;
842 }
843 case IE_EQUALIZE: {
844 KImageEffect::equalize(_tmpImage);
845 break;
846 }
847 case IE_THRESHOLD: {
848 KImageEffect::threshold(_tmpImage, m_ie_par1.toInt());
849 break;
850 }
851 case IE_SOLARIZE: {
852 KImageEffect::solarize(_tmpImage, m_ie_par1.toDouble());
853 break;
854 }
855 case IE_EMBOSS: {
856 _tmpImage = KImageEffect::emboss(_tmpImage);
857 break;
858 }
859 case IE_DESPECKLE: {
860 _tmpImage = KImageEffect::despeckle(_tmpImage);
861 break;
862 }
863 case IE_CHARCOAL: {
864 _tmpImage = KImageEffect::charcoal(_tmpImage, m_ie_par1.toDouble());
865 break;
866 }
867 case IE_NOISE: {
868 _tmpImage = KImageEffect::addNoise(_tmpImage, static_cast<KImageEffect::NoiseType>(m_ie_par1.toInt()));
869 break;
870 }
871 case IE_BLUR: {
872 _tmpImage = KImageEffect::blur(_tmpImage, m_ie_par1.toDouble());
873 break;
874 }
875 case IE_EDGE: {
876 _tmpImage = KImageEffect::edge(_tmpImage, m_ie_par1.toDouble());
877 break;
878 }
879 case IE_IMPLODE: {
880 _tmpImage = KImageEffect::implode(_tmpImage, m_ie_par1.toDouble());
881 break;
882 }
883 case IE_OIL_PAINT: {
884 _tmpImage = KImageEffect::oilPaint(_tmpImage, m_ie_par1.toInt());
885 break;
886 }
887 case IE_SHARPEN: {
888 _tmpImage = KImageEffect::sharpen(_tmpImage, m_ie_par1.toDouble());
889 break;
890 }
891 case IE_SPREAD: {
892 _tmpImage = KImageEffect::spread(_tmpImage, m_ie_par1.toInt());
893 break;
894 }
895 case IE_SHADE: {
896 _tmpImage = KImageEffect::shade(_tmpImage, m_ie_par1.toBool(), m_ie_par2.toDouble(), m_ie_par3.toDouble());
897 break;
898 }
899 case IE_SWIRL: {
900 _tmpImage = KImageEffect::swirl(_tmpImage, m_ie_par1.toDouble());
901 break;
902 }
903 case IE_WAVE: {
904 _tmpImage = KImageEffect::wave(_tmpImage, m_ie_par1.toDouble(), m_ie_par2.toDouble());
905 break;
906 }
907 case IE_NONE:
908 default:
909 break;
910 }
911
912 _tmpPixmap.convertFromImage( _tmpImage );
913
914 return _tmpPixmap;
915}
916
917void KPrPixmapObject::flip( bool horizontal )
918{
919 KPr2DObject::flip( horizontal );
920 if ( horizontal )
921 {
922 switch ( mirrorType )
923 {
924 case PM_NORMAL:
925 mirrorType = PM_HORIZONTAL;
926 break;
927 case PM_HORIZONTAL:
928 mirrorType = PM_NORMAL;
929 break;
930 case PM_VERTICAL:
931 mirrorType = PM_HORIZONTALANDVERTICAL;
932 break;
933 case PM_HORIZONTALANDVERTICAL:
934 mirrorType = PM_VERTICAL;
935 break;
936 }
937 }
938 else
939 {
940 switch ( mirrorType )
941 {
942 case PM_NORMAL:
943 mirrorType = PM_VERTICAL;
944 break;
945 case PM_HORIZONTAL:
946 mirrorType = PM_HORIZONTALANDVERTICAL;
947 break;
948 case PM_VERTICAL:
949 mirrorType = PM_NORMAL;
950 break;
951 case PM_HORIZONTALANDVERTICAL:
952 mirrorType = PM_HORIZONTAL;
953 break;
954 }
955 }
956}
957
Temporary information used only during loading.
virtual void paint(TQPainter *, KoTextZoomHandler *, int, bool drawingShadow, bool=false)
This method is to be implemented by all KPShadowObjects, to draw themselves.