Line data Source code
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 : #include "svdfmtf.hxx"
21 : #include <editeng/editdata.hxx>
22 : #include <math.h>
23 : #include <svx/xpoly.hxx>
24 : #include <vcl/svapp.hxx>
25 : #include <editeng/eeitem.hxx>
26 : #include <editeng/fhgtitem.hxx>
27 : #include <editeng/wghtitem.hxx>
28 : #include <editeng/postitem.hxx>
29 : #include <editeng/udlnitem.hxx>
30 : #include <editeng/crossedoutitem.hxx>
31 : #include <editeng/shdditem.hxx>
32 : #include <svx/xlnclit.hxx>
33 : #include <svx/xlncapit.hxx>
34 : #include <svx/xlnwtit.hxx>
35 : #include <svx/xflclit.hxx>
36 : #include <svx/xgrad.hxx>
37 : #include <svx/xflgrit.hxx>
38 : #include <editeng/fontitem.hxx>
39 : #include <editeng/autokernitem.hxx>
40 : #include <editeng/wrlmitem.hxx>
41 : #include <editeng/contouritem.hxx>
42 : #include <editeng/colritem.hxx>
43 : #include <vcl/metric.hxx>
44 : #include <editeng/charscaleitem.hxx>
45 : #include <svx/xflhtit.hxx>
46 : #include <svx/svdattr.hxx>
47 : #include <svx/svdmodel.hxx>
48 : #include <svx/svdpage.hxx>
49 : #include <svx/svdobj.hxx>
50 : #include <svx/svdotext.hxx>
51 : #include <svx/svdorect.hxx>
52 : #include <svx/svdocirc.hxx>
53 : #include <svx/svdograf.hxx>
54 : #include <svx/svdopath.hxx>
55 : #include <svx/svdetc.hxx>
56 : #include <svl/itemset.hxx>
57 : #include <basegfx/polygon/b2dpolygon.hxx>
58 : #include <tools/helpers.hxx>
59 : #include <basegfx/matrix/b2dhommatrix.hxx>
60 : #include <basegfx/matrix/b2dhommatrixtools.hxx>
61 : #include <svx/xlinjoit.hxx>
62 : #include <svx/xlndsit.hxx>
63 : #include <basegfx/polygon/b2dpolygonclipper.hxx>
64 : #include <svx/xbtmpit.hxx>
65 : #include <svx/xfltrit.hxx>
66 : #include <vcl/bmpacc.hxx>
67 : #include <svx/xflbmtit.hxx>
68 : #include <svx/xflbstit.hxx>
69 : #include <svx/svdpntv.hxx>
70 : #include <basegfx/polygon/b2dpolypolygontools.hxx>
71 : #include <svx/svditer.hxx>
72 : #include <svx/svdogrp.hxx>
73 :
74 : using namespace com::sun::star;
75 :
76 0 : ImpSdrGDIMetaFileImport::ImpSdrGDIMetaFileImport(
77 : SdrModel& rModel,
78 : SdrLayerID nLay,
79 : const Rectangle& rRect)
80 : : maTmpList(),
81 : mpVD(VclPtr<VirtualDevice>::Create()),
82 : maScaleRect(rRect),
83 : mnMapScalingOfs(0),
84 : mpLineAttr(0),
85 : mpFillAttr(0),
86 : mpTextAttr(0),
87 : mpModel(&rModel),
88 : mnLayer(nLay),
89 : maOldLineColor(),
90 : mnLineWidth(0),
91 : maLineJoin(basegfx::B2DLineJoin::NONE),
92 : maLineCap(com::sun::star::drawing::LineCap_BUTT),
93 : maDash(css::drawing::DashStyle_RECT, 0, 0, 0, 0, 0),
94 : mbMov(false),
95 : mbSize(false),
96 : maOfs(0, 0),
97 : mfScaleX(1.0),
98 : mfScaleY(1.0),
99 : maScaleX(1.0),
100 : maScaleY(1.0),
101 : mbFntDirty(true),
102 : mbLastObjWasPolyWithoutLine(false),
103 : mbNoLine(false),
104 : mbNoFill(false),
105 : mbLastObjWasLine(false),
106 0 : maClip()
107 : {
108 0 : mpVD->EnableOutput(false);
109 0 : mpVD->SetLineColor();
110 0 : mpVD->SetFillColor();
111 0 : maOldLineColor.SetRed( mpVD->GetLineColor().GetRed() + 1 );
112 0 : mpLineAttr = new SfxItemSet(rModel.GetItemPool(), XATTR_LINE_FIRST, XATTR_LINE_LAST, 0, 0);
113 0 : mpFillAttr = new SfxItemSet(rModel.GetItemPool(), XATTR_FILL_FIRST, XATTR_FILL_LAST, 0, 0);
114 0 : mpTextAttr = new SfxItemSet(rModel.GetItemPool(), EE_ITEMS_START, EE_ITEMS_END, 0, 0);
115 0 : checkClip();
116 0 : }
117 :
118 0 : ImpSdrGDIMetaFileImport::~ImpSdrGDIMetaFileImport()
119 : {
120 0 : delete mpLineAttr;
121 0 : delete mpFillAttr;
122 0 : delete mpTextAttr;
123 0 : }
124 :
125 0 : void ImpSdrGDIMetaFileImport::DoLoopActions(GDIMetaFile& rMtf, SvdProgressInfo* pProgrInfo, sal_uInt32* pActionsToReport)
126 : {
127 0 : const sal_uLong nCount(rMtf.GetActionSize());
128 :
129 0 : for(sal_uLong a(0); a < nCount; a++)
130 : {
131 0 : MetaAction* pAct = rMtf.GetAction(a);
132 :
133 0 : if(!pAct)
134 : {
135 : OSL_ENSURE(false, "OOps, no action at valid position (!)");
136 0 : pAct = rMtf.GetAction(0);
137 : }
138 :
139 0 : switch (pAct->GetType())
140 : {
141 0 : case MetaActionType::PIXEL : break;
142 0 : case MetaActionType::POINT : break;
143 0 : case MetaActionType::LINE : DoAction(static_cast<MetaLineAction &>(*pAct)); break;
144 0 : case MetaActionType::RECT : DoAction(static_cast<MetaRectAction &>(*pAct)); break;
145 0 : case MetaActionType::ROUNDRECT : DoAction(static_cast<MetaRoundRectAction &>(*pAct)); break;
146 0 : case MetaActionType::ELLIPSE : DoAction(static_cast<MetaEllipseAction &>(*pAct)); break;
147 0 : case MetaActionType::ARC : DoAction(static_cast<MetaArcAction &>(*pAct)); break;
148 0 : case MetaActionType::PIE : DoAction(static_cast<MetaPieAction &>(*pAct)); break;
149 0 : case MetaActionType::CHORD : DoAction(static_cast<MetaChordAction &>(*pAct)); break;
150 0 : case MetaActionType::POLYLINE : DoAction(static_cast<MetaPolyLineAction &>(*pAct)); break;
151 0 : case MetaActionType::POLYGON : DoAction(static_cast<MetaPolygonAction &>(*pAct)); break;
152 0 : case MetaActionType::POLYPOLYGON : DoAction(static_cast<MetaPolyPolygonAction &>(*pAct)); break;
153 0 : case MetaActionType::TEXT : DoAction(static_cast<MetaTextAction &>(*pAct)); break;
154 0 : case MetaActionType::TEXTARRAY : DoAction(static_cast<MetaTextArrayAction &>(*pAct)); break;
155 0 : case MetaActionType::STRETCHTEXT : DoAction(static_cast<MetaStretchTextAction &>(*pAct)); break;
156 0 : case MetaActionType::BMP : DoAction(static_cast<MetaBmpAction &>(*pAct)); break;
157 0 : case MetaActionType::BMPSCALE : DoAction(static_cast<MetaBmpScaleAction &>(*pAct)); break;
158 0 : case MetaActionType::BMPEX : DoAction(static_cast<MetaBmpExAction &>(*pAct)); break;
159 0 : case MetaActionType::BMPEXSCALE : DoAction(static_cast<MetaBmpExScaleAction &>(*pAct)); break;
160 0 : case MetaActionType::LINECOLOR : DoAction(static_cast<MetaLineColorAction &>(*pAct)); break;
161 0 : case MetaActionType::FILLCOLOR : DoAction(static_cast<MetaFillColorAction &>(*pAct)); break;
162 0 : case MetaActionType::TEXTCOLOR : DoAction(static_cast<MetaTextColorAction &>(*pAct)); break;
163 0 : case MetaActionType::TEXTFILLCOLOR : DoAction(static_cast<MetaTextFillColorAction &>(*pAct)); break;
164 0 : case MetaActionType::FONT : DoAction(static_cast<MetaFontAction &>(*pAct)); break;
165 0 : case MetaActionType::TEXTALIGN : DoAction(static_cast<MetaTextAlignAction &>(*pAct)); break;
166 0 : case MetaActionType::MAPMODE : DoAction(static_cast<MetaMapModeAction &>(*pAct)); break;
167 0 : case MetaActionType::CLIPREGION : DoAction(static_cast<MetaClipRegionAction &>(*pAct)); break;
168 0 : case MetaActionType::MOVECLIPREGION : DoAction(static_cast<MetaMoveClipRegionAction &>(*pAct)); break;
169 0 : case MetaActionType::ISECTRECTCLIPREGION: DoAction(static_cast<MetaISectRectClipRegionAction&>(*pAct)); break;
170 0 : case MetaActionType::ISECTREGIONCLIPREGION: DoAction(static_cast<MetaISectRegionClipRegionAction&>(*pAct)); break;
171 0 : case MetaActionType::RASTEROP : DoAction(static_cast<MetaRasterOpAction &>(*pAct)); break;
172 0 : case MetaActionType::PUSH : DoAction(static_cast<MetaPushAction &>(*pAct)); break;
173 0 : case MetaActionType::POP : DoAction(static_cast<MetaPopAction &>(*pAct)); break;
174 0 : case MetaActionType::HATCH : DoAction(static_cast<MetaHatchAction &>(*pAct)); break;
175 :
176 : // #i125211# MetaCommentAction may change index, thus hand it over
177 0 : case MetaActionType::COMMENT : DoAction(static_cast<MetaCommentAction&>(*pAct), rMtf, a);
178 0 : break;
179 :
180 : // missing actions added
181 0 : case MetaActionType::TEXTRECT : DoAction(static_cast<MetaTextRectAction&>(*pAct)); break;
182 0 : case MetaActionType::BMPSCALEPART : DoAction(static_cast<MetaBmpScalePartAction&>(*pAct)); break;
183 0 : case MetaActionType::BMPEXSCALEPART : DoAction(static_cast<MetaBmpExScalePartAction&>(*pAct)); break;
184 0 : case MetaActionType::MASK : DoAction(static_cast<MetaMaskAction&>(*pAct)); break;
185 0 : case MetaActionType::MASKSCALE : DoAction(static_cast<MetaMaskScaleAction&>(*pAct)); break;
186 0 : case MetaActionType::MASKSCALEPART : DoAction(static_cast<MetaMaskScalePartAction&>(*pAct)); break;
187 0 : case MetaActionType::GRADIENT : DoAction(static_cast<MetaGradientAction&>(*pAct)); break;
188 0 : case MetaActionType::WALLPAPER : DoAction(static_cast<MetaWallpaperAction&>(*pAct)); break;
189 0 : case MetaActionType::Transparent : DoAction(static_cast<MetaTransparentAction&>(*pAct)); break;
190 0 : case MetaActionType::EPS : DoAction(static_cast<MetaEPSAction&>(*pAct)); break;
191 0 : case MetaActionType::REFPOINT : DoAction(static_cast<MetaRefPointAction&>(*pAct)); break;
192 0 : case MetaActionType::TEXTLINECOLOR : DoAction(static_cast<MetaTextLineColorAction&>(*pAct)); break;
193 0 : case MetaActionType::TEXTLINE : DoAction(static_cast<MetaTextLineAction&>(*pAct)); break;
194 0 : case MetaActionType::FLOATTRANSPARENT : DoAction(static_cast<MetaFloatTransparentAction&>(*pAct)); break;
195 0 : case MetaActionType::GRADIENTEX : DoAction(static_cast<MetaGradientExAction&>(*pAct)); break;
196 0 : case MetaActionType::LAYOUTMODE : DoAction(static_cast<MetaLayoutModeAction&>(*pAct)); break;
197 0 : case MetaActionType::TEXTLANGUAGE : DoAction(static_cast<MetaTextLanguageAction&>(*pAct)); break;
198 0 : case MetaActionType::OVERLINECOLOR : DoAction(static_cast<MetaOverlineColorAction&>(*pAct)); break;
199 0 : default: break;
200 : }
201 :
202 0 : if(pProgrInfo && pActionsToReport)
203 : {
204 0 : (*pActionsToReport)++;
205 :
206 0 : if(*pActionsToReport >= 16) // update all 16 actions
207 : {
208 0 : if(!pProgrInfo->ReportActions(*pActionsToReport))
209 0 : break;
210 :
211 0 : *pActionsToReport = 0;
212 : }
213 : }
214 : }
215 0 : }
216 :
217 0 : size_t ImpSdrGDIMetaFileImport::DoImport(
218 : const GDIMetaFile& rMtf,
219 : SdrObjList& rOL,
220 : size_t nInsPos,
221 : SvdProgressInfo* pProgrInfo)
222 : {
223 : // setup some global scale parameter
224 : // mfScaleX, mfScaleY, maScaleX, maScaleY, mbMov, mbSize
225 0 : mfScaleX = mfScaleY = 1.0;
226 0 : const Size aMtfSize(rMtf.GetPrefSize());
227 :
228 0 : if(aMtfSize.Width() & aMtfSize.Height() && (!maScaleRect.IsEmpty()))
229 : {
230 0 : maOfs = maScaleRect.TopLeft();
231 :
232 0 : if(aMtfSize.Width() != (maScaleRect.GetWidth() - 1))
233 : {
234 0 : mfScaleX = (double)( maScaleRect.GetWidth() - 1 ) / (double)aMtfSize.Width();
235 : }
236 :
237 0 : if(aMtfSize.Height() != (maScaleRect.GetHeight() - 1))
238 : {
239 0 : mfScaleY = (double)( maScaleRect.GetHeight() - 1 ) / (double)aMtfSize.Height();
240 : }
241 : }
242 :
243 0 : mbMov = maOfs.X()!=0 || maOfs.Y()!=0;
244 0 : mbSize = false;
245 0 : maScaleX = Fraction( 1, 1 );
246 0 : maScaleY = Fraction( 1, 1 );
247 :
248 0 : if(aMtfSize.Width() != (maScaleRect.GetWidth() - 1))
249 : {
250 0 : maScaleX = Fraction(maScaleRect.GetWidth() - 1, aMtfSize.Width());
251 0 : mbSize = true;
252 : }
253 :
254 0 : if(aMtfSize.Height() != (maScaleRect.GetHeight() - 1))
255 : {
256 0 : maScaleY = Fraction(maScaleRect.GetHeight() - 1, aMtfSize.Height());
257 0 : mbSize = true;
258 : }
259 :
260 0 : if(pProgrInfo)
261 : {
262 0 : pProgrInfo->SetActionCount(rMtf.GetActionSize());
263 : }
264 :
265 0 : sal_uInt32 nActionsToReport(0);
266 :
267 : // execute
268 0 : DoLoopActions(const_cast< GDIMetaFile& >(rMtf), pProgrInfo, &nActionsToReport);
269 :
270 0 : if(pProgrInfo)
271 : {
272 0 : pProgrInfo->ReportActions(nActionsToReport);
273 0 : nActionsToReport = 0;
274 : }
275 :
276 : // MapMode scaling
277 0 : MapScaling();
278 :
279 : // To calculate the progress meter, we use GetActionSize()*3.
280 : // However, maTmpList has a lower entry count limit than GetActionSize(),
281 : // so the actions that were assumed were too much have to be re-added.
282 0 : nActionsToReport = (rMtf.GetActionSize() - maTmpList.size()) * 2;
283 :
284 : // announce all currently unannounced rescales
285 0 : if(pProgrInfo)
286 : {
287 0 : pProgrInfo->ReportRescales(nActionsToReport);
288 0 : pProgrInfo->SetInsertCount(maTmpList.size());
289 : }
290 :
291 0 : nActionsToReport = 0;
292 :
293 : // insert all objects cached in aTmpList now into rOL from nInsPos
294 0 : nInsPos = std::min(nInsPos, rOL.GetObjCount());
295 :
296 0 : SdrInsertReason aReason(SDRREASON_VIEWCALL);
297 :
298 0 : for(size_t i = 0; i < maTmpList.size(); ++i)
299 : {
300 0 : SdrObject* pObj = maTmpList[i];
301 0 : rOL.NbcInsertObject(pObj, nInsPos, &aReason);
302 0 : nInsPos++;
303 :
304 0 : if(pProgrInfo)
305 : {
306 0 : nActionsToReport++;
307 :
308 0 : if(nActionsToReport >= 32) // update all 32 actions
309 : {
310 0 : pProgrInfo->ReportInserts(nActionsToReport);
311 0 : nActionsToReport = 0;
312 : }
313 : }
314 : }
315 :
316 : // report all remaining inserts for the last time
317 0 : if(pProgrInfo)
318 : {
319 0 : pProgrInfo->ReportInserts(nActionsToReport);
320 : }
321 :
322 0 : return maTmpList.size();
323 : }
324 :
325 0 : void ImpSdrGDIMetaFileImport::SetAttributes(SdrObject* pObj, bool bForceTextAttr)
326 : {
327 0 : mbNoLine = false;
328 0 : mbNoFill = false;
329 0 : bool bLine(!bForceTextAttr);
330 0 : bool bFill(!pObj || (pObj->IsClosedObj() && !bForceTextAttr));
331 0 : bool bText(bForceTextAttr || (pObj && pObj->GetOutlinerParaObject()));
332 :
333 0 : if(bLine)
334 : {
335 0 : if(mnLineWidth)
336 : {
337 0 : mpLineAttr->Put(XLineWidthItem(mnLineWidth));
338 : }
339 : else
340 : {
341 0 : mpLineAttr->Put(XLineWidthItem(0));
342 : }
343 :
344 0 : maOldLineColor = mpVD->GetLineColor();
345 :
346 0 : if(mpVD->IsLineColor())
347 : {
348 0 : mpLineAttr->Put(XLineStyleItem(drawing::LineStyle_SOLID));
349 0 : mpLineAttr->Put(XLineColorItem(OUString(), mpVD->GetLineColor()));
350 : }
351 : else
352 : {
353 0 : mpLineAttr->Put(XLineStyleItem(drawing::LineStyle_NONE));
354 : }
355 :
356 0 : switch(maLineJoin)
357 : {
358 : default : // basegfx::B2DLineJoin::NONE
359 0 : mpLineAttr->Put(XLineJointItem(com::sun::star::drawing::LineJoint_NONE));
360 0 : break;
361 : case basegfx::B2DLineJoin::Middle:
362 0 : mpLineAttr->Put(XLineJointItem(com::sun::star::drawing::LineJoint_MIDDLE));
363 0 : break;
364 : case basegfx::B2DLineJoin::Bevel:
365 0 : mpLineAttr->Put(XLineJointItem(com::sun::star::drawing::LineJoint_BEVEL));
366 0 : break;
367 : case basegfx::B2DLineJoin::Miter:
368 0 : mpLineAttr->Put(XLineJointItem(com::sun::star::drawing::LineJoint_MITER));
369 0 : break;
370 : case basegfx::B2DLineJoin::Round:
371 0 : mpLineAttr->Put(XLineJointItem(com::sun::star::drawing::LineJoint_ROUND));
372 0 : break;
373 : }
374 :
375 : // Add LineCap support
376 0 : mpLineAttr->Put(XLineCapItem(maLineCap));
377 :
378 0 : if(((maDash.GetDots() && maDash.GetDotLen()) || (maDash.GetDashes() && maDash.GetDashLen())) && maDash.GetDistance())
379 : {
380 0 : mpLineAttr->Put(XLineDashItem(OUString(), maDash));
381 : }
382 : else
383 : {
384 0 : mpLineAttr->Put(XLineDashItem(OUString(), XDash(css::drawing::DashStyle_RECT)));
385 : }
386 : }
387 : else
388 : {
389 0 : mbNoLine = true;
390 : }
391 :
392 0 : if(bFill)
393 : {
394 0 : if(mpVD->IsFillColor())
395 : {
396 0 : mpFillAttr->Put(XFillStyleItem(drawing::FillStyle_SOLID));
397 0 : mpFillAttr->Put(XFillColorItem(OUString(), mpVD->GetFillColor()));
398 : }
399 : else
400 : {
401 0 : mpFillAttr->Put(XFillStyleItem(drawing::FillStyle_NONE));
402 : }
403 : }
404 : else
405 : {
406 0 : mbNoFill = true;
407 : }
408 :
409 0 : if(bText && mbFntDirty)
410 : {
411 0 : vcl::Font aFnt(mpVD->GetFont());
412 0 : const sal_uInt32 nHeight(FRound(aFnt.GetSize().Height() * mfScaleY));
413 :
414 0 : mpTextAttr->Put( SvxFontItem( aFnt.GetFamily(), aFnt.GetName(), aFnt.GetStyleName(), aFnt.GetPitch(), aFnt.GetCharSet(), EE_CHAR_FONTINFO ) );
415 0 : mpTextAttr->Put( SvxFontItem( aFnt.GetFamily(), aFnt.GetName(), aFnt.GetStyleName(), aFnt.GetPitch(), aFnt.GetCharSet(), EE_CHAR_FONTINFO_CJK ) );
416 0 : mpTextAttr->Put( SvxFontItem( aFnt.GetFamily(), aFnt.GetName(), aFnt.GetStyleName(), aFnt.GetPitch(), aFnt.GetCharSet(), EE_CHAR_FONTINFO_CTL ) );
417 0 : mpTextAttr->Put(SvxPostureItem(aFnt.GetItalic(), EE_CHAR_ITALIC));
418 0 : mpTextAttr->Put(SvxWeightItem(aFnt.GetWeight(), EE_CHAR_WEIGHT));
419 0 : mpTextAttr->Put( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT ) );
420 0 : mpTextAttr->Put( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT_CJK ) );
421 0 : mpTextAttr->Put( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT_CTL ) );
422 0 : mpTextAttr->Put(SvxCharScaleWidthItem(100, EE_CHAR_FONTWIDTH));
423 0 : mpTextAttr->Put(SvxUnderlineItem(aFnt.GetUnderline(), EE_CHAR_UNDERLINE));
424 0 : mpTextAttr->Put(SvxOverlineItem(aFnt.GetOverline(), EE_CHAR_OVERLINE));
425 0 : mpTextAttr->Put(SvxCrossedOutItem(aFnt.GetStrikeout(), EE_CHAR_STRIKEOUT));
426 0 : mpTextAttr->Put(SvxShadowedItem(aFnt.IsShadow(), EE_CHAR_SHADOW));
427 :
428 : // #i118485# Setting this item leads to problems (written #i118498# for this)
429 : // mpTextAttr->Put(SvxAutoKernItem(aFnt.IsKerning(), EE_CHAR_KERNING));
430 :
431 0 : mpTextAttr->Put(SvxWordLineModeItem(aFnt.IsWordLineMode(), EE_CHAR_WLM));
432 0 : mpTextAttr->Put(SvxContourItem(aFnt.IsOutline(), EE_CHAR_OUTLINE));
433 0 : mpTextAttr->Put(SvxColorItem(mpVD->GetTextColor(), EE_CHAR_COLOR));
434 : //... svxfont textitem svditext
435 0 : mbFntDirty = false;
436 : }
437 :
438 0 : if(pObj)
439 : {
440 0 : pObj->SetLayer(mnLayer);
441 :
442 0 : if(bLine)
443 : {
444 0 : pObj->SetMergedItemSet(*mpLineAttr);
445 : }
446 :
447 0 : if(bFill)
448 : {
449 0 : pObj->SetMergedItemSet(*mpFillAttr);
450 : }
451 :
452 0 : if(bText)
453 : {
454 0 : pObj->SetMergedItemSet(*mpTextAttr);
455 0 : pObj->SetMergedItem(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_LEFT));
456 : }
457 : }
458 0 : }
459 :
460 0 : void ImpSdrGDIMetaFileImport::InsertObj(SdrObject* pObj, bool bScale)
461 : {
462 0 : if(bScale && !maScaleRect.IsEmpty())
463 : {
464 0 : if(mbSize)
465 : {
466 0 : pObj->NbcResize(Point(), maScaleX, maScaleY);
467 : }
468 :
469 0 : if(mbMov)
470 : {
471 0 : pObj->NbcMove(Size(maOfs.X(), maOfs.Y()));
472 : }
473 : }
474 :
475 0 : if(isClip())
476 : {
477 0 : const basegfx::B2DPolyPolygon aPoly(pObj->TakeXorPoly());
478 0 : const basegfx::B2DRange aOldRange(aPoly.getB2DRange());
479 0 : const SdrLayerID aOldLayer(pObj->GetLayer());
480 0 : const SfxItemSet aOldItemSet(pObj->GetMergedItemSet());
481 0 : const SdrGrafObj* pSdrGrafObj = dynamic_cast< SdrGrafObj* >(pObj);
482 0 : const SdrTextObj* pSdrTextObj = dynamic_cast< SdrTextObj* >(pObj);
483 :
484 0 : if(pSdrTextObj && pSdrTextObj->HasText())
485 : {
486 : // all text objects are created from ImportText and have no line or fill attributes, so
487 : // it is okay to concentrate on the text itself
488 : while(true)
489 : {
490 0 : const basegfx::B2DPolyPolygon aTextContour(pSdrTextObj->TakeContour());
491 0 : const basegfx::B2DRange aTextRange(aTextContour.getB2DRange());
492 0 : const basegfx::B2DRange aClipRange(maClip.getB2DRange());
493 :
494 : // no overlap -> completely outside
495 0 : if(!aClipRange.overlaps(aTextRange))
496 : {
497 0 : SdrObject::Free(pObj);
498 0 : break;
499 : }
500 :
501 : // when the clip is a rectangle fast check for inside is possible
502 0 : if(basegfx::tools::isRectangle(maClip) && aClipRange.isInside(aTextRange))
503 : {
504 : // completely inside ClipRect
505 0 : break;
506 : }
507 :
508 : // here text needs to be clipped; to do so, convert to SdrObjects with polygons
509 : // and add these recursively. Delete original object, do not add in this run
510 0 : SdrObject* pConverted = pSdrTextObj->ConvertToPolyObj(true, true);
511 0 : SdrObject::Free(pObj);
512 :
513 0 : if(pConverted)
514 : {
515 : // recursively add created conversion; per definition this shall not
516 : // contain further SdrTextObjs. Visit only non-group objects
517 0 : SdrObjListIter aIter(*pConverted, IM_DEEPNOGROUPS);
518 :
519 : // work with clones; the created conversion may contain group objects
520 : // and when working with the original objects the loop itself could
521 : // break and the cleanup later would be pretty complicated (only delete group
522 : // objects, are these empty, ...?)
523 0 : while(aIter.IsMore())
524 : {
525 0 : SdrObject* pCandidate = aIter.Next();
526 : OSL_ENSURE(pCandidate && 0 == dynamic_cast< SdrObjGroup* >(pCandidate), "SdrObjListIter with IM_DEEPNOGROUPS error (!)");
527 0 : SdrObject* pNewClone = pCandidate->Clone();
528 :
529 0 : if(pNewClone)
530 : {
531 0 : InsertObj(pNewClone, false);
532 : }
533 : else
534 : {
535 : OSL_ENSURE(false, "SdrObject::Clone() failed (!)");
536 : }
537 : }
538 :
539 : // cleanup temporary conversion objects
540 0 : SdrObject::Free(pConverted);
541 : }
542 :
543 0 : break;
544 0 : }
545 : }
546 : else
547 : {
548 0 : BitmapEx aBitmapEx;
549 :
550 0 : if(pSdrGrafObj)
551 : {
552 0 : aBitmapEx = pSdrGrafObj->GetGraphic().GetBitmapEx();
553 : }
554 :
555 0 : SdrObject::Free(pObj);
556 :
557 0 : if(!aOldRange.isEmpty())
558 : {
559 : // clip against ClipRegion
560 : const basegfx::B2DPolyPolygon aNewPoly(
561 : basegfx::tools::clipPolyPolygonOnPolyPolygon(
562 : aPoly,
563 : maClip,
564 : true,
565 0 : !aPoly.isClosed()));
566 0 : const basegfx::B2DRange aNewRange(aNewPoly.getB2DRange());
567 :
568 0 : if(!aNewRange.isEmpty())
569 : {
570 : pObj = new SdrPathObj(
571 0 : aNewPoly.isClosed() ? OBJ_POLY : OBJ_PLIN,
572 0 : aNewPoly);
573 :
574 0 : pObj->SetLayer(aOldLayer);
575 0 : pObj->SetMergedItemSet(aOldItemSet);
576 :
577 0 : if(!!aBitmapEx)
578 : {
579 : // aNewRange is inside of aOldRange and defines which part of aBitmapEx is used
580 0 : const double fScaleX(aBitmapEx.GetSizePixel().Width() / (aOldRange.getWidth() ? aOldRange.getWidth() : 1.0));
581 0 : const double fScaleY(aBitmapEx.GetSizePixel().Height() / (aOldRange.getHeight() ? aOldRange.getHeight() : 1.0));
582 0 : basegfx::B2DRange aPixel(aNewRange);
583 0 : basegfx::B2DHomMatrix aTrans;
584 :
585 0 : aTrans.translate(-aOldRange.getMinX(), -aOldRange.getMinY());
586 0 : aTrans.scale(fScaleX, fScaleY);
587 0 : aPixel.transform(aTrans);
588 :
589 0 : const Size aOrigSizePixel(aBitmapEx.GetSizePixel());
590 : const Point aClipTopLeft(
591 0 : basegfx::fround(floor(std::max(0.0, aPixel.getMinX()))),
592 0 : basegfx::fround(floor(std::max(0.0, aPixel.getMinY()))));
593 : const Size aClipSize(
594 0 : basegfx::fround(ceil(std::min((double)aOrigSizePixel.Width(), aPixel.getWidth()))),
595 0 : basegfx::fround(ceil(std::min((double)aOrigSizePixel.Height(), aPixel.getHeight()))));
596 : const BitmapEx aClippedBitmap(
597 : aBitmapEx,
598 : aClipTopLeft,
599 0 : aClipSize);
600 :
601 0 : pObj->SetMergedItem(XFillStyleItem(drawing::FillStyle_BITMAP));
602 0 : pObj->SetMergedItem(XFillBitmapItem(OUString(), Graphic(aClippedBitmap)));
603 0 : pObj->SetMergedItem(XFillBmpTileItem(false));
604 0 : pObj->SetMergedItem(XFillBmpStretchItem(true));
605 : }
606 0 : }
607 0 : }
608 0 : }
609 : }
610 :
611 0 : if(pObj)
612 : {
613 : // #i111954# check object for visibility
614 : // used are SdrPathObj, SdrRectObj, SdrCircObj, SdrGrafObj
615 0 : bool bVisible(false);
616 :
617 0 : if(pObj->HasLineStyle())
618 : {
619 0 : bVisible = true;
620 : }
621 :
622 0 : if(!bVisible && pObj->HasFillStyle())
623 : {
624 0 : bVisible = true;
625 : }
626 :
627 0 : if(!bVisible)
628 : {
629 0 : SdrTextObj* pTextObj = dynamic_cast< SdrTextObj* >(pObj);
630 :
631 0 : if(pTextObj && pTextObj->HasText())
632 : {
633 0 : bVisible = true;
634 : }
635 : }
636 :
637 0 : if(!bVisible)
638 : {
639 0 : SdrGrafObj* pGrafObj = dynamic_cast< SdrGrafObj* >(pObj);
640 :
641 0 : if(pGrafObj)
642 : {
643 : // this may be refined to check if the graphic really is visible. It
644 : // is here to ensure that graphic objects without fill, line and text
645 : // get created
646 0 : bVisible = true;
647 : }
648 : }
649 :
650 0 : if(!bVisible)
651 : {
652 0 : SdrObject::Free(pObj);
653 : }
654 : else
655 : {
656 0 : maTmpList.push_back(pObj);
657 :
658 0 : if(dynamic_cast< SdrPathObj* >(pObj))
659 : {
660 0 : const bool bClosed(pObj->IsClosedObj());
661 :
662 0 : mbLastObjWasPolyWithoutLine = mbNoLine && bClosed;
663 0 : mbLastObjWasLine = !bClosed;
664 : }
665 : else
666 : {
667 0 : mbLastObjWasPolyWithoutLine = false;
668 0 : mbLastObjWasLine = false;
669 : }
670 : }
671 : }
672 0 : }
673 :
674 0 : void ImpSdrGDIMetaFileImport::DoAction(MetaLineAction& rAct)
675 : {
676 : // #i73407# reformulation to use new B2DPolygon classes
677 0 : const basegfx::B2DPoint aStart(rAct.GetStartPoint().X(), rAct.GetStartPoint().Y());
678 0 : const basegfx::B2DPoint aEnd(rAct.GetEndPoint().X(), rAct.GetEndPoint().Y());
679 :
680 0 : if(!aStart.equal(aEnd))
681 : {
682 0 : basegfx::B2DPolygon aLine;
683 0 : const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(mfScaleX, mfScaleY, maOfs.X(), maOfs.Y()));
684 :
685 0 : aLine.append(aStart);
686 0 : aLine.append(aEnd);
687 0 : aLine.transform(aTransform);
688 :
689 0 : const LineInfo& rLineInfo = rAct.GetLineInfo();
690 0 : const sal_Int32 nNewLineWidth(rLineInfo.GetWidth());
691 0 : bool bCreateLineObject(true);
692 :
693 0 : if(mbLastObjWasLine && (nNewLineWidth == mnLineWidth) && CheckLastLineMerge(aLine))
694 : {
695 0 : bCreateLineObject = false;
696 : }
697 :
698 0 : if(bCreateLineObject)
699 : {
700 0 : SdrPathObj* pPath = new SdrPathObj(OBJ_LINE, basegfx::B2DPolyPolygon(aLine));
701 0 : mnLineWidth = nNewLineWidth;
702 0 : maLineJoin = rLineInfo.GetLineJoin();
703 0 : maLineCap = rLineInfo.GetLineCap();
704 : maDash = XDash(css::drawing::DashStyle_RECT,
705 0 : rLineInfo.GetDotCount(), rLineInfo.GetDotLen(),
706 0 : rLineInfo.GetDashCount(), rLineInfo.GetDashLen(),
707 0 : rLineInfo.GetDistance());
708 0 : SetAttributes(pPath);
709 0 : mnLineWidth = 0;
710 0 : maLineJoin = basegfx::B2DLineJoin::NONE;
711 0 : maDash = XDash();
712 0 : InsertObj(pPath, false);
713 0 : }
714 0 : }
715 0 : }
716 :
717 0 : void ImpSdrGDIMetaFileImport::DoAction(MetaRectAction& rAct)
718 : {
719 0 : SdrRectObj* pRect=new SdrRectObj(rAct.GetRect());
720 0 : SetAttributes(pRect);
721 0 : InsertObj(pRect);
722 0 : }
723 :
724 0 : void ImpSdrGDIMetaFileImport::DoAction(MetaRoundRectAction& rAct)
725 : {
726 0 : SdrRectObj* pRect=new SdrRectObj(rAct.GetRect());
727 0 : SetAttributes(pRect);
728 0 : long nRad=(rAct.GetHorzRound()+rAct.GetVertRound())/2;
729 0 : if (nRad!=0) {
730 0 : SfxItemSet aSet(*mpLineAttr->GetPool(), SDRATTR_ECKENRADIUS, SDRATTR_ECKENRADIUS, 0, 0);
731 0 : aSet.Put(SdrMetricItem(SDRATTR_ECKENRADIUS, nRad));
732 0 : pRect->SetMergedItemSet(aSet);
733 : }
734 0 : InsertObj(pRect);
735 0 : }
736 :
737 0 : void ImpSdrGDIMetaFileImport::DoAction(MetaEllipseAction& rAct)
738 : {
739 0 : SdrCircObj* pCirc=new SdrCircObj(OBJ_CIRC,rAct.GetRect());
740 0 : SetAttributes(pCirc);
741 0 : InsertObj(pCirc);
742 0 : }
743 :
744 0 : void ImpSdrGDIMetaFileImport::DoAction(MetaArcAction& rAct)
745 : {
746 0 : Point aCenter(rAct.GetRect().Center());
747 0 : long nStart=GetAngle(rAct.GetStartPoint()-aCenter);
748 0 : long nEnd=GetAngle(rAct.GetEndPoint()-aCenter);
749 0 : SdrCircObj* pCirc=new SdrCircObj(OBJ_CARC,rAct.GetRect(),nStart,nEnd);
750 0 : SetAttributes(pCirc);
751 0 : InsertObj(pCirc);
752 0 : }
753 :
754 0 : void ImpSdrGDIMetaFileImport::DoAction(MetaPieAction& rAct)
755 : {
756 0 : Point aCenter(rAct.GetRect().Center());
757 0 : long nStart=GetAngle(rAct.GetStartPoint()-aCenter);
758 0 : long nEnd=GetAngle(rAct.GetEndPoint()-aCenter);
759 0 : SdrCircObj* pCirc=new SdrCircObj(OBJ_SECT,rAct.GetRect(),nStart,nEnd);
760 0 : SetAttributes(pCirc);
761 0 : InsertObj(pCirc);
762 0 : }
763 :
764 0 : void ImpSdrGDIMetaFileImport::DoAction(MetaChordAction& rAct)
765 : {
766 0 : Point aCenter(rAct.GetRect().Center());
767 0 : long nStart=GetAngle(rAct.GetStartPoint()-aCenter);
768 0 : long nEnd=GetAngle(rAct.GetEndPoint()-aCenter);
769 0 : SdrCircObj* pCirc=new SdrCircObj(OBJ_CCUT,rAct.GetRect(),nStart,nEnd);
770 0 : SetAttributes(pCirc);
771 0 : InsertObj(pCirc);
772 0 : }
773 :
774 0 : bool ImpSdrGDIMetaFileImport::CheckLastLineMerge(const basegfx::B2DPolygon& rSrcPoly)
775 : {
776 : // #i102706# Do not merge closed polygons
777 0 : if(rSrcPoly.isClosed())
778 : {
779 0 : return false;
780 : }
781 :
782 : // #i73407# reformulation to use new B2DPolygon classes
783 0 : if(mbLastObjWasLine && (maOldLineColor == mpVD->GetLineColor()) && rSrcPoly.count())
784 : {
785 0 : SdrObject* pTmpObj = maTmpList.size() ? maTmpList[maTmpList.size() - 1] : 0;
786 0 : SdrPathObj* pLastPoly = dynamic_cast< SdrPathObj* >(pTmpObj);
787 :
788 0 : if(pLastPoly)
789 : {
790 0 : if(1L == pLastPoly->GetPathPoly().count())
791 : {
792 0 : bool bOk(false);
793 0 : basegfx::B2DPolygon aDstPoly(pLastPoly->GetPathPoly().getB2DPolygon(0L));
794 :
795 : // #i102706# Do not merge closed polygons
796 0 : if(aDstPoly.isClosed())
797 : {
798 0 : return false;
799 : }
800 :
801 0 : if(aDstPoly.count())
802 : {
803 0 : const sal_uInt32 nMaxDstPnt(aDstPoly.count() - 1L);
804 0 : const sal_uInt32 nMaxSrcPnt(rSrcPoly.count() - 1L);
805 :
806 0 : if(aDstPoly.getB2DPoint(nMaxDstPnt) == rSrcPoly.getB2DPoint(0L))
807 : {
808 0 : aDstPoly.append(rSrcPoly, 1L, rSrcPoly.count() - 1L);
809 0 : bOk = true;
810 : }
811 0 : else if(aDstPoly.getB2DPoint(0L) == rSrcPoly.getB2DPoint(nMaxSrcPnt))
812 : {
813 0 : basegfx::B2DPolygon aNew(rSrcPoly);
814 0 : aNew.append(aDstPoly, 1L, aDstPoly.count() - 1L);
815 0 : aDstPoly = aNew;
816 0 : bOk = true;
817 : }
818 0 : else if(aDstPoly.getB2DPoint(0L) == rSrcPoly.getB2DPoint(0L))
819 : {
820 0 : aDstPoly.flip();
821 0 : aDstPoly.append(rSrcPoly, 1L, rSrcPoly.count() - 1L);
822 0 : bOk = true;
823 : }
824 0 : else if(aDstPoly.getB2DPoint(nMaxDstPnt) == rSrcPoly.getB2DPoint(nMaxSrcPnt))
825 : {
826 0 : basegfx::B2DPolygon aNew(rSrcPoly);
827 0 : aNew.flip();
828 0 : aDstPoly.append(aNew, 1L, aNew.count() - 1L);
829 0 : bOk = true;
830 : }
831 : }
832 :
833 0 : if(bOk)
834 : {
835 0 : pLastPoly->NbcSetPathPoly(basegfx::B2DPolyPolygon(aDstPoly));
836 : }
837 :
838 0 : return bOk;
839 : }
840 : }
841 : }
842 :
843 0 : return false;
844 : }
845 :
846 0 : bool ImpSdrGDIMetaFileImport::CheckLastPolyLineAndFillMerge(const basegfx::B2DPolyPolygon & rPolyPolygon)
847 : {
848 : // #i73407# reformulation to use new B2DPolygon classes
849 0 : if(mbLastObjWasPolyWithoutLine)
850 : {
851 0 : SdrObject* pTmpObj = maTmpList.size() ? maTmpList[maTmpList.size() - 1] : 0;
852 0 : SdrPathObj* pLastPoly = dynamic_cast< SdrPathObj* >(pTmpObj);
853 :
854 0 : if(pLastPoly)
855 : {
856 0 : if(pLastPoly->GetPathPoly() == rPolyPolygon)
857 : {
858 0 : SetAttributes(NULL);
859 :
860 0 : if(!mbNoLine && mbNoFill)
861 : {
862 0 : pLastPoly->SetMergedItemSet(*mpLineAttr);
863 :
864 0 : return true;
865 : }
866 : }
867 : }
868 : }
869 :
870 0 : return false;
871 : }
872 :
873 0 : void ImpSdrGDIMetaFileImport::checkClip()
874 : {
875 0 : if(mpVD->IsClipRegion())
876 : {
877 0 : maClip = mpVD->GetClipRegion().GetAsB2DPolyPolygon();
878 :
879 0 : if(isClip())
880 : {
881 : const basegfx::B2DHomMatrix aTransform(
882 : basegfx::tools::createScaleTranslateB2DHomMatrix(
883 : mfScaleX,
884 : mfScaleY,
885 0 : maOfs.X(),
886 0 : maOfs.Y()));
887 :
888 0 : maClip.transform(aTransform);
889 : }
890 : }
891 0 : }
892 :
893 0 : bool ImpSdrGDIMetaFileImport::isClip() const
894 : {
895 0 : return !maClip.getB2DRange().isEmpty();
896 : }
897 :
898 0 : void ImpSdrGDIMetaFileImport::DoAction( MetaPolyLineAction& rAct )
899 : {
900 : // #i73407# reformulation to use new B2DPolygon classes
901 0 : basegfx::B2DPolygon aSource(rAct.GetPolygon().getB2DPolygon());
902 :
903 0 : if(aSource.count())
904 : {
905 0 : const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(mfScaleX, mfScaleY, maOfs.X(), maOfs.Y()));
906 0 : aSource.transform(aTransform);
907 : }
908 :
909 0 : const LineInfo& rLineInfo = rAct.GetLineInfo();
910 0 : const sal_Int32 nNewLineWidth(rLineInfo.GetWidth());
911 0 : bool bCreateLineObject(true);
912 :
913 0 : if(mbLastObjWasLine && (nNewLineWidth == mnLineWidth) && CheckLastLineMerge(aSource))
914 : {
915 0 : bCreateLineObject = false;
916 : }
917 0 : else if(mbLastObjWasPolyWithoutLine && CheckLastPolyLineAndFillMerge(basegfx::B2DPolyPolygon(aSource)))
918 : {
919 0 : bCreateLineObject = false;
920 : }
921 :
922 0 : if(bCreateLineObject)
923 : {
924 : SdrPathObj* pPath = new SdrPathObj(
925 0 : aSource.isClosed() ? OBJ_POLY : OBJ_PLIN,
926 0 : basegfx::B2DPolyPolygon(aSource));
927 0 : mnLineWidth = nNewLineWidth;
928 0 : maLineJoin = rLineInfo.GetLineJoin();
929 0 : maLineCap = rLineInfo.GetLineCap();
930 : maDash = XDash(css::drawing::DashStyle_RECT,
931 0 : rLineInfo.GetDotCount(), rLineInfo.GetDotLen(),
932 0 : rLineInfo.GetDashCount(), rLineInfo.GetDashLen(),
933 0 : rLineInfo.GetDistance());
934 0 : SetAttributes(pPath);
935 0 : mnLineWidth = 0;
936 0 : maLineJoin = basegfx::B2DLineJoin::NONE;
937 0 : maDash = XDash();
938 0 : InsertObj(pPath, false);
939 0 : }
940 0 : }
941 :
942 0 : void ImpSdrGDIMetaFileImport::DoAction( MetaPolygonAction& rAct )
943 : {
944 : // #i73407# reformulation to use new B2DPolygon classes
945 0 : basegfx::B2DPolygon aSource(rAct.GetPolygon().getB2DPolygon());
946 :
947 0 : if(aSource.count())
948 : {
949 0 : const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(mfScaleX, mfScaleY, maOfs.X(), maOfs.Y()));
950 0 : aSource.transform(aTransform);
951 :
952 0 : if(!mbLastObjWasPolyWithoutLine || !CheckLastPolyLineAndFillMerge(basegfx::B2DPolyPolygon(aSource)))
953 : {
954 : // #i73407# make sure polygon is closed, it's a filled primitive
955 0 : aSource.setClosed(true);
956 0 : SdrPathObj* pPath = new SdrPathObj(OBJ_POLY, basegfx::B2DPolyPolygon(aSource));
957 0 : SetAttributes(pPath);
958 0 : InsertObj(pPath, false);
959 0 : }
960 0 : }
961 0 : }
962 :
963 0 : void ImpSdrGDIMetaFileImport::DoAction(MetaPolyPolygonAction& rAct)
964 : {
965 : // #i73407# reformulation to use new B2DPolygon classes
966 0 : basegfx::B2DPolyPolygon aSource(rAct.GetPolyPolygon().getB2DPolyPolygon());
967 :
968 0 : if(aSource.count())
969 : {
970 0 : const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(mfScaleX, mfScaleY, maOfs.X(), maOfs.Y()));
971 0 : aSource.transform(aTransform);
972 :
973 0 : if(!mbLastObjWasPolyWithoutLine || !CheckLastPolyLineAndFillMerge(aSource))
974 : {
975 : // #i73407# make sure polygon is closed, it's a filled primitive
976 0 : aSource.setClosed(true);
977 0 : SdrPathObj* pPath = new SdrPathObj(OBJ_POLY, aSource);
978 0 : SetAttributes(pPath);
979 0 : InsertObj(pPath, false);
980 0 : }
981 0 : }
982 0 : }
983 :
984 0 : void ImpSdrGDIMetaFileImport::ImportText( const Point& rPos, const OUString& rStr, const MetaAction& rAct )
985 : {
986 : // calc text box size, add 5% to make it fit safely
987 :
988 0 : FontMetric aFontMetric( mpVD->GetFontMetric() );
989 0 : vcl::Font aFnt( mpVD->GetFont() );
990 0 : FontAlign eAlg( aFnt.GetAlign() );
991 :
992 0 : sal_Int32 nTextWidth = (sal_Int32)( mpVD->GetTextWidth( rStr ) * mfScaleX );
993 0 : sal_Int32 nTextHeight = (sal_Int32)( mpVD->GetTextHeight() * mfScaleY );
994 :
995 0 : Point aPos( FRound(rPos.X() * mfScaleX + maOfs.X()), FRound(rPos.Y() * mfScaleY + maOfs.Y()) );
996 0 : Size aSize( nTextWidth, nTextHeight );
997 :
998 0 : if ( eAlg == ALIGN_BASELINE )
999 0 : aPos.Y() -= FRound(aFontMetric.GetAscent() * mfScaleY);
1000 0 : else if ( eAlg == ALIGN_BOTTOM )
1001 0 : aPos.Y() -= nTextHeight;
1002 :
1003 0 : Rectangle aTextRect( aPos, aSize );
1004 0 : SdrRectObj* pText =new SdrRectObj( OBJ_TEXT, aTextRect );
1005 :
1006 0 : pText->SetMergedItem ( makeSdrTextUpperDistItem (0));
1007 0 : pText->SetMergedItem ( makeSdrTextLowerDistItem (0));
1008 0 : pText->SetMergedItem ( makeSdrTextRightDistItem (0));
1009 0 : pText->SetMergedItem ( makeSdrTextLeftDistItem (0));
1010 :
1011 0 : if ( aFnt.GetWidth() || ( rAct.GetType() == MetaActionType::STRETCHTEXT ) )
1012 : {
1013 0 : pText->ClearMergedItem( SDRATTR_TEXT_AUTOGROWWIDTH );
1014 0 : pText->SetMergedItem( makeSdrTextAutoGrowHeightItem( false ) );
1015 : // don't let the margins eat the space needed for the text
1016 0 : pText->SetMergedItem( SdrTextFitToSizeTypeItem( SDRTEXTFIT_ALLLINES ) );
1017 : }
1018 : else
1019 : {
1020 0 : pText->SetMergedItem( makeSdrTextAutoGrowWidthItem( true ) );
1021 : }
1022 :
1023 0 : pText->SetModel(mpModel);
1024 0 : pText->SetLayer(mnLayer);
1025 0 : pText->NbcSetText( rStr );
1026 0 : SetAttributes( pText, true );
1027 0 : pText->SetSnapRect( aTextRect );
1028 :
1029 0 : if (!aFnt.IsTransparent())
1030 : {
1031 0 : SfxItemSet aAttr(*mpFillAttr->GetPool(), XATTR_FILL_FIRST, XATTR_FILL_LAST, 0, 0);
1032 0 : aAttr.Put(XFillStyleItem(drawing::FillStyle_SOLID));
1033 0 : aAttr.Put(XFillColorItem(OUString(), aFnt.GetFillColor()));
1034 0 : pText->SetMergedItemSet(aAttr);
1035 : }
1036 0 : sal_uInt32 nAngle = aFnt.GetOrientation();
1037 0 : if ( nAngle )
1038 : {
1039 0 : nAngle*=10;
1040 0 : double a=nAngle*nPi180;
1041 0 : double nSin=sin(a);
1042 0 : double nCos=cos(a);
1043 0 : pText->NbcRotate(aPos,nAngle,nSin,nCos);
1044 : }
1045 0 : InsertObj( pText, false );
1046 0 : }
1047 :
1048 0 : void ImpSdrGDIMetaFileImport::DoAction(MetaTextAction& rAct)
1049 : {
1050 0 : OUString aStr(rAct.GetText());
1051 0 : aStr = aStr.copy(rAct.GetIndex(), rAct.GetLen());
1052 0 : ImportText( rAct.GetPoint(), aStr, rAct );
1053 0 : }
1054 :
1055 0 : void ImpSdrGDIMetaFileImport::DoAction(MetaTextArrayAction& rAct)
1056 : {
1057 0 : OUString aStr(rAct.GetText());
1058 0 : aStr = aStr.copy(rAct.GetIndex(), rAct.GetLen());
1059 0 : ImportText( rAct.GetPoint(), aStr, rAct );
1060 0 : }
1061 :
1062 0 : void ImpSdrGDIMetaFileImport::DoAction(MetaStretchTextAction& rAct)
1063 : {
1064 0 : OUString aStr(rAct.GetText());
1065 0 : aStr = aStr.copy(rAct.GetIndex(), rAct.GetLen());
1066 0 : ImportText( rAct.GetPoint(), aStr, rAct );
1067 0 : }
1068 :
1069 0 : void ImpSdrGDIMetaFileImport::DoAction(MetaBmpAction& rAct)
1070 : {
1071 0 : Rectangle aRect(rAct.GetPoint(),rAct.GetBitmap().GetSizePixel());
1072 0 : aRect.Right()++; aRect.Bottom()++;
1073 0 : SdrGrafObj* pGraf=new SdrGrafObj(Graphic(rAct.GetBitmap()),aRect);
1074 :
1075 : // This action is not creating line and fill, set directly, do not use SetAttributes(..)
1076 0 : pGraf->SetMergedItem(XLineStyleItem(drawing::LineStyle_NONE));
1077 0 : pGraf->SetMergedItem(XFillStyleItem(drawing::FillStyle_NONE));
1078 0 : InsertObj(pGraf);
1079 0 : }
1080 :
1081 0 : void ImpSdrGDIMetaFileImport::DoAction(MetaBmpScaleAction& rAct)
1082 : {
1083 0 : Rectangle aRect(rAct.GetPoint(),rAct.GetSize());
1084 0 : aRect.Right()++; aRect.Bottom()++;
1085 0 : SdrGrafObj* pGraf=new SdrGrafObj(Graphic(rAct.GetBitmap()),aRect);
1086 :
1087 : // This action is not creating line and fill, set directly, do not use SetAttributes(..)
1088 0 : pGraf->SetMergedItem(XLineStyleItem(drawing::LineStyle_NONE));
1089 0 : pGraf->SetMergedItem(XFillStyleItem(drawing::FillStyle_NONE));
1090 0 : InsertObj(pGraf);
1091 0 : }
1092 :
1093 0 : void ImpSdrGDIMetaFileImport::DoAction(MetaBmpExAction& rAct)
1094 : {
1095 0 : Rectangle aRect(rAct.GetPoint(),rAct.GetBitmapEx().GetSizePixel());
1096 0 : aRect.Right()++; aRect.Bottom()++;
1097 0 : SdrGrafObj* pGraf=new SdrGrafObj( rAct.GetBitmapEx(), aRect );
1098 :
1099 : // This action is not creating line and fill, set directly, do not use SetAttributes(..)
1100 0 : pGraf->SetMergedItem(XLineStyleItem(drawing::LineStyle_NONE));
1101 0 : pGraf->SetMergedItem(XFillStyleItem(drawing::FillStyle_NONE));
1102 0 : InsertObj(pGraf);
1103 0 : }
1104 :
1105 0 : void ImpSdrGDIMetaFileImport::DoAction(MetaBmpExScaleAction& rAct)
1106 : {
1107 0 : Rectangle aRect(rAct.GetPoint(),rAct.GetSize());
1108 0 : aRect.Right()++; aRect.Bottom()++;
1109 0 : SdrGrafObj* pGraf=new SdrGrafObj( rAct.GetBitmapEx(), aRect );
1110 :
1111 : // This action is not creating line and fill, set directly, do not use SetAttributes(..)
1112 0 : pGraf->SetMergedItem(XLineStyleItem(drawing::LineStyle_NONE));
1113 0 : pGraf->SetMergedItem(XFillStyleItem(drawing::FillStyle_NONE));
1114 0 : InsertObj(pGraf);
1115 0 : }
1116 :
1117 :
1118 :
1119 0 : void ImpSdrGDIMetaFileImport::DoAction( MetaHatchAction& rAct )
1120 : {
1121 : // #i73407# reformulation to use new B2DPolygon classes
1122 0 : basegfx::B2DPolyPolygon aSource(rAct.GetPolyPolygon().getB2DPolyPolygon());
1123 :
1124 0 : if(aSource.count())
1125 : {
1126 0 : const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(mfScaleX, mfScaleY, maOfs.X(), maOfs.Y()));
1127 0 : aSource.transform(aTransform);
1128 :
1129 0 : if(!mbLastObjWasPolyWithoutLine || !CheckLastPolyLineAndFillMerge(aSource))
1130 : {
1131 0 : const Hatch& rHatch = rAct.GetHatch();
1132 0 : SdrPathObj* pPath = new SdrPathObj(OBJ_POLY, aSource);
1133 : // #i125211# Use the ranges from the SdrObject to create a new empty SfxItemSet
1134 0 : SfxItemSet aHatchAttr(mpModel->GetItemPool(), pPath->GetMergedItemSet().GetRanges());
1135 : css::drawing::HatchStyle eStyle;
1136 :
1137 0 : switch(rHatch.GetStyle())
1138 : {
1139 : case(HATCH_TRIPLE) :
1140 : {
1141 0 : eStyle = css::drawing::HatchStyle_TRIPLE;
1142 0 : break;
1143 : }
1144 :
1145 : case(HATCH_DOUBLE) :
1146 : {
1147 0 : eStyle = css::drawing::HatchStyle_DOUBLE;
1148 0 : break;
1149 : }
1150 :
1151 : default:
1152 : {
1153 0 : eStyle = css::drawing::HatchStyle_SINGLE;
1154 0 : break;
1155 : }
1156 : }
1157 :
1158 0 : SetAttributes(pPath);
1159 0 : aHatchAttr.Put(XFillStyleItem(drawing::FillStyle_HATCH));
1160 0 : aHatchAttr.Put(XFillHatchItem(&mpModel->GetItemPool(), XHatch(rHatch.GetColor(), eStyle, rHatch.GetDistance(), rHatch.GetAngle())));
1161 0 : pPath->SetMergedItemSet(aHatchAttr);
1162 :
1163 0 : InsertObj(pPath, false);
1164 0 : }
1165 0 : }
1166 0 : }
1167 :
1168 :
1169 :
1170 0 : void ImpSdrGDIMetaFileImport::DoAction(MetaLineColorAction& rAct)
1171 : {
1172 0 : rAct.Execute(mpVD);
1173 0 : }
1174 :
1175 0 : void ImpSdrGDIMetaFileImport::DoAction(MetaMapModeAction& rAct)
1176 : {
1177 0 : MapScaling();
1178 0 : rAct.Execute(mpVD);
1179 0 : mbLastObjWasPolyWithoutLine = false;
1180 0 : mbLastObjWasLine = false;
1181 0 : }
1182 :
1183 0 : void ImpSdrGDIMetaFileImport::MapScaling()
1184 : {
1185 0 : const size_t nCount(maTmpList.size());
1186 0 : const MapMode& rMap = mpVD->GetMapMode();
1187 0 : Point aMapOrg( rMap.GetOrigin() );
1188 0 : bool bMov2(aMapOrg.X() != 0 || aMapOrg.Y() != 0);
1189 :
1190 0 : if(bMov2)
1191 : {
1192 0 : for(size_t i = mnMapScalingOfs; i < nCount; i++)
1193 : {
1194 0 : SdrObject* pObj = maTmpList[i];
1195 :
1196 0 : pObj->NbcMove(Size(aMapOrg.X(), aMapOrg.Y()));
1197 : }
1198 : }
1199 :
1200 0 : mnMapScalingOfs = nCount;
1201 0 : }
1202 :
1203 :
1204 :
1205 0 : void ImpSdrGDIMetaFileImport::DoAction( MetaCommentAction& rAct, GDIMetaFile& rMtf, sal_uLong& a) // GDIMetaFile* pMtf )
1206 : {
1207 0 : bool aSkipComment = false;
1208 :
1209 0 : if (a < rMtf.GetActionSize() && rAct.GetComment().equalsIgnoreAsciiCase("XGRAD_SEQ_BEGIN"))
1210 : {
1211 : // #i125211# Check if next action is a MetaGradientExAction
1212 0 : MetaGradientExAction* pAct = dynamic_cast< MetaGradientExAction* >(rMtf.GetAction(a + 1));
1213 :
1214 0 : if( pAct && pAct->GetType() == MetaActionType::GRADIENTEX )
1215 : {
1216 : // #i73407# reformulation to use new B2DPolygon classes
1217 0 : basegfx::B2DPolyPolygon aSource(pAct->GetPolyPolygon().getB2DPolyPolygon());
1218 :
1219 0 : if(aSource.count())
1220 : {
1221 0 : if(!mbLastObjWasPolyWithoutLine || !CheckLastPolyLineAndFillMerge(aSource))
1222 : {
1223 0 : const Gradient& rGrad = pAct->GetGradient();
1224 0 : SdrPathObj* pPath = new SdrPathObj(OBJ_POLY, aSource);
1225 : // #i125211# Use the ranges from the SdrObject to create a new empty SfxItemSet
1226 0 : SfxItemSet aGradAttr(mpModel->GetItemPool(), pPath->GetMergedItemSet().GetRanges());
1227 0 : XGradient aXGradient;
1228 :
1229 0 : aXGradient.SetGradientStyle((css::awt::GradientStyle)rGrad.GetStyle());
1230 0 : aXGradient.SetStartColor(rGrad.GetStartColor());
1231 0 : aXGradient.SetEndColor(rGrad.GetEndColor());
1232 0 : aXGradient.SetAngle((sal_uInt16)rGrad.GetAngle());
1233 0 : aXGradient.SetBorder(rGrad.GetBorder());
1234 0 : aXGradient.SetXOffset(rGrad.GetOfsX());
1235 0 : aXGradient.SetYOffset(rGrad.GetOfsY());
1236 0 : aXGradient.SetStartIntens(rGrad.GetStartIntensity());
1237 0 : aXGradient.SetEndIntens(rGrad.GetEndIntensity());
1238 0 : aXGradient.SetSteps(rGrad.GetSteps());
1239 :
1240 : // no need to use SetAttributes(..) here since line and fill style
1241 : // need to be set individually
1242 : // SetAttributes(pPath);
1243 :
1244 : // switch line off; if there was one there will be a
1245 : // MetaActionType::POLYLINE following creating another object
1246 0 : aGradAttr.Put(XLineStyleItem(drawing::LineStyle_NONE));
1247 :
1248 : // add detected gradient fillstyle
1249 0 : aGradAttr.Put(XFillStyleItem(drawing::FillStyle_GRADIENT));
1250 0 : aGradAttr.Put(XFillGradientItem(aXGradient));
1251 :
1252 0 : pPath->SetMergedItemSet(aGradAttr);
1253 :
1254 0 : InsertObj(pPath);
1255 : }
1256 : }
1257 :
1258 0 : aSkipComment = true;
1259 : }
1260 : }
1261 :
1262 0 : if(aSkipComment)
1263 : {
1264 : // #i125211# forward until closing MetaCommentAction
1265 0 : MetaAction* pSkipAct = rMtf.GetAction(++a);
1266 :
1267 0 : while( pSkipAct
1268 0 : && ((pSkipAct->GetType() != MetaActionType::COMMENT )
1269 0 : || !(static_cast<MetaCommentAction*>(pSkipAct)->GetComment().equalsIgnoreAsciiCase("XGRAD_SEQ_END"))))
1270 : {
1271 0 : pSkipAct = rMtf.GetAction(++a);
1272 : }
1273 : }
1274 0 : }
1275 :
1276 0 : void ImpSdrGDIMetaFileImport::DoAction(MetaTextRectAction& rAct)
1277 : {
1278 0 : GDIMetaFile aTemp;
1279 :
1280 0 : mpVD->AddTextRectActions(rAct.GetRect(), rAct.GetText(), rAct.GetStyle(), aTemp);
1281 0 : DoLoopActions(aTemp, 0, 0);
1282 0 : }
1283 :
1284 0 : void ImpSdrGDIMetaFileImport::DoAction(MetaBmpScalePartAction& rAct)
1285 : {
1286 0 : Rectangle aRect(rAct.GetDestPoint(), rAct.GetDestSize());
1287 0 : Bitmap aBitmap(rAct.GetBitmap());
1288 :
1289 0 : aRect.Right()++;
1290 0 : aRect.Bottom()++;
1291 0 : aBitmap.Crop(Rectangle(rAct.GetSrcPoint(), rAct.GetSrcSize()));
1292 0 : SdrGrafObj* pGraf = new SdrGrafObj(aBitmap, aRect);
1293 :
1294 : // This action is not creating line and fill, set directly, do not use SetAttributes(..)
1295 0 : pGraf->SetMergedItem(XLineStyleItem(drawing::LineStyle_NONE));
1296 0 : pGraf->SetMergedItem(XFillStyleItem(drawing::FillStyle_NONE));
1297 0 : InsertObj(pGraf);
1298 0 : }
1299 :
1300 0 : void ImpSdrGDIMetaFileImport::DoAction(MetaBmpExScalePartAction& rAct)
1301 : {
1302 0 : Rectangle aRect(rAct.GetDestPoint(),rAct.GetDestSize());
1303 0 : BitmapEx aBitmapEx(rAct.GetBitmapEx());
1304 :
1305 0 : aRect.Right()++;
1306 0 : aRect.Bottom()++;
1307 0 : aBitmapEx.Crop(Rectangle(rAct.GetSrcPoint(), rAct.GetSrcSize()));
1308 0 : SdrGrafObj* pGraf = new SdrGrafObj(aBitmapEx, aRect);
1309 :
1310 : // This action is not creating line and fill, set directly, do not use SetAttributes(..)
1311 0 : pGraf->SetMergedItem(XLineStyleItem(drawing::LineStyle_NONE));
1312 0 : pGraf->SetMergedItem(XFillStyleItem(drawing::FillStyle_NONE));
1313 0 : InsertObj(pGraf);
1314 0 : }
1315 :
1316 0 : void ImpSdrGDIMetaFileImport::DoAction(MetaMaskAction& rAct)
1317 : {
1318 0 : Rectangle aRect(rAct.GetPoint(), rAct.GetBitmap().GetSizePixel());
1319 0 : BitmapEx aBitmapEx(rAct.GetBitmap(), rAct.GetColor());
1320 :
1321 0 : aRect.Right()++; aRect.Bottom()++;
1322 0 : SdrGrafObj* pGraf = new SdrGrafObj(aBitmapEx, aRect);
1323 :
1324 : // This action is not creating line and fill, set directly, do not use SetAttributes(..)
1325 0 : pGraf->SetMergedItem(XLineStyleItem(drawing::LineStyle_NONE));
1326 0 : pGraf->SetMergedItem(XFillStyleItem(drawing::FillStyle_NONE));
1327 0 : InsertObj(pGraf);
1328 0 : }
1329 :
1330 0 : void ImpSdrGDIMetaFileImport::DoAction(MetaMaskScaleAction& rAct)
1331 : {
1332 0 : Rectangle aRect(rAct.GetPoint(), rAct.GetSize());
1333 0 : BitmapEx aBitmapEx(rAct.GetBitmap(), rAct.GetColor());
1334 :
1335 0 : aRect.Right()++; aRect.Bottom()++;
1336 0 : SdrGrafObj* pGraf = new SdrGrafObj(aBitmapEx, aRect);
1337 :
1338 : // This action is not creating line and fill, set directly, do not use SetAttributes(..)
1339 0 : pGraf->SetMergedItem(XLineStyleItem(drawing::LineStyle_NONE));
1340 0 : pGraf->SetMergedItem(XFillStyleItem(drawing::FillStyle_NONE));
1341 0 : InsertObj(pGraf);
1342 0 : }
1343 :
1344 0 : void ImpSdrGDIMetaFileImport::DoAction(MetaMaskScalePartAction& rAct)
1345 : {
1346 0 : Rectangle aRect(rAct.GetDestPoint(), rAct.GetDestSize());
1347 0 : BitmapEx aBitmapEx(rAct.GetBitmap(), rAct.GetColor());
1348 :
1349 0 : aRect.Right()++; aRect.Bottom()++;
1350 0 : aBitmapEx.Crop(Rectangle(rAct.GetSrcPoint(), rAct.GetSrcSize()));
1351 0 : SdrGrafObj* pGraf = new SdrGrafObj(aBitmapEx, aRect);
1352 :
1353 : // This action is not creating line and fill, set directly, do not use SetAttributes(..)
1354 0 : pGraf->SetMergedItem(XLineStyleItem(drawing::LineStyle_NONE));
1355 0 : pGraf->SetMergedItem(XFillStyleItem(drawing::FillStyle_NONE));
1356 0 : InsertObj(pGraf);
1357 0 : }
1358 :
1359 : namespace
1360 : {
1361 0 : css::awt::GradientStyle getXGradientStyleFromGradientStyle(const GradientStyle& rGradientStyle)
1362 : {
1363 0 : css::awt::GradientStyle aXGradientStyle(css::awt::GradientStyle_LINEAR);
1364 :
1365 0 : switch(rGradientStyle)
1366 : {
1367 0 : case GradientStyle_LINEAR: aXGradientStyle = css::awt::GradientStyle_LINEAR; break;
1368 0 : case GradientStyle_AXIAL: aXGradientStyle = css::awt::GradientStyle_AXIAL; break;
1369 0 : case GradientStyle_RADIAL: aXGradientStyle = css::awt::GradientStyle_RADIAL; break;
1370 0 : case GradientStyle_ELLIPTICAL: aXGradientStyle = css::awt::GradientStyle_ELLIPTICAL; break;
1371 0 : case GradientStyle_SQUARE: aXGradientStyle = css::awt::GradientStyle_SQUARE; break;
1372 0 : case GradientStyle_RECT: aXGradientStyle = css::awt::GradientStyle_RECT; break;
1373 :
1374 : // Needed due to GradientStyle_FORCE_EQUAL_SIZE; this again is needed
1375 : // to force the enum defines in VCL to a defined size for the compilers,
1376 : // so despite it is never used it cannot be removed (would break the
1377 : // API implementation probably).
1378 0 : case GradientStyle_FORCE_EQUAL_SIZE: break;
1379 : default:
1380 0 : break;
1381 : }
1382 :
1383 0 : return aXGradientStyle;
1384 : }
1385 : }
1386 :
1387 0 : void ImpSdrGDIMetaFileImport::DoAction(MetaGradientAction& rAct)
1388 : {
1389 0 : basegfx::B2DRange aRange(rAct.GetRect().Left(), rAct.GetRect().Top(), rAct.GetRect().Right(), rAct.GetRect().Bottom());
1390 :
1391 0 : if(!aRange.isEmpty())
1392 : {
1393 0 : const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(mfScaleX, mfScaleY, maOfs.X(), maOfs.Y()));
1394 0 : aRange.transform(aTransform);
1395 0 : const Gradient& rGradient = rAct.GetGradient();
1396 : SdrRectObj* pRect = new SdrRectObj(
1397 : Rectangle(
1398 0 : floor(aRange.getMinX()),
1399 0 : floor(aRange.getMinY()),
1400 0 : ceil(aRange.getMaxX()),
1401 0 : ceil(aRange.getMaxY())));
1402 : // #i125211# Use the ranges from the SdrObject to create a new empty SfxItemSet
1403 0 : SfxItemSet aGradientAttr(mpModel->GetItemPool(), pRect->GetMergedItemSet().GetRanges());
1404 0 : const css::awt::GradientStyle aXGradientStyle(getXGradientStyleFromGradientStyle(rGradient.GetStyle()));
1405 : const XFillGradientItem aXFillGradientItem(
1406 : XGradient(
1407 0 : rGradient.GetStartColor(),
1408 0 : rGradient.GetEndColor(),
1409 : aXGradientStyle,
1410 0 : rGradient.GetAngle(),
1411 0 : rGradient.GetOfsX(),
1412 0 : rGradient.GetOfsY(),
1413 0 : rGradient.GetBorder(),
1414 0 : rGradient.GetStartIntensity(),
1415 0 : rGradient.GetEndIntensity(),
1416 0 : rGradient.GetSteps()));
1417 :
1418 0 : SetAttributes(pRect);
1419 0 : aGradientAttr.Put(XFillStyleItem(drawing::FillStyle_GRADIENT)); // #i125211#
1420 0 : aGradientAttr.Put(aXFillGradientItem);
1421 0 : pRect->SetMergedItemSet(aGradientAttr);
1422 :
1423 0 : InsertObj(pRect, false);
1424 : }
1425 0 : }
1426 :
1427 0 : void ImpSdrGDIMetaFileImport::DoAction(MetaWallpaperAction&)
1428 : {
1429 : OSL_ENSURE(false, "Tried to construct SdrObject from MetaWallpaperAction: not supported (!)");
1430 0 : }
1431 :
1432 0 : void ImpSdrGDIMetaFileImport::DoAction(MetaTransparentAction& rAct)
1433 : {
1434 0 : basegfx::B2DPolyPolygon aSource(rAct.GetPolyPolygon().getB2DPolyPolygon());
1435 :
1436 0 : if(aSource.count())
1437 : {
1438 0 : const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(mfScaleX, mfScaleY, maOfs.X(), maOfs.Y()));
1439 0 : aSource.transform(aTransform);
1440 0 : aSource.setClosed(true);
1441 :
1442 0 : SdrPathObj* pPath = new SdrPathObj(OBJ_POLY, aSource);
1443 0 : SetAttributes(pPath);
1444 0 : pPath->SetMergedItem(XFillTransparenceItem(rAct.GetTransparence()));
1445 0 : InsertObj(pPath, false);
1446 0 : }
1447 0 : }
1448 :
1449 0 : void ImpSdrGDIMetaFileImport::DoAction(MetaEPSAction&)
1450 : {
1451 : OSL_ENSURE(false, "Tried to construct SdrObject from MetaEPSAction: not supported (!)");
1452 0 : }
1453 :
1454 0 : void ImpSdrGDIMetaFileImport::DoAction(MetaTextLineAction&)
1455 : {
1456 : OSL_ENSURE(false, "Tried to construct SdrObject from MetaTextLineAction: not supported (!)");
1457 0 : }
1458 :
1459 0 : void ImpSdrGDIMetaFileImport::DoAction(MetaGradientExAction& rAct)
1460 : {
1461 0 : basegfx::B2DPolyPolygon aSource(rAct.GetPolyPolygon().getB2DPolyPolygon());
1462 :
1463 0 : if(aSource.count())
1464 : {
1465 0 : const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(mfScaleX, mfScaleY, maOfs.X(), maOfs.Y()));
1466 0 : aSource.transform(aTransform);
1467 :
1468 0 : if(!mbLastObjWasPolyWithoutLine || !CheckLastPolyLineAndFillMerge(aSource))
1469 : {
1470 0 : const Gradient& rGradient = rAct.GetGradient();
1471 0 : SdrPathObj* pPath = new SdrPathObj(OBJ_POLY, aSource);
1472 : // #i125211# Use the ranges from the SdrObject to create a new empty SfxItemSet
1473 0 : SfxItemSet aGradientAttr(mpModel->GetItemPool(), pPath->GetMergedItemSet().GetRanges());
1474 0 : const css::awt::GradientStyle aXGradientStyle(getXGradientStyleFromGradientStyle(rGradient.GetStyle()));
1475 : const XFillGradientItem aXFillGradientItem(
1476 : XGradient(
1477 0 : rGradient.GetStartColor(),
1478 0 : rGradient.GetEndColor(),
1479 : aXGradientStyle,
1480 0 : rGradient.GetAngle(),
1481 0 : rGradient.GetOfsX(),
1482 0 : rGradient.GetOfsY(),
1483 0 : rGradient.GetBorder(),
1484 0 : rGradient.GetStartIntensity(),
1485 0 : rGradient.GetEndIntensity(),
1486 0 : rGradient.GetSteps()));
1487 :
1488 0 : SetAttributes(pPath);
1489 0 : aGradientAttr.Put(XFillStyleItem(drawing::FillStyle_GRADIENT)); // #i125211#
1490 0 : aGradientAttr.Put(aXFillGradientItem);
1491 0 : pPath->SetMergedItemSet(aGradientAttr);
1492 :
1493 0 : InsertObj(pPath, false);
1494 0 : }
1495 0 : }
1496 0 : }
1497 :
1498 0 : void ImpSdrGDIMetaFileImport::DoAction(MetaFloatTransparentAction& rAct)
1499 : {
1500 0 : const GDIMetaFile& rMtf = rAct.GetGDIMetaFile();
1501 :
1502 0 : if(rMtf.GetActionSize())
1503 : {
1504 0 : const Rectangle aRect(rAct.GetPoint(),rAct.GetSize());
1505 :
1506 : // convert metafile sub-content to BitmapEx
1507 : BitmapEx aBitmapEx(
1508 : convertMetafileToBitmapEx(
1509 : rMtf,
1510 : basegfx::B2DRange(
1511 0 : aRect.Left(), aRect.Top(),
1512 0 : aRect.Right(), aRect.Bottom()),
1513 0 : 125000));
1514 :
1515 : // handle colors
1516 0 : const Gradient& rGradient = rAct.GetGradient();
1517 0 : basegfx::BColor aStart(rGradient.GetStartColor().getBColor());
1518 0 : basegfx::BColor aEnd(rGradient.GetEndColor().getBColor());
1519 :
1520 0 : if(100 != rGradient.GetStartIntensity())
1521 : {
1522 0 : aStart *= (double)rGradient.GetStartIntensity() / 100.0;
1523 : }
1524 :
1525 0 : if(100 != rGradient.GetEndIntensity())
1526 : {
1527 0 : aEnd *= (double)rGradient.GetEndIntensity() / 100.0;
1528 : }
1529 :
1530 0 : const bool bEqualColors(aStart == aEnd);
1531 0 : const bool bNoSteps(1 == rGradient.GetSteps());
1532 0 : bool bCreateObject(true);
1533 0 : bool bHasNewMask(false);
1534 0 : AlphaMask aNewMask;
1535 0 : double fTransparence(0.0);
1536 0 : bool bFixedTransparence(false);
1537 :
1538 0 : if(bEqualColors || bNoSteps)
1539 : {
1540 : // single transparence
1541 0 : const basegfx::BColor aMedium(basegfx::average(aStart, aEnd));
1542 0 : fTransparence = aMedium.luminance();
1543 :
1544 0 : if(basegfx::fTools::lessOrEqual(fTransparence, 0.0))
1545 : {
1546 : // no transparence needed, all done
1547 : }
1548 0 : else if(basegfx::fTools::moreOrEqual(fTransparence, 1.0))
1549 : {
1550 : // all transparent, no object
1551 0 : bCreateObject = false;
1552 : }
1553 : else
1554 : {
1555 : // 0.0 < transparence < 1.0, apply fixed transparence
1556 0 : bFixedTransparence = true;
1557 0 : }
1558 : }
1559 : else
1560 : {
1561 : // gradient transparence
1562 0 : ScopedVclPtrInstance< VirtualDevice > pVDev;
1563 :
1564 0 : pVDev->SetOutputSizePixel(aBitmapEx.GetBitmap().GetSizePixel());
1565 0 : pVDev->DrawGradient(Rectangle(Point(0, 0), pVDev->GetOutputSizePixel()), rGradient);
1566 :
1567 0 : aNewMask = AlphaMask(pVDev->GetBitmap(Point(0, 0), pVDev->GetOutputSizePixel()));
1568 0 : bHasNewMask = true;
1569 : }
1570 :
1571 0 : if(bCreateObject)
1572 : {
1573 0 : if(bHasNewMask || bFixedTransparence)
1574 : {
1575 0 : if(!aBitmapEx.IsAlpha() && !aBitmapEx.IsTransparent())
1576 : {
1577 : // no transparence yet, apply new one
1578 0 : if(bFixedTransparence)
1579 : {
1580 0 : sal_uInt8 aAlpha(basegfx::fround(fTransparence * 255.0));
1581 :
1582 0 : aNewMask = AlphaMask(aBitmapEx.GetBitmap().GetSizePixel(), &aAlpha);
1583 : }
1584 :
1585 0 : aBitmapEx = BitmapEx(aBitmapEx.GetBitmap(), aNewMask);
1586 : }
1587 : else
1588 : {
1589 : // mix existing and new alpha mask
1590 0 : AlphaMask aOldMask;
1591 :
1592 0 : if(aBitmapEx.IsAlpha())
1593 : {
1594 0 : aOldMask = aBitmapEx.GetAlpha();
1595 : }
1596 0 : else if(TRANSPARENT_BITMAP == aBitmapEx.GetTransparentType())
1597 : {
1598 0 : aOldMask = aBitmapEx.GetMask();
1599 : }
1600 0 : else if(TRANSPARENT_COLOR == aBitmapEx.GetTransparentType())
1601 : {
1602 0 : aOldMask = aBitmapEx.GetBitmap().CreateMask(aBitmapEx.GetTransparentColor());
1603 : }
1604 :
1605 0 : BitmapWriteAccess* pOld = aOldMask.AcquireWriteAccess();
1606 :
1607 0 : if(pOld)
1608 : {
1609 0 : const double fFactor(1.0 / 255.0);
1610 :
1611 0 : if(bFixedTransparence)
1612 : {
1613 0 : const double fOpNew(1.0 - fTransparence);
1614 :
1615 0 : for(long y(0); y < pOld->Height(); y++)
1616 : {
1617 0 : for(long x(0); x < pOld->Width(); x++)
1618 : {
1619 0 : const double fOpOld(1.0 - (pOld->GetPixel(y, x).GetIndex() * fFactor));
1620 0 : const sal_uInt8 aCol(basegfx::fround((1.0 - (fOpOld * fOpNew)) * 255.0));
1621 :
1622 0 : pOld->SetPixel(y, x, BitmapColor(aCol));
1623 : }
1624 : }
1625 : }
1626 : else
1627 : {
1628 0 : BitmapReadAccess* pNew = aNewMask.AcquireReadAccess();
1629 :
1630 0 : if(pNew)
1631 : {
1632 0 : if(pOld->Width() == pNew->Width() && pOld->Height() == pNew->Height())
1633 : {
1634 0 : for(long y(0); y < pOld->Height(); y++)
1635 : {
1636 0 : for(long x(0); x < pOld->Width(); x++)
1637 : {
1638 0 : const double fOpOld(1.0 - (pOld->GetPixel(y, x).GetIndex() * fFactor));
1639 0 : const double fOpNew(1.0 - (pNew->GetPixel(y, x).GetIndex() * fFactor));
1640 0 : const sal_uInt8 aCol(basegfx::fround((1.0 - (fOpOld * fOpNew)) * 255.0));
1641 :
1642 0 : pOld->SetPixel(y, x, BitmapColor(aCol));
1643 : }
1644 : }
1645 : }
1646 : else
1647 : {
1648 : OSL_ENSURE(false, "Alpha masks have different sizes (!)");
1649 : }
1650 :
1651 0 : aNewMask.ReleaseAccess(pNew);
1652 : }
1653 : else
1654 : {
1655 : OSL_ENSURE(false, "Got no access to new alpha mask (!)");
1656 : }
1657 : }
1658 :
1659 0 : aOldMask.ReleaseAccess(pOld);
1660 : }
1661 : else
1662 : {
1663 : OSL_ENSURE(false, "Got no access to old alpha mask (!)");
1664 : }
1665 :
1666 : // apply combined bitmap as mask
1667 0 : aBitmapEx = BitmapEx(aBitmapEx.GetBitmap(), aOldMask);
1668 : }
1669 : }
1670 :
1671 : // create and add object
1672 0 : SdrGrafObj* pGraf = new SdrGrafObj(aBitmapEx, aRect);
1673 :
1674 : // for MetaFloatTransparentAction, do not use SetAttributes(...)
1675 : // since these metafile content is not used to draw line/fill
1676 : // dependent of these setting at the device content
1677 0 : pGraf->SetMergedItem(XLineStyleItem(drawing::LineStyle_NONE));
1678 0 : pGraf->SetMergedItem(XFillStyleItem(drawing::FillStyle_NONE));
1679 0 : InsertObj(pGraf);
1680 0 : }
1681 : }
1682 435 : }
1683 :
1684 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|