From 39387fda8c027722d7db2a1320a2bebf95efb641 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= Date: Wed, 9 Mar 2011 14:22:04 +0000 Subject: [PATCH] Resolves: rhbz#682621 better resizing of overtall glyphsubs --- vcl/inc/vcl/outdev.hxx | 5 +++ vcl/source/gdi/outdev3.cxx | 70 ++++++++++++++++++++++++++++++++++--------- 2 files changed, 60 insertions(+), 15 deletions(-) diff --git a/vcl/inc/vcl/outdev.hxx b/vcl/inc/vcl/outdev.hxx index 251b2e8..859020f 100644 --- a/vcl/inc/vcl/outdev.hxx +++ b/vcl/inc/vcl/outdev.hxx @@ -276,6 +276,8 @@ enum OutDevViewType { OUTDEV_VIEWTYPE_DONTKNOW, OUTDEV_VIEWTYPE_PRINTPREVIEW, OU class VirtualDevice; class Printer; +class ImplFontSelectData; +class ImplFontMetricData; const char* ImplDbgCheckOutputDevice( const void* pObj ); @@ -563,6 +565,9 @@ public: // Helper for line geometry paint with support for graphic expansion (pattern and fat_to_area) void impPaintLineGeometryWithEvtlExpand(const LineInfo& rInfo, basegfx::B2DPolyPolygon aLinePolyPolygon); + SAL_DLLPRIVATE void forceFallbackFontToFit(SalLayout &rFallback, ImplFontEntry &rFallbackFont, + ImplFontSelectData &rFontSelData, int nFallbackLevel, + ImplLayoutArgs& rLayoutArgs, const ImplFontMetricData& rOrigMetric) const; protected: OutputDevice(); diff --git a/vcl/source/gdi/outdev3.cxx b/vcl/source/gdi/outdev3.cxx index 84a7b5d..7a439f2 100644 --- a/vcl/source/gdi/outdev3.cxx +++ b/vcl/source/gdi/outdev3.cxx @@ -6023,6 +6023,58 @@ return pSalLayout; } +void OutputDevice::forceFallbackFontToFit(SalLayout &rFallback, ImplFontEntry &rFallbackFont, + ImplFontSelectData &rFontSelData, int nFallbackLevel, + ImplLayoutArgs& rLayoutArgs, const ImplFontMetricData& rOrigMetric) const +{ + Rectangle aBoundRect; + bool bHaveBounding = false; + Rectangle aRectangle; + + rFallback.AdjustLayout( rLayoutArgs ); + + //All we care about here is getting the vertical bounds of this text and + //make sure it will fit inside the available space + Point aPos; + for( int nStart = 0;;) + { + sal_GlyphId nLGlyph; + if( !rFallback.GetNextGlyphs( 1, &nLGlyph, aPos, nStart ) ) + break; + + int nFontTag = nFallbackLevel << GF_FONTSHIFT; + nLGlyph |= nFontTag; + + // get bounding rectangle of individual glyph + if( mpGraphics->GetGlyphBoundRect( nLGlyph, aRectangle ) ) + { + // merge rectangle + aRectangle += aPos; + aBoundRect.Union( aRectangle ); + bHaveBounding = true; + } + } + + //Shrink it down if it won't fit + if (bHaveBounding) + { + long nGlyphsAscent = -aBoundRect.Top(); + float fScaleTop = nGlyphsAscent > rOrigMetric.mnAscent ? + rOrigMetric.mnAscent/(float)nGlyphsAscent : 1; + long nGlyphsDescent = aBoundRect.Bottom(); + float fScaleBottom = nGlyphsDescent > rOrigMetric.mnDescent ? + rOrigMetric.mnDescent/(float)nGlyphsDescent : 1; + float fScale = fScaleBottom < fScaleTop ? fScaleBottom : fScaleTop; + if (fScale < 1) + { + long nOrigHeight = rFontSelData.mnHeight; + rFontSelData.mnHeight *= fScale; + rFallbackFont.mnSetFontFlags = mpGraphics->SetFont( &rFontSelData, nFallbackLevel ); + rFontSelData.mnHeight = nOrigHeight; + } + } +} + // ----------------------------------------------------------------------- SalLayout* OutputDevice::ImplGlyphFallbackLayout( SalLayout* pSalLayout, ImplLayoutArgs& rLayoutArgs ) const @@ -6102,22 +6154,7 @@ } #endif - ImplFontMetricData aSubstituteMetric(aFontSelData); pFallbackFont->mnSetFontFlags = mpGraphics->SetFont( &aFontSelData, nFallbackLevel ); - mpGraphics->GetFontMetric(&aSubstituteMetric, nFallbackLevel); - - long nOriginalHeight = aOrigMetric.mnAscent + aOrigMetric.mnDescent; - long nSubstituteHeight = aSubstituteMetric.mnAscent + aSubstituteMetric.mnDescent; - //Too tall, shrink it a bit. Need a better calculation to include extra - //factors and any extra wriggle room we might have available ? - if (nSubstituteHeight > nOriginalHeight) - { - float fScale = nOriginalHeight/(float)nSubstituteHeight; - long nOrigHeight = aFontSelData.mnHeight; - aFontSelData.mnHeight *= fScale; - pFallbackFont->mnSetFontFlags = mpGraphics->SetFont( &aFontSelData, nFallbackLevel ); - aFontSelData.mnHeight = nOrigHeight; - } // create and add glyph fallback layout to multilayout rLayoutArgs.ResetPos(); @@ -6126,6 +6163,9 @@ { if( pFallback->LayoutText( rLayoutArgs ) ) { + forceFallbackFontToFit(*pFallback, *pFallbackFont, aFontSelData, + nFallbackLevel, rLayoutArgs, aOrigMetric); + if( !pMultiSalLayout ) pMultiSalLayout = new MultiSalLayout( *pSalLayout ); pMultiSalLayout->AddFallback( *pFallback,