tdf#152048: Fix underline width for Kashida-justified text
Fix GenericSalLayout::GetTextWidth() again, this time doing away with
using linearPos as it is wrong, the glyph’s position is not directly
related to how much it contributes to the text width (for example,
combining marks have zero advance width yet their position is different
from the base glyph they apply too). This is a followup to:
commit ce7c1c608fa99c86c8f2380cd8b82d02123f514e
Author: Khaled Hosny <khaled@aliftype.com>
Date: Wed Aug 31 07:07:54 2022 +0200
vcl: Fix GenericSalLayout::GetTextWidth()
Additionally, inserted Kashida should have its origWidth and newWidth
both set to zero, since it does not add to the text width, all
additional width is already added to the glyph the Kashida is applied
to.
With both fixes, the text width of Kashida-justified lines is correctly
calculated and the underline no longer extends beyond the text line.
Fix test expectation now we are reporting the real text width.
Change-Id: I0de93f955929cf3030cf420cb4f4e94df974fb79
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/152267
Tested-by: Jenkins
Reviewed-by: خالد حسني <khaled@libreoffice.org>
diff --git a/vcl/qa/cppunit/pdfexport/pdfexport.cxx b/vcl/qa/cppunit/pdfexport/pdfexport.cxx
index 4bdc920..bf2ca13 100644
--- a/vcl/qa/cppunit/pdfexport/pdfexport.cxx
+++ b/vcl/qa/cppunit/pdfexport/pdfexport.cxx
@@ -777,15 +777,15 @@ CPPUNIT_TEST_FIXTURE(PdfExportTest, testTdf108963)
pSegment = pPdfPageObject->getPathSegment(1);
CPPUNIT_ASSERT_EQUAL(vcl::pdf::PDFSegmentType::Lineto, pSegment->getType());
aPoint = pSegment->getPoint();
CPPUNIT_ASSERT_DOUBLES_EQUAL(275.074, aPoint.getX(), 0.0005);
CPPUNIT_ASSERT_DOUBLES_EQUAL(267.590, aPoint.getY(), 0.0005);
CPPUNIT_ASSERT_DOUBLES_EQUAL(275.216, aPoint.getX(), 0.0005);
CPPUNIT_ASSERT_DOUBLES_EQUAL(267.732, aPoint.getY(), 0.0005);
CPPUNIT_ASSERT(!pSegment->isClosed());
pSegment = pPdfPageObject->getPathSegment(2);
CPPUNIT_ASSERT_EQUAL(vcl::pdf::PDFSegmentType::Lineto, pSegment->getType());
aPoint = pSegment->getPoint();
CPPUNIT_ASSERT_DOUBLES_EQUAL(287.490, aPoint.getX(), 0.0005);
CPPUNIT_ASSERT_DOUBLES_EQUAL(251.801, aPoint.getY(), 0.0005);
CPPUNIT_ASSERT_DOUBLES_EQUAL(287.660, aPoint.getX(), 0.0005);
CPPUNIT_ASSERT_DOUBLES_EQUAL(251.914, aPoint.getY(), 0.0005);
CPPUNIT_ASSERT(!pSegment->isClosed());
pSegment = pPdfPageObject->getPathSegment(3);
diff --git a/vcl/source/gdi/CommonSalLayout.cxx b/vcl/source/gdi/CommonSalLayout.cxx
index 0c6043a..907197c7 100644
--- a/vcl/source/gdi/CommonSalLayout.cxx
+++ b/vcl/source/gdi/CommonSalLayout.cxx
@@ -834,7 +834,7 @@ void GenericSalLayout::ApplyDXArray(const double* pDXArray, const sal_Bool* pKas
aPos.adjustX(-nClusterWidth + pGlyphIter->origWidth());
while (nCopies--)
{
GlyphItem aKashida(nCharPos, 0, nKashidaIndex, aPos, nFlags, nKashidaWidth, 0, 0);
GlyphItem aKashida(nCharPos, 0, nKashidaIndex, aPos, nFlags, 0, 0, 0);
pGlyphIter = m_GlyphItems.insert(pGlyphIter, aKashida);
aPos.adjustX(nKashidaWidth - nOverlap);
++pGlyphIter;
diff --git a/vcl/source/gdi/sallayout.cxx b/vcl/source/gdi/sallayout.cxx
index 85ad838..1ed2a37a 100644
--- a/vcl/source/gdi/sallayout.cxx
+++ b/vcl/source/gdi/sallayout.cxx
@@ -269,19 +269,10 @@ DeviceCoordinate GenericSalLayout::GetTextWidth() const
if (!m_GlyphItems.IsValid())
return 0;
// initialize the extent
DeviceCoordinate nMinPos = 0;
DeviceCoordinate nMaxPos = 0;
DeviceCoordinate nWidth = 0;
for (auto const& aGlyphItem : m_GlyphItems)
{
// update the text extent with the glyph extent
DeviceCoordinate nXPos = aGlyphItem.linearPos().getX() - aGlyphItem.xOffset();
nMinPos = std::min(nMinPos, nXPos);
nMaxPos = std::max(nMaxPos, nXPos + aGlyphItem.newWidth());
}
nWidth += aGlyphItem.newWidth();
DeviceCoordinate nWidth = nMaxPos - nMinPos;
return nWidth;
}