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