BLF API: Add BLF_width_to_strlen,rstrlen gives a byte offset from a string width
This commit is contained in:
parent
c193dbe30b
commit
ce3f42e16a
|
@ -79,6 +79,11 @@ void BLF_draw(int fontid, const char *str, size_t len);
|
|||
void BLF_draw_ascii(int fontid, const char *str, size_t len);
|
||||
int BLF_draw_mono(int fontid, const char *str, size_t len, int cwidth);
|
||||
|
||||
/* Get the string byte offset that fits within a given width */
|
||||
size_t BLF_width_to_strlen(int fontid, const char *str, size_t len, float width, float *r_width);
|
||||
/* Same as BLF_width_to_strlen but search from the string end */
|
||||
size_t BLF_width_to_rstrlen(int fontid, const char *str, size_t len, float width, float *r_width);
|
||||
|
||||
/* This function return the bounding box of the string
|
||||
* and are not multiplied by the aspect.
|
||||
*/
|
||||
|
|
|
@ -592,6 +592,46 @@ int BLF_draw_mono(int fontid, const char *str, size_t len, int cwidth)
|
|||
return columns;
|
||||
}
|
||||
|
||||
size_t BLF_width_to_strlen(int fontid, const char *str, size_t len, float width, float *r_width)
|
||||
{
|
||||
FontBLF *font = blf_get(fontid);
|
||||
|
||||
if (font) {
|
||||
const float xa = (font->flags & BLF_ASPECT) ? font->aspect[0] : 1.0f;
|
||||
size_t ret;
|
||||
ret = blf_font_width_to_strlen(font, str, len, width / xa, r_width);
|
||||
if (r_width) {
|
||||
*r_width *= xa;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (r_width) {
|
||||
*r_width = 0.0f;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t BLF_width_to_rstrlen(int fontid, const char *str, size_t len, float width, float *r_width)
|
||||
{
|
||||
FontBLF *font = blf_get(fontid);
|
||||
|
||||
if (font) {
|
||||
const float xa = (font->flags & BLF_ASPECT) ? font->aspect[0] : 1.0f;
|
||||
size_t ret;
|
||||
ret = blf_font_width_to_rstrlen(font, str, len, width / xa, r_width);
|
||||
if (r_width) {
|
||||
*r_width *= xa;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (r_width) {
|
||||
*r_width = 0.0f;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void BLF_boundbox(int fontid, const char *str, size_t len, rctf *box)
|
||||
{
|
||||
FontBLF *font = blf_get(fontid);
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
#include "BLI_string.h"
|
||||
#include "BLI_string_utf8.h"
|
||||
#include "BLI_threads.h"
|
||||
#include "BLI_alloca.h"
|
||||
#include "BLI_linklist.h" /* linknode */
|
||||
#include "BLI_strict_flags.h"
|
||||
|
||||
|
@ -415,6 +416,134 @@ void blf_font_buffer(FontBLF *font, const char *str)
|
|||
}
|
||||
}
|
||||
|
||||
size_t blf_font_width_to_strlen(FontBLF *font, const char *str, size_t len, float width, float *r_width)
|
||||
{
|
||||
unsigned int c;
|
||||
GlyphBLF *g, *g_prev = NULL;
|
||||
FT_Vector delta;
|
||||
int pen_x = 0;
|
||||
size_t i = 0, i_prev;
|
||||
GlyphBLF **glyph_ascii_table = font->glyph_cache->glyph_ascii_table;
|
||||
const int width_i = (int)width + 1;
|
||||
int width_new;
|
||||
|
||||
BLF_KERNING_VARS(font, has_kerning, kern_mode);
|
||||
|
||||
blf_font_ensure_ascii_table(font);
|
||||
|
||||
while ((i_prev = i), (width_new = pen_x), ((i < len) && str[i]))
|
||||
{
|
||||
BLF_UTF8_NEXT_FAST(font, g, str, i, c, glyph_ascii_table);
|
||||
|
||||
if (c == BLI_UTF8_ERR)
|
||||
break;
|
||||
if (g == NULL)
|
||||
continue;
|
||||
if (has_kerning)
|
||||
BLF_KERNING_STEP(font, kern_mode, g_prev, g, delta, pen_x);
|
||||
|
||||
pen_x += (int)g->advance;
|
||||
|
||||
if (width_i < pen_x) {
|
||||
break;
|
||||
}
|
||||
|
||||
g_prev = g;
|
||||
}
|
||||
|
||||
if (r_width) {
|
||||
*r_width = (float)width_new;
|
||||
}
|
||||
|
||||
return i_prev;
|
||||
}
|
||||
|
||||
size_t blf_font_width_to_rstrlen(FontBLF *font, const char *str, size_t len, float width, float *r_width)
|
||||
{
|
||||
unsigned int c;
|
||||
GlyphBLF *g, *g_prev = NULL;
|
||||
FT_Vector delta;
|
||||
int pen_x = 0;
|
||||
size_t i = 0, i_prev;
|
||||
GlyphBLF **glyph_ascii_table = font->glyph_cache->glyph_ascii_table;
|
||||
const int width_i = (int)width + 1;
|
||||
int width_new;
|
||||
|
||||
bool is_malloc;
|
||||
int (*width_accum)[2];
|
||||
int width_accum_ofs = 0;
|
||||
|
||||
BLF_KERNING_VARS(font, has_kerning, kern_mode);
|
||||
|
||||
/* skip allocs in simple cases */
|
||||
len = BLI_strnlen(str, len);
|
||||
if (width_i <= 1 || len == 0) {
|
||||
if (r_width) {
|
||||
*r_width = 0.0f;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
if (len < 2048) {
|
||||
width_accum = BLI_array_alloca(width_accum, len);
|
||||
is_malloc = false;
|
||||
}
|
||||
else {
|
||||
width_accum = MEM_mallocN(sizeof(*width_accum) * len, __func__);
|
||||
is_malloc = true;
|
||||
}
|
||||
|
||||
blf_font_ensure_ascii_table(font);
|
||||
|
||||
while ((i < len) && str[i]) {
|
||||
BLF_UTF8_NEXT_FAST(font, g, str, i, c, glyph_ascii_table);
|
||||
|
||||
if (c == BLI_UTF8_ERR)
|
||||
break;
|
||||
if (g == NULL)
|
||||
continue;
|
||||
if (has_kerning)
|
||||
BLF_KERNING_STEP(font, kern_mode, g_prev, g, delta, pen_x);
|
||||
|
||||
pen_x += (int)g->advance;
|
||||
|
||||
width_accum[width_accum_ofs][0] = (int)i;
|
||||
width_accum[width_accum_ofs][1] = pen_x;
|
||||
width_accum_ofs++;
|
||||
|
||||
g_prev = g;
|
||||
}
|
||||
|
||||
if (pen_x > width_i && width_accum_ofs != 0) {
|
||||
const int min_x = pen_x - width_i;
|
||||
|
||||
/* search backwards */
|
||||
width_new = pen_x;
|
||||
while (width_accum_ofs-- > 0) {
|
||||
if (min_x > width_accum[width_accum_ofs][1]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
width_accum_ofs++;
|
||||
width_new = pen_x - width_accum[width_accum_ofs][1];
|
||||
i_prev = (size_t)width_accum[width_accum_ofs][0];
|
||||
}
|
||||
else {
|
||||
width_new = pen_x;
|
||||
i_prev = 0;
|
||||
}
|
||||
|
||||
if (is_malloc) {
|
||||
MEM_freeN(width_accum);
|
||||
}
|
||||
|
||||
if (r_width) {
|
||||
*r_width = (float)width_new;
|
||||
}
|
||||
|
||||
return i_prev;
|
||||
}
|
||||
|
||||
void blf_font_boundbox(FontBLF *font, const char *str, size_t len, rctf *box)
|
||||
{
|
||||
unsigned int c;
|
||||
|
|
|
@ -55,6 +55,8 @@ void blf_font_draw(struct FontBLF *font, const char *str, size_t len);
|
|||
void blf_font_draw_ascii(struct FontBLF *font, const char *str, size_t len);
|
||||
int blf_font_draw_mono(struct FontBLF *font, const char *str, size_t len, int cwidth);
|
||||
void blf_font_buffer(struct FontBLF *font, const char *str);
|
||||
size_t blf_font_width_to_strlen(struct FontBLF *font, const char *str, size_t len, float width, float *r_width);
|
||||
size_t blf_font_width_to_rstrlen(struct FontBLF *font, const char *str, size_t len, float width, float *r_width);
|
||||
void blf_font_boundbox(struct FontBLF *font, const char *str, size_t len, struct rctf *box);
|
||||
void blf_font_width_and_height(struct FontBLF *font, const char *str, size_t len, float *width, float *height);
|
||||
float blf_font_width(struct FontBLF *font, const char *str, size_t len);
|
||||
|
|
Loading…
Reference in New Issue