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