summaryrefslogtreecommitdiff
path: root/vcl/quartz/ctlayout.cxx
diff options
context:
space:
mode:
authorHerbert Dürr <hdu@apache.org>2014-05-20 12:00:50 +0000
committerCaolán McNamara <caolanm@redhat.com>2014-06-03 09:22:52 +0100
commit687f0c9300d499b78deea2890b4c2019adb2d67d (patch)
treee3b0d8cef03b52e2d73ecd48865309bea4f7176c /vcl/quartz/ctlayout.cxx
parentee9dd6c086f7bda615d5b28d3319a83ce1673607 (diff)
Resolves: #i124935# fix expanded/condensed text breaking...
in the CoreText engine the concept of an extra-width per code-unit was obsolete at least since apps supported unicode with its different normalization forms, diacritical marks, surrogate-pairs, non-printing characters such as ZWJ/ZWNJ/RLM, etc. so of course modern engines like CoreText don't aid this typographical crime. The fix here extends the CTLayout::GetTextBreak() method to handle the obsolete semantic of per code-unit extra-widths by successively approximating the number of involved code-units. (cherry picked from commit a9b9ceff86f35be1eeff5f251d24e338db760a1e) Conflicts: vcl/aqua/source/gdi/ctlayout.cxx Change-Id: I52a7f7488a9e8a303ed7271df2a24a3c85098ce3
Diffstat (limited to 'vcl/quartz/ctlayout.cxx')
-rw-r--r--vcl/quartz/ctlayout.cxx35
1 files changed, 27 insertions, 8 deletions
diff --git a/vcl/quartz/ctlayout.cxx b/vcl/quartz/ctlayout.cxx
index 347cc5e7fbee..8c42cc8537bb 100644
--- a/vcl/quartz/ctlayout.cxx
+++ b/vcl/quartz/ctlayout.cxx
@@ -580,20 +580,39 @@ long CTLayout::FillDXArray( sal_Int32* pDXArray ) const
return nPixWidth;
}
-sal_Int32 CTLayout::GetTextBreak( long nMaxWidth, long /*nCharExtra*/, int nFactor ) const
+sal_Int32 CTLayout::GetTextBreak( long nMaxWidth, long nCharExtra, int nFactor ) const
{
if( !mpCTLine )
return -1;
CTTypesetterRef aCTTypeSetter = CTTypesetterCreateWithAttributedString( mpAttrString );
- const double fCTMaxWidth = (double)nMaxWidth / nFactor;
- CFIndex nIndex = CTTypesetterSuggestClusterBreak( aCTTypeSetter, 0, fCTMaxWidth );
- CFRelease( aCTTypeSetter );
-
- if( nIndex >= mnCharCount )
- return -1;
+ CFIndex nBestGuess = (nCharExtra >= 0) ? 0 : mnCharCount;
+ for( int i = 1; i <= mnCharCount; i *= 2 )
+ {
+ // guess the target width considering char-extra expansion/condensation
+ const double nTargetWidth = nMaxWidth - nBestGuess * nCharExtra;
+ const double fCTMaxWidth = nTargetWidth / nFactor;
+ // calculate the breaking index for the guessed target width
+ const CFIndex nNewIndex = CTTypesetterSuggestClusterBreak( aCTTypeSetter, 0, fCTMaxWidth );
+ if( nNewIndex >= mnCharCount ) {
+ CFRelease( aCTTypeSetter );
+ return -1;
+ }
+ // check if the original extra-width guess was good
+ if( !nCharExtra )
+ nBestGuess = nNewIndex;
+ if( nBestGuess == nNewIndex )
+ break;
+ // prepare another round for a different number of characters
+ CFIndex nNewGuess = (nNewIndex + nBestGuess + 1) / 2;
+ if( nNewGuess == nBestGuess )
+ nNewGuess += (nNewIndex > nBestGuess) ? +1 : -1;
+ nBestGuess = nNewGuess;
+ }
- nIndex += mnMinCharPos;
+ // suggest the best fitting cluster break as breaking position
+ CFRelease( aCTTypeSetter );
+ const int nIndex = nBestGuess + mnMinCharPos;
return nIndex;
}