Skip to content

Commit 339ffd2

Browse files
committed
Internals: Renamed ImBoolVector to ImBitVector, added low-level loose function to replicate the behavior include a help SetBitRange() function.
1 parent 1d5612a commit 339ffd2

File tree

4 files changed

+59
-42
lines changed

4 files changed

+59
-42
lines changed

imgui_draw.cpp

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1921,7 +1921,7 @@ struct ImFontBuildSrcData
19211921
int DstIndex; // Index into atlas->Fonts[] and dst_tmp_array[]
19221922
int GlyphsHighest; // Highest requested codepoint
19231923
int GlyphsCount; // Glyph count (excluding missing glyphs and glyphs already set by an earlier source font)
1924-
ImBoolVector GlyphsSet; // Glyph bit map (random access, 1-bit per codepoint. This will be a maximum of 8KB)
1924+
ImBitVector GlyphsSet; // Glyph bit map (random access, 1-bit per codepoint. This will be a maximum of 8KB)
19251925
ImVector<int> GlyphsList; // Glyph codepoints list (flattened version of GlyphsMap)
19261926
};
19271927

@@ -1931,19 +1931,19 @@ struct ImFontBuildDstData
19311931
int SrcCount; // Number of source fonts targeting this destination font.
19321932
int GlyphsHighest;
19331933
int GlyphsCount;
1934-
ImBoolVector GlyphsSet; // This is used to resolve collision when multiple sources are merged into a same destination font.
1934+
ImBitVector GlyphsSet; // This is used to resolve collision when multiple sources are merged into a same destination font.
19351935
};
19361936

1937-
static void UnpackBoolVectorToFlatIndexList(const ImBoolVector* in, ImVector<int>* out)
1937+
static void UnpackBitVectorToFlatIndexList(const ImBitVector* in, ImVector<int>* out)
19381938
{
19391939
IM_ASSERT(sizeof(in->Storage.Data[0]) == sizeof(int));
1940-
const int* it_begin = in->Storage.begin();
1941-
const int* it_end = in->Storage.end();
1942-
for (const int* it = it_begin; it < it_end; it++)
1943-
if (int entries_32 = *it)
1944-
for (int bit_n = 0; bit_n < 32; bit_n++)
1945-
if (entries_32 & (1u << bit_n))
1946-
out->push_back((int)((it - it_begin) << 5) + bit_n);
1940+
const ImU32* it_begin = in->Storage.begin();
1941+
const ImU32* it_end = in->Storage.end();
1942+
for (const ImU32* it = it_begin; it < it_end; it++)
1943+
if (ImU32 entries_32 = *it)
1944+
for (ImU32 bit_n = 0; bit_n < 32; bit_n++)
1945+
if (entries_32 & ((ImU32)1 << bit_n))
1946+
out->push_back((int)(((it - it_begin) << 5) + bit_n));
19471947
}
19481948

19491949
bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
@@ -2004,23 +2004,23 @@ bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
20042004
{
20052005
ImFontBuildSrcData& src_tmp = src_tmp_array[src_i];
20062006
ImFontBuildDstData& dst_tmp = dst_tmp_array[src_tmp.DstIndex];
2007-
src_tmp.GlyphsSet.Resize(src_tmp.GlyphsHighest + 1);
2007+
src_tmp.GlyphsSet.Create(src_tmp.GlyphsHighest + 1);
20082008
if (dst_tmp.GlyphsSet.Storage.empty())
2009-
dst_tmp.GlyphsSet.Resize(dst_tmp.GlyphsHighest + 1);
2009+
dst_tmp.GlyphsSet.Create(dst_tmp.GlyphsHighest + 1);
20102010

20112011
for (const ImWchar* src_range = src_tmp.SrcRanges; src_range[0] && src_range[1]; src_range += 2)
20122012
for (unsigned int codepoint = src_range[0]; codepoint <= src_range[1]; codepoint++)
20132013
{
2014-
if (dst_tmp.GlyphsSet.GetBit(codepoint)) // Don't overwrite existing glyphs. We could make this an option for MergeMode (e.g. MergeOverwrite==true)
2014+
if (dst_tmp.GlyphsSet.TestBit(codepoint)) // Don't overwrite existing glyphs. We could make this an option for MergeMode (e.g. MergeOverwrite==true)
20152015
continue;
20162016
if (!stbtt_FindGlyphIndex(&src_tmp.FontInfo, codepoint)) // It is actually in the font?
20172017
continue;
20182018

20192019
// Add to avail set/counters
20202020
src_tmp.GlyphsCount++;
20212021
dst_tmp.GlyphsCount++;
2022-
src_tmp.GlyphsSet.SetBit(codepoint, true);
2023-
dst_tmp.GlyphsSet.SetBit(codepoint, true);
2022+
src_tmp.GlyphsSet.SetBit(codepoint);
2023+
dst_tmp.GlyphsSet.SetBit(codepoint);
20242024
total_glyphs_count++;
20252025
}
20262026
}
@@ -2030,7 +2030,7 @@ bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
20302030
{
20312031
ImFontBuildSrcData& src_tmp = src_tmp_array[src_i];
20322032
src_tmp.GlyphsList.reserve(src_tmp.GlyphsCount);
2033-
UnpackBoolVectorToFlatIndexList(&src_tmp.GlyphsSet, &src_tmp.GlyphsList);
2033+
UnpackBitVectorToFlatIndexList(&src_tmp.GlyphsSet, &src_tmp.GlyphsList);
20342034
src_tmp.GlyphsSet.Clear();
20352035
IM_ASSERT(src_tmp.GlyphsList.Size == src_tmp.GlyphsCount);
20362036
}

imgui_internal.h

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ Index of this file:
7373
// Forward declarations
7474
//-----------------------------------------------------------------------------
7575

