diff options
author | Armin Le Grand <alg@apache.org> | 2012-05-08 08:27:10 +0000 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2013-03-13 13:40:41 +0000 |
commit | 684c502ed0a6782fe1b9c7d7cd1911a4a88b543a (patch) | |
tree | 25c0e098a8dc307d51fd722e5a7a856ea901609a /svx | |
parent | ec8d4b1d23e85cc27f1d08e1b1ed9c18e63f7a3c (diff) |
Related: #119125# Added usage of the ClipRegion for dismantling Metafiles
to SdrObjects (ImpSdrGDIMetaFileImport) as good as possible with Metafile usage
Conflicts:
svx/source/svdraw/svdfmtf.cxx
svx/source/svdraw/svdfmtf.hxx
Change-Id: I41422696e97f919e618f7e385c68d4ac737a52c1
Diffstat (limited to 'svx')
-rw-r--r-- | svx/source/svdraw/svdfmtf.cxx | 174 | ||||
-rw-r--r-- | svx/source/svdraw/svdfmtf.hxx | 20 | ||||
-rw-r--r-- | svx/source/svdraw/svdxcgv.cxx | 32 |
3 files changed, 164 insertions, 62 deletions
diff --git a/svx/source/svdraw/svdfmtf.cxx b/svx/source/svdraw/svdfmtf.cxx index 7e38fc6e5f22..1d9b94840f31 100644 --- a/svx/source/svdraw/svdfmtf.cxx +++ b/svx/source/svdraw/svdfmtf.cxx @@ -61,6 +61,8 @@ #include <basegfx/matrix/b2dhommatrixtools.hxx> #include <svx/xlinjoit.hxx> #include <svx/xlndsit.hxx> +#include <basegfx/polygon/b2dpolygonclipper.hxx> +#include <svx/xbtmpit.hxx> //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -74,7 +76,11 @@ ImpSdrGDIMetaFileImport::ImpSdrGDIMetaFileImport(SdrModel& rModel): maDash(XDASH_RECT, 0, 0, 0, 0, 0), fScaleX(0.0),fScaleY(0.0), bFntDirty(sal_True), - bLastObjWasPolyWithoutLine(sal_False),bNoLine(sal_False),bNoFill(sal_False),bLastObjWasLine(sal_False) + bLastObjWasPolyWithoutLine(sal_False), + bNoLine(sal_False), + bNoFill(sal_False), + bLastObjWasLine(sal_False), + maClip() { aVD.EnableOutput(sal_False); @@ -87,6 +93,7 @@ ImpSdrGDIMetaFileImport::ImpSdrGDIMetaFileImport(SdrModel& rModel): pFillAttr=new SfxItemSet(rModel.GetItemPool(),XATTR_FILL_FIRST,XATTR_FILL_LAST); pTextAttr=new SfxItemSet(rModel.GetItemPool(),EE_ITEMS_START,EE_ITEMS_END); pModel=&rModel; + checkClip(); } ImpSdrGDIMetaFileImport::~ImpSdrGDIMetaFileImport() @@ -371,7 +378,7 @@ void ImpSdrGDIMetaFileImport::SetAttributes(SdrObject* pObj, bool bForceTextAttr } } -void ImpSdrGDIMetaFileImport::InsertObj( SdrObject* pObj, sal_Bool bScale ) +void ImpSdrGDIMetaFileImport::InsertObj(SdrObject* pObj, sal_Bool bScale) { if ( bScale && !aScaleRect.IsEmpty() ) { @@ -381,60 +388,123 @@ void ImpSdrGDIMetaFileImport::InsertObj( SdrObject* pObj, sal_Bool bScale ) pObj->NbcMove( Size( aOfs.X(), aOfs.Y() ) ); } - // #i111954# check object for visibility - // used are SdrPathObj, SdrRectObj, SdrCircObj, SdrGrafObj - bool bVisible(false); - - if(pObj->HasLineStyle()) + if(isClip()) { - bVisible = true; - } + const basegfx::B2DPolyPolygon aPoly(pObj->TakeXorPoly()); + const basegfx::B2DRange aOldRange(aPoly.getB2DRange()); + const SdrLayerID aOldLayer(pObj->GetLayer()); + const SfxItemSet aOldItemSet(pObj->GetMergedItemSet()); + const SdrGrafObj* pSdrGrafObj = dynamic_cast< SdrGrafObj* >(pObj); + BitmapEx aBitmapEx; + + if(pSdrGrafObj) + { + aBitmapEx = pSdrGrafObj->GetGraphic().GetBitmapEx(); + } - if(!bVisible && pObj->HasFillStyle()) - { - bVisible = true; + SdrObject::Free(pObj); + + if(!aOldRange.isEmpty()) + { + // clip against ClipRegion + const basegfx::B2DPolyPolygon aNewPoly( + basegfx::tools::clipPolyPolygonOnPolyPolygon( + aPoly, + maClip, + true, + aPoly.isClosed() ? false : true)); + const basegfx::B2DRange aNewRange(aNewPoly.getB2DRange()); + + if(!aNewRange.isEmpty()) + { + pObj = new SdrPathObj( + aNewPoly.isClosed() ? OBJ_POLY : OBJ_PLIN, + aNewPoly); + + pObj->SetLayer(aOldLayer); + pObj->SetMergedItemSet(aOldItemSet); + + if(!!aBitmapEx) + { + // aNewRange is inside of aOldRange and defines which part of aBitmapEx is used + const double fLclScaleX(aBitmapEx.GetSizePixel().Width() / (aOldRange.getWidth() ? aOldRange.getWidth() : 1.0)); + const double fLclScaleY(aBitmapEx.GetSizePixel().Height() / (aOldRange.getHeight() ? aOldRange.getHeight() : 1.0)); + basegfx::B2DRange aPixel(aNewRange); + basegfx::B2DHomMatrix aTrans; + + aTrans.translate(-aOldRange.getMinX(), -aOldRange.getMinY()); + aTrans.scale(fLclScaleX, fLclScaleY); + aPixel.transform(aTrans); + + const BitmapEx aClippedBitmap( + aBitmapEx, + Point(floor(std::max(0.0, aPixel.getMinX())), floor(std::max(0.0, aPixel.getMinY()))), + Size(ceil(aPixel.getWidth()), ceil(aPixel.getHeight()))); + + pObj->SetMergedItem(XFillStyleItem(XFILL_BITMAP)); + pObj->SetMergedItem(XFillBitmapItem(String(), aClippedBitmap.GetBitmap())); + } + } + } } - if(!bVisible) + if(pObj) { - SdrTextObj* pTextObj = dynamic_cast< SdrTextObj* >(pObj); + // #i111954# check object for visibility + // used are SdrPathObj, SdrRectObj, SdrCircObj, SdrGrafObj + bool bVisible(false); - if(pTextObj && pTextObj->HasText()) + if(pObj->HasLineStyle()) { bVisible = true; } - } - - if(!bVisible) - { - SdrGrafObj* pGrafObj = dynamic_cast< SdrGrafObj* >(pObj); - if(pGrafObj) + if(!bVisible && pObj->HasFillStyle()) { - // 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.push_back( pObj ); - if ( HAS_BASE( SdrPathObj, pObj ) ) + if(!bVisible) { - bool bClosed=pObj->IsClosedObj(); - bLastObjWasPolyWithoutLine=bNoLine && bClosed; - bLastObjWasLine=!bClosed; + 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 { - bLastObjWasPolyWithoutLine = sal_False; - bLastObjWasLine = sal_False; + aTmpList.push_back( pObj ); + if ( HAS_BASE( SdrPathObj, pObj ) ) + { + bool bClosed=pObj->IsClosedObj(); + bLastObjWasPolyWithoutLine=bNoLine && bClosed; + bLastObjWasLine=!bClosed; + } + else + { + bLastObjWasPolyWithoutLine = sal_False; + bLastObjWasLine = sal_False; + } } } } @@ -651,6 +721,32 @@ bool ImpSdrGDIMetaFileImport::CheckLastPolyLineAndFillMerge(const basegfx::B2DPo return false; } +void ImpSdrGDIMetaFileImport::checkClip() +{ + if(aVD.IsClipRegion()) + { + Region aRegion(aVD.GetClipRegion()); + + maClip = aRegion.ConvertToB2DPolyPolygon(); + + if(isClip()) + { + const basegfx::B2DHomMatrix aTransform( + basegfx::tools::createScaleTranslateB2DHomMatrix( + fScaleX, + fScaleY, + aOfs.X(), + aOfs.Y())); + + maClip.transform(aTransform); + } + } +} + +bool ImpSdrGDIMetaFileImport::isClip() const +{ + return !maClip.getB2DRange().isEmpty(); +} void ImpSdrGDIMetaFileImport::DoAction( MetaPolyLineAction& rAct ) { @@ -710,7 +806,6 @@ void ImpSdrGDIMetaFileImport::DoAction( MetaPolygonAction& rAct ) { // #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); @@ -732,7 +827,6 @@ void ImpSdrGDIMetaFileImport::DoAction(MetaPolyPolygonAction& rAct) { // #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); diff --git a/svx/source/svdraw/svdfmtf.hxx b/svx/source/svdraw/svdfmtf.hxx index 5f31f583e45e..c1e7d5c860f9 100644 --- a/svx/source/svdraw/svdfmtf.hxx +++ b/svx/source/svdraw/svdfmtf.hxx @@ -77,7 +77,15 @@ protected: // to optimize multiple lines into a Polyline sal_Bool bLastObjWasLine; + // clipregion + basegfx::B2DPolyPolygon maClip; + protected: + // check for clip and evtl. fill maClip + void checkClip(); + bool isClip() const; + + // actions void DoAction(MetaPixelAction & rAct) const; void DoAction(MetaPointAction & rAct) const; void DoAction(MetaLineAction & rAct); @@ -105,13 +113,13 @@ protected: void DoAction(MetaTextFillColorAction & rAct) { rAct.Execute(&aVD); } void DoAction(MetaFontAction & rAct) { rAct.Execute(&aVD); bFntDirty=sal_True; } void DoAction(MetaTextAlignAction & rAct) { rAct.Execute(&aVD); bFntDirty=sal_True; } - void DoAction(MetaClipRegionAction & rAct) { rAct.Execute(&aVD); } + void DoAction(MetaClipRegionAction & rAct) { rAct.Execute(&aVD); checkClip(); } void DoAction(MetaRasterOpAction & rAct) { rAct.Execute(&aVD); } - void DoAction(MetaPushAction & rAct) { rAct.Execute(&aVD); } - void DoAction(MetaPopAction & rAct) { rAct.Execute(&aVD); bFntDirty=sal_True; } - void DoAction(MetaMoveClipRegionAction & rAct) { rAct.Execute(&aVD); } - void DoAction(MetaISectRectClipRegionAction& rAct) { rAct.Execute(&aVD); } - void DoAction(MetaISectRegionClipRegionAction& rAct) { rAct.Execute(&aVD); } + void DoAction(MetaPushAction & rAct) { rAct.Execute(&aVD); checkClip(); } + void DoAction(MetaPopAction & rAct) { rAct.Execute(&aVD); bFntDirty=sal_True; checkClip(); } + void DoAction(MetaMoveClipRegionAction & rAct) { rAct.Execute(&aVD); checkClip(); } + void DoAction(MetaISectRectClipRegionAction& rAct) { rAct.Execute(&aVD); checkClip(); } + void DoAction(MetaISectRegionClipRegionAction& rAct) { rAct.Execute(&aVD); checkClip(); } void DoAction(MetaCommentAction& rAct, GDIMetaFile* pMtf); void ImportText( const Point& rPos, const XubString& rStr, const MetaAction& rAct ); diff --git a/svx/source/svdraw/svdxcgv.cxx b/svx/source/svdraw/svdxcgv.cxx index df282db62db8..6256e237c8e1 100644 --- a/svx/source/svdraw/svdxcgv.cxx +++ b/svx/source/svdraw/svdxcgv.cxx @@ -529,27 +529,27 @@ GDIMetaFile SdrExchangeView::GetMarkedObjMetaFile(bool bNoVDevIfOneMtfMarked) co if( !aMtf.GetActionSize() ) { - VirtualDevice aOut; - Size aDummySize( 2, 2 ); - - aOut.SetOutputSizePixel( aDummySize ); - aOut.EnableOutput( sal_False ); - aOut.SetMapMode( aMap ); + VirtualDevice aOut; + const Size aDummySize(2, 2); + aOut.SetOutputSizePixel(aDummySize); + aOut.EnableOutput(false); + aOut.SetMapMode(aMap); aMtf.Clear(); - aMtf.Record( &aOut ); - - // Replace offset given formally to DrawMarkedObj and used at XOutDev with relative - // MapMode (which was also used in XOutDev in that case). Goal is to paint the object - // as if TopLeft point is (0,0) - const Fraction aNeutralFraction(1, 1); - const MapMode aRelativeMapMode(MAP_RELATIVE, Point(-aBound.Left(), -aBound.Top()), aNeutralFraction, aNeutralFraction); - aOut.SetMapMode(aRelativeMapMode); + aMtf.Record(&aOut); DrawMarkedObj(aOut); aMtf.Stop(); aMtf.WindStart(); + + // moving the result is more reliable then setting a relative MapMode at the VDev (used + // before), also see #i99268# in GetObjGraphic() below. Some draw actions at + // the OutDev are simply not handled correctly when a MapMode is set at the + // target devive, e.g. MetaFloatTransparentAction. Even the Move for this action + // was missing the manipulation of the embedded Metafile + aMtf.Move(-aBound.Left(), -aBound.Top()); + aMtf.SetPrefMapMode( aMap ); // removed PrefSize extension. It is principally wrong to set a reduced size at @@ -633,8 +633,8 @@ Graphic SdrExchangeView::GetObjGraphic( const SdrModel* pModel, const SdrObject* // #i99268# replace the original offset from using XOutDev's SetOffset // NOT (as tried with #i92760#) with another MapMode which gets recorded - // by the Metafile itself (what always leads to problems), but by hardly - // moving the result + // by the Metafile itself (what always leads to problems), but by + // moving the result directly aMtf.Move(-aBoundRect.Left(), -aBoundRect.Top()); aMtf.SetPrefMapMode( aMap ); |