libs/flake

KoShapePainter.cpp

Go to the documentation of this file.
00001 /* This file is part of the KDE project
00002  *
00003  * Copyright (C) 2007 Jan Hambrecht <jaham@gmx.net>
00004  *
00005  * This library is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU Library General Public
00007  * License as published by the Free Software Foundation; either
00008  * version 2 of the License, or (at your option) any later version.
00009  *
00010  * This library is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  * Library General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU Library General Public License
00016  * along with this library; see the file COPYING.LIB.  If not, write to
00017  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018  * Boston, MA 02110-1301, USA.
00019  */
00020 
00021 #include "KoShapePainter.h"
00022 
00023 #include <KoCanvasBase.h>
00024 #include <KoShapeManager.h>
00025 #include <KoShapeManagerPaintingStrategy.h>
00026 #include <KoZoomHandler.h>
00027 #include <KoUnit.h>
00028 #include <KoShape.h>
00029 #include <KoShapeBorderModel.h>
00030 #include <KoShapeGroup.h>
00031 #include <KoShapeContainer.h>
00032 
00033 #include <QtGui/QImage>
00034 
00035 class SimpleCanvas : public KoCanvasBase
00036 {
00037 public:
00038     SimpleCanvas()
00039         : KoCanvasBase(0), m_shapeManager( new KoShapeManager( this ) )
00040         , m_zoomHandler( new KoZoomHandler() )
00041     {
00042     }
00043 
00044     ~SimpleCanvas()
00045     {
00046         delete m_shapeManager;
00047         delete m_zoomHandler;
00048     }
00049 
00050     virtual void gridSize(qreal *horizontal, qreal *vertical) const
00051     {
00052         if( horizontal )
00053             *horizontal = 0;
00054         if( vertical )
00055             *vertical = 0;
00056     };
00057 
00058     virtual bool snapToGrid() const
00059     {
00060         return false;
00061     }
00062 
00063     virtual void addCommand(QUndoCommand *command)
00064     {
00065         Q_UNUSED( command );
00066     };
00067 
00068     virtual KoShapeManager *shapeManager() const
00069     {
00070         return m_shapeManager;
00071     };
00072 
00073     virtual void updateCanvas(const QRectF& rc)
00074     {
00075         Q_UNUSED( rc );
00076     };
00077 
00078     virtual KoToolProxy * toolProxy() const
00079     {
00080         return 0;
00081     };
00082 
00083     virtual const KoViewConverter *viewConverter() const
00084     {
00085         return m_zoomHandler;
00086     }
00087 
00088     virtual QWidget* canvasWidget()
00089     {
00090         return 0;
00091     };
00092 
00093     virtual const QWidget* canvasWidget() const {
00094         return 0;
00095     }
00096 
00097     virtual KoUnit unit() const
00098     {
00099         return KoUnit( KoUnit::Point );
00100     }
00101 
00102     virtual void updateInputMethodInfo() {};
00103 private:
00104     KoShapeManager * m_shapeManager;
00105     KoZoomHandler * m_zoomHandler;
00106 };
00107 
00108 class KoShapePainter::Private
00109 {
00110 public:
00111     Private()
00112     : canvas( new SimpleCanvas() )
00113     {
00114     }
00115     ~Private() { delete canvas; }
00116     SimpleCanvas * canvas;
00117 };
00118 
00119 KoShapePainter::KoShapePainter(KoShapeManagerPaintingStrategy * strategy)
00120     : d( new Private() )
00121 {
00122     if (strategy) {
00123         strategy->setShapeManager(d->canvas->shapeManager());
00124         d->canvas->shapeManager()->setPaintingStrategy(strategy);
00125     }
00126 }
00127 
00128 KoShapePainter::~KoShapePainter()
00129 {
00130     delete d;
00131 }
00132 
00133 void KoShapePainter::setShapes( const QList<KoShape*> &shapes )
00134 {
00135     d->canvas->shapeManager()->setShapes(shapes, KoShapeManager::AddWithoutRepaint);
00136 }
00137 
00138 void KoShapePainter::paintShapes( QPainter & painter, KoViewConverter & converter )
00139 {
00140     foreach (KoShape *shape, d->canvas->shapeManager()->shapes()) {
00141         shape->waitUntilReady(converter, false);
00142     }
00143 
00144     d->canvas->shapeManager()->paint( painter, converter, true );
00145 }
00146 
00147 void KoShapePainter::paintShapes( QPainter & painter, const QRect & painterRect, const QRectF & documentRect )
00148 {
00149     KoZoomHandler zoomHandler;
00150     // calculate the painter destination rectangle size in document coordinates
00151     QRectF paintBox = zoomHandler.viewToDocument(QRectF(QPointF(), painterRect.size()));
00152 
00153     // compute the zoom factor based on the bounding rects in document coordinates
00154     // so that the content fits into the image
00155     qreal zoomW = paintBox.width() / documentRect.width();
00156     qreal zoomH = paintBox.height() / documentRect.height();
00157     qreal zoom = qMin( zoomW, zoomH );
00158 
00159     // now set the zoom into the zoom handler used for painting the shape
00160     zoomHandler.setZoom( zoom );
00161 
00162     painter.save();
00163 
00164     // initialize painter
00165     painter.setPen( QPen(Qt::NoPen) );
00166     painter.setBrush( Qt::NoBrush );
00167     painter.setRenderHint(QPainter::Antialiasing);
00168     painter.setClipRect( painterRect.adjusted(-1,-1,1,1) );
00169 
00170     // convert document rectangle to view coordinates
00171     QRectF zoomedBound = zoomHandler.documentToView( documentRect );
00172     // calculate offset between painter rectangle and converted document rectangle
00173     QPointF offset = QPointF(painterRect.center()) - zoomedBound.center();
00174     // center content in painter rectangle
00175     painter.translate( offset.x(), offset.y() );
00176 
00177     // finally paint the shapes
00178     paintShapes( painter, zoomHandler );
00179 
00180     painter.restore();
00181 }
00182 
00183 bool KoShapePainter::paintShapes( QImage & image )
00184 {
00185     if( image.isNull() )
00186         return false;
00187 
00188     QPainter painter( &image );
00189 
00190     paintShapes( painter, image.rect(), contentRect() );
00191 
00192     return true;
00193 }
00194 
00195 QRectF KoShapePainter::contentRect()
00196 {
00197     QRectF bound;
00198     foreach(KoShape * shape, d->canvas->shapeManager()->shapes()) {
00199         if (! shape->isVisible( true ))
00200             continue;
00201         if (dynamic_cast<KoShapeGroup*>(shape))
00202             continue;
00203 
00204         QRectF shapeRect = shape->boundingRect();
00205 
00206         if (bound.isEmpty())
00207             bound = shapeRect;
00208         else
00209             bound = bound.united(shapeRect);
00210     }
00211     return bound;
00212 }