kpresenter

KPrPolygonObject.cpp
1/* This file is part of the KDE project
2 Copyright (C) 2001 Toshitaka Fujioka <fujioka@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#include "KPrPolygonObject.h"
22#include "KPrGradient.h"
23#include <KoTextZoomHandler.h>
24#include <kdebug.h>
25#include <tqbitmap.h>
26#include <tqregion.h>
27#include <tqdom.h>
28#include <tqpicture.h>
29#include <tqpainter.h>
30#include "KPrPolygonObjectIface.h"
31#include <KoUnit.h>
32#include <KoOasisContext.h>
33#include <math.h>
34#include <KoXmlNS.h>
35#include "KoPen.h"
36
37using namespace std;
38
39KPrPolygonObject::KPrPolygonObject()
40 : KPr2DObject()
41{
42}
43
44KPrPolygonObject::KPrPolygonObject( const KoPointArray &_points, const KoSize &_size,
45 const KoPen &_pen, const TQBrush &_brush,
46 FillType _fillType, const TQColor &_gColor1, const TQColor &_gColor2, BCType _gType,
47 bool _unbalanced, int _xfactor, int _yfactor,
48 bool _checkConcavePolygon, int _cornersValue, int _sharpnessValue )
49 : KPr2DObject( _pen, _brush, _fillType, _gColor1, _gColor2, _gType, _unbalanced, _xfactor, _yfactor )
50{
51 points = KoPointArray( _points );
52 ext = _size;
53
54 checkConcavePolygon = _checkConcavePolygon;
55 cornersValue = _cornersValue;
56 sharpnessValue = _sharpnessValue;
57}
58
59KPrPolygonObject &KPrPolygonObject::operator=( const KPrPolygonObject & )
60{
61 return *this;
62}
63
64DCOPObject* KPrPolygonObject::dcopObject()
65{
66 if ( !dcop )
67 dcop = new KPrPolygonObjectIface( this );
68 return dcop;
69}
70
71bool KPrPolygonObject::saveOasisObjectAttributes( KPOasisSaveContext &sc ) const
72{
73 sc.xmlWriter.addAttribute( "draw:corners", cornersValue );
74 sc.xmlWriter.addAttribute( "draw:concave", checkConcavePolygon ? "true" : "false" );
75 if ( checkConcavePolygon )
76 {
77 sc.xmlWriter.addAttribute( "draw:sharpness", TQString( "%1%").arg( sharpnessValue ) );
78 }
79
80 return true;
81}
82
83const char * KPrPolygonObject::getOasisElementName() const
84{
85 return "draw:regular-polygon";
86}
87
88
89TQDomDocumentFragment KPrPolygonObject::save( TQDomDocument& doc, double offset )
90{
91 TQDomDocumentFragment fragment = KPr2DObject::save( doc, offset );
92
93 TQDomElement elemSettings = doc.createElement( "SETTINGS" );
94
95 elemSettings.setAttribute( "checkConcavePolygon", static_cast<int>( checkConcavePolygon ) );
96 elemSettings.setAttribute( "cornersValue", cornersValue );
97 elemSettings.setAttribute( "sharpnessValue", sharpnessValue );
98
99 fragment.appendChild( elemSettings );
100
101 if ( !points.isNull() ) {
102 TQDomElement elemPoints = doc.createElement( "POINTS" );
103 KoPointArray::ConstIterator it;
104 for ( it = points.begin(); it != points.end(); ++it ) {
105 TQDomElement elemPoint = doc.createElement( "Point" );
106 KoPoint point = (*it);
107 elemPoint.setAttribute( "point_x", point.x() );
108 elemPoint.setAttribute( "point_y", point.y() );
109
110 elemPoints.appendChild( elemPoint );
111 }
112 fragment.appendChild( elemPoints );
113 }
114
115 return fragment;
116}
117
118void KPrPolygonObject::loadOasis( const TQDomElement &element, KoOasisContext & context, KPrLoadingInfo *info )
119{
120 kdDebug()<<"void KPrPolygonObject::loadOasis( const TQDomElement &element )***********\n";
121 KPr2DObject::loadOasis( element,context, info );
122 cornersValue = element.attributeNS( KoXmlNS::draw, "corners", TQString() ).toInt();
123 checkConcavePolygon = element.attributeNS( KoXmlNS::draw, "concave", TQString() ) == "true";
124 sharpnessValue = 0;
125 if ( checkConcavePolygon )
126 {
127 sharpnessValue = element.attributeNS( KoXmlNS::draw, "sharpness", TQString() ).remove( '%').toInt();
128 }
129 drawPolygon();
130}
131
132double KPrPolygonObject::load( const TQDomElement &element )
133{
134 double offset=KPr2DObject::load( element );
135
136 TQDomElement e = element.namedItem( "SETTINGS" ).toElement();
137 if ( !e.isNull() ) {
138 bool _checkConcavePolygon = false;
139 int _cornersValue = 3;
140 int _sharpnessValue = 0;
141
142 if ( e.hasAttribute( "checkConcavePolygon" ) )
143 _checkConcavePolygon = static_cast<bool>( e.attribute( "checkConcavePolygon" ).toInt() );
144 if ( e.hasAttribute( "cornersValue" ) )
145 _cornersValue = e.attribute( "cornersValue" ).toInt();
146 if ( e.hasAttribute( "sharpnessValue" ) )
147 _sharpnessValue = e.attribute( "sharpnessValue" ).toInt();
148
149 checkConcavePolygon = _checkConcavePolygon;
150 cornersValue = _cornersValue;
151 sharpnessValue = _sharpnessValue;
152 }
153
154 e = element.namedItem( "POINTS" ).toElement();
155 if ( !e.isNull() ) {
156 TQDomElement elemPoint = e.firstChild().toElement();
157 unsigned int index = 0;
158 while ( !elemPoint.isNull() ) {
159 if ( elemPoint.tagName() == "Point" ) {
160 double tmpX = 0;
161 double tmpY = 0;
162 if( elemPoint.hasAttribute( "point_x" ) )
163 tmpX = elemPoint.attribute( "point_x" ).toDouble();
164 if( elemPoint.hasAttribute( "point_y" ) )
165 tmpY = elemPoint.attribute( "point_y" ).toDouble();
166
167 points.putPoints( index, 1, tmpX,tmpY );
168 }
169 elemPoint = elemPoint.nextSibling().toElement();
170 ++index;
171 }
172 }
173 return offset;
174}
175
176void KPrPolygonObject::setSize( double _width, double _height )
177{
178 KoSize origSize( ext );
179 KPrObject::setSize( _width, _height );
180
181 double fx = ext.width() / origSize.width();
182 double fy = ext.height() / origSize.height();
183
184 updatePoints( fx, fy );
185}
186
187void KPrPolygonObject::updatePoints( double _fx, double _fy )
188{
189 int index = 0;
190 KoPointArray tmpPoints;
191 KoPointArray::ConstIterator it;
192 for ( it = points.begin(); it != points.end(); ++it ) {
193 KoPoint point = (*it);
194 double tmpX = point.x() * _fx;
195 double tmpY = point.y() * _fy;
196
197 tmpPoints.putPoints( index, 1, tmpX,tmpY );
198 ++index;
199 }
200 points = tmpPoints;
201}
202
203void KPrPolygonObject::paint( TQPainter* _painter,KoTextZoomHandler*_zoomHandler,
204 int /* pageNum */, bool drawingShadow, bool drawContour )
205{
206 int _w = ( pen.style() == TQt::NoPen ) ? 1 : pen.width();//pen.width();
207
208 if ( drawContour ) {
209 TQPointArray pointArray2 = points.zoomPointArray( _zoomHandler );
210 TQPen pen3( TQt::black, 1, TQt::DotLine );
211 _painter->setPen( pen3 );
212 _painter->setRasterOp( TQt::NotXorROP );
213 _painter->drawPolygon( pointArray2 );
214 return;
215 }
216
217 TQPointArray pointArray = points.zoomPointArray( _zoomHandler, _w );
218 TQPen pen2 = pen.zoomedPen( _zoomHandler );
219
220 if ( drawingShadow || getFillType() == FT_BRUSH || !gradient ) {
221 _painter->setPen( pen2 );
222 _painter->setBrush( getBrush() );
223 _painter->drawPolygon( pointArray );
224 }
225 else {
226 TQSize size( _zoomHandler->zoomSize( ext ) );
227 if ( m_redrawGradientPix || gradient->size() != size )
228 {
229 m_redrawGradientPix = false;
230 gradient->setSize( size );
231 TQRegion clipregion( pointArray );
232 m_gradientPix.resize( size );
233 m_gradientPix.fill( TQt::white );
234
235 TQPainter p;
236 p.begin( &m_gradientPix );
237 p.setClipRegion( clipregion );
238 p.drawPixmap( 0, 0, gradient->pixmap() );
239 p.end();
240
241 m_gradientPix.setMask( m_gradientPix.createHeuristicMask() );
242 }
243
244 TQRect _rect = pointArray.boundingRect();
245 _painter->drawPixmap( 0, 0, m_gradientPix, 0, 0, _rect.width(), _rect.height() );
246
247 _painter->setPen( pen2 );
248 _painter->setBrush( TQt::NoBrush );
249 _painter->drawPolygon( pointArray );
250
251 }
252}
253
254void KPrPolygonObject::drawPolygon()
255{
256 kdDebug()<<"void KPrPolygonObject::drawPolygon()***********\n";
257 KoRect _rect( 0, 0, ext.width(), ext.height() );
258 double angle = 2 * M_PI / cornersValue;
259 double diameter = static_cast<double>( TQMAX( _rect.width(), _rect.height() ) );
260 double radius = diameter * 0.5;
261
262 KoPointArray _points( checkConcavePolygon ? cornersValue * 2 : cornersValue );
263 _points.setPoint( 0, 0, tqRound( -radius ) );
264
265 double xmin = 0;
266 double ymin = tqRound( -radius );
267
268 if ( checkConcavePolygon ) {
269 angle = angle / 2.0;
270 double a = angle;
271 double r = radius - ( sharpnessValue / 100.0 * radius );
272 for ( int i = 1; i < cornersValue * 2; ++i ) {
273 double xp, yp;
274 if ( i % 2 ) {
275 xp = r * sin( a );
276 yp = -r * cos( a );
277 }
278 else {
279 xp = radius * sin( a );
280 yp = -radius * cos( a );
281 }
282 a += angle;
283 _points.setPoint( i, xp, yp );
284 if (xp < xmin)
285 xmin = xp;
286 if (yp < ymin)
287 ymin = yp;
288 }
289 }
290 else {
291 double a = angle;
292 for ( int i = 1; i < cornersValue; ++i ) {
293 double xp = radius * sin( a );
294 double yp = -radius * cos( a );
295 a += angle;
296 _points.setPoint( i, xp, yp );
297 if (xp < xmin)
298 xmin = xp;
299 if (yp < ymin)
300 ymin = yp;
301 }
302 }
303
304 // calculate the points as offsets to 0,0
305 KoRect _changRect = _points.boundingRect();
306 double fx = _rect.width() / _changRect.width();
307 double fy = _rect.height() / _changRect.height();
308
309 int _index = 0;
310 KoPointArray tmpPoints;
311 KoPointArray::ConstIterator it;
312 for ( it = _points.begin(); it != _points.end(); ++it ) {
313 KoPoint point = (*it);
314 double tmpX = ( point.x() - xmin) * fx;
315 double tmpY = ( point.y() - ymin) * fy;
316
317 tmpPoints.putPoints( _index, 1, tmpX,tmpY );
318 ++_index;
319 }
320
321 points = tmpPoints;
322
323 if ( getFillType() == FT_GRADIENT && gradient )
324 m_redrawGradientPix = true;
325}
326
327void KPrPolygonObject::flip( bool horizontal )
328{
329 KPr2DObject::flip( horizontal );
330 // flip the points
331 KoPointArray tmpPoints;
332 int index = 0;
333 if ( ! horizontal )
334 {
335 KoPointArray::ConstIterator it;
336 double horiz = getSize().height()/2;
337 for ( it = points.begin(); it != points.end(); ++it ) {
338 KoPoint point = (*it);
339 if ( point.y()> horiz )
340 tmpPoints.putPoints( index, 1, point.x(),point.y()- 2*(point.y()-horiz) );
341 else
342 tmpPoints.putPoints( index, 1, point.x(),point.y()+ 2*(horiz - point.y()) );
343 ++index;
344 }
345 }
346 else
347 {
348 KoPointArray::ConstIterator it;
349 double vert = getSize().width()/2;
350 for ( it = points.begin(); it != points.end(); ++it ) {
351 KoPoint point = (*it);
352 if ( point.x()> vert )
353 tmpPoints.putPoints( index, 1, point.x()- 2*(point.x()-vert), point.y() );
354 else
355 tmpPoints.putPoints( index, 1, point.x()+ 2*(vert - point.x()),point.y() );
356 ++index;
357 }
358 }
359 points = tmpPoints;
360}
361
362KoSize KPrPolygonObject::getRealSize() const {
363 KoSize size( ext );
364 KoPoint realOrig( orig );
365 KoPointArray p( points );
366 getRealSizeAndOrigFromPoints( p, angle, size, realOrig );
367 return size;
368}
369
370KoPoint KPrPolygonObject::getRealOrig() const {
371 KoSize size( ext );
372 KoPoint realOrig( orig );
373 KoPointArray p( points );
374 getRealSizeAndOrigFromPoints( p, angle, size, realOrig );
375 return realOrig;
376}
Temporary information used only during loading.