[Libreoffice-commits] core.git: svx/source sw/qa vcl/source
Armin Le Grand
alg at apache.org
Wed Mar 13 06:41:00 PDT 2013
svx/source/svdraw/svdfmtf.cxx | 174 +++++++++++++++++++++++--------
svx/source/svdraw/svdfmtf.hxx | 20 ++-
svx/source/svdraw/svdxcgv.cxx | 32 ++---
sw/qa/extras/ooxmlimport/ooxmlimport.cxx | 2
vcl/source/gdi/metaact.cxx | 3
vcl/source/gdi/outdev6.cxx | 3
vcl/source/gdi/outmap.cxx | 11 +
7 files changed, 180 insertions(+), 65 deletions(-)
New commits:
commit 684c502ed0a6782fe1b9c7d7cd1911a4a88b543a
Author: Armin Le Grand <alg at apache.org>
Date: Tue May 8 08:27:10 2012 +0000
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
diff --git a/svx/source/svdraw/svdfmtf.cxx b/svx/source/svdraw/svdfmtf.cxx
index 7e38fc6..1d9b948 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 5f31f58..c1e7d5c 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 df282db6..6256e23 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 );
diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
index 0332a0c..5094e79 100644
--- a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
+++ b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
@@ -814,7 +814,7 @@ void Test::testN777345()
Graphic aGraphic(xGraphic);
// If this changes later, feel free to update it, but make sure it's not
// the checksum of a white/transparent placeholder rectangle.
- CPPUNIT_ASSERT_EQUAL(sal_uLong(3816010727U), aGraphic.GetChecksum());
+ CPPUNIT_ASSERT_EQUAL(sal_uLong(2529763117U), aGraphic.GetChecksum());
}
void Test::testN777337()
diff --git a/vcl/source/gdi/metaact.cxx b/vcl/source/gdi/metaact.cxx
index b63ca2d..f44e14f 100644
--- a/vcl/source/gdi/metaact.cxx
+++ b/vcl/source/gdi/metaact.cxx
@@ -3758,6 +3758,9 @@ MetaAction* MetaFloatTransparentAction::Clone()
void MetaFloatTransparentAction::Move( long nHorzMove, long nVertMove )
{
maPoint.Move( nHorzMove, nVertMove );
+
+ // also neeed to move the content metafile
+ maMtf.Move( nHorzMove, nVertMove );
}
// ------------------------------------------------------------------------
diff --git a/vcl/source/gdi/outdev6.cxx b/vcl/source/gdi/outdev6.cxx
index 680a63d..821d9ce 100644
--- a/vcl/source/gdi/outdev6.cxx
+++ b/vcl/source/gdi/outdev6.cxx
@@ -607,7 +607,10 @@ void OutputDevice::DrawTransparent( const GDIMetaFile& rMtf, const Point& rPos,
const Color aBlack( COL_BLACK );
if( mpMetaFile )
+ {
+ // missing here is to map the data using the DeviceTransformation
mpMetaFile->AddAction( new MetaFloatTransparentAction( rMtf, rPos, rSize, rTransparenceGradient ) );
+ }
if( ( rTransparenceGradient.GetStartColor() == aBlack && rTransparenceGradient.GetEndColor() == aBlack ) ||
( mnDrawMode & ( DRAWMODE_NOTRANSPARENCY ) ) )
diff --git a/vcl/source/gdi/outmap.cxx b/vcl/source/gdi/outmap.cxx
index 6d55f18..b1a5e01 100644
--- a/vcl/source/gdi/outmap.cxx
+++ b/vcl/source/gdi/outmap.cxx
@@ -1427,10 +1427,17 @@ Region OutputDevice::PixelToLogic( const Region& rDeviceRegion ) const
return rDeviceRegion;
Region aRegion;
- PolyPolygon* pPolyPoly = rDeviceRegion.ImplGetImplRegion()->mpPolyPoly;
+ basegfx::B2DPolyPolygon* pB2DPolyPoly = rDeviceRegion.ImplGetImplRegion()->mpB2DPolyPoly;
+ PolyPolygon* pPolyPoly = pB2DPolyPoly ? 0 : rDeviceRegion.ImplGetImplRegion()->mpPolyPoly;
- if ( pPolyPoly )
+ if ( pB2DPolyPoly ) // conversion with B2DPolyPolygon lost polygon-based ClipRegion
+ {
+ aRegion = Region( PixelToLogic( *pB2DPolyPoly ) );
+ }
+ else if ( pPolyPoly )
+ {
aRegion = Region( PixelToLogic( *pPolyPoly ) );
+ }
else
{
long nX;
More information about the Libreoffice-commits
mailing list