vcl/inc/font/LogicalFontInstance.hxx           |    2 
 vcl/inc/pdf/pdfbuildin_fonts.hxx               |    2 
 vcl/inc/qt5/QtFont.hxx                         |    1 
 vcl/inc/quartz/salgdi.h                        |    2 
 vcl/inc/unx/freetype_glyphcache.hxx            |    2 
 vcl/inc/unx/glyphcache.hxx                     |    1 
 vcl/inc/win/winlayout.hxx                      |    1 
 vcl/qa/cppunit/cjktext.cxx                     |    2 
 vcl/qa/cppunit/complextext.cxx                 |   91 +++++++++++++------------
 vcl/qa/cppunit/fontmocks.hxx                   |    3 
 vcl/qa/cppunit/logicalfontinstance.cxx         |    9 +-
 vcl/qt5/QtFont.cxx                             |    7 -
 vcl/quartz/ctfonts.cxx                         |   21 -----
 vcl/source/font/LogicalFontInstance.cxx        |   33 ++++++++-
 vcl/source/gdi/pdfbuildin_fonts.cxx            |    5 -
 vcl/unx/generic/glyphs/freetype_glyphcache.cxx |   38 ----------
 vcl/unx/generic/glyphs/glyphcache.cxx          |    8 --
 vcl/win/gdi/salfont.cxx                        |   50 -------------
 18 files changed, 88 insertions(+), 190 deletions(-)

New commits:
commit 2a19b5fb9af4b0d6c8903ce64ce67ccb536276e1
Author:     Khaled Hosny <kha...@libreoffice.org>
AuthorDate: Sun Jul 16 07:38:06 2023 +0300
Commit:     خالد حسني <kha...@libreoffice.org>
CommitDate: Sun Jul 23 06:00:39 2023 +0200

    vcl: Set font size to UPEM in some tests
    
    Reduces the chance of rounding differences.
    
    Change-Id: I4ad3e00a41c2dba01fe113ba1261dcf12f0b19f0
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/154381
    Tested-by: Jenkins
    Reviewed-by: خالد حسني <kha...@libreoffice.org>

diff --git a/vcl/qa/cppunit/complextext.cxx b/vcl/qa/cppunit/complextext.cxx
index bcf96cb4f99b..db8593e48fbb 100644
--- a/vcl/qa/cppunit/complextext.cxx
+++ b/vcl/qa/cppunit/complextext.cxx
@@ -72,33 +72,35 @@ CPPUNIT_TEST_FIXTURE(VclComplexTextTest, testArabic)
 #if HAVE_MORE_FONTS
     OUString aOneTwoThree(u"واحِدْ إثٍنين ثلاثةٌ");
 
-    vcl::Font aFont("DejaVu Sans", "Book", Size(0, 12));
+    vcl::Font aFont("DejaVu Sans", "Book", Size(0, 2048));
 
     ScopedVclPtrInstance<VirtualDevice> pOutDev;
     pOutDev->SetFont( aFont );
 
     // absolute character widths AKA text array.
-    std::vector<sal_Int32> aRefCharWidths {6,  9,  16, 16, 22, 22, 26, 29, 32, 
32,
-                                      36, 40, 49, 53, 56, 63, 63, 66, 72, 72};
+    tools::Long nRefTextWidth = 12595;
+    std::vector<sal_Int32> aRefCharWidths = { 989, 1558, 2824, 2824, 3899,
+        3899, 4550, 5119, 5689, 5689, 6307, 6925, 8484, 9135, 9705, 10927,
+        10927, 11497, 12595, 12595 };
     KernArray aCharWidths;
     tools::Long nTextWidth = pOutDev->GetTextArray(aOneTwoThree, &aCharWidths);
 
     CPPUNIT_ASSERT_EQUAL(aRefCharWidths, aCharWidths.get_subunit_array());
     // this sporadically returns 75 or 74 on some of the windows tinderboxes 
eg. tb73
-    CPPUNIT_ASSERT_EQUAL(tools::Long(72), nTextWidth);
+    CPPUNIT_ASSERT_EQUAL(nRefTextWidth, nTextWidth);
     CPPUNIT_ASSERT_EQUAL(sal_Int32(nTextWidth), aCharWidths.back());
 
     // text advance width and line height
-    CPPUNIT_ASSERT_EQUAL(tools::Long(72), pOutDev->GetTextWidth(aOneTwoThree));
-    CPPUNIT_ASSERT_EQUAL(tools::Long(14), pOutDev->GetTextHeight());
+    CPPUNIT_ASSERT_EQUAL(nRefTextWidth, pOutDev->GetTextWidth(aOneTwoThree));
+    CPPUNIT_ASSERT_EQUAL(tools::Long(2384), pOutDev->GetTextHeight());
 
     // exact bounding rectangle, not essentially the same as text width/height
     tools::Rectangle aBoundRect;
     pOutDev->GetTextBoundRect(aBoundRect, aOneTwoThree);
-    CPPUNIT_ASSERT_DOUBLES_EQUAL(0, aBoundRect.Left(), 1); // This sometimes 
equals to 1
-    CPPUNIT_ASSERT_DOUBLES_EQUAL(1, aBoundRect.Top(), 1);
-    CPPUNIT_ASSERT_DOUBLES_EQUAL(71, aBoundRect.GetWidth(), 2); // This 
sometimes equals to 70
-    CPPUNIT_ASSERT_DOUBLES_EQUAL(15, aBoundRect.getOpenHeight(), 1);
+    CPPUNIT_ASSERT_EQUAL(tools::Long(145), aBoundRect.Left());
+    CPPUNIT_ASSERT_EQUAL(tools::Long(212), aBoundRect.Top());
+    CPPUNIT_ASSERT_EQUAL(tools::Long(12294), aBoundRect.GetWidth());
+    CPPUNIT_ASSERT_EQUAL(tools::Long(2279), aBoundRect.getOpenHeight());
 
     // normal orientation
     tools::Rectangle aInput;
@@ -242,7 +244,8 @@ CPPUNIT_TEST_FIXTURE(VclComplexTextTest, testCaret)
 #if HAVE_MORE_FONTS
     // Test caret placement in fonts *without* ligature carets in GDEF table.
 
-    vcl::Font aFont("DejaVu Sans", "Book", Size(0, 200));
+    // Set font size to its UPEM to decrease rounding issues
+    vcl::Font aFont("DejaVu Sans", "Book", Size(0, 2048));
 
     ScopedVclPtrInstance<VirtualDevice> pOutDev;
     pOutDev->SetFont( aFont );
@@ -250,38 +253,39 @@ CPPUNIT_TEST_FIXTURE(VclComplexTextTest, testCaret)
     OUString aText;
     KernArray aCharWidths;
     std::vector<sal_Int32> aRefCharWidths;
-    tools::Long nTextWidth, nTextWidth2;
+    tools::Long nTextWidth, nTextWidth2, nRefTextWidth;
 
     // A. RTL text
     aText = u"لا بلا";
 
     // 1) Regular DX array, the ligature width is given to the first components
     // and the next ones are all zero width.
-    aRefCharWidths = { 114, 114, 178, 234, 353, 353 };
+    nRefTextWidth = 3611;
+    aRefCharWidths = { 1168, 1168, 1819, 2389, 3611, 3611 };
     nTextWidth = pOutDev->GetTextArray(aText, &aCharWidths, 0, -1, 
/*bCaret*/false);
     CPPUNIT_ASSERT_EQUAL(aRefCharWidths, aCharWidths.get_subunit_array());
-    CPPUNIT_ASSERT_EQUAL(tools::Long(353), nTextWidth);
+    CPPUNIT_ASSERT_EQUAL(nRefTextWidth, nTextWidth);
     CPPUNIT_ASSERT_EQUAL(sal_Int32(nTextWidth), aCharWidths.back());
 
     // 2) Caret placement DX array, ligature width is distributed over its
     // components.
-    aRefCharWidths = { 57, 114, 178, 234, 293, 353 };
+    aRefCharWidths = { 584, 1168, 1819, 2389, 3000, 3611 };
     nTextWidth = pOutDev->GetTextArray(aText, &aCharWidths, 0, -1, 
/*bCaret*/true);
     CPPUNIT_ASSERT_EQUAL(aRefCharWidths, aCharWidths.get_subunit_array());
-    CPPUNIT_ASSERT_EQUAL(tools::Long(353), nTextWidth);
+    CPPUNIT_ASSERT_EQUAL(nRefTextWidth, nTextWidth);
     CPPUNIT_ASSERT_EQUAL(sal_Int32(nTextWidth), aCharWidths.back());
 
     // 3) caret placement with combining marks, they should not add to ligature
     // component count.
     aText = u"لَاَ بلَاَ";
-    aRefCharWidths = { 57, 57, 114, 114, 178, 234, 293, 293, 353, 353 };
+    aRefCharWidths = { 584, 584, 1168, 1168, 1819, 2389, 3000, 3000, 3611, 
3611 };
     nTextWidth2 = pOutDev->GetTextArray(aText, &aCharWidths, 0, -1, 
/*bCaret*/true);
     CPPUNIT_ASSERT_EQUAL(aCharWidths[0], aCharWidths[1]);
     CPPUNIT_ASSERT_EQUAL(aCharWidths[2], aCharWidths[3]);
     CPPUNIT_ASSERT_EQUAL(aCharWidths[6], aCharWidths[7]);
     CPPUNIT_ASSERT_EQUAL(aCharWidths[8], aCharWidths[9]);
     CPPUNIT_ASSERT_EQUAL(aRefCharWidths, aCharWidths.get_subunit_array());
-    CPPUNIT_ASSERT_EQUAL(tools::Long(353), nTextWidth2);
+    CPPUNIT_ASSERT_EQUAL(nRefTextWidth, nTextWidth2);
     CPPUNIT_ASSERT_EQUAL(nTextWidth, nTextWidth2);
     CPPUNIT_ASSERT_EQUAL(sal_Int32(nTextWidth), aCharWidths.back());
 
@@ -290,18 +294,19 @@ CPPUNIT_TEST_FIXTURE(VclComplexTextTest, testCaret)
 
     // 1) Regular DX array, the ligature width is given to the first components
     // and the next ones are all zero width.
-    aRefCharWidths = { 126, 126, 190, 316, 316, 380, 573, 573, 573, 637, 830, 
830, 830 };
+    nRefTextWidth = 8493;
+    aRefCharWidths = { 1290, 1290, 1941, 3231, 3231, 3882, 5862, 5862, 5862, 
6513, 8493, 8493, 8493 };
     nTextWidth = pOutDev->GetTextArray(aText, &aCharWidths, 0, -1, 
/*bCaret*/false);
     CPPUNIT_ASSERT_EQUAL(aRefCharWidths, aCharWidths.get_subunit_array());
-    CPPUNIT_ASSERT_EQUAL(tools::Long(830), nTextWidth);
+    CPPUNIT_ASSERT_EQUAL(nRefTextWidth, nTextWidth);
     CPPUNIT_ASSERT_EQUAL(sal_Int32(nTextWidth), aCharWidths.back());
 
     // 2) Caret placement DX array, ligature width is distributed over its
     // components.
-    aRefCharWidths = { 63, 126, 190, 253, 316, 380, 444, 508, 573, 637, 701, 
765, 830 };
+    aRefCharWidths = { 645, 1290, 1941, 2586, 3231, 3882, 4542, 5202, 5862, 
6513, 7173, 7833, 8493 };
     nTextWidth = pOutDev->GetTextArray(aText, &aCharWidths, 0, -1, 
/*bCaret*/true);
     CPPUNIT_ASSERT_EQUAL(aRefCharWidths, aCharWidths.get_subunit_array());
-    CPPUNIT_ASSERT_EQUAL(tools::Long(830), nTextWidth);
+    CPPUNIT_ASSERT_EQUAL(nRefTextWidth, nTextWidth);
     CPPUNIT_ASSERT_EQUAL(sal_Int32(nTextWidth), aCharWidths.back());
 #endif
 }
@@ -317,66 +322,70 @@ CPPUNIT_TEST_FIXTURE(VclComplexTextTest, testGdefCaret)
     OUString aText;
     KernArray aCharWidths;
     std::vector<sal_Int32> aRefCharWidths;
-    tools::Long nTextWidth, nTextWidth2;
+    tools::Long nTextWidth, nTextWidth2, nRefTextWidth;
 
     // A. RTL text
-    aFont = vcl::Font("Noto Naskh Arabic", "Regular", Size(0, 200));
+    // Set font size to its UPEM to decrease rounding issues
+    aFont = vcl::Font("Noto Naskh Arabic", "Regular", Size(0, 2048));
     pOutDev->SetFont(aFont);
 
     aText = u"لا بلا";
 
     // 1) Regular DX array, the ligature width is given to the first components
     // and the next ones are all zero width.
-    aRefCharWidths= { 104, 104, 148, 203, 325, 325 };
+    nRefTextWidth = 3325;
+    aRefCharWidths= { 1060, 1060, 1512, 2076, 3325, 3325 };
     nTextWidth = pOutDev->GetTextArray(aText, &aCharWidths, 0, -1, 
/*bCaret*/false);
     CPPUNIT_ASSERT_EQUAL(aRefCharWidths, aCharWidths.get_subunit_array());
-    CPPUNIT_ASSERT_EQUAL(tools::Long(325), nTextWidth);
+    CPPUNIT_ASSERT_EQUAL(nRefTextWidth, nTextWidth);
     CPPUNIT_ASSERT_EQUAL(sal_Int32(nTextWidth), aCharWidths.back());
 
     // 2) Caret placement DX array, ligature width is distributed over its
     // components.
-    aRefCharWidths = { 53, 104, 148, 203, 265, 325 };
+    aRefCharWidths = { 530, 1060, 1512, 2076, 2701, 3325 };
     nTextWidth = pOutDev->GetTextArray(aText, &aCharWidths, 0, -1, 
/*bCaret*/true);
     CPPUNIT_ASSERT_EQUAL(aRefCharWidths, aCharWidths.get_subunit_array());
-    CPPUNIT_ASSERT_EQUAL(tools::Long(325), nTextWidth);
+    CPPUNIT_ASSERT_EQUAL(nRefTextWidth, nTextWidth);
     CPPUNIT_ASSERT_EQUAL(sal_Int32(nTextWidth), aCharWidths.back());
 
     // 3) caret placement with combining marks, they should not add to ligature
     // component count.
     aText = u"لَاَ بلَاَ";
-    aRefCharWidths = { 53, 53, 104, 104, 148, 203, 265, 265, 325, 325 };
+    aRefCharWidths = { 530, 530, 1060, 1060, 1512, 2076, 2701, 2701, 3325, 
3325 };
     nTextWidth2 = pOutDev->GetTextArray(aText, &aCharWidths, 0, -1, 
/*bCaret*/true);
     CPPUNIT_ASSERT_EQUAL(aCharWidths[0], aCharWidths[1]);
     CPPUNIT_ASSERT_EQUAL(aCharWidths[2], aCharWidths[3]);
     CPPUNIT_ASSERT_EQUAL(aCharWidths[6], aCharWidths[7]);
     CPPUNIT_ASSERT_EQUAL(aCharWidths[8], aCharWidths[9]);
     CPPUNIT_ASSERT_EQUAL(aRefCharWidths, aCharWidths.get_subunit_array());
-    CPPUNIT_ASSERT_EQUAL(tools::Long(325), nTextWidth2);
+    CPPUNIT_ASSERT_EQUAL(nRefTextWidth, nTextWidth2);
     CPPUNIT_ASSERT_EQUAL(nTextWidth, nTextWidth2);
     CPPUNIT_ASSERT_EQUAL(sal_Int32(nTextWidth), aCharWidths.back());
 
     // B. LTR text
