nss: upgrade to release 3.73
[LibreOffice.git] / filter / source / graphicfilter / icgm / class4.cxx
blob18eff3452451f4aabbcb89fb534bf258dc683e77
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "bitmap.hxx"
22 #include "cgm.hxx"
23 #include "chart.hxx"
24 #include "elements.hxx"
25 #include "outact.hxx"
27 #include <o3tl/safeint.hxx>
29 #include <math.h>
30 #include <memory>
32 using namespace ::com::sun::star;
34 double CGM::ImplGetOrientation( FloatPoint const & rCenter, FloatPoint const & rPoint )
36 double nX = rPoint.X - rCenter.X;
37 double nY = rPoint.Y - rCenter.Y;
39 double fSqrt = sqrt(nX * nX + nY * nY);
40 double fOrientation = fSqrt != 0.0 ? (acos(nX / fSqrt) * 57.29577951308) : 0.0;
41 if (nY > 0)
42 fOrientation = 360 - fOrientation;
44 return fOrientation;
48 void CGM::ImplSwitchStartEndAngle( double& rStartAngle, double& rEndAngle )
50 double nTemp;
51 nTemp = rStartAngle;
52 rStartAngle = rEndAngle;
53 rEndAngle = nTemp;
57 void CGM::ImplGetVector( double* pVector )
59 if ( pElement->eVDCType == VDC_REAL )
61 for ( sal_uInt32 i = 0; i < 4; i++ )
63 pVector[ i ] = ImplGetFloat( pElement->eVDCRealPrecision, pElement->nVDCRealSize );
66 else
68 for ( sal_uInt32 i = 0; i < 4; i++ )
70 pVector[ i ] = static_cast<double>(ImplGetI( pElement->nVDCIntegerPrecision ));
73 pVector[ 0 ] *= mnVDCXmul;
74 pVector[ 2 ] *= mnVDCXmul;
75 pVector[ 1 ] *= mnVDCYmul;
76 pVector[ 3 ] *= mnVDCYmul;
80 bool CGM::ImplGetEllipse( FloatPoint& rCenter, FloatPoint& rRadius, double& rAngle )
82 FloatPoint aPoint1, aPoint2;
83 double fRot1, fRot2;
84 ImplGetPoint( rCenter, true );
85 ImplGetPoint( aPoint1, true );
86 ImplGetPoint( aPoint2, true );
87 fRot1 = ImplGetOrientation( rCenter, aPoint1 );
88 fRot2 = ImplGetOrientation( rCenter, aPoint2 );
89 rAngle = ImplGetOrientation( rCenter, aPoint1 );
90 aPoint1.X -= rCenter.X;
91 aPoint1.Y -= rCenter.Y;
92 rRadius.X = sqrt( aPoint1.X * aPoint1.X + aPoint1.Y * aPoint1.Y );
93 aPoint2.X -= rCenter.X;
94 aPoint2.Y -= rCenter.Y;
95 rRadius.Y = sqrt( aPoint2.X * aPoint2.X + aPoint2.Y * aPoint2.Y );
97 if ( fRot1 > fRot2 )
99 if ( ( fRot1 - fRot2 ) < 180 )
100 return false;
102 else
104 if ( ( fRot2 - fRot1 ) > 180 )
105 return false;
107 return true;
110 void CGM::ImplDoClass4()
112 if ( mbFirstOutPut )
113 mpOutAct->FirstOutPut();
115 if ( mpBitmapInUse && ( mnElementID != 9 ) ) // process existed graphic
116 { // because there are now no pending bitmap actions
117 CGMBitmapDescriptor* pBmpDesc = mpBitmapInUse->GetBitmap();
118 // do anything with the bitmap
119 mpOutAct->DrawBitmap( pBmpDesc );
120 mpBitmapInUse.reset();
123 if ( ( mpChart == nullptr ) || mpChart->IsAnnotation() )
125 switch ( mnElementID )
127 case 0x01 : /*PolyLine*/
129 sal_uInt32 nPoints = mnElementSize / ImplGetPointSize();
130 tools::Polygon aPolygon( static_cast<sal_uInt16>(nPoints) );
131 for ( sal_uInt32 i = 0; i < nPoints; i++)
133 FloatPoint aFloatPoint;
134 ImplGetPoint( aFloatPoint, true );
135 aPolygon.SetPoint( Point( static_cast<tools::Long>(aFloatPoint.X), static_cast<tools::Long>(aFloatPoint.Y) ), i );
137 if ( mbFigure )
138 mpOutAct->RegPolyLine( aPolygon );
139 else
140 mpOutAct->DrawPolyLine( aPolygon );
142 break;
144 case 0x02 : /*Disjoint PolyLine*/
146 sal_uInt16 nPoints = sal::static_int_cast< sal_uInt16 >(
147 mnElementSize / ImplGetPointSize());
148 if ( ! ( nPoints & 1 ) )
150 nPoints >>= 1;
151 FloatPoint aFloatPoint;
152 if ( mbFigure )
154 tools::Polygon aPolygon( nPoints );
155 for ( sal_uInt16 i = 0; i < nPoints; i++ )
157 ImplGetPoint( aFloatPoint, true );
158 aPolygon.SetPoint( Point( static_cast<tools::Long>(aFloatPoint.X), static_cast<tools::Long>(aFloatPoint.Y) ), 0 );
160 mpOutAct->RegPolyLine( aPolygon );
162 else
164 mpOutAct->BeginGroup();
165 tools::Polygon aPolygon( sal_uInt16(2) );
166 for ( sal_uInt16 i = 0; i < nPoints; i++ )
168 ImplGetPoint( aFloatPoint, true );
169 aPolygon.SetPoint( Point( static_cast<tools::Long>(aFloatPoint.X), static_cast<tools::Long>(aFloatPoint.Y) ), 0 );
170 ImplGetPoint( aFloatPoint, true );
171 aPolygon.SetPoint( Point( static_cast<tools::Long>(aFloatPoint.X), static_cast<tools::Long>(aFloatPoint.Y) ), 1);
172 mpOutAct->DrawPolyLine( aPolygon );
174 mpOutAct->EndGroup();
178 break;
180 case 0x03 : /*PolyMarker*/ break;
181 case 0x04 : /*Text*/
183 FloatPoint aFloatPoint;
185 if ( mbFigure )
186 mpOutAct->CloseRegion();
188 ImplGetPoint ( aFloatPoint, true );
189 sal_uInt32 nType = ImplGetUI16();
190 sal_uInt32 nSize = ImplGetUI( 1 );
192 if (o3tl::make_unsigned(mpEndValidSource - (mpSource + mnParaSize)) < nSize)
193 throw css::uno::Exception("attempt to read past end of input", nullptr);
195 OUString aStr(reinterpret_cast<char*>(mpSource) + mnParaSize, nSize, RTL_TEXTENCODING_ASCII_US);
197 awt::Size aSize;
198 awt::Point aPoint( static_cast<tools::Long>(aFloatPoint.X), static_cast<tools::Long>(aFloatPoint.Y) );
199 mpOutAct->DrawText(aPoint, aSize, aStr, static_cast<FinalFlag>(nType));
200 mnParaSize = mnElementSize;
202 break;
204 case 0x05 : /*Restricted Text*/
206 double dx, dy;
207 FloatPoint aFloatPoint;
209 if ( mbFigure )
210 mpOutAct->CloseRegion();
212 if ( pElement->eVDCType == VDC_REAL )
214 dx = ImplGetFloat( pElement->eVDCRealPrecision, pElement->nVDCRealSize );
215 dy = ImplGetFloat( pElement->eVDCRealPrecision, pElement->nVDCRealSize );
217 else
219 dx = static_cast<double>(ImplGetI( pElement->nVDCIntegerPrecision ));
220 dy = static_cast<double>(ImplGetI( pElement->nVDCIntegerPrecision ));
222 ImplMapDouble( dx );
223 ImplMapDouble( dy );
225 ImplGetPoint ( aFloatPoint, true );
226 sal_uInt32 nType = ImplGetUI16();
227 sal_uInt32 nSize = ImplGetUI(1);
229 if (o3tl::make_unsigned(mpEndValidSource - (mpSource + mnParaSize)) < nSize)
230 throw css::uno::Exception("attempt to read past end of input", nullptr);
232 OUString aStr(reinterpret_cast<char*>(mpSource) + mnParaSize, nSize, RTL_TEXTENCODING_ASCII_US);
234 awt::Point aPoint( static_cast<tools::Long>(aFloatPoint.X), static_cast<tools::Long>(aFloatPoint.Y) );
235 awt::Size aSize(static_cast<tools::Long>(dx), static_cast<tools::Long>(dy));
236 mpOutAct->DrawText(aPoint, aSize , aStr, static_cast<FinalFlag>(nType));
237 mnParaSize = mnElementSize;
239 break;
241 case 0x06 : /*Append Text*/
243 (void)ImplGetUI16(); // nType
244 sal_uInt32 nSize = ImplGetUI( 1 );
246 if (o3tl::make_unsigned(mpEndValidSource - (mpSource + mnParaSize)) <= nSize)
247 throw css::uno::Exception("attempt to read past end of input", nullptr);
249 mpSource[ mnParaSize + nSize ] = 0;
251 mpOutAct->AppendText( reinterpret_cast<char*>(mpSource) + mnParaSize );
252 mnParaSize = mnElementSize;
254 break;
256 case 0x07 : /*Polygon*/
258 if ( mbFigure )
259 mpOutAct->CloseRegion();
261 sal_uInt16 nPoints = sal::static_int_cast< sal_uInt16 >(
262 mnElementSize / ImplGetPointSize());
263 tools::Polygon aPolygon( nPoints );
264 for ( sal_uInt16 i = 0; i < nPoints; i++)
266 FloatPoint aFloatPoint;
267 ImplGetPoint( aFloatPoint, true );
268 aPolygon.SetPoint( Point ( static_cast<tools::Long>( aFloatPoint.X ), static_cast<tools::Long>( aFloatPoint.Y ) ), i );
270 mpOutAct->DrawPolygon( aPolygon );
272 break;
274 case 0x08 : /*Polygon Set*/
276 if ( mbFigure )
277 mpOutAct->CloseRegion();
279 sal_uInt16 nPoints = 0;
280 std::unique_ptr<Point[]> pPoints(new Point[ 0x4000 ]);
282 tools::PolyPolygon aPolyPolygon;
283 FloatPoint aFloatPoint;
284 sal_uInt32 nEdgeFlag;
285 while ( mnParaSize < mnElementSize )
287 ImplGetPoint( aFloatPoint, true );
288 nEdgeFlag = ImplGetUI16();
289 pPoints[ nPoints++ ] = Point( static_cast<tools::Long>(aFloatPoint.X), static_cast<tools::Long>(aFloatPoint.Y) );
290 if ( ( nEdgeFlag & 2 ) || ( mnParaSize == mnElementSize ) )
292 tools::Polygon aPolygon( nPoints );
293 for ( sal_uInt16 i = 0; i < nPoints; i++ )
295 aPolygon.SetPoint( pPoints[ i ], i );
297 aPolyPolygon.Insert( aPolygon );
298 nPoints = 0;
301 pPoints.reset();
302 mpOutAct->DrawPolyPolygon( aPolyPolygon );
304 break;
306 case 0x09 : /*Cell Array*/
308 if ( mbFigure )
309 mpOutAct->CloseRegion();
311 if ( mpBitmapInUse )
313 std::unique_ptr<CGMBitmap> xBmpDesc(mpBitmapInUse->GetNext());
314 if (xBmpDesc) // we possibly get a bitmap back which does not fit to
315 { // to the previous -> we need to delete this one too
316 mpOutAct->DrawBitmap(xBmpDesc->GetBitmap());
319 else
321 mpBitmapInUse.reset( new CGMBitmap( *this ) );
324 break;
326 case 0x0a : /*Generalized Drawing Primitive*/
328 ImplGetI( pElement->nIntegerPrecision ); //-Wall is this needed
329 ImplGetUI( pElement->nIntegerPrecision ); //-Wall is this needed
330 mnParaSize = mnElementSize;
332 break;
334 case 0x0b : /*Rectangle*/
336 if ( mbFigure )
337 mpOutAct->CloseRegion();
339 FloatRect aFloatRect;
340 ImplGetRectangle( aFloatRect, true );
341 mpOutAct->DrawRectangle( aFloatRect );
343 break;
345 case 0x0c : /*Circle*/
347 if ( mbFigure )
348 mpOutAct->CloseRegion();
350 double fRotation = 0;
351 FloatPoint aCenter, aRadius;
352 ImplGetPoint( aCenter, true );
353 if ( pElement->eVDCType == VDC_REAL )
354 aRadius.X = ImplGetFloat( pElement->eVDCRealPrecision, pElement->nVDCRealSize );
355 else
356 aRadius.X = static_cast<double>(ImplGetI( pElement->nVDCIntegerPrecision ));
357 ImplMapDouble( aRadius.X );
358 aRadius.Y = aRadius.X;
359 mpOutAct->DrawEllipse( aCenter, aRadius, fRotation );
361 break;
363 case 0x0d : /*Circular Arc 3 Point*/
365 FloatPoint aStartingPoint, aIntermediatePoint, aEndingPoint;
366 ImplGetPoint( aStartingPoint, true );
367 ImplGetPoint( aIntermediatePoint, true );
368 ImplGetPoint( aEndingPoint, true );
370 double fA = aIntermediatePoint.X - aStartingPoint.X;
371 double fB = aIntermediatePoint.Y - aStartingPoint.Y;
372 double fC = aEndingPoint.X - aStartingPoint.X;
373 double fD = aEndingPoint.Y - aStartingPoint.Y;
375 double fE = fA * ( aStartingPoint.X + aIntermediatePoint.X ) + fB * ( aStartingPoint.Y + aIntermediatePoint.Y );
376 double fF = fC * ( aStartingPoint.X + aEndingPoint.X ) + fD * ( aStartingPoint.Y + aEndingPoint.Y );
378 double fG = 2.0 * ( fA * ( aEndingPoint.Y - aIntermediatePoint.Y ) - fB * ( aEndingPoint.X - aIntermediatePoint.X ) );
380 if ( fG != 0 )
382 FloatPoint aCenterPoint;
383 aCenterPoint.X = ( fD * fE - fB * fF ) / fG;
384 aCenterPoint.Y = ( fA * fF - fC * fE ) / fG;
385 double fStartAngle = ImplGetOrientation( aCenterPoint, aStartingPoint );
386 double fInterAngle = ImplGetOrientation( aCenterPoint, aIntermediatePoint );
387 double fEndAngle = ImplGetOrientation( aCenterPoint, aEndingPoint );
389 int nSwitch = 0;
391 if ( fStartAngle > fEndAngle )
393 nSwitch ^=1;
394 aIntermediatePoint = aEndingPoint;
395 aEndingPoint = aStartingPoint;
396 aStartingPoint = aIntermediatePoint;
397 fG = fStartAngle;
398 fStartAngle = fEndAngle;
399 fEndAngle = fG;
401 if ( ! ( fInterAngle > fStartAngle ) && ( fInterAngle < fEndAngle ) )
403 nSwitch ^=1;
404 aIntermediatePoint = aEndingPoint;
405 aEndingPoint = aStartingPoint;
406 aStartingPoint = aIntermediatePoint;
407 fG = fStartAngle;
408 fStartAngle = fEndAngle;
409 fEndAngle = fG;
411 double fRadius = sqrt( pow( ( aStartingPoint.X - aCenterPoint.X ), 2 ) + pow( ( aStartingPoint.Y - aCenterPoint.Y ), 2 ) ) ;
413 if ( mbFigure )
415 tools::Rectangle aBoundingBox(aCenterPoint.X - fRadius, aCenterPoint.Y - fRadius);
416 aBoundingBox.SaturatingSetSize(Size(2 * fRadius, 2 * fRadius));
417 tools::Polygon aPolygon( aBoundingBox, Point( static_cast<tools::Long>(aStartingPoint.X), static_cast<tools::Long>(aStartingPoint.Y) ) ,Point( static_cast<tools::Long>(aEndingPoint.X), static_cast<tools::Long>(aEndingPoint.Y) ), PolyStyle::Arc );
418 if ( nSwitch )
419 mpOutAct->RegPolyLine( aPolygon, true );
420 else
421 mpOutAct->RegPolyLine( aPolygon );
423 else
425 fG = 0;
426 FloatPoint aRadius;
427 aRadius.X = aRadius.Y = fRadius;
428 mpOutAct->DrawEllipticalArc( aCenterPoint, aRadius, fG, 2, fStartAngle, fEndAngle );
432 break;
434 case 0x0e : /*Circular Arc 3 Point Close*/
436 if ( mbFigure )
437 mpOutAct->CloseRegion();
439 FloatPoint aStartingPoint, aIntermediatePoint, aEndingPoint;
440 ImplGetPoint( aStartingPoint );
441 ImplGetPoint( aIntermediatePoint );
442 ImplGetPoint( aEndingPoint );
444 double fA = aIntermediatePoint.X - aStartingPoint.X;
445 double fB = aIntermediatePoint.Y - aStartingPoint.Y;
446 double fC = aEndingPoint.X - aStartingPoint.X;
447 double fD = aEndingPoint.Y - aStartingPoint.Y;
449 double fE = fA * ( aStartingPoint.X + aIntermediatePoint.X ) + fB * ( aStartingPoint.Y + aIntermediatePoint.Y );
450 double fF = fC * ( aStartingPoint.X + aEndingPoint.X ) + fD * ( aStartingPoint.Y + aEndingPoint.Y );
452 double fG = 2.0 * ( fA * ( aEndingPoint.Y - aIntermediatePoint.Y ) - fB * ( aEndingPoint.X - aIntermediatePoint.X ) );
454 if ( fG != 0 )
456 FloatPoint aCenterPoint;
457 aCenterPoint.X = ( fD * fE - fB * fF ) / fG;
458 aCenterPoint.Y = ( fA * fF - fC * fE ) / fG;
459 double fStartAngle = ImplGetOrientation( aCenterPoint, aStartingPoint );
460 double fInterAngle = ImplGetOrientation( aCenterPoint, aIntermediatePoint );
461 double fEndAngle = ImplGetOrientation( aCenterPoint, aEndingPoint );
463 if ( fStartAngle > fEndAngle )
465 aIntermediatePoint = aEndingPoint;
466 aEndingPoint = aStartingPoint;
467 aStartingPoint = aIntermediatePoint;
468 fG = fStartAngle;
469 fStartAngle = fEndAngle;
470 fEndAngle = fG;
472 if ( ! ( fInterAngle > fStartAngle ) && ( fInterAngle < fEndAngle ) )
474 aIntermediatePoint = aEndingPoint;
475 aEndingPoint = aStartingPoint;
476 aStartingPoint = aIntermediatePoint;
477 fG = fStartAngle;
478 fStartAngle = fEndAngle;
479 fEndAngle = fG;
481 FloatPoint fRadius;
482 fRadius.Y = fRadius.X = sqrt( pow( ( aStartingPoint.X - aCenterPoint.X ), 2 ) + pow( ( aStartingPoint.Y - aCenterPoint.Y ), 2 ) ) ;
484 sal_uInt32 nType = ImplGetUI16();
485 if ( nType == 0 )
486 nType = 0; // is PIE
487 else
488 nType = 1; // is CHORD
490 double fOrientation = 0;
491 mpOutAct->DrawEllipticalArc( aCenterPoint, fRadius, fOrientation, nType, fStartAngle, fEndAngle );
494 break;
496 case 0x0f : /*Circular Arc Centre*/
498 double fStartAngle, fEndAngle, vector[ 4 ];
499 FloatPoint aCenter, aRadius;
501 if ( mbFigure )
502 mpOutAct->CloseRegion();
504 ImplGetPoint( aCenter, true );
505 ImplGetVector( &vector[ 0 ] );
507 if ( pElement->eVDCType == VDC_REAL )
509 aRadius.X = ImplGetFloat( pElement->eVDCRealPrecision, pElement->nVDCRealSize );
511 else
513 aRadius.X = static_cast<double>(ImplGetI( pElement->nVDCIntegerPrecision ));
516 ImplMapDouble( aRadius.X );
517 aRadius.Y = aRadius.X;
519 const double fStartSqrt = sqrt(vector[0] * vector[ 0 ] + vector[1] * vector[1]);
520 fStartAngle = fStartSqrt != 0.0 ? (acos(vector[0] / fStartSqrt) * 57.29577951308) : 0.0;
521 const double fEndSqrt = sqrt(vector[2] * vector[ 2 ] + vector[3] * vector[3]);
522 fEndAngle = fEndSqrt != 0.0 ? (acos(vector[ 2 ] / fEndSqrt) * 57.29577951308) : 0.0;
524 if ( vector[ 1 ] > 0 )
525 fStartAngle = 360 - fStartAngle;
526 if ( vector[ 3 ] > 0 )
527 fEndAngle = 360 - fEndAngle;
529 if ( mbAngReverse )
530 ImplSwitchStartEndAngle( fStartAngle, fEndAngle );
532 if ( mbFigure )
534 tools::Rectangle aBoundingBox(aCenter.X - aRadius.X, aCenter.Y - aRadius.X);
535 aBoundingBox.SaturatingSetSize(Size(2 * aRadius.X, 2 * aRadius.X));
536 tools::Polygon aPolygon( aBoundingBox,
537 Point( static_cast<tools::Long>(vector[ 0 ]), static_cast<tools::Long>(vector[ 1 ]) ),
538 Point( static_cast<tools::Long>(vector[ 2 ]), static_cast<tools::Long>(vector[ 3 ]) ), PolyStyle::Arc );
539 mpOutAct->RegPolyLine( aPolygon );
541 else
543 double fOrientation = 0;
544 mpOutAct->DrawEllipticalArc( aCenter, aRadius, fOrientation, 2, fStartAngle, fEndAngle );
546 mnParaSize = mnElementSize;
549 break;
551 case 0x10 : /*Circular Arc Centre Close*/
553 double fOrientation, vector[ 4 ];
554 FloatPoint aCenter, aRadius;
556 if ( mbFigure )
557 mpOutAct->CloseRegion();
559 ImplGetPoint( aCenter, true );
560 ImplGetVector( &vector[ 0 ] );
561 if ( pElement->eVDCType == VDC_REAL )
563 aRadius.X = ImplGetFloat( pElement->eVDCRealPrecision, pElement->nVDCRealSize );
565 else
567 aRadius.X = static_cast<double>(ImplGetI( pElement->nVDCIntegerPrecision ));
569 ImplMapDouble( aRadius.X );
570 aRadius.Y = aRadius.X;
571 const double fStartSqrt = sqrt(vector[0] * vector[0] + vector[1] * vector[1]);
572 double fStartAngle = fStartSqrt ? (acos(vector[0] / fStartSqrt) * 57.29577951308) : 0.0;
573 const double fEndSqrt = sqrt(vector[2] * vector[2] + vector[3] * vector[3]);
574 double fEndAngle = fEndSqrt ? acos(vector[2] / fEndSqrt) * 57.29577951308 : 0.0;
576 if ( vector[ 1 ] > 0 )
577 fStartAngle = 360 - fStartAngle;
578 if ( vector[ 3 ] > 0 )
579 fEndAngle = 360 - fEndAngle;
581 if ( mbAngReverse )
582 ImplSwitchStartEndAngle( fStartAngle, fEndAngle );
585 sal_uInt32 nType = ImplGetUI16();
586 if ( nType == 0 )
587 nType = 0; // is PIE
588 else
589 nType = 1; // is CHORD
590 fOrientation = 0;
592 mpOutAct->DrawEllipticalArc( aCenter, aRadius, fOrientation,
593 nType, fStartAngle, fEndAngle );
594 mnParaSize = mnElementSize;
596 break;
598 case 0x11 : /*Ellipse*/
600 double fOrientation;
601 FloatPoint aCenter, aRadius;
603 if ( mbFigure )
604 mpOutAct->CloseRegion();
606 ImplGetEllipse( aCenter, aRadius, fOrientation ) ;
607 mpOutAct->DrawEllipse( aCenter, aRadius, fOrientation ) ;
609 break;
611 case 0x12 : /*Elliptical Arc*/
613 if ( mbFigure )
614 mpOutAct->CloseRegion();
616 double fOrientation, fStartAngle, fEndAngle, vector[ 4 ];
617 FloatPoint aCenter, aRadius;
619 if ( mbFigure )
620 mpOutAct->CloseRegion();
622 bool bDirection = ImplGetEllipse( aCenter, aRadius, fOrientation );
623 ImplGetVector( &vector[ 0 ] );
625 double fStartSqrt = sqrt(vector[0] * vector[0] + vector[1] * vector[1]);
626 fStartAngle = fStartSqrt ? (acos(vector[0] / fStartSqrt) * 57.29577951308) : 0.0;
627 double fEndSqrt = sqrt(vector[2] * vector[2] + vector[3] * vector[3]);
628 fEndAngle = fEndSqrt ? (acos(vector[2] / fEndSqrt) * 57.29577951308) : 0.0;
630 if ( vector[ 1 ] > 0 )
631 fStartAngle = 360 - fStartAngle;
632 if ( vector[ 3 ] > 0 )
633 fEndAngle = 360 - fEndAngle;
635 if ( bDirection )
636 mpOutAct->DrawEllipticalArc( aCenter, aRadius, fOrientation,
637 2, fStartAngle, fEndAngle );
638 else
639 mpOutAct->DrawEllipticalArc( aCenter, aRadius, fOrientation,
640 2, fEndAngle, fStartAngle);
642 break;
644 case 0x13 : /*Elliptical Arc Close*/
646 double fOrientation, fStartAngle, fEndAngle, vector[ 4 ];
647 FloatPoint aCenter, aRadius;
649 if ( mbFigure )
650 mpOutAct->CloseRegion();
652 bool bDirection = ImplGetEllipse( aCenter, aRadius, fOrientation );
653 ImplGetVector( &vector[ 0 ] );
655 double fStartSqrt = sqrt(vector[0] * vector[0] + vector[1] * vector[1]);
656 fStartAngle = fStartSqrt ? (acos(vector[0] / fStartSqrt) * 57.29577951308) : 0.0;
657 double fEndSqrt = sqrt(vector[2] * vector[2] + vector[3] * vector[3]);
658 fEndAngle = fEndSqrt ? (acos(vector[2] / fEndSqrt) * 57.29577951308) : 0.0;
660 if ( vector[ 1 ] > 0 )
661 fStartAngle = 360 - fStartAngle;
662 if ( vector[ 3 ] > 0 )
663 fEndAngle = 360 - fEndAngle;
665 sal_uInt32 nType = ImplGetUI16();
666 if ( nType == 0 )
667 nType = 0; // is PIE
668 else
669 nType = 1; // is CHORD
671 if ( bDirection )
672 mpOutAct->DrawEllipticalArc( aCenter, aRadius, fOrientation,
673 nType, fStartAngle, fEndAngle );
674 else
675 mpOutAct->DrawEllipticalArc( aCenter, aRadius, fOrientation,
676 nType, fEndAngle, fStartAngle);
678 break;
679 case 0x14 : /*Circular Arc Centre Reversed*/
681 if ( mbFigure )
682 mpOutAct->CloseRegion();
684 break;
685 case 0x15 : /*Connection Edge */ // NS
687 // if ( mbFigure )
688 // mpOutAct->CloseRegion();
690 break;
691 case 0x16 : /*Hyperbolic Arc */ // NS
693 if ( mbFigure )
694 mpOutAct->CloseRegion();
696 break;
697 case 0x17 : /*Parabolic Arc */ // NS
699 if ( mbFigure )
700 mpOutAct->CloseRegion();
702 break;
703 case 0x18 : /*Non Uniform B-Spline */ // NS
705 if ( mbFigure )
706 mpOutAct->CloseRegion();
708 break;
709 case 0x19 : /*Non Uniform Rational B-Spline */ // NS
711 if ( mbFigure )
712 mpOutAct->CloseRegion();
714 break;
715 case 0x1a : /*Polybezier*/
717 sal_uInt32 nOrder = ImplGetI( pElement->nIntegerPrecision );
719 sal_uInt16 nNumberOfPoints = sal::static_int_cast< sal_uInt16 >(( mnElementSize - pElement->nIntegerPrecision ) / ImplGetPointSize());
721 tools::Polygon aPolygon( nNumberOfPoints );
723 for ( sal_uInt16 i = 0; i < nNumberOfPoints; i++)
725 FloatPoint aFloatPoint;
726 ImplGetPoint( aFloatPoint, true );
727 aPolygon.SetPoint( Point ( static_cast<tools::Long>( aFloatPoint.X ), static_cast<tools::Long>( aFloatPoint.Y ) ), i );
729 if ( nOrder & 4 )
731 for ( sal_uInt16 i = 0; i < nNumberOfPoints; i++ )
733 if ( ( i % 3 ) == 0 )
734 aPolygon.SetFlags( i, PolyFlags::Normal );
735 else
736 aPolygon.SetFlags( i, PolyFlags::Control );
739 else
741 for ( sal_uInt16 i = 0; i < nNumberOfPoints; i++ )
743 switch ( i & 3 )
745 case 0 :
746 case 3 : aPolygon.SetFlags( i, PolyFlags::Normal ); break;
747 default : aPolygon.SetFlags( i, PolyFlags::Control ); break;
751 if ( mbFigure )
752 mpOutAct->RegPolyLine( aPolygon );
753 else
754 mpOutAct->DrawPolybezier( aPolygon );
755 mnParaSize = mnElementSize;
757 break;
759 case 0x1b : /*Polysymbol */ // NS
761 if ( mbFigure )
762 mpOutAct->CloseRegion();
764 break;
765 case 0x1c : /*Bitonal Tile */ // NS
767 if ( mbFigure )
768 mpOutAct->CloseRegion();
770 break;
771 case 0x1d : /*Tile */ // NS
773 if ( mbFigure )
774 mpOutAct->CloseRegion();
776 break;
777 case 0x1e : /*Insert Object*/
779 if ( mbFigure )
780 mpOutAct->CloseRegion();
782 break;
783 case 0xff : /*Polybezier*/
785 if ( mbFigure )
786 mpOutAct->CloseRegion();
788 break;
789 case 0xfe : /*Sharp Polybezier*/
791 if ( mbFigure )
792 mpOutAct->CloseRegion();
794 break;
795 case 0xfd : /*Polyspline*/
797 if ( mbFigure )
798 mpOutAct->CloseRegion();
800 break;
801 case 0xfc : /*Rounded Rectangle*/
803 if ( mbFigure )
804 mpOutAct->CloseRegion();
806 break;
807 case 0xfb : /*Begin Cell Array*/
809 if ( mbFigure )
810 mpOutAct->CloseRegion();
812 break;
813 case 0xfa : /*End Cell Array*/
815 if ( mbFigure )
816 mpOutAct->CloseRegion();
818 break;
819 case 0xf9 : /*Insert File*/
821 if ( mbFigure )
822 mpOutAct->CloseRegion();
824 break;
825 case 0xf8 : /*Block Text*/
827 if ( mbFigure )
828 mpOutAct->CloseRegion();
830 break;
831 case 0xf7 : /*Variable Width Polyline*/
833 if ( mbFigure )
834 mpOutAct->CloseRegion();
836 break;
837 case 0xf6 : /*Elliptical Arc 3 Point*/
839 if ( mbFigure )
840 mpOutAct->CloseRegion();
842 break;
843 case 0xf1 : /*Hyperlink Definition */break;
844 default: break;
847 else
848 mnParaSize = mnElementSize;
852 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */