Refactor: Store BLF Glyphs in blender::Map #118528
|
@ -23,8 +23,6 @@ set(SRC
|
|||
intern/blf_font_default.cc
|
||||
intern/blf_glyph.cc
|
||||
intern/blf_thumbs.cc
|
||||
intern/blf_util.cc
|
||||
|
||||
BLF_api.hh
|
||||
intern/blf_internal.hh
|
||||
intern/blf_internal_types.hh
|
||||
|
|
|
@ -91,7 +91,7 @@ static GlyphCacheBLF *blf_glyph_cache_find(FontBLF *font)
|
|||
|
||||
static GlyphCacheBLF *blf_glyph_cache_new(FontBLF *font)
|
||||
{
|
||||
std::unique_ptr<GlyphCacheBLF> gc = std::make_unique<GlyphCacheBLF>(GlyphCacheBLF{});
|
||||
std::unique_ptr<GlyphCacheBLF> gc = std::make_unique<GlyphCacheBLF>();
|
||||
|
||||
gc->size = font->size;
|
||||
gc->bold = ((font->flags & BLF_BOLD) != 0);
|
||||
|
@ -101,8 +101,6 @@ static GlyphCacheBLF *blf_glyph_cache_new(FontBLF *font)
|
|||
gc->char_width = font->char_width;
|
||||
gc->char_spacing = font->char_spacing;
|
||||
|
||||
memset(gc->bucket, 0, sizeof(gc->bucket));
|
||||
|
||||
blf_ensure_size(font);
|
||||
|
||||
/* Determine ideal fixed-width size for monospaced output. */
|
||||
|
@ -146,11 +144,7 @@ void blf_glyph_cache_release(FontBLF *font)
|
|||
|
||||
GlyphCacheBLF::~GlyphCacheBLF()
|
||||
{
|
||||
for (uint i = 0; i < ARRAY_SIZE(this->bucket); i++) {
|
||||
while (GlyphBLF *g = static_cast<GlyphBLF *>(BLI_pophead(&this->bucket[i]))) {
|
||||
blf_glyph_free(g);
|
||||
}
|
||||
}
|
||||
this->glyphs.clear_and_shrink();
|
||||
if (this->texture) {
|
||||
GPU_texture_free(this->texture);
|
||||
}
|
||||
|
@ -174,12 +168,10 @@ static GlyphBLF *blf_glyph_cache_find_glyph(const GlyphCacheBLF *gc,
|
|||
uint charcode,
|
||||
uint8_t subpixel)
|
||||
{
|
||||
GlyphBLF *g = static_cast<GlyphBLF *>(gc->bucket[blf_hash(charcode << 6 | subpixel)].first);
|
||||
while (g) {
|
||||
if (g->c == charcode && g->subpixel == subpixel) {
|
||||
return g;
|
||||
}
|
||||
g = g->next;
|
||||
const std::unique_ptr<GlyphBLF> *ptr = gc->glyphs.lookup_ptr_as(
|
||||
GlyphCacheKey{charcode, subpixel});
|
||||
if (ptr != nullptr) {
|
||||
return ptr->get();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -231,7 +223,7 @@ static GlyphBLF *blf_glyph_cache_add_glyph(FontBLF *font,
|
|||
FT_UInt glyph_index,
|
||||
uint8_t subpixel)
|
||||
{
|
||||
GlyphBLF *g = (GlyphBLF *)MEM_callocN(sizeof(GlyphBLF), "blf_glyph_get");
|
||||
std::unique_ptr<GlyphBLF> g = std::make_unique<GlyphBLF>();
|
||||
g->c = charcode;
|
||||
g->idx = glyph_index;
|
||||
g->advance_x = (ft_pix)glyph->advance.x;
|
||||
|
@ -344,9 +336,9 @@ static GlyphBLF *blf_glyph_cache_add_glyph(FontBLF *font,
|
|||
}
|
||||
}
|
||||
|
||||
BLI_addhead(&(gc->bucket[blf_hash(g->c << 6 | subpixel)]), g);
|
||||
|
||||
return g;
|
||||
GlyphCacheKey key = {charcode, subpixel};
|
||||
gc->glyphs.add(key, std::move(g));
|
||||
return gc->glyphs.lookup(key).get();
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
@ -1326,12 +1318,11 @@ GlyphBLF *blf_glyph_ensure_subpixel(FontBLF *font, GlyphCacheBLF *gc, GlyphBLF *
|
|||
}
|
||||
#endif
|
||||
|
||||
void blf_glyph_free(GlyphBLF *g)
|
||||
GlyphBLF::~GlyphBLF()
|
||||
{
|
||||
if (g->bitmap) {
|
||||
MEM_freeN(g->bitmap);
|
||||
if (this->bitmap) {
|
||||
MEM_freeN(this->bitmap);
|
||||
}
|
||||
MEM_freeN(g);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -54,8 +54,6 @@ extern struct FontBLF *global_font[BLF_MAX_FONT];
|
|||
void blf_batch_draw_begin(struct FontBLF *font);
|
||||
void blf_batch_draw(void);
|
||||
|
||||
unsigned int blf_next_p2(unsigned int x);
|
||||
unsigned int blf_hash(unsigned int val);
|
||||
/**
|
||||
* Some font have additional file with metrics information,
|
||||
* in general, the extension of the file is: `.afm` or `.pfm`
|
||||
|
@ -200,7 +198,6 @@ float blf_character_to_curves(FontBLF *font,
|
|||
struct ListBase *nurbsbase,
|
||||
const float scale);
|
||||
|
||||
void blf_glyph_free(struct GlyphBLF *g);
|
||||
void blf_glyph_draw(
|
||||
struct FontBLF *font, struct GlyphCacheBLF *gc, struct GlyphBLF *g, int x, int y);
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include <mutex>
|
||||
|
||||
#include "BLI_map.hh"
|
||||
#include "BLI_vector.hh"
|
||||
|
||||
#include "GPU_texture.h"
|
||||
|
@ -116,6 +117,19 @@ struct KerningCacheBLF {
|
|||
int ascii_table[KERNING_CACHE_TABLE_SIZE][KERNING_CACHE_TABLE_SIZE];
|
||||
};
|
||||
|
||||
struct GlyphCacheKey {
|
||||
uint charcode;
|
||||
uint8_t subpixel;
|
||||
friend bool operator==(const GlyphCacheKey &a, const GlyphCacheKey &b)
|
||||
{
|
||||
return a.charcode == b.charcode && a.subpixel == b.subpixel;
|
||||
}
|
||||
uint64_t hash() const
|
||||
{
|
||||
return blender::get_default_hash(charcode, subpixel);
|
||||
Harley marked this conversation as resolved
Outdated
|
||||
}
|
||||
};
|
||||
|
||||
struct GlyphCacheBLF {
|
||||
/** Font size. */
|
||||
float size;
|
||||
|
@ -132,7 +146,7 @@ struct GlyphCacheBLF {
|
|||
int fixed_width;
|
||||
|
||||
/** The glyphs. */
|
||||
ListBase bucket[257];
|
||||
blender::Map<GlyphCacheKey, std::unique_ptr<GlyphBLF>> glyphs;
|
||||
|
||||
/** Texture array, to draw the glyphs. */
|
||||
GPUTexture *texture;
|
||||
|
@ -145,9 +159,6 @@ struct GlyphCacheBLF {
|
|||
};
|
||||
|
||||
struct GlyphBLF {
|
||||
GlyphBLF *next;
|
||||
GlyphBLF *prev;
|
||||
|
||||
/** The character, as UTF-32. */
|
||||
unsigned int c;
|
||||
|
||||
|
@ -192,6 +203,8 @@ struct GlyphBLF {
|
|||
int pos[2];
|
||||
|
||||
GlyphCacheBLF *glyph_cache;
|
||||
|
||||
~GlyphBLF();
|
||||
};
|
||||
|
||||
struct FontBufInfoBLF {
|
||||
|
|
|
@ -1,43 +0,0 @@
|
|||
/* SPDX-FileCopyrightText: 2009 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup blf
|
||||
*
|
||||
* Internal utility API for BLF.
|
||||
*/
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "blf_internal.hh"
|
||||
|
||||
uint blf_next_p2(uint x)
|
||||
{
|
||||
x -= 1;
|
||||
x |= (x >> 16);
|
||||
x |= (x >> 8);
|
||||
x |= (x >> 4);
|
||||
x |= (x >> 2);
|
||||
x |= (x >> 1);
|
||||
x += 1;
|
||||
return x;
|
||||
}
|
||||
|
||||
uint blf_hash(uint val)
|
||||
{
|
||||
uint key;
|
||||
|
||||
key = val;
|
||||
key += ~(key << 16);
|
||||
key ^= (key >> 5);
|
||||
key += (key << 3);
|
||||
key ^= (key >> 13);
|
||||
key += ~(key << 9);
|
||||
key ^= (key >> 17);
|
||||
return key % 257;
|
||||
}
|
Loading…
Reference in New Issue
get_default_hash(charcode, subpixel)
might be more straightforward, unless there's still a reason to use this hashMy hesitancy is mostly about my own unknowns with
get_default_hash
Unicode codepoints max out at U+10FFFF, so with a byte for subpixel I am well within 32-bit integer. But then I see that
DefaultHash
drops the lower four bits of each before multiplying them?DefaultHash
for all integer types is just the value unchanged. Then the two hashes are combined like this:h1 ^ (h2 * 19349669);
My reasoning was more like "just use the default unless we know some reason to do it differently"
I can see the multiples being combined like that. The only part that gives me pause is that each part first goes through a change that looks like it drops 4 bits.
Seems like you're looking at the
DefaultHash
specialization for pointers. For integers it's this:Yup, I sure was. LOL