summaryrefslogtreecommitdiff
path: root/svx/source/svdraw/svdfmtf.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'svx/source/svdraw/svdfmtf.cxx')
-rw-r--r--svx/source/svdraw/svdfmtf.cxx1028
1 files changed, 1028 insertions, 0 deletions
diff --git a/svx/source/svdraw/svdfmtf.cxx b/svx/source/svdraw/svdfmtf.cxx
new file mode 100644
index 000000000000..6a207ca4cba4
--- /dev/null
+++ b/svx/source/svdraw/svdfmtf.cxx
@@ -0,0 +1,1028 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include "svdfmtf.hxx"
+#include <editeng/editdata.hxx>
+#include <math.h>
+#include <svx/xpoly.hxx>
+#include <vcl/svapp.hxx>
+#include <editeng/eeitem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/crsditem.hxx>
+#include <editeng/shdditem.hxx>
+#include <svx/xlnclit.hxx>
+#include <svx/xlnwtit.hxx>
+#include <svx/xflclit.hxx>
+#include <svx/xgrad.hxx>
+#include <svx/xflgrit.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/akrnitem.hxx>
+#include <editeng/wrlmitem.hxx>
+#include <editeng/cntritem.hxx>
+#include <editeng/colritem.hxx>
+#include <vcl/metric.hxx>
+#include <editeng/charscaleitem.hxx>
+#include <svx/xflhtit.hxx>
+#include <svx/svdattr.hxx>
+#include <svx/svdmodel.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdobj.hxx>
+#include "svx/svditext.hxx"
+#include <svx/svdotext.hxx>
+#include <svx/svdorect.hxx>
+#include <svx/svdocirc.hxx>
+#include <svx/svdograf.hxx>
+#include <svx/svdopath.hxx>
+#include <svx/svdetc.hxx>
+#include <svl/itemset.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <vcl/salbtype.hxx> // FRound
+#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
+#include <svx/xlinjoit.hxx>
+#include <svx/xlndsit.hxx>
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ImpSdrGDIMetaFileImport::ImpSdrGDIMetaFileImport(SdrModel& rModel):
+ nMapScalingOfs(0),
+ pLineAttr(NULL),pFillAttr(NULL),pTextAttr(NULL),
+ pPage(NULL),pModel(NULL),nLayer(0),
+ nLineWidth(0),
+ maLineJoin(basegfx::B2DLINEJOIN_NONE),
+ maDash(XDASH_RECT, 0, 0, 0, 0, 0),
+ bFntDirty(sal_True),
+ bLastObjWasPolyWithoutLine(sal_False),bNoLine(sal_False),bNoFill(sal_False),bLastObjWasLine(sal_False)
+{
+ aVD.EnableOutput(sal_False);
+
+ // #i111954# init to no fill and no line initially
+ aVD.SetLineColor();
+ aVD.SetFillColor();
+
+ aOldLineColor.SetRed( aVD.GetLineColor().GetRed() + 1 ); // invalidate old line color
+ pLineAttr=new SfxItemSet(rModel.GetItemPool(),XATTR_LINE_FIRST,XATTR_LINE_LAST);
+ pFillAttr=new SfxItemSet(rModel.GetItemPool(),XATTR_FILL_FIRST,XATTR_FILL_LAST);
+ pTextAttr=new SfxItemSet(rModel.GetItemPool(),EE_ITEMS_START,EE_ITEMS_END);
+ pModel=&rModel;
+}
+
+ImpSdrGDIMetaFileImport::~ImpSdrGDIMetaFileImport()
+{
+ delete pLineAttr;
+ delete pFillAttr;
+ delete pTextAttr;
+}
+
+sal_uIntPtr ImpSdrGDIMetaFileImport::DoImport(const GDIMetaFile& rMtf,
+ SdrObjList& rOL,
+ sal_uIntPtr nInsPos,
+ SvdProgressInfo *pProgrInfo)
+{
+ pPage = rOL.GetPage();
+ GDIMetaFile* pTmpMtf=NULL;
+ GDIMetaFile* pMtf = (GDIMetaFile*) &rMtf;
+ sal_uIntPtr nActionAnz=pMtf->GetActionCount();
+ sal_Bool bError = sal_False;
+
+
+ // setup some global scale parameter
+ // fScaleX, fScaleY, aScaleX, aScaleY, bMov, bSize
+ fScaleX = fScaleY = 1.0;
+ Size aMtfSize( pMtf->GetPrefSize() );
+ if ( aMtfSize.Width() & aMtfSize.Height() && ( aScaleRect.IsEmpty() == sal_False ) )
+ {
+ aOfs = aScaleRect.TopLeft();
+ if ( aMtfSize.Width() != ( aScaleRect.GetWidth() - 1 ) )
+ fScaleX = (double)( aScaleRect.GetWidth() - 1 ) / (double)aMtfSize.Width();
+ if ( aMtfSize.Height() != ( aScaleRect.GetHeight() - 1 ) )
+ fScaleY = (double)( aScaleRect.GetHeight() - 1 ) / (double)aMtfSize.Height();
+ }
+
+ bMov = aOfs.X()!=0 || aOfs.Y()!=0;
+ bSize = sal_False;
+
+ aScaleX = Fraction( 1, 1 );
+ aScaleY = Fraction( 1, 1 );
+ if ( aMtfSize.Width() != ( aScaleRect.GetWidth() - 1 ) )
+ {
+ aScaleX = Fraction( aScaleRect.GetWidth() - 1, aMtfSize.Width() );
+ bSize = sal_True;
+ }
+ if ( aMtfSize.Height() != ( aScaleRect.GetHeight() - 1 ) )
+ {
+ aScaleY = Fraction( aScaleRect.GetHeight() - 1, aMtfSize.Height() );
+ bSize = sal_True;
+ }
+
+ if(65000 < nActionAnz)
+ {
+ nActionAnz = 65000;
+ bError = sal_True;
+ }
+
+ if(pProgrInfo)
+ pProgrInfo->SetActionCount(nActionAnz);
+
+ sal_uIntPtr nActionsToReport = 0;
+
+ for( MetaAction* pAct = pMtf->FirstAction(); pAct; pAct = pMtf->NextAction() )
+ {
+ switch (pAct->GetType())
+ {
+ case META_PIXEL_ACTION : DoAction((MetaPixelAction &)*pAct); break;
+ case META_POINT_ACTION : DoAction((MetaPointAction &)*pAct); break;
+ case META_LINE_ACTION : DoAction((MetaLineAction &)*pAct); break;
+ case META_RECT_ACTION : DoAction((MetaRectAction &)*pAct); break;
+ case META_ROUNDRECT_ACTION : DoAction((MetaRoundRectAction &)*pAct); break;
+ case META_ELLIPSE_ACTION : DoAction((MetaEllipseAction &)*pAct); break;
+ case META_ARC_ACTION : DoAction((MetaArcAction &)*pAct); break;
+ case META_PIE_ACTION : DoAction((MetaPieAction &)*pAct); break;
+ case META_CHORD_ACTION : DoAction((MetaChordAction &)*pAct); break;
+ case META_POLYLINE_ACTION : DoAction((MetaPolyLineAction &)*pAct); break;
+ case META_POLYGON_ACTION : DoAction((MetaPolygonAction &)*pAct); break;
+ case META_POLYPOLYGON_ACTION : DoAction((MetaPolyPolygonAction &)*pAct); break;
+ case META_TEXT_ACTION : DoAction((MetaTextAction &)*pAct); break;
+ case META_TEXTARRAY_ACTION : DoAction((MetaTextArrayAction &)*pAct); break;
+ case META_STRETCHTEXT_ACTION : DoAction((MetaStretchTextAction &)*pAct); break;
+ case META_BMP_ACTION : DoAction((MetaBmpAction &)*pAct); break;
+ case META_BMPSCALE_ACTION : DoAction((MetaBmpScaleAction &)*pAct); break;
+ case META_BMPEX_ACTION : DoAction((MetaBmpExAction &)*pAct); break;
+ case META_BMPEXSCALE_ACTION : DoAction((MetaBmpExScaleAction &)*pAct); break;
+ case META_LINECOLOR_ACTION : DoAction((MetaLineColorAction &)*pAct); break;
+ case META_FILLCOLOR_ACTION : DoAction((MetaFillColorAction &)*pAct); break;
+ case META_TEXTCOLOR_ACTION : DoAction((MetaTextColorAction &)*pAct); break;
+ case META_TEXTFILLCOLOR_ACTION : DoAction((MetaTextFillColorAction &)*pAct); break;
+ case META_FONT_ACTION : DoAction((MetaFontAction &)*pAct); break;
+ case META_TEXTALIGN_ACTION : DoAction((MetaTextAlignAction &)*pAct); break;
+ case META_MAPMODE_ACTION : DoAction((MetaMapModeAction &)*pAct); break;
+ case META_CLIPREGION_ACTION : DoAction((MetaClipRegionAction &)*pAct); break;
+ case META_MOVECLIPREGION_ACTION : DoAction((MetaMoveClipRegionAction &)*pAct); break;
+ case META_ISECTRECTCLIPREGION_ACTION: DoAction((MetaISectRectClipRegionAction&)*pAct); break;
+ case META_ISECTREGIONCLIPREGION_ACTION: DoAction((MetaISectRegionClipRegionAction&)*pAct); break;
+ case META_RASTEROP_ACTION : DoAction((MetaRasterOpAction &)*pAct); break;
+ case META_PUSH_ACTION : DoAction((MetaPushAction &)*pAct); break;
+ case META_POP_ACTION : DoAction((MetaPopAction &)*pAct); break;
+ case META_HATCH_ACTION : DoAction((MetaHatchAction &)*pAct); break;
+ case META_COMMENT_ACTION : DoAction((MetaCommentAction &)*pAct, pMtf); break;
+
+ }
+
+ if(pProgrInfo != NULL)
+ {
+ nActionsToReport++;
+ if(nActionsToReport >= 16) // Alle 16 Action updaten
+ {
+ if(!pProgrInfo->ReportActions(nActionsToReport))
+ break;
+ nActionsToReport = 0;
+ }
+ }
+ }
+
+ if(pProgrInfo != NULL)
+ {
+ pProgrInfo->ReportActions(nActionsToReport);
+ nActionsToReport = 0;
+ }
+
+ // MapMode-Scaling vornehmen
+ MapScaling();
+ // Objekte in vorgegebenes Rechteck hineinskalieren
+ sal_uIntPtr nAnz=aTmpList.GetObjCount();
+
+ // Beim berechnen der Fortschrittsanzeige wird GetActionCount()*3 benutzt.
+ // Da in aTmpList allerdings weniger eintraege als GetActionCount()
+ // existieren koennen, muessen hier die zuviel vermuteten Actionen wieder
+ // hinzugefuegt werden.
+ nActionsToReport = (pMtf->GetActionCount() - nAnz)*2;
+
+
+ // Alle noch nicht gemeldeten Rescales melden
+ if(pProgrInfo)
+ {
+ pProgrInfo->ReportRescales(nActionsToReport);
+ pProgrInfo->SetInsertCount(nAnz);
+ }
+ nActionsToReport = 0;
+
+ // alle in aTmpList zwischengespeicherten Objekte nun in rOL ab der Position nInsPos einfuegen
+ if (nInsPos>rOL.GetObjCount()) nInsPos=rOL.GetObjCount();
+ SdrInsertReason aReason(SDRREASON_VIEWCALL);
+ for (sal_uIntPtr i=0; i<nAnz; i++)
+ {
+ SdrObject* pObj=aTmpList.GetObj(i);
+ rOL.NbcInsertObject(pObj,nInsPos,&aReason);
+ nInsPos++;
+
+ if(pProgrInfo != NULL)
+ {
+ nActionsToReport++;
+ if(nActionsToReport >= 32) // Alle 32 Action updaten
+ {
+ pProgrInfo->ReportInserts(nActionsToReport);
+ nActionsToReport = 0;
+ }
+ }
+ }
+ if (pTmpMtf!=NULL) delete pTmpMtf;
+
+ // ein letztesmal alle verbliebennen Inserts reporten
+ if(pProgrInfo != NULL)
+ {
+ pProgrInfo->ReportInserts(nActionsToReport);
+ if(bError)
+ pProgrInfo->ReportError();
+ }
+
+ return aTmpList.GetObjCount();
+}
+
+void ImpSdrGDIMetaFileImport::SetAttributes(SdrObject* pObj, FASTBOOL bForceTextAttr)
+{
+ bNoLine = sal_False; bNoFill = sal_False;
+ FASTBOOL bLine=sal_True && !bForceTextAttr;
+ FASTBOOL bFill=pObj==NULL || pObj->IsClosedObj() && !bForceTextAttr;
+ FASTBOOL bText=bForceTextAttr || (pObj!=NULL && pObj->GetOutlinerParaObject()!=NULL);
+
+ if ( bLine )
+ {
+ if ( nLineWidth )
+ pLineAttr->Put( XLineWidthItem( nLineWidth ) );
+ else
+ pLineAttr->Put( XLineWidthItem( 0 ) );
+
+ aOldLineColor = aVD.GetLineColor();
+ if( aVD.IsLineColor() )
+ {
+ pLineAttr->Put(XLineStyleItem(XLINE_SOLID));
+ pLineAttr->Put(XLineColorItem(String(), aVD.GetLineColor()));
+ }
+ else
+ pLineAttr->Put(XLineStyleItem(XLINE_NONE));
+
+ switch(maLineJoin)
+ {
+ default : // basegfx::B2DLINEJOIN_NONE
+ pLineAttr->Put(XLineJointItem(XLINEJOINT_NONE));
+ break;
+ case basegfx::B2DLINEJOIN_MIDDLE:
+ pLineAttr->Put(XLineJointItem(XLINEJOINT_MIDDLE));
+ break;
+ case basegfx::B2DLINEJOIN_BEVEL:
+ pLineAttr->Put(XLineJointItem(XLINEJOINT_BEVEL));
+ break;
+ case basegfx::B2DLINEJOIN_MITER:
+ pLineAttr->Put(XLineJointItem(XLINEJOINT_MITER));
+ break;
+ case basegfx::B2DLINEJOIN_ROUND:
+ pLineAttr->Put(XLineJointItem(XLINEJOINT_ROUND));
+ break;
+ }
+
+ if(((maDash.GetDots() && maDash.GetDotLen()) || (maDash.GetDashes() && maDash.GetDashLen())) && maDash.GetDistance())
+ {
+ pLineAttr->Put(XLineDashItem(String(), maDash));
+ }
+ else
+ {
+ pLineAttr->Put(XLineDashItem(String(), XDash(XDASH_RECT)));
+ }
+ }
+ else
+ bNoLine = sal_True;
+
+ if ( bFill )
+ {
+ if( aVD.IsFillColor() )
+ {
+ pFillAttr->Put(XFillStyleItem(XFILL_SOLID));
+ pFillAttr->Put(XFillColorItem(String(), aVD.GetFillColor()));
+ }
+ else
+ pFillAttr->Put(XFillStyleItem(XFILL_NONE));
+ }
+ else
+ bNoFill = sal_True;
+
+ if ( bText && bFntDirty )
+ {
+ Font aFnt(aVD.GetFont());
+ pTextAttr->Put( SvxFontItem( aFnt.GetFamily(), aFnt.GetName(), aFnt.GetStyleName(),
+ aFnt.GetPitch(), aFnt.GetCharSet(), EE_CHAR_FONTINFO ) );
+ pTextAttr->Put( SvxFontItem( aFnt.GetFamily(), aFnt.GetName(), aFnt.GetStyleName(),
+ aFnt.GetPitch(), aFnt.GetCharSet(), EE_CHAR_FONTINFO_CJK ) );
+ pTextAttr->Put( SvxFontItem( aFnt.GetFamily(), aFnt.GetName(), aFnt.GetStyleName(),
+ aFnt.GetPitch(), aFnt.GetCharSet(), EE_CHAR_FONTINFO_CTL ) );
+ pTextAttr->Put(SvxPostureItem(aFnt.GetItalic(), EE_CHAR_ITALIC));
+ pTextAttr->Put(SvxWeightItem(aFnt.GetWeight(), EE_CHAR_WEIGHT));
+ sal_uInt32 nHeight = FRound(aFnt.GetSize().Height() * fScaleY);
+ pTextAttr->Put( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT ) );
+ pTextAttr->Put( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT_CJK ) );
+ pTextAttr->Put( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT_CTL ) );
+ pTextAttr->Put(SvxCharScaleWidthItem(100, EE_CHAR_FONTWIDTH));
+ pTextAttr->Put(SvxUnderlineItem(aFnt.GetUnderline(), EE_CHAR_UNDERLINE));
+ pTextAttr->Put(SvxOverlineItem(aFnt.GetOverline(), EE_CHAR_OVERLINE));
+ pTextAttr->Put(SvxCrossedOutItem(aFnt.GetStrikeout(), EE_CHAR_STRIKEOUT));
+ pTextAttr->Put(SvxShadowedItem(aFnt.IsShadow(), EE_CHAR_SHADOW));
+ pTextAttr->Put(SvxAutoKernItem(aFnt.IsKerning(), EE_CHAR_KERNING));
+ pTextAttr->Put(SvxWordLineModeItem(aFnt.IsWordLineMode(), EE_CHAR_WLM));
+ pTextAttr->Put(SvxContourItem(aFnt.IsOutline(), EE_CHAR_OUTLINE));
+ pTextAttr->Put(SvxColorItem(aFnt.GetColor(), EE_CHAR_COLOR));
+ //... svxfont textitem svditext
+ bFntDirty=sal_False;
+ }
+ if (pObj!=NULL)
+ {
+ pObj->SetLayer(nLayer);
+ if (bLine) pObj->SetMergedItemSet(*pLineAttr);
+ if (bFill) pObj->SetMergedItemSet(*pFillAttr);
+ if (bText)
+ {
+ pObj->SetMergedItemSet(*pTextAttr);
+ pObj->SetMergedItem( SdrTextHorzAdjustItem( SDRTEXTHORZADJUST_LEFT ) );
+ }
+ }
+}
+
+void ImpSdrGDIMetaFileImport::InsertObj( SdrObject* pObj, sal_Bool bScale )
+{
+ if ( bScale && !aScaleRect.IsEmpty() )
+ {
+ if ( bSize )
+ pObj->NbcResize( Point(), aScaleX, aScaleY );
+ if ( bMov )
+ pObj->NbcMove( Size( aOfs.X(), aOfs.Y() ) );
+ }
+
+ // #i111954# check object for visibility
+ // used are SdrPathObj, SdrRectObj, SdrCircObj, SdrGrafObj
+ bool bVisible(false);
+
+ if(pObj->HasLineStyle())
+ {
+ bVisible = true;
+ }
+
+ if(!bVisible && pObj->HasFillStyle())
+ {
+ bVisible = true;
+ }
+
+ if(!bVisible)
+ {
+ SdrTextObj* pTextObj = dynamic_cast< SdrTextObj* >(pObj);
+
+ if(pTextObj && pTextObj->HasText())
+ {
+ bVisible = true;
+ }
+ }
+
+ if(!bVisible)
+ {
+ SdrGrafObj* pGrafObj = dynamic_cast< SdrGrafObj* >(pObj);
+
+ if(pGrafObj)
+ {
+ // this may be refined to check if the graphic really is visible. It
+ // is here to ensure that graphic objects without fill, line and text
+ // get created
+ bVisible = true;
+ }
+ }
+
+ if(!bVisible)
+ {
+ SdrObject::Free(pObj);
+ }
+ else
+ {
+ aTmpList.InsertObject( pObj );
+ if ( HAS_BASE( SdrPathObj, pObj ) )
+ {
+ FASTBOOL bClosed=pObj->IsClosedObj();
+ bLastObjWasPolyWithoutLine=bNoLine && bClosed;
+ bLastObjWasLine=!bClosed;
+ }
+ else
+ {
+ bLastObjWasPolyWithoutLine = sal_False;
+ bLastObjWasLine = sal_False;
+ }
+ }
+}
+
+/**************************************************************************************************/
+
+void ImpSdrGDIMetaFileImport::DoAction(MetaPixelAction& /*rAct*/)
+{
+}
+
+void ImpSdrGDIMetaFileImport::DoAction(MetaPointAction& /*rAct*/)
+{
+}
+
+void ImpSdrGDIMetaFileImport::DoAction(MetaLineAction& rAct)
+{
+ // #i73407# reformulation to use new B2DPolygon classes
+ const basegfx::B2DPoint aStart(rAct.GetStartPoint().X(), rAct.GetStartPoint().Y());
+ const basegfx::B2DPoint aEnd(rAct.GetEndPoint().X(), rAct.GetEndPoint().Y());
+
+ if(!aStart.equal(aEnd))
+ {
+ basegfx::B2DPolygon aLine;
+ const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(fScaleX, fScaleY, aOfs.X(), aOfs.Y()));
+
+ aLine.append(aStart);
+ aLine.append(aEnd);
+ aLine.transform(aTransform);
+
+ const LineInfo& rLineInfo = rAct.GetLineInfo();
+ const sal_Int32 nNewLineWidth(rLineInfo.GetWidth());
+ bool bCreateLineObject(true);
+
+ if(bLastObjWasLine && (nNewLineWidth == nLineWidth) && CheckLastLineMerge(aLine))
+ {
+ bCreateLineObject = false;
+ }
+
+ if(bCreateLineObject)
+ {
+ SdrPathObj* pPath = new SdrPathObj(OBJ_LINE, basegfx::B2DPolyPolygon(aLine));
+ nLineWidth = nNewLineWidth;
+ maLineJoin = rLineInfo.GetLineJoin();
+ maDash = XDash(XDASH_RECT,
+ rLineInfo.GetDotCount(), rLineInfo.GetDotLen(),
+ rLineInfo.GetDashCount(), rLineInfo.GetDashLen(),
+ rLineInfo.GetDistance());
+ SetAttributes(pPath);
+ nLineWidth = 0;
+ maLineJoin = basegfx::B2DLINEJOIN_NONE;
+ maDash = XDash();
+ InsertObj(pPath, false);
+ }
+ }
+}
+
+void ImpSdrGDIMetaFileImport::DoAction(MetaRectAction& rAct)
+{
+ SdrRectObj* pRect=new SdrRectObj(rAct.GetRect());
+ SetAttributes(pRect);
+ InsertObj(pRect);
+}
+
+void ImpSdrGDIMetaFileImport::DoAction(MetaRoundRectAction& rAct)
+{
+ SdrRectObj* pRect=new SdrRectObj(rAct.GetRect());
+ SetAttributes(pRect);
+ long nRad=(rAct.GetHorzRound()+rAct.GetVertRound())/2;
+ if (nRad!=0) {
+ SfxItemSet aSet(*pLineAttr->GetPool(),SDRATTR_ECKENRADIUS,SDRATTR_ECKENRADIUS);
+ aSet.Put(SdrEckenradiusItem(nRad));
+ pRect->SetMergedItemSet(aSet);
+ }
+ InsertObj(pRect);
+}
+
+/**************************************************************************************************/
+
+void ImpSdrGDIMetaFileImport::DoAction(MetaEllipseAction& rAct)
+{
+ SdrCircObj* pCirc=new SdrCircObj(OBJ_CIRC,rAct.GetRect());
+ SetAttributes(pCirc);
+ InsertObj(pCirc);
+}
+
+void ImpSdrGDIMetaFileImport::DoAction(MetaArcAction& rAct)
+{
+ Point aCenter(rAct.GetRect().Center());
+ long nStart=GetAngle(rAct.GetStartPoint()-aCenter);
+ long nEnd=GetAngle(rAct.GetEndPoint()-aCenter);
+ SdrCircObj* pCirc=new SdrCircObj(OBJ_CARC,rAct.GetRect(),nStart,nEnd);
+ SetAttributes(pCirc);
+ InsertObj(pCirc);
+}
+
+void ImpSdrGDIMetaFileImport::DoAction(MetaPieAction& rAct)
+{
+ Point aCenter(rAct.GetRect().Center());
+ long nStart=GetAngle(rAct.GetStartPoint()-aCenter);
+ long nEnd=GetAngle(rAct.GetEndPoint()-aCenter);
+ SdrCircObj* pCirc=new SdrCircObj(OBJ_SECT,rAct.GetRect(),nStart,nEnd);
+ SetAttributes(pCirc);
+ InsertObj(pCirc);
+}
+
+void ImpSdrGDIMetaFileImport::DoAction(MetaChordAction& rAct)
+{
+ Point aCenter(rAct.GetRect().Center());
+ long nStart=GetAngle(rAct.GetStartPoint()-aCenter);
+ long nEnd=GetAngle(rAct.GetEndPoint()-aCenter);
+ SdrCircObj* pCirc=new SdrCircObj(OBJ_CCUT,rAct.GetRect(),nStart,nEnd);
+ SetAttributes(pCirc);
+ InsertObj(pCirc);
+}
+
+/**************************************************************************************************/
+
+bool ImpSdrGDIMetaFileImport::CheckLastLineMerge(const basegfx::B2DPolygon& rSrcPoly)
+{
+ // #i102706# Do not merge closed polygons
+ if(rSrcPoly.isClosed())
+ {
+ return false;
+ }
+
+ // #i73407# reformulation to use new B2DPolygon classes
+ if(bLastObjWasLine && (aOldLineColor == aVD.GetLineColor()) && rSrcPoly.count())
+ {
+ SdrObject* pTmpObj = aTmpList.GetObj(aTmpList.GetObjCount() - 1);
+ SdrPathObj* pLastPoly = PTR_CAST(SdrPathObj, pTmpObj);
+
+ if(pLastPoly)
+ {
+ if(1L == pLastPoly->GetPathPoly().count())
+ {
+ bool bOk(false);
+ basegfx::B2DPolygon aDstPoly(pLastPoly->GetPathPoly().getB2DPolygon(0L));
+
+ // #i102706# Do not merge closed polygons
+ if(aDstPoly.isClosed())
+ {
+ return false;
+ }
+
+ if(aDstPoly.count())
+ {
+ const sal_uInt32 nMaxDstPnt(aDstPoly.count() - 1L);
+ const sal_uInt32 nMaxSrcPnt(rSrcPoly.count() - 1L);
+
+ if(aDstPoly.getB2DPoint(nMaxDstPnt) == rSrcPoly.getB2DPoint(0L))
+ {
+ aDstPoly.append(rSrcPoly, 1L, rSrcPoly.count() - 1L);
+ bOk = true;
+ }
+ else if(aDstPoly.getB2DPoint(0L) == rSrcPoly.getB2DPoint(nMaxSrcPnt))
+ {
+ basegfx::B2DPolygon aNew(rSrcPoly);
+ aNew.append(aDstPoly, 1L, aDstPoly.count() - 1L);
+ aDstPoly = aNew;
+ bOk = true;
+ }
+ else if(aDstPoly.getB2DPoint(0L) == rSrcPoly.getB2DPoint(0L))
+ {
+ aDstPoly.flip();
+ aDstPoly.append(rSrcPoly, 1L, rSrcPoly.count() - 1L);
+ bOk = true;
+ }
+ else if(aDstPoly.getB2DPoint(nMaxDstPnt) == rSrcPoly.getB2DPoint(nMaxSrcPnt))
+ {
+ basegfx::B2DPolygon aNew(rSrcPoly);
+ aNew.flip();
+ aDstPoly.append(aNew, 1L, aNew.count() - 1L);
+ bOk = true;
+ }
+ }
+
+ if(bOk)
+ {
+ pLastPoly->NbcSetPathPoly(basegfx::B2DPolyPolygon(aDstPoly));
+ }
+
+ return bOk;
+ }
+ }
+ }
+
+ return false;
+}
+
+bool ImpSdrGDIMetaFileImport::CheckLastPolyLineAndFillMerge(const basegfx::B2DPolyPolygon & rPolyPolygon)
+{
+ // #i73407# reformulation to use new B2DPolygon classes
+ if(bLastObjWasPolyWithoutLine)
+ {
+ SdrObject* pTmpObj = aTmpList.GetObj(aTmpList.GetObjCount() - 1);
+ SdrPathObj* pLastPoly = PTR_CAST(SdrPathObj, pTmpObj);
+
+ if(pLastPoly)
+ {
+ if(pLastPoly->GetPathPoly() == rPolyPolygon)
+ {
+ SetAttributes(NULL);
+
+ if(!bNoLine && bNoFill)
+ {
+ pLastPoly->SetMergedItemSet(*pLineAttr);
+
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
+
+void ImpSdrGDIMetaFileImport::DoAction( MetaPolyLineAction& rAct )
+{
+ // #i73407# reformulation to use new B2DPolygon classes
+ basegfx::B2DPolygon aSource(rAct.GetPolygon().getB2DPolygon());
+
+ if(aSource.count())
+ {
+ const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(fScaleX, fScaleY, aOfs.X(), aOfs.Y()));
+ aSource.transform(aTransform);
+ }
+
+ const LineInfo& rLineInfo = rAct.GetLineInfo();
+ const sal_Int32 nNewLineWidth(rLineInfo.GetWidth());
+ bool bCreateLineObject(true);
+
+ if(bLastObjWasLine && (nNewLineWidth == nLineWidth) && CheckLastLineMerge(aSource))
+ {
+ bCreateLineObject = false;
+ }
+ else if(bLastObjWasPolyWithoutLine && CheckLastPolyLineAndFillMerge(basegfx::B2DPolyPolygon(aSource)))
+ {
+ bCreateLineObject = false;
+ }
+
+ if(bCreateLineObject)
+ {
+ SdrPathObj* pPath = new SdrPathObj(
+ aSource.isClosed() ? OBJ_POLY : OBJ_PLIN,
+ basegfx::B2DPolyPolygon(aSource));
+ nLineWidth = nNewLineWidth;
+ maLineJoin = rLineInfo.GetLineJoin();
+ maDash = XDash(XDASH_RECT,
+ rLineInfo.GetDotCount(), rLineInfo.GetDotLen(),
+ rLineInfo.GetDashCount(), rLineInfo.GetDashLen(),
+ rLineInfo.GetDistance());
+ SetAttributes(pPath);
+ nLineWidth = 0;
+ maLineJoin = basegfx::B2DLINEJOIN_NONE;
+ maDash = XDash();
+ InsertObj(pPath, false);
+ }
+}
+
+void ImpSdrGDIMetaFileImport::DoAction( MetaPolygonAction& rAct )
+{
+ // #i73407# reformulation to use new B2DPolygon classes
+ basegfx::B2DPolygon aSource(rAct.GetPolygon().getB2DPolygon());
+
+ if(aSource.count())
+ {
+ const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(fScaleX, fScaleY, aOfs.X(), aOfs.Y()));
+ aSource.transform(aTransform);
+
+ if(!bLastObjWasPolyWithoutLine || !CheckLastPolyLineAndFillMerge(basegfx::B2DPolyPolygon(aSource)))
+ {
+ // #i73407# make sure polygon is closed, it's a filled primitive
+ aSource.setClosed(true);
+
+ SdrPathObj* pPath = new SdrPathObj(OBJ_POLY, basegfx::B2DPolyPolygon(aSource));
+ SetAttributes(pPath);
+ InsertObj(pPath, false);
+ }
+ }
+}
+
+void ImpSdrGDIMetaFileImport::DoAction(MetaPolyPolygonAction& rAct)
+{
+ // #i73407# reformulation to use new B2DPolygon classes
+ basegfx::B2DPolyPolygon aSource(rAct.GetPolyPolygon().getB2DPolyPolygon());
+
+ if(aSource.count())
+ {
+ const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(fScaleX, fScaleY, aOfs.X(), aOfs.Y()));
+ aSource.transform(aTransform);
+
+ if(!bLastObjWasPolyWithoutLine || !CheckLastPolyLineAndFillMerge(aSource))
+ {
+ // #i73407# make sure polygon is closed, it's a filled primitive
+ aSource.setClosed(true);
+
+ SdrPathObj* pPath = new SdrPathObj(OBJ_POLY, aSource);
+ SetAttributes(pPath);
+ InsertObj(pPath, false);
+ }
+ }
+}
+
+/**************************************************************************************************/
+
+void ImpSdrGDIMetaFileImport::ImportText( const Point& rPos, const XubString& rStr, const MetaAction& rAct )
+{
+ // calc text box size, add 5% to make it fit safely
+
+ FontMetric aFontMetric( aVD.GetFontMetric() );
+ Font aFnt( aVD.GetFont() );
+ FontAlign eAlg( aFnt.GetAlign() );
+
+ sal_Int32 nTextWidth = (sal_Int32)( aVD.GetTextWidth( rStr ) * fScaleX );
+ sal_Int32 nTextHeight = (sal_Int32)( aVD.GetTextHeight() * fScaleY );
+ //sal_Int32 nDxWidth = 0;
+ //sal_Int32 nLen = rStr.Len();
+
+ Point aPos( FRound(rPos.X() * fScaleX + aOfs.X()), FRound(rPos.Y() * fScaleY + aOfs.Y()) );
+ Size aSize( nTextWidth, nTextHeight );
+
+ if ( eAlg == ALIGN_BASELINE )
+ aPos.Y() -= FRound(aFontMetric.GetAscent() * fScaleY);
+ else if ( eAlg == ALIGN_BOTTOM )
+ aPos.Y() -= nTextHeight;
+
+ Rectangle aTextRect( aPos, aSize );
+ SdrRectObj* pText =new SdrRectObj( OBJ_TEXT, aTextRect );
+
+ if ( aFnt.GetWidth() || ( rAct.GetType() == META_STRETCHTEXT_ACTION ) )
+ {
+ pText->ClearMergedItem( SDRATTR_TEXT_AUTOGROWWIDTH );
+ pText->SetMergedItem( SdrTextAutoGrowHeightItem( sal_False ) );
+ // don't let the margins eat the space needed for the text
+ pText->SetMergedItem ( SdrTextUpperDistItem (0));
+ pText->SetMergedItem ( SdrTextLowerDistItem (0));
+ pText->SetMergedItem ( SdrTextRightDistItem (0));
+ pText->SetMergedItem ( SdrTextLeftDistItem (0));
+ pText->SetMergedItem( SdrTextFitToSizeTypeItem( SDRTEXTFIT_ALLLINES ) );
+ }
+ else
+ pText->SetMergedItem( SdrTextAutoGrowWidthItem( sal_True ) );
+
+ pText->SetModel( pModel );
+ pText->SetLayer( nLayer );
+ pText->NbcSetText( rStr );
+ SetAttributes( pText, sal_True );
+ pText->SetSnapRect( aTextRect );
+
+ if (!aFnt.IsTransparent())
+ {
+ SfxItemSet aAttr(*pFillAttr->GetPool(),XATTR_FILL_FIRST,XATTR_FILL_LAST);
+ aAttr.Put(XFillStyleItem(XFILL_SOLID));
+ aAttr.Put(XFillColorItem(String(), aFnt.GetFillColor()));
+ pText->SetMergedItemSet(aAttr);
+ }
+ sal_uInt32 nWink = aFnt.GetOrientation();
+ if ( nWink )
+ {
+ nWink*=10;
+ double a=nWink*nPi180;
+ double nSin=sin(a);
+ double nCos=cos(a);
+ pText->NbcRotate(aPos,nWink,nSin,nCos);
+ }
+ InsertObj( pText, sal_False );
+}
+
+void ImpSdrGDIMetaFileImport::DoAction(MetaTextAction& rAct)
+{
+ XubString aStr(rAct.GetText());
+ aStr.Erase(0,rAct.GetIndex());
+ aStr.Erase(rAct.GetLen());
+ ImportText( rAct.GetPoint(), aStr, rAct );
+}
+
+void ImpSdrGDIMetaFileImport::DoAction(MetaTextArrayAction& rAct)
+{
+ XubString aStr(rAct.GetText());
+ aStr.Erase(0,rAct.GetIndex());
+ aStr.Erase(rAct.GetLen());
+ ImportText( rAct.GetPoint(), aStr, rAct );
+}
+
+void ImpSdrGDIMetaFileImport::DoAction(MetaStretchTextAction& rAct)
+{
+ XubString aStr(rAct.GetText());
+ aStr.Erase(0,rAct.GetIndex());
+ aStr.Erase(rAct.GetLen());
+ ImportText( rAct.GetPoint(), aStr, rAct );
+}
+
+void ImpSdrGDIMetaFileImport::DoAction(MetaBmpAction& rAct)
+{
+ Rectangle aRect(rAct.GetPoint(),rAct.GetBitmap().GetSizePixel());
+ aRect.Right()++; aRect.Bottom()++;
+ SdrGrafObj* pGraf=new SdrGrafObj(Graphic(rAct.GetBitmap()),aRect);
+ InsertObj(pGraf);
+}
+
+void ImpSdrGDIMetaFileImport::DoAction(MetaBmpScaleAction& rAct)
+{
+ Rectangle aRect(rAct.GetPoint(),rAct.GetSize());
+ aRect.Right()++; aRect.Bottom()++;
+ SdrGrafObj* pGraf=new SdrGrafObj(Graphic(rAct.GetBitmap()),aRect);
+ InsertObj(pGraf);
+}
+
+void ImpSdrGDIMetaFileImport::DoAction(MetaBmpExAction& rAct)
+{
+ Rectangle aRect(rAct.GetPoint(),rAct.GetBitmapEx().GetSizePixel());
+ aRect.Right()++; aRect.Bottom()++;
+ SdrGrafObj* pGraf=new SdrGrafObj( rAct.GetBitmapEx(), aRect );
+ InsertObj(pGraf);
+}
+
+void ImpSdrGDIMetaFileImport::DoAction(MetaBmpExScaleAction& rAct)
+{
+ Rectangle aRect(rAct.GetPoint(),rAct.GetSize());
+ aRect.Right()++; aRect.Bottom()++;
+ SdrGrafObj* pGraf=new SdrGrafObj( rAct.GetBitmapEx(), aRect );
+ InsertObj(pGraf);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void ImpSdrGDIMetaFileImport::DoAction( MetaHatchAction& rAct )
+{
+ // #i73407# reformulation to use new B2DPolygon classes
+ basegfx::B2DPolyPolygon aSource(rAct.GetPolyPolygon().getB2DPolyPolygon());
+
+ if(aSource.count())
+ {
+ const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(fScaleX, fScaleY, aOfs.X(), aOfs.Y()));
+ aSource.transform(aTransform);
+
+ if(!bLastObjWasPolyWithoutLine || !CheckLastPolyLineAndFillMerge(aSource))
+ {
+ const Hatch& rHatch = rAct.GetHatch();
+ SdrPathObj* pPath = new SdrPathObj(OBJ_POLY, aSource);
+ SfxItemSet aHatchAttr(pModel->GetItemPool(),
+ XATTR_FILLSTYLE, XATTR_FILLSTYLE,
+ XATTR_FILLHATCH, XATTR_FILLHATCH, 0, 0 );
+ XHatchStyle eStyle;
+
+ switch(rHatch.GetStyle())
+ {
+ case(HATCH_TRIPLE) :
+ {
+ eStyle = XHATCH_TRIPLE;
+ break;
+ }
+
+ case(HATCH_DOUBLE) :
+ {
+ eStyle = XHATCH_DOUBLE;
+ break;
+ }
+
+ default:
+ {
+ eStyle = XHATCH_SINGLE;
+ break;
+ }
+ }
+
+ SetAttributes(pPath);
+ aHatchAttr.Put(XFillStyleItem(XFILL_HATCH));
+ aHatchAttr.Put(XFillHatchItem(&pModel->GetItemPool(), XHatch(rHatch.GetColor(), eStyle, rHatch.GetDistance(), rHatch.GetAngle())));
+ pPath->SetMergedItemSet(aHatchAttr);
+
+ InsertObj(pPath, false);
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void ImpSdrGDIMetaFileImport::DoAction(MetaLineColorAction& rAct)
+{
+ rAct.Execute(&aVD);
+}
+
+void ImpSdrGDIMetaFileImport::DoAction(MetaMapModeAction& rAct)
+{
+ MapScaling();
+ rAct.Execute(&aVD);
+ bLastObjWasPolyWithoutLine=sal_False;
+ bLastObjWasLine=sal_False;
+}
+
+void ImpSdrGDIMetaFileImport::MapScaling()
+{
+ sal_uInt32 i, nAnz = aTmpList.GetObjCount();
+ const MapMode& rMap = aVD.GetMapMode();
+ Point aMapOrg( rMap.GetOrigin() );
+ sal_Bool bMov2 = aMapOrg.X() != 0 || aMapOrg.Y() != 0;
+ if ( bMov2 )
+ {
+ for ( i = nMapScalingOfs; i < nAnz; i++ )
+ {
+ SdrObject* pObj = aTmpList.GetObj(i);
+ if ( bMov2 )
+ pObj->NbcMove( Size( aMapOrg.X(), aMapOrg.Y() ) );
+ }
+ }
+ nMapScalingOfs = nAnz;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void ImpSdrGDIMetaFileImport::DoAction( MetaCommentAction& rAct, GDIMetaFile* pMtf )
+{
+ ByteString aSkipComment;
+
+ if( rAct.GetComment().CompareIgnoreCaseToAscii( "XGRAD_SEQ_BEGIN" ) == COMPARE_EQUAL )
+ {
+ MetaGradientExAction* pAct = (MetaGradientExAction*) pMtf->NextAction();
+
+ if( pAct && pAct->GetType() == META_GRADIENTEX_ACTION )
+ {
+ // #i73407# reformulation to use new B2DPolygon classes
+ basegfx::B2DPolyPolygon aSource(pAct->GetPolyPolygon().getB2DPolyPolygon());
+
+ if(aSource.count())
+ {
+ if(!bLastObjWasPolyWithoutLine || !CheckLastPolyLineAndFillMerge(aSource))
+ {
+ const Gradient& rGrad = pAct->GetGradient();
+ SdrPathObj* pPath = new SdrPathObj(OBJ_POLY, aSource);
+ SfxItemSet aGradAttr(pModel->GetItemPool(),
+ XATTR_FILLSTYLE, XATTR_FILLSTYLE,
+ XATTR_FILLGRADIENT, XATTR_FILLGRADIENT, 0, 0 );
+ XGradient aXGradient;
+
+ aXGradient.SetGradientStyle((XGradientStyle)rGrad.GetStyle());
+ aXGradient.SetStartColor(rGrad.GetStartColor());
+ aXGradient.SetEndColor(rGrad.GetEndColor());
+ aXGradient.SetAngle((sal_uInt16)rGrad.GetAngle());
+ aXGradient.SetBorder(rGrad.GetBorder());
+ aXGradient.SetXOffset(rGrad.GetOfsX());
+ aXGradient.SetYOffset(rGrad.GetOfsY());
+ aXGradient.SetStartIntens(rGrad.GetStartIntensity());
+ aXGradient.SetEndIntens(rGrad.GetEndIntensity());
+ aXGradient.SetSteps(rGrad.GetSteps());
+
+ if(aVD.IsLineColor())
+ {
+ // switch line off; when there was one there will be a
+ // META_POLYLINE_ACTION following creating another object
+ const Color aLineColor(aVD.GetLineColor());
+ aVD.SetLineColor();
+ SetAttributes(pPath);
+ aVD.SetLineColor(aLineColor);
+ }
+ else
+ {
+ SetAttributes(pPath);
+ }
+
+ aGradAttr.Put(XFillStyleItem(XFILL_GRADIENT));
+ aGradAttr.Put(XFillGradientItem(&pModel->GetItemPool(), aXGradient));
+ pPath->SetMergedItemSet(aGradAttr);
+
+ InsertObj(pPath);
+ }
+ }
+
+ aSkipComment = "XGRAD_SEQ_END";
+ }
+ }
+
+ if(aSkipComment.Len())
+ {
+ MetaAction* pSkipAct = pMtf->NextAction();
+
+ while( pSkipAct
+ && ((pSkipAct->GetType() != META_COMMENT_ACTION )
+ || (((MetaCommentAction*)pSkipAct)->GetComment().CompareIgnoreCaseToAscii(aSkipComment.GetBuffer()) != COMPARE_EQUAL)))
+ {
+ pSkipAct = pMtf->NextAction();
+ }
+ }
+}
+
+// eof