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 :
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((MetaPixelAction &)*pAct); break;
142 0 : case META_POINT_ACTION : DoAction((MetaPointAction &)*pAct); break;
143 0 : case META_LINE_ACTION : DoAction((MetaLineAction &)*pAct); break;
144 0 : case META_RECT_ACTION : DoAction((MetaRectAction &)*pAct); break;
145 0 : case META_ROUNDRECT_ACTION : DoAction((MetaRoundRectAction &)*pAct); break;
146 0 : case META_ELLIPSE_ACTION : DoAction((MetaEllipseAction &)*pAct); break;
147 0 : case META_ARC_ACTION : DoAction((MetaArcAction &)*pAct); break;
148 0 : case META_PIE_ACTION : DoAction((MetaPieAction &)*pAct); break;
149 0 : case META_CHORD_ACTION : DoAction((MetaChordAction &)*pAct); break;
150 0 : case META_POLYLINE_ACTION : DoAction((MetaPolyLineAction &)*pAct); break;
151 0 : case META_POLYGON_ACTION : DoAction((MetaPolygonAction &)*pAct); break;
152 0 : case META_POLYPOLYGON_ACTION : DoAction((MetaPolyPolygonAction &)*pAct); break;
153 0 : case META_TEXT_ACTION : DoAction((MetaTextAction &)*pAct); break;
154 0 : case META_TEXTARRAY_ACTION : DoAction((MetaTextArrayAction &)*pAct); break;
155 0 : case META_STRETCHTEXT_ACTION : DoAction((MetaStretchTextAction &)*pAct); break;
156 0 : case META_BMP_ACTION : DoAction((MetaBmpAction &)*pAct); break;
157 0 : case META_BMPSCALE_ACTION : DoAction((MetaBmpScaleAction &)*pAct); break;
158 0 : case META_BMPEX_ACTION : DoAction((MetaBmpExAction &)*pAct); break;
159 0 : case META_BMPEXSCALE_ACTION : DoAction((MetaBmpExScaleAction &)*pAct); break;
160 0 : case META_LINECOLOR_ACTION : DoAction((MetaLineColorAction &)*pAct); break;
161 0 : case META_FILLCOLOR_ACTION : DoAction((MetaFillColorAction &)*pAct); break;
162 0 : case META_TEXTCOLOR_ACTION : DoAction((MetaTextColorAction &)*pAct); break;
163 0 : case META_TEXTFILLCOLOR_ACTION : DoAction((MetaTextFillColorAction &)*pAct); break;
164 0 : case META_FONT_ACTION : DoAction((MetaFontAction &)*pAct); break;
165 0 : case META_TEXTALIGN_ACTION : DoAction((MetaTextAlignAction &)*pAct); break;
166 0 : case META_MAPMODE_ACTION : DoAction((MetaMapModeAction &)*pAct); break;
167 0 : case META_CLIPREGION_ACTION : DoAction((MetaClipRegionAction &)*pAct); break;
168 0 : case META_MOVECLIPREGION_ACTION : DoAction((MetaMoveClipRegionAction &)*pAct); break;
169 0 : case META_ISECTRECTCLIPREGION_ACTION: DoAction((MetaISectRectClipRegionAction&)*pAct); break;
170 0 : case META_ISECTREGIONCLIPREGION_ACTION: DoAction((MetaISectRegionClipRegionAction&)*pAct); break;
171 0 : case META_RASTEROP_ACTION : DoAction((MetaRasterOpAction &)*pAct); break;
172 0 : case META_PUSH_ACTION : DoAction((MetaPushAction &)*pAct); break;
173 0 : case META_POP_ACTION : DoAction((MetaPopAction &)*pAct); break;
174 0 : case META_HATCH_ACTION : DoAction((MetaHatchAction &)*pAct); break;
175 0 : case META_COMMENT_ACTION : DoAction((MetaCommentAction &)*pAct, &rMtf); break;
176 :
177 : // missing actions added
178 0 : case META_TEXTRECT_ACTION : DoAction((MetaTextRectAction&)*pAct); break;
179 0 : case META_BMPSCALEPART_ACTION : DoAction((MetaBmpScalePartAction&)*pAct); break;
180 0 : case META_BMPEXSCALEPART_ACTION : DoAction((MetaBmpExScalePartAction&)*pAct); break;
181 0 : case META_MASK_ACTION : DoAction((MetaMaskAction&)*pAct); break;
182 0 : case META_MASKSCALE_ACTION : DoAction((MetaMaskScaleAction&)*pAct); break;
183 0 : case META_MASKSCALEPART_ACTION : DoAction((MetaMaskScalePartAction&)*pAct); break;
184 0 : case META_GRADIENT_ACTION : DoAction((MetaGradientAction&)*pAct); break;
185 0 : case META_WALLPAPER_ACTION : DoAction((MetaWallpaperAction&)*pAct); break;
186 0 : case META_TRANSPARENT_ACTION : DoAction((MetaTransparentAction&)*pAct); break;
187 0 : case META_EPS_ACTION : DoAction((MetaEPSAction&)*pAct); break;
188 0 : case META_REFPOINT_ACTION : DoAction((MetaRefPointAction&)*pAct); break;
189 0 : case META_TEXTLINECOLOR_ACTION : DoAction((MetaTextLineColorAction&)*pAct); break;
190 0 : case META_TEXTLINE_ACTION : DoAction((MetaTextLineAction&)*pAct); break;
191 0 : case META_FLOATTRANSPARENT_ACTION : DoAction((MetaFloatTransparentAction&)*pAct); break;
192 0 : case META_GRADIENTEX_ACTION : DoAction((MetaGradientExAction&)*pAct); break;
193 0 : case META_LAYOUTMODE_ACTION : DoAction((MetaLayoutModeAction&)*pAct); break;
194 0 : case META_TEXTLANGUAGE_ACTION : DoAction((MetaTextLanguageAction&)*pAct); break;
195 0 : case META_OVERLINECOLOR_ACTION : DoAction((MetaOverlineColorAction&)*pAct); break;
196 : }
197 :
198 0 : if(pProgrInfo && pActionsToReport)
199 : {
200 0 : (*pActionsToReport)++;
201 :
202 0 : if(*pActionsToReport >= 16) // update all 16 actions
203 : {
204 0 : if(!pProgrInfo->ReportActions(*pActionsToReport))
205 0 : break;
206 :
207 0 : *pActionsToReport = 0;
208 : }
209 : }
210 : }
211 0 : }
212 :
213 0 : sal_uInt32 ImpSdrGDIMetaFileImport::DoImport(
214 : const GDIMetaFile& rMtf,
215 : SdrObjList& rOL,
216 : sal_uLong nInsPos,
217 : SvdProgressInfo* pProgrInfo)
218 : {
219 : // setup some global scale parameter
220 : // mfScaleX, mfScaleY, maScaleX, maScaleY, mbMov, mbSize
221 0 : mfScaleX = mfScaleY = 1.0;
222 0 : const Size aMtfSize(rMtf.GetPrefSize());
223 :
224 0 : if(aMtfSize.Width() & aMtfSize.Height() && (!maScaleRect.IsEmpty()))
225 : {
226 0 : maOfs = maScaleRect.TopLeft();
227 :
228 0 : if(aMtfSize.Width() != (maScaleRect.GetWidth() - 1))
229 : {
230 0 : mfScaleX = (double)( maScaleRect.GetWidth() - 1 ) / (double)aMtfSize.Width();
231 : }
232 :
233 0 : if(aMtfSize.Height() != (maScaleRect.GetHeight() - 1))
234 : {
235 0 : mfScaleY = (double)( maScaleRect.GetHeight() - 1 ) / (double)aMtfSize.Height();
236 : }
237 : }
238 :
239 0 : mbMov = maOfs.X()!=0 || maOfs.Y()!=0;
240 0 : mbSize = false;
241 0 : maScaleX = Fraction( 1, 1 );
242 0 : maScaleY = Fraction( 1, 1 );
243 :
244 0 : if(aMtfSize.Width() != (maScaleRect.GetWidth() - 1))
245 : {
246 0 : maScaleX = Fraction(maScaleRect.GetWidth() - 1, aMtfSize.Width());
247 0 : mbSize = true;
248 : }
249 :
250 0 : if(aMtfSize.Height() != (maScaleRect.GetHeight() - 1))
251 : {
252 0 : maScaleY = Fraction(maScaleRect.GetHeight() - 1, aMtfSize.Height());
253 0 : mbSize = true;
254 : }
255 :
256 0 : if(pProgrInfo)
257 : {
258 0 : pProgrInfo->SetActionCount(rMtf.GetActionSize());
259 : }
260 :
261 0 : sal_uInt32 nActionsToReport(0);
262 :
263 : // execute
264 0 : DoLoopActions(const_cast< GDIMetaFile& >(rMtf), pProgrInfo, &nActionsToReport);
265 :
266 0 : if(pProgrInfo)
267 : {
268 0 : pProgrInfo->ReportActions(nActionsToReport);
269 0 : nActionsToReport = 0;
270 : }
271 :
272 : // MapMode scaling
273 0 : MapScaling();
274 :
275 : // To calculate the progress meter, we use GetActionSize()*3.
276 : // However, maTmpList has a lower entry count limit than GetActionSize(),
277 : // so the actions that were assumed were too much have to be re-added.
278 0 : nActionsToReport = (rMtf.GetActionSize() - maTmpList.size()) * 2;
279 :
280 : // announce all currently unannounced rescales
281 0 : if(pProgrInfo)
282 : {
283 0 : pProgrInfo->ReportRescales(nActionsToReport);
284 0 : pProgrInfo->SetInsertCount(maTmpList.size());
285 : }
286 :
287 0 : nActionsToReport = 0;
288 :
289 : // insert all objects cached in aTmpList now into rOL from nInsPos
290 0 : if(nInsPos > rOL.GetObjCount())
291 : {
292 0 : nInsPos = rOL.GetObjCount();
293 : }
294 :
295 0 : SdrInsertReason aReason(SDRREASON_VIEWCALL);
296 :
297 0 : for(sal_uInt32 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(XFILL_SOLID));
396 0 : mpFillAttr->Put(XFillColorItem(OUString(), maVD.GetFillColor()));
397 : }
398 : else
399 : {
400 0 : mpFillAttr->Put(XFillStyleItem(XFILL_NONE));
401 : }
402 : }
403 : else
404 : {
405 0 : mbNoFill = true;
406 : }
407 :
408 0 : if(bText && mbFntDirty)
409 : {
410 0 : 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(XFILL_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 : /**************************************************************************************************/
674 0 : void ImpSdrGDIMetaFileImport::DoAction(MetaPixelAction& /*rAct*/) const
675 : {
676 0 : }
677 :
678 0 : void ImpSdrGDIMetaFileImport::DoAction(MetaPointAction& /*rAct*/) const
679 : {
680 0 : }
681 :
682 0 : void ImpSdrGDIMetaFileImport::DoAction(MetaLineAction& rAct)
683 : {
684 : // #i73407# reformulation to use new B2DPolygon classes
685 0 : const basegfx::B2DPoint aStart(rAct.GetStartPoint().X(), rAct.GetStartPoint().Y());
686 0 : const basegfx::B2DPoint aEnd(rAct.GetEndPoint().X(), rAct.GetEndPoint().Y());
687 :
688 0 : if(!aStart.equal(aEnd))
689 : {
690 0 : basegfx::B2DPolygon aLine;
691 0 : const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(mfScaleX, mfScaleY, maOfs.X(), maOfs.Y()));
692 :
693 0 : aLine.append(aStart);
694 0 : aLine.append(aEnd);
695 0 : aLine.transform(aTransform);
696 :
697 0 : const LineInfo& rLineInfo = rAct.GetLineInfo();
698 0 : const sal_Int32 nNewLineWidth(rLineInfo.GetWidth());
699 0 : bool bCreateLineObject(true);
700 :
701 0 : if(mbLastObjWasLine && (nNewLineWidth == mnLineWidth) && CheckLastLineMerge(aLine))
702 : {
703 0 : bCreateLineObject = false;
704 : }
705 :
706 0 : if(bCreateLineObject)
707 : {
708 0 : SdrPathObj* pPath = new SdrPathObj(OBJ_LINE, basegfx::B2DPolyPolygon(aLine));
709 0 : mnLineWidth = nNewLineWidth;
710 0 : maLineJoin = rLineInfo.GetLineJoin();
711 0 : maLineCap = rLineInfo.GetLineCap();
712 : maDash = XDash(XDASH_RECT,
713 0 : rLineInfo.GetDotCount(), rLineInfo.GetDotLen(),
714 0 : rLineInfo.GetDashCount(), rLineInfo.GetDashLen(),
715 0 : rLineInfo.GetDistance());
716 0 : SetAttributes(pPath);
717 0 : mnLineWidth = 0;
718 0 : maLineJoin = basegfx::B2DLINEJOIN_NONE;
719 0 : maDash = XDash();
720 0 : InsertObj(pPath, false);
721 0 : }
722 0 : }
723 0 : }
724 :
725 0 : void ImpSdrGDIMetaFileImport::DoAction(MetaRectAction& rAct)
726 : {
727 0 : SdrRectObj* pRect=new SdrRectObj(rAct.GetRect());
728 0 : SetAttributes(pRect);
729 0 : InsertObj(pRect);
730 0 : }
731 :
732 0 : void ImpSdrGDIMetaFileImport::DoAction(MetaRoundRectAction& rAct)
733 : {
734 0 : SdrRectObj* pRect=new SdrRectObj(rAct.GetRect());
735 0 : SetAttributes(pRect);
736 0 : long nRad=(rAct.GetHorzRound()+rAct.GetVertRound())/2;
737 0 : if (nRad!=0) {
738 0 : SfxItemSet aSet(*mpLineAttr->GetPool(), SDRATTR_ECKENRADIUS, SDRATTR_ECKENRADIUS, 0, 0);
739 0 : aSet.Put(SdrEckenradiusItem(nRad));
740 0 : pRect->SetMergedItemSet(aSet);
741 : }
742 0 : InsertObj(pRect);
743 0 : }
744 :
745 : /**************************************************************************************************/
746 :
747 0 : void ImpSdrGDIMetaFileImport::DoAction(MetaEllipseAction& rAct)
748 : {
749 0 : SdrCircObj* pCirc=new SdrCircObj(OBJ_CIRC,rAct.GetRect());
750 0 : SetAttributes(pCirc);
751 0 : InsertObj(pCirc);
752 0 : }
753 :
754 0 : void ImpSdrGDIMetaFileImport::DoAction(MetaArcAction& 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_CARC,rAct.GetRect(),nStart,nEnd);
760 0 : SetAttributes(pCirc);
761 0 : InsertObj(pCirc);
762 0 : }
763 :
764 0 : void ImpSdrGDIMetaFileImport::DoAction(MetaPieAction& 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_SECT,rAct.GetRect(),nStart,nEnd);
770 0 : SetAttributes(pCirc);
771 0 : InsertObj(pCirc);
772 0 : }
773 :
774 0 : void ImpSdrGDIMetaFileImport::DoAction(MetaChordAction& rAct)
775 : {
776 0 : Point aCenter(rAct.GetRect().Center());
777 0 : long nStart=GetAngle(rAct.GetStartPoint()-aCenter);
778 0 : long nEnd=GetAngle(rAct.GetEndPoint()-aCenter);
779 0 : SdrCircObj* pCirc=new SdrCircObj(OBJ_CCUT,rAct.GetRect(),nStart,nEnd);
780 0 : SetAttributes(pCirc);
781 0 : InsertObj(pCirc);
782 0 : }
783 :
784 : /**************************************************************************************************/
785 :
786 0 : bool ImpSdrGDIMetaFileImport::CheckLastLineMerge(const basegfx::B2DPolygon& rSrcPoly)
787 : {
788 : // #i102706# Do not merge closed polygons
789 0 : if(rSrcPoly.isClosed())
790 : {
791 0 : return false;
792 : }
793 :
794 : // #i73407# reformulation to use new B2DPolygon classes
795 0 : if(mbLastObjWasLine && (maOldLineColor == maVD.GetLineColor()) && rSrcPoly.count())
796 : {
797 0 : SdrObject* pTmpObj = maTmpList.size() ? maTmpList[maTmpList.size() - 1] : 0;
798 0 : SdrPathObj* pLastPoly = dynamic_cast< SdrPathObj* >(pTmpObj);
799 :
800 0 : if(pLastPoly)
801 : {
802 0 : if(1L == pLastPoly->GetPathPoly().count())
803 : {
804 0 : bool bOk(false);
805 0 : basegfx::B2DPolygon aDstPoly(pLastPoly->GetPathPoly().getB2DPolygon(0L));
806 :
807 : // #i102706# Do not merge closed polygons
808 0 : if(aDstPoly.isClosed())
809 : {
810 0 : return false;
811 : }
812 :
813 0 : if(aDstPoly.count())
814 : {
815 0 : const sal_uInt32 nMaxDstPnt(aDstPoly.count() - 1L);
816 0 : const sal_uInt32 nMaxSrcPnt(rSrcPoly.count() - 1L);
817 :
818 0 : if(aDstPoly.getB2DPoint(nMaxDstPnt) == rSrcPoly.getB2DPoint(0L))
819 : {
820 0 : aDstPoly.append(rSrcPoly, 1L, rSrcPoly.count() - 1L);
821 0 : bOk = true;
822 : }
823 0 : else if(aDstPoly.getB2DPoint(0L) == rSrcPoly.getB2DPoint(nMaxSrcPnt))
824 : {
825 0 : basegfx::B2DPolygon aNew(rSrcPoly);
826 0 : aNew.append(aDstPoly, 1L, aDstPoly.count() - 1L);
827 0 : aDstPoly = aNew;
828 0 : bOk = true;
829 : }
830 0 : else if(aDstPoly.getB2DPoint(0L) == rSrcPoly.getB2DPoint(0L))
831 : {
832 0 : aDstPoly.flip();
833 0 : aDstPoly.append(rSrcPoly, 1L, rSrcPoly.count() - 1L);
834 0 : bOk = true;
835 : }
836 0 : else if(aDstPoly.getB2DPoint(nMaxDstPnt) == rSrcPoly.getB2DPoint(nMaxSrcPnt))
837 : {
838 0 : basegfx::B2DPolygon aNew(rSrcPoly);
839 0 : aNew.flip();
840 0 : aDstPoly.append(aNew, 1L, aNew.count() - 1L);
841 0 : bOk = true;
842 : }
843 : }
844 :
845 0 : if(bOk)
846 : {
847 0 : pLastPoly->NbcSetPathPoly(basegfx::B2DPolyPolygon(aDstPoly));
848 : }
849 :
850 0 : return bOk;
851 : }
852 : }
853 : }
854 :
855 0 : return false;
856 : }
857 :
858 0 : bool ImpSdrGDIMetaFileImport::CheckLastPolyLineAndFillMerge(const basegfx::B2DPolyPolygon & rPolyPolygon)
859 : {
860 : // #i73407# reformulation to use new B2DPolygon classes
861 0 : if(mbLastObjWasPolyWithoutLine)
862 : {
863 0 : SdrObject* pTmpObj = maTmpList.size() ? maTmpList[maTmpList.size() - 1] : 0;
864 0 : SdrPathObj* pLastPoly = dynamic_cast< SdrPathObj* >(pTmpObj);
865 :
866 0 : if(pLastPoly)
867 : {
868 0 : if(pLastPoly->GetPathPoly() == rPolyPolygon)
869 : {
870 0 : SetAttributes(NULL);
871 :
872 0 : if(!mbNoLine && mbNoFill)
873 : {
874 0 : pLastPoly->SetMergedItemSet(*mpLineAttr);
875 :
876 0 : return true;
877 : }
878 : }
879 : }
880 : }
881 :
882 0 : return false;
883 : }
884 :
885 0 : void ImpSdrGDIMetaFileImport::checkClip()
886 : {
887 0 : if(maVD.IsClipRegion())
888 : {
889 0 : maClip = maVD.GetClipRegion().GetAsB2DPolyPolygon();
890 :
891 0 : if(isClip())
892 : {
893 : const basegfx::B2DHomMatrix aTransform(
894 : basegfx::tools::createScaleTranslateB2DHomMatrix(
895 : mfScaleX,
896 : mfScaleY,
897 0 : maOfs.X(),
898 0 : maOfs.Y()));
899 :
900 0 : maClip.transform(aTransform);
901 : }
902 : }
903 0 : }
904 :
905 0 : bool ImpSdrGDIMetaFileImport::isClip() const
906 : {
907 0 : return !maClip.getB2DRange().isEmpty();
908 : }
909 :
910 0 : void ImpSdrGDIMetaFileImport::DoAction( MetaPolyLineAction& rAct )
911 : {
912 : // #i73407# reformulation to use new B2DPolygon classes
913 0 : basegfx::B2DPolygon aSource(rAct.GetPolygon().getB2DPolygon());
914 :
915 0 : if(aSource.count())
916 : {
917 0 : const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(mfScaleX, mfScaleY, maOfs.X(), maOfs.Y()));
918 0 : aSource.transform(aTransform);
919 : }
920 :
921 0 : const LineInfo& rLineInfo = rAct.GetLineInfo();
922 0 : const sal_Int32 nNewLineWidth(rLineInfo.GetWidth());
923 0 : bool bCreateLineObject(true);
924 :
925 0 : if(mbLastObjWasLine && (nNewLineWidth == mnLineWidth) && CheckLastLineMerge(aSource))
926 : {
927 0 : bCreateLineObject = false;
928 : }
929 0 : else if(mbLastObjWasPolyWithoutLine && CheckLastPolyLineAndFillMerge(basegfx::B2DPolyPolygon(aSource)))
930 : {
931 0 : bCreateLineObject = false;
932 : }
933 :
934 0 : if(bCreateLineObject)
935 : {
936 : SdrPathObj* pPath = new SdrPathObj(
937 0 : aSource.isClosed() ? OBJ_POLY : OBJ_PLIN,
938 0 : basegfx::B2DPolyPolygon(aSource));
939 0 : mnLineWidth = nNewLineWidth;
940 0 : maLineJoin = rLineInfo.GetLineJoin();
941 0 : maLineCap = rLineInfo.GetLineCap();
942 : maDash = XDash(XDASH_RECT,
943 0 : rLineInfo.GetDotCount(), rLineInfo.GetDotLen(),
944 0 : rLineInfo.GetDashCount(), rLineInfo.GetDashLen(),
945 0 : rLineInfo.GetDistance());
946 0 : SetAttributes(pPath);
947 0 : mnLineWidth = 0;
948 0 : maLineJoin = basegfx::B2DLINEJOIN_NONE;
949 0 : maDash = XDash();
950 0 : InsertObj(pPath, false);
951 0 : }
952 0 : }
953 :
954 0 : void ImpSdrGDIMetaFileImport::DoAction( MetaPolygonAction& rAct )
955 : {
956 : // #i73407# reformulation to use new B2DPolygon classes
957 0 : basegfx::B2DPolygon aSource(rAct.GetPolygon().getB2DPolygon());
958 :
959 0 : if(aSource.count())
960 : {
961 0 : const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(mfScaleX, mfScaleY, maOfs.X(), maOfs.Y()));
962 0 : aSource.transform(aTransform);
963 :
964 0 : if(!mbLastObjWasPolyWithoutLine || !CheckLastPolyLineAndFillMerge(basegfx::B2DPolyPolygon(aSource)))
965 : {
966 : // #i73407# make sure polygon is closed, it's a filled primitive
967 0 : aSource.setClosed(true);
968 0 : SdrPathObj* pPath = new SdrPathObj(OBJ_POLY, basegfx::B2DPolyPolygon(aSource));
969 0 : SetAttributes(pPath);
970 0 : InsertObj(pPath, false);
971 0 : }
972 0 : }
973 0 : }
974 :
975 0 : void ImpSdrGDIMetaFileImport::DoAction(MetaPolyPolygonAction& rAct)
976 : {
977 : // #i73407# reformulation to use new B2DPolygon classes
978 0 : basegfx::B2DPolyPolygon aSource(rAct.GetPolyPolygon().getB2DPolyPolygon());
979 :
980 0 : if(aSource.count())
981 : {
982 0 : const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(mfScaleX, mfScaleY, maOfs.X(), maOfs.Y()));
983 0 : aSource.transform(aTransform);
984 :
985 0 : if(!mbLastObjWasPolyWithoutLine || !CheckLastPolyLineAndFillMerge(aSource))
986 : {
987 : // #i73407# make sure polygon is closed, it's a filled primitive
988 0 : aSource.setClosed(true);
989 0 : SdrPathObj* pPath = new SdrPathObj(OBJ_POLY, aSource);
990 0 : SetAttributes(pPath);
991 0 : InsertObj(pPath, false);
992 0 : }
993 0 : }
994 0 : }
995 :
996 : /**************************************************************************************************/
997 :
998 0 : void ImpSdrGDIMetaFileImport::ImportText( const Point& rPos, const OUString& rStr, const MetaAction& rAct )
999 : {
1000 : // calc text box size, add 5% to make it fit safely
1001 :
1002 0 : FontMetric aFontMetric( maVD.GetFontMetric() );
1003 0 : Font aFnt( maVD.GetFont() );
1004 0 : FontAlign eAlg( aFnt.GetAlign() );
1005 :
1006 0 : sal_Int32 nTextWidth = (sal_Int32)( maVD.GetTextWidth( rStr ) * mfScaleX );
1007 0 : sal_Int32 nTextHeight = (sal_Int32)( maVD.GetTextHeight() * mfScaleY );
1008 :
1009 0 : Point aPos( FRound(rPos.X() * mfScaleX + maOfs.X()), FRound(rPos.Y() * mfScaleY + maOfs.Y()) );
1010 0 : Size aSize( nTextWidth, nTextHeight );
1011 :
1012 0 : if ( eAlg == ALIGN_BASELINE )
1013 0 : aPos.Y() -= FRound(aFontMetric.GetAscent() * mfScaleY);
1014 0 : else if ( eAlg == ALIGN_BOTTOM )
1015 0 : aPos.Y() -= nTextHeight;
1016 :
1017 0 : Rectangle aTextRect( aPos, aSize );
1018 0 : SdrRectObj* pText =new SdrRectObj( OBJ_TEXT, aTextRect );
1019 :
1020 0 : pText->SetMergedItem ( SdrTextUpperDistItem (0));
1021 0 : pText->SetMergedItem ( SdrTextLowerDistItem (0));
1022 0 : pText->SetMergedItem ( SdrTextRightDistItem (0));
1023 0 : pText->SetMergedItem ( SdrTextLeftDistItem (0));
1024 :
1025 0 : if ( aFnt.GetWidth() || ( rAct.GetType() == META_STRETCHTEXT_ACTION ) )
1026 : {
1027 0 : pText->ClearMergedItem( SDRATTR_TEXT_AUTOGROWWIDTH );
1028 0 : pText->SetMergedItem( SdrTextAutoGrowHeightItem( false ) );
1029 : // don't let the margins eat the space needed for the text
1030 0 : pText->SetMergedItem( SdrTextFitToSizeTypeItem( SDRTEXTFIT_ALLLINES ) );
1031 : }
1032 : else
1033 : {
1034 0 : pText->SetMergedItem( SdrTextAutoGrowWidthItem( true ) );
1035 : }
1036 :
1037 0 : pText->SetModel(mpModel);
1038 0 : pText->SetLayer(mnLayer);
1039 0 : pText->NbcSetText( rStr );
1040 0 : SetAttributes( pText, true );
1041 0 : pText->SetSnapRect( aTextRect );
1042 :
1043 0 : if (!aFnt.IsTransparent())
1044 : {
1045 0 : SfxItemSet aAttr(*mpFillAttr->GetPool(), XATTR_FILL_FIRST, XATTR_FILL_LAST, 0, 0);
1046 0 : aAttr.Put(XFillStyleItem(XFILL_SOLID));
1047 0 : aAttr.Put(XFillColorItem(OUString(), aFnt.GetFillColor()));
1048 0 : pText->SetMergedItemSet(aAttr);
1049 : }
1050 0 : sal_uInt32 nWink = aFnt.GetOrientation();
1051 0 : if ( nWink )
1052 : {
1053 0 : nWink*=10;
1054 0 : double a=nWink*nPi180;
1055 0 : double nSin=sin(a);
1056 0 : double nCos=cos(a);
1057 0 : pText->NbcRotate(aPos,nWink,nSin,nCos);
1058 : }
1059 0 : InsertObj( pText, false );
1060 0 : }
1061 :
1062 0 : void ImpSdrGDIMetaFileImport::DoAction(MetaTextAction& 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(MetaTextArrayAction& 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(MetaStretchTextAction& rAct)
1077 : {
1078 0 : OUString aStr(rAct.GetText());
1079 0 : aStr = aStr.copy(rAct.GetIndex(), rAct.GetLen());
1080 0 : ImportText( rAct.GetPoint(), aStr, rAct );
1081 0 : }
1082 :
1083 0 : void ImpSdrGDIMetaFileImport::DoAction(MetaBmpAction& rAct)
1084 : {
1085 0 : Rectangle aRect(rAct.GetPoint(),rAct.GetBitmap().GetSizePixel());
1086 0 : aRect.Right()++; aRect.Bottom()++;
1087 0 : SdrGrafObj* pGraf=new SdrGrafObj(Graphic(rAct.GetBitmap()),aRect);
1088 :
1089 : // This action is not creating line and fill, set directly, do not use SetAttributes(..)
1090 0 : pGraf->SetMergedItem(XLineStyleItem(XLINE_NONE));
1091 0 : pGraf->SetMergedItem(XFillStyleItem(XFILL_NONE));
1092 0 : InsertObj(pGraf);
1093 0 : }
1094 :
1095 0 : void ImpSdrGDIMetaFileImport::DoAction(MetaBmpScaleAction& rAct)
1096 : {
1097 0 : Rectangle aRect(rAct.GetPoint(),rAct.GetSize());
1098 0 : aRect.Right()++; aRect.Bottom()++;
1099 0 : SdrGrafObj* pGraf=new SdrGrafObj(Graphic(rAct.GetBitmap()),aRect);
1100 :
1101 : // This action is not creating line and fill, set directly, do not use SetAttributes(..)
1102 0 : pGraf->SetMergedItem(XLineStyleItem(XLINE_NONE));
1103 0 : pGraf->SetMergedItem(XFillStyleItem(XFILL_NONE));
1104 0 : InsertObj(pGraf);
1105 0 : }
1106 :
1107 0 : void ImpSdrGDIMetaFileImport::DoAction(MetaBmpExAction& rAct)
1108 : {
1109 0 : Rectangle aRect(rAct.GetPoint(),rAct.GetBitmapEx().GetSizePixel());
1110 0 : aRect.Right()++; aRect.Bottom()++;
1111 0 : SdrGrafObj* pGraf=new SdrGrafObj( rAct.GetBitmapEx(), aRect );
1112 :
1113 : // This action is not creating line and fill, set directly, do not use SetAttributes(..)
1114 0 : pGraf->SetMergedItem(XLineStyleItem(XLINE_NONE));
1115 0 : pGraf->SetMergedItem(XFillStyleItem(XFILL_NONE));
1116 0 : InsertObj(pGraf);
1117 0 : }
1118 :
1119 0 : void ImpSdrGDIMetaFileImport::DoAction(MetaBmpExScaleAction& rAct)
1120 : {
1121 0 : Rectangle aRect(rAct.GetPoint(),rAct.GetSize());
1122 0 : aRect.Right()++; aRect.Bottom()++;
1123 0 : SdrGrafObj* pGraf=new SdrGrafObj( rAct.GetBitmapEx(), aRect );
1124 :
1125 : // This action is not creating line and fill, set directly, do not use SetAttributes(..)
1126 0 : pGraf->SetMergedItem(XLineStyleItem(XLINE_NONE));
1127 0 : pGraf->SetMergedItem(XFillStyleItem(XFILL_NONE));
1128 0 : InsertObj(pGraf);
1129 0 : }
1130 :
1131 :
1132 :
1133 0 : void ImpSdrGDIMetaFileImport::DoAction( MetaHatchAction& rAct )
1134 : {
1135 : // #i73407# reformulation to use new B2DPolygon classes
1136 0 : basegfx::B2DPolyPolygon aSource(rAct.GetPolyPolygon().getB2DPolyPolygon());
1137 :
1138 0 : if(aSource.count())
1139 : {
1140 0 : const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(mfScaleX, mfScaleY, maOfs.X(), maOfs.Y()));
1141 0 : aSource.transform(aTransform);
1142 :
1143 0 : if(!mbLastObjWasPolyWithoutLine || !CheckLastPolyLineAndFillMerge(aSource))
1144 : {
1145 0 : const Hatch& rHatch = rAct.GetHatch();
1146 0 : SdrPathObj* pPath = new SdrPathObj(OBJ_POLY, aSource);
1147 0 : SfxItemSet aHatchAttr(mpModel->GetItemPool(), XATTR_FILLSTYLE, XATTR_FILLSTYLE, XATTR_FILLHATCH, XATTR_FILLHATCH, 0, 0);
1148 : XHatchStyle eStyle;
1149 :
1150 0 : switch(rHatch.GetStyle())
1151 : {
1152 : case(HATCH_TRIPLE) :
1153 : {
1154 0 : eStyle = XHATCH_TRIPLE;
1155 0 : break;
1156 : }
1157 :
1158 : case(HATCH_DOUBLE) :
1159 : {
1160 0 : eStyle = XHATCH_DOUBLE;
1161 0 : break;
1162 : }
1163 :
1164 : default:
1165 : {
1166 0 : eStyle = XHATCH_SINGLE;
1167 0 : break;
1168 : }
1169 : }
1170 :
1171 0 : SetAttributes(pPath);
1172 0 : aHatchAttr.Put(XFillStyleItem(XFILL_HATCH));
1173 0 : aHatchAttr.Put(XFillHatchItem(&mpModel->GetItemPool(), XHatch(rHatch.GetColor(), eStyle, rHatch.GetDistance(), rHatch.GetAngle())));
1174 0 : pPath->SetMergedItemSet(aHatchAttr);
1175 :
1176 0 : InsertObj(pPath, false);
1177 0 : }
1178 0 : }
1179 0 : }
1180 :
1181 :
1182 :
1183 0 : void ImpSdrGDIMetaFileImport::DoAction(MetaLineColorAction& rAct)
1184 : {
1185 0 : rAct.Execute(&maVD);
1186 0 : }
1187 :
1188 0 : void ImpSdrGDIMetaFileImport::DoAction(MetaMapModeAction& rAct)
1189 : {
1190 0 : MapScaling();
1191 0 : rAct.Execute(&maVD);
1192 0 : mbLastObjWasPolyWithoutLine = false;
1193 0 : mbLastObjWasLine = false;
1194 0 : }
1195 :
1196 0 : void ImpSdrGDIMetaFileImport::MapScaling()
1197 : {
1198 0 : const size_t nAnz(maTmpList.size());
1199 0 : const MapMode& rMap = maVD.GetMapMode();
1200 0 : Point aMapOrg( rMap.GetOrigin() );
1201 0 : bool bMov2(aMapOrg.X() != 0 || aMapOrg.Y() != 0);
1202 :
1203 0 : if(bMov2)
1204 : {
1205 0 : for(size_t i = mnMapScalingOfs; i < nAnz; i++)
1206 : {
1207 0 : SdrObject* pObj = maTmpList[i];
1208 :
1209 0 : pObj->NbcMove(Size(aMapOrg.X(), aMapOrg.Y()));
1210 : }
1211 : }
1212 :
1213 0 : mnMapScalingOfs = nAnz;
1214 0 : }
1215 :
1216 :
1217 :
1218 0 : void ImpSdrGDIMetaFileImport::DoAction( MetaCommentAction& rAct, GDIMetaFile* pMtf )
1219 : {
1220 0 : bool aSkipComment = false;
1221 :
1222 0 : if (rAct.GetComment().equalsIgnoreAsciiCase("XGRAD_SEQ_BEGIN"))
1223 : {
1224 0 : MetaGradientExAction* pAct = (MetaGradientExAction*) pMtf->NextAction();
1225 :
1226 0 : if( pAct && pAct->GetType() == META_GRADIENTEX_ACTION )
1227 : {
1228 : // #i73407# reformulation to use new B2DPolygon classes
1229 0 : basegfx::B2DPolyPolygon aSource(pAct->GetPolyPolygon().getB2DPolyPolygon());
1230 :
1231 0 : if(aSource.count())
1232 : {
1233 0 : if(!mbLastObjWasPolyWithoutLine || !CheckLastPolyLineAndFillMerge(aSource))
1234 : {
1235 0 : const Gradient& rGrad = pAct->GetGradient();
1236 0 : SdrPathObj* pPath = new SdrPathObj(OBJ_POLY, aSource);
1237 0 : SfxItemSet aGradAttr(mpModel->GetItemPool(), XATTR_FILLSTYLE, XATTR_FILLSTYLE, XATTR_FILLGRADIENT, XATTR_FILLGRADIENT, 0, 0);
1238 0 : XGradient aXGradient;
1239 :
1240 0 : aXGradient.SetGradientStyle((XGradientStyle)rGrad.GetStyle());
1241 0 : aXGradient.SetStartColor(rGrad.GetStartColor());
1242 0 : aXGradient.SetEndColor(rGrad.GetEndColor());
1243 0 : aXGradient.SetAngle((sal_uInt16)rGrad.GetAngle());
1244 0 : aXGradient.SetBorder(rGrad.GetBorder());
1245 0 : aXGradient.SetXOffset(rGrad.GetOfsX());
1246 0 : aXGradient.SetYOffset(rGrad.GetOfsY());
1247 0 : aXGradient.SetStartIntens(rGrad.GetStartIntensity());
1248 0 : aXGradient.SetEndIntens(rGrad.GetEndIntensity());
1249 0 : aXGradient.SetSteps(rGrad.GetSteps());
1250 :
1251 : // no need to use SetAttributes(..) here since line and fill style
1252 : // need to be set individually
1253 : // SetAttributes(pPath);
1254 :
1255 : // switch line off; if there was one there will be a
1256 : // META_POLYLINE_ACTION following creating another object
1257 0 : aGradAttr.Put(XLineStyleItem(XLINE_NONE));
1258 :
1259 : // add detected gradient fillstyle
1260 0 : aGradAttr.Put(XFillStyleItem(XFILL_GRADIENT));
1261 0 : aGradAttr.Put(XFillGradientItem(aXGradient));
1262 :
1263 0 : pPath->SetMergedItemSet(aGradAttr);
1264 :
1265 0 : InsertObj(pPath);
1266 : }
1267 : }
1268 :
1269 0 : aSkipComment = true;
1270 : }
1271 : }
1272 :
1273 0 : if(aSkipComment)
1274 : {
1275 0 : MetaAction* pSkipAct = pMtf->NextAction();
1276 :
1277 0 : while( pSkipAct
1278 0 : && ((pSkipAct->GetType() != META_COMMENT_ACTION )
1279 0 : || !(((MetaCommentAction*)pSkipAct)->GetComment().equalsIgnoreAsciiCase("XGRAD_SEQ_END"))))
1280 : {
1281 0 : pSkipAct = pMtf->NextAction();
1282 : }
1283 : }
1284 0 : }
1285 :
1286 0 : void ImpSdrGDIMetaFileImport::DoAction(MetaTextRectAction& rAct)
1287 : {
1288 0 : GDIMetaFile aTemp;
1289 :
1290 0 : maVD.AddTextRectActions(rAct.GetRect(), rAct.GetText(), rAct.GetStyle(), aTemp);
1291 0 : DoLoopActions(aTemp, 0, 0);
1292 0 : }
1293 :
1294 0 : void ImpSdrGDIMetaFileImport::DoAction(MetaBmpScalePartAction& rAct)
1295 : {
1296 0 : Rectangle aRect(rAct.GetDestPoint(), rAct.GetDestSize());
1297 0 : Bitmap aBitmap(rAct.GetBitmap());
1298 :
1299 0 : aRect.Right()++;
1300 0 : aRect.Bottom()++;
1301 0 : aBitmap.Crop(Rectangle(rAct.GetSrcPoint(), rAct.GetSrcSize()));
1302 0 : SdrGrafObj* pGraf = new SdrGrafObj(aBitmap, aRect);
1303 :
1304 : // This action is not creating line and fill, set directly, do not use SetAttributes(..)
1305 0 : pGraf->SetMergedItem(XLineStyleItem(XLINE_NONE));
1306 0 : pGraf->SetMergedItem(XFillStyleItem(XFILL_NONE));
1307 0 : InsertObj(pGraf);
1308 0 : }
1309 :
1310 0 : void ImpSdrGDIMetaFileImport::DoAction(MetaBmpExScalePartAction& rAct)
1311 : {
1312 0 : Rectangle aRect(rAct.GetDestPoint(),rAct.GetDestSize());
1313 0 : BitmapEx aBitmapEx(rAct.GetBitmapEx());
1314 :
1315 0 : aRect.Right()++;
1316 0 : aRect.Bottom()++;
1317 0 : aBitmapEx.Crop(Rectangle(rAct.GetSrcPoint(), rAct.GetSrcSize()));
1318 0 : SdrGrafObj* pGraf = new SdrGrafObj(aBitmapEx, aRect);
1319 :
1320 : // This action is not creating line and fill, set directly, do not use SetAttributes(..)
1321 0 : pGraf->SetMergedItem(XLineStyleItem(XLINE_NONE));
1322 0 : pGraf->SetMergedItem(XFillStyleItem(XFILL_NONE));
1323 0 : InsertObj(pGraf);
1324 0 : }
1325 :
1326 0 : void ImpSdrGDIMetaFileImport::DoAction(MetaMaskAction& rAct)
1327 : {
1328 0 : Rectangle aRect(rAct.GetPoint(), rAct.GetBitmap().GetSizePixel());
1329 0 : BitmapEx aBitmapEx(rAct.GetBitmap(), rAct.GetColor());
1330 :
1331 0 : aRect.Right()++; aRect.Bottom()++;
1332 0 : SdrGrafObj* pGraf = new SdrGrafObj(aBitmapEx, aRect);
1333 :
1334 : // This action is not creating line and fill, set directly, do not use SetAttributes(..)
1335 0 : pGraf->SetMergedItem(XLineStyleItem(XLINE_NONE));
1336 0 : pGraf->SetMergedItem(XFillStyleItem(XFILL_NONE));
1337 0 : InsertObj(pGraf);
1338 0 : }
1339 :
1340 0 : void ImpSdrGDIMetaFileImport::DoAction(MetaMaskScaleAction& rAct)
1341 : {
1342 0 : Rectangle aRect(rAct.GetPoint(), rAct.GetSize());
1343 0 : BitmapEx aBitmapEx(rAct.GetBitmap(), rAct.GetColor());
1344 :
1345 0 : aRect.Right()++; aRect.Bottom()++;
1346 0 : SdrGrafObj* pGraf = new SdrGrafObj(aBitmapEx, aRect);
1347 :
1348 : // This action is not creating line and fill, set directly, do not use SetAttributes(..)
1349 0 : pGraf->SetMergedItem(XLineStyleItem(XLINE_NONE));
1350 0 : pGraf->SetMergedItem(XFillStyleItem(XFILL_NONE));
1351 0 : InsertObj(pGraf);
1352 0 : }
1353 :
1354 0 : void ImpSdrGDIMetaFileImport::DoAction(MetaMaskScalePartAction& rAct)
1355 : {
1356 0 : Rectangle aRect(rAct.GetDestPoint(), rAct.GetDestSize());
1357 0 : BitmapEx aBitmapEx(rAct.GetBitmap(), rAct.GetColor());
1358 :
1359 0 : aRect.Right()++; aRect.Bottom()++;
1360 0 : aBitmapEx.Crop(Rectangle(rAct.GetSrcPoint(), rAct.GetSrcSize()));
1361 0 : SdrGrafObj* pGraf = new SdrGrafObj(aBitmapEx, aRect);
1362 :
1363 : // This action is not creating line and fill, set directly, do not use SetAttributes(..)
1364 0 : pGraf->SetMergedItem(XLineStyleItem(XLINE_NONE));
1365 0 : pGraf->SetMergedItem(XFillStyleItem(XFILL_NONE));
1366 0 : InsertObj(pGraf);
1367 0 : }
1368 :
1369 : namespace
1370 : {
1371 0 : XGradientStyle getXGradientStyleFromGradientStyle(const GradientStyle& rGradientStyle)
1372 : {
1373 0 : XGradientStyle aXGradientStyle(XGRAD_LINEAR);
1374 :
1375 0 : switch(rGradientStyle)
1376 : {
1377 0 : case GradientStyle_LINEAR: aXGradientStyle = XGRAD_LINEAR; break;
1378 0 : case GradientStyle_AXIAL: aXGradientStyle = XGRAD_AXIAL; break;
1379 0 : case GradientStyle_RADIAL: aXGradientStyle = XGRAD_RADIAL; break;
1380 0 : case GradientStyle_ELLIPTICAL: aXGradientStyle = XGRAD_ELLIPTICAL; break;
1381 0 : case GradientStyle_SQUARE: aXGradientStyle = XGRAD_SQUARE; break;
1382 0 : case GradientStyle_RECT: aXGradientStyle = XGRAD_RECT; break;
1383 :
1384 : // Needed due to GradientStyle_FORCE_EQUAL_SIZE; this again is needed
1385 : // to force the enum defines in VCL to a defined size for the compilers,
1386 : // so despite it is never used it cannot be removed (would break the
1387 : // API implementation probably).
1388 0 : case GradientStyle_FORCE_EQUAL_SIZE: break;
1389 : }
1390 :
1391 0 : return aXGradientStyle;
1392 : }
1393 : }
1394 :
1395 0 : void ImpSdrGDIMetaFileImport::DoAction(MetaGradientAction& rAct)
1396 : {
1397 0 : basegfx::B2DRange aRange(rAct.GetRect().Left(), rAct.GetRect().Top(), rAct.GetRect().Right(), rAct.GetRect().Bottom());
1398 :
1399 0 : if(!aRange.isEmpty())
1400 : {
1401 0 : const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(mfScaleX, mfScaleY, maOfs.X(), maOfs.Y()));
1402 0 : aRange.transform(aTransform);
1403 0 : const Gradient& rGradient = rAct.GetGradient();
1404 : SdrRectObj* pRect = new SdrRectObj(
1405 : Rectangle(
1406 0 : floor(aRange.getMinX()),
1407 0 : floor(aRange.getMinY()),
1408 0 : ceil(aRange.getMaxX()),
1409 0 : ceil(aRange.getMaxY())));
1410 0 : SfxItemSet aGradientAttr(mpModel->GetItemPool(), XATTR_FILLSTYLE, XATTR_FILLSTYLE, XATTR_FILLGRADIENT, XATTR_FILLGRADIENT, 0, 0);
1411 0 : const XGradientStyle aXGradientStyle(getXGradientStyleFromGradientStyle(rGradient.GetStyle()));
1412 : const XFillGradientItem aXFillGradientItem(
1413 : XGradient(
1414 0 : rGradient.GetStartColor(),
1415 0 : rGradient.GetEndColor(),
1416 : aXGradientStyle,
1417 0 : rGradient.GetAngle(),
1418 0 : rGradient.GetOfsX(),
1419 0 : rGradient.GetOfsY(),
1420 0 : rGradient.GetBorder(),
1421 0 : rGradient.GetStartIntensity(),
1422 0 : rGradient.GetEndIntensity(),
1423 0 : rGradient.GetSteps()));
1424 :
1425 0 : SetAttributes(pRect);
1426 0 : aGradientAttr.Put(XFillStyleItem(XFILL_HATCH));
1427 0 : aGradientAttr.Put(aXFillGradientItem);
1428 0 : pRect->SetMergedItemSet(aGradientAttr);
1429 :
1430 0 : InsertObj(pRect, false);
1431 : }
1432 0 : }
1433 :
1434 0 : void ImpSdrGDIMetaFileImport::DoAction(MetaWallpaperAction&)
1435 : {
1436 : OSL_ENSURE(false, "Tried to construct SdrObject from MetaWallpaperAction: not supported (!)");
1437 0 : }
1438 :
1439 0 : void ImpSdrGDIMetaFileImport::DoAction(MetaTransparentAction& rAct)
1440 : {
1441 0 : basegfx::B2DPolyPolygon aSource(rAct.GetPolyPolygon().getB2DPolyPolygon());
1442 :
1443 0 : if(aSource.count())
1444 : {
1445 0 : const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(mfScaleX, mfScaleY, maOfs.X(), maOfs.Y()));
1446 0 : aSource.transform(aTransform);
1447 0 : aSource.setClosed(true);
1448 :
1449 0 : SdrPathObj* pPath = new SdrPathObj(OBJ_POLY, aSource);
1450 0 : SetAttributes(pPath);
1451 0 : pPath->SetMergedItem(XFillTransparenceItem(rAct.GetTransparence()));
1452 0 : InsertObj(pPath, false);
1453 0 : }
1454 0 : }
1455 :
1456 0 : void ImpSdrGDIMetaFileImport::DoAction(MetaEPSAction&)
1457 : {
1458 : OSL_ENSURE(false, "Tried to construct SdrObject from MetaEPSAction: not supported (!)");
1459 0 : }
1460 :
1461 0 : void ImpSdrGDIMetaFileImport::DoAction(MetaTextLineAction&)
1462 : {
1463 : OSL_ENSURE(false, "Tried to construct SdrObject from MetaTextLineAction: not supported (!)");
1464 0 : }
1465 :
1466 0 : void ImpSdrGDIMetaFileImport::DoAction(MetaGradientExAction& rAct)
1467 : {
1468 0 : basegfx::B2DPolyPolygon aSource(rAct.GetPolyPolygon().getB2DPolyPolygon());
1469 :
1470 0 : if(aSource.count())
1471 : {
1472 0 : const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(mfScaleX, mfScaleY, maOfs.X(), maOfs.Y()));
1473 0 : aSource.transform(aTransform);
1474 :
1475 0 : if(!mbLastObjWasPolyWithoutLine || !CheckLastPolyLineAndFillMerge(aSource))
1476 : {
1477 0 : const Gradient& rGradient = rAct.GetGradient();
1478 0 : SdrPathObj* pPath = new SdrPathObj(OBJ_POLY, aSource);
1479 0 : SfxItemSet aGradientAttr(mpModel->GetItemPool(), XATTR_FILLSTYLE, XATTR_FILLSTYLE, XATTR_FILLGRADIENT, XATTR_FILLGRADIENT, 0, 0);
1480 0 : const XGradientStyle aXGradientStyle(getXGradientStyleFromGradientStyle(rGradient.GetStyle()));
1481 : const XFillGradientItem aXFillGradientItem(
1482 : XGradient(
1483 0 : rGradient.GetStartColor(),
1484 0 : rGradient.GetEndColor(),
1485 : aXGradientStyle,
1486 0 : rGradient.GetAngle(),
1487 0 : rGradient.GetOfsX(),
1488 0 : rGradient.GetOfsY(),
1489 0 : rGradient.GetBorder(),
1490 0 : rGradient.GetStartIntensity(),
1491 0 : rGradient.GetEndIntensity(),
1492 0 : rGradient.GetSteps()));
1493 :
1494 0 : SetAttributes(pPath);
1495 0 : aGradientAttr.Put(XFillStyleItem(XFILL_HATCH));
1496 0 : aGradientAttr.Put(aXFillGradientItem);
1497 0 : pPath->SetMergedItemSet(aGradientAttr);
1498 :
1499 0 : InsertObj(pPath, false);
1500 0 : }
1501 0 : }
1502 0 : }
1503 :
1504 0 : void ImpSdrGDIMetaFileImport::DoAction(MetaFloatTransparentAction& rAct)
1505 : {
1506 0 : const GDIMetaFile& rMtf = rAct.GetGDIMetaFile();
1507 :
1508 0 : if(rMtf.GetActionSize())
1509 : {
1510 0 : const Rectangle aRect(rAct.GetPoint(),rAct.GetSize());
1511 :
1512 : // convert metafile sub-content to BitmapEx
1513 : BitmapEx aBitmapEx(
1514 : convertMetafileToBitmapEx(
1515 : rMtf,
1516 : basegfx::B2DRange(
1517 0 : aRect.Left(), aRect.Top(),
1518 0 : aRect.Right(), aRect.Bottom()),
1519 0 : 125000));
1520 :
1521 : // handle colors
1522 0 : const Gradient& rGradient = rAct.GetGradient();
1523 0 : basegfx::BColor aStart(rGradient.GetStartColor().getBColor());
1524 0 : basegfx::BColor aEnd(rGradient.GetEndColor().getBColor());
1525 :
1526 0 : if(100 != rGradient.GetStartIntensity())
1527 : {
1528 0 : aStart *= (double)rGradient.GetStartIntensity() / 100.0;
1529 : }
1530 :
1531 0 : if(100 != rGradient.GetEndIntensity())
1532 : {
1533 0 : aEnd *= (double)rGradient.GetEndIntensity() / 100.0;
1534 : }
1535 :
1536 0 : const bool bEqualColors(aStart == aEnd);
1537 0 : const bool bNoSteps(1 == rGradient.GetSteps());
1538 0 : bool bCreateObject(true);
1539 0 : bool bHasNewMask(false);
1540 0 : AlphaMask aNewMask;
1541 0 : double fTransparence(0.0);
1542 0 : bool bFixedTransparence(false);
1543 :
1544 0 : if(bEqualColors || bNoSteps)
1545 : {
1546 : // single transparence
1547 0 : const basegfx::BColor aMedium(basegfx::average(aStart, aEnd));
1548 0 : fTransparence = aMedium.luminance();
1549 :
1550 0 : if(basegfx::fTools::lessOrEqual(fTransparence, 0.0))
1551 : {
1552 : // no transparence needed, all done
1553 : }
1554 0 : else if(basegfx::fTools::moreOrEqual(fTransparence, 1.0))
1555 : {
1556 : // all transparent, no object
1557 0 : bCreateObject = false;
1558 : }
1559 : else
1560 : {
1561 : // 0.0 < transparence < 1.0, apply fixed transparence
1562 0 : bFixedTransparence = true;
1563 0 : }
1564 : }
1565 : else
1566 : {
1567 : // gradient transparence
1568 0 : VirtualDevice aVDev;
1569 :
1570 0 : aVDev.SetOutputSizePixel(aBitmapEx.GetBitmap().GetSizePixel());
1571 0 : aVDev.DrawGradient(Rectangle(Point(0, 0), aVDev.GetOutputSizePixel()), rGradient);
1572 :
1573 0 : aNewMask = AlphaMask(aVDev.GetBitmap(Point(0, 0), aVDev.GetOutputSizePixel()));
1574 0 : bHasNewMask = true;
1575 : }
1576 :
1577 0 : if(bCreateObject)
1578 : {
1579 0 : if(bHasNewMask || bFixedTransparence)
1580 : {
1581 0 : if(!aBitmapEx.IsAlpha() && !aBitmapEx.IsTransparent())
1582 : {
1583 : // no transparence yet, apply new one
1584 0 : if(bFixedTransparence)
1585 : {
1586 0 : sal_uInt8 aAlpha(basegfx::fround(fTransparence * 255.0));
1587 :
1588 0 : aNewMask = AlphaMask(aBitmapEx.GetBitmap().GetSizePixel(), &aAlpha);
1589 : }
1590 :
1591 0 : aBitmapEx = BitmapEx(aBitmapEx.GetBitmap(), aNewMask);
1592 : }
1593 : else
1594 : {
1595 : // mix existing and new alpha mask
1596 0 : AlphaMask aOldMask;
1597 :
1598 0 : if(aBitmapEx.IsAlpha())
1599 : {
1600 0 : aOldMask = aBitmapEx.GetAlpha();
1601 : }
1602 0 : else if(TRANSPARENT_BITMAP == aBitmapEx.GetTransparentType())
1603 : {
1604 0 : aOldMask = aBitmapEx.GetMask();
1605 : }
1606 0 : else if(TRANSPARENT_COLOR == aBitmapEx.GetTransparentType())
1607 : {
1608 0 : aOldMask = aBitmapEx.GetBitmap().CreateMask(aBitmapEx.GetTransparentColor());
1609 : }
1610 :
1611 0 : BitmapWriteAccess* pOld = aOldMask.AcquireWriteAccess();
1612 :
1613 0 : if(pOld)
1614 : {
1615 0 : const double fFactor(1.0 / 255.0);
1616 :
1617 0 : if(bFixedTransparence)
1618 : {
1619 0 : const double fOpNew(1.0 - fTransparence);
1620 :
1621 0 : for(int y(0); y < pOld->Height(); y++)
1622 : {
1623 0 : for(int x(0); x < pOld->Width(); x++)
1624 : {
1625 0 : const double fOpOld(1.0 - (pOld->GetPixel(y, x).GetIndex() * fFactor));
1626 0 : const sal_uInt8 aCol(basegfx::fround((1.0 - (fOpOld * fOpNew)) * 255.0));
1627 :
1628 0 : pOld->SetPixel(y, x, BitmapColor(aCol));
1629 : }
1630 : }
1631 : }
1632 : else
1633 : {
1634 0 : BitmapReadAccess* pNew = aNewMask.AcquireReadAccess();
1635 :
1636 0 : if(pNew)
1637 : {
1638 0 : if(pOld->Width() == pNew->Width() && pOld->Height() == pNew->Height())
1639 : {
1640 0 : for(int y(0); y < pOld->Height(); y++)
1641 : {
1642 0 : for(int x(0); x < pOld->Width(); x++)
1643 : {
1644 0 : const double fOpOld(1.0 - (pOld->GetPixel(y, x).GetIndex() * fFactor));
1645 0 : const double fOpNew(1.0 - (pNew->GetPixel(y, x).GetIndex() * fFactor));
1646 0 : const sal_uInt8 aCol(basegfx::fround((1.0 - (fOpOld * fOpNew)) * 255.0));
1647 :
1648 0 : pOld->SetPixel(y, x, BitmapColor(aCol));
1649 : }
1650 : }
1651 : }
1652 : else
1653 : {
1654 : OSL_ENSURE(false, "Alpha masks have different sizes (!)");
1655 : }
1656 :
1657 0 : aNewMask.ReleaseAccess(pNew);
1658 : }
1659 : else
1660 : {
1661 : OSL_ENSURE(false, "Got no access to new alpha mask (!)");
1662 : }
1663 : }
1664 :
1665 0 : aOldMask.ReleaseAccess(pOld);
1666 : }
1667 : else
1668 : {
1669 : OSL_ENSURE(false, "Got no access to old alpha mask (!)");
1670 : }
1671 :
1672 : // apply combined bitmap as mask
1673 0 : aBitmapEx = BitmapEx(aBitmapEx.GetBitmap(), aOldMask);
1674 : }
1675 : }
1676 :
1677 : // create and add object
1678 0 : SdrGrafObj* pGraf = new SdrGrafObj(aBitmapEx, aRect);
1679 :
1680 : // for MetaFloatTransparentAction, do not use SetAttributes(...)
1681 : // since these metafile content is not used to draw line/fill
1682 : // dependent of these setting at the device content
1683 0 : pGraf->SetMergedItem(XLineStyleItem(XLINE_NONE));
1684 0 : pGraf->SetMergedItem(XFillStyleItem(XFILL_NONE));
1685 0 : InsertObj(pGraf);
1686 0 : }
1687 : }
1688 0 : }
1689 :
1690 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|