1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
22 #include <sal/config.h>
24 #include <basegfx/polygon/b2dpolypolygon.hxx>
25 #include <o3tl/hash_combine.hxx>
26 #include <rtl/ref.hxx>
27 #include <salhelper/simplereferenceobject.hxx>
28 #include <tools/gen.hxx>
29 #include <tools/fontenum.hxx>
30 #include <tools/degree.hxx>
32 #include <font/FontSelectPattern.hxx>
33 #include <impfontmetricdata.hxx>
34 #include <glyphid.hxx>
37 #include <unordered_map>
45 constexpr float ARTIFICIAL_ITALIC_MATRIX_XX
= 1 << 16;
46 constexpr float ARTIFICIAL_ITALIC_MATRIX_XY
= (1 << 16) / 3.f
;
47 constexpr float ARTIFICIAL_ITALIC_SKEW
= ARTIFICIAL_ITALIC_MATRIX_XY
/ ARTIFICIAL_ITALIC_MATRIX_XX
;
49 // extend std namespace to add custom hash needed for LogicalFontInstance
53 template <> struct hash
<pair
<sal_UCS4
, FontWeight
>>
55 size_t operator()(const pair
<sal_UCS4
, FontWeight
>& rData
) const
58 o3tl::hash_combine(seed
, rData
.first
);
59 o3tl::hash_combine(seed
, rData
.second
);
65 // TODO: allow sharing of metrics for related fonts
67 class VCL_PLUGIN_PUBLIC LogicalFontInstance
: public salhelper::SimpleReferenceObject
69 // just declaring the factory function doesn't work AKA
70 // friend LogicalFontInstance* PhysicalFontFace::CreateFontInstance(const FontSelectPattern&) const;
71 friend class vcl::font::PhysicalFontFace
;
72 friend class ImplFontCache
;
74 public: // TODO: make data members private
75 virtual ~LogicalFontInstance() override
;
77 ImplFontMetricDataRef mxFontMetric
; // Font attributes
78 const ConvertChar
* mpConversion
; // used e.g. for StarBats->StarSymbol
80 tools::Long mnLineHeight
;
81 Degree10 mnOwnOrientation
; // text angle if lower layers don't rotate text themselves
82 Degree10 mnOrientation
; // text angle in 3600 system
83 bool mbInit
; // true if maFontMetric member is valid
85 void AddFallbackForUnicode(sal_UCS4 cChar
, FontWeight eWeight
, const OUString
& rFontName
,
86 bool bEmbolden
, const ItalicMatrix
& rMatrix
);
87 bool GetFallbackForUnicode(sal_UCS4 cInChar
, FontWeight eInWeight
, OUString
* pOutFontName
,
88 bool* pOutEmbolden
, ItalicMatrix
* pOutItalicMatrix
) const;
89 void IgnoreFallbackForUnicode(sal_UCS4
, FontWeight eWeight
, std::u16string_view rFontName
);
91 inline hb_font_t
* GetHbFont();
92 bool IsGraphiteFont();
93 // NeedOffsetCorrection: Return if the font need offset correction in TTB direction.
94 // nYOffset is the original offset. It is used to check if the correction is necessary.
95 bool NeedOffsetCorrection(sal_Int32 nYOffset
);
96 void SetAverageWidthFactor(double nFactor
) { m_nAveWidthFactor
= std::abs(nFactor
); }
97 double GetAverageWidthFactor() const { return m_nAveWidthFactor
; }
98 const vcl::font::FontSelectPattern
& GetFontSelectPattern() const { return m_aFontSelData
; }
100 const vcl::font::PhysicalFontFace
* GetFontFace() const { return m_pFontFace
.get(); }
101 vcl::font::PhysicalFontFace
* GetFontFace() { return m_pFontFace
.get(); }
102 const ImplFontCache
* GetFontCache() const { return mpFontCache
; }
104 bool GetGlyphBoundRect(sal_GlyphId
, tools::Rectangle
&, bool) const;
105 virtual bool GetGlyphOutline(sal_GlyphId
, basegfx::B2DPolyPolygon
&, bool) const = 0;
106 bool GetGlyphOutlineUntransformed(sal_GlyphId
, basegfx::B2DPolyPolygon
&) const;
108 sal_GlyphId
GetGlyphIndex(uint32_t, uint32_t = 0) const;
110 double GetGlyphWidth(sal_GlyphId
, bool = false, bool = true) const;
112 int GetKashidaWidth() const;
114 void GetScale(double* nXScale
, double* nYScale
) const;
116 bool NeedsArtificialItalic() const;
117 bool NeedsArtificialBold() const;
120 explicit LogicalFontInstance(const vcl::font::PhysicalFontFace
&,
121 const vcl::font::FontSelectPattern
&);
123 virtual bool ImplGetGlyphBoundRect(sal_GlyphId
, tools::Rectangle
&, bool) const = 0;
125 hb_font_t
* InitHbFont();
126 virtual void ImplInitHbFont(hb_font_t
*) {}
129 hb_font_t
* GetHbFontUntransformed() const;
135 ItalicMatrix aItalicMatrix
;
137 // cache of Unicode characters and replacement font names and attributes
138 // TODO: a fallback map can be shared with many other ImplFontEntries
139 // TODO: at least the ones which just differ in orientation, stretching or height
140 typedef ::std::unordered_map
<::std::pair
<sal_UCS4
, FontWeight
>, MapEntry
> UnicodeFallbackList
;
141 UnicodeFallbackList maUnicodeFallbackList
;
142 mutable ImplFontCache
* mpFontCache
;
143 const vcl::font::FontSelectPattern m_aFontSelData
;
144 hb_font_t
* m_pHbFont
;
145 mutable hb_font_t
* m_pHbFontUntransformed
= nullptr;
146 double m_nAveWidthFactor
;
147 rtl::Reference
<vcl::font::PhysicalFontFace
> m_pFontFace
;
148 std::optional
<bool> m_xbIsGraphiteFont
;
150 enum class FontFamilyEnum
156 // The value is initialized and used in NeedOffsetCorrection().
157 std::optional
<FontFamilyEnum
> m_xeFontFamilyEnum
;
159 mutable hb_draw_funcs_t
* m_pHbDrawFuncs
= nullptr;
160 basegfx::B2DPolygon m_aDrawPolygon
;
163 inline hb_font_t
* LogicalFontInstance::GetHbFont()
166 m_pHbFont
= InitHbFont();
170 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */