You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openoffice.apache.org by hd...@apache.org on 2014/02/18 16:32:47 UTC
svn commit: r1569388 -
/openoffice/trunk/main/vcl/aqua/source/gdi/ctlayout.cxx
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 ) {