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/float_int_conversion.hxx>
28 #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
= std::hypot(nX
, nY
);
40 double fOrientation
= fSqrt
!= 0.0 ? basegfx::rad2deg(acos(nX
/ fSqrt
)) : 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
= std::hypot(aPoint1
.X
, aPoint1
.Y
);
93 aPoint2
.X
-= rCenter
.X
;
94 aPoint2
.Y
-= rCenter
.Y
;
95 rRadius
.Y
= std::hypot(aPoint2
.X
, 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(u
"attempt to read past end of input"_ustr
, 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(u
"attempt to read past end of input"_ustr
, 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(u
"attempt to read past end of input"_ustr
, 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 std::vector
<Point
> aPoints
;
280 tools::PolyPolygon aPolyPolygon
;
281 FloatPoint aFloatPoint
;
283 while ( mnParaSize
< mnElementSize
)
285 ImplGetPoint( aFloatPoint
, true );
286 sal_uInt32 nEdgeFlag
= ImplGetUI16();
287 aPoints
.push_back(Point(static_cast<tools::Long
>(aFloatPoint
.X
), static_cast<tools::Long
>(aFloatPoint
.Y
)));
288 if ( ( nEdgeFlag
& 2 ) || ( mnParaSize
== mnElementSize
) )
290 aPolyPolygon
.Insert(tools::Polygon(aPoints
.size(), aPoints
.data()));
294 mpOutAct
->DrawPolyPolygon( aPolyPolygon
);
298 case 0x09 : /*Cell Array*/
301 mpOutAct
->CloseRegion();
305 std::unique_ptr
<CGMBitmap
> xBmpDesc(mpBitmapInUse
->GetNext());
306 if (xBmpDesc
) // we possibly get a bitmap back which does not fit to
307 { // to the previous -> we need to delete this one too
308 mpOutAct
->DrawBitmap(xBmpDesc
->GetBitmap());
313 mpBitmapInUse
.reset( new CGMBitmap( *this ) );
318 case 0x0a : /*Generalized Drawing Primitive*/
320 ImplGetI( pElement
->nIntegerPrecision
); //-Wall is this needed
321 ImplGetUI( pElement
->nIntegerPrecision
); //-Wall is this needed
322 mnParaSize
= mnElementSize
;
326 case 0x0b : /*Rectangle*/
329 mpOutAct
->CloseRegion();
331 FloatRect aFloatRect
;
332 ImplGetRectangle( aFloatRect
, true );
333 mpOutAct
->DrawRectangle( aFloatRect
);
337 case 0x0c : /*Circle*/
340 mpOutAct
->CloseRegion();
342 double fRotation
= 0;
343 FloatPoint aCenter
, aRadius
;
344 ImplGetPoint( aCenter
, true );
345 if ( pElement
->eVDCType
== VDC_REAL
)
346 aRadius
.X
= ImplGetFloat( pElement
->eVDCRealPrecision
, pElement
->nVDCRealSize
);
348 aRadius
.X
= static_cast<double>(ImplGetI( pElement
->nVDCIntegerPrecision
));
349 ImplMapDouble( aRadius
.X
);
350 aRadius
.Y
= aRadius
.X
;
351 mpOutAct
->DrawEllipse( aCenter
, aRadius
, fRotation
);
355 case 0x0d : /*Circular Arc 3 Point*/
357 FloatPoint aStartingPoint
, aIntermediatePoint
, aEndingPoint
;
358 ImplGetPoint( aStartingPoint
, true );
359 ImplGetPoint( aIntermediatePoint
, true );
360 ImplGetPoint( aEndingPoint
, true );
362 double fA
= aIntermediatePoint
.X
- aStartingPoint
.X
;
363 double fB
= aIntermediatePoint
.Y
- aStartingPoint
.Y
;
364 double fC
= aEndingPoint
.X
- aStartingPoint
.X
;
365 double fD
= aEndingPoint
.Y
- aStartingPoint
.Y
;
367 double fE
= fA
* ( aStartingPoint
.X
+ aIntermediatePoint
.X
) + fB
* ( aStartingPoint
.Y
+ aIntermediatePoint
.Y
);
368 double fF
= fC
* ( aStartingPoint
.X
+ aEndingPoint
.X
) + fD
* ( aStartingPoint
.Y
+ aEndingPoint
.Y
);
370 double fG
= 2.0 * ( fA
* ( aEndingPoint
.Y
- aIntermediatePoint
.Y
) - fB
* ( aEndingPoint
.X
- aIntermediatePoint
.X
) );
372 bool bUseless
= fG
== 0;
374 FloatPoint aCenterPoint
;
377 aCenterPoint
.X
= ( fD
* fE
- fB
* fF
) / fG
;
378 aCenterPoint
.Y
= ( fA
* fF
- fC
* fE
) / fG
;
379 bUseless
= useless(aCenterPoint
.X
) || useless(aCenterPoint
.Y
);
383 bUseless
= useless(aStartingPoint
.X
) || useless(aStartingPoint
.Y
);
387 double fStartAngle
= ImplGetOrientation( aCenterPoint
, aStartingPoint
);
388 double fInterAngle
= ImplGetOrientation( aCenterPoint
, aIntermediatePoint
);
389 double fEndAngle
= ImplGetOrientation( aCenterPoint
, aEndingPoint
);
393 if ( fStartAngle
> fEndAngle
)
396 aIntermediatePoint
= aEndingPoint
;
397 aEndingPoint
= aStartingPoint
;
398 aStartingPoint
= aIntermediatePoint
;
400 fStartAngle
= fEndAngle
;
403 if ( ! ( fInterAngle
> fStartAngle
) && ( fInterAngle
< fEndAngle
) )
406 aIntermediatePoint
= aEndingPoint
;
407 aEndingPoint
= aStartingPoint
;
408 aStartingPoint
= aIntermediatePoint
;
410 fStartAngle
= fEndAngle
;
413 double fRadius
= std::hypot(aStartingPoint
.X
- aCenterPoint
.X
, aStartingPoint
.Y
- aCenterPoint
.Y
);
417 double fLeft
= aCenterPoint
.X
- fRadius
;
418 double fTop
= aCenterPoint
.Y
- fRadius
;
419 double fRight
= fLeft
+ (2 * fRadius
);
420 double fBottom
= fTop
+ (2 * fRadius
);
421 bUseless
= useless(fLeft
) || useless(fTop
) || useless(2 * fRadius
) || useless(fRight
) || useless(fBottom
);
424 double fCenterCalc
= fLeft
+ fRight
;
425 bUseless
= !o3tl::convertsToAtLeast(fCenterCalc
, std::numeric_limits
<tools::Long
>::min()) ||
426 !o3tl::convertsToAtMost(fCenterCalc
, std::numeric_limits
<tools::Long
>::max());
430 double fCenterCalc
= fTop
+ fBottom
;
431 bUseless
= !o3tl::convertsToAtLeast(fCenterCalc
, std::numeric_limits
<tools::Long
>::min()) ||
432 !o3tl::convertsToAtMost(fCenterCalc
, std::numeric_limits
<tools::Long
>::max());
436 tools::Rectangle
aBoundingBox(Point(fLeft
, fTop
), Size(2 * fRadius
, 2 * fRadius
));
437 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
);
439 mpOutAct
->RegPolyLine( aPolygon
, true );
441 mpOutAct
->RegPolyLine( aPolygon
);
448 aRadius
.X
= aRadius
.Y
= fRadius
;
449 mpOutAct
->DrawEllipticalArc( aCenterPoint
, aRadius
, fG
, 2, fStartAngle
, fEndAngle
);
455 case 0x0e : /*Circular Arc 3 Point Close*/
458 mpOutAct
->CloseRegion();
460 FloatPoint aStartingPoint
, aIntermediatePoint
, aEndingPoint
;
461 ImplGetPoint( aStartingPoint
);
462 ImplGetPoint( aIntermediatePoint
);
463 ImplGetPoint( aEndingPoint
);
465 double fA
= aIntermediatePoint
.X
- aStartingPoint
.X
;
466 double fB
= aIntermediatePoint
.Y
- aStartingPoint
.Y
;
467 double fC
= aEndingPoint
.X
- aStartingPoint
.X
;
468 double fD
= aEndingPoint
.Y
- aStartingPoint
.Y
;
470 double fE
= fA
* ( aStartingPoint
.X
+ aIntermediatePoint
.X
) + fB
* ( aStartingPoint
.Y
+ aIntermediatePoint
.Y
);
471 double fF
= fC
* ( aStartingPoint
.X
+ aEndingPoint
.X
) + fD
* ( aStartingPoint
.Y
+ aEndingPoint
.Y
);
473 double fG
= 2.0 * ( fA
* ( aEndingPoint
.Y
- aIntermediatePoint
.Y
) - fB
* ( aEndingPoint
.X
- aIntermediatePoint
.X
) );
477 FloatPoint aCenterPoint
;
478 aCenterPoint
.X
= ( fD
* fE
- fB
* fF
) / fG
;
479 aCenterPoint
.Y
= ( fA
* fF
- fC
* fE
) / fG
;
480 double fStartAngle
= ImplGetOrientation( aCenterPoint
, aStartingPoint
);
481 double fInterAngle
= ImplGetOrientation( aCenterPoint
, aIntermediatePoint
);
482 double fEndAngle
= ImplGetOrientation( aCenterPoint
, aEndingPoint
);
484 if ( fStartAngle
> fEndAngle
)
486 aIntermediatePoint
= aEndingPoint
;
487 aEndingPoint
= aStartingPoint
;
488 aStartingPoint
= aIntermediatePoint
;
490 fStartAngle
= fEndAngle
;
493 if ( ! ( fInterAngle
> fStartAngle
) && ( fInterAngle
< fEndAngle
) )
495 aIntermediatePoint
= aEndingPoint
;
496 aEndingPoint
= aStartingPoint
;
497 aStartingPoint
= aIntermediatePoint
;
499 fStartAngle
= fEndAngle
;
503 fRadius
.Y
= fRadius
.X
= std::hypot(aStartingPoint
.X
- aCenterPoint
.X
, aStartingPoint
.Y
- aCenterPoint
.Y
);
505 sal_uInt32 nType
= ImplGetUI16();
509 nType
= 1; // is CHORD
511 double fOrientation
= 0;
512 mpOutAct
->DrawEllipticalArc( aCenterPoint
, fRadius
, fOrientation
, nType
, fStartAngle
, fEndAngle
);
517 case 0x0f : /*Circular Arc Centre*/
519 double fStartAngle
, fEndAngle
, vector
[ 4 ];
520 FloatPoint aCenter
, aRadius
;
523 mpOutAct
->CloseRegion();
525 ImplGetPoint( aCenter
, true );
526 ImplGetVector( &vector
[ 0 ] );
528 if ( pElement
->eVDCType
== VDC_REAL
)
530 aRadius
.X
= ImplGetFloat( pElement
->eVDCRealPrecision
, pElement
->nVDCRealSize
);
534 aRadius
.X
= static_cast<double>(ImplGetI( pElement
->nVDCIntegerPrecision
));
537 ImplMapDouble( aRadius
.X
);
538 aRadius
.Y
= aRadius
.X
;
540 bool bUseless
= useless(vector
[0]) || useless(vector
[1]) || useless(vector
[2]) || useless(vector
[3]);
543 const double fStartSqrt
= std::hypot(vector
[0], vector
[1]);
544 fStartAngle
= fStartSqrt
!= 0.0 ? basegfx::rad2deg(acos(vector
[0] / fStartSqrt
)) : 0.0;
545 const double fEndSqrt
= std::hypot(vector
[2], vector
[3]);
546 fEndAngle
= fEndSqrt
!= 0.0 ? basegfx::rad2deg(acos(vector
[ 2 ] / fEndSqrt
)) : 0.0;
548 if ( vector
[ 1 ] > 0 )
549 fStartAngle
= 360 - fStartAngle
;
550 if ( vector
[ 3 ] > 0 )
551 fEndAngle
= 360 - fEndAngle
;
554 ImplSwitchStartEndAngle( fStartAngle
, fEndAngle
);
558 double fLeft
= aCenter
.X
- aRadius
.X
;
559 double fTop
= aCenter
.Y
- aRadius
.X
;
560 double fRight
= fLeft
+ (2 * aRadius
.X
);
561 double fBottom
= fTop
+ (2 * aRadius
.X
);
562 bUseless
= useless(fLeft
) || useless(fTop
) || useless(2 * aRadius
.X
) || useless(fRight
) || useless(fBottom
);
565 double fCenterCalc
= fLeft
+ fRight
;
566 bUseless
= !o3tl::convertsToAtLeast(fCenterCalc
, std::numeric_limits
<tools::Long
>::min()) ||
567 !o3tl::convertsToAtMost(fCenterCalc
, std::numeric_limits
<tools::Long
>::max());
571 double fCenterCalc
= fTop
+ fBottom
;
572 bUseless
= !o3tl::convertsToAtLeast(fCenterCalc
, std::numeric_limits
<tools::Long
>::min()) ||
573 !o3tl::convertsToAtMost(fCenterCalc
, std::numeric_limits
<tools::Long
>::max());
577 tools::Rectangle
aBoundingBox(Point(fLeft
, fTop
), Size(2 * aRadius
.X
, 2 * aRadius
.X
));
578 tools::Polygon
aPolygon( aBoundingBox
,
579 Point( static_cast<tools::Long
>(vector
[ 0 ]), static_cast<tools::Long
>(vector
[ 1 ]) ),
580 Point( static_cast<tools::Long
>(vector
[ 2 ]), static_cast<tools::Long
>(vector
[ 3 ]) ), PolyStyle::Arc
);
581 mpOutAct
->RegPolyLine( aPolygon
);
586 double fOrientation
= 0;
587 mpOutAct
->DrawEllipticalArc( aCenter
, aRadius
, fOrientation
, 2, fStartAngle
, fEndAngle
);
591 mnParaSize
= mnElementSize
;
595 case 0x10 : /*Circular Arc Centre Close*/
597 double fOrientation
, vector
[ 4 ];
598 FloatPoint aCenter
, aRadius
;
601 mpOutAct
->CloseRegion();
603 ImplGetPoint( aCenter
, true );
604 ImplGetVector( &vector
[ 0 ] );
605 if ( pElement
->eVDCType
== VDC_REAL
)
607 aRadius
.X
= ImplGetFloat( pElement
->eVDCRealPrecision
, pElement
->nVDCRealSize
);
611 aRadius
.X
= static_cast<double>(ImplGetI( pElement
->nVDCIntegerPrecision
));
613 ImplMapDouble( aRadius
.X
);
614 aRadius
.Y
= aRadius
.X
;
616 sal_uInt32 nType
= ImplGetUI16();
618 bool bUseless
= useless(vector
[0]) || useless(vector
[1]) || useless(vector
[2]) || useless(vector
[3]);
621 const double fStartSqrt
= std::hypot(vector
[0], vector
[1]);
622 double fStartAngle
= fStartSqrt
? basegfx::rad2deg(acos(vector
[0] / fStartSqrt
)) : 0.0;
623 const double fEndSqrt
= std::hypot(vector
[2], vector
[3]);
624 double fEndAngle
= fEndSqrt
? basegfx::rad2deg(acos(vector
[2] / fEndSqrt
)) : 0.0;
626 if ( vector
[ 1 ] > 0 )
627 fStartAngle
= 360 - fStartAngle
;
628 if ( vector
[ 3 ] > 0 )
629 fEndAngle
= 360 - fEndAngle
;
632 ImplSwitchStartEndAngle( fStartAngle
, fEndAngle
);
637 nType
= 1; // is CHORD
640 mpOutAct
->DrawEllipticalArc( aCenter
, aRadius
, fOrientation
,
641 nType
, fStartAngle
, fEndAngle
);
644 mnParaSize
= mnElementSize
;
648 case 0x11 : /*Ellipse*/
651 FloatPoint aCenter
, aRadius
;
654 mpOutAct
->CloseRegion();
656 ImplGetEllipse( aCenter
, aRadius
, fOrientation
) ;
657 mpOutAct
->DrawEllipse( aCenter
, aRadius
, fOrientation
) ;
661 case 0x12 : /*Elliptical Arc*/
664 mpOutAct
->CloseRegion();
666 double fOrientation
, fStartAngle
, fEndAngle
, vector
[ 4 ];
667 FloatPoint aCenter
, aRadius
;
670 mpOutAct
->CloseRegion();
672 bool bDirection
= ImplGetEllipse( aCenter
, aRadius
, fOrientation
);
673 ImplGetVector( &vector
[ 0 ] );
675 bool bUseless
= useless(vector
[0]) || useless(vector
[1]) || useless(vector
[2]) || useless(vector
[3]);
678 double fStartSqrt
= std::hypot(vector
[0], vector
[1]);
679 fStartAngle
= fStartSqrt
? basegfx::rad2deg(acos(vector
[0] / fStartSqrt
)) : 0.0;
680 double fEndSqrt
= std::hypot(vector
[2], vector
[3]);
681 fEndAngle
= fEndSqrt
? basegfx::rad2deg(acos(vector
[2] / fEndSqrt
)) : 0.0;
683 if ( vector
[ 1 ] > 0 )
684 fStartAngle
= 360 - fStartAngle
;
685 if ( vector
[ 3 ] > 0 )
686 fEndAngle
= 360 - fEndAngle
;
689 mpOutAct
->DrawEllipticalArc( aCenter
, aRadius
, fOrientation
,
690 2, fStartAngle
, fEndAngle
);
692 mpOutAct
->DrawEllipticalArc( aCenter
, aRadius
, fOrientation
,
693 2, fEndAngle
, fStartAngle
);
698 case 0x13 : /*Elliptical Arc Close*/
700 double fOrientation
, fStartAngle
, fEndAngle
, vector
[ 4 ];
701 FloatPoint aCenter
, aRadius
;
704 mpOutAct
->CloseRegion();
706 bool bDirection
= ImplGetEllipse( aCenter
, aRadius
, fOrientation
);
707 ImplGetVector( &vector
[ 0 ] );
709 sal_uInt32 nType
= ImplGetUI16();
711 bool bUseless
= useless(vector
[0]) || useless(vector
[1]) || useless(vector
[2]) || useless(vector
[3]);
714 double fStartSqrt
= std::hypot(vector
[0], vector
[1]);
715 fStartAngle
= fStartSqrt
? basegfx::rad2deg(acos(vector
[0] / fStartSqrt
)) : 0.0;
716 double fEndSqrt
= std::hypot(vector
[2], vector
[3]);
717 fEndAngle
= fEndSqrt
? basegfx::rad2deg(acos(vector
[2] / fEndSqrt
)) : 0.0;
719 if ( vector
[ 1 ] > 0 )
720 fStartAngle
= 360 - fStartAngle
;
721 if ( vector
[ 3 ] > 0 )
722 fEndAngle
= 360 - fEndAngle
;
727 nType
= 1; // is CHORD
730 mpOutAct
->DrawEllipticalArc( aCenter
, aRadius
, fOrientation
,
731 nType
, fStartAngle
, fEndAngle
);
733 mpOutAct
->DrawEllipticalArc( aCenter
, aRadius
, fOrientation
,
734 nType
, fEndAngle
, fStartAngle
);
738 case 0x14 : /*Circular Arc Centre Reversed*/
741 mpOutAct
->CloseRegion();
744 case 0x15 : /*Connection Edge */ // NS
747 // mpOutAct->CloseRegion();
750 case 0x16 : /*Hyperbolic Arc */ // NS
753 mpOutAct
->CloseRegion();
756 case 0x17 : /*Parabolic Arc */ // NS
759 mpOutAct
->CloseRegion();
762 case 0x18 : /*Non Uniform B-Spline */ // NS
765 mpOutAct
->CloseRegion();
768 case 0x19 : /*Non Uniform Rational B-Spline */ // NS
771 mpOutAct
->CloseRegion();
774 case 0x1a : /*Polybezier*/
776 sal_uInt32 nOrder
= ImplGetI( pElement
->nIntegerPrecision
);
778 sal_uInt16 nNumberOfPoints
= sal::static_int_cast
< sal_uInt16
>(( mnElementSize
- pElement
->nIntegerPrecision
) / ImplGetPointSize());
780 tools::Polygon
aPolygon( nNumberOfPoints
);
782 for ( sal_uInt16 i
= 0; i
< nNumberOfPoints
; i
++)
784 FloatPoint aFloatPoint
;
785 ImplGetPoint( aFloatPoint
, true );
786 aPolygon
.SetPoint( Point ( static_cast<tools::Long
>( aFloatPoint
.X
), static_cast<tools::Long
>( aFloatPoint
.Y
) ), i
);
790 for ( sal_uInt16 i
= 0; i
< nNumberOfPoints
; i
++ )
792 if ( ( i
% 3 ) == 0 )
793 aPolygon
.SetFlags( i
, PolyFlags::Normal
);
795 aPolygon
.SetFlags( i
, PolyFlags::Control
);
800 for ( sal_uInt16 i
= 0; i
< nNumberOfPoints
; i
++ )
805 case 3 : aPolygon
.SetFlags( i
, PolyFlags::Normal
); break;
806 default : aPolygon
.SetFlags( i
, PolyFlags::Control
); break;
811 mpOutAct
->RegPolyLine( aPolygon
);
813 mpOutAct
->DrawPolybezier( aPolygon
);
814 mnParaSize
= mnElementSize
;
818 case 0x1b : /*Polysymbol */ // NS
821 mpOutAct
->CloseRegion();
824 case 0x1c : /*Bitonal Tile */ // NS
827 mpOutAct
->CloseRegion();
830 case 0x1d : /*Tile */ // NS
833 mpOutAct
->CloseRegion();
836 case 0x1e : /*Insert Object*/
839 mpOutAct
->CloseRegion();
842 case 0xff : /*Polybezier*/
845 mpOutAct
->CloseRegion();
848 case 0xfe : /*Sharp Polybezier*/
851 mpOutAct
->CloseRegion();
854 case 0xfd : /*Polyspline*/
857 mpOutAct
->CloseRegion();
860 case 0xfc : /*Rounded Rectangle*/
863 mpOutAct
->CloseRegion();
866 case 0xfb : /*Begin Cell Array*/
869 mpOutAct
->CloseRegion();
872 case 0xfa : /*End Cell Array*/
875 mpOutAct
->CloseRegion();
878 case 0xf9 : /*Insert File*/
881 mpOutAct
->CloseRegion();
884 case 0xf8 : /*Block Text*/
887 mpOutAct
->CloseRegion();
890 case 0xf7 : /*Variable Width Polyline*/
893 mpOutAct
->CloseRegion();
896 case 0xf6 : /*Elliptical Arc 3 Point*/
899 mpOutAct
->CloseRegion();
902 case 0xf1 : /*Hyperlink Definition */break;
907 mnParaSize
= mnElementSize
;
911 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */