summaryrefslogtreecommitdiff
path: root/scene/resources
diff options
context:
space:
mode:
Diffstat (limited to 'scene/resources')
-rw-r--r--scene/resources/default_theme/default_theme.cpp30
-rw-r--r--scene/resources/default_theme/tab_current.pngbin346 -> 754 bytes
-rw-r--r--scene/resources/default_theme/theme_data.h2
-rw-r--r--scene/resources/environment.cpp22
-rw-r--r--scene/resources/environment.h13
-rw-r--r--scene/resources/font.cpp880
-rw-r--r--scene/resources/font.h12
-rw-r--r--scene/resources/material.cpp12
-rw-r--r--scene/resources/material.h1
-rw-r--r--scene/resources/mesh.cpp184
-rw-r--r--scene/resources/packed_scene.cpp14
-rw-r--r--scene/resources/primitive_meshes.h3
-rw-r--r--scene/resources/separation_ray_shape_2d.cpp16
-rw-r--r--scene/resources/separation_ray_shape_3d.cpp7
-rw-r--r--scene/resources/skin.cpp1
-rw-r--r--scene/resources/sky_material.cpp49
-rw-r--r--scene/resources/sky_material.h7
-rw-r--r--scene/resources/style_box.cpp23
-rw-r--r--scene/resources/syntax_highlighter.cpp48
-rw-r--r--scene/resources/text_paragraph.cpp20
-rw-r--r--scene/resources/texture.cpp6
-rw-r--r--scene/resources/theme.cpp138
-rw-r--r--scene/resources/theme.h56
-rw-r--r--scene/resources/tile_set.cpp94
-rw-r--r--scene/resources/visual_shader.cpp6
-rw-r--r--scene/resources/visual_shader.h2
-rw-r--r--scene/resources/world_boundary_shape_3d.cpp23
27 files changed, 1262 insertions, 407 deletions
diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp
index dd1c5b3711..c22f16cbde 100644
--- a/scene/resources/default_theme/default_theme.cpp
+++ b/scene/resources/default_theme/default_theme.cpp
@@ -407,6 +407,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_constant("minimum_character_width", "LineEdit", 4);
theme->set_constant("outline_size", "LineEdit", 0);
+ theme->set_constant("caret_width", "LineEdit", 1);
theme->set_icon("clear", "LineEdit", make_icon(line_edit_clear_png));
@@ -451,6 +452,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_constant("line_spacing", "TextEdit", 4 * scale);
theme->set_constant("outline_size", "TextEdit", 0);
+ theme->set_constant("caret_width", "TextEdit", 1);
// CodeEdit
@@ -770,8 +772,8 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
tc_sb->set_default_margin(SIDE_TOP, 8 * scale);
theme->set_stylebox("tab_selected", "TabContainer", sb_expand(make_stylebox(tab_current_png, 4, 4, 4, 1, 16, 4, 16, 4), 2, 2, 2, 2));
- theme->set_stylebox("tab_unselected", "TabContainer", sb_expand(make_stylebox(tab_behind_png, 5, 5, 5, 1, 16, 6, 16, 4), 3, 0, 3, 3));
- theme->set_stylebox("tab_disabled", "TabContainer", sb_expand(make_stylebox(tab_disabled_png, 5, 5, 5, 1, 16, 6, 16, 4), 3, 0, 3, 3));
+ theme->set_stylebox("tab_unselected", "TabContainer", sb_expand(make_stylebox(tab_behind_png, 5, 5, 5, 1, 16, 6, 16, 4), 3, 0, 3, 0));
+ theme->set_stylebox("tab_disabled", "TabContainer", sb_expand(make_stylebox(tab_disabled_png, 5, 5, 5, 1, 16, 6, 16, 4), 3, 0, 3, 0));
theme->set_stylebox("panel", "TabContainer", tc_sb);
theme->set_icon("increment", "TabContainer", make_icon(scroll_button_right_png));
@@ -795,9 +797,9 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
// TabBar
- theme->set_stylebox("tab_selected", "TabBar", sb_expand(make_stylebox(tab_current_png, 4, 3, 4, 1, 16, 3, 16, 2), 2, 2, 2, 2));
- theme->set_stylebox("tab_unselected", "TabBar", sb_expand(make_stylebox(tab_behind_png, 5, 4, 5, 1, 16, 5, 16, 2), 3, 3, 3, 3));
- theme->set_stylebox("tab_disabled", "TabBar", sb_expand(make_stylebox(tab_disabled_png, 5, 5, 5, 1, 16, 6, 16, 4), 3, 0, 3, 3));
+ theme->set_stylebox("tab_selected", "TabBar", sb_expand(make_stylebox(tab_current_png, 4, 4, 4, 1, 16, 4, 16, 4), 2, 2, 2, 2));
+ theme->set_stylebox("tab_unselected", "TabBar", sb_expand(make_stylebox(tab_behind_png, 5, 5, 5, 1, 16, 6, 16, 4), 3, 0, 3, 0));
+ theme->set_stylebox("tab_disabled", "TabBar", sb_expand(make_stylebox(tab_disabled_png, 5, 5, 5, 1, 16, 6, 16, 4), 3, 0, 3, 0));
theme->set_stylebox("close_bg_pressed", "TabBar", make_stylebox(button_pressed_png, 4, 4, 4, 4));
theme->set_stylebox("close_bg_highlight", "TabBar", make_stylebox(button_normal_png, 4, 4, 4, 4));
@@ -998,7 +1000,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
// Visual Node Ports
theme->set_constant("port_grab_distance_horizontal", "GraphEdit", 24 * scale);
- theme->set_constant("port_grab_distance_vertical", "GraphEdit", 6 * scale);
+ theme->set_constant("port_grab_distance_vertical", "GraphEdit", 26 * scale);
theme->set_stylebox("bg", "GraphEditMinimap", make_flat_stylebox(Color(0.24, 0.24, 0.24), 0, 0, 0, 0));
Ref<StyleBoxFlat> style_minimap_camera = make_flat_stylebox(Color(0.65, 0.65, 0.65, 0.2), 0, 0, 0, 0);
@@ -1057,17 +1059,17 @@ void make_default_theme(bool p_hidpi, Ref<Font> p_font) {
fill_default_theme(t, default_font, large_font, default_icon, default_style, default_scale);
Theme::set_default(t);
- Theme::set_default_base_scale(default_scale);
- Theme::set_default_icon(default_icon);
- Theme::set_default_style(default_style);
- Theme::set_default_font(default_font);
- Theme::set_default_font_size(default_font_size);
+ Theme::set_fallback_base_scale(default_scale);
+ Theme::set_fallback_icon(default_icon);
+ Theme::set_fallback_style(default_style);
+ Theme::set_fallback_font(default_font);
+ Theme::set_fallback_font_size(default_font_size);
}
void clear_default_theme() {
Theme::set_project_default(nullptr);
Theme::set_default(nullptr);
- Theme::set_default_icon(nullptr);
- Theme::set_default_style(nullptr);
- Theme::set_default_font(nullptr);
+ Theme::set_fallback_icon(nullptr);
+ Theme::set_fallback_style(nullptr);
+ Theme::set_fallback_font(nullptr);
}
diff --git a/scene/resources/default_theme/tab_current.png b/scene/resources/default_theme/tab_current.png
index d5641e917a..ce2b9b0925 100644
--- a/scene/resources/default_theme/tab_current.png
+++ b/scene/resources/default_theme/tab_current.png
Binary files differ
diff --git a/scene/resources/default_theme/theme_data.h b/scene/resources/default_theme/theme_data.h
index 57ff9a5325..1cec50eab4 100644
--- a/scene/resources/default_theme/theme_data.h
+++ b/scene/resources/default_theme/theme_data.h
@@ -395,7 +395,7 @@ static const unsigned char tab_container_bg_png[] = {
};
static const unsigned char tab_current_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x99, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3f, 0x3d, 0x48, 0x5b, 0x58, 0x66, 0x5b, 0x57, 0x65, 0x57, 0x54, 0x62, 0x55, 0x53, 0x62, 0x4a, 0x46, 0x52, 0x46, 0x41, 0x4e, 0x45, 0x41, 0x4d, 0x55, 0x52, 0x60, 0x44, 0x41, 0x4c, 0x53, 0x50, 0x5e, 0x43, 0x40, 0x4b, 0x52, 0x4e, 0x5d, 0x41, 0x3e, 0x4a, 0x4f, 0x4d, 0x5a, 0x3f, 0x3d, 0x48, 0x4e, 0x4b, 0x59, 0x3e, 0x3c, 0x47, 0x4d, 0x4a, 0x58, 0x3d, 0x3b, 0x46, 0x4b, 0x49, 0x54, 0x3c, 0x3a, 0x44, 0x4b, 0x47, 0x54, 0x3b, 0x39, 0x43, 0x3b, 0x39, 0x42, 0x3b, 0x38, 0x43, 0x3b, 0x38, 0x42, 0x3a, 0x37, 0x41, 0x39, 0x37, 0x41, 0x3a, 0x38, 0x41, 0x39, 0x36, 0x3f, 0x38, 0x36, 0x3f, 0x39, 0x36, 0x40, 0x38, 0x36, 0x40, 0x37, 0x35, 0x3e, 0x37, 0x34, 0x3e, 0x36, 0x35, 0x3d, 0xd7, 0x41, 0xa4, 0x19, 0x0, 0x0, 0x0, 0x11, 0x74, 0x52, 0x4e, 0x53, 0x4, 0xa, 0x11, 0x19, 0x1f, 0x22, 0x24, 0x15, 0x25, 0x34, 0x3f, 0x46, 0x47, 0x48, 0x77, 0xef, 0xef, 0xa3, 0x31, 0x6b, 0xc2, 0x0, 0x0, 0x0, 0x5f, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x55, 0xca, 0x85, 0xd, 0xc0, 0x40, 0x14, 0xc3, 0x50, 0x27, 0xf7, 0xd5, 0xfd, 0xd7, 0x2d, 0xa6, 0x4c, 0x16, 0x3f, 0x59, 0xe8, 0x8, 0xc8, 0x91, 0xd4, 0x5d, 0x92, 0xa3, 0xa1, 0x76, 0xb1, 0xd8, 0xcb, 0x92, 0x41, 0x1b, 0xb8, 0xe9, 0x2, 0xcf, 0xd2, 0x7e, 0xc4, 0x9c, 0x2d, 0xed, 0x3c, 0xc4, 0x95, 0xa3, 0x3f, 0xb0, 0x3, 0x7f, 0xa0, 0xe0, 0xb, 0x50, 0xe4, 0xb, 0xa1, 0xf2, 0x87, 0x38, 0x31, 0x4f, 0x4e, 0xa, 0x30, 0x22, 0x58, 0x33, 0x81, 0x1d, 0x4a, 0x44, 0x5a, 0xec, 0x8c, 0x27, 0x34, 0x10, 0x58, 0xf1, 0xf8, 0x39, 0xe0, 0x60, 0x56, 0x63, 0x63, 0x30, 0x69, 0xf8, 0x3c, 0xb4, 0xd1, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x1, 0x71, 0x69, 0x43, 0x43, 0x50, 0x69, 0x63, 0x63, 0x0, 0x0, 0x28, 0x91, 0x75, 0x91, 0x3d, 0x4b, 0xc3, 0x50, 0x14, 0x86, 0xdf, 0xb6, 0x8a, 0xa2, 0x91, 0xe, 0x15, 0x11, 0x71, 0xc8, 0x50, 0xc5, 0xa1, 0x85, 0xa2, 0x20, 0x8e, 0x5a, 0x87, 0x2e, 0x45, 0x4a, 0xad, 0x60, 0xd5, 0x25, 0xb9, 0x4d, 0x5a, 0x21, 0x49, 0xc3, 0x4d, 0x8a, 0x14, 0x57, 0xc1, 0xc5, 0xa1, 0xe0, 0x20, 0xba, 0xf8, 0x35, 0xf8, 0xf, 0x74, 0x15, 0x5c, 0x15, 0x4, 0x41, 0x11, 0x44, 0x9c, 0xfc, 0x1, 0x7e, 0x2d, 0x52, 0xe2, 0xb9, 0x4d, 0xa1, 0x45, 0xda, 0x13, 0x6e, 0xce, 0xc3, 0x7b, 0xcf, 0x7b, 0xb8, 0xf7, 0x5c, 0x20, 0x98, 0x36, 0x98, 0xe9, 0xf4, 0x24, 0x0, 0xd3, 0x72, 0x79, 0x36, 0x95, 0x94, 0x57, 0xf3, 0x6b, 0x72, 0xdf, 0x3b, 0x2, 0x90, 0x30, 0x82, 0x8, 0x24, 0x85, 0x39, 0xf6, 0x42, 0x26, 0x93, 0x46, 0xd7, 0xf8, 0x79, 0xa4, 0x6a, 0x8a, 0x87, 0xb8, 0xe8, 0xd5, 0xbd, 0xae, 0x63, 0xc, 0x16, 0x34, 0x87, 0x1, 0x81, 0x7e, 0xe2, 0x59, 0x66, 0x73, 0x97, 0x78, 0x9e, 0x38, 0xbd, 0xe5, 0xda, 0x82, 0xf7, 0x88, 0x87, 0x59, 0x49, 0x29, 0x10, 0x9f, 0x10, 0xc7, 0x38, 0x1d, 0x90, 0xf8, 0x56, 0xe8, 0xaa, 0xcf, 0x6f, 0x82, 0x8b, 0x3e, 0x7f, 0x9, 0xe6, 0xb9, 0xec, 0x22, 0x10, 0x14, 0x3d, 0xe5, 0x62, 0x1b, 0xab, 0x6d, 0xcc, 0x4a, 0xdc, 0x24, 0x9e, 0x22, 0x8e, 0x9a, 0x46, 0x85, 0x35, 0xcf, 0x23, 0x6e, 0x22, 0x69, 0xd6, 0xca, 0x32, 0xe5, 0x31, 0x5a, 0xe3, 0x70, 0x90, 0x45, 0xa, 0x49, 0xc8, 0x50, 0x51, 0xc1, 0x26, 0xc, 0xb8, 0x88, 0x53, 0xb6, 0x68, 0x66, 0x9d, 0x7d, 0x89, 0x86, 0x6f, 0x9, 0x65, 0xf2, 0x30, 0xfa, 0xdb, 0xa8, 0x82, 0x93, 0xa3, 0x88, 0x12, 0x79, 0x63, 0xa4, 0x56, 0xa8, 0xab, 0x46, 0x59, 0x27, 0x5d, 0xa3, 0xcf, 0x40, 0x55, 0xcc, 0xfd, 0xff, 0x3c, 0x1d, 0x7d, 0x66, 0xda, 0xef, 0x2e, 0x25, 0x81, 0xde, 0x57, 0xcf, 0xfb, 0x9c, 0x0, 0xfa, 0xf6, 0x81, 0x7a, 0xcd, 0xf3, 0x7e, 0x4f, 0x3d, 0xaf, 0x7e, 0x6, 0x84, 0x5e, 0x80, 0x6b, 0xab, 0xe5, 0x2f, 0xd3, 0x9c, 0xe6, 0xbe, 0x49, 0xaf, 0xb5, 0xb4, 0xe8, 0x31, 0x10, 0xde, 0x1, 0x2e, 0x6f, 0x5a, 0x9a, 0x7a, 0x0, 0x5c, 0xed, 0x2, 0xa3, 0xcf, 0xb6, 0xc2, 0x95, 0x86, 0x14, 0xa2, 0x15, 0xd4, 0x75, 0xe0, 0xe3, 0x2, 0x18, 0xca, 0x3, 0x91, 0x7b, 0x60, 0x60, 0xdd, 0x9f, 0x55, 0x73, 0x1f, 0xe7, 0x4f, 0x40, 0x6e, 0x9b, 0x9e, 0xe8, 0xe, 0x38, 0x3c, 0x2, 0x26, 0xa9, 0x3e, 0xbc, 0xf1, 0x7, 0x9c, 0x2f, 0x67, 0xdc, 0x46, 0x9a, 0x3c, 0x4e, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x12, 0x0, 0x0, 0xb, 0x12, 0x1, 0xd2, 0xdd, 0x7e, 0xfc, 0x0, 0x0, 0x1, 0x27, 0x49, 0x44, 0x41, 0x54, 0x38, 0xcb, 0x9d, 0x93, 0x41, 0x4e, 0xc3, 0x30, 0x10, 0x45, 0xc7, 0xee, 0xd0, 0x82, 0x58, 0xd4, 0x6b, 0x28, 0xdc, 0x4, 0xc1, 0x92, 0x35, 0xa7, 0xe9, 0x11, 0x38, 0xd, 0x6b, 0x36, 0x2c, 0x10, 0x3b, 0xee, 0xc0, 0x6, 0x95, 0x1d, 0x6a, 0x83, 0x54, 0x4, 0xad, 0x1d, 0xf, 0x7f, 0xf0, 0x4, 0xb5, 0x52, 0x11, 0xe, 0x3f, 0x7a, 0x91, 0x93, 0x7c, 0xff, 0x78, 0x9c, 0x89, 0x23, 0x22, 0x6, 0x43, 0x30, 0x2, 0xfb, 0x36, 0x1e, 0x0, 0x4f, 0xdb, 0xca, 0xa0, 0x5, 0x6b, 0xf0, 0x9, 0x56, 0x3a, 0xee, 0x26, 0x1f, 0x82, 0x0, 0xc6, 0x36, 0xd6, 0x30, 0x67, 0xa8, 0xc4, 0xd0, 0x49, 0xef, 0xe0, 0xd, 0x34, 0x64, 0x6f, 0x57, 0x73, 0x38, 0x3f, 0xbb, 0xbc, 0x9a, 0x1c, 0x9f, 0x4e, 0x53, 0x4a, 0x21, 0xb, 0xed, 0x94, 0x47, 0x1c, 0x33, 0x37, 0xb3, 0x97, 0xe7, 0xeb, 0xfb, 0x87, 0xdb, 0x1b, 0xdc, 0x4a, 0x6c, 0xcb, 0x1e, 0x4f, 0x8e, 0x4e, 0xa6, 0x8b, 0xf9, 0x6b, 0x48, 0x31, 0xe1, 0x55, 0xbb, 0x13, 0x1c, 0xe, 0xde, 0xe3, 0xa0, 0x5e, 0x5c, 0xde, 0x81, 0xe5, 0x4f, 0x9, 0xeb, 0x18, 0x43, 0x8c, 0xf1, 0xd7, 0xc9, 0xa5, 0xe, 0x21, 0xf5, 0xa8, 0xd7, 0x4a, 0x1d, 0xb2, 0x6d, 0xd8, 0x28, 0xe7, 0x4c, 0x59, 0x32, 0xfd, 0x25, 0xd, 0x51, 0xaf, 0x95, 0x3e, 0x60, 0xdb, 0x6d, 0x27, 0x59, 0x1f, 0x8, 0xd5, 0x48, 0x8a, 0x4f, 0x37, 0xd8, 0x73, 0x57, 0x5e, 0x2b, 0x6d, 0xd5, 0xa, 0x54, 0xea, 0xed, 0xbe, 0x10, 0x6f, 0xa6, 0x8a, 0xf4, 0x5a, 0x1, 0x6d, 0x6, 0x88, 0x4e, 0xae, 0xe, 0x28, 0xbe, 0xef, 0x93, 0xb7, 0xe, 0x43, 0x68, 0xa2, 0x5a, 0x99, 0x57, 0x3, 0xb2, 0xb7, 0xf6, 0x5c, 0x51, 0xa6, 0x7a, 0x15, 0xaf, 0x76, 0x65, 0xcb, 0x5b, 0x8d, 0xe2, 0x1c, 0xf5, 0x15, 0xdb, 0x8f, 0xd1, 0xfc, 0x23, 0xe0, 0xa0, 0x6b, 0x24, 0xfd, 0xbb, 0x96, 0xa5, 0xd7, 0x7b, 0x5, 0xcc, 0xc1, 0x87, 0xee, 0xc1, 0x2, 0x3c, 0x81, 0xb, 0xa1, 0xba, 0x43, 0xbd, 0xe0, 0x11, 0xcc, 0xbe, 0x0, 0xbe, 0xe0, 0x95, 0x8, 0xaf, 0xb2, 0x52, 0x33, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char tab_disabled_png[] = {
diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp
index 7e71ad8986..0afe040f33 100644
--- a/scene/resources/environment.cpp
+++ b/scene/resources/environment.cpp
@@ -496,13 +496,13 @@ bool Environment::is_sdfgi_enabled() const {
return sdfgi_enabled;
}
-void Environment::set_sdfgi_cascades(SDFGICascades p_cascades) {
- ERR_FAIL_INDEX(p_cascades, SDFGI_CASCADES_8 + 1);
+void Environment::set_sdfgi_cascades(int p_cascades) {
+ ERR_FAIL_COND_MSG(p_cascades < 1 || p_cascades > 8, "Invalid number of SDFGI cascades (must be between 1 and 8).");
sdfgi_cascades = p_cascades;
_update_sdfgi();
}
-Environment::SDFGICascades Environment::get_sdfgi_cascades() const {
+int Environment::get_sdfgi_cascades() const {
return sdfgi_cascades;
}
@@ -517,9 +517,7 @@ float Environment::get_sdfgi_min_cell_size() const {
void Environment::set_sdfgi_max_distance(float p_distance) {
p_distance /= 64.0;
- int cc[3] = { 4, 6, 8 };
- int cascades = cc[sdfgi_cascades];
- for (int i = 0; i < cascades; i++) {
+ for (int i = 0; i < sdfgi_cascades; i++) {
p_distance *= 0.5; //halve for each cascade
}
sdfgi_min_cell_size = p_distance;
@@ -529,9 +527,7 @@ void Environment::set_sdfgi_max_distance(float p_distance) {
float Environment::get_sdfgi_max_distance() const {
float md = sdfgi_min_cell_size;
md *= 64.0;
- int cc[3] = { 4, 6, 8 };
- int cascades = cc[sdfgi_cascades];
- for (int i = 0; i < cascades; i++) {
+ for (int i = 0; i < sdfgi_cascades; i++) {
md *= 2.0;
}
return md;
@@ -612,7 +608,7 @@ void Environment::_update_sdfgi() {
RS::get_singleton()->environment_set_sdfgi(
environment,
sdfgi_enabled,
- RS::EnvironmentSDFGICascades(sdfgi_cascades),
+ sdfgi_cascades,
sdfgi_min_cell_size,
RS::EnvironmentSDFGIYScale(sdfgi_y_scale),
sdfgi_use_occlusion,
@@ -1303,7 +1299,7 @@ void Environment::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sdfgi_use_occlusion"), "set_sdfgi_use_occlusion", "is_sdfgi_using_occlusion");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sdfgi_read_sky_light"), "set_sdfgi_read_sky_light", "is_sdfgi_reading_sky_light");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sdfgi_bounce_feedback", PROPERTY_HINT_RANGE, "0,1.99,0.01"), "set_sdfgi_bounce_feedback", "get_sdfgi_bounce_feedback");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "sdfgi_cascades", PROPERTY_HINT_ENUM, "4 Cascades,6 Cascades,8 Cascades"), "set_sdfgi_cascades", "get_sdfgi_cascades");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "sdfgi_cascades", PROPERTY_HINT_RANGE, "1,8,1"), "set_sdfgi_cascades", "get_sdfgi_cascades");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sdfgi_min_cell_size", PROPERTY_HINT_RANGE, "0.01,64,0.01"), "set_sdfgi_min_cell_size", "get_sdfgi_min_cell_size");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sdfgi_cascade0_distance", PROPERTY_HINT_RANGE, "0.1,16384,0.1,or_greater"), "set_sdfgi_cascade0_distance", "get_sdfgi_cascade0_distance");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sdfgi_max_distance", PROPERTY_HINT_RANGE, "0.1,16384,0.1,or_greater"), "set_sdfgi_max_distance", "get_sdfgi_max_distance");
@@ -1480,10 +1476,6 @@ void Environment::_bind_methods() {
BIND_ENUM_CONSTANT(GLOW_BLEND_MODE_REPLACE);
BIND_ENUM_CONSTANT(GLOW_BLEND_MODE_MIX);
- BIND_ENUM_CONSTANT(SDFGI_CASCADES_4);
- BIND_ENUM_CONSTANT(SDFGI_CASCADES_6);
- BIND_ENUM_CONSTANT(SDFGI_CASCADES_8);
-
BIND_ENUM_CONSTANT(SDFGI_Y_SCALE_DISABLED);
BIND_ENUM_CONSTANT(SDFGI_Y_SCALE_75_PERCENT);
BIND_ENUM_CONSTANT(SDFGI_Y_SCALE_50_PERCENT);
diff --git a/scene/resources/environment.h b/scene/resources/environment.h
index 98e755c336..3f05315013 100644
--- a/scene/resources/environment.h
+++ b/scene/resources/environment.h
@@ -70,12 +70,6 @@ public:
TONE_MAPPER_ACES,
};
- enum SDFGICascades {
- SDFGI_CASCADES_4,
- SDFGI_CASCADES_6,
- SDFGI_CASCADES_8,
- };
-
enum SDFGIYScale {
SDFGI_Y_SCALE_DISABLED,
SDFGI_Y_SCALE_75_PERCENT,
@@ -153,7 +147,7 @@ private:
// SDFGI
bool sdfgi_enabled = false;
- SDFGICascades sdfgi_cascades = SDFGI_CASCADES_6;
+ int sdfgi_cascades = 6;
float sdfgi_min_cell_size = 0.2;
SDFGIYScale sdfgi_y_scale = SDFGI_Y_SCALE_DISABLED;
bool sdfgi_use_occlusion = false;
@@ -320,8 +314,8 @@ public:
// SDFGI
void set_sdfgi_enabled(bool p_enabled);
bool is_sdfgi_enabled() const;
- void set_sdfgi_cascades(SDFGICascades p_cascades);
- SDFGICascades get_sdfgi_cascades() const;
+ void set_sdfgi_cascades(int p_cascades);
+ int get_sdfgi_cascades() const;
void set_sdfgi_min_cell_size(float p_size);
float get_sdfgi_min_cell_size() const;
void set_sdfgi_max_distance(float p_distance);
@@ -433,7 +427,6 @@ VARIANT_ENUM_CAST(Environment::BGMode)
VARIANT_ENUM_CAST(Environment::AmbientSource)
VARIANT_ENUM_CAST(Environment::ReflectionSource)
VARIANT_ENUM_CAST(Environment::ToneMapper)
-VARIANT_ENUM_CAST(Environment::SDFGICascades)
VARIANT_ENUM_CAST(Environment::SDFGIYScale)
VARIANT_ENUM_CAST(Environment::GlowBlendMode)
diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp
index 9bd98237ff..f040041aa5 100644
--- a/scene/resources/font.cpp
+++ b/scene/resources/font.cpp
@@ -30,6 +30,7 @@
#include "font.h"
+#include "core/io/image_loader.h"
#include "core/io/resource_loader.h"
#include "core/string/translation.h"
#include "core/templates/hashfuncs.h"
@@ -64,6 +65,9 @@ _FORCE_INLINE_ void FontData::_ensure_rid(int p_cache_index) const {
}
void FontData::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("load_bitmap_font", "path"), &FontData::load_bitmap_font);
+ ClassDB::bind_method(D_METHOD("load_dynamic_font", "path"), &FontData::load_dynamic_font);
+
ClassDB::bind_method(D_METHOD("set_data", "data"), &FontData::set_data);
ClassDB::bind_method(D_METHOD("get_data"), &FontData::get_data);
@@ -184,6 +188,9 @@ void FontData::_bind_methods() {
ClassDB::bind_method(D_METHOD("remove_script_support_override", "script"), &FontData::remove_script_support_override);
ClassDB::bind_method(D_METHOD("get_script_support_overrides"), &FontData::get_script_support_overrides);
+ ClassDB::bind_method(D_METHOD("set_opentype_feature_overrides", "overrides"), &FontData::set_opentype_feature_overrides);
+ ClassDB::bind_method(D_METHOD("get_opentype_feature_overrides"), &FontData::get_opentype_feature_overrides);
+
ClassDB::bind_method(D_METHOD("has_char", "char"), &FontData::has_char);
ClassDB::bind_method(D_METHOD("get_supported_chars"), &FontData::get_supported_chars);
@@ -191,49 +198,25 @@ void FontData::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_supported_feature_list"), &FontData::get_supported_feature_list);
ClassDB::bind_method(D_METHOD("get_supported_variation_list"), &FontData::get_supported_variation_list);
+
+ ADD_PROPERTY(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_data", "get_data");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "antialiased", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_antialiased", "is_antialiased");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "font_name", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_font_name", "get_font_name");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "style_name", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_font_style_name", "get_font_style_name");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "font_style", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_font_style", "get_font_style");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "multichannel_signed_distance_field", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_multichannel_signed_distance_field", "is_multichannel_signed_distance_field");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "msdf_pixel_range", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_msdf_pixel_range", "get_msdf_pixel_range");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "msdf_size", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_msdf_size", "get_msdf_size");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "force_autohinter", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_force_autohinter", "is_force_autohinter");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "hinting", PROPERTY_HINT_ENUM, "None,Light,Normal", PROPERTY_USAGE_STORAGE), "set_hinting", "get_hinting");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "oversampling", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_oversampling", "get_oversampling");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "fixed_size", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_fixed_size", "get_fixed_size");
+ ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "opentype_feature_overrides", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_opentype_feature_overrides", "get_opentype_feature_overrides");
}
bool FontData::_set(const StringName &p_name, const Variant &p_value) {
Vector<String> tokens = p_name.operator String().split("/");
- if (tokens.size() == 1) {
- if (tokens[0] == "data") {
- set_data(p_value);
- return true;
- } else if (tokens[0] == "antialiased") {
- set_antialiased(p_value);
- return true;
- } else if (tokens[0] == "font_name") {
- set_font_name(p_value);
- return true;
- } else if (tokens[0] == "style_name") {
- set_font_style_name(p_value);
- return true;
- } else if (tokens[0] == "font_style") {
- set_font_style(p_value);
- return true;
- } else if (tokens[0] == "multichannel_signed_distance_field") {
- set_multichannel_signed_distance_field(p_value);
- return true;
- } else if (tokens[0] == "msdf_pixel_range") {
- set_msdf_pixel_range(p_value);
- return true;
- } else if (tokens[0] == "msdf_size") {
- set_msdf_size(p_value);
- return true;
- } else if (tokens[0] == "fixed_size") {
- set_fixed_size(p_value);
- return true;
- } else if (tokens[0] == "hinting") {
- set_hinting((TextServer::Hinting)p_value.operator int());
- return true;
- } else if (tokens[0] == "force_autohinter") {
- set_force_autohinter(p_value);
- return true;
- } else if (tokens[0] == "oversampling") {
- set_oversampling(p_value);
- return true;
- }
- } else if (tokens.size() == 2 && tokens[0] == "language_support_override") {
+ if (tokens.size() == 2 && tokens[0] == "language_support_override") {
String lang = tokens[1];
set_language_support_override(lang, p_value);
return true;
@@ -309,45 +292,7 @@ bool FontData::_set(const StringName &p_name, const Variant &p_value) {
bool FontData::_get(const StringName &p_name, Variant &r_ret) const {
Vector<String> tokens = p_name.operator String().split("/");
- if (tokens.size() == 1) {
- if (tokens[0] == "data") {
- r_ret = get_data();
- return true;
- } else if (tokens[0] == "antialiased") {
- r_ret = is_antialiased();
- return true;
- } else if (tokens[0] == "font_name") {
- r_ret = get_font_name();
- return true;
- } else if (tokens[0] == "style_name") {
- r_ret = get_font_style_name();
- return true;
- } else if (tokens[0] == "font_style") {
- r_ret = get_font_style();
- return true;
- } else if (tokens[0] == "multichannel_signed_distance_field") {
- r_ret = is_multichannel_signed_distance_field();
- return true;
- } else if (tokens[0] == "msdf_pixel_range") {
- r_ret = get_msdf_pixel_range();
- return true;
- } else if (tokens[0] == "msdf_size") {
- r_ret = get_msdf_size();
- return true;
- } else if (tokens[0] == "fixed_size") {
- r_ret = get_fixed_size();
- return true;
- } else if (tokens[0] == "hinting") {
- r_ret = get_hinting();
- return true;
- } else if (tokens[0] == "force_autohinter") {
- r_ret = is_force_autohinter();
- return true;
- } else if (tokens[0] == "oversampling") {
- r_ret = get_oversampling();
- return true;
- }
- } else if (tokens.size() == 2 && tokens[0] == "language_support_override") {
+ if (tokens.size() == 2 && tokens[0] == "language_support_override") {
String lang = tokens[1];
r_ret = get_language_support_override(lang);
return true;
@@ -422,20 +367,6 @@ bool FontData::_get(const StringName &p_name, Variant &r_ret) const {
}
void FontData::_get_property_list(List<PropertyInfo> *p_list) const {
- p_list->push_back(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
-
- p_list->push_back(PropertyInfo(Variant::STRING, "font_name", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
- p_list->push_back(PropertyInfo(Variant::STRING, "style_name", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
- p_list->push_back(PropertyInfo(Variant::INT, "font_style", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
- p_list->push_back(PropertyInfo(Variant::BOOL, "antialiased", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
- p_list->push_back(PropertyInfo(Variant::BOOL, "multichannel_signed_distance_field", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
- p_list->push_back(PropertyInfo(Variant::INT, "msdf_pixel_range", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
- p_list->push_back(PropertyInfo(Variant::INT, "msdf_size", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
- p_list->push_back(PropertyInfo(Variant::INT, "fixed_size", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
- p_list->push_back(PropertyInfo(Variant::INT, "hinting", PROPERTY_HINT_ENUM, "None,Light,Normal", PROPERTY_USAGE_STORAGE));
- p_list->push_back(PropertyInfo(Variant::BOOL, "force_autohinter", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
- p_list->push_back(PropertyInfo(Variant::FLOAT, "oversampling", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
-
Vector<String> lang_over = get_language_support_overrides();
for (int i = 0; i < lang_over.size(); i++) {
p_list->push_back(PropertyInfo(Variant::BOOL, "language_support_override/" + lang_over[i], PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
@@ -501,11 +432,766 @@ void FontData::reset_state() {
hinting = TextServer::HINTING_LIGHT;
msdf_pixel_range = 14;
msdf_size = 128;
+ fixed_size = 0;
oversampling = 0.f;
}
+void FontData::_convert_packed_8bit(Ref<Image> &p_source, int p_page, int p_sz) {
+ int w = p_source->get_width();
+ int h = p_source->get_height();
+
+ PackedByteArray imgdata = p_source->get_data();
+ const uint8_t *r = imgdata.ptr();
+
+ PackedByteArray imgdata_r;
+ imgdata_r.resize(w * h * 2);
+ uint8_t *wr = imgdata_r.ptrw();
+
+ PackedByteArray imgdata_g;
+ imgdata_g.resize(w * h * 2);
+ uint8_t *wg = imgdata_g.ptrw();
+
+ PackedByteArray imgdata_b;
+ imgdata_b.resize(w * h * 2);
+ uint8_t *wb = imgdata_b.ptrw();
+
+ PackedByteArray imgdata_a;
+ imgdata_a.resize(w * h * 2);
+ uint8_t *wa = imgdata_a.ptrw();
+
+ for (int i = 0; i < h; i++) {
+ for (int j = 0; j < w; j++) {
+ int ofs_src = (i * w + j) * 4;
+ int ofs_dst = (i * w + j) * 2;
+ wr[ofs_dst + 0] = 255;
+ wr[ofs_dst + 1] = r[ofs_src + 0];
+ wg[ofs_dst + 0] = 255;
+ wg[ofs_dst + 1] = r[ofs_src + 1];
+ wb[ofs_dst + 0] = 255;
+ wb[ofs_dst + 1] = r[ofs_src + 2];
+ wa[ofs_dst + 0] = 255;
+ wa[ofs_dst + 1] = r[ofs_src + 3];
+ }
+ }
+ Ref<Image> img_r = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_r));
+ set_texture_image(0, Vector2i(p_sz, 0), p_page * 4 + 0, img_r);
+ Ref<Image> img_g = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_g));
+ set_texture_image(0, Vector2i(p_sz, 0), p_page * 4 + 1, img_g);
+ Ref<Image> img_b = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_b));
+ set_texture_image(0, Vector2i(p_sz, 0), p_page * 4 + 2, img_b);
+ Ref<Image> img_a = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_a));
+ set_texture_image(0, Vector2i(p_sz, 0), p_page * 4 + 3, img_a);
+}
+
+void FontData::_convert_packed_4bit(Ref<Image> &p_source, int p_page, int p_sz) {
+ int w = p_source->get_width();
+ int h = p_source->get_height();
+
+ PackedByteArray imgdata = p_source->get_data();
+ const uint8_t *r = imgdata.ptr();
+
+ PackedByteArray imgdata_r;
+ imgdata_r.resize(w * h * 2);
+ uint8_t *wr = imgdata_r.ptrw();
+
+ PackedByteArray imgdata_g;
+ imgdata_g.resize(w * h * 2);
+ uint8_t *wg = imgdata_g.ptrw();
+
+ PackedByteArray imgdata_b;
+ imgdata_b.resize(w * h * 2);
+ uint8_t *wb = imgdata_b.ptrw();
+
+ PackedByteArray imgdata_a;
+ imgdata_a.resize(w * h * 2);
+ uint8_t *wa = imgdata_a.ptrw();
+
+ PackedByteArray imgdata_ro;
+ imgdata_ro.resize(w * h * 2);
+ uint8_t *wro = imgdata_ro.ptrw();
+
+ PackedByteArray imgdata_go;
+ imgdata_go.resize(w * h * 2);
+ uint8_t *wgo = imgdata_go.ptrw();
+
+ PackedByteArray imgdata_bo;
+ imgdata_bo.resize(w * h * 2);
+ uint8_t *wbo = imgdata_bo.ptrw();
+
+ PackedByteArray imgdata_ao;
+ imgdata_ao.resize(w * h * 2);
+ uint8_t *wao = imgdata_ao.ptrw();
+
+ for (int i = 0; i < h; i++) {
+ for (int j = 0; j < w; j++) {
+ int ofs_src = (i * w + j) * 4;
+ int ofs_dst = (i * w + j) * 2;
+ wr[ofs_dst + 0] = 255;
+ wro[ofs_dst + 0] = 255;
+ if (r[ofs_src + 0] > 0x0F) {
+ wr[ofs_dst + 1] = (r[ofs_src + 0] - 0x0F) * 2;
+ wro[ofs_dst + 1] = 0;
+ } else {
+ wr[ofs_dst + 1] = 0;
+ wro[ofs_dst + 1] = r[ofs_src + 0] * 2;
+ }
+ wg[ofs_dst + 0] = 255;
+ wgo[ofs_dst + 0] = 255;
+ if (r[ofs_src + 1] > 0x0F) {
+ wg[ofs_dst + 1] = (r[ofs_src + 1] - 0x0F) * 2;
+ wgo[ofs_dst + 1] = 0;
+ } else {
+ wg[ofs_dst + 1] = 0;
+ wgo[ofs_dst + 1] = r[ofs_src + 1] * 2;
+ }
+ wb[ofs_dst + 0] = 255;
+ wbo[ofs_dst + 0] = 255;
+ if (r[ofs_src + 2] > 0x0F) {
+ wb[ofs_dst + 1] = (r[ofs_src + 2] - 0x0F) * 2;
+ wbo[ofs_dst + 1] = 0;
+ } else {
+ wb[ofs_dst + 1] = 0;
+ wbo[ofs_dst + 1] = r[ofs_src + 2] * 2;
+ }
+ wa[ofs_dst + 0] = 255;
+ wao[ofs_dst + 0] = 255;
+ if (r[ofs_src + 3] > 0x0F) {
+ wa[ofs_dst + 1] = (r[ofs_src + 3] - 0x0F) * 2;
+ wao[ofs_dst + 1] = 0;
+ } else {
+ wa[ofs_dst + 1] = 0;
+ wao[ofs_dst + 1] = r[ofs_src + 3] * 2;
+ }
+ }
+ }
+ Ref<Image> img_r = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_r));
+ set_texture_image(0, Vector2i(p_sz, 0), p_page * 4 + 0, img_r);
+ Ref<Image> img_g = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_g));
+ set_texture_image(0, Vector2i(p_sz, 0), p_page * 4 + 1, img_g);
+ Ref<Image> img_b = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_b));
+ set_texture_image(0, Vector2i(p_sz, 0), p_page * 4 + 2, img_b);
+ Ref<Image> img_a = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_a));
+ set_texture_image(0, Vector2i(p_sz, 0), p_page * 4 + 3, img_a);
+
+ Ref<Image> img_ro = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_ro));
+ set_texture_image(0, Vector2i(p_sz, 1), p_page * 4 + 0, img_ro);
+ Ref<Image> img_go = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_go));
+ set_texture_image(0, Vector2i(p_sz, 1), p_page * 4 + 1, img_go);
+ Ref<Image> img_bo = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_bo));
+ set_texture_image(0, Vector2i(p_sz, 1), p_page * 4 + 2, img_bo);
+ Ref<Image> img_ao = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_ao));
+ set_texture_image(0, Vector2i(p_sz, 1), p_page * 4 + 3, img_ao);
+}
+
+void FontData::_convert_rgba_4bit(Ref<Image> &p_source, int p_page, int p_sz) {
+ int w = p_source->get_width();
+ int h = p_source->get_height();
+
+ PackedByteArray imgdata = p_source->get_data();
+ const uint8_t *r = imgdata.ptr();
+
+ PackedByteArray imgdata_g;
+ imgdata_g.resize(w * h * 4);
+ uint8_t *wg = imgdata_g.ptrw();
+
+ PackedByteArray imgdata_o;
+ imgdata_o.resize(w * h * 4);
+ uint8_t *wo = imgdata_o.ptrw();
+
+ for (int i = 0; i < h; i++) {
+ for (int j = 0; j < w; j++) {
+ int ofs = (i * w + j) * 4;
+
+ if (r[ofs + 0] > 0x7F) {
+ wg[ofs + 0] = r[ofs + 0];
+ wo[ofs + 0] = 0;
+ } else {
+ wg[ofs + 0] = 0;
+ wo[ofs + 0] = r[ofs + 0] * 2;
+ }
+ if (r[ofs + 1] > 0x7F) {
+ wg[ofs + 1] = r[ofs + 1];
+ wo[ofs + 1] = 0;
+ } else {
+ wg[ofs + 1] = 0;
+ wo[ofs + 1] = r[ofs + 1] * 2;
+ }
+ if (r[ofs + 2] > 0x7F) {
+ wg[ofs + 2] = r[ofs + 2];
+ wo[ofs + 2] = 0;
+ } else {
+ wg[ofs + 2] = 0;
+ wo[ofs + 2] = r[ofs + 2] * 2;
+ }
+ if (r[ofs + 3] > 0x7F) {
+ wg[ofs + 3] = r[ofs + 3];
+ wo[ofs + 3] = 0;
+ } else {
+ wg[ofs + 3] = 0;
+ wo[ofs + 3] = r[ofs + 3] * 2;
+ }
+ }
+ }
+ Ref<Image> img_g = memnew(Image(w, h, 0, Image::FORMAT_RGBA8, imgdata_g));
+ set_texture_image(0, Vector2i(p_sz, 0), p_page, img_g);
+
+ Ref<Image> img_o = memnew(Image(w, h, 0, Image::FORMAT_RGBA8, imgdata_o));
+ set_texture_image(0, Vector2i(p_sz, 1), p_page, img_o);
+}
+
+void FontData::_convert_mono_8bit(Ref<Image> &p_source, int p_page, int p_ch, int p_sz, int p_ol) {
+ int w = p_source->get_width();
+ int h = p_source->get_height();
+
+ PackedByteArray imgdata = p_source->get_data();
+ const uint8_t *r = imgdata.ptr();
+
+ int size = 4;
+ if (p_source->get_format() == Image::FORMAT_L8) {
+ size = 1;
+ p_ch = 0;
+ }
+
+ PackedByteArray imgdata_g;
+ imgdata_g.resize(w * h * 2);
+ uint8_t *wg = imgdata_g.ptrw();
+
+ for (int i = 0; i < h; i++) {
+ for (int j = 0; j < w; j++) {
+ int ofs_src = (i * w + j) * size;
+ int ofs_dst = (i * w + j) * 2;
+ wg[ofs_dst + 0] = 255;
+ wg[ofs_dst + 1] = r[ofs_src + p_ch];
+ }
+ }
+ Ref<Image> img_g = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_g));
+ set_texture_image(0, Vector2i(p_sz, p_ol), p_page, img_g);
+}
+
+void FontData::_convert_mono_4bit(Ref<Image> &p_source, int p_page, int p_ch, int p_sz, int p_ol) {
+ int w = p_source->get_width();
+ int h = p_source->get_height();
+
+ PackedByteArray imgdata = p_source->get_data();
+ const uint8_t *r = imgdata.ptr();
+
+ int size = 4;
+ if (p_source->get_format() == Image::FORMAT_L8) {
+ size = 1;
+ p_ch = 0;
+ }
+
+ PackedByteArray imgdata_g;
+ imgdata_g.resize(w * h * 2);
+ uint8_t *wg = imgdata_g.ptrw();
+
+ PackedByteArray imgdata_o;
+ imgdata_o.resize(w * h * 2);
+ uint8_t *wo = imgdata_o.ptrw();
+
+ for (int i = 0; i < h; i++) {
+ for (int j = 0; j < w; j++) {
+ int ofs_src = (i * w + j) * size;
+ int ofs_dst = (i * w + j) * 2;
+ wg[ofs_dst + 0] = 255;
+ wo[ofs_dst + 0] = 255;
+ if (r[ofs_src + p_ch] > 0x7F) {
+ wg[ofs_dst + 1] = r[ofs_src + p_ch];
+ wo[ofs_dst + 1] = 0;
+ } else {
+ wg[ofs_dst + 1] = 0;
+ wo[ofs_dst + 1] = r[ofs_src + p_ch] * 2;
+ }
+ }
+ }
+ Ref<Image> img_g = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_g));
+ set_texture_image(0, Vector2i(p_sz, 0), p_page, img_g);
+
+ Ref<Image> img_o = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_o));
+ set_texture_image(0, Vector2i(p_sz, p_ol), p_page, img_o);
+}
+
/*************************************************************************/
+Error FontData::load_bitmap_font(const String &p_path) {
+ reset_state();
+
+ antialiased = false;
+ msdf = false;
+ force_autohinter = false;
+ hinting = TextServer::HINTING_NONE;
+ oversampling = 1.0f;
+
+ FileAccessRef f = FileAccess::open(p_path, FileAccess::READ);
+ if (f == nullptr) {
+ ERR_FAIL_V_MSG(ERR_CANT_CREATE, TTR("Cannot open font from file ") + "\"" + p_path + "\".");
+ }
+
+ int base_size = 16;
+ int height = 0;
+ int ascent = 0;
+ int outline = 0;
+ uint32_t st_flags = 0;
+ String font_name;
+
+ bool packed = false;
+ uint8_t ch[4] = { 0, 0, 0, 0 }; // RGBA
+ int first_gl_ch = -1;
+ int first_ol_ch = -1;
+ int first_cm_ch = -1;
+
+ unsigned char magic[4];
+ f->get_buffer((unsigned char *)&magic, 4);
+ if (magic[0] == 'B' && magic[1] == 'M' && magic[2] == 'F') {
+ // Binary BMFont file.
+ ERR_FAIL_COND_V_MSG(magic[3] != 3, ERR_CANT_CREATE, vformat(TTR("Version %d of BMFont is not supported."), (int)magic[3]));
+
+ uint8_t block_type = f->get_8();
+ uint32_t block_size = f->get_32();
+ while (!f->eof_reached()) {
+ uint64_t off = f->get_position();
+ switch (block_type) {
+ case 1: /* info */ {
+ ERR_FAIL_COND_V_MSG(block_size < 15, ERR_CANT_CREATE, TTR("Invalid BMFont info block size."));
+ base_size = f->get_16();
+ uint8_t flags = f->get_8();
+ ERR_FAIL_COND_V_MSG(flags & 0x02, ERR_CANT_CREATE, TTR("Non-unicode version of BMFont is not supported."));
+ if (flags & (1 << 3)) {
+ st_flags |= TextServer::FONT_BOLD;
+ }
+ if (flags & (1 << 2)) {
+ st_flags |= TextServer::FONT_ITALIC;
+ }
+ f->get_8(); // non-unicode charset, skip
+ f->get_16(); // stretch_h, skip
+ f->get_8(); // aa, skip
+ f->get_32(); // padding, skip
+ f->get_16(); // spacing, skip
+ outline = f->get_8();
+ // font name
+ PackedByteArray name_data;
+ name_data.resize(block_size - 14);
+ f->get_buffer(name_data.ptrw(), block_size - 14);
+ font_name = String::utf8((const char *)name_data.ptr(), block_size - 14);
+ set_fixed_size(base_size);
+ } break;
+ case 2: /* common */ {
+ ERR_FAIL_COND_V_MSG(block_size != 15, ERR_CANT_CREATE, TTR("Invalid BMFont common block size."));
+ height = f->get_16();
+ ascent = f->get_16();
+ f->get_32(); // scale, skip
+ f->get_16(); // pages, skip
+ uint8_t flags = f->get_8();
+ packed = (flags & 0x01);
+ ch[3] = f->get_8();
+ ch[0] = f->get_8();
+ ch[1] = f->get_8();
+ ch[2] = f->get_8();
+ for (int i = 0; i < 4; i++) {
+ if (ch[i] == 0 && first_gl_ch == -1) {
+ first_gl_ch = i;
+ }
+ if (ch[i] == 1 && first_ol_ch == -1) {
+ first_ol_ch = i;
+ }
+ if (ch[i] == 2 && first_cm_ch == -1) {
+ first_cm_ch = i;
+ }
+ }
+ } break;
+ case 3: /* pages */ {
+ int page = 0;
+ CharString cs;
+ char32_t c = f->get_8();
+ while (!f->eof_reached() && f->get_position() <= off + block_size) {
+ if (c == '\0') {
+ String base_dir = p_path.get_base_dir();
+ String file = base_dir.plus_file(String::utf8(cs.ptr(), cs.length()));
+ if (RenderingServer::get_singleton() != nullptr) {
+ Ref<Image> img;
+ img.instantiate();
+ Error err = ImageLoader::load_image(file, img);
+ ERR_FAIL_COND_V_MSG(err != OK, ERR_FILE_CANT_READ, TTR("Can't load font texture: ") + "\"" + file + "\".");
+
+ if (packed) {
+ if (ch[3] == 0) { // 4 x 8 bit monochrome, no outline
+ outline = 0;
+ ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8, ERR_FILE_CANT_READ, TTR("Unsupported BMFont texture format."));
+ _convert_packed_8bit(img, page, base_size);
+ } else if ((ch[3] == 2) && (outline > 0)) { // 4 x 4 bit monochrome, gl + outline
+ ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8, ERR_FILE_CANT_READ, TTR("Unsupported BMFont texture format."));
+ _convert_packed_4bit(img, page, base_size);
+ } else {
+ ERR_FAIL_V_MSG(ERR_CANT_CREATE, TTR("Unsupported BMFont texture format."));
+ }
+ } else {
+ if ((ch[0] == 0) && (ch[1] == 0) && (ch[2] == 0) && (ch[3] == 0)) { // RGBA8 color, no outline
+ outline = 0;
+ ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8, ERR_FILE_CANT_READ, TTR("Unsupported BMFont texture format."));
+ set_texture_image(0, Vector2i(base_size, 0), page, img);
+ } else if ((ch[0] == 2) && (ch[1] == 2) && (ch[2] == 2) && (ch[3] == 2) && (outline > 0)) { // RGBA4 color, gl + outline
+ ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8, ERR_FILE_CANT_READ, TTR("Unsupported BMFont texture format."));
+ _convert_rgba_4bit(img, page, base_size);
+ } else if ((first_gl_ch >= 0) && (first_ol_ch >= 0) && (outline > 0)) { // 1 x 8 bit monochrome, gl + outline
+ ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8 && img->get_format() != Image::FORMAT_L8, ERR_FILE_CANT_READ, TTR("Unsupported BMFont texture format."));
+ _convert_mono_8bit(img, page, first_gl_ch, base_size, 0);
+ _convert_mono_8bit(img, page, first_ol_ch, base_size, 1);
+ } else if ((first_cm_ch >= 0) && (outline > 0)) { // 1 x 4 bit monochrome, gl + outline
+ ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8 && img->get_format() != Image::FORMAT_L8, ERR_FILE_CANT_READ, TTR("Unsupported BMFont texture format."));
+ _convert_mono_4bit(img, page, first_cm_ch, base_size, 1);
+ } else if (first_gl_ch >= 0) { // 1 x 8 bit monochrome, no outline
+ outline = 0;
+ ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8 && img->get_format() != Image::FORMAT_L8, ERR_FILE_CANT_READ, TTR("Unsupported BMFont texture format."));
+ _convert_mono_8bit(img, page, first_gl_ch, base_size, 0);
+ } else {
+ ERR_FAIL_V_MSG(ERR_CANT_CREATE, TTR("Unsupported BMFont texture format."));
+ }
+ }
+ }
+ page++;
+ cs = "";
+ } else {
+ cs += c;
+ }
+ c = f->get_8();
+ }
+ } break;
+ case 4: /* chars */ {
+ int char_count = block_size / 20;
+ for (int i = 0; i < char_count; i++) {
+ Vector2 advance;
+ Vector2 size;
+ Vector2 offset;
+ Rect2 uv_rect;
+
+ char32_t idx = f->get_32();
+ uv_rect.position.x = (int16_t)f->get_16();
+ uv_rect.position.y = (int16_t)f->get_16();
+ uv_rect.size.width = (int16_t)f->get_16();
+ size.width = uv_rect.size.width;
+ uv_rect.size.height = (int16_t)f->get_16();
+ size.height = uv_rect.size.height;
+ offset.x = (int16_t)f->get_16();
+ offset.y = (int16_t)f->get_16() - ascent;
+ advance.x = (int16_t)f->get_16();
+ if (advance.x < 0) {
+ advance.x = size.width + 1;
+ }
+
+ int texture_idx = f->get_8();
+ uint8_t channel = f->get_8();
+
+ ERR_FAIL_COND_V_MSG(!packed && channel != 15, ERR_CANT_CREATE, TTR("Invalid glyph channel."));
+ int ch_off = 0;
+ switch (channel) {
+ case 1:
+ ch_off = 2;
+ break; // B
+ case 2:
+ ch_off = 1;
+ break; // G
+ case 4:
+ ch_off = 0;
+ break; // R
+ case 8:
+ ch_off = 3;
+ break; // A
+ default:
+ ch_off = 0;
+ break;
+ }
+ set_glyph_advance(0, base_size, idx, advance);
+ set_glyph_offset(0, Vector2i(base_size, 0), idx, offset);
+ set_glyph_size(0, Vector2i(base_size, 0), idx, size);
+ set_glyph_uv_rect(0, Vector2i(base_size, 0), idx, uv_rect);
+ set_glyph_texture_idx(0, Vector2i(base_size, 0), idx, texture_idx * (packed ? 4 : 1) + ch_off);
+ if (outline > 0) {
+ set_glyph_offset(0, Vector2i(base_size, 1), idx, offset);
+ set_glyph_size(0, Vector2i(base_size, 1), idx, size);
+ set_glyph_uv_rect(0, Vector2i(base_size, 1), idx, uv_rect);
+ set_glyph_texture_idx(0, Vector2i(base_size, 1), idx, texture_idx * (packed ? 4 : 1) + ch_off);
+ }
+ }
+ } break;
+ case 5: /* kerning */ {
+ int pair_count = block_size / 10;
+ for (int i = 0; i < pair_count; i++) {
+ Vector2i kpk;
+ kpk.x = f->get_32();
+ kpk.y = f->get_32();
+ set_kerning(0, base_size, kpk, Vector2((int16_t)f->get_16(), 0));
+ }
+ } break;
+ default: {
+ ERR_FAIL_V_MSG(ERR_CANT_CREATE, TTR("Invalid BMFont block type."));
+ } break;
+ }
+ f->seek(off + block_size);
+ block_type = f->get_8();
+ block_size = f->get_32();
+ }
+
+ } else {
+ // Text BMFont file.
+ f->seek(0);
+ while (true) {
+ String line = f->get_line();
+
+ int delimiter = line.find(" ");
+ String type = line.substr(0, delimiter);
+ int pos = delimiter + 1;
+ Map<String, String> keys;
+
+ while (pos < line.size() && line[pos] == ' ') {
+ pos++;
+ }
+
+ while (pos < line.size()) {
+ int eq = line.find("=", pos);
+ if (eq == -1) {
+ break;
+ }
+ String key = line.substr(pos, eq - pos);
+ int end = -1;
+ String value;
+ if (line[eq + 1] == '"') {
+ end = line.find("\"", eq + 2);
+ if (end == -1) {
+ break;
+ }
+ value = line.substr(eq + 2, end - 1 - eq - 1);
+ pos = end + 1;
+ } else {
+ end = line.find(" ", eq + 1);
+ if (end == -1) {
+ end = line.size();
+ }
+ value = line.substr(eq + 1, end - eq);
+ pos = end;
+ }
+
+ while (pos < line.size() && line[pos] == ' ') {
+ pos++;
+ }
+
+ keys[key] = value;
+ }
+
+ if (type == "info") {
+ if (keys.has("size")) {
+ base_size = keys["size"].to_int();
+ set_fixed_size(base_size);
+ }
+ if (keys.has("outline")) {
+ outline = keys["outline"].to_int();
+ }
+ if (keys.has("bold")) {
+ if (keys["bold"].to_int()) {
+ st_flags |= TextServer::FONT_BOLD;
+ }
+ }
+ if (keys.has("italic")) {
+ if (keys["italic"].to_int()) {
+ st_flags |= TextServer::FONT_ITALIC;
+ }
+ }
+ if (keys.has("face")) {
+ font_name = keys["face"];
+ }
+ ERR_FAIL_COND_V_MSG((!keys.has("unicode") || keys["unicode"].to_int() != 1), ERR_CANT_CREATE, TTR("Non-unicode version of BMFont is not supported."));
+ } else if (type == "common") {
+ if (keys.has("lineHeight")) {
+ height = keys["lineHeight"].to_int();
+ }
+ if (keys.has("base")) {
+ ascent = keys["base"].to_int();
+ }
+ if (keys.has("packed")) {
+ packed = (keys["packed"].to_int() == 1);
+ }
+ if (keys.has("alphaChnl")) {
+ ch[3] = keys["alphaChnl"].to_int();
+ }
+ if (keys.has("redChnl")) {
+ ch[0] = keys["redChnl"].to_int();
+ }
+ if (keys.has("greenChnl")) {
+ ch[1] = keys["greenChnl"].to_int();
+ }
+ if (keys.has("blueChnl")) {
+ ch[2] = keys["blueChnl"].to_int();
+ }
+ for (int i = 0; i < 4; i++) {
+ if (ch[i] == 0 && first_gl_ch == -1) {
+ first_gl_ch = i;
+ }
+ if (ch[i] == 1 && first_ol_ch == -1) {
+ first_ol_ch = i;
+ }
+ if (ch[i] == 2 && first_cm_ch == -1) {
+ first_cm_ch = i;
+ }
+ }
+ } else if (type == "page") {
+ int page = 0;
+ if (keys.has("id")) {
+ page = keys["id"].to_int();
+ }
+ if (keys.has("file")) {
+ String base_dir = p_path.get_base_dir();
+ String file = base_dir.plus_file(keys["file"]);
+ if (RenderingServer::get_singleton() != nullptr) {
+ Ref<Image> img;
+ img.instantiate();
+ Error err = ImageLoader::load_image(file, img);
+ ERR_FAIL_COND_V_MSG(err != OK, ERR_FILE_CANT_READ, TTR("Can't load font texture: ") + "\"" + file + "\".");
+ if (packed) {
+ if (ch[3] == 0) { // 4 x 8 bit monochrome, no outline
+ outline = 0;
+ ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8, ERR_FILE_CANT_READ, TTR("Unsupported BMFont texture format."));
+ _convert_packed_8bit(img, page, base_size);
+ } else if ((ch[3] == 2) && (outline > 0)) { // 4 x 4 bit monochrome, gl + outline
+ ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8, ERR_FILE_CANT_READ, TTR("Unsupported BMFont texture format."));
+ _convert_packed_4bit(img, page, base_size);
+ } else {
+ ERR_FAIL_V_MSG(ERR_CANT_CREATE, TTR("Unsupported BMFont texture format."));
+ }
+ } else {
+ if ((ch[0] == 0) && (ch[1] == 0) && (ch[2] == 0) && (ch[3] == 0)) { // RGBA8 color, no outline
+ outline = 0;
+ ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8, ERR_FILE_CANT_READ, TTR("Unsupported BMFont texture format."));
+ set_texture_image(0, Vector2i(base_size, 0), page, img);
+ } else if ((ch[0] == 2) && (ch[1] == 2) && (ch[2] == 2) && (ch[3] == 2) && (outline > 0)) { // RGBA4 color, gl + outline
+ ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8, ERR_FILE_CANT_READ, TTR("Unsupported BMFont texture format."));
+ _convert_rgba_4bit(img, page, base_size);
+ } else if ((first_gl_ch >= 0) && (first_ol_ch >= 0) && (outline > 0)) { // 1 x 8 bit monochrome, gl + outline
+ ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8 && img->get_format() != Image::FORMAT_L8, ERR_FILE_CANT_READ, TTR("Unsupported BMFont texture format."));
+ _convert_mono_8bit(img, page, first_gl_ch, base_size, 0);
+ _convert_mono_8bit(img, page, first_ol_ch, base_size, 1);
+ } else if ((first_cm_ch >= 0) && (outline > 0)) { // 1 x 4 bit monochrome, gl + outline
+ ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8 && img->get_format() != Image::FORMAT_L8, ERR_FILE_CANT_READ, TTR("Unsupported BMFont texture format."));
+ _convert_mono_4bit(img, page, first_cm_ch, base_size, 1);
+ } else if (first_gl_ch >= 0) { // 1 x 8 bit monochrome, no outline
+ outline = 0;
+ ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8 && img->get_format() != Image::FORMAT_L8, ERR_FILE_CANT_READ, TTR("Unsupported BMFont texture format."));
+ _convert_mono_8bit(img, page, first_gl_ch, base_size, 0);
+ } else {
+ ERR_FAIL_V_MSG(ERR_CANT_CREATE, TTR("Unsupported BMFont texture format."));
+ }
+ }
+ }
+ }
+ } else if (type == "char") {
+ char32_t idx = 0;
+ Vector2 advance;
+ Vector2 size;
+ Vector2 offset;
+ Rect2 uv_rect;
+ int texture_idx = -1;
+ uint8_t channel = 15;
+
+ if (keys.has("id")) {
+ idx = keys["id"].to_int();
+ }
+ if (keys.has("x")) {
+ uv_rect.position.x = keys["x"].to_int();
+ }
+ if (keys.has("y")) {
+ uv_rect.position.y = keys["y"].to_int();
+ }
+ if (keys.has("width")) {
+ uv_rect.size.width = keys["width"].to_int();
+ size.width = keys["width"].to_int();
+ }
+ if (keys.has("height")) {
+ uv_rect.size.height = keys["height"].to_int();
+ size.height = keys["height"].to_int();
+ }
+ if (keys.has("xoffset")) {
+ offset.x = keys["xoffset"].to_int();
+ }
+ if (keys.has("yoffset")) {
+ offset.y = keys["yoffset"].to_int() - ascent;
+ }
+ if (keys.has("page")) {
+ texture_idx = keys["page"].to_int();
+ }
+ if (keys.has("xadvance")) {
+ advance.x = keys["xadvance"].to_int();
+ }
+ if (advance.x < 0) {
+ advance.x = size.width + 1;
+ }
+ if (keys.has("chnl")) {
+ channel = keys["chnl"].to_int();
+ }
+
+ ERR_FAIL_COND_V_MSG(!packed && channel != 15, ERR_CANT_CREATE, TTR("Invalid glyph channel."));
+ int ch_off = 0;
+ switch (channel) {
+ case 1:
+ ch_off = 2;
+ break; // B
+ case 2:
+ ch_off = 1;
+ break; // G
+ case 4:
+ ch_off = 0;
+ break; // R
+ case 8:
+ ch_off = 3;
+ break; // A
+ default:
+ ch_off = 0;
+ break;
+ }
+ set_glyph_advance(0, base_size, idx, advance);
+ set_glyph_offset(0, Vector2i(base_size, 0), idx, offset);
+ set_glyph_size(0, Vector2i(base_size, 0), idx, size);
+ set_glyph_uv_rect(0, Vector2i(base_size, 0), idx, uv_rect);
+ set_glyph_texture_idx(0, Vector2i(base_size, 0), idx, texture_idx * (packed ? 4 : 1) + ch_off);
+ if (outline > 0) {
+ set_glyph_offset(0, Vector2i(base_size, 1), idx, offset);
+ set_glyph_size(0, Vector2i(base_size, 1), idx, size);
+ set_glyph_uv_rect(0, Vector2i(base_size, 1), idx, uv_rect);
+ set_glyph_texture_idx(0, Vector2i(base_size, 1), idx, texture_idx * (packed ? 4 : 1) + ch_off);
+ }
+ } else if (type == "kerning") {
+ Vector2i kpk;
+ if (keys.has("first")) {
+ kpk.x = keys["first"].to_int();
+ }
+ if (keys.has("second")) {
+ kpk.y = keys["second"].to_int();
+ }
+ if (keys.has("amount")) {
+ set_kerning(0, base_size, kpk, Vector2(keys["amount"].to_int(), 0));
+ }
+ }
+
+ if (f->eof_reached()) {
+ break;
+ }
+ }
+ }
+
+ set_font_name(font_name);
+ set_font_style(st_flags);
+ set_ascent(0, base_size, ascent);
+ set_descent(0, base_size, height - ascent);
+
+ return OK;
+}
+
+Error FontData::load_dynamic_font(const String &p_path) {
+ reset_state();
+
+ Vector<uint8_t> data = FileAccess::get_file_as_array(p_path);
+ set_data(data);
+
+ return OK;
+}
+
void FontData::set_data_ptr(const uint8_t *p_data, size_t p_size) {
data.clear();
data_ptr = p_data;
@@ -1077,6 +1763,16 @@ Vector<String> FontData::get_script_support_overrides() const {
return TS->font_get_script_support_overrides(cache[0]);
}
+void FontData::set_opentype_feature_overrides(const Dictionary &p_overrides) {
+ _ensure_rid(0);
+ TS->font_set_opentype_feature_overrides(cache[0], p_overrides);
+}
+
+Dictionary FontData::get_opentype_feature_overrides() const {
+ _ensure_rid(0);
+ return TS->font_get_opentype_feature_overrides(cache[0]);
+}
+
bool FontData::has_char(char32_t p_char) const {
_ensure_rid(0);
return TS->font_has_char(cache[0], p_char);
diff --git a/scene/resources/font.h b/scene/resources/font.h
index 9c3672bd69..93351a3493 100644
--- a/scene/resources/font.h
+++ b/scene/resources/font.h
@@ -63,6 +63,12 @@ class FontData : public Resource {
_FORCE_INLINE_ void _clear_cache();
_FORCE_INLINE_ void _ensure_rid(int p_cache_index) const;
+ void _convert_packed_8bit(Ref<Image> &p_source, int p_page, int p_sz);
+ void _convert_packed_4bit(Ref<Image> &p_source, int p_page, int p_sz);
+ void _convert_rgba_4bit(Ref<Image> &p_source, int p_page, int p_sz);
+ void _convert_mono_8bit(Ref<Image> &p_source, int p_page, int p_ch, int p_sz, int p_ol);
+ void _convert_mono_4bit(Ref<Image> &p_source, int p_page, int p_ch, int p_sz, int p_ol);
+
protected:
static void _bind_methods();
@@ -73,6 +79,9 @@ protected:
virtual void reset_state() override;
public:
+ Error load_bitmap_font(const String &p_path);
+ Error load_dynamic_font(const String &p_path);
+
// Font source data.
virtual void set_data_ptr(const uint8_t *p_data, size_t p_size);
virtual void set_data(const PackedByteArray &p_data);
@@ -198,6 +207,9 @@ public:
virtual void remove_script_support_override(const String &p_script);
virtual Vector<String> get_script_support_overrides() const;
+ virtual void set_opentype_feature_overrides(const Dictionary &p_overrides);
+ virtual Dictionary get_opentype_feature_overrides() const;
+
// Base font properties.
virtual bool has_char(char32_t p_char) const;
virtual String get_supported_chars() const;
diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp
index b36204241a..f3e5ece1f9 100644
--- a/scene/resources/material.cpp
+++ b/scene/resources/material.cpp
@@ -1659,18 +1659,6 @@ bool BaseMaterial3D::get_feature(Feature p_feature) const {
void BaseMaterial3D::set_texture(TextureParam p_param, const Ref<Texture2D> &p_texture) {
ERR_FAIL_INDEX(p_param, TEXTURE_MAX);
- if (get_texture(TEXTURE_ROUGHNESS).is_null() && p_texture.is_valid() && p_param == TEXTURE_ROUGHNESS) {
- // If no roughness texture is currently set, automatically set the recommended value
- // for roughness when using a roughness map.
- set_roughness(1.0);
- }
-
- if (get_texture(TEXTURE_METALLIC).is_null() && p_texture.is_valid() && p_param == TEXTURE_METALLIC) {
- // If no metallic texture is currently set, automatically set the recommended value
- // for metallic when using a metallic map.
- set_metallic(1.0);
- }
-
textures[p_param] = p_texture;
RID rid = p_texture.is_valid() ? p_texture->get_rid() : RID();
RS::get_singleton()->material_set_param(_get_material(), shader_names->texture_names[p_param], rid);
diff --git a/scene/resources/material.h b/scene/resources/material.h
index 7250544d10..57591bee2f 100644
--- a/scene/resources/material.h
+++ b/scene/resources/material.h
@@ -35,7 +35,6 @@
#include "core/templates/self_list.h"
#include "scene/resources/shader.h"
#include "scene/resources/texture.h"
-#include "servers/rendering/shader_language.h"
#include "servers/rendering_server.h"
class Material : public Resource {
diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp
index 1df40fc08e..d2d96b1f06 100644
--- a/scene/resources/mesh.cpp
+++ b/scene/resources/mesh.cpp
@@ -596,7 +596,7 @@ enum OldArrayFormat {
OLD_ARRAY_FLAG_USE_2D_VERTICES = OLD_ARRAY_COMPRESS_INDEX << 1,
OLD_ARRAY_FLAG_USE_16_BIT_BONES = OLD_ARRAY_COMPRESS_INDEX << 2,
OLD_ARRAY_FLAG_USE_DYNAMIC_UPDATE = OLD_ARRAY_COMPRESS_INDEX << 3,
-
+ OLD_ARRAY_FLAG_USE_OCTAHEDRAL_COMPRESSION = OLD_ARRAY_COMPRESS_INDEX << 4,
};
#ifndef DISABLE_DEPRECATED
@@ -626,6 +626,27 @@ static Mesh::PrimitiveType _old_primitives[7] = {
};
#endif // DISABLE_DEPRECATED
+// Convert Octahedron-mapped normalized vector back to Cartesian
+// Assumes normalized format (elements of v within range [-1, 1])
+Vector3 _oct_to_norm(const Vector2 v) {
+ Vector3 res(v.x, v.y, 1 - (Math::absf(v.x) + Math::absf(v.y)));
+ float t = MAX(-res.z, 0.0f);
+ res.x += t * -SIGN(res.x);
+ res.y += t * -SIGN(res.y);
+ return res.normalized();
+}
+
+// Convert Octahedron-mapped normalized tangent vector back to Cartesian
+// out_sign provides the direction for the original cartesian tangent
+// Assumes normalized format (elements of v within range [-1, 1])
+Vector3 _oct_to_tangent(const Vector2 v, float *out_sign) {
+ Vector2 v_decompressed = v;
+ v_decompressed.y = Math::absf(v_decompressed.y) * 2 - 1;
+ Vector3 res = _oct_to_norm(v_decompressed);
+ *out_sign = SIGN(v[1]);
+ return res;
+}
+
void _fix_array_compatibility(const Vector<uint8_t> &p_src, uint32_t p_old_format, uint32_t p_new_format, uint32_t p_elements, Vector<uint8_t> &vertex_data, Vector<uint8_t> &attribute_data, Vector<uint8_t> &skin_data) {
uint32_t dst_vertex_stride;
uint32_t dst_attribute_stride;
@@ -692,66 +713,133 @@ void _fix_array_compatibility(const Vector<uint8_t> &p_src, uint32_t p_old_forma
}
} break;
case OLD_ARRAY_NORMAL: {
- if (p_old_format & OLD_ARRAY_COMPRESS_NORMAL) {
- const float multiplier = 1.f / 127.f * 1023.0f;
+ if (p_old_format & OLD_ARRAY_FLAG_USE_OCTAHEDRAL_COMPRESSION) {
+ if ((p_old_format & OLD_ARRAY_COMPRESS_NORMAL) && (p_old_format & OLD_ARRAY_FORMAT_TANGENT) && (p_old_format & OLD_ARRAY_COMPRESS_TANGENT)) {
+ for (uint32_t i = 0; i < p_elements; i++) {
+ const int8_t *src = (const int8_t *)&src_vertex_ptr[i * src_vertex_stride + src_offset];
+ uint32_t *dst = (uint32_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_NORMAL]];
+ const Vector2 src_vec(src[0] / 127.0f, src[1] / 127.0f);
+
+ const Vector3 res = _oct_to_norm(src_vec) * Vector3(0.5, 0.5, 0.5) + Vector3(0.5, 0.5, 0.5);
+ *dst = 0;
+ *dst |= CLAMP(int(res.x * 1023.0f), 0, 1023);
+ *dst |= CLAMP(int(res.y * 1023.0f), 0, 1023) << 10;
+ *dst |= CLAMP(int(res.z * 1023.0f), 0, 1023) << 20;
+ }
+ src_offset += sizeof(int8_t) * 2;
+ } else {
+ for (uint32_t i = 0; i < p_elements; i++) {
+ const int16_t *src = (const int16_t *)&src_vertex_ptr[i * src_vertex_stride + src_offset];
+ uint32_t *dst = (uint32_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_NORMAL]];
+ const Vector2 src_vec(src[0] / 32767.0f, src[1] / 32767.0f);
+
+ const Vector3 res = _oct_to_norm(src_vec) * Vector3(0.5, 0.5, 0.5) + Vector3(0.5, 0.5, 0.5);
+ *dst = 0;
+ *dst |= CLAMP(int(res.x * 1023.0f), 0, 1023);
+ *dst |= CLAMP(int(res.y * 1023.0f), 0, 1023) << 10;
+ *dst |= CLAMP(int(res.z * 1023.0f), 0, 1023) << 20;
+ }
+ src_offset += sizeof(int16_t) * 2;
+ }
+ } else { // No Octahedral compression
+ if (p_old_format & OLD_ARRAY_COMPRESS_NORMAL) {
+ const float multiplier = 1.f / 127.f * 1023.0f;
- for (uint32_t i = 0; i < p_elements; i++) {
- const int8_t *src = (const int8_t *)&src_vertex_ptr[i * src_vertex_stride + src_offset];
- uint32_t *dst = (uint32_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_NORMAL]];
+ for (uint32_t i = 0; i < p_elements; i++) {
+ const int8_t *src = (const int8_t *)&src_vertex_ptr[i * src_vertex_stride + src_offset];
+ uint32_t *dst = (uint32_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_NORMAL]];
- *dst = 0;
- *dst |= CLAMP(int(src[0] * multiplier), 0, 1023);
- *dst |= CLAMP(int(src[1] * multiplier), 0, 1023) << 10;
- *dst |= CLAMP(int(src[2] * multiplier), 0, 1023) << 20;
- }
- src_offset += sizeof(uint32_t);
- } else {
- for (uint32_t i = 0; i < p_elements; i++) {
- const float *src = (const float *)&src_vertex_ptr[i * src_vertex_stride + src_offset];
- uint32_t *dst = (uint32_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_NORMAL]];
+ *dst = 0;
+ *dst |= CLAMP(int(src[0] * multiplier), 0, 1023);
+ *dst |= CLAMP(int(src[1] * multiplier), 0, 1023) << 10;
+ *dst |= CLAMP(int(src[2] * multiplier), 0, 1023) << 20;
+ }
+ src_offset += sizeof(uint32_t);
+ } else {
+ for (uint32_t i = 0; i < p_elements; i++) {
+ const float *src = (const float *)&src_vertex_ptr[i * src_vertex_stride + src_offset];
+ uint32_t *dst = (uint32_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_NORMAL]];
- *dst = 0;
- *dst |= CLAMP(int(src[0] * 1023.0), 0, 1023);
- *dst |= CLAMP(int(src[1] * 1023.0), 0, 1023) << 10;
- *dst |= CLAMP(int(src[2] * 1023.0), 0, 1023) << 20;
+ *dst = 0;
+ *dst |= CLAMP(int(src[0] * 1023.0), 0, 1023);
+ *dst |= CLAMP(int(src[1] * 1023.0), 0, 1023) << 10;
+ *dst |= CLAMP(int(src[2] * 1023.0), 0, 1023) << 20;
+ }
+ src_offset += sizeof(float) * 3;
}
- src_offset += sizeof(float) * 3;
}
} break;
case OLD_ARRAY_TANGENT: {
- if (p_old_format & OLD_ARRAY_COMPRESS_TANGENT) {
- const float multiplier = 1.f / 127.f * 1023.0f;
-
- for (uint32_t i = 0; i < p_elements; i++) {
- const int8_t *src = (const int8_t *)&src_vertex_ptr[i * src_vertex_stride + src_offset];
- uint32_t *dst = (uint32_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_TANGENT]];
-
- *dst = 0;
- *dst |= CLAMP(int(src[0] * multiplier), 0, 1023);
- *dst |= CLAMP(int(src[1] * multiplier), 0, 1023) << 10;
- *dst |= CLAMP(int(src[2] * multiplier), 0, 1023) << 20;
- if (src[3] > 0) {
- *dst |= 3 << 30;
+ if (p_old_format & OLD_ARRAY_FLAG_USE_OCTAHEDRAL_COMPRESSION) {
+ if (p_old_format & OLD_ARRAY_COMPRESS_TANGENT) { // int8
+ for (uint32_t i = 0; i < p_elements; i++) {
+ const int8_t *src = (const int8_t *)&src_vertex_ptr[i * src_vertex_stride + src_offset];
+ uint32_t *dst = (uint32_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_TANGENT]];
+ const Vector2 src_vec(src[0] / 127.0f, src[1] / 127.0f);
+ float out_sign;
+ const Vector3 res = _oct_to_tangent(src_vec, &out_sign) * Vector3(0.5, 0.5, 0.5) + Vector3(0.5, 0.5, 0.5);
+
+ *dst = 0;
+ *dst |= CLAMP(int(res.x * 1023.0), 0, 1023);
+ *dst |= CLAMP(int(res.y * 1023.0), 0, 1023) << 10;
+ *dst |= CLAMP(int(res.z * 1023.0), 0, 1023) << 20;
+ if (out_sign > 0) {
+ *dst |= 3 << 30;
+ }
}
+ src_offset += sizeof(int8_t) * 2;
+ } else { // int16
+ for (uint32_t i = 0; i < p_elements; i++) {
+ const int16_t *src = (const int16_t *)&src_vertex_ptr[i * src_vertex_stride + src_offset];
+ uint32_t *dst = (uint32_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_TANGENT]];
+ const Vector2 src_vec(src[0] / 32767.0f, src[1] / 32767.0f);
+ float out_sign;
+ Vector3 res = _oct_to_tangent(src_vec, &out_sign) * Vector3(0.5, 0.5, 0.5) + Vector3(0.5, 0.5, 0.5);
+
+ *dst = 0;
+ *dst |= CLAMP(int(res.x * 1023.0), 0, 1023);
+ *dst |= CLAMP(int(res.y * 1023.0), 0, 1023) << 10;
+ *dst |= CLAMP(int(res.z * 1023.0), 0, 1023) << 20;
+ if (out_sign > 0) {
+ *dst |= 3 << 30;
+ }
+ }
+ src_offset += sizeof(int16_t) * 2;
}
- src_offset += sizeof(uint32_t);
- } else {
- for (uint32_t i = 0; i < p_elements; i++) {
- const float *src = (const float *)&src_vertex_ptr[i * src_vertex_stride + src_offset];
- uint32_t *dst = (uint32_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_TANGENT]];
-
- *dst = 0;
- *dst |= CLAMP(int(src[0] * 1023.0), 0, 1023);
- *dst |= CLAMP(int(src[1] * 1023.0), 0, 1023) << 10;
- *dst |= CLAMP(int(src[2] * 1023.0), 0, 1023) << 20;
- if (src[3] > 0) {
- *dst |= 3 << 30;
+ } else { // No Octahedral compression
+ if (p_old_format & OLD_ARRAY_COMPRESS_TANGENT) {
+ const float multiplier = 1.f / 127.f * 1023.0f;
+
+ for (uint32_t i = 0; i < p_elements; i++) {
+ const int8_t *src = (const int8_t *)&src_vertex_ptr[i * src_vertex_stride + src_offset];
+ uint32_t *dst = (uint32_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_TANGENT]];
+
+ *dst = 0;
+ *dst |= CLAMP(int(src[0] * multiplier), 0, 1023);
+ *dst |= CLAMP(int(src[1] * multiplier), 0, 1023) << 10;
+ *dst |= CLAMP(int(src[2] * multiplier), 0, 1023) << 20;
+ if (src[3] > 0) {
+ *dst |= 3 << 30;
+ }
+ }
+ src_offset += sizeof(uint32_t);
+ } else {
+ for (uint32_t i = 0; i < p_elements; i++) {
+ const float *src = (const float *)&src_vertex_ptr[i * src_vertex_stride + src_offset];
+ uint32_t *dst = (uint32_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_TANGENT]];
+
+ *dst = 0;
+ *dst |= CLAMP(int(src[0] * 1023.0), 0, 1023);
+ *dst |= CLAMP(int(src[1] * 1023.0), 0, 1023) << 10;
+ *dst |= CLAMP(int(src[2] * 1023.0), 0, 1023) << 20;
+ if (src[3] > 0) {
+ *dst |= 3 << 30;
+ }
}
+ src_offset += sizeof(float) * 4;
}
- src_offset += sizeof(float) * 4;
}
-
} break;
case OLD_ARRAY_COLOR: {
if (p_old_format & OLD_ARRAY_COMPRESS_COLOR) {
diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp
index 402e67a0f1..f9a4eba978 100644
--- a/scene/resources/packed_scene.cpp
+++ b/scene/resources/packed_scene.cpp
@@ -175,14 +175,12 @@ Node *SceneState::instantiate(GenEditState p_edit_state) const {
#endif
}
} else {
- Object *obj = nullptr;
+ //node belongs to this scene and must be created
+ Object *obj = ClassDB::instantiate(snames[n.type]);
- if (ClassDB::is_class_enabled(snames[n.type])) {
- //node belongs to this scene and must be created
- obj = ClassDB::instantiate(snames[n.type]);
- }
+ node = Object::cast_to<Node>(obj);
- if (!Object::cast_to<Node>(obj)) {
+ if (!node) {
if (obj) {
memdelete(obj);
obj = nullptr;
@@ -203,9 +201,9 @@ Node *SceneState::instantiate(GenEditState p_edit_state) const {
if (!obj) {
obj = memnew(Node);
}
- }
- node = Object::cast_to<Node>(obj);
+ node = Object::cast_to<Node>(obj);
+ }
}
if (node) {
diff --git a/scene/resources/primitive_meshes.h b/scene/resources/primitive_meshes.h
index 75ea6a0f12..aa9682bd80 100644
--- a/scene/resources/primitive_meshes.h
+++ b/scene/resources/primitive_meshes.h
@@ -36,11 +36,10 @@
///@TODO probably should change a few integers to unsigned integers...
/**
- @author Bastiaan Olij <mux213@gmail.com>
-
Base class for all the classes in this file, handles a number of code functions that are shared among all meshes.
This class is set apart that it assumes a single surface is always generated for our mesh.
*/
+
class PrimitiveMesh : public Mesh {
GDCLASS(PrimitiveMesh, Mesh);
diff --git a/scene/resources/separation_ray_shape_2d.cpp b/scene/resources/separation_ray_shape_2d.cpp
index 5ac8d0a475..0406c91b70 100644
--- a/scene/resources/separation_ray_shape_2d.cpp
+++ b/scene/resources/separation_ray_shape_2d.cpp
@@ -59,15 +59,13 @@ void SeparationRayShape2D::draw(const RID &p_to_rid, const Color &p_color) {
xf.rotate(target_position.angle());
xf.translate(Vector2(no_line ? 0 : target_position.length() - arrow_size, 0));
- Vector<Vector2> pts;
- pts.push_back(xf.xform(Vector2(arrow_size, 0)));
- pts.push_back(xf.xform(Vector2(0, 0.5 * arrow_size)));
- pts.push_back(xf.xform(Vector2(0, -0.5 * arrow_size)));
-
- Vector<Color> cols;
- for (int i = 0; i < 3; i++) {
- cols.push_back(p_color);
- }
+ Vector<Vector2> pts = {
+ xf.xform(Vector2(arrow_size, 0)),
+ xf.xform(Vector2(0, 0.5 * arrow_size)),
+ xf.xform(Vector2(0, -0.5 * arrow_size))
+ };
+
+ Vector<Color> cols = { p_color, p_color, p_color };
RS::get_singleton()->canvas_item_add_primitive(p_to_rid, pts, cols, Vector<Point2>(), RID());
}
diff --git a/scene/resources/separation_ray_shape_3d.cpp b/scene/resources/separation_ray_shape_3d.cpp
index a059d55bbe..5aa7616589 100644
--- a/scene/resources/separation_ray_shape_3d.cpp
+++ b/scene/resources/separation_ray_shape_3d.cpp
@@ -33,9 +33,10 @@
#include "servers/physics_server_3d.h"
Vector<Vector3> SeparationRayShape3D::get_debug_mesh_lines() const {
- Vector<Vector3> points;
- points.push_back(Vector3());
- points.push_back(Vector3(0, 0, get_length()));
+ Vector<Vector3> points = {
+ Vector3(),
+ Vector3(0, 0, get_length())
+ };
return points;
}
diff --git a/scene/resources/skin.cpp b/scene/resources/skin.cpp
index d371598cc0..54ed71999c 100644
--- a/scene/resources/skin.cpp
+++ b/scene/resources/skin.cpp
@@ -143,6 +143,7 @@ void Skin::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_bind_count"), &Skin::get_bind_count);
ClassDB::bind_method(D_METHOD("add_bind", "bone", "pose"), &Skin::add_bind);
+ ClassDB::bind_method(D_METHOD("add_named_bind", "name", "pose"), &Skin::add_named_bind);
ClassDB::bind_method(D_METHOD("set_bind_pose", "bind_index", "pose"), &Skin::set_bind_pose);
ClassDB::bind_method(D_METHOD("get_bind_pose", "bind_index"), &Skin::get_bind_pose);
diff --git a/scene/resources/sky_material.cpp b/scene/resources/sky_material.cpp
index 3918cc5ef8..6ec16f12df 100644
--- a/scene/resources/sky_material.cpp
+++ b/scene/resources/sky_material.cpp
@@ -308,14 +308,30 @@ Ref<Texture2D> PanoramaSkyMaterial::get_panorama() const {
return panorama;
}
+void PanoramaSkyMaterial::set_filtering_enabled(bool p_enabled) {
+ filter = p_enabled;
+ notify_property_list_changed();
+ _update_shader();
+ // Only set if shader already compiled
+ if (shader_set) {
+ RS::get_singleton()->material_set_shader(_get_material(), shader_cache[int(filter)]);
+ }
+}
+
+bool PanoramaSkyMaterial::is_filtering_enabled() const {
+ return filter;
+}
+
Shader::Mode PanoramaSkyMaterial::get_shader_mode() const {
return Shader::MODE_SKY;
}
RID PanoramaSkyMaterial::get_rid() const {
_update_shader();
+ // Don't compile shaders until first use, then compile both
if (!shader_set) {
- RS::get_singleton()->material_set_shader(_get_material(), shader);
+ RS::get_singleton()->material_set_shader(_get_material(), shader_cache[1 - int(filter)]);
+ RS::get_singleton()->material_set_shader(_get_material(), shader_cache[int(filter)]);
shader_set = true;
}
return _get_material();
@@ -323,42 +339,47 @@ RID PanoramaSkyMaterial::get_rid() const {
RID PanoramaSkyMaterial::get_shader_rid() const {
_update_shader();
- return shader;
+ return shader_cache[int(filter)];
}
void PanoramaSkyMaterial::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_panorama", "texture"), &PanoramaSkyMaterial::set_panorama);
ClassDB::bind_method(D_METHOD("get_panorama"), &PanoramaSkyMaterial::get_panorama);
+ ClassDB::bind_method(D_METHOD("set_filtering_enabled", "enabled"), &PanoramaSkyMaterial::set_filtering_enabled);
+ ClassDB::bind_method(D_METHOD("is_filtering_enabled"), &PanoramaSkyMaterial::is_filtering_enabled);
+
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "panorama", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_panorama", "get_panorama");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "filter"), "set_filtering_enabled", "is_filtering_enabled");
}
Mutex PanoramaSkyMaterial::shader_mutex;
-RID PanoramaSkyMaterial::shader;
+RID PanoramaSkyMaterial::shader_cache[2];
void PanoramaSkyMaterial::cleanup_shader() {
- if (shader.is_valid()) {
- RS::get_singleton()->free(shader);
+ if (shader_cache[0].is_valid()) {
+ RS::get_singleton()->free(shader_cache[0]);
+ RS::get_singleton()->free(shader_cache[1]);
}
}
void PanoramaSkyMaterial::_update_shader() {
shader_mutex.lock();
- if (shader.is_null()) {
- shader = RS::get_singleton()->shader_create();
+ if (shader_cache[0].is_null()) {
+ for (int i = 0; i < 2; i++) {
+ shader_cache[i] = RS::get_singleton()->shader_create();
- // Add a comment to describe the shader origin (useful when converting to ShaderMaterial).
- RS::get_singleton()->shader_set_code(shader, R"(
+ // Add a comment to describe the shader origin (useful when converting to ShaderMaterial).
+ RS::get_singleton()->shader_set_code(shader_cache[i], vformat(R"(
// NOTE: Shader automatically converted from )" VERSION_NAME " " VERSION_FULL_CONFIG R"('s PanoramaSkyMaterial.
-
shader_type sky;
-
-uniform sampler2D source_panorama : filter_linear, hint_albedo;
-
+uniform sampler2D source_panorama : %s, hint_albedo;
void sky() {
COLOR = texture(source_panorama, SKY_COORDS).rgb;
}
-)");
+)",
+ i ? "filter_linear" : "filter_nearest"));
+ }
}
shader_mutex.unlock();
diff --git a/scene/resources/sky_material.h b/scene/resources/sky_material.h
index 74b2965ce8..7f421beb8d 100644
--- a/scene/resources/sky_material.h
+++ b/scene/resources/sky_material.h
@@ -110,10 +110,12 @@ private:
Ref<Texture2D> panorama;
static Mutex shader_mutex;
- static RID shader;
+ static RID shader_cache[2];
static void _update_shader();
mutable bool shader_set = false;
+ bool filter = true;
+
protected:
static void _bind_methods();
@@ -121,6 +123,9 @@ public:
void set_panorama(const Ref<Texture2D> &p_panorama);
Ref<Texture2D> get_panorama() const;
+ void set_filtering_enabled(bool p_enabled);
+ bool is_filtering_enabled() const;
+
virtual Shader::Mode get_shader_mode() const override;
virtual RID get_shader_rid() const override;
virtual RID get_rid() const override;
diff --git a/scene/resources/style_box.cpp b/scene/resources/style_box.cpp
index c39902739f..5afd424e03 100644
--- a/scene/resources/style_box.cpp
+++ b/scene/resources/style_box.cpp
@@ -521,21 +521,22 @@ inline void draw_ring(Vector<Vector2> &verts, Vector<int> &indices, Vector<Color
set_inner_corner_radius(style_rect, ring_rect, corner_radius, ring_corner_radius);
// Corner radius center points.
- Vector<Point2> outer_points;
- outer_points.push_back(ring_rect.position + Vector2(ring_corner_radius[0], ring_corner_radius[0])); //tl
- outer_points.push_back(Point2(ring_rect.position.x + ring_rect.size.x - ring_corner_radius[1], ring_rect.position.y + ring_corner_radius[1])); //tr
- outer_points.push_back(ring_rect.position + ring_rect.size - Vector2(ring_corner_radius[2], ring_corner_radius[2])); //br
- outer_points.push_back(Point2(ring_rect.position.x + ring_corner_radius[3], ring_rect.position.y + ring_rect.size.y - ring_corner_radius[3])); //bl
+ Vector<Point2> outer_points = {
+ ring_rect.position + Vector2(ring_corner_radius[0], ring_corner_radius[0]), //tl
+ Point2(ring_rect.position.x + ring_rect.size.x - ring_corner_radius[1], ring_rect.position.y + ring_corner_radius[1]), //tr
+ ring_rect.position + ring_rect.size - Vector2(ring_corner_radius[2], ring_corner_radius[2]), //br
+ Point2(ring_rect.position.x + ring_corner_radius[3], ring_rect.position.y + ring_rect.size.y - ring_corner_radius[3]) //bl
+ };
real_t inner_corner_radius[4];
set_inner_corner_radius(style_rect, inner_rect, corner_radius, inner_corner_radius);
- Vector<Point2> inner_points;
- inner_points.push_back(inner_rect.position + Vector2(inner_corner_radius[0], inner_corner_radius[0])); //tl
- inner_points.push_back(Point2(inner_rect.position.x + inner_rect.size.x - inner_corner_radius[1], inner_rect.position.y + inner_corner_radius[1])); //tr
- inner_points.push_back(inner_rect.position + inner_rect.size - Vector2(inner_corner_radius[2], inner_corner_radius[2])); //br
- inner_points.push_back(Point2(inner_rect.position.x + inner_corner_radius[3], inner_rect.position.y + inner_rect.size.y - inner_corner_radius[3])); //bl
-
+ Vector<Point2> inner_points = {
+ inner_rect.position + Vector2(inner_corner_radius[0], inner_corner_radius[0]), //tl
+ Point2(inner_rect.position.x + inner_rect.size.x - inner_corner_radius[1], inner_rect.position.y + inner_corner_radius[1]), //tr
+ inner_rect.position + inner_rect.size - Vector2(inner_corner_radius[2], inner_corner_radius[2]), //br
+ Point2(inner_rect.position.x + inner_corner_radius[3], inner_rect.position.y + inner_rect.size.y - inner_corner_radius[3]) //bl
+ };
// Calculate the vertices.
for (int corner_index = 0; corner_index < 4; corner_index++) {
for (int detail = 0; detail <= adapted_corner_detail; detail++) {
diff --git a/scene/resources/syntax_highlighter.cpp b/scene/resources/syntax_highlighter.cpp
index 2efda08e08..e0aa21ac37 100644
--- a/scene/resources/syntax_highlighter.cpp
+++ b/scene/resources/syntax_highlighter.cpp
@@ -171,12 +171,15 @@ Dictionary CodeHighlighter::_get_line_syntax_highlighting_impl(int p_line) {
/* color regions */
if (is_a_symbol || in_region != -1) {
int from = j;
- for (; from < line_length; from++) {
- if (str[from] == '\\') {
- from++;
- continue;
+
+ if (in_region == -1) {
+ for (; from < line_length; from++) {
+ if (str[from] == '\\') {
+ from++;
+ continue;
+ }
+ break;
}
- break;
}
if (from != line_length) {
@@ -208,6 +211,12 @@ Dictionary CodeHighlighter::_get_line_syntax_highlighting_impl(int p_line) {
/* check if it's the whole line */
if (end_key_length == 0 || color_regions[c].line_only || from + end_key_length > line_length) {
+ if (from + end_key_length > line_length && (color_regions[in_region].start_key == "\"" || color_regions[in_region].start_key == "\'")) {
+ // If it's key length and there is a '\', dont skip to highlight esc chars.
+ if (str.find("\\", from) >= 0) {
+ break;
+ }
+ }
prev_color = color_regions[in_region].color;
highlighter_info["color"] = color_regions[c].color;
color_map[j] = highlighter_info;
@@ -227,13 +236,23 @@ Dictionary CodeHighlighter::_get_line_syntax_highlighting_impl(int p_line) {
/* if we are in one find the end key */
if (in_region != -1) {
+ bool is_string = (color_regions[in_region].start_key == "\"" || color_regions[in_region].start_key == "\'");
+
+ Color region_color = color_regions[in_region].color;
+ prev_color = region_color;
+ highlighter_info["color"] = region_color;
+ color_map[j] = highlighter_info;
+
/* search the line */
int region_end_index = -1;
int end_key_length = color_regions[in_region].end_key.length();
const char32_t *end_key = color_regions[in_region].end_key.get_data();
for (; from < line_length; from++) {
if (line_length - from < end_key_length) {
- break;
+ // Don't break if '\' to highlight esc chars.
+ if (!is_string || str.find("\\", from) < 0) {
+ break;
+ }
}
if (!is_symbol(str[from])) {
@@ -241,7 +260,20 @@ Dictionary CodeHighlighter::_get_line_syntax_highlighting_impl(int p_line) {
}
if (str[from] == '\\') {
+ if (is_string) {
+ Dictionary escape_char_highlighter_info;
+ escape_char_highlighter_info["color"] = symbol_color;
+ color_map[from] = escape_char_highlighter_info;
+ }
+
from++;
+
+ if (is_string) {
+ Dictionary region_continue_highlighter_info;
+ prev_color = region_color;
+ region_continue_highlighter_info["color"] = region_color;
+ color_map[from + 1] = region_continue_highlighter_info;
+ }
continue;
}
@@ -258,10 +290,6 @@ Dictionary CodeHighlighter::_get_line_syntax_highlighting_impl(int p_line) {
}
}
- prev_color = color_regions[in_region].color;
- highlighter_info["color"] = color_regions[in_region].color;
- color_map[j] = highlighter_info;
-
j = from + (end_key_length - 1);
if (region_end_index == -1) {
color_region_cache[p_line] = in_region;
diff --git a/scene/resources/text_paragraph.cpp b/scene/resources/text_paragraph.cpp
index 18e46e5476..c3bdef7b01 100644
--- a/scene/resources/text_paragraph.cpp
+++ b/scene/resources/text_paragraph.cpp
@@ -561,7 +561,7 @@ void TextParagraph::draw(RID p_canvas, const Vector2 &p_pos, const Color &p_colo
if (h_offset > 0) {
// Draw dropcap.
Vector2 dc_off = ofs;
- if (TS->shaped_text_get_direction(dropcap_rid) == TextServer::DIRECTION_RTL) {
+ if (TS->shaped_text_get_inferred_direction(dropcap_rid) == TextServer::DIRECTION_RTL) {
if (TS->shaped_text_get_orientation(dropcap_rid) == TextServer::ORIENTATION_HORIZONTAL) {
dc_off.x += width - h_offset;
} else {
@@ -579,7 +579,7 @@ void TextParagraph::draw(RID p_canvas, const Vector2 &p_pos, const Color &p_colo
ofs.x = p_pos.x;
ofs.y += TS->shaped_text_get_ascent(lines_rid[i]) + spacing_top;
if (i <= dropcap_lines) {
- if (TS->shaped_text_get_direction(dropcap_rid) == TextServer::DIRECTION_LTR) {
+ if (TS->shaped_text_get_inferred_direction(dropcap_rid) == TextServer::DIRECTION_LTR) {
ofs.x -= h_offset;
}
l_width -= h_offset;
@@ -588,7 +588,7 @@ void TextParagraph::draw(RID p_canvas, const Vector2 &p_pos, const Color &p_colo
ofs.y = p_pos.y;
ofs.x += TS->shaped_text_get_ascent(lines_rid[i]) + spacing_top;
if (i <= dropcap_lines) {
- if (TS->shaped_text_get_direction(dropcap_rid) == TextServer::DIRECTION_LTR) {
+ if (TS->shaped_text_get_inferred_direction(dropcap_rid) == TextServer::DIRECTION_LTR) {
ofs.x -= h_offset;
}
l_width -= h_offset;
@@ -598,7 +598,7 @@ void TextParagraph::draw(RID p_canvas, const Vector2 &p_pos, const Color &p_colo
if (width > 0) {
switch (alignment) {
case HORIZONTAL_ALIGNMENT_FILL:
- if (TS->shaped_text_get_direction(lines_rid[i]) == TextServer::DIRECTION_RTL) {
+ if (TS->shaped_text_get_inferred_direction(lines_rid[i]) == TextServer::DIRECTION_RTL) {
if (TS->shaped_text_get_orientation(lines_rid[i]) == TextServer::ORIENTATION_HORIZONTAL) {
ofs.x += l_width - line_width;
} else {
@@ -655,7 +655,7 @@ void TextParagraph::draw_outline(RID p_canvas, const Vector2 &p_pos, int p_outli
if (h_offset > 0) {
// Draw dropcap.
Vector2 dc_off = ofs;
- if (TS->shaped_text_get_direction(dropcap_rid) == TextServer::DIRECTION_RTL) {
+ if (TS->shaped_text_get_inferred_direction(dropcap_rid) == TextServer::DIRECTION_RTL) {
if (TS->shaped_text_get_orientation(dropcap_rid) == TextServer::ORIENTATION_HORIZONTAL) {
dc_off.x += width - h_offset;
} else {
@@ -671,7 +671,7 @@ void TextParagraph::draw_outline(RID p_canvas, const Vector2 &p_pos, int p_outli
ofs.x = p_pos.x;
ofs.y += TS->shaped_text_get_ascent(lines_rid[i]) + spacing_top;
if (i <= dropcap_lines) {
- if (TS->shaped_text_get_direction(dropcap_rid) == TextServer::DIRECTION_LTR) {
+ if (TS->shaped_text_get_inferred_direction(dropcap_rid) == TextServer::DIRECTION_LTR) {
ofs.x -= h_offset;
}
l_width -= h_offset;
@@ -680,7 +680,7 @@ void TextParagraph::draw_outline(RID p_canvas, const Vector2 &p_pos, int p_outli
ofs.y = p_pos.y;
ofs.x += TS->shaped_text_get_ascent(lines_rid[i]) + spacing_top;
if (i <= dropcap_lines) {
- if (TS->shaped_text_get_direction(dropcap_rid) == TextServer::DIRECTION_LTR) {
+ if (TS->shaped_text_get_inferred_direction(dropcap_rid) == TextServer::DIRECTION_LTR) {
ofs.x -= h_offset;
}
l_width -= h_offset;
@@ -690,7 +690,7 @@ void TextParagraph::draw_outline(RID p_canvas, const Vector2 &p_pos, int p_outli
if (width > 0) {
switch (alignment) {
case HORIZONTAL_ALIGNMENT_FILL:
- if (TS->shaped_text_get_direction(lines_rid[i]) == TextServer::DIRECTION_RTL) {
+ if (TS->shaped_text_get_inferred_direction(lines_rid[i]) == TextServer::DIRECTION_RTL) {
if (TS->shaped_text_get_orientation(lines_rid[i]) == TextServer::ORIENTATION_HORIZONTAL) {
ofs.x += l_width - length;
} else {
@@ -772,7 +772,7 @@ void TextParagraph::draw_dropcap(RID p_canvas, const Vector2 &p_pos, const Color
if (h_offset > 0) {
// Draw dropcap.
- if (TS->shaped_text_get_direction(dropcap_rid) == TextServer::DIRECTION_RTL) {
+ if (TS->shaped_text_get_inferred_direction(dropcap_rid) == TextServer::DIRECTION_RTL) {
if (TS->shaped_text_get_orientation(dropcap_rid) == TextServer::ORIENTATION_HORIZONTAL) {
ofs.x += width - h_offset;
} else {
@@ -794,7 +794,7 @@ void TextParagraph::draw_dropcap_outline(RID p_canvas, const Vector2 &p_pos, int
if (h_offset > 0) {
// Draw dropcap.
- if (TS->shaped_text_get_direction(dropcap_rid) == TextServer::DIRECTION_RTL) {
+ if (TS->shaped_text_get_inferred_direction(dropcap_rid) == TextServer::DIRECTION_RTL) {
if (TS->shaped_text_get_orientation(dropcap_rid) == TextServer::ORIENTATION_HORIZONTAL) {
ofs.x += width - h_offset;
} else {
diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp
index 28dc869c4f..331674d248 100644
--- a/scene/resources/texture.cpp
+++ b/scene/resources/texture.cpp
@@ -1156,7 +1156,7 @@ void AtlasTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_m
rc.size.height = atlas->get_height();
}
- RS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, Rect2(p_pos + margin.position, rc.size), atlas->get_rid(), rc, p_modulate, p_transpose, filter_clip);
+ atlas->draw_rect_region(p_canvas_item, Rect2(p_pos + margin.position, rc.size), rc, p_modulate, p_transpose, filter_clip);
}
void AtlasTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose) const {
@@ -1177,7 +1177,7 @@ void AtlasTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile
Vector2 scale = p_rect.size / (region.size + margin.size);
Rect2 dr(p_rect.position + margin.position * scale, rc.size * scale);
- RS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, dr, atlas->get_rid(), rc, p_modulate, p_transpose, filter_clip);
+ atlas->draw_rect_region(p_canvas_item, dr, rc, p_modulate, p_transpose, filter_clip);
}
void AtlasTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, bool p_clip_uv) const {
@@ -1190,7 +1190,7 @@ void AtlasTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, cons
Rect2 src_c;
get_rect_region(p_rect, p_src_rect, dr, src_c);
- RS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, dr, atlas->get_rid(), src_c, p_modulate, p_transpose, filter_clip);
+ atlas->draw_rect_region(p_canvas_item, dr, src_c, p_modulate, p_transpose, filter_clip);
}
bool AtlasTexture::get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const {
diff --git a/scene/resources/theme.cpp b/scene/resources/theme.cpp
index 186bbab689..8da287042e 100644
--- a/scene/resources/theme.cpp
+++ b/scene/resources/theme.cpp
@@ -36,11 +36,11 @@ Ref<Theme> Theme::default_theme;
Ref<Theme> Theme::project_default_theme;
// Universal default values, final fallback for every theme.
-float Theme::default_base_scale = 1.0;
-Ref<Texture2D> Theme::default_icon;
-Ref<StyleBox> Theme::default_style;
-Ref<Font> Theme::default_font;
-int Theme::default_font_size = 16;
+float Theme::fallback_base_scale = 1.0;
+Ref<Texture2D> Theme::fallback_icon;
+Ref<StyleBox> Theme::fallback_style;
+Ref<Font> Theme::fallback_font;
+int Theme::fallback_font_size = 16;
// Dynamic properties.
bool Theme::_set(const StringName &p_name, const Variant &p_value) {
@@ -220,87 +220,107 @@ void Theme::set_project_default(const Ref<Theme> &p_project_default) {
}
// Universal fallback values for theme item types.
-void Theme::set_default_base_scale(float p_base_scale) {
- default_base_scale = p_base_scale;
+void Theme::set_fallback_base_scale(float p_base_scale) {
+ fallback_base_scale = p_base_scale;
}
-void Theme::set_default_icon(const Ref<Texture2D> &p_icon) {
- default_icon = p_icon;
+void Theme::set_fallback_icon(const Ref<Texture2D> &p_icon) {
+ fallback_icon = p_icon;
}
-void Theme::set_default_style(const Ref<StyleBox> &p_style) {
- default_style = p_style;
+void Theme::set_fallback_style(const Ref<StyleBox> &p_style) {
+ fallback_style = p_style;
}
-void Theme::set_default_font(const Ref<Font> &p_font) {
- default_font = p_font;
+void Theme::set_fallback_font(const Ref<Font> &p_font) {
+ fallback_font = p_font;
}
-void Theme::set_default_font_size(int p_font_size) {
- default_font_size = p_font_size;
+void Theme::set_fallback_font_size(int p_font_size) {
+ fallback_font_size = p_font_size;
+}
+
+float Theme::get_fallback_base_scale() {
+ return fallback_base_scale;
+}
+
+Ref<Texture2D> Theme::get_fallback_icon() {
+ return fallback_icon;
+}
+
+Ref<StyleBox> Theme::get_fallback_style() {
+ return fallback_style;
+}
+
+Ref<Font> Theme::get_fallback_font() {
+ return fallback_font;
+}
+
+int Theme::get_fallback_font_size() {
+ return fallback_font_size;
}
// Fallback values for theme item types, configurable per theme.
-void Theme::set_default_theme_base_scale(float p_base_scale) {
- if (default_theme_base_scale == p_base_scale) {
+void Theme::set_default_base_scale(float p_base_scale) {
+ if (default_base_scale == p_base_scale) {
return;
}
- default_theme_base_scale = p_base_scale;
+ default_base_scale = p_base_scale;
_emit_theme_changed();
}
-float Theme::get_default_theme_base_scale() const {
- return default_theme_base_scale;
+float Theme::get_default_base_scale() const {
+ return default_base_scale;
}
-bool Theme::has_default_theme_base_scale() const {
- return default_theme_base_scale > 0.0;
+bool Theme::has_default_base_scale() const {
+ return default_base_scale > 0.0;
}
-void Theme::set_default_theme_font(const Ref<Font> &p_default_font) {
- if (default_theme_font == p_default_font) {
+void Theme::set_default_font(const Ref<Font> &p_default_font) {
+ if (default_font == p_default_font) {
return;
}
- if (default_theme_font.is_valid()) {
- default_theme_font->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed));
+ if (default_font.is_valid()) {
+ default_font->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed));
}
- default_theme_font = p_default_font;
+ default_font = p_default_font;
- if (default_theme_font.is_valid()) {
- default_theme_font->connect("changed", callable_mp(this, &Theme::_emit_theme_changed), varray(false), CONNECT_REFERENCE_COUNTED);
+ if (default_font.is_valid()) {
+ default_font->connect("changed", callable_mp(this, &Theme::_emit_theme_changed), varray(false), CONNECT_REFERENCE_COUNTED);
}
_emit_theme_changed();
}
-Ref<Font> Theme::get_default_theme_font() const {
- return default_theme_font;
+Ref<Font> Theme::get_default_font() const {
+ return default_font;
}
-bool Theme::has_default_theme_font() const {
- return default_theme_font.is_valid();
+bool Theme::has_default_font() const {
+ return default_font.is_valid();
}
-void Theme::set_default_theme_font_size(int p_font_size) {
- if (default_theme_font_size == p_font_size) {
+void Theme::set_default_font_size(int p_font_size) {
+ if (default_font_size == p_font_size) {
return;
}
- default_theme_font_size = p_font_size;
+ default_font_size = p_font_size;
_emit_theme_changed();
}
-int Theme::get_default_theme_font_size() const {
- return default_theme_font_size;
+int Theme::get_default_font_size() const {
+ return default_font_size;
}
-bool Theme::has_default_theme_font_size() const {
- return default_theme_font_size > 0;
+bool Theme::has_default_font_size() const {
+ return default_font_size > 0;
}
// Icons.
@@ -324,7 +344,7 @@ Ref<Texture2D> Theme::get_icon(const StringName &p_name, const StringName &p_the
if (icon_map.has(p_theme_type) && icon_map[p_theme_type].has(p_name) && icon_map[p_theme_type][p_name].is_valid()) {
return icon_map[p_theme_type][p_name];
} else {
- return default_icon;
+ return fallback_icon;
}
}
@@ -411,7 +431,7 @@ Ref<StyleBox> Theme::get_stylebox(const StringName &p_name, const StringName &p_
if (style_map.has(p_theme_type) && style_map[p_theme_type].has(p_name) && style_map[p_theme_type][p_name].is_valid()) {
return style_map[p_theme_type][p_name];
} else {
- return default_style;
+ return fallback_style;
}
}
@@ -497,15 +517,15 @@ void Theme::set_font(const StringName &p_name, const StringName &p_theme_type, c
Ref<Font> Theme::get_font(const StringName &p_name, const StringName &p_theme_type) const {
if (font_map.has(p_theme_type) && font_map[p_theme_type].has(p_name) && font_map[p_theme_type][p_name].is_valid()) {
return font_map[p_theme_type][p_name];
- } else if (has_default_theme_font()) {
- return default_theme_font;
- } else {
+ } else if (has_default_font()) {
return default_font;
+ } else {
+ return fallback_font;
}
}
bool Theme::has_font(const StringName &p_name, const StringName &p_theme_type) const {
- return ((font_map.has(p_theme_type) && font_map[p_theme_type].has(p_name) && font_map[p_theme_type][p_name].is_valid()) || has_default_theme_font());
+ return ((font_map.has(p_theme_type) && font_map[p_theme_type].has(p_name) && font_map[p_theme_type][p_name].is_valid()) || has_default_font());
}
bool Theme::has_font_nocheck(const StringName &p_name, const StringName &p_theme_type) const {
@@ -577,15 +597,15 @@ void Theme::set_font_size(const StringName &p_name, const StringName &p_theme_ty
int Theme::get_font_size(const StringName &p_name, const StringName &p_theme_type) const {
if (font_size_map.has(p_theme_type) && font_size_map[p_theme_type].has(p_name) && (font_size_map[p_theme_type][p_name] > 0)) {
return font_size_map[p_theme_type][p_name];
- } else if (has_default_theme_font_size()) {
- return default_theme_font_size;
- } else {
+ } else if (has_default_font_size()) {
return default_font_size;
+ } else {
+ return fallback_font_size;
}
}
bool Theme::has_font_size(const StringName &p_name, const StringName &p_theme_type) const {
- return ((font_size_map.has(p_theme_type) && font_size_map[p_theme_type].has(p_name) && (font_size_map[p_theme_type][p_name] > 0)) || has_default_theme_font_size());
+ return ((font_size_map.has(p_theme_type) && font_size_map[p_theme_type].has(p_name) && (font_size_map[p_theme_type][p_name] > 0)) || has_default_font_size());
}
bool Theme::has_font_size_nocheck(const StringName &p_name, const StringName &p_theme_type) const {
@@ -1622,17 +1642,17 @@ void Theme::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_constant_list", "theme_type"), &Theme::_get_constant_list);
ClassDB::bind_method(D_METHOD("get_constant_type_list"), &Theme::_get_constant_type_list);
- ClassDB::bind_method(D_METHOD("set_default_base_scale", "font_size"), &Theme::set_default_theme_base_scale);
- ClassDB::bind_method(D_METHOD("get_default_base_scale"), &Theme::get_default_theme_base_scale);
- ClassDB::bind_method(D_METHOD("has_default_base_scale"), &Theme::has_default_theme_base_scale);
+ ClassDB::bind_method(D_METHOD("set_default_base_scale", "base_scale"), &Theme::set_default_base_scale);
+ ClassDB::bind_method(D_METHOD("get_default_base_scale"), &Theme::get_default_base_scale);
+ ClassDB::bind_method(D_METHOD("has_default_base_scale"), &Theme::has_default_base_scale);
- ClassDB::bind_method(D_METHOD("set_default_font", "font"), &Theme::set_default_theme_font);
- ClassDB::bind_method(D_METHOD("get_default_font"), &Theme::get_default_theme_font);
- ClassDB::bind_method(D_METHOD("has_default_font"), &Theme::has_default_theme_font);
+ ClassDB::bind_method(D_METHOD("set_default_font", "font"), &Theme::set_default_font);
+ ClassDB::bind_method(D_METHOD("get_default_font"), &Theme::get_default_font);
+ ClassDB::bind_method(D_METHOD("has_default_font"), &Theme::has_default_font);
- ClassDB::bind_method(D_METHOD("set_default_font_size", "font_size"), &Theme::set_default_theme_font_size);
- ClassDB::bind_method(D_METHOD("get_default_font_size"), &Theme::get_default_theme_font_size);
- ClassDB::bind_method(D_METHOD("has_default_font_size"), &Theme::has_default_theme_font_size);
+ ClassDB::bind_method(D_METHOD("set_default_font_size", "font_size"), &Theme::set_default_font_size);
+ ClassDB::bind_method(D_METHOD("get_default_font_size"), &Theme::get_default_font_size);
+ ClassDB::bind_method(D_METHOD("has_default_font_size"), &Theme::has_default_font_size);
ClassDB::bind_method(D_METHOD("set_theme_item", "data_type", "name", "theme_type", "value"), &Theme::set_theme_item);
ClassDB::bind_method(D_METHOD("get_theme_item", "data_type", "name", "theme_type"), &Theme::get_theme_item);
diff --git a/scene/resources/theme.h b/scene/resources/theme.h
index 2e0a645005..822743a1fe 100644
--- a/scene/resources/theme.h
+++ b/scene/resources/theme.h
@@ -101,16 +101,16 @@ protected:
static Ref<Theme> project_default_theme;
// Universal default values, final fallback for every theme.
- static float default_base_scale;
- static Ref<Texture2D> default_icon;
- static Ref<StyleBox> default_style;
- static Ref<Font> default_font;
- static int default_font_size;
+ static float fallback_base_scale;
+ static Ref<Texture2D> fallback_icon;
+ static Ref<StyleBox> fallback_style;
+ static Ref<Font> fallback_font;
+ static int fallback_font_size;
// Default values configurable for each individual theme.
- float default_theme_base_scale = 0.0;
- Ref<Font> default_theme_font;
- int default_theme_font_size = -1;
+ float default_base_scale = 0.0;
+ Ref<Font> default_font;
+ int default_font_size = -1;
static void _bind_methods();
@@ -126,23 +126,29 @@ public:
static Ref<Theme> get_project_default();
static void set_project_default(const Ref<Theme> &p_project_default);
- static void set_default_base_scale(float p_base_scale);
- static void set_default_icon(const Ref<Texture2D> &p_icon);
- static void set_default_style(const Ref<StyleBox> &p_style);
- static void set_default_font(const Ref<Font> &p_font);
- static void set_default_font_size(int p_font_size);
-
- void set_default_theme_base_scale(float p_base_scale);
- float get_default_theme_base_scale() const;
- bool has_default_theme_base_scale() const;
-
- void set_default_theme_font(const Ref<Font> &p_default_font);
- Ref<Font> get_default_theme_font() const;
- bool has_default_theme_font() const;
-
- void set_default_theme_font_size(int p_font_size);
- int get_default_theme_font_size() const;
- bool has_default_theme_font_size() const;
+ static void set_fallback_base_scale(float p_base_scale);
+ static void set_fallback_icon(const Ref<Texture2D> &p_icon);
+ static void set_fallback_style(const Ref<StyleBox> &p_style);
+ static void set_fallback_font(const Ref<Font> &p_font);
+ static void set_fallback_font_size(int p_font_size);
+
+ static float get_fallback_base_scale();
+ static Ref<Texture2D> get_fallback_icon();
+ static Ref<StyleBox> get_fallback_style();
+ static Ref<Font> get_fallback_font();
+ static int get_fallback_font_size();
+
+ void set_default_base_scale(float p_base_scale);
+ float get_default_base_scale() const;
+ bool has_default_base_scale() const;
+
+ void set_default_font(const Ref<Font> &p_default_font);
+ Ref<Font> get_default_font() const;
+ bool has_default_font() const;
+
+ void set_default_font_size(int p_font_size);
+ int get_default_font_size() const;
+ bool has_default_font_size() const;
void set_icon(const StringName &p_name, const StringName &p_theme_type, const Ref<Texture2D> &p_icon);
Ref<Texture2D> get_icon(const StringName &p_name, const StringName &p_theme_type) const;
diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp
index 44a7af75b9..ddb9cc7440 100644
--- a/scene/resources/tile_set.cpp
+++ b/scene/resources/tile_set.cpp
@@ -1765,11 +1765,14 @@ Vector<Point2> TileSet::_get_square_corner_or_side_terrain_bit_polygon(Vector2i
break;
}
bit_rect.position *= Vector2(p_size) / 6.0;
- Vector<Vector2> polygon;
- polygon.push_back(bit_rect.position);
- polygon.push_back(Vector2(bit_rect.get_end().x, bit_rect.position.y));
- polygon.push_back(bit_rect.get_end());
- polygon.push_back(Vector2(bit_rect.position.x, bit_rect.get_end().y));
+
+ Vector<Vector2> polygon = {
+ bit_rect.position,
+ Vector2(bit_rect.get_end().x, bit_rect.position.y),
+ bit_rect.get_end(),
+ Vector2(bit_rect.position.x, bit_rect.get_end().y)
+ };
+
return polygon;
}
@@ -1984,25 +1987,26 @@ Vector<Point2> TileSet::_get_isometric_side_terrain_bit_polygon(Vector2i p_size,
}
Vector<Point2> TileSet::_get_half_offset_corner_or_side_terrain_bit_polygon(Vector2i p_size, TileSet::CellNeighbor p_bit, float p_overlap, TileSet::TileOffsetAxis p_offset_axis) {
- Vector<Vector2> point_list;
- point_list.push_back(Vector2(3, (3.0 * (1.0 - p_overlap * 2.0)) / 2.0));
- point_list.push_back(Vector2(3, 3.0 * (1.0 - p_overlap * 2.0)));
- point_list.push_back(Vector2(2, 3.0 * (1.0 - (p_overlap * 2.0) * 2.0 / 3.0)));
- point_list.push_back(Vector2(1, 3.0 - p_overlap * 2.0));
- point_list.push_back(Vector2(0, 3));
- point_list.push_back(Vector2(-1, 3.0 - p_overlap * 2.0));
- point_list.push_back(Vector2(-2, 3.0 * (1.0 - (p_overlap * 2.0) * 2.0 / 3.0)));
- point_list.push_back(Vector2(-3, 3.0 * (1.0 - p_overlap * 2.0)));
- point_list.push_back(Vector2(-3, (3.0 * (1.0 - p_overlap * 2.0)) / 2.0));
- point_list.push_back(Vector2(-3, -(3.0 * (1.0 - p_overlap * 2.0)) / 2.0));
- point_list.push_back(Vector2(-3, -3.0 * (1.0 - p_overlap * 2.0)));
- point_list.push_back(Vector2(-2, -3.0 * (1.0 - (p_overlap * 2.0) * 2.0 / 3.0)));
- point_list.push_back(Vector2(-1, -(3.0 - p_overlap * 2.0)));
- point_list.push_back(Vector2(0, -3));
- point_list.push_back(Vector2(1, -(3.0 - p_overlap * 2.0)));
- point_list.push_back(Vector2(2, -3.0 * (1.0 - (p_overlap * 2.0) * 2.0 / 3.0)));
- point_list.push_back(Vector2(3, -3.0 * (1.0 - p_overlap * 2.0)));
- point_list.push_back(Vector2(3, -(3.0 * (1.0 - p_overlap * 2.0)) / 2.0));
+ Vector<Vector2> point_list = {
+ Vector2(3, (3.0 * (1.0 - p_overlap * 2.0)) / 2.0),
+ Vector2(3, 3.0 * (1.0 - p_overlap * 2.0)),
+ Vector2(2, 3.0 * (1.0 - (p_overlap * 2.0) * 2.0 / 3.0)),
+ Vector2(1, 3.0 - p_overlap * 2.0),
+ Vector2(0, 3),
+ Vector2(-1, 3.0 - p_overlap * 2.0),
+ Vector2(-2, 3.0 * (1.0 - (p_overlap * 2.0) * 2.0 / 3.0)),
+ Vector2(-3, 3.0 * (1.0 - p_overlap * 2.0)),
+ Vector2(-3, (3.0 * (1.0 - p_overlap * 2.0)) / 2.0),
+ Vector2(-3, -(3.0 * (1.0 - p_overlap * 2.0)) / 2.0),
+ Vector2(-3, -3.0 * (1.0 - p_overlap * 2.0)),
+ Vector2(-2, -3.0 * (1.0 - (p_overlap * 2.0) * 2.0 / 3.0)),
+ Vector2(-1, -(3.0 - p_overlap * 2.0)),
+ Vector2(0, -3),
+ Vector2(1, -(3.0 - p_overlap * 2.0)),
+ Vector2(2, -3.0 * (1.0 - (p_overlap * 2.0) * 2.0 / 3.0)),
+ Vector2(3, -3.0 * (1.0 - p_overlap * 2.0)),
+ Vector2(3, -(3.0 * (1.0 - p_overlap * 2.0)) / 2.0)
+ };
Vector2 unit = Vector2(p_size) / 6.0;
for (int i = 0; i < point_list.size(); i++) {
@@ -2144,19 +2148,20 @@ Vector<Point2> TileSet::_get_half_offset_corner_or_side_terrain_bit_polygon(Vect
}
Vector<Point2> TileSet::_get_half_offset_corner_terrain_bit_polygon(Vector2i p_size, TileSet::CellNeighbor p_bit, float p_overlap, TileSet::TileOffsetAxis p_offset_axis) {
- Vector<Vector2> point_list;
- point_list.push_back(Vector2(3, 0));
- point_list.push_back(Vector2(3, 3.0 * (1.0 - p_overlap * 2.0)));
- point_list.push_back(Vector2(1.5, (3.0 * (1.0 - p_overlap * 2.0) + 3.0) / 2.0));
- point_list.push_back(Vector2(0, 3));
- point_list.push_back(Vector2(-1.5, (3.0 * (1.0 - p_overlap * 2.0) + 3.0) / 2.0));
- point_list.push_back(Vector2(-3, 3.0 * (1.0 - p_overlap * 2.0)));
- point_list.push_back(Vector2(-3, 0));
- point_list.push_back(Vector2(-3, -3.0 * (1.0 - p_overlap * 2.0)));
- point_list.push_back(Vector2(-1.5, -(3.0 * (1.0 - p_overlap * 2.0) + 3.0) / 2.0));
- point_list.push_back(Vector2(0, -3));
- point_list.push_back(Vector2(1.5, -(3.0 * (1.0 - p_overlap * 2.0) + 3.0) / 2.0));
- point_list.push_back(Vector2(3, -3.0 * (1.0 - p_overlap * 2.0)));
+ Vector<Vector2> point_list = {
+ Vector2(3, 0),
+ Vector2(3, 3.0 * (1.0 - p_overlap * 2.0)),
+ Vector2(1.5, (3.0 * (1.0 - p_overlap * 2.0) + 3.0) / 2.0),
+ Vector2(0, 3),
+ Vector2(-1.5, (3.0 * (1.0 - p_overlap * 2.0) + 3.0) / 2.0),
+ Vector2(-3, 3.0 * (1.0 - p_overlap * 2.0)),
+ Vector2(-3, 0),
+ Vector2(-3, -3.0 * (1.0 - p_overlap * 2.0)),
+ Vector2(-1.5, -(3.0 * (1.0 - p_overlap * 2.0) + 3.0) / 2.0),
+ Vector2(0, -3),
+ Vector2(1.5, -(3.0 * (1.0 - p_overlap * 2.0) + 3.0) / 2.0),
+ Vector2(3, -3.0 * (1.0 - p_overlap * 2.0))
+ };
Vector2 unit = Vector2(p_size) / 6.0;
for (int i = 0; i < point_list.size(); i++) {
@@ -2250,13 +2255,14 @@ Vector<Point2> TileSet::_get_half_offset_corner_terrain_bit_polygon(Vector2i p_s
}
Vector<Point2> TileSet::_get_half_offset_side_terrain_bit_polygon(Vector2i p_size, TileSet::CellNeighbor p_bit, float p_overlap, TileSet::TileOffsetAxis p_offset_axis) {
- Vector<Vector2> point_list;
- point_list.push_back(Vector2(3, 3.0 * (1.0 - p_overlap * 2.0)));
- point_list.push_back(Vector2(0, 3));
- point_list.push_back(Vector2(-3, 3.0 * (1.0 - p_overlap * 2.0)));
- point_list.push_back(Vector2(-3, -3.0 * (1.0 - p_overlap * 2.0)));
- point_list.push_back(Vector2(0, -3));
- point_list.push_back(Vector2(3, -3.0 * (1.0 - p_overlap * 2.0)));
+ Vector<Vector2> point_list = {
+ Vector2(3, 3.0 * (1.0 - p_overlap * 2.0)),
+ Vector2(0, 3),
+ Vector2(-3, 3.0 * (1.0 - p_overlap * 2.0)),
+ Vector2(-3, -3.0 * (1.0 - p_overlap * 2.0)),
+ Vector2(0, -3),
+ Vector2(3, -3.0 * (1.0 - p_overlap * 2.0))
+ };
Vector2 unit = Vector2(p_size) / 6.0;
for (int i = 0; i < point_list.size(); i++) {
diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp
index ed34c906a1..ece1ba1972 100644
--- a/scene/resources/visual_shader.cpp
+++ b/scene/resources/visual_shader.cpp
@@ -349,11 +349,11 @@ String VisualShaderNodeCustom::get_output_port_name(int p_port) const {
String VisualShaderNodeCustom::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
ERR_FAIL_COND_V(!GDVIRTUAL_IS_OVERRIDDEN(_get_code), "");
- Vector<String> input_vars;
+ TypedArray<String> input_vars;
for (int i = 0; i < get_input_port_count(); i++) {
input_vars.push_back(p_input_vars[i]);
}
- Array output_vars;
+ TypedArray<String> output_vars;
for (int i = 0; i < get_output_port_count(); i++) {
output_vars.push_back(p_output_vars[i]);
}
@@ -2015,7 +2015,7 @@ void VisualShader::_bind_methods() {
ClassDB::bind_method(D_METHOD("_update_shader"), &VisualShader::_update_shader);
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "graph_offset", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_graph_offset", "get_graph_offset");
- ADD_PROPERTY(PropertyInfo(Variant::STRING, "engine_version", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_engine_version", "get_engine_version");
+ ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "engine_version", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_engine_version", "get_engine_version");
ADD_PROPERTY_DEFAULT("code", ""); // Inherited from Shader, prevents showing default code as override in docs.
diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h
index c8b577088d..066c18e3bc 100644
--- a/scene/resources/visual_shader.h
+++ b/scene/resources/visual_shader.h
@@ -326,7 +326,7 @@ protected:
GDVIRTUAL0RC(int, _get_output_port_count)
GDVIRTUAL1RC(int, _get_output_port_type, int)
GDVIRTUAL1RC(String, _get_output_port_name, int)
- GDVIRTUAL4RC(String, _get_code, Vector<String>, TypedArray<String>, Shader::Mode, VisualShader::Type)
+ GDVIRTUAL4RC(String, _get_code, TypedArray<String>, TypedArray<String>, Shader::Mode, VisualShader::Type)
GDVIRTUAL1RC(String, _get_global_code, Shader::Mode)
GDVIRTUAL0RC(bool, _is_highend)
diff --git a/scene/resources/world_boundary_shape_3d.cpp b/scene/resources/world_boundary_shape_3d.cpp
index efa288511d..09d41e8291 100644
--- a/scene/resources/world_boundary_shape_3d.cpp
+++ b/scene/resources/world_boundary_shape_3d.cpp
@@ -34,7 +34,6 @@
Vector<Vector3> WorldBoundaryShape3D::get_debug_mesh_lines() const {
Plane p = get_plane();
- Vector<Vector3> points;
Vector3 n1 = p.get_any_perpendicular_normal();
Vector3 n2 = p.normal.cross(n1).normalized();
@@ -46,16 +45,18 @@ Vector<Vector3> WorldBoundaryShape3D::get_debug_mesh_lines() const {
p.normal * p.d + n1 * -10.0 + n2 * 10.0,
};
- points.push_back(pface[0]);
- points.push_back(pface[1]);
- points.push_back(pface[1]);
- points.push_back(pface[2]);
- points.push_back(pface[2]);
- points.push_back(pface[3]);
- points.push_back(pface[3]);
- points.push_back(pface[0]);
- points.push_back(p.normal * p.d);
- points.push_back(p.normal * p.d + p.normal * 3);
+ Vector<Vector3> points = {
+ pface[0],
+ pface[1],
+ pface[1],
+ pface[2],
+ pface[2],
+ pface[3],
+ pface[3],
+ pface[0],
+ p.normal * p.d,
+ p.normal * p.d + p.normal * 3
+ };
return points;
}