summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHerbert Dürr <hdu@apache.org>2014-05-20 12:00:50 +0000
committerChristian Lohmaier <lohmaier+LibreOffice@googlemail.com>2014-07-01 23:33:01 +0000
commit4adebd56d21cf104dca28a62c7015466a7a0c357 (patch)
tree393ea6df75b0187c2475b89424298296c5f874b2
parent8bee126e1c8fe83c909fd65d8a2ea5d7fb421da1 (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 (cherry picked from commit 687f0c9300d499b78deea2890b4c2019adb2d67d) Reviewed-on: https://gerrit.libreoffice.org/9627 Reviewed-by: Christian Lohmaier <lohmaier+LibreOffice@googlemail.com> Tested-by: Christian Lohmaier <lohmaier+LibreOffice@googlemail.com>
-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 1d96f905065e..f0cdc8a0b64a 100644
--- a/vcl/quartz/ctlayout.cxx
+++ b/vcl/quartz/ctlayout.cxx
@@ -569,20 +569,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;
}