Add split caret direction markers. Fix block/overtype caret size.

This commit is contained in:
bruvzg 2022-10-06 14:30:50 +03:00
parent 88309dee4e
commit a750ca7ec1
No known key found for this signature in database
GPG Key ID: 7960FCF39844EC38
3 changed files with 57 additions and 33 deletions

View File

@ -971,7 +971,18 @@ void LineEdit::_notification(int p_what) {
} else { } else {
if (caret.l_caret != Rect2() && caret.l_dir == TextServer::DIRECTION_AUTO) { if (caret.l_caret != Rect2() && caret.l_dir == TextServer::DIRECTION_AUTO) {
// Draw extra marker on top of mid caret. // Draw extra marker on top of mid caret.
Rect2 trect = Rect2(caret.l_caret.position.x - 3 * caret_width, caret.l_caret.position.y, 6 * caret_width, caret_width); Rect2 trect = Rect2(caret.l_caret.position.x - 2.5 * caret_width, caret.l_caret.position.y, 6 * caret_width, caret_width);
trect.position += ofs;
RenderingServer::get_singleton()->canvas_item_add_rect(ci, trect, caret_color);
} else if (caret.l_caret != Rect2() && caret.t_caret != Rect2() && caret.l_dir != caret.t_dir) {
// Draw extra direction marker on top of split caret.
float d = (caret.l_dir == TextServer::DIRECTION_LTR) ? 0.5 : -3;
Rect2 trect = Rect2(caret.l_caret.position.x + d * caret_width, caret.l_caret.position.y + caret.l_caret.size.y - caret_width, 3 * caret_width, caret_width);
trect.position += ofs;
RenderingServer::get_singleton()->canvas_item_add_rect(ci, trect, caret_color);
d = (caret.t_dir == TextServer::DIRECTION_LTR) ? 0.5 : -3;
trect = Rect2(caret.t_caret.position.x + d * caret_width, caret.t_caret.position.y, 3 * caret_width, caret_width);
trect.position += ofs; trect.position += ofs;
RenderingServer::get_singleton()->canvas_item_add_rect(ci, trect, caret_color); RenderingServer::get_singleton()->canvas_item_add_rect(ci, trect, caret_color);
} }

View File

@ -1350,9 +1350,14 @@ void TextEdit::_notification(int p_what) {
draw_rect(ts_caret.t_caret, caret_color, overtype_mode); draw_rect(ts_caret.t_caret, caret_color, overtype_mode);
if (ts_caret.l_caret != Rect2() && ts_caret.l_dir != ts_caret.t_dir) { if (ts_caret.l_caret != Rect2() && ts_caret.l_dir != ts_caret.t_dir) {
// Draw split caret (leading part).
ts_caret.l_caret.position += Vector2(char_margin + ofs_x, ofs_y); ts_caret.l_caret.position += Vector2(char_margin + ofs_x, ofs_y);
ts_caret.l_caret.size.x = caret_width; ts_caret.l_caret.size.x = caret_width;
draw_rect(ts_caret.l_caret, caret_color * Color(1, 1, 1, 0.5)); draw_rect(ts_caret.l_caret, caret_color);
// Draw extra direction marker on top of split caret.
float d = (ts_caret.l_dir == TextServer::DIRECTION_LTR) ? 0.5 : -3;
Rect2 trect = Rect2(ts_caret.l_caret.position.x + d * caret_width, ts_caret.l_caret.position.y + ts_caret.l_caret.size.y - caret_width, 3 * caret_width, caret_width);
RenderingServer::get_singleton()->canvas_item_add_rect(ci, trect, caret_color);
} }
} else { // End of the line. } else { // End of the line.
if (gl_size > 0) { if (gl_size > 0) {
@ -1383,7 +1388,18 @@ void TextEdit::_notification(int p_what) {
// Normal caret. // Normal caret.
if (ts_caret.l_caret != Rect2() && ts_caret.l_dir == TextServer::DIRECTION_AUTO) { if (ts_caret.l_caret != Rect2() && ts_caret.l_dir == TextServer::DIRECTION_AUTO) {
// Draw extra marker on top of mid caret. // Draw extra marker on top of mid caret.
Rect2 trect = Rect2(ts_caret.l_caret.position.x - 3 * caret_width, ts_caret.l_caret.position.y, 6 * caret_width, caret_width); Rect2 trect = Rect2(ts_caret.l_caret.position.x - 2.5 * caret_width, ts_caret.l_caret.position.y, 6 * caret_width, caret_width);
trect.position += Vector2(char_margin + ofs_x, ofs_y);
RenderingServer::get_singleton()->canvas_item_add_rect(ci, trect, caret_color);
} else if (ts_caret.l_caret != Rect2() && ts_caret.t_caret != Rect2() && ts_caret.l_dir != ts_caret.t_dir) {
// Draw extra direction marker on top of split caret.
float d = (ts_caret.l_dir == TextServer::DIRECTION_LTR) ? 0.5 : -3;
Rect2 trect = Rect2(ts_caret.l_caret.position.x + d * caret_width, ts_caret.l_caret.position.y + ts_caret.l_caret.size.y - caret_width, 3 * caret_width, caret_width);
trect.position += Vector2(char_margin + ofs_x, ofs_y);
RenderingServer::get_singleton()->canvas_item_add_rect(ci, trect, caret_color);
d = (ts_caret.t_dir == TextServer::DIRECTION_LTR) ? 0.5 : -3;
trect = Rect2(ts_caret.t_caret.position.x + d * caret_width, ts_caret.t_caret.position.y, 3 * caret_width, caret_width);
trect.position += Vector2(char_margin + ofs_x, ofs_y); trect.position += Vector2(char_margin + ofs_x, ofs_y);
RenderingServer::get_singleton()->canvas_item_add_rect(ci, trect, caret_color); RenderingServer::get_singleton()->canvas_item_add_rect(ci, trect, caret_color);
} }

View File

@ -956,6 +956,11 @@ CaretInfo TextServer::shaped_text_get_carets(const RID &p_shaped, int64_t p_posi
if (glyphs[i].count > 0) { if (glyphs[i].count > 0) {
// Caret before grapheme (top / left). // Caret before grapheme (top / left).
if (p_position == glyphs[i].start && ((glyphs[i].flags & GRAPHEME_IS_VIRTUAL) != GRAPHEME_IS_VIRTUAL)) { if (p_position == glyphs[i].start && ((glyphs[i].flags & GRAPHEME_IS_VIRTUAL) != GRAPHEME_IS_VIRTUAL)) {
real_t advance = 0.f;
for (int j = 0; j < glyphs[i].count; j++) {
advance += glyphs[i + j].advance * glyphs[i + j].repeat;
}
real_t char_adv = advance / (real_t)(glyphs[i].end - glyphs[i].start);
Rect2 cr; Rect2 cr;
if (orientation == ORIENTATION_HORIZONTAL) { if (orientation == ORIENTATION_HORIZONTAL) {
if (glyphs[i].start == range.x) { if (glyphs[i].start == range.x) {
@ -967,15 +972,11 @@ CaretInfo TextServer::shaped_text_get_carets(const RID &p_shaped, int64_t p_posi
cr.position.x = off; cr.position.x = off;
if ((glyphs[i].flags & GRAPHEME_IS_RTL) == GRAPHEME_IS_RTL) { if ((glyphs[i].flags & GRAPHEME_IS_RTL) == GRAPHEME_IS_RTL) {
caret.t_dir = DIRECTION_RTL; caret.t_dir = DIRECTION_RTL;
for (int j = 0; j < glyphs[i].count; j++) { cr.position.x += advance;
cr.position.x += glyphs[i + j].advance * glyphs[i + j].repeat; cr.size.x = -char_adv;
cr.size.x -= glyphs[i + j].advance * glyphs[i + j].repeat;
}
} else { } else {
caret.t_dir = DIRECTION_LTR; caret.t_dir = DIRECTION_LTR;
for (int j = 0; j < glyphs[i].count; j++) { cr.size.x = char_adv;
cr.size.x += glyphs[i + j].advance * glyphs[i + j].repeat;
}
} }
} else { } else {
if (glyphs[i].start == range.x) { if (glyphs[i].start == range.x) {
@ -987,21 +988,22 @@ CaretInfo TextServer::shaped_text_get_carets(const RID &p_shaped, int64_t p_posi
cr.position.y = off; cr.position.y = off;
if ((glyphs[i].flags & GRAPHEME_IS_RTL) == GRAPHEME_IS_RTL) { if ((glyphs[i].flags & GRAPHEME_IS_RTL) == GRAPHEME_IS_RTL) {
caret.t_dir = DIRECTION_RTL; caret.t_dir = DIRECTION_RTL;
for (int j = 0; j < glyphs[i].count; j++) { cr.position.y += advance;
cr.position.y += glyphs[i + j].advance * glyphs[i + j].repeat; cr.size.y = -char_adv;
cr.size.y -= glyphs[i + j].advance * glyphs[i + j].repeat;
}
} else { } else {
caret.t_dir = DIRECTION_LTR; caret.t_dir = DIRECTION_LTR;
for (int j = 0; j < glyphs[i].count; j++) { cr.size.y = char_adv;
cr.size.y += glyphs[i + j].advance * glyphs[i + j].repeat;
}
} }
} }
caret.t_caret = cr; caret.t_caret = cr;
} }
// Caret after grapheme (bottom / right). // Caret after grapheme (bottom / right).
if (p_position == glyphs[i].end && ((glyphs[i].flags & GRAPHEME_IS_VIRTUAL) != GRAPHEME_IS_VIRTUAL)) { if (p_position == glyphs[i].end && ((glyphs[i].flags & GRAPHEME_IS_VIRTUAL) != GRAPHEME_IS_VIRTUAL)) {
real_t advance = 0.f;
for (int j = 0; j < glyphs[i].count; j++) {
advance += glyphs[i + j].advance * glyphs[i + j].repeat;
}
real_t char_adv = advance / (real_t)(glyphs[i].end - glyphs[i].start);
Rect2 cr; Rect2 cr;
if (orientation == ORIENTATION_HORIZONTAL) { if (orientation == ORIENTATION_HORIZONTAL) {
if (glyphs[i].end == range.y) { if (glyphs[i].end == range.y) {
@ -1014,15 +1016,11 @@ CaretInfo TextServer::shaped_text_get_carets(const RID &p_shaped, int64_t p_posi
cr.position.x = off; cr.position.x = off;
if ((glyphs[i].flags & GRAPHEME_IS_RTL) != GRAPHEME_IS_RTL) { if ((glyphs[i].flags & GRAPHEME_IS_RTL) != GRAPHEME_IS_RTL) {
caret.l_dir = DIRECTION_LTR; caret.l_dir = DIRECTION_LTR;
for (int j = 0; j < glyphs[i].count; j++) { cr.position.x += advance;
cr.position.x += glyphs[i + j].advance * glyphs[i + j].repeat; cr.size.x = -char_adv;
cr.size.x -= glyphs[i + j].advance * glyphs[i + j].repeat;
}
} else { } else {
caret.l_dir = DIRECTION_RTL; caret.l_dir = DIRECTION_RTL;
for (int j = 0; j < glyphs[i].count; j++) { cr.size.x = char_adv;
cr.size.x += glyphs[i + j].advance * glyphs[i + j].repeat;
}
} }
} else { } else {
cr.size.y = 1.0f; cr.size.y = 1.0f;
@ -1036,15 +1034,12 @@ CaretInfo TextServer::shaped_text_get_carets(const RID &p_shaped, int64_t p_posi
cr.position.y = off; cr.position.y = off;
if ((glyphs[i].flags & GRAPHEME_IS_RTL) != GRAPHEME_IS_RTL) { if ((glyphs[i].flags & GRAPHEME_IS_RTL) != GRAPHEME_IS_RTL) {
caret.l_dir = DIRECTION_LTR; caret.l_dir = DIRECTION_LTR;
for (int j = 0; j < glyphs[i].count; j++) { cr.position.y += advance;
cr.position.y += glyphs[i + j].advance * glyphs[i + j].repeat; cr.size.y = -char_adv;
cr.size.y -= glyphs[i + j].advance * glyphs[i + j].repeat;
}
} else { } else {
caret.l_dir = DIRECTION_RTL; caret.l_dir = DIRECTION_RTL;
for (int j = 0; j < glyphs[i].count; j++) { cr.position.x += advance;
cr.size.y += glyphs[i + j].advance * glyphs[i + j].repeat; cr.size.y = char_adv;
}
} }
} }
caret.l_caret = cr; caret.l_caret = cr;
@ -1058,22 +1053,24 @@ CaretInfo TextServer::shaped_text_get_carets(const RID &p_shaped, int64_t p_posi
real_t char_adv = advance / (real_t)(glyphs[i].end - glyphs[i].start); real_t char_adv = advance / (real_t)(glyphs[i].end - glyphs[i].start);
Rect2 cr; Rect2 cr;
if (orientation == ORIENTATION_HORIZONTAL) { if (orientation == ORIENTATION_HORIZONTAL) {
cr.size.x = 1.0f;
cr.size.y = height * 2; cr.size.y = height * 2;
cr.position.y = -ascent; cr.position.y = -ascent;
if ((glyphs[i].flags & GRAPHEME_IS_RTL) == GRAPHEME_IS_RTL) { if ((glyphs[i].flags & GRAPHEME_IS_RTL) == GRAPHEME_IS_RTL) {
cr.position.x = off + char_adv * (glyphs[i].end - p_position); cr.position.x = off + char_adv * (glyphs[i].end - p_position);
cr.size.x = -char_adv;
} else { } else {
cr.position.x = off + char_adv * (p_position - glyphs[i].start); cr.position.x = off + char_adv * (p_position - glyphs[i].start);
cr.size.x = char_adv;
} }
} else { } else {
cr.size.y = 1.0f;
cr.size.x = height * 2; cr.size.x = height * 2;
cr.position.x = -ascent; cr.position.x = -ascent;
if ((glyphs[i].flags & GRAPHEME_IS_RTL) == GRAPHEME_IS_RTL) { if ((glyphs[i].flags & GRAPHEME_IS_RTL) == GRAPHEME_IS_RTL) {
cr.position.y = off + char_adv * (glyphs[i].end - p_position); cr.position.y = off + char_adv * (glyphs[i].end - p_position);
cr.size.y = -char_adv;
} else { } else {
cr.position.y = off + char_adv * (p_position - glyphs[i].start); cr.position.y = off + char_adv * (p_position - glyphs[i].start);
cr.size.y = char_adv;
} }
} }
caret.t_caret = cr; caret.t_caret = cr;