1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_filter.hxx"
26 
27 #include <main.hxx>
28 #include <chart.hxx>
29 #include <outact.hxx>
30 #include <math.h>
31 
32 using namespace ::com::sun::star;
33 
ImplGetOrientation(FloatPoint & rCenter,FloatPoint & rPoint)34 double CGM::ImplGetOrientation( FloatPoint& rCenter, FloatPoint& rPoint )
35 {
36 	double fOrientation;
37 
38 	double nX = rPoint.X - rCenter.X;
39 	double nY = rPoint.Y - rCenter.Y;
40 
41 	fOrientation = acos( nX / sqrt( nX * nX + nY * nY ) ) * 57.29577951308;
42 	if ( nY > 0 )
43 		fOrientation = 360 - fOrientation;
44 
45 	return fOrientation;
46 }
47 
48 // ---------------------------------------------------------------
49 
ImplSwitchStartEndAngle(double & rStartAngle,double & rEndAngle)50 void CGM::ImplSwitchStartEndAngle( double& rStartAngle, double& rEndAngle )
51 {
52 	double nTemp;
53 	nTemp = rStartAngle;
54 	rStartAngle = rEndAngle;
55 	rEndAngle = nTemp;
56 }
57 
58 // ---------------------------------------------------------------
59 
ImplGetVector(double * pVector)60 void CGM::ImplGetVector( double* pVector )
61 {
62 	if ( pElement->eVDCType == VDC_REAL )
63 	{
64 		for ( sal_uInt32 i = 0; i < 4; i++ )
65 		{
66 			pVector[ i ] = (double)ImplGetFloat( pElement->eVDCRealPrecision, pElement->nVDCRealSize );
67 		}
68 	}
69 	else
70 	{
71 		for ( sal_uInt32 i = 0; i < 4; i++ )
72 		{
73 			pVector[ i ] = (double)ImplGetI( pElement->nVDCIntegerPrecision );
74 		}
75 	}
76 	pVector[ 0 ] *= mnVDCXmul;
77 	pVector[ 2 ] *= mnVDCXmul;
78 	pVector[ 1 ] *= mnVDCYmul;
79 	pVector[ 3 ] *= mnVDCYmul;
80 }
81 
82 // ---------------------------------------------------------------
ImplGetEllipse(FloatPoint & rCenter,FloatPoint & rRadius,double & rAngle)83 sal_Bool CGM::ImplGetEllipse( FloatPoint& rCenter, FloatPoint& rRadius, double& rAngle )
84 {
85 	FloatPoint	aPoint1, aPoint2;
86 	double		fRot1, fRot2;
87 	ImplGetPoint( rCenter, sal_True );
88 	ImplGetPoint( aPoint1, sal_True );
89 	ImplGetPoint( aPoint2, sal_True );
90 	fRot1 = ImplGetOrientation( rCenter, aPoint1 );
91 	fRot2 = ImplGetOrientation( rCenter, aPoint2 );
92 	rAngle = ImplGetOrientation( rCenter, aPoint1 );
93 	aPoint1.X -= rCenter.X;
94 	aPoint1.Y -= rCenter.Y;
95 	rRadius.X = sqrt( aPoint1.X * aPoint1.X + aPoint1.Y * aPoint1.Y );
96 	aPoint2.X -= rCenter.X;
97 	aPoint2.Y -= rCenter.Y;
98 	rRadius.Y = sqrt( aPoint2.X * aPoint2.X + aPoint2.Y * aPoint2.Y );
99 
100 	if ( fRot1 > fRot2 )
101 	{
102 		if ( ( fRot1 - fRot2 ) < 180 )
103 			return sal_False;
104 	}
105 	else
106 	{
107 		if ( ( fRot2 - fRot1 ) > 180 )
108 			return sal_False;
109 	}
110 	return sal_True;
111 }
112 
ImplDoClass4()113 void CGM::ImplDoClass4()
114 {
115 	if ( mbFirstOutPut )
116 		mpOutAct->FirstOutPut();
117 
118 	if ( mpBitmapInUse && ( mnElementID != 9 ) )	// vorhandene grafik verarbeiten,
119 	{												// da jetzt nicht bitmap actions anstehen
120 		CGMBitmapDescriptor* pBmpDesc = mpBitmapInUse->GetBitmap();
121 		// irgendetwas mit der Bitmap anfangen
122 		mpOutAct->DrawBitmap( pBmpDesc );
123 		delete mpBitmapInUse;
124 		mpBitmapInUse = NULL;
125 	}
126 
127 	if ( ( mpChart == NULL ) || mpChart->IsAnnotation() )
128 	{
129 		switch ( mnElementID )
130 		{
131 			case 0x01 : ComOut( CGM_LEVEL1, "PolyLine" )
132 			{
133 				sal_uInt32 nPoints = mnElementSize / ImplGetPointSize();
134 				Polygon aPolygon( (sal_uInt16)nPoints );
135 				for ( sal_uInt16 i = 0; i < nPoints; i++)
136 				{
137 					FloatPoint	aFloatPoint;
138 					ImplGetPoint( aFloatPoint, sal_True );
139 					aPolygon.SetPoint( Point( (long)aFloatPoint.X, (long)aFloatPoint.Y ), i );
140 				}
141 				if ( mbFigure )
142 					mpOutAct->RegPolyLine( aPolygon );
143 				else
144 					mpOutAct->DrawPolyLine( aPolygon );
145 			}
146 			break;
147 
148 			case 0x02 : ComOut( CGM_LEVEL1 | CGM_EXTENDED_PRIMITIVES_SET, "Disjoint PolyLine" )
149 			{
150 				sal_uInt16 nPoints = sal::static_int_cast< sal_uInt16 >(
151                     mnElementSize / ImplGetPointSize());
152 				if ( ! ( nPoints & 1 ) )
153 				{
154 					nPoints >>= 1;
155 					FloatPoint	aFloatPoint;
156 					if ( mbFigure )
157 					{
158 						Polygon aPolygon( nPoints );
159 						for ( sal_uInt16 i = 0; i < nPoints; i++ )
160 						{
161 							ImplGetPoint( aFloatPoint, sal_True );
162 							aPolygon.SetPoint( Point( (long)aFloatPoint.X, (long)aFloatPoint.Y ), 0 );
163 						}
164 						mpOutAct->RegPolyLine( aPolygon );
165 					}
166 					else
167 					{
168 						mpOutAct->BeginGroup();
169 						Polygon aPolygon( (sal_uInt16)2 );
170 						for ( sal_uInt16 i = 0; i < nPoints; i++ )
171 						{
172 							ImplGetPoint( aFloatPoint, sal_True );
173 							aPolygon.SetPoint( Point( (long)aFloatPoint.X, (long)aFloatPoint.Y ), 0 );
174 							ImplGetPoint( aFloatPoint, sal_True );
175 							aPolygon.SetPoint( Point( (long)aFloatPoint.X, (long)aFloatPoint.Y ), 1);
176 							mpOutAct->DrawPolyLine( aPolygon );
177 						}
178 						mpOutAct->EndGroup();
179 					}
180 				}
181 			}
182 			break;
183 
184 			case 0x03 : ComOut( CGM_LEVEL1, "PolyMarker" ) break;
185 			case 0x04 : ComOut( CGM_LEVEL1, "Text" )
186 			{
187 				FloatPoint	aFloatPoint;
188 				sal_uInt32		nType, nSize;
189 
190 				if ( mbFigure )
191 					mpOutAct->CloseRegion();
192 
193 				ImplGetPoint ( aFloatPoint, sal_True );
194 				nType = ImplGetUI16( 4 );
195 				nSize = ImplGetUI( 1 );
196 				mpSource[ mnParaSize + nSize ] = 0;
197 
198 				ComOut( CGM_DESCRIPTION, (char*)mpSource + mnParaSize );
199 
200 				awt::Size aSize;
201 				awt::Point aPoint( (long)aFloatPoint.X, (long)aFloatPoint.Y );
202 				mpOutAct->DrawText( aPoint, aSize,
203 								(char*)mpSource + mnParaSize, nSize, (FinalFlag)nType );
204 //				mnParaSize += nSize;
205 				mnParaSize = mnElementSize;
206 			}
207 			break;
208 
209 			case 0x05 : ComOut( CGM_LEVEL1 | CGM_EXTENDED_PRIMITIVES_SET, "Restricted Text" )
210 			{
211 				double		dx, dy;
212 				FloatPoint	aFloatPoint;
213 				sal_uInt32		nType, nSize;
214 
215 				if ( mbFigure )
216 					mpOutAct->CloseRegion();
217 
218 				if ( pElement->eVDCType == VDC_REAL )
219 				{
220 					dx = ImplGetFloat( pElement->eVDCRealPrecision, pElement->nVDCRealSize );
221 					dy = ImplGetFloat( pElement->eVDCRealPrecision, pElement->nVDCRealSize );
222 				}
223 				else
224 				{
225 					dx = (double)ImplGetI( pElement->nVDCIntegerPrecision );
226 					dy = (double)ImplGetI( pElement->nVDCIntegerPrecision );
227 				}
228 				ImplMapDouble( dx );
229 				ImplMapDouble( dy );
230 
231 				ImplGetPoint ( aFloatPoint, sal_True );
232 				nType = ImplGetUI16( 4 );
233 				nSize = ImplGetUI( 1 );
234 
235 				mpSource[ mnParaSize + nSize ] = 0;
236 
237 				ComOut( CGM_DESCRIPTION, (char*)mpSource + mnParaSize );
238 
239 				awt::Point aPoint( (long)aFloatPoint.X, (long)aFloatPoint.Y );
240 				awt::Size aSize((long)dx, (long)dy);
241 				mpOutAct->DrawText( aPoint, aSize ,
242 								(char*)mpSource + mnParaSize, nSize, (FinalFlag)nType );
243 //				mnParaSize += nSize;
244 				mnParaSize = mnElementSize;
245 			}
246 			break;
247 
248 			case 0x06 : ComOut( CGM_LEVEL1 | CGM_EXTENDED_PRIMITIVES_SET, "Append Text" )
249 			{
250 				sal_uInt32 nSize;
251 				sal_uInt32 nType = ImplGetUI16( 4 );
252 
253 				nSize = ImplGetUI( 1 );
254 				mpSource[ mnParaSize + nSize ] = 0;
255 
256 				ComOut( CGM_DESCRIPTION, (char*)mpSource + mnParaSize );
257 
258 				mpOutAct->AppendText( (char*)mpSource + mnParaSize, nSize, (FinalFlag)nType );
259 //				mnParaSize += nSize;
260 				mnParaSize = mnElementSize;
261 			}
262 			break;
263 
264 			case 0x07 : ComOut( CGM_LEVEL1, "Polygon" )
265 			{
266 				if ( mbFigure )
267 					mpOutAct->CloseRegion();
268 
269 				sal_uInt16 nPoints = sal::static_int_cast< sal_uInt16 >(
270                     mnElementSize / ImplGetPointSize());
271 				Polygon aPolygon( nPoints );
272 				for ( sal_uInt16 i = 0; i < nPoints; i++)
273 				{
274 					FloatPoint	aFloatPoint;
275 					ImplGetPoint( aFloatPoint, sal_True );
276 					aPolygon.SetPoint( Point ( (long)( aFloatPoint.X ), (long)( aFloatPoint.Y ) ), i );
277 				}
278 				mpOutAct->DrawPolygon( aPolygon );
279 			}
280 			break;
281 
282 			case 0x08 : ComOut( CGM_LEVEL1 | CGM_EXTENDED_PRIMITIVES_SET, "Polygon Set" )
283 			{
284 				if ( mbFigure )
285 					mpOutAct->CloseRegion();
286 
287 				sal_uInt16		nPoints = 0;
288 				Point*		pPoints = new Point[ 0x4000 ];
289 
290 				PolyPolygon aPolyPolygon;
291 				FloatPoint	aFloatPoint;
292 				sal_uInt32		nEdgeFlag;
293 				while ( mnParaSize < mnElementSize )
294 				{
295 					ImplGetPoint( aFloatPoint, sal_True );
296 					nEdgeFlag = ImplGetUI16();
297 					pPoints[ nPoints++ ] = Point( (long)aFloatPoint.X, (long)aFloatPoint.Y );
298 					if ( ( nEdgeFlag & 2 ) || ( mnParaSize == mnElementSize ) )
299 					{
300 						Polygon aPolygon( nPoints );
301 						for ( sal_uInt16 i = 0; i < nPoints; i++ )
302 						{
303 							aPolygon.SetPoint( pPoints[ i ], i );
304 						}
305 						aPolyPolygon.Insert( aPolygon, POLYPOLY_APPEND );
306 						nPoints = 0;
307 					}
308 				}
309 				delete[] pPoints;
310 				mpOutAct->DrawPolyPolygon( aPolyPolygon );
311 			}
312 			break;
313 
314 			case 0x09 : ComOut( CGM_LEVEL1, "Cell Array" )
315 			{
316 				if ( mbFigure )
317 					mpOutAct->CloseRegion();
318 
319 				if ( mpBitmapInUse )
320 				{
321 					CGMBitmap* pBmpDesc = mpBitmapInUse->GetNext();
322 					if ( pBmpDesc )	// eventuell bekommen wir eine bitmap zur�ck, die nicht
323 					{				// zur vorherigen pa�t -> diese m�ssen wir dann auch l�schen
324 						mpOutAct->DrawBitmap( pBmpDesc->GetBitmap() );
325 						delete pBmpDesc;
326 					}
327 				}
328 				else
329 				{
330 					mpBitmapInUse = new CGMBitmap( *this );
331 				}
332 			}
333 			break;
334 
335 			case 0x0a : ComOut( CGM_LEVEL1, "Generalized Drawing Primitive" )
336 			{
337 				ImplGetI( pElement->nIntegerPrecision );  //-Wall is this needed
338 				ImplGetUI( pElement->nIntegerPrecision ); //-Wall is this needed
339 				mnParaSize = mnElementSize;
340 			}
341 			break;
342 
343 			case 0x0b : ComOut( CGM_LEVEL1 | CGM_EXTENDED_PRIMITIVES_SET, "Rectangle" )
344 			{
345 				if ( mbFigure )
346 					mpOutAct->CloseRegion();
347 
348 				FloatRect	aFloatRect;
349 				ImplGetRectangle( aFloatRect, sal_True );
350 				mpOutAct->DrawRectangle( aFloatRect );
351 			}
352 			break;
353 
354 			case 0x0c : ComOut( CGM_LEVEL1 | CGM_EXTENDED_PRIMITIVES_SET, "Circle" )
355 			{
356 				if ( mbFigure )
357 					mpOutAct->CloseRegion();
358 
359 				double fRotation = 0;
360 				FloatPoint aCenter, aRadius;
361 				ImplGetPoint( aCenter, sal_True );
362 				if ( pElement->eVDCType == VDC_REAL )
363 					aRadius.X = ImplGetFloat( pElement->eVDCRealPrecision, pElement->nVDCRealSize );
364 				else
365 					aRadius.X = (double)ImplGetI( pElement->nVDCIntegerPrecision );
366 				ImplMapDouble( aRadius.X );
367 				aRadius.Y = aRadius.X;
368 				mpOutAct->DrawEllipse( aCenter, aRadius, fRotation );
369 			}
370 			break;
371 
372 			case 0x0d : ComOut( CGM_LEVEL1 | CGM_EXTENDED_PRIMITIVES_SET, "Circular Arc 3 Point" )
373 			{
374 				int		nSwitch = 0;
375 
376 				FloatPoint aStartingPoint, aIntermediatePoint, aEndingPoint, aCenterPoint;
377 				ImplGetPoint( aStartingPoint, sal_True );
378 				ImplGetPoint( aIntermediatePoint, sal_True );
379 				ImplGetPoint( aEndingPoint, sal_True );
380 
381 				double fA = aIntermediatePoint.X - aStartingPoint.X;
382 				double fB = aIntermediatePoint.Y - aStartingPoint.Y;
383 				double fC = aEndingPoint.X - aStartingPoint.X;
384 				double fD = aEndingPoint.Y - aStartingPoint.Y;
385 
386 				double fE = fA * ( aStartingPoint.X + aIntermediatePoint.X ) + fB * ( aStartingPoint.Y + aIntermediatePoint.Y );
387 				double fF = fC * ( aStartingPoint.X + aEndingPoint.X ) + fD * ( aStartingPoint.Y + aEndingPoint.Y );
388 
389 				double fG = 2.0 * ( fA * ( aEndingPoint.Y - aIntermediatePoint.Y ) - fB * ( aEndingPoint.X - aIntermediatePoint.X ) );
390 
391 				aCenterPoint.X = ( fD * fE - fB * fF ) / fG;
392 				aCenterPoint.Y = ( fA * fF - fC * fE ) / fG;
393 
394 				if ( fG != 0 )
395 				{
396 					double fStartAngle = ImplGetOrientation( aCenterPoint, aStartingPoint );
397 					double fInterAngle = ImplGetOrientation( aCenterPoint, aIntermediatePoint );
398 					double fEndAngle = ImplGetOrientation( aCenterPoint, aEndingPoint );
399 
400 					if ( fStartAngle > fEndAngle )
401 					{
402 						nSwitch ^=1;
403 						aIntermediatePoint = aEndingPoint;
404 						aEndingPoint = aStartingPoint;
405 						aStartingPoint = aIntermediatePoint;
406 						fG = fStartAngle;
407 						fStartAngle = fEndAngle;
408 						fEndAngle = fG;
409 					}
410 					if ( ! ( fInterAngle > fStartAngle )  && ( fInterAngle < fEndAngle ) )
411 					{
412 						nSwitch ^=1;
413 						aIntermediatePoint = aEndingPoint;
414 						aEndingPoint = aStartingPoint;
415 						aStartingPoint = aIntermediatePoint;
416 						fG = fStartAngle;
417 						fStartAngle = fEndAngle;
418 						fEndAngle = fG;
419 					}
420 					double fRadius = sqrt( pow( ( aStartingPoint.X - aCenterPoint.X ), 2 ) + pow( ( aStartingPoint.Y - aCenterPoint.Y ), 2 ) ) ;
421 
422 					if ( mbFigure )
423 					{
424 						Rectangle aBoundingBox( Point( (long)( aCenterPoint.X - fRadius ), long( aCenterPoint.Y - fRadius ) ),
425 							Size( ( static_cast< long >( 2 * fRadius ) ), (long)( 2 * fRadius) ) );
426 						Polygon aPolygon( aBoundingBox, Point( (long)aStartingPoint.X, (long)aStartingPoint.Y ) ,Point( (long)aEndingPoint.X, (long)aEndingPoint.Y ), POLY_ARC );
427 						if ( nSwitch )
428 							mpOutAct->RegPolyLine( aPolygon, sal_True );
429 						else
430 							mpOutAct->RegPolyLine( aPolygon );
431 					}
432 					else
433 					{
434 						fG = 0;
435 						FloatPoint aRadius;
436 						aRadius.X = aRadius.Y = fRadius;
437 						mpOutAct->DrawEllipticalArc( aCenterPoint, aRadius, fG, 2, fStartAngle, fEndAngle );
438 					}
439 				}
440 			}
441 			break;
442 
443 			case 0x0e : ComOut( CGM_LEVEL1 | CGM_EXTENDED_PRIMITIVES_SET, "Circular Arc 3 Point Close" )
444 			{
445 				int nSwitch = 0;
446 
447 				if ( mbFigure )
448 					mpOutAct->CloseRegion();
449 
450 				FloatPoint aStartingPoint, aIntermediatePoint, aEndingPoint, aCenterPoint;
451 				ImplGetPoint( aStartingPoint );
452 				ImplGetPoint( aIntermediatePoint );
453 				ImplGetPoint( aEndingPoint );
454 
455 				double fA = aIntermediatePoint.X - aStartingPoint.X;
456 				double fB = aIntermediatePoint.Y - aStartingPoint.Y;
457 				double fC = aEndingPoint.X - aStartingPoint.X;
458 				double fD = aEndingPoint.Y - aStartingPoint.Y;
459 
460 				double fE = fA * ( aStartingPoint.X + aIntermediatePoint.X ) + fB * ( aStartingPoint.Y + aIntermediatePoint.Y );
461 				double fF = fC * ( aStartingPoint.X + aEndingPoint.X ) + fD * ( aStartingPoint.Y + aEndingPoint.Y );
462 
463 				double fG = 2.0 * ( fA * ( aEndingPoint.Y - aIntermediatePoint.Y ) - fB * ( aEndingPoint.X - aIntermediatePoint.X ) );
464 
465 				aCenterPoint.X = ( fD * fE - fB * fF ) / fG;
466 				aCenterPoint.Y = ( fA * fF - fC * fE ) / fG;
467 
468 				if ( fG != 0 )
469 				{
470 					double fStartAngle = ImplGetOrientation( aCenterPoint, aStartingPoint );
471 					double fInterAngle = ImplGetOrientation( aCenterPoint, aIntermediatePoint );
472 					double fEndAngle = ImplGetOrientation( aCenterPoint, aEndingPoint );
473 
474 					if ( fStartAngle > fEndAngle )
475 					{
476 						nSwitch ^=1;
477 						aIntermediatePoint = aEndingPoint;
478 						aEndingPoint = aStartingPoint;
479 						aStartingPoint = aIntermediatePoint;
480 						fG = fStartAngle;
481 						fStartAngle = fEndAngle;
482 						fEndAngle = fG;
483 					}
484 					if ( ! ( fInterAngle > fStartAngle )  && ( fInterAngle < fEndAngle ) )
485 					{
486 						nSwitch ^=1;
487 						aIntermediatePoint = aEndingPoint;
488 						aEndingPoint = aStartingPoint;
489 						aStartingPoint = aIntermediatePoint;
490 						fG = fStartAngle;
491 						fStartAngle = fEndAngle;
492 						fEndAngle = fG;
493 					}
494 					FloatPoint fRadius;
495 					fRadius.Y = fRadius.X = sqrt( pow( ( aStartingPoint.X - aCenterPoint.X ), 2 ) + pow( ( aStartingPoint.Y - aCenterPoint.Y ), 2 ) ) ;
496 
497 					sal_uInt32 nType = ImplGetUI16();
498 					if ( nType == 0 )
499 						nType =	0;			// is PIE
500 					else
501 						nType =	1;			// is CHORD
502 
503 					double fOrientation = 0;
504 					mpOutAct->DrawEllipticalArc( aCenterPoint, fRadius, fOrientation, nType, fStartAngle, fEndAngle );
505 				}
506 			}
507 			break;
508 
509 			case 0x0f : ComOut( CGM_LEVEL1 | CGM_EXTENDED_PRIMITIVES_SET, "Circular Arc Centre" )
510 			{
511 				double fOrientation, fStartAngle, fEndAngle, vector[ 4 ];
512 				FloatPoint aCenter, aRadius;
513 
514 				if ( mbFigure )
515 					mpOutAct->CloseRegion();
516 
517 				ImplGetPoint( aCenter, sal_True );
518 				ImplGetVector( &vector[ 0 ] );
519 
520 				if ( pElement->eVDCType == VDC_REAL )
521 				{
522 					aRadius.X = (double)ImplGetFloat( pElement->eVDCRealPrecision, pElement->nVDCRealSize );
523 				}
524 				else
525 				{
526 					aRadius.X = (double)ImplGetI( pElement->nVDCIntegerPrecision );
527 				}
528 
529 				ImplMapDouble( aRadius.X );
530 				aRadius.Y = aRadius.X;
531 
532 				fStartAngle = acos( vector[ 0 ] / sqrt( vector[ 0 ] * vector[ 0 ] + vector[ 1 ] * vector[ 1 ] ) ) * 57.29577951308;
533 				fEndAngle = acos( vector[ 2 ] / sqrt( vector[ 2 ] * vector[ 2 ] + vector[ 3 ] * vector[ 3 ] ) ) * 57.29577951308;
534 
535 				if ( vector[ 1 ] > 0 )
536 					fStartAngle = 360 - fStartAngle;
537 				if ( vector[ 3 ] > 0 )
538 					fEndAngle = 360 - fEndAngle;
539 
540 				if ( mbAngReverse )
541 					ImplSwitchStartEndAngle( fStartAngle, fEndAngle );
542 
543 				if ( mbFigure )
544 				{
545 					Rectangle aBoundingBox(
546 						Point( (long)( aCenter.X - aRadius.X ), long( aCenter.Y - aRadius.X ) ),
547 						Size( static_cast< long >( 2 * aRadius.X ), (long)( 2 * aRadius.X ) ) );
548 					Polygon aPolygon( aBoundingBox,
549 						Point( (long)vector[ 0 ], (long)vector[ 1 ] ),
550 						Point( (long)vector[ 2 ], (long)vector[ 3 ] ), POLY_ARC );
551 					mpOutAct->RegPolyLine( aPolygon );
552 				}
553 				else
554 				{
555 					fOrientation = 0;
556 					mpOutAct->DrawEllipticalArc( aCenter, aRadius, fOrientation, 2, fStartAngle, fEndAngle );
557 				}
558 				mnParaSize = mnElementSize;
559 
560 			}
561 			break;
562 
563 			case 0x10 : ComOut( CGM_LEVEL1 | CGM_EXTENDED_PRIMITIVES_SET, "Circular Arc Centre Close" )
564 			{
565 				double fOrientation, fStartAngle, fEndAngle, vector[ 4 ];
566 				FloatPoint aCenter, aRadius;
567 
568 				if ( mbFigure )
569 					mpOutAct->CloseRegion();
570 
571 				ImplGetPoint( aCenter, sal_True );
572 				ImplGetVector( &vector[ 0 ] );
573 				if ( pElement->eVDCType == VDC_REAL )
574 				{
575 					aRadius.X = (double)ImplGetFloat( pElement->eVDCRealPrecision, pElement->nVDCRealSize );
576 				}
577 				else
578 				{
579 					aRadius.X = (double)ImplGetI( pElement->nVDCIntegerPrecision );
580 				}
581 				ImplMapDouble( aRadius.X );
582 				aRadius.Y = aRadius.X;
583 				fStartAngle = acos( vector[ 0 ] / sqrt( vector[ 0 ] * vector[ 0 ] + vector[ 1 ] * vector[ 1 ] ) ) * 57.29577951308;
584 				fEndAngle = acos( vector[ 2 ] / sqrt( vector[ 2 ] * vector[ 2 ] + vector[ 3 ] * vector[ 3 ] ) ) * 57.29577951308;
585 
586 				if ( vector[ 1 ] > 0 )
587 					fStartAngle = 360 - fStartAngle;
588 				if ( vector[ 3 ] > 0 )
589 					fEndAngle = 360 - fEndAngle;
590 
591 				if ( mbAngReverse )
592 					ImplSwitchStartEndAngle( fStartAngle, fEndAngle );
593 
594 
595 				sal_uInt32 nType = ImplGetUI16();
596 				if ( nType == 0 )
597 					nType =	0;			// is PIE
598 				else
599 					nType =	1;			// is CHORD
600 				fOrientation = 0;
601 
602 				mpOutAct->DrawEllipticalArc( aCenter, aRadius, fOrientation,
603 							nType, fStartAngle, fEndAngle );
604 				mnParaSize = mnElementSize;
605 			}
606 			break;
607 
608 			case 0x11 : ComOut( CGM_LEVEL1 | CGM_EXTENDED_PRIMITIVES_SET, "Ellipse" )
609 			{
610 				double fOrientation;
611 				FloatPoint aCenter, aRadius;
612 
613 				if ( mbFigure )
614 					mpOutAct->CloseRegion();
615 
616 				ImplGetEllipse( aCenter, aRadius, fOrientation ) ;
617 				mpOutAct->DrawEllipse( aCenter, aRadius, fOrientation ) ;
618 			}
619 			break;
620 
621 			case 0x12 : ComOut( CGM_LEVEL1 | CGM_EXTENDED_PRIMITIVES_SET, "Elliptical Arc" )
622 			{
623 				if ( mbFigure )
624 					mpOutAct->CloseRegion();
625 
626 				double fOrientation, fStartAngle, fEndAngle, vector[ 4 ];
627 				FloatPoint aCenter, aRadius;
628 
629 				if ( mbFigure )
630 					mpOutAct->CloseRegion();
631 
632 				sal_Bool bDirection = ImplGetEllipse( aCenter, aRadius, fOrientation );
633 				ImplGetVector( &vector[ 0 ] );
634 
635 				fStartAngle = acos( vector[ 0 ] / sqrt( vector[ 0 ] * vector[ 0 ] + vector[ 1 ] * vector[ 1 ] ) ) * 57.29577951308;
636 				fEndAngle = acos( vector[ 2 ] / sqrt( vector[ 2 ] * vector[ 2 ] + vector[ 3 ] * vector[ 3 ] ) ) * 57.29577951308;
637 
638 				if ( vector[ 1 ] > 0 )
639 					fStartAngle = 360 - fStartAngle;
640 				if ( vector[ 3 ] > 0 )
641 					fEndAngle = 360 - fEndAngle;
642 
643 				if ( bDirection )
644 					mpOutAct->DrawEllipticalArc( aCenter, aRadius, fOrientation,
645 								2, fStartAngle, fEndAngle );
646 				else
647 					mpOutAct->DrawEllipticalArc( aCenter, aRadius, fOrientation,
648 								2, fEndAngle, fStartAngle);
649 			}
650 			break;
651 
652 			case 0x13 : ComOut( CGM_LEVEL1 | CGM_EXTENDED_PRIMITIVES_SET, "Elliptical Arc Close" )
653 			{
654 				double fOrientation, fStartAngle, fEndAngle, vector[ 4 ];
655 				FloatPoint aCenter, aRadius;
656 
657 				if ( mbFigure )
658 					mpOutAct->CloseRegion();
659 
660 				sal_Bool bDirection = ImplGetEllipse( aCenter, aRadius, fOrientation );
661 				ImplGetVector( &vector[ 0 ] );
662 
663 				fStartAngle = acos( vector[ 0 ] / sqrt( vector[ 0 ] * vector[ 0 ] + vector[ 1 ] * vector[ 1 ] ) ) * 57.29577951308;
664 				fEndAngle = acos( vector[ 2 ] / sqrt( vector[ 2 ] * vector[ 2 ] + vector[ 3 ] * vector[ 3 ] ) ) * 57.29577951308;
665 
666 				if ( vector[ 1 ] > 0 )
667 					fStartAngle = 360 - fStartAngle;
668 				if ( vector[ 3 ] > 0 )
669 					fEndAngle = 360 - fEndAngle;
670 
671 				sal_uInt32 nType = ImplGetUI16();
672 				if ( nType == 0 )
673 					nType =	0;			// is PIE
674 				else
675 					nType =	1;			// is CHORD
676 
677 				if ( bDirection )
678 					mpOutAct->DrawEllipticalArc( aCenter, aRadius, fOrientation,
679 								nType, fStartAngle, fEndAngle );
680 				else
681 					mpOutAct->DrawEllipticalArc( aCenter, aRadius, fOrientation,
682 								nType, fEndAngle, fStartAngle);
683 			}
684 			break;
685 			case 0x14 : ComOut( CGM_LEVEL2, "Circular Arc Centre Reversed" )
686 			{
687 				if ( mbFigure )
688 					mpOutAct->CloseRegion();
689 			}
690 			break;
691 			case 0x15 : ComOut( CGM_LEVEL2, "Connection Edge" )							// NS
692 			{
693 //				if ( mbFigure )
694 //					mpOutAct->CloseRegion();
695 			}
696 			break;
697 			case 0x16 : ComOut( CGM_LEVEL3, "Hyperbolic Arc" )							// NS
698 			{
699 				if ( mbFigure )
700 					mpOutAct->CloseRegion();
701 			}
702 			break;
703 			case 0x17 : ComOut( CGM_LEVEL3, "Parabolic Arc" )							// NS
704 			{
705 				if ( mbFigure )
706 					mpOutAct->CloseRegion();
707 			}
708 			break;
709 			case 0x18 : ComOut( CGM_LEVEL3, "Non Uniform B-Spline" )					// NS
710 			{
711 				if ( mbFigure )
712 					mpOutAct->CloseRegion();
713 			}
714 			break;
715 			case 0x19 : ComOut( CGM_LEVEL3, "Non Uniform Rational B-Spline" )			// NS
716 			{
717 				if ( mbFigure )
718 					mpOutAct->CloseRegion();
719 			}
720 			break;
721 			case 0x1a : ComOut( CGM_LEVEL3, "Polybezier" )
722 			{
723 				sal_uInt32 nOrder = ImplGetI( pElement->nIntegerPrecision );
724 
725 				sal_uInt16 nNumberOfPoints = sal::static_int_cast< sal_uInt16 >(( mnElementSize - pElement->nIntegerPrecision ) / ImplGetPointSize());
726 
727 				Polygon aPolygon( nNumberOfPoints );
728 
729 				for ( sal_uInt16 i = 0; i < nNumberOfPoints; i++)
730 				{
731 					FloatPoint	aFloatPoint;
732 					ImplGetPoint( aFloatPoint, sal_True );
733 					aPolygon.SetPoint( Point ( (long)( aFloatPoint.X ), (long)( aFloatPoint.Y ) ), i );
734 				}
735 				if ( nOrder & 4 )
736 				{
737 					for ( sal_uInt16 i = 0; i < nNumberOfPoints; i++ )
738 					{
739 						if ( ( i % 3 ) == 0 )
740 							aPolygon.SetFlags( i, POLY_NORMAL );
741 						else
742 							aPolygon.SetFlags( i, POLY_CONTROL );
743 					}
744 				}
745 				else
746 				{
747 					for ( sal_uInt16 i = 0; i < nNumberOfPoints; i++ )
748 					{
749 						switch ( i & 3 )
750 						{
751 							case 0 :
752 							case 3 : aPolygon.SetFlags( i, POLY_NORMAL ); break;
753 							default : aPolygon.SetFlags( i, POLY_CONTROL ); break;
754 						}
755 					}
756 				}
757 				if ( mbFigure )
758 					mpOutAct->RegPolyLine( aPolygon );
759 				else
760 					mpOutAct->DrawPolybezier( aPolygon );
761 				mnParaSize = mnElementSize;
762 			}
763 			break;
764 
765 			case 0x1b : ComOut( CGM_LEVEL3, "Polysymbol" )								// NS
766 			{
767 				if ( mbFigure )
768 					mpOutAct->CloseRegion();
769 			}
770 			break;
771 			case 0x1c : ComOut( CGM_LEVEL3, "Bitonal Tile" )							// NS
772 			{
773 				if ( mbFigure )
774 					mpOutAct->CloseRegion();
775 			}
776 			break;
777 			case 0x1d : ComOut( CGM_LEVEL3, "Tile" )									// NS
778 			{
779 				if ( mbFigure )
780 					mpOutAct->CloseRegion();
781 			}
782 			break;
783 			case 0x1e : ComOut( CGM_UNKNOWN_LEVEL, "Insert Object" )
784 			{
785 				if ( mbFigure )
786 					mpOutAct->CloseRegion();
787 			}
788 			break;
789 			case 0xff : ComOut( CGM_GDSF_ONLY, "Polybezier" )
790 			{
791 				if ( mbFigure )
792 					mpOutAct->CloseRegion();
793 			}
794 			break;
795 			case 0xfe : ComOut( CGM_GDSF_ONLY, "Sharp Polybezier" )
796 			{
797 				if ( mbFigure )
798 					mpOutAct->CloseRegion();
799 			}
800 			break;
801 			case 0xfd : ComOut( CGM_GDSF_ONLY, "Polyspline" )
802 			{
803 				if ( mbFigure )
804 					mpOutAct->CloseRegion();
805 			}
806 			break;
807 			case 0xfc : ComOut( CGM_GDSF_ONLY, "Reounded Rectangle" )
808 			{
809 				if ( mbFigure )
810 					mpOutAct->CloseRegion();
811 			}
812 			break;
813 			case 0xfb : ComOut( CGM_GDSF_ONLY, "Begin Cell Array" )
814 			{
815 				if ( mbFigure )
816 					mpOutAct->CloseRegion();
817 			}
818 			break;
819 			case 0xfa : ComOut( CGM_GDSF_ONLY, "End Cell Array" )
820 			{
821 				if ( mbFigure )
822 					mpOutAct->CloseRegion();
823 			}
824 			break;
825 			case 0xf9 : ComOut( CGM_GDSF_ONLY, "Insert File" )
826 			{
827 				if ( mbFigure )
828 					mpOutAct->CloseRegion();
829 			}
830 			break;
831 			case 0xf8 : ComOut( CGM_GDSF_ONLY, "Block Text" )
832 			{
833 				if ( mbFigure )
834 					mpOutAct->CloseRegion();
835 			}
836 			break;
837 			case 0xf7 : ComOut( CGM_GDSF_ONLY, "Variable Width Polyline" )
838 			{
839 				if ( mbFigure )
840 					mpOutAct->CloseRegion();
841 			}
842 			break;
843 			case 0xf6 : ComOut( CGM_GDSF_ONLY, "Elliptical Arc 3 Point" )
844 			{
845 				if ( mbFigure )
846 					mpOutAct->CloseRegion();
847 			}
848 			break;
849 			case 0xf1 : ComOut( CGM_GDSF_ONLY, "Hyperlink Definition" )	break;
850 			default: ComOut( CGM_UNKNOWN_COMMAND, "" ) break;
851 		}
852 	}
853 	else
854 		mnParaSize = mnElementSize;
855 };
856 
857 
858