-    aFont = vcl::Font("Amiri", "Regular", Size(0, 200));
+    // Set font size to its UPEM to decrease rounding issues
+    aFont = vcl::Font("Amiri", "Regular", Size(0, 1000));
     pOutDev->SetFont(aFont);
 
     aText = u"fi ffi fl ffl fb ffb";
 
     // 1) Regular DX array, the ligature width is given to the first components
     // and the next ones are all zero width.
-    aRefCharWidths = { 104, 104, 162, 321, 321, 321, 379, 487, 487, 545, 708,
-                       708, 708, 766, 926, 926, 984, 1198, 1198, 1198 };
+    nRefTextWidth = 5996;
+    aRefCharWidths = { 519, 519, 811, 1606, 1606, 1606, 1898, 2439, 2439, 2731,
+                       3544, 3544, 3544, 3836, 4634, 4634, 4926, 5996, 5996, 
5996 };
     nTextWidth = pOutDev->GetTextArray(aText, &aCharWidths, 0, -1, 
/*bCaret*/false);
     CPPUNIT_ASSERT_EQUAL(aRefCharWidths, aCharWidths.get_subunit_array());
-    CPPUNIT_ASSERT_EQUAL(tools::Long(1198), nTextWidth);
+    CPPUNIT_ASSERT_EQUAL(nRefTextWidth, nTextWidth);
     CPPUNIT_ASSERT_EQUAL(sal_Int32(nTextWidth), aCharWidths.back());
 
     // 2) Caret placement DX array, ligature width is distributed over its
     // components.
-    aRefCharWidths = { 53, 104, 162, 215, 269, 321, 379, 433, 487, 545, 599,
-                       654, 708, 766, 826, 926, 984, 1038, 1097, 1198 };
+    aRefCharWidths = { 269, 519, 811, 1080, 1348, 1606, 1898, 2171, 2439, 2731,
+                       3004, 3278, 3544, 3836, 4138, 4634, 4926, 5199, 5494, 
5996 };
     nTextWidth = pOutDev->GetTextArray(aText, &aCharWidths, 0, -1, 
/*bCaret*/true);
     CPPUNIT_ASSERT_EQUAL(aRefCharWidths, aCharWidths.get_subunit_array());
-    CPPUNIT_ASSERT_EQUAL(tools::Long(1198), nTextWidth);
+    CPPUNIT_ASSERT_EQUAL(nRefTextWidth, nTextWidth);
     CPPUNIT_ASSERT_EQUAL(sal_Int32(nTextWidth), aCharWidths.back());
 #endif
 }
@@ -386,14 +395,14 @@ CPPUNIT_TEST_FIXTURE(VclComplexTextTest, testTdf152048)
 #if HAVE_MORE_FONTS
     OUString aText(u"می‌شود");
 
-    vcl::Font aFont(u"Noto Naskh Arabic", u"Regular", Size(0, 72));
+    vcl::Font aFont(u"Noto Naskh Arabic", u"Regular", Size(0, 2048));
 
     ScopedVclPtrInstance<VirtualDevice> pOutDev;
     pOutDev->SetFont(aFont);
 
     // get an compare the default text array
-    std::vector<sal_Int32> aRefCharWidths{ 33, 82, 82, 129, 163, 193 };
-    tools::Long nRefTextWidth(193);
+    std::vector<sal_Int32> aRefCharWidths{ 933, 2340, 2340, 3687, 4646, 5493 };
+    tools::Long nRefTextWidth(5493);
 
     KernArray aCharWidths;
     tools::Long nTextWidth = pOutDev->GetTextArray(aText, &aCharWidths);
@@ -405,7 +414,7 @@ CPPUNIT_TEST_FIXTURE(VclComplexTextTest, testTdf152048)
     // Simulate Kashida insertion using Kashida array and extending text array
     // to have room for Kashida.
     std::vector<sal_Bool> aKashidaArray{ false, false, false, true, false, 
false };
-    auto nKashida = 200;
+    auto nKashida = 4000;
 
     aCharWidths.set(3, aCharWidths[3] + nKashida);
     aCharWidths.set(4, aCharWidths[4] + nKashida);
commit dfe42e756b37642355356a6035081f4473609832
Author:     Khaled Hosny <kha...@libreoffice.org>
AuthorDate: Sun Jul 16 07:37:55 2023 +0300
Commit:     خالد حسني <kha...@libreoffice.org>
CommitDate: Sun Jul 23 06:00:30 2023 +0200

    vcl: Use HarfBuzz to get glyph bounding rectangle
    
    For consistent cross-platform results that also matches our glyph
    advances since platform functions might be using hints which we don’t
    use.
    
    Change-Id: I4aebd3e7c5f460dff584f5eba74f7a11bab0f9b1
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/154388
    Tested-by: Jenkins
    Reviewed-by: خالد حسني <kha...@libreoffice.org>

diff --git a/vcl/inc/font/LogicalFontInstance.hxx 
b/vcl/inc/font/LogicalFontInstance.hxx
index 2261246b069b..e85d25b41f10 100644
--- a/vcl/inc/font/LogicalFontInstance.hxx
+++ b/vcl/inc/font/LogicalFontInstance.hxx
@@ -120,8 +120,6 @@ protected:
     explicit LogicalFontInstance(const vcl::font::PhysicalFontFace&,
                                  const vcl::font::FontSelectPattern&);
 
-    virtual bool ImplGetGlyphBoundRect(sal_GlyphId, tools::Rectangle&, bool) 
const = 0;
-
     hb_font_t* InitHbFont();
     virtual void ImplInitHbFont(hb_font_t*) {}
 
diff --git a/vcl/inc/pdf/pdfbuildin_fonts.hxx b/vcl/inc/pdf/pdfbuildin_fonts.hxx
index 8cb34e74922b..a0c2fc06287d 100644
--- a/vcl/inc/pdf/pdfbuildin_fonts.hxx
+++ b/vcl/inc/pdf/pdfbuildin_fonts.hxx
@@ -49,8 +49,6 @@ struct BuildinFont
 
 class BuildinFontInstance final : public LogicalFontInstance
 {
-    bool ImplGetGlyphBoundRect(sal_GlyphId nID, tools::Rectangle& rRect, bool) 
const override;
-
 public:
     BuildinFontInstance(const vcl::font::PhysicalFontFace&, const 
vcl::font::FontSelectPattern&);
 
diff --git a/vcl/inc/qt5/QtFont.hxx b/vcl/inc/qt5/QtFont.hxx
index e19d6de21aa2..7d0b338c939d 100644
--- a/vcl/inc/qt5/QtFont.hxx
+++ b/vcl/inc/qt5/QtFont.hxx
@@ -33,7 +33,6 @@ class QtFont final : public QFont, public LogicalFontInstance
     QtFontFace::CreateFontInstance(const vcl::font::FontSelectPattern&) const;
 
     bool GetGlyphOutline(sal_GlyphId, basegfx::B2DPolyPolygon&, bool) const 
override;
-    bool ImplGetGlyphBoundRect(sal_GlyphId, tools::Rectangle&, bool) const 
override;
 
     explicit QtFont(const vcl::font::PhysicalFontFace&, const 
vcl::font::FontSelectPattern&);
 };
diff --git a/vcl/inc/quartz/salgdi.h b/vcl/inc/quartz/salgdi.h
index 06b9b08b431d..01826c5c93e0 100644
--- a/vcl/inc/quartz/salgdi.h
+++ b/vcl/inc/quartz/salgdi.h
@@ -103,8 +103,6 @@ public:
 private:
     explicit CoreTextFont(const CoreTextFontFace&, const 
vcl::font::FontSelectPattern&);
 
-    bool ImplGetGlyphBoundRect(sal_GlyphId, tools::Rectangle&, bool) const 
override;
-
     CTFontRef mpCTFont;
 };
 
diff --git a/vcl/inc/unx/freetype_glyphcache.hxx 
b/vcl/inc/unx/freetype_glyphcache.hxx
index 36499b5ca38f..7a13fca8329d 100644
--- a/vcl/inc/unx/freetype_glyphcache.hxx
+++ b/vcl/inc/unx/freetype_glyphcache.hxx
@@ -108,8 +108,6 @@ class SAL_DLLPUBLIC_RTTI FreetypeFontInstance final : 
public LogicalFontInstance
 
     std::unique_ptr<FreetypeFont> mxFreetypeFont;
 
-    virtual bool ImplGetGlyphBoundRect(sal_GlyphId, tools::Rectangle&, bool) 
const override;
-
     explicit FreetypeFontInstance(const vcl::font::PhysicalFontFace& rPFF, 
const vcl::font::FontSelectPattern& rFSP);
 
 public:
diff --git a/vcl/inc/unx/glyphcache.hxx b/vcl/inc/unx/glyphcache.hxx
index cd8f31ef0df2..f5ce328b0aa1 100644
--- a/vcl/inc/unx/glyphcache.hxx
+++ b/vcl/inc/unx/glyphcache.hxx
@@ -123,7 +123,6 @@ public:
 
     void                    GetFontMetric(FontMetricDataRef const &) const;
 
-    bool                    GetGlyphBoundRect(sal_GlyphId, tools::Rectangle&, 
bool) const;
     bool                    GetGlyphOutline(sal_GlyphId, 
basegfx::B2DPolyPolygon&, bool) const;
     bool                    GetAntialiasAdvice() const;
 
diff --git a/vcl/inc/win/winlayout.hxx b/vcl/inc/win/winlayout.hxx
index 07c80e8e8b39..e1d66a0e1ab2 100644
--- a/vcl/inc/win/winlayout.hxx
+++ b/vcl/inc/win/winlayout.hxx
@@ -59,7 +59,6 @@ private:
     explicit WinFontInstance(const WinFontFace&, const 
vcl::font::FontSelectPattern&);
 
     virtual void ImplInitHbFont(hb_font_t*) override;
-    bool ImplGetGlyphBoundRect(sal_GlyphId, tools::Rectangle&, bool) const 
override;
 
     WinSalGraphics *m_pGraphics;
     HFONT m_hFont;
diff --git a/vcl/qa/cppunit/cjktext.cxx b/vcl/qa/cppunit/cjktext.cxx
index 3adc89ddcc47..d35208fcd6a3 100644
--- a/vcl/qa/cppunit/cjktext.cxx
+++ b/vcl/qa/cppunit/cjktext.cxx
@@ -178,7 +178,7 @@ void VclCjkTextTest::testVerticalText()
     tools::Long height36Rotated = getCharacterRightSideHeight(device, 
Point(99, 35));
     CPPUNIT_ASSERT_DOUBLES_EQUAL(height36, height36Rotated, 1);
     tools::Long width36Rotated = getCharacterTopWidth(device, Point(25, 0));
-    CPPUNIT_ASSERT_DOUBLES_EQUAL(width36, width36Rotated, 1);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(width36, width36Rotated, 2);
 
     font = baseFont;
     font.SetFontSize(Size(0, 72));
diff --git a/vcl/qa/cppunit/fontmocks.hxx b/vcl/qa/cppunit/fontmocks.hxx
index 7e33ce8e7e13..8eac463c143f 100644
--- a/vcl/qa/cppunit/fontmocks.hxx
+++ b/vcl/qa/cppunit/fontmocks.hxx
@@ -30,9 +30,6 @@ public:
     {
         return true;
     }
-
-protected:
-    bool ImplGetGlyphBoundRect(sal_GlyphId, tools::Rectangle&, bool) const 
override { return true; }
 };
 
 class TestFontFace : public vcl::font::PhysicalFontFace
diff --git a/vcl/qa/cppunit/logicalfontinstance.cxx 
b/vcl/qa/cppunit/logicalfontinstance.cxx
index ffe9bb995ff9..6d5bbc4dafda 100644
--- a/vcl/qa/cppunit/logicalfontinstance.cxx
+++ b/vcl/qa/cppunit/logicalfontinstance.cxx
@@ -50,13 +50,14 @@ void VclLogicalFontInstanceTest::testglyphboundrect()
 
     const tools::Long nExpectedX = 7;
     const tools::Long nExpectedY = -80;
+    const tools::Long nExpectedWidth = 51;
+    const tools::Long nExpectedHeight = 83;
 
     CPPUNIT_ASSERT_EQUAL_MESSAGE("x of glyph is wrong", nExpectedX, 
aBoundRect.getX());
     CPPUNIT_ASSERT_EQUAL_MESSAGE("y of glyph is wrong", nExpectedY, 
aBoundRect.getY());
-    CPPUNIT_ASSERT_MESSAGE("height of glyph of wrong",
-                           aBoundRect.GetWidth() == 50 || 
aBoundRect.GetWidth() == 51);
-    CPPUNIT_ASSERT_MESSAGE("width of glyph of wrong",
-                           aBoundRect.GetHeight() == 82 || 
aBoundRect.GetHeight() == 83);
+    CPPUNIT_ASSERT_EQUAL_MESSAGE("height of glyph of wrong", nExpectedWidth, 
aBoundRect.GetWidth());
+    CPPUNIT_ASSERT_EQUAL_MESSAGE("width of glyph of wrong", nExpectedHeight,
+                                 aBoundRect.GetHeight());
 }
 
 CPPUNIT_TEST_SUITE_REGISTRATION(VclLogicalFontInstanceTest);
diff --git a/vcl/qt5/QtFont.cxx b/vcl/qt5/QtFont.cxx
index 384f56774ffd..e3a6c0b0a9d7 100644
--- a/vcl/qt5/QtFont.cxx
+++ b/vcl/qt5/QtFont.cxx
@@ -187,11 +187,4 @@ bool QtFont::GetGlyphOutline(sal_GlyphId nId, 
basegfx::B2DPolyPolygon& rB2DPolyP
     return true;
 }
 
-bool QtFont::ImplGetGlyphBoundRect(sal_GlyphId nId, tools::Rectangle& rRect, 
bool) const
-{
-    QRawFont aRawFont(QRawFont::fromFont(*this));
-    rRect = toRectangle(aRawFont.boundingRect(nId).toAlignedRect());
-    return true;
-}
-
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/quartz/ctfonts.cxx b/vcl/quartz/ctfonts.cxx
index 2d9b7c896781..3d3298f6f50f 100644
--- a/vcl/quartz/ctfonts.cxx
+++ b/vcl/quartz/ctfonts.cxx
@@ -89,27 +89,6 @@ void CoreTextFont::GetFontMetric( FontMetricDataRef const & 
rxFontMetric )
     rxFontMetric->SetMinKashida(GetKashidaWidth());
 }
 
