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_BLGLYPHBUFFER_P_H
8#define BLEND2D_BLGLYPHBUFFER_P_H
9
10#include "./blapi-internal_p.h"
11#include "./blfont.h"
12#include "./blglyphbuffer.h"
13
14//! \cond INTERNAL
15//! \addtogroup blend2d_internal
16//! \{
17
18// ============================================================================
19// [BLGlyphBuffer - Internal Enums]
20// ============================================================================
21
22enum BLGlyphBufferFlags : uint32_t {
23 //! Glyph-buffer already contains glyph advances.
24 BL_GLYPH_BUFFER_GLYPH_ADVANCES = 0x00000001u,
25 //! Glyph-buffer has a calculated bounding box.
26 BL_GLYPH_BUFFER_BOUNDING_BOX = 0x00000002u
27};
28
29enum BLGlyphBufferEnums : uint32_t {
30 //! Size of either GlyphIdData+GlyphItemData or PlacementData.
31 BL_GLYPH_BUFFER_ANY_ITEM_SIZE = 16,
32
33 BL_GLYPH_BUFFER_INITIAL_CAPACITY = 256,
34 BL_GLYPH_BUFFER_AGGRESIVE_GROWTH = BL_ALLOC_GROW_LIMIT / BL_GLYPH_BUFFER_ANY_ITEM_SIZE,
35};
36
37// ============================================================================
38// [BLGlyphBuffer - Internal Data]
39// ============================================================================
40
41struct BLInternalGlyphBufferImpl : public BLGlyphBufferImpl {
42 uint8_t* buffer[2];
43 size_t capacity[2];
44
45 // Default-constructed data should not be initialized.
46 constexpr BLInternalGlyphBufferImpl() noexcept
47 : BLGlyphBufferImpl {},
48 buffer { nullptr, nullptr },
49 capacity { 0, 0 } {}
50
51 static BLInternalGlyphBufferImpl* create() noexcept {
52 BLInternalGlyphBufferImpl* d = (BLInternalGlyphBufferImpl*)malloc(sizeof(BLInternalGlyphBufferImpl));
53 if (BL_UNLIKELY(!d))
54 return nullptr;
55
56 d->glyphItemData = nullptr;
57 d->placementData = nullptr;
58 d->size = 0;
59 d->glyphRun.glyphIdSize = uint8_t(sizeof(BLGlyphItem));
60 d->glyphRun.placementType = BL_GLYPH_PLACEMENT_TYPE_NONE;
61 d->glyphRun.glyphIdAdvance = int8_t(sizeof(BLGlyphItem));
62 d->glyphRun.placementAdvance = int8_t(sizeof(BLGlyphPlacement));
63 d->flags = 0;
64
65 d->glyphInfoData = nullptr;
66 d->buffer[0] = nullptr;
67 d->buffer[1] = nullptr;
68 d->capacity[0] = 0;
69 d->capacity[1] = 0;
70
71 return d;
72 }
73
74 BL_INLINE void destroy() noexcept {
75 resetBuffers();
76 free(this);
77 }
78
79 BL_INLINE void resetBuffers() noexcept {
80 if (buffer[0]) { free(buffer[0]); buffer[0] = nullptr; }
81 if (buffer[1]) { free(buffer[1]); buffer[1] = nullptr; }
82 }
83
84 BL_INLINE void clear() noexcept {
85 size = 0;
86 glyphRun.placementType = BL_GLYPH_PLACEMENT_TYPE_NONE;
87 glyphRun.flags = 0;
88 placementData = nullptr;
89 getGlyphDataPtrs(0, &glyphItemData, &glyphInfoData);
90 }
91
92 BL_HIDDEN BLResult ensureBuffer(size_t bufferId, size_t copySize, size_t minCapacity) noexcept;
93
94 BL_INLINE BLResult ensurePlacement() noexcept {
95 BL_PROPAGATE(ensureBuffer(1, 0, size));
96 placementData = reinterpret_cast<BLGlyphPlacement*>(buffer[1]);
97 return BL_SUCCESS;
98 }
99
100 BL_INLINE void flip() noexcept {
101 std::swap(buffer[0], buffer[1]);
102 std::swap(capacity[0], capacity[1]);
103 }
104
105 BL_INLINE void getGlyphDataPtrs(size_t bufferId, BLGlyphItem** glyphItemOut, BLGlyphInfo** glyphInfoOut) noexcept {
106 *glyphItemOut = reinterpret_cast<BLGlyphItem*>(buffer[bufferId]);
107 *glyphInfoOut = reinterpret_cast<BLGlyphInfo*>(buffer[bufferId] + capacity[bufferId] * sizeof(BLGlyphItem));
108 }
109};
110
111template<>
112struct BLInternalCastImpl<BLGlyphBufferImpl> { typedef BLInternalGlyphBufferImpl Type; };
113
114static BL_INLINE void blCopyGlyphData(BLGlyphItem* itemDst, BLGlyphInfo* infoDst, const BLGlyphItem* itemSrc, const BLGlyphInfo* infoSrc, size_t n) noexcept {
115 const BLGlyphItem* itemEnd = itemSrc + n;
116 while (itemSrc != itemEnd) {
117 *itemDst++ = *itemSrc++;
118 *infoDst++ = *infoSrc++;
119 }
120}
121
122//! \}
123//! \endcond
124
125#endif // BLEND2D_BLGLYPHBUFFER_P_H
126