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 "svdfmtf.hxx"
22 #include <editeng/eeitem.hxx>
23 #include <editeng/fhgtitem.hxx>
24 #include <editeng/wghtitem.hxx>
25 #include <editeng/postitem.hxx>
26 #include <editeng/udlnitem.hxx>
27 #include <editeng/crossedoutitem.hxx>
28 #include <editeng/shdditem.hxx>
29 #include <svx/xlineit0.hxx>
30 #include <svx/xlnclit.hxx>
31 #include <svx/xlncapit.hxx>
32 #include <svx/xlnwtit.hxx>
33 #include <svx/xfillit0.hxx>
34 #include <svx/xflclit.hxx>
35 #include <svx/xgrad.hxx>
36 #include <svx/xflgrit.hxx>
37 #include <editeng/fontitem.hxx>
38 #include <editeng/wrlmitem.hxx>
39 #include <editeng/contouritem.hxx>
40 #include <editeng/colritem.hxx>
41 #include <vcl/canvastools.hxx>
42 #include <vcl/metric.hxx>
43 #include <editeng/charscaleitem.hxx>
44 #include <svx/xflhtit.hxx>
45 #include <svx/sdmetitm.hxx>
46 #include <svx/sdtagitm.hxx>
47 #include <svx/sdtaitm.hxx>
48 #include <svx/sdtditm.hxx>
49 #include <svx/sdtfsitm.hxx>
50 #include <svx/svdmodel.hxx>
51 #include <svx/svdpage.hxx>
52 #include <svx/svdobj.hxx>
53 #include <svx/svdotext.hxx>
54 #include <svx/svdorect.hxx>
55 #include <svx/svdocirc.hxx>
56 #include <svx/svdograf.hxx>
57 #include <svx/svdopath.hxx>
58 #include <svx/svdetc.hxx>
59 #include <svl/itemset.hxx>
60 #include <basegfx/polygon/b2dpolygon.hxx>
61 #include <tools/helpers.hxx>
62 #include <basegfx/matrix/b2dhommatrix.hxx>
63 #include <basegfx/matrix/b2dhommatrixtools.hxx>
64 #include <svx/xlinjoit.hxx>
65 #include <svx/xlndsit.hxx>
66 #include <basegfx/polygon/b2dpolygonclipper.hxx>
67 #include <svx/xbtmpit.hxx>
68 #include <svx/xfltrit.hxx>
69 #include <svx/xflbmtit.hxx>
70 #include <svx/xflbstit.hxx>
71 #include <svx/svdpntv.hxx>
72 #include <basegfx/polygon/b2dpolypolygontools.hxx>
73 #include <svx/svditer.hxx>
74 #include <svx/svdogrp.hxx>
75 #include <vcl/BitmapTools.hxx>
77 using namespace com::sun::star
;
79 ImpSdrGDIMetaFileImport::ImpSdrGDIMetaFileImport(
82 const tools::Rectangle
& rRect
)
84 mpVD(VclPtr
<VirtualDevice
>::Create()),
91 maLineJoin(basegfx::B2DLineJoin::NONE
),
92 maLineCap(css::drawing::LineCap_BUTT
),
93 maDash(css::drawing::DashStyle_RECT
, 0, 0, 0, 0, 0),
102 mbLastObjWasPolyWithoutLine(false),
105 mbLastObjWasLine(false),
108 mpVD
->EnableOutput(false);
109 mpVD
->SetLineColor();
110 mpVD
->SetFillColor();
111 maOldLineColor
.SetRed( mpVD
->GetLineColor().GetRed() + 1 );
112 mpLineAttr
= std::make_unique
<SfxItemSet
>(rModel
.GetItemPool(), svl::Items
<XATTR_LINE_FIRST
, XATTR_LINE_LAST
>{});
113 mpFillAttr
= std::make_unique
<SfxItemSet
>(rModel
.GetItemPool(), svl::Items
<XATTR_FILL_FIRST
, XATTR_FILL_LAST
>{});
114 mpTextAttr
= std::make_unique
<SfxItemSet
>(rModel
.GetItemPool(), svl::Items
<EE_ITEMS_START
, EE_ITEMS_END
>{});
118 void ImpSdrGDIMetaFileImport::DoLoopActions(GDIMetaFile
const & rMtf
, SvdProgressInfo
* pProgrInfo
, sal_uInt32
* pActionsToReport
)
120 const sal_uLong
nCount(rMtf
.GetActionSize());
122 for(sal_uLong
a(0); a
< nCount
; a
++)
124 MetaAction
* pAct
= rMtf
.GetAction(a
);
128 OSL_ENSURE(false, "OOps, no action at valid position (!)");
129 pAct
= rMtf
.GetAction(0);
132 switch (pAct
->GetType())
134 case MetaActionType::PIXEL
: break;
135 case MetaActionType::POINT
: break;
136 case MetaActionType::LINE
: DoAction(static_cast<MetaLineAction
&>(*pAct
)); break;
137 case MetaActionType::RECT
: DoAction(static_cast<MetaRectAction
&>(*pAct
)); break;
138 case MetaActionType::ROUNDRECT
: DoAction(static_cast<MetaRoundRectAction
&>(*pAct
)); break;
139 case MetaActionType::ELLIPSE
: DoAction(static_cast<MetaEllipseAction
&>(*pAct
)); break;
140 case MetaActionType::ARC
: DoAction(static_cast<MetaArcAction
&>(*pAct
)); break;
141 case MetaActionType::PIE
: DoAction(static_cast<MetaPieAction
&>(*pAct
)); break;
142 case MetaActionType::CHORD
: DoAction(static_cast<MetaChordAction
&>(*pAct
)); break;
143 case MetaActionType::POLYLINE
: DoAction(static_cast<MetaPolyLineAction
&>(*pAct
)); break;
144 case MetaActionType::POLYGON
: DoAction(static_cast<MetaPolygonAction
&>(*pAct
)); break;
145 case MetaActionType::POLYPOLYGON
: DoAction(static_cast<MetaPolyPolygonAction
&>(*pAct
)); break;
146 case MetaActionType::TEXT
: DoAction(static_cast<MetaTextAction
&>(*pAct
)); break;
147 case MetaActionType::TEXTARRAY
: DoAction(static_cast<MetaTextArrayAction
&>(*pAct
)); break;
148 case MetaActionType::STRETCHTEXT
: DoAction(static_cast<MetaStretchTextAction
&>(*pAct
)); break;
149 case MetaActionType::BMP
: DoAction(static_cast<MetaBmpAction
&>(*pAct
)); break;
150 case MetaActionType::BMPSCALE
: DoAction(static_cast<MetaBmpScaleAction
&>(*pAct
)); break;
151 case MetaActionType::BMPEX
: DoAction(static_cast<MetaBmpExAction
&>(*pAct
)); break;
152 case MetaActionType::BMPEXSCALE
: DoAction(static_cast<MetaBmpExScaleAction
&>(*pAct
)); break;
153 case MetaActionType::LINECOLOR
: DoAction(static_cast<MetaLineColorAction
&>(*pAct
)); break;
154 case MetaActionType::FILLCOLOR
: DoAction(static_cast<MetaFillColorAction
&>(*pAct
)); break;
155 case MetaActionType::TEXTCOLOR
: DoAction(static_cast<MetaTextColorAction
&>(*pAct
)); break;
156 case MetaActionType::TEXTFILLCOLOR
: DoAction(static_cast<MetaTextFillColorAction
&>(*pAct
)); break;
157 case MetaActionType::FONT
: DoAction(static_cast<MetaFontAction
&>(*pAct
)); break;
158 case MetaActionType::TEXTALIGN
: DoAction(static_cast<MetaTextAlignAction
&>(*pAct
)); break;
159 case MetaActionType::MAPMODE
: DoAction(static_cast<MetaMapModeAction
&>(*pAct
)); break;
160 case MetaActionType::CLIPREGION
: DoAction(static_cast<MetaClipRegionAction
&>(*pAct
)); break;
161 case MetaActionType::MOVECLIPREGION
: DoAction(static_cast<MetaMoveClipRegionAction
&>(*pAct
)); break;
162 case MetaActionType::ISECTRECTCLIPREGION
: DoAction(static_cast<MetaISectRectClipRegionAction
&>(*pAct
)); break;
163 case MetaActionType::ISECTREGIONCLIPREGION
: DoAction(static_cast<MetaISectRegionClipRegionAction
&>(*pAct
)); break;
164 case MetaActionType::RASTEROP
: DoAction(static_cast<MetaRasterOpAction
&>(*pAct
)); break;
165 case MetaActionType::PUSH
: DoAction(static_cast<MetaPushAction
&>(*pAct
)); break;
166 case MetaActionType::POP
: DoAction(static_cast<MetaPopAction
&>(*pAct
)); break;
167 case MetaActionType::HATCH
: DoAction(static_cast<MetaHatchAction
&>(*pAct
)); break;
169 // #i125211# MetaCommentAction may change index, thus hand it over
170 case MetaActionType::COMMENT
: DoAction(static_cast<MetaCommentAction
&>(*pAct
), rMtf
, a
);
173 // missing actions added
174 case MetaActionType::TEXTRECT
: DoAction(static_cast<MetaTextRectAction
&>(*pAct
)); break;
175 case MetaActionType::BMPSCALEPART
: DoAction(static_cast<MetaBmpScalePartAction
&>(*pAct
)); break;
176 case MetaActionType::BMPEXSCALEPART
: DoAction(static_cast<MetaBmpExScalePartAction
&>(*pAct
)); break;
177 case MetaActionType::MASK
: DoAction(static_cast<MetaMaskAction
&>(*pAct
)); break;
178 case MetaActionType::MASKSCALE
: DoAction(static_cast<MetaMaskScaleAction
&>(*pAct
)); break;
179 case MetaActionType::MASKSCALEPART
: DoAction(static_cast<MetaMaskScalePartAction
&>(*pAct
)); break;
180 case MetaActionType::GRADIENT
: DoAction(static_cast<MetaGradientAction
&>(*pAct
)); break;
181 case MetaActionType::WALLPAPER
: OSL_ENSURE(false, "Tried to construct SdrObject from MetaWallpaperAction: not supported (!)"); break;
182 case MetaActionType::Transparent
: DoAction(static_cast<MetaTransparentAction
&>(*pAct
)); break;
183 case MetaActionType::EPS
: OSL_ENSURE(false, "Tried to construct SdrObject from MetaEPSAction: not supported (!)"); break;
184 case MetaActionType::REFPOINT
: DoAction(static_cast<MetaRefPointAction
&>(*pAct
)); break;
185 case MetaActionType::TEXTLINECOLOR
: DoAction(static_cast<MetaTextLineColorAction
&>(*pAct
)); break;
186 case MetaActionType::TEXTLINE
: OSL_ENSURE(false, "Tried to construct SdrObject from MetaTextLineAction: not supported (!)"); break;
187 case MetaActionType::FLOATTRANSPARENT
: DoAction(static_cast<MetaFloatTransparentAction
&>(*pAct
)); break;
188 case MetaActionType::GRADIENTEX
: DoAction(static_cast<MetaGradientExAction
&>(*pAct
)); break;
189 case MetaActionType::LAYOUTMODE
: DoAction(static_cast<MetaLayoutModeAction
&>(*pAct
)); break;
190 case MetaActionType::TEXTLANGUAGE
: DoAction(static_cast<MetaTextLanguageAction
&>(*pAct
)); break;
191 case MetaActionType::OVERLINECOLOR
: DoAction(static_cast<MetaOverlineColorAction
&>(*pAct
)); break;
195 if(pProgrInfo
&& pActionsToReport
)
197 (*pActionsToReport
)++;
199 if(*pActionsToReport
>= 16) // update all 16 actions
201 if(!pProgrInfo
->ReportActions(*pActionsToReport
))
204 *pActionsToReport
= 0;
210 size_t ImpSdrGDIMetaFileImport::DoImport(
211 const GDIMetaFile
& rMtf
,
214 SvdProgressInfo
* pProgrInfo
)
216 // setup some global scale parameter
217 // mfScaleX, mfScaleY, maScaleX, maScaleY, mbMov, mbSize
218 mfScaleX
= mfScaleY
= 1.0;
219 const Size
aMtfSize(rMtf
.GetPrefSize());
221 if(aMtfSize
.Width() & aMtfSize
.Height() && (!maScaleRect
.IsEmpty()))
223 maOfs
= maScaleRect
.TopLeft();
225 if(aMtfSize
.Width() != (maScaleRect
.GetWidth() - 1))
227 mfScaleX
= static_cast<double>( maScaleRect
.GetWidth() - 1 ) / static_cast<double>(aMtfSize
.Width());
230 if(aMtfSize
.Height() != (maScaleRect
.GetHeight() - 1))
232 mfScaleY
= static_cast<double>( maScaleRect
.GetHeight() - 1 ) / static_cast<double>(aMtfSize
.Height());
236 mbMov
= maOfs
.X()!=0 || maOfs
.Y()!=0;
238 maScaleX
= Fraction( 1, 1 );
239 maScaleY
= Fraction( 1, 1 );
241 if(aMtfSize
.Width() != (maScaleRect
.GetWidth() - 1))
243 maScaleX
= Fraction(maScaleRect
.GetWidth() - 1, aMtfSize
.Width());
247 if(aMtfSize
.Height() != (maScaleRect
.GetHeight() - 1))
249 maScaleY
= Fraction(maScaleRect
.GetHeight() - 1, aMtfSize
.Height());
255 pProgrInfo
->SetActionCount(rMtf
.GetActionSize());
258 sal_uInt32
nActionsToReport(0);
261 DoLoopActions(rMtf
, pProgrInfo
, &nActionsToReport
);
265 pProgrInfo
->ReportActions(nActionsToReport
);
266 nActionsToReport
= 0;
272 // To calculate the progress meter, we use GetActionSize()*3.
273 // However, maTmpList has a lower entry count limit than GetActionSize(),
274 // so the actions that were assumed were too much have to be re-added.
275 nActionsToReport
= (rMtf
.GetActionSize() - maTmpList
.size()) * 2;
277 // announce all currently unannounced rescales
280 pProgrInfo
->ReportRescales(nActionsToReport
);
281 pProgrInfo
->SetInsertCount(maTmpList
.size());
284 nActionsToReport
= 0;
286 // insert all objects cached in aTmpList now into rOL from nInsPos
287 nInsPos
= std::min(nInsPos
, rOL
.GetObjCount());
289 for(SdrObject
* pObj
: maTmpList
)
291 rOL
.NbcInsertObject(pObj
, nInsPos
);
298 if(nActionsToReport
>= 32) // update all 32 actions
300 pProgrInfo
->ReportInserts(nActionsToReport
);
301 nActionsToReport
= 0;
306 // report all remaining inserts for the last time
309 pProgrInfo
->ReportInserts(nActionsToReport
);
312 return maTmpList
.size();
315 void ImpSdrGDIMetaFileImport::SetAttributes(SdrObject
* pObj
, bool bForceTextAttr
)
319 bool bLine(!bForceTextAttr
);
320 bool bFill(!pObj
|| (pObj
->IsClosedObj() && !bForceTextAttr
));
321 bool bText(bForceTextAttr
|| (pObj
&& pObj
->GetOutlinerParaObject()));
327 mpLineAttr
->Put(XLineWidthItem(mnLineWidth
));
331 mpLineAttr
->Put(XLineWidthItem(0));
334 maOldLineColor
= mpVD
->GetLineColor();
336 if(mpVD
->IsLineColor())
338 mpLineAttr
->Put(XLineStyleItem(drawing::LineStyle_SOLID
));
339 mpLineAttr
->Put(XLineColorItem(OUString(), mpVD
->GetLineColor()));
343 mpLineAttr
->Put(XLineStyleItem(drawing::LineStyle_NONE
));
348 case basegfx::B2DLineJoin::NONE
:
349 mpLineAttr
->Put(XLineJointItem(css::drawing::LineJoint_NONE
));
351 case basegfx::B2DLineJoin::Bevel
:
352 mpLineAttr
->Put(XLineJointItem(css::drawing::LineJoint_BEVEL
));
354 case basegfx::B2DLineJoin::Miter
:
355 mpLineAttr
->Put(XLineJointItem(css::drawing::LineJoint_MITER
));
357 case basegfx::B2DLineJoin::Round
:
358 mpLineAttr
->Put(XLineJointItem(css::drawing::LineJoint_ROUND
));
362 // Add LineCap support
363 mpLineAttr
->Put(XLineCapItem(maLineCap
));
365 if(((maDash
.GetDots() && maDash
.GetDotLen()) || (maDash
.GetDashes() && maDash
.GetDashLen())) && maDash
.GetDistance())
367 mpLineAttr
->Put(XLineDashItem(OUString(), maDash
));
371 mpLineAttr
->Put(XLineDashItem(OUString(), XDash(css::drawing::DashStyle_RECT
)));
381 if(mpVD
->IsFillColor())
383 mpFillAttr
->Put(XFillStyleItem(drawing::FillStyle_SOLID
));
384 mpFillAttr
->Put(XFillColorItem(OUString(), mpVD
->GetFillColor()));
388 mpFillAttr
->Put(XFillStyleItem(drawing::FillStyle_NONE
));
396 if(bText
&& mbFntDirty
)
398 vcl::Font
aFnt(mpVD
->GetFont());
399 const sal_uInt32
nHeight(FRound(aFnt
.GetFontSize().Height() * mfScaleY
));
401 mpTextAttr
->Put( SvxFontItem( aFnt
.GetFamilyType(), aFnt
.GetFamilyName(), aFnt
.GetStyleName(), aFnt
.GetPitch(), aFnt
.GetCharSet(), EE_CHAR_FONTINFO
) );
402 mpTextAttr
->Put( SvxFontItem( aFnt
.GetFamilyType(), aFnt
.GetFamilyName(), aFnt
.GetStyleName(), aFnt
.GetPitch(), aFnt
.GetCharSet(), EE_CHAR_FONTINFO_CJK
) );
403 mpTextAttr
->Put( SvxFontItem( aFnt
.GetFamilyType(), aFnt
.GetFamilyName(), aFnt
.GetStyleName(), aFnt
.GetPitch(), aFnt
.GetCharSet(), EE_CHAR_FONTINFO_CTL
) );
404 mpTextAttr
->Put(SvxPostureItem(aFnt
.GetItalic(), EE_CHAR_ITALIC
));
405 mpTextAttr
->Put(SvxWeightItem(aFnt
.GetWeight(), EE_CHAR_WEIGHT
));
406 mpTextAttr
->Put( SvxFontHeightItem( nHeight
, 100, EE_CHAR_FONTHEIGHT
) );
407 mpTextAttr
->Put( SvxFontHeightItem( nHeight
, 100, EE_CHAR_FONTHEIGHT_CJK
) );
408 mpTextAttr
->Put( SvxFontHeightItem( nHeight
, 100, EE_CHAR_FONTHEIGHT_CTL
) );
409 mpTextAttr
->Put(SvxCharScaleWidthItem(100, EE_CHAR_FONTWIDTH
));
410 mpTextAttr
->Put(SvxUnderlineItem(aFnt
.GetUnderline(), EE_CHAR_UNDERLINE
));
411 mpTextAttr
->Put(SvxOverlineItem(aFnt
.GetOverline(), EE_CHAR_OVERLINE
));
412 mpTextAttr
->Put(SvxCrossedOutItem(aFnt
.GetStrikeout(), EE_CHAR_STRIKEOUT
));
413 mpTextAttr
->Put(SvxShadowedItem(aFnt
.IsShadow(), EE_CHAR_SHADOW
));
415 // #i118485# Setting this item leads to problems (written #i118498# for this)
416 // mpTextAttr->Put(SvxAutoKernItem(aFnt.IsKerning(), EE_CHAR_KERNING));
418 mpTextAttr
->Put(SvxWordLineModeItem(aFnt
.IsWordLineMode(), EE_CHAR_WLM
));
419 mpTextAttr
->Put(SvxContourItem(aFnt
.IsOutline(), EE_CHAR_OUTLINE
));
420 mpTextAttr
->Put(SvxColorItem(mpVD
->GetTextColor(), EE_CHAR_COLOR
));
421 //... svxfont textitem svditext
428 pObj
->SetLayer(mnLayer
);
432 pObj
->SetMergedItemSet(*mpLineAttr
);
437 pObj
->SetMergedItemSet(*mpFillAttr
);
442 pObj
->SetMergedItemSet(*mpTextAttr
);
443 pObj
->SetMergedItem(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_LEFT
));
447 void ImpSdrGDIMetaFileImport::InsertObj(SdrObject
* pObj
, bool bScale
)
449 if(bScale
&& !maScaleRect
.IsEmpty())
453 pObj
->NbcResize(Point(), maScaleX
, maScaleY
);
458 pObj
->NbcMove(Size(maOfs
.X(), maOfs
.Y()));
464 const basegfx::B2DPolyPolygon
aPoly(pObj
->TakeXorPoly());
465 const basegfx::B2DRange
aOldRange(aPoly
.getB2DRange());
466 const SdrLayerID
aOldLayer(pObj
->GetLayer());
467 const SfxItemSet
aOldItemSet(pObj
->GetMergedItemSet());
468 const SdrGrafObj
* pSdrGrafObj
= dynamic_cast< SdrGrafObj
* >(pObj
);
469 const SdrTextObj
* pSdrTextObj
= dynamic_cast< SdrTextObj
* >(pObj
);
471 if(pSdrTextObj
&& pSdrTextObj
->HasText())
473 // all text objects are created from ImportText and have no line or fill attributes, so
474 // it is okay to concentrate on the text itself
477 const basegfx::B2DPolyPolygon
aTextContour(pSdrTextObj
->TakeContour());
478 const basegfx::B2DRange
aTextRange(aTextContour
.getB2DRange());
479 const basegfx::B2DRange
aClipRange(maClip
.getB2DRange());
481 // no overlap -> completely outside
482 if(!aClipRange
.overlaps(aTextRange
))
484 SdrObject::Free(pObj
);
488 // when the clip is a rectangle fast check for inside is possible
489 if(basegfx::utils::isRectangle(maClip
) && aClipRange
.isInside(aTextRange
))
491 // completely inside ClipRect
495 // here text needs to be clipped; to do so, convert to SdrObjects with polygons
496 // and add these recursively. Delete original object, do not add in this run
497 SdrObject
* pConverted
= pSdrTextObj
->ConvertToPolyObj(true, true).release();
498 SdrObject::Free(pObj
);
502 // recursively add created conversion; per definition this shall not
503 // contain further SdrTextObjs. Visit only non-group objects
504 SdrObjListIter
aIter(*pConverted
, SdrIterMode::DeepNoGroups
);
506 // work with clones; the created conversion may contain group objects
507 // and when working with the original objects the loop itself could
508 // break and the cleanup later would be pretty complicated (only delete group
509 // objects, are these empty, ...?)
510 while(aIter
.IsMore())
512 SdrObject
* pCandidate
= aIter
.Next();
513 OSL_ENSURE(pCandidate
&& dynamic_cast< SdrObjGroup
* >(pCandidate
) == nullptr, "SdrObjListIter with SdrIterMode::DeepNoGroups error (!)");
514 SdrObject
* pNewClone(pCandidate
->CloneSdrObject(pCandidate
->getSdrModelFromSdrObject()));
518 InsertObj(pNewClone
, false);
522 OSL_ENSURE(false, "SdrObject::Clone() failed (!)");
526 // cleanup temporary conversion objects
527 SdrObject::Free(pConverted
);
539 aBitmapEx
= pSdrGrafObj
->GetGraphic().GetBitmapEx();
542 SdrObject::Free(pObj
);
544 if(!aOldRange
.isEmpty())
546 // clip against ClipRegion
547 const basegfx::B2DPolyPolygon
aNewPoly(
548 basegfx::utils::clipPolyPolygonOnPolyPolygon(
553 const basegfx::B2DRange
aNewRange(aNewPoly
.getB2DRange());
555 if(!aNewRange
.isEmpty())
557 pObj
= new SdrPathObj(
559 aNewPoly
.isClosed() ? OBJ_POLY
: OBJ_PLIN
,
562 pObj
->SetLayer(aOldLayer
);
563 pObj
->SetMergedItemSet(aOldItemSet
);
567 // aNewRange is inside of aOldRange and defines which part of aBitmapEx is used
568 const double fScaleX(aBitmapEx
.GetSizePixel().Width() / (aOldRange
.getWidth() ? aOldRange
.getWidth() : 1.0));
569 const double fScaleY(aBitmapEx
.GetSizePixel().Height() / (aOldRange
.getHeight() ? aOldRange
.getHeight() : 1.0));
570 basegfx::B2DRange
aPixel(aNewRange
);
571 basegfx::B2DHomMatrix aTrans
;
573 aTrans
.translate(-aOldRange
.getMinX(), -aOldRange
.getMinY());
574 aTrans
.scale(fScaleX
, fScaleY
);
575 aPixel
.transform(aTrans
);
577 const Size
aOrigSizePixel(aBitmapEx
.GetSizePixel());
578 const Point
aClipTopLeft(
579 basegfx::fround(floor(std::max(0.0, aPixel
.getMinX()))),
580 basegfx::fround(floor(std::max(0.0, aPixel
.getMinY()))));
581 const Size
aClipSize(
582 basegfx::fround(ceil(std::min(static_cast<double>(aOrigSizePixel
.Width()), aPixel
.getWidth()))),
583 basegfx::fround(ceil(std::min(static_cast<double>(aOrigSizePixel
.Height()), aPixel
.getHeight()))));
584 const BitmapEx
aClippedBitmap(
589 pObj
->SetMergedItem(XFillStyleItem(drawing::FillStyle_BITMAP
));
590 pObj
->SetMergedItem(XFillBitmapItem(OUString(), Graphic(aClippedBitmap
)));
591 pObj
->SetMergedItem(XFillBmpTileItem(false));
592 pObj
->SetMergedItem(XFillBmpStretchItem(true));
602 // #i111954# check object for visibility
603 // used are SdrPathObj, SdrRectObj, SdrCircObj, SdrGrafObj
604 bool bVisible(false);
606 if(pObj
->HasLineStyle())
611 if(!bVisible
&& pObj
->HasFillStyle())
618 SdrTextObj
* pTextObj
= dynamic_cast< SdrTextObj
* >(pObj
);
620 if(pTextObj
&& pTextObj
->HasText())
628 SdrGrafObj
* pGrafObj
= dynamic_cast< SdrGrafObj
* >(pObj
);
632 // this may be refined to check if the graphic really is visible. It
633 // is here to ensure that graphic objects without fill, line and text
641 SdrObject::Free(pObj
);
645 maTmpList
.push_back(pObj
);
647 if(dynamic_cast< SdrPathObj
* >(pObj
))
649 const bool bClosed(pObj
->IsClosedObj());
651 mbLastObjWasPolyWithoutLine
= mbNoLine
&& bClosed
;
652 mbLastObjWasLine
= !bClosed
;
656 mbLastObjWasPolyWithoutLine
= false;
657 mbLastObjWasLine
= false;
662 void ImpSdrGDIMetaFileImport::DoAction(MetaLineAction
const & rAct
)
664 // #i73407# reformulation to use new B2DPolygon classes
665 const basegfx::B2DPoint
aStart(rAct
.GetStartPoint().X(), rAct
.GetStartPoint().Y());
666 const basegfx::B2DPoint
aEnd(rAct
.GetEndPoint().X(), rAct
.GetEndPoint().Y());
668 if(aStart
.equal(aEnd
))
671 basegfx::B2DPolygon aLine
;
672 const basegfx::B2DHomMatrix
aTransform(basegfx::utils::createScaleTranslateB2DHomMatrix(mfScaleX
, mfScaleY
, maOfs
.X(), maOfs
.Y()));
674 aLine
.append(aStart
);
676 aLine
.transform(aTransform
);
678 const LineInfo
& rLineInfo
= rAct
.GetLineInfo();
679 const sal_Int32
nNewLineWidth(rLineInfo
.GetWidth());
680 bool bCreateLineObject(true);
682 if(mbLastObjWasLine
&& (nNewLineWidth
== mnLineWidth
) && CheckLastLineMerge(aLine
))
684 bCreateLineObject
= false;
687 if(!bCreateLineObject
)
690 SdrPathObj
* pPath
= new SdrPathObj(
693 basegfx::B2DPolyPolygon(aLine
));
694 mnLineWidth
= nNewLineWidth
;
695 maLineJoin
= rLineInfo
.GetLineJoin();
696 maLineCap
= rLineInfo
.GetLineCap();
697 maDash
= XDash(css::drawing::DashStyle_RECT
,
698 rLineInfo
.GetDotCount(), rLineInfo
.GetDotLen(),
699 rLineInfo
.GetDashCount(), rLineInfo
.GetDashLen(),
700 rLineInfo
.GetDistance());
701 SetAttributes(pPath
);
703 maLineJoin
= basegfx::B2DLineJoin::NONE
;
705 InsertObj(pPath
, false);
708 void ImpSdrGDIMetaFileImport::DoAction(MetaRectAction
const & rAct
)
710 SdrRectObj
* pRect
= new SdrRectObj(
713 SetAttributes(pRect
);
717 void ImpSdrGDIMetaFileImport::DoAction(MetaRoundRectAction
const & rAct
)
719 SdrRectObj
* pRect
= new SdrRectObj(
722 SetAttributes(pRect
);
723 tools::Long nRad
=(rAct
.GetHorzRound()+rAct
.GetVertRound())/2;
725 SfxItemSet
aSet(*mpLineAttr
->GetPool(), svl::Items
<SDRATTR_ECKENRADIUS
, SDRATTR_ECKENRADIUS
>{});
726 aSet
.Put(SdrMetricItem(SDRATTR_ECKENRADIUS
, nRad
));
727 pRect
->SetMergedItemSet(aSet
);
732 void ImpSdrGDIMetaFileImport::DoAction(MetaEllipseAction
const & rAct
)
734 SdrCircObj
* pCirc
=new SdrCircObj(
738 SetAttributes(pCirc
);
742 void ImpSdrGDIMetaFileImport::DoAction(MetaArcAction
const & rAct
)
744 Point
aCenter(rAct
.GetRect().Center());
745 tools::Long nStart
=GetAngle(rAct
.GetStartPoint()-aCenter
);
746 tools::Long nEnd
=GetAngle(rAct
.GetEndPoint()-aCenter
);
747 SdrCircObj
* pCirc
= new SdrCircObj(
750 rAct
.GetRect(),nStart
,nEnd
);
751 SetAttributes(pCirc
);
755 void ImpSdrGDIMetaFileImport::DoAction(MetaPieAction
const & rAct
)
757 Point
aCenter(rAct
.GetRect().Center());
758 tools::Long nStart
=GetAngle(rAct
.GetStartPoint()-aCenter
);
759 tools::Long nEnd
=GetAngle(rAct
.GetEndPoint()-aCenter
);
760 SdrCircObj
* pCirc
= new SdrCircObj(
762 SdrCircKind::Section
,
766 SetAttributes(pCirc
);
770 void ImpSdrGDIMetaFileImport::DoAction(MetaChordAction
const & rAct
)
772 Point
aCenter(rAct
.GetRect().Center());
773 tools::Long nStart
=GetAngle(rAct
.GetStartPoint()-aCenter
);
774 tools::Long nEnd
=GetAngle(rAct
.GetEndPoint()-aCenter
);
775 SdrCircObj
* pCirc
= new SdrCircObj(
781 SetAttributes(pCirc
);
785 bool ImpSdrGDIMetaFileImport::CheckLastLineMerge(const basegfx::B2DPolygon
& rSrcPoly
)
787 // #i102706# Do not merge closed polygons
788 if(rSrcPoly
.isClosed())
793 // #i73407# reformulation to use new B2DPolygon classes
794 if(mbLastObjWasLine
&& (maOldLineColor
== mpVD
->GetLineColor()) && rSrcPoly
.count())
796 SdrObject
* pTmpObj
= !maTmpList
.empty() ? maTmpList
[maTmpList
.size() - 1] : nullptr;
797 SdrPathObj
* pLastPoly
= dynamic_cast< SdrPathObj
* >(pTmpObj
);
801 if(1 == pLastPoly
->GetPathPoly().count())
804 basegfx::B2DPolygon
aDstPoly(pLastPoly
->GetPathPoly().getB2DPolygon(0));
806 // #i102706# Do not merge closed polygons
807 if(aDstPoly
.isClosed())
814 const sal_uInt32
nMaxDstPnt(aDstPoly
.count() - 1);
815 const sal_uInt32
nMaxSrcPnt(rSrcPoly
.count() - 1);
817 if(aDstPoly
.getB2DPoint(nMaxDstPnt
) == rSrcPoly
.getB2DPoint(0))
819 aDstPoly
.append(rSrcPoly
, 1, rSrcPoly
.count() - 1);
822 else if(aDstPoly
.getB2DPoint(0) == rSrcPoly
.getB2DPoint(nMaxSrcPnt
))
824 basegfx::B2DPolygon
aNew(rSrcPoly
);
825 aNew
.append(aDstPoly
, 1, aDstPoly
.count() - 1);
829 else if(aDstPoly
.getB2DPoint(0) == rSrcPoly
.getB2DPoint(0))
832 aDstPoly
.append(rSrcPoly
, 1, rSrcPoly
.count() - 1);
835 else if(aDstPoly
.getB2DPoint(nMaxDstPnt
) == rSrcPoly
.getB2DPoint(nMaxSrcPnt
))
837 basegfx::B2DPolygon
aNew(rSrcPoly
);
839 aDstPoly
.append(aNew
, 1, aNew
.count() - 1);
846 pLastPoly
->NbcSetPathPoly(basegfx::B2DPolyPolygon(aDstPoly
));
857 bool ImpSdrGDIMetaFileImport::CheckLastPolyLineAndFillMerge(const basegfx::B2DPolyPolygon
& rPolyPolygon
)
859 // #i73407# reformulation to use new B2DPolygon classes
860 if(mbLastObjWasPolyWithoutLine
)
862 SdrObject
* pTmpObj
= !maTmpList
.empty() ? maTmpList
[maTmpList
.size() - 1] : nullptr;
863 SdrPathObj
* pLastPoly
= dynamic_cast< SdrPathObj
* >(pTmpObj
);
867 if(pLastPoly
->GetPathPoly() == rPolyPolygon
)
869 SetAttributes(nullptr);
871 if(!mbNoLine
&& mbNoFill
)
873 pLastPoly
->SetMergedItemSet(*mpLineAttr
);
884 void ImpSdrGDIMetaFileImport::checkClip()
886 if(!mpVD
->IsClipRegion())
889 maClip
= mpVD
->GetClipRegion().GetAsB2DPolyPolygon();
893 const basegfx::B2DHomMatrix
aTransform(
894 basegfx::utils::createScaleTranslateB2DHomMatrix(
900 maClip
.transform(aTransform
);
904 bool ImpSdrGDIMetaFileImport::isClip() const
906 return !maClip
.getB2DRange().isEmpty();
909 void ImpSdrGDIMetaFileImport::DoAction( MetaPolyLineAction
const & rAct
)
911 // #i73407# reformulation to use new B2DPolygon classes
912 basegfx::B2DPolygon
aSource(rAct
.GetPolygon().getB2DPolygon());
916 const basegfx::B2DHomMatrix
aTransform(basegfx::utils::createScaleTranslateB2DHomMatrix(mfScaleX
, mfScaleY
, maOfs
.X(), maOfs
.Y()));
917 aSource
.transform(aTransform
);
920 const LineInfo
& rLineInfo
= rAct
.GetLineInfo();
921 const sal_Int32
nNewLineWidth(rLineInfo
.GetWidth());
922 bool bCreateLineObject(true);
924 if(mbLastObjWasLine
&& (nNewLineWidth
== mnLineWidth
) && CheckLastLineMerge(aSource
))
926 bCreateLineObject
= false;
928 else if(mbLastObjWasPolyWithoutLine
&& CheckLastPolyLineAndFillMerge(basegfx::B2DPolyPolygon(aSource
)))
930 bCreateLineObject
= false;
933 if(!bCreateLineObject
)
936 SdrPathObj
* pPath
= new SdrPathObj(
938 aSource
.isClosed() ? OBJ_POLY
: OBJ_PLIN
,
939 basegfx::B2DPolyPolygon(aSource
));
940 mnLineWidth
= nNewLineWidth
;
941 maLineJoin
= rLineInfo
.GetLineJoin();
942 maLineCap
= rLineInfo
.GetLineCap();
943 maDash
= XDash(css::drawing::DashStyle_RECT
,
944 rLineInfo
.GetDotCount(), rLineInfo
.GetDotLen(),
945 rLineInfo
.GetDashCount(), rLineInfo
.GetDashLen(),
946 rLineInfo
.GetDistance());
947 SetAttributes(pPath
);
949 maLineJoin
= basegfx::B2DLineJoin::NONE
;
951 InsertObj(pPath
, false);
954 void ImpSdrGDIMetaFileImport::DoAction( MetaPolygonAction
const & rAct
)
956 // #i73407# reformulation to use new B2DPolygon classes
957 basegfx::B2DPolygon
aSource(rAct
.GetPolygon().getB2DPolygon());
962 const basegfx::B2DHomMatrix
aTransform(basegfx::utils::createScaleTranslateB2DHomMatrix(mfScaleX
, mfScaleY
, maOfs
.X(), maOfs
.Y()));
963 aSource
.transform(aTransform
);
965 if(!mbLastObjWasPolyWithoutLine
|| !CheckLastPolyLineAndFillMerge(basegfx::B2DPolyPolygon(aSource
)))
967 // #i73407# make sure polygon is closed, it's a filled primitive
968 aSource
.setClosed(true);
969 SdrPathObj
* pPath
= new SdrPathObj(
972 basegfx::B2DPolyPolygon(aSource
));
973 SetAttributes(pPath
);
974 InsertObj(pPath
, false);
978 void ImpSdrGDIMetaFileImport::DoAction(MetaPolyPolygonAction
const & rAct
)
980 // #i73407# reformulation to use new B2DPolygon classes
981 basegfx::B2DPolyPolygon
aSource(rAct
.GetPolyPolygon().getB2DPolyPolygon());
986 const basegfx::B2DHomMatrix
aTransform(basegfx::utils::createScaleTranslateB2DHomMatrix(mfScaleX
, mfScaleY
, maOfs
.X(), maOfs
.Y()));
987 aSource
.transform(aTransform
);
989 if(!mbLastObjWasPolyWithoutLine
|| !CheckLastPolyLineAndFillMerge(aSource
))
991 // #i73407# make sure polygon is closed, it's a filled primitive
992 aSource
.setClosed(true);
993 SdrPathObj
* pPath
= new SdrPathObj(
997 SetAttributes(pPath
);
998 InsertObj(pPath
, false);
1002 void ImpSdrGDIMetaFileImport::ImportText( const Point
& rPos
, const OUString
& rStr
, const MetaAction
& rAct
)
1004 // calc text box size, add 5% to make it fit safely
1006 FontMetric
aFontMetric( mpVD
->GetFontMetric() );
1007 vcl::Font
aFnt( mpVD
->GetFont() );
1008 FontAlign
eAlg( aFnt
.GetAlignment() );
1010 sal_Int32 nTextWidth
= static_cast<sal_Int32
>( mpVD
->GetTextWidth( rStr
) * mfScaleX
);
1011 sal_Int32 nTextHeight
= static_cast<sal_Int32
>( mpVD
->GetTextHeight() * mfScaleY
);
1013 Point
aPos( FRound(rPos
.X() * mfScaleX
+ maOfs
.X()), FRound(rPos
.Y() * mfScaleY
+ maOfs
.Y()) );
1014 Size
aSize( nTextWidth
, nTextHeight
);
1016 if ( eAlg
== ALIGN_BASELINE
)
1017 aPos
.AdjustY( -(FRound(aFontMetric
.GetAscent() * mfScaleY
)) );
1018 else if ( eAlg
== ALIGN_BOTTOM
)
1019 aPos
.AdjustY( -nTextHeight
);
1021 tools::Rectangle
aTextRect( aPos
, aSize
);
1022 SdrRectObj
* pText
= new SdrRectObj(
1027 pText
->SetMergedItem ( makeSdrTextUpperDistItem (0));
1028 pText
->SetMergedItem ( makeSdrTextLowerDistItem (0));
1029 pText
->SetMergedItem ( makeSdrTextRightDistItem (0));
1030 pText
->SetMergedItem ( makeSdrTextLeftDistItem (0));
1032 if ( aFnt
.GetAverageFontWidth() || ( rAct
.GetType() == MetaActionType::STRETCHTEXT
) )
1034 pText
->ClearMergedItem( SDRATTR_TEXT_AUTOGROWWIDTH
);
1035 pText
->SetMergedItem( makeSdrTextAutoGrowHeightItem( false ) );
1036 // don't let the margins eat the space needed for the text
1037 pText
->SetMergedItem( SdrTextFitToSizeTypeItem(drawing::TextFitToSizeType_ALLLINES
) );
1041 pText
->SetMergedItem( makeSdrTextAutoGrowWidthItem( true ) );
1044 pText
->SetLayer(mnLayer
);
1045 pText
->NbcSetText( rStr
);
1046 SetAttributes( pText
, true );
1047 pText
->SetSnapRect( aTextRect
);
1049 if (!aFnt
.IsTransparent())
1051 SfxItemSet
aAttr(*mpFillAttr
->GetPool(), svl::Items
<XATTR_FILL_FIRST
, XATTR_FILL_LAST
>{});
1052 aAttr
.Put(XFillStyleItem(drawing::FillStyle_SOLID
));
1053 aAttr
.Put(XFillColorItem(OUString(), aFnt
.GetFillColor()));
1054 pText
->SetMergedItemSet(aAttr
);
1056 sal_Int32 nAngle
= aFnt
.GetOrientation().get();
1060 double a
= nAngle
* F_PI18000
;
1063 pText
->NbcRotate(aPos
,nAngle
,nSin
,nCos
);
1065 InsertObj( pText
, false );
1068 void ImpSdrGDIMetaFileImport::DoAction(MetaTextAction
const & rAct
)
1070 OUString
aStr(rAct
.GetText());
1071 aStr
= aStr
.copy(rAct
.GetIndex(), rAct
.GetLen());
1072 ImportText( rAct
.GetPoint(), aStr
, rAct
);
1075 void ImpSdrGDIMetaFileImport::DoAction(MetaTextArrayAction
const & rAct
)
1077 OUString
aStr(rAct
.GetText());
1078 aStr
= aStr
.copy(rAct
.GetIndex(), rAct
.GetLen());
1079 ImportText( rAct
.GetPoint(), aStr
, rAct
);
1082 void ImpSdrGDIMetaFileImport::DoAction(MetaStretchTextAction
const & rAct
)
1084 OUString
aStr(rAct
.GetText());
1085 aStr
= aStr
.copy(rAct
.GetIndex(), rAct
.GetLen());
1086 ImportText( rAct
.GetPoint(), aStr
, rAct
);
1089 void ImpSdrGDIMetaFileImport::DoAction(MetaBmpAction
const & rAct
)
1091 tools::Rectangle
aRect(rAct
.GetPoint(),rAct
.GetBitmap().GetSizePixel());
1092 aRect
.AdjustRight( 1 ); aRect
.AdjustBottom( 1 );
1093 SdrGrafObj
* pGraf
= new SdrGrafObj(
1095 Graphic(BitmapEx(rAct
.GetBitmap())),
1098 // This action is not creating line and fill, set directly, do not use SetAttributes(..)
1099 pGraf
->SetMergedItem(XLineStyleItem(drawing::LineStyle_NONE
));
1100 pGraf
->SetMergedItem(XFillStyleItem(drawing::FillStyle_NONE
));
1104 void ImpSdrGDIMetaFileImport::DoAction(MetaBmpScaleAction
const & rAct
)
1106 tools::Rectangle
aRect(rAct
.GetPoint(),rAct
.GetSize());
1107 aRect
.AdjustRight( 1 ); aRect
.AdjustBottom( 1 );
1108 SdrGrafObj
* pGraf
= new SdrGrafObj(
1110 Graphic(BitmapEx(rAct
.GetBitmap())),
1113 // This action is not creating line and fill, set directly, do not use SetAttributes(..)
1114 pGraf
->SetMergedItem(XLineStyleItem(drawing::LineStyle_NONE
));
1115 pGraf
->SetMergedItem(XFillStyleItem(drawing::FillStyle_NONE
));
1119 void ImpSdrGDIMetaFileImport::DoAction(MetaBmpExAction
const & rAct
)
1121 tools::Rectangle
aRect(rAct
.GetPoint(),rAct
.GetBitmapEx().GetSizePixel());
1122 aRect
.AdjustRight( 1 ); aRect
.AdjustBottom( 1 );
1123 SdrGrafObj
* pGraf
= new SdrGrafObj(
1128 // This action is not creating line and fill, set directly, do not use SetAttributes(..)
1129 pGraf
->SetMergedItem(XLineStyleItem(drawing::LineStyle_NONE
));
1130 pGraf
->SetMergedItem(XFillStyleItem(drawing::FillStyle_NONE
));
1134 void ImpSdrGDIMetaFileImport::DoAction(MetaBmpExScaleAction
const & rAct
)
1136 tools::Rectangle
aRect(rAct
.GetPoint(),rAct
.GetSize());
1137 aRect
.AdjustRight( 1 ); aRect
.AdjustBottom( 1 );
1138 SdrGrafObj
* pGraf
= new SdrGrafObj(
1143 // This action is not creating line and fill, set directly, do not use SetAttributes(..)
1144 pGraf
->SetMergedItem(XLineStyleItem(drawing::LineStyle_NONE
));
1145 pGraf
->SetMergedItem(XFillStyleItem(drawing::FillStyle_NONE
));
1150 void ImpSdrGDIMetaFileImport::DoAction( MetaHatchAction
const & rAct
)
1152 // #i73407# reformulation to use new B2DPolygon classes
1153 basegfx::B2DPolyPolygon
aSource(rAct
.GetPolyPolygon().getB2DPolyPolygon());
1155 if(!aSource
.count())
1158 const basegfx::B2DHomMatrix
aTransform(basegfx::utils::createScaleTranslateB2DHomMatrix(mfScaleX
, mfScaleY
, maOfs
.X(), maOfs
.Y()));
1159 aSource
.transform(aTransform
);
1161 if(mbLastObjWasPolyWithoutLine
&& CheckLastPolyLineAndFillMerge(aSource
))
1164 const Hatch
& rHatch
= rAct
.GetHatch();
1165 SdrPathObj
* pPath
= new SdrPathObj(
1169 // #i125211# Use the ranges from the SdrObject to create a new empty SfxItemSet
1170 SfxItemSet
aHatchAttr(mpModel
->GetItemPool(), pPath
->GetMergedItemSet().GetRanges());
1171 css::drawing::HatchStyle eStyle
;
1173 switch(rHatch
.GetStyle())
1175 case HatchStyle::Triple
:
1177 eStyle
= css::drawing::HatchStyle_TRIPLE
;
1181 case HatchStyle::Double
:
1183 eStyle
= css::drawing::HatchStyle_DOUBLE
;
1189 eStyle
= css::drawing::HatchStyle_SINGLE
;
1194 SetAttributes(pPath
);
1195 aHatchAttr
.Put(XFillStyleItem(drawing::FillStyle_HATCH
));
1196 aHatchAttr
.Put(XFillHatchItem(XHatch(rHatch
.GetColor(), eStyle
, rHatch
.GetDistance(), rHatch
.GetAngle())));
1197 pPath
->SetMergedItemSet(aHatchAttr
);
1199 InsertObj(pPath
, false);
1203 void ImpSdrGDIMetaFileImport::DoAction(MetaLineColorAction
& rAct
)
1208 void ImpSdrGDIMetaFileImport::DoAction(MetaMapModeAction
& rAct
)
1212 mbLastObjWasPolyWithoutLine
= false;
1213 mbLastObjWasLine
= false;
1216 void ImpSdrGDIMetaFileImport::MapScaling()
1218 const size_t nCount(maTmpList
.size());
1219 const MapMode
& rMap
= mpVD
->GetMapMode();
1220 Point
aMapOrg( rMap
.GetOrigin() );
1221 bool bMov2(aMapOrg
.X() != 0 || aMapOrg
.Y() != 0);
1225 for(size_t i
= mnMapScalingOfs
; i
< nCount
; i
++)
1227 SdrObject
* pObj
= maTmpList
[i
];
1229 pObj
->NbcMove(Size(aMapOrg
.X(), aMapOrg
.Y()));
1233 mnMapScalingOfs
= nCount
;
1237 void ImpSdrGDIMetaFileImport::DoAction( MetaCommentAction
const & rAct
, GDIMetaFile
const & rMtf
, sal_uLong
& a
) // GDIMetaFile* pMtf )
1239 bool aSkipComment
= false;
1241 if (a
< rMtf
.GetActionSize() && rAct
.GetComment().equalsIgnoreAsciiCase("XGRAD_SEQ_BEGIN"))
1243 // #i125211# Check if next action is a MetaGradientExAction
1244 MetaGradientExAction
* pAct
= dynamic_cast< MetaGradientExAction
* >(rMtf
.GetAction(a
+ 1));
1246 if( pAct
&& pAct
->GetType() == MetaActionType::GRADIENTEX
)
1248 // #i73407# reformulation to use new B2DPolygon classes
1249 basegfx::B2DPolyPolygon
aSource(pAct
->GetPolyPolygon().getB2DPolyPolygon());
1253 if(!mbLastObjWasPolyWithoutLine
|| !CheckLastPolyLineAndFillMerge(aSource
))
1255 const Gradient
& rGrad
= pAct
->GetGradient();
1256 SdrPathObj
* pPath
= new SdrPathObj(
1260 // #i125211# Use the ranges from the SdrObject to create a new empty SfxItemSet
1261 SfxItemSet
aGradAttr(mpModel
->GetItemPool(), pPath
->GetMergedItemSet().GetRanges());
1262 XGradient aXGradient
;
1264 aXGradient
.SetGradientStyle(static_cast<css::awt::GradientStyle
>(rGrad
.GetStyle()));
1265 aXGradient
.SetStartColor(rGrad
.GetStartColor());
1266 aXGradient
.SetEndColor(rGrad
.GetEndColor());
1267 aXGradient
.SetAngle(rGrad
.GetAngle());
1268 aXGradient
.SetBorder(rGrad
.GetBorder());
1269 aXGradient
.SetXOffset(rGrad
.GetOfsX());
1270 aXGradient
.SetYOffset(rGrad
.GetOfsY());
1271 aXGradient
.SetStartIntens(rGrad
.GetStartIntensity());
1272 aXGradient
.SetEndIntens(rGrad
.GetEndIntensity());
1273 aXGradient
.SetSteps(rGrad
.GetSteps());
1275 // no need to use SetAttributes(..) here since line and fill style
1276 // need to be set individually
1277 // SetAttributes(pPath);
1279 // switch line off; if there was one there will be a
1280 // MetaActionType::POLYLINE following creating another object
1281 aGradAttr
.Put(XLineStyleItem(drawing::LineStyle_NONE
));
1283 // add detected gradient fillstyle
1284 aGradAttr
.Put(XFillStyleItem(drawing::FillStyle_GRADIENT
));
1285 aGradAttr
.Put(XFillGradientItem(aXGradient
));
1287 pPath
->SetMergedItemSet(aGradAttr
);
1293 aSkipComment
= true;
1299 // #i125211# forward until closing MetaCommentAction
1300 MetaAction
* pSkipAct
= rMtf
.GetAction(++a
);
1303 && ((pSkipAct
->GetType() != MetaActionType::COMMENT
)
1304 || !(static_cast<MetaCommentAction
*>(pSkipAct
)->GetComment().equalsIgnoreAsciiCase("XGRAD_SEQ_END"))))
1306 pSkipAct
= rMtf
.GetAction(++a
);
1311 void ImpSdrGDIMetaFileImport::DoAction(MetaTextRectAction
const & rAct
)
1315 mpVD
->AddTextRectActions(rAct
.GetRect(), rAct
.GetText(), rAct
.GetStyle(), aTemp
);
1316 DoLoopActions(aTemp
, nullptr, nullptr);
1319 void ImpSdrGDIMetaFileImport::DoAction(MetaBmpScalePartAction
const & rAct
)
1321 tools::Rectangle
aRect(rAct
.GetDestPoint(), rAct
.GetDestSize());
1322 BitmapEx
aBitmapEx(rAct
.GetBitmap());
1324 aRect
.AdjustRight( 1 );
1325 aRect
.AdjustBottom( 1 );
1326 aBitmapEx
.Crop(tools::Rectangle(rAct
.GetSrcPoint(), rAct
.GetSrcSize()));
1327 SdrGrafObj
* pGraf
= new SdrGrafObj(
1332 // This action is not creating line and fill, set directly, do not use SetAttributes(..)
1333 pGraf
->SetMergedItem(XLineStyleItem(drawing::LineStyle_NONE
));
1334 pGraf
->SetMergedItem(XFillStyleItem(drawing::FillStyle_NONE
));
1338 void ImpSdrGDIMetaFileImport::DoAction(MetaBmpExScalePartAction
const & rAct
)
1340 tools::Rectangle
aRect(rAct
.GetDestPoint(),rAct
.GetDestSize());
1341 BitmapEx
aBitmapEx(rAct
.GetBitmapEx());
1343 aRect
.AdjustRight( 1 );
1344 aRect
.AdjustBottom( 1 );
1345 aBitmapEx
.Crop(tools::Rectangle(rAct
.GetSrcPoint(), rAct
.GetSrcSize()));
1346 SdrGrafObj
* pGraf
= new SdrGrafObj(
1351 // This action is not creating line and fill, set directly, do not use SetAttributes(..)
1352 pGraf
->SetMergedItem(XLineStyleItem(drawing::LineStyle_NONE
));
1353 pGraf
->SetMergedItem(XFillStyleItem(drawing::FillStyle_NONE
));
1357 void ImpSdrGDIMetaFileImport::DoAction(MetaMaskAction
const & rAct
)
1359 tools::Rectangle
aRect(rAct
.GetPoint(), rAct
.GetBitmap().GetSizePixel());
1360 BitmapEx
aBitmapEx(rAct
.GetBitmap(), rAct
.GetColor());
1362 aRect
.AdjustRight( 1 ); aRect
.AdjustBottom( 1 );
1363 SdrGrafObj
* pGraf
= new SdrGrafObj(
1368 // This action is not creating line and fill, set directly, do not use SetAttributes(..)
1369 pGraf
->SetMergedItem(XLineStyleItem(drawing::LineStyle_NONE
));
1370 pGraf
->SetMergedItem(XFillStyleItem(drawing::FillStyle_NONE
));
1374 void ImpSdrGDIMetaFileImport::DoAction(MetaMaskScaleAction
const & rAct
)
1376 tools::Rectangle
aRect(rAct
.GetPoint(), rAct
.GetSize());
1377 BitmapEx
aBitmapEx(rAct
.GetBitmap(), rAct
.GetColor());
1379 aRect
.AdjustRight( 1 ); aRect
.AdjustBottom( 1 );
1380 SdrGrafObj
* pGraf
= new SdrGrafObj(
1385 // This action is not creating line and fill, set directly, do not use SetAttributes(..)
1386 pGraf
->SetMergedItem(XLineStyleItem(drawing::LineStyle_NONE
));
1387 pGraf
->SetMergedItem(XFillStyleItem(drawing::FillStyle_NONE
));
1391 void ImpSdrGDIMetaFileImport::DoAction(MetaMaskScalePartAction
const & rAct
)
1393 tools::Rectangle
aRect(rAct
.GetDestPoint(), rAct
.GetDestSize());
1394 BitmapEx
aBitmapEx(rAct
.GetBitmap(), rAct
.GetColor());
1396 aRect
.AdjustRight( 1 ); aRect
.AdjustBottom( 1 );
1397 aBitmapEx
.Crop(tools::Rectangle(rAct
.GetSrcPoint(), rAct
.GetSrcSize()));
1398 SdrGrafObj
* pGraf
= new SdrGrafObj(
1403 // This action is not creating line and fill, set directly, do not use SetAttributes(..)
1404 pGraf
->SetMergedItem(XLineStyleItem(drawing::LineStyle_NONE
));
1405 pGraf
->SetMergedItem(XFillStyleItem(drawing::FillStyle_NONE
));
1411 css::awt::GradientStyle
getXGradientStyleFromGradientStyle(const GradientStyle
& rGradientStyle
)
1413 css::awt::GradientStyle
aXGradientStyle(css::awt::GradientStyle_LINEAR
);
1415 switch(rGradientStyle
)
1417 case GradientStyle::Linear
: aXGradientStyle
= css::awt::GradientStyle_LINEAR
; break;
1418 case GradientStyle::Axial
: aXGradientStyle
= css::awt::GradientStyle_AXIAL
; break;
1419 case GradientStyle::Radial
: aXGradientStyle
= css::awt::GradientStyle_RADIAL
; break;
1420 case GradientStyle::Elliptical
: aXGradientStyle
= css::awt::GradientStyle_ELLIPTICAL
; break;
1421 case GradientStyle::Square
: aXGradientStyle
= css::awt::GradientStyle_SQUARE
; break;
1422 case GradientStyle::Rect
: aXGradientStyle
= css::awt::GradientStyle_RECT
; break;
1424 // Needed due to GradientStyle::FORCE_EQUAL_SIZE; this again is needed
1425 // to force the enum defines in VCL to a defined size for the compilers,
1426 // so despite it is never used it cannot be removed (would break the
1427 // API implementation probably).
1428 case GradientStyle::FORCE_EQUAL_SIZE
: break;
1433 return aXGradientStyle
;
1437 void ImpSdrGDIMetaFileImport::DoAction(MetaGradientAction
const & rAct
)
1439 basegfx::B2DRange aRange
= vcl::unotools::b2DRectangleFromRectangle(rAct
.GetRect());
1441 if(aRange
.isEmpty())
1444 const basegfx::B2DHomMatrix
aTransform(basegfx::utils::createScaleTranslateB2DHomMatrix(mfScaleX
, mfScaleY
, maOfs
.X(), maOfs
.Y()));
1445 aRange
.transform(aTransform
);
1446 const Gradient
& rGradient
= rAct
.GetGradient();
1447 SdrRectObj
* pRect
= new SdrRectObj(
1450 floor(aRange
.getMinX()),
1451 floor(aRange
.getMinY()),
1452 ceil(aRange
.getMaxX()),
1453 ceil(aRange
.getMaxY())));
1454 // #i125211# Use the ranges from the SdrObject to create a new empty SfxItemSet
1455 SfxItemSet
aGradientAttr(mpModel
->GetItemPool(), pRect
->GetMergedItemSet().GetRanges());
1456 const css::awt::GradientStyle
aXGradientStyle(getXGradientStyleFromGradientStyle(rGradient
.GetStyle()));
1457 const XFillGradientItem
aXFillGradientItem(
1459 rGradient
.GetStartColor(),
1460 rGradient
.GetEndColor(),
1462 rGradient
.GetAngle(),
1463 rGradient
.GetOfsX(),
1464 rGradient
.GetOfsY(),
1465 rGradient
.GetBorder(),
1466 rGradient
.GetStartIntensity(),
1467 rGradient
.GetEndIntensity(),
1468 rGradient
.GetSteps()));
1470 SetAttributes(pRect
);
1471 aGradientAttr
.Put(XFillStyleItem(drawing::FillStyle_GRADIENT
)); // #i125211#
1472 aGradientAttr
.Put(aXFillGradientItem
);
1473 pRect
->SetMergedItemSet(aGradientAttr
);
1475 InsertObj(pRect
, false);
1478 void ImpSdrGDIMetaFileImport::DoAction(MetaTransparentAction
const & rAct
)
1480 basegfx::B2DPolyPolygon
aSource(rAct
.GetPolyPolygon().getB2DPolyPolygon());
1482 if(!aSource
.count())
1485 const basegfx::B2DHomMatrix
aTransform(basegfx::utils::createScaleTranslateB2DHomMatrix(mfScaleX
, mfScaleY
, maOfs
.X(), maOfs
.Y()));
1486 aSource
.transform(aTransform
);
1487 aSource
.setClosed(true);
1489 SdrPathObj
* pPath
= new SdrPathObj(
1493 SetAttributes(pPath
);
1494 pPath
->SetMergedItem(XFillTransparenceItem(rAct
.GetTransparence()));
1495 InsertObj(pPath
, false);
1498 void ImpSdrGDIMetaFileImport::DoAction(MetaGradientExAction
const & rAct
)
1500 basegfx::B2DPolyPolygon
aSource(rAct
.GetPolyPolygon().getB2DPolyPolygon());
1502 if(!aSource
.count())
1505 const basegfx::B2DHomMatrix
aTransform(basegfx::utils::createScaleTranslateB2DHomMatrix(mfScaleX
, mfScaleY
, maOfs
.X(), maOfs
.Y()));
1506 aSource
.transform(aTransform
);
1508 if(mbLastObjWasPolyWithoutLine
&& CheckLastPolyLineAndFillMerge(aSource
))
1511 const Gradient
& rGradient
= rAct
.GetGradient();
1512 SdrPathObj
* pPath
= new SdrPathObj(
1516 // #i125211# Use the ranges from the SdrObject to create a new empty SfxItemSet
1517 SfxItemSet
aGradientAttr(mpModel
->GetItemPool(), pPath
->GetMergedItemSet().GetRanges());
1518 const css::awt::GradientStyle
aXGradientStyle(getXGradientStyleFromGradientStyle(rGradient
.GetStyle()));
1519 const XFillGradientItem
aXFillGradientItem(
1521 rGradient
.GetStartColor(),
1522 rGradient
.GetEndColor(),
1524 rGradient
.GetAngle(),
1525 rGradient
.GetOfsX(),
1526 rGradient
.GetOfsY(),
1527 rGradient
.GetBorder(),
1528 rGradient
.GetStartIntensity(),
1529 rGradient
.GetEndIntensity(),
1530 rGradient
.GetSteps()));
1532 SetAttributes(pPath
);
1533 aGradientAttr
.Put(XFillStyleItem(drawing::FillStyle_GRADIENT
)); // #i125211#
1534 aGradientAttr
.Put(aXFillGradientItem
);
1535 pPath
->SetMergedItemSet(aGradientAttr
);
1537 InsertObj(pPath
, false);
1540 void ImpSdrGDIMetaFileImport::DoAction(MetaFloatTransparentAction
const & rAct
)
1542 const GDIMetaFile
& rMtf
= rAct
.GetGDIMetaFile();
1544 if(!rMtf
.GetActionSize())
1547 const tools::Rectangle
aRect(rAct
.GetPoint(),rAct
.GetSize());
1549 // convert metafile sub-content to BitmapEx
1551 convertMetafileToBitmapEx(
1553 vcl::unotools::b2DRectangleFromRectangle(aRect
),
1557 const Gradient
& rGradient
= rAct
.GetGradient();
1558 basegfx::BColor
aStart(rGradient
.GetStartColor().getBColor());
1559 basegfx::BColor
aEnd(rGradient
.GetEndColor().getBColor());
1561 if(100 != rGradient
.GetStartIntensity())
1563 aStart
*= static_cast<double>(rGradient
.GetStartIntensity()) / 100.0;
1566 if(100 != rGradient
.GetEndIntensity())
1568 aEnd
*= static_cast<double>(rGradient
.GetEndIntensity()) / 100.0;
1571 const bool bEqualColors(aStart
== aEnd
);
1572 const bool bNoSteps(1 == rGradient
.GetSteps());
1573 bool bCreateObject(true);
1574 bool bHasNewMask(false);
1576 double fTransparence(0.0);
1577 bool bFixedTransparence(false);
1579 if(bEqualColors
|| bNoSteps
)
1581 // single transparence
1582 const basegfx::BColor
aMedium(basegfx::average(aStart
, aEnd
));
1583 fTransparence
= aMedium
.luminance();
1585 if(basegfx::fTools::lessOrEqual(fTransparence
, 0.0))
1587 // no transparence needed, all done
1589 else if(basegfx::fTools::moreOrEqual(fTransparence
, 1.0))
1591 // all transparent, no object
1592 bCreateObject
= false;
1596 // 0.0 < transparence < 1.0, apply fixed transparence
1597 bFixedTransparence
= true;
1602 // gradient transparence
1603 ScopedVclPtrInstance
< VirtualDevice
> pVDev
;
1605 pVDev
->SetOutputSizePixel(aBitmapEx
.GetBitmap().GetSizePixel());
1606 pVDev
->DrawGradient(tools::Rectangle(Point(0, 0), pVDev
->GetOutputSizePixel()), rGradient
);
1608 aNewMask
= AlphaMask(pVDev
->GetBitmap(Point(0, 0), pVDev
->GetOutputSizePixel()));
1615 if(bHasNewMask
|| bFixedTransparence
)
1617 if(!aBitmapEx
.IsAlpha() && !aBitmapEx
.IsTransparent())
1619 // no transparence yet, apply new one
1620 if(bFixedTransparence
)
1622 sal_uInt8
aAlpha(basegfx::fround(fTransparence
* 255.0));
1624 aNewMask
= AlphaMask(aBitmapEx
.GetBitmap().GetSizePixel(), &aAlpha
);
1627 aBitmapEx
= BitmapEx(aBitmapEx
.GetBitmap(), aNewMask
);
1631 vcl::bitmap::DrawAlphaBitmapAndAlphaGradient(aBitmapEx
, bFixedTransparence
, fTransparence
, aNewMask
);
1635 // create and add object
1636 SdrGrafObj
* pGraf
= new SdrGrafObj(
1641 // for MetaFloatTransparentAction, do not use SetAttributes(...)
1642 // since these metafile content is not used to draw line/fill
1643 // dependent of these setting at the device content
1644 pGraf
->SetMergedItem(XLineStyleItem(drawing::LineStyle_NONE
));
1645 pGraf
->SetMergedItem(XFillStyleItem(drawing::FillStyle_NONE
));
1649 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */