diff --git a/doc/classes/TextEdit.xml b/doc/classes/TextEdit.xml index ebe796574aa..cbef102d66c 100644 --- a/doc/classes/TextEdit.xml +++ b/doc/classes/TextEdit.xml @@ -1309,7 +1309,6 @@ Set the type of caret to draw. - If [code]true[/code], a right-click displays the context menu. diff --git a/editor/script/script_text_editor.cpp b/editor/script/script_text_editor.cpp index 35caec6cb68..6e195da0b24 100644 --- a/editor/script/script_text_editor.cpp +++ b/editor/script/script_text_editor.cpp @@ -523,9 +523,10 @@ void ScriptTextEditor::_inline_object_draw(const Dictionary &p_info, const Rect2 if (color_alpha_texture.is_null()) { color_alpha_texture = inline_color_picker->get_theme_icon("sample_bg", "ColorPicker"); } - code_editor->get_text_editor()->draw_texture_rect(color_alpha_texture, col_rect, false); - code_editor->get_text_editor()->draw_rect(col_rect, Color(p_info["color"])); - code_editor->get_text_editor()->draw_rect(col_rect, Color(1, 1, 1), false, 1); + RID text_ci = code_editor->get_text_editor()->get_text_canvas_item(); + RS::get_singleton()->canvas_item_add_rect(text_ci, p_rect.grow(-3), Color(1, 1, 1)); + color_alpha_texture->draw_rect(text_ci, col_rect); + RS::get_singleton()->canvas_item_add_rect(text_ci, col_rect, Color(p_info["color"])); } } diff --git a/scene/gui/code_edit.cpp b/scene/gui/code_edit.cpp index 56d15231b4d..a7fe3319726 100644 --- a/scene/gui/code_edit.cpp +++ b/scene/gui/code_edit.cpp @@ -69,7 +69,7 @@ void CodeEdit::_notification(int p_what) { } break; case NOTIFICATION_DRAW: { - RID ci = get_canvas_item(); + RID ci = get_text_canvas_item(); const bool caret_visible = is_caret_visible(); const bool rtl = is_layout_rtl(); const int row_height = get_line_height(); @@ -103,7 +103,7 @@ void CodeEdit::_notification(int p_what) { hint_ofs.y -= (code_hint_minsize.y + row_height) - theme_cache.line_spacing; } - draw_style_box(theme_cache.code_hint_style, Rect2(hint_ofs, code_hint_minsize)); + theme_cache.code_hint_style->draw(ci, Rect2(hint_ofs, code_hint_minsize)); int yofs = 0; for (int i = 0; i < line_count; i++) { @@ -118,17 +118,17 @@ void CodeEdit::_notification(int p_what) { Point2 round_ofs = hint_ofs + theme_cache.code_hint_style->get_offset() + Vector2(0, theme_cache.font->get_ascent(theme_cache.font_size) + font_height * i + yofs); round_ofs = round_ofs.round(); - draw_string(theme_cache.font, round_ofs, line.remove_char(0xFFFF), HORIZONTAL_ALIGNMENT_LEFT, -1, theme_cache.font_size, theme_cache.code_hint_color); + theme_cache.font->draw_string(ci, round_ofs, line.remove_char(0xFFFF), HORIZONTAL_ALIGNMENT_LEFT, -1, theme_cache.font_size, theme_cache.code_hint_color); if (end > 0) { // Draw an underline for the currently edited function parameter. const Vector2 b = hint_ofs + theme_cache.code_hint_style->get_offset() + Vector2(begin, font_height + font_height * i + yofs); - draw_line(b, b + Vector2(end - begin, 0), theme_cache.code_hint_color, 2); + RS::get_singleton()->canvas_item_add_line(ci, b, b + Vector2(end - begin, 0), theme_cache.code_hint_color, 2); // Draw a translucent text highlight as well. const Rect2 highlight_rect = Rect2( b - Vector2(0, font_height), Vector2(end - begin, font_height)); - draw_rect(highlight_rect, theme_cache.code_hint_color * Color(1, 1, 1, 0.2)); + RS::get_singleton()->canvas_item_add_rect(ci, highlight_rect, theme_cache.code_hint_color * Color(1, 1, 1, 0.2)); } yofs += theme_cache.line_spacing; } @@ -177,7 +177,7 @@ void CodeEdit::_notification(int p_what) { code_completion_rect.position.x = caret_pos.x - code_completion_base_width; } - draw_style_box(theme_cache.code_completion_style, Rect2(code_completion_rect.position - theme_cache.code_completion_style->get_offset(), code_completion_rect.size + theme_cache.code_completion_style->get_minimum_size() + Size2(scroll_width, 0))); + theme_cache.code_completion_style->draw(ci, Rect2(code_completion_rect.position - theme_cache.code_completion_style->get_offset(), code_completion_rect.size + theme_cache.code_completion_style->get_minimum_size() + Size2(scroll_width, 0))); if (theme_cache.code_completion_background_color.a > 0.01) { RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(code_completion_rect.position, code_completion_rect.size + Size2(scroll_width, 0)), theme_cache.code_completion_background_color); } @@ -211,7 +211,7 @@ void CodeEdit::_notification(int p_what) { tl->set_width(code_completion_rect.size.width - (icon_area_size.x + theme_cache.code_completion_icon_separation)); if (rtl) { if (code_completion_options[l].default_value.get_type() == Variant::COLOR) { - draw_rect(Rect2(Point2(code_completion_rect.position.x, icon_area.position.y), icon_area_size), (Color)code_completion_options[l].default_value); + RS::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(code_completion_rect.position.x, icon_area.position.y), icon_area_size), (Color)code_completion_options[l].default_value); } tl->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_RIGHT); } else { @@ -219,10 +219,10 @@ void CodeEdit::_notification(int p_what) { const Color color = code_completion_options[l].default_value; const Rect2 rect = Rect2(Point2(code_completion_rect.position.x + code_completion_rect.size.width - icon_area_size.x, icon_area.position.y), icon_area_size); if (color.a < 1.0) { - draw_texture_rect(theme_cache.completion_color_bg, rect, true); + theme_cache.completion_color_bg->draw_rect(ci, rect, true); } - draw_rect(rect, color); + RS::get_singleton()->canvas_item_add_rect(ci, rect, color); } tl->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_LEFT); } @@ -234,7 +234,7 @@ void CodeEdit::_notification(int p_what) { int match_offset = theme_cache.font->get_string_size(code_completion_options[l].display.substr(0, match_segment.first), HORIZONTAL_ALIGNMENT_LEFT, -1, theme_cache.font_size).width; int match_len = theme_cache.font->get_string_size(code_completion_options[l].display.substr(match_segment.first, match_segment.second), HORIZONTAL_ALIGNMENT_LEFT, -1, theme_cache.font_size).width; - draw_rect(Rect2(match_pos + Point2(match_offset, 0), Size2(match_len, row_height)), theme_cache.code_completion_existing_color); + RS::get_singleton()->canvas_item_add_rect(ci, Rect2(match_pos + Point2(match_offset, 0), Size2(match_len, row_height)), theme_cache.code_completion_existing_color); } tl->draw(ci, title_pos, code_completion_options[l].font_color); } @@ -245,7 +245,7 @@ void CodeEdit::_notification(int p_what) { float r = (float)theme_cache.code_completion_max_lines / code_completion_options_count; float o = (float)code_completion_line_ofs / code_completion_options_count; - draw_rect(Rect2(code_completion_rect.position.x + code_completion_rect.size.width, code_completion_rect.position.y + o * code_completion_rect.size.y, scroll_width, code_completion_rect.size.y * r), scroll_color); + RS::get_singleton()->canvas_item_add_rect(ci, Rect2(code_completion_rect.position.x + code_completion_rect.size.width, code_completion_rect.position.y + o * code_completion_rect.size.y, scroll_width, code_completion_rect.size.y * r), scroll_color); } } } @@ -1341,6 +1341,7 @@ bool CodeEdit::is_drawing_executing_lines_gutter() const { void CodeEdit::_main_gutter_draw_callback(int p_line, int p_gutter, const Rect2 &p_region) { bool hovering = get_hovered_gutter() == Vector2i(main_gutter, p_line); + RID ci = get_text_canvas_item(); if (draw_breakpoints && theme_cache.breakpoint_icon.is_valid()) { bool breakpointed = is_line_breakpointed(p_line); bool shift_pressed = Input::get_singleton()->is_key_pressed(Key::SHIFT); @@ -1355,7 +1356,7 @@ void CodeEdit::_main_gutter_draw_callback(int p_line, int p_gutter, const Rect2 Rect2 icon_region = p_region; icon_region.position += Point2(padding, padding); icon_region.size -= Point2(padding, padding) * 2; - theme_cache.breakpoint_icon->draw_rect(get_canvas_item(), icon_region, false, use_color); + theme_cache.breakpoint_icon->draw_rect(ci, icon_region, false, use_color); } } @@ -1374,7 +1375,7 @@ void CodeEdit::_main_gutter_draw_callback(int p_line, int p_gutter, const Rect2 Rect2 icon_region = p_region; icon_region.position += Point2(horizontal_padding, 0); icon_region.size -= Point2(horizontal_padding * 1.1, vertical_padding); - theme_cache.bookmark_icon->draw_rect(get_canvas_item(), icon_region, false, use_color); + theme_cache.bookmark_icon->draw_rect(ci, icon_region, false, use_color); } } @@ -1385,7 +1386,7 @@ void CodeEdit::_main_gutter_draw_callback(int p_line, int p_gutter, const Rect2 Rect2 icon_region = p_region; icon_region.position += Point2(horizontal_padding, vertical_padding); icon_region.size -= Point2(horizontal_padding, vertical_padding) * 2; - theme_cache.executing_line_icon->draw_rect(get_canvas_item(), icon_region, false, theme_cache.executing_line_color); + theme_cache.executing_line_icon->draw_rect(ci, icon_region, false, theme_cache.executing_line_color); } } @@ -1546,7 +1547,7 @@ void CodeEdit::_line_number_draw_callback(int p_line, int p_gutter, const Rect2 number_color = theme_cache.line_number_color; } - TS->shaped_text_draw(text_rid, get_canvas_item(), ofs, -1, -1, number_color); + TS->shaped_text_draw(text_rid, get_text_canvas_item(), ofs, -1, -1, number_color); } void CodeEdit::_clear_line_number_text_cache() { @@ -1575,6 +1576,7 @@ void CodeEdit::_fold_gutter_draw_callback(int p_line, int p_gutter, Rect2 p_regi return; } set_line_gutter_clickable(p_line, fold_gutter, true); + RID ci = get_text_canvas_item(); int horizontal_padding = p_region.size.x / 10; int vertical_padding = p_region.size.y / 6; @@ -1588,17 +1590,17 @@ void CodeEdit::_fold_gutter_draw_callback(int p_line, int p_gutter, Rect2 p_regi Color region_icon_color = theme_cache.folded_code_region_color; region_icon_color.a = MAX(region_icon_color.a, 0.4f); if (can_fold) { - theme_cache.can_fold_code_region_icon->draw_rect(get_canvas_item(), p_region, false, region_icon_color); + theme_cache.can_fold_code_region_icon->draw_rect(ci, p_region, false, region_icon_color); } else { - theme_cache.folded_code_region_icon->draw_rect(get_canvas_item(), p_region, false, region_icon_color); + theme_cache.folded_code_region_icon->draw_rect(ci, p_region, false, region_icon_color); } return; } if (can_fold) { - theme_cache.can_fold_icon->draw_rect(get_canvas_item(), p_region, false, theme_cache.code_folding_color); + theme_cache.can_fold_icon->draw_rect(ci, p_region, false, theme_cache.code_folding_color); return; } - theme_cache.folded_icon->draw_rect(get_canvas_item(), p_region, false, theme_cache.code_folding_color); + theme_cache.folded_icon->draw_rect(ci, p_region, false, theme_cache.code_folding_color); } /* Line Folding */ diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 2659d0b1755..e1cad1a1720 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -932,7 +932,14 @@ void TextEdit::_notification(int p_what) { _update_scrollbars(); + RS::get_singleton()->canvas_item_clear(text_ci); + RS::get_singleton()->canvas_item_set_custom_rect(text_ci, !is_visibility_clip_disabled(), Rect2(Point2(0, 0), size)); + RS::get_singleton()->canvas_item_set_clip(text_ci, true); + RS::get_singleton()->canvas_item_set_visibility_layer(text_ci, get_visibility_layer()); + RS::get_singleton()->canvas_item_set_default_texture_filter(text_ci, RS::CanvasItemTextureFilter(get_texture_filter_in_tree())); + RID ci = get_canvas_item(); + int xmargin_beg = Math::ceil(theme_cache.style_normal->get_margin(SIDE_LEFT)) + gutters_width + gutter_padding; int xmargin_end = size.width - Math::ceil(theme_cache.style_normal->get_margin(SIDE_RIGHT)); @@ -952,7 +959,7 @@ void TextEdit::_notification(int p_what) { int visible_rows = get_visible_line_count() + 1; if (theme_cache.background_color.a > 0.01) { - RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2i(), get_size()), theme_cache.background_color); + RS::get_singleton()->canvas_item_add_rect(text_ci, Rect2(Point2i(), get_size()), theme_cache.background_color); } Vector brace_matching; @@ -1157,9 +1164,9 @@ void TextEdit::_notification(int p_what) { } if (rtl) { - RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(size.width - (xmargin_end + 2) - minimap_width, viewport_offset_y, minimap_width, viewport_height), viewport_color); + RS::get_singleton()->canvas_item_add_rect(text_ci, Rect2(size.width - (xmargin_end + 2) - minimap_width, viewport_offset_y, minimap_width, viewport_height), viewport_color); } else { - RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2((xmargin_end + 2), viewport_offset_y, minimap_width, viewport_height), viewport_color); + RS::get_singleton()->canvas_item_add_rect(text_ci, Rect2((xmargin_end + 2), viewport_offset_y, minimap_width, viewport_height), viewport_color); } for (int i = 0; i < minimap_draw_amount; i++) { @@ -1222,15 +1229,15 @@ void TextEdit::_notification(int p_what) { if (highlight_current_line && highlighted_lines.has(Pair(minimap_line, line_wrap_index))) { if (rtl) { - RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(size.width - (xmargin_end + 2) - minimap_width, i * 3, minimap_width, 2), theme_cache.current_line_color); + RS::get_singleton()->canvas_item_add_rect(text_ci, Rect2(size.width - (xmargin_end + 2) - minimap_width, i * 3, minimap_width, 2), theme_cache.current_line_color); } else { - RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2((xmargin_end + 2), i * 3, minimap_width, 2), theme_cache.current_line_color); + RS::get_singleton()->canvas_item_add_rect(text_ci, Rect2((xmargin_end + 2), i * 3, minimap_width, 2), theme_cache.current_line_color); } } else if (line_background_color.a > 0) { if (rtl) { - RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(size.width - (xmargin_end + 2) - minimap_width, i * 3, minimap_width, 2), line_background_color); + RS::get_singleton()->canvas_item_add_rect(text_ci, Rect2(size.width - (xmargin_end + 2) - minimap_width, i * 3, minimap_width, 2), line_background_color); } else { - RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2((xmargin_end + 2), i * 3, minimap_width, 2), line_background_color); + RS::get_singleton()->canvas_item_add_rect(text_ci, Rect2((xmargin_end + 2), i * 3, minimap_width, 2), line_background_color); } } @@ -1280,9 +1287,9 @@ void TextEdit::_notification(int p_what) { if (characters > 0) { if (rtl) { - RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(size.width - xpos - minimap_char_size.x * characters, minimap_line_height * i), Point2(minimap_char_size.x * characters, minimap_char_size.y)), current_color); + RS::get_singleton()->canvas_item_add_rect(text_ci, Rect2(Point2(size.width - xpos - minimap_char_size.x * characters, minimap_line_height * i), Point2(minimap_char_size.x * characters, minimap_char_size.y)), current_color); } else { - RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(xpos, minimap_line_height * i), Point2(minimap_char_size.x * characters, minimap_char_size.y)), current_color); + RS::get_singleton()->canvas_item_add_rect(text_ci, Rect2(Point2(xpos, minimap_line_height * i), Point2(minimap_char_size.x * characters, minimap_char_size.y)), current_color); } } @@ -1407,18 +1414,18 @@ void TextEdit::_notification(int p_what) { if (text.get_line_background_color(line).a > 0.0) { if (rtl) { - RS::get_singleton()->canvas_item_add_rect(ci, Rect2(size.width - ofs_x - xmargin_end, ofs_y, xmargin_end - xmargin_beg, row_height), text.get_line_background_color(line)); + RS::get_singleton()->canvas_item_add_rect(text_ci, Rect2(size.width - ofs_x - xmargin_end, ofs_y, xmargin_end - xmargin_beg, row_height), text.get_line_background_color(line)); } else { - RS::get_singleton()->canvas_item_add_rect(ci, Rect2(xmargin_beg + ofs_x, ofs_y, xmargin_end - xmargin_beg, row_height), text.get_line_background_color(line)); + RS::get_singleton()->canvas_item_add_rect(text_ci, Rect2(xmargin_beg + ofs_x, ofs_y, xmargin_end - xmargin_beg, row_height), text.get_line_background_color(line)); } } // Draw current line highlight. if (highlight_current_line && highlighted_lines.has(Pair(line, line_wrap_index))) { if (rtl) { - RS::get_singleton()->canvas_item_add_rect(ci, Rect2(size.width - ofs_x - xmargin_end, ofs_y, xmargin_end, row_height), theme_cache.current_line_color); + RS::get_singleton()->canvas_item_add_rect(text_ci, Rect2(size.width - ofs_x - xmargin_end, ofs_y, xmargin_end, row_height), theme_cache.current_line_color); } else { - RS::get_singleton()->canvas_item_add_rect(ci, Rect2(ofs_x, ofs_y, xmargin_end, row_height), theme_cache.current_line_color); + RS::get_singleton()->canvas_item_add_rect(text_ci, Rect2(ofs_x, ofs_y, xmargin_end, row_height), theme_cache.current_line_color); } } @@ -1448,9 +1455,9 @@ void TextEdit::_notification(int p_what) { int yofs = ofs_y + (row_height - tl->get_size().y) / 2; if (theme_cache.outline_size > 0 && theme_cache.outline_color.a > 0) { - tl->draw_outline(ci, Point2(gutter_offset + ofs_x, yofs), theme_cache.outline_size, theme_cache.outline_color); + tl->draw_outline(text_ci, Point2(gutter_offset + ofs_x, yofs), theme_cache.outline_size, theme_cache.outline_color); } - tl->draw(ci, Point2(gutter_offset + ofs_x, yofs), get_line_gutter_item_color(line, g)); + tl->draw(text_ci, Point2(gutter_offset + ofs_x, yofs), get_line_gutter_item_color(line, g)); } break; case GUTTER_TYPE_ICON: { const Ref icon = get_line_gutter_icon(line, g); @@ -1478,7 +1485,7 @@ void TextEdit::_notification(int p_what) { gutter_rect.position.x = size.width - gutter_rect.position.x - gutter_rect.size.x; } - icon->draw_rect(ci, gutter_rect, false, get_line_gutter_item_color(line, g)); + icon->draw_rect(text_ci, gutter_rect, false, get_line_gutter_item_color(line, g)); } break; case GUTTER_TYPE_CUSTOM: { if (gutter.custom_draw_callback.is_valid()) { @@ -1555,7 +1562,7 @@ void TextEdit::_notification(int p_what) { if (rect.position.x + rect.size.x > xmargin_end) { rect.size.x = xmargin_end - rect.position.x; } - RS::get_singleton()->canvas_item_add_rect(ci, rect, theme_cache.selection_color); + RS::get_singleton()->canvas_item_add_rect(text_ci, rect, theme_cache.selection_color); } } } @@ -1577,8 +1584,8 @@ void TextEdit::_notification(int p_what) { } else if (rect.position.x + rect.size.x > xmargin_end) { rect.size.x = xmargin_end - rect.position.x; } - RS::get_singleton()->canvas_item_add_rect(ci, rect, theme_cache.search_result_color); - draw_rect(rect, theme_cache.search_result_border_color, false); + RS::get_singleton()->canvas_item_add_rect(text_ci, rect, theme_cache.search_result_color); + _draw_rect_unfilled(text_ci, rect, theme_cache.search_result_border_color); } search_text_col = _get_column_pos_of_word(search_text, str, search_flags, search_text_col + search_text_len); @@ -1601,7 +1608,7 @@ void TextEdit::_notification(int p_what) { } else if (rect.position.x + rect.size.x > xmargin_end) { rect.size.x = xmargin_end - rect.position.x; } - RS::get_singleton()->canvas_item_add_rect(ci, rect, theme_cache.word_highlighted_color); + RS::get_singleton()->canvas_item_add_rect(text_ci, rect, theme_cache.word_highlighted_color); } highlighted_text_col = _get_column_pos_of_word(highlighted_text, str, SEARCH_MATCH_CASE | SEARCH_WHOLE_WORDS, highlighted_text_col + highlighted_text_len); @@ -1628,7 +1635,7 @@ void TextEdit::_notification(int p_what) { } rect.position.y += std::ceil(TS->shaped_text_get_ascent(rid)) + std::ceil(theme_cache.font->get_underline_position(theme_cache.font_size)); rect.size.y = MAX(1, theme_cache.font->get_underline_thickness(theme_cache.font_size)); - RS::get_singleton()->canvas_item_add_rect(ci, rect, highlight_underline_color); + RS::get_singleton()->canvas_item_add_rect(text_ci, rect, highlight_underline_color); } lookup_symbol_word_col = _get_column_pos_of_word(lookup_symbol_word, str, SEARCH_MATCH_CASE | SEARCH_WHOLE_WORDS, lookup_symbol_word_col + lookup_symbol_word_len); @@ -1652,7 +1659,7 @@ void TextEdit::_notification(int p_what) { for (int k = 0; k < glyphs[j].repeat; k++) { if ((char_ofs + char_margin) >= xmargin_beg && (char_ofs + glyphs[j].advance + char_margin) <= xmargin_end) { if (glyphs[j].font_rid != RID()) { - TS->font_draw_glyph_outline(glyphs[j].font_rid, ci, glyphs[j].font_size, theme_cache.outline_size, Vector2(char_margin + char_ofs + ofs_x + glyphs[j].x_off, ofs_y + glyphs[j].y_off), glyphs[j].index, theme_cache.outline_color); + TS->font_draw_glyph_outline(glyphs[j].font_rid, text_ci, glyphs[j].font_size, theme_cache.outline_size, Vector2(char_margin + char_ofs + ofs_x + glyphs[j].x_off, ofs_y + glyphs[j].y_off), glyphs[j].index, theme_cache.outline_color); } } char_ofs += glyphs[j].advance; @@ -1708,7 +1715,7 @@ void TextEdit::_notification(int p_what) { gl_color = _get_brace_mismatch_color(); } Rect2 rect = Rect2(char_pos, ofs_y + theme_cache.font->get_underline_position(theme_cache.font_size), glyphs[j].advance * glyphs[j].repeat, MAX(theme_cache.font->get_underline_thickness(theme_cache.font_size) * theme_cache.base_scale, 1)); - RS::get_singleton()->canvas_item_add_rect(ci, rect, gl_color); + RS::get_singleton()->canvas_item_add_rect(text_ci, rect, gl_color); } if ((brace_match.close_match_line == line && brace_match.close_match_column == glyphs[j].start) || @@ -1717,18 +1724,18 @@ void TextEdit::_notification(int p_what) { gl_color = _get_brace_mismatch_color(); } Rect2 rect = Rect2(char_pos, ofs_y + theme_cache.font->get_underline_position(theme_cache.font_size), glyphs[j].advance * glyphs[j].repeat, MAX(theme_cache.font->get_underline_thickness(theme_cache.font_size) * theme_cache.base_scale, 1)); - RS::get_singleton()->canvas_item_add_rect(ci, rect, gl_color); + RS::get_singleton()->canvas_item_add_rect(text_ci, rect, gl_color); } } } if (draw_tabs && ((glyphs[j].flags & TextServer::GRAPHEME_IS_TAB) == TextServer::GRAPHEME_IS_TAB)) { int yofs = (text_height - theme_cache.tab_icon->get_height()) / 2 - ldata->get_line_ascent(line_wrap_index); - theme_cache.tab_icon->draw(ci, Point2(char_pos, ofs_y + yofs), gl_color); + theme_cache.tab_icon->draw(text_ci, Point2(char_pos, ofs_y + yofs), gl_color); } else if (draw_spaces && ((glyphs[j].flags & TextServer::GRAPHEME_IS_SPACE) == TextServer::GRAPHEME_IS_SPACE) && ((glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL)) { int yofs = (text_height - theme_cache.space_icon->get_height()) / 2 - ldata->get_line_ascent(line_wrap_index); int xofs = (glyphs[j].advance * glyphs[j].repeat - theme_cache.space_icon->get_width()) / 2; - theme_cache.space_icon->draw(ci, Point2(char_pos + xofs, ofs_y + yofs), gl_color); + theme_cache.space_icon->draw(text_ci, Point2(char_pos + xofs, ofs_y + yofs), gl_color); } } @@ -1736,10 +1743,10 @@ void TextEdit::_notification(int p_what) { for (int k = 0; k < glyphs[j].repeat; k++) { if (!clipped && (char_ofs + char_margin) >= xmargin_beg && (char_ofs + glyphs[j].advance + char_margin) <= xmargin_end) { if (glyphs[j].font_rid != RID()) { - TS->font_draw_glyph(glyphs[j].font_rid, ci, glyphs[j].font_size, Vector2(char_margin + char_ofs + ofs_x + glyphs[j].x_off, ofs_y + glyphs[j].y_off), glyphs[j].index, gl_color); + TS->font_draw_glyph(glyphs[j].font_rid, text_ci, glyphs[j].font_size, Vector2(char_margin + char_ofs + ofs_x + glyphs[j].x_off, ofs_y + glyphs[j].y_off), glyphs[j].index, gl_color); had_glyphs_drawn = true; } else if (((glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) && ((glyphs[j].flags & TextServer::GRAPHEME_IS_EMBEDDED_OBJECT) != TextServer::GRAPHEME_IS_EMBEDDED_OBJECT)) { - TS->draw_hex_code_box(ci, glyphs[j].font_size, Vector2(char_margin + char_ofs + ofs_x + glyphs[j].x_off, ofs_y + glyphs[j].y_off), glyphs[j].index, gl_color); + TS->draw_hex_code_box(text_ci, glyphs[j].font_size, Vector2(char_margin + char_ofs + ofs_x + glyphs[j].x_off, ofs_y + glyphs[j].y_off), glyphs[j].index, gl_color); had_glyphs_drawn = true; } } @@ -1770,7 +1777,7 @@ void TextEdit::_notification(int p_what) { int yofs = (text_height - _get_folded_eol_icon()->get_height()) / 2 - ldata->get_line_ascent(line_wrap_index); Color eol_color = _get_code_folding_color(); eol_color.a = 1; - _get_folded_eol_icon()->draw(ci, Point2(xofs, ofs_y + yofs), eol_color); + _get_folded_eol_icon()->draw(text_ci, Point2(xofs, ofs_y + yofs), eol_color); } } @@ -1822,17 +1829,21 @@ void TextEdit::_notification(int p_what) { ts_caret.t_caret.size.y = h; } ts_caret.t_caret.position += Vector2(char_margin + ofs_x, ofs_y); - draw_rect(ts_caret.t_caret, theme_cache.caret_color, overtype_mode); + if (overtype_mode) { + RS::get_singleton()->canvas_item_add_rect(text_ci, ts_caret.t_caret, theme_cache.caret_color); + } else { + _draw_rect_unfilled(text_ci, ts_caret.t_caret, theme_cache.caret_color); + } 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.size.x = caret_width; - RS::get_singleton()->canvas_item_add_rect(ci, ts_caret.l_caret, theme_cache.caret_color); + RS::get_singleton()->canvas_item_add_rect(text_ci, ts_caret.l_caret, theme_cache.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); - RS::get_singleton()->canvas_item_add_rect(ci, trect, theme_cache.caret_color); + RS::get_singleton()->canvas_item_add_rect(text_ci, trect, theme_cache.caret_color); } } else { // End of the line. if (gl_size > 0) { @@ -1857,7 +1868,11 @@ void TextEdit::_notification(int p_what) { if (ts_caret.l_dir == TextServer::DIRECTION_RTL) { ts_caret.l_caret.position.x -= ts_caret.l_caret.size.x; } - draw_rect(ts_caret.l_caret, theme_cache.caret_color, overtype_mode); + if (overtype_mode) { + RS::get_singleton()->canvas_item_add_rect(text_ci, ts_caret.l_caret, theme_cache.caret_color); + } else { + _draw_rect_unfilled(text_ci, ts_caret.l_caret, theme_cache.caret_color); + } } } else { // Normal caret. @@ -1865,28 +1880,28 @@ void TextEdit::_notification(int p_what) { // Draw extra marker on top of mid caret. 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); - RS::get_singleton()->canvas_item_add_rect(ci, trect, theme_cache.caret_color); + RS::get_singleton()->canvas_item_add_rect(text_ci, trect, theme_cache.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); - RS::get_singleton()->canvas_item_add_rect(ci, trect, theme_cache.caret_color); + RS::get_singleton()->canvas_item_add_rect(text_ci, trect, theme_cache.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); - RS::get_singleton()->canvas_item_add_rect(ci, trect, theme_cache.caret_color); + RS::get_singleton()->canvas_item_add_rect(text_ci, trect, theme_cache.caret_color); } ts_caret.l_caret.position += Vector2(char_margin + ofs_x, ofs_y); ts_caret.l_caret.size.x = caret_width; - RS::get_singleton()->canvas_item_add_rect(ci, ts_caret.l_caret, theme_cache.caret_color); + RS::get_singleton()->canvas_item_add_rect(text_ci, ts_caret.l_caret, theme_cache.caret_color); ts_caret.t_caret.position += Vector2(char_margin + ofs_x, ofs_y); ts_caret.t_caret.size.x = caret_width; - RS::get_singleton()->canvas_item_add_rect(ci, ts_caret.t_caret, theme_cache.caret_color); + RS::get_singleton()->canvas_item_add_rect(text_ci, ts_caret.t_caret, theme_cache.caret_color); } } } @@ -1907,7 +1922,7 @@ void TextEdit::_notification(int p_what) { rect.size.x = xmargin_end - rect.position.x; } rect.size.y = caret_width; - draw_rect(rect, theme_cache.caret_color); + RS::get_singleton()->canvas_item_add_rect(text_ci, rect, theme_cache.caret_color); carets.write[c].draw_pos.x = rect.position.x; } } @@ -1926,7 +1941,7 @@ void TextEdit::_notification(int p_what) { rect.size.x = xmargin_end - rect.position.x; } rect.size.y = caret_width * 3; - draw_rect(rect, theme_cache.caret_color); + RS::get_singleton()->canvas_item_add_rect(text_ci, rect, theme_cache.caret_color); carets.write[c].draw_pos.x = rect.position.x; } } @@ -6446,6 +6461,10 @@ bool TextEdit::is_scroll_past_end_of_file_enabled() const { return scroll_past_end_of_file_enabled; } +RID TextEdit::get_text_canvas_item() const { + return text_ci; +} + VScrollBar *TextEdit::get_v_scroll_bar() const { return v_scroll; } @@ -9232,6 +9251,26 @@ void TextEdit::_base_remove_text(int p_from_line, int p_from_column, int p_to_li emit_signal(SNAME("lines_edited_from"), p_to_line, p_from_line); } +void TextEdit::_draw_rect_unfilled(RID p_canvas_item, const Rect2 &p_rect, const Color &p_color, real_t p_width, bool p_antialiased) const { + Rect2 rect = p_rect.abs(); + + if (p_width >= rect.size.width || p_width >= rect.size.height) { + RS::get_singleton()->canvas_item_add_rect(p_canvas_item, rect.grow(0.5f * p_width), p_color, p_antialiased); + } else { + Vector points; + points.resize(5); + points.write[0] = rect.position; + points.write[1] = rect.position + Vector2(rect.size.x, 0); + points.write[2] = rect.position + rect.size; + points.write[3] = rect.position + Vector2(0, rect.size.y); + points.write[4] = rect.position; + + Vector colors = { p_color }; + + RS::get_singleton()->canvas_item_add_polyline(p_canvas_item, points, colors, p_width, p_antialiased); + } +} + TextEdit::TextEdit(const String &p_placeholder) { placeholder_data_buf.instantiate(); carets.push_back(Caret()); @@ -9243,6 +9282,10 @@ TextEdit::TextEdit(const String &p_placeholder) { text.set_tab_size(text.get_tab_size()); + text_ci = RS::get_singleton()->canvas_item_create(); + RS::get_singleton()->canvas_item_set_parent(text_ci, get_canvas_item()); + RS::get_singleton()->canvas_item_set_use_parent_material(text_ci, true); + h_scroll = memnew(HScrollBar); v_scroll = memnew(VScrollBar); @@ -9277,6 +9320,9 @@ TextEdit::TextEdit(const String &p_placeholder) { set_placeholder(p_placeholder); - set_clip_contents(true); set_editable(true); } + +TextEdit::~TextEdit() { + RS::get_singleton()->free(text_ci); +} diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h index a92dde1feb1..0cabfae0f03 100644 --- a/scene/gui/text_edit.h +++ b/scene/gui/text_edit.h @@ -288,6 +288,7 @@ private: /* Text */ Text text; + RID text_ci; bool setting_text = false; enum AltInputMode { @@ -657,6 +658,9 @@ private: RID accessibility_text_root_element_nl; + // FIXME: Helper method to draw unfilled rects, should be moved to RenderingServer. + void _draw_rect_unfilled(RID p_canvas_item, const Rect2 &p_rect, const Color &p_color, real_t p_width = -1.0, bool p_antialiased = false) const; + /*** Super internal Core API. Everything builds on it. ***/ bool text_changed_dirty = false; void _text_changed(); @@ -783,6 +787,8 @@ public: /* Text */ // Text properties. + RID get_text_canvas_item() const; + bool has_ime_text() const; void cancel_ime(); void apply_ime(); @@ -1188,6 +1194,7 @@ public: #endif TextEdit(const String &p_placeholder = String()); + ~TextEdit(); }; VARIANT_ENUM_CAST(TextEdit::EditAction);