|
|
|
/* This file is part of the KDE project
|
|
|
|
Copyright (C) 1998, 1999 Reginald Stadlbauer <reggie@kde.org>
|
|
|
|
Copyright (C) 2005-2006 Thorsten Zachmann <zachmann@kde.org>
|
|
|
|
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU Library General Public
|
|
|
|
License as published by the Free Software Foundation; either
|
|
|
|
version 2 of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
Library General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Library General Public License
|
|
|
|
along with this library; see the file COPYING.LIB. If not, write to
|
|
|
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
|
|
* Boston, MA 02110-1301, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "KPrPieObject.h"
|
|
|
|
#include "KPrGradient.h"
|
|
|
|
#include "KPrUtils.h"
|
|
|
|
#include "KPrPieObjectIface.h"
|
|
|
|
|
|
|
|
#include <KoTextZoomHandler.h>
|
|
|
|
#include <KoOasisContext.h>
|
|
|
|
#include <KoStyleStack.h>
|
|
|
|
#include <KoXmlNS.h>
|
|
|
|
|
|
|
|
#include <kdebug.h>
|
|
|
|
|
|
|
|
#include <tqregion.h>
|
|
|
|
#include <tqpicture.h>
|
|
|
|
#include <tqdom.h>
|
|
|
|
#include <tqpainter.h>
|
|
|
|
#include <tqbitmap.h>
|
|
|
|
using namespace std;
|
|
|
|
|
|
|
|
KPrPieObject::KPrPieObject()
|
|
|
|
: KPr2DObject()
|
|
|
|
, KPrStartEndLine( L_NORMAL, L_NORMAL )
|
|
|
|
{
|
|
|
|
pieType = PT_PIE;
|
|
|
|
p_angle = 45 * 16;
|
|
|
|
p_len = 270 * 16;
|
|
|
|
}
|
|
|
|
|
|
|
|
KPrPieObject::KPrPieObject( const KoPen &_pen, const TQBrush &_brush, FillType _fillType,
|
|
|
|
const TQColor &_gColor1, const TQColor &_gColor2, BCType _gType,
|
|
|
|
PieType _pieType, int _p_angle, int _p_len,
|
|
|
|
LineEnd _lineBegin, LineEnd _lineEnd,
|
|
|
|
bool _unbalanced, int _xfactor, int _yfactor )
|
|
|
|
: KPr2DObject( _pen, _brush, _fillType, _gColor1, _gColor2, _gType, _unbalanced, _xfactor, _yfactor )
|
|
|
|
, KPrStartEndLine( _lineBegin, _lineEnd )
|
|
|
|
{
|
|
|
|
pieType = _pieType;
|
|
|
|
p_angle = _p_angle;
|
|
|
|
p_len = _p_len;
|
|
|
|
}
|
|
|
|
|
|
|
|
DCOPObject* KPrPieObject::dcopObject()
|
|
|
|
{
|
|
|
|
if ( !dcop )
|
|
|
|
dcop = new KPrPieObjectIface( this );
|
|
|
|
return dcop;
|
|
|
|
}
|
|
|
|
|
|
|
|
KPrPieObject &KPrPieObject::operator=( const KPrPieObject & )
|
|
|
|
{
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQDomDocumentFragment KPrPieObject::save( TQDomDocument& doc, double offset )
|
|
|
|
{
|
|
|
|
TQDomDocumentFragment fragment=KPr2DObject::save(doc, offset);
|
|
|
|
KPrStartEndLine::save( fragment, doc );
|
|
|
|
if (p_angle!=720)
|
|
|
|
fragment.appendChild(KPrObject::createValueElement("PIEANGLE", p_angle, doc));
|
|
|
|
if (p_len!=1440)
|
|
|
|
fragment.appendChild(KPrObject::createValueElement("PIELENGTH", p_len, doc));
|
|
|
|
if (pieType!=PT_PIE)
|
|
|
|
fragment.appendChild(KPrObject::createValueElement("PIETYPE", static_cast<int>(pieType), doc));
|
|
|
|
return fragment;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool KPrPieObject::saveOasisObjectAttributes( KPOasisSaveContext &sc ) const
|
|
|
|
{
|
|
|
|
switch( pieType )
|
|
|
|
{
|
|
|
|
case PT_PIE:
|
|
|
|
sc.xmlWriter.addAttribute( "draw:kind", "section" );
|
|
|
|
break;
|
|
|
|
case PT_CHORD:
|
|
|
|
sc.xmlWriter.addAttribute( "draw:kind", "cut" );
|
|
|
|
break;
|
|
|
|
case PT_ARC:
|
|
|
|
sc.xmlWriter.addAttribute( "draw:kind", "arc" );
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
kdDebug() << " type of pie not supported" << endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
int startangle = ( (int)p_angle / 16 );
|
|
|
|
sc.xmlWriter.addAttribute( "draw:start-angle", startangle );
|
|
|
|
|
|
|
|
int endangle = ( (int) p_len / 16 ) + startangle;
|
|
|
|
sc.xmlWriter.addAttribute( "draw:end-angle", endangle );
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void KPrPieObject::fillStyle( KoGenStyle& styleObjectAuto, KoGenStyles& mainStyles ) const
|
|
|
|
{
|
|
|
|
KPrShadowObject::fillStyle( styleObjectAuto, mainStyles );
|
|
|
|
if ( pieType == PT_ARC )
|
|
|
|
{
|
|
|
|
saveOasisMarkerElement( mainStyles, styleObjectAuto );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_brush.saveOasisFillStyle( styleObjectAuto, mainStyles );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const char * KPrPieObject::getOasisElementName() const
|
|
|
|
{
|
|
|
|
return ext.width() == ext.height() ? "draw:circle" : "draw:ellipse";
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void KPrPieObject::loadOasis(const TQDomElement &element, KoOasisContext & context, KPrLoadingInfo *info)
|
|
|
|
{
|
|
|
|
kdDebug()<<"void KPrPieObject::loadOasis(const TQDomElement &element) ***************\n";
|
|
|
|
KPr2DObject::loadOasis(element, context, info);
|
|
|
|
TQString kind = element.attributeNS( KoXmlNS::draw, "kind", TQString() );
|
|
|
|
if ( kind == "section" )
|
|
|
|
pieType = PT_PIE;
|
|
|
|
else if ( kind == "cut" )
|
|
|
|
pieType = PT_CHORD;
|
|
|
|
else if ( kind == "arc" )
|
|
|
|
pieType =PT_ARC;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
kdDebug()<<" KPrPieObject::loadOasis(const TQDomElement &element) type indefined :"<<kind<<endl;
|
|
|
|
pieType = PT_PIE;
|
|
|
|
}
|
|
|
|
kdDebug()<<" type of pie object :"<<( ( pieType == PT_PIE ) ? "pie" : ( pieType == PT_CHORD )?"cut" : "arc" )<<endl;
|
|
|
|
|
|
|
|
int start = (int) ( element.attributeNS( KoXmlNS::draw, "start-angle", TQString() ).toDouble() );
|
|
|
|
p_angle=start*16;
|
|
|
|
|
|
|
|
int end = (int) ( element.attributeNS( KoXmlNS::draw, "end-angle", TQString() ).toDouble() );
|
|
|
|
if ( end < start )
|
|
|
|
p_len = ( ( 360 - start + end ) * 16 );
|
|
|
|
else
|
|
|
|
p_len = ( ( end - start ) * 16 );
|
|
|
|
|
|
|
|
kdDebug()<<"KPrPieObject::loadOasis(const TQDomElement &element) : p_angle :"<<p_angle<<" p_len :"<<p_len<<endl;
|
|
|
|
if ( pieType == PT_ARC )
|
|
|
|
{
|
|
|
|
loadOasisMarkerElement( context, "marker-start", lineBegin );
|
|
|
|
loadOasisMarkerElement( context, "marker-end", lineEnd );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
double KPrPieObject::load(const TQDomElement &element)
|
|
|
|
{
|
|
|
|
double offset=KPr2DObject::load(element);
|
|
|
|
KPrStartEndLine::load( element );
|
|
|
|
TQDomElement e=element.namedItem("PIEANGLE").toElement();
|
|
|
|
if(!e.isNull()) {
|
|
|
|
int tmp=0;
|
|
|
|
if(e.hasAttribute("value"))
|
|
|
|
tmp=e.attribute("value").toInt();
|
|
|
|
p_angle=tmp;
|
|
|
|
}
|
|
|
|
e=element.namedItem("PIELENGTH").toElement();
|
|
|
|
if(!e.isNull()) {
|
|
|
|
int tmp=0;
|
|
|
|
if(e.hasAttribute("value"))
|
|
|
|
tmp=e.attribute("value").toInt();
|
|
|
|
p_len=tmp;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
p_len=1440; //necessary to reinitialise p_len
|
|
|
|
//I don't know who change default value
|
|
|
|
e=element.namedItem("PIETYPE").toElement();
|
|
|
|
if(!e.isNull()) {
|
|
|
|
int tmp=0;
|
|
|
|
if(e.hasAttribute("value"))
|
|
|
|
tmp=e.attribute("value").toInt();
|
|
|
|
pieType=static_cast<PieType>(tmp);
|
|
|
|
}
|
|
|
|
return offset;
|
|
|
|
}
|
|
|
|
|
|
|
|
void KPrPieObject::paint( TQPainter* _painter, KoTextZoomHandler*_zoomHandler,
|
|
|
|
int /* pageNum */, bool drawingShadow, bool drawContour )
|
|
|
|
{
|
|
|
|
double ow = ext.width();
|
|
|
|
double oh = ext.height();
|
|
|
|
double pw = ( ( pen.style() == TQt::NoPen ) ? 1 : pen.pointWidth() ) / 2.0;
|
|
|
|
|
|
|
|
if ( drawContour ) {
|
|
|
|
TQPen pen3( TQt::black, 1, TQt::DotLine );
|
|
|
|
_painter->setPen( pen3 );
|
|
|
|
_painter->setRasterOp( TQt::NotXorROP );
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
TQPen pen2 = pen.zoomedPen( _zoomHandler );
|
|
|
|
_painter->setPen( pen2 );
|
|
|
|
if ( drawingShadow || getFillType() == FT_BRUSH || !gradient )
|
|
|
|
{
|
|
|
|
_painter->setBrush( getBrush() );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ( pieType != PT_ARC )
|
|
|
|
{
|
|
|
|
TQSize size( _zoomHandler->zoomSize( ext ) );
|
|
|
|
|
|
|
|
if ( m_redrawGradientPix || gradient->size() != size )
|
|
|
|
{
|
|
|
|
m_redrawGradientPix = false;
|
|
|
|
gradient->setSize( size );
|
|
|
|
|
|
|
|
m_gradientPix.resize ( size );
|
|
|
|
m_gradientPix.fill( TQt::white );
|
|
|
|
TQPainter p;
|
|
|
|
p.begin( &m_gradientPix );
|
|
|
|
p.drawPixmap( 0, 0, gradient->pixmap() );
|
|
|
|
p.end();
|
|
|
|
|
|
|
|
TQBitmap mask( size, true );
|
|
|
|
p.begin( &mask );
|
|
|
|
p.setPen( TQPen( TQt::color1 ) );
|
|
|
|
p.setBrush( TQBrush( TQt::color1 ) );
|
|
|
|
if ( pieType == PT_CHORD )
|
|
|
|
{
|
|
|
|
p.drawChord( _zoomHandler->zoomItX(pw), _zoomHandler->zoomItY(pw),
|
|
|
|
_zoomHandler->zoomItX(ow - 2 * pw),
|
|
|
|
_zoomHandler->zoomItY(oh - 2 * pw), p_angle, p_len );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
p.drawPie( _zoomHandler->zoomItX(pw), _zoomHandler->zoomItY(pw),
|
|
|
|
_zoomHandler->zoomItX( ow - 2 * pw),
|
|
|
|
_zoomHandler->zoomItY( oh - 2 * pw), p_angle, p_len );
|
|
|
|
}
|
|
|
|
p.end();
|
|
|
|
m_gradientPix.setMask( mask );
|
|
|
|
}
|
|
|
|
_painter->drawPixmap( 0, 0, m_gradientPix, 0, 0, size.width(), size.height() );
|
|
|
|
_painter->setBrush( TQt::NoBrush );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( pieType == PT_ARC )
|
|
|
|
{
|
|
|
|
KoPointArray points( 2 );
|
|
|
|
setEndPoints( points );
|
|
|
|
KoPoint start( points.point( 0 ) );
|
|
|
|
KoPoint end( points.point( 1 ) );
|
|
|
|
|
|
|
|
double ys = ( ( 1 - start.x() / ( ext.width() * ext.width() / 4 ) ) * ext.height() * ext.height() / 4 ) / start.y();
|
|
|
|
double s_angle = 90 + ( atan( ( start.x() - 1 ) / ( start.y() - ys ) ) * 180 / M_PI );
|
|
|
|
if ( p_angle / 16 >= 90 && p_angle / 16 <= 270 )
|
|
|
|
{
|
|
|
|
s_angle += 180.0;
|
|
|
|
}
|
|
|
|
double ye = ( ( 1 - end.x() / ( ext.width() * ext.width() / 4 ) ) * ext.height() * ext.height() / 4 ) / end.y();
|
|
|
|
double e_angle = 270 + ( atan( ( end.x() - 1 ) / ( end.y() - ye ) ) * 180 / M_PI );
|
|
|
|
if ( ( ( p_angle + p_len ) / 16 ) % 360 >= 90 && ( ( p_angle + p_len ) / 16 ) % 360 <= 270 )
|
|
|
|
{
|
|
|
|
e_angle -= 180.0;
|
|
|
|
}
|
|
|
|
|
|
|
|
start = KoPoint( ext.width() / 2.0 + start.x(), ext.height() / 2.0 - start.y() );
|
|
|
|
end = KoPoint( ext.width() / 2.0 + end.x(), ext.height() / 2.0 - end.y() );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ( lineBegin != L_NORMAL )
|
|
|
|
drawFigureWithOffset( lineBegin, _painter, start,
|
|
|
|
pen2.color(), int( pen.pointWidth() ), s_angle, _zoomHandler, true );
|
|
|
|
|
|
|
|
if ( lineEnd != L_NORMAL )
|
|
|
|
drawFigureWithOffset( lineEnd, _painter, end,
|
|
|
|
pen2.color(), int( pen.pointWidth() ), e_angle, _zoomHandler, false );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
switch ( pieType )
|
|
|
|
{
|
|
|
|
case PT_PIE:
|
|
|
|
_painter->drawPie( _zoomHandler->zoomItX(pw), _zoomHandler->zoomItY( pw),
|
|
|
|
_zoomHandler->zoomItX( ow - 2 * pw),
|
|
|
|
_zoomHandler->zoomItY( oh - 2 * pw), p_angle, p_len );
|
|
|
|
break;
|
|
|
|
case PT_ARC:
|
|
|
|
_painter->drawArc( _zoomHandler->zoomItX(pw), _zoomHandler->zoomItY(pw),
|
|
|
|
_zoomHandler->zoomItX(ow - 2 * pw),
|
|
|
|
_zoomHandler->zoomItY(oh - 2 * pw), p_angle, p_len );
|
|
|
|
break;
|
|
|
|
case PT_CHORD:
|
|
|
|
_painter->drawChord( _zoomHandler->zoomItX(pw), _zoomHandler->zoomItY(pw),
|
|
|
|
_zoomHandler->zoomItX(ow - 2 * pw),
|
|
|
|
_zoomHandler->zoomItY(oh - 2 * pw), p_angle, p_len );
|
|
|
|
break;
|
|
|
|
default: break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void KPrPieObject::flip( bool horizontal )
|
|
|
|
{
|
|
|
|
KPr2DObject::flip( horizontal );
|
|
|
|
if ( ! horizontal )
|
|
|
|
{
|
|
|
|
p_angle = 360*16 - p_angle -p_len;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
p_angle = 180*16 - p_angle - p_len;
|
|
|
|
}
|
|
|
|
// angle smaller 0
|
|
|
|
while ( p_angle < 0 ) {
|
|
|
|
p_angle += 360*16;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void KPrPieObject::setMinMax( double &min_x, double &min_y,
|
|
|
|
double &max_x, double &max_y, KoPoint point ) const
|
|
|
|
{
|
|
|
|
double tmp_x = point.x();
|
|
|
|
double tmp_y = point.y();
|
|
|
|
|
|
|
|
if ( tmp_x < min_x ) {
|
|
|
|
min_x = tmp_x;
|
|
|
|
}
|
|
|
|
else if ( tmp_x > max_x ) {
|
|
|
|
max_x = tmp_x;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( tmp_y < min_y ) {
|
|
|
|
min_y = tmp_y;
|
|
|
|
}
|
|
|
|
else if ( tmp_y > max_y ) {
|
|
|
|
max_y = tmp_y;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The calculation of the real size and origin for a pie object is a little more
|
|
|
|
* complicated. It took me quite a whlie to get it right.
|
|
|
|
* Here is how it works:
|
|
|
|
* 1. calculate the position of the end points
|
|
|
|
* 2. calculate the 4 maximal points, the points with max x or y position, of the
|
|
|
|
* hole ellipse
|
|
|
|
* 3. find minimal and maximal points
|
|
|
|
* 4. check if the maximal points lie on the arc
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
void KPrPieObject::getRealSizeAndOrig( KoSize &size, KoPoint &realOrig ) const {
|
|
|
|
double radius1 = size.width() / 2.0;
|
|
|
|
double radius2 = size.height() / 2.0;
|
|
|
|
|
|
|
|
// the rotation angle
|
|
|
|
double angInRad = angle * M_PI / 180;
|
|
|
|
|
|
|
|
// 1. calulate position of end points
|
|
|
|
KoPointArray points(2);
|
|
|
|
setEndPoints( points );
|
|
|
|
|
|
|
|
// rotate point
|
|
|
|
for ( int i = 0; i < 2; i++ ) {
|
|
|
|
if ( angle != 0 ) {
|
|
|
|
double sinus = sin( angInRad );
|
|
|
|
double cosinus = cos( angInRad );
|
|
|
|
|
|
|
|
double tmp_x = points.point( i ).x();
|
|
|
|
double tmp_y = points.point( i ).y();
|
|
|
|
|
|
|
|
double x = tmp_x * cosinus + tmp_y * sinus;
|
|
|
|
double y = - tmp_x * sinus + tmp_y * cosinus;
|
|
|
|
points.setPoint( i, x, y );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
KoPoint firstPoint( points.point(0) );
|
|
|
|
KoPoint secondPoint( points.point(1) );
|
|
|
|
|
|
|
|
// 2. calulate maximal points
|
|
|
|
KoPointArray maxPoints(4);
|
|
|
|
if ( angle == 0 ) {
|
|
|
|
maxPoints.setPoint( 0, 0, radius2 );
|
|
|
|
maxPoints.setPoint( 1, radius1, 0 );
|
|
|
|
maxPoints.setPoint( 2, 0, -radius2 );
|
|
|
|
maxPoints.setPoint( 3, -radius1, 0 );
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
double sinus = sin( angInRad );
|
|
|
|
double cosinus = cos( angInRad );
|
|
|
|
|
|
|
|
double x = sqrt( pow( radius1 * cosinus , 2 ) + pow(radius2 * sinus, 2));
|
|
|
|
double y = ( pow( radius2, 2 ) - pow( radius1, 2) ) * sinus * cosinus / x;
|
|
|
|
maxPoints.setPoint( 0, x, y );
|
|
|
|
maxPoints.setPoint( 1, -x, -y );
|
|
|
|
|
|
|
|
y = sqrt( pow( radius1 * sinus , 2 ) + pow(radius2 * cosinus, 2));
|
|
|
|
x = ( pow( radius1, 2 ) - pow( radius2, 2) ) * sinus * cosinus / y;
|
|
|
|
maxPoints.setPoint( 2, x, y);
|
|
|
|
maxPoints.setPoint( 3, -x, -y );
|
|
|
|
}
|
|
|
|
|
|
|
|
// 3. find minimal and maximal points
|
|
|
|
double min_x = firstPoint.x();
|
|
|
|
double min_y = firstPoint.y();
|
|
|
|
double max_x = firstPoint.x();
|
|
|
|
double max_y = firstPoint.y();
|
|
|
|
|
|
|
|
if ( pieType == PT_PIE ) {
|
|
|
|
KoPoint zero(0,0);
|
|
|
|
setMinMax( min_x, min_y, max_x, max_y, zero );
|
|
|
|
}
|
|
|
|
setMinMax( min_x, min_y, max_x, max_y, secondPoint );
|
|
|
|
|
|
|
|
/* 4. check if maximal points lie on the arc.
|
|
|
|
* There are three posibilities how many sections have to
|
|
|
|
* been checked.
|
|
|
|
* 1. the arc is only once on one side of the x axis
|
|
|
|
* 2. the arc is on both sides of the x axis
|
|
|
|
* 3. the arc is twice on one one side of the x axis
|
|
|
|
*
|
|
|
|
* 1) 2) 3)
|
|
|
|
* y y y
|
|
|
|
* ex|xx xx|xs s |
|
|
|
|
* | x x | x | e
|
|
|
|
* | s x | x | x
|
|
|
|
* ----+---- x ----+---- x ----+---- x
|
|
|
|
* | x | x | x
|
|
|
|
* | x | x | x
|
|
|
|
* | e | xx|xx
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
if ( firstPoint.y() >= 0 ) {
|
|
|
|
if ( secondPoint.y() >= 0 ) {
|
|
|
|
if ( firstPoint.x() > secondPoint.x() || p_len == 0 ) {
|
|
|
|
// 1 section
|
|
|
|
// f.x() <= x <= s.x() && y >= 0
|
|
|
|
KoPointArray::ConstIterator it( maxPoints.begin() );
|
|
|
|
for ( ; it != maxPoints.end(); ++it ) {
|
|
|
|
if ( (*it).y() >= 0 &&
|
|
|
|
(*it).x() <= firstPoint.x() && (*it).x() >= secondPoint.x() )
|
|
|
|
{
|
|
|
|
setMinMax( min_x, min_y, max_x, max_y, *it );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// 3 sections
|
|
|
|
// x <= f.x() && y >= 0
|
|
|
|
// y < 0
|
|
|
|
// x >= s.x() && y >= 0
|
|
|
|
KoPointArray::ConstIterator it( maxPoints.begin() );
|
|
|
|
for ( ; it != maxPoints.end(); ++it ) {
|
|
|
|
if ( (*it).y() >= 0 ) {
|
|
|
|
if ( (*it).x() <= firstPoint.x() || (*it).x() >= secondPoint.x() ) {
|
|
|
|
setMinMax( min_x, min_y, max_x, max_y, *it );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
setMinMax( min_x, min_y, max_x, max_y, *it );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// 2 sections
|
|
|
|
// x <= f.x() && y >= 0
|
|
|
|
// x <= s.x() && y < 0
|
|
|
|
KoPointArray::ConstIterator it( maxPoints.begin() );
|
|
|
|
for ( ; it != maxPoints.end(); ++it ) {
|
|
|
|
if ( (*it).y() >= 0 ) {
|
|
|
|
if ( (*it).x() <= firstPoint.x() ) {
|
|
|
|
setMinMax( min_x, min_y, max_x, max_y, *it );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if ( (*it).x() <= secondPoint.x() ) {
|
|
|
|
setMinMax( min_x, min_y, max_x, max_y, *it );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if ( secondPoint.y() >= 0 ) {
|
|
|
|
// 2 sections
|
|
|
|
// x >= f.x() && y < 0
|
|
|
|
// x >= s.x() && y >= 0
|
|
|
|
KoPointArray::ConstIterator it( maxPoints.begin() );
|
|
|
|
for ( ; it != maxPoints.end(); ++it ) {
|
|
|
|
if ( (*it).y() < 0 ) {
|
|
|
|
if ( (*it).x() >= firstPoint.x() ) {
|
|
|
|
setMinMax( min_x, min_y, max_x, max_y, *it );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if ( (*it).x() >= secondPoint.x() ) {
|
|
|
|
setMinMax( min_x, min_y, max_x, max_y, *it );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if ( firstPoint.x() < secondPoint.x() || p_len == 0 ) {
|
|
|
|
// 1 section
|
|
|
|
// f.x() <= x <= s.x() && y < 0
|
|
|
|
KoPointArray::ConstIterator it( maxPoints.begin() );
|
|
|
|
for ( ; it != maxPoints.end(); ++it ) {
|
|
|
|
if ( (*it).y() < 0 &&
|
|
|
|
(*it).x() >= firstPoint.x() && (*it).x() <= secondPoint.x() )
|
|
|
|
{
|
|
|
|
setMinMax( min_x, min_y, max_x, max_y, *it );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// 3 sections
|
|
|
|
// x >= f.x() && y < 0
|
|
|
|
// y >= 0
|
|
|
|
// x <= s.x() && y < 0
|
|
|
|
KoPointArray::ConstIterator it( maxPoints.begin() );
|
|
|
|
for ( ; it != maxPoints.end(); ++it ) {
|
|
|
|
if ( (*it).y() < 0 ) {
|
|
|
|
if ( (*it).x() >= firstPoint.x() || (*it).x() <= secondPoint.x() ) {
|
|
|
|
setMinMax( min_x, min_y, max_x, max_y, *it );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
setMinMax( min_x, min_y, max_x, max_y, *it );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
double mid_x = size.width() / 2;
|
|
|
|
double mid_y = size.height() / 2;
|
|
|
|
|
|
|
|
size.setWidth( max_x - min_x );
|
|
|
|
size.setHeight( max_y - min_y );
|
|
|
|
|
|
|
|
realOrig.setX( realOrig.x() + mid_x + min_x );
|
|
|
|
realOrig.setY( realOrig.y() + mid_y - max_y );
|
|
|
|
}
|
|
|
|
|
|
|
|
void KPrPieObject::setEndPoints( KoPointArray &points ) const
|
|
|
|
{
|
|
|
|
int angles[] = { p_angle, ( p_angle + p_len ) % ( 16 * 360 ) };
|
|
|
|
double anglesInRad[] = { p_angle / 16.0 * M_PI / 180, ( angles[1] ) / 16.0 * M_PI / 180 };
|
|
|
|
|
|
|
|
double radius1 = ext.width() / 2.0;
|
|
|
|
double radius2 = ext.height() / 2.0;
|
|
|
|
|
|
|
|
double prop = radius2 / radius1;
|
|
|
|
|
|
|
|
for ( int i = 0; i < 2; i++ ) {
|
|
|
|
double x = 0;
|
|
|
|
double y = 0;
|
|
|
|
|
|
|
|
// be carefull
|
|
|
|
if ( angles[i] == 90 * 16 ) {
|
|
|
|
y = radius2;
|
|
|
|
}
|
|
|
|
else if ( angles[i] == 270 * 16 ) {
|
|
|
|
y = -radius2;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// The real angle is not what was given. It is only ok if radius1 == radius2,
|
|
|
|
// otherwise it is arctan ( radius2 / radius1 tan ( angle ) )
|
|
|
|
double tanalpha = tan( anglesInRad[i] ) * prop;
|
|
|
|
x = sqrt( 1 / ( pow ( 1 / radius1, 2 ) + pow( tanalpha / radius2, 2 ) ) );
|
|
|
|
if ( angles[i] > 90 * 16 && angles[i] < 270 * 16 )
|
|
|
|
x = -x;
|
|
|
|
y = tanalpha * x;
|
|
|
|
}
|
|
|
|
points.setPoint( i, x, y );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
KoSize KPrPieObject::getRealSize() const {
|
|
|
|
KoSize size( ext );
|
|
|
|
KoPoint realOrig( orig );
|
|
|
|
getRealSizeAndOrig( size, realOrig );
|
|
|
|
return size;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
KoPoint KPrPieObject::getRealOrig() const {
|
|
|
|
KoSize size( ext );
|
|
|
|
KoPoint realOrig( orig );
|
|
|
|
getRealSizeAndOrig( size, realOrig );
|
|
|
|
return realOrig;
|
|
|
|
}
|