diff options
author | Thorsten Behrens <tbehrens@novell.com> | 2010-09-17 10:11:31 +0200 |
---|---|---|
committer | Jan Holesovsky <kendy@suse.cz> | 2010-09-17 10:14:53 +0200 |
commit | e479f47f7d48dbd0d701bf347b6a2d5121ba3d34 (patch) | |
tree | 75bb4c012292178482dfab7dd052d9864121e230 /svx/source/svdraw/svdotext.cxx | |
parent | 1ea6792208820a5d1920b59ee895336beb994085 (diff) |
fit-list-to-size.diff: Shrink font automatically when text overflows.
i#94086
Scale-font-down if typing text in Impress and the text box becomes too small.
Diffstat (limited to 'svx/source/svdraw/svdotext.cxx')
-rw-r--r-- | svx/source/svdraw/svdotext.cxx | 117 |
1 files changed, 99 insertions, 18 deletions
diff --git a/svx/source/svdraw/svdotext.cxx b/svx/source/svdraw/svdotext.cxx index 6a79359e1a00..c784859c731a 100644 --- a/svx/source/svdraw/svdotext.cxx +++ b/svx/source/svdraw/svdotext.cxx @@ -137,6 +137,7 @@ SdrTextObj::SdrTextObj() // #i25616# mbSupportTextIndentingOnLineWidthChange = sal_True; + mbInDownScale = sal_False; } SdrTextObj::SdrTextObj(const Rectangle& rNewRect) @@ -162,6 +163,7 @@ SdrTextObj::SdrTextObj(const Rectangle& rNewRect) // #111096# mbTextAnimationAllowed = sal_True; + mbInDownScale = sal_False; // #108784# maTextEditOffset = Point(0, 0); @@ -192,6 +194,7 @@ SdrTextObj::SdrTextObj(SdrObjKind eNewTextKind) // #111096# mbTextAnimationAllowed = sal_True; + mbInDownScale = sal_False; // #108784# maTextEditOffset = Point(0, 0); @@ -224,6 +227,7 @@ SdrTextObj::SdrTextObj(SdrObjKind eNewTextKind, const Rectangle& rNewRect) // #111096# mbTextAnimationAllowed = sal_True; + mbInDownScale = sal_False; // #108784# maTextEditOffset = Point(0, 0); @@ -258,6 +262,7 @@ SdrTextObj::SdrTextObj(SdrObjKind eNewTextKind, const Rectangle& rNewRect, SvStr // #111096# mbTextAnimationAllowed = sal_True; + mbInDownScale = sal_False; // #108784# maTextEditOffset = Point(0, 0); @@ -834,8 +839,7 @@ void SdrTextObj::TakeTextRect( SdrOutliner& rOutliner, Rectangle& rTextRect, FAS SdrTextAniKind eAniKind=GetTextAniKind(); SdrTextAniDirection eAniDirection=GetTextAniDirection(); - SdrFitToSizeType eFit=GetFitToSize(); - FASTBOOL bFitToSize=(eFit==SDRTEXTFIT_PROPORTIONAL || eFit==SDRTEXTFIT_ALLLINES); + FASTBOOL bFitToSize(IsFitToSize()); FASTBOOL bContourFrame=IsContourTextFrame(); FASTBOOL bFrame=IsTextFrame(); @@ -996,7 +1000,7 @@ OutlinerParaObject* SdrTextObj::GetEditOutlinerParaObject() const return pPara; } -void SdrTextObj::ImpSetCharStretching(SdrOutliner& rOutliner, const Rectangle& rTextRect, const Rectangle& rAnchorRect, Fraction& rFitXKorreg) const +void SdrTextObj::ImpSetCharStretching(SdrOutliner& rOutliner, const Size& rTextSize, const Size& rShapeSize, Fraction& rFitXKorreg) const { OutputDevice* pOut = rOutliner.GetRefDevice(); BOOL bNoStretching(FALSE); @@ -1041,12 +1045,12 @@ void SdrTextObj::ImpSetCharStretching(SdrOutliner& rOutliner, const Rectangle& r unsigned nLoopCount=0; FASTBOOL bNoMoreLoop=FALSE; long nXDiff0=0x7FFFFFFF; - long nWantWdt=rAnchorRect.Right()-rAnchorRect.Left(); - long nIsWdt=rTextRect.Right()-rTextRect.Left(); + long nWantWdt=rShapeSize.Width(); + long nIsWdt=rTextSize.Width(); if (nIsWdt==0) nIsWdt=1; - long nWantHgt=rAnchorRect.Bottom()-rAnchorRect.Top(); - long nIsHgt=rTextRect.Bottom()-rTextRect.Top(); + long nWantHgt=rShapeSize.Height(); + long nIsHgt=rTextSize.Height(); if (nIsHgt==0) nIsHgt=1; long nXTolPl=nWantWdt/100; // Toleranz +1% @@ -1274,8 +1278,7 @@ basegfx::B2DPolyPolygon SdrTextObj::TakeContour() const Rectangle aR; TakeTextRect(rOutliner,aR,FALSE,&aAnchor2); rOutliner.Clear(); - SdrFitToSizeType eFit=GetFitToSize(); - FASTBOOL bFitToSize=(eFit==SDRTEXTFIT_PROPORTIONAL || eFit==SDRTEXTFIT_ALLLINES); + FASTBOOL bFitToSize(IsFitToSize()); if (bFitToSize) aR=aAnchor2; Polygon aPol(aR); if (aGeo.nDrehWink!=0) RotatePoly(aPol,aR.TopLeft(),aGeo.nSin,aGeo.nCos); @@ -1392,8 +1395,7 @@ void SdrTextObj::ImpSetupDrawOutlinerForPaint( FASTBOOL bContourFrame, if (!bContourFrame) { // FitToSize erstmal nicht mit ContourFrame - SdrFitToSizeType eFit=GetFitToSize(); - if (eFit==SDRTEXTFIT_PROPORTIONAL || eFit==SDRTEXTFIT_ALLLINES) + if (IsFitToSize() || IsAutoFit()) { ULONG nStat=rOutliner.GetControlWord(); nStat|=EE_CNTRL_STRETCHING|EE_CNTRL_AUTOPAGESIZE; @@ -1407,13 +1409,73 @@ void SdrTextObj::ImpSetupDrawOutlinerForPaint( FASTBOOL bContourFrame, if (!bContourFrame) { // FitToSize erstmal nicht mit ContourFrame - SdrFitToSizeType eFit=GetFitToSize(); - if (eFit==SDRTEXTFIT_PROPORTIONAL || eFit==SDRTEXTFIT_ALLLINES) + if (IsFitToSize()) { - ImpSetCharStretching(rOutliner,rTextRect,rAnchorRect,rFitXKorreg); + ImpSetCharStretching(rOutliner,rTextRect.GetSize(),rAnchorRect.GetSize(),rFitXKorreg); rPaintRect=rAnchorRect; } + else if (IsAutoFit()) + { + ImpAutoFitText(rOutliner); + } + } +} + +void SdrTextObj::ImpAutoFitText( SdrOutliner& rOutliner ) const +{ + const Size aShapeSize=GetSnapRect().GetSize(); + ImpAutoFitText( rOutliner, + Size(aShapeSize.Width()-GetTextLeftDistance()-GetTextRightDistance(), + aShapeSize.Height()-GetTextUpperDistance()-GetTextLowerDistance()), + IsVerticalWriting() ); +} + +void SdrTextObj::ImpAutoFitText( SdrOutliner& rOutliner, const Size& rTextSize, bool bIsVerticalWriting ) +{ + // EditEngine formatting is unstable enough for + // line-breaking text that we need some more samples + + // loop early-exits if we detect an already attained value + USHORT nMinStretchX=0, nMinStretchY=0; + USHORT aOldStretchXVals[]={0,0,0,0,0,0,0,0,0,0}; + const size_t aStretchArySize=sizeof(aOldStretchXVals)/sizeof(*aOldStretchXVals); + for(int i=0; i<aStretchArySize; ++i) + { + const Size aCurrTextSize = rOutliner.CalcTextSize(); + double fFactor(1.0); + if( bIsVerticalWriting ) + fFactor = double(rTextSize.Width())/aCurrTextSize.Width(); + else + fFactor = double(rTextSize.Height())/aCurrTextSize.Height(); + + USHORT nCurrStretchX, nCurrStretchY; + rOutliner.GetGlobalCharStretching(nCurrStretchX, nCurrStretchY); + + if (fFactor >= 1.0 ) + { + // resulting text area fits into available shape rect - + // err on the larger streching, to optimally fill area + nMinStretchX = std::max(nMinStretchX,nCurrStretchX); + nMinStretchY = std::max(nMinStretchY,nCurrStretchY); + } + + aOldStretchXVals[i] = nCurrStretchX; + if( std::find(aOldStretchXVals, aOldStretchXVals+i, nCurrStretchX) != aOldStretchXVals+i ) + break; // same value already attained once; algo is looping, exit + + if (fFactor < 1.0 || (fFactor >= 1.0 && nCurrStretchX != 100)) + { + nCurrStretchX = sal::static_int_cast<USHORT>(nCurrStretchX*fFactor); + nCurrStretchY = sal::static_int_cast<USHORT>(nCurrStretchY*fFactor); + rOutliner.SetGlobalCharStretching(std::min(USHORT(100),nCurrStretchX), + std::min(USHORT(100),nCurrStretchY)); + OSL_TRACE("SdrTextObj::onEditOutlinerStatusEvent(): zoom is %d", nCurrStretchX); + } } + + OSL_TRACE("---- SdrTextObj::onEditOutlinerStatusEvent(): final zoom is %d ----", nMinStretchX); + rOutliner.SetGlobalCharStretching(std::min(USHORT(100),nMinStretchX), + std::min(USHORT(100),nMinStretchY)); } void SdrTextObj::SetupOutlinerFormatting( SdrOutliner& rOutl, Rectangle& rPaintRect ) const @@ -1992,6 +2054,17 @@ bool SdrTextObj::IsTextAnimationAllowed() const return mbTextAnimationAllowed; } +FASTBOOL SdrTextObj::IsAutoFit() const +{ + return GetFitToSize()==SDRTEXTFIT_AUTOFIT; +} + +FASTBOOL SdrTextObj::IsFitToSize() const +{ + const SdrFitToSizeType eFit=GetFitToSize(); + return (eFit==SDRTEXTFIT_PROPORTIONAL || eFit==SDRTEXTFIT_ALLLINES); +} + void SdrTextObj::SetTextAnimationAllowed(sal_Bool bNew) { if(mbTextAnimationAllowed != bNew) @@ -2009,13 +2082,21 @@ void SdrTextObj::onEditOutlinerStatusEvent( EditStatus* pEditStatus ) const bool bGrowY=(nStat & EE_STAT_TEXTHEIGHTCHANGED) !=0; if(bTextFrame && (bGrowX || bGrowY)) { - const bool bAutoGrowHgt= bTextFrame && IsAutoGrowHeight(); - const bool bAutoGrowWdt= bTextFrame && IsAutoGrowWidth(); - - if ((bGrowX && bAutoGrowWdt) || (bGrowY && bAutoGrowHgt)) + if ((bGrowX && IsAutoGrowWidth()) || (bGrowY && IsAutoGrowHeight())) { AdjustTextFrameWidthAndHeight(); } + else if (IsAutoFit() && !mbInDownScale) + { + OSL_ASSERT(pEdtOutl); + mbInDownScale = sal_True; + + // sucks that we cannot disable paints via + // pEdtOutl->SetUpdateMode(FALSE) - but EditEngine skips + // formatting as well, then. + ImpAutoFitText(*pEdtOutl); + mbInDownScale = sal_False; + } } } |