vcl/inc/font/LogicalFontInstance.hxx | 2 ++ vcl/source/font/LogicalFontInstance.cxx | 28 +++++++++++++++++++++++----- vcl/source/gdi/pdfwriter_impl.cxx | 19 ++++--------------- 3 files changed, 29 insertions(+), 20 deletions(-)
New commits: commit 60fd694ac362e9314f54fa992e31e8baa5bdf80f Author: Khaled Hosny <kha...@aliftype.com> AuthorDate: Tue Sep 6 00:56:37 2022 +0200 Commit: خالد حسني <kha...@aliftype.com> CommitDate: Tue Sep 6 15:05:39 2022 +0200 vcl: Add LogicalFontInstance::GetGlyphWidth() To be used it in PDF export where we need the unshaped glyph width to calculate PDF glyph adjustments. Getting the advances from HarfBuzz instead of reading them font the font makes sure we are always getting the correct values (e.g. when using variable fonts, though we still don’t correctly embed them in PDF). Change-Id: I91365a1580d3848c2f93044adcb366fd01173155 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/139462 Tested-by: Jenkins Reviewed-by: خالد حسني <kha...@aliftype.com> diff --git a/vcl/inc/font/LogicalFontInstance.hxx b/vcl/inc/font/LogicalFontInstance.hxx index 8187ccc2e7e0..c08e3e5bc937 100644 --- a/vcl/inc/font/LogicalFontInstance.hxx +++ b/vcl/inc/font/LogicalFontInstance.hxx @@ -100,6 +100,8 @@ public: // TODO: make data members private bool GetGlyphBoundRect(sal_GlyphId, tools::Rectangle&, bool) const; virtual bool GetGlyphOutline(sal_GlyphId, basegfx::B2DPolyPolygon&, bool) const = 0; + double GetGlyphWidth(sal_GlyphId, bool = false, bool = false) const; + int GetKashidaWidth() const; void GetScale(double* nXScale, double* nYScale) const; diff --git a/vcl/source/font/LogicalFontInstance.cxx b/vcl/source/font/LogicalFontInstance.cxx index 0936bb7286b9..611c84f44610 100644 --- a/vcl/source/font/LogicalFontInstance.cxx +++ b/vcl/source/font/LogicalFontInstance.cxx @@ -71,11 +71,7 @@ int LogicalFontInstance::GetKashidaWidth() const hb_codepoint_t nIndex = 0; if (hb_font_get_glyph(pHbFont, 0x0640, 0, &nIndex)) - { - double nXScale = 0; - GetScale(&nXScale, nullptr); - nWidth = std::ceil(hb_font_get_glyph_h_advance(pHbFont, nIndex) * nXScale); - } + nWidth = std::ceil(GetGlyphWidth(nIndex)); return nWidth; } @@ -150,6 +146,28 @@ bool LogicalFontInstance::GetGlyphBoundRect(sal_GlyphId nID, tools::Rectangle& r return res; } +double LogicalFontInstance::GetGlyphWidth(sal_GlyphId nGlyph, bool bVertical, bool bPDF) const +{ + auto* pHbFont = const_cast<LogicalFontInstance*>(this)->GetHbFont(); + int nWidth; + if (bVertical) + nWidth = hb_font_get_glyph_v_advance(pHbFont, nGlyph); + else + nWidth = hb_font_get_glyph_h_advance(pHbFont, nGlyph); + + if (bPDF) + { + unsigned int nUPEM = hb_face_get_upem(hb_font_get_face(pHbFont)); + return (nWidth * 1000) / nUPEM; + } + else + { + double nScale = 0; + GetScale(&nScale, nullptr); + return double(nWidth * nScale); + } +} + bool LogicalFontInstance::IsGraphiteFont() { if (!m_xbIsGraphiteFont) diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx index 9fe9dab2ecd8..76c47b54ba45 100644 --- a/vcl/source/gdi/pdfwriter_impl.cxx +++ b/vcl/source/gdi/pdfwriter_impl.cxx @@ -3905,13 +3905,7 @@ void PDFWriterImpl::createDefaultCheckBoxAppearance( PDFWidget& rBox, const PDFW const GlyphItem aItem(0, 0, pMap->GetGlyphIndex(cMark), DevicePoint(), GlyphItemFlags::NONE, 0, 0, 0); const std::vector<sal_Ucs> aCodeUnits={ cMark }; - sal_Int32 nGlyphWidth = 0; - SalGraphics *pGraphics = GetGraphics(); - if (pGraphics) - nGlyphWidth = m_aFontCache.getGlyphWidth(pDevFont, - aItem.glyphId(), - aItem.IsVertical(), - pGraphics); + auto nGlyphWidth = pFontInstance->GetGlyphWidth(aItem.glyphId(), aItem.IsVertical(), true); sal_uInt8 nMappedGlyph; sal_Int32 nMappedFontObject; @@ -6240,13 +6234,14 @@ void PDFWriterImpl::drawLayout( SalLayout& rLayout, const OUString& rText, bool const vcl::font::PhysicalFontFace* pDevFont = GetFontInstance()->GetFontFace(); const GlyphItem* pGlyph = nullptr; const vcl::font::PhysicalFontFace* pFallbackFont = nullptr; + const LogicalFontInstance* pGlyphFont = nullptr; // collect the glyphs into a single array std::vector< PDFGlyph > aGlyphs; aGlyphs.reserve( nMaxGlyphs ); // first get all the glyphs and register them; coordinates still in Pixel DevicePoint aPos; - while (rLayout.GetNextGlyph(&pGlyph, aPos, nIndex, nullptr, &pFallbackFont)) + while (rLayout.GetNextGlyph(&pGlyph, aPos, nIndex, &pGlyphFont, &pFallbackFont)) { const auto* pFont = pFallbackFont ? pFallbackFont : pDevFont; @@ -6302,13 +6297,7 @@ void PDFWriterImpl::drawLayout( SalLayout& rLayout, const OUString& rText, bool assert(!aCodeUnits.empty() || bUseActualText || pGlyph->IsInCluster()); - sal_Int32 nGlyphWidth = 0; - SalGraphics *pGraphics = GetGraphics(); - if (pGraphics) - nGlyphWidth = m_aFontCache.getGlyphWidth(pFont, - pGlyph->glyphId(), - pGlyph->IsVertical(), - pGraphics); + auto nGlyphWidth = pGlyphFont->GetGlyphWidth(pGlyph->glyphId(), pGlyph->IsVertical(), true); sal_uInt8 nMappedGlyph; sal_Int32 nMappedFontObject;