This page provides an overview of the text rendering and editing controls available in Godot's scene system, covering their class relationships, internal architecture, and how they connect to the underlying text shaping infrastructure.
Scope: This page covers the GUI control classes responsible for displaying and editing text: TextEdit, CodeEdit, RichTextLabel, Label, and LineEdit, as well as the TextParagraph and TextLine resources that provide the text shaping abstraction layer they share.
For details on the TextServer interface that drives all text shaping, bidirectional text, and complex script support, see Text Shaping System. For syntax highlighting resources used by TextEdit and CodeEdit, those are documented in TextEdit & CodeEdit.
All text controls extend Control from the scene/GUI system. They differ in whether they support editing, formatting, and how they delegate shaping to the text server.
| Class | File | Role |
|---|---|---|
TextEdit | scene/gui/text_edit.h | Multiline editable plain text |
CodeEdit | scene/gui/code_edit.h | Multiline code editor, extends TextEdit |
RichTextLabel | scene/gui/rich_text_label.h | Formatted read-only text with BBCode and effects |
Label | scene/gui/label.h | Non-editable plain text display, single or multiline |
LineEdit | scene/gui/line_edit.h | Single-line editable text input |
TextParagraph | scene/resources/text_paragraph.h | Shaped paragraph resource wrapping TextServer |
TextLine | scene/resources/text_line.h | Shaped single line resource wrapping TextServer |
Class hierarchy of text controls
Sources: scene/gui/text_edit.h40-41 scene/gui/code_edit.h36-37 scene/gui/rich_text_label.h47-48 scene/gui/label.h scene/gui/line_edit.h36-37
All controls delegate glyph layout to the TextServer singleton (accessed as TS). The TextParagraph and TextLine resource classes provide a higher-level API over the raw TextServer RID-based API. Both TextParagraph and TextLine hold a shaped text RID internally and expose operations like add_string, add_object, tab_align, set_width, and get_line_count.
Shaping infrastructure relationships
Sources: scene/gui/text_edit.h149-170 scene/gui/rich_text_label.h160-200 scene/gui/label.cpp140-237 scene/gui/line_edit.cpp204-224 scene/resources/text_paragraph.h scene/resources/text_line.h
TextEdit is a scrollable multiline editor that stores content as a Vector<Line> inside the private inner class TextEdit::Text. Each Line owns a Ref<TextParagraph> named data_buf that holds the shaped representation of the line's raw string.
Key internals:
TextEdit::Text manages the full line array, line wrapping, gutter columns, font/size settings, and line-level caching.TextEdit::Text::invalidate_cache rebuilds the data_buf for a specific line by calling data_buf->add_string(...) and then data_buf->tab_align(...).Caret struct tracks line, column, draw_pos, and an optional Selection.Vector<Caret> carets where index 0 is the primary caret.HScrollBar *h_scroll and VScrollBar *v_scroll.Vector<GutterInfo> gutters.Ref<SyntaxHighlighter> syntax_highlighter.TextEdit::Text line cache structure
Sources: scene/gui/text_edit.h136-287 scene/gui/text_edit.cpp267-393
CodeEdit extends TextEdit and adds features common in code editors:
NOTIFICATION_DRAW handler using TextLine for each entry.indent_using_spaces.symbol_tooltip_timer triggers a symbol_lookup signal for hover-based documentation.CodeEdit always forces left-to-right text direction regardless of locale, as source code is always LTR.
Sources: scene/gui/code_edit.h36-200 scene/gui/code_edit.cpp44-270
RichTextLabel stores content as a doubly linked list of Item objects that form a tag stack. Text is organized into Line structures (each representing a paragraph) stored inside ItemFrame objects.
Item type enumeration (from scene/gui/rich_text_label.h74-105):
| Enum Value | Meaning |
|---|---|
ITEM_FRAME | Container/table cell frame holding sub-lines |
ITEM_TEXT | Raw text content (ItemText::text) |
ITEM_IMAGE | Inline image (ItemImage) |
ITEM_NEWLINE | Paragraph break |
ITEM_FONT, ITEM_FONT_SIZE | Font overrides |
ITEM_COLOR, ITEM_OUTLINE_SIZE, ITEM_OUTLINE_COLOR | Color styling |
ITEM_UNDERLINE, ITEM_STRIKETHROUGH | Text decoration |
ITEM_TABLE | Multi-column table |
ITEM_LIST | Ordered/unordered list |
ITEM_META | Clickable metadata link |
ITEM_DROPCAP | Drop capital character |
ITEM_FADE, ITEM_SHAKE, ITEM_WAVE, ITEM_TORNADO, ITEM_RAINBOW, ITEM_PULSE | Built-in animated effects |
ITEM_CUSTOMFX | User-defined RichTextEffect |
RichTextLabel data model
Shaping is performed in _shape_line which iterates the item list for a given Line, calling l.text_buf->add_string(...) for ITEM_TEXT and l.text_buf->add_object(...) for ITEM_IMAGE and ITEM_TABLE. The function stores a character offset (char_offset) on each line for visible_characters trimming.
Sources: scene/gui/rich_text_label.h160-198 scene/gui/rich_text_label.cpp602-822
Label displays non-editable text. It splits the full text string on paragraph_separator (default "\n") into Paragraph objects, each owning a shaped text RID created with TS->create_shaped_text(). Line breaking is computed by TS->shaped_text_get_line_breaks(...) and stored as a Vector<RID> lines_rid per paragraph.
Notable features:
autowrap_mode controls line wrapping strategy (AUTOWRAP_OFF, AUTOWRAP_WORD, AUTOWRAP_WORD_SMART, AUTOWRAP_ARBITRARY).overrun_behavior controls ellipsis and clipping when text overflows.uppercase applies TS->string_to_upper(...) before shaping.LabelSettings resource allows font, font size, line spacing, shadow, and outline to be bundled as a reusable resource.visible_characters / visible_ratio enable animated text reveal.Sources: scene/gui/label.h scene/gui/label.cpp140-238
LineEdit handles single-line text input. It stores the full text in a String text and shapes it into a single RID text_rid via the TextServer singleton directly (no TextParagraph wrapper). The shaped RID is used for hit testing, word break navigation, and selection rendering.
Key behaviors:
pass is true, the display string is replaced with secret_character repeated.ime_text holds the in-progress composition string; apply_ime() / cancel_ime() finalize or discard it.AltInputMode alt_mode.Selection::begin / Selection::end track the selected character range.× icon that clears the field.Ref<Texture2D> right_icon drawn at the trailing edge.DisplayServer::virtual_keyboard_show(...).editing flag: LineEdit distinguishes between focused (keyboard navigation) and actively-editing states.Sources: scene/gui/line_edit.h36-200 scene/gui/line_edit.cpp53-434
All text controls ultimately call TextServer shaped text draw functions during their NOTIFICATION_DRAW handler. The draw call chain differs per control:
Draw call paths per control
Sources: scene/gui/text_edit.cpp907-960 scene/gui/rich_text_label.cpp scene/gui/label.cpp140-238 scene/gui/line_edit.cpp436-616
All text controls integrate with Godot's accessibility system via NOTIFICATION_ACCESSIBILITY_UPDATE:
TextEdit creates per-line-wrap accessibility elements using DisplayServer::accessibility_create_sub_text_edit_elements(...), stored on TextEdit::Text::Line::accessibility_text_root_element. It reports its role as ROLE_MULTILINE_TEXT_FIELD.LineEdit tracks a single accessibility_text_root_element RID.RichTextLabel creates per-paragraph accessibility elements.Sources: scene/gui/text_edit.cpp237-254 scene/gui/text_edit.cpp747-829
| Page | Covers |
|---|---|
| TextEdit & CodeEdit | Full TextEdit API, gutter system, syntax highlighting, multi-caret editing; CodeEdit completion, folding, delimiter detection |
| Text Shaping System | TextServer interface, TextLine, TextParagraph, BiDi, complex scripts |
| RichTextLabel | BBCode parsing, item tag stack, effects system, tables, RichTextEffect |
| Label & LineEdit | Label paragraph layout and overrun; LineEdit editing state machine, IME, selection |
Refresh this wiki
This wiki was recently refreshed. Please wait 2 days to refresh again.