[Libreoffice-commits] core.git: include/vcl sw/source vcl/inc vcl/source

Mark Hung marklh9 at gmail.com
Tue Nov 3 12:02:10 PST 2015


 include/vcl/metric.hxx              |    1 +
 sw/source/core/inc/scriptinfo.hxx   |    3 ++-
 sw/source/core/text/porlay.cxx      |   12 +++++++++---
 sw/source/core/txtnode/fntcache.cxx |   24 ++++++++++++++++--------
 vcl/inc/impfont.hxx                 |    3 ++-
 vcl/inc/outfont.hxx                 |    1 +
 vcl/source/gdi/metric.cxx           |    5 +++++
 vcl/source/outdev/font.cxx          |   19 +++++++++++++++++++
 8 files changed, 55 insertions(+), 13 deletions(-)

New commits:
commit 281be263619a8e513a26e6a9165d1d77cf6524ea
Author: Mark Hung <marklh9 at gmail.com>
Date:   Wed Oct 21 22:34:08 2015 +0800

    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 at libreoffice.org>
    Reviewed-by: Norbert Thiebaud <nthiebaud at gmail.com>

diff --git a/include/vcl/metric.hxx b/include/vcl/metric.hxx
index ba2393d..ddf27eb 100644
--- a/include/vcl/metric.hxx
+++ b/include/vcl/metric.hxx
@@ -72,6 +72,7 @@ public:
     long                GetExtLeading() const;
     long                GetLineHeight() const;
     long                GetSlant() const;
+    bool                IsFullstopCentered() const;
 
     FontMetric&         operator=( const FontMetric& rMetric );
     bool                operator==( const FontMetric& rMetric ) const;
diff --git a/sw/source/core/inc/scriptinfo.hxx b/sw/source/core/inc/scriptinfo.hxx
index ee476ac..2201343 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 d7c217d..c5952ab 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 2f09296..ea290e4 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;
diff --git a/vcl/inc/impfont.hxx b/vcl/inc/impfont.hxx
index 25aa15a..fd9fb34 100644
--- a/vcl/inc/impfont.hxx
+++ b/vcl/inc/impfont.hxx
@@ -103,7 +103,7 @@ private:
     sal_uInt16          mnMiscFlags;   // Misc Flags
     sal_uInt32          mnRefCount;    // Reference Counter
 
-    enum { DEVICE_FLAG=1, SCALABLE_FLAG=2, LATIN_FLAG=4, CJK_FLAG=8, CTL_FLAG=16 };
+    enum { DEVICE_FLAG=1, SCALABLE_FLAG=2, LATIN_FLAG=4, CJK_FLAG=8, CTL_FLAG=16, FULLSTOP_CENTERED_FLAG=32 };
 
 public:
                         ImplFontMetric();
@@ -116,6 +116,7 @@ public:
     long                GetExtLeading() const   { return mnExtLeading; }
     long                GetLineHeight() const   { return mnLineHeight; }
     long                GetSlant() const        { return mnSlant; }
+    bool                IsFullstopCentered() const { return  ((mnMiscFlags & FULLSTOP_CENTERED_FLAG ) != 0); }
 
     bool                IsScalable() const      { return ((mnMiscFlags & SCALABLE_FLAG) != 0); }
 
diff --git a/vcl/inc/outfont.hxx b/vcl/inc/outfont.hxx
index c4c30fb..0becf0a 100644
--- a/vcl/inc/outfont.hxx
+++ b/vcl/inc/outfont.hxx
@@ -183,6 +183,7 @@ public: // TODO: hide members behind accessor methods
     bool                mbDevice;                   // Flag for Device Fonts
     bool                mbScalableFont;
     bool                mbKernableFont;
+    bool                mbFullstopCentered;
 
     // font metrics that are usually derived from the measurements
     long                mnUnderlineSize;            // Lineheight of Underline
