21#include "KPrPieObject.h"
22#include "KPrGradient.h"
24#include "KPrPieObjectIface.h"
26#include <KoTextZoomHandler.h>
27#include <KoOasisContext.h>
28#include <KoStyleStack.h>
40KPrPieObject::KPrPieObject()
42, KPrStartEndLine( L_NORMAL, L_NORMAL )
49KPrPieObject::KPrPieObject(
const KoPen &_pen,
const TQBrush &_brush, FillType _fillType,
50 const TQColor &_gColor1,
const TQColor &_gColor2, BCType _gType,
51 PieType _pieType,
int _p_angle,
int _p_len,
52 LineEnd _lineBegin, LineEnd _lineEnd,
53 bool _unbalanced,
int _xfactor,
int _yfactor )
54: KPr2DObject( _pen, _brush, _fillType, _gColor1, _gColor2, _gType, _unbalanced, _xfactor, _yfactor )
55, KPrStartEndLine( _lineBegin, _lineEnd )
62DCOPObject* KPrPieObject::dcopObject()
65 dcop =
new KPrPieObjectIface(
this );
69KPrPieObject &KPrPieObject::operator=(
const KPrPieObject & )
74TQDomDocumentFragment KPrPieObject::save( TQDomDocument& doc,
double offset )
76 TQDomDocumentFragment fragment=KPr2DObject::save(doc, offset);
77 KPrStartEndLine::save( fragment, doc );
79 fragment.appendChild(KPrObject::createValueElement(
"PIEANGLE", p_angle, doc));
81 fragment.appendChild(KPrObject::createValueElement(
"PIELENGTH", p_len, doc));
83 fragment.appendChild(KPrObject::createValueElement(
"PIETYPE",
static_cast<int>(pieType), doc));
87bool KPrPieObject::saveOasisObjectAttributes( KPOasisSaveContext &sc )
const
92 sc.xmlWriter.addAttribute(
"draw:kind",
"section" );
95 sc.xmlWriter.addAttribute(
"draw:kind",
"cut" );
98 sc.xmlWriter.addAttribute(
"draw:kind",
"arc" );
101 kdDebug() <<
" type of pie not supported" << endl;
104 int startangle = ( (int)p_angle / 16 );
105 sc.xmlWriter.addAttribute(
"draw:start-angle", startangle );
107 int endangle = ( (int) p_len / 16 ) + startangle;
108 sc.xmlWriter.addAttribute(
"draw:end-angle", endangle );
113void KPrPieObject::fillStyle( KoGenStyle& styleObjectAuto, KoGenStyles& mainStyles )
const
115 KPrShadowObject::fillStyle( styleObjectAuto, mainStyles );
116 if ( pieType == PT_ARC )
118 saveOasisMarkerElement( mainStyles, styleObjectAuto );
122 m_brush.saveOasisFillStyle( styleObjectAuto, mainStyles );
126const char * KPrPieObject::getOasisElementName()
const
128 return ext.width() == ext.height() ?
"draw:circle" :
"draw:ellipse";
132void KPrPieObject::loadOasis(
const TQDomElement &element, KoOasisContext & context,
KPrLoadingInfo *info)
134 kdDebug()<<
"void KPrPieObject::loadOasis(const TQDomElement &element) ***************\n";
135 KPr2DObject::loadOasis(element, context, info);
136 TQString kind = element.attributeNS( KoXmlNS::draw,
"kind", TQString() );
137 if ( kind ==
"section" )
139 else if ( kind ==
"cut" )
141 else if ( kind ==
"arc" )
145 kdDebug()<<
" KPrPieObject::loadOasis(const TQDomElement &element) type indefined :"<<kind<<endl;
148 kdDebug()<<
" type of pie object :"<<( ( pieType == PT_PIE ) ?
"pie" : ( pieType == PT_CHORD )?
"cut" :
"arc" )<<endl;
150 int start = (int) ( element.attributeNS( KoXmlNS::draw,
"start-angle", TQString() ).toDouble() );
153 int end = (int) ( element.attributeNS( KoXmlNS::draw,
"end-angle", TQString() ).toDouble() );
155 p_len = ( ( 360 - start + end ) * 16 );
157 p_len = ( ( end - start ) * 16 );
159 kdDebug()<<
"KPrPieObject::loadOasis(const TQDomElement &element) : p_angle :"<<p_angle<<
" p_len :"<<p_len<<endl;
160 if ( pieType == PT_ARC )
162 loadOasisMarkerElement( context,
"marker-start", lineBegin );
163 loadOasisMarkerElement( context,
"marker-end", lineEnd );
167double KPrPieObject::load(
const TQDomElement &element)
169 double offset=KPr2DObject::load(element);
170 KPrStartEndLine::load( element );
171 TQDomElement e=element.namedItem(
"PIEANGLE").toElement();
174 if(e.hasAttribute(
"value"))
175 tmp=e.attribute(
"value").toInt();
178 e=element.namedItem(
"PIELENGTH").toElement();
181 if(e.hasAttribute(
"value"))
182 tmp=e.attribute(
"value").toInt();
188 e=element.namedItem(
"PIETYPE").toElement();
191 if(e.hasAttribute(
"value"))
192 tmp=e.attribute(
"value").toInt();
193 pieType=
static_cast<PieType
>(tmp);
198void KPrPieObject::paint( TQPainter* _painter, KoTextZoomHandler*_zoomHandler,
199 int ,
bool drawingShadow,
bool drawContour )
201 double ow = ext.width();
202 double oh = ext.height();
203 double pw = ( ( pen.style() == TQt::NoPen ) ? 1 : pen.pointWidth() ) / 2.0;
206 TQPen pen3( TQt::black, 1, TQt::DotLine );
207 _painter->setPen( pen3 );
208 _painter->setRasterOp( TQt::NotXorROP );
211 TQPen pen2 = pen.zoomedPen( _zoomHandler );
212 _painter->setPen( pen2 );
213 if ( drawingShadow || getFillType() == FT_BRUSH || !gradient )
215 _painter->setBrush( getBrush() );
219 if ( pieType != PT_ARC )
221 TQSize size( _zoomHandler->zoomSize( ext ) );
223 if ( m_redrawGradientPix || gradient->size() != size )
225 m_redrawGradientPix =
false;
226 gradient->setSize( size );
228 m_gradientPix.resize ( size );
229 m_gradientPix.fill( TQt::white );
231 p.begin( &m_gradientPix );
232 p.drawPixmap( 0, 0, gradient->pixmap() );
235 TQBitmap mask( size,
true );
237 p.setPen( TQPen( TQt::color1 ) );
238 p.setBrush( TQBrush( TQt::color1 ) );
239 if ( pieType == PT_CHORD )
241 p.drawChord( _zoomHandler->zoomItX(pw), _zoomHandler->zoomItY(pw),
242 _zoomHandler->zoomItX(ow - 2 * pw),
243 _zoomHandler->zoomItY(oh - 2 * pw), p_angle, p_len );
247 p.drawPie( _zoomHandler->zoomItX(pw), _zoomHandler->zoomItY(pw),
248 _zoomHandler->zoomItX( ow - 2 * pw),
249 _zoomHandler->zoomItY( oh - 2 * pw), p_angle, p_len );
252 m_gradientPix.setMask( mask );
254 _painter->drawPixmap( 0, 0, m_gradientPix, 0, 0, size.width(), size.height() );
255 _painter->setBrush( TQt::NoBrush );
258 if ( pieType == PT_ARC )
260 KoPointArray points( 2 );
261 setEndPoints( points );
262 KoPoint start( points.point( 0 ) );
263 KoPoint end( points.point( 1 ) );
265 double ys = ( ( 1 - start.x() / ( ext.width() * ext.width() / 4 ) ) * ext.height() * ext.height() / 4 ) / start.y();
266 double s_angle = 90 + ( atan( ( start.x() - 1 ) / ( start.y() - ys ) ) * 180 / M_PI );
267 if ( p_angle / 16 >= 90 && p_angle / 16 <= 270 )
271 double ye = ( ( 1 - end.x() / ( ext.width() * ext.width() / 4 ) ) * ext.height() * ext.height() / 4 ) / end.y();
272 double e_angle = 270 + ( atan( ( end.x() - 1 ) / ( end.y() - ye ) ) * 180 / M_PI );
273 if ( ( ( p_angle + p_len ) / 16 ) % 360 >= 90 && ( ( p_angle + p_len ) / 16 ) % 360 <= 270 )
278 start = KoPoint( ext.width() / 2.0 + start.x(), ext.height() / 2.0 - start.y() );
279 end = KoPoint( ext.width() / 2.0 + end.x(), ext.height() / 2.0 - end.y() );
283 if ( lineBegin != L_NORMAL )
284 drawFigureWithOffset( lineBegin, _painter, start,
285 pen2.color(),
int( pen.pointWidth() ), s_angle, _zoomHandler,
true );
287 if ( lineEnd != L_NORMAL )
288 drawFigureWithOffset( lineEnd, _painter, end,
289 pen2.color(),
int( pen.pointWidth() ), e_angle, _zoomHandler,
false );
295 _painter->drawPie( _zoomHandler->zoomItX(pw), _zoomHandler->zoomItY( pw),
296 _zoomHandler->zoomItX( ow - 2 * pw),
297 _zoomHandler->zoomItY( oh - 2 * pw), p_angle, p_len );
300 _painter->drawArc( _zoomHandler->zoomItX(pw), _zoomHandler->zoomItY(pw),
301 _zoomHandler->zoomItX(ow - 2 * pw),
302 _zoomHandler->zoomItY(oh - 2 * pw), p_angle, p_len );
305 _painter->drawChord( _zoomHandler->zoomItX(pw), _zoomHandler->zoomItY(pw),
306 _zoomHandler->zoomItX(ow - 2 * pw),
307 _zoomHandler->zoomItY(oh - 2 * pw), p_angle, p_len );
313void KPrPieObject::flip(
bool horizontal )
315 KPr2DObject::flip( horizontal );
318 p_angle = 360*16 - p_angle -p_len;
322 p_angle = 180*16 - p_angle - p_len;
325 while ( p_angle < 0 ) {
332void KPrPieObject::setMinMax(
double &min_x,
double &min_y,
333 double &max_x,
double &max_y, KoPoint point )
const
335 double tmp_x = point.x();
336 double tmp_y = point.y();
338 if ( tmp_x < min_x ) {
341 else if ( tmp_x > max_x ) {
345 if ( tmp_y < min_y ) {
348 else if ( tmp_y > max_y ) {
365void KPrPieObject::getRealSizeAndOrig( KoSize &size, KoPoint &realOrig )
const {
366 double radius1 = size.width() / 2.0;
367 double radius2 = size.height() / 2.0;
370 double angInRad = angle * M_PI / 180;
373 KoPointArray points(2);
374 setEndPoints( points );
377 for (
int i = 0; i < 2; i++ ) {
379 double sinus = sin( angInRad );
380 double cosinus = cos( angInRad );
382 double tmp_x = points.point( i ).x();
383 double tmp_y = points.point( i ).y();
385 double x = tmp_x * cosinus + tmp_y * sinus;
386 double y = - tmp_x * sinus + tmp_y * cosinus;
387 points.setPoint( i, x, y );
391 KoPoint firstPoint( points.point(0) );
392 KoPoint secondPoint( points.point(1) );
395 KoPointArray maxPoints(4);
397 maxPoints.setPoint( 0, 0, radius2 );
398 maxPoints.setPoint( 1, radius1, 0 );
399 maxPoints.setPoint( 2, 0, -radius2 );
400 maxPoints.setPoint( 3, -radius1, 0 );
403 double sinus = sin( angInRad );
404 double cosinus = cos( angInRad );
406 double x = sqrt( pow( radius1 * cosinus , 2 ) + pow(radius2 * sinus, 2));
407 double y = ( pow( radius2, 2 ) - pow( radius1, 2) ) * sinus * cosinus / x;
408 maxPoints.setPoint( 0, x, y );
409 maxPoints.setPoint( 1, -x, -y );
411 y = sqrt( pow( radius1 * sinus , 2 ) + pow(radius2 * cosinus, 2));
412 x = ( pow( radius1, 2 ) - pow( radius2, 2) ) * sinus * cosinus / y;
413 maxPoints.setPoint( 2, x, y);
414 maxPoints.setPoint( 3, -x, -y );
418 double min_x = firstPoint.x();
419 double min_y = firstPoint.y();
420 double max_x = firstPoint.x();
421 double max_y = firstPoint.y();
423 if ( pieType == PT_PIE ) {
425 setMinMax( min_x, min_y, max_x, max_y, zero );
427 setMinMax( min_x, min_y, max_x, max_y, secondPoint );
447 if ( firstPoint.y() >= 0 ) {
448 if ( secondPoint.y() >= 0 ) {
449 if ( firstPoint.x() > secondPoint.x() || p_len == 0 ) {
452 KoPointArray::ConstIterator it( maxPoints.begin() );
453 for ( ; it != maxPoints.end(); ++it ) {
454 if ( (*it).y() >= 0 &&
455 (*it).x() <= firstPoint.x() && (*it).x() >= secondPoint.x() )
457 setMinMax( min_x, min_y, max_x, max_y, *it );
466 KoPointArray::ConstIterator it( maxPoints.begin() );
467 for ( ; it != maxPoints.end(); ++it ) {
468 if ( (*it).y() >= 0 ) {
469 if ( (*it).x() <= firstPoint.x() || (*it).x() >= secondPoint.x() ) {
470 setMinMax( min_x, min_y, max_x, max_y, *it );
474 setMinMax( min_x, min_y, max_x, max_y, *it );
483 KoPointArray::ConstIterator it( maxPoints.begin() );
484 for ( ; it != maxPoints.end(); ++it ) {
485 if ( (*it).y() >= 0 ) {
486 if ( (*it).x() <= firstPoint.x() ) {
487 setMinMax( min_x, min_y, max_x, max_y, *it );
491 if ( (*it).x() <= secondPoint.x() ) {
492 setMinMax( min_x, min_y, max_x, max_y, *it );
499 if ( secondPoint.y() >= 0 ) {
503 KoPointArray::ConstIterator it( maxPoints.begin() );
504 for ( ; it != maxPoints.end(); ++it ) {
505 if ( (*it).y() < 0 ) {
506 if ( (*it).x() >= firstPoint.x() ) {
507 setMinMax( min_x, min_y, max_x, max_y, *it );
511 if ( (*it).x() >= secondPoint.x() ) {
512 setMinMax( min_x, min_y, max_x, max_y, *it );
518 if ( firstPoint.x() < secondPoint.x() || p_len == 0 ) {
521 KoPointArray::ConstIterator it( maxPoints.begin() );
522 for ( ; it != maxPoints.end(); ++it ) {
523 if ( (*it).y() < 0 &&
524 (*it).x() >= firstPoint.x() && (*it).x() <= secondPoint.x() )
526 setMinMax( min_x, min_y, max_x, max_y, *it );
535 KoPointArray::ConstIterator it( maxPoints.begin() );
536 for ( ; it != maxPoints.end(); ++it ) {
537 if ( (*it).y() < 0 ) {
538 if ( (*it).x() >= firstPoint.x() || (*it).x() <= secondPoint.x() ) {
539 setMinMax( min_x, min_y, max_x, max_y, *it );
543 setMinMax( min_x, min_y, max_x, max_y, *it );
550 double mid_x = size.width() / 2;
551 double mid_y = size.height() / 2;
553 size.setWidth( max_x - min_x );
554 size.setHeight( max_y - min_y );
556 realOrig.setX( realOrig.x() + mid_x + min_x );
557 realOrig.setY( realOrig.y() + mid_y - max_y );
560void KPrPieObject::setEndPoints( KoPointArray &points )
const
562 int angles[] = { p_angle, ( p_angle + p_len ) % ( 16 * 360 ) };
563 double anglesInRad[] = { p_angle / 16.0 * M_PI / 180, ( angles[1] ) / 16.0 * M_PI / 180 };
565 double radius1 = ext.width() / 2.0;
566 double radius2 = ext.height() / 2.0;
568 double prop = radius2 / radius1;
570 for (
int i = 0; i < 2; i++ ) {
575 if ( angles[i] == 90 * 16 ) {
578 else if ( angles[i] == 270 * 16 ) {
584 double tanalpha = tan( anglesInRad[i] ) * prop;
585 x = sqrt( 1 / ( pow ( 1 / radius1, 2 ) + pow( tanalpha / radius2, 2 ) ) );
586 if ( angles[i] > 90 * 16 && angles[i] < 270 * 16 )
590 points.setPoint( i, x, y );
594KoSize KPrPieObject::getRealSize()
const {
596 KoPoint realOrig( orig );
597 getRealSizeAndOrig( size, realOrig );
602KoPoint KPrPieObject::getRealOrig()
const {
604 KoPoint realOrig( orig );
605 getRealSizeAndOrig( size, realOrig );
Temporary information used only during loading.