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