Author: hdu
Date: Fri Dec 20 16:25:18 2013
New Revision: 1552720

URL: http://svn.apache.org/r1552720
Log:
#i123895# improve text justification for CoreText layouts

Justification of text containing whitespaces is problematic because
- Writer goes crazy with its HalfSpace magic in SwFntObj::DrawText()
- LayoutEngine handles spaces specially (in particular at the text start or end)

The change here improves the important space-at-text-end scenario considerably
by adjusting to Writer's text-end assumptions and by relieving the LayoutEngine
by stripping out trailing spaces before requesting the text justification.

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

Modified: openoffice/branches/rejuvenate01/main/vcl/aqua/source/gdi/ctlayout.cxx
URL: 
http://svn.apache.org/viewvc/openoffice/branches/rejuvenate01/main/vcl/aqua/source/gdi/ctlayout.cxx?rev=1552720&r1=1552719&r2=1552720&view=diff
==============================================================================
--- openoffice/branches/rejuvenate01/main/vcl/aqua/source/gdi/ctlayout.cxx 
(original)
+++ openoffice/branches/rejuvenate01/main/vcl/aqua/source/gdi/ctlayout.cxx Fri 
Dec 20 16:25:18 2013
@@ -152,7 +152,6 @@ void CTLayout::AdjustLayout( ImplLayoutA
        const int nTrailingSpaceWidth = rint( mfFontScale * 
mfTrailingSpaceWidth );
 
        int nOrigWidth = GetTextWidth();
-       nOrigWidth -= nTrailingSpaceWidth;
        int nPixelWidth = rArgs.mnLayoutWidth;
        if( nPixelWidth )
        {
@@ -181,6 +180,29 @@ void CTLayout::AdjustLayout( ImplLayoutA
        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)
+       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 )
+                       return;
+               // recreate the CoreText line layout without trailing spaces
+               CFRelease( mpCTLine );
+               CFStringRef aCFText = CFStringCreateWithCharactersNoCopy( NULL, 
rArgs.mpStr + mnMinCharPos,
+                       mnCharCount - mnTrailingSpaces, kCFAllocatorNull );
+               CFAttributedStringRef pAttrStr = CFAttributedStringCreate( 
NULL, aCFText, mpTextStyle->GetStyleDict() );
+               mpCTLine = CTLineCreateWithAttributedString( pAttrStr );
+               CFRelease( aCFText);
+               CFRelease( pAttrStr );
+       }
+
        CTLineRef pNewCTLine = rCT.LineCreateJustifiedLine( mpCTLine, 1.0, 
nPixelWidth / mfFontScale );
        if( !pNewCTLine ) { // CTLineCreateJustifiedLine can and does fail
                // handle failure by keeping the unjustified layout
@@ -344,12 +366,10 @@ long CTLayout::GetTextWidth() const
        if( (mnCharCount <= 0) || !mpCTLine )
                return 0;
 
-       if( mfCachedWidth < 0.0 ) {
-               mfCachedWidth = CTLineGetTypographicBounds( mpCTLine, NULL, 
NULL, NULL);
-               mfTrailingSpaceWidth = CTLineGetTrailingWhitespaceWidth( 
mpCTLine);
-       }
+       if( mfCachedWidth < 0.0 )
+               mfCachedWidth = CTLineGetTypographicBounds( mpCTLine, NULL, 
NULL, NULL );
 
-       const long nScaledWidth = lrint( mfFontScale * (mfCachedWidth + 
mfTrailingSpaceWidth));
+       const long nScaledWidth = lrint( mfFontScale * mfCachedWidth );
        return nScaledWidth;
 }
 
@@ -361,9 +381,6 @@ long CTLayout::FillDXArray( sal_Int32* p
        if( !pDXArray )
                return GetTextWidth();
 
-       // check assumptions
-       DBG_ASSERT( mfTrailingSpaceWidth==0.0, "CTLayout::FillDXArray() with 
fTSW!=0" );
-
        long nPixWidth = GetTextWidth();
        if( pDXArray ) {
                // initialize the result array


Reply via email to