xref: /AOO41X/main/filter/source/graphicfilter/icgm/class4.cxx (revision 9e0fc027f109ec4ffcb6033aeec742a099701108)
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