LibreOffice Module filter (master) 1
class4.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20
21#include "bitmap.hxx"
22#include "cgm.hxx"
23#include "chart.hxx"
24#include "elements.hxx"
25#include "outact.hxx"
26
28#include <o3tl/safeint.hxx>
29
30#include <memory>
31
32using namespace ::com::sun::star;
33
34double CGM::ImplGetOrientation( FloatPoint const & rCenter, FloatPoint const & rPoint )
35{
36 double nX = rPoint.X - rCenter.X;
37 double nY = rPoint.Y - rCenter.Y;
38
39 double fSqrt = std::hypot(nX, nY);
40 double fOrientation = fSqrt != 0.0 ? basegfx::rad2deg(acos(nX / fSqrt)) : 0.0;
41 if (nY > 0)
42 fOrientation = 360 - fOrientation;
43
44 return fOrientation;
45}
46
47
48void CGM::ImplSwitchStartEndAngle( double& rStartAngle, double& rEndAngle )
49{
50 double nTemp;
51 nTemp = rStartAngle;
52 rStartAngle = rEndAngle;
53 rEndAngle = nTemp;
54}
55
56
57void CGM::ImplGetVector( double* pVector )
58{
59 if ( pElement->eVDCType == VDC_REAL )
60 {
61 for ( sal_uInt32 i = 0; i < 4; i++ )
62 {
63 pVector[ i ] = ImplGetFloat( pElement->eVDCRealPrecision, pElement->nVDCRealSize );
64 }
65 }
66 else
67 {
68 for ( sal_uInt32 i = 0; i < 4; i++ )
69 {
70 pVector[ i ] = static_cast<double>(ImplGetI( pElement->nVDCIntegerPrecision ));
71 }
72 }
73 pVector[ 0 ] *= mnVDCXmul;
74 pVector[ 2 ] *= mnVDCXmul;
75 pVector[ 1 ] *= mnVDCYmul;
76 pVector[ 3 ] *= mnVDCYmul;
77}
78
79
80bool CGM::ImplGetEllipse( FloatPoint& rCenter, FloatPoint& rRadius, double& rAngle )
81{
82 FloatPoint aPoint1, aPoint2;
83 double fRot1, fRot2;
84 ImplGetPoint( rCenter, true );
85 ImplGetPoint( aPoint1, true );
86 ImplGetPoint( aPoint2, true );
87 fRot1 = ImplGetOrientation( rCenter, aPoint1 );
88 fRot2 = ImplGetOrientation( rCenter, aPoint2 );
89 rAngle = ImplGetOrientation( rCenter, aPoint1 );
90 aPoint1.X -= rCenter.X;
91 aPoint1.Y -= rCenter.Y;
92 rRadius.X = 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);
96
97 if ( fRot1 > fRot2 )
98 {
99 if ( ( fRot1 - fRot2 ) < 180 )
100 return false;
101 }
102 else
103 {
104 if ( ( fRot2 - fRot1 ) > 180 )
105 return false;
106 }
107 return true;
108}
109
111{
112 if ( mbFirstOutPut )
113 mpOutAct->FirstOutPut();
114
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();
121 }
122
123 if ( ( mpChart == nullptr ) || mpChart->IsAnnotation() )
124 {
125 switch ( mnElementID )
126 {
127 case 0x01 : /*PolyLine*/
128 {
129 sal_uInt32 nPoints = mnElementSize / ImplGetPointSize();
130 tools::Polygon aPolygon( static_cast<sal_uInt16>(nPoints) );
131 for ( sal_uInt32 i = 0; i < nPoints; i++)
132 {
133 FloatPoint aFloatPoint;
134 ImplGetPoint( aFloatPoint, true );
135 aPolygon.SetPoint( Point( static_cast<tools::Long>(aFloatPoint.X), static_cast<tools::Long>(aFloatPoint.Y) ), i );
136 }
137 if ( mbFigure )
138 mpOutAct->RegPolyLine( aPolygon );
139 else
140 mpOutAct->DrawPolyLine( aPolygon );
141 }
142 break;
143
144 case 0x02 : /*Disjoint PolyLine*/
145 {
146 sal_uInt16 nPoints = sal::static_int_cast< sal_uInt16 >(
148 if ( ! ( nPoints & 1 ) )
149 {
150 nPoints >>= 1;
151 FloatPoint aFloatPoint;
152 if ( mbFigure )
153 {
154 tools::Polygon aPolygon( nPoints );
155 for ( sal_uInt16 i = 0; i < nPoints; i++ )
156 {
157 ImplGetPoint( aFloatPoint, true );
158 aPolygon.SetPoint( Point( static_cast<tools::Long>(aFloatPoint.X), static_cast<tools::Long>(aFloatPoint.Y) ), 0 );
159 }
160 mpOutAct->RegPolyLine( aPolygon );
161 }
162 else
163 {
164 mpOutAct->BeginGroup();
165 tools::Polygon aPolygon( sal_uInt16(2) );
166 for ( sal_uInt16 i = 0; i < nPoints; i++ )
167 {
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 );
173 }
174 mpOutAct->EndGroup();
175 }
176 }
177 }
178 break;
179
180 case 0x03 : /*PolyMarker*/ break;
181 case 0x04 : /*Text*/
182 {
183 FloatPoint aFloatPoint;
184
185 if ( mbFigure )
186 mpOutAct->CloseRegion();
187
188 ImplGetPoint ( aFloatPoint, true );
189 sal_uInt32 nType = ImplGetUI16();
190 sal_uInt32 nSize = ImplGetUI( 1 );
191
193 throw css::uno::Exception("attempt to read past end of input", nullptr);
194
195 OUString aStr(reinterpret_cast<char*>(mpSource) + mnParaSize, nSize, RTL_TEXTENCODING_ASCII_US);
196
197 awt::Size aSize;
198 awt::Point aPoint( static_cast<tools::Long>(aFloatPoint.X), static_cast<tools::Long>(aFloatPoint.Y) );
199 mpOutAct->DrawText(aPoint, aSize, aStr, static_cast<FinalFlag>(nType));
201 }
202 break;
203
204 case 0x05 : /*Restricted Text*/
205 {
206 double dx, dy;
207 FloatPoint aFloatPoint;
208
209 if ( mbFigure )
210 mpOutAct->CloseRegion();
211
212 if ( pElement->eVDCType == VDC_REAL )
213 {
214 dx = ImplGetFloat( pElement->eVDCRealPrecision, pElement->nVDCRealSize );
215 dy = ImplGetFloat( pElement->eVDCRealPrecision, pElement->nVDCRealSize );
216 }
217 else
218 {
219 dx = static_cast<double>(ImplGetI( pElement->nVDCIntegerPrecision ));
220 dy = static_cast<double>(ImplGetI( pElement->nVDCIntegerPrecision ));
221 }
222 ImplMapDouble( dx );
223 ImplMapDouble( dy );
224
225 ImplGetPoint ( aFloatPoint, true );
226 sal_uInt32 nType = ImplGetUI16();
227 sal_uInt32 nSize = ImplGetUI(1);
228
230 throw css::uno::Exception("attempt to read past end of input", nullptr);
231
232 OUString aStr(reinterpret_cast<char*>(mpSource) + mnParaSize, nSize, RTL_TEXTENCODING_ASCII_US);
233
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));
238 }
239 break;
240
241 case 0x06 : /*Append Text*/
242 {
243 (void)ImplGetUI16(); // nType
244 sal_uInt32 nSize = ImplGetUI( 1 );
245
247 throw css::uno::Exception("attempt to read past end of input", nullptr);
248
249 mpSource[ mnParaSize + nSize ] = 0;
250
251 mpOutAct->AppendText( reinterpret_cast<char*>(mpSource) + mnParaSize );
253 }
254 break;
255
256 case 0x07 : /*Polygon*/
257 {
258 if ( mbFigure )
259 mpOutAct->CloseRegion();
260
261 sal_uInt16 nPoints = sal::static_int_cast< sal_uInt16 >(
263 tools::Polygon aPolygon( nPoints );
264 for ( sal_uInt16 i = 0; i < nPoints; i++)
265 {
266 FloatPoint aFloatPoint;
267 ImplGetPoint( aFloatPoint, true );
268 aPolygon.SetPoint( Point ( static_cast<tools::Long>( aFloatPoint.X ), static_cast<tools::Long>( aFloatPoint.Y ) ), i );
269 }
270 mpOutAct->DrawPolygon( aPolygon );
271 }
272 break;
273
274 case 0x08 : /*Polygon Set*/
275 {
276 if ( mbFigure )
277 mpOutAct->CloseRegion();
278
279 std::vector<Point> aPoints;
280 tools::PolyPolygon aPolyPolygon;
281 FloatPoint aFloatPoint;
282
283 while ( mnParaSize < mnElementSize )
284 {
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 ) )
289 {
290 aPolyPolygon.Insert(tools::Polygon(aPoints.size(), aPoints.data()));
291 aPoints.clear();
292 }
293 }
294 mpOutAct->DrawPolyPolygon( aPolyPolygon );
295 }
296 break;
297
298 case 0x09 : /*Cell Array*/
299 {
300 if ( mbFigure )
301 mpOutAct->CloseRegion();
302
303 if ( mpBitmapInUse )
304 {
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());
309 }
310 }
311 else
312 {
313 mpBitmapInUse.reset( new CGMBitmap( *this ) );
314 }
315 }
316 break;
317
318 case 0x0a : /*Generalized Drawing Primitive*/
319 {
320 ImplGetI( pElement->nIntegerPrecision ); //-Wall is this needed
321 ImplGetUI( pElement->nIntegerPrecision ); //-Wall is this needed
323 }
324 break;
325
326 case 0x0b : /*Rectangle*/
327 {
328 if ( mbFigure )
329 mpOutAct->CloseRegion();
330
331 FloatRect aFloatRect;
332 ImplGetRectangle( aFloatRect, true );
333 mpOutAct->DrawRectangle( aFloatRect );
334 }
335 break;
336
337 case 0x0c : /*Circle*/
338 {
339 if ( mbFigure )
340 mpOutAct->CloseRegion();
341
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 );
347 else
348 aRadius.X = static_cast<double>(ImplGetI( pElement->nVDCIntegerPrecision ));
349 ImplMapDouble( aRadius.X );
350 aRadius.Y = aRadius.X;
351 mpOutAct->DrawEllipse( aCenter, aRadius, fRotation );
352 }
353 break;
354
355 case 0x0d : /*Circular Arc 3 Point*/
356 {
357 FloatPoint aStartingPoint, aIntermediatePoint, aEndingPoint;
358 ImplGetPoint( aStartingPoint, true );
359 ImplGetPoint( aIntermediatePoint, true );
360 ImplGetPoint( aEndingPoint, true );
361
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;
366
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 );
369
370 double fG = 2.0 * ( fA * ( aEndingPoint.Y - aIntermediatePoint.Y ) - fB * ( aEndingPoint.X - aIntermediatePoint.X ) );
371
372 bool bUseless = fG == 0;
373
374 FloatPoint aCenterPoint;
375 if (!bUseless)
376 {
377 aCenterPoint.X = ( fD * fE - fB * fF ) / fG;
378 aCenterPoint.Y = ( fA * fF - fC * fE ) / fG;
379 bUseless = useless(aCenterPoint.X) || useless(aCenterPoint.Y);
380 }
381
382 if (!bUseless)
383 bUseless = useless(aStartingPoint.X) || useless(aStartingPoint.Y);
384
385 if (!bUseless)
386 {
387 double fStartAngle = ImplGetOrientation( aCenterPoint, aStartingPoint );
388 double fInterAngle = ImplGetOrientation( aCenterPoint, aIntermediatePoint );
389 double fEndAngle = ImplGetOrientation( aCenterPoint, aEndingPoint );
390
391 int nSwitch = 0;
392
393 if ( fStartAngle > fEndAngle )
394 {
395 nSwitch ^=1;
396 aIntermediatePoint = aEndingPoint;
397 aEndingPoint = aStartingPoint;
398 aStartingPoint = aIntermediatePoint;
399 fG = fStartAngle;
400 fStartAngle = fEndAngle;
401 fEndAngle = fG;
402 }
403 if ( ! ( fInterAngle > fStartAngle ) && ( fInterAngle < fEndAngle ) )
404 {
405 nSwitch ^=1;
406 aIntermediatePoint = aEndingPoint;
407 aEndingPoint = aStartingPoint;
408 aStartingPoint = aIntermediatePoint;
409 fG = fStartAngle;
410 fStartAngle = fEndAngle;
411 fEndAngle = fG;
412 }
413 double fRadius = std::hypot(aStartingPoint.X - aCenterPoint.X, aStartingPoint.Y - aCenterPoint.Y);
414
415 if ( mbFigure )
416 {
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);
422 if (!bUseless)
423 {
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());
427 }
428 if (!bUseless)
429 {
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());
433 }
434 if (!bUseless)
435 {
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 );
438 if ( nSwitch )
439 mpOutAct->RegPolyLine( aPolygon, true );
440 else
441 mpOutAct->RegPolyLine( aPolygon );
442 }
443 }
444 else
445 {
446 fG = 0;
447 FloatPoint aRadius;
448 aRadius.X = aRadius.Y = fRadius;
449 mpOutAct->DrawEllipticalArc( aCenterPoint, aRadius, fG, 2, fStartAngle, fEndAngle );
450 }
451 }
452 }
453 break;
454
455 case 0x0e : /*Circular Arc 3 Point Close*/
456 {
457 if ( mbFigure )
458 mpOutAct->CloseRegion();
459
460 FloatPoint aStartingPoint, aIntermediatePoint, aEndingPoint;
461 ImplGetPoint( aStartingPoint );
462 ImplGetPoint( aIntermediatePoint );
463 ImplGetPoint( aEndingPoint );
464
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;
469
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 );
472
473 double fG = 2.0 * ( fA * ( aEndingPoint.Y - aIntermediatePoint.Y ) - fB * ( aEndingPoint.X - aIntermediatePoint.X ) );
474
475 if ( fG != 0 )
476 {
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 );
483
484 if ( fStartAngle > fEndAngle )
485 {
486 aIntermediatePoint = aEndingPoint;
487 aEndingPoint = aStartingPoint;
488 aStartingPoint = aIntermediatePoint;
489 fG = fStartAngle;
490 fStartAngle = fEndAngle;
491 fEndAngle = fG;
492 }
493 if ( ! ( fInterAngle > fStartAngle ) && ( fInterAngle < fEndAngle ) )
494 {
495 aIntermediatePoint = aEndingPoint;
496 aEndingPoint = aStartingPoint;
497 aStartingPoint = aIntermediatePoint;
498 fG = fStartAngle;
499 fStartAngle = fEndAngle;
500 fEndAngle = fG;
501 }
502 FloatPoint fRadius;
503 fRadius.Y = fRadius.X = std::hypot(aStartingPoint.X - aCenterPoint.X, aStartingPoint.Y - aCenterPoint.Y);
504
505 sal_uInt32 nType = ImplGetUI16();
506 if ( nType == 0 )
507 nType = 0; // is PIE
508 else
509 nType = 1; // is CHORD
510
511 double fOrientation = 0;
512 mpOutAct->DrawEllipticalArc( aCenterPoint, fRadius, fOrientation, nType, fStartAngle, fEndAngle );
513 }
514 }
515 break;
516
517 case 0x0f : /*Circular Arc Centre*/
518 {
519 double fStartAngle, fEndAngle, vector[ 4 ];
520 FloatPoint aCenter, aRadius;
521
522 if ( mbFigure )
523 mpOutAct->CloseRegion();
524
525 ImplGetPoint( aCenter, true );
526 ImplGetVector( &vector[ 0 ] );
527
528 if ( pElement->eVDCType == VDC_REAL )
529 {
530 aRadius.X = ImplGetFloat( pElement->eVDCRealPrecision, pElement->nVDCRealSize );
531 }
532 else
533 {
534 aRadius.X = static_cast<double>(ImplGetI( pElement->nVDCIntegerPrecision ));
535 }
536
537 ImplMapDouble( aRadius.X );
538 aRadius.Y = aRadius.X;
539
540 bool bUseless = useless(vector[0]) || useless(vector[1]) || useless(vector[2]) || useless(vector[3]);
541 if (!bUseless)
542 {
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;
547
548 if ( vector[ 1 ] > 0 )
549 fStartAngle = 360 - fStartAngle;
550 if ( vector[ 3 ] > 0 )
551 fEndAngle = 360 - fEndAngle;
552
553 if ( mbAngReverse )
554 ImplSwitchStartEndAngle( fStartAngle, fEndAngle );
555
556 if ( mbFigure )
557 {
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);
563 if (!bUseless)
564 {
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());
568 }
569 if (!bUseless)
570 {
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());
574 }
575 if (!bUseless)
576 {
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 );
582 }
583 }
584 else
585 {
586 double fOrientation = 0;
587 mpOutAct->DrawEllipticalArc( aCenter, aRadius, fOrientation, 2, fStartAngle, fEndAngle );
588 }
589 }
590
592 }
593 break;
594
595 case 0x10 : /*Circular Arc Centre Close*/
596 {
597 double fOrientation, vector[ 4 ];
598 FloatPoint aCenter, aRadius;
599
600 if ( mbFigure )
601 mpOutAct->CloseRegion();
602
603 ImplGetPoint( aCenter, true );
604 ImplGetVector( &vector[ 0 ] );
605 if ( pElement->eVDCType == VDC_REAL )
606 {
607 aRadius.X = ImplGetFloat( pElement->eVDCRealPrecision, pElement->nVDCRealSize );
608 }
609 else
610 {
611 aRadius.X = static_cast<double>(ImplGetI( pElement->nVDCIntegerPrecision ));
612 }
613 ImplMapDouble( aRadius.X );
614 aRadius.Y = aRadius.X;
615
616 sal_uInt32 nType = ImplGetUI16();
617
618 bool bUseless = useless(vector[0]) || useless(vector[1]) || useless(vector[2]) || useless(vector[3]);
619 if (!bUseless)
620 {
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;
625
626 if ( vector[ 1 ] > 0 )
627 fStartAngle = 360 - fStartAngle;
628 if ( vector[ 3 ] > 0 )
629 fEndAngle = 360 - fEndAngle;
630
631 if ( mbAngReverse )
632 ImplSwitchStartEndAngle( fStartAngle, fEndAngle );
633
634 if ( nType == 0 )
635 nType = 0; // is PIE
636 else
637 nType = 1; // is CHORD
638 fOrientation = 0;
639
640 mpOutAct->DrawEllipticalArc( aCenter, aRadius, fOrientation,
641 nType, fStartAngle, fEndAngle );
642 }
643
645 }
646 break;
647
648 case 0x11 : /*Ellipse*/
649 {
650 double fOrientation;
651 FloatPoint aCenter, aRadius;
652
653 if ( mbFigure )
654 mpOutAct->CloseRegion();
655
656 ImplGetEllipse( aCenter, aRadius, fOrientation ) ;
657 mpOutAct->DrawEllipse( aCenter, aRadius, fOrientation ) ;
658 }
659 break;
660
661 case 0x12 : /*Elliptical Arc*/
662 {
663 if ( mbFigure )
664 mpOutAct->CloseRegion();
665
666 double fOrientation, fStartAngle, fEndAngle, vector[ 4 ];
667 FloatPoint aCenter, aRadius;
668
669 if ( mbFigure )
670 mpOutAct->CloseRegion();
671
672 bool bDirection = ImplGetEllipse( aCenter, aRadius, fOrientation );
673 ImplGetVector( &vector[ 0 ] );
674
675 bool bUseless = useless(vector[0]) || useless(vector[1]) || useless(vector[2]) || useless(vector[3]);
676 if (!bUseless)
677 {
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;
682
683 if ( vector[ 1 ] > 0 )
684 fStartAngle = 360 - fStartAngle;
685 if ( vector[ 3 ] > 0 )
686 fEndAngle = 360 - fEndAngle;
687
688 if ( bDirection )
689 mpOutAct->DrawEllipticalArc( aCenter, aRadius, fOrientation,
690 2, fStartAngle, fEndAngle );
691 else
692 mpOutAct->DrawEllipticalArc( aCenter, aRadius, fOrientation,
693 2, fEndAngle, fStartAngle);
694 }
695 }
696 break;
697
698 case 0x13 : /*Elliptical Arc Close*/
699 {
700 double fOrientation, fStartAngle, fEndAngle, vector[ 4 ];
701 FloatPoint aCenter, aRadius;
702
703 if ( mbFigure )
704 mpOutAct->CloseRegion();
705
706 bool bDirection = ImplGetEllipse( aCenter, aRadius, fOrientation );
707 ImplGetVector( &vector[ 0 ] );
708
709 sal_uInt32 nType = ImplGetUI16();
710
711 bool bUseless = useless(vector[0]) || useless(vector[1]) || useless(vector[2]) || useless(vector[3]);
712 if (!bUseless)
713 {
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;
718
719 if ( vector[ 1 ] > 0 )
720 fStartAngle = 360 - fStartAngle;
721 if ( vector[ 3 ] > 0 )
722 fEndAngle = 360 - fEndAngle;
723
724 if ( nType == 0 )
725 nType = 0; // is PIE
726 else
727 nType = 1; // is CHORD
728
729 if ( bDirection )
730 mpOutAct->DrawEllipticalArc( aCenter, aRadius, fOrientation,
731 nType, fStartAngle, fEndAngle );
732 else
733 mpOutAct->DrawEllipticalArc( aCenter, aRadius, fOrientation,
734 nType, fEndAngle, fStartAngle);
735 }
736 }
737 break;
738 case 0x14 : /*Circular Arc Centre Reversed*/
739 {
740 if ( mbFigure )
741 mpOutAct->CloseRegion();
742 }
743 break;
744 case 0x15 : /*Connection Edge */ // NS
745 {
746// if ( mbFigure )
747// mpOutAct->CloseRegion();
748 }
749 break;
750 case 0x16 : /*Hyperbolic Arc */ // NS
751 {
752 if ( mbFigure )
753 mpOutAct->CloseRegion();
754 }
755 break;
756 case 0x17 : /*Parabolic Arc */ // NS
757 {
758 if ( mbFigure )
759 mpOutAct->CloseRegion();
760 }
761 break;
762 case 0x18 : /*Non Uniform B-Spline */ // NS
763 {
764 if ( mbFigure )
765 mpOutAct->CloseRegion();
766 }
767 break;
768 case 0x19 : /*Non Uniform Rational B-Spline */ // NS
769 {
770 if ( mbFigure )
771 mpOutAct->CloseRegion();
772 }
773 break;
774 case 0x1a : /*Polybezier*/
775 {
776 sal_uInt32 nOrder = ImplGetI( pElement->nIntegerPrecision );
777
778 sal_uInt16 nNumberOfPoints = sal::static_int_cast< sal_uInt16 >(( mnElementSize - pElement->nIntegerPrecision ) / ImplGetPointSize());
779
780 tools::Polygon aPolygon( nNumberOfPoints );
781
782 for ( sal_uInt16 i = 0; i < nNumberOfPoints; i++)
783 {
784 FloatPoint aFloatPoint;
785 ImplGetPoint( aFloatPoint, true );
786 aPolygon.SetPoint( Point ( static_cast<tools::Long>( aFloatPoint.X ), static_cast<tools::Long>( aFloatPoint.Y ) ), i );
787 }
788 if ( nOrder & 4 )
789 {
790 for ( sal_uInt16 i = 0; i < nNumberOfPoints; i++ )
791 {
792 if ( ( i % 3 ) == 0 )
793 aPolygon.SetFlags( i, PolyFlags::Normal );
794 else
795 aPolygon.SetFlags( i, PolyFlags::Control );
796 }
797 }
798 else
799 {
800 for ( sal_uInt16 i = 0; i < nNumberOfPoints; i++ )
801 {
802 switch ( i & 3 )
803 {
804 case 0 :
805 case 3 : aPolygon.SetFlags( i, PolyFlags::Normal ); break;
806 default : aPolygon.SetFlags( i, PolyFlags::Control ); break;
807 }
808 }
809 }
810 if ( mbFigure )
811 mpOutAct->RegPolyLine( aPolygon );
812 else
813 mpOutAct->DrawPolybezier( aPolygon );
815 }
816 break;
817
818 case 0x1b : /*Polysymbol */ // NS
819 {
820 if ( mbFigure )
821 mpOutAct->CloseRegion();
822 }
823 break;
824 case 0x1c : /*Bitonal Tile */ // NS
825 {
826 if ( mbFigure )
827 mpOutAct->CloseRegion();
828 }
829 break;
830 case 0x1d : /*Tile */ // NS
831 {
832 if ( mbFigure )
833 mpOutAct->CloseRegion();
834 }
835 break;
836 case 0x1e : /*Insert Object*/
837 {
838 if ( mbFigure )
839 mpOutAct->CloseRegion();
840 }
841 break;
842 case 0xff : /*Polybezier*/
843 {
844 if ( mbFigure )
845 mpOutAct->CloseRegion();
846 }
847 break;
848 case 0xfe : /*Sharp Polybezier*/
849 {
850 if ( mbFigure )
851 mpOutAct->CloseRegion();
852 }
853 break;
854 case 0xfd : /*Polyspline*/
855 {
856 if ( mbFigure )
857 mpOutAct->CloseRegion();
858 }
859 break;
860 case 0xfc : /*Rounded Rectangle*/
861 {
862 if ( mbFigure )
863 mpOutAct->CloseRegion();
864 }
865 break;
866 case 0xfb : /*Begin Cell Array*/
867 {
868 if ( mbFigure )
869 mpOutAct->CloseRegion();
870 }
871 break;
872 case 0xfa : /*End Cell Array*/
873 {
874 if ( mbFigure )
875 mpOutAct->CloseRegion();
876 }
877 break;
878 case 0xf9 : /*Insert File*/
879 {
880 if ( mbFigure )
881 mpOutAct->CloseRegion();
882 }
883 break;
884 case 0xf8 : /*Block Text*/
885 {
886 if ( mbFigure )
887 mpOutAct->CloseRegion();
888 }
889 break;
890 case 0xf7 : /*Variable Width Polyline*/
891 {
892 if ( mbFigure )
893 mpOutAct->CloseRegion();
894 }
895 break;
896 case 0xf6 : /*Elliptical Arc 3 Point*/
897 {
898 if ( mbFigure )
899 mpOutAct->CloseRegion();
900 }
901 break;
902 case 0xf1 : /*Hyperlink Definition */break;
903 default: break;
904 }
905 }
906 else
908};
909
910
911/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
bool useless(double value)
Definition: cgm.hxx:142
FinalFlag
Definition: cgmtypes.hxx:106
@ VDC_REAL
Definition: cgmtypes.hxx:89
std::unique_ptr< CGMBitmap > mpBitmapInUse
Definition: cgm.hxx:65
void ImplDoClass4()
Definition: class4.cxx:110
static double ImplGetOrientation(FloatPoint const &rCenter, FloatPoint const &rPoint)
Definition: class4.cxx:34
std::unique_ptr< CGMChart > mpChart
Definition: cgm.hxx:66
static void ImplSwitchStartEndAngle(double &rStartAngle, double &rEndAngle)
Definition: class4.cxx:48
std::unique_ptr< CGMImpressOutAct > mpOutAct
Definition: cgm.hxx:71
friend class CGMBitmap
Definition: cgm.hxx:41
double ImplGetFloat(RealPrecision, sal_uInt32 nRealSize)
Definition: cgm.cxx:172
bool ImplGetEllipse(FloatPoint &rCenter, FloatPoint &rRadius, double &rOrientation)
Definition: class4.cxx:80
double mnVDCXmul
Definition: cgm.hxx:47
void ImplGetVector(double *)
Definition: class4.cxx:57
bool mbAngReverse
Definition: cgm.hxx:53
sal_Int32 ImplGetI(sal_uInt32 nPrecision)
Definition: cgm.cxx:96
void ImplMapDouble(double &)
Definition: cgm.cxx:420
sal_uInt32 mnElementID
Definition: cgm.hxx:86
sal_uInt32 ImplGetUI16()
Definition: cgm.cxx:82
sal_uInt8 * mpSource
Definition: cgm.hxx:75
void ImplGetPoint(FloatPoint &rFloatPoint, bool bMap=false)
Definition: cgm.cxx:274
bool mbFirstOutPut
Definition: cgm.hxx:61
bool mbFigure
Definition: cgm.hxx:60
void ImplGetRectangle(FloatRect &, bool bMap=false)
Definition: cgm.cxx:290
sal_uInt8 * mpEndValidSource
Definition: cgm.hxx:77
sal_uInt32 ImplGetUI(sal_uInt32 nPrecision)
Definition: cgm.cxx:128
sal_uInt32 mnElementSize
Definition: cgm.hxx:87
std::unique_ptr< CGMElements > pElement
Definition: cgm.hxx:69
sal_uInt32 ImplGetPointSize()
Definition: cgm.cxx:246
double mnVDCYmul
Definition: cgm.hxx:48
sal_uInt32 mnParaSize
Definition: cgm.hxx:78
void Insert(const tools::Polygon &rPoly, sal_uInt16 nPos=POLYPOLY_APPEND)
void SetPoint(const Point &rPt, sal_uInt16 nPos)
void SetFlags(sal_uInt16 nPos, PolyFlags eFlags)
aStr
constexpr double rad2deg(double v)
Shape IDs per cluster in DGG atom.
int i
Definition: gentoken.py:48
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
constexpr std::enable_if_t< std::is_floating_point_v< F > &&std::is_integral_v< I >, bool > convertsToAtLeast(F value, I min)
constexpr std::enable_if_t< std::is_floating_point_v< F > &&std::is_integral_v< I >, bool > convertsToAtMost(F value, I max)
long Long
QPRO_FUNC_TYPE nType
double Y
Definition: cgmtypes.hxx:27
double X
Definition: cgmtypes.hxx:26