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();