diff options
Diffstat (limited to 'vcl/inc/font')
-rw-r--r-- | vcl/inc/font/DirectFontSubstitution.hxx | 68 | ||||
-rw-r--r-- | vcl/inc/font/EmphasisMark.hxx | 45 | ||||
-rw-r--r-- | vcl/inc/font/FeatureCollector.hxx | 49 | ||||
-rw-r--r-- | vcl/inc/font/FontMetricData.hxx | 155 | ||||
-rw-r--r-- | vcl/inc/font/FontSelectPattern.hxx | 86 | ||||
-rw-r--r-- | vcl/inc/font/LogicalFontInstance.hxx | 167 | ||||
-rw-r--r-- | vcl/inc/font/OpenTypeFeatureDefinitionList.hxx | 38 | ||||
-rw-r--r-- | vcl/inc/font/OpenTypeFeatureStrings.hrc | 104 | ||||
-rw-r--r-- | vcl/inc/font/PhysicalFontCollection.hxx | 103 | ||||
-rw-r--r-- | vcl/inc/font/PhysicalFontFace.hxx | 213 | ||||
-rw-r--r-- | vcl/inc/font/PhysicalFontFaceCollection.hxx | 48 | ||||
-rw-r--r-- | vcl/inc/font/PhysicalFontFamily.hxx | 111 | ||||
-rw-r--r-- | vcl/inc/font/fontsubstitution.hxx | 68 |
13 files changed, 1255 insertions, 0 deletions
diff --git a/vcl/inc/font/DirectFontSubstitution.hxx b/vcl/inc/font/DirectFontSubstitution.hxx new file mode 100644 index 0000000000..150bc37281 --- /dev/null +++ b/vcl/inc/font/DirectFontSubstitution.hxx @@ -0,0 +1,68 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#pragma once + +#include <sal/config.h> + +#include <rtl/ustring.hxx> +#include <unotools/fontdefs.hxx> + +#include <vcl/rendercontext/AddFontSubstituteFlags.hxx> + +#include <font/fontsubstitution.hxx> + +#include <string_view> +#include <vector> + +namespace vcl::font +{ +struct FontSubstEntry +{ + FontSubstEntry(std::u16string_view rFontName, std::u16string_view rSubstFontName, + AddFontSubstituteFlags nSubstFlags) + : maSearchName(GetEnglishSearchFontName(rFontName)) + , maSearchReplaceName(GetEnglishSearchFontName(rSubstFontName)) + , mnFlags(nSubstFlags) + { + } + + OUString maSearchName; + OUString maSearchReplaceName; + AddFontSubstituteFlags mnFlags; +}; + +/** DirectFontSubstitution is for Tools->Options->FontReplacement and PsPrinter substitutions + The class is just a simple port of the unmaintainable manual-linked-list based mechanism + */ +// TODO: get rid of this class when the Tools->Options->FontReplacement tabpage is gone for good +class DirectFontSubstitution final : public FontSubstitution +{ +private: + std::vector<FontSubstEntry> maFontSubstList; + +public: + void AddFontSubstitute(const OUString& rFontName, const OUString& rSubstName, + AddFontSubstituteFlags nFlags); + void RemoveFontsSubstitute(); + bool FindFontSubstitute(OUString& rSubstName, std::u16string_view rFontName) const; +}; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/vcl/inc/font/EmphasisMark.hxx b/vcl/inc/font/EmphasisMark.hxx new file mode 100644 index 0000000000..5e902da262 --- /dev/null +++ b/vcl/inc/font/EmphasisMark.hxx @@ -0,0 +1,45 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include <sal/config.h> + +#include <tools/fontenum.hxx> +#include <tools/gen.hxx> +#include <tools/long.hxx> +#include <tools/poly.hxx> + +#include <vcl/dllapi.h> + +namespace vcl::font +{ +class VCL_DLLPUBLIC EmphasisMark +{ +public: + EmphasisMark(FontEmphasisMark eEmphasis, tools::Long nHeight, sal_Int32 nDPIY); + + tools::PolyPolygon GetShape() const { return maPolyPoly; } + bool IsShapePolyLine() const { return mbIsPolyLine; } + tools::Rectangle GetRect1() const { return maRect1; } + tools::Rectangle GetRect2() const { return maRect2; } + tools::Long GetYOffset() const { return mnYOff; } + tools::Long GetWidth() const { return mnWidth; } + +private: + tools::PolyPolygon maPolyPoly; + bool mbIsPolyLine; + tools::Rectangle maRect1; + tools::Rectangle maRect2; + tools::Long mnYOff; + tools::Long mnWidth; +}; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/vcl/inc/font/FeatureCollector.hxx b/vcl/inc/font/FeatureCollector.hxx new file mode 100644 index 0000000000..1b71d02159 --- /dev/null +++ b/vcl/inc/font/FeatureCollector.hxx @@ -0,0 +1,49 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + */ + +#pragma once + +#include <vcl/font/Feature.hxx> +#include <hb.h> +#include <i18nlangtag/languagetag.hxx> + +#include <font/PhysicalFontFace.hxx> + +namespace vcl::font +{ +class FeatureCollector +{ +private: + const PhysicalFontFace* m_pFace; + hb_face_t* m_pHbFace; + std::vector<vcl::font::Feature>& m_rFontFeatures; + const LanguageTag& m_rLanguageTag; + +public: + FeatureCollector(const PhysicalFontFace* pFace, std::vector<vcl::font::Feature>& rFontFeatures, + const LanguageTag& rLanguageTag) + : m_pFace(pFace) + , m_pHbFace(pFace->GetHbFace()) + , m_rFontFeatures(rFontFeatures) + , m_rLanguageTag(rLanguageTag) + { + } + +private: + void collectForTable(hb_tag_t aTableTag); + bool collectGraphite(); + +public: + bool collect(); +}; + +} // namespace vcl::font + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/inc/font/FontMetricData.hxx b/vcl/inc/font/FontMetricData.hxx new file mode 100644 index 0000000000..83eb77d54c --- /dev/null +++ b/vcl/inc/font/FontMetricData.hxx @@ -0,0 +1,155 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#pragma once + +#include <sal/config.h> + +#include <vcl/dllapi.h> +#include <tools/degree.hxx> +#include <tools/long.hxx> +#include <tools/ref.hxx> +#include <fontattributes.hxx> + +class FontMetricData; +typedef tools::SvRef<FontMetricData> FontMetricDataRef; + +class OutputDevice; +namespace vcl::font +{ +class FontSelectPattern; +} +class LogicalFontInstance; + +class VCL_DLLPUBLIC FontMetricData final : public FontAttributes, public SvRefBase +{ +public: + explicit FontMetricData( const vcl::font::FontSelectPattern& ); + + // font instance attributes from the font request + tools::Long GetWidth() const { return mnWidth; } + Degree10 GetOrientation() const { return mnOrientation; } + + void SetWidth(tools::Long nWidth) { mnWidth=nWidth; } + void SetOrientation(Degree10 nOrientation) { mnOrientation=nOrientation; } + + // font metrics measured for the font instance + tools::Long GetAscent() const { return mnAscent; } + tools::Long GetDescent() const { return mnDescent; } + tools::Long GetInternalLeading() const { return mnIntLeading; } + tools::Long GetExternalLeading() const { return mnExtLeading; } + int GetSlant() const { return mnSlant; } + double GetMinKashida() const { return mnMinKashida; } + tools::Long GetHangingBaseline() const { return mnHangingBaseline; } + + void SetSlant(int nSlant) { mnSlant=nSlant; } + void SetMinKashida(double nMinKashida ) { mnMinKashida=nMinKashida; } + + // font attributes queried from the font instance + bool IsFullstopCentered() const { return mbFullstopCentered; } + tools::Long GetBulletOffset() const { return mnBulletOffset; } + + void SetFullstopCenteredFlag(bool bFullstopCentered) { mbFullstopCentered = bFullstopCentered; } + + // font metrics that are usually derived from the measurements + tools::Long GetUnderlineSize() const { return mnUnderlineSize; } + tools::Long GetUnderlineOffset() const { return mnUnderlineOffset; } + tools::Long GetBoldUnderlineSize() const { return mnBUnderlineSize; } + tools::Long GetBoldUnderlineOffset() const { return mnBUnderlineOffset; } + tools::Long GetDoubleUnderlineSize() const { return mnDUnderlineSize; } + tools::Long GetDoubleUnderlineOffset1() const { return mnDUnderlineOffset1; } + tools::Long GetDoubleUnderlineOffset2() const { return mnDUnderlineOffset2; } + tools::Long GetWavelineUnderlineSize() const { return mnWUnderlineSize; } + tools::Long GetWavelineUnderlineOffset() const { return mnWUnderlineOffset; } + tools::Long GetAboveUnderlineSize() const { return mnAboveUnderlineSize; } + tools::Long GetAboveUnderlineOffset() const { return mnAboveUnderlineOffset; } + tools::Long GetAboveBoldUnderlineSize() const { return mnAboveBUnderlineSize; } + tools::Long GetAboveBoldUnderlineOffset() const { return mnAboveBUnderlineOffset; } + tools::Long GetAboveDoubleUnderlineSize() const { return mnAboveDUnderlineSize; } + tools::Long GetAboveDoubleUnderlineOffset1() const { return mnAboveDUnderlineOffset1; } + tools::Long GetAboveDoubleUnderlineOffset2() const { return mnAboveDUnderlineOffset2; } + tools::Long GetAboveWavelineUnderlineSize() const { return mnAboveWUnderlineSize; } + tools::Long GetAboveWavelineUnderlineOffset() const { return mnAboveWUnderlineOffset; } + tools::Long GetStrikeoutSize() const { return mnStrikeoutSize; } + tools::Long GetStrikeoutOffset() const { return mnStrikeoutOffset; } + tools::Long GetBoldStrikeoutSize() const { return mnBStrikeoutSize; } + tools::Long GetBoldStrikeoutOffset() const { return mnBStrikeoutOffset; } + tools::Long GetDoubleStrikeoutSize() const { return mnDStrikeoutSize; } + tools::Long GetDoubleStrikeoutOffset1() const { return mnDStrikeoutOffset1; } + tools::Long GetDoubleStrikeoutOffset2() const { return mnDStrikeoutOffset2; } + + void ImplInitTextLineSize( const OutputDevice* pDev ); + void ImplInitAboveTextLineSize( const OutputDevice* pDev ); + void ImplInitFlags( const OutputDevice* pDev ); + void ImplCalcLineSpacing(LogicalFontInstance *pFontInstance); + void ImplInitBaselines(LogicalFontInstance *pFontInstance); + +private: + bool ShouldNotUseUnderlineMetrics() const; + bool ImplInitTextLineSizeHarfBuzz(LogicalFontInstance *pFontInstance); + bool ShouldUseWinMetrics(int, int, int, int, int, int) const; + + // font instance attributes from the font request + tools::Long mnHeight; // Font size + tools::Long mnWidth; // Reference Width + Degree10 mnOrientation; // Rotation in 1/10 degrees + + // font metrics measured for the font instance + tools::Long mnAscent; // Ascent + tools::Long mnDescent; // Descent + tools::Long mnIntLeading; // Internal Leading + tools::Long mnExtLeading; // External Leading + int mnSlant; // Slant (Italic/Oblique) + double mnMinKashida; // Minimal width of kashida (Arabic) + tools::Long mnHangingBaseline; // Offset of hanging baseline to Romn baseline + + // font attributes queried from the font instance + bool mbFullstopCentered; + tools::Long mnBulletOffset; // Offset to position non-print character + + // font metrics that are usually derived from the measurements + tools::Long mnUnderlineSize; // Lineheight of Underline + tools::Long mnUnderlineOffset; // Offset from Underline to Baseline + tools::Long mnBUnderlineSize; // Height of bold underline + tools::Long mnBUnderlineOffset; // Offset from bold underline to baseline + tools::Long mnDUnderlineSize; // Height of double underline + tools::Long mnDUnderlineOffset1; // Offset from double underline to baseline + tools::Long mnDUnderlineOffset2; // Offset from double underline to baseline + tools::Long mnWUnderlineSize; // Height of WaveLine underline + tools::Long mnWUnderlineOffset; // Offset from WaveLine underline to baseline, but centrered to WaveLine + tools::Long mnAboveUnderlineSize; // Height of single underline (for Vertical Right) + tools::Long mnAboveUnderlineOffset; // Offset from single underline to baseline (for Vertical Right) + tools::Long mnAboveBUnderlineSize; // Height of bold underline (for Vertical Right) + tools::Long mnAboveBUnderlineOffset; // Offset from bold underline to baseline (for Vertical Right) + tools::Long mnAboveDUnderlineSize; // Height of double underline (for Vertical Right) + tools::Long mnAboveDUnderlineOffset1; // Offset from double underline to baseline (for Vertical Right) + tools::Long mnAboveDUnderlineOffset2; // Offset from double underline to baseline (for Vertical Right) + tools::Long mnAboveWUnderlineSize; // Height of WaveLine-strike-out (for Vertical Right) + tools::Long mnAboveWUnderlineOffset; // Offset from WaveLine-strike-out to baseline, but centrered to the WaveLine (for Vertical Right) + tools::Long mnStrikeoutSize; // Height of single strike-out + tools::Long mnStrikeoutOffset; // Offset from single strike-out to baseline + tools::Long mnBStrikeoutSize; // Height of bold strike-out + tools::Long mnBStrikeoutOffset; // Offset of bold strike-out to baseline + tools::Long mnDStrikeoutSize; // Height of double strike-out + tools::Long mnDStrikeoutOffset1; // Offset of double strike-out to baseline + tools::Long mnDStrikeoutOffset2; // Offset of double strike-out to baseline + +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/inc/font/FontSelectPattern.hxx b/vcl/inc/font/FontSelectPattern.hxx new file mode 100644 index 0000000000..8e21cf5696 --- /dev/null +++ b/vcl/inc/font/FontSelectPattern.hxx @@ -0,0 +1,86 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#pragma once + +#include <i18nlangtag/lang.h> +#include <tools/degree.hxx> + +#include <vcl/vclenum.hxx> + +#include <fontattributes.hxx> + +#include <ostream> + +namespace vcl { class Font; } + +class LogicalFontInstance; +class Size; + +namespace vcl::font +{ +class PhysicalFontFace; + +class VCL_DLLPUBLIC FontSelectPattern : public FontAttributes +{ +public: + FontSelectPattern(const vcl::Font&, OUString aSearchName, + const Size&, float fExactHeight, bool bNonAntialias = false); +#ifdef _WIN32 + FontSelectPattern( const PhysicalFontFace&, const Size&, + float fExactHeight, int nOrientation, bool bVertical ); +#endif + + size_t hashCode() const; + bool operator==(const FontSelectPattern& rOther) const; + bool operator!=(const FontSelectPattern& rOther) const + { + return !(*this == rOther); + } + + static const char FEAT_PREFIX; + static const char FEAT_SEPARATOR; + +public: + OUString maTargetName; // name of the font name token that is chosen + OUString maSearchName; // name of the font that matches best + int mnWidth; // width of font in pixel units + int mnHeight; // height of font in pixel units + float mfExactHeight; // requested height (in pixels with subpixel details) + Degree10 mnOrientation; // text orientation in 1/10 degree (0-3600) + LanguageType meLanguage; // text language + bool mbVertical; // vertical mode of requested font + bool mbNonAntialiased; // true if antialiasing is disabled + + bool mbEmbolden; // Force emboldening + ItalicMatrix maItalicMatrix; // Force matrix for slant +}; +} + +template< typename charT, typename traits > +inline std::basic_ostream<charT, traits> & operator <<( + std::basic_ostream<charT, traits> & stream, const vcl::font::FontSelectPattern & rFSP) +{ + stream << (rFSP.maTargetName.isEmpty() ? "<default>" : rFSP.maTargetName) + << " (" << rFSP.maSearchName << ") w: " << rFSP.mnWidth << " h: " + << rFSP.mnHeight << " alias: " << rFSP.mbNonAntialiased; + return stream; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/inc/font/LogicalFontInstance.hxx b/vcl/inc/font/LogicalFontInstance.hxx new file mode 100644 index 0000000000..40d3c57c4e --- /dev/null +++ b/vcl/inc/font/LogicalFontInstance.hxx @@ -0,0 +1,167 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#pragma once + +#include <sal/config.h> + +#include <basegfx/polygon/b2dpolypolygon.hxx> +#include <o3tl/hash_combine.hxx> +#include <rtl/ref.hxx> +#include <salhelper/simplereferenceobject.hxx> +#include <tools/gen.hxx> +#include <tools/fontenum.hxx> +#include <tools/degree.hxx> + +#include <font/FontSelectPattern.hxx> +#include <font/FontMetricData.hxx> +#include <glyphid.hxx> + +#include <optional> +#include <unordered_map> + +#include <hb.h> + +class ConvertChar; +class ImplFontCache; + +constexpr float ARTIFICIAL_ITALIC_MATRIX_XX = 1 << 16; +constexpr float ARTIFICIAL_ITALIC_MATRIX_XY = (1 << 16) / 3.f; +constexpr float ARTIFICIAL_ITALIC_SKEW = ARTIFICIAL_ITALIC_MATRIX_XY / ARTIFICIAL_ITALIC_MATRIX_XX; + +// extend std namespace to add custom hash needed for LogicalFontInstance + +namespace std +{ +template <> struct hash<pair<sal_UCS4, FontWeight>> +{ + size_t operator()(const pair<sal_UCS4, FontWeight>& rData) const + { + std::size_t seed = 0; + o3tl::hash_combine(seed, rData.first); + o3tl::hash_combine(seed, rData.second); + return seed; + } +}; +} + +// TODO: allow sharing of metrics for related fonts + +class VCL_PLUGIN_PUBLIC LogicalFontInstance : public salhelper::SimpleReferenceObject +{ + // just declaring the factory function doesn't work AKA + // friend LogicalFontInstance* PhysicalFontFace::CreateFontInstance(const FontSelectPattern&) const; + friend class vcl::font::PhysicalFontFace; + friend class ImplFontCache; + +public: // TODO: make data members private + virtual ~LogicalFontInstance() override; + + FontMetricDataRef mxFontMetric; // Font attributes + const ConvertChar* mpConversion; // used e.g. for StarBats->StarSymbol + + tools::Long mnLineHeight; + Degree10 mnOwnOrientation; // text angle if lower layers don't rotate text themselves + Degree10 mnOrientation; // text angle in 3600 system + bool mbInit; // true if maFontMetric member is valid + + void AddFallbackForUnicode(sal_UCS4 cChar, FontWeight eWeight, const OUString& rFontName, + bool bEmbolden, const ItalicMatrix& rMatrix); + bool GetFallbackForUnicode(sal_UCS4 cInChar, FontWeight eInWeight, OUString* pOutFontName, + bool* pOutEmbolden, ItalicMatrix* pOutItalicMatrix) const; + void IgnoreFallbackForUnicode(sal_UCS4, FontWeight eWeight, std::u16string_view rFontName); + + inline hb_font_t* GetHbFont(); + bool IsGraphiteFont(); + // NeedOffsetCorrection: Return if the font need offset correction in TTB direction. + // nYOffset is the original offset. It is used to check if the correction is necessary. + bool NeedOffsetCorrection(sal_Int32 nYOffset); + void SetAverageWidthFactor(double nFactor) { m_nAveWidthFactor = std::abs(nFactor); } + double GetAverageWidthFactor() const { return m_nAveWidthFactor; } + const vcl::font::FontSelectPattern& GetFontSelectPattern() const { return m_aFontSelData; } + + const vcl::font::PhysicalFontFace* GetFontFace() const { return m_pFontFace.get(); } + vcl::font::PhysicalFontFace* GetFontFace() { return m_pFontFace.get(); } + const ImplFontCache* GetFontCache() const { return mpFontCache; } + + bool GetGlyphBoundRect(sal_GlyphId, tools::Rectangle&, bool) const; + virtual bool GetGlyphOutline(sal_GlyphId, basegfx::B2DPolyPolygon&, bool) const = 0; + basegfx::B2DPolyPolygon GetGlyphOutlineUntransformed(sal_GlyphId) const; + + sal_GlyphId GetGlyphIndex(uint32_t, uint32_t = 0) const; + + double GetGlyphWidth(sal_GlyphId, bool = false, bool = true) const; + + double GetKashidaWidth() const; + + void GetScale(double* nXScale, double* nYScale) const; + + bool NeedsArtificialItalic() const; + bool NeedsArtificialBold() const; + +protected: + explicit LogicalFontInstance(const vcl::font::PhysicalFontFace&, + const vcl::font::FontSelectPattern&); + + hb_font_t* InitHbFont(); + virtual void ImplInitHbFont(hb_font_t*) {} + +private: + hb_font_t* GetHbFontUntransformed() const; + + struct MapEntry + { + OUString sFontName; + bool bEmbolden; + ItalicMatrix aItalicMatrix; + }; + // cache of Unicode characters and replacement font names and attributes + // TODO: a fallback map can be shared with many other ImplFontEntries + // TODO: at least the ones which just differ in orientation, stretching or height + typedef ::std::unordered_map<::std::pair<sal_UCS4, FontWeight>, MapEntry> UnicodeFallbackList; + UnicodeFallbackList maUnicodeFallbackList; + mutable ImplFontCache* mpFontCache; + const vcl::font::FontSelectPattern m_aFontSelData; + hb_font_t* m_pHbFont; + mutable hb_font_t* m_pHbFontUntransformed = nullptr; + double m_nAveWidthFactor; + rtl::Reference<vcl::font::PhysicalFontFace> m_pFontFace; + std::optional<bool> m_xbIsGraphiteFont; + + enum class FontFamilyEnum + { + Unclassified, + DFKaiSB + }; + + // The value is initialized and used in NeedOffsetCorrection(). + std::optional<FontFamilyEnum> m_xeFontFamilyEnum; + + mutable hb_draw_funcs_t* m_pHbDrawFuncs = nullptr; + basegfx::B2DPolygon m_aDrawPolygon; +}; + +inline hb_font_t* LogicalFontInstance::GetHbFont() +{ + if (!m_pHbFont) + m_pHbFont = InitHbFont(); + return m_pHbFont; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/inc/font/OpenTypeFeatureDefinitionList.hxx b/vcl/inc/font/OpenTypeFeatureDefinitionList.hxx new file mode 100644 index 0000000000..1ae634deab --- /dev/null +++ b/vcl/inc/font/OpenTypeFeatureDefinitionList.hxx @@ -0,0 +1,38 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include <vcl/dllapi.h> +#include <vcl/font/Feature.hxx> +#include <vector> +#include <unordered_map> + +namespace vcl::font +{ +class OpenTypeFeatureDefinitionListPrivate +{ +private: + std::vector<FeatureDefinition> m_aFeatureDefinition; + std::unordered_map<sal_uInt32, size_t> m_aCodeToIndex; + std::vector<sal_uInt32> m_aRequiredFeatures; + + void init(); + +public: + OpenTypeFeatureDefinitionListPrivate(); + FeatureDefinition getDefinition(vcl::font::Feature& rFeature); + bool isRequired(sal_uInt32 nFeatureCode); +}; + +VCL_DLLPUBLIC OpenTypeFeatureDefinitionListPrivate& OpenTypeFeatureDefinitionList(); + +} // namespace vcl::font + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/inc/font/OpenTypeFeatureStrings.hrc b/vcl/inc/font/OpenTypeFeatureStrings.hrc new file mode 100644 index 0000000000..086d7d500c --- /dev/null +++ b/vcl/inc/font/OpenTypeFeatureStrings.hrc @@ -0,0 +1,104 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_VCL_INC_FONT_OPENTYPEFEATRESTRINGS_HRC +#define INCLUDED_VCL_INC_FONT_OPENTYPEFEATRESTRINGS_HRC + +#define NC_(Context, String) TranslateId(Context, u8##String) + +#define STR_FONT_FEATURE_ID_AALT NC_("STR_FONT_FEATURE_ID_AALT", "Access All Alternates") +#define STR_FONT_FEATURE_ID_AFRC NC_("STR_FONT_FEATURE_ID_AFRC", "Alternative (Vertical) Fractions") +#define STR_FONT_FEATURE_ID_ALIG NC_("STR_FONT_FEATURE_ID_ALIG", "Ancient Ligatures") +#define STR_FONT_FEATURE_ID_C2PC NC_("STR_FONT_FEATURE_ID_C2PC", "Capitals to Petite Capitals") +#define STR_FONT_FEATURE_ID_C2SC NC_("STR_FONT_FEATURE_ID_C2SC", "Capitals to Small Capitals") +#define STR_FONT_FEATURE_ID_CALT NC_("STR_FONT_FEATURE_ID_CALT", "Contextual Alternates") +#define STR_FONT_FEATURE_ID_CASE NC_("STR_FONT_FEATURE_ID_CASE", "Case-Sensitive Forms") +#define STR_FONT_FEATURE_ID_CLIG NC_("STR_FONT_FEATURE_ID_CLIG", "Contextual Ligatures") +#define STR_FONT_FEATURE_ID_CPCT NC_("STR_FONT_FEATURE_ID_CPCT", "Centered CJK Punctuation") +#define STR_FONT_FEATURE_ID_CPSP NC_("STR_FONT_FEATURE_ID_CPSP", "Capital Spacing") +#define STR_FONT_FEATURE_ID_CSWH NC_("STR_FONT_FEATURE_ID_CSWH", "Contextual Swash") +#define STR_FONT_FEATURE_ID_CVXX NC_("STR_FONT_FEATURE_ID_CVXX", "Character Variant %1") +#define STR_FONT_FEATURE_ID_DCAP NC_("STR_FONT_FEATURE_ID_DCAP", "Drop Caps") +#define STR_FONT_FEATURE_ID_DLIG NC_("STR_FONT_FEATURE_ID_DLIG", "Discretionary Ligatures") +#define STR_FONT_FEATURE_ID_DNOM NC_("STR_FONT_FEATURE_ID_DNOM", "Denominators") +#define STR_FONT_FEATURE_ID_DPNG NC_("STR_FONT_FEATURE_ID_DPNG", "Diphthongs (Obsolete)") +#define STR_FONT_FEATURE_ID_EXPT NC_("STR_FONT_FEATURE_ID_EXPT", "Expert Forms") +#define STR_FONT_FEATURE_ID_FALT NC_("STR_FONT_FEATURE_ID_FALT", "Final Glyph on Line Alternates") +#define STR_FONT_FEATURE_ID_FRAC NC_("STR_FONT_FEATURE_ID_FRAC", "Fraction style") +#define STR_FONT_FEATURE_ID_FWID NC_("STR_FONT_FEATURE_ID_FWID", "Full Widths") +#define STR_FONT_FEATURE_ID_HALT NC_("STR_FONT_FEATURE_ID_HALT", "Alternate Half Widths") +#define STR_FONT_FEATURE_ID_HIST NC_("STR_FONT_FEATURE_ID_HIST", "Historical Forms") +#define STR_FONT_FEATURE_ID_HKNA NC_("STR_FONT_FEATURE_ID_HKNA", "Horizontal Kana Alternates") +#define STR_FONT_FEATURE_ID_HLIG NC_("STR_FONT_FEATURE_ID_HLIG", "Historical Ligatures") +#define STR_FONT_FEATURE_ID_HNGL NC_("STR_FONT_FEATURE_ID_HNGL", "Hanja to Hangul (Obsolete)") +#define STR_FONT_FEATURE_ID_HOJO NC_("STR_FONT_FEATURE_ID_HOJO", "Hojo Kanji Forms (JIS X 0212-1990 Kanji Forms)") +#define STR_FONT_FEATURE_ID_HWID NC_("STR_FONT_FEATURE_ID_HWID", "Half Widths") +#define STR_FONT_FEATURE_ID_ITAL NC_("STR_FONT_FEATURE_ID_ITAL", "Italics") +#define STR_FONT_FEATURE_ID_JALT NC_("STR_FONT_FEATURE_ID_JALT", "Justification Alternates") +#define STR_FONT_FEATURE_ID_JP04 NC_("STR_FONT_FEATURE_ID_JP04", "JIS2004 Forms") +#define STR_FONT_FEATURE_ID_JP78 NC_("STR_FONT_FEATURE_ID_JP78", "JIS78 Forms") +#define STR_FONT_FEATURE_ID_JP83 NC_("STR_FONT_FEATURE_ID_JP83", "JIS83 Forms") +#define STR_FONT_FEATURE_ID_JP90 NC_("STR_FONT_FEATURE_ID_JP90", "JIS90 Forms") +#define STR_FONT_FEATURE_ID_KERN NC_("STR_FONT_FEATURE_ID_KERN", "Horizontal Kerning") +#define STR_FONT_FEATURE_ID_LFBD NC_("STR_FONT_FEATURE_ID_LFBD", "Left Bounds") +#define STR_FONT_FEATURE_ID_LIGA NC_("STR_FONT_FEATURE_ID_LIGA", "Standard Ligatures") +#define STR_FONT_FEATURE_ID_LNUM NC_("STR_FONT_FEATURE_ID_LNUM", "Lining Figures") +#define STR_FONT_FEATURE_ID_MGRK NC_("STR_FONT_FEATURE_ID_MGRK", "Mathematical Greek") +#define STR_FONT_FEATURE_ID_NALT NC_("STR_FONT_FEATURE_ID_NALT", "Alternate Annotation Forms") +#define STR_FONT_FEATURE_ID_NLCK NC_("STR_FONT_FEATURE_ID_NLCK", "NLC Kanji Forms") +#define STR_FONT_FEATURE_ID_NUMR NC_("STR_FONT_FEATURE_ID_NUMR", "Numerators") +#define STR_FONT_FEATURE_ID_ONUM NC_("STR_FONT_FEATURE_ID_ONUM", "Oldstyle Figures") +#define STR_FONT_FEATURE_ID_OPBD NC_("STR_FONT_FEATURE_ID_OPBD", "Optical Bounds") +#define STR_FONT_FEATURE_ID_ORDN NC_("STR_FONT_FEATURE_ID_ORDN", "Ordinals") +#define STR_FONT_FEATURE_ID_ORNM NC_("STR_FONT_FEATURE_ID_ORNM", "Ornaments") +#define STR_FONT_FEATURE_ID_PALT NC_("STR_FONT_FEATURE_ID_PALT", "Proportional Alternate Metrics") +#define STR_FONT_FEATURE_ID_PCAP NC_("STR_FONT_FEATURE_ID_PCAP", "Lowercase to Petite Capitals") +#define STR_FONT_FEATURE_ID_PKNA NC_("STR_FONT_FEATURE_ID_PKNA", "Proportional Kana") +#define STR_FONT_FEATURE_ID_PNUM NC_("STR_FONT_FEATURE_ID_PNUM", "Proportional Numbers") +#define STR_FONT_FEATURE_ID_PWID NC_("STR_FONT_FEATURE_ID_PWID", "Proportional Widths") +#define STR_FONT_FEATURE_ID_QWID NC_("STR_FONT_FEATURE_ID_QWID", "Quarter Widths") +#define STR_FONT_FEATURE_ID_RTBD NC_("STR_FONT_FEATURE_ID_RTBD", "Right Bounds") +#define STR_FONT_FEATURE_ID_RUBY NC_("STR_FONT_FEATURE_ID_RUBY", "Ruby Notation Forms") +#define STR_FONT_FEATURE_ID_SALT NC_("STR_FONT_FEATURE_ID_SALT", "Stylistic Alternates") +#define STR_FONT_FEATURE_ID_SINF NC_("STR_FONT_FEATURE_ID_SINF", "Scientific Inferiors") +#define STR_FONT_FEATURE_ID_SMCP NC_("STR_FONT_FEATURE_ID_SMCP", "Lowercase to Small Capitals") +#define STR_FONT_FEATURE_ID_SMPL NC_("STR_FONT_FEATURE_ID_SMPL", "Simplified Forms") +#define STR_FONT_FEATURE_ID_SSXX NC_("STR_FONT_FEATURE_ID_SSXX", "Stylistic Set %1") +#define STR_FONT_FEATURE_ID_SUBS NC_("STR_FONT_FEATURE_ID_SUBS", "Subscript") +#define STR_FONT_FEATURE_ID_SUPS NC_("STR_FONT_FEATURE_ID_SUPS", "Superscript") +#define STR_FONT_FEATURE_ID_SWSH NC_("STR_FONT_FEATURE_ID_SWSH", "Swash") +#define STR_FONT_FEATURE_ID_TITL NC_("STR_FONT_FEATURE_ID_TITL", "Titling") +#define STR_FONT_FEATURE_ID_TNAM NC_("STR_FONT_FEATURE_ID_TNAM", "Traditional Name Forms") +#define STR_FONT_FEATURE_ID_TNUM NC_("STR_FONT_FEATURE_ID_TNUM", "Tabular Numbers") +#define STR_FONT_FEATURE_ID_TRAD NC_("STR_FONT_FEATURE_ID_TRAD", "Traditional Forms") +#define STR_FONT_FEATURE_ID_TWID NC_("STR_FONT_FEATURE_ID_TWID", "Third Widths") +#define STR_FONT_FEATURE_ID_UNIC NC_("STR_FONT_FEATURE_ID_UNIC", "Unicase") +#define STR_FONT_FEATURE_ID_VALT NC_("STR_FONT_FEATURE_ID_VALT", "Alternate Vertical Metrics") +#define STR_FONT_FEATURE_ID_VHAL NC_("STR_FONT_FEATURE_ID_VHAL", "Alternate Vertical Half Metrics") +#define STR_FONT_FEATURE_ID_VKNA NC_("STR_FONT_FEATURE_ID_VKNA", "Vertical Kana Alternates") +#define STR_FONT_FEATURE_ID_VKRN NC_("STR_FONT_FEATURE_ID_VKRN", "Vertical Kerning") +#define STR_FONT_FEATURE_ID_VPAL NC_("STR_FONT_FEATURE_ID_VPAL", "Proportional Alternate Vertical Metrics") +#define STR_FONT_FEATURE_ID_VRT2 NC_("STR_FONT_FEATURE_ID_VRT2", "Vertical Alternates and Rotation") +#define STR_FONT_FEATURE_ID_VRTR NC_("STR_FONT_FEATURE_ID_VRTR", "Vertical Alternates for Rotation") +#define STR_FONT_FEATURE_ID_ZERO NC_("STR_FONT_FEATURE_ID_ZERO", "Slashed Zero") +#define STR_FONT_FEATURE_PARAM_NONE NC_("STR_FONT_FEATURE_PARAM_NONE", "None") + +#endif // INCLUDED_VCL_INC_STRINGS_HRC + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/inc/font/PhysicalFontCollection.hxx b/vcl/inc/font/PhysicalFontCollection.hxx new file mode 100644 index 0000000000..d791f7b692 --- /dev/null +++ b/vcl/inc/font/PhysicalFontCollection.hxx @@ -0,0 +1,103 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#pragma once + +#include <sal/config.h> + +#include <vcl/dllapi.h> + +#include <font/LogicalFontInstance.hxx> + +#include "PhysicalFontFamily.hxx" + +#include <array> +#include <string_view> + +#define MAX_GLYPHFALLBACK 16 + +namespace vcl::font +{ +class GlyphFallbackFontSubstitution; +class PreMatchFontSubstitution; +} + +// TODO: merge with ImplFontCache +// TODO: rename to LogicalFontManager + +namespace vcl::font +{ + +class VCL_PLUGIN_PUBLIC PhysicalFontCollection final +{ +public: + explicit PhysicalFontCollection(); + ~PhysicalFontCollection(); + + // fill the list with device font faces + void Add( vcl::font::PhysicalFontFace* ); + void Clear(); + int Count() const { return maPhysicalFontFamilies.size(); } + + // find the device font family + vcl::font::PhysicalFontFamily* FindFontFamily( std::u16string_view rFontName ) const; + vcl::font::PhysicalFontFamily* FindOrCreateFontFamily( const OUString &rFamilyName ); + vcl::font::PhysicalFontFamily* FindFontFamily( vcl::font::FontSelectPattern& ) const; + vcl::font::PhysicalFontFamily* FindFontFamilyByTokenNames(std::u16string_view rTokenStr) const; + vcl::font::PhysicalFontFamily* FindFontFamilyByAttributes(ImplFontAttrs nSearchType, FontWeight, FontWidth, + FontItalic, std::u16string_view rSearchFamily) const; + + // suggest fonts for glyph fallback + vcl::font::PhysicalFontFamily* GetGlyphFallbackFont( vcl::font::FontSelectPattern&, + LogicalFontInstance* pLogicalFont, + OUString& rMissingCodes, int nFallbackLevel ) const; + + // prepare platform specific font substitutions + void SetPreMatchHook( vcl::font::PreMatchFontSubstitution* ); + void SetFallbackHook( vcl::font::GlyphFallbackFontSubstitution* ); + + // misc utilities + std::shared_ptr<PhysicalFontCollection> Clone() const; + std::unique_ptr<vcl::font::PhysicalFontFaceCollection> GetFontFaceCollection() const; + +private: + mutable bool mbMatchData; // true if matching attributes are initialized + + typedef std::unordered_map<OUString, std::unique_ptr<vcl::font::PhysicalFontFamily>> PhysicalFontFamilies; + PhysicalFontFamilies maPhysicalFontFamilies; + + vcl::font::PreMatchFontSubstitution* mpPreMatchHook; // device specific prematch substitution + vcl::font::GlyphFallbackFontSubstitution* mpFallbackHook; // device specific glyph fallback substitution + + mutable std::unique_ptr<std::array<vcl::font::PhysicalFontFamily*,MAX_GLYPHFALLBACK>> mpFallbackList; + mutable int mnFallbackCount; + + void ImplInitMatchData() const; + void ImplInitGenericGlyphFallback() const; + + vcl::font::PhysicalFontFamily* ImplFindFontFamilyBySearchName( const OUString& ) const; + vcl::font::PhysicalFontFamily* ImplFindFontFamilyBySubstFontAttr( const utl::FontNameAttr& ) const; + + vcl::font::PhysicalFontFamily* ImplFindFontFamilyOfDefaultFont() const; + +}; + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/vcl/inc/font/PhysicalFontFace.hxx b/vcl/inc/font/PhysicalFontFace.hxx new file mode 100644 index 0000000000..1fce6a6cba --- /dev/null +++ b/vcl/inc/font/PhysicalFontFace.hxx @@ -0,0 +1,213 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#pragma once + +#include <sal/config.h> + +#include <i18nlangtag/languagetag.hxx> +#include <rtl/ref.hxx> +#include <salhelper/simplereferenceobject.hxx> +#include <tools/color.hxx> +#include <vcl/dllapi.h> +#include <vcl/fontcapabilities.hxx> +#include <vcl/fontcharmap.hxx> + +#include <fontattributes.hxx> +#include <fontsubset.hxx> + +#include <hb.h> +#include <hb-ot.h> + +class LogicalFontInstance; +struct FontMatchStatus; +namespace vcl::font +{ +class FontSelectPattern; +} + +namespace vcl +{ +class PhysicalFontFamily; +} + +namespace vcl::font +{ +class FontSelectPattern; + +struct FontMatchStatus +{ +public: + int mnFaceMatch; + const OUString* mpTargetStyleName; +}; + +struct RawFontData +{ +public: + RawFontData(hb_blob_t* pBlob = nullptr) + : mpBlob(pBlob ? pBlob : hb_blob_get_empty()) + { + } + + RawFontData(const RawFontData& rOther) + : mpBlob(hb_blob_reference(rOther.mpBlob)) + { + } + + ~RawFontData() { hb_blob_destroy(mpBlob); } + + RawFontData& operator=(const RawFontData& rOther) + { + hb_blob_destroy(mpBlob); + mpBlob = hb_blob_reference(rOther.mpBlob); + return *this; + } + + size_t size() const { return hb_blob_get_length(mpBlob); } + bool empty() const { return size() == 0; } + const uint8_t* data() const + { + return reinterpret_cast<const uint8_t*>(hb_blob_get_data(mpBlob, nullptr)); + } + +private: + hb_blob_t* mpBlob; +}; + +struct ColorLayer +{ + sal_GlyphId nGlyphIndex; + uint32_t nColorIndex; +}; + +typedef std::vector<Color> ColorPalette; + +// https://learn.microsoft.com/en-us/typography/opentype/spec/name#name-ids +typedef enum : hb_ot_name_id_t { + NAME_ID_COPYRIGHT = 0, + NAME_ID_FONT_FAMILY = 1, + NAME_ID_FONT_SUBFAMILY = 2, + NAME_ID_UNIQUE_ID = 3, + NAME_ID_FULL_NAME = 4, + NAME_ID_VERSION_STRING = 5, + NAME_ID_POSTSCRIPT_NAME = 6, + NAME_ID_TRADEMARK = 7, + NAME_ID_MANUFACTURER = 8, + NAME_ID_DESIGNER = 9, + NAME_ID_DESCRIPTION = 10, + NAME_ID_VENDOR_URL = 11, + NAME_ID_DESIGNER_URL = 12, + NAME_ID_LICENSE = 13, + NAME_ID_LICENSE_URL = 14, + //NAME_ID_RESERVED = 15, + NAME_ID_TYPOGRAPHIC_FAMILY = 16, + NAME_ID_TYPOGRAPHIC_SUBFAMILY = 17, + NAME_ID_MAC_FULL_NAME = 18, + NAME_ID_SAMPLE_TEXT = 19, + NAME_ID_CID_FINDFONT_NAME = 20, + NAME_ID_WWS_FAMILY = 21, + NAME_ID_WWS_SUBFAMILY = 22, + NAME_ID_LIGHT_BACKGROUND = 23, + NAME_ID_DARK_BACKGROUND = 24, + NAME_ID_VARIATIONS_PS_PREFIX = 25, +} NameID; + +// TODO: no more direct access to members +// TODO: get rid of height/width for scalable fonts +// TODO: make cloning cheaper + +/** + * abstract base class for physical font faces + * + * It acts as a factory for its corresponding LogicalFontInstances and + * can be extended to cache device and font instance specific data. + */ +class VCL_PLUGIN_PUBLIC PhysicalFontFace : public FontAttributes, + public salhelper::SimpleReferenceObject +{ +public: + ~PhysicalFontFace(); + + virtual rtl::Reference<LogicalFontInstance> + CreateFontInstance(const vcl::font::FontSelectPattern&) const = 0; + + virtual sal_IntPtr GetFontId() const = 0; + virtual FontCharMapRef GetFontCharMap() const; + virtual bool GetFontCapabilities(vcl::FontCapabilities&) const; + + RawFontData GetRawFontData(uint32_t) const; + + bool IsBetterMatch(const vcl::font::FontSelectPattern&, FontMatchStatus&) const; + sal_Int32 CompareIgnoreSize(const PhysicalFontFace&) const; + + // CreateFontSubset: a method to get a subset of glyphs of a font inside a + // new valid font file + // returns true if creation of subset was successful + // parameters: rOutBuffer: vector to write the subset to + // pGlyphIDs: the glyph ids to be extracted + // pEncoding: the character code corresponding to each glyph + // nGlyphs: the number of glyphs + // rInfo: additional outgoing information + // implementation note: encoding 0 with glyph id 0 should be added implicitly + // as "undefined character" + bool CreateFontSubset(std::vector<sal_uInt8>&, const sal_GlyphId*, const sal_uInt8*, const int, + FontSubsetInfo&) const; + + bool IsColorFont() const { return HasColorLayers() || HasColorBitmaps(); } + + bool HasColorLayers() const; + std::vector<ColorLayer> GetGlyphColorLayers(sal_GlyphId) const; + + const std::vector<ColorPalette>& GetColorPalettes() const; + + bool HasColorBitmaps() const; + RawFontData GetGlyphColorBitmap(sal_GlyphId, tools::Rectangle&) const; + + OString GetGlyphName(sal_GlyphId, bool = false) const; + + uint32_t UnitsPerEm() const { return hb_face_get_upem(GetHbFace()); } + + OUString GetName(NameID, const LanguageTag&) const; + OUString GetName(NameID aNameID) const { return GetName(aNameID, LanguageTag(LANGUAGE_NONE)); } + + virtual hb_face_t* GetHbFace() const; + virtual hb_blob_t* GetHbTable(hb_tag_t) const + { + assert(false); + return nullptr; + } + + virtual const std::vector<hb_variation_t>& GetVariations(const LogicalFontInstance&) const; + +protected: + mutable hb_face_t* mpHbFace; + mutable hb_font_t* mpHbUnscaledFont; + mutable FontCharMapRef mxCharMap; + mutable std::optional<vcl::FontCapabilities> mxFontCapabilities; + mutable std::optional<std::vector<ColorPalette>> mxColorPalettes; + mutable std::optional<std::vector<hb_variation_t>> mxVariations; + + explicit PhysicalFontFace(const FontAttributes&); + + hb_font_t* GetHbUnscaledFont() const; +}; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/inc/font/PhysicalFontFaceCollection.hxx b/vcl/inc/font/PhysicalFontFaceCollection.hxx new file mode 100644 index 0000000000..8208af44c4 --- /dev/null +++ b/vcl/inc/font/PhysicalFontFaceCollection.hxx @@ -0,0 +1,48 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#pragma once + +#include <sal/config.h> + +#include "PhysicalFontFace.hxx" + +#include <vector> + +/** + A PhysicalFontFaceCollection is created by a PhysicalFontCollection and + becomes invalid when original PhysicalFontCollection is modified. + */ + +namespace vcl::font +{ +class PhysicalFontFaceCollection +{ +private: + std::vector<rtl::Reference<PhysicalFontFace>> maDevFontVector; + +public: + PhysicalFontFaceCollection() { maDevFontVector.reserve(1024); } + void Add(PhysicalFontFace* pFace) { maDevFontVector.push_back(pFace); } + PhysicalFontFace* Get(int nIndex) const { return maDevFontVector[nIndex].get(); } + int Count() const { return maDevFontVector.size(); } +}; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/vcl/inc/font/PhysicalFontFamily.hxx b/vcl/inc/font/PhysicalFontFamily.hxx new file mode 100644 index 0000000000..a944ed72fe --- /dev/null +++ b/vcl/inc/font/PhysicalFontFamily.hxx @@ -0,0 +1,111 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#pragma once + +#include <sal/config.h> + +#include <vcl/dllapi.h> +#include <vcl/outdev.hxx> + +#include <unotools/fontcfg.hxx> + +namespace vcl::font +{ +// flags for mnTypeFaces member +enum class FontTypeFaces +{ + NONE = 0x00, + Scalable = 0x01, + Symbol = 0x02, + NoneSymbol = 0x04, + Light = 0x08, + Bold = 0x10, + Normal = 0x20, + NoneItalic = 0x40, + Italic = 0x80 +}; +} +namespace o3tl +{ +template <> +struct typed_flags<vcl::font::FontTypeFaces> : is_typed_flags<vcl::font::FontTypeFaces, 0xff> +{ +}; +}; + +namespace vcl::font +{ +class FontSelectPattern; +class PhysicalFontCollection; +class PhysicalFontFace; +class PhysicalFontFaceCollection; + +class VCL_PLUGIN_PUBLIC PhysicalFontFamily +{ +public: + PhysicalFontFamily(OUString aSearchName); + ~PhysicalFontFamily(); + + // Avoid implicitly defined copy constructors/assignments for the DLLPUBLIC class (they may + // require forward-declared classes used internally to be defined in places using this) + PhysicalFontFamily(const PhysicalFontFamily&) = delete; + PhysicalFontFamily(PhysicalFontFamily&&) = delete; + PhysicalFontFamily& operator=(const PhysicalFontFamily&) = delete; + PhysicalFontFamily& operator=(PhysicalFontFamily&&) = delete; + + const OUString& GetFamilyName() const { return maFamilyName; } + const OUString& GetSearchName() const { return maSearchName; } + int GetMinQuality() const { return mnMinQuality; } + FontTypeFaces GetTypeFaces() const { return mnTypeFaces; } + + const OUString& GetMatchFamilyName() const { return maMatchFamilyName; } + ImplFontAttrs GetMatchType() const { return mnMatchType; } + FontWeight GetMatchWeight() const { return meMatchWeight; } + FontWidth GetMatchWidth() const { return meMatchWidth; } + void InitMatchData(const utl::FontSubstConfiguration&, const OUString& rSearchName); + + void AddFontFace(PhysicalFontFace*); + + PhysicalFontFace* FindBestFontFace(const vcl::font::FontSelectPattern& rFSD) const; + + void UpdateDevFontList(PhysicalFontFaceCollection&) const; + void UpdateCloneFontList(PhysicalFontCollection&) const; + + static void CalcType(ImplFontAttrs& rType, FontWeight& rWeight, FontWidth& rWidth, + FontFamily eFamily, const utl::FontNameAttr* pFontAttr); + +private: + std::vector<rtl::Reference<PhysicalFontFace>> maFontFaces; + + OUString maFamilyName; // original font family name + OUString maSearchName; // normalized font family name + FontTypeFaces mnTypeFaces; // Typeface Flags + FontFamily meFamily; + FontPitch mePitch; + int mnMinQuality; // quality of the worst font face + + ImplFontAttrs mnMatchType; // MATCH - Type + OUString maMatchFamilyName; // MATCH - FamilyName + FontWeight meMatchWeight; // MATCH - Weight + FontWidth meMatchWidth; // MATCH - Width +}; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/vcl/inc/font/fontsubstitution.hxx b/vcl/inc/font/fontsubstitution.hxx new file mode 100644 index 0000000000..f7befca4c3 --- /dev/null +++ b/vcl/inc/font/fontsubstitution.hxx @@ -0,0 +1,68 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +// nowadays these substitutions are needed for backward compatibility and tight platform integration: +// - substitutions from configuration entries (Tools->Options->FontReplacement and/or fontconfig) +// - device specific substitutions (e.g. for PS printer builtin fonts) +// - substitutions for missing fonts defined by configuration entries (generic and/or platform dependent fallbacks) +// - substitutions for missing fonts defined by multi-token fontnames (e.g. fontname="SpecialFont;FallbackA;FallbackB") +// - substitutions for incomplete fonts (implicit, generic, EUDC and/or platform dependent fallbacks) +// - substitutions for missing symbol fonts by translating code points into other symbol fonts + +#pragma once + +#include <sal/config.h> + +#include <rtl/ustring.hxx> + +#include <font/FontSelectPattern.hxx> + +namespace vcl::font +{ +class FontSelectPattern; + +class FontSubstitution +{ + // TODO: there is more commonality between the different substitutions +protected: + virtual ~FontSubstitution() {} +}; + +/// Abstracts the concept of finding the best font to support an incomplete font +class GlyphFallbackFontSubstitution : public FontSubstitution +{ +public: + virtual bool FindFontSubstitute(vcl::font::FontSelectPattern&, + LogicalFontInstance* pLogicalFont, + OUString& rMissingCodes) const = 0; +}; + +/** Abstracts the concept of a configured font substitution before the + availability of the originally selected font has been checked. + */ +class PreMatchFontSubstitution : public FontSubstitution +{ +public: + virtual bool FindFontSubstitute(vcl::font::FontSelectPattern&) const = 0; +}; + +void ImplFontSubstitute(OUString& rFontName); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ |