xref: /aoo41x/main/svx/source/svdraw/svdfmtf.cxx (revision 70d3707a)
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 
74 ////////////////////////////////////////////////////////////////////////////////////////////////////
75 
76 ImpSdrGDIMetaFileImport::ImpSdrGDIMetaFileImport(SdrModel& rModel):
77 	nMapScalingOfs(0),
78 	pLineAttr(NULL),pFillAttr(NULL),pTextAttr(NULL),
79 	pPage(NULL),pModel(NULL),nLayer(0),
80 	nLineWidth(0),
81 	maLineJoin(basegfx::B2DLINEJOIN_NONE),
82 	maLineCap(com::sun::star::drawing::LineCap_BUTT),
83 	maDash(XDASH_RECT, 0, 0, 0, 0, 0),
84 	bFntDirty(sal_True),
85 	bLastObjWasPolyWithoutLine(sal_False),
86     bNoLine(sal_False),
87     bNoFill(sal_False),
88     bLastObjWasLine(sal_False),
89     maClip()
90 {
91 	aVD.EnableOutput(sal_False);
92 
93     // #i111954# init to no fill and no line initially
94     aVD.SetLineColor();
95     aVD.SetFillColor();
96 
97 	aOldLineColor.SetRed( aVD.GetLineColor().GetRed() + 1 ); // invalidate old line color
98 	pLineAttr=new SfxItemSet(rModel.GetItemPool(),XATTR_LINE_FIRST,XATTR_LINE_LAST);
99 	pFillAttr=new SfxItemSet(rModel.GetItemPool(),XATTR_FILL_FIRST,XATTR_FILL_LAST);
100 	pTextAttr=new SfxItemSet(rModel.GetItemPool(),EE_ITEMS_START,EE_ITEMS_END);
101 	pModel=&rModel;
102     checkClip();
103 }
104 
105 ImpSdrGDIMetaFileImport::~ImpSdrGDIMetaFileImport()
106 {
107 	delete pLineAttr;
108 	delete pFillAttr;
109 	delete pTextAttr;
110 }
111 
112 sal_uIntPtr ImpSdrGDIMetaFileImport::DoImport(const GDIMetaFile& rMtf,
113 	SdrObjList& rOL,
114 	sal_uIntPtr nInsPos,
115 	SvdProgressInfo *pProgrInfo)
116 {
117 	pPage = rOL.GetPage();
118 	GDIMetaFile* pTmpMtf=NULL;
119 	GDIMetaFile* pMtf = (GDIMetaFile*) &rMtf;
120 	sal_uIntPtr nActionAnz=pMtf->GetActionCount();
121 	sal_Bool bError = sal_False;
122 
123 
124 	// setup some global scale parameter
125 	// fScaleX, fScaleY, aScaleX, aScaleY, bMov, bSize
126     fScaleX = fScaleY = 1.0;
127 	Size  aMtfSize( pMtf->GetPrefSize() );
128 	if ( aMtfSize.Width() & aMtfSize.Height() && ( aScaleRect.IsEmpty() == sal_False ) )
129     {
130 		aOfs = aScaleRect.TopLeft();
131         if ( aMtfSize.Width() != ( aScaleRect.GetWidth() - 1 ) )
132             fScaleX = (double)( aScaleRect.GetWidth() - 1 ) / (double)aMtfSize.Width();
133         if ( aMtfSize.Height() != ( aScaleRect.GetHeight() - 1 ) )
134             fScaleY = (double)( aScaleRect.GetHeight() - 1 ) / (double)aMtfSize.Height();
135     }
136 
137 	bMov = aOfs.X()!=0 || aOfs.Y()!=0;
138     bSize = sal_False;
139 
140 	aScaleX = Fraction( 1, 1 );
141 	aScaleY = Fraction( 1, 1 );
142     if ( aMtfSize.Width() != ( aScaleRect.GetWidth() - 1 ) )
143     {
144         aScaleX = Fraction( aScaleRect.GetWidth() - 1, aMtfSize.Width() );
145         bSize = sal_True;
146     }
147     if ( aMtfSize.Height() != ( aScaleRect.GetHeight() - 1 ) )
148     {
149         aScaleY = Fraction( aScaleRect.GetHeight() - 1, aMtfSize.Height() );
150         bSize = sal_True;
151     }
152 
153 	if(65000 < nActionAnz)
154 	{
155 		nActionAnz = 65000;
156 		bError = sal_True;
157 	}
158 
159 	if(pProgrInfo)
160 		pProgrInfo->SetActionCount(nActionAnz);
161 
162 	sal_uIntPtr nActionsToReport = 0;
163 
164 	for( MetaAction* pAct = pMtf->FirstAction(); pAct; pAct = pMtf->NextAction() )
165 	{
166 		switch (pAct->GetType())
167 		{
168 			case META_PIXEL_ACTION          : DoAction((MetaPixelAction          &)*pAct); break;
169 			case META_POINT_ACTION          : DoAction((MetaPointAction          &)*pAct); break;
170 			case META_LINE_ACTION           : DoAction((MetaLineAction           &)*pAct); break;
171 			case META_RECT_ACTION           : DoAction((MetaRectAction           &)*pAct); break;
172 			case META_ROUNDRECT_ACTION      : DoAction((MetaRoundRectAction      &)*pAct); break;
173 			case META_ELLIPSE_ACTION        : DoAction((MetaEllipseAction        &)*pAct); break;
174 			case META_ARC_ACTION            : DoAction((MetaArcAction            &)*pAct); break;
175 			case META_PIE_ACTION            : DoAction((MetaPieAction            &)*pAct); break;
176 			case META_CHORD_ACTION          : DoAction((MetaChordAction          &)*pAct); break;
177 			case META_POLYLINE_ACTION	    : DoAction((MetaPolyLineAction		 &)*pAct); break;
178 			case META_POLYGON_ACTION        : DoAction((MetaPolygonAction        &)*pAct); break;
179 			case META_POLYPOLYGON_ACTION    : DoAction((MetaPolyPolygonAction    &)*pAct); break;
180 			case META_TEXT_ACTION           : DoAction((MetaTextAction           &)*pAct); break;
181 			case META_TEXTARRAY_ACTION      : DoAction((MetaTextArrayAction      &)*pAct); break;
182 			case META_STRETCHTEXT_ACTION    : DoAction((MetaStretchTextAction    &)*pAct); break;
183 			case META_BMP_ACTION			: DoAction((MetaBmpAction			 &)*pAct); break;
184 			case META_BMPSCALE_ACTION		: DoAction((MetaBmpScaleAction		 &)*pAct); break;
185 			case META_BMPEX_ACTION			: DoAction((MetaBmpExAction			 &)*pAct); break;
186 			case META_BMPEXSCALE_ACTION		: DoAction((MetaBmpExScaleAction	 &)*pAct); break;
187 			case META_LINECOLOR_ACTION      : DoAction((MetaLineColorAction      &)*pAct); break;
188 			case META_FILLCOLOR_ACTION      : DoAction((MetaFillColorAction      &)*pAct); break;
189 			case META_TEXTCOLOR_ACTION      : DoAction((MetaTextColorAction      &)*pAct); break;
190 			case META_TEXTFILLCOLOR_ACTION  : DoAction((MetaTextFillColorAction  &)*pAct); break;
191 			case META_FONT_ACTION           : DoAction((MetaFontAction           &)*pAct); break;
192 			case META_TEXTALIGN_ACTION		: DoAction((MetaTextAlignAction		 &)*pAct); break;
193 			case META_MAPMODE_ACTION        : DoAction((MetaMapModeAction        &)*pAct); break;
194 			case META_CLIPREGION_ACTION     : DoAction((MetaClipRegionAction     &)*pAct); break;
195 			case META_MOVECLIPREGION_ACTION : DoAction((MetaMoveClipRegionAction &)*pAct); break;
196 			case META_ISECTRECTCLIPREGION_ACTION: DoAction((MetaISectRectClipRegionAction&)*pAct); break;
197 			case META_ISECTREGIONCLIPREGION_ACTION: DoAction((MetaISectRegionClipRegionAction&)*pAct); break;
198 			case META_RASTEROP_ACTION       : DoAction((MetaRasterOpAction       &)*pAct); break;
199 			case META_PUSH_ACTION           : DoAction((MetaPushAction           &)*pAct); break;
200 			case META_POP_ACTION            : DoAction((MetaPopAction            &)*pAct); break;
201 			case META_HATCH_ACTION			: DoAction((MetaHatchAction          &)*pAct); break;
202 			case META_COMMENT_ACTION		: DoAction((MetaCommentAction        &)*pAct, pMtf); break;
203 		}
204 
205 		if(pProgrInfo != NULL)
206 		{
207 		  nActionsToReport++;
208 		  if(nActionsToReport >= 16) // Alle 16 Action updaten
209 		  {
210 			if(!pProgrInfo->ReportActions(nActionsToReport))
211 			  break;
212 			nActionsToReport = 0;
213 		  }
214 		}
215 	}
216 
217 	if(pProgrInfo != NULL)
218 	{
219 		pProgrInfo->ReportActions(nActionsToReport);
220 		nActionsToReport = 0;
221 	}
222 
223 	// MapMode-Scaling  vornehmen
224 	MapScaling();
225 	// Objekte in vorgegebenes Rechteck hineinskalieren
226 	sal_uIntPtr nAnz=aTmpList.GetObjCount();
227 
228 	// Beim berechnen der Fortschrittsanzeige wird GetActionCount()*3 benutzt.
229 	// Da in aTmpList allerdings weniger eintraege als GetActionCount()
230 	// existieren koennen, muessen hier die zuviel vermuteten Actionen wieder
231 	// hinzugefuegt werden.
232 	nActionsToReport = (pMtf->GetActionCount() - nAnz)*2;
233 
234 
235 	// Alle noch nicht gemeldeten Rescales melden
236 	if(pProgrInfo)
237 	{
238 		pProgrInfo->ReportRescales(nActionsToReport);
239 		pProgrInfo->SetInsertCount(nAnz);
240 	}
241 	nActionsToReport = 0;
242 
243 	// alle in aTmpList zwischengespeicherten Objekte nun in rOL ab der Position nInsPos einfuegen
244 	if (nInsPos>rOL.GetObjCount()) nInsPos=rOL.GetObjCount();
245 	SdrInsertReason aReason(SDRREASON_VIEWCALL);
246 	for (sal_uIntPtr i=0; i<nAnz; i++)
247 	{
248 		 SdrObject* pObj=aTmpList.GetObj(i);
249 		 rOL.NbcInsertObject(pObj,nInsPos,&aReason);
250 		 nInsPos++;
251 
252 		if(pProgrInfo != NULL)
253 		{
254 			nActionsToReport++;
255 			if(nActionsToReport >= 32) // Alle 32 Action updaten
256 			{
257 				pProgrInfo->ReportInserts(nActionsToReport);
258 				nActionsToReport = 0;
259 			}
260 		}
261 	}
262 	if (pTmpMtf!=NULL) delete pTmpMtf;
263 
264 	// ein letztesmal alle verbliebennen Inserts reporten
265 	if(pProgrInfo != NULL)
266 	{
267 		pProgrInfo->ReportInserts(nActionsToReport);
268 		if(bError)
269 			pProgrInfo->ReportError();
270 	}
271 
272 	return aTmpList.GetObjCount();
273 }
274 
275 void ImpSdrGDIMetaFileImport::SetAttributes(SdrObject* pObj, FASTBOOL bForceTextAttr)
276 {
277 	bNoLine = sal_False; bNoFill = sal_False;
278 	FASTBOOL bLine=sal_True && !bForceTextAttr;
279 	FASTBOOL bFill=pObj==NULL || ( pObj->IsClosedObj() && !bForceTextAttr );
280 	FASTBOOL bText=bForceTextAttr || (pObj!=NULL && pObj->GetOutlinerParaObject()!=NULL);
281 
282 	if ( bLine )
283 	{
284 		if ( nLineWidth )
285 			pLineAttr->Put( XLineWidthItem( nLineWidth ) );
286         else
287 			pLineAttr->Put( XLineWidthItem( 0 ) );
288 
289 		aOldLineColor = aVD.GetLineColor();
290 		if( aVD.IsLineColor() )
291 		{
292 			pLineAttr->Put(XLineStyleItem(XLINE_SOLID));
293 			pLineAttr->Put(XLineColorItem(String(), aVD.GetLineColor()));
294 		}
295 		else
296 			pLineAttr->Put(XLineStyleItem(XLINE_NONE));
297 
298 		switch(maLineJoin)
299 		{
300 			default : // basegfx::B2DLINEJOIN_NONE
301 				pLineAttr->Put(XLineJointItem(XLINEJOINT_NONE));
302 				break;
303 			case basegfx::B2DLINEJOIN_MIDDLE:
304 				pLineAttr->Put(XLineJointItem(XLINEJOINT_MIDDLE));
305 				break;
306 			case basegfx::B2DLINEJOIN_BEVEL:
307 				pLineAttr->Put(XLineJointItem(XLINEJOINT_BEVEL));
308 				break;
309 			case basegfx::B2DLINEJOIN_MITER:
310 				pLineAttr->Put(XLineJointItem(XLINEJOINT_MITER));
311 				break;
312 			case basegfx::B2DLINEJOIN_ROUND:
313 				pLineAttr->Put(XLineJointItem(XLINEJOINT_ROUND));
314 				break;
315 		}
316 
317         // Add LineCap support
318         pLineAttr->Put(XLineCapItem(maLineCap));
319 
320 		if(((maDash.GetDots() && maDash.GetDotLen()) || (maDash.GetDashes() && maDash.GetDashLen())) && maDash.GetDistance())
321 		{
322 			pLineAttr->Put(XLineDashItem(String(), maDash));
323 		}
324         else
325         {
326 			pLineAttr->Put(XLineDashItem(String(), XDash(XDASH_RECT)));
327         }
328 	}
329 	else
330 		bNoLine = sal_True;
331 
332 	if ( bFill )
333 	{
334 		if( aVD.IsFillColor() )
335 		{
336 			pFillAttr->Put(XFillStyleItem(XFILL_SOLID));
337 			pFillAttr->Put(XFillColorItem(String(), aVD.GetFillColor()));
338 		}
339 		else
340 			pFillAttr->Put(XFillStyleItem(XFILL_NONE));
341 	}
342 	else
343 		bNoFill = sal_True;
344 
345 	if ( bText && bFntDirty )
346 	{
347 		Font aFnt(aVD.GetFont());
348 		pTextAttr->Put( SvxFontItem( aFnt.GetFamily(), aFnt.GetName(), aFnt.GetStyleName(),
349 							aFnt.GetPitch(), aFnt.GetCharSet(), EE_CHAR_FONTINFO ) );
350 		pTextAttr->Put( SvxFontItem( aFnt.GetFamily(), aFnt.GetName(), aFnt.GetStyleName(),
351 							aFnt.GetPitch(), aFnt.GetCharSet(), EE_CHAR_FONTINFO_CJK ) );
352 		pTextAttr->Put( SvxFontItem( aFnt.GetFamily(), aFnt.GetName(), aFnt.GetStyleName(),
353 							aFnt.GetPitch(), aFnt.GetCharSet(), EE_CHAR_FONTINFO_CTL ) );
354         pTextAttr->Put(SvxPostureItem(aFnt.GetItalic(), EE_CHAR_ITALIC));
355         pTextAttr->Put(SvxWeightItem(aFnt.GetWeight(), EE_CHAR_WEIGHT));
356 		sal_uInt32 nHeight = FRound(aFnt.GetSize().Height() * fScaleY);
357 		pTextAttr->Put( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT ) );
358 		pTextAttr->Put( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT_CJK ) );
359 		pTextAttr->Put( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT_CTL ) );
360         pTextAttr->Put(SvxCharScaleWidthItem(100, EE_CHAR_FONTWIDTH));
361         pTextAttr->Put(SvxUnderlineItem(aFnt.GetUnderline(), EE_CHAR_UNDERLINE));
362         pTextAttr->Put(SvxOverlineItem(aFnt.GetOverline(), EE_CHAR_OVERLINE));
363         pTextAttr->Put(SvxCrossedOutItem(aFnt.GetStrikeout(), EE_CHAR_STRIKEOUT));
364         pTextAttr->Put(SvxShadowedItem(aFnt.IsShadow(), EE_CHAR_SHADOW));
365 
366         // #i118485# Setting this item leads to problems (written #i118498# for this)
367         // pTextAttr->Put(SvxAutoKernItem(aFnt.IsKerning(), EE_CHAR_KERNING));
368 
369         pTextAttr->Put(SvxWordLineModeItem(aFnt.IsWordLineMode(), EE_CHAR_WLM));
370         pTextAttr->Put(SvxContourItem(aFnt.IsOutline(), EE_CHAR_OUTLINE));
371         pTextAttr->Put(SvxColorItem(aVD.GetTextColor(), EE_CHAR_COLOR));
372 		//... svxfont textitem svditext
373 		bFntDirty=sal_False;
374 	}
375 	if (pObj!=NULL)
376 	{
377 		pObj->SetLayer(nLayer);
378 		if (bLine) pObj->SetMergedItemSet(*pLineAttr);
379 		if (bFill) pObj->SetMergedItemSet(*pFillAttr);
380 		if (bText)
381 		{
382 			pObj->SetMergedItemSet(*pTextAttr);
383 			pObj->SetMergedItem( SdrTextHorzAdjustItem( SDRTEXTHORZADJUST_LEFT ) );
384 		}
385 	}
386 }
387 
388 void ImpSdrGDIMetaFileImport::InsertObj(SdrObject* pObj, sal_Bool bScale)
389 {
390     if ( bScale && !aScaleRect.IsEmpty() )
391     {
392 		if ( bSize )
393 			pObj->NbcResize( Point(), aScaleX, aScaleY );
394 		if ( bMov )
395 			pObj->NbcMove( Size( aOfs.X(), aOfs.Y() ) );
396 	}
397 
398     if(isClip())
399     {
400         const basegfx::B2DPolyPolygon aPoly(pObj->TakeXorPoly());
401         const basegfx::B2DRange aOldRange(aPoly.getB2DRange());
402     	const SdrLayerID aOldLayer(pObj->GetLayer());
403     	const SfxItemSet aOldItemSet(pObj->GetMergedItemSet());
404         const SdrGrafObj* pSdrGrafObj = dynamic_cast< SdrGrafObj* >(pObj);
405         BitmapEx aBitmapEx;
406 
407         if(pSdrGrafObj)
408         {
409         	aBitmapEx = pSdrGrafObj->GetGraphic().GetBitmapEx();
410         }
411 
412         SdrObject::Free(pObj);
413 
414         if(!aOldRange.isEmpty())
415         {
416             // clip against ClipRegion
417             const basegfx::B2DPolyPolygon aNewPoly(
418                 basegfx::tools::clipPolyPolygonOnPolyPolygon(
419                     aPoly,
420                     maClip,
421                     true,
422                     aPoly.isClosed() ? false : true));
423             const basegfx::B2DRange aNewRange(aNewPoly.getB2DRange());
424 
425             if(!aNewRange.isEmpty())
426             {
427                 pObj = new SdrPathObj(
428                     aNewPoly.isClosed() ? OBJ_POLY : OBJ_PLIN,
429                     aNewPoly);
430 
431 		        pObj->SetLayer(aOldLayer);
432 		        pObj->SetMergedItemSet(aOldItemSet);
433 
434                 if(!!aBitmapEx)
435                 {
436                     // aNewRange is inside of aOldRange and defines which part of aBitmapEx is used
437                     const double fScaleX(aBitmapEx.GetSizePixel().Width() / (aOldRange.getWidth() ? aOldRange.getWidth() : 1.0));
438                     const double fScaleY(aBitmapEx.GetSizePixel().Height() / (aOldRange.getHeight() ? aOldRange.getHeight() : 1.0));
439                     basegfx::B2DRange aPixel(aNewRange);
440                     basegfx::B2DHomMatrix aTrans;
441 
442                     aTrans.translate(-aOldRange.getMinX(), -aOldRange.getMinY());
443                     aTrans.scale(fScaleX, fScaleY);
444                     aPixel.transform(aTrans);
445 
446                     const BitmapEx aClippedBitmap(
447                         aBitmapEx,
448                         Point(floor(std::max(0.0, aPixel.getMinX())), floor(std::max(0.0, aPixel.getMinY()))),
449                         Size(ceil(aPixel.getWidth()), ceil(aPixel.getHeight())));
450 
451                     pObj->SetMergedItem(XFillStyleItem(XFILL_BITMAP));
452                     pObj->SetMergedItem(XFillBitmapItem(String(), Graphic(aClippedBitmap)));
453                 }
454             }
455         }
456     }
457 
458     if(pObj)
459     {
460         // #i111954# check object for visibility
461         // used are SdrPathObj, SdrRectObj, SdrCircObj, SdrGrafObj
462         bool bVisible(false);
463 
464         if(pObj->HasLineStyle())
465         {
466             bVisible = true;
467         }
468 
469         if(!bVisible && pObj->HasFillStyle())
470         {
471             bVisible = true;
472         }
473 
474         if(!bVisible)
475         {
476             SdrTextObj* pTextObj = dynamic_cast< SdrTextObj* >(pObj);
477 
478             if(pTextObj && pTextObj->HasText())
479             {
480                 bVisible = true;
481             }
482         }
483 
484         if(!bVisible)
485         {
486             SdrGrafObj* pGrafObj = dynamic_cast< SdrGrafObj* >(pObj);
487 
488             if(pGrafObj)
489             {
490                 // this may be refined to check if the graphic really is visible. It
491                 // is here to ensure that graphic objects without fill, line and text
492                 // get created
493                 bVisible = true;
494             }
495         }
496 
497         if(!bVisible)
498         {
499             SdrObject::Free(pObj);
500         }
501         else
502         {
503 	        aTmpList.InsertObject( pObj );
504 	        if ( HAS_BASE( SdrPathObj, pObj ) )
505 	        {
506 		        FASTBOOL bClosed=pObj->IsClosedObj();
507 		        bLastObjWasPolyWithoutLine=bNoLine && bClosed;
508 		        bLastObjWasLine=!bClosed;
509 	        }
510 	        else
511 	        {
512 		        bLastObjWasPolyWithoutLine = sal_False;
513 		        bLastObjWasLine = sal_False;
514 	        }
515         }
516     }
517 }
518 
519 /**************************************************************************************************/
520 
521 void ImpSdrGDIMetaFileImport::DoAction(MetaPixelAction& /*rAct*/)
522 {
523 }
524 
525 void ImpSdrGDIMetaFileImport::DoAction(MetaPointAction& /*rAct*/)
526 {
527 }
528 
529 void ImpSdrGDIMetaFileImport::DoAction(MetaLineAction& rAct)
530 {
531 	// #i73407# reformulation to use new B2DPolygon classes
532 	const basegfx::B2DPoint aStart(rAct.GetStartPoint().X(), rAct.GetStartPoint().Y());
533 	const basegfx::B2DPoint aEnd(rAct.GetEndPoint().X(), rAct.GetEndPoint().Y());
534 
535 	if(!aStart.equal(aEnd))
536 	{
537 		basegfx::B2DPolygon aLine;
538 		const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(fScaleX, fScaleY, aOfs.X(), aOfs.Y()));
539 
540 		aLine.append(aStart);
541 		aLine.append(aEnd);
542 		aLine.transform(aTransform);
543 
544 		const LineInfo& rLineInfo = rAct.GetLineInfo();
545 		const sal_Int32 nNewLineWidth(rLineInfo.GetWidth());
546 		bool bCreateLineObject(true);
547 
548 		if(bLastObjWasLine && (nNewLineWidth == nLineWidth) && CheckLastLineMerge(aLine))
549 		{
550 			bCreateLineObject = false;
551 		}
552 
553 		if(bCreateLineObject)
554 		{
555 			SdrPathObj* pPath = new SdrPathObj(OBJ_LINE, basegfx::B2DPolyPolygon(aLine));
556 			nLineWidth = nNewLineWidth;
557 			maLineJoin = rLineInfo.GetLineJoin();
558             maLineCap = rLineInfo.GetLineCap();
559 			maDash = XDash(XDASH_RECT,
560 				rLineInfo.GetDotCount(), rLineInfo.GetDotLen(),
561 				rLineInfo.GetDashCount(), rLineInfo.GetDashLen(),
562 				rLineInfo.GetDistance());
563 			SetAttributes(pPath);
564 			nLineWidth = 0;
565 			maLineJoin = basegfx::B2DLINEJOIN_NONE;
566 			maDash = XDash();
567 			InsertObj(pPath, false);
568 		}
569 	}
570 }
571 
572 void ImpSdrGDIMetaFileImport::DoAction(MetaRectAction& rAct)
573 {
574     SdrRectObj* pRect=new SdrRectObj(rAct.GetRect());
575 	SetAttributes(pRect);
576 	InsertObj(pRect);
577 }
578 
579 void ImpSdrGDIMetaFileImport::DoAction(MetaRoundRectAction& rAct)
580 {
581     SdrRectObj* pRect=new SdrRectObj(rAct.GetRect());
582 	SetAttributes(pRect);
583 	long nRad=(rAct.GetHorzRound()+rAct.GetVertRound())/2;
584 	if (nRad!=0) {
585 		SfxItemSet aSet(*pLineAttr->GetPool(),SDRATTR_ECKENRADIUS,SDRATTR_ECKENRADIUS);
586 		aSet.Put(SdrEckenradiusItem(nRad));
587 		pRect->SetMergedItemSet(aSet);
588 	}
589 	InsertObj(pRect);
590 }
591 
592 /**************************************************************************************************/
593 
594 void ImpSdrGDIMetaFileImport::DoAction(MetaEllipseAction& rAct)
595 {
596     SdrCircObj* pCirc=new SdrCircObj(OBJ_CIRC,rAct.GetRect());
597 	SetAttributes(pCirc);
598 	InsertObj(pCirc);
599 }
600 
601 void ImpSdrGDIMetaFileImport::DoAction(MetaArcAction& rAct)
602 {
603     Point aCenter(rAct.GetRect().Center());
604 	long nStart=GetAngle(rAct.GetStartPoint()-aCenter);
605 	long nEnd=GetAngle(rAct.GetEndPoint()-aCenter);
606 	SdrCircObj* pCirc=new SdrCircObj(OBJ_CARC,rAct.GetRect(),nStart,nEnd);
607 	SetAttributes(pCirc);
608 	InsertObj(pCirc);
609 }
610 
611 void ImpSdrGDIMetaFileImport::DoAction(MetaPieAction& rAct)
612 {
613     Point aCenter(rAct.GetRect().Center());
614 	long nStart=GetAngle(rAct.GetStartPoint()-aCenter);
615 	long nEnd=GetAngle(rAct.GetEndPoint()-aCenter);
616 	SdrCircObj* pCirc=new SdrCircObj(OBJ_SECT,rAct.GetRect(),nStart,nEnd);
617 	SetAttributes(pCirc);
618 	InsertObj(pCirc);
619 }
620 
621 void ImpSdrGDIMetaFileImport::DoAction(MetaChordAction& rAct)
622 {
623     Point aCenter(rAct.GetRect().Center());
624 	long nStart=GetAngle(rAct.GetStartPoint()-aCenter);
625 	long nEnd=GetAngle(rAct.GetEndPoint()-aCenter);
626 	SdrCircObj* pCirc=new SdrCircObj(OBJ_CCUT,rAct.GetRect(),nStart,nEnd);
627 	SetAttributes(pCirc);
628 	InsertObj(pCirc);
629 }
630 
631 /**************************************************************************************************/
632 
633 bool ImpSdrGDIMetaFileImport::CheckLastLineMerge(const basegfx::B2DPolygon& rSrcPoly)
634 {
635 	// #i102706# Do not merge closed polygons
636 	if(rSrcPoly.isClosed())
637 	{
638 		return false;
639 	}
640 
641 	// #i73407# reformulation to use new B2DPolygon classes
642 	if(bLastObjWasLine && (aOldLineColor == aVD.GetLineColor()) && rSrcPoly.count())
643 	{
644 		SdrObject* pTmpObj = aTmpList.GetObj(aTmpList.GetObjCount() - 1);
645 		SdrPathObj* pLastPoly = PTR_CAST(SdrPathObj, pTmpObj);
646 
647 		if(pLastPoly)
648 		{
649 			if(1L == pLastPoly->GetPathPoly().count())
650 			{
651 				bool bOk(false);
652 				basegfx::B2DPolygon aDstPoly(pLastPoly->GetPathPoly().getB2DPolygon(0L));
653 
654 				// #i102706# Do not merge closed polygons
655 				if(aDstPoly.isClosed())
656 				{
657 					return false;
658 				}
659 
660 				if(aDstPoly.count())
661 				{
662 					const sal_uInt32 nMaxDstPnt(aDstPoly.count() - 1L);
663 					const sal_uInt32 nMaxSrcPnt(rSrcPoly.count() - 1L);
664 
665 					if(aDstPoly.getB2DPoint(nMaxDstPnt) == rSrcPoly.getB2DPoint(0L))
666 					{
667 						aDstPoly.append(rSrcPoly, 1L, rSrcPoly.count() - 1L);
668 						bOk = true;
669 					}
670 					else if(aDstPoly.getB2DPoint(0L) == rSrcPoly.getB2DPoint(nMaxSrcPnt))
671 					{
672 						basegfx::B2DPolygon aNew(rSrcPoly);
673 						aNew.append(aDstPoly, 1L, aDstPoly.count() - 1L);
674 						aDstPoly = aNew;
675 						bOk = true;
676 					}
677 					else if(aDstPoly.getB2DPoint(0L) == rSrcPoly.getB2DPoint(0L))
678 					{
679 						aDstPoly.flip();
680 						aDstPoly.append(rSrcPoly, 1L, rSrcPoly.count() - 1L);
681 						bOk = true;
682 					}
683 					else if(aDstPoly.getB2DPoint(nMaxDstPnt) == rSrcPoly.getB2DPoint(nMaxSrcPnt))
684 					{
685 						basegfx::B2DPolygon aNew(rSrcPoly);
686 						aNew.flip();
687 						aDstPoly.append(aNew, 1L, aNew.count() - 1L);
688 						bOk = true;
689 					}
690 				}
691 
692 				if(bOk)
693 				{
694 					pLastPoly->NbcSetPathPoly(basegfx::B2DPolyPolygon(aDstPoly));
695 				}
696 
697 				return bOk;
698 			}
699 		}
700 	}
701 
702 	return false;
703 }
704 
705 bool ImpSdrGDIMetaFileImport::CheckLastPolyLineAndFillMerge(const basegfx::B2DPolyPolygon & rPolyPolygon)
706 {
707 	// #i73407# reformulation to use new B2DPolygon classes
708 	if(bLastObjWasPolyWithoutLine)
709 	{
710 		SdrObject* pTmpObj = aTmpList.GetObj(aTmpList.GetObjCount() - 1);
711 		SdrPathObj* pLastPoly = PTR_CAST(SdrPathObj, pTmpObj);
712 
713 		if(pLastPoly)
714 		{
715 			if(pLastPoly->GetPathPoly() == rPolyPolygon)
716 			{
717 				SetAttributes(NULL);
718 
719 				if(!bNoLine && bNoFill)
720 				{
721 					pLastPoly->SetMergedItemSet(*pLineAttr);
722 
723 					return true;
724 				}
725 			}
726 		}
727 	}
728 
729 	return false;
730 }
731 
732 void ImpSdrGDIMetaFileImport::checkClip()
733 {
734     if(aVD.IsClipRegion())
735     {
736         Region aRegion(aVD.GetClipRegion());
737 
738         maClip = aRegion.ConvertToB2DPolyPolygon();
739 
740         if(isClip())
741         {
742     		const basegfx::B2DHomMatrix aTransform(
743                 basegfx::tools::createScaleTranslateB2DHomMatrix(
744                     fScaleX,
745                     fScaleY,
746                     aOfs.X(),
747                     aOfs.Y()));
748 
749             maClip.transform(aTransform);
750         }
751     }
752 }
753 
754 bool ImpSdrGDIMetaFileImport::isClip() const
755 {
756     return !maClip.getB2DRange().isEmpty();
757 }
758 
759 void ImpSdrGDIMetaFileImport::DoAction( MetaPolyLineAction& rAct )
760 {
761 	// #i73407# reformulation to use new B2DPolygon classes
762 	basegfx::B2DPolygon aSource(rAct.GetPolygon().getB2DPolygon());
763 
764 	if(aSource.count())
765 	{
766 		const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(fScaleX, fScaleY, aOfs.X(), aOfs.Y()));
767 		aSource.transform(aTransform);
768 	}
769 
770 	const LineInfo& rLineInfo = rAct.GetLineInfo();
771 	const sal_Int32 nNewLineWidth(rLineInfo.GetWidth());
772 	bool bCreateLineObject(true);
773 
774 	if(bLastObjWasLine && (nNewLineWidth == nLineWidth) && CheckLastLineMerge(aSource))
775 	{
776 		bCreateLineObject = false;
777 	}
778 	else if(bLastObjWasPolyWithoutLine && CheckLastPolyLineAndFillMerge(basegfx::B2DPolyPolygon(aSource)))
779 	{
780 		bCreateLineObject = false;
781 	}
782 
783 	if(bCreateLineObject)
784 	{
785         SdrPathObj* pPath = new SdrPathObj(
786 			aSource.isClosed() ? OBJ_POLY : OBJ_PLIN,
787 			basegfx::B2DPolyPolygon(aSource));
788 		nLineWidth = nNewLineWidth;
789 		maLineJoin = rLineInfo.GetLineJoin();
790         maLineCap = rLineInfo.GetLineCap();
791 		maDash = XDash(XDASH_RECT,
792 			rLineInfo.GetDotCount(), rLineInfo.GetDotLen(),
793 			rLineInfo.GetDashCount(), rLineInfo.GetDashLen(),
794 			rLineInfo.GetDistance());
795 		SetAttributes(pPath);
796 		nLineWidth = 0;
797 		maLineJoin = basegfx::B2DLINEJOIN_NONE;
798 		maDash = XDash();
799 		InsertObj(pPath, false);
800 	}
801 }
802 
803 void ImpSdrGDIMetaFileImport::DoAction( MetaPolygonAction& rAct )
804 {
805 	// #i73407# reformulation to use new B2DPolygon classes
806 	basegfx::B2DPolygon aSource(rAct.GetPolygon().getB2DPolygon());
807 
808 	if(aSource.count())
809 	{
810 		const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(fScaleX, fScaleY, aOfs.X(), aOfs.Y()));
811 		aSource.transform(aTransform);
812 
813 		if(!bLastObjWasPolyWithoutLine || !CheckLastPolyLineAndFillMerge(basegfx::B2DPolyPolygon(aSource)))
814 		{
815 			// #i73407# make sure polygon is closed, it's a filled primitive
816 			aSource.setClosed(true);
817             SdrPathObj* pPath = new SdrPathObj(OBJ_POLY, basegfx::B2DPolyPolygon(aSource));
818 			SetAttributes(pPath);
819 			InsertObj(pPath, false);
820 		}
821 	}
822 }
823 
824 void ImpSdrGDIMetaFileImport::DoAction(MetaPolyPolygonAction& rAct)
825 {
826 	// #i73407# reformulation to use new B2DPolygon classes
827 	basegfx::B2DPolyPolygon aSource(rAct.GetPolyPolygon().getB2DPolyPolygon());
828 
829 	if(aSource.count())
830 	{
831 		const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(fScaleX, fScaleY, aOfs.X(), aOfs.Y()));
832 		aSource.transform(aTransform);
833 
834 		if(!bLastObjWasPolyWithoutLine || !CheckLastPolyLineAndFillMerge(aSource))
835 		{
836 			// #i73407# make sure polygon is closed, it's a filled primitive
837 			aSource.setClosed(true);
838             SdrPathObj* pPath = new SdrPathObj(OBJ_POLY, aSource);
839 			SetAttributes(pPath);
840 			InsertObj(pPath, false);
841 		}
842 	}
843 }
844 
845 /**************************************************************************************************/
846 
847 void ImpSdrGDIMetaFileImport::ImportText( const Point& rPos, const XubString& rStr, const MetaAction& rAct )
848 {
849 	// calc text box size, add 5% to make it fit safely
850 
851 	FontMetric aFontMetric( aVD.GetFontMetric() );
852 	Font aFnt( aVD.GetFont() );
853 	FontAlign eAlg( aFnt.GetAlign() );
854 
855     sal_Int32 nTextWidth = (sal_Int32)( aVD.GetTextWidth( rStr ) * fScaleX );
856     sal_Int32 nTextHeight = (sal_Int32)( aVD.GetTextHeight() * fScaleY );
857 	//sal_Int32 nDxWidth = 0;
858 	//sal_Int32 nLen = rStr.Len();
859 
860 	Point aPos( FRound(rPos.X() * fScaleX + aOfs.X()), FRound(rPos.Y() * fScaleY + aOfs.Y()) );
861     Size aSize( nTextWidth, nTextHeight );
862 
863 	if ( eAlg == ALIGN_BASELINE )
864 		aPos.Y() -= FRound(aFontMetric.GetAscent() * fScaleY);
865 	else if ( eAlg == ALIGN_BOTTOM )
866 		aPos.Y() -= nTextHeight;
867 
868 	Rectangle aTextRect( aPos, aSize );
869 	SdrRectObj* pText =new SdrRectObj( OBJ_TEXT, aTextRect );
870 
871 	if ( aFnt.GetWidth() || ( rAct.GetType() == META_STRETCHTEXT_ACTION ) )
872 	{
873 		pText->ClearMergedItem( SDRATTR_TEXT_AUTOGROWWIDTH );
874 		pText->SetMergedItem( SdrTextAutoGrowHeightItem( sal_False ) );
875 		// don't let the margins eat the space needed for the text
876 		pText->SetMergedItem ( SdrTextUpperDistItem (0));
877 		pText->SetMergedItem ( SdrTextLowerDistItem (0));
878 		pText->SetMergedItem ( SdrTextRightDistItem (0));
879 		pText->SetMergedItem ( SdrTextLeftDistItem (0));
880 		pText->SetMergedItem( SdrTextFitToSizeTypeItem( SDRTEXTFIT_ALLLINES ) );
881 	}
882 	else
883 		pText->SetMergedItem( SdrTextAutoGrowWidthItem( sal_True ) );
884 
885 	pText->SetModel( pModel );
886 	pText->SetLayer( nLayer );
887 	pText->NbcSetText( rStr );
888 	SetAttributes( pText, sal_True );
889 	pText->SetSnapRect( aTextRect );
890 
891 	if (!aFnt.IsTransparent())
892 	{
893 		SfxItemSet aAttr(*pFillAttr->GetPool(),XATTR_FILL_FIRST,XATTR_FILL_LAST);
894 		aAttr.Put(XFillStyleItem(XFILL_SOLID));
895 		aAttr.Put(XFillColorItem(String(), aFnt.GetFillColor()));
896 		pText->SetMergedItemSet(aAttr);
897 	}
898 	sal_uInt32 nWink = aFnt.GetOrientation();
899 	if ( nWink )
900 	{
901 		nWink*=10;
902 		double a=nWink*nPi180;
903 		double nSin=sin(a);
904 		double nCos=cos(a);
905 		pText->NbcRotate(aPos,nWink,nSin,nCos);
906 	}
907 	InsertObj( pText, sal_False );
908 }
909 
910 void ImpSdrGDIMetaFileImport::DoAction(MetaTextAction& rAct)
911 {
912 	XubString aStr(rAct.GetText());
913 	aStr.Erase(0,rAct.GetIndex());
914 	aStr.Erase(rAct.GetLen());
915 	ImportText( rAct.GetPoint(), aStr, rAct );
916 }
917 
918 void ImpSdrGDIMetaFileImport::DoAction(MetaTextArrayAction& rAct)
919 {
920 	XubString aStr(rAct.GetText());
921 	aStr.Erase(0,rAct.GetIndex());
922 	aStr.Erase(rAct.GetLen());
923 	ImportText( rAct.GetPoint(), aStr, rAct );
924 }
925 
926 void ImpSdrGDIMetaFileImport::DoAction(MetaStretchTextAction& rAct)
927 {
928 	XubString aStr(rAct.GetText());
929 	aStr.Erase(0,rAct.GetIndex());
930 	aStr.Erase(rAct.GetLen());
931 	ImportText( rAct.GetPoint(), aStr, rAct );
932 }
933 
934 void ImpSdrGDIMetaFileImport::DoAction(MetaBmpAction& rAct)
935 {
936 	Rectangle aRect(rAct.GetPoint(),rAct.GetBitmap().GetSizePixel());
937 	aRect.Right()++; aRect.Bottom()++;
938     SdrGrafObj* pGraf=new SdrGrafObj(Graphic(rAct.GetBitmap()),aRect);
939 	InsertObj(pGraf);
940 }
941 
942 void ImpSdrGDIMetaFileImport::DoAction(MetaBmpScaleAction& rAct)
943 {
944 	Rectangle aRect(rAct.GetPoint(),rAct.GetSize());
945 	aRect.Right()++; aRect.Bottom()++;
946     SdrGrafObj* pGraf=new SdrGrafObj(Graphic(rAct.GetBitmap()),aRect);
947 	InsertObj(pGraf);
948 }
949 
950 void ImpSdrGDIMetaFileImport::DoAction(MetaBmpExAction& rAct)
951 {
952 	Rectangle aRect(rAct.GetPoint(),rAct.GetBitmapEx().GetSizePixel());
953 	aRect.Right()++; aRect.Bottom()++;
954     SdrGrafObj* pGraf=new SdrGrafObj( rAct.GetBitmapEx(), aRect );
955 	InsertObj(pGraf);
956 }
957 
958 void ImpSdrGDIMetaFileImport::DoAction(MetaBmpExScaleAction& rAct)
959 {
960 	Rectangle aRect(rAct.GetPoint(),rAct.GetSize());
961 	aRect.Right()++; aRect.Bottom()++;
962     SdrGrafObj* pGraf=new SdrGrafObj( rAct.GetBitmapEx(), aRect );
963 	InsertObj(pGraf);
964 }
965 
966 ////////////////////////////////////////////////////////////////////////////////////////////////////
967 
968 void ImpSdrGDIMetaFileImport::DoAction( MetaHatchAction& rAct )
969 {
970 	// #i73407# reformulation to use new B2DPolygon classes
971 	basegfx::B2DPolyPolygon aSource(rAct.GetPolyPolygon().getB2DPolyPolygon());
972 
973 	if(aSource.count())
974 	{
975 		const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(fScaleX, fScaleY, aOfs.X(), aOfs.Y()));
976 		aSource.transform(aTransform);
977 
978 		if(!bLastObjWasPolyWithoutLine || !CheckLastPolyLineAndFillMerge(aSource))
979 		{
980 			const Hatch& rHatch = rAct.GetHatch();
981             SdrPathObj* pPath = new SdrPathObj(OBJ_POLY, aSource);
982 			SfxItemSet aHatchAttr(pModel->GetItemPool(),
983 				XATTR_FILLSTYLE, XATTR_FILLSTYLE,
984 				XATTR_FILLHATCH, XATTR_FILLHATCH, 0, 0 );
985 			XHatchStyle eStyle;
986 
987 			switch(rHatch.GetStyle())
988 			{
989 				case(HATCH_TRIPLE) :
990 				{
991 					eStyle = XHATCH_TRIPLE;
992 					break;
993 				}
994 
995 				case(HATCH_DOUBLE) :
996 				{
997 					eStyle = XHATCH_DOUBLE;
998 					break;
999 				}
1000 
1001 				default:
1002 				{
1003 					eStyle = XHATCH_SINGLE;
1004 					break;
1005 				}
1006 			}
1007 
1008 			SetAttributes(pPath);
1009 			aHatchAttr.Put(XFillStyleItem(XFILL_HATCH));
1010 			aHatchAttr.Put(XFillHatchItem(&pModel->GetItemPool(), XHatch(rHatch.GetColor(), eStyle, rHatch.GetDistance(), rHatch.GetAngle())));
1011 			pPath->SetMergedItemSet(aHatchAttr);
1012 
1013 			InsertObj(pPath, false);
1014 		}
1015 	}
1016 }
1017 
1018 ////////////////////////////////////////////////////////////////////////////////////////////////////
1019 
1020 void ImpSdrGDIMetaFileImport::DoAction(MetaLineColorAction& rAct)
1021 {
1022 	rAct.Execute(&aVD);
1023 }
1024 
1025 void ImpSdrGDIMetaFileImport::DoAction(MetaMapModeAction& rAct)
1026 {
1027 	MapScaling();
1028 	rAct.Execute(&aVD);
1029 	bLastObjWasPolyWithoutLine=sal_False;
1030 	bLastObjWasLine=sal_False;
1031 }
1032 
1033 void ImpSdrGDIMetaFileImport::MapScaling()
1034 {
1035 	sal_uInt32 i, nAnz = aTmpList.GetObjCount();
1036 	const MapMode& rMap = aVD.GetMapMode();
1037 	Point aMapOrg( rMap.GetOrigin() );
1038 	sal_Bool bMov2 = aMapOrg.X() != 0 || aMapOrg.Y() != 0;
1039 	if ( bMov2 )
1040     {
1041 		for ( i = nMapScalingOfs; i < nAnz; i++ )
1042         {
1043 			SdrObject* pObj = aTmpList.GetObj(i);
1044 			if ( bMov2 )
1045 				pObj->NbcMove( Size( aMapOrg.X(), aMapOrg.Y() ) );
1046 		}
1047 	}
1048 	nMapScalingOfs = nAnz;
1049 }
1050 
1051 ////////////////////////////////////////////////////////////////////////////////////////////////////
1052 
1053 void ImpSdrGDIMetaFileImport::DoAction( MetaCommentAction& rAct, GDIMetaFile* pMtf )
1054 {
1055 	ByteString aSkipComment;
1056 
1057 	if( rAct.GetComment().CompareIgnoreCaseToAscii( "XGRAD_SEQ_BEGIN" ) == COMPARE_EQUAL )
1058 	{
1059 		MetaGradientExAction* pAct = (MetaGradientExAction*) pMtf->NextAction();
1060 
1061 		if( pAct && pAct->GetType() == META_GRADIENTEX_ACTION )
1062 		{
1063 			// #i73407# reformulation to use new B2DPolygon classes
1064 			basegfx::B2DPolyPolygon aSource(pAct->GetPolyPolygon().getB2DPolyPolygon());
1065 
1066 			if(aSource.count())
1067 			{
1068 				if(!bLastObjWasPolyWithoutLine || !CheckLastPolyLineAndFillMerge(aSource))
1069 				{
1070 					const Gradient&	rGrad = pAct->GetGradient();
1071                     SdrPathObj* pPath = new SdrPathObj(OBJ_POLY, aSource);
1072 					SfxItemSet aGradAttr(pModel->GetItemPool(),
1073 					   XATTR_FILLSTYLE, XATTR_FILLSTYLE,
1074 					   XATTR_FILLGRADIENT, XATTR_FILLGRADIENT, 0, 0 );
1075 					XGradient aXGradient;
1076 
1077 					aXGradient.SetGradientStyle((XGradientStyle)rGrad.GetStyle());
1078 					aXGradient.SetStartColor(rGrad.GetStartColor());
1079 					aXGradient.SetEndColor(rGrad.GetEndColor());
1080 					aXGradient.SetAngle((sal_uInt16)rGrad.GetAngle());
1081 					aXGradient.SetBorder(rGrad.GetBorder());
1082 					aXGradient.SetXOffset(rGrad.GetOfsX());
1083 					aXGradient.SetYOffset(rGrad.GetOfsY());
1084 					aXGradient.SetStartIntens(rGrad.GetStartIntensity());
1085 					aXGradient.SetEndIntens(rGrad.GetEndIntensity());
1086 					aXGradient.SetSteps(rGrad.GetSteps());
1087 
1088             		if(aVD.IsLineColor())
1089                     {
1090                         // switch line off; when there was one there will be a
1091                         // META_POLYLINE_ACTION following creating another object
1092     		            const Color aLineColor(aVD.GetLineColor());
1093     		            aVD.SetLineColor();
1094                         SetAttributes(pPath);
1095     		            aVD.SetLineColor(aLineColor);
1096                     }
1097                     else
1098                     {
1099                         SetAttributes(pPath);
1100                     }
1101 
1102 					aGradAttr.Put(XFillStyleItem(XFILL_GRADIENT));
1103 					aGradAttr.Put(XFillGradientItem(&pModel->GetItemPool(), aXGradient));
1104 					pPath->SetMergedItemSet(aGradAttr);
1105 
1106 					InsertObj(pPath);
1107 				}
1108 			}
1109 
1110 			aSkipComment = "XGRAD_SEQ_END";
1111 		}
1112 	}
1113 
1114 	if(aSkipComment.Len())
1115 	{
1116 		MetaAction* pSkipAct = pMtf->NextAction();
1117 
1118 		while( pSkipAct
1119 			&& ((pSkipAct->GetType() != META_COMMENT_ACTION )
1120 				|| (((MetaCommentAction*)pSkipAct)->GetComment().CompareIgnoreCaseToAscii(aSkipComment.GetBuffer()) != COMPARE_EQUAL)))
1121 		{
1122 			pSkipAct = pMtf->NextAction();
1123 		}
1124 	}
1125 }
1126 
1127 ////////////////////////////////////////////////////////////////////////////////////////////////////
1128 // eof
1129