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