Version 3.6.0.2, tag libreoffice-3.6.0.2
[LibreOffice.git] / svx / source / svdraw / svdfmtf.cxx
blobd62255cadac9af22faeb03a992bdcdabdacb32e2
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
30 #include "svdfmtf.hxx"
31 #include <editeng/editdata.hxx>
32 #include <math.h>
33 #include <svx/xpoly.hxx>
34 #include <vcl/svapp.hxx>
35 #include <editeng/eeitem.hxx>
36 #include <editeng/fhgtitem.hxx>
37 #include <editeng/wghtitem.hxx>
38 #include <editeng/postitem.hxx>
39 #include <editeng/udlnitem.hxx>
40 #include <editeng/crsditem.hxx>
41 #include <editeng/shdditem.hxx>
42 #include <svx/xlnclit.hxx>
43 #include <svx/xlnwtit.hxx>
44 #include <svx/xflclit.hxx>
45 #include <svx/xgrad.hxx>
46 #include <svx/xflgrit.hxx>
47 #include <editeng/fontitem.hxx>
48 #include <editeng/akrnitem.hxx>
49 #include <editeng/wrlmitem.hxx>
50 #include <editeng/cntritem.hxx>
51 #include <editeng/colritem.hxx>
52 #include <vcl/metric.hxx>
53 #include <editeng/charscaleitem.hxx>
54 #include <svx/xflhtit.hxx>
55 #include <svx/svdattr.hxx>
56 #include <svx/svdmodel.hxx>
57 #include <svx/svdpage.hxx>
58 #include <svx/svdobj.hxx>
59 #include "svx/svditext.hxx"
60 #include <svx/svdotext.hxx>
61 #include <svx/svdorect.hxx>
62 #include <svx/svdocirc.hxx>
63 #include <svx/svdograf.hxx>
64 #include <svx/svdopath.hxx>
65 #include <svx/svdetc.hxx>
66 #include <svl/itemset.hxx>
67 #include <basegfx/polygon/b2dpolygon.hxx>
68 #include <vcl/salbtype.hxx> // FRound
69 #include <basegfx/matrix/b2dhommatrix.hxx>
70 #include <basegfx/matrix/b2dhommatrixtools.hxx>
71 #include <svx/xlinjoit.hxx>
72 #include <svx/xlndsit.hxx>
74 ////////////////////////////////////////////////////////////////////////////////////////////////////
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 maDash(XDASH_RECT, 0, 0, 0, 0, 0),
83 fScaleX(0.0),fScaleY(0.0),
84 bFntDirty(sal_True),
85 bLastObjWasPolyWithoutLine(sal_False),bNoLine(sal_False),bNoFill(sal_False),bLastObjWasLine(sal_False)
87 aVD.EnableOutput(sal_False);
89 // #i111954# init to no fill and no line initially
90 aVD.SetLineColor();
91 aVD.SetFillColor();
93 aOldLineColor.SetRed( aVD.GetLineColor().GetRed() + 1 ); // invalidate old line color
94 pLineAttr=new SfxItemSet(rModel.GetItemPool(),XATTR_LINE_FIRST,XATTR_LINE_LAST);
95 pFillAttr=new SfxItemSet(rModel.GetItemPool(),XATTR_FILL_FIRST,XATTR_FILL_LAST);
96 pTextAttr=new SfxItemSet(rModel.GetItemPool(),EE_ITEMS_START,EE_ITEMS_END);
97 pModel=&rModel;
100 ImpSdrGDIMetaFileImport::~ImpSdrGDIMetaFileImport()
102 delete pLineAttr;
103 delete pFillAttr;
104 delete pTextAttr;
107 sal_uIntPtr ImpSdrGDIMetaFileImport::DoImport(const GDIMetaFile& rMtf,
108 SdrObjList& rOL,
109 sal_uIntPtr nInsPos,
110 SvdProgressInfo *pProgrInfo)
112 pPage = rOL.GetPage();
113 GDIMetaFile* pTmpMtf=NULL;
114 GDIMetaFile* pMtf = (GDIMetaFile*) &rMtf;
115 size_t nActionAnz = pMtf->GetActionSize();
116 sal_Bool bError = sal_False;
119 // setup some global scale parameters
120 // fScaleX, fScaleY, aScaleX, aScaleY, bMov, bSize
121 fScaleX = fScaleY = 1.0;
122 Size aMtfSize( pMtf->GetPrefSize() );
123 if ( aMtfSize.Width() & aMtfSize.Height() && ( aScaleRect.IsEmpty() == sal_False ) )
125 aOfs = aScaleRect.TopLeft();
126 if ( aMtfSize.Width() != ( aScaleRect.GetWidth() - 1 ) )
127 fScaleX = (double)( aScaleRect.GetWidth() - 1 ) / (double)aMtfSize.Width();
128 if ( aMtfSize.Height() != ( aScaleRect.GetHeight() - 1 ) )
129 fScaleY = (double)( aScaleRect.GetHeight() - 1 ) / (double)aMtfSize.Height();
132 bMov = aOfs.X()!=0 || aOfs.Y()!=0;
133 bSize = sal_False;
135 aScaleX = Fraction( 1, 1 );
136 aScaleY = Fraction( 1, 1 );
137 if ( aMtfSize.Width() != ( aScaleRect.GetWidth() - 1 ) )
139 aScaleX = Fraction( aScaleRect.GetWidth() - 1, aMtfSize.Width() );
140 bSize = sal_True;
142 if ( aMtfSize.Height() != ( aScaleRect.GetHeight() - 1 ) )
144 aScaleY = Fraction( aScaleRect.GetHeight() - 1, aMtfSize.Height() );
145 bSize = sal_True;
148 if(65000 < nActionAnz)
150 nActionAnz = 65000;
151 bError = sal_True;
154 if(pProgrInfo)
155 pProgrInfo->SetActionCount(nActionAnz);
157 size_t nActionsToReport = 0;
159 for( MetaAction* pAct = pMtf->FirstAction(); pAct; pAct = pMtf->NextAction() )
161 switch (pAct->GetType())
163 case META_PIXEL_ACTION : DoAction((MetaPixelAction &)*pAct); break;
164 case META_POINT_ACTION : DoAction((MetaPointAction &)*pAct); break;
165 case META_LINE_ACTION : DoAction((MetaLineAction &)*pAct); break;
166 case META_RECT_ACTION : DoAction((MetaRectAction &)*pAct); break;
167 case META_ROUNDRECT_ACTION : DoAction((MetaRoundRectAction &)*pAct); break;
168 case META_ELLIPSE_ACTION : DoAction((MetaEllipseAction &)*pAct); break;
169 case META_ARC_ACTION : DoAction((MetaArcAction &)*pAct); break;
170 case META_PIE_ACTION : DoAction((MetaPieAction &)*pAct); break;
171 case META_CHORD_ACTION : DoAction((MetaChordAction &)*pAct); break;
172 case META_POLYLINE_ACTION : DoAction((MetaPolyLineAction &)*pAct); break;
173 case META_POLYGON_ACTION : DoAction((MetaPolygonAction &)*pAct); break;
174 case META_POLYPOLYGON_ACTION : DoAction((MetaPolyPolygonAction &)*pAct); break;
175 case META_TEXT_ACTION : DoAction((MetaTextAction &)*pAct); break;
176 case META_TEXTARRAY_ACTION : DoAction((MetaTextArrayAction &)*pAct); break;
177 case META_STRETCHTEXT_ACTION : DoAction((MetaStretchTextAction &)*pAct); break;
178 case META_BMP_ACTION : DoAction((MetaBmpAction &)*pAct); break;
179 case META_BMPSCALE_ACTION : DoAction((MetaBmpScaleAction &)*pAct); break;
180 case META_BMPEX_ACTION : DoAction((MetaBmpExAction &)*pAct); break;
181 case META_BMPEXSCALE_ACTION : DoAction((MetaBmpExScaleAction &)*pAct); break;
182 case META_LINECOLOR_ACTION : DoAction((MetaLineColorAction &)*pAct); break;
183 case META_FILLCOLOR_ACTION : DoAction((MetaFillColorAction &)*pAct); break;
184 case META_TEXTCOLOR_ACTION : DoAction((MetaTextColorAction &)*pAct); break;
185 case META_TEXTFILLCOLOR_ACTION : DoAction((MetaTextFillColorAction &)*pAct); break;
186 case META_FONT_ACTION : DoAction((MetaFontAction &)*pAct); break;
187 case META_TEXTALIGN_ACTION : DoAction((MetaTextAlignAction &)*pAct); break;
188 case META_MAPMODE_ACTION : DoAction((MetaMapModeAction &)*pAct); break;
189 case META_CLIPREGION_ACTION : DoAction((MetaClipRegionAction &)*pAct); break;
190 case META_MOVECLIPREGION_ACTION : DoAction((MetaMoveClipRegionAction &)*pAct); break;
191 case META_ISECTRECTCLIPREGION_ACTION: DoAction((MetaISectRectClipRegionAction&)*pAct); break;
192 case META_ISECTREGIONCLIPREGION_ACTION: DoAction((MetaISectRegionClipRegionAction&)*pAct); break;
193 case META_RASTEROP_ACTION : DoAction((MetaRasterOpAction &)*pAct); break;
194 case META_PUSH_ACTION : DoAction((MetaPushAction &)*pAct); break;
195 case META_POP_ACTION : DoAction((MetaPopAction &)*pAct); break;
196 case META_HATCH_ACTION : DoAction((MetaHatchAction &)*pAct); break;
197 case META_COMMENT_ACTION : DoAction((MetaCommentAction &)*pAct, pMtf); break;
198 case META_RENDERGRAPHIC_ACTION : DoAction((MetaRenderGraphicAction &)*pAct); break;
201 if(pProgrInfo != NULL)
203 nActionsToReport++;
204 if(nActionsToReport >= 16) // update all 16 actions
206 if(!pProgrInfo->ReportActions(nActionsToReport))
207 break;
208 nActionsToReport = 0;
213 if(pProgrInfo != NULL)
215 pProgrInfo->ReportActions(nActionsToReport);
216 nActionsToReport = 0;
219 // MapMode scaling
220 MapScaling();
221 // scale objects to predetermined rectangle
222 sal_uIntPtr nAnz=aTmpList.GetObjCount();
224 // To calculate the progress meter, we use GetActionSize()*3.
225 // However, aTmpList has a lower entry count limit than GetActionSize(),
226 // so the actions that were assumed were too much have to be re-added.
227 nActionsToReport = (pMtf->GetActionSize() - nAnz)*2;
230 // announce all currently unannounced rescales
231 if(pProgrInfo)
233 pProgrInfo->ReportRescales(nActionsToReport);
234 pProgrInfo->SetInsertCount(nAnz);
236 nActionsToReport = 0;
238 // insert all objects cached in aTmpList now into rOL from nInsPos
239 if (nInsPos>rOL.GetObjCount()) nInsPos=rOL.GetObjCount();
240 SdrInsertReason aReason(SDRREASON_VIEWCALL);
241 for (sal_uIntPtr i=0; i<nAnz; i++)
243 SdrObject* pObj=aTmpList.GetObj(i);
244 rOL.NbcInsertObject(pObj,nInsPos,&aReason);
245 nInsPos++;
247 if(pProgrInfo != NULL)
249 nActionsToReport++;
250 if(nActionsToReport >= 32) // update all 32 actions
252 pProgrInfo->ReportInserts(nActionsToReport);
253 nActionsToReport = 0;
257 if (pTmpMtf!=NULL) delete pTmpMtf;
259 // report all remaining inserts for the last time
260 if(pProgrInfo != NULL)
262 pProgrInfo->ReportInserts(nActionsToReport);
263 if(bError)
264 pProgrInfo->ReportError();
267 return aTmpList.GetObjCount();
270 void ImpSdrGDIMetaFileImport::SetAttributes(SdrObject* pObj, bool bForceTextAttr)
272 bNoLine = sal_False; bNoFill = sal_False;
273 bool bLine = !bForceTextAttr;
274 bool bFill = (pObj==NULL) || (pObj->IsClosedObj() && !bForceTextAttr);
275 bool bText = bForceTextAttr || (pObj!=NULL && pObj->GetOutlinerParaObject()!=NULL);
277 if ( bLine )
279 if ( nLineWidth )
280 pLineAttr->Put( XLineWidthItem( nLineWidth ) );
281 else
282 pLineAttr->Put( XLineWidthItem( 0 ) );
284 aOldLineColor = aVD.GetLineColor();
285 if( aVD.IsLineColor() )
287 pLineAttr->Put(XLineStyleItem(XLINE_SOLID));
288 pLineAttr->Put(XLineColorItem(String(), aVD.GetLineColor()));
290 else
291 pLineAttr->Put(XLineStyleItem(XLINE_NONE));
293 switch(maLineJoin)
295 default : // basegfx::B2DLINEJOIN_NONE
296 pLineAttr->Put(XLineJointItem(XLINEJOINT_NONE));
297 break;
298 case basegfx::B2DLINEJOIN_MIDDLE:
299 pLineAttr->Put(XLineJointItem(XLINEJOINT_MIDDLE));
300 break;
301 case basegfx::B2DLINEJOIN_BEVEL:
302 pLineAttr->Put(XLineJointItem(XLINEJOINT_BEVEL));
303 break;
304 case basegfx::B2DLINEJOIN_MITER:
305 pLineAttr->Put(XLineJointItem(XLINEJOINT_MITER));
306 break;
307 case basegfx::B2DLINEJOIN_ROUND:
308 pLineAttr->Put(XLineJointItem(XLINEJOINT_ROUND));
309 break;
312 if(((maDash.GetDots() && maDash.GetDotLen()) || (maDash.GetDashes() && maDash.GetDashLen())) && maDash.GetDistance())
314 pLineAttr->Put(XLineDashItem(String(), maDash));
316 else
318 pLineAttr->Put(XLineDashItem(String(), XDash(XDASH_RECT)));
321 else
322 bNoLine = sal_True;
324 if ( bFill )
326 if( aVD.IsFillColor() )
328 pFillAttr->Put(XFillStyleItem(XFILL_SOLID));
329 pFillAttr->Put(XFillColorItem(String(), aVD.GetFillColor()));
331 else
332 pFillAttr->Put(XFillStyleItem(XFILL_NONE));
334 else
335 bNoFill = sal_True;
337 if ( bText && bFntDirty )
339 Font aFnt(aVD.GetFont());
340 pTextAttr->Put( SvxFontItem( aFnt.GetFamily(), aFnt.GetName(), aFnt.GetStyleName(),
341 aFnt.GetPitch(), aFnt.GetCharSet(), EE_CHAR_FONTINFO ) );
342 pTextAttr->Put( SvxFontItem( aFnt.GetFamily(), aFnt.GetName(), aFnt.GetStyleName(),
343 aFnt.GetPitch(), aFnt.GetCharSet(), EE_CHAR_FONTINFO_CJK ) );
344 pTextAttr->Put( SvxFontItem( aFnt.GetFamily(), aFnt.GetName(), aFnt.GetStyleName(),
345 aFnt.GetPitch(), aFnt.GetCharSet(), EE_CHAR_FONTINFO_CTL ) );
346 pTextAttr->Put(SvxPostureItem(aFnt.GetItalic(), EE_CHAR_ITALIC));
347 pTextAttr->Put(SvxWeightItem(aFnt.GetWeight(), EE_CHAR_WEIGHT));
348 sal_uInt32 nHeight = FRound(aFnt.GetSize().Height() * fScaleY);
349 pTextAttr->Put( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT ) );
350 pTextAttr->Put( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT_CJK ) );
351 pTextAttr->Put( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT_CTL ) );
352 pTextAttr->Put(SvxCharScaleWidthItem(100, EE_CHAR_FONTWIDTH));
353 pTextAttr->Put(SvxUnderlineItem(aFnt.GetUnderline(), EE_CHAR_UNDERLINE));
354 pTextAttr->Put(SvxOverlineItem(aFnt.GetOverline(), EE_CHAR_OVERLINE));
355 pTextAttr->Put(SvxCrossedOutItem(aFnt.GetStrikeout(), EE_CHAR_STRIKEOUT));
356 pTextAttr->Put(SvxShadowedItem(aFnt.IsShadow(), EE_CHAR_SHADOW));
357 pTextAttr->Put(SvxAutoKernItem(aFnt.IsKerning(), EE_CHAR_KERNING));
358 pTextAttr->Put(SvxWordLineModeItem(aFnt.IsWordLineMode(), EE_CHAR_WLM));
359 pTextAttr->Put(SvxContourItem(aFnt.IsOutline(), EE_CHAR_OUTLINE));
360 pTextAttr->Put(SvxColorItem(aFnt.GetColor(), EE_CHAR_COLOR));
361 //... svxfont textitem svditext
362 bFntDirty=sal_False;
364 if (pObj!=NULL)
366 pObj->SetLayer(nLayer);
367 if (bLine) pObj->SetMergedItemSet(*pLineAttr);
368 if (bFill) pObj->SetMergedItemSet(*pFillAttr);
369 if (bText)
371 pObj->SetMergedItemSet(*pTextAttr);
372 pObj->SetMergedItem( SdrTextHorzAdjustItem( SDRTEXTHORZADJUST_LEFT ) );
377 void ImpSdrGDIMetaFileImport::InsertObj( SdrObject* pObj, sal_Bool bScale )
379 if ( bScale && !aScaleRect.IsEmpty() )
381 if ( bSize )
382 pObj->NbcResize( Point(), aScaleX, aScaleY );
383 if ( bMov )
384 pObj->NbcMove( Size( aOfs.X(), aOfs.Y() ) );
387 // #i111954# check object for visibility
388 // used are SdrPathObj, SdrRectObj, SdrCircObj, SdrGrafObj
389 bool bVisible(false);
391 if(pObj->HasLineStyle())
393 bVisible = true;
396 if(!bVisible && pObj->HasFillStyle())
398 bVisible = true;
401 if(!bVisible)
403 SdrTextObj* pTextObj = dynamic_cast< SdrTextObj* >(pObj);
405 if(pTextObj && pTextObj->HasText())
407 bVisible = true;
411 if(!bVisible)
413 SdrGrafObj* pGrafObj = dynamic_cast< SdrGrafObj* >(pObj);
415 if(pGrafObj)
417 // this may be refined to check if the graphic really is visible. It
418 // is here to ensure that graphic objects without fill, line and text
419 // get created
420 bVisible = true;
424 if(!bVisible)
426 SdrObject::Free(pObj);
428 else
430 aTmpList.InsertObject( pObj );
431 if ( HAS_BASE( SdrPathObj, pObj ) )
433 bool bClosed=pObj->IsClosedObj();
434 bLastObjWasPolyWithoutLine=bNoLine && bClosed;
435 bLastObjWasLine=!bClosed;
437 else
439 bLastObjWasPolyWithoutLine = sal_False;
440 bLastObjWasLine = sal_False;
445 /**************************************************************************************************/
446 void ImpSdrGDIMetaFileImport::DoAction(MetaPixelAction& /*rAct*/) const
450 void ImpSdrGDIMetaFileImport::DoAction(MetaPointAction& /*rAct*/) const
454 void ImpSdrGDIMetaFileImport::DoAction(MetaLineAction& rAct)
456 // #i73407# reformulation to use new B2DPolygon classes
457 const basegfx::B2DPoint aStart(rAct.GetStartPoint().X(), rAct.GetStartPoint().Y());
458 const basegfx::B2DPoint aEnd(rAct.GetEndPoint().X(), rAct.GetEndPoint().Y());
460 if(!aStart.equal(aEnd))
462 basegfx::B2DPolygon aLine;
463 const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(fScaleX, fScaleY, aOfs.X(), aOfs.Y()));
465 aLine.append(aStart);
466 aLine.append(aEnd);
467 aLine.transform(aTransform);
469 const LineInfo& rLineInfo = rAct.GetLineInfo();
470 const sal_Int32 nNewLineWidth(rLineInfo.GetWidth());
471 bool bCreateLineObject(true);
473 if(bLastObjWasLine && (nNewLineWidth == nLineWidth) && CheckLastLineMerge(aLine))
475 bCreateLineObject = false;
478 if(bCreateLineObject)
480 SdrPathObj* pPath = new SdrPathObj(OBJ_LINE, basegfx::B2DPolyPolygon(aLine));
481 nLineWidth = nNewLineWidth;
482 maLineJoin = rLineInfo.GetLineJoin();
483 maDash = XDash(XDASH_RECT,
484 rLineInfo.GetDotCount(), rLineInfo.GetDotLen(),
485 rLineInfo.GetDashCount(), rLineInfo.GetDashLen(),
486 rLineInfo.GetDistance());
487 SetAttributes(pPath);
488 nLineWidth = 0;
489 maLineJoin = basegfx::B2DLINEJOIN_NONE;
490 maDash = XDash();
491 InsertObj(pPath, false);
496 void ImpSdrGDIMetaFileImport::DoAction(MetaRectAction& rAct)
498 SdrRectObj* pRect=new SdrRectObj(rAct.GetRect());
499 SetAttributes(pRect);
500 InsertObj(pRect);
503 void ImpSdrGDIMetaFileImport::DoAction(MetaRoundRectAction& rAct)
505 SdrRectObj* pRect=new SdrRectObj(rAct.GetRect());
506 SetAttributes(pRect);
507 long nRad=(rAct.GetHorzRound()+rAct.GetVertRound())/2;
508 if (nRad!=0) {
509 SfxItemSet aSet(*pLineAttr->GetPool(),SDRATTR_ECKENRADIUS,SDRATTR_ECKENRADIUS);
510 aSet.Put(SdrEckenradiusItem(nRad));
511 pRect->SetMergedItemSet(aSet);
513 InsertObj(pRect);
516 /**************************************************************************************************/
518 void ImpSdrGDIMetaFileImport::DoAction(MetaEllipseAction& rAct)
520 SdrCircObj* pCirc=new SdrCircObj(OBJ_CIRC,rAct.GetRect());
521 SetAttributes(pCirc);
522 InsertObj(pCirc);
525 void ImpSdrGDIMetaFileImport::DoAction(MetaArcAction& rAct)
527 Point aCenter(rAct.GetRect().Center());
528 long nStart=GetAngle(rAct.GetStartPoint()-aCenter);
529 long nEnd=GetAngle(rAct.GetEndPoint()-aCenter);
530 SdrCircObj* pCirc=new SdrCircObj(OBJ_CARC,rAct.GetRect(),nStart,nEnd);
531 SetAttributes(pCirc);
532 InsertObj(pCirc);
535 void ImpSdrGDIMetaFileImport::DoAction(MetaPieAction& rAct)
537 Point aCenter(rAct.GetRect().Center());
538 long nStart=GetAngle(rAct.GetStartPoint()-aCenter);
539 long nEnd=GetAngle(rAct.GetEndPoint()-aCenter);
540 SdrCircObj* pCirc=new SdrCircObj(OBJ_SECT,rAct.GetRect(),nStart,nEnd);
541 SetAttributes(pCirc);
542 InsertObj(pCirc);
545 void ImpSdrGDIMetaFileImport::DoAction(MetaChordAction& rAct)
547 Point aCenter(rAct.GetRect().Center());
548 long nStart=GetAngle(rAct.GetStartPoint()-aCenter);
549 long nEnd=GetAngle(rAct.GetEndPoint()-aCenter);
550 SdrCircObj* pCirc=new SdrCircObj(OBJ_CCUT,rAct.GetRect(),nStart,nEnd);
551 SetAttributes(pCirc);
552 InsertObj(pCirc);
555 /**************************************************************************************************/
557 bool ImpSdrGDIMetaFileImport::CheckLastLineMerge(const basegfx::B2DPolygon& rSrcPoly)
559 // #i102706# Do not merge closed polygons
560 if(rSrcPoly.isClosed())
562 return false;
565 // #i73407# reformulation to use new B2DPolygon classes
566 if(bLastObjWasLine && (aOldLineColor == aVD.GetLineColor()) && rSrcPoly.count())
568 SdrObject* pTmpObj = aTmpList.GetObj(aTmpList.GetObjCount() - 1);
569 SdrPathObj* pLastPoly = PTR_CAST(SdrPathObj, pTmpObj);
571 if(pLastPoly)
573 if(1L == pLastPoly->GetPathPoly().count())
575 bool bOk(false);
576 basegfx::B2DPolygon aDstPoly(pLastPoly->GetPathPoly().getB2DPolygon(0L));
578 // #i102706# Do not merge closed polygons
579 if(aDstPoly.isClosed())
581 return false;
584 if(aDstPoly.count())
586 const sal_uInt32 nMaxDstPnt(aDstPoly.count() - 1L);
587 const sal_uInt32 nMaxSrcPnt(rSrcPoly.count() - 1L);
589 if(aDstPoly.getB2DPoint(nMaxDstPnt) == rSrcPoly.getB2DPoint(0L))
591 aDstPoly.append(rSrcPoly, 1L, rSrcPoly.count() - 1L);
592 bOk = true;
594 else if(aDstPoly.getB2DPoint(0L) == rSrcPoly.getB2DPoint(nMaxSrcPnt))
596 basegfx::B2DPolygon aNew(rSrcPoly);
597 aNew.append(aDstPoly, 1L, aDstPoly.count() - 1L);
598 aDstPoly = aNew;
599 bOk = true;
601 else if(aDstPoly.getB2DPoint(0L) == rSrcPoly.getB2DPoint(0L))
603 aDstPoly.flip();
604 aDstPoly.append(rSrcPoly, 1L, rSrcPoly.count() - 1L);
605 bOk = true;
607 else if(aDstPoly.getB2DPoint(nMaxDstPnt) == rSrcPoly.getB2DPoint(nMaxSrcPnt))
609 basegfx::B2DPolygon aNew(rSrcPoly);
610 aNew.flip();
611 aDstPoly.append(aNew, 1L, aNew.count() - 1L);
612 bOk = true;
616 if(bOk)
618 pLastPoly->NbcSetPathPoly(basegfx::B2DPolyPolygon(aDstPoly));
621 return bOk;
626 return false;
629 bool ImpSdrGDIMetaFileImport::CheckLastPolyLineAndFillMerge(const basegfx::B2DPolyPolygon & rPolyPolygon)
631 // #i73407# reformulation to use new B2DPolygon classes
632 if(bLastObjWasPolyWithoutLine)
634 SdrObject* pTmpObj = aTmpList.GetObj(aTmpList.GetObjCount() - 1);
635 SdrPathObj* pLastPoly = PTR_CAST(SdrPathObj, pTmpObj);
637 if(pLastPoly)
639 if(pLastPoly->GetPathPoly() == rPolyPolygon)
641 SetAttributes(NULL);
643 if(!bNoLine && bNoFill)
645 pLastPoly->SetMergedItemSet(*pLineAttr);
647 return true;
653 return false;
657 void ImpSdrGDIMetaFileImport::DoAction( MetaPolyLineAction& rAct )
659 // #i73407# reformulation to use new B2DPolygon classes
660 basegfx::B2DPolygon aSource(rAct.GetPolygon().getB2DPolygon());
662 if(aSource.count())
664 const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(fScaleX, fScaleY, aOfs.X(), aOfs.Y()));
665 aSource.transform(aTransform);
668 const LineInfo& rLineInfo = rAct.GetLineInfo();
669 const sal_Int32 nNewLineWidth(rLineInfo.GetWidth());
670 bool bCreateLineObject(true);
672 if(bLastObjWasLine && (nNewLineWidth == nLineWidth) && CheckLastLineMerge(aSource))
674 bCreateLineObject = false;
676 else if(bLastObjWasPolyWithoutLine && CheckLastPolyLineAndFillMerge(basegfx::B2DPolyPolygon(aSource)))
678 bCreateLineObject = false;
681 if(bCreateLineObject)
683 SdrPathObj* pPath = new SdrPathObj(
684 aSource.isClosed() ? OBJ_POLY : OBJ_PLIN,
685 basegfx::B2DPolyPolygon(aSource));
686 nLineWidth = nNewLineWidth;
687 maLineJoin = rLineInfo.GetLineJoin();
688 maDash = XDash(XDASH_RECT,
689 rLineInfo.GetDotCount(), rLineInfo.GetDotLen(),
690 rLineInfo.GetDashCount(), rLineInfo.GetDashLen(),
691 rLineInfo.GetDistance());
692 SetAttributes(pPath);
693 nLineWidth = 0;
694 maLineJoin = basegfx::B2DLINEJOIN_NONE;
695 maDash = XDash();
696 InsertObj(pPath, false);
700 void ImpSdrGDIMetaFileImport::DoAction( MetaPolygonAction& rAct )
702 // #i73407# reformulation to use new B2DPolygon classes
703 basegfx::B2DPolygon aSource(rAct.GetPolygon().getB2DPolygon());
705 if(aSource.count())
707 const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(fScaleX, fScaleY, aOfs.X(), aOfs.Y()));
708 aSource.transform(aTransform);
710 if(!bLastObjWasPolyWithoutLine || !CheckLastPolyLineAndFillMerge(basegfx::B2DPolyPolygon(aSource)))
712 // #i73407# make sure polygon is closed, it's a filled primitive
713 aSource.setClosed(true);
715 SdrPathObj* pPath = new SdrPathObj(OBJ_POLY, basegfx::B2DPolyPolygon(aSource));
716 SetAttributes(pPath);
717 InsertObj(pPath, false);
722 void ImpSdrGDIMetaFileImport::DoAction(MetaPolyPolygonAction& rAct)
724 // #i73407# reformulation to use new B2DPolygon classes
725 basegfx::B2DPolyPolygon aSource(rAct.GetPolyPolygon().getB2DPolyPolygon());
727 if(aSource.count())
729 const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(fScaleX, fScaleY, aOfs.X(), aOfs.Y()));
730 aSource.transform(aTransform);
732 if(!bLastObjWasPolyWithoutLine || !CheckLastPolyLineAndFillMerge(aSource))
734 // #i73407# make sure polygon is closed, it's a filled primitive
735 aSource.setClosed(true);
737 SdrPathObj* pPath = new SdrPathObj(OBJ_POLY, aSource);
738 SetAttributes(pPath);
739 InsertObj(pPath, false);
744 /**************************************************************************************************/
746 void ImpSdrGDIMetaFileImport::ImportText( const Point& rPos, const XubString& rStr, const MetaAction& rAct )
748 // calc text box size, add 5% to make it fit safely
750 FontMetric aFontMetric( aVD.GetFontMetric() );
751 Font aFnt( aVD.GetFont() );
752 FontAlign eAlg( aFnt.GetAlign() );
754 sal_Int32 nTextWidth = (sal_Int32)( aVD.GetTextWidth( rStr ) * fScaleX );
755 sal_Int32 nTextHeight = (sal_Int32)( aVD.GetTextHeight() * fScaleY );
757 Point aPos( FRound(rPos.X() * fScaleX + aOfs.X()), FRound(rPos.Y() * fScaleY + aOfs.Y()) );
758 Size aSize( nTextWidth, nTextHeight );
760 if ( eAlg == ALIGN_BASELINE )
761 aPos.Y() -= FRound(aFontMetric.GetAscent() * fScaleY);
762 else if ( eAlg == ALIGN_BOTTOM )
763 aPos.Y() -= nTextHeight;
765 Rectangle aTextRect( aPos, aSize );
766 SdrRectObj* pText =new SdrRectObj( OBJ_TEXT, aTextRect );
768 if ( aFnt.GetWidth() || ( rAct.GetType() == META_STRETCHTEXT_ACTION ) )
770 pText->ClearMergedItem( SDRATTR_TEXT_AUTOGROWWIDTH );
771 pText->SetMergedItem( SdrTextAutoGrowHeightItem( sal_False ) );
772 // don't let the margins eat the space needed for the text
773 pText->SetMergedItem ( SdrTextUpperDistItem (0));
774 pText->SetMergedItem ( SdrTextLowerDistItem (0));
775 pText->SetMergedItem ( SdrTextRightDistItem (0));
776 pText->SetMergedItem ( SdrTextLeftDistItem (0));
777 pText->SetMergedItem( SdrTextFitToSizeTypeItem( SDRTEXTFIT_ALLLINES ) );
779 else
780 pText->SetMergedItem( SdrTextAutoGrowWidthItem( sal_True ) );
782 pText->SetModel( pModel );
783 pText->SetLayer( nLayer );
784 pText->NbcSetText( rStr );
785 SetAttributes( pText, sal_True );
786 pText->SetSnapRect( aTextRect );
788 if (!aFnt.IsTransparent())
790 SfxItemSet aAttr(*pFillAttr->GetPool(),XATTR_FILL_FIRST,XATTR_FILL_LAST);
791 aAttr.Put(XFillStyleItem(XFILL_SOLID));
792 aAttr.Put(XFillColorItem(String(), aFnt.GetFillColor()));
793 pText->SetMergedItemSet(aAttr);
795 sal_uInt32 nWink = aFnt.GetOrientation();
796 if ( nWink )
798 nWink*=10;
799 double a=nWink*nPi180;
800 double nSin=sin(a);
801 double nCos=cos(a);
802 pText->NbcRotate(aPos,nWink,nSin,nCos);
804 InsertObj( pText, sal_False );
807 void ImpSdrGDIMetaFileImport::DoAction(MetaTextAction& rAct)
809 XubString aStr(rAct.GetText());
810 aStr.Erase(0,rAct.GetIndex());
811 aStr.Erase(rAct.GetLen());
812 ImportText( rAct.GetPoint(), aStr, rAct );
815 void ImpSdrGDIMetaFileImport::DoAction(MetaTextArrayAction& rAct)
817 XubString aStr(rAct.GetText());
818 aStr.Erase(0,rAct.GetIndex());
819 aStr.Erase(rAct.GetLen());
820 ImportText( rAct.GetPoint(), aStr, rAct );
823 void ImpSdrGDIMetaFileImport::DoAction(MetaStretchTextAction& rAct)
825 XubString aStr(rAct.GetText());
826 aStr.Erase(0,rAct.GetIndex());
827 aStr.Erase(rAct.GetLen());
828 ImportText( rAct.GetPoint(), aStr, rAct );
831 void ImpSdrGDIMetaFileImport::DoAction(MetaBmpAction& rAct)
833 Rectangle aRect(rAct.GetPoint(),rAct.GetBitmap().GetSizePixel());
834 aRect.Right()++; aRect.Bottom()++;
835 SdrGrafObj* pGraf=new SdrGrafObj(Graphic(rAct.GetBitmap()),aRect);
836 InsertObj(pGraf);
839 void ImpSdrGDIMetaFileImport::DoAction(MetaBmpScaleAction& rAct)
841 Rectangle aRect(rAct.GetPoint(),rAct.GetSize());
842 aRect.Right()++; aRect.Bottom()++;
843 SdrGrafObj* pGraf=new SdrGrafObj(Graphic(rAct.GetBitmap()),aRect);
844 InsertObj(pGraf);
847 void ImpSdrGDIMetaFileImport::DoAction(MetaBmpExAction& rAct)
849 Rectangle aRect(rAct.GetPoint(),rAct.GetBitmapEx().GetSizePixel());
850 aRect.Right()++; aRect.Bottom()++;
851 SdrGrafObj* pGraf=new SdrGrafObj( rAct.GetBitmapEx(), aRect );
852 InsertObj(pGraf);
855 void ImpSdrGDIMetaFileImport::DoAction(MetaBmpExScaleAction& rAct)
857 Rectangle aRect(rAct.GetPoint(),rAct.GetSize());
858 aRect.Right()++; aRect.Bottom()++;
859 SdrGrafObj* pGraf=new SdrGrafObj( rAct.GetBitmapEx(), aRect );
860 InsertObj(pGraf);
863 ////////////////////////////////////////////////////////////////////////////////////////////////////
865 void ImpSdrGDIMetaFileImport::DoAction( MetaHatchAction& rAct )
867 // #i73407# reformulation to use new B2DPolygon classes
868 basegfx::B2DPolyPolygon aSource(rAct.GetPolyPolygon().getB2DPolyPolygon());
870 if(aSource.count())
872 const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(fScaleX, fScaleY, aOfs.X(), aOfs.Y()));
873 aSource.transform(aTransform);
875 if(!bLastObjWasPolyWithoutLine || !CheckLastPolyLineAndFillMerge(aSource))
877 const Hatch& rHatch = rAct.GetHatch();
878 SdrPathObj* pPath = new SdrPathObj(OBJ_POLY, aSource);
879 SfxItemSet aHatchAttr(pModel->GetItemPool(),
880 XATTR_FILLSTYLE, XATTR_FILLSTYLE,
881 XATTR_FILLHATCH, XATTR_FILLHATCH, 0, 0 );
882 XHatchStyle eStyle;
884 switch(rHatch.GetStyle())
886 case(HATCH_TRIPLE) :
888 eStyle = XHATCH_TRIPLE;
889 break;
892 case(HATCH_DOUBLE) :
894 eStyle = XHATCH_DOUBLE;
895 break;
898 default:
900 eStyle = XHATCH_SINGLE;
901 break;
905 SetAttributes(pPath);
906 aHatchAttr.Put(XFillStyleItem(XFILL_HATCH));
907 aHatchAttr.Put(XFillHatchItem(&pModel->GetItemPool(), XHatch(rHatch.GetColor(), eStyle, rHatch.GetDistance(), rHatch.GetAngle())));
908 pPath->SetMergedItemSet(aHatchAttr);
910 InsertObj(pPath, false);
915 ////////////////////////////////////////////////////////////////////////////////////////////////////
917 void ImpSdrGDIMetaFileImport::DoAction(MetaLineColorAction& rAct)
919 rAct.Execute(&aVD);
922 void ImpSdrGDIMetaFileImport::DoAction(MetaMapModeAction& rAct)
924 MapScaling();
925 rAct.Execute(&aVD);
926 bLastObjWasPolyWithoutLine=sal_False;
927 bLastObjWasLine=sal_False;
930 void ImpSdrGDIMetaFileImport::MapScaling()
932 sal_uInt32 i, nAnz = aTmpList.GetObjCount();
933 const MapMode& rMap = aVD.GetMapMode();
934 Point aMapOrg( rMap.GetOrigin() );
935 sal_Bool bMov2 = aMapOrg.X() != 0 || aMapOrg.Y() != 0;
936 if ( bMov2 )
938 for ( i = nMapScalingOfs; i < nAnz; i++ )
940 SdrObject* pObj = aTmpList.GetObj(i);
941 if ( bMov2 )
942 pObj->NbcMove( Size( aMapOrg.X(), aMapOrg.Y() ) );
945 nMapScalingOfs = nAnz;
948 ////////////////////////////////////////////////////////////////////////////////////////////////////
950 void ImpSdrGDIMetaFileImport::DoAction( MetaCommentAction& rAct, GDIMetaFile* pMtf )
952 bool aSkipComment = false;
954 if (rAct.GetComment().equalsIgnoreAsciiCaseL(RTL_CONSTASCII_STRINGPARAM("XGRAD_SEQ_BEGIN")))
956 MetaGradientExAction* pAct = (MetaGradientExAction*) pMtf->NextAction();
958 if( pAct && pAct->GetType() == META_GRADIENTEX_ACTION )
960 // #i73407# reformulation to use new B2DPolygon classes
961 basegfx::B2DPolyPolygon aSource(pAct->GetPolyPolygon().getB2DPolyPolygon());
963 if(aSource.count())
965 if(!bLastObjWasPolyWithoutLine || !CheckLastPolyLineAndFillMerge(aSource))
967 const Gradient& rGrad = pAct->GetGradient();
968 SdrPathObj* pPath = new SdrPathObj(OBJ_POLY, aSource);
969 SfxItemSet aGradAttr(pModel->GetItemPool(),
970 XATTR_FILLSTYLE, XATTR_FILLSTYLE,
971 XATTR_FILLGRADIENT, XATTR_FILLGRADIENT, 0, 0 );
972 XGradient aXGradient;
974 aXGradient.SetGradientStyle((XGradientStyle)rGrad.GetStyle());
975 aXGradient.SetStartColor(rGrad.GetStartColor());
976 aXGradient.SetEndColor(rGrad.GetEndColor());
977 aXGradient.SetAngle((sal_uInt16)rGrad.GetAngle());
978 aXGradient.SetBorder(rGrad.GetBorder());
979 aXGradient.SetXOffset(rGrad.GetOfsX());
980 aXGradient.SetYOffset(rGrad.GetOfsY());
981 aXGradient.SetStartIntens(rGrad.GetStartIntensity());
982 aXGradient.SetEndIntens(rGrad.GetEndIntensity());
983 aXGradient.SetSteps(rGrad.GetSteps());
985 if(aVD.IsLineColor())
987 // switch line off; if there was one, there will be a
988 // META_POLYLINE_ACTION following creating another object
989 const Color aLineColor(aVD.GetLineColor());
990 aVD.SetLineColor();
991 SetAttributes(pPath);
992 aVD.SetLineColor(aLineColor);
994 else
996 SetAttributes(pPath);
999 aGradAttr.Put(XFillStyleItem(XFILL_GRADIENT));
1000 aGradAttr.Put(XFillGradientItem(aXGradient));
1001 pPath->SetMergedItemSet(aGradAttr);
1003 InsertObj(pPath);
1007 aSkipComment = true;
1011 if(aSkipComment)
1013 MetaAction* pSkipAct = pMtf->NextAction();
1015 while( pSkipAct
1016 && ((pSkipAct->GetType() != META_COMMENT_ACTION )
1017 || !(((MetaCommentAction*)pSkipAct)->GetComment().equalsIgnoreAsciiCase("XGRAD_SEQ_END"))))
1019 pSkipAct = pMtf->NextAction();
1024 ////////////////////////////////////////////////////////////////////////////////////////////////////
1026 void ImpSdrGDIMetaFileImport::DoAction(MetaRenderGraphicAction& rAct)
1028 GDIMetaFile aMtf;
1029 const ::vcl::RenderGraphic& rRenderGraphic = rAct.GetRenderGraphic();
1030 Rectangle aRect( rAct.GetPoint(), rAct.GetSize() );
1031 const Point aPos;
1032 const Size aPrefSize( rRenderGraphic.GetPrefSize() );
1034 aRect.Right()++; aRect.Bottom()++;
1036 aMtf.SetPrefMapMode( rRenderGraphic.GetPrefMapMode() );
1037 aMtf.SetPrefSize( aPrefSize );
1038 aMtf.AddAction( new MetaRenderGraphicAction( aPos, aPrefSize, rRenderGraphic ) );
1039 aMtf.WindStart();
1041 SdrGrafObj* pGraf=new SdrGrafObj( aMtf, aRect );
1042 InsertObj( pGraf );
1045 // eof
1047 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */