If first character in GUI textbox is right to left, set the textbox direction to that

This commit is contained in:
Yousef Khadadeh 2025-11-16 09:41:09 +03:00
parent 9120062889
commit 4fe52ef7f6
3 changed files with 41 additions and 8 deletions

View file

@ -21,6 +21,7 @@ template <typename T> class TextBox : public Element {
force_update_textbox(io, false);
textbox->set_width(std::numeric_limits<float>::max());
textbox->set_text_direction_between(0, 0, textbox->get_suggested_direction(0));
CLAY({
.layout = {

View file

@ -548,18 +548,32 @@ void TextBox::set_text_style_modifier_between(TextPosition p1, TextPosition p2,
void TextBox::set_text_alignment_between(size_t paragraphIndex1, size_t paragraphIndex2, skia::textlayout::TextAlign newAlignment) {
auto [start, end] = get_start_end_paragraph_pos(paragraphIndex1, paragraphIndex2);
for(size_t i = start; i <= end; i++)
paragraphs[i].pStyleData.textAlignment = newAlignment;
inputChangedTextBox = true;
needsRebuild = true;
bool anythingChanged = false;
for(size_t i = start; i <= end; i++) {
if(paragraphs[i].pStyleData.textAlignment != newAlignment) {
anythingChanged = true;
paragraphs[i].pStyleData.textAlignment = newAlignment;
}
}
if(anythingChanged) {
inputChangedTextBox = true;
needsRebuild = true;
}
}
void TextBox::set_text_direction_between(size_t paragraphIndex1, size_t paragraphIndex2, skia::textlayout::TextDirection newDirection) {
auto [start, end] = get_start_end_paragraph_pos(paragraphIndex1, paragraphIndex2);
for(size_t i = start; i <= end; i++)
paragraphs[i].pStyleData.textDirection = newDirection;
inputChangedTextBox = true;
needsRebuild = true;
bool anythingChanged = false;
for(size_t i = start; i <= end; i++) {
if(paragraphs[i].pStyleData.textDirection != newDirection) {
anythingChanged = true;
paragraphs[i].pStyleData.textDirection = newDirection;
}
}
if(anythingChanged) {
inputChangedTextBox = true;
needsRebuild = true;
}
}
ParagraphStyleData TextBox::get_paragraph_style_data_at(size_t paragraphIndex) {
@ -1031,6 +1045,22 @@ SkRect TextBox::get_cursor_rect(TextPosition pos) {
return SkRect::MakeXYWH(topPoint.x() - CURSOR_WIDTH * 0.5f, topPoint.y(), CURSOR_WIDTH, height);
}
skia::textlayout::TextDirection TextBox::get_suggested_direction(size_t pIndex) {
rebuild();
auto u = SkUnicodes::ICU::Make();
pIndex = std::min(pIndex, paragraphs.size() - 1);
auto& pData = paragraphs[pIndex];
if(pData.text.empty())
return skia::textlayout::TextDirection::kLtr;
skia::textlayout::Paragraph::GlyphClusterInfo glyphInfo;
bool exists = pData.p->getGlyphClusterAt(0, &glyphInfo);
if(!exists)
return skia::textlayout::TextDirection::kLtr;
return glyphInfo.fGlyphClusterPosition;
}
void TextBox::rects_between_text_positions_func(TextPosition p1, TextPosition p2, std::function<void(const SkRect& r)> f) {
auto [start, end] = get_start_end_text_pos(p1, p2);

View file

@ -145,6 +145,8 @@ class TextBox {
void process_rich_text_input(Cursor& cur, const TextData& richText);
SkRect get_cursor_rect(TextPosition pos);
skia::textlayout::TextDirection get_suggested_direction(size_t pIndex);
private:
std::pair<TextPosition, TextPosition> get_start_end_text_pos(TextPosition p1, TextPosition p2);
std::pair<size_t, size_t> get_start_end_paragraph_pos(size_t p1, size_t p2);