diff --git a/vcl/source/gdi/metric.cxx b/vcl/source/gdi/metric.cxx
index 5ed467e..05630c6 100644
--- a/vcl/source/gdi/metric.cxx
+++ b/vcl/source/gdi/metric.cxx
@@ -151,6 +151,11 @@ long FontMetric::GetSlant() const
     return mpImplMetric->GetSlant();
 }
 
+bool FontMetric::IsFullstopCentered() const
+{
+    return mpImplMetric->IsFullstopCentered();
+}
+
 FontMetric& FontMetric::operator =( const FontMetric& rMetric )
 {
     vcl::FontInfo::operator=( rMetric );
diff --git a/vcl/source/outdev/font.cxx b/vcl/source/outdev/font.cxx
index fd7b818..6d64164 100644
--- a/vcl/source/outdev/font.cxx
+++ b/vcl/source/outdev/font.cxx
@@ -216,6 +216,8 @@ FontMetric OutputDevice::GetFontMetric() const
             aMetric.mpImplMetric->mnMiscFlags |= ImplFontMetric::DEVICE_FLAG;
     if( pMetric->mbScalableFont )
             aMetric.mpImplMetric->mnMiscFlags |= ImplFontMetric::SCALABLE_FLAG;
+    if ( pMetric->mbFullstopCentered)
+            aMetric.mpImplMetric->mnMiscFlags |= ImplFontMetric::FULLSTOP_CENTERED_FLAG;
     aMetric.mpImplMetric->mnAscent      = ImplDevicePixelToLogicHeight( pMetric->mnAscent+mnEmphasisAscent );
     aMetric.mpImplMetric->mnDescent     = ImplDevicePixelToLogicHeight( pMetric->mnDescent+mnEmphasisDescent );
     aMetric.mpImplMetric->mnIntLeading  = ImplDevicePixelToLogicHeight( pMetric->mnIntLeading+mnEmphasisAscent );
@@ -1744,6 +1746,7 @@ ImplFontMetricData::ImplFontMetricData( const FontSelectPattern& rFontSelData )
     , mnMinKashida( 0 )
     , meFamilyType(FAMILY_DONTKNOW)
     , mbScalableFont(false)
+    , mbFullstopCentered(false)
     , mnUnderlineSize( 0 )
     , mnUnderlineOffset( 0 )
     , mnBUnderlineSize( 0 )
@@ -1788,6 +1791,7 @@ ImplFontMetricData::ImplFontMetricData( const FontSelectPattern& rFontSelData )
     }
 }
 
+
 void ImplFontMetricData::ImplInitTextLineSize( const OutputDevice* pDev )
 {
     long nDescent = mnDescent;
@@ -1870,6 +1874,21 @@ void ImplFontMetricData::ImplInitTextLineSize( const OutputDevice* pDev )
     mnDStrikeoutSize       = n2LineHeight;
     mnDStrikeoutOffset1    = nStrikeoutOffset - n2LineDY2 - n2LineHeight;
     mnDStrikeoutOffset2    = mnDStrikeoutOffset1 + n2LineDY + n2LineHeight;
+
+    const vcl::Font& rFont ( pDev->GetFont() );
+    bool bCentered = true;
+    if (MsLangId::isCJK(rFont.GetLanguage()))
+    {
+        const OUString sFullstop( sal_Unicode( 0x3001 ) ); // Fullwidth fullstop
+        Rectangle aRect;
+        pDev->GetTextBoundRect( aRect, sFullstop );
+        const sal_uInt16 nH = rFont.GetSize().Height();
+        const sal_uInt16 nB = aRect.Left();
+        // Use 18.75% as a threshold to define a centered fullwidth fullstop.
+        // In general, nB/nH < 5% for most Japanese fonts.
+        bCentered = (nB > (((nH >> 1)+nH)>>3)) ? true : false;
+    }
+    mbFullstopCentered = bCentered ;
 }
 
 void ImplFontMetricData::ImplInitAboveTextLineSize()


More information about the Libreoffice-commits mailing list