1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/config.h>
22 #include <o3tl/any.hxx>
23 #include <o3tl/safeint.hxx>
24 #include <vcl/bitmapex.hxx>
25 #include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
26 #include <com/sun/star/drawing/LineStyle.hpp>
27 #include <com/sun/star/drawing/LineDash.hpp>
28 #include <com/sun/star/drawing/FillStyle.hpp>
29 #include <com/sun/star/drawing/Hatch.hpp>
30 #include <com/sun/star/awt/FontDescriptor.hpp>
31 #include <com/sun/star/awt/FontWeight.hpp>
32 #include <com/sun/star/awt/FontUnderline.hpp>
33 #include <com/sun/star/drawing/XShapeGrouper.hpp>
34 #include <com/sun/star/drawing/CircleKind.hpp>
35 #include <com/sun/star/awt/XBitmap.hpp>
36 #include <com/sun/star/drawing/PointSequenceSequence.hpp>
37 #include <com/sun/star/drawing/PointSequence.hpp>
38 #include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp>
39 #include <com/sun/star/drawing/FlagSequence.hpp>
40 #include <com/sun/star/drawing/ShapeCollection.hpp>
41 #include <com/sun/star/drawing/TextAdjust.hpp>
42 #include <com/sun/star/text/XText.hpp>
43 #include <com/sun/star/text/XTextRange.hpp>
44 #include <com/sun/star/style/HorizontalAlignment.hpp>
46 #include <comphelper/processfactory.hxx>
47 #include <toolkit/helper/vclunohelper.hxx>
48 #include <tools/helpers.hxx>
49 #include <unotools/configmgr.hxx>
52 #include "elements.hxx"
55 #define MAX_PAGES_FOR_FUZZING 2048
57 using namespace ::com::sun::star
;
59 CGMImpressOutAct::CGMImpressOutAct(CGM
& rCGM
, const uno::Reference
< frame::XModel
> & rModel
)
67 if ( !mpCGM
->mbStatus
)
70 bool bStatRet
= false;
72 uno::Reference
< drawing::XDrawPagesSupplier
> aDrawPageSup( rModel
, uno::UNO_QUERY
);
73 if( aDrawPageSup
.is() )
75 maXDrawPages
= aDrawPageSup
->getDrawPages();
76 if ( maXDrawPages
.is() )
78 maXMultiServiceFactory
.set( rModel
, uno::UNO_QUERY
);
79 if( maXMultiServiceFactory
.is() )
81 maXDrawPage
= *o3tl::doAccess
<uno::Reference
<drawing::XDrawPage
>>(maXDrawPages
->getByIndex( 0 ));
87 mpCGM
->mbStatus
= bStatRet
;
90 CGMImpressOutAct::~CGMImpressOutAct()
92 for (auto &a
: maLockedNewXShapes
)
93 a
->removeActionLock();
96 bool CGMImpressOutAct::ImplInitPage()
98 bool bStatRet
= false;
99 if( maXDrawPage
.is() )
101 maXShapes
= maXDrawPage
;
102 if ( maXShapes
.is() )
110 bool CGMImpressOutAct::ImplCreateShape( const OUString
& rType
)
112 if (utl::ConfigManager::IsFuzzing())
114 uno::Reference
< uno::XInterface
> xNewShape( maXMultiServiceFactory
->createInstance( rType
) );
115 maXShape
.set( xNewShape
, uno::UNO_QUERY
);
116 maXPropSet
.set( xNewShape
, uno::UNO_QUERY
);
117 if ( maXShape
.is() && maXPropSet
.is() )
119 maXShapes
->add( maXShape
);
120 uno::Reference
<document::XActionLockable
> xLockable(maXShape
, uno::UNO_QUERY
);
123 xLockable
->addActionLock();
124 maLockedNewXShapes
.push_back(xLockable
);
131 void CGMImpressOutAct::ImplSetOrientation( FloatPoint
const & rRefPoint
, double rOrientation
)
133 maXPropSet
->setPropertyValue( "RotationPointX", uno::Any(static_cast<sal_Int32
>(rRefPoint
.X
)) );
134 maXPropSet
->setPropertyValue( "RotationPointY", uno::Any(static_cast<sal_Int32
>(rRefPoint
.Y
)) );
135 maXPropSet
->setPropertyValue( "RotateAngle", uno::Any(static_cast<sal_Int32
>( rOrientation
* 100.0 )) );
139 void CGMImpressOutAct::ImplSetLineBundle()
141 drawing::LineStyle eLS
;
143 sal_uInt32 nLineColor
;
147 if ( mpCGM
->pElement
->nAspectSourceFlags
& ASF_LINECOLOR
)
148 nLineColor
= mpCGM
->pElement
->pLineBundle
->GetColor();
150 nLineColor
= mpCGM
->pElement
->aLineBundle
.GetColor();
151 if ( mpCGM
->pElement
->nAspectSourceFlags
& ASF_LINETYPE
)
152 eLineType
= mpCGM
->pElement
->pLineBundle
->eLineType
;
154 eLineType
= mpCGM
->pElement
->aLineBundle
.eLineType
;
155 if ( mpCGM
->pElement
->nAspectSourceFlags
& ASF_LINEWIDTH
)
156 fLineWidth
= mpCGM
->pElement
->pLineBundle
->nLineWidth
;
158 fLineWidth
= mpCGM
->pElement
->aLineBundle
.nLineWidth
;
160 maXPropSet
->setPropertyValue( "LineColor", uno::Any(static_cast<sal_Int32
>(nLineColor
)) );
162 maXPropSet
->setPropertyValue( "LineWidth", uno::Any(static_cast<sal_Int32
>(fLineWidth
)) );
167 eLS
= drawing::LineStyle_NONE
;
172 case LT_DOTDOTSPACE
:
174 case LT_DASHDASHDOT
:
175 eLS
= drawing::LineStyle_DASH
;
179 eLS
= drawing::LineStyle_SOLID
;
182 maXPropSet
->setPropertyValue( "LineStyle", uno::Any(eLS
) );
183 if ( eLS
== drawing::LineStyle_DASH
)
185 drawing::LineDash
aLineDash( drawing::DashStyle_RECTRELATIVE
, 1, 50, 3, 33, 100 );
186 maXPropSet
->setPropertyValue( "LineDash", uno::Any(aLineDash
) );
190 void CGMImpressOutAct::ImplSetFillBundle()
192 drawing::LineStyle eLS
;
193 drawing::FillStyle eFS
;
195 sal_uInt32 nEdgeColor
= 0;
197 double fEdgeWidth
= 0;
199 sal_uInt32 nFillColor
;
200 FillInteriorStyle eFillStyle
;
201 sal_uInt32 nHatchIndex
;
203 if ( mpCGM
->pElement
->eEdgeVisibility
== EV_ON
)
205 if ( mpCGM
->pElement
->nAspectSourceFlags
& ASF_EDGETYPE
)
206 eEdgeType
= mpCGM
->pElement
->pEdgeBundle
->eEdgeType
;
208 eEdgeType
= mpCGM
->pElement
->aEdgeBundle
.eEdgeType
;
209 if ( mpCGM
->pElement
->nAspectSourceFlags
& ASF_EDGEWIDTH
)
210 fEdgeWidth
= mpCGM
->pElement
->pEdgeBundle
->nEdgeWidth
;
212 fEdgeWidth
= mpCGM
->pElement
->aEdgeBundle
.nEdgeWidth
;
213 if ( mpCGM
->pElement
->nAspectSourceFlags
& ASF_EDGECOLOR
)
214 nEdgeColor
= mpCGM
->pElement
->pEdgeBundle
->GetColor();
216 nEdgeColor
= mpCGM
->pElement
->aEdgeBundle
.GetColor();
221 if ( mpCGM
->pElement
->nAspectSourceFlags
& ASF_FILLINTERIORSTYLE
)
222 eFillStyle
= mpCGM
->pElement
->pFillBundle
->eFillInteriorStyle
;
224 eFillStyle
= mpCGM
->pElement
->aFillBundle
.eFillInteriorStyle
;
225 if ( mpCGM
->pElement
->nAspectSourceFlags
& ASF_FILLCOLOR
)
226 nFillColor
= mpCGM
->pElement
->pFillBundle
->GetColor();
228 nFillColor
= mpCGM
->pElement
->aFillBundle
.GetColor();
229 if ( mpCGM
->pElement
->nAspectSourceFlags
& ASF_HATCHINDEX
)
230 nHatchIndex
= static_cast<sal_uInt32
>(mpCGM
->pElement
->pFillBundle
->nFillHatchIndex
);
232 nHatchIndex
= static_cast<sal_uInt32
>(mpCGM
->pElement
->aFillBundle
.nFillHatchIndex
);
234 maXPropSet
->setPropertyValue( "FillColor", uno::Any(static_cast<sal_Int32
>(nFillColor
)) );
236 switch ( eFillStyle
)
240 if ( nHatchIndex
== 0 )
241 eFS
= drawing::FillStyle_NONE
;
243 eFS
= drawing::FillStyle_HATCH
;
249 eFS
= drawing::FillStyle_SOLID
;
253 case FIS_GEOPATTERN
:
255 if ( mpCGM
->pElement
->eTransparency
== T_ON
)
256 nFillColor
= mpCGM
->pElement
->nAuxiliaryColor
;
257 eFS
= drawing::FillStyle_NONE
;
261 case FIS_INTERPOLATED
:
264 eFS
= drawing::FillStyle_GRADIENT
;
272 eFS
= drawing::FillStyle_NONE
;
276 if ( mpCGM
->mnAct4PostReset
& ACT4_GRADIENT_ACTION
)
277 eFS
= drawing::FillStyle_GRADIENT
;
279 if ( eFS
== drawing::FillStyle_GRADIENT
)
281 maXPropSet
->setPropertyValue( "FillGradient", uno::Any(*mpGradient
) );
283 maXPropSet
->setPropertyValue( "FillStyle", uno::Any(eFS
) );
285 eLS
= drawing::LineStyle_NONE
;
286 if ( eFillStyle
== FIS_HOLLOW
)
288 eLS
= drawing::LineStyle_SOLID
;
289 maXPropSet
->setPropertyValue( "LineColor", uno::Any(static_cast<sal_Int32
>(nFillColor
)) );
290 maXPropSet
->setPropertyValue( "LineWidth", uno::Any(sal_Int32(0)) );
292 else if ( eEdgeType
!= ET_NONE
)
294 maXPropSet
->setPropertyValue( "LineColor", uno::Any(static_cast<sal_Int32
>(nEdgeColor
)) );
296 maXPropSet
->setPropertyValue( "LineWidth", uno::Any(static_cast<sal_Int32
>(fEdgeWidth
)) );
304 case ET_DOTDOTSPACE
:
306 case ET_DASHDASHDOT
:
307 default: // case ET_SOLID :
309 eLS
= drawing::LineStyle_SOLID
;
315 maXPropSet
->setPropertyValue( "LineStyle", uno::Any(eLS
) );
317 if ( eFS
!= drawing::FillStyle_HATCH
)
320 drawing::Hatch aHatch
;
322 aHatch
.Color
= nFillColor
;
323 if ( mpCGM
->pElement
->maHatchMap
.find( nHatchIndex
) != mpCGM
->pElement
->maHatchMap
.end() )
325 HatchEntry
& rHatchEntry
= mpCGM
->pElement
->maHatchMap
[ nHatchIndex
];
326 switch ( rHatchEntry
.HatchStyle
)
328 case 0 : aHatch
.Style
= drawing::HatchStyle_SINGLE
; break;
329 case 1 : aHatch
.Style
= drawing::HatchStyle_DOUBLE
; break;
330 case 2 : aHatch
.Style
= drawing::HatchStyle_TRIPLE
; break;
332 aHatch
.Distance
= rHatchEntry
.HatchDistance
;
333 aHatch
.Angle
= rHatchEntry
.HatchAngle
;
337 aHatch
.Style
= drawing::HatchStyle_TRIPLE
;
338 aHatch
.Distance
= 10 * ( nHatchIndex
& 0x1f ) | 100;
339 aHatch
.Angle
= 15 * ( ( nHatchIndex
& 0x1f ) - 5 );
341 maXPropSet
->setPropertyValue( "FillHatch", uno::Any(aHatch
) );
344 void CGMImpressOutAct::ImplSetTextBundle( const uno::Reference
< beans::XPropertySet
> & rProperty
)
346 sal_uInt32 nTextFontIndex
;
347 sal_uInt32 nTextColor
;
349 if ( mpCGM
->pElement
->nAspectSourceFlags
& ASF_TEXTFONTINDEX
)
350 nTextFontIndex
= mpCGM
->pElement
->pTextBundle
->nTextFontIndex
;
352 nTextFontIndex
= mpCGM
->pElement
->aTextBundle
.nTextFontIndex
;
353 if ( mpCGM
->pElement
->nAspectSourceFlags
& ASF_TEXTCOLOR
)
354 nTextColor
= mpCGM
->pElement
->pTextBundle
->GetColor();
356 nTextColor
= mpCGM
->pElement
->aTextBundle
.GetColor();
358 rProperty
->setPropertyValue( "CharColor", uno::Any(static_cast<sal_Int32
>(nTextColor
)) );
360 sal_uInt32 nFontType
= 0;
361 awt::FontDescriptor aFontDescriptor
;
362 FontEntry
* pFontEntry
= mpCGM
->pElement
->aFontList
.GetFontEntry( nTextFontIndex
);
365 nFontType
= pFontEntry
->nFontType
;
366 aFontDescriptor
.Name
= OUString(reinterpret_cast<char*>(pFontEntry
->aFontName
.data()),
367 pFontEntry
->aFontName
.size(),
368 RTL_TEXTENCODING_ASCII_US
);
370 aFontDescriptor
.Height
= sal_Int16( mpCGM
->pElement
->nCharacterHeight
* 1.50 );
372 aFontDescriptor
.Slant
= awt::FontSlant_ITALIC
;
374 aFontDescriptor
.Weight
= awt::FontWeight::BOLD
;
376 aFontDescriptor
.Weight
= awt::FontWeight::NORMAL
;
378 if ( mpCGM
->pElement
->eUnderlineMode
!= UM_OFF
)
380 aFontDescriptor
.Underline
= awt::FontUnderline::SINGLE
;
382 rProperty
->setPropertyValue( "FontDescriptor", uno::Any(aFontDescriptor
) );
385 void CGMImpressOutAct::InsertPage()
387 if ( mnCurrentPage
) // one side is always existing, therefore the first side will be left out
389 uno::Reference
< drawing::XDrawPage
> xPage
= maXDrawPages
->insertNewByIndex( 0xffff );
391 if ( !ImplInitPage() )
392 mpCGM
->mbStatus
= false;
393 if (mnCurrentPage
> MAX_PAGES_FOR_FUZZING
&& utl::ConfigManager::IsFuzzing())
395 // ofz#21753 that's enough pages for fuzzing, we're not doing anything productive now
396 mpCGM
->mbStatus
= false;
402 void CGMImpressOutAct::BeginGroup()
404 if ( mnGroupLevel
< CGM_OUTACT_MAX_GROUP_LEVEL
)
406 maGroupLevel
[mnGroupLevel
] = maXShapes
->getCount();
409 mnGroupActCount
= mpCGM
->mnActCount
;
412 void CGMImpressOutAct::EndGroup()
417 if ( mnGroupLevel
>= CGM_OUTACT_MAX_GROUP_LEVEL
)
420 sal_uInt32 nFirstIndex
= maGroupLevel
[mnGroupLevel
];
421 if ( nFirstIndex
== 0xffffffff )
423 sal_uInt32 nCurrentCount
= maXShapes
->getCount();
424 if ( ( nCurrentCount
- nFirstIndex
) <= 1 )
427 uno::Reference
< drawing::XShapeGrouper
> aXShapeGrouper
;
428 aXShapeGrouper
.set( maXDrawPage
, uno::UNO_QUERY
);
429 if( !aXShapeGrouper
.is() )
432 uno::Reference
< drawing::XShapes
> aXShapes
= drawing::ShapeCollection::create(comphelper::getProcessComponentContext());
433 for ( sal_uInt32 i
= nFirstIndex
; i
< nCurrentCount
; i
++ )
435 uno::Reference
< drawing::XShape
> aXShape
= *o3tl::doAccess
<uno::Reference
<drawing::XShape
>>(maXShapes
->getByIndex( i
));
438 aXShapes
->add( aXShape
);
441 aXShapeGrouper
->group( aXShapes
);
444 void CGMImpressOutAct::EndGrouping()
446 while ( mnGroupLevel
)
452 void CGMImpressOutAct::DrawRectangle( FloatRect
const & rFloatRect
)
454 if ( mnGroupActCount
!= ( mpCGM
->mnActCount
- 1 ) ) // POWERPOINT HACK !!!
456 if ( ImplCreateShape( "com.sun.star.drawing.RectangleShape" ) )
458 awt::Size
aSize( static_cast<tools::Long
>(rFloatRect
.Right
- rFloatRect
.Left
), static_cast<tools::Long
>(rFloatRect
.Bottom
-rFloatRect
.Top
) );
459 maXShape
->setSize( aSize
);
460 maXShape
->setPosition( awt::Point( static_cast<tools::Long
>(rFloatRect
.Left
), static_cast<tools::Long
>(rFloatRect
.Top
) ) );
466 void CGMImpressOutAct::DrawEllipse( FloatPoint
const & rCenter
, FloatPoint
const & rSize
, double& rOrientation
)
468 if ( !ImplCreateShape( "com.sun.star.drawing.EllipseShape" ) )
471 drawing::CircleKind eCircleKind
= drawing::CircleKind_FULL
;
472 uno::Any
aAny( &eCircleKind
, ::cppu::UnoType
<drawing::CircleKind
>::get() );
473 maXPropSet
->setPropertyValue( "CircleKind", aAny
);
475 tools::Long nXSize
= static_cast<tools::Long
>( rSize
.X
* 2.0 ); // strange behaviour with an awt::Size of 0
476 tools::Long nYSize
= static_cast<tools::Long
>( rSize
.Y
* 2.0 );
481 maXShape
->setSize( awt::Size( nXSize
, nYSize
) );
482 maXShape
->setPosition( awt::Point( static_cast<tools::Long
>( rCenter
.X
- rSize
.X
), static_cast<tools::Long
>( rCenter
.Y
- rSize
.Y
) ) );
484 if ( rOrientation
!= 0 )
486 ImplSetOrientation( rCenter
, rOrientation
);
491 void CGMImpressOutAct::DrawEllipticalArc( FloatPoint
const & rCenter
, FloatPoint
const & rSize
, double& rOrientation
,
492 sal_uInt32 nType
, double& fStartAngle
, double& fEndAngle
)
494 if ( !ImplCreateShape( "com.sun.star.drawing.EllipseShape" ) )
498 drawing::CircleKind eCircleKind
;
501 tools::Long nXSize
= static_cast<tools::Long
>( rSize
.X
* 2.0 ); // strange behaviour with an awt::Size of 0
502 tools::Long nYSize
= static_cast<tools::Long
>( rSize
.Y
* 2.0 );
508 maXShape
->setSize( awt::Size ( nXSize
, nYSize
) );
510 if ( rOrientation
!= 0 )
512 fStartAngle
= NormAngle360(fStartAngle
+ rOrientation
);
513 fEndAngle
= NormAngle360(fEndAngle
+ rOrientation
);
517 case 0 : eCircleKind
= drawing::CircleKind_SECTION
; break;
518 case 1 : eCircleKind
= drawing::CircleKind_CUT
; break;
519 case 2 : eCircleKind
= drawing::CircleKind_ARC
; break;
520 default : eCircleKind
= drawing::CircleKind_FULL
; break;
522 if ( static_cast<tools::Long
>(fStartAngle
) == static_cast<tools::Long
>(fEndAngle
) )
524 eCircleKind
= drawing::CircleKind_FULL
;
525 maXPropSet
->setPropertyValue( "CircleKind", uno::Any(eCircleKind
) );
529 maXPropSet
->setPropertyValue( "CircleKind", uno::Any(eCircleKind
) );
530 maXPropSet
->setPropertyValue( "CircleStartAngle", uno::Any(static_cast<sal_Int32
>( fStartAngle
* 100 )) );
531 maXPropSet
->setPropertyValue( "CircleEndAngle", uno::Any(static_cast<sal_Int32
>( fEndAngle
* 100 )) );
533 maXShape
->setPosition( awt::Point( static_cast<tools::Long
>( rCenter
.X
- rSize
.X
), static_cast<tools::Long
>( rCenter
.Y
- rSize
.Y
) ) );
534 if ( rOrientation
!= 0 )
536 ImplSetOrientation( rCenter
, rOrientation
);
538 if ( eCircleKind
== drawing::CircleKind_ARC
)
548 aAny
<<= drawing::FillStyle_NONE
;
549 maXPropSet
->setPropertyValue( "FillStyle", aAny
);
554 void CGMImpressOutAct::DrawBitmap( CGMBitmapDescriptor
* pBmpDesc
)
556 if ( !pBmpDesc
->mbStatus
|| !pBmpDesc
->mxBitmap
)
559 FloatPoint aOrigin
= pBmpDesc
->mnOrigin
;
560 double fdx
= pBmpDesc
->mndx
;
561 double fdy
= pBmpDesc
->mndy
;
563 BmpMirrorFlags nMirr
= BmpMirrorFlags::NONE
;
564 if ( pBmpDesc
->mbVMirror
)
565 nMirr
|= BmpMirrorFlags::Vertical
;
566 if ( nMirr
!= BmpMirrorFlags::NONE
)
567 pBmpDesc
->mxBitmap
.Mirror( nMirr
);
569 mpCGM
->ImplMapPoint( aOrigin
);
570 mpCGM
->ImplMapX( fdx
);
571 mpCGM
->ImplMapY( fdy
);
573 if ( !ImplCreateShape( "com.sun.star.drawing.GraphicObjectShape" ) )
576 maXShape
->setSize( awt::Size( static_cast<tools::Long
>(fdx
), static_cast<tools::Long
>(fdy
) ) );
577 maXShape
->setPosition( awt::Point( static_cast<tools::Long
>(aOrigin
.X
), static_cast<tools::Long
>(aOrigin
.Y
) ) );
579 if ( pBmpDesc
->mnOrientation
!= 0 )
581 ImplSetOrientation( aOrigin
, pBmpDesc
->mnOrientation
);
584 uno::Reference
< awt::XBitmap
> xBitmap( VCLUnoHelper::CreateBitmap( pBmpDesc
->mxBitmap
) );
585 maXPropSet
->setPropertyValue( "GraphicObjectFillBitmap", uno::Any(xBitmap
) );
588 void CGMImpressOutAct::DrawPolygon( tools::Polygon
& rPoly
)
590 sal_uInt16 nPoints
= rPoly
.GetSize();
592 if ( !(( nPoints
> 1 ) && ImplCreateShape( "com.sun.star.drawing.PolyPolygonShape" )) )
595 drawing::PointSequenceSequence aRetval
;
597 // prepare inside polygons
598 aRetval
.realloc( 1 );
600 // get pointer to outside arrays
601 drawing::PointSequence
* pOuterSequence
= aRetval
.getArray();
603 // make room in arrays
604 pOuterSequence
->realloc(static_cast<sal_Int32
>(nPoints
));
606 // get pointer to arrays
607 awt::Point
* pInnerSequence
= pOuterSequence
->getArray();
609 for( sal_uInt16 n
= 0; n
< nPoints
; n
++ )
610 *pInnerSequence
++ = awt::Point( rPoly
[ n
].X(), rPoly
[n
].Y() );
614 maXPropSet
->setPropertyValue( "PolyPolygon", aParam
);
618 void CGMImpressOutAct::DrawPolyLine( tools::Polygon
& rPoly
)
620 sal_uInt16 nPoints
= rPoly
.GetSize();
622 if ( !(( nPoints
> 1 ) && ImplCreateShape( "com.sun.star.drawing.PolyLineShape" )) )
625 drawing::PointSequenceSequence aRetval
;
627 // prepare inside polygons
628 aRetval
.realloc( 1 );
630 // get pointer to outside arrays
631 drawing::PointSequence
* pOuterSequence
= aRetval
.getArray();
633 // make room in arrays
634 pOuterSequence
->realloc(static_cast<sal_Int32
>(nPoints
));
636 // get pointer to arrays
637 awt::Point
* pInnerSequence
= pOuterSequence
->getArray();
639 for( sal_uInt16 n
= 0; n
< nPoints
; n
++ )
640 *pInnerSequence
++ = awt::Point( rPoly
[ n
].X(), rPoly
[n
].Y() );
644 maXPropSet
->setPropertyValue( "PolyPolygon", aParam
);
648 void CGMImpressOutAct::DrawPolybezier( tools::Polygon
& rPolygon
)
650 sal_uInt16 nPoints
= rPolygon
.GetSize();
651 if ( !(( nPoints
> 1 ) && ImplCreateShape( "com.sun.star.drawing.OpenBezierShape" )) )
654 drawing::PolyPolygonBezierCoords aRetval
;
656 aRetval
.Coordinates
.realloc( 1 );
657 aRetval
.Flags
.realloc( 1 );
659 // get pointer to outside arrays
660 drawing::PointSequence
* pOuterSequence
= aRetval
.Coordinates
.getArray();
661 drawing::FlagSequence
* pOuterFlags
= aRetval
.Flags
.getArray();
663 // make room in arrays
664 pOuterSequence
->realloc( nPoints
);
665 pOuterFlags
->realloc( nPoints
);
667 awt::Point
* pInnerSequence
= pOuterSequence
->getArray();
668 drawing::PolygonFlags
* pInnerFlags
= pOuterFlags
->getArray();
670 for( sal_uInt16 i
= 0; i
< nPoints
; i
++ )
672 *pInnerSequence
++ = awt::Point( rPolygon
[ i
].X(), rPolygon
[ i
].Y() );
673 *pInnerFlags
++ = static_cast<drawing::PolygonFlags
>(rPolygon
.GetFlags( i
));
677 maXPropSet
->setPropertyValue( "PolyPolygonBezier", aParam
);
681 void CGMImpressOutAct::DrawPolyPolygon( tools::PolyPolygon
const & rPolyPolygon
)
683 sal_uInt32 nNumPolys
= rPolyPolygon
.Count();
684 if ( !(nNumPolys
&& ImplCreateShape( "com.sun.star.drawing.ClosedBezierShape" )) )
687 drawing::PolyPolygonBezierCoords aRetval
;
689 // prepare inside polygons
690 aRetval
.Coordinates
.realloc(static_cast<sal_Int32
>(nNumPolys
));
691 aRetval
.Flags
.realloc(static_cast<sal_Int32
>(nNumPolys
));
693 // get pointer to outside arrays
694 drawing::PointSequence
* pOuterSequence
= aRetval
.Coordinates
.getArray();
695 drawing::FlagSequence
* pOuterFlags
= aRetval
.Flags
.getArray();
697 for( sal_uInt32 a
= 0; a
< nNumPolys
; a
++ )
699 const tools::Polygon
& aPolygon( rPolyPolygon
.GetObject( a
) );
700 sal_uInt32 nNumPoints
= aPolygon
.GetSize();
702 // make room in arrays
703 pOuterSequence
->realloc(static_cast<sal_Int32
>(nNumPoints
));
704 pOuterFlags
->realloc(static_cast<sal_Int32
>(nNumPoints
));
706 // get pointer to arrays
707 awt::Point
* pInnerSequence
= pOuterSequence
->getArray();
708 drawing::PolygonFlags
* pInnerFlags
= pOuterFlags
->getArray();
710 for( sal_uInt32 b
= 0; b
< nNumPoints
; b
++ )
712 *pInnerSequence
++ = awt::Point( aPolygon
.GetPoint( b
).X(), aPolygon
.GetPoint( b
).Y() ) ;
713 *pInnerFlags
++ = static_cast<drawing::PolygonFlags
>(aPolygon
.GetFlags( b
));
720 maXPropSet
->setPropertyValue( "PolyPolygonBezier", aParam
);
724 void CGMImpressOutAct::DrawText(awt::Point
const & rTextPos
, awt::Size
const & rTextSize
, const OUString
& rString
, FinalFlag eFlag
)
726 if ( !ImplCreateShape( "com.sun.star.drawing.TextShape" ) )
730 tools::Long nWidth
= rTextSize
.Width
;
731 tools::Long nHeight
= rTextSize
.Height
;
733 awt::Point
aTextPos( rTextPos
);
734 switch ( mpCGM
->pElement
->eTextAlignmentV
)
738 aTextPos
.Y
= o3tl::saturating_add(aTextPos
.X
, static_cast<sal_Int32
>((mpCGM
->pElement
->nCharacterHeight
* -1.5) / 2));
745 aTextPos
.Y
= o3tl::saturating_add(aTextPos
.Y
, static_cast<sal_Int32
>(mpCGM
->pElement
->nCharacterHeight
* -1.5));
751 break; // -Wall these two were not here.
758 else if ( nWidth
== 0 )
766 else if ( nHeight
== 0 )
770 maXShape
->setPosition( aTextPos
);
771 maXShape
->setSize( awt::Size( nWidth
, nHeight
) );
772 double nX
= mpCGM
->pElement
->nCharacterOrientation
[ 2 ];
773 double nY
= mpCGM
->pElement
->nCharacterOrientation
[ 3 ];
774 double fSqrt
= sqrt(nX
* nX
+ nY
* nY
);
775 double nOrientation
= fSqrt
!= 0.0 ? (acos(nX
/ fSqrt
) * 57.29577951308) : 0.0;
777 nOrientation
= 360 - nOrientation
;
781 maXPropSet
->setPropertyValue( "RotationPointX", uno::Any(aTextPos
.X
) );
782 maXPropSet
->setPropertyValue( "RotationPointY", uno::Any(static_cast<sal_Int32
>( aTextPos
.Y
+ nHeight
)) );
783 maXPropSet
->setPropertyValue( "RotateAngle", uno::Any(static_cast<sal_Int32
>( nOrientation
* 100 )) );
788 maXPropSet
->setPropertyValue( "TextAutoGrowWidth", aAny
);
790 drawing::TextAdjust eTextAdjust
;
791 switch ( mpCGM
->pElement
->eTextAlignmentH
)
794 eTextAdjust
= drawing::TextAdjust_RIGHT
;
799 eTextAdjust
= drawing::TextAdjust_LEFT
;
802 eTextAdjust
= drawing::TextAdjust_CENTER
;
805 maXPropSet
->setPropertyValue( "TextHorizontalAdjust", uno::Any(eTextAdjust
) );
809 maXPropSet
->setPropertyValue( "TextAutoGrowHeight", uno::Any(true) );
811 uno::Reference
< text::XText
> xText
;
812 uno::Any
aFirstQuery( maXShape
->queryInterface( cppu::UnoType
<text::XText
>::get()));
813 if( aFirstQuery
>>= xText
)
815 uno::Reference
< text::XTextCursor
> aXTextCursor( xText
->createTextCursor() );
817 aXTextCursor
->gotoEnd( false );
818 uno::Reference
< text::XTextRange
> aCursorText
;
819 uno::Any
aSecondQuery( aXTextCursor
->queryInterface( cppu::UnoType
<text::XTextRange
>::get()));
820 if ( aSecondQuery
>>= aCursorText
)
822 uno::Reference
< beans::XPropertySet
> aCursorPropSet
;
824 uno::Any
aQuery( aCursorText
->queryInterface( cppu::UnoType
<beans::XPropertySet
>::get()));
825 if( aQuery
>>= aCursorPropSet
)
827 if ( nWidth
!= -1 ) // paragraph adjusting in a valid textbox ?
829 switch ( mpCGM
->pElement
->eTextAlignmentH
)
832 aAny
<<= sal_Int16(style::HorizontalAlignment_RIGHT
);
837 aAny
<<= sal_Int16(style::HorizontalAlignment_LEFT
);
840 aAny
<<= sal_Int16(style::HorizontalAlignment_CENTER
);
843 aCursorPropSet
->setPropertyValue( "ParaAdjust", aAny
);
845 if ( nWidth
> 0 && nHeight
> 0 ) // restricted text
848 maXPropSet
->setPropertyValue( "TextFitToSize", aAny
);
850 aCursorText
->setString(rString
);
851 aXTextCursor
->gotoEnd( true );
852 ImplSetTextBundle( aCursorPropSet
);
857 if ( eFlag
== FF_NOT_FINAL
)
859 nFinalTextCount
= maXShapes
->getCount();
863 void CGMImpressOutAct::AppendText( const char* pString
)
865 if ( !nFinalTextCount
)
868 uno::Reference
< drawing::XShape
> aShape
= *o3tl::doAccess
<uno::Reference
<drawing::XShape
>>(maXShapes
->getByIndex( nFinalTextCount
- 1 ));
872 uno::Reference
< text::XText
> xText
;
873 uno::Any
aFirstQuery( aShape
->queryInterface( cppu::UnoType
<text::XText
>::get()) );
874 if( !(aFirstQuery
>>= xText
) )
877 OUString
aStr(pString
, strlen(pString
), RTL_TEXTENCODING_ASCII_US
);
879 uno::Reference
< text::XTextCursor
> aXTextCursor( xText
->createTextCursor() );
880 if ( !aXTextCursor
.is() )
883 aXTextCursor
->gotoEnd( false );
884 uno::Reference
< text::XTextRange
> aCursorText
;
885 uno::Any
aSecondQuery(aXTextCursor
->queryInterface( cppu::UnoType
<text::XTextRange
>::get()));
886 if ( aSecondQuery
>>= aCursorText
)
888 uno::Reference
< beans::XPropertySet
> aPropSet
;
889 uno::Any
aQuery(aCursorText
->queryInterface( cppu::UnoType
<beans::XPropertySet
>::get()));
890 if( aQuery
>>= aPropSet
)
892 aCursorText
->setString( aStr
);
893 aXTextCursor
->gotoEnd( true );
894 ImplSetTextBundle( aPropSet
);
900 void CGMImpressOutAct::BeginFigure()
902 if (!maPoints
.empty())
910 void CGMImpressOutAct::CloseRegion()
912 if (maPoints
.size() > 2)
915 DrawPolyPolygon( maPolyPolygon
);
916 maPolyPolygon
.Clear();
920 void CGMImpressOutAct::NewRegion()
922 if (maPoints
.size() > 2)
924 tools::Polygon
aPolygon(maPoints
.size(), maPoints
.data(), maFlags
.data());
925 maPolyPolygon
.Insert( aPolygon
);
931 void CGMImpressOutAct::EndFigure()
934 DrawPolyPolygon( maPolyPolygon
);
935 maPolyPolygon
.Clear();
941 void CGMImpressOutAct::RegPolyLine( tools::Polygon
const & rPolygon
, bool bReverse
)
943 sal_uInt16 nPoints
= rPolygon
.GetSize();
949 for ( sal_uInt16 i
= 0; i
< nPoints
; i
++ )
951 maPoints
.push_back(rPolygon
.GetPoint(nPoints
- i
- 1));
952 maFlags
.push_back(rPolygon
.GetFlags(nPoints
- i
- 1));
957 for ( sal_uInt16 i
= 0; i
< nPoints
; i
++ )
959 maPoints
.push_back(rPolygon
.GetPoint(i
));
960 maFlags
.push_back(rPolygon
.GetFlags(i
));
965 void CGMImpressOutAct::SetGradientOffset( tools::Long nHorzOfs
, tools::Long nVertOfs
)
968 mpGradient
.reset( new awt::Gradient
);
969 mpGradient
->XOffset
= ( static_cast<sal_uInt16
>(nHorzOfs
) & 0x7f );
970 mpGradient
->YOffset
= ( static_cast<sal_uInt16
>(nVertOfs
) & 0x7f );
973 void CGMImpressOutAct::SetGradientAngle( tools::Long nAngle
)
976 mpGradient
.reset( new awt::Gradient
);
977 mpGradient
->Angle
= sal::static_int_cast
< sal_Int16
>(nAngle
);
980 void CGMImpressOutAct::SetGradientDescriptor( sal_uInt32 nColorFrom
, sal_uInt32 nColorTo
)
983 mpGradient
.reset( new awt::Gradient
);
984 mpGradient
->StartColor
= nColorFrom
;
985 mpGradient
->EndColor
= nColorTo
;
988 void CGMImpressOutAct::SetGradientStyle( sal_uInt32 nStyle
)
991 mpGradient
.reset( new awt::Gradient
);
996 mpGradient
->Style
= awt::GradientStyle_AXIAL
;
1001 mpGradient
->Style
= awt::GradientStyle_RADIAL
; // CONICAL
1006 mpGradient
->Style
= awt::GradientStyle_RECT
;
1011 mpGradient
->Style
= awt::GradientStyle_ELLIPTICAL
;
1016 mpGradient
->Style
= awt::GradientStyle_LINEAR
;
1021 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */