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     if (image.isNull()) {
00255         // this happens for example when doing copy&paste from a different KPresenter instance
00256         image = imageCollection->loadPicture( image.getKey().filename() );
00257     }
00258 }
00259 
00260 QDomDocumentFragment KPrPixmapObject::save( QDomDocument& doc, double offset )
00261 {
00262     QDomDocumentFragment fragment=KPr2DObject::save(doc, offset);
00263     QDomElement elem=doc.createElement("KEY");
00264     image.getKey().saveAttributes(elem);
00265     fragment.appendChild(elem);
00266 
00267     QDomElement elemSettings = doc.createElement( "PICTURESETTINGS" );
00268 
00269     elemSettings.setAttribute( "mirrorType", static_cast<int>( mirrorType ) );
00270     elemSettings.setAttribute( "depth", depth );
00271     elemSettings.setAttribute( "swapRGB", static_cast<int>( swapRGB ) );
00272     elemSettings.setAttribute( "grayscal", static_cast<int>( grayscal ) );
00273     elemSettings.setAttribute( "bright", bright );
00274     fragment.appendChild( elemSettings );
00275 
00276     if (m_effect!=IE_NONE) {
00277         QDomElement imageEffects = doc.createElement("EFFECTS");
00278         imageEffects.setAttribute("type", static_cast<int>(m_effect));
00279         if (m_ie_par1.isValid())
00280             imageEffects.setAttribute("param1", m_ie_par1.toString());
00281         if (m_ie_par2.isValid())
00282             imageEffects.setAttribute("param2", m_ie_par2.toString());
00283         if (m_ie_par3.isValid())
00284             imageEffects.setAttribute("param3", m_ie_par3.toString());
00285         fragment.appendChild( imageEffects );
00286     }
00287 
00288     return fragment;
00289 }
00290 
00291 void KPrPixmapObject::loadOasisPictureEffect(KoOasisContext & context )
00292 {
00293     KoStyleStack &styleStack = context.styleStack();
00294     styleStack.setTypeProperties( "graphic" );
00295     if ( styleStack.hasAttributeNS( KoXmlNS::draw, "color-mode" ) &&  ( styleStack.attributeNS( KoXmlNS::draw, "color-mode" )=="greyscale" ) )
00296     {
00297         grayscal = true;
00298     }
00299 
00300     if ( styleStack.hasAttributeNS( KoXmlNS::draw, "contrast" ) )
00301     {
00302         QString str( styleStack.attributeNS( KoXmlNS::draw, "contrast" ) );
00303         str = str.remove( '%' );
00304         int val = str.toInt();
00305         m_effect = IE_CONTRAST;
00306         val = ( int )( 255.0 *val/100.0 );
00307         m_ie_par1 = QVariant(val);
00308     }
00309     if ( styleStack.hasAttributeNS( KoXmlNS::draw, "red" ) && styleStack.attributeNS( KoXmlNS::draw, "red" ) != "0%" )
00310     {
00311         QString str( styleStack.attributeNS( KoXmlNS::draw, "red" ) );
00312         str = str.remove( '%' );
00313         int val = str.toInt();
00314         m_effect = IE_CHANNEL_INTENSITY;
00315         m_ie_par1 = QVariant(val);
00316         m_ie_par2 = QVariant( ( int )KImageEffect::Red );
00317     }
00318     if ( styleStack.hasAttributeNS( KoXmlNS::draw, "green" ) && styleStack.attributeNS( KoXmlNS::draw, "green" ) != "0%" )
00319     {
00320         QString str( styleStack.attributeNS( KoXmlNS::draw, "green" ) );
00321         str = str.remove( '%' );
00322         int val = str.toInt();
00323         m_effect = IE_CHANNEL_INTENSITY;
00324         m_ie_par1 = QVariant(val);
00325         m_ie_par2 = QVariant( ( int )KImageEffect::Green );
00326     }
00327     if ( styleStack.hasAttributeNS( KoXmlNS::draw, "blue" ) && styleStack.attributeNS( KoXmlNS::draw, "blue" ) != "0%" )
00328     {
00329         QString str( styleStack.attributeNS( KoXmlNS::draw, "blue" ) );
00330         str = str.remove( '%' );
00331         int val = str.toInt();
00332         m_effect = IE_CHANNEL_INTENSITY;
00333         m_ie_par1 = QVariant(val);
00334         m_ie_par2 = QVariant( ( int )KImageEffect::Blue );
00335     }
00336     if ( styleStack.hasAttributeNS( KoXmlNS::draw, "luminance" ) )
00337     {
00338        QString str( styleStack.attributeNS( KoXmlNS::draw, "luminance" ) );
00339        str = str.remove( '%' );
00340        bright = str.toInt();
00341     }
00342 
00343 }
00344 
00345 void KPrPixmapObject::fillStyle( KoGenStyle& styleObjectAuto, KoGenStyles& mainStyles ) const
00346 {
00347     KPr2DObject::fillStyle( styleObjectAuto, mainStyles );
00348     saveOasisPictureElement( styleObjectAuto );
00349 }
00350 
00351 void KPrPixmapObject::loadOasis(const QDomElement &element, KoOasisContext & context, KPrLoadingInfo *info)
00352 {
00353     //load it into kpresenter_doc
00354     KPr2DObject::loadOasis( element, context, info );
00355     loadOasisPictureEffect( context );
00356     QDomNode imageBox = KoDom::namedItemNS( element, KoXmlNS::draw, "image" );
00357     const QString href( imageBox.toElement().attributeNS( KoXmlNS::xlink, "href", QString::null) );
00358     kdDebug()<<" href: "<<href<<endl;
00359     if ( !href.isEmpty() /*&& href[0] == '#'*/ )
00360     {
00361         QString strExtension;
00362         const int result=href.findRev(".");
00363         if (result>=0)
00364         {
00365             strExtension=href.mid(result+1); // As we are using KoPicture, the extension should be without the dot.
00366         }
00367         QString filename(href/*.mid(1)*/);
00368         const KoPictureKey key(filename, QDateTime::currentDateTime(Qt::UTC));
00369         image.setKey(key);
00370 
00371         KoStore* store = context.store();
00372         if ( store->open( filename ) )
00373         {
00374             KoStoreDevice dev(store);
00375             if ( !image.load( &dev, strExtension ) )
00376                 kdWarning() << "Cannot load picture: " << filename << " " << href << endl;
00377             store->close();
00378         }
00379         imageCollection->insertPicture( key, image );
00380     }
00381     // ### TODO: load remote file
00382 }
00383 
00384 
00385 double KPrPixmapObject::load(const QDomElement &element)
00386 {
00387     double offset=KPr2DObject::load(element);
00388     QDomElement e=element.namedItem("KEY").toElement();
00389     if(!e.isNull()) {
00390         KoPictureKey key;
00391         key.loadAttributes( e );
00392         image.clear();
00393         image.setKey(key);
00394     }
00395     else {
00396         // try to find a PIXMAP tag if the KEY is not available...
00397         e=element.namedItem("PIXMAP").toElement();
00398         if (e.isNull()) {
00399             // try to find a FILENAME tag (old cliparts...)
00400             e=element.namedItem("FILENAME").toElement();
00401             if(!e.isNull()) {
00402                 // Loads from the disk directly (unless it's in the collection already?)
00403                 image = imageCollection->loadPicture( e.attribute("filename") );
00404             }
00405         } else {
00406             bool openPic = true;
00407             QString _data;
00408             QString _fileName;
00409             if(e.hasAttribute("data"))
00410                 _data=e.attribute("data");
00411             if ( _data.isEmpty() )
00412                 openPic = true;
00413             else
00414                 openPic = false;
00415             if(e.hasAttribute("filename"))
00416                 _fileName=e.attribute("filename");
00417             if ( !_fileName.isEmpty() )
00418             {
00419                 if ( int _envVarB = _fileName.find( '$' ) >= 0 )
00420                 {
00421                     int _envVarE = _fileName.find( '/', _envVarB );
00422                     // ### FIXME: it should be QString::local8Bit instead of QFile::encodeName, shouldn't it?
00423                     QString path = getenv( QFile::encodeName(_fileName.mid( _envVarB, _envVarE-_envVarB )) );
00424                     _fileName.replace( _envVarB-1, _envVarE-_envVarB+1, path );
00425                 }
00426             }
00427 
00428             if ( openPic )
00429                 // !! this loads it from the disk (unless it's in the image collection already)
00430                 image = imageCollection->loadPicture( _fileName );
00431             else
00432             {
00433                 KoPictureKey key( _fileName );
00434                 image.clear();
00435                 image.setKey(key);
00436                 QByteArray rawData=_data.utf8(); // XPM is normally ASCII, therefore UTF-8
00437                 rawData[rawData.size()-1]=char(10); // Replace the NULL character by a LINE FEED
00438                 QBuffer buffer(rawData); // ### TODO: open?
00439                 image.loadXpm(&buffer);
00440             }
00441         }
00442     }
00443 
00444     e = element.namedItem( "PICTURESETTINGS" ).toElement();
00445     if ( !e.isNull() ) {
00446         PictureMirrorType _mirrorType = PM_NORMAL;
00447         int _depth = 0;
00448         bool _swapRGB = false;
00449         bool _grayscal = false;
00450         int _bright = 0;
00451 
00452         if ( e.hasAttribute( "mirrorType" ) )
00453             _mirrorType = static_cast<PictureMirrorType>( e.attribute( "mirrorType" ).toInt() );
00454         if ( e.hasAttribute( "depth" ) )
00455             _depth = e.attribute( "depth" ).toInt();
00456         if ( e.hasAttribute( "swapRGB" ) )
00457             _swapRGB = static_cast<bool>( e.attribute( "swapRGB" ).toInt() );
00458         if ( e.hasAttribute( "grayscal" ) )
00459             _grayscal = static_cast<bool>( e.attribute( "grayscal" ).toInt() );
00460         if ( e.hasAttribute( "bright" ) )
00461             _bright = e.attribute( "bright" ).toInt();
00462 
00463         mirrorType = _mirrorType;
00464         depth = _depth;
00465         swapRGB = _swapRGB;
00466         grayscal = _grayscal;
00467         bright = _bright;
00468     }
00469     else {
00470         mirrorType = PM_NORMAL;
00471         depth = 0;
00472         swapRGB = false;
00473         grayscal = false;
00474         bright = 0;
00475     }
00476 
00477     e = element.namedItem( "EFFECTS" ).toElement();
00478     if (!e.isNull()) {
00479         if (e.hasAttribute("type"))
00480             m_effect = static_cast<ImageEffect>(e.attribute("type").toInt());
00481         if (e.hasAttribute("param1"))
00482             m_ie_par1 = QVariant(e.attribute("param1"));
00483         else
00484             m_ie_par1 = QVariant();
00485         if (e.hasAttribute("param2"))
00486             m_ie_par2 = QVariant(e.attribute("param2"));
00487         else
00488             m_ie_par2 = QVariant();
00489         if (e.hasAttribute("param3"))
00490             m_ie_par3 = QVariant(e.attribute("param3"));
00491         else
00492             m_ie_par3 = QVariant();
00493     }
00494     else
00495         m_effect = IE_NONE;
00496 
00497     return offset;
00498 }
00499 
00500 void KPrPixmapObject::drawShadow( QPainter* _painter, KoZoomHandler* _zoomHandler)
00501 {
00502     const double ox = orig.x();
00503     const double oy = orig.y();
00504     const double ow = ext.width();
00505     const double oh = ext.height();
00506 
00507     _painter->save();
00508 
00509     QPen pen2 = pen.zoomedPen( _zoomHandler );
00510     _painter->setPen( pen2 );
00511     _painter->setBrush( getBrush() );
00512 
00513     double sx = 0;
00514     double sy = 0;
00515 
00516     getShadowCoords( sx, sy );
00517 
00518     _painter->translate( _zoomHandler->zoomItX( ox ), _zoomHandler->zoomItY( oy ) );
00519     _painter->setPen( QPen( shadowColor ) );
00520     _painter->setBrush( shadowColor );
00521     if ( kAbs(angle) <= DBL_EPSILON )
00522         _painter->drawRect( _zoomHandler->zoomItX( sx ), _zoomHandler->zoomItY( sy ),
00523                             _zoomHandler->zoomItX( ext.width() ), _zoomHandler->zoomItY( ext.height() ) );
00524     else
00525     {
00526         QSize bs = QSize( _zoomHandler->zoomItX( ow ), _zoomHandler->zoomItY( oh ) );
00527         QRect br = QRect( 0, 0, bs.width(), bs.height() );
00528         int pw = br.width();
00529         int ph = br.height();
00530         QRect rr = br;
00531         int pixYPos = -rr.y();
00532         int pixXPos = -rr.x();
00533         br.moveTopLeft( QPoint( -br.width() / 2, -br.height() / 2 ) );
00534         rr.moveTopLeft( QPoint( -rr.width() / 2, -rr.height() / 2 ) );
00535 
00536         QWMatrix m;
00537         m.translate( pw / 2, ph / 2 );
00538         m.rotate( angle );
00539         m.translate( rr.left() + pixXPos + _zoomHandler->zoomItX( sx ),
00540                      rr.top() + pixYPos + _zoomHandler->zoomItY( sy ) );
00541 
00542         _painter->setWorldMatrix( m, true );
00543 
00544         _painter->drawRect( 0, 0, bs.width(), bs.height() );
00545     }
00546 
00547     _painter->restore();
00548 }
00549 
00550 QPixmap KPrPixmapObject::generatePixmap(KoZoomHandler*_zoomHandler)
00551 {
00552     const double penw = _zoomHandler->zoomItX( ( ( pen.style() == Qt::NoPen ) ? 1 : pen.width() ) / 2.0 );
00553 
00554     QSize size( _zoomHandler->zoomSize( ext ) );
00555     //kdDebug(33001) << "KPrPixmapObject::generatePixmap size= " << size << endl;
00556     QPixmap pixmap(size);
00557     QPainter paint;
00558 
00559     paint.begin( &pixmap );
00560     pixmap.fill( Qt::white );
00561 
00562     // Draw background
00563     paint.setPen( Qt::NoPen );
00564     paint.setBrush( getBrush() );
00565 
00566     QRect rect( (int)( penw ), (int)( penw ),
00567                 (int)( _zoomHandler->zoomItX( ext.width() ) - 2.0 * penw ),
00568                 (int)( _zoomHandler->zoomItY( ext.height() ) - 2.0 * penw ) );
00569 
00570     if ( getFillType() == FT_BRUSH || !gradient )
00571         paint.drawRect( rect );
00572     else {
00573         // ### TODO: this was also drawn for drawContour==true, but why?
00574         gradient->setSize( size );
00575         paint.drawPixmap( (int)( penw ), (int)( penw ),
00576                           gradient->pixmap(), 0, 0,
00577                           (int)( _zoomHandler->zoomItX( ext.width() ) - 2 * penw ),
00578                           (int)( _zoomHandler->zoomItY( ext.height() ) - 2 * penw ) );
00579     }
00580 
00581 
00582     image.draw(paint, 0, 0, size.width(), size.height(), 0, 0, -1, -1, false); // Always slow mode!
00583     image.clearCache(); // Release the memoy of the picture cache
00584 
00585     image.setAlphaBuffer(true);
00586     QBitmap tmpMask;
00587     tmpMask = image.createAlphaMask().scale(size);
00588     pixmap.setMask(tmpMask);
00589 
00590     paint.end();
00591     return pixmap;
00592 }
00593 
00594 void KPrPixmapObject::draw( QPainter *_painter, KoTextZoomHandler*_zoomHandler,
00595                            int pageNum, SelectionMode selectionMode, bool drawContour )
00596 {
00597     if ( image.isNull() ) return;
00598 
00599     if ( shadowDistance > 0 && !drawContour )
00600         drawShadow(_painter, _zoomHandler);
00601 
00602     const double ox = orig.x();
00603     const double oy = orig.y();
00604     const double ow = ext.width();
00605     const double oh = ext.height();
00606     const double penw = _zoomHandler->zoomItX( ( ( pen.style() == Qt::NoPen ) ? 1.0 : pen.width() ) / 2.0 );
00607 
00608     _painter->save();
00609 
00610     _painter->translate( _zoomHandler->zoomItX( ox ), _zoomHandler->zoomItY( oy ) );
00611 
00612     if ( kAbs(angle)> DBL_EPSILON ) {
00613         QSize bs = QSize( _zoomHandler->zoomItX( ow ), _zoomHandler->zoomItY( oh ) );
00614         QRect br = QRect( 0, 0, bs.width(), bs.height() );
00615         int pw = br.width();
00616         int ph = br.height();
00617         QRect rr = br;
00618         int pixYPos = -rr.y();
00619         int pixXPos = -rr.x();
00620         br.moveTopLeft( QPoint( -br.width() / 2, -br.height() / 2 ) );
00621         rr.moveTopLeft( QPoint( -rr.width() / 2, -rr.height() / 2 ) );
00622 
00623         QWMatrix m;
00624         m.translate( pw / 2, ph / 2 );
00625         m.rotate( angle );
00626         m.translate( rr.left() + pixXPos, rr.top() + pixYPos );
00627         _painter->setWorldMatrix( m, true );
00628     }
00629 
00630     if ( !drawContour )
00631     {
00632         QRect rect( 0, 0, (int)( _zoomHandler->zoomItX( ow ) ),
00633                     (int)( _zoomHandler->zoomItY(  oh ) ) );
00634         // ### HACK QT seems not to be able to correctly compare QVariant
00635         bool variants1;
00636         if (m_ie_par1.isNull())
00637             variants1=m_cachedPar1.isNull();
00638         else
00639             variants1=(m_ie_par1 == m_cachedPar1);
00640         bool variants2;
00641         if (m_ie_par2.isNull())
00642             variants2=m_cachedPar2.isNull();
00643         else
00644             variants2=(m_ie_par2 == m_cachedPar2);
00645         bool variants3;
00646         if (m_ie_par3.isNull())
00647             variants3=m_cachedPar3.isNull();
00648         else
00649             variants3=(m_ie_par3 == m_cachedPar3);
00650 
00651         if (m_cachedRect == rect
00652             // All what KPrPixmapObject::changePictureSettings needs
00653             && m_cachedMirrorType == mirrorType && m_cachedSwapRGB == swapRGB && m_cachedGrayscal == grayscal
00654             && m_cachedBright == bright && m_cachedEffect == m_effect
00655             // Who needs it?
00656             && m_cachedDepth == depth
00657 #if 0
00658             && m_ie_par1 == m_cachedPar1 && m_ie_par2 == m_cachedPar2 && m_ie_par3 == m_cachedPar3
00659 #else
00660             && variants1 && variants2 && variants3
00661 #endif
00662             )
00663         {
00664             //kdDebug(33001) << "Drawing cached pixmap " << (void*) this << " " << k_funcinfo << endl;
00665         }
00666         else
00667         {
00668             if (mirrorType != PM_NORMAL || depth != 0 || swapRGB || grayscal || bright != 0 || m_effect!=IE_NONE)
00669                 m_cachedPixmap = changePictureSettings( generatePixmap( _zoomHandler ) );
00670             else
00671                 m_cachedPixmap = generatePixmap( _zoomHandler );
00672             m_cachedRect = rect;
00673             m_cachedMirrorType = mirrorType;
00674             m_cachedSwapRGB = swapRGB;
00675             m_cachedGrayscal = grayscal;
00676             m_cachedBright = bright;
00677             m_cachedEffect = m_effect;
00678             m_cachedDepth = depth;
00679             m_cachedPar1 = m_ie_par1;
00680             m_cachedPar2 = m_ie_par2;
00681             m_cachedPar3 = m_ie_par3;
00682             //kdDebug(33001) <<  "Drawing non-cached pixmap " << (void*) this << " " << k_funcinfo << endl;
00683         }
00684         _painter->drawPixmap( rect, m_cachedPixmap);
00685     }
00686 
00687     // Draw border
00688     // ### TODO port to KoBorder::drawBorders() (after writing a simplified version of it, that takes the same border on each size)
00689     QPen pen2;
00690     if ( drawContour ) {
00691         pen2 = QPen( Qt::black, 1, Qt::DotLine );
00692         _painter->setRasterOp( Qt::NotXorROP );
00693     }
00694     else {
00695         pen2 = pen;
00696         pen2.setWidth( _zoomHandler->zoomItX( ( pen.style() == Qt::NoPen ) ? 1.0 : (double)pen.width() ) );
00697     }
00698     _painter->setPen( pen2 );
00699     _painter->setBrush( Qt::NoBrush );
00700     _painter->drawRect( (int)( penw ), (int)( penw ),
00701                         (int)( _zoomHandler->zoomItX( ow ) - 2.0 * penw ),
00702                         (int)( _zoomHandler->zoomItY( oh ) - 2.0 * penw ) );
00703 
00704     _painter->restore();
00705 
00706     KPrObject::draw( _painter, _zoomHandler, pageNum, selectionMode, drawContour );
00707 }
00708 
00709 QPixmap KPrPixmapObject::getOriginalPixmap()
00710 {
00711     QSize _pixSize = image.getOriginalSize();
00712     kdDebug(33001) << "KPrPixmapObject::getOriginalPixmap size= " << _pixSize << endl;
00713     QPixmap _pixmap = image.generatePixmap( _pixSize, true );
00714     image.clearCache(); // Release the memoy of the picture cache
00715 
00716     return _pixmap;
00717 }
00718 
00719 QPixmap KPrPixmapObject::changePictureSettings( QPixmap _tmpPixmap )
00720 {
00721     QImage _tmpImage = _tmpPixmap.convertToImage();
00722 
00723     if (_tmpImage.isNull())
00724         return _tmpPixmap;
00725 
00726     bool _horizontal = false;
00727     bool _vertical = false;
00728     if ( mirrorType == PM_HORIZONTAL )
00729         _horizontal = true;
00730     else if ( mirrorType == PM_VERTICAL )
00731         _vertical = true;
00732     else if ( mirrorType == PM_HORIZONTALANDVERTICAL ) {
00733         _horizontal = true;
00734         _vertical = true;
00735     }
00736 
00737     _tmpImage = _tmpImage.mirror( _horizontal, _vertical );
00738 
00739     if ( depth != 0 ) {
00740         QImage tmpImg = _tmpImage.convertDepth( depth );
00741         if ( !tmpImg.isNull() )
00742             _tmpImage = tmpImg;
00743     }
00744 
00745     if ( swapRGB )
00746         _tmpImage = _tmpImage.swapRGB();
00747 
00748     if ( grayscal ) {
00749         if ( depth == 1 || depth == 8 ) {
00750             for ( int i = 0; i < _tmpImage.numColors(); ++i ) {
00751                 QRgb rgb = _tmpImage.color( i );
00752                 int gray = qGray( rgb );
00753                 rgb = qRgb( gray, gray, gray );
00754                 _tmpImage.setColor( i, rgb );
00755             }
00756         }
00757         else {
00758             int _width = _tmpImage.width();
00759             int _height = _tmpImage.height();
00760             int _x = 0;
00761             int _y = 0;
00762 
00763             for ( _x = 0; _x < _width; ++_x ) {
00764                 for ( _y = 0; _y < _height; ++_y ) {
00765                     if ( _tmpImage.valid( _x, _y ) ) {
00766                         QRgb rgb = _tmpImage.pixel( _x, _y );
00767                         int gray = qGray( rgb );
00768                         rgb = qRgb( gray, gray, gray );
00769                         _tmpImage.setPixel( _x, _y, rgb );
00770                     }
00771                 }
00772             }
00773         }
00774     }
00775 
00776     if ( bright != 0 ) {
00777         if ( depth == 1 || depth == 8 ) {
00778             for ( int i = 0; i < _tmpImage.numColors(); ++i ) {
00779                 QRgb rgb = _tmpImage.color( i );
00780                 QColor c( rgb );
00781 
00782                 if ( bright > 0 )
00783                     rgb = c.light( 100 + bright ).rgb();
00784                 else
00785                     rgb = c.dark( 100 + abs( bright ) ).rgb();
00786 
00787                 _tmpImage.setColor( i, rgb );
00788             }
00789         }
00790         else {
00791             int _width = _tmpImage.width();
00792             int _height = _tmpImage.height();
00793             int _x = 0;
00794             int _y = 0;
00795 
00796             for ( _x = 0; _x < _width; ++_x ) {
00797                 for ( _y = 0; _y < _height; ++_y ) {
00798                     if ( _tmpImage.valid( _x, _y ) ) {
00799                         QRgb rgb = _tmpImage.pixel( _x, _y );
00800                         QColor c( rgb );
00801 
00802                         if ( bright > 0 )
00803                             rgb = c.light( 100 + bright ).rgb();
00804                         else
00805                             rgb = c.dark( 100 + abs( bright ) ).rgb();
00806 
00807                         _tmpImage.setPixel( _x, _y, rgb );
00808                     }
00809                 }
00810             }
00811         }
00812     }
00813 
00814     switch (m_effect) {
00815     case IE_CHANNEL_INTENSITY: {
00816         _tmpImage = KImageEffect::channelIntensity(_tmpImage, m_ie_par1.toDouble()/100.0,
00817                                                    static_cast<KImageEffect::RGBComponent>(m_ie_par2.toInt()));
00818         break;
00819     }
00820     case IE_FADE: {
00821         _tmpImage = KImageEffect::fade(_tmpImage, m_ie_par1.toDouble(), m_ie_par2.toColor());
00822         break;
00823     }
00824     case IE_FLATTEN: {
00825         _tmpImage = KImageEffect::flatten(_tmpImage, m_ie_par1.toColor(), m_ie_par2.toColor());
00826         break;
00827     }
00828     case IE_INTENSITY: {
00829         _tmpImage = KImageEffect::intensity(_tmpImage, m_ie_par1.toDouble()/100.0);
00830         break;
00831     }
00832     case IE_DESATURATE: {
00833         _tmpImage = KImageEffect::desaturate(_tmpImage, m_ie_par1.toDouble());
00834         break;
00835     }
00836     case IE_CONTRAST: {
00837         _tmpImage = KImageEffect::contrast(_tmpImage, m_ie_par1.toInt());
00838         break;
00839     }
00840     case IE_NORMALIZE: {
00841         KImageEffect::normalize(_tmpImage);
00842         break;
00843     }
00844     case IE_EQUALIZE: {
00845         KImageEffect::equalize(_tmpImage);
00846         break;
00847     }
00848     case IE_THRESHOLD: {
00849         KImageEffect::threshold(_tmpImage, m_ie_par1.toInt());
00850         break;
00851     }
00852     case IE_SOLARIZE: {
00853         KImageEffect::solarize(_tmpImage, m_ie_par1.toDouble());
00854         break;
00855     }
00856     case IE_EMBOSS: {
00857         _tmpImage = KImageEffect::emboss(_tmpImage);
00858         break;
00859     }
00860     case IE_DESPECKLE: {
00861         _tmpImage = KImageEffect::despeckle(_tmpImage);
00862         break;
00863     }
00864     case IE_CHARCOAL: {
00865         _tmpImage = KImageEffect::charcoal(_tmpImage, m_ie_par1.toDouble());
00866         break;
00867     }
00868     case IE_NOISE: {
00869         _tmpImage = KImageEffect::addNoise(_tmpImage, static_cast<KImageEffect::NoiseType>(m_ie_par1.toInt()));
00870         break;
00871     }
00872     case IE_BLUR: {
00873         _tmpImage = KImageEffect::blur(_tmpImage, m_ie_par1.toDouble());
00874         break;
00875     }
00876     case IE_EDGE: {
00877         _tmpImage = KImageEffect::edge(_tmpImage, m_ie_par1.toDouble());
00878         break;
00879     }
00880     case IE_IMPLODE: {
00881         _tmpImage = KImageEffect::implode(_tmpImage, m_ie_par1.toDouble());
00882         break;
00883     }
00884     case IE_OIL_PAINT: {
00885         _tmpImage = KImageEffect::oilPaint(_tmpImage, m_ie_par1.toInt());
00886         break;
00887     }
00888     case IE_SHARPEN: {
00889         _tmpImage = KImageEffect::sharpen(_tmpImage, m_ie_par1.toDouble());
00890         break;
00891     }
00892     case IE_SPREAD: {
00893         _tmpImage = KImageEffect::spread(_tmpImage, m_ie_par1.toInt());
00894         break;
00895     }
00896     case IE_SHADE: {
00897         _tmpImage = KImageEffect::shade(_tmpImage, m_ie_par1.toBool(), m_ie_par2.toDouble(), m_ie_par3.toDouble());
00898         break;
00899     }
00900     case IE_SWIRL: {
00901         _tmpImage = KImageEffect::swirl(_tmpImage, m_ie_par1.toDouble());
00902         break;
00903     }
00904     case IE_WAVE: {
00905         _tmpImage = KImageEffect::wave(_tmpImage, m_ie_par1.toDouble(), m_ie_par2.toDouble());
00906         break;
00907     }
00908     case IE_NONE:
00909     default:
00910         break;
00911     }
00912 
00913     _tmpPixmap.convertFromImage( _tmpImage );
00914 
00915     return _tmpPixmap;
00916 }
00917 
00918 void KPrPixmapObject::flip( bool horizontal )
00919 {
00920     KPr2DObject::flip( horizontal );
00921     if ( horizontal )
00922     {
00923         switch ( mirrorType )
00924         {
00925             case PM_NORMAL:
00926                 mirrorType = PM_HORIZONTAL;
00927                 break;
00928             case PM_HORIZONTAL:
00929                 mirrorType = PM_NORMAL;
00930                 break;
00931             case PM_VERTICAL:
00932                 mirrorType = PM_HORIZONTALANDVERTICAL;
00933                 break;
00934             case PM_HORIZONTALANDVERTICAL:
00935                 mirrorType = PM_VERTICAL;
00936                 break;
00937         }
00938     }
00939     else
00940     {
00941         switch ( mirrorType )
00942         {
00943             case PM_NORMAL:
00944                 mirrorType = PM_VERTICAL;
00945                 break;
00946             case PM_HORIZONTAL:
00947                 mirrorType = PM_HORIZONTALANDVERTICAL;
00948                 break;
00949             case PM_VERTICAL:
00950                 mirrorType = PM_NORMAL;
00951                 break;
00952             case PM_HORIZONTALANDVERTICAL:
00953                 mirrorType = PM_HORIZONTAL;
00954                 break;
00955         }
00956     }
00957 }
00958 
KDE Home | KDE Accessibility Home | Description of Access Keys