Merge branch 'blender-v2.83-release'
This commit is contained in:
commit
a8d684d87f
|
@ -37,6 +37,7 @@ extern "C" {
|
|||
struct ColorManagedDisplay;
|
||||
struct ResultBLF;
|
||||
struct rctf;
|
||||
struct rcti;
|
||||
|
||||
int BLF_init(void);
|
||||
void BLF_exit(void);
|
||||
|
@ -115,6 +116,24 @@ void BLF_draw_ascii_ex(int fontid, const char *str, size_t len, struct ResultBLF
|
|||
void BLF_draw_ascii(int fontid, const char *str, size_t len) ATTR_NONNULL(2);
|
||||
int BLF_draw_mono(int fontid, const char *str, size_t len, int cwidth) ATTR_NONNULL(2);
|
||||
|
||||
typedef bool (*BLF_GlyphBoundsFn)(const char *str,
|
||||
const size_t str_ofs,
|
||||
const struct rcti *glyph_bounds,
|
||||
const int glyph_advance_x,
|
||||
void *user_data);
|
||||
|
||||
void BLF_boundbox_foreach_glyph_ex(int fontid,
|
||||
const char *str,
|
||||
size_t len,
|
||||
BLF_GlyphBoundsFn user_fn,
|
||||
void *user_data,
|
||||
struct ResultBLF *r_info) ATTR_NONNULL(2);
|
||||
void BLF_boundbox_foreach_glyph(int fontid,
|
||||
const char *str,
|
||||
size_t len,
|
||||
BLF_GlyphBoundsFn user_fn,
|
||||
void *user_data) ATTR_NONNULL(2);
|
||||
|
||||
/* 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)
|
||||
ATTR_NONNULL(2);
|
||||
|
|
|
@ -682,6 +682,42 @@ int BLF_draw_mono(int fontid, const char *str, size_t len, int cwidth)
|
|||
return columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run \a user_fn for each character, with the bound-box that would be used for drawing.
|
||||
*
|
||||
* \param user_fn: Callback that runs on each glyph, returning false early exits.
|
||||
* \param user_data: User argument passed to \a user_fn.
|
||||
*
|
||||
* \note The font position, clipping, matrix and rotation are not applied.
|
||||
*/
|
||||
void BLF_boundbox_foreach_glyph_ex(int fontid,
|
||||
const char *str,
|
||||
size_t len,
|
||||
BLF_GlyphBoundsFn user_fn,
|
||||
void *user_data,
|
||||
struct ResultBLF *r_info)
|
||||
{
|
||||
FontBLF *font = blf_get(fontid);
|
||||
|
||||
BLF_RESULT_CHECK_INIT(r_info);
|
||||
|
||||
if (font) {
|
||||
if (font->flags & BLF_WORD_WRAP) {
|
||||
/* TODO: word-wrap support. */
|
||||
BLI_assert(0);
|
||||
}
|
||||
else {
|
||||
blf_font_boundbox_foreach_glyph(font, str, len, user_fn, user_data, r_info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BLF_boundbox_foreach_glyph(
|
||||
int fontid, const char *str, size_t len, BLF_GlyphBoundsFn user_fn, void *user_data)
|
||||
{
|
||||
BLF_boundbox_foreach_glyph_ex(fontid, str, len, user_fn, user_data, NULL);
|
||||
}
|
||||
|
||||
size_t BLF_width_to_strlen(int fontid, const char *str, size_t len, float width, float *r_width)
|
||||
{
|
||||
FontBLF *font = blf_get(fontid);
|
||||
|
|
|
@ -1201,6 +1201,84 @@ float blf_font_fixed_width(FontBLF *font)
|
|||
return g->advance;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Glyph Bound Box with Callback
|
||||
* \{ */
|
||||
|
||||
static void blf_font_boundbox_foreach_glyph_ex(FontBLF *font,
|
||||
GlyphCacheBLF *gc,
|
||||
const char *str,
|
||||
size_t len,
|
||||
BLF_GlyphBoundsFn user_fn,
|
||||
void *user_data,
|
||||
struct ResultBLF *r_info,
|
||||
int pen_y)
|
||||
{
|
||||
unsigned int c, c_prev = BLI_UTF8_ERR;
|
||||
GlyphBLF *g, *g_prev = NULL;
|
||||
int pen_x = 0;
|
||||
size_t i = 0, i_curr;
|
||||
rcti gbox;
|
||||
|
||||
if (len == 0) {
|
||||
/* early output. */
|
||||
return;
|
||||
}
|
||||
|
||||
GlyphBLF **glyph_ascii_table = blf_font_ensure_ascii_table(font, gc);
|
||||
|
||||
BLF_KERNING_VARS(font, has_kerning, kern_mode);
|
||||
|
||||
blf_font_ensure_ascii_kerning(font, gc, kern_mode);
|
||||
|
||||
while ((i < len) && str[i]) {
|
||||
i_curr = i;
|
||||
BLF_UTF8_NEXT_FAST(font, gc, g, str, i, c, glyph_ascii_table);
|
||||
|
||||
if (UNLIKELY(c == BLI_UTF8_ERR)) {
|
||||
break;
|
||||
}
|
||||
if (UNLIKELY(g == NULL)) {
|
||||
continue;
|
||||
}
|
||||
if (has_kerning) {
|
||||
BLF_KERNING_STEP_FAST(font, kern_mode, g_prev, g, c_prev, c, pen_x);
|
||||
}
|
||||
|
||||
gbox.xmin = pen_x;
|
||||
gbox.xmax = gbox.xmin + MIN2(g->advance_i, g->width);
|
||||
gbox.ymin = pen_y;
|
||||
gbox.ymax = gbox.ymin - g->height;
|
||||
|
||||
pen_x += g->advance_i;
|
||||
|
||||
if (user_fn(str, i_curr, &gbox, g->advance_i, user_data) == false) {
|
||||
break;
|
||||
}
|
||||
|
||||
g_prev = g;
|
||||
c_prev = c;
|
||||
}
|
||||
|
||||
if (r_info) {
|
||||
r_info->lines = 1;
|
||||
r_info->width = pen_x;
|
||||
}
|
||||
}
|
||||
void blf_font_boundbox_foreach_glyph(FontBLF *font,
|
||||
const char *str,
|
||||
size_t len,
|
||||
BLF_GlyphBoundsFn user_fn,
|
||||
void *user_data,
|
||||
struct ResultBLF *r_info)
|
||||
{
|
||||
GlyphCacheBLF *gc = blf_glyph_cache_acquire(font);
|
||||
blf_font_boundbox_foreach_glyph_ex(font, gc, str, len, user_fn, user_data, r_info, 0);
|
||||
blf_glyph_cache_release(font);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
int blf_font_count_missing_chars(FontBLF *font,
|
||||
const char *str,
|
||||
const size_t len,
|
||||
|
|
|
@ -29,6 +29,7 @@ struct GlyphBLF;
|
|||
struct GlyphCacheBLF;
|
||||
struct ResultBLF;
|
||||
struct rctf;
|
||||
struct rcti;
|
||||
|
||||
void blf_batch_draw_vao_clear(void);
|
||||
void blf_batch_draw_begin(struct FontBLF *font);
|
||||
|
@ -98,6 +99,17 @@ int blf_font_width_max(struct FontBLF *font);
|
|||
float blf_font_descender(struct FontBLF *font);
|
||||
float blf_font_ascender(struct FontBLF *font);
|
||||
|
||||
void blf_font_boundbox_foreach_glyph(struct FontBLF *font,
|
||||
const char *str,
|
||||
size_t len,
|
||||
bool (*user_fn)(const char *str,
|
||||
const size_t str_ofs,
|
||||
const struct rcti *glyph_bounds,
|
||||
const int glyph_advance_x,
|
||||
void *user_data),
|
||||
void *user_data,
|
||||
struct ResultBLF *r_info);
|
||||
|
||||
int blf_font_count_missing_chars(struct FontBLF *font,
|
||||
const char *str,
|
||||
const size_t len,
|
||||
|
|
|
@ -27,10 +27,10 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "blf_internal.h"
|
||||
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "blf_internal.h"
|
||||
|
||||
unsigned int blf_next_p2(unsigned int x)
|
||||
{
|
||||
x -= 1;
|
||||
|
|
|
@ -141,7 +141,6 @@ static bool workbench_in_front_history_needed(WORKBENCH_Data *vedata)
|
|||
WORKBENCH_StorageList *stl = vedata->stl;
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
const View3D *v3d = draw_ctx->v3d;
|
||||
const Object *obact = draw_ctx->obact;
|
||||
|
||||
if (!v3d || (v3d->flag2 & V3D_HIDE_OVERLAYS)) {
|
||||
return false;
|
||||
|
|
|
@ -2094,6 +2094,22 @@ static void widget_draw_text_ime_underline(const uiFontStyle *fstyle,
|
|||
}
|
||||
#endif /* WITH_INPUT_IME */
|
||||
|
||||
static bool widget_draw_text_underline_calc_center_x(const char *UNUSED(str),
|
||||
const size_t str_ofs,
|
||||
const rcti *glyph_bounds,
|
||||
const int glyph_advance_x,
|
||||
void *user_data)
|
||||
{
|
||||
/* The index of the character to get, set to the x-position. */
|
||||
int *ul_data = user_data;
|
||||
if (ul_data[0] == (int)str_ofs) {
|
||||
ul_data[1] = glyph_bounds->xmin + (glyph_advance_x / 2);
|
||||
/* Early exit. */
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void widget_draw_text(const uiFontStyle *fstyle,
|
||||
const uiWidgetColors *wcol,
|
||||
uiBut *but,
|
||||
|
@ -2322,31 +2338,40 @@ static void widget_draw_text(const uiFontStyle *fstyle,
|
|||
NULL);
|
||||
|
||||
if (but->menu_key != '\0') {
|
||||
char fixedbuf[128];
|
||||
const char *str;
|
||||
const char *drawstr_ofs = drawstr + but->ofs;
|
||||
int ul_index = -1;
|
||||
|
||||
BLI_strncpy(fixedbuf, drawstr + but->ofs, min_ii(sizeof(fixedbuf), drawlen));
|
||||
|
||||
str = strchr(fixedbuf, but->menu_key - 32); /* upper case */
|
||||
if (str == NULL) {
|
||||
str = strchr(fixedbuf, but->menu_key);
|
||||
{
|
||||
/* Find upper case, fallback to lower case. */
|
||||
const char *drawstr_end = drawstr_ofs + drawlen;
|
||||
const char keys[] = {but->menu_key - 32, but->menu_key};
|
||||
for (int i = 0; i < ARRAY_SIZE(keys); i++) {
|
||||
const char *drawstr_menu = strchr(drawstr_ofs, keys[i]);
|
||||
if (drawstr_menu != NULL && drawstr_menu < drawstr_end) {
|
||||
ul_index = (int)(drawstr_menu - drawstr_ofs);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (str) {
|
||||
int ul_index = -1;
|
||||
float ul_advance;
|
||||
|
||||
ul_index = (int)(str - fixedbuf);
|
||||
|
||||
if (ul_index != -1) {
|
||||
if (fstyle->kerning == 1) {
|
||||
BLF_enable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
|
||||
}
|
||||
|
||||
fixedbuf[ul_index] = '\0';
|
||||
ul_advance = BLF_width(fstyle->uifont_id, fixedbuf, ul_index) + (1.0f * UI_DPI_FAC);
|
||||
int ul_data[2] = {
|
||||
ul_index, /* Character index to test. */
|
||||
0, /* Write the x-offset here. */
|
||||
};
|
||||
BLF_boundbox_foreach_glyph(fstyle->uifont_id,
|
||||
drawstr_ofs,
|
||||
ul_index + 1,
|
||||
widget_draw_text_underline_calc_center_x,
|
||||
ul_data);
|
||||
ul_data[1] -= BLF_width(fstyle->uifont_id, "_", 2) / 2.0f;
|
||||
|
||||
BLF_position(fstyle->uifont_id,
|
||||
rect->xmin + font_xofs + (int)ul_advance,
|
||||
rect->xmin + font_xofs + ul_data[1],
|
||||
rect->ymin + font_yofs,
|
||||
0.0f);
|
||||
BLF_color4ubv(fstyle->uifont_id, wcol->text);
|
||||
|
|
Loading…
Reference in New Issue