WIP: Optional VFont Char Loading by Glyph ID #116288
|
@ -78,13 +78,25 @@ char *BLF_display_name_from_id(int fontid);
|
|||
*/
|
||||
bool BLF_get_vfont_metrics(int fontid, float *ascend_ratio, float *em_ratio, float *scale);
|
||||
|
||||
typedef struct GlyphData {
|
||||
uint32_t glyphid;
|
||||
uint32_t codepoint;
|
||||
int logical_position;
|
||||
float advance_x;
|
||||
float advance_y;
|
||||
float offset_x;
|
||||
float offset_y;
|
||||
} GlyphData;
|
||||
|
||||
//int BLF_glyph_data(int fontid, const char32_t *str, int len, struct GlyphData **r_glyphs);
|
||||
|
||||
/**
|
||||
* Convert a character's outlines into curves.
|
||||
*/
|
||||
float BLF_character_to_curves(int fontid,
|
||||
unsigned int unicode,
|
||||
struct ListBase *nurbsbase,
|
||||
const float scale);
|
||||
bool BLF_character_to_curves(int fontid,
|
||||
const float scale,
|
||||
struct GlyphData *rw_glyph_data,
|
||||
struct ListBase *nurbsbase);
|
||||
|
||||
/**
|
||||
* Check if font supports a particular glyph.
|
||||
|
|
|
@ -1008,13 +1008,16 @@ bool BLF_get_vfont_metrics(int fontid, float *ascend_ratio, float *em_ratio, flo
|
|||
return true;
|
||||
}
|
||||
|
||||
float BLF_character_to_curves(int fontid, uint unicode, ListBase *nurbsbase, const float scale)
|
||||
bool BLF_character_to_curves(int fontid,
|
||||
const float scale,
|
||||
GlyphData *rw_glyph_data,
|
||||
ListBase *nurbsbase)
|
||||
{
|
||||
FontBLF *font = blf_get(fontid);
|
||||
if (!font) {
|
||||
return 0.0f;
|
||||
return false;
|
||||
}
|
||||
return blf_character_to_curves(font, unicode, nurbsbase, scale);
|
||||
return blf_character_to_curves(font, scale, rw_glyph_data, nurbsbase);
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
|
|
|
@ -1805,11 +1805,16 @@ static void blf_glyph_to_curves(FT_Outline ftoutline, ListBase *nurbsbase, const
|
|||
MEM_freeN(onpoints);
|
||||
}
|
||||
|
||||
static FT_GlyphSlot blf_glyphslot_ensure_outline(FontBLF *font, const uint charcode)
|
||||
static FT_GlyphSlot blf_glyphslot_ensure_outline(FontBLF *font, const uint charcode, const uint glypyid)
|
||||
{
|
||||
/* Glyph might not come from the initial font. */
|
||||
FontBLF *font_with_glyph = font;
|
||||
FT_UInt glyph_index = blf_glyph_index_from_charcode(&font_with_glyph, charcode);
|
||||
|
||||
FT_UInt glyph_index = glypyid;
|
||||
|
||||
if (!glyph_index) {
|
||||
glyph_index = blf_glyph_index_from_charcode(&font_with_glyph, charcode);
|
||||
}
|
||||
|
||||
if (!blf_ensure_face(font_with_glyph)) {
|
||||
return nullptr;
|
||||
|
@ -1831,15 +1836,27 @@ static FT_GlyphSlot blf_glyphslot_ensure_outline(FontBLF *font, const uint charc
|
|||
return glyph;
|
||||
}
|
||||
|
||||
float blf_character_to_curves(FontBLF *font, uint unicode, ListBase *nurbsbase, const float scale)
|
||||
bool blf_character_to_curves(FontBLF *font,
|
||||
const float scale,
|
||||
GlyphData *rw_glyph_data,
|
||||
ListBase *nurbsbase)
|
||||
|
||||
{
|
||||
FT_GlyphSlot glyph = blf_glyphslot_ensure_outline(font, unicode);
|
||||
FT_GlyphSlot glyph = blf_glyphslot_ensure_outline(
|
||||
font, rw_glyph_data->codepoint, rw_glyph_data->glyphid);
|
||||
if (!glyph) {
|
||||
return 0.0f;
|
||||
return false;
|
||||
}
|
||||
|
||||
blf_glyph_to_curves(glyph->outline, nurbsbase, scale);
|
||||
return float(glyph->advance.x) * scale;
|
||||
|
||||
rw_glyph_data->glyphid = glyph->glyph_index;
|
||||
rw_glyph_data->advance_x = float(glyph->advance.x) * scale;
|
||||
rw_glyph_data->advance_y = float(glyph->advance.y) * scale;
|
||||
rw_glyph_data->offset_x = 0.0f;
|
||||
rw_glyph_data->offset_y = 0.0f;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -189,10 +189,10 @@ struct GlyphBLF *blf_glyph_ensure_subpixel(struct FontBLF *font,
|
|||
/**
|
||||
* Convert a character's outlines into curves.
|
||||
*/
|
||||
float blf_character_to_curves(FontBLF *font,
|
||||
unsigned int unicode,
|
||||
struct ListBase *nurbsbase,
|
||||
const float scale);
|
||||
bool blf_character_to_curves(FontBLF *font,
|
||||
const float scale,
|
||||
struct GlyphData *rw_glyph_data,
|
||||
struct ListBase *nurbsbase);
|
||||
|
||||
void blf_glyph_free(struct GlyphBLF *g);
|
||||
void blf_glyph_draw(
|
||||
|
|
|
@ -110,7 +110,8 @@ int BKE_vfont_cursor_to_text_index(Object *ob, float cursor_location[2]);
|
|||
bool BKE_vfont_to_curve(Object *ob, eEditFontMode mode);
|
||||
void BKE_vfont_build_char(Curve *cu,
|
||||
ListBase *nubase,
|
||||
unsigned int character,
|
||||
uint codepoint,
|
||||
uint glyphid,
|
||||
CharInfo *info,
|
||||
float ofsx,
|
||||
float ofsy,
|
||||
|
|
|
@ -18,6 +18,7 @@ struct VFont;
|
|||
|
||||
struct VFontData {
|
||||
GHash *characters;
|
||||
GHash *glyphs;
|
||||
char name[128];
|
||||
float scale;
|
||||
/* Calculated from the font. */
|
||||
|
@ -27,8 +28,17 @@ struct VFontData {
|
|||
|
||||
struct VChar {
|
||||
ListBase nurbsbase;
|
||||
unsigned int index;
|
||||
float width;
|
||||
/* UTF-32/UCS-4 code unit of the character in the Unicode set. */
|
||||
unsigned int codepoint;
|
||||
/* Index of the character within the current font. */
|
||||
unsigned int glyphid;
|
||||
/* How much the pen is moved after this character is placed. */
|
||||
float advance_x;
|
||||
float advance_y;
|
||||
/* Positional adjustment unrelated to advance. Usually used for centering
|
||||
* typographical marks above previous character when complex shaping. */
|
||||
float offset_x;
|
||||
float offset_y;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -40,5 +50,5 @@ struct VChar {
|
|||
VFontData *BKE_vfontdata_from_freetypefont(PackedFile *pf);
|
||||
VFontData *BKE_vfontdata_copy(const VFontData *vfont_src, int flag);
|
||||
|
||||
VChar *BKE_vfontdata_char_from_freetypefont(VFont *vfont, unsigned long character);
|
||||
VChar *BKE_vfontdata_char_from_freetypefont(VFont *vfont, ulong codepoint, ulong glyphid = 0);
|
||||
VChar *BKE_vfontdata_char_copy(const VChar *vchar_src);
|
||||
|
|
|
@ -196,21 +196,30 @@ void BKE_vfont_free_data(VFont *vfont)
|
|||
GHashIterator gh_iter;
|
||||
GHASH_ITER (gh_iter, vfont->data->characters) {
|
||||
VChar *che = static_cast<VChar *>(BLI_ghashIterator_getValue(&gh_iter));
|
||||
|
||||
while (che->nurbsbase.first) {
|
||||
while (che && che->nurbsbase.first) {
|
||||
Nurb *nu = static_cast<Nurb *>(che->nurbsbase.first);
|
||||
if (nu->bezt) {
|
||||
MEM_freeN(nu->bezt);
|
||||
}
|
||||
MEM_SAFE_FREE(nu->bezt);
|
||||
BLI_freelinkN(&che->nurbsbase, nu);
|
||||
}
|
||||
|
||||
MEM_freeN(che);
|
||||
MEM_SAFE_FREE(che);
|
||||
}
|
||||
|
||||
BLI_ghash_free(vfont->data->characters, nullptr, nullptr);
|
||||
}
|
||||
|
||||
if (vfont->data->glyphs) {
|
||||
GHashIterator gh_iter;
|
||||
GHASH_ITER (gh_iter, vfont->data->glyphs) {
|
||||
VChar *che = static_cast<VChar *>(BLI_ghashIterator_getValue(&gh_iter));
|
||||
while (che && che->nurbsbase.first) {
|
||||
Nurb *nu = static_cast<Nurb *>(che->nurbsbase.first);
|
||||
MEM_SAFE_FREE(nu->bezt);
|
||||
BLI_freelinkN(&che->nurbsbase, nu);
|
||||
}
|
||||
MEM_SAFE_FREE(che);
|
||||
}
|
||||
BLI_ghash_free(vfont->data->glyphs, nullptr, nullptr);
|
||||
}
|
||||
|
||||
MEM_freeN(vfont->data);
|
||||
vfont->data = nullptr;
|
||||
}
|
||||
|
@ -427,9 +436,25 @@ VFont *BKE_vfont_builtin_get()
|
|||
return vfont;
|
||||
}
|
||||
|
||||
static VChar *find_vfont_char(VFontData *vfd, uint character)
|
||||
static VChar *find_vfont_char(VFontData *vfd, uint codepoint, uint glyphid = 0)
|
||||
{
|
||||
return static_cast<VChar *>(BLI_ghash_lookup(vfd->characters, POINTER_FROM_UINT(character)));
|
||||
VChar *che = nullptr;
|
||||
|
||||
if (glyphid) {
|
||||
che = static_cast<VChar *>(BLI_ghash_lookup(vfd->glyphs, POINTER_FROM_UINT(glyphid)));
|
||||
if (che) {
|
||||
return che;
|
||||
}
|
||||
}
|
||||
|
||||
if (codepoint) {
|
||||
che = static_cast<VChar *>(BLI_ghash_lookup(vfd->characters, POINTER_FROM_UINT(codepoint)));
|
||||
if (che) {
|
||||
return che;
|
||||
}
|
||||
}
|
||||
|
||||
return che;
|
||||
}
|
||||
|
||||
static void build_underline(Curve *cu,
|
||||
|
@ -498,7 +523,8 @@ static void build_underline(Curve *cu,
|
|||
|
||||
void BKE_vfont_build_char(Curve *cu,
|
||||
ListBase *nubase,
|
||||
uint character,
|
||||
uint codepoint,
|
||||
uint glyphid,
|
||||
CharInfo *info,
|
||||
float ofsx,
|
||||
float ofsy,
|
||||
|
@ -516,7 +542,7 @@ void BKE_vfont_build_char(Curve *cu,
|
|||
float si = sinf(rot);
|
||||
float co = cosf(rot);
|
||||
|
||||
VChar *che = find_vfont_char(vfd, character);
|
||||
VChar *che = find_vfont_char(vfd, codepoint, glyphid);
|
||||
|
||||
/* Select the glyph data */
|
||||
Nurb *nu1 = nullptr;
|
||||
|
@ -678,10 +704,10 @@ static float char_width(Curve *cu, VChar *che, CharInfo *info)
|
|||
return 0.0f;
|
||||
}
|
||||
if (info->flag & CU_CHINFO_SMALLCAPS_CHECK) {
|
||||
return che->width * cu->smallcaps_scale;
|
||||
return che->advance_x * cu->smallcaps_scale;
|
||||
}
|
||||
|
||||
return che->width;
|
||||
return che->advance_x;
|
||||
}
|
||||
|
||||
static void textbox_scale(TextBox *tb_dst, const TextBox *tb_src, float scale)
|
||||
|
@ -1688,7 +1714,7 @@ static bool vfont_to_curve(Object *ob,
|
|||
}
|
||||
/* We don't want to see any character for '\n'. */
|
||||
if (cha != '\n') {
|
||||
BKE_vfont_build_char(cu, r_nubase, cha, info, ct->xof, ct->yof, ct->rot, i, font_size);
|
||||
BKE_vfont_build_char(cu, r_nubase, cha, 0, info, ct->xof, ct->yof, ct->rot, i, font_size);
|
||||
}
|
||||
|
||||
if ((info->flag & CU_CHINFO_UNDERLINE) && (cha != '\n')) {
|
||||
|
|
|
@ -52,6 +52,7 @@ VFontData *BKE_vfontdata_from_freetypefont(PackedFile *pf)
|
|||
BLF_get_vfont_metrics(fontid, &vfd->ascender, &vfd->em_height, &vfd->scale);
|
||||
|
||||
vfd->characters = BLI_ghash_int_new_ex(__func__, 255);
|
||||
vfd->glyphs = BLI_ghash_int_new_ex(__func__, 255);
|
||||
|
||||
BLF_unload_id(fontid);
|
||||
|
||||
|
@ -71,11 +72,15 @@ VFontData *BKE_vfontdata_copy(const VFontData *vfont_src, const int /*flag*/)
|
|||
vfont_dst->characters = BLI_ghash_copy(
|
||||
vfont_src->characters, nullptr, vfontdata_copy_characters_value_cb);
|
||||
}
|
||||
if (vfont_src->glyphs != nullptr) {
|
||||
vfont_dst->glyphs = BLI_ghash_copy(
|
||||
vfont_src->glyphs, nullptr, vfontdata_copy_characters_value_cb);
|
||||
}
|
||||
|
||||
return vfont_dst;
|
||||
}
|
||||
|
||||
VChar *BKE_vfontdata_char_from_freetypefont(VFont *vfont, ulong character)
|
||||
VChar *BKE_vfontdata_char_from_freetypefont(VFont *vfont, ulong codepoint, ulong glyphid)
|
||||
{
|
||||
if (!vfont) {
|
||||
return nullptr;
|
||||
|
@ -97,14 +102,30 @@ VChar *BKE_vfontdata_char_from_freetypefont(VFont *vfont, ulong character)
|
|||
}
|
||||
|
||||
VChar *che = (VChar *)MEM_callocN(sizeof(VChar), "objfnt_char");
|
||||
che->index = character;
|
||||
|
||||
/* need to set a size for embolden, etc. */
|
||||
BLF_size(font_id, 16);
|
||||
|
||||
che->width = BLF_character_to_curves(font_id, character, &che->nurbsbase, vfont->data->scale);
|
||||
GlyphData glyph_data;
|
||||
glyph_data.codepoint = codepoint;
|
||||
glyph_data.glyphid = glyphid;
|
||||
|
||||
if (BLF_character_to_curves(font_id, vfont->data->scale, &glyph_data, &che->nurbsbase)) {
|
||||
che->codepoint = glyph_data.codepoint;
|
||||
che->glyphid = glyph_data.glyphid;
|
||||
che->advance_x = glyph_data.advance_x;
|
||||
che->advance_y = glyph_data.advance_y;
|
||||
che->offset_x = glyph_data.offset_x;
|
||||
che->offset_y = glyph_data.offset_y;
|
||||
|
||||
if (codepoint) {
|
||||
BLI_ghash_insert(vfont->data->characters, POINTER_FROM_UINT(che->codepoint), che);
|
||||
}
|
||||
else if (che->glyphid) {
|
||||
BLI_ghash_insert(vfont->data->glyphs, POINTER_FROM_UINT(che->glyphid), che);
|
||||
}
|
||||
}
|
||||
|
||||
BLI_ghash_insert(vfont->data->characters, POINTER_FROM_UINT(che->index), che);
|
||||
BLF_unload_id(font_id);
|
||||
return che;
|
||||
}
|
||||
|
|
|
@ -285,7 +285,7 @@ static Map<int, int> create_curve_instances(GeoNodeExecParams ¶ms,
|
|||
CharInfo charinfo = {0};
|
||||
charinfo.mat_nr = 1;
|
||||
|
||||
BKE_vfont_build_char(&cu, &cu.nurb, layout.char_codes[i], &charinfo, 0, 0, 0, i, 1);
|
||||
BKE_vfont_build_char(&cu, &cu.nurb, layout.char_codes[i], 0, &charinfo, 0, 0, 0, i, 1);
|
||||
Curves *curves_id = bke::curve_legacy_to_curves(cu);
|
||||
if (curves_id == nullptr) {
|
||||
if (pivot_required) {
|
||||
|
|
Loading…
Reference in New Issue