Kaydet (Commit) e0146946 authored tarafından Armin Le Grand's avatar Armin Le Grand Kaydeden (comit) Caolán McNamara

Resolves: #i122326# added text clipping, corrected text box distances

(cherry picked from commit 58b44ad7)

Conflicts:
	svx/source/svdraw/svdfmtf.cxx

Change-Id: I313c2f50269b8ba97c32a24b92aafafb49f3ca70
üst e0d8fb0c
...@@ -68,6 +68,9 @@ ...@@ -68,6 +68,9 @@
#include <svx/xflbmtit.hxx> #include <svx/xflbmtit.hxx>
#include <svx/xflbstit.hxx> #include <svx/xflbstit.hxx>
#include <svx/svdpntv.hxx> #include <svx/svdpntv.hxx>
#include <basegfx/polygon/b2dpolypolygontools.hxx>
#include <svx/svditer.hxx>
#include <svx/svdogrp.hxx>
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
...@@ -476,63 +479,130 @@ void ImpSdrGDIMetaFileImport::InsertObj(SdrObject* pObj, bool bScale) ...@@ -476,63 +479,130 @@ void ImpSdrGDIMetaFileImport::InsertObj(SdrObject* pObj, bool bScale)
const SdrLayerID aOldLayer(pObj->GetLayer()); const SdrLayerID aOldLayer(pObj->GetLayer());
const SfxItemSet aOldItemSet(pObj->GetMergedItemSet()); const SfxItemSet aOldItemSet(pObj->GetMergedItemSet());
const SdrGrafObj* pSdrGrafObj = dynamic_cast< SdrGrafObj* >(pObj); const SdrGrafObj* pSdrGrafObj = dynamic_cast< SdrGrafObj* >(pObj);
BitmapEx aBitmapEx; const SdrTextObj* pSdrTextObj = dynamic_cast< SdrTextObj* >(pObj);
if(pSdrGrafObj) if(pSdrTextObj && pSdrTextObj->HasText())
{ {
aBitmapEx = pSdrGrafObj->GetGraphic().GetBitmapEx(); // all text objects are created from ImportText and have no line or fill attributes, so
} // it is okay to concentrate on the text itself
while(true)
{
const basegfx::B2DPolyPolygon aTextContour(pSdrTextObj->TakeContour());
const basegfx::B2DRange aTextRange(aTextContour.getB2DRange());
const basegfx::B2DRange aClipRange(maClip.getB2DRange());
// no overlap -> completely outside
if(!aClipRange.overlaps(aTextRange))
{
SdrObject::Free(pObj);
break;
}
// when the clip is a rectangle fast check for inside is possible
if(basegfx::tools::isRectangle(maClip) && aClipRange.isInside(aTextRange))
{
// completely inside ClipRect
break;
}
SdrObject::Free(pObj); // here text needs to be clipped; to do so, convert to SdrObjects with polygons
// and add these recursively. Delete original object, do not add in this run
SdrObject* pConverted = pSdrTextObj->ConvertToPolyObj(true, true);
SdrObject::Free(pObj);
if(!aOldRange.isEmpty()) if(pConverted)
{
// recursively add created conversion; per definition this shall not
// contain further SdrTextObjs. Visit only non-group objects
SdrObjListIter aIter(*pConverted, IM_DEEPNOGROUPS);
// work with clones; the created conversion may contain group objects
// and when working with the original objects the loop itself could
// break and the cleanup later would be pretty complicated (only delete group
// objects, are these empty, ...?)
while(aIter.IsMore())
{
SdrObject* pCandidate = aIter.Next();
OSL_ENSURE(pCandidate && 0 == dynamic_cast< SdrObjGroup* >(pCandidate), "SdrObjListIter with IM_DEEPNOGROUPS error (!)");
SdrObject* pNewClone = pCandidate->Clone();
if(pNewClone)
{
InsertObj(pNewClone, false);
}
else
{
OSL_ENSURE(false, "SdrObject::Clone() failed (!)");
}
}
// cleanup temporary conversion objects
SdrObject::Free(pConverted);
}
break;
}
}
else
{ {
// clip against ClipRegion BitmapEx aBitmapEx;
const basegfx::B2DPolyPolygon aNewPoly(
basegfx::tools::clipPolyPolygonOnPolyPolygon( if(pSdrGrafObj)
aPoly,
maClip,
true,
aPoly.isClosed() ? false : true));
const basegfx::B2DRange aNewRange(aNewPoly.getB2DRange());
if(!aNewRange.isEmpty())
{ {
pObj = new SdrPathObj( aBitmapEx = pSdrGrafObj->GetGraphic().GetBitmapEx();
aNewPoly.isClosed() ? OBJ_POLY : OBJ_PLIN, }
aNewPoly);
pObj->SetLayer(aOldLayer); SdrObject::Free(pObj);
pObj->SetMergedItemSet(aOldItemSet);
if(!!aBitmapEx) 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())
{ {
// aNewRange is inside of aOldRange and defines which part of aBitmapEx is used pObj = new SdrPathObj(
const double fLclScaleX(aBitmapEx.GetSizePixel().Width() / (aOldRange.getWidth() ? aOldRange.getWidth() : 1.0)); aNewPoly.isClosed() ? OBJ_POLY : OBJ_PLIN,
const double fLclScaleY(aBitmapEx.GetSizePixel().Height() / (aOldRange.getHeight() ? aOldRange.getHeight() : 1.0)); aNewPoly);
basegfx::B2DRange aPixel(aNewRange);
basegfx::B2DHomMatrix aTrans; pObj->SetLayer(aOldLayer);
pObj->SetMergedItemSet(aOldItemSet);
aTrans.translate(-aOldRange.getMinX(), -aOldRange.getMinY());
aTrans.scale(fLclScaleX, fLclScaleY); if(!!aBitmapEx)
aPixel.transform(aTrans); {
// aNewRange is inside of aOldRange and defines which part of aBitmapEx is used
const Size aOrigSizePixel(aBitmapEx.GetSizePixel()); const double fScaleX(aBitmapEx.GetSizePixel().Width() / (aOldRange.getWidth() ? aOldRange.getWidth() : 1.0));
const Point aClipTopLeft( const double fScaleY(aBitmapEx.GetSizePixel().Height() / (aOldRange.getHeight() ? aOldRange.getHeight() : 1.0));
basegfx::fround(floor(std::max(0.0, aPixel.getMinX()))), basegfx::B2DRange aPixel(aNewRange);
basegfx::fround(floor(std::max(0.0, aPixel.getMinY())))); basegfx::B2DHomMatrix aTrans;
const Size aClipSize(
basegfx::fround(ceil(std::min((double)aOrigSizePixel.Width(), aPixel.getWidth()))), aTrans.translate(-aOldRange.getMinX(), -aOldRange.getMinY());
basegfx::fround(ceil(std::min((double)aOrigSizePixel.Height(), aPixel.getHeight())))); aTrans.scale(fScaleX, fScaleY);
const BitmapEx aClippedBitmap( aPixel.transform(aTrans);
aBitmapEx,
aClipTopLeft, const Size aOrigSizePixel(aBitmapEx.GetSizePixel());
aClipSize); const Point aClipTopLeft(
basegfx::fround(floor(std::max(0.0, aPixel.getMinX()))),
pObj->SetMergedItem(XFillStyleItem(XFILL_BITMAP)); basegfx::fround(floor(std::max(0.0, aPixel.getMinY()))));
pObj->SetMergedItem(XFillBitmapItem(String(), Graphic(aClippedBitmap))); const Size aClipSize(
pObj->SetMergedItem(XFillBmpTileItem(false)); basegfx::fround(ceil(std::min((double)aOrigSizePixel.Width(), aPixel.getWidth()))),
pObj->SetMergedItem(XFillBmpStretchItem(true)); basegfx::fround(ceil(std::min((double)aOrigSizePixel.Height(), aPixel.getHeight()))));
const BitmapEx aClippedBitmap(
aBitmapEx,
aClipTopLeft,
aClipSize);
pObj->SetMergedItem(XFillStyleItem(XFILL_BITMAP));
pObj->SetMergedItem(XFillBitmapItem(String(), Graphic(aClippedBitmap)));
pObj->SetMergedItem(XFillBmpTileItem(false));
pObj->SetMergedItem(XFillBmpStretchItem(true));
}
} }
} }
} }
...@@ -948,19 +1018,22 @@ void ImpSdrGDIMetaFileImport::ImportText( const Point& rPos, const XubString& rS ...@@ -948,19 +1018,22 @@ void ImpSdrGDIMetaFileImport::ImportText( const Point& rPos, const XubString& rS
Rectangle aTextRect( aPos, aSize ); Rectangle aTextRect( aPos, aSize );
SdrRectObj* pText =new SdrRectObj( OBJ_TEXT, aTextRect ); SdrRectObj* pText =new SdrRectObj( OBJ_TEXT, aTextRect );
pText->SetMergedItem ( SdrTextUpperDistItem (0));
pText->SetMergedItem ( SdrTextLowerDistItem (0));
pText->SetMergedItem ( SdrTextRightDistItem (0));
pText->SetMergedItem ( SdrTextLeftDistItem (0));
if ( aFnt.GetWidth() || ( rAct.GetType() == META_STRETCHTEXT_ACTION ) ) if ( aFnt.GetWidth() || ( rAct.GetType() == META_STRETCHTEXT_ACTION ) )
{ {
pText->ClearMergedItem( SDRATTR_TEXT_AUTOGROWWIDTH ); pText->ClearMergedItem( SDRATTR_TEXT_AUTOGROWWIDTH );
pText->SetMergedItem( SdrTextAutoGrowHeightItem( false ) ); pText->SetMergedItem( SdrTextAutoGrowHeightItem( false ) );
// don't let the margins eat the space needed for the text // 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 ) ); pText->SetMergedItem( SdrTextFitToSizeTypeItem( SDRTEXTFIT_ALLLINES ) );
} }
else else
{
pText->SetMergedItem( SdrTextAutoGrowWidthItem( true ) ); pText->SetMergedItem( SdrTextAutoGrowWidthItem( true ) );
}
pText->SetModel(mpModel); pText->SetModel(mpModel);
pText->SetLayer(mnLayer); pText->SetLayer(mnLayer);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment