kpresenter

KPrPixmapObject.cpp

00001 // -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4; -*-
00002 /* This file is part of the KDE project
00003    Copyright (C) 1998, 1999 Reginald Stadlbauer <reggie@kde.org>
00004    Copyright (C) 2005 Thorsten Zachmann <zachmann@kde.org>
00005 
00006    This library is free software; you can redistribute it and/or
00007    modify it under the terms of the GNU Library General Public
00008    License as published by the Free Software Foundation; either
00009    version 2 of the License, or (at your option) any later version.
00010 
00011    This library is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00014    Library General Public License for more details.
00015 
00016    You should have received a copy of the GNU Library General Public License
00017    along with this library; see the file COPYING.LIB.  If not, write to
00018    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00019  * Boston, MA 02110-1301, USA.
00020 */
00021 
00022 // ### TODO: fix copyright date/authors
00023 
00024 // for getenv ()
00025 #include <stdlib.h>
00026 #include <float.h>
00027 
00028 #include <qbuffer.h>
00029 #include <qpainter.h>
00030 #include <qwmatrix.h>
00031 #include <qfileinfo.h>
00032 #include <qpixmap.h>
00033 #include <qdom.h>
00034 #include <qimage.h>
00035 #include <qbitmap.h>
00036 
00037 #include <kdebug.h>
00038 #include <kimageeffect.h>
00039 #include <KoSize.h>
00040 #include <KoTextZoomHandler.h>
00041 #include <KoStore.h>
00042 #include <KoStoreDevice.h>
00043 #include <KoOasisContext.h>
00044 #include <KoXmlNS.h>
00045 #include <KoDom.h>
00046 
00047 #include "KPrPixmapObject.h"
00048 #include "KPrGradient.h"
00049 #include "KPrPixmapObjectIface.h"
00050 
00051 
00052 KPrPixmapObject::KPrPixmapObject( KoPictureCollection *_imageCollection )
00053     : KPr2DObject()
00054 {
00055     imageCollection = _imageCollection;
00056     pen = KoPen( Qt::black, 1.0, Qt::NoPen );
00057     mirrorType = PM_NORMAL;
00058     depth = 0;
00059     swapRGB = false;
00060     grayscal = false;
00061     bright = 0;
00062     m_effect = IE_NONE;
00063     m_ie_par1 = QVariant();
00064     m_ie_par2 = QVariant();
00065     m_ie_par3 = QVariant();
00066     // Forbid QPixmap to cache the X-Window resources (Yes, it is slower!)
00067     m_cachedPixmap.setOptimization(QPixmap::MemoryOptim);
00068     keepRatio = true;
00069 }
00070 
00071 KPrPixmapObject::KPrPixmapObject( KoPictureCollection *_imageCollection, const KoPictureKey & key )
00072     : KPr2DObject()
00073 {
00074     imageCollection = _imageCollection;
00075 
00076     ext = KoSize(); // invalid size means unset
00077     pen = KoPen( Qt::black, 1.0, Qt::NoPen );
00078     mirrorType = PM_NORMAL;
00079     depth = 0;
00080     swapRGB = false;
00081     grayscal = false;
00082     bright = 0;
00083     m_effect = IE_NONE;
00084     m_ie_par1 = QVariant();
00085     m_ie_par2 = QVariant();
00086     m_ie_par3 = QVariant();
00087     // Forbid QPixmap to cache the X-Window resources (Yes, it is slower!)
00088     m_cachedPixmap.setOptimization(QPixmap::MemoryOptim);
00089 
00090     setPicture( key );
00091 }
00092 
00093 DCOPObject* KPrPixmapObject::dcopObject()
00094 {
00095     if ( !dcop )
00096         dcop = new KPrPixmapObjectIface( this );
00097     return dcop;
00098 }
00099 
00100 QString KPrPixmapObject::convertValueToPercent( int val ) const
00101 {
00102    return QString::number( val )+"%";
00103 }
00104 
00105 void KPrPixmapObject::saveOasisPictureElement( KoGenStyle &styleobjectauto ) const
00106 {
00107 
00108     if ( bright != 0 )
00109     {
00110         styleobjectauto.addProperty( "draw:luminance", convertValueToPercent( bright ) );
00111     }
00112     if ( grayscal )
00113     {
00114         styleobjectauto.addProperty( "draw:color-mode","greyscale" );
00115     }
00116 
00117     switch (m_effect)
00118     {
00119     case IE_NONE:
00120         //nothing
00121         break;
00122     case IE_CHANNEL_INTENSITY:
00123     {
00124         //for the moment kpresenter support just one channel
00125         QString percent = convertValueToPercent( m_ie_par1.toInt() );
00126         KImageEffect::RGBComponent channel = static_cast<KImageEffect::RGBComponent>( m_ie_par2.toInt() );
00127         switch( channel )
00128         {
00129         case KImageEffect::Red:
00130             styleobjectauto.addProperty( "draw:red", percent );
00131             styleobjectauto.addProperty( "draw:blue", "0%" );
00132             styleobjectauto.addProperty( "draw:green", "0%" );
00133             break;
00134         case KImageEffect::Green:
00135             styleobjectauto.addProperty( "draw:green", percent );
00136             styleobjectauto.addProperty( "draw:red", "0%" );
00137             styleobjectauto.addProperty( "draw:blue", "0%" );
00138             break;
00139         case KImageEffect::Blue:
00140             styleobjectauto.addProperty( "draw:blue", percent );
00141             styleobjectauto.addProperty( "draw:red", "0%" );
00142             styleobjectauto.addProperty( "draw:green", "0%" );
00143             break;
00144         case KImageEffect::Gray:
00145             break;
00146         case KImageEffect::All:
00147             break;
00148         }
00149     }
00150     break;
00151     case IE_FADE:
00152         break;
00153     case IE_FLATTEN:
00154         break;
00155     case IE_INTENSITY:
00156         break;
00157     case IE_DESATURATE:
00158         break;
00159     case IE_CONTRAST:
00160     {
00161         //kpresenter use value between -255 and 255
00162         //oo impress between -100% and 100%
00163         int val =  m_ie_par1.toInt();
00164         val = ( int )( ( double )val*100.0/255.0 );
00165         styleobjectauto.addProperty( "draw:contrast", convertValueToPercent( val ) );
00166     }
00167     break;
00168     case IE_NORMALIZE:
00169         break;
00170     case IE_EQUALIZE:
00171         break;
00172     case IE_THRESHOLD:
00173         break;
00174     case IE_SOLARIZE:
00175         break;
00176     case IE_EMBOSS:
00177         break;
00178     case IE_DESPECKLE:
00179         break;
00180     case IE_CHARCOAL:
00181         break;
00182     case IE_NOISE:
00183         break;
00184     case IE_BLUR:
00185         break;
00186     case IE_EDGE:
00187         break;
00188     case IE_IMPLODE:
00189         break;
00190     case IE_OIL_PAINT:
00191         break;
00192     case IE_SHARPEN:
00193         break;
00194     case IE_SPREAD:
00195         break;
00196     case IE_SHADE:
00197         break;
00198     case IE_SWIRL:
00199         break;
00200     case IE_WAVE:
00201         break;
00202     }
00203 }
00204 
00205 bool KPrPixmapObject::saveOasisObjectAttributes( KPOasisSaveContext &sc ) const
00206 {
00207     sc.xmlWriter.startElement( "draw:image" );
00208     sc.xmlWriter.addAttribute( "xlink:type", "simple" );
00209     sc.xmlWriter.addAttribute( "xlink:show", "embed" );
00210     sc.xmlWriter.addAttribute( "xlink:actuate", "onLoad" );
00211     sc.xmlWriter.addAttribute( "xlink:href", imageCollection->getOasisFileName( image ) );
00212     sc.xmlWriter.endElement();
00213 
00214     return true;
00215 }
00216 
00217 const char * KPrPixmapObject::getOasisElementName() const
00218 {
00219     return "draw:frame";
00220 }
00221 
00222 
00223 // Deprecated, same as KPrPixmapObject::loadPicture
00224 void KPrPixmapObject::loadImage( const QString & fileName )
00225 {
00226     loadPicture( fileName );
00227 }
00228 
00229 void KPrPixmapObject::loadPicture( const QString & fileName )
00230 {
00231     image = imageCollection->loadPicture( fileName );
00232 }
00233 
00234 KPrPixmapObject &KPrPixmapObject::operator=( const KPrPixmapObject & )
00235 {
00236     return *this;
00237 }
00238 
00239 // Deprecated, same as KPrPixmapObject::setPicture
00240 void KPrPixmapObject::setPixmap( const KoPictureKey & key )
00241 {
00242     setPicture( key );
00243 }
00244 
00245 void KPrPixmapObject::setPicture( const KoPictureKey & key )
00246 {
00247     image = imageCollection->findPicture( key );
00248 }
00249 
00250 void KPrPixmapObject::reload( void )
00251 {
00252     // ### FIXME: this seems wrong, KoPictureCollection will never reload it (or perhaps it is the function name that is wrong)
00253     setPicture( image.getKey() );
00254 }
00255 
00256 QDomDocumentFragment KPrPixmapObject::save( QDomDocument& doc, double offset )
00257 {
00258     QDomDocumentFragment fragment=KPr2DObject::save(doc, offset);
00259     QDomElement elem=doc.createElement("KEY");
00260     image.getKey().saveAttributes(elem);
00261     fragment.appendChild(elem);
00262 
00263     QDomElement elemSettings = doc.createElement( "PICTURESETTINGS" );
00264 
00265     elemSettings.setAttribute( "mirrorType", static_cast<int>( mirrorType ) );
00266     elemSettings.setAttribute( "depth", depth );
00267     elemSettings.setAttribute( "swapRGB", static_cast<int>( swapRGB ) );
00268     elemSettings.setAttribute( "grayscal", static_cast<int>( grayscal ) );
00269     elemSettings.setAttribute( "bright", bright );
00270     fragment.appendChild( elemSettings );
00271 
00272     if (m_effect!=IE_NONE) {
00273         QDomElement imageEffects = doc.createElement("EFFECTS");
00274         imageEffects.setAttribute("type", static_cast<int>(m_effect));
00275         if (m_ie_par1.isValid())
00276             imageEffects.setAttribute("param1", m_ie_par1.toString());
00277         if (m_ie_par2.isValid())
00278             imageEffects.setAttribute("param2", m_ie_par2.toString());
00279         if (m_ie_par3.isValid())
00280             imageEffects.setAttribute("param3", m_ie_par3.toString());
00281         fragment.appendChild( imageEffects );
00282     }
00283 
00284     return fragment;
00285 }
00286 
00287 void KPrPixmapObject::loadOasisPictureEffect(KoOasisContext & context )
00288 {
00289     KoStyleStack &styleStack = context.styleStack();
00290     styleStack.setTypeProperties( "graphic" );
00291     if ( styleStack.hasAttributeNS( KoXmlNS::draw, "color-mode" ) &&  ( styleStack.attributeNS( KoXmlNS::draw, "color-mode" )=="greyscale" ) )
00292     {
00293         grayscal = true;
00294     }
00295 
00296     if ( styleStack.hasAttributeNS( KoXmlNS::draw, "contrast" ) )
00297     {
00298         QString str( styleStack.attributeNS( KoXmlNS::draw, "contrast" ) );
00299         str = str.remove( '%' );
00300         int val = str.toInt();
00301         m_effect = IE_CONTRAST;
00302         val = ( int )( 255.0 *val/100.0 );
00303         m_ie_par1 = QVariant(val);
00304     }
00305     if ( styleStack.hasAttributeNS( KoXmlNS::draw, "red" ) && styleStack.attributeNS( KoXmlNS::draw, "red" ) != "0%" )
00306     {
00307         QString str( styleStack.attributeNS( KoXmlNS::draw, "red" ) );
00308         str = str.remove( '%' );
00309         int val = str.toInt();
00310         m_effect = IE_CHANNEL_INTENSITY;
00311         m_ie_par1 = QVariant(val);
00312         m_ie_par2 = QVariant( ( int )KImageEffect::Red );
00313     }
00314     if ( styleStack.hasAttributeNS( KoXmlNS::draw, "green" ) && styleStack.attributeNS( KoXmlNS::draw, "green" ) != "0%" )
00315     {
00316         QString str( styleStack.attributeNS( KoXmlNS::draw, "green" ) );
00317         str = str.remove( '%' );
00318         int val = str.toInt();
00319         m_effect = IE_CHANNEL_INTENSITY;
00320         m_ie_par1 = QVariant(val);
00321         m_ie_par2 = QVariant( ( int )KImageEffect::Green );
00322     }
00323     if ( styleStack.hasAttributeNS( KoXmlNS::draw, "blue" ) && styleStack.attributeNS( KoXmlNS::draw, "blue" ) != "0%" )
00324     {
00325         QString str( styleStack.attributeNS( KoXmlNS::draw, "blue" ) );
00326         str = str.remove( '%' );
00327         int val = str.toInt();
00328         m_effect = IE_CHANNEL_INTENSITY;
00329         m_ie_par1 = QVariant(val);
00330         m_ie_par2 = QVariant( ( int )KImageEffect::Blue );
00331     }
00332     if ( styleStack.hasAttributeNS( KoXmlNS::draw, "luminance" ) )
00333     {
00334        QString str( styleStack.attributeNS( KoXmlNS::draw, "luminance" ) );
00335        str = str.remove( '%' );
00336        bright = str.toInt();
00337     }
00338 
00339 }
00340 
00341 void KPrPixmapObject::fillStyle( KoGenStyle& styleObjectAuto, KoGenStyles& mainStyles ) const
00342 {
00343     KPr2DObject::fillStyle( styleObjectAuto, mainStyles );
00344     saveOasisPictureElement( styleObjectAuto );
00345 }
00346 
00347 void KPrPixmapObject::loadOasis(const QDomElement &element, KoOasisContext & context, KPrLoadingInfo *info)
00348 {
00349     //load it into kpresenter_doc
00350     KPr2DObject::loadOasis( element, context, info );
00351     loadOasisPictureEffect( context );
00352     QDomNode imageBox = KoDom::namedItemNS( element, KoXmlNS::draw, "image" );
00353     const QString href( imageBox.toElement().attributeNS( KoXmlNS::xlink, "href", QString::null) );
00354     kdDebug()<<" href: "<<href<<endl;
00355     if ( !href.isEmpty() /*&& href[0] == '#'*/ )
00356     {
00357         QString strExtension;
00358         const int result=href.findRev(".");
00359         if (result>=0)
00360         {
00361             strExtension=href.mid(result+1); // As we are using KoPicture, the extension should be without the dot.
00362         }
00363         QString filename(href/*.mid(1)*/);
00364         const KoPictureKey key(filename, QDateTime::currentDateTime(Qt::UTC));
00365         image.setKey(key);
00366 
00367         KoStore* store = context.store();
00368         if ( store->open( filename ) )
00369         {
00370             KoStoreDevice dev(store);
00371             if ( !image.load( &dev, strExtension ) )
00372                 kdWarning() << "Cannot load picture: " << filename << " " << href << endl;
00373             store->close();
00374         }
00375         imageCollection->insertPicture( key, image );
00376     }
00377     // ### TODO: load remote file
00378 }
00379 
00380 
00381 double KPrPixmapObject::load(const QDomElement &element)
00382 {
00383     double offset=KPr2DObject::load(element);
00384     QDomElement e=element.namedItem("KEY").toElement();
00385     if(!e.isNull()) {
00386         KoPictureKey key;
00387         key.loadAttributes( e );
00388         image.clear();
00389         image.setKey(key);
00390     }
00391     else {
00392         // try to find a PIXMAP tag if the KEY is not available...
00393         e=element.namedItem("PIXMAP").toElement();
00394         if (e.isNull()) {
00395             // try to find a FILENAME tag (old cliparts...)
00396             e=element.namedItem("FILENAME").toElement();
00397             if(!e.isNull()) {
00398                 // Loads from the disk directly (unless it's in the collection already?)
00399                 image = imageCollection->loadPicture( e.attribute("filename") );
00400             }
00401         } else {
00402             bool openPic = true;
00403             QString _data;
00404             QString _fileName;
00405             if(e.hasAttribute("data"))
00406                 _data=e.attribute("data");
00407             if ( _data.isEmpty() )
00408                 openPic = true;
00409             else
00410                 openPic = false;
00411             if(e.hasAttribute("filename"))
00412                 _fileName=e.attribute("filename");
00413             if ( !_fileName.isEmpty() )
00414             {
00415                 if ( int _envVarB = _fileName.find( '$' ) >= 0 )
00416                 {
00417                     int _envVarE = _fileName.find( '/', _envVarB );
00418                     // ### FIXME: it should be QString::local8Bit instead of QFile::encodeName, shouldn't it?
00419                     QString path = getenv( QFile::encodeName(_fileName.mid( _envVarB, _envVarE-_envVarB )) );
00420                     _fileName.replace( _envVarB-1, _envVarE-_envVarB+1, path );
00421                 }
00422             }
00423 
00424             if ( openPic )
00425                 // !! this loads it from the disk (unless it's in the image collection already)
00426                 image = imageCollection->loadPicture( _fileName );
00427             else
00428             {
00429                 KoPictureKey key( _fileName );
00430                 image.clear();
00431                 image.setKey(key);
00432                 QByteArray rawData=_data.utf8(); // XPM is normally ASCII, therefore UTF-8
00433                 rawData[rawData.size()-1]=char(10); // Replace the NULL character by a LINE FEED
00434                 QBuffer buffer(rawData); // ### TODO: open?
00435                 image.loadXpm(&buffer);
00436             }
00437         }
00438     }
00439 
00440     e = element.namedItem( "PICTURESETTINGS" ).toElement();
00441     if ( !e.isNull() ) {
00442         PictureMirrorType _mirrorType = PM_NORMAL;
00443         int _depth = 0;
00444         bool _swapRGB = false;
00445         bool _grayscal = false;
00446         int _bright = 0;
00447 
00448         if ( e.hasAttribute( "mirrorType" ) )
00449             _mirrorType = static_cast<PictureMirrorType>( e.attribute( "mirrorType" ).toInt() );
00450         if ( e.hasAttribute( "depth" ) )
00451             _depth = e.attribute( "depth" ).toInt();
00452         if ( e.hasAttribute( "swapRGB" ) )
00453             _swapRGB = static_cast<bool>( e.attribute( "swapRGB" ).toInt() );
00454         if ( e.hasAttribute( "grayscal" ) )
00455             _grayscal = static_cast<bool>( e.attribute( "grayscal" ).toInt() );
00456         if ( e.hasAttribute( "bright" ) )
00457             _bright = e.attribute( "bright" ).toInt();
00458 
00459         mirrorType = _mirrorType;
00460         depth = _depth;
00461         swapRGB = _swapRGB;
00462         grayscal = _grayscal;
00463         bright = _bright;
00464     }
00465     else {
00466         mirrorType = PM_NORMAL;
00467         depth = 0;
00468         swapRGB = false;
00469         grayscal = false;
00470         bright = 0;
00471     }
00472 
00473     e = element.namedItem( "EFFECTS" ).toElement();
00474     if (!e.isNull()) {
00475         if (e.hasAttribute("type"))
00476             m_effect = static_cast<ImageEffect>(e.attribute("type").toInt());
00477         if (e.hasAttribute("param1"))
00478             m_ie_par1 = QVariant(e.attribute("param1"));
00479         else
00480             m_ie_par1 = QVariant();
00481         if (e.hasAttribute("param2"))
00482             m_ie_par2 = QVariant(e.attribute("param2"));
00483         else
00484             m_ie_par2 = QVariant();
00485         if (e.hasAttribute("param3"))
00486             m_ie_par3 = QVariant(e.attribute("param3"));
00487         else
00488             m_ie_par3 = QVariant();
00489     }
00490     else
00491         m_effect = IE_NONE;
00492 
00493     return offset;
00494 }
00495 
00496 void KPrPixmapObject::drawShadow( QPainter* _painter, KoZoomHandler* _zoomHandler)
00497 {
00498     const double ox = orig.x();
00499     const double oy = orig.y();
00500     const double ow = ext.width();
00501     const double oh = ext.height();
00502 
00503     _painter->save();
00504 
00505     QPen pen2 = pen.zoomedPen( _zoomHandler );
00506     _painter->setPen( pen2 );
00507     _painter->setBrush( getBrush() );
00508 
00509     double sx = 0;
00510     double sy = 0;
00511 
00512     getShadowCoords( sx, sy );
00513 
00514     _painter->translate( _zoomHandler->zoomItX( ox ), _zoomHandler->zoomItY( oy ) );
00515     _painter->setPen( QPen( shadowColor ) );
00516     _painter->setBrush( shadowColor );
00517     if ( kAbs(angle) <= DBL_EPSILON )
00518         _painter->drawRect( _zoomHandler->zoomItX( sx ), _zoomHandler->zoomItY( sy ),
00519                             _zoomHandler->zoomItX( ext.width() ), _zoomHandler->zoomItY( ext.height() ) );
00520     else
00521     {
00522         QSize bs = QSize( _zoomHandler->zoomItX( ow ), _zoomHandler->zoomItY( oh ) );
00523         QRect br = QRect( 0, 0, bs.width(), bs.height() );
00524         int pw = br.width();
00525         int ph = br.height();
00526         QRect rr = br;
00527         int pixYPos = -rr.y();
00528         int pixXPos = -rr.x();
00529         br.moveTopLeft( QPoint( -br.width() / 2, -br.height() / 2 ) );
00530         rr.moveTopLeft( QPoint( -rr.width() / 2, -rr.height() / 2 ) );
00531 
00532         QWMatrix m;
00533         m.translate( pw / 2, ph / 2 );
00534         m.rotate( angle );
00535         m.translate( rr.left() + pixXPos + _zoomHandler->zoomItX( sx ),
00536                      rr.top() + pixYPos + _zoomHandler->zoomItY( sy ) );
00537 
00538         _painter->setWorldMatrix( m, true );
00539 
00540         _painter->drawRect( 0, 0, bs.width(), bs.height() );
00541     }
00542 
00543     _painter->restore();
00544 }
00545 
00546 QPixmap KPrPixmapObject::generatePixmap(KoZoomHandler*_zoomHandler)
00547 {
00548     const double penw = _zoomHandler->zoomItX( ( ( pen.style() == Qt::NoPen ) ? 1 : pen.width() ) / 2.0 );
00549 
00550     QSize size( _zoomHandler->zoomSize( ext ) );
00551     //kdDebug(33001) << "KPrPixmapObject::generatePixmap size= " << size << endl;
00552     QPixmap pixmap(size);
00553     QPainter paint;
00554 
00555     paint.begin( &pixmap );
00556     pixmap.fill( Qt::white );
00557 
00558     // Draw background
00559     paint.setPen( Qt::NoPen );
00560     paint.setBrush( getBrush() );
00561 
00562     QRect rect( (int)( penw ), (int)( penw ),
00563                 (int)( _zoomHandler->zoomItX( ext.width() ) - 2.0 * penw ),
00564                 (int)( _zoomHandler->zoomItY( ext.height() ) - 2.0 * penw ) );
00565 
00566     if ( getFillType() == FT_BRUSH || !gradient )
00567         paint.drawRect( rect );
00568     else {
00569         // ### TODO: this was also drawn for drawContour==true, but why?
00570         gradient->setSize( size );
00571         paint.drawPixmap( (int)( penw ), (int)( penw ),
00572                           gradient->pixmap(), 0, 0,
00573                           (int)( _zoomHandler->zoomItX( ext.width() ) - 2 * penw ),
00574                           (int)( _zoomHandler->zoomItY( ext.height() ) - 2 * penw ) );
00575     }
00576 
00577 
00578     image.draw(paint, 0, 0, size.width(), size.height(), 0, 0, -1, -1, false); // Always slow mode!
00579     image.clearCache(); // Release the memoy of the picture cache
00580 
00581     image.setAlphaBuffer(true);
00582     QBitmap tmpMask;
00583     tmpMask = image.createAlphaMask().scale(size);
00584     pixmap.setMask(tmpMask);
00585 
00586     paint.end();
00587     return pixmap;
00588 }
00589 
00590 void KPrPixmapObject::draw( QPainter *_painter, KoTextZoomHandler*_zoomHandler,
00591                            int pageNum, SelectionMode selectionMode, bool drawContour )
00592 {
00593     if ( image.isNull() ) return;
00594 
00595     if ( shadowDistance > 0 && !drawContour )
00596         drawShadow(_painter, _zoomHandler);
00597 
00598     const double ox = orig.x();
00599     const double oy = orig.y();
00600     const double ow = ext.width();
00601     const double oh = ext.height();
00602     const double penw = _zoomHandler->zoomItX( ( ( pen.style() == Qt::NoPen ) ? 1.0 : pen.width() ) / 2.0 );
00603 
00604     _painter->save();
00605 
00606     _painter->translate( _zoomHandler->zoomItX( ox ), _zoomHandler->zoomItY( oy ) );
00607 
00608     if ( kAbs(angle)> DBL_EPSILON ) {
00609         QSize bs = QSize( _zoomHandler->zoomItX( ow ), _zoomHandler->zoomItY( oh ) );
00610         QRect br = QRect( 0, 0, bs.width(), bs.height() );
00611         int pw = br.width();
00612         int ph = br.height();
00613         QRect rr = br;
00614         int pixYPos = -rr.y();
00615         int pixXPos = -rr.x();
00616         br.moveTopLeft( QPoint( -br.width() / 2, -br.height() / 2 ) );
00617         rr.moveTopLeft( QPoint( -rr.width() / 2, -rr.height() / 2 ) );
00618 
00619         QWMatrix m;
00620         m.translate( pw / 2, ph / 2 );
00621         m.rotate( angle );
00622         m.translate( rr.left() + pixXPos, rr.top() + pixYPos );
00623         _painter->setWorldMatrix( m, true );
00624     }
00625 
00626     if ( !drawContour )
00627     {
00628         QRect rect( 0, 0, (int)( _zoomHandler->zoomItX( ow ) ),
00629                     (int)( _zoomHandler->zoomItY(  oh ) ) );
00630         // ### HACK QT seems not to be able to correctly compare QVariant
00631         bool variants1;
00632         if (m_ie_par1.isNull())
00633             variants1=m_cachedPar1.isNull();
00634         else
00635             variants1=(m_ie_par1 == m_cachedPar1);
00636         bool variants2;
00637         if (m_ie_par2.isNull())
00638             variants2=m_cachedPar2.isNull();
00639         else
00640             variants2=(m_ie_par2 == m_cachedPar2);
00641         bool variants3;
00642         if (m_ie_par3.isNull())
00643             variants3=m_cachedPar3.isNull();
00644         else
00645             variants3=(m_ie_par3 == m_cachedPar3);
00646 
00647         if (m_cachedRect == rect
00648             // All what KPrPixmapObject::changePictureSettings needs
00649             && m_cachedMirrorType == mirrorType && m_cachedSwapRGB == swapRGB && m_cachedGrayscal == grayscal
00650             && m_cachedBright == bright && m_cachedEffect == m_effect
00651             // Who needs it?
00652             && m_cachedDepth == depth
00653 #if 0
00654             && m_ie_par1 == m_cachedPar1 && m_ie_par2 == m_cachedPar2 && m_ie_par3 == m_cachedPar3
00655 #else
00656             && variants1 && variants2 && variants3
00657 #endif
00658             )
00659         {
00660             //kdDebug(33001) << "Drawing cached pixmap " << (void*) this << " " << k_funcinfo << endl;
00661         }
00662         else
00663         {
00664             if (mirrorType != PM_NORMAL || depth != 0 || swapRGB || grayscal || bright != 0 || m_effect!=IE_NONE)
00665                 m_cachedPixmap = changePictureSettings( generatePixmap( _zoomHandler ) );
00666             else
00667                 m_cachedPixmap = generatePixmap( _zoomHandler );
00668             m_cachedRect = rect;
00669             m_cachedMirrorType = mirrorType;
00670             m_cachedSwapRGB = swapRGB;
00671             m_cachedGrayscal = grayscal;
00672             m_cachedBright = bright;
00673             m_cachedEffect = m_effect;
00674             m_cachedDepth = depth;
00675             m_cachedPar1 = m_ie_par1;
00676             m_cachedPar2 = m_ie_par2;
00677             m_cachedPar3 = m_ie_par3;
00678             //kdDebug(33001) <<  "Drawing non-cached pixmap " << (void*) this << " " << k_funcinfo << endl;
00679         }
00680         _painter->drawPixmap( rect, m_cachedPixmap);
00681     }
00682 
00683     // Draw border
00684     // ### TODO port to KoBorder::drawBorders() (after writing a simplified version of it, that takes the same border on each size)
00685     QPen pen2;
00686     if ( drawContour ) {
00687         pen2 = QPen( Qt::black, 1, Qt::DotLine );
00688         _painter->setRasterOp( Qt::NotXorROP );
00689     }
00690     else {
00691         pen2 = pen;
00692         pen2.setWidth( _zoomHandler->zoomItX( ( pen.style() == Qt::NoPen ) ? 1.0 : (double)pen.width() ) );
00693     }
00694     _painter->setPen( pen2 );
00695     _painter->setBrush( Qt::NoBrush );
00696     _painter->drawRect( (int)( penw ), (int)( penw ),
00697                         (int)( _zoomHandler->zoomItX( ow ) - 2.0 * penw ),
00698                         (int)( _zoomHandler->zoomItY( oh ) - 2.0 * penw ) );
00699 
00700     _painter->restore();
00701 
00702     KPrObject::draw( _painter, _zoomHandler, pageNum, selectionMode, drawContour );
00703 }
00704 
00705 QPixmap KPrPixmapObject::getOriginalPixmap()
00706 {
00707     QSize _pixSize = image.getOriginalSize();
00708     kdDebug(33001) << "KPrPixmapObject::getOriginalPixmap size= " << _pixSize << endl;
00709     QPixmap _pixmap = image.generatePixmap( _pixSize, true );
00710     image.clearCache(); // Release the memoy of the picture cache
00711 
00712     return _pixmap;
00713 }
00714 
00715 QPixmap KPrPixmapObject::changePictureSettings( QPixmap _tmpPixmap )
00716 {
00717     QImage _tmpImage = _tmpPixmap.convertToImage();
00718 
00719     if (_tmpImage.isNull())
00720         return _tmpPixmap;
00721 
00722     bool _horizontal = false;
00723     bool _vertical = false;
00724     if ( mirrorType == PM_HORIZONTAL )
00725         _horizontal = true;
00726     else if ( mirrorType == PM_VERTICAL )
00727         _vertical = true;
00728     else if ( mirrorType == PM_HORIZONTALANDVERTICAL ) {
00729         _horizontal = true;
00730         _vertical = true;
00731     }
00732 
00733     _tmpImage = _tmpImage.mirror( _horizontal, _vertical );
00734 
00735     if ( depth != 0 ) {
00736         QImage tmpImg = _tmpImage.convertDepth( depth );
00737         if ( !tmpImg.isNull() )
00738             _tmpImage = tmpImg;
00739     }
00740 
00741     if ( swapRGB )
00742         _tmpImage = _tmpImage.swapRGB();
00743 
00744     if ( grayscal ) {
00745         if ( depth == 1 || depth == 8 ) {
00746             for ( int i = 0; i < _tmpImage.numColors(); ++i ) {
00747                 QRgb rgb = _tmpImage.color( i );
00748                 int gray = qGray( rgb );
00749                 rgb = qRgb( gray, gray, gray );
00750                 _tmpImage.setColor( i, rgb );
00751             }
00752         }
00753         else {
00754             int _width = _tmpImage.width();
00755             int _height = _tmpImage.height();
00756             int _x = 0;
00757             int _y = 0;
00758 
00759             for ( _x = 0; _x < _width; ++_x ) {
00760                 for ( _y = 0; _y < _height; ++_y ) {
00761                     if ( _tmpImage.valid( _x, _y ) ) {
00762                         QRgb rgb = _tmpImage.pixel( _x, _y );
00763                         int gray = qGray( rgb );
00764                         rgb = qRgb( gray, gray, gray );
00765                         _tmpImage.setPixel( _x, _y, rgb );
00766                     }
00767                 }
00768             }
00769         }
00770     }
00771 
00772     if ( bright != 0 ) {
00773         if ( depth == 1 || depth == 8 ) {
00774             for ( int i = 0; i < _tmpImage.numColors(); ++i ) {
00775                 QRgb rgb = _tmpImage.color( i );
00776                 QColor c( rgb );
00777 
00778                 if ( bright > 0 )
00779                     rgb = c.light( 100 + bright ).rgb();
00780                 else
00781                     rgb = c.dark( 100 + abs( bright ) ).rgb();
00782 
00783                 _tmpImage.setColor( i, rgb );
00784             }
00785         }
00786         else {
00787             int _width = _tmpImage.width();
00788             int _height = _tmpImage.height();
00789             int _x = 0;
00790             int _y = 0;
00791 
00792             for ( _x = 0; _x < _width; ++_x ) {
00793                 for ( _y = 0; _y < _height; ++_y ) {
00794                     if ( _tmpImage.valid( _x, _y ) ) {
00795                         QRgb rgb = _tmpImage.pixel( _x, _y );
00796                         QColor c( rgb );
00797 
00798                         if ( bright > 0 )
00799                             rgb = c.light( 100 + bright ).rgb();
00800                         else
00801                             rgb = c.dark( 100 + abs( bright ) ).rgb();
00802 
00803                         _tmpImage.setPixel( _x, _y, rgb );
00804                     }
00805                 }
00806             }
00807         }
00808     }
00809 
00810     switch (m_effect) {
00811     case IE_CHANNEL_INTENSITY: {
00812         _tmpImage = KImageEffect::channelIntensity(_tmpImage, m_ie_par1.toDouble()/100.0,
00813                                                    static_cast<KImageEffect::RGBComponent>(m_ie_par2.toInt()));
00814         break;
00815     }
00816     case IE_FADE: {
00817         _tmpImage = KImageEffect::fade(_tmpImage, m_ie_par1.toDouble(), m_ie_par2.toColor());
00818         break;
00819     }
00820     case IE_FLATTEN: {
00821         _tmpImage = KImageEffect::flatten(_tmpImage, m_ie_par1.toColor(), m_ie_par2.toColor());
00822         break;
00823     }
00824     case IE_INTENSITY: {
00825         _tmpImage = KImageEffect::intensity(_tmpImage, m_ie_par1.toDouble()/100.0);
00826         break;
00827     }
00828     case IE_DESATURATE: {
00829         _tmpImage = KImageEffect::desaturate(_tmpImage, m_ie_par1.toDouble());
00830         break;
00831     }
00832     case IE_CONTRAST: {
00833         _tmpImage = KImageEffect::contrast(_tmpImage, m_ie_par1.toInt());
00834         break;
00835     }
00836     case IE_NORMALIZE: {
00837         KImageEffect::normalize(_tmpImage);
00838         break;
00839     }
00840     case IE_EQUALIZE: {
00841         KImageEffect::equalize(_tmpImage);
00842         break;
00843     }
00844     case IE_THRESHOLD: {
00845         KImageEffect::threshold(_tmpImage, m_ie_par1.toInt());
00846         break;
00847     }
00848     case IE_SOLARIZE: {
00849         KImageEffect::solarize(_tmpImage, m_ie_par1.toDouble());
00850         break;
00851     }
00852     case IE_EMBOSS: {
00853         _tmpImage = KImageEffect::emboss(_tmpImage);
00854         break;
00855     }
00856     case IE_DESPECKLE: {
00857         _tmpImage = KImageEffect::despeckle(_tmpImage);
00858         break;
00859     }
00860     case IE_CHARCOAL: {
00861         _tmpImage = KImageEffect::charcoal(_tmpImage, m_ie_par1.toDouble());
00862         break;
00863     }
00864     case IE_NOISE: {
00865         _tmpImage = KImageEffect::addNoise(_tmpImage, static_cast<KImageEffect::NoiseType>(m_ie_par1.toInt()));
00866         break;
00867     }
00868     case IE_BLUR: {
00869         _tmpImage = KImageEffect::blur(_tmpImage, m_ie_par1.toDouble());
00870         break;
00871     }
00872     case IE_EDGE: {
00873         _tmpImage = KImageEffect::edge(_tmpImage, m_ie_par1.toDouble());
00874         break;
00875     }
00876     case IE_IMPLODE: {
00877         _tmpImage = KImageEffect::implode(_tmpImage, m_ie_par1.toDouble());
00878         break;
00879     }
00880     case IE_OIL_PAINT: {
00881         _tmpImage = KImageEffect::oilPaint(_tmpImage, m_ie_par1.toInt());
00882         break;
00883     }
00884     case IE_SHARPEN: {
00885         _tmpImage = KImageEffect::sharpen(_tmpImage, m_ie_par1.toDouble());
00886         break;
00887     }
00888     case IE_SPREAD: {
00889         _tmpImage = KImageEffect::spread(_tmpImage, m_ie_par1.toInt());
00890         break;
00891     }
00892     case IE_SHADE: {
00893         _tmpImage = KImageEffect::shade(_tmpImage, m_ie_par1.toBool(), m_ie_par2.toDouble(), m_ie_par3.toDouble());
00894         break;
00895     }
00896     case IE_SWIRL: {
00897         _tmpImage = KImageEffect::swirl(_tmpImage, m_ie_par1.toDouble());
00898         break;
00899     }
00900     case IE_WAVE: {
00901         _tmpImage = KImageEffect::wave(_tmpImage, m_ie_par1.toDouble(), m_ie_par2.toDouble());
00902         break;
00903     }
00904     case IE_NONE:
00905     default:
00906         break;
00907     }
00908 
00909     _tmpPixmap.convertFromImage( _tmpImage );
00910 
00911     return _tmpPixmap;
00912 }
00913 
00914 void KPrPixmapObject::flip( bool horizontal )
00915 {
00916     KPr2DObject::flip( horizontal );
00917     if ( horizontal )
00918     {
00919         switch ( mirrorType )
00920         {
00921             case PM_NORMAL:
00922                 mirrorType = PM_HORIZONTAL;
00923                 break;
00924             case PM_HORIZONTAL:
00925                 mirrorType = PM_NORMAL;
00926                 break;
00927             case PM_VERTICAL:
00928                 mirrorType = PM_HORIZONTALANDVERTICAL;
00929                 break;
00930             case PM_HORIZONTALANDVERTICAL:
00931                 mirrorType = PM_VERTICAL;
00932                 break;
00933         }
00934     }
00935     else
00936     {
00937         switch ( mirrorType )
00938         {
00939             case PM_NORMAL:
00940                 mirrorType = PM_VERTICAL;
00941                 break;
00942             case PM_HORIZONTAL:
00943                 mirrorType = PM_HORIZONTALANDVERTICAL;
00944                 break;
00945             case PM_VERTICAL:
00946                 mirrorType = PM_NORMAL;
00947                 break;
00948             case PM_HORIZONTALANDVERTICAL:
00949                 mirrorType = PM_HORIZONTAL;
00950                 break;
00951         }
00952     }
00953 }
00954 
KDE Home | KDE Accessibility Home | Description of Access Keys