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>
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
):
78 pLineAttr(NULL
),pFillAttr(NULL
),pTextAttr(NULL
),
79 pPage(NULL
),pModel(NULL
),nLayer(0),
81 maLineJoin(basegfx::B2DLINEJOIN_NONE
),
82 maDash(XDASH_RECT
, 0, 0, 0, 0, 0),
83 fScaleX(0.0),fScaleY(0.0),
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
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
);
100 ImpSdrGDIMetaFileImport::~ImpSdrGDIMetaFileImport()
107 sal_uIntPtr
ImpSdrGDIMetaFileImport::DoImport(const GDIMetaFile
& rMtf
,
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;
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() );
142 if ( aMtfSize
.Height() != ( aScaleRect
.GetHeight() - 1 ) )
144 aScaleY
= Fraction( aScaleRect
.GetHeight() - 1, aMtfSize
.Height() );
148 if(65000 < nActionAnz
)
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
)
204 if(nActionsToReport
>= 16) // update all 16 actions
206 if(!pProgrInfo
->ReportActions(nActionsToReport
))
208 nActionsToReport
= 0;
213 if(pProgrInfo
!= NULL
)
215 pProgrInfo
->ReportActions(nActionsToReport
);
216 nActionsToReport
= 0;
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
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
);
247 if(pProgrInfo
!= NULL
)
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
);
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
);
280 pLineAttr
->Put( XLineWidthItem( nLineWidth
) );
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()));
291 pLineAttr
->Put(XLineStyleItem(XLINE_NONE
));
295 default : // basegfx::B2DLINEJOIN_NONE
296 pLineAttr
->Put(XLineJointItem(XLINEJOINT_NONE
));
298 case basegfx::B2DLINEJOIN_MIDDLE
:
299 pLineAttr
->Put(XLineJointItem(XLINEJOINT_MIDDLE
));
301 case basegfx::B2DLINEJOIN_BEVEL
:
302 pLineAttr
->Put(XLineJointItem(XLINEJOINT_BEVEL
));
304 case basegfx::B2DLINEJOIN_MITER
:
305 pLineAttr
->Put(XLineJointItem(XLINEJOINT_MITER
));
307 case basegfx::B2DLINEJOIN_ROUND
:
308 pLineAttr
->Put(XLineJointItem(XLINEJOINT_ROUND
));
312 if(((maDash
.GetDots() && maDash
.GetDotLen()) || (maDash
.GetDashes() && maDash
.GetDashLen())) && maDash
.GetDistance())
314 pLineAttr
->Put(XLineDashItem(String(), maDash
));
318 pLineAttr
->Put(XLineDashItem(String(), XDash(XDASH_RECT
)));
326 if( aVD
.IsFillColor() )
328 pFillAttr
->Put(XFillStyleItem(XFILL_SOLID
));
329 pFillAttr
->Put(XFillColorItem(String(), aVD
.GetFillColor()));
332 pFillAttr
->Put(XFillStyleItem(XFILL_NONE
));
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
366 pObj
->SetLayer(nLayer
);
367 if (bLine
) pObj
->SetMergedItemSet(*pLineAttr
);
368 if (bFill
) pObj
->SetMergedItemSet(*pFillAttr
);
371 pObj
->SetMergedItemSet(*pTextAttr
);
372 pObj
->SetMergedItem( SdrTextHorzAdjustItem( SDRTEXTHORZADJUST_LEFT
) );
377 void ImpSdrGDIMetaFileImport::InsertObj( SdrObject
* pObj
, sal_Bool bScale
)
379 if ( bScale
&& !aScaleRect
.IsEmpty() )
382 pObj
->NbcResize( Point(), aScaleX
, aScaleY
);
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())
396 if(!bVisible
&& pObj
->HasFillStyle())
403 SdrTextObj
* pTextObj
= dynamic_cast< SdrTextObj
* >(pObj
);
405 if(pTextObj
&& pTextObj
->HasText())
413 SdrGrafObj
* pGrafObj
= dynamic_cast< SdrGrafObj
* >(pObj
);
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
426 SdrObject::Free(pObj
);
430 aTmpList
.InsertObject( pObj
);
431 if ( HAS_BASE( SdrPathObj
, pObj
) )
433 bool bClosed
=pObj
->IsClosedObj();
434 bLastObjWasPolyWithoutLine
=bNoLine
&& bClosed
;
435 bLastObjWasLine
=!bClosed
;
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
);
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
);
489 maLineJoin
= basegfx::B2DLINEJOIN_NONE
;
491 InsertObj(pPath
, false);
496 void ImpSdrGDIMetaFileImport::DoAction(MetaRectAction
& rAct
)
498 SdrRectObj
* pRect
=new SdrRectObj(rAct
.GetRect());
499 SetAttributes(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;
509 SfxItemSet
aSet(*pLineAttr
->GetPool(),SDRATTR_ECKENRADIUS
,SDRATTR_ECKENRADIUS
);
510 aSet
.Put(SdrEckenradiusItem(nRad
));
511 pRect
->SetMergedItemSet(aSet
);
516 /**************************************************************************************************/
518 void ImpSdrGDIMetaFileImport::DoAction(MetaEllipseAction
& rAct
)
520 SdrCircObj
* pCirc
=new SdrCircObj(OBJ_CIRC
,rAct
.GetRect());
521 SetAttributes(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
);
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
);
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
);
555 /**************************************************************************************************/
557 bool ImpSdrGDIMetaFileImport::CheckLastLineMerge(const basegfx::B2DPolygon
& rSrcPoly
)
559 // #i102706# Do not merge closed polygons
560 if(rSrcPoly
.isClosed())
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
);
573 if(1L == pLastPoly
->GetPathPoly().count())
576 basegfx::B2DPolygon
aDstPoly(pLastPoly
->GetPathPoly().getB2DPolygon(0L));
578 // #i102706# Do not merge closed polygons
579 if(aDstPoly
.isClosed())
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);
594 else if(aDstPoly
.getB2DPoint(0L) == rSrcPoly
.getB2DPoint(nMaxSrcPnt
))
596 basegfx::B2DPolygon
aNew(rSrcPoly
);
597 aNew
.append(aDstPoly
, 1L, aDstPoly
.count() - 1L);
601 else if(aDstPoly
.getB2DPoint(0L) == rSrcPoly
.getB2DPoint(0L))
604 aDstPoly
.append(rSrcPoly
, 1L, rSrcPoly
.count() - 1L);
607 else if(aDstPoly
.getB2DPoint(nMaxDstPnt
) == rSrcPoly
.getB2DPoint(nMaxSrcPnt
))
609 basegfx::B2DPolygon
aNew(rSrcPoly
);
611 aDstPoly
.append(aNew
, 1L, aNew
.count() - 1L);
618 pLastPoly
->NbcSetPathPoly(basegfx::B2DPolyPolygon(aDstPoly
));
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
);
639 if(pLastPoly
->GetPathPoly() == rPolyPolygon
)
643 if(!bNoLine
&& bNoFill
)
645 pLastPoly
->SetMergedItemSet(*pLineAttr
);
657 void ImpSdrGDIMetaFileImport::DoAction( MetaPolyLineAction
& rAct
)
659 // #i73407# reformulation to use new B2DPolygon classes
660 basegfx::B2DPolygon
aSource(rAct
.GetPolygon().getB2DPolygon());
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
);
694 maLineJoin
= basegfx::B2DLINEJOIN_NONE
;
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());
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());
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
) );
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();
799 double a
=nWink
*nPi180
;
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
);
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
);
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
);
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
);
863 ////////////////////////////////////////////////////////////////////////////////////////////////////
865 void ImpSdrGDIMetaFileImport::DoAction( MetaHatchAction
& rAct
)
867 // #i73407# reformulation to use new B2DPolygon classes
868 basegfx::B2DPolyPolygon
aSource(rAct
.GetPolyPolygon().getB2DPolyPolygon());
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 );
884 switch(rHatch
.GetStyle())
888 eStyle
= XHATCH_TRIPLE
;
894 eStyle
= XHATCH_DOUBLE
;
900 eStyle
= XHATCH_SINGLE
;
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
)
922 void ImpSdrGDIMetaFileImport::DoAction(MetaMapModeAction
& rAct
)
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;
938 for ( i
= nMapScalingOfs
; i
< nAnz
; i
++ )
940 SdrObject
* pObj
= aTmpList
.GetObj(i
);
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());
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());
991 SetAttributes(pPath
);
992 aVD
.SetLineColor(aLineColor
);
996 SetAttributes(pPath
);
999 aGradAttr
.Put(XFillStyleItem(XFILL_GRADIENT
));
1000 aGradAttr
.Put(XFillGradientItem(aXGradient
));
1001 pPath
->SetMergedItemSet(aGradAttr
);
1007 aSkipComment
= true;
1013 MetaAction
* pSkipAct
= pMtf
->NextAction();
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
)
1029 const ::vcl::RenderGraphic
& rRenderGraphic
= rAct
.GetRenderGraphic();
1030 Rectangle
aRect( rAct
.GetPoint(), rAct
.GetSize() );
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
) );
1041 SdrGrafObj
* pGraf
=new SdrGrafObj( aMtf
, aRect
);
1047 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */