1// [Blend2D]
2// 2D Vector Graphics Powered by a JIT Compiler.
3//
4// [License]
5// Zlib - See LICENSE.md file in the package.
6
7#ifndef BLEND2D_BLFONT_P_H
8#define BLEND2D_BLFONT_P_H
9
10#include "./blapi-internal_p.h"
11#include "./blarray_p.h"
12#include "./blfont.h"
13#include "./blmatrix_p.h"
14
15//! \cond INTERNAL
16//! \addtogroup blend2d_internal
17//! \{
18
19// ============================================================================
20// [Forward Declarations]
21// ============================================================================
22
23struct BLOTFaceImpl;
24
25// ============================================================================
26// [Constants]
27// ============================================================================
28
29static constexpr uint32_t BL_FONT_GET_GLYPH_OUTLINE_BUFFER_SIZE = 2048;
30
31// ============================================================================
32// [Utilities]
33// ============================================================================
34
35//! Returns `true` if the given `tag` is valid. A valid tag consists of 4
36//! ASCII characters within [32..126] range (inclusive).
37static BL_INLINE bool blFontTagIsValid(uint32_t tag) noexcept {
38 return (bool)( (((tag - 0x20202020u) & 0xFF000000u) < 0x5F000000u) &
39 (((tag - 0x20202020u) & 0x00FF0000u) < 0x005F0000u) &
40 (((tag - 0x20202020u) & 0x0000FF00u) < 0x00005F00u) &
41 (((tag - 0x20202020u) & 0x000000FFu) < 0x0000005Fu) );
42}
43
44//! Converts `tag` to a null-terminated ASCII string `str`. Characters that are
45//! not printable are replaced by '?' character, thus it's not safe to convert
46//! the output string back to tag if it was invalid.
47static BL_INLINE void blFontTagToAscii(char str[5], uint32_t tag) noexcept {
48 for (size_t i = 0; i < 4; i++, tag <<= 8) {
49 uint32_t c = tag >> 24;
50 str[i] = (c < 32 || c > 127) ? char('?') : char(c);
51 }
52 str[4] = '\0';
53}
54
55BL_INLINE void blFontMatrixMultiply(BLMatrix2D* dst, const BLFontMatrix* a, const BLMatrix2D* b) noexcept {
56 dst->reset(a->m00 * b->m00 + a->m01 * b->m10,
57 a->m00 * b->m01 + a->m01 * b->m11,
58 a->m10 * b->m00 + a->m11 * b->m10,
59 a->m10 * b->m01 + a->m11 * b->m11,
60 b->m20,
61 b->m21);
62}
63
64BL_INLINE void blFontMatrixMultiply(BLMatrix2D* dst, const BLMatrix2D* a, const BLFontMatrix* b) noexcept {
65 dst->reset(a->m00 * b->m00 + a->m01 * b->m10,
66 a->m00 * b->m01 + a->m01 * b->m11,
67 a->m10 * b->m00 + a->m11 * b->m10,
68 a->m10 * b->m01 + a->m11 * b->m11,
69 a->m20 * b->m00 + a->m21 * b->m10,
70 a->m20 * b->m01 + a->m21 * b->m11);
71}
72
73// ============================================================================
74// [BLFontTableT]
75// ============================================================================
76
77//! A convenience class that maps `BLFontTable` to a typed table.
78template<typename T>
79class BLFontTableT : public BLFontTable {
80public:
81 BL_INLINE BLFontTableT() noexcept = default;
82 constexpr BLFontTableT(const BLFontTableT& other) noexcept = default;
83
84 constexpr BLFontTableT(const BLFontTable& other) noexcept
85 : BLFontTable(other) {}
86
87 constexpr BLFontTableT(const uint8_t* data, size_t size) noexcept
88 : BLFontTable { data, size } {}
89
90 BL_INLINE BLFontTableT& operator=(const BLFontTableT& other) noexcept = default;
91 BL_INLINE const T* operator->() const noexcept { return dataAs<T>(); }
92};
93
94static BL_INLINE bool blFontTableFitsN(const BLFontTable& table, size_t requiredSize, size_t offset = 0) noexcept {
95 return (table.size - offset) >= requiredSize;
96}
97
98template<typename T>
99static BL_INLINE bool blFontTableFitsT(const BLFontTable& table, size_t offset = 0) noexcept {
100 return blFontTableFitsN(table, T::kMinSize, offset);
101}
102
103static BL_INLINE BLFontTable blFontSubTable(const BLFontTable& table, size_t offset) noexcept {
104 BL_ASSERT(offset <= table.size);
105 return BLFontTable { table.data + offset, table.size - offset };
106}
107
108static BL_INLINE BLFontTable blFontSubTableChecked(const BLFontTable& table, size_t offset) noexcept {
109 return blFontSubTable(table, blMin(table.size, offset));
110}
111
112template<typename T>
113static BL_INLINE BLFontTableT<T> blFontSubTableT(const BLFontTable& table, size_t offset) noexcept {
114 BL_ASSERT(offset <= table.size);
115 return BLFontTableT<T> { table.data + offset, table.size - offset };
116}
117
118template<typename T>
119static BL_INLINE BLFontTableT<T> blFontSubTableCheckedT(const BLFontTable& table, size_t offset) noexcept {
120 return blFontSubTableT<T>(table, blMin(table.size, offset));
121}
122
123// ============================================================================
124// [BLFontFace - Internal]
125// ============================================================================
126
127struct BLInternalFontFaceFuncs {
128 BLResult (BL_CDECL* mapTextToGlyphs)(
129 const BLFontFaceImpl* impl,
130 BLGlyphItem* itemData,
131 size_t count,
132 BLGlyphMappingState* state) BL_NOEXCEPT;
133
134 BLResult (BL_CDECL* getGlyphBounds)(
135 const BLFontFaceImpl* impl,
136 const BLGlyphId* glyphIdData,
137 intptr_t glyphIdAdvance,
138 BLBoxI* boxes,
139 size_t count) BL_NOEXCEPT;
140
141 BLResult (BL_CDECL* getGlyphAdvances)(
142 const BLFontFaceImpl* impl,
143 const BLGlyphId* glyphIdData,
144 intptr_t glyphIdAdvance,
145 BLGlyphPlacement* placementData,
146 size_t count) BL_NOEXCEPT;
147
148 BLResult (BL_CDECL* applyKern)(
149 const BLFontFaceImpl* faceI,
150 BLGlyphItem* itemData,
151 BLGlyphPlacement* placementData,
152 size_t count) BL_NOEXCEPT;
153
154 BLResult (BL_CDECL* applyGSub)(
155 const BLFontFaceImpl* impl,
156 BLGlyphBuffer* gb,
157 size_t index,
158 BLBitWord lookups) BL_NOEXCEPT;
159
160 BLResult (BL_CDECL* applyGPos)(
161 const BLFontFaceImpl* impl,
162 BLGlyphBuffer* gb,
163 size_t index,
164 BLBitWord lookups) BL_NOEXCEPT;
165
166 BLResult (BL_CDECL* positionGlyphs)(
167 const BLFontFaceImpl* impl,
168 BLGlyphItem* itemData,
169 BLGlyphPlacement* placementData,
170 size_t count) BL_NOEXCEPT;
171
172 BLResult (BL_CDECL* decodeGlyph)(
173 const BLFontFaceImpl* impl,
174 uint32_t glyphId,
175 const BLMatrix2D* userMatrix,
176 BLPath* out,
177 BLMemBuffer* tmpBuffer,
178 BLPathSinkFunc sink, size_t sinkGlyphIndex, void* closure) BL_NOEXCEPT;
179};
180
181BL_HIDDEN extern BLInternalFontFaceFuncs blNullFontFaceFuncs;
182
183struct BLInternalFontFaceImpl : public BLFontFaceImpl {
184 BLInternalFontFaceFuncs funcs;
185};
186
187template<>
188struct BLInternalCastImpl<BLFontFaceImpl> { typedef BLInternalFontFaceImpl Type; };
189
190// ============================================================================
191// [BLFont - Internal]
192// ============================================================================
193
194struct BLInternalFontImpl : public BLFontImpl {};
195
196template<>
197struct BLInternalCastImpl<BLFontImpl> { typedef BLInternalFontImpl Type; };
198
199BL_HIDDEN BLResult blFontImplDelete(BLFontImpl* impl_) noexcept;
200
201//! \}
202//! \endcond
203
204#endif // BLEND2D_BLFONT_P_H
205