vcl: add PhysicalFontFace::GetVariations()

Use it to set the variations on hb_font_t, and we will use it for other
things in later commits.

Change-Id: Iae1861f74b38af4921ac97c1facecf0d4815c201
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/142024
Tested-by: Jenkins
Reviewed-by: خالد حسني <khaled@aliftype.com>
This commit is contained in:
Khaled Hosny
2022-10-29 20:17:35 +02:00
committed by خالد حسني
parent 29f318f90d
commit 643fec7cf7
8 changed files with 77 additions and 68 deletions

View File

@ -194,6 +194,8 @@ public:
return nullptr;
}
virtual std::vector<hb_variation_t> GetVariations() const { return {}; };
protected:
mutable hb_face_t* mpHbFace;
mutable hb_font_t* mpHbUnscaledFont;
@ -201,6 +203,7 @@ protected:
mutable vcl::FontCapabilities maFontCapabilities;
mutable bool mbFontCapabilitiesRead;
mutable std::vector<ColorPalette> maColorPalettes;
mutable std::vector<hb_variation_t> m_aVariations;
explicit PhysicalFontFace(const FontAttributes&);

View File

@ -72,6 +72,8 @@ public:
virtual hb_blob_t* GetHbTable(hb_tag_t nTag) const override;
std::vector<hb_variation_t> GetVariations() const override;
private:
CTFontDescriptorRef mxFontDescriptor;
};
@ -98,11 +100,8 @@ public:
private:
explicit CoreTextFont(const CoreTextFontFace&, const vcl::font::FontSelectPattern&);
virtual void ImplInitHbFont(hb_font_t*) override;
bool ImplGetGlyphBoundRect(sal_GlyphId, tools::Rectangle&, bool) const override;
void SetFontVariationsOnHBFont(hb_font_t*) const;
CTFontRef mpCTFont;
};

View File

@ -100,6 +100,8 @@ public:
virtual hb_face_t* GetHbFace() const override;
virtual hb_blob_t* GetHbTable(hb_tag_t nTag) const override;
std::vector<hb_variation_t> GetVariations() const override;
};
class SAL_DLLPUBLIC_RTTI FreetypeFontInstance final : public LogicalFontInstance
@ -108,7 +110,6 @@ class SAL_DLLPUBLIC_RTTI FreetypeFontInstance final : public LogicalFontInstance
std::unique_ptr<FreetypeFont> mxFreetypeFont;
virtual void ImplInitHbFont(hb_font_t*) override;
virtual bool ImplGetGlyphBoundRect(sal_GlyphId, tools::Rectangle&, bool) const override;
explicit FreetypeFontInstance(const vcl::font::PhysicalFontFace& rPFF, const vcl::font::FontSelectPattern& rFSP);

View File

@ -129,7 +129,7 @@ public:
bool GetGlyphOutline(sal_GlyphId, basegfx::B2DPolyPolygon&, bool) const;
bool GetAntialiasAdvice() const;
void SetFontVariationsOnHBFont(hb_font_t* pHbFace) const;
std::vector<hb_variation_t> GetVariations() const;
private:
friend class FreetypeFontInstance;

View File

@ -269,49 +269,49 @@ hb_blob_t* CoreTextFontFace::GetHbTable(hb_tag_t nTag) const
return pBlob;
}
void CoreTextFont::SetFontVariationsOnHBFont(hb_font_t* pHbFont) const
std::vector<hb_variation_t> CoreTextFontFace::GetVariations() const
{
CTFontRef pFont = CTFontCreateWithFontDescriptor(mxFontDescriptor, 0.0, nullptr);
CFArrayRef pAxes = CTFontCopyVariationAxes(mpCTFont);
if (!pAxes)
return;
CFDictionaryRef pVariations = CTFontCopyVariation(mpCTFont);
std::vector<hb_variation_t> aHBVariations;
if (pVariations)
if (m_aVariations.empty())
{
CFIndex nAxes = CFArrayGetCount(pAxes);
for (CFIndex i = 0; i < nAxes; ++i)
CFArrayRef pAxes = CTFontCopyVariationAxes(pFont);
if (pAxes)
{
auto pAxis = static_cast<CFDictionaryRef>(CFArrayGetValueAtIndex(pAxes, i));
if (pAxis)
CFDictionaryRef pVariations = CTFontCopyVariation(pFont);
std::vector<hb_variation_t> aHBVariations;
if (pVariations)
{
hb_tag_t nTag;
auto pTag = static_cast<CFNumberRef>(CFDictionaryGetValue(pAxis, kCTFontVariationAxisIdentifierKey));
if (!pTag)
continue;
CFNumberGetValue(pTag, kCFNumberIntType, &nTag);
CFIndex nAxes = CFArrayGetCount(pAxes);
for (CFIndex i = 0; i < nAxes; ++i)
{
auto pAxis = static_cast<CFDictionaryRef>(CFArrayGetValueAtIndex(pAxes, i));
if (pAxis)
{
hb_tag_t nTag;
auto pTag = static_cast<CFNumberRef>(
CFDictionaryGetValue(pAxis, kCTFontVariationAxisIdentifierKey));
if (!pTag)
continue;
CFNumberGetValue(pTag, kCFNumberIntType, &nTag);
float fValue;
auto pValue = static_cast<CFNumberRef>(CFDictionaryGetValue(pVariations, pTag));
if (!pValue)
continue;
CFNumberGetValue(pValue, kCFNumberFloatType, &fValue);
float fValue;
auto pValue
= static_cast<CFNumberRef>(CFDictionaryGetValue(pVariations, pTag));
if (!pValue)
continue;
CFNumberGetValue(pValue, kCFNumberFloatType, &fValue);
aHBVariations.push_back({ nTag, fValue });
m_aVariations.push_back({ nTag, fValue });
}
}
CFRelease(pVariations);
}
CFRelease(pAxes);
}
CFRelease(pVariations);
}
CFRelease(pAxes);
if (!aHBVariations.empty())
hb_font_set_variations(pHbFont, aHBVariations.data(), aHBVariations.size());
}
void CoreTextFont::ImplInitHbFont(hb_font_t* pHbFont)
{
SetFontVariationsOnHBFont(pHbFont);
return m_aVariations;
}
rtl::Reference<LogicalFontInstance> CoreTextFontFace::CreateFontInstance(const vcl::font::FontSelectPattern& rFSD) const

