### Godot version

v4.2.rc1.official [ad72de508]

### System information

Godot v4.2.rc1 - Windows 10.0.22621 - Vulkan (Forward+) - dedicated NVIDIA GeForce GTX 1660 Ti (NVIDIA; 31.0.15.3742) - Intel(R) Core(TM) i7-10700F CPU @ 2.90GHz (16 Threads)

### Issue description

While trying to use a custom effect script as a workaround for the [rainbow bbcode effect](https://github.com/godotengine/godot/issues/85031) at the RichTextLabel I found a bug regarding the `CharFXTransform.relative_index`.
The variable is explained as follows in the [documentation](https://docs.godotengine.org/en/4.0/classes/class_charfxtransform.html#class-charfxtransform-property-relative-index): 
```
The character offset of the glyph, relative to the current RichTextEffect custom block.
```
However, when using the script below, the character index shifts one to the left each time instead of being at the same position for each new effect block.
![grafik](https://github.com/godotengine/godot/assets/71942164/7b1b0557-d515-4d56-a25e-d2a2810b2966)


### Steps to reproduce

Add this script as Custom Effect to the RichTextLabel (or see the MRP):
```@tool
extends RichTextEffect
class_name test

var bbcode = "test"

func _process_custom_fx(char_fx):
	if char_fx.relative_index == 5:
		char_fx.color = Color.BLACK
	pass
```
Add this Text to a Rich TextLabel:
```
[test]0123456789[/test]
[test]0123456789[/test]
[test]0123456789[/test]
[test]0123456789[/test]
[test]0123456789[/test]
[test]0123456789[/test]
``` 

### Minimal reproduction project

[relative_index_issue.zip](https://github.com/godotengine/godot/files/13462368/relative_index_issue.zip)

set_physics_process_internal(false); 
			} else {
				
				if ((progress_delay > 0) && (OS::get_singleton()->get_ticks_msec() - loading_started >= (uint64_t)progress_delay)) {
					Vector2 p_size = Vector2(size.width - (theme_cache.normal_style->get_offset().x + vscroll->get_combined_minimum_size().width) * 2, vscroll->get_combined_minimum_size().width);
					Vector2 p_pos = Vector2(theme_cache.normal_style->get_offset().x, size.height - theme_cache.normal_style->get_offset().y - vscroll->get_combined_minimum_size().width);
					draw_style_box(theme_cache.progress_bg_style, Rect2(p_pos, p_size));
					bool right_to_left = is_layout_rtl();
					double r = loaded.load();
					int mp = theme_cache.progress_fg_style->get_minimum_size().width;
					int p = round(r * (p_size.width - mp));
					if (right_to_left) {
						int p_remaining = round((1.0 - r) * (p_size.width - mp));
						draw_style_box(theme_cache.progress_fg_style, Rect2(p_pos + Point2(p_remaining, 0), Size2(p + theme_cache.progress_fg_style->get_minimum_size().width, p_size.height)));
					} else {
						draw_style_box(theme_cache.progress_fg_style, Rect2(p_pos, Size2(p + theme_cache.progress_fg_style->get_minimum_size().width, p_size.height)));
					}
				}
			}
			
			Rect2 text_rect = _get_text_rect();
			float vofs = vscroll->get_value();
			
			int to_line = main->first_invalid_line.load();
			int from_line = _find_first_line(0, to_line, vofs);
			Point2 shadow_ofs(theme_cache.shadow_offset_x, theme_cache.shadow_offset_y);
			visible_paragraph_count = 0;
			visible_line_count = 0;
			
			Point2 ofs = text_rect.get_position() + Vector2(0, main->lines[from_line].offset.y - vofs);