Refactoring: Corrections and unifications in mathematics vfont gizmos #107193
|
@ -23,10 +23,14 @@ struct CharTrans {
|
|||
char dobreak;
|
||||
};
|
||||
|
||||
typedef struct EditFontSelBox {
|
||||
float x, y, w, h;
|
||||
/**
|
||||
* Extra gizmo transform for symbol.
|
||||
* */
|
||||
typedef struct EditFontCharExtra {
|
||||
float loc[2];
|
||||
float size[2];
|
||||
float rot;
|
||||
} EditFontSelBox;
|
||||
} EditFontCharExtra;
|
||||
|
||||
/**
|
||||
* Edit data for #Curve (a text curve, with an #Object::type of `OB_FONT`).
|
||||
|
@ -37,9 +41,8 @@ typedef struct EditFont {
|
|||
/** Text style info (aligned with `textbuf`). */
|
||||
struct CharInfo *textbufinfo;
|
||||
|
||||
/** Array of rectangles & rotation. */
|
||||
float textcurs[4][2];
|
||||
EditFontSelBox *selboxes;
|
||||
EditFontCharExtra cursor;
|
||||
EditFontCharExtra *selboxes;
|
||||
int selboxes_len;
|
||||
|
||||
/* Positional vars relative to the `textbuf` (not utf8 bytes)
|
||||
|
|
|
@ -801,7 +801,7 @@ static bool vfont_to_curve(Object *ob,
|
|||
struct CharTrans **r_chartransdata)
|
||||
{
|
||||
EditFont *ef = cu->editfont;
|
||||
EditFontSelBox *selboxes = NULL;
|
||||
EditFontCharExtra *selboxes = NULL;
|
||||
VFont *vfont, *oldvfont;
|
||||
VFontData *vfd = NULL;
|
||||
CharInfo *info = NULL, *custrinfo;
|
||||
|
@ -810,7 +810,7 @@ static bool vfont_to_curve(Object *ob,
|
|||
VChar *che;
|
||||
struct CharTrans *chartransdata = NULL, *ct;
|
||||
struct TempLineInfo *lineinfo;
|
||||
float *f, xof, yof, xtrax, linedist;
|
||||
float xof, yof, xtrax, linedist;
|
||||
float twidth = 0, maxlen = 0;
|
||||
int i, slen, j;
|
||||
int curbox;
|
||||
|
@ -897,7 +897,8 @@ static bool vfont_to_curve(Object *ob,
|
|||
|
||||
if (BKE_vfont_select_get(ob, &selstart, &selend)) {
|
||||
ef->selboxes_len = (selend - selstart) + 1;
|
||||
ef->selboxes = MEM_calloc_arrayN(ef->selboxes_len, sizeof(EditFontSelBox), "font selboxes");
|
||||
ef->selboxes = MEM_calloc_arrayN(
|
||||
ef->selboxes_len, sizeof(EditFontCharExtra), "font selboxes");
|
||||
}
|
||||
else {
|
||||
ef->selboxes_len = 0;
|
||||
|
@ -1112,7 +1113,7 @@ static bool vfont_to_curve(Object *ob,
|
|||
xof = MARGIN_X_MIN + tabfac;
|
||||
}
|
||||
else {
|
||||
EditFontSelBox *sb = NULL;
|
||||
EditFontCharExtra *sb = NULL;
|
||||
float wsfac;
|
||||
|
||||
ct->xof = xof;
|
||||
|
@ -1122,9 +1123,9 @@ static bool vfont_to_curve(Object *ob,
|
|||
|
||||
if (selboxes && (i >= selstart) && (i <= selend)) {
|
||||
sb = &selboxes[i - selstart];
|
||||
sb->y = yof * font_size - linedist * font_size * 0.1f;
|
||||
sb->h = linedist * font_size;
|
||||
sb->w = xof * font_size;
|
||||
sb->loc[1] = yof * font_size - linedist * font_size * 0.1f;
|
||||
sb->size[0] = xof * font_size;
|
||||
sb->size[1] = linedist * font_size;
|
||||
}
|
||||
|
||||
if (ascii == ' ') { /* Space character. */
|
||||
|
@ -1141,7 +1142,7 @@ static bool vfont_to_curve(Object *ob,
|
|||
xof += (twidth * wsfac * (1.0f + (info->kern / 40.0f))) + xtrax;
|
||||
|
||||
if (sb) {
|
||||
sb->w = (xof * font_size) - sb->w;
|
||||
sb->size[0] = (xof * font_size) - sb->size[0];
|
||||
}
|
||||
}
|
||||
ct++;
|
||||
|
@ -1442,22 +1443,30 @@ static bool vfont_to_curve(Object *ob,
|
|||
ct->yof = vec[1] + co * yof;
|
||||
|
||||
if (selboxes && (i >= selstart) && (i <= selend)) {
|
||||
EditFontSelBox *sb;
|
||||
sb = &selboxes[i - selstart];
|
||||
EditFontCharExtra *sb = &selboxes[i - selstart];
|
||||
sb->rot = -ct->rot;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const float descender_downship = 0.25f;
|
||||
|
||||
if (selboxes) {
|
||||
ct = chartransdata;
|
||||
for (i = 0; i <= selend; i++, ct++) {
|
||||
if (i >= selstart) {
|
||||
selboxes[i - selstart].x = ct->xof * font_size;
|
||||
selboxes[i - selstart].y = (ct->yof - 0.25f) * font_size;
|
||||
selboxes[i - selstart].h = font_size;
|
||||
}
|
||||
ct += selstart;
|
||||
for (i = 0; i < ef->selboxes_len; i++, ct++) {
|
||||
|
||||
selboxes[i].size[1] = font_size;
|
||||
|
||||
float centre_offset[2];
|
||||
copy_v2_v2(centre_offset, selboxes[i].size);
|
||||
mul_v2_fl(centre_offset, 1.0f / font_size);
|
||||
mul_v2_fl(centre_offset, 0.5f);
|
||||
centre_offset[1] -= descender_downship;
|
||||
rotate_v2_v2fl(selboxes[i].loc, centre_offset, selboxes[i].rot);
|
||||
add_v2_v2(selboxes[i].loc, &ct->xof);
|
||||
mul_v2_fl(selboxes[i].loc, font_size);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1534,27 +1543,75 @@ static bool vfont_to_curve(Object *ob,
|
|||
}
|
||||
}
|
||||
|
||||
/* Cursor first. */
|
||||
/* Cursor transform. */
|
||||
if (ef) {
|
||||
float si, co;
|
||||
const int cursor_index = ef->pos;
|
||||
const int prev_index = cursor_index != 0 ? cursor_index - 1 : cursor_index;
|
||||
|
||||
ct = &chartransdata[ef->pos];
|
||||
si = sinf(ct->rot);
|
||||
co = cosf(ct->rot);
|
||||
const bool is_line_cap = ELEM(cursor_index, 0, slen) || ELEM(mem[cursor_index], '\n', '\0') ||
|
||||
ELEM(mem[cursor_index - 1], '\n', '\0');
|
||||
const bool is_start_cap = (cursor_index == 0) || ELEM(mem[cursor_index - 1], '\n', '\0');
|
||||
|
||||
f = ef->textcurs[0];
|
||||
const bool is_word_space = !is_line_cap && (mem[prev_index] != ' ') &&
|
||||
(mem[cursor_index] == ' ');
|
||||
const bool is_space_word = !is_line_cap && (mem[prev_index] == ' ') &&
|
||||
(mem[cursor_index] != ' ');
|
||||
|
||||
f[0] = font_size * (-0.02f * co + ct->xof);
|
||||
f[1] = font_size * (0.1f * si - (0.25f * co) + ct->yof);
|
||||
const bool is_between_space_and_word = is_word_space || is_space_word;
|
||||
|
||||
f[2] = font_size * (0.02f * co + ct->xof);
|
||||
f[3] = font_size * (-0.1f * si - (0.25f * co) + ct->yof);
|
||||
/* After or before of selections. Cursor alway related with selection if is exist. */
|
||||
const bool cursor_to_selection = selboxes != NULL;
|
||||
const bool is_before_selection = cursor_index == selstart;
|
||||
|
||||
f[4] = font_size * (0.02f * co + 0.8f * si + ct->xof);
|
||||
f[5] = font_size * (-0.1f * si + 0.75f * co + ct->yof);
|
||||
const float curent_char_rot = -chartransdata[cursor_index].rot;
|
||||
const float prev_char_rot = -chartransdata[prev_index].rot;
|
||||
|
||||
f[6] = font_size * (-0.02f * co + 0.8f * si + ct->xof);
|
||||
f[7] = font_size * (0.1f * si + 0.75f * co + ct->yof);
|
||||
float current_char_loc[2];
|
||||
copy_v2_v2(current_char_loc, &chartransdata[cursor_index].xof);
|
||||
float prev_char_loc[2];
|
||||
copy_v2_v2(prev_char_loc, &chartransdata[prev_index].xof);
|
||||
if (cursor_index != prev_index) {
|
||||
che = find_vfont_char(vfd, mem[prev_index]);
|
||||
info = &custrinfo[prev_index];
|
||||
|
||||
float prev_offset[2];
|
||||
zero_v2(prev_offset);
|
||||
prev_offset[0] = char_width(cu, che, info);
|
||||
float tmp_rotated[2];
|
||||
rotate_v2_v2fl(tmp_rotated, prev_offset, prev_char_rot);
|
||||
add_v2_v2(prev_char_loc, tmp_rotated);
|
||||
}
|
||||
|
||||
float cursor_loc[2];
|
||||
float cursor_centre[2] = {0.0f, 0.5f};
|
||||
cursor_centre[1] -= descender_downship;
|
||||
float cursor_rot = 0.0f;
|
||||
|
||||
/* Default alignment is between previous and current symbol. */
|
||||
float align_factor = 0.5f;
|
||||
if (is_line_cap) {
|
||||
/* Align to start or end of each line. */
|
||||
align_factor = is_start_cap ? 1.0f : 0.0f;
|
||||
}
|
||||
else if (cursor_to_selection) {
|
||||
align_factor = is_before_selection ? 1.0f : 0.0f;
|
||||
}
|
||||
else if (is_between_space_and_word) {
|
||||
/* Align to text, if cursor between regular text and space. */
|
||||
align_factor = is_space_word ? 1.0f : 0.0f;
|
||||
}
|
||||
cursor_rot = slerp_r_r(prev_char_rot, curent_char_rot, align_factor);
|
||||
interp_v2_v2v2(cursor_loc, prev_char_loc, current_char_loc, align_factor);
|
||||
|
||||
rotate_v2_v2fl(ef->cursor.loc, cursor_centre, cursor_rot);
|
||||
add_v2_v2(ef->cursor.loc, cursor_loc);
|
||||
mul_v2_fl(ef->cursor.loc, font_size);
|
||||
|
||||
ef->cursor.size[0] = 0.05f;
|
||||
ef->cursor.size[1] = 1.0f;
|
||||
mul_v2_fl(ef->cursor.size, font_size);
|
||||
|
||||
ef->cursor.rot = cursor_rot;
|
||||
}
|
||||
|
||||
if (mode == FO_SELCHANGE) {
|
||||
|
@ -1787,16 +1844,8 @@ bool BKE_vfont_to_curve_ex(Object *ob,
|
|||
};
|
||||
|
||||
do {
|
||||
data.ok &= vfont_to_curve(ob,
|
||||
cu,
|
||||
mode,
|
||||
&data,
|
||||
NULL,
|
||||
r_nubase,
|
||||
r_text,
|
||||
r_text_len,
|
||||
r_text_free,
|
||||
r_chartransdata);
|
||||
data.ok &= vfont_to_curve(
|
||||
ob, cu, mode, &data, NULL, r_nubase, r_text, r_text_len, r_text_free, r_chartransdata);
|
||||
} while (data.ok && ELEM(data.status, VFONT_TO_CURVE_SCALE_ONCE, VFONT_TO_CURVE_BISECT));
|
||||
|
||||
return data.ok;
|
||||
|
|
|
@ -106,6 +106,7 @@ bool is_zero_qt(const float q[4]);
|
|||
void interp_dot_slerp(float t, float cosom, float r_w[2]);
|
||||
void interp_qt_qtqt(float q[4], const float a[4], const float b[4], float t);
|
||||
void add_qt_qtqt(float q[4], const float a[4], const float b[4], float t);
|
||||
float slerp_r_r(const float r1, const float r2, const float t);
|
||||
|
||||
/* Conversion. */
|
||||
|
||||
|
|
|
@ -898,6 +898,20 @@ void add_qt_qtqt(float q[4], const float a[4], const float b[4], const float t)
|
|||
q[3] = a[3] + t * b[3];
|
||||
}
|
||||
|
||||
float slerp_r_r(const float r1, const float r2, const float t)
|
||||
{
|
||||
const float r1_s = sinf(r1);
|
||||
const float r1_c = cosf(r1);
|
||||
|
||||
const float r2_s = sinf(r2);
|
||||
const float r2_c = cosf(r2);
|
||||
|
||||
const float m_s = r1_s + (r2_s - r1_s) * t;
|
||||
const float m_c = r1_c + (r2_c - r1_c) * t;
|
||||
|
||||
return atan2f(m_s, m_c);
|
||||
}
|
||||
|
||||
void tri_to_quat_ex(
|
||||
float quat[4], const float v1[3], const float v2[3], const float v3[3], const float no_orig[3])
|
||||
{
|
||||
|
|
|
@ -66,61 +66,30 @@ void OVERLAY_edit_text_cache_init(OVERLAY_Data *vedata)
|
|||
}
|
||||
}
|
||||
|
||||
/* Use 2D quad corners to create a matrix that set
|
||||
* a [-1..1] quad at the right position. */
|
||||
static void v2_quad_corners_to_mat4(const float corners[4][2], float r_mat[4][4])
|
||||
static void v2_transform_to_mat4(const float loc[2],
|
||||
const float rot,
|
||||
const float scale[2],
|
||||
float r_mat[4][4])
|
||||
{
|
||||
unit_m4(r_mat);
|
||||
sub_v2_v2v2(r_mat[0], corners[1], corners[0]);
|
||||
sub_v2_v2v2(r_mat[1], corners[3], corners[0]);
|
||||
mul_v2_fl(r_mat[0], 0.5f);
|
||||
mul_v2_fl(r_mat[1], 0.5f);
|
||||
copy_v2_v2(r_mat[3], corners[0]);
|
||||
add_v2_v2(r_mat[3], r_mat[0]);
|
||||
add_v2_v2(r_mat[3], r_mat[1]);
|
||||
const float loc_v3[3] = {loc[0], loc[1], 0.0f};
|
||||
const float rot_v3[3] = {0.0f, 0.0f, rot};
|
||||
float size_v3[3] = {scale[0], scale[1], 0.0f};
|
||||
mul_v3_fl(size_v3, 0.5f);
|
||||
loc_eul_size_to_mat4(r_mat, loc_v3, rot_v3, size_v3);
|
||||
}
|
||||
|
||||
static void edit_text_cache_populate_select(OVERLAY_Data *vedata, Object *ob)
|
||||
{
|
||||
OVERLAY_PrivateData *pd = vedata->stl->pd;
|
||||
const Curve *cu = static_cast<Curve *>(ob->data);
|
||||
EditFont *ef = cu->editfont;
|
||||
float final_mat[4][4], box[4][2];
|
||||
EditFont &edit_font = *cu->editfont;
|
||||
struct GPUBatch *geom = DRW_cache_quad_get();
|
||||
|
||||
for (int i = 0; i < ef->selboxes_len; i++) {
|
||||
EditFontSelBox *sb = &ef->selboxes[i];
|
||||
|
||||
float selboxw;
|
||||
if (i + 1 != ef->selboxes_len) {
|
||||
if (ef->selboxes[i + 1].y == sb->y) {
|
||||
selboxw = ef->selboxes[i + 1].x - sb->x;
|
||||
}
|
||||
else {
|
||||
selboxw = sb->w;
|
||||
}
|
||||
}
|
||||
else {
|
||||
selboxw = sb->w;
|
||||
}
|
||||
/* NOTE: v2_quad_corners_to_mat4 don't need the 3rd corner. */
|
||||
if (sb->rot == 0.0f) {
|
||||
copy_v2_fl2(box[0], sb->x, sb->y);
|
||||
copy_v2_fl2(box[1], sb->x + selboxw, sb->y);
|
||||
copy_v2_fl2(box[3], sb->x, sb->y + sb->h);
|
||||
}
|
||||
else {
|
||||
float mat[2][2];
|
||||
angle_to_mat2(mat, sb->rot);
|
||||
copy_v2_fl2(box[0], sb->x, sb->y);
|
||||
mul_v2_v2fl(box[1], mat[0], selboxw);
|
||||
add_v2_v2(box[1], &sb->x);
|
||||
mul_v2_v2fl(box[3], mat[1], sb->h);
|
||||
add_v2_v2(box[3], &sb->x);
|
||||
}
|
||||
v2_quad_corners_to_mat4(box, final_mat);
|
||||
float final_mat[4][4];
|
||||
for (int i = 0; i < edit_font.selboxes_len; i++) {
|
||||
EditFontCharExtra &sb = edit_font.selboxes[i];
|
||||
v2_transform_to_mat4(sb.loc, sb.rot, sb.size, final_mat);
|
||||
mul_m4_m4m4(final_mat, ob->object_to_world, final_mat);
|
||||
|
||||
DRW_shgroup_call_obmat(pd->edit_text_selection_grp, geom, final_mat);
|
||||
}
|
||||
}
|
||||
|
@ -129,11 +98,11 @@ static void edit_text_cache_populate_cursor(OVERLAY_Data *vedata, Object *ob)
|
|||
{
|
||||
OVERLAY_PrivateData *pd = vedata->stl->pd;
|
||||
const Curve *cu = static_cast<Curve *>(ob->data);
|
||||
EditFont *edit_font = cu->editfont;
|
||||
float(*cursor)[2] = edit_font->textcurs;
|
||||
float mat[4][4];
|
||||
EditFont &edit_font = *cu->editfont;
|
||||
EditFontCharExtra &cursor = edit_font.cursor;
|
||||
|
||||
v2_quad_corners_to_mat4(cursor, mat);
|
||||
float mat[4][4];
|
||||
v2_transform_to_mat4(cursor.loc, cursor.rot, cursor.size, mat);
|
||||
mul_m4_m4m4(mat, ob->object_to_world, mat);
|
||||
|
||||
struct GPUBatch *geom = DRW_cache_quad_get();
|
||||
|
|
|
@ -259,13 +259,14 @@ bool view3d_orbit_calc_center(bContext *C, float r_dyn_ofs[3])
|
|||
}
|
||||
else if (ob_act && (ob_act->mode & OB_MODE_EDIT) && (ob_act->type == OB_FONT)) {
|
||||
Curve *cu = static_cast<Curve *>(ob_act_eval->data);
|
||||
EditFont *ef = cu->editfont;
|
||||
EditFont &edit_font = *cu->editfont;
|
||||
EditFontCharExtra &cursor = edit_font.cursor;
|
||||
|
||||
zero_v3(lastofs);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
add_v2_v2(lastofs, ef->textcurs[i]);
|
||||
}
|
||||
mul_v2_fl(lastofs, 1.0f / 4.0f);
|
||||
float centre[3];
|
||||
zero_v3(centre);
|
||||
centre[1] = cursor.size[1] / 2.0f;
|
||||
rotate_v2_v2fl(lastofs, centre, cursor.rot);
|
||||
add_v2_v2(lastofs, cursor.loc);
|
||||
|
||||
mul_m4_v3(ob_act_eval->object_to_world, lastofs);
|
||||
|
||||
|
|
Loading…
Reference in New Issue