-bool CoreTextFont::ImplGetGlyphBoundRect(sal_GlyphId nId, tools::Rectangle& 
rRect, bool bVertical) const
-{
-    CGGlyph nCGGlyph = nId;
-
-    SAL_WNODEPRECATED_DECLARATIONS_PUSH //TODO: 10.11 kCTFontDefaultOrientation
-    const CTFontOrientation aFontOrientation = kCTFontDefaultOrientation; // 
TODO: horz/vert
-    SAL_WNODEPRECATED_DECLARATIONS_POP
-    CGRect aCGRect = CTFontGetBoundingRectsForGlyphs(mpCTFont, 
aFontOrientation, &nCGGlyph, nullptr, 1);
-
-    // Apply font rotation to non-vertical glyphs.
-    if (mfFontRotation && !bVertical)
-        aCGRect = CGRectApplyAffineTransform(aCGRect, 
CGAffineTransformMakeRotation(mfFontRotation));
-
-    tools::Long xMin = floor(aCGRect.origin.x);
-    tools::Long yMin = floor(aCGRect.origin.y);
-    tools::Long xMax = ceil(aCGRect.origin.x + aCGRect.size.width);
-    tools::Long yMax = ceil(aCGRect.origin.y + aCGRect.size.height);
-    rRect = tools::Rectangle(xMin, -yMax, xMax, -yMin);
-    return true;
-}
-
 namespace {
 
 // callbacks from CTFontCreatePathForGlyph+CGPathApply for GetGlyphOutline()
diff --git a/vcl/source/font/LogicalFontInstance.cxx 
b/vcl/source/font/LogicalFontInstance.cxx
index d8a5bf378aae..766dd2514120 100644
--- a/vcl/source/font/LogicalFontInstance.cxx
+++ b/vcl/source/font/LogicalFontInstance.cxx
@@ -172,7 +172,38 @@ bool LogicalFontInstance::GetGlyphBoundRect(sal_GlyphId 
nID, tools::Rectangle& r
     if (mpFontCache && mpFontCache->GetCachedGlyphBoundRect(this, nID, rRect))
         return true;
 
-    bool res = ImplGetGlyphBoundRect(nID, rRect, bVertical);
+    auto* pHbFont = const_cast<LogicalFontInstance*>(this)->GetHbFont();
+    hb_glyph_extents_t aExtents;
+    bool res = hb_font_get_glyph_extents(pHbFont, nID, &aExtents);
+
+    if (res)
+    {
+        double nXScale = 0, nYScale = 0;
+        GetScale(&nXScale, &nYScale);
+
+        double fMinX = aExtents.x_bearing;
+        double fMinY = aExtents.y_bearing;
+        double fMaxX = aExtents.x_bearing + aExtents.width;
+        double fMaxY = aExtents.y_bearing + aExtents.height;
+
+        tools::Rectangle aRect(std::floor(fMinX * nXScale), -std::ceil(fMinY * 
nYScale),
+                               std::ceil(fMaxX * nXScale), -std::floor(fMaxY * 
nYScale));
+        if (mnOrientation && !bVertical)
+        {
+            // Apply font rotation.
+            const double fRad = toRadians(mnOrientation);
+            const double fCos = cos(fRad);
+            const double fSin = sin(fRad);
+
+            rRect.SetLeft(fCos * aRect.Left() + fSin * aRect.Top());
+            rRect.SetTop(-fSin * aRect.Left() - fCos * aRect.Top());
+            rRect.SetRight(fCos * aRect.Right() + fSin * aRect.Bottom());
+            rRect.SetBottom(-fSin * aRect.Right() - fCos * aRect.Bottom());
+        }
+        else
+            rRect = aRect;
+    }
+
     if (mpFontCache && res)
         mpFontCache->CacheGlyphBoundRect(this, nID, rRect);
     return res;
diff --git a/vcl/source/gdi/pdfbuildin_fonts.cxx 
b/vcl/source/gdi/pdfbuildin_fonts.cxx
index e387f78638d3..7f80bfdd030d 100644
--- a/vcl/source/gdi/pdfbuildin_fonts.cxx
+++ b/vcl/source/gdi/pdfbuildin_fonts.cxx
@@ -738,11 +738,6 @@ BuildinFontInstance::BuildinFontInstance(const 
vcl::font::PhysicalFontFace& rFon
 {
 }
 
-bool BuildinFontInstance::ImplGetGlyphBoundRect(sal_GlyphId, 
tools::Rectangle&, bool) const
-{
-    return false;
-}
-
 bool BuildinFontInstance::GetGlyphOutline(sal_GlyphId, 
basegfx::B2DPolyPolygon&, bool) const
 {
     return false;
diff --git a/vcl/unx/generic/glyphs/freetype_glyphcache.cxx 
b/vcl/unx/generic/glyphs/freetype_glyphcache.cxx
index bc73ed0168a9..2543b76b5719 100644
--- a/vcl/unx/generic/glyphs/freetype_glyphcache.cxx
+++ b/vcl/unx/generic/glyphs/freetype_glyphcache.cxx
@@ -596,44 +596,6 @@ void FreetypeFont::ApplyGlyphTransform(bool bVertical, 
FT_Glyph pGlyphFT ) const
     }
 }
 
-bool FreetypeFont::GetGlyphBoundRect(sal_GlyphId nID, tools::Rectangle& rRect, 
bool bVertical) const
-{
-    FT_Activate_Size( maSizeFT );
-
-    FT_Error rc = FT_Load_Glyph(maFaceFT, nID, mnLoadFlags);
-
-    if (rc != FT_Err_Ok)
-        return false;
-
-    if (mrFontInstance.NeedsArtificialBold())
-        FT_GlyphSlot_Embolden(maFaceFT->glyph);
-
-    FT_Glyph pGlyphFT;
-    rc = FT_Get_Glyph(maFaceFT->glyph, &pGlyphFT);
-    if (rc != FT_Err_Ok)
-        return false;
-
-    ApplyGlyphTransform(bVertical, pGlyphFT);
-
-    FT_BBox aBbox;
-    FT_Glyph_Get_CBox( pGlyphFT, FT_GLYPH_BBOX_PIXELS, &aBbox );
-    FT_Done_Glyph( pGlyphFT );
-
-    tools::Rectangle aRect(aBbox.xMin, -aBbox.yMax, aBbox.xMax, -aBbox.yMin);
-    if (mnCos != 0x10000 && mnSin != 0)
-    {
-        const double nCos = mnCos / 65536.0;
-        const double nSin = mnSin / 65536.0;
-        rRect.SetLeft(  nCos*aRect.Left() + nSin*aRect.Top() );
-        rRect.SetTop( -nSin*aRect.Left() - nCos*aRect.Top() );
-        rRect.SetRight(  nCos*aRect.Right() + nSin*aRect.Bottom() );
-        rRect.SetBottom( -nSin*aRect.Right() - nCos*aRect.Bottom() );
-    }
-    else
-        rRect = aRect;
-    return true;
-}
-
 bool FreetypeFont::GetAntialiasAdvice() const
 {
     // TODO: also use GASP info
diff --git a/vcl/unx/generic/glyphs/glyphcache.cxx 
b/vcl/unx/generic/glyphs/glyphcache.cxx
index 39b10c78e123..ac3c5e15ab73 100644
--- a/vcl/unx/generic/glyphs/glyphcache.cxx
+++ b/vcl/unx/generic/glyphs/glyphcache.cxx
@@ -75,14 +75,6 @@ FreetypeFontInstance::~FreetypeFontInstance()
 {
 }
 
-bool FreetypeFontInstance::ImplGetGlyphBoundRect(sal_GlyphId nId, 
tools::Rectangle& rRect, bool bVertical) const
-{
-    assert(mxFreetypeFont);
-    if (!mxFreetypeFont)
-        return false;
-    return mxFreetypeFont->GetGlyphBoundRect(nId, rRect, bVertical);
-}
-
 bool FreetypeFontInstance::GetGlyphOutline(sal_GlyphId nId, 
basegfx::B2DPolyPolygon& rPoly, bool bVertical) const
 {
     assert(mxFreetypeFont);
diff --git a/vcl/win/gdi/salfont.cxx b/vcl/win/gdi/salfont.cxx
index 3b31028c88bb..51ddcce741b7 100644
--- a/vcl/win/gdi/salfont.cxx
+++ b/vcl/win/gdi/salfont.cxx
@@ -1156,56 +1156,6 @@ void WinSalGraphics::ClearDevFontCache()
     ImplReleaseTempFonts(*GetSalData(), false);
 }
 
-bool WinFontInstance::ImplGetGlyphBoundRect(sal_GlyphId nId, tools::Rectangle& 
rRect, bool bIsVertical) const
-{
-    assert(m_pGraphics);
-    HDC hDC = m_pGraphics->getHDC();
-    const HFONT hOrigFont = static_cast<HFONT>(GetCurrentObject(hDC, 
OBJ_FONT));
-    const HFONT hFont = GetHFONT();
-    if (hFont != hOrigFont)
-        SelectObject(hDC, hFont);
-
-    const ::comphelper::ScopeGuard aFontRestoreScopeGuard([hFont, hOrigFont, 
hDC]()
-        { if (hFont != hOrigFont) SelectObject(hDC, hOrigFont); });
-
-    // use unity matrix
-    MAT2 aMat;
-    const vcl::font::FontSelectPattern& rFSD = GetFontSelectPattern();
-
-    // Use identity matrix for fonts requested in horizontal
-    // writing (LTR or RTL), or rotated glyphs in vertical writing.
-    if (!rFSD.mbVertical || !bIsVertical)
-    {
-        aMat.eM11 = aMat.eM22 = FixedFromDouble(1.0);
-        aMat.eM12 = aMat.eM21 = FixedFromDouble(0.0);
-    }
-    else
-    {
-        constexpr double nCos = 0.0;
-        constexpr double nSin = 1.0;
-        aMat.eM11 = FixedFromDouble(nCos);
-        aMat.eM12 = FixedFromDouble(nSin);
-        aMat.eM21 = FixedFromDouble(-nSin);
-        aMat.eM22 = FixedFromDouble(nCos);
-    }
-
-    UINT nGGOFlags = GGO_METRICS;
-    nGGOFlags |= GGO_GLYPH_INDEX;
-
-    GLYPHMETRICS aGM;
-    aGM.gmptGlyphOrigin.x = aGM.gmptGlyphOrigin.y = 0;
-    aGM.gmBlackBoxX = aGM.gmBlackBoxY = 0;
-    DWORD nSize = ::GetGlyphOutlineW(hDC, nId, nGGOFlags, &aGM, 0, nullptr, 
&aMat);
-    if (nSize == GDI_ERROR)
-        return false;
-
-    rRect = tools::Rectangle( Point( +aGM.gmptGlyphOrigin.x, 
-aGM.gmptGlyphOrigin.y ),
-        Size( aGM.gmBlackBoxX, aGM.gmBlackBoxY ) );
-    rRect.SetRight(rRect.Right() + 1);
-    rRect.SetBottom(rRect.Bottom() + 1);
-    return true;
-}
-
 bool WinFontInstance::GetGlyphOutline(sal_GlyphId nId, 
basegfx::B2DPolyPolygon& rB2DPolyPoly, bool) const
 {
     rB2DPolyPoly.clear();

Reply via email to