76-
struct ImBoolVector; // Store 1-bit per value
76+
struct ImBitVector; // Store 1-bit per value
7777
struct ImRect; // An axis-aligned rectangle (2 points)
7878
struct ImDrawDataBuilder; // Helper to build a ImDrawData instance
7979
struct ImDrawListSharedData; // Data shared between all ImDrawList instances
@@ -204,7 +204,8 @@ extern IMGUI_API ImGuiContext* GImGui; // Current implicit context pointer
204204
// - Helpers: ImVec2/ImVec4 operators
205205
// - Helpers: Maths
206206
// - Helpers: Geometry
207-
// - Helper: ImBoolVector
207+
// - Helpers: Bit arrays
208+
// - Helper: ImBitVector
208209
// - Helper: ImPool<>
209210
// - Helper: ImChunkStream<>
210211
//-----------------------------------------------------------------------------
@@ -350,16 +351,32 @@ IMGUI_API void ImTriangleBarycentricCoords(const ImVec2& a, const ImVec2&
350351
inline float ImTriangleArea(const ImVec2& a, const ImVec2& b, const ImVec2& c) { return ImFabs((a.x * (b.y - c.y)) + (b.x * (c.y - a.y)) + (c.x * (a.y - b.y))) * 0.5f; }
351352
IMGUI_API ImGuiDir ImGetDirQuadrantFromDelta(float dx, float dy);
352353

353-
// Helper: ImBoolVector
354-
// Store 1-bit per value. Note that Resize() currently clears the whole vector.
355-
struct IMGUI_API ImBoolVector
354+
// Helpers: Bit arrays
355+
inline bool ImBitArrayTestBit(const ImU32* arr, int n) { ImU32 mask = (ImU32)1 << (n & 31); return (arr[n >> 5] & mask) != 0; }
356+
inline void ImBitArrayClearBit(ImU32* arr, int n) { ImU32 mask = (ImU32)1 << (n & 31); arr[n >> 5] &= ~mask; }
357+
inline void ImBitArraySetBit(ImU32* arr, int n) { ImU32 mask = (ImU32)1 << (n & 31); arr[n >> 5] |= mask; }
358+
inline void ImBitArraySetBitRange(ImU32* arr, int n, int n2)
356359
{
357-
ImVector<int> Storage;
358-
ImBoolVector() { }
359-
void Resize(int sz) { Storage.resize((sz + 31) >> 5); memset(Storage.Data, 0, (size_t)Storage.Size * sizeof(Storage.Data[0])); }
360-
void Clear() { Storage.clear(); }
361-
bool GetBit(int n) const { int off = (n >> 5); int mask = 1 << (n & 31); return (Storage[off] & mask) != 0; }
362-
void SetBit(int n, bool v) { int off = (n >> 5); int mask = 1 << (n & 31); if (v) Storage[off] |= mask; else Storage[off] &= ~mask; }
360+
while (n <= n2)
361+
{
362+
int a_mod = (n & 31);
363+
int b_mod = ((n2 >= n + 31) ? 31 : (n2 & 31)) + 1;
364+
ImU32 mask = (ImU32)(((ImU64)1 << b_mod) - 1) & ~(ImU32)(((ImU64)1 << a_mod) - 1);
365+
arr[n >> 5] |= mask;
366+
n = (n + 32) & ~31;
367+
}
368+
}
369+
370+
// Helper: ImBitVector
371+
// Store 1-bit per value.
372+
struct IMGUI_API ImBitVector
373+
{
374+
ImVector<ImU32> Storage;
375+
void Create(int sz) { Storage.resize((sz + 31) >> 5); memset(Storage.Data, 0, (size_t)Storage.Size * sizeof(Storage.Data[0])); }
376+
void Clear() { Storage.clear(); }
377+
bool TestBit(int n) const { IM_ASSERT(n < (Storage.Size << 5)); return ImBitArrayTestBit(Storage.Data, n); }
378+
void SetBit(int n) { IM_ASSERT(n < (Storage.Size << 5)); ImBitArraySetBit(Storage.Data, n); }
379+
void ClearBit(int n) { IM_ASSERT(n < (Storage.Size << 5)); ImBitArrayClearBit(Storage.Data, n); }
363380
};
364381

365382
// Helper: ImPool<>

misc/freetype/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Build font atlases using FreeType instead of stb_truetype (which is the default
55

66
### Usage
77

8-
1. Get latest FreeType binaries or build yourself (under Windows you may use vcpkg with `vcpkg install freetype`).
8+
1. Get latest FreeType binaries or build yourself (under Windows you may use vcpkg with `vcpkg install freetype`, `vcpkg integrate install`).
99
2. Add imgui_freetype.h/cpp alongside your imgui sources.
1010
3. Include imgui_freetype.h after imgui.h.
1111
4. Call `ImGuiFreeType::BuildFontAtlas()` *BEFORE* calling `ImFontAtlas::GetTexDataAsRGBA32()` or `ImFontAtlas::Build()` (so normal Build() won't be called):

misc/freetype/imgui_freetype.cpp

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ struct ImFontBuildSrcDataFT
300300
int DstIndex; // Index into atlas->Fonts[] and dst_tmp_array[]
301301
int GlyphsHighest; // Highest requested codepoint
302302
int GlyphsCount; // Glyph count (excluding missing glyphs and glyphs already set by an earlier source font)
303-
ImBoolVector GlyphsSet; // Glyph bit map (random access, 1-bit per codepoint. This will be a maximum of 8KB)
303+
ImBitVector GlyphsSet; // Glyph bit map (random access, 1-bit per codepoint. This will be a maximum of 8KB)
304304
ImVector<ImFontBuildSrcGlyphFT> GlyphsList;
305305
};
306306

@@ -310,7 +310,7 @@ struct ImFontBuildDstDataFT
310310
int SrcCount; // Number of source fonts targeting this destination font.
311311
int GlyphsHighest;
312312
int GlyphsCount;
313-
ImBoolVector GlyphsSet; // This is used to resolve collision when multiple sources are merged into a same destination font.
313+
ImBitVector GlyphsSet; // This is used to resolve collision when multiple sources are merged into a same destination font.
314314
};
315315

316316
bool ImFontAtlasBuildWithFreeType(FT_Library ft_library, ImFontAtlas* atlas, unsigned int extra_flags)
@@ -370,14 +370,14 @@ bool ImFontAtlasBuildWithFreeType(FT_Library ft_library, ImFontAtlas* atlas, uns
370370
{
371371
ImFontBuildSrcDataFT& src_tmp = src_tmp_array[src_i];
372372
ImFontBuildDstDataFT& dst_tmp = dst_tmp_array[src_tmp.DstIndex];
373-
src_tmp.GlyphsSet.Resize(src_tmp.GlyphsHighest + 1);
373+
src_tmp.GlyphsSet.Create(src_tmp.GlyphsHighest + 1);
374374
if (dst_tmp.GlyphsSet.Storage.empty())
375-
dst_tmp.GlyphsSet.Resize(dst_tmp.GlyphsHighest + 1);
375+
dst_tmp.GlyphsSet.Create(dst_tmp.GlyphsHighest + 1);
376376

377377
for (const ImWchar* src_range = src_tmp.SrcRanges; src_range[0] && src_range[1]; src_range += 2)
378378
for (int codepoint = src_range[0]; codepoint <= src_range[1]; codepoint++)
379379
{
380-
if (dst_tmp.GlyphsSet.GetBit(codepoint)) // Don't overwrite existing glyphs. We could make this an option (e.g. MergeOverwrite)
380+
if (dst_tmp.GlyphsSet.TestBit(codepoint)) // Don't overwrite existing glyphs. We could make this an option (e.g. MergeOverwrite)
381381
continue;
382382
uint32_t glyph_index = FT_Get_Char_Index(src_tmp.Font.Face, codepoint); // It is actually in the font? (FIXME-OPT: We are not storing the glyph_index..)
383383
if (glyph_index == 0)
@@ -386,8 +386,8 @@ bool ImFontAtlasBuildWithFreeType(FT_Library ft_library, ImFontAtlas* atlas, uns
386386
// Add to avail set/counters
387387
src_tmp.GlyphsCount++;
388388
dst_tmp.GlyphsCount++;
389-
src_tmp.GlyphsSet.SetBit(codepoint, true);
390-
dst_tmp.GlyphsSet.SetBit(codepoint, true);
389+
src_tmp.GlyphsSet.SetBit(codepoint);
390+
dst_tmp.GlyphsSet.SetBit(codepoint);
391391
total_glyphs_count++;
392392
}
393393
}
@@ -398,13 +398,13 @@ bool ImFontAtlasBuildWithFreeType(FT_Library ft_library, ImFontAtlas* atlas, uns
398398
ImFontBuildSrcDataFT& src_tmp = src_tmp_array[src_i];
399399
src_tmp.GlyphsList.reserve(src_tmp.GlyphsCount);
400400

401-
IM_ASSERT(sizeof(src_tmp.GlyphsSet.Storage.Data[0]) == sizeof(int));
402-
const int* it_begin = src_tmp.GlyphsSet.Storage.begin();
403-
const int* it_end = src_tmp.GlyphsSet.Storage.end();
404-
for (const int* it = it_begin; it < it_end; it++)
405-
if (int entries_32 = *it)
406-
for (int bit_n = 0; bit_n < 32; bit_n++)
407-
if (entries_32 & (1 << bit_n))
401+
IM_ASSERT(sizeof(src_tmp.GlyphsSet.Storage.Data[0]) == sizeof(ImU32));
402+
const ImU32* it_begin = src_tmp.GlyphsSet.Storage.begin();
403+
const ImU32* it_end = src_tmp.GlyphsSet.Storage.end();
404+
for (const ImU32* it = it_begin; it < it_end; it++)
405+
if (ImU32 entries_32 = *it)
406+
for (ImU32 bit_n = 0; bit_n < 32; bit_n++)
407+
if (entries_32 & ((ImU32)1 << bit_n))
408408
{
409409
ImFontBuildSrcGlyphFT src_glyph;
410410
memset(&src_glyph, 0, sizeof(src_glyph));

0 commit comments

Comments
 (0)