View File

@ -57,11 +57,18 @@ hb_font_t* LogicalFontInstance::InitHbFont()
auto pFace = GetFontFace();
hb_face_t* pHbFace = pFace->GetHbFace();
assert(pHbFace);
hb_font_t* pHbFont = hb_font_create(pHbFace);
auto nUPEM = pFace->UnitsPerEm();
hb_font_t* pHbFont = hb_font_create(pHbFace);
hb_font_set_scale(pHbFont, nUPEM, nUPEM);
hb_ot_font_set_funcs(pHbFont);
auto aVariations = pFace->GetVariations();
if (!aVariations.empty())
hb_font_set_variations(pHbFont, aVariations.data(), aVariations.size());
ImplInitHbFont(pHbFont);
return pHbFont;
}

View File

@ -211,30 +211,6 @@ FT_FaceRec_* FreetypeFontInfo::GetFaceFT()
return maFaceFT;
}
void FreetypeFont::SetFontVariationsOnHBFont(hb_font_t* pHbFont) const
{
sal_uInt32 nFaceVariation = mxFontInfo->GetFontFaceVariation();
if (!(maFaceFT && nFaceVariation))
return;
FT_MM_Var *pFtMMVar;
if (FT_Get_MM_Var(maFaceFT, &pFtMMVar) != 0)
return;
if (nFaceVariation <= pFtMMVar->num_namedstyles)
{
FT_Var_Named_Style *instance = &pFtMMVar->namedstyle[nFaceVariation - 1];
std::vector<hb_variation_t> aVariations(pFtMMVar->num_axis);
for (FT_UInt i = 0; i < pFtMMVar->num_axis; ++i)
{
aVariations[i].tag = pFtMMVar->axis[i].tag;
aVariations[i].value = instance->coords[i] / 65536.0;
}
hb_font_set_variations(pHbFont, aVariations.data(), aVariations.size());
}
dlFT_Done_MM_Var(aLibFT, pFtMMVar);
}
void FreetypeFontInfo::ReleaseFaceFT()
{
if (--mnRefCount == 0)
@ -391,6 +367,35 @@ hb_blob_t* FreetypeFontFace::GetHbTable(hb_tag_t nTag) const
return hb_face_reference_table(mpHbFace, nTag);
}
std::vector<hb_variation_t> FreetypeFontFace::GetVariations() const
{
if (m_aVariations.empty())
{
FT_Face aFaceFT = mpFreetypeFontInfo->GetFaceFT();
sal_uInt32 nFaceVariation = mpFreetypeFontInfo->GetFontFaceVariation();
if (!(aFaceFT && nFaceVariation))
return m_aVariations;
FT_MM_Var* pFtMMVar;
if (FT_Get_MM_Var(aFaceFT, &pFtMMVar) != 0)
return m_aVariations;
if (nFaceVariation <= pFtMMVar->num_namedstyles)
{
FT_Var_Named_Style* instance = &pFtMMVar->namedstyle[nFaceVariation - 1];
m_aVariations.resize(pFtMMVar->num_axis);
for (FT_UInt i = 0; i < pFtMMVar->num_axis; ++i)
{
m_aVariations[i].tag = pFtMMVar->axis[i].tag;
m_aVariations[i].value = instance->coords[i] / 65536.0;
}
}
dlFT_Done_MM_Var(aLibFT, pFtMMVar);
}
return m_aVariations;
}
// FreetypeFont
FreetypeFont::FreetypeFont(FreetypeFontInstance& rFontInstance, std::shared_ptr<FreetypeFontInfo> xFI)

View File

@ -75,12 +75,6 @@ FreetypeFontInstance::~FreetypeFontInstance()
{
}
void FreetypeFontInstance::ImplInitHbFont(hb_font_t* pHbFont)
{
assert(mxFreetypeFont);
mxFreetypeFont->SetFontVariationsOnHBFont(pHbFont);
}
bool FreetypeFontInstance::ImplGetGlyphBoundRect(sal_GlyphId nId, tools::Rectangle& rRect, bool bVertical) const
{
assert(mxFreetypeFont);