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 | |
23 | struct BLOTFaceImpl; |
24 | |
25 | // ============================================================================ |
26 | // [Constants] |
27 | // ============================================================================ |
28 | |
29 | static 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). |
37 | static 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. |
47 | static 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 | |
55 | BL_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 | |
64 | BL_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. |
78 | template<typename T> |
79 | class BLFontTableT : public BLFontTable { |
80 | public: |
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 | |
94 | static BL_INLINE bool blFontTableFitsN(const BLFontTable& table, size_t requiredSize, size_t offset = 0) noexcept { |
95 | return (table.size - offset) >= requiredSize; |
96 | } |
97 | |
98 | template<typename T> |
99 | static BL_INLINE bool blFontTableFitsT(const BLFontTable& table, size_t offset = 0) noexcept { |
100 | return blFontTableFitsN(table, T::kMinSize, offset); |
101 | } |
102 | |
103 | static 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 | |
108 | static BL_INLINE BLFontTable blFontSubTableChecked(const BLFontTable& table, size_t offset) noexcept { |
109 | return blFontSubTable(table, blMin(table.size, offset)); |
110 | } |
111 | |
112 | template<typename T> |
113 | static 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 | |
118 | template<typename T> |
119 | static 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 | |
127 | struct 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 | |
181 | BL_HIDDEN extern BLInternalFontFaceFuncs blNullFontFaceFuncs; |
182 | |
183 | struct BLInternalFontFaceImpl : public BLFontFaceImpl { |
184 | BLInternalFontFaceFuncs funcs; |
185 | }; |
186 | |
187 | template<> |
188 | struct BLInternalCastImpl<BLFontFaceImpl> { typedef BLInternalFontFaceImpl Type; }; |
189 | |
190 | // ============================================================================ |
191 | // [BLFont - Internal] |
192 | // ============================================================================ |
193 | |
194 | struct BLInternalFontImpl : public BLFontImpl {}; |
195 | |
196 | template<> |
197 | struct BLInternalCastImpl<BLFontImpl> { typedef BLInternalFontImpl Type; }; |
198 | |
199 | BL_HIDDEN BLResult blFontImplDelete(BLFontImpl* impl_) noexcept; |
200 | |
201 | //! \} |
202 | //! \endcond |
203 | |
204 | #endif // BLEND2D_BLFONT_P_H |
205 | |