summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHerbert Dürr <hdu@apache.org>2014-02-20 13:52:52 +0000
committerCaolán McNamara <caolanm@redhat.com>2014-02-26 06:08:11 -0600
commiteb35d71c2cb46d066b42be49b7749d96a647b50f (patch)
treeb4af2d15b23c97b17e230daff33372a0282ead6b
parentdf9206c4ad9227029f85caa84df358e66ecafe9d (diff)
fdo#64957: #i124233# prevent the accumulation of rounding errors
in CTLayout::FillDXArry() Change-Id: Ifb4f16fb76f67d5b5c96fdb0545c64eb8316aa3c Reviewed-on: https://gerrit.libreoffice.org/8359 Reviewed-by: Caolán McNamara <caolanm@redhat.com> Tested-by: Caolán McNamara <caolanm@redhat.com>
-rw-r--r--vcl/coretext/ctlayout.cxx16
1 files changed, 12 insertions, 4 deletions
diff --git a/vcl/coretext/ctlayout.cxx b/vcl/coretext/ctlayout.cxx
index 0e9a6e0430ac..d248c487e396 100644
--- a/vcl/coretext/ctlayout.cxx
+++ b/vcl/coretext/ctlayout.cxx
@@ -369,9 +369,8 @@ long CTLayout::FillDXArray( sal_Int32* pDXArray ) const
long nPixWidth = GetTextWidth();
if( pDXArray ) {
- // initialize the result array
- for( int i = 0; i < mnCharCount; ++i)
- pDXArray[i] = 0;
+ // prepare the sub-pixel accurate logical-width array
+ ::std::vector<float> aWidthVector( mnCharCount );
// handle each glyph run
CFArrayRef aGlyphRuns = CTLineGetGlyphRuns( mpCTLine );
const int nRunCount = CFArrayGetCount( aGlyphRuns );
@@ -389,9 +388,18 @@ long CTLayout::FillDXArray( sal_Int32* pDXArray ) const
CTRunGetStringIndices( pGlyphRun, aFullRange, &aIndexVec[0] );
for( int i = 0; i != nGlyphCount; ++i ) {
const int nRelIdx = aIndexVec[i];
- pDXArray[ nRelIdx ] += lrint(aSizeVec[i].width);
+ aWidthVector[nRelIdx] += aSizeVec[i].width;
}
}
+
+ // convert the sub-pixel accurate array into classic pDXArray integers
+ float fWidthSum = 0.0;
+ sal_Int32 nOldDX = 0;
+ for( int i = 0; i < mnCharCount; ++i) {
+ const sal_Int32 nNewDX = rint( fWidthSum += aWidthVector[i]);
+ pDXArray[i] = nNewDX - nOldDX;
+ nOldDX = nNewDX;
+ }
}
return nPixWidth;