@@ -7058,6 +7058,7 @@ void RichTextLabel::set_visible_ratio(float p_ratio) {
70587058 if (visible_ratio != p_ratio) {
70597059 _stop_thread ();
70607060
7061+ int prev_vc = visible_characters;
70617062 if (p_ratio >= 1.0 ) {
70627063 visible_characters = -1 ;
70637064 visible_ratio = 1.0 ;
@@ -7069,10 +7070,44 @@ void RichTextLabel::set_visible_ratio(float p_ratio) {
70697070 visible_ratio = p_ratio;
70707071 }
70717072
7072- if (visible_chars_behavior == TextServer::VC_CHARS_BEFORE_SHAPING) {
7073- main->first_invalid_line .store (0 ); // Invalidate all lines..
7074- _invalidate_accessibility ();
7075- _validate_line_caches ();
7073+ if (visible_chars_behavior == TextServer::VC_CHARS_BEFORE_SHAPING && visible_characters != prev_vc) {
7074+ int new_vc = (visible_characters < 0 ) ? get_total_character_count () : visible_characters;
7075+ int old_vc = (prev_vc < 0 ) ? get_total_character_count () : prev_vc;
7076+ int to_line = main->first_invalid_line .load ();
7077+ int old_from_l = to_line;
7078+ int new_from_l = to_line;
7079+ for (int i = 0 ; i < to_line; i++) {
7080+ const Line &l = main->lines [i];
7081+ if (l.char_offset <= old_vc && l.char_offset + l.char_count > old_vc) {
7082+ old_from_l = i;
7083+ }
7084+ if (l.char_offset <= new_vc && l.char_offset + l.char_count > new_vc) {
7085+ new_from_l = i;
7086+ }
7087+ }
7088+ Rect2 text_rect = _get_text_rect ();
7089+ int first_invalid = MIN (new_from_l, old_from_l);
7090+ int second_invalid = MAX (new_from_l, old_from_l);
7091+
7092+ float total_height = (first_invalid == 0 ) ? 0 : _calculate_line_vertical_offset (main->lines [first_invalid - 1 ]);
7093+ if (first_invalid < to_line) {
7094+ int total_chars = main->lines [first_invalid].char_offset ;
7095+ total_height = _shape_line (main, first_invalid, theme_cache.normal_font , theme_cache.normal_font_size , text_rect.get_size ().width - scroll_w, total_height, &total_chars);
7096+ }
7097+ if (first_invalid != second_invalid) {
7098+ for (int i = first_invalid + 1 ; i < second_invalid; i++) {
7099+ main->lines [i].offset .y = total_height;
7100+ total_height = _calculate_line_vertical_offset (main->lines [i]);
7101+ }
7102+ if (second_invalid < to_line) {
7103+ int total_chars = main->lines [second_invalid].char_offset ;
7104+ total_height = _shape_line (main, second_invalid, theme_cache.normal_font , theme_cache.normal_font_size , text_rect.get_size ().width - scroll_w, total_height, &total_chars);
7105+ }
7106+ }
7107+ for (int i = second_invalid + 1 ; i < to_line; i++) {
7108+ main->lines [i].offset .y = total_height;
7109+ total_height = _calculate_line_vertical_offset (main->lines [i]);
7110+ }
70767111 }
70777112 queue_redraw ();
70787113 }
@@ -7497,6 +7532,7 @@ void RichTextLabel::set_visible_characters(int p_visible) {
74977532 if (visible_characters != p_visible) {
74987533 _stop_thread ();
74997534
7535+ int prev_vc = visible_characters;
75007536 visible_characters = p_visible;
75017537 if (p_visible == -1 ) {
75027538 visible_ratio = 1 ;
@@ -7506,10 +7542,44 @@ void RichTextLabel::set_visible_characters(int p_visible) {
75067542 visible_ratio = (float )p_visible / (float )total_char_count;
75077543 }
75087544 }
7509- if (visible_chars_behavior == TextServer::VC_CHARS_BEFORE_SHAPING) {
7510- main->first_invalid_line .store (0 ); // Invalidate all lines.
7511- _invalidate_accessibility ();
7512- _validate_line_caches ();
7545+ if (visible_chars_behavior == TextServer::VC_CHARS_BEFORE_SHAPING && visible_characters != prev_vc) {
7546+ int new_vc = (visible_characters < 0 ) ? get_total_character_count () : visible_characters;
7547+ int old_vc = (prev_vc < 0 ) ? get_total_character_count () : prev_vc;
7548+ int to_line = main->first_invalid_line .load ();
7549+ int old_from_l = to_line;
7550+ int new_from_l = to_line;
7551+ for (int i = 0 ; i < to_line; i++) {
7552+ const Line &l = main->lines [i];
7553+ if (l.char_offset <= old_vc && l.char_offset + l.char_count > old_vc) {
7554+ old_from_l = i;
7555+ }
7556+ if (l.char_offset <= new_vc && l.char_offset + l.char_count > new_vc) {
7557+ new_from_l = i;
7558+ }
7559+ }
7560+ Rect2 text_rect = _get_text_rect ();
7561+ int first_invalid = MIN (new_from_l, old_from_l);
7562+ int second_invalid = MAX (new_from_l, old_from_l);
7563+
7564+ float total_height = (first_invalid == 0 ) ? 0 : _calculate_line_vertical_offset (main->lines [first_invalid - 1 ]);
7565+ if (first_invalid < to_line) {
7566+ int total_chars = main->lines [first_invalid].char_offset ;
7567+ total_height = _shape_line (main, first_invalid, theme_cache.normal_font , theme_cache.normal_font_size , text_rect.get_size ().width - scroll_w, total_height, &total_chars);
7568+ }
7569+ if (first_invalid != second_invalid) {
7570+ for (int i = first_invalid + 1 ; i < second_invalid; i++) {
7571+ main->lines [i].offset .y = total_height;
7572+ total_height = _calculate_line_vertical_offset (main->lines [i]);
7573+ }
7574+ if (second_invalid < to_line) {
7575+ int total_chars = main->lines [second_invalid].char_offset ;
7576+ total_height = _shape_line (main, second_invalid, theme_cache.normal_font , theme_cache.normal_font_size , text_rect.get_size ().width - scroll_w, total_height, &total_chars);
7577+ }
7578+ }
7579+ for (int i = second_invalid + 1 ; i < to_line; i++) {
7580+ main->lines [i].offset .y = total_height;
7581+ total_height = _calculate_line_vertical_offset (main->lines [i]);
7582+ }
75137583 }
75147584 queue_redraw ();
75157585 }
0 commit comments