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