Kaydet (Commit) 58b44ad7 authored tarafından Armin Le Grand's avatar Armin Le Grand

i122326 added text clipping, corrected text box distances

üst 10e1831a
......@@ -75,6 +75,9 @@
#include <svx/xflbmtit.hxx>
#include <svx/xflbstit.hxx>
#include <svx/svdpntv.hxx>
#include <basegfx/polygon/b2dpolypolygontools.hxx>
#include <svx/svditer.hxx>
#include <svx/svdogrp.hxx>
////////////////////////////////////////////////////////////////////////////////////////////////////
......@@ -484,63 +487,130 @@ void ImpSdrGDIMetaFileImport::InsertObj(SdrObject* pObj, bool bScale)
const SdrLayerID aOldLayer(pObj->GetLayer());
const SfxItemSet aOldItemSet(pObj->GetMergedItemSet());
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
const basegfx::B2DPolyPolygon aNewPoly(
basegfx::tools::clipPolyPolygonOnPolyPolygon(
aPoly,
maClip,
true,
aPoly.isClosed() ? false : true));
const basegfx::B2DRange aNewRange(aNewPoly.getB2DRange());
if(!aNewRange.isEmpty())
BitmapEx aBitmapEx;
if(pSdrGrafObj)
{
pObj = new SdrPathObj(
aNewPoly.isClosed() ? OBJ_POLY : OBJ_PLIN,
aNewPoly);
aBitmapEx = pSdrGrafObj->GetGraphic().GetBitmapEx();
}
pObj->SetLayer(aOldLayer);
pObj->SetMergedItemSet(aOldItemSet);
SdrObject::Free(pObj);
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
const double fScaleX(aBitmapEx.GetSizePixel().Width() / (aOldRange.getWidth() ? aOldRange.getWidth() : 1.0));
const double fScaleY(aBitmapEx.GetSizePixel().Height() / (aOldRange.getHeight() ? aOldRange.getHeight() : 1.0));
basegfx::B2DRange aPixel(aNewRange);
basegfx::B2DHomMatrix aTrans;
aTrans.translate(-aOldRange.getMinX(), -aOldRange.getMinY());
aTrans.scale(fScaleX, fScaleY);
aPixel.transform(aTrans);
const Size aOrigSizePixel(aBitmapEx.GetSizePixel());
const Point aClipTopLeft(
basegfx::fround(floor(std::max(0.0, aPixel.getMinX()))),
basegfx::fround(floor(std::max(0.0, aPixel.getMinY()))));
const Size aClipSize(
basegfx::fround(ceil(std::min((double)aOrigSizePixel.Width(), aPixel.getWidth()))),
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));
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 fScaleX(aBitmapEx.GetSizePixel().Width() / (aOldRange.getWidth() ? aOldRange.getWidth() : 1.0));
const double fScaleY(aBitmapEx.GetSizePixel().Height() / (aOldRange.getHeight() ? aOldRange.getHeight() : 1.0));
basegfx::B2DRange aPixel(aNewRange);
basegfx::B2DHomMatrix aTrans;
aTrans.translate(-aOldRange.getMinX(), -aOldRange.getMinY());
aTrans.scale(fScaleX, fScaleY);
aPixel.transform(aTrans);
const Size aOrigSizePixel(aBitmapEx.GetSizePixel());
const Point aClipTopLeft(
basegfx::fround(floor(std::max(0.0, aPixel.getMinX()))),
basegfx::fround(floor(std::max(0.0, aPixel.getMinY()))));
const Size aClipSize(
basegfx::fround(ceil(std::min((double)aOrigSizePixel.Width(), aPixel.getWidth()))),
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));
}
}
}
}
......@@ -959,19 +1029,22 @@ void ImpSdrGDIMetaFileImport::ImportText( const Point& rPos, const XubString& rS
Rectangle aTextRect( aPos, aSize );
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 ) )
{
pText->ClearMergedItem( SDRATTR_TEXT_AUTOGROWWIDTH );
pText->SetMergedItem( SdrTextAutoGrowHeightItem( 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( true ) );
}
pText->SetModel(mpModel);
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