BLF: Utility to Wrap a String into Multiple Lines #118436
|
@ -9,7 +9,9 @@
|
|||
#pragma once
|
||||
|
||||
#include "BLI_compiler_attrs.h"
|
||||
Harley marked this conversation as resolved
Outdated
|
||||
#include "BLI_string_ref.hh"
|
||||
#include "BLI_sys_types.h"
|
||||
#include "BLI_vector.hh"
|
||||
|
||||
/* Name of sub-directory inside #BLENDER_DATAFILES that contains font files. */
|
||||
#define BLF_DATAFILES_FONTS_DIR "fonts"
|
||||
|
@ -254,6 +256,10 @@ void BLF_rotation(int fontid, float angle);
|
|||
void BLF_clipping(int fontid, int xmin, int ymin, int xmax, int ymax);
|
||||
void BLF_wordwrap(int fontid, int wrap_width);
|
||||
|
||||
blender::Vector<blender::StringRef> BLF_string_wrap(int fontid,
|
||||
blender::StringRef str,
|
||||
const int max_pixel_width);
|
||||
|
||||
#if BLF_BLUR_ENABLE
|
||||
void BLF_blur(int fontid, int size);
|
||||
#endif
|
||||
|
|
|
@ -935,6 +935,17 @@ void BLF_draw_buffer(int fontid, const char *str, const size_t str_len)
|
|||
BLF_draw_buffer_ex(fontid, str, str_len, nullptr);
|
||||
}
|
||||
|
||||
blender::Vector<blender::StringRef> BLF_string_wrap(int fontid,
|
||||
blender::StringRef str,
|
||||
const int max_pixel_width)
|
||||
{
|
||||
FontBLF *font = blf_get(fontid);
|
||||
Harley marked this conversation as resolved
Hans Goudey
commented
Flip the check and Flip the check and `return {}` inside. It's nice to consistently put error handling at the start of the function
|
||||
if (!font) {
|
||||
return {};
|
||||
}
|
||||
return blf_font_string_wrap(font, str, max_pixel_width);
|
||||
}
|
||||
|
||||
char *BLF_display_name_from_file(const char *filepath)
|
||||
{
|
||||
/* While listing font directories this function can be called simultaneously from a greater
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include "BLI_string_cursor_utf8.h"
|
||||
#include "BLI_string_utf8.h"
|
||||
#include "BLI_threads.h"
|
||||
#include "BLI_vector.hh"
|
||||
|
||||
#include "BLF_api.hh"
|
||||
|
||||
|
@ -1085,6 +1086,7 @@ void blf_str_offset_to_glyph_bounds(FontBLF *font,
|
|||
static void blf_font_wrap_apply(FontBLF *font,
|
||||
const char *str,
|
||||
const size_t str_len,
|
||||
const int max_pixel_width,
|
||||
ResultBLF *r_info,
|
||||
void (*callback)(FontBLF *font,
|
||||
GlyphCacheBLF *gc,
|
||||
|
@ -1109,7 +1111,7 @@ static void blf_font_wrap_apply(FontBLF *font,
|
|||
struct WordWrapVars {
|
||||
ft_pix wrap_width;
|
||||
size_t start, last[2];
|
||||
} wrap = {font->wrap_width != -1 ? ft_pix_from_int(font->wrap_width) : INT_MAX, 0, {0, 0}};
|
||||
} wrap = {max_pixel_width != -1 ? ft_pix_from_int(max_pixel_width) : INT_MAX, 0, {0, 0}};
|
||||
|
||||
// printf("%s wrapping (%d, %d) `%s`:\n", __func__, str_len, strlen(str), str);
|
||||
while ((i < str_len) && str[i]) {
|
||||
|
@ -1198,7 +1200,8 @@ static void blf_font_draw__wrap_cb(FontBLF *font,
|
|||
}
|
||||
void blf_font_draw__wrap(FontBLF *font, const char *str, const size_t str_len, ResultBLF *r_info)
|
||||
{
|
||||
blf_font_wrap_apply(font, str, str_len, r_info, blf_font_draw__wrap_cb, nullptr);
|
||||
blf_font_wrap_apply(
|
||||
font, str, str_len, font->wrap_width, r_info, blf_font_draw__wrap_cb, nullptr);
|
||||
}
|
||||
|
||||
/** Utility for #blf_font_boundbox__wrap. */
|
||||
|
@ -1223,7 +1226,8 @@ void blf_font_boundbox__wrap(
|
|||
box->ymin = 32000;
|
||||
box->ymax = -32000;
|
||||
|
||||
blf_font_wrap_apply(font, str, str_len, r_info, blf_font_boundbox_wrap_cb, box);
|
||||
blf_font_wrap_apply(
|
||||
font, str, str_len, font->wrap_width, r_info, blf_font_boundbox_wrap_cb, box);
|
||||
}
|
||||
|
||||
/** Utility for #blf_font_draw_buffer__wrap. */
|
||||
|
@ -1241,7 +1245,37 @@ void blf_font_draw_buffer__wrap(FontBLF *font,
|
|||
const size_t str_len,
|
||||
ResultBLF *r_info)
|
||||
{
|
||||
blf_font_wrap_apply(font, str, str_len, r_info, blf_font_draw_buffer__wrap_cb, nullptr);
|
||||
blf_font_wrap_apply(
|
||||
font, str, str_len, font->wrap_width, r_info, blf_font_draw_buffer__wrap_cb, nullptr);
|
||||
}
|
||||
|
||||
/** Wrap a blender::StringRef. */
|
||||
static void blf_font_string_wrap_cb(FontBLF * /*font*/,
|
||||
GlyphCacheBLF * /*gc*/,
|
||||
const char *str,
|
||||
const size_t str_len,
|
||||
ft_pix /*pen_y*/,
|
||||
Harley marked this conversation as resolved
Outdated
Hans Goudey
commented
Unused variable Unused variable `pen_y`? and `gc`?
|
||||
void *str_list_ptr)
|
||||
Harley marked this conversation as resolved
Hans Goudey
commented
Just as an example, these two lines do a fair amount of expensive things:
Just as an example, these two lines do a fair amount of expensive things:
- First is the `line` variable. This has to allocate space for `str_len` and copy the characters
- Next is an empty string as the vector increases in size. This is cheap, but worth keeping in mind (
- Finally, putting the sliced string into the vector. Copy assignment allocates new characters for the string in the vector, then copies from `line`. With `std::vector`, `emplace_back` is used to construct the new value in place rather than default constructing it then filling its value with copy assignment. C++ also has `std::move` for this reason: `line` is just temporary data, we can move it into the vector to avoid the copy
|
||||
{
|
||||
blender::Vector<blender::StringRef> *list = static_cast<blender::Vector<blender::StringRef> *>(
|
||||
str_list_ptr);
|
||||
blender::StringRef line(str, str + str_len);
|
||||
list->append(line);
|
||||
}
|
||||
|
||||
Harley marked this conversation as resolved
Outdated
Hans Goudey
commented
To be clear, I meant this should return To be clear, I meant this should return `Vector<StringRef>`. Then this function doesn't need to do any allocation or copying at all. The only requirement is that the lifetime of the input string is at least as long as the lifetime of the output. But that's a nice tradeoff.
|
||||
blender::Vector<blender::StringRef> blf_font_string_wrap(FontBLF *font,
|
||||
blender::StringRef str,
|
||||
int max_pixel_width)
|
||||
{
|
||||
blender::Vector<blender::StringRef> list;
|
||||
blf_font_wrap_apply(font,
|
||||
str.data(),
|
||||
size_t(str.size()),
|
||||
max_pixel_width,
|
||||
nullptr,
|
||||
blf_font_string_wrap_cb,
|
||||
&list);
|
||||
return list;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -8,6 +8,9 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "BLI_string_ref.hh"
|
||||
Harley marked this conversation as resolved
Outdated
Hans Goudey
commented
And here too And here too
|
||||
#include "BLI_vector.hh"
|
||||
|
||||
struct FontBLF;
|
||||
struct GlyphBLF;
|
||||
struct GlyphCacheBLF;
|
||||
|
@ -96,6 +99,10 @@ void blf_font_draw__wrap(struct FontBLF *font,
|
|||
size_t str_len,
|
||||
struct ResultBLF *r_info);
|
||||
|
||||
blender::Vector<blender::StringRef> blf_font_string_wrap(FontBLF *font,
|
||||
blender::StringRef str,
|
||||
int max_pixel_width);
|
||||
Harley marked this conversation as resolved
Outdated
Hans Goudey
commented
`const` is meaningless in declarations for arguments passed by value
|
||||
|
||||
/**
|
||||
Harley marked this conversation as resolved
Outdated
Hans Goudey
commented
`const int` means the same thing as `int` here in the declaration, so typically `const` isn't included here.
|
||||
* Use fixed column width, but an utf8 character may occupy multiple columns.
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue
Unnecessary include now :)