vcl/qa/cppunit/logicalfontinstance.cxx  |   25 +++++++++++++++++++++++++
 vcl/source/font/LogicalFontInstance.cxx |   11 +++++++----
 2 files changed, 32 insertions(+), 4 deletions(-)

New commits:
commit 61e94a59a947c372a5802134d94f0908327a2366
Author:     Mike Kaganski <[email protected]>
AuthorDate: Sun Mar 31 00:45:25 2024 +0500
Commit:     Xisco Fauli <[email protected]>
CommitDate: Tue Apr 9 13:56:23 2024 +0200

    tdf#160436: fix glyph bounds calculation for vertical glyphs
    
    It is unclear if LogicalFontInstance::GetGlyphBoundRect can be called
    for both normal and rotated variants of the same glyph in the same font.
    If yes, then the normal and vertical variants must be cached separately,
    or possibly vertical variant can be not cached, but always calculated.
    This problem already existed before, so this change doesn't introduce
    a new issue.
    
    Change-Id: I9b50ef340c9e38db7bef890165519aadc96d3ffa
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/165581
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <[email protected]>
    (cherry picked from commit dff57d2b4f5abd1b51ebfb0015339471f61e72f9)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/165843
    Reviewed-by: Xisco Fauli <[email protected]>

diff --git a/vcl/qa/cppunit/logicalfontinstance.cxx 
b/vcl/qa/cppunit/logicalfontinstance.cxx
index 2a0e30d50c34..eb803ed40363 100644
--- a/vcl/qa/cppunit/logicalfontinstance.cxx
+++ b/vcl/qa/cppunit/logicalfontinstance.cxx
@@ -46,6 +46,7 @@ void VclLogicalFontInstanceTest::testglyphboundrect()
 
     basegfx::B2DRectangle aBoundRect;
     const auto LATIN_SMALL_LETTER_B = 0x0062;
+    const auto SECTION_SIGN = 0x00A7; // UTR#50: Vertical_Orientation (vo) 
property value U
     
pFontInstance->GetGlyphBoundRect(pFontInstance->GetGlyphIndex(LATIN_SMALL_LETTER_B),
 aBoundRect,
                                      false);
 
@@ -54,6 +55,14 @@ void VclLogicalFontInstanceTest::testglyphboundrect()
     CPPUNIT_ASSERT_DOUBLES_EQUAL(49.5, aBoundRect.getWidth(), 0.05);
     CPPUNIT_ASSERT_DOUBLES_EQUAL(80.8, aBoundRect.getHeight(), 0.05);
 
+    // tdf#160436: test vertically oriented glyphs
+    
pFontInstance->GetGlyphBoundRect(pFontInstance->GetGlyphIndex(SECTION_SIGN), 
aBoundRect, true);
+
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(-79.7, aBoundRect.getMinX(), 0.05);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(-55.0, aBoundRect.getMinY(), 0.05);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(88.9, aBoundRect.getWidth(), 0.05);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(48.8, aBoundRect.getHeight(), 0.05);
+
     font.SetOrientation(900_deg10);
     device->SetFont(font);
 
@@ -67,6 +76,14 @@ void VclLogicalFontInstanceTest::testglyphboundrect()
     CPPUNIT_ASSERT_DOUBLES_EQUAL(80.8, aBoundRect.getWidth(), 0.05);
     CPPUNIT_ASSERT_DOUBLES_EQUAL(49.5, aBoundRect.getHeight(), 0.05);
 
+    // tdf#160436: test vertically oriented glyphs
+    
pFontInstance->GetGlyphBoundRect(pFontInstance->GetGlyphIndex(SECTION_SIGN), 
aBoundRect, true);
+
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(-55.0, aBoundRect.getMinX(), 0.05);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(-9.2, aBoundRect.getMinY(), 0.05);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(48.8, aBoundRect.getWidth(), 0.05);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(88.9, aBoundRect.getHeight(), 0.05);
+
     font.SetOrientation(450_deg10);
     device->SetFont(font);
 
@@ -79,6 +96,14 @@ void VclLogicalFontInstanceTest::testglyphboundrect()
     CPPUNIT_ASSERT_DOUBLES_EQUAL(-96.4, aBoundRect.getMinY(), 0.05);
     CPPUNIT_ASSERT_DOUBLES_EQUAL(92.1, aBoundRect.getWidth(), 0.05);
     CPPUNIT_ASSERT_DOUBLES_EQUAL(92.1, aBoundRect.getHeight(), 0.05);
+
+    // tdf#160436: test vertically oriented glyphs
+    
pFontInstance->GetGlyphBoundRect(pFontInstance->GetGlyphIndex(SECTION_SIGN), 
aBoundRect, true);
+
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(-95.3, aBoundRect.getMinX(), 0.05);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(-45.4, aBoundRect.getMinY(), 0.05);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(97.4, aBoundRect.getWidth(), 0.05);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(97.4, aBoundRect.getHeight(), 0.05);
 }
 
 CPPUNIT_TEST_SUITE_REGISTRATION(VclLogicalFontInstanceTest);
diff --git a/vcl/source/font/LogicalFontInstance.cxx 
b/vcl/source/font/LogicalFontInstance.cxx
index fbb115825828..3cf95cab8d65 100644
--- a/vcl/source/font/LogicalFontInstance.cxx
+++ b/vcl/source/font/LogicalFontInstance.cxx
@@ -171,8 +171,8 @@ void LogicalFontInstance::IgnoreFallbackForUnicode(sal_UCS4 
cChar, FontWeight eW
 bool LogicalFontInstance::GetGlyphBoundRect(sal_GlyphId nID, 
basegfx::B2DRectangle& rRect,
                                             bool bVertical) const
 {
-    // TODO/FIXME: bVertical handling here is highly suspicious. When it's 
true, it may
-    // return different rectangle, depending on if this glyph was cached 
already or not.
+    // TODO: find out if it's possible for the same glyph in the same font to 
be used both
+    // normally and vertically; if yes, then these two variants must be cached 
separately
 
     if (mpFontCache && mpFontCache->GetCachedGlyphBoundRect(this, nID, rRect))
         return true;
@@ -191,10 +191,13 @@ bool LogicalFontInstance::GetGlyphBoundRect(sal_GlyphId 
nID, basegfx::B2DRectang
     double fMaxY = -(aExtents.y_bearing + aExtents.height) * nYScale;
     rRect = basegfx::B2DRectangle(fMinX, fMinY, fMaxX, fMaxY);
 
-    if (mnOrientation && !bVertical)
+    auto orientation = mnOrientation;
+    if (bVertical)
+        orientation += 900_deg10;
+    if (orientation)
     {
         // Apply font rotation.
-        
rRect.transform(basegfx::utils::createRotateB2DHomMatrix(-toRadians(mnOrientation)));
+        
rRect.transform(basegfx::utils::createRotateB2DHomMatrix(-toRadians(orientation)));
     }
 
     if (mpFontCache)

Reply via email to