Author: hdu
Date: Tue Feb 18 15:32:46 2014
New Revision: 1569388

URL: http://svn.apache.org/r1569388
Log:
#i124233# fix CoreText justification of text with trailing spaces

the fix works also for EditEngine by ignoring Writer's halfspace magic.
TODO: replace that halfspace magic with a generic solution.

Modified:
    openoffice/trunk/main/vcl/aqua/source/gdi/ctlayout.cxx

Modified: openoffice/trunk/main/vcl/aqua/source/gdi/ctlayout.cxx
URL: 
http://svn.apache.org/viewvc/openoffice/trunk/main/vcl/aqua/source/gdi/ctlayout.cxx?rev=1569388&r1=1569387&r2=1569388&view=diff
==============================================================================
--- openoffice/trunk/main/vcl/aqua/source/gdi/ctlayout.cxx (original)
+++ openoffice/trunk/main/vcl/aqua/source/gdi/ctlayout.cxx Tue Feb 18 15:32:46 
2014
@@ -72,7 +72,6 @@ private:
        // cached details about the resulting layout
        // mutable members since these details are all lazy initialized
        mutable double  mfCachedWidth;                  // cached value of 
resulting typographical width
-       mutable double  mfTrailingSpaceWidth;   // in Pixels
 
        // x-offset relative to layout origin
        // currently only used in RTL-layouts
