summaryrefslogtreecommitdiff
path: root/svx
diff options
context:
space:
mode:
authorArmin Le Grand <alg@apache.org>2012-05-08 08:27:10 +0000
committerCaolán McNamara <caolanm@redhat.com>2013-03-13 13:40:41 +0000
commit684c502ed0a6782fe1b9c7d7cd1911a4a88b543a (patch)
tree25c0e098a8dc307d51fd722e5a7a856ea901609a /svx
parentec8d4b1d23e85cc27f1d08e1b1ed9c18e63f7a3c (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.cxx174
-rw-r--r--svx/source/svdraw/svdfmtf.hxx20
-rw-r--r--svx/source/svdraw/svdxcgv.cxx32
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 );