diff options
-rw-r--r-- | core/array.cpp | 4 | ||||
-rw-r--r-- | core/error_list.h | 2 | ||||
-rw-r--r-- | core/error_macros.h | 21 | ||||
-rw-r--r-- | core/global_constants.cpp | 2 | ||||
-rw-r--r-- | core/image.cpp | 6 | ||||
-rw-r--r-- | core/object.cpp | 2 | ||||
-rw-r--r-- | core/object.h | 6 | ||||
-rw-r--r-- | core/typedefs.h | 8 | ||||
-rw-r--r-- | core/ustring.cpp | 12 | ||||
-rw-r--r-- | core/variant.cpp | 4 | ||||
-rw-r--r-- | doc/classes/@Global Scope.xml | 2 | ||||
-rw-r--r-- | editor/plugins/canvas_item_editor_plugin.cpp | 3 | ||||
-rw-r--r-- | modules/gdnative/include/gdnative/gdnative.h | 2 | ||||
-rw-r--r-- | modules/gdscript/gd_function.cpp | 6 | ||||
-rw-r--r-- | platform/uwp/gl_context_egl.cpp | 36 | ||||
-rw-r--r-- | scene/gui/rich_text_label.cpp | 66 | ||||
-rw-r--r-- | scene/gui/rich_text_label.h | 4 |
17 files changed, 117 insertions, 69 deletions
diff --git a/core/array.cpp b/core/array.cpp index 2e3fbf858d..30184a002e 100644 --- a/core/array.cpp +++ b/core/array.cpp @@ -47,11 +47,11 @@ void Array::_ref(const Array &p_from) const { ERR_FAIL_COND(!_fp); // should NOT happen. if (_fp == _p) - return; //wathever it is, nothing to do here move along + return; // whatever it is, nothing to do here move along bool success = _fp->refcount.ref(); - ERR_FAIL_COND(!success); //should really not happen either + ERR_FAIL_COND(!success); // should really not happen either _unref(); diff --git a/core/error_list.h b/core/error_list.h index bc65ad0ee4..50d248b3d0 100644 --- a/core/error_list.h +++ b/core/error_list.h @@ -66,7 +66,7 @@ enum Error { ERR_CANT_CONNECT, // (25) ERR_CANT_RESOLVE, ERR_CONNECTION_ERROR, - ERR_CANT_AQUIRE_RESOURCE, + ERR_CANT_ACQUIRE_RESOURCE, ERR_CANT_FORK, ERR_INVALID_DATA, ///< Data passed is invalid (30) ERR_INVALID_PARAMETER, ///< Parameter passed is invalid diff --git a/core/error_macros.h b/core/error_macros.h index 005b0e32a3..1fa7f2c134 100644 --- a/core/error_macros.h +++ b/core/error_macros.h @@ -30,6 +30,7 @@ #ifndef ERROR_MACROS_H #define ERROR_MACROS_H +#include "typedefs.h" /** * Error macros. Unlike exceptions and asserts, these macros try to mantain consistency and stability * inside the code. It is recommended to always return processable data, so in case of an error, the @@ -130,7 +131,7 @@ extern bool _err_error_exists; #define ERR_FAIL_INDEX(m_index, m_size) \ do { \ - if ((m_index) < 0 || (m_index) >= (m_size)) { \ + if (unlikely((m_index) < 0 || (m_index) >= (m_size))) { \ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Index " _STR(m_index) " out of size (" _STR(m_size) ")."); \ return; \ } else \ @@ -144,7 +145,7 @@ extern bool _err_error_exists; #define ERR_FAIL_INDEX_V(m_index, m_size, m_retval) \ do { \ - if ((m_index) < 0 || (m_index) >= (m_size)) { \ + if (unlikely((m_index) < 0 || (m_index) >= (m_size))) { \ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Index " _STR(m_index) " out of size (" _STR(m_size) ")."); \ return m_retval; \ } else \ @@ -156,7 +157,7 @@ extern bool _err_error_exists; */ #define CRASH_BAD_INDEX(m_index, m_size) \ do { \ - if ((m_index) < 0 || (m_index) >= (m_size)) { \ + if (unlikely((m_index) < 0 || (m_index) >= (m_size))) { \ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "FATAL: Index " _STR(m_index) " out of size (" _STR(m_size) ")."); \ GENERATE_TRAP \ } \ @@ -168,7 +169,7 @@ extern bool _err_error_exists; #define ERR_FAIL_NULL(m_param) \ { \ - if (!m_param) { \ + if (unlikely(!m_param)) { \ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Parameter ' " _STR(m_param) " ' is null."); \ return; \ } else \ @@ -177,7 +178,7 @@ extern bool _err_error_exists; #define ERR_FAIL_NULL_V(m_param, m_retval) \ { \ - if (!m_param) { \ + if (unlikely(!m_param)) { \ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Parameter ' " _STR(m_param) " ' is null."); \ return m_retval; \ } else \ @@ -190,7 +191,7 @@ extern bool _err_error_exists; #define ERR_FAIL_COND(m_cond) \ { \ - if (m_cond) { \ + if (unlikely(m_cond)) { \ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition ' " _STR(m_cond) " ' is true."); \ return; \ } else \ @@ -202,7 +203,7 @@ extern bool _err_error_exists; #define CRASH_COND(m_cond) \ { \ - if (m_cond) { \ + if (unlikely(m_cond)) { \ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "FATAL: Condition ' " _STR(m_cond) " ' is true."); \ GENERATE_TRAP \ } \ @@ -216,7 +217,7 @@ extern bool _err_error_exists; #define ERR_FAIL_COND_V(m_cond, m_retval) \ { \ - if (m_cond) { \ + if (unlikely(m_cond)) { \ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition ' " _STR(m_cond) " ' is true. returned: " _STR(m_retval)); \ return m_retval; \ } else \ @@ -229,7 +230,7 @@ extern bool _err_error_exists; #define ERR_CONTINUE(m_cond) \ { \ - if (m_cond) { \ + if (unlikely(m_cond)) { \ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition ' " _STR(m_cond) " ' is true. Continuing..:"); \ continue; \ } else \ @@ -242,7 +243,7 @@ extern bool _err_error_exists; #define ERR_BREAK(m_cond) \ { \ - if (m_cond) { \ + if (unlikely(m_cond)) { \ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition ' " _STR(m_cond) " ' is true. Breaking..:"); \ break; \ } else \ diff --git a/core/global_constants.cpp b/core/global_constants.cpp index 224ee0e0aa..6f58af2ccf 100644 --- a/core/global_constants.cpp +++ b/core/global_constants.cpp @@ -472,7 +472,7 @@ void register_global_constants() { BIND_GLOBAL_ENUM_CONSTANT(ERR_ALREADY_IN_USE); BIND_GLOBAL_ENUM_CONSTANT(ERR_LOCKED); ///< resource is locked BIND_GLOBAL_ENUM_CONSTANT(ERR_TIMEOUT); - BIND_GLOBAL_ENUM_CONSTANT(ERR_CANT_AQUIRE_RESOURCE); + BIND_GLOBAL_ENUM_CONSTANT(ERR_CANT_ACQUIRE_RESOURCE); BIND_GLOBAL_ENUM_CONSTANT(ERR_INVALID_DATA); ///< Data passed is invalid BIND_GLOBAL_ENUM_CONSTANT(ERR_INVALID_PARAMETER); ///< Parameter passed is invalid BIND_GLOBAL_ENUM_CONSTANT(ERR_ALREADY_EXISTS); ///< When adding ), item already exists diff --git a/core/image.cpp b/core/image.cpp index 4d1f32c360..70a7b2bceb 100644 --- a/core/image.cpp +++ b/core/image.cpp @@ -530,7 +530,7 @@ static void _scale_cubic(const uint8_t *p_src, uint8_t *p_dst, uint32_t p_src_wi int height = p_src_height; double xfac = (double)width / p_dst_width; double yfac = (double)height / p_dst_height; - // coordinates of source points and cooefficiens + // coordinates of source points and coefficients double ox, oy, dx, dy, k1, k2; int ox1, oy1, ox2, oy2; // destination pixel values @@ -561,7 +561,7 @@ static void _scale_cubic(const uint8_t *p_src, uint8_t *p_dst, uint32_t p_src_wi } for (int n = -1; n < 3; n++) { - // get Y cooefficient + // get Y coefficient k1 = _bicubic_interp_kernel(dy - (double)n); oy2 = oy1 + n; @@ -571,7 +571,7 @@ static void _scale_cubic(const uint8_t *p_src, uint8_t *p_dst, uint32_t p_src_wi oy2 = ymax; for (int m = -1; m < 3; m++) { - // get X cooefficient + // get X coefficient k2 = k1 * _bicubic_interp_kernel((double)m - dx); ox2 = ox1 + m; diff --git a/core/object.cpp b/core/object.cpp index b1770f1d7a..823cbe14d4 100644 --- a/core/object.cpp +++ b/core/object.cpp @@ -1052,7 +1052,7 @@ Variant Object::_emit_signal(const Variant **p_args, int p_argcount, Variant::Ca Error Object::emit_signal(const StringName &p_name, const Variant **p_args, int p_argcount) { if (_block_signals) - return ERR_CANT_AQUIRE_RESOURCE; //no emit, signals blocked + return ERR_CANT_ACQUIRE_RESOURCE; //no emit, signals blocked Signal *s = signal_map.getptr(p_name); if (!s) { diff --git a/core/object.h b/core/object.h index 3070439138..7af2c78fc3 100644 --- a/core/object.h +++ b/core/object.h @@ -64,9 +64,9 @@ enum PropertyHint { PROPERTY_HINT_LAYERS_3D_RENDER, PROPERTY_HINT_LAYERS_3D_PHYSICS, PROPERTY_HINT_FILE, ///< a file path must be passed, hint_text (optionally) is a filter "*.png,*.wav,*.doc," - PROPERTY_HINT_DIR, ///< a directort path must be passed + PROPERTY_HINT_DIR, ///< a directory path must be passed PROPERTY_HINT_GLOBAL_FILE, ///< a file path must be passed, hint_text (optionally) is a filter "*.png,*.wav,*.doc," - PROPERTY_HINT_GLOBAL_DIR, ///< a directort path must be passed + PROPERTY_HINT_GLOBAL_DIR, ///< a directory path must be passed PROPERTY_HINT_RESOURCE_TYPE, ///< a resource object type PROPERTY_HINT_MULTILINE_TEXT, ///< used for string properties that can contain multiple lines PROPERTY_HINT_COLOR_NO_ALPHA, ///< used for ignoring alpha component when editing a color @@ -221,7 +221,7 @@ struct MethodInfo { //return NULL; /* - the following is an uncomprehensible blob of hacks and workarounds to compensate for many of the fallencies in C++. As a plus, this macro pretty much alone defines the object model. + the following is an incomprehensible blob of hacks and workarounds to compensate for many of the fallencies in C++. As a plus, this macro pretty much alone defines the object model. */ #define REVERSE_GET_PROPERTY_LIST \ diff --git a/core/typedefs.h b/core/typedefs.h index 565e28020b..bf5c8b0f75 100644 --- a/core/typedefs.h +++ b/core/typedefs.h @@ -290,4 +290,12 @@ struct _GlobalLock { #define __STRX(m_index) #m_index #define __STR(m_index) __STRX(m_index) +#ifdef __GNUC__ +#define likely(x) __builtin_expect(!!(x), 1) +#define unlikely(x) __builtin_expect(!!(x), 0) +#else +#define likely(x) x +#define unlikely(x) x +#endif + #endif /* typedefs.h */ diff --git a/core/ustring.cpp b/core/ustring.cpp index 8273ed144b..b85996e3d1 100644 --- a/core/ustring.cpp +++ b/core/ustring.cpp @@ -1755,7 +1755,7 @@ static double built_in_strtod(const C *string, /* A decimal ASCII floating-point register int c; int exp = 0; /* Exponent read from "EX" field. */ int fracExp = 0; /* Exponent that derives from the fractional - * part. Under normal circumstatnces, it is + * part. Under normal circumstances, it is * the negative of the number of digits in F. * However, if I is very long, the last digits * of I get dropped (otherwise a long I with a @@ -2332,12 +2332,12 @@ int String::findn(String p_str, int p_from) const { int String::rfind(String p_str, int p_from) const { - //stabilish a limit + // establish a limit int limit = length() - p_str.length(); if (limit < 0) return -1; - //stabilish a starting point + // establish a starting point if (p_from < 0) p_from = limit; else if (p_from > limit) @@ -2347,7 +2347,7 @@ int String::rfind(String p_str, int p_from) const { int len = length(); if (src_len == 0 || len == 0) - return -1; //wont find anything! + return -1; // won't find anything! const CharType *src = c_str(); @@ -2378,12 +2378,12 @@ int String::rfind(String p_str, int p_from) const { } int String::rfindn(String p_str, int p_from) const { - //stabilish a limit + // establish a limit int limit = length() - p_str.length(); if (limit < 0) return -1; - //stabilish a starting point + // establish a starting point if (p_from < 0) p_from = limit; else if (p_from > limit) diff --git a/core/variant.cpp b/core/variant.cpp index 52bdd4e22d..f70e4a5218 100644 --- a/core/variant.cpp +++ b/core/variant.cpp @@ -2469,10 +2469,10 @@ Variant::Variant(const Vector<Color> &p_array) { void Variant::operator=(const Variant &p_variant) { - if (this == &p_variant) + if (unlikely(this == &p_variant)) return; - if (type != p_variant.type) { + if (unlikely(type != p_variant.type)) { reference(p_variant); return; } diff --git a/doc/classes/@Global Scope.xml b/doc/classes/@Global Scope.xml index a8fd377ecf..d8c9a57a88 100644 --- a/doc/classes/@Global Scope.xml +++ b/doc/classes/@Global Scope.xml @@ -1013,7 +1013,7 @@ </constant> <constant name="ERR_TIMEOUT" value="24"> </constant> - <constant name="ERR_CANT_AQUIRE_RESOURCE" value="28"> + <constant name="ERR_CANT_ACQUIRE_RESOURCE" value="28"> </constant> <constant name="ERR_INVALID_DATA" value="30"> </constant> diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index bc5f11e734..e621394a07 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -2693,7 +2693,8 @@ void CanvasItemEditor::_draw_viewport() { _draw_grid(); _draw_selection(); _draw_axis(); - _draw_locks_and_groups(editor->get_edited_scene(), transform); + if (editor->get_edited_scene()) + _draw_locks_and_groups(editor->get_edited_scene(), transform); RID ci = viewport->get_canvas_item(); VisualServer::get_singleton()->canvas_item_add_set_transform(ci, Transform2D()); diff --git a/modules/gdnative/include/gdnative/gdnative.h b/modules/gdnative/include/gdnative/gdnative.h index 1c5e91d733..18d51daeb3 100644 --- a/modules/gdnative/include/gdnative/gdnative.h +++ b/modules/gdnative/include/gdnative/gdnative.h @@ -103,7 +103,7 @@ typedef enum { GODOT_ERR_CANT_CONNECT, // (25) GODOT_ERR_CANT_RESOLVE, GODOT_ERR_CONNECTION_ERROR, - GODOT_ERR_CANT_AQUIRE_RESOURCE, + GODOT_ERR_CANT_ACQUIRE_RESOURCE, GODOT_ERR_CANT_FORK, GODOT_ERR_INVALID_DATA, ///< Data passed is invalid (30) GODOT_ERR_INVALID_PARAMETER, ///< Parameter passed is invalid diff --git a/modules/gdscript/gd_function.cpp b/modules/gdscript/gd_function.cpp index df7b16c96e..70340f0823 100644 --- a/modules/gdscript/gd_function.cpp +++ b/modules/gdscript/gd_function.cpp @@ -42,7 +42,7 @@ Variant *GDFunction::_get_variant(int p_address, GDInstance *p_instance, GDScrip case ADDR_TYPE_SELF: { - if (!p_instance) { + if (unlikely(!p_instance)) { r_error = "Cannot access self without instance."; return NULL; } @@ -54,7 +54,7 @@ Variant *GDFunction::_get_variant(int p_address, GDInstance *p_instance, GDScrip } break; case ADDR_TYPE_MEMBER: { //member indexing is O(1) - if (!p_instance) { + if (unlikely(!p_instance)) { r_error = "Cannot access member without instance."; return NULL; } @@ -279,7 +279,7 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a #define GET_VARIANT_PTR(m_v, m_code_ofs) \ Variant *m_v; \ m_v = _get_variant(_code_ptr[ip + m_code_ofs], p_instance, _class, self, stack, err_text); \ - if (!m_v) \ + if (unlikely(!m_v)) \ break; #else diff --git a/platform/uwp/gl_context_egl.cpp b/platform/uwp/gl_context_egl.cpp index dd186c97d6..ed3db65cdf 100644 --- a/platform/uwp/gl_context_egl.cpp +++ b/platform/uwp/gl_context_egl.cpp @@ -31,7 +31,7 @@ #include "EGL/eglext.h" -using namespace Platform; +using Platform::Exception; void ContextEGL::release_current() { @@ -103,23 +103,23 @@ Error ContextEGL::initialize() { const EGLint displayAttributes[] = { - /*EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, - EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, 9, - EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, 3, - EGL_NONE,*/ - // These are the default display attributes, used to request ANGLE's D3D11 renderer. - // eglInitialize will only succeed with these attributes if the hardware supports D3D11 Feature Level 10_0+. - EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, - - // EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER is an optimization that can have large performance benefits on mobile devices. - // Its syntax is subject to change, though. Please update your Visual Studio templates if you experience compilation issues with it. - //EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER, EGL_TRUE, - - // EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE is an option that enables ANGLE to automatically call - // the IDXGIDevice3::Trim method on behalf of the application when it gets suspended. - // Calling IDXGIDevice3::Trim when an application is suspended is a Windows Store application certification requirement. - EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE, EGL_TRUE, - EGL_NONE, + /*EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, + EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, 9, + EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, 3, + EGL_NONE,*/ + // These are the default display attributes, used to request ANGLE's D3D11 renderer. + // eglInitialize will only succeed with these attributes if the hardware supports D3D11 Feature Level 10_0+. + EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, + + // EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER is an optimization that can have large performance benefits on mobile devices. + // Its syntax is subject to change, though. Please update your Visual Studio templates if you experience compilation issues with it. + //EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER, EGL_TRUE, + + // EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE is an option that enables ANGLE to automatically call + // the IDXGIDevice3::Trim method on behalf of the application when it gets suspended. + // Calling IDXGIDevice3::Trim when an application is suspended is a Windows Store application certification requirement. + EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE, EGL_TRUE, + EGL_NONE, }; PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT = reinterpret_cast<PFNEGLGETPLATFORMDISPLAYEXTPROC>(eglGetProcAddress("eglGetPlatformDisplayEXT")); diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index 71b9c4ec72..d9287e6f63 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -84,7 +84,7 @@ Rect2 RichTextLabel::_get_text_rect() { Ref<StyleBox> style = get_stylebox("normal"); return Rect2(style->get_offset(), get_size() - style->get_minimum_size()); } -void RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &y, int p_width, int p_line, ProcessMode p_mode, const Ref<Font> &p_base_font, const Color &p_base_color, const Point2i &p_click_pos, Item **r_click_item, int *r_click_char, bool *r_outside, int p_char_count) { +int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &y, int p_width, int p_line, ProcessMode p_mode, const Ref<Font> &p_base_font, const Color &p_base_color, const Point2i &p_click_pos, Item **r_click_item, int *r_click_char, bool *r_outside, int p_char_count) { RID ci; if (r_outside) @@ -104,9 +104,11 @@ void RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int int line = 0; int spaces = 0; + int height = get_size().y; + if (p_mode != PROCESS_CACHE) { - ERR_FAIL_INDEX(line, l.offset_caches.size()); + ERR_FAIL_INDEX_V(line, l.offset_caches.size(), 0); line_ofs = l.offset_caches[line]; } @@ -133,12 +135,20 @@ void RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int //line height should be the font height for the first time, this ensures that an empty line will never have zero height and successive newlines are displayed int line_height = cfont->get_height(); + int nonblank_line_count = 0; //number of nonblank lines as counted during PROCESS_DRAW + Variant meta; +#define RETURN return nonblank_line_count + #define NEW_LINE \ { \ if (p_mode != PROCESS_CACHE) { \ line++; \ + if (!line_is_blank) { \ + nonblank_line_count++; \ + } \ + line_is_blank = true; \ if (line < l.offset_caches.size()) \ line_ofs = l.offset_caches[line]; \ wofs = margin; \ @@ -168,7 +178,7 @@ void RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int if (r_outside) *r_outside = true; \ *r_click_item = it; \ *r_click_char = rchar; \ - return; \ + RETURN; \ } \ } @@ -185,7 +195,7 @@ void RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int if (r_outside) *r_outside = true; \ *r_click_item = it; \ *r_click_char = rchar; \ - return; \ + RETURN; \ } \ NEW_LINE \ } @@ -196,7 +206,7 @@ void RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int if (r_outside) *r_outside = false; \ *r_click_item = it; \ *r_click_char = rchar; \ - return; \ + RETURN; \ } \ wofs += m_width; \ } @@ -206,6 +216,9 @@ void RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int line_height = m_height; \ } +#define YRANGE_VISIBLE(m_top, m_height) \ + (m_height > 0 && ((m_top >= 0 && m_top < height) || ((m_top + m_height - 1) >= 0 && (m_top + m_height - 1) < height))) + Color selection_fg; Color selection_bg; @@ -214,8 +227,10 @@ void RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int selection_fg = get_color("font_color_selected"); selection_bg = get_color("selection_color"); } + int rchar = 0; int lh = 0; + bool line_is_blank = true; while (it) { @@ -327,7 +342,10 @@ void RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int int cw = 0; - bool visible = visible_characters < 0 || p_char_count < visible_characters; + bool visible = visible_characters < 0 || p_char_count < visible_characters && YRANGE_VISIBLE(y + lh - (fh - 0 * ascent), fh); //getting rid of ascent seems to work?? + if (visible) + line_is_blank = false; + if (c[i] == '\t') visible = false; @@ -384,7 +402,9 @@ void RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int ENSURE_WIDTH(img->image->get_width()); - bool visible = visible_characters < 0 || p_char_count < visible_characters; + bool visible = visible_characters < 0 || p_char_count < visible_characters && YRANGE_VISIBLE(y + lh - font->get_descent() - img->image->get_height(), img->image->get_height()); + if (visible) + line_is_blank = false; if (p_mode == PROCESS_DRAW && visible) { img->image->draw(ci, p_ofs + Point2(align_ofs + wofs, y + lh - font->get_descent() - img->image->get_height())); @@ -398,8 +418,10 @@ void RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int case ITEM_NEWLINE: { lh = 0; - if (p_mode != PROCESS_CACHE) + if (p_mode != PROCESS_CACHE) { lh = line < l.height_caches.size() ? l.height_caches[line] : 1; + line_is_blank = true; + } } break; case ITEM_TABLE: { @@ -436,7 +458,7 @@ void RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int idx++; } - //compute available width and total radio (for expanders) + //compute available width and total ratio (for expanders) int total_ratio = 0; int available_width = p_width - hseparation * (table->columns.size() - 1); @@ -494,12 +516,14 @@ void RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int int lines_ofs = p_ofs.y + offset.y + draw_ofs.y; bool visible = lines_ofs < get_size().height && lines_ofs + lines_h >= 0; + if (visible) + line_is_blank = false; for (int i = 0; i < frame->lines.size(); i++) { if (visible) { if (p_mode == PROCESS_DRAW) { - _process_line(frame, p_ofs + offset + draw_ofs + Vector2(0, yofs), ly, table->columns[column].width, i, PROCESS_DRAW, cfont, ccolor); + nonblank_line_count += _process_line(frame, p_ofs + offset + draw_ofs + Vector2(0, yofs), ly, table->columns[column].width, i, PROCESS_DRAW, cfont, ccolor); } else if (p_mode == PROCESS_POINTER) { _process_line(frame, p_ofs + offset + draw_ofs + Vector2(0, yofs), ly, table->columns[column].width, i, PROCESS_POINTER, cfont, ccolor, p_click_pos, r_click_item, r_click_char, r_outside); } @@ -547,15 +571,17 @@ void RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int if (r_outside) *r_outside = true; *r_click_item = itp; *r_click_char = rchar; - return; + RETURN; } break; } } - NEW_LINE; + RETURN; + +#undef RETURN #undef NEW_LINE #undef ENSURE_WIDTH #undef ADVANCE @@ -665,14 +691,14 @@ void RichTextLabel::_notification(int p_what) { if (from_line >= main->lines.size()) break; //nothing to draw - int y = (main->lines[from_line].height_accum_cache - main->lines[from_line].height_cache) - ofs; Ref<Font> base_font = get_font("normal_font"); Color base_color = get_color("default_color"); + visible_line_count = 0; while (y < size.height && from_line < main->lines.size()) { - _process_line(main, text_rect.get_position(), y, text_rect.get_size().width - scroll_w, from_line, PROCESS_DRAW, base_font, base_color, Point2i(), NULL, NULL, NULL, total_chars); + visible_line_count += _process_line(main, text_rect.get_position(), y, text_rect.get_size().width - scroll_w, from_line, PROCESS_DRAW, base_font, base_color, Point2i(), NULL, NULL, NULL, total_chars); total_chars += main->lines[from_line].char_count; from_line++; } @@ -1013,7 +1039,7 @@ void RichTextLabel::_validate_line_caches(ItemFrame *p_frame) { if (p_frame->first_invalid_line == p_frame->lines.size()) return; - //validate invalid lines!s + //validate invalid lines Size2 size = get_size(); Rect2 text_rect = _get_text_rect(); @@ -1665,6 +1691,12 @@ int RichTextLabel::get_line_count() const { return current_frame->lines.size(); } +int RichTextLabel::get_visible_line_count() const { + if (!is_visible()) + return 0; + return visible_line_count; +} + void RichTextLabel::set_selection_enabled(bool p_enabled) { selection.enabled = p_enabled; @@ -1907,6 +1939,9 @@ void RichTextLabel::_bind_methods() { ClassDB::bind_method(D_METHOD("set_use_bbcode", "enable"), &RichTextLabel::set_use_bbcode); ClassDB::bind_method(D_METHOD("is_using_bbcode"), &RichTextLabel::is_using_bbcode); + ClassDB::bind_method(D_METHOD("get_line_count"), &RichTextLabel::get_line_count); + ClassDB::bind_method(D_METHOD("get_visible_line_count"), &RichTextLabel::get_visible_line_count); + ADD_GROUP("BBCode", "bbcode_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "bbcode_enabled"), "set_use_bbcode", "is_using_bbcode"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "bbcode_text", PROPERTY_HINT_MULTILINE_TEXT), "set_bbcode", "get_bbcode"); @@ -1995,6 +2030,7 @@ RichTextLabel::RichTextLabel() { visible_characters = -1; percent_visible = 1; + visible_line_count = 0; set_clip_contents(true); } diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h index 4db2c3a8e9..24c1e5eb59 100644 --- a/scene/gui/rich_text_label.h +++ b/scene/gui/rich_text_label.h @@ -217,6 +217,7 @@ private: int scroll_w; bool updating_scroll; int current_idx; + int visible_line_count; int tab_size; bool underline_meta; @@ -260,7 +261,7 @@ private: int visible_characters; float percent_visible; - void _process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &y, int p_width, int p_line, ProcessMode p_mode, const Ref<Font> &p_base_font, const Color &p_base_color, const Point2i &p_click_pos = Point2i(), Item **r_click_item = NULL, int *r_click_char = NULL, bool *r_outside = NULL, int p_char_count = 0); + int _process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &y, int p_width, int p_line, ProcessMode p_mode, const Ref<Font> &p_base_font, const Color &p_base_color, const Point2i &p_click_pos = Point2i(), Item **r_click_item = NULL, int *r_click_char = NULL, bool *r_outside = NULL, int p_char_count = 0); void _find_click(ItemFrame *p_frame, const Point2i &p_click, Item **r_click_item = NULL, int *r_click_char = NULL, bool *r_outside = NULL); Ref<Font> _find_font(Item *p_item); @@ -325,6 +326,7 @@ public: void scroll_to_line(int p_line); int get_line_count() const; + int get_visible_line_count() const; VScrollBar *get_v_scroll() { return vscroll; } |