1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
24 #include "elements.hxx"
27 #include <o3tl/safeint.hxx>
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;
42 fOrientation
= 360 - fOrientation
;
48 void CGM::ImplSwitchStartEndAngle( double& rStartAngle
, double& rEndAngle
)
52 rStartAngle
= rEndAngle
;
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
);
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
;
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
);
99 if ( ( fRot1
- fRot2
) < 180 )
104 if ( ( fRot2
- fRot1
) > 180 )
110 void CGM::ImplDoClass4()
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
);
138 mpOutAct
->RegPolyLine( aPolygon
);
140 mpOutAct
->DrawPolyLine( aPolygon
);
144 case 0x02 : /*Disjoint PolyLine*/
146 sal_uInt16 nPoints
= sal::static_int_cast
< sal_uInt16
>(
147 mnElementSize
/ ImplGetPointSize());
148 if ( ! ( nPoints
& 1 ) )
151 FloatPoint aFloatPoint
;
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
);
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();
180 case 0x03 : /*PolyMarker*/ break;
183 FloatPoint aFloatPoint
;
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
);
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
;
204 case 0x05 : /*Restricted Text*/
207 FloatPoint aFloatPoint
;
210 mpOutAct
->CloseRegion();
212 if ( pElement
->eVDCType
== VDC_REAL
)
214 dx
= ImplGetFloat( pElement
->eVDCRealPrecision
, pElement
->nVDCRealSize
);
215 dy
= ImplGetFloat( pElement
->eVDCRealPrecision
, pElement
->nVDCRealSize
);
219 dx
= static_cast<double>(ImplGetI( pElement
->nVDCIntegerPrecision
));
220 dy
= static_cast<double>(ImplGetI( pElement
->nVDCIntegerPrecision
));
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
;
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
;
256 case 0x07 : /*Polygon*/
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
);
274 case 0x08 : /*Polygon Set*/
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
);
302 mpOutAct
->DrawPolyPolygon( aPolyPolygon
);
306 case 0x09 : /*Cell Array*/
309 mpOutAct
->CloseRegion();
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());
321 mpBitmapInUse
.reset( new CGMBitmap( *this ) );
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
;
334 case 0x0b : /*Rectangle*/
337 mpOutAct
->CloseRegion();
339 FloatRect aFloatRect
;
340 ImplGetRectangle( aFloatRect
, true );
341 mpOutAct
->DrawRectangle( aFloatRect
);
345 case 0x0c : /*Circle*/
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
);
356 aRadius
.X
= static_cast<double>(ImplGetI( pElement
->nVDCIntegerPrecision
));
357 ImplMapDouble( aRadius
.X
);
358 aRadius
.Y
= aRadius
.X
;
359 mpOutAct
->DrawEllipse( aCenter
, aRadius
, fRotation
);
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
) );
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
);
391 if ( fStartAngle
> fEndAngle
)
394 aIntermediatePoint
= aEndingPoint
;
395 aEndingPoint
= aStartingPoint
;
396 aStartingPoint
= aIntermediatePoint
;
398 fStartAngle
= fEndAngle
;
401 if ( ! ( fInterAngle
> fStartAngle
) && ( fInterAngle
< fEndAngle
) )
404 aIntermediatePoint
= aEndingPoint
;
405 aEndingPoint
= aStartingPoint
;
406 aStartingPoint
= aIntermediatePoint
;
408 fStartAngle
= fEndAngle
;
411 double fRadius
= sqrt( pow( ( aStartingPoint
.X
- aCenterPoint
.X
), 2 ) + pow( ( aStartingPoint
.Y
- aCenterPoint
.Y
), 2 ) ) ;
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
);
419 mpOutAct
->RegPolyLine( aPolygon
, true );
421 mpOutAct
->RegPolyLine( aPolygon
);
427 aRadius
.X
= aRadius
.Y
= fRadius
;
428 mpOutAct
->DrawEllipticalArc( aCenterPoint
, aRadius
, fG
, 2, fStartAngle
, fEndAngle
);
434 case 0x0e : /*Circular Arc 3 Point Close*/
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
) );
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
;
469 fStartAngle
= fEndAngle
;
472 if ( ! ( fInterAngle
> fStartAngle
) && ( fInterAngle
< fEndAngle
) )
474 aIntermediatePoint
= aEndingPoint
;
475 aEndingPoint
= aStartingPoint
;
476 aStartingPoint
= aIntermediatePoint
;
478 fStartAngle
= fEndAngle
;
482 fRadius
.Y
= fRadius
.X
= sqrt( pow( ( aStartingPoint
.X
- aCenterPoint
.X
), 2 ) + pow( ( aStartingPoint
.Y
- aCenterPoint
.Y
), 2 ) ) ;
484 sal_uInt32 nType
= ImplGetUI16();
488 nType
= 1; // is CHORD
490 double fOrientation
= 0;
491 mpOutAct
->DrawEllipticalArc( aCenterPoint
, fRadius
, fOrientation
, nType
, fStartAngle
, fEndAngle
);
496 case 0x0f : /*Circular Arc Centre*/
498 double fStartAngle
, fEndAngle
, vector
[ 4 ];
499 FloatPoint aCenter
, aRadius
;
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
);
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
;
530 ImplSwitchStartEndAngle( fStartAngle
, fEndAngle
);
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
);
543 double fOrientation
= 0;
544 mpOutAct
->DrawEllipticalArc( aCenter
, aRadius
, fOrientation
, 2, fStartAngle
, fEndAngle
);
546 mnParaSize
= mnElementSize
;
551 case 0x10 : /*Circular Arc Centre Close*/
553 double fOrientation
, vector
[ 4 ];
554 FloatPoint aCenter
, aRadius
;
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
);
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
;
582 ImplSwitchStartEndAngle( fStartAngle
, fEndAngle
);
585 sal_uInt32 nType
= ImplGetUI16();
589 nType
= 1; // is CHORD
592 mpOutAct
->DrawEllipticalArc( aCenter
, aRadius
, fOrientation
,
593 nType
, fStartAngle
, fEndAngle
);
594 mnParaSize
= mnElementSize
;
598 case 0x11 : /*Ellipse*/
601 FloatPoint aCenter
, aRadius
;
604 mpOutAct
->CloseRegion();
606 ImplGetEllipse( aCenter
, aRadius
, fOrientation
) ;
607 mpOutAct
->DrawEllipse( aCenter
, aRadius
, fOrientation
) ;
611 case 0x12 : /*Elliptical Arc*/
614 mpOutAct
->CloseRegion();
616 double fOrientation
, fStartAngle
, fEndAngle
, vector
[ 4 ];
617 FloatPoint aCenter
, aRadius
;
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
;
636 mpOutAct
->DrawEllipticalArc( aCenter
, aRadius
, fOrientation
,
637 2, fStartAngle
, fEndAngle
);
639 mpOutAct
->DrawEllipticalArc( aCenter
, aRadius
, fOrientation
,
640 2, fEndAngle
, fStartAngle
);
644 case 0x13 : /*Elliptical Arc Close*/
646 double fOrientation
, fStartAngle
, fEndAngle
, vector
[ 4 ];
647 FloatPoint aCenter
, aRadius
;
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();
669 nType
= 1; // is CHORD
672 mpOutAct
->DrawEllipticalArc( aCenter
, aRadius
, fOrientation
,
673 nType
, fStartAngle
, fEndAngle
);
675 mpOutAct
->DrawEllipticalArc( aCenter
, aRadius
, fOrientation
,
676 nType
, fEndAngle
, fStartAngle
);
679 case 0x14 : /*Circular Arc Centre Reversed*/
682 mpOutAct
->CloseRegion();
685 case 0x15 : /*Connection Edge */ // NS
688 // mpOutAct->CloseRegion();
691 case 0x16 : /*Hyperbolic Arc */ // NS
694 mpOutAct
->CloseRegion();
697 case 0x17 : /*Parabolic Arc */ // NS
700 mpOutAct
->CloseRegion();
703 case 0x18 : /*Non Uniform B-Spline */ // NS
706 mpOutAct
->CloseRegion();
709 case 0x19 : /*Non Uniform Rational B-Spline */ // NS
712 mpOutAct
->CloseRegion();
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
);
731 for ( sal_uInt16 i
= 0; i
< nNumberOfPoints
; i
++ )
733 if ( ( i
% 3 ) == 0 )
734 aPolygon
.SetFlags( i
, PolyFlags::Normal
);
736 aPolygon
.SetFlags( i
, PolyFlags::Control
);
741 for ( sal_uInt16 i
= 0; i
< nNumberOfPoints
; i
++ )
746 case 3 : aPolygon
.SetFlags( i
, PolyFlags::Normal
); break;
747 default : aPolygon
.SetFlags( i
, PolyFlags::Control
); break;
752 mpOutAct
->RegPolyLine( aPolygon
);
754 mpOutAct
->DrawPolybezier( aPolygon
);
755 mnParaSize
= mnElementSize
;
759 case 0x1b : /*Polysymbol */ // NS
762 mpOutAct
->CloseRegion();
765 case 0x1c : /*Bitonal Tile */ // NS
768 mpOutAct
->CloseRegion();
771 case 0x1d : /*Tile */ // NS
774 mpOutAct
->CloseRegion();
777 case 0x1e : /*Insert Object*/
780 mpOutAct
->CloseRegion();
783 case 0xff : /*Polybezier*/
786 mpOutAct
->CloseRegion();
789 case 0xfe : /*Sharp Polybezier*/
792 mpOutAct
->CloseRegion();
795 case 0xfd : /*Polyspline*/
798 mpOutAct
->CloseRegion();
801 case 0xfc : /*Rounded Rectangle*/
804 mpOutAct
->CloseRegion();
807 case 0xfb : /*Begin Cell Array*/
810 mpOutAct
->CloseRegion();
813 case 0xfa : /*End Cell Array*/
816 mpOutAct
->CloseRegion();
819 case 0xf9 : /*Insert File*/
822 mpOutAct
->CloseRegion();
825 case 0xf8 : /*Block Text*/
828 mpOutAct
->CloseRegion();
831 case 0xf7 : /*Variable Width Polyline*/
834 mpOutAct
->CloseRegion();
837 case 0xf6 : /*Elliptical Arc 3 Point*/
840 mpOutAct
->CloseRegion();
843 case 0xf1 : /*Hyperlink Definition */break;
848 mnParaSize
= mnElementSize
;
852 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */