diff options
author | Mark Hung <marklh9@gmail.com> | 2015-10-21 22:34:08 +0800 |
---|---|---|
committer | Norbert Thiebaud <nthiebaud@gmail.com> | 2015-11-03 20:01:46 +0000 |
commit | 281be263619a8e513a26e6a9165d1d77cf6524ea (patch) | |
tree | 93b961416e794b100fbc86ac5af80ec3a65428a2 /sw | |
parent | 2b48a5f1550e6f62931c2973086e8970f88f58ee (diff) |
tdf#81144 Chinese full-width punctuation does not align properly
Ideographic fullstop and comma in most Chinese fonts are centered,
while those in Japanese fonts align closer to the left. Original
compression algorithm trimed right side of the punctuation, making
fullwidth fullstop or comma in Chinese font visually unbalanced.
In worst case, it crowds together with the followed compressed
punctuation.
This patch fix the situation in the folowing way
1) make compression less stronger.
2) Trim space according to glyph bearing to font height ratio.
3) fix a memory access violation issue
Change-Id: Icff215064e6c442fd36eac8e01b01fb6acb27594
Reviewed-on: https://gerrit.libreoffice.org/19517
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Norbert Thiebaud <nthiebaud@gmail.com>
Diffstat (limited to 'sw')
-rw-r--r-- | sw/source/core/inc/scriptinfo.hxx | 3 | ||||
-rw-r--r-- | sw/source/core/text/porlay.cxx | 12 | ||||
-rw-r--r-- | sw/source/core/txtnode/fntcache.cxx | 24 |
3 files changed, 27 insertions, 12 deletions
diff --git a/sw/source/core/inc/scriptinfo.hxx b/sw/source/core/inc/scriptinfo.hxx index ee476ac983e4..2201343dc183 100644 --- a/sw/source/core/inc/scriptinfo.hxx +++ b/sw/source/core/inc/scriptinfo.hxx @@ -37,7 +37,7 @@ typedef std::list< sal_Int32 > PositionList; class SwScriptInfo { public: - enum CompType { KANA, SPECIAL_LEFT, SPECIAL_RIGHT, NONE }; + enum CompType { KANA, SPECIAL_LEFT, SPECIAL_RIGHT, NONE, SPECIAL_MIDDLE}; private: //! Records a single change in script type. @@ -255,6 +255,7 @@ public: // modifies the kerning array according to a given compress value long Compress( long* pKernArray, sal_Int32 nIdx, sal_Int32 nLen, const sal_uInt16 nCompress, const sal_uInt16 nFontHeight, + const bool bCentered, Point* pPoint = NULL ) const; /** Performs a kashida justification on the kerning array diff --git a/sw/source/core/text/porlay.cxx b/sw/source/core/text/porlay.cxx index d7c217dc31d3..c5952abf2b65 100644 --- a/sw/source/core/text/porlay.cxx +++ b/sw/source/core/text/porlay.cxx @@ -874,12 +874,15 @@ void SwScriptInfo::InitScriptInfo( const SwTextNode& rNode, bool bRTL ) eState = SPECIAL_LEFT; break; // Right punctuation found - case 0x3001: case 0x3002: case 0x3009: case 0x300B: + case 0x3009: case 0x300B: case 0x300D: case 0x300F: case 0x3011: case 0x3015: case 0x3017: case 0x3019: case 0x301B: case 0x301E: case 0x301F: eState = SPECIAL_RIGHT; break; + case 0x3001: case 0x3002: // Fullstop or comma + eState = SPECIAL_MIDDLE ; + break; default: eState = ( 0x3040 <= cChar && 0x3100 > cChar ) ? KANA : NONE; } @@ -1509,6 +1512,7 @@ size_t SwScriptInfo::HasKana( sal_Int32 nStart, const sal_Int32 nLen ) const long SwScriptInfo::Compress( long* pKernArray, sal_Int32 nIdx, sal_Int32 nLen, const sal_uInt16 nCompress, const sal_uInt16 nFontHeight, + bool bCenter, Point* pPoint ) const { SAL_WARN_IF( !nCompress, "sw.core", "Compression without compression?!" ); @@ -1571,7 +1575,7 @@ long SwScriptInfo::Compress( long* pKernArray, sal_Int32 nIdx, sal_Int32 nLen, long nMove = 0; if( SwScriptInfo::KANA != nType ) { - nLast /= 20000; + nLast /= 24000; if( pPoint && SwScriptInfo::SPECIAL_LEFT == nType ) { if( nI ) @@ -1582,12 +1586,14 @@ long SwScriptInfo::Compress( long* pKernArray, sal_Int32 nIdx, sal_Int32 nLen, nLast = 0; } } + else if( bCenter && SwScriptInfo::SPECIAL_MIDDLE == nType ) + nMove = nLast / 2; } else nLast /= 100000; nSub -= nLast; nLast = pKernArray[ nI ]; - if( nMove ) + if( nI && nMove ) pKernArray[ nI - 1 ] += nMove; pKernArray[ nI++ ] -= nSub; ++nIdx; diff --git a/sw/source/core/txtnode/fntcache.cxx b/sw/source/core/txtnode/fntcache.cxx index 2f09296b023b..ea290e4e7f06 100644 --- a/sw/source/core/txtnode/fntcache.cxx +++ b/sw/source/core/txtnode/fntcache.cxx @@ -629,6 +629,12 @@ static bool lcl_IsMonoSpaceFont( const vcl::RenderContext& rOut ) return nWidth1 == nWidth2; } +static bool lcl_IsFullstopCentered( const vcl::RenderContext& rOut ) +{ + const FontMetric aMetric( rOut.GetFontMetric() ); + return aMetric.IsFullstopCentered() ; +} + /* This helper structure (SwForbidden) contains the already marked parts of the string to avoid double lines (e.g grammar + spell check error) */ @@ -1053,7 +1059,7 @@ void SwFntObj::DrawText( SwDrawTextInfo &rInf ) lcl_IsMonoSpaceFont( *(rInf.GetpOut()) ) ) { pSI->Compress( pKernArray, rInf.GetIdx(), rInf.GetLen(), - rInf.GetKanaComp(), (sal_uInt16)aFont.GetSize().Height(), &aTextOriginPos ); + rInf.GetKanaComp(), (sal_uInt16)aFont.GetSize().Height(), lcl_IsFullstopCentered( rInf.GetOut() ) , &aTextOriginPos ); bSpecialJust = true; } ///Asian Justification @@ -1224,7 +1230,7 @@ void SwFntObj::DrawText( SwDrawTextInfo &rInf ) { pSI->Compress( pKernArray, rInf.GetIdx(), rInf.GetLen(), rInf.GetKanaComp(), - (sal_uInt16)aFont.GetSize().Height(), &aTextOriginPos ); + (sal_uInt16)aFont.GetSize().Height(), lcl_IsFullstopCentered( rInf.GetOut() ), &aTextOriginPos ); bSpecialJust = true; } @@ -1434,10 +1440,10 @@ void SwFntObj::DrawText( SwDrawTextInfo &rInf ) Point aTmpPos( aTextOriginPos ); pSI->Compress( pScrArray, rInf.GetIdx(), rInf.GetLen(), rInf.GetKanaComp(), - (sal_uInt16)aFont.GetSize().Height(), &aTmpPos ); + (sal_uInt16)aFont.GetSize().Height(), lcl_IsFullstopCentered( rInf.GetOut() ), &aTmpPos ); pSI->Compress( pKernArray, rInf.GetIdx(), rInf.GetLen(), rInf.GetKanaComp(), - (sal_uInt16)aFont.GetSize().Height(), &aTextOriginPos ); + (sal_uInt16)aFont.GetSize().Height(), lcl_IsFullstopCentered( rInf.GetOut() ), &aTextOriginPos ); } // Asian Justification @@ -1904,7 +1910,7 @@ Size SwFntObj::GetTextSize( SwDrawTextInfo& rInf ) if( bCompress ) rInf.SetKanaDiff( rInf.GetScriptInfo()->Compress( pKernArray, rInf.GetIdx(), nLn, rInf.GetKanaComp(), - (sal_uInt16)aFont.GetSize().Height() ) ); + (sal_uInt16)aFont.GetSize().Height() ,lcl_IsFullstopCentered( rInf.GetOut() ) ) ); else rInf.SetKanaDiff( 0 ); @@ -1967,7 +1973,7 @@ Size SwFntObj::GetTextSize( SwDrawTextInfo& rInf ) rInf.GetIdx(), nLn ); rInf.SetKanaDiff( rInf.GetScriptInfo()->Compress( pKernArray, rInf.GetIdx(), nLn, rInf.GetKanaComp(), - (sal_uInt16) aFont.GetSize().Height() ) ); + (sal_uInt16) aFont.GetSize().Height() ,lcl_IsFullstopCentered( rInf.GetOut() ) ) ); aTextSize.Width() = pKernArray[ nLn - 1 ]; delete[] pKernArray; } @@ -2027,7 +2033,8 @@ sal_Int32 SwFntObj::GetCrsrOfst( SwDrawTextInfo &rInf ) { pSI->Compress( pKernArray, rInf.GetIdx(), rInf.GetLen(), rInf.GetKanaComp(), - (sal_uInt16) aFont.GetSize().Height() ); + (sal_uInt16) aFont.GetSize().Height(), + lcl_IsFullstopCentered( rInf.GetOut() ) ); } // Asian Justification @@ -2466,7 +2473,8 @@ sal_Int32 SwFont::GetTextBreak( SwDrawTextInfo& rInf, long nTextWidth ) rInf.GetOut().GetTextArray( rInf.GetText(), pKernArray, rInf.GetIdx(), nLn ); if( rInf.GetScriptInfo()->Compress( pKernArray, rInf.GetIdx(), nLn, - rInf.GetKanaComp(), (sal_uInt16)GetHeight( m_nActual ) ) ) + rInf.GetKanaComp(), (sal_uInt16)GetHeight( m_nActual ), + lcl_IsFullstopCentered( rInf.GetOut() ) ) ) { long nKernAdd = nKern; sal_Int32 nTmpBreak = nTextBreak2; |