108 if (vfont_dst->
data) {
129 if (vf->
id.
us > 0 || is_undo) {
160 .struct_size =
sizeof(
VFont),
162 .name_plural =
"fonts",
171 .foreach_cache =
NULL,
176 .blend_read_lib =
NULL,
177 .blend_read_expand =
NULL,
179 .blend_read_undo_preserve =
NULL,
181 .lib_override_apply_post =
NULL,
416 for (vfont =
G_MAIN->fonts.first; vfont; vfont = vfont->
id.
next) {
437 const float font_size)
473 for (
int i = nu2->
pntsu; i > 0; i--) {
476 float x = fp[0] - rect->
xmin;
477 float y = fp[1] - rect->
ymin;
479 fp[0] = (+co *
x + si *
y) + rect->
xmin;
480 fp[1] = (-si *
x + co *
y) + rect->
ymin;
496 unsigned int character,
510 float shear = cu->
shear;
530 memcpy(nu2, nu1,
sizeof(
struct Nurb));
551 memcpy(bezt2, bezt1, u *
sizeof(
struct BezTriple));
557 for (
int i = nu2->
pntsu; i > 0; i--) {
558 bezt2->
vec[0][0] += shear * bezt2->
vec[0][1];
559 bezt2->
vec[1][0] += shear * bezt2->
vec[1][1];
560 bezt2->
vec[2][0] += shear * bezt2->
vec[2][1];
566 for (
int i = nu2->
pntsu; i > 0; i--) {
567 float *fp = bezt2->
vec[0];
570 fp[0] = co *
x + si * fp[1];
571 fp[1] = -si *
x + co * fp[1];
573 fp[3] = co *
x + si * fp[4];
574 fp[4] = -si *
x + co * fp[4];
576 fp[6] = co *
x + si * fp[7];
577 fp[7] = -si *
x + co * fp[7];
586 for (
int i = nu2->
pntsu; i > 0; i--) {
587 float *fp = bezt2->
vec[0];
599 for (
int i = nu2->
pntsu; i > 0; i--) {
600 float *fp = bezt2->
vec[0];
601 fp[0] = (fp[0] + ofsx) * fsize;
602 fp[1] = (fp[1] + ofsy) * fsize;
603 fp[3] = (fp[3] + ofsx) * fsize;
604 fp[4] = (fp[4] + ofsy) * fsize;
605 fp[6] = (fp[6] + ofsx) * fsize;
606 fp[7] = (fp[7] + ofsy) * fsize;
621 int start, end, direction;
647 if (start == end + 1) {
684 tb_dst->
x = tb_src->
x * scale;
685 tb_dst->
y = tb_src->
y * scale;
686 tb_dst->
w = tb_src->
w * scale;
687 tb_dst->
h = tb_src->
h * scale;
738 #define FONT_TO_CURVE_SCALE_ITERATIONS 20
739 #define FONT_TO_CURVE_SCALE_THRESHOLD 0.0001f
757 #define ASCENT(vfd) ((vfd)->ascender * (vfd)->em_height)
758 #define DESCENT(vfd) ((vfd)->em_height - ASCENT(vfd))
765 const char32_t **r_text,
772 VFont *vfont, *oldvfont;
780 float *f, xof, yof, xtrax, linedist;
781 float twidth = 0, maxlen = 0;
784 int selstart = 0, selend = 0;
785 int cnr = 0, lnr = 0, wsnr = 0;
786 const char32_t *mem =
NULL;
790 const bool word_wrap = iter_data->
word_wrap;
791 const float xof_scale = cu->
xof / font_size;
792 const float yof_scale = cu->
yof / font_size;
795 float current_line_length = 0.0f;
796 float longest_line_length = 0.0f;
801 "TextBox initial char index");
803 #define MARGIN_X_MIN (xof_scale + tb_scale.x)
804 #define MARGIN_Y_MIN (yof_scale + tb_scale.y)
887 use_textbox = (tb_scale.
w != 0.0f);
892 xtrax = 0.5f * cu->
spacing - 0.5f;
896 for (i = 0; i < slen; i++) {
900 for (i = 0; i <= slen; i++) {
903 info = &custrinfo[i];
906 ascii = towupper(ascii);
907 if (mem[i] != ascii) {
918 if (vfont != oldvfont) {
926 chartransdata =
NULL;
931 if (!
ELEM(ascii,
'\n',
'\0')) {
963 if ((tb_scale.
w != 0.0f) && (ct->dobreak == 0)) {
964 const float x_available = xof_scale + tb_scale.
w;
965 const float x_used = (xof - tb_scale.
x) + twidth;
967 if (word_wrap ==
false) {
973 if (x_used > x_available) {
975 "VFontToCurveIter.scale_to_fit not set correctly!");
978 else if (x_used > x_available) {
980 for (j = i; j && (mem[j] !=
'\n') && (chartransdata[j].dobreak == 0); j--) {
981 bool dobreak =
false;
982 if (
ELEM(mem[j],
' ',
'-')) {
984 cnr -= (i - (j - 1));
997 else if (chartransdata[j].dobreak) {
1008 if (tb_scale.
h == 0.0f) {
1018 if (ascii ==
'\n' || ascii == 0 || ct->dobreak) {
1026 lineinfo[lnr].
x_min = (xof - xtrax) - tb_scale.
x;
1027 lineinfo[lnr].
x_max = tb_scale.
w;
1033 if ((tb_scale.
h != 0.0f) && ((-(yof - tb_scale.
y)) > (tb_scale.
h - linedist) - yof_scale)) {
1034 if (cu->
totbox > (curbox + 1)) {
1037 i_textbox_array[curbox] = i + 1;
1043 else if (last_line == -1) {
1044 last_line = lnr + 1;
1051 current_line_length += twidth;
1054 longest_line_length =
MAX2(current_line_length, longest_line_length);
1055 current_line_length = 0.0f;
1060 if (ascii ==
'\n') {
1073 else if (ascii == 9) {
1082 tabfac = 2.0f *
ceilf(tabfac / 2.0f);
1094 if (selboxes && (i >= selstart) && (i <= selend)) {
1095 sb = &selboxes[i - selstart];
1096 sb->
y = yof * font_size - linedist * font_size * 0.1f;
1097 sb->
h = linedist * font_size;
1098 sb->
w = xof * font_size;
1112 xof += (twidth * wsfac * (1.0f + (info->
kern / 40.0f))) + xtrax;
1115 sb->
w = (xof * font_size) - sb->
w;
1121 longest_line_length =
MAX2(current_line_length, longest_line_length);
1124 for (i = 0; i <= slen; i++) {
1126 ct = &chartransdata[i];
1127 if (ascii ==
'\n' || ct->dobreak) {
1140 for (i = 0, li = lineinfo; i < lnr; i++, li++) {
1144 for (i = 0; i <= slen; i++) {
1145 ct->xof += lineinfo[ct->linenr].
x_min;
1152 for (i = 0, li = lineinfo; i < lnr; i++, li++) {
1156 for (i = 0; i <= slen; i++) {
1157 ct->xof += lineinfo[ct->linenr].
x_min;
1164 for (i = 0, li = lineinfo; i < lnr; i++, li++) {
1171 for (i = 0; i <= slen; i++) {
1172 for (j = i; (!
ELEM(mem[j],
'\0',
'\n')) && (chartransdata[j].dobreak == 0) && (j < slen);
1178 ct->xof += ct->charnr * lineinfo[ct->linenr].
x_min;
1184 float curofs = 0.0f;
1185 for (i = 0; i <= slen; i++) {
1186 for (j = i; (mem[j]) && (mem[j] !=
'\n') && (chartransdata[j].
dobreak == 0) && (j < slen);
1191 if ((mem[j] !=
'\n') && ((chartransdata[j].
dobreak != 0))) {
1192 if (mem[i] ==
' ') {
1195 li = &lineinfo[ct->linenr];
1200 if (mem[i] ==
'\n' || chartransdata[i].dobreak) {
1210 if (tb_scale.
h != 0.0f) {
1213 for (
int tb_index = 0; tb_index < cu->
totbox; tb_index++) {
1215 const int i_textbox = i_textbox_array[tb_index];
1216 const int i_textbox_next = i_textbox_array[tb_index + 1];
1217 const bool is_last_filled_textbox =
ELEM(i_textbox_next, 0, slen + 1);
1220 ct_first = chartransdata + i_textbox;
1221 ct_last = chartransdata + (is_last_filled_textbox ? slen : i_textbox_next - 1);
1227 if ((tb_index == cu->
totbox - 1) && (last_line != -1)) {
1228 lines = last_line - ct_first->
linenr;
1234 const float textbox_y_origin = 1.0f;
1241 yoff = textbox_y_origin -
ASCENT(vfd);
1244 yoff = ((((vfd->
em_height + (lines - 1) * linedist) * 0.5f) -
ASCENT(vfd)) -
1245 (tb_scale.
h * 0.5f) + textbox_y_origin);
1248 yoff = textbox_y_origin + ((lines - 1) * linedist) - tb_scale.
h;
1251 yoff = textbox_y_origin + ((lines - 1) * linedist) - tb_scale.
h +
DESCENT(vfd);
1255 for (ct = ct_first; ct <= ct_last; ct++) {
1259 if (is_last_filled_textbox) {
1275 yoff = ((vfd->
em_height + (lnr - 1) * linedist) * 0.5f) -
ASCENT(vfd);
1278 yoff = (lnr - 1) * linedist;
1281 yoff = (lnr - 1) * linedist +
DESCENT(vfd);
1286 for (i = 0; i <= slen; i++) {
1302 float distfac, imat[4][4], imat3[3][3], cmat[3][3];
1304 float timeofs, sizefac;
1319 minx = maxx = ct->
xof;
1321 for (i = 1; i <= slen; i++, ct++) {
1322 if (minx > ct->xof) {
1325 if (maxx < ct->
xof) {
1333 const float chartrans_size_x = maxx - minx;
1334 if (chartrans_size_x != 0.0f) {
1337 distfac = (sizefac * totdist) / chartrans_size_x;
1338 distfac = (distfac > 1.0f) ? (1.0f / distfac) : 1.0f;
1347 if (distfac < 1.0f) {
1351 timeofs = 1.0f - distfac;
1354 timeofs = (1.0f - distfac) / 2.0f;
1361 if (chartrans_size_x != 0.0f) {
1362 distfac /= chartrans_size_x;
1365 timeofs += distfac * cu->
xof;
1368 for (i = 0; i <= slen; i++, ct++) {
1369 float ctime, dtime, vec[4], tvec[4], rotvec[3];
1373 info = &custrinfo[i];
1376 ascii = towupper(ascii);
1383 dtime = distfac * 0.5f * twidth;
1385 ctime = timeofs + distfac * (ct->xof - minx);
1386 CLAMP(ctime, 0.0f, 1.0f);
1402 ct->xof = vec[0] + si *
yof;
1403 ct->yof = vec[1] + co *
yof;
1405 if (selboxes && (i >= selstart) && (i <= selend)) {
1407 sb = &selboxes[i - selstart];
1416 for (i = 0; i <= selend; i++, ct++) {
1417 if (i >= selstart) {
1418 selboxes[i - selstart].
x = ct->xof * font_size;
1419 selboxes[i - selstart].
y = ct->yof * font_size;
1426 ct = &chartransdata[ef->
pos];
1437 lnr = ct->linenr - 1;
1440 lnr = ct->linenr + 1;
1443 lnr = ct->linenr - 10;
1446 lnr = ct->linenr + 10;
1453 for (i = 0; i < slen; i++) {
1454 if (ct->linenr == lnr) {
1455 if ((ct->charnr == cnr) || ((ct + 1)->charnr == 0)) {
1459 else if (ct->linenr > lnr) {
1472 ct = &chartransdata[ef->
pos];
1478 f[0] = font_size * (-0.1f * co + ct->xof);
1479 f[1] = font_size * (0.1f * si + ct->yof);
1481 f[2] = font_size * (0.1f * co + ct->xof);
1482 f[3] = font_size * (-0.1f * si + ct->yof);
1484 f[4] = font_size * (0.1f * co + 0.8f * si + ct->xof);
1485 f[5] = font_size * (-0.1f * si + 0.8f * co + ct->yof);
1487 f[6] = font_size * (-0.1f * co + 0.8f * si + ct->xof);
1488 f[7] = font_size * (0.1f * si + 0.8f * co + ct->yof);
1493 chartransdata =
NULL;
1500 for (i = 0; i < slen; i++) {
1501 unsigned int cha = (
unsigned int)mem[i];
1502 info = &(custrinfo[i]);
1510 cha = towupper(cha);
1522 buildchar(cu, r_nubase, cha, info, ct->xof, ct->yof, ct->rot, i, font_size);
1526 float ulwidth, uloverlap = 0.0f;
1529 if ((i < (slen - 1)) && (mem[i + 1] !=
'\n') &&
1532 uloverlap = xtrax + 0.1f;
1539 ulwidth = (twidth * (1.0f + (info->
kern / 40.0f))) + uloverlap;
1541 rect.
xmin = ct->xof;
1544 rect.
ymin = ct->yof;
1548 cu, r_nubase, &rect, cu->
ulpos - 0.05f, ct->rot, i, info->
mat_nr, font_size);
1562 else if ((tb_scale.
h == 0.0f) && (tb_scale.
w == 0.0f)) {
1566 if ((cu->
totbox == 1) && ((tb_scale.
w == 0.0f) || (tb_scale.
h == 0.0f))) {
1568 if (tb_scale.
w == 0.0f) {
1571 if ((last_line != -1) && (lnr > last_line)) {
1572 const float total_text_height = lnr * linedist;
1578 else if (tb_scale.
h == 0.0f) {
1580 if (longest_line_length > tb_scale.
w) {
1582 float scale_to_fit = tb_scale.
w / longest_line_length;
1601 for (
int tb_index = 0; tb_index <= curbox; tb_index++) {
1603 if ((tb->
w == 0.0f) || (tb->
h == 0.0f)) {
1609 if (valid && (last_line != -1) && (lnr > last_line)) {
1610 const float total_text_height = lnr * linedist;
1611 float scale_to_fit = tb_scale.
h / total_text_height;
1625 if ((last_line != -1) && (lnr > last_line)) {
1656 if (r_nubase !=
NULL) {
1660 if (chartransdata !=
NULL) {
1675 *r_text_free = (ef ==
NULL);
1683 if (chartransdata) {
1684 if (ok && r_chartransdata) {
1685 *r_chartransdata = chartransdata;
1708 const char32_t **r_text,
1715 .scale_to_fit = 1.0f,
1723 ob, cu, mode, &
data, r_nubase, r_text, r_text_len, r_text_free, r_chartransdata);
1729 #undef FONT_TO_CURVE_SCALE_ITERATIONS
1730 #undef FONT_TO_CURVE_SCALE_THRESHOLD
1788 memcpy(text, text_buf,
len *
sizeof(*text));
1802 size_t *r_len_utf32)
typedef float(TangentPoint)[2]
bool BKE_where_on_path(const struct Object *ob, float ctime, float r_vec[4], float r_dir[3], float r_quat[4], float *r_radius, float *r_weight)
float BKE_anim_path_get_length(const struct CurveCache *curve_cache)
void BKE_nurbList_free(struct ListBase *lb)
@ IDTYPE_FLAGS_NO_ANIMDATA
@ LIB_ID_CREATE_NO_USER_REFCOUNT
void * BKE_libblock_alloc(struct Main *bmain, short type, const char *name, const int flag) ATTR_WARN_UNUSED_RESULT
void id_us_plus(struct ID *id)
void BKE_id_blend_write(struct BlendWriter *writer, struct ID *id)
const char * BKE_main_blendfile_path(const struct Main *bmain) ATTR_NONNULL()
struct PackedFile * BKE_packedfile_new_from_memory(void *mem, int memlen)
struct PackedFile * BKE_packedfile_duplicate(const struct PackedFile *pf_src)
void BKE_packedfile_blend_write(struct BlendWriter *writer, struct PackedFile *pf)
struct PackedFile * BKE_packedfile_new(struct ReportList *reports, const char *filename, const char *basepath)
void BKE_packedfile_blend_read(struct BlendDataReader *reader, struct PackedFile **pf_p)
void BKE_packedfile_free(struct PackedFile *pf)
BLI_INLINE void * BLI_ghashIterator_getValue(GHashIterator *ghi) ATTR_WARN_UNUSED_RESULT
#define GHASH_ITER(gh_iter_, ghash_)
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
void * BLI_ghash_lookup(GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
void BLI_freelinkN(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
MINLINE int compare_ff_relative(float a, float b, const float max_diff, const int max_ulps)
void copy_m3_m4(float m1[3][3], const float m2[4][4])
void unit_m4(float m[4][4])
bool invert_m4_m4(float R[4][4], const float A[4][4])
void mul_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3])
MINLINE void copy_v4_fl4(float v[4], float x, float y, float z, float w)
MINLINE float normalize_v3(float r[3])
MINLINE void mul_v2_fl(float r[2], float f)
MINLINE void mul_v3_fl(float r[3], float f)
void BLI_split_file_part(const char *string, char *file, const size_t filelen)
bool BLI_path_abs(char *path, const char *basepath) ATTR_NONNULL()
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy) ATTR_NONNULL()
size_t BLI_str_utf32_as_utf8_len(const char32_t *src) ATTR_NONNULL()
size_t BLI_str_utf8_as_utf32(char32_t *__restrict dst_w, const char *__restrict src_c, const size_t maxncpy) ATTR_NONNULL()
pthread_rwlock_t ThreadRWMutex
#define THREAD_LOCK_WRITE
#define BLI_RWLOCK_INITIALIZER
void BLI_rw_mutex_lock(ThreadRWMutex *mutex, int mode)
void BLI_rw_mutex_unlock(ThreadRWMutex *mutex)
#define POINTER_FROM_UINT(i)
A structure to represent vector fonts, and to load them from PostScript fonts.
VFontData * BLI_vfontdata_from_freetypefont(struct PackedFile *pf)
VFontData * BLI_vfontdata_copy(const VFontData *vfont_src, const int flag)
VChar * BLI_vfontchar_from_freetypefont(struct VFont *vfont, unsigned long character)
#define BLO_write_id_struct(writer, struct_name, id_address, id)
bool BLO_write_is_undo(BlendWriter *writer)
#define BLT_I18NCONTEXT_ID_VFONT
#define CLOG_ERROR(clg_ref,...)
#define CLOG_WARN(clg_ref,...)
#define ID_BLEND_PATH_FROM_GLOBAL(_id)
#define ID_BLEND_PATH(_bmain, _id)
#define ID_IS_OVERRIDE_LIBRARY(_id)
@ CU_ALIGN_Y_BOTTOM_BASELINE
@ CU_ALIGN_Y_TOP_BASELINE
@ CU_CHINFO_SMALLCAPS_CHECK
Object is a sort of wrapper for general info.
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
Read Guarded memory(de)allocation.
static void init_data(ModifierData *md)
Group RGB to Bright Vector Camera CLAMP
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
bool BKE_vfont_is_builtin(struct VFont *vfont)
static PackedFile * get_builtin_packedfile(void)
void BKE_vfont_builtin_register(void *mem, int size)
VFont * BKE_vfont_load_exists(struct Main *bmain, const char *filepath)
static void vfont_init_data(ID *id)
VFont * BKE_vfont_load_exists_ex(struct Main *bmain, const char *filepath, bool *r_exists)
void BKE_vfont_select_clamp(Object *ob)
static float char_width(Curve *cu, VChar *che, CharInfo *info)
VFont * BKE_vfont_builtin_get(void)
static int builtin_font_size
bool BKE_vfont_to_curve(Object *ob, int mode)
void BKE_vfont_free_data(struct VFont *vfont)
static void vfont_blend_read_data(BlendDataReader *reader, ID *id)
static VChar * find_vfont_char(VFontData *vfd, unsigned int character)
static void buildchar(Curve *cu, ListBase *nubase, unsigned int character, CharInfo *info, float ofsx, float ofsy, float rot, int charidx, const float fsize)
int BKE_vfont_select_get(Object *ob, int *r_start, int *r_end)
static ThreadRWMutex vfont_rwlock
bool BKE_vfont_to_curve_ex(Object *ob, Curve *cu, int mode, ListBase *r_nubase, const char32_t **r_text, int *r_text_len, bool *r_text_free, struct CharTrans **r_chartransdata)
static VFont * which_vfont(Curve *cu, CharInfo *info)
static struct @88 g_vfont_clipboard
static void build_underline(Curve *cu, ListBase *nubase, const rctf *rect, float yofs, float rot, int charidx, short mat_nr, const float font_size)
void BKE_vfont_clipboard_set(const char32_t *text_buf, const CharInfo *info_buf, const size_t len)
VFont * BKE_vfont_load(Main *bmain, const char *filepath)
static VFontData * vfont_get_data(VFont *vfont)
@ VFONT_TO_CURVE_SCALE_ONCE
#define FONT_TO_CURVE_SCALE_THRESHOLD
static void vfont_blend_write(BlendWriter *writer, ID *id, const void *id_address)
void BKE_vfont_clipboard_get(char32_t **r_text_buf, CharInfo **r_info_buf, size_t *r_len_utf8, size_t *r_len_utf32)
static bool vfont_to_curve(Object *ob, Curve *cu, int mode, VFontToCurveIter *iter_data, ListBase *r_nubase, const char32_t **r_text, int *r_text_len, bool *r_text_free, struct CharTrans **r_chartransdata)
struct VFontToCurveIter VFontToCurveIter
bool BKE_vfont_to_curve_nubase(Object *ob, int mode, ListBase *r_nubase)
#define FONT_TO_CURVE_SCALE_ITERATIONS
void BKE_vfont_clipboard_free(void)
static void * builtin_font_data
static void textbox_scale(TextBox *tb_dst, const TextBox *tb_src, float scale)
static void vfont_free_data(ID *id)
static void vfont_copy_data(Main *UNUSED(bmain), ID *id_dst, const ID *UNUSED(id_src), const int flag)
#define pf(_x, _i)
Prefetch 64.
void *(* MEM_malloc_arrayN)(size_t len, size_t size, const char *str)
void(* MEM_freeN)(void *vmemh)
void *(* MEM_calloc_arrayN)(size_t len, size_t size, const char *str)
void *(* MEM_callocN)(size_t len, const char *str)
void *(* MEM_mallocN)(size_t len, const char *str)
const float * anim_path_accum_length
struct EditFont * editfont
struct CharInfo * strinfo
struct Object * textoncurve
EditFontSelBox * selboxes
struct CharInfo * textbufinfo
struct CurveCache * curve_cache
struct GHash * characters
struct VFontToCurveIter::@89 bisect
struct PackedFile * temp_pf
struct PackedFile * packedfile