diff options
author | Herbert Duerr <hdu@openoffice.org> | 2002-10-01 14:35:44 +0000 |
---|---|---|
committer | Herbert Duerr <hdu@openoffice.org> | 2002-10-01 14:35:44 +0000 |
commit | b6c0e10c2b80ed5ae44d9bc54dd876744e72d74e (patch) | |
tree | dc789d73298b113a8499a45fab953e48a7e6ea60 /vcl/win/source | |
parent | 99a299383f2f16e5e8eefbb28e88a6a8f90ab95b (diff) |
#102411# implement workaround for GetCharacterPlacement kerning problem
Diffstat (limited to 'vcl/win/source')
-rw-r--r-- | vcl/win/source/gdi/salgdi3.cxx | 84 | ||||
-rwxr-xr-x | vcl/win/source/gdi/winlayout.cxx | 79 |
2 files changed, 117 insertions, 46 deletions
diff --git a/vcl/win/source/gdi/salgdi3.cxx b/vcl/win/source/gdi/salgdi3.cxx index b1176d228e87..d25e74402dcb 100644 --- a/vcl/win/source/gdi/salgdi3.cxx +++ b/vcl/win/source/gdi/salgdi3.cxx @@ -2,9 +2,9 @@ * * $RCSfile: salgdi3.cxx,v $ * - * $Revision: 1.30 $ + * $Revision: 1.31 $ * - * last change: $Author: hdu $ $Date: 2002-09-19 11:17:59 $ + * last change: $Author: hdu $ $Date: 2002-10-01 15:34:48 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -108,6 +108,10 @@ #endif // _SV_POLY_HXX #endif // ENABLE_CTL +#ifdef GCP_KERN_HACK +#include <algorithm> +#endif // GCP_KERN_HACK + #ifndef _DEBUG_HXX #include <tools/debug.hxx> #endif @@ -869,8 +873,8 @@ USHORT SalGraphics::SetFont( ImplFontSelectData* pFont ) maGraphicsData.mbFontKernInit = TRUE; if ( maGraphicsData.mpFontKernPairs ) { - delete maGraphicsData.mpFontKernPairs; - maGraphicsData.mpFontKernPairs = 0; + delete[] maGraphicsData.mpFontKernPairs; + maGraphicsData.mpFontKernPairs = NULL; } maGraphicsData.mnFontKernPairCount = 0; @@ -1057,7 +1061,7 @@ static void ImplAddKerningPairs( SalGraphicsData* pData ) pData->mpFontKernPairs = new KERNINGPAIR[nPairs+pData->mnFontKernPairCount]; memcpy( pData->mpFontKernPairs, pOldPairs, pData->mnFontKernPairCount*sizeof( KERNINGPAIR ) ); - delete pOldPairs; + delete[] pOldPairs; } UINT nCP = aInfo.ciACP; @@ -1142,24 +1146,36 @@ ULONG SalGraphics::GetKernPairs( ULONG nPairs, ImplKernPairData* pKernPairs ) DBG_ASSERT( sizeof( KERNINGPAIR ) == sizeof( ImplKernPairData ), "SalGraphics::GetKernPairs(): KERNINGPAIR != ImplKernPairData" ); - if ( aSalShlData.mbWNT ) - { - if ( !pKernPairs ) - return ::GetKerningPairsW( maGraphicsData.mhDC, 0, NULL ); - else - return ::GetKerningPairsW( maGraphicsData.mhDC, nPairs, (KERNINGPAIR*)pKernPairs ); - } - else + if ( maGraphicsData.mbFontKernInit ) { - if ( maGraphicsData.mbFontKernInit ) + if( maGraphicsData.mpFontKernPairs ) { - if ( maGraphicsData.mpFontKernPairs ) + delete[] maGraphicsData.mpFontKernPairs; + maGraphicsData.mpFontKernPairs = NULL; + } + maGraphicsData.mnFontKernPairCount = 0; + + if ( aSalShlData.mbWNT ) + { + KERNINGPAIR* pPairs = NULL; + int nCount = ::GetKerningPairsW( maGraphicsData.mhDC, 0, NULL ); + if( nCount ) { - delete maGraphicsData.mpFontKernPairs; - maGraphicsData.mpFontKernPairs = 0; +#ifdef GCP_KERN_HACK + pPairs = new KERNINGPAIR[ nCount+1 ]; + maGraphicsData.mpFontKernPairs = pPairs; + maGraphicsData.mnFontKernPairCount = nCount; + ::GetKerningPairsW( maGraphicsData.mhDC, nCount, pPairs ); +#else // GCP_KERN_HACK + pPairs = pKernPairs; + nCount = (nCount < nPairs) : nCount : nPairs; + ::GetKerningPairsW( maGraphicsData.mhDC, nCount, pPairs ); + return nCount; +#endif // GCP_KERN_HACK } - maGraphicsData.mnFontKernPairCount = 0; - + } + else + { if ( !maGraphicsData.mnFontCharSetCount ) ImplGetAllFontCharSets( &maGraphicsData ); @@ -1178,21 +1194,27 @@ ULONG SalGraphics::GetKernPairs( ULONG nPairs, ImplKernPairData* pKernPairs ) DeleteFont( hNewFont ); } } - - maGraphicsData.mbFontKernInit = FALSE; } - if ( !pKernPairs ) - return maGraphicsData.mnFontKernPairCount; - else - { - if ( nPairs > maGraphicsData.mnFontKernPairCount ) - nPairs = maGraphicsData.mnFontKernPairCount; - memcpy( pKernPairs, maGraphicsData.mpFontKernPairs, - nPairs*sizeof( ImplKernPairData ) ); - return nPairs; - } + maGraphicsData.mbFontKernInit = FALSE; + + std::sort( maGraphicsData.mpFontKernPairs, + maGraphicsData.mpFontKernPairs + maGraphicsData.mnFontKernPairCount, + ImplCmpKernData ); + } + + if( !pKernPairs ) + return maGraphicsData.mnFontKernPairCount; + else if( maGraphicsData.mpFontKernPairs ) + { + if ( nPairs < maGraphicsData.mnFontKernPairCount ) + nPairs = maGraphicsData.mnFontKernPairCount; + memcpy( pKernPairs, maGraphicsData.mpFontKernPairs, + nPairs*sizeof( ImplKernPairData ) ); + return nPairs; } + + return 0; } // ----------------------------------------------------------------------- diff --git a/vcl/win/source/gdi/winlayout.cxx b/vcl/win/source/gdi/winlayout.cxx index 8db2b095b07e..bfe6b2e85b5e 100755 --- a/vcl/win/source/gdi/winlayout.cxx +++ b/vcl/win/source/gdi/winlayout.cxx @@ -2,9 +2,9 @@ * * $RCSfile: winlayout.cxx,v $ * - * $Revision: 1.49 $ + * $Revision: 1.50 $ * - * last change: $Author: hdu $ $Date: 2002-09-26 19:01:34 $ + * last change: $Author: hdu $ $Date: 2002-10-01 15:35:44 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -78,9 +78,9 @@ #include <malloc.h> #define alloca _alloca -#ifndef DISABLE_UNISCRIBE //TODO: use ENABLE_UNISCRIBE in pmk -#define USE_UNISCRIBE -#endif +#ifdef GCP_KERN_HACK +#include <algorithm> +#endif // GCP_KERN_HACK // ======================================================================= @@ -100,7 +100,12 @@ public: class SimpleWinLayout : public WinLayout { public: - SimpleWinLayout( HDC hDC, const ImplLayoutArgs& ); + SimpleWinLayout( HDC hDC, const ImplLayoutArgs& +#ifdef GCP_KERN_HACK + , const KERNINGPAIR* pPairs, int nPairs +#endif // GCP_KERN_HACK + ); + virtual ~SimpleWinLayout(); virtual bool LayoutText( const ImplLayoutArgs& ); @@ -130,13 +135,26 @@ private: UINT* mpGlyphs2Chars; int mnNotdefWidth; long mnWidth; + +#ifdef GCP_KERN_HACK + const KERNINGPAIR* mpKerningPairs; + int mnKerningPairs; +#endif // GCP_KERN_HACK }; // ----------------------------------------------------------------------- -SimpleWinLayout::SimpleWinLayout( HDC hDC, const ImplLayoutArgs& rArgs ) +SimpleWinLayout::SimpleWinLayout( HDC hDC, const ImplLayoutArgs& rArgs, +#ifdef GCP_KERN_HACK + const KERNINGPAIR* pKerningPairs, int nKerningPairs +#endif // GCP_KERN_HACK + ) : WinLayout( rArgs ), mhDC( hDC ), +#ifdef GCP_KERN_HACK + mpKerningPairs( pKerningPairs ), + mnKerningPairs( nKerningPairs ), +#endif // GCP_KERN_HACK mnGlyphCount( 0 ), mnCharCount( 0 ), mpOutGlyphs( NULL ), @@ -207,9 +225,11 @@ bool SimpleWinLayout::LayoutText( const ImplLayoutArgs& rArgs ) if( rArgs.mnFlags & (SAL_LAYOUT_KERNING_PAIRS | SAL_LAYOUT_KERNING_ASIAN) ) mpGlyphOrigAdvs = new int[ nMaxGlyphCount ]; +#ifndef GCP_KERN_HACK // enable kerning if requested if( rArgs.mnFlags & SAL_LAYOUT_KERNING_PAIRS ) nGcpOption |= GCP_USEKERNING; +#endif // GCP_KERN_HACK // apply reordering if requested char* pGcpClass = NULL; @@ -255,6 +275,7 @@ bool SimpleWinLayout::LayoutText( const ImplLayoutArgs& rArgs ) 0, &aGCPW, nGcpOption ); mnGlyphCount = aGCPW.lpOutString ? aGCPW.nMaxFit : aGCPW.nGlyphs; +#ifndef GCP_KERN_HACK // get undisturbed placement if( rArgs.mnFlags & SAL_LAYOUT_KERNING_PAIRS ) { @@ -264,6 +285,7 @@ bool SimpleWinLayout::LayoutText( const ImplLayoutArgs& rArgs ) rArgs.mpStr + rArgs.mnMinCharPos, nMaxGlyphCount, 0, &aGCPW, (nGcpOption & ~GCP_USEKERNING) ); } +#endif // GCP_KERN_HACK } else { @@ -331,6 +353,7 @@ bool SimpleWinLayout::LayoutText( const ImplLayoutArgs& rArgs ) // TODO: map lpOrderA to lpOrderW // CHECK: lpDxA->lpDxW mapping +#ifndef GCP_KERN_HACK if( rArgs.mnFlags & SAL_LAYOUT_KERNING_PAIRS ) { aGCPA.lpOrder = NULL; @@ -338,6 +361,7 @@ bool SimpleWinLayout::LayoutText( const ImplLayoutArgs& rArgs ) nRC = ::GetCharacterPlacementA( mhDC, pMBStr, nMBLen, 0, &aGCPA, (nGcpOption & ~GCP_USEKERNING) ); } +#endif // GCP_KERN_HACK } // cache essential layout properties @@ -348,7 +372,7 @@ bool SimpleWinLayout::LayoutText( const ImplLayoutArgs& rArgs ) // #101097# fixup display of notdef glyphs // TODO: is there a way to convince Win32(incl W95) API to use notdef directly? - int i; + int i, j; for( i = 0; i < mnGlyphCount; ++i ) { if( (mpGlyphAdvances[i] != 0) @@ -375,7 +399,7 @@ bool SimpleWinLayout::LayoutText( const ImplLayoutArgs& rArgs ) { mpGlyphs2Chars = new UINT[ nMaxGlyphCount ]; i = 0; - for( int j = mnGlyphCount; --j >= i; ++i ) + for( j = mnGlyphCount; --j >= i; ++i ) { WCHAR nTempGlyph = mpOutGlyphs[ i ]; int nTempAdvance = mpGlyphAdvances[ i ]; @@ -406,15 +430,16 @@ bool SimpleWinLayout::LayoutText( const ImplLayoutArgs& rArgs ) ApplyDXArray( rArgs.mpDXArray ); else if( rArgs.mnLayoutWidth ) Justify( rArgs.mnLayoutWidth ); - - if( (rArgs.mnFlags & SAL_LAYOUT_KERNING_ASIAN) - && !rArgs.mpDXArray && !rArgs.mnLayoutWidth ) +#ifdef GCP_KERN_HACK + else if( rArgs.mnFlags & (SAL_LAYOUT_KERNING_ASIAN|SAL_LAYOUT_KERNING_PAIRS) ) + { +#else // GCP_KERN_HACK + else if( rArgs.mnFlags & SAL_LAYOUT_KERNING_ASIAN ) { if( !(rArgs.mnFlags & SAL_LAYOUT_KERNING_PAIRS) ) - { +#endif // GCP_KERN_HACK for( i = 0; i < mnGlyphCount; ++i ) mpGlyphOrigAdvs[i] = mpGlyphAdvances[i]; - } bool bVertical = false; const xub_Unicode* pStr = rArgs.mpStr + rArgs.mnMinCharPos; @@ -424,6 +449,21 @@ bool SimpleWinLayout::LayoutText( const ImplLayoutArgs& rArgs ) ++nLen; for( i = 1; i < nLen; ++i ) { +#ifdef GCP_KERN_HACK + if( (rArgs.mnFlags & SAL_LAYOUT_KERNING_PAIRS) && mnKerningPairs ) + { + const KERNINGPAIR aRefPair = {pStr[i-1],pStr[i],0}; + const KERNINGPAIR* pPair = std::lower_bound( mpKerningPairs, + mpKerningPairs + mnKerningPairs, aRefPair, ImplCmpKernData ); + if( pPair->wFirst==aRefPair.wFirst && pPair->wSecond==aRefPair.wSecond ) + { + mpGlyphAdvances[ i-1 ] += pPair->iKernAmount; + mnWidth += pPair->iKernAmount; + } + } + else if( rArgs.mnFlags & SAL_LAYOUT_KERNING_ASIAN ) +#endif // GCP_KERN_HACK + if( (0x3000 == (0xFF00 & pStr[i-1])) && (0x3000 == (0xFF00 & pStr[i])) ) { @@ -1707,7 +1747,16 @@ SalLayout* SalGraphics::LayoutText( ImplLayoutArgs& rArgs ) else #endif // USE_UNISCRIBE { - pWinLayout = new SimpleWinLayout( maGraphicsData.mhDC, rArgs ); +#ifdef GCP_KERN_HACK + if( (rArgs.mnFlags & SAL_LAYOUT_KERNING_PAIRS) && maGraphicsData.mbFontKernInit ) + GetKernPairs( 0, NULL ); +#endif // GCP_KERN_HACK + + pWinLayout = new SimpleWinLayout( maGraphicsData.mhDC, rArgs +#ifdef GCP_KERN_HACK + , maGraphicsData.mpFontKernPairs, maGraphicsData.mnFontKernPairCount +#endif // GCP_KERN_HACK + ); } if( !pWinLayout->LayoutText( rArgs ) ) |