@@ -89,7 +88,6 @@ CTLayout::CTLayout( const CTTextStyle* p
 ,      mnTrailingSpaces( 0 )
 ,      mfFontScale( pTextStyle->mfFontScale )
 ,      mfCachedWidth( -1 )
-,      mfTrailingSpaceWidth( 0 )
 ,      mnBaseAdv( 0 )
 {
        CFRetain( mpTextStyle->GetStyleDict() );
@@ -146,60 +144,49 @@ void CTLayout::AdjustLayout( ImplLayoutA
                return;
 
        const DynCoreTextSyms& rCT = DynCoreTextSyms::get();
-       // CoreText fills trailing space during justification so we have to
-       // take that into account when requesting CT to justify something
-       mfTrailingSpaceWidth = rCT.LineGetTrailingWhitespaceWidth( mpCTLine );
-       const int nTrailingSpaceWidth = rint( mfFontScale * 
mfTrailingSpaceWidth );
 
-       int nOrigWidth = GetTextWidth();
        int nPixelWidth = rArgs.mnLayoutWidth;
-       if( nPixelWidth )
-       {
-               nPixelWidth -= nTrailingSpaceWidth;
-               if( nPixelWidth <= 0)
-                       return;
-       }
-       else if( rArgs.mpDXArray )
+       if( rArgs.mpDXArray )
        {
                // for now we are only interested in the layout width
                // TODO: use all mpDXArray elements for layouting
-               nPixelWidth = rArgs.mpDXArray[ mnCharCount - 1 - 
mnTrailingSpaces ];
+               nPixelWidth = rArgs.mpDXArray[ mnCharCount-1 ];
        }
 
        // short-circuit when justifying an all-whitespace string
        if( mnTrailingSpaces >= mnCharCount)
        {
-               mfCachedWidth = mfTrailingSpaceWidth = nPixelWidth / 
mfFontScale;
+               mfCachedWidth = nPixelWidth / mfFontScale;
                return;
        }
 
-       // in RTL-layouts trailing spaces are leftmost
-       // TODO: use BiDi-algorithm to thoroughly check this assumption
-       if( rArgs.mnFlags & SAL_LAYOUT_BIDI_RTL)
-               mnBaseAdv = nTrailingSpaceWidth;
-
        // return early if there is nothing to do
        if( nPixelWidth <= 0 )
                return;
 
        // HACK: justification requests which change the width by just one 
pixel are probably
        // #i86038# introduced by lossy conversions between integer based 
coordinate system
+       const int nOrigWidth = GetTextWidth();
        if( (nOrigWidth >= nPixelWidth-1) && (nOrigWidth <= nPixelWidth+1) )
                return;
 
        // if the text to be justified has whitespace in it then
        // - Writer goes crazy with its HalfSpace magic
-       // - LayoutEngine handles spaces specially (in particular at the text 
start or end)
+       // - CoreText handles spaces specially (in particular at the text end)
        if( mnTrailingSpaces ) {
-               // adjust for Writer's SwFntObj::DrawText() Halfspace magic at 
the text end
-               std::vector<sal_Int32> aOrigDXAry;
-               aOrigDXAry.resize( mnCharCount);
-               FillDXArray( &aOrigDXAry[0] );
-               int nLastCharSpace = rArgs.mpDXArray[ 
mnCharCount-1-mnTrailingSpaces ]
-                       - aOrigDXAry[ mnCharCount-1-mnTrailingSpaces ];
-               nPixelWidth -= nLastCharSpace;
-               if( nPixelWidth < 0 )
+               int nTrailingSpaceWidth = 0;
+               if( rArgs.mpDXArray) {
+                       const int nFullPixWidth = nPixelWidth;
+                       nPixelWidth = rArgs.mpDXArray[ 
mnCharCount-1-mnTrailingSpaces ];
+                       nTrailingSpaceWidth = nFullPixWidth - nPixelWidth;
+               } else {
+                       const double fTrailingSpaceWidth = 
rCT.LineGetTrailingWhitespaceWidth( mpCTLine );
+                       nTrailingSpaceWidth = rint(fTrailingSpaceWidth);
+               }
+               nPixelWidth -= nTrailingSpaceWidth;
+               if( nPixelWidth <= 0 )
                        return;
+
                // recreate the CoreText line layout without trailing spaces
                CFRelease( mpCTLine );
                CFStringRef aCFText = CFStringCreateWithCharactersNoCopy( NULL, 
rArgs.mpStr + mnMinCharPos,
@@ -208,9 +195,15 @@ void CTLayout::AdjustLayout( ImplLayoutA
                mpCTLine = CTLineCreateWithAttributedString( pAttrStr );
                CFRelease( aCFText);
                CFRelease( pAttrStr );
+
+               // in RTL-layouts trailing spaces are leftmost
+               // TODO: use BiDi-algorithm to thoroughly check this assumption
+               if( rArgs.mnFlags & SAL_LAYOUT_BIDI_RTL)
+                       mnBaseAdv = nTrailingSpaceWidth;
        }
 
-       CTLineRef pNewCTLine = rCT.LineCreateJustifiedLine( mpCTLine, 1.0, 
nPixelWidth / mfFontScale );
+       const double fAdjustedWidth = nPixelWidth / mfFontScale;
+       CTLineRef pNewCTLine = rCT.LineCreateJustifiedLine( mpCTLine, 1.0, 
fAdjustedWidth );
        if( !pNewCTLine ) { // CTLineCreateJustifiedLine can and does fail
                // handle failure by keeping the unjustified layout
                // TODO: a better solution such as
@@ -221,8 +214,7 @@ void CTLayout::AdjustLayout( ImplLayoutA
        }
        CFRelease( mpCTLine );
        mpCTLine = pNewCTLine;
-       mfCachedWidth = -1; // TODO: can we set it directly to target width we 
requested? For now we re-measure
-       mfTrailingSpaceWidth = 0;
+       mfCachedWidth = fAdjustedWidth;
 }
 
 // -----------------------------------------------------------------------
@@ -404,8 +396,8 @@ long CTLayout::FillDXArray( sal_Int32* p
                        CTRunRef pGlyphRun = (CTRunRef)CFArrayGetValueAtIndex( 
aGlyphRuns, nRunIndex );
                        const CFIndex nGlyphCount = CTRunGetGlyphCount( 
pGlyphRun );
                        const CFRange aFullRange = CFRangeMake( 0, nGlyphCount 
);
-                       aSizeVec.reserve( nGlyphCount );
-                       aIndexVec.reserve( nGlyphCount );
+                       aSizeVec.resize( nGlyphCount );
+                       aIndexVec.resize( nGlyphCount );
                        CTRunGetAdvances( pGlyphRun, aFullRange, &aSizeVec[0] );
                        CTRunGetStringIndices( pGlyphRun, aFullRange, 
&aIndexVec[0] );
                        for( int i = 0; i != nGlyphCount; ++i ) {


Reply via email to