diff -Nru vcl/inc/vcl/outdev.hxx vcl-gil/inc/vcl/outdev.hxx --- vcl/inc/vcl/outdev.hxx 2010-11-11 16:22:48.000000000 +0100 +++ vcl-gil/inc/vcl/outdev.hxx 2011-03-15 01:59:38.000000000 +0100 @@ -277,6 +277,8 @@ class VirtualDevice; class Printer; +class ImplFontSelectData; +class ImplFontMetricData; const char* ImplDbgCheckOutputDevice( const void* pObj ); @@ -564,6 +566,9 @@ // 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 -Nru vcl/source/gdi/outdev3.cxx vcl-gil/source/gdi/outdev3.cxx --- vcl/source/gdi/outdev3.cxx 2010-12-03 16:11:22.000000000 +0100 +++ vcl-gil/source/gdi/outdev3.cxx 2011-03-15 02:04:10.000000000 +0100 @@ -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,