summaryrefslogtreecommitdiff
path: root/scene
diff options
context:
space:
mode:
Diffstat (limited to 'scene')
-rw-r--r--scene/2d/parallax_layer.cpp19
-rw-r--r--scene/3d/baked_light_instance.cpp10
-rw-r--r--scene/3d/baked_light_instance.h2
-rw-r--r--scene/gui/file_dialog.cpp19
-rw-r--r--scene/gui/file_dialog.h2
-rw-r--r--scene/gui/graph_edit.cpp5
-rw-r--r--scene/gui/graph_edit.h1
-rw-r--r--scene/gui/graph_node.cpp5
-rw-r--r--scene/gui/label.cpp4
-rw-r--r--scene/gui/line_edit.cpp2
-rw-r--r--scene/gui/spin_box.cpp2
-rw-r--r--scene/gui/text_edit.cpp29
-rw-r--r--scene/gui/text_edit.h2
-rw-r--r--scene/gui/tree.cpp8
-rw-r--r--scene/main/http_request.cpp108
-rw-r--r--scene/main/http_request.h13
-rw-r--r--scene/main/viewport.cpp27
-rw-r--r--scene/resources/curve.cpp6
-rw-r--r--scene/resources/dynamic_font.cpp174
-rw-r--r--scene/resources/dynamic_font.h52
-rw-r--r--scene/resources/world_2d.cpp2
21 files changed, 394 insertions, 98 deletions
diff --git a/scene/2d/parallax_layer.cpp b/scene/2d/parallax_layer.cpp
index e9378b1d02..05136de5d6 100644
--- a/scene/2d/parallax_layer.cpp
+++ b/scene/2d/parallax_layer.cpp
@@ -123,26 +123,15 @@ void ParallaxLayer::set_base_offset_and_scale(const Point2& p_offset,float p_sca
Point2 new_ofs = ((orig_offset+p_offset)*motion_scale)*p_scale+motion_offset;
if (mirroring.x) {
-
- while( new_ofs.x>=0) {
- new_ofs.x -= mirroring.x*p_scale;
- }
- while(new_ofs.x < -mirroring.x*p_scale) {
- new_ofs.x += mirroring.x*p_scale;
- }
+ double den = mirroring.x*p_scale;
+ new_ofs.x -= den*ceil(new_ofs.x/den);
}
if (mirroring.y) {
-
- while( new_ofs.y>=0) {
- new_ofs.y -= mirroring.y*p_scale;
- }
- while(new_ofs.y < -mirroring.y*p_scale) {
- new_ofs.y += mirroring.y*p_scale;
- }
+ double den = mirroring.y*p_scale;
+ new_ofs.y -= den*ceil(new_ofs.y/den);
}
-
set_pos(new_ofs);
set_scale(Vector2(1,1)*p_scale);
diff --git a/scene/3d/baked_light_instance.cpp b/scene/3d/baked_light_instance.cpp
index fafa62866f..ca3a309568 100644
--- a/scene/3d/baked_light_instance.cpp
+++ b/scene/3d/baked_light_instance.cpp
@@ -60,6 +60,8 @@ void BakedLightInstance::set_baked_light(const Ref<BakedLight>& p_baked_light) {
// VS::get_singleton()->instance_geometry_set_baked_light(E->get()->get_instance(),baked_light.is_valid()?get_instance():RID());
// }
}
+
+ update_configuration_warning();
}
Ref<BakedLight> BakedLightInstance::get_baked_light() const{
@@ -77,6 +79,14 @@ DVector<Face3> BakedLightInstance::get_faces(uint32_t p_usage_flags) const {
}
+String BakedLightInstance::get_configuration_warning() const {
+ if (get_baked_light().is_null()) {
+ return TTR("BakedLightInstance does not contain a BakedLight resource.");
+ }
+ return String();
+}
+
+
void BakedLightInstance::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_baked_light","baked_light"),&BakedLightInstance::set_baked_light);
diff --git a/scene/3d/baked_light_instance.h b/scene/3d/baked_light_instance.h
index 92c2d50986..002e55df1d 100644
--- a/scene/3d/baked_light_instance.h
+++ b/scene/3d/baked_light_instance.h
@@ -55,6 +55,8 @@ public:
virtual AABB get_aabb() const;
virtual DVector<Face3> get_faces(uint32_t p_usage_flags) const;
+ String get_configuration_warning() const;
+
BakedLightInstance();
};
diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp
index d335399caa..6b43425edc 100644
--- a/scene/gui/file_dialog.cpp
+++ b/scene/gui/file_dialog.cpp
@@ -475,7 +475,7 @@ void FileDialog::update_filters() {
String flt=filters[i].get_slice(";",0).strip_edges();
String desc=filters[i].get_slice(";",1).strip_edges();
if (desc.length())
- filter->add_item(desc+" ( "+flt+" )");
+ filter->add_item(String(XL_MESSAGE(desc))+" ( "+flt+" )");
else
filter->add_item("( "+flt+" )");
}
@@ -498,6 +498,16 @@ void FileDialog::add_filter(const String& p_filter) {
}
+void FileDialog::set_filters(const Vector<String>& p_filters){
+ filters=p_filters;
+ update_filters();
+ invalidate();
+}
+
+Vector<String> FileDialog::get_filters() const{
+ return filters;
+}
+
String FileDialog::get_current_dir() const {
return dir->get_text();
@@ -686,6 +696,8 @@ void FileDialog::_bind_methods() {
ObjectTypeDB::bind_method(_MD("clear_filters"),&FileDialog::clear_filters);
ObjectTypeDB::bind_method(_MD("add_filter","filter"),&FileDialog::add_filter);
+ ObjectTypeDB::bind_method(_MD("set_filters","filters"),&FileDialog::set_filters);
+ ObjectTypeDB::bind_method(_MD("get_filters"),&FileDialog::get_filters);
ObjectTypeDB::bind_method(_MD("get_current_dir"),&FileDialog::get_current_dir);
ObjectTypeDB::bind_method(_MD("get_current_file"),&FileDialog::get_current_file);
ObjectTypeDB::bind_method(_MD("get_current_path"),&FileDialog::get_current_path);
@@ -722,6 +734,11 @@ void FileDialog::_bind_methods() {
BIND_CONSTANT( ACCESS_USERDATA );
BIND_CONSTANT( ACCESS_FILESYSTEM );
+ ADD_PROPERTY( PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Open one,Open many,Open folder,Open any,Save"),_SCS("set_mode"),_SCS("get_mode") );
+ ADD_PROPERTY( PropertyInfo(Variant::INT, "access", PROPERTY_HINT_ENUM, "Resources,User data,File system"),_SCS("set_access"),_SCS("get_access") );
+ ADD_PROPERTY( PropertyInfo(Variant::STRING_ARRAY, "filters"),_SCS("set_filters"),_SCS("get_filters") );
+ ADD_PROPERTY( PropertyInfo(Variant::BOOL, "show_hidden_files"),_SCS("set_show_hidden_files"),_SCS("is_showing_hidden_files") );
+
}
diff --git a/scene/gui/file_dialog.h b/scene/gui/file_dialog.h
index 1fcf8387ce..150b24cb3f 100644
--- a/scene/gui/file_dialog.h
+++ b/scene/gui/file_dialog.h
@@ -131,6 +131,8 @@ public:
void clear_filters();
void add_filter(const String& p_filter);
+ void set_filters(const Vector<String>& p_filters);
+ Vector<String> get_filters() const;
void set_enable_multiple_selection(bool p_enable);
Vector<String> get_selected_files() const;
diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp
index d24c59a21f..adda54ad70 100644
--- a/scene/gui/graph_edit.cpp
+++ b/scene/gui/graph_edit.cpp
@@ -592,7 +592,9 @@ void GraphEdit::_input_event(const InputEvent& p_ev) {
if (p_ev.type==InputEvent::MOUSE_MOTION && dragging) {
just_selected=true;
- drag_accum+=Vector2(p_ev.mouse_motion.relative_x,p_ev.mouse_motion.relative_y);
+ // TODO: Remove local mouse pos hack if/when InputEventMouseMotion is fixed to support floats
+ //drag_accum+=Vector2(p_ev.mouse_motion.relative_x,p_ev.mouse_motion.relative_y);
+ drag_accum = get_local_mouse_pos() - drag_origin;
for(int i=get_child_count()-1;i>=0;i--) {
GraphNode *gn=get_child(i)->cast_to<GraphNode>();
if (gn && gn->is_selected())
@@ -709,6 +711,7 @@ void GraphEdit::_input_event(const InputEvent& p_ev) {
dragging = true;
drag_accum = Vector2();
+ drag_origin = get_local_mouse_pos();
just_selected = !gn->is_selected();
if(!gn->is_selected() && !Input::get_singleton()->is_key_pressed(KEY_CONTROL)) {
for (int i = 0; i < get_child_count(); i++) {
diff --git a/scene/gui/graph_edit.h b/scene/gui/graph_edit.h
index 100b6e94ab..e97d6bcb74 100644
--- a/scene/gui/graph_edit.h
+++ b/scene/gui/graph_edit.h
@@ -92,6 +92,7 @@ private:
bool dragging;
bool just_selected;
Vector2 drag_accum;
+ Point2 drag_origin; // Workaround for GH-5907
float zoom;
diff --git a/scene/gui/graph_node.cpp b/scene/gui/graph_node.cpp
index 5914ea222d..1efc9a1ceb 100644
--- a/scene/gui/graph_node.cpp
+++ b/scene/gui/graph_node.cpp
@@ -571,7 +571,12 @@ Color GraphNode::get_connection_output_color(int p_idx) {
void GraphNode::_input_event(const InputEvent& p_ev) {
if (p_ev.type==InputEvent::MOUSE_BUTTON) {
+
+ ERR_EXPLAIN("GraphNode must be the child of a GraphEdit node.");
+ ERR_FAIL_COND(get_parent_control() == NULL);
+
get_parent_control()->grab_focus();
+
if(p_ev.mouse_button.pressed && p_ev.mouse_button.button_index==BUTTON_LEFT) {
Vector2 mpos = Vector2(p_ev.mouse_button.x,p_ev.mouse_button.y);
diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp
index 4c025e92df..ec89b7b690 100644
--- a/scene/gui/label.cpp
+++ b/scene/gui/label.cpp
@@ -334,7 +334,7 @@ int Label::get_longest_line_width() const {
}
} else {
- int char_width=font->get_char_size(current).width;
+ int char_width=font->get_char_size(current,text[i+1]).width;
line_width+=char_width;
}
@@ -454,7 +454,7 @@ void Label::regenerate_word_cache() {
word_pos=i;
}
- char_width=font->get_char_size(current).width;
+ char_width=font->get_char_size(current,text[i+1]).width;
current_word_size+=char_width;
line_width+=char_width;
total_char_cache++;
diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp
index 89c235e101..fcea12fd6b 100644
--- a/scene/gui/line_edit.cpp
+++ b/scene/gui/line_edit.cpp
@@ -468,7 +468,7 @@ void LineEdit::_input_event(InputEvent p_event) {
if (handled) {
accept_event();
- } else {
+ } else if (!k.mod.alt && !k.mod.command) {
if (k.unicode>=32 && k.scancode!=KEY_DELETE) {
if (editable) {
diff --git a/scene/gui/spin_box.cpp b/scene/gui/spin_box.cpp
index 2b64d36a81..98e1a32aef 100644
--- a/scene/gui/spin_box.cpp
+++ b/scene/gui/spin_box.cpp
@@ -39,7 +39,7 @@ Size2 SpinBox::get_minimum_size() const {
void SpinBox::_value_changed(double) {
- String value = String::num(get_val(),Math::decimals(get_step()));
+ String value = String::num(get_val(),Math::step_decimals(get_step()));
if (prefix!="")
value=prefix+" "+value;
if (suffix!="")
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index 50b44c55a9..b265ef840a 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -2993,6 +2993,34 @@ void TextEdit::adjust_viewport_to_cursor() {
}
+void TextEdit::center_viewport_to_cursor() {
+
+ if (cursor.line_ofs>cursor.line)
+ cursor.line_ofs=cursor.line;
+
+ int visible_width=cache.size.width-cache.style_normal->get_minimum_size().width-cache.line_number_w-cache.breakpoint_gutter_width;
+ if (v_scroll->is_visible())
+ visible_width-=v_scroll->get_combined_minimum_size().width;
+ visible_width-=20; // give it a little more space
+
+ int visible_rows = get_visible_rows();
+ if (h_scroll->is_visible())
+ visible_rows-=((h_scroll->get_combined_minimum_size().height-1)/get_row_height());
+
+ int max_ofs = text.size()-(scroll_past_end_of_file_enabled?1:visible_rows);
+ cursor.line_ofs=CLAMP(cursor.line-(visible_rows/2),0,max_ofs);
+
+ int cursor_x = get_column_x_offset( cursor.column, text[cursor.line] );
+
+ if (cursor_x>(cursor.x_ofs+visible_width))
+ cursor.x_ofs=cursor_x-visible_width+1;
+
+ if (cursor_x < cursor.x_ofs)
+ cursor.x_ofs=cursor_x;
+
+ update();
+}
+
void TextEdit::cursor_set_column(int p_col, bool p_adjust_viewport) {
if (p_col<0)
@@ -4480,6 +4508,7 @@ void TextEdit::_bind_methods() {
ObjectTypeDB::bind_method(_MD("menu_option"),&TextEdit::menu_option);
ObjectTypeDB::bind_method(_MD("get_menu:PopupMenu"),&TextEdit::get_menu);
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "syntax_highlighting"), _SCS("set_syntax_coloring"), _SCS("is_syntax_coloring_enabled"));
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "show_line_numbers"), _SCS("set_show_line_numbers"), _SCS("is_show_line_numbers_enabled"));
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "highlight_all_occurrences"), _SCS("set_highlight_all_occurrences"), _SCS("is_highlight_all_occurrences_enabled"));
diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h
index 65e9615911..c3bdf7c856 100644
--- a/scene/gui/text_edit.h
+++ b/scene/gui/text_edit.h
@@ -396,6 +396,8 @@ public:
}
void set_auto_indent(bool p_auto_indent);
+ void center_viewport_to_cursor();
+
void cursor_set_column(int p_col, bool p_adjust_viewport=true);
void cursor_set_line(int p_row, bool p_adjust_viewport=true);
diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp
index 82459ba0ab..487f62ed44 100644
--- a/scene/gui/tree.cpp
+++ b/scene/gui/tree.cpp
@@ -1179,8 +1179,8 @@ int Tree::draw_item(const Point2i& p_pos,const Point2& p_draw_ofs, const Size2&
Ref<Texture> updown = cache.updown;
- //String valtext = String::num( p_item->cells[i].val, Math::decimals( p_item->cells[i].step ) );
- String valtext = rtos( p_item->cells[i].val );
+ String valtext = String::num( p_item->cells[i].val, Math::step_decimals( p_item->cells[i].step ) );
+ //String valtext = rtos( p_item->cells[i].val );
font->draw( ci, text_pos, valtext, col, item_rect.size.x-updown->get_width());
if (!p_item->cells[i].editable)
@@ -1746,7 +1746,7 @@ int Tree::propagate_mouse_event(const Point2i &p_pos,int x_ofs,int y_ofs,bool p_
} else {
- editor_text=String::num( p_item->cells[col].val, Math::decimals( p_item->cells[col].step ) );
+ editor_text=String::num( p_item->cells[col].val, Math::step_decimals( p_item->cells[col].step ) );
if (select_mode==SELECT_MULTI && get_tree()->get_last_event_id() == focus_in_id)
bring_up_editor=false;
@@ -2521,7 +2521,7 @@ bool Tree::edit_selected() {
text_editor->set_pos( textedpos );
text_editor->set_size( rect.size);
text_editor->clear();
- text_editor->set_text( c.mode==TreeItem::CELL_MODE_STRING?c.text:rtos(c.val) );
+ text_editor->set_text( c.mode==TreeItem::CELL_MODE_STRING?c.text:String::num( c.val, Math::step_decimals( c.step ) ) );
text_editor->select_all();
if (c.mode==TreeItem::CELL_MODE_RANGE || c.mode==TreeItem::CELL_MODE_RANGE_EXPRESSION ) {
diff --git a/scene/main/http_request.cpp b/scene/main/http_request.cpp
index 040d509286..9b79af32bf 100644
--- a/scene/main/http_request.cpp
+++ b/scene/main/http_request.cpp
@@ -105,6 +105,9 @@ Error HTTPRequest::request(const String& p_url, const Vector<String>& p_custom_h
}
Error err = _parse_url(p_url);
+ if (err)
+ return err;
+
validate_ssl=p_ssl_validate_domain;
bool has_user_agent=false;
@@ -127,19 +130,52 @@ Error HTTPRequest::request(const String& p_url, const Vector<String>& p_custom_h
headers.push_back("Accept: */*");
}
+ requesting=true;
+
+ if (use_threads) {
- err = _request();
+ thread_done=false;
+ thread_request_quit=false;
+ client->set_blocking_mode(true);
+ thread=Thread::create(_thread_func,this);
+ } else {
+ client->set_blocking_mode(false);
+ err = _request();
+ if (err!=OK) {
+ call_deferred("_request_done",RESULT_CANT_CONNECT,0,StringArray(),ByteArray());
+ return ERR_CANT_CONNECT;
+ }
- if (err==OK) {
set_process(true);
- requesting=true;
+
}
- return err;
+ return OK;
}
+void HTTPRequest::_thread_func(void *p_userdata) {
+
+ HTTPRequest *hr = (HTTPRequest*)p_userdata;
+
+ Error err = hr->_request();
+
+ if (err!=OK) {
+ hr->call_deferred("_request_done",RESULT_CANT_CONNECT,0,StringArray(),ByteArray());
+ } else {
+ while(!hr->thread_request_quit) {
+
+ bool exit = hr->_update_connection();
+ if (exit)
+ break;
+ OS::get_singleton()->delay_usec(1);
+ }
+ }
+
+ hr->thread_done=true;
+}
+
void HTTPRequest::cancel_request() {
if (!requesting)
@@ -147,6 +183,11 @@ void HTTPRequest::cancel_request() {
if (!use_threads) {
set_process(false);
+ } else {
+ thread_request_quit=true;
+ Thread::wait_to_finish(thread);
+ memdelete(thread);
+ thread=NULL;
}
if (file) {
@@ -167,7 +208,7 @@ void HTTPRequest::cancel_request() {
bool HTTPRequest::_handle_response(bool *ret_value) {
if (!client->has_response()) {
- call_deferred("emit_signal","request_completed",RESULT_NO_RESPONSE,0,StringArray(),ByteArray());
+ call_deferred("_request_done",RESULT_NO_RESPONSE,0,StringArray(),ByteArray());
*ret_value=true;
return true;
}
@@ -187,7 +228,7 @@ bool HTTPRequest::_handle_response(bool *ret_value) {
//redirect
if (max_redirects>=0 && redirections>=max_redirects) {
- call_deferred("emit_signal","request_completed",RESULT_REDIRECT_LIMIT_REACHED,response_code,response_headers,ByteArray());
+ call_deferred("_request_done",RESULT_REDIRECT_LIMIT_REACHED,response_code,response_headers,ByteArray());
*ret_value=true;
return true;
}
@@ -239,7 +280,8 @@ bool HTTPRequest::_update_connection() {
switch( client->get_status() ) {
case HTTPClient::STATUS_DISCONNECTED: {
- return true; //end it, since it's doing something
+ call_deferred("_request_done",RESULT_CANT_CONNECT,0,StringArray(),ByteArray());
+ return true; //end it, since it's doing something
} break;
case HTTPClient::STATUS_RESOLVING: {
client->poll();
@@ -247,7 +289,7 @@ bool HTTPRequest::_update_connection() {
return false;
} break;
case HTTPClient::STATUS_CANT_RESOLVE: {
- call_deferred("emit_signal","request_completed",RESULT_CANT_RESOLVE,0,StringArray(),ByteArray());
+ call_deferred("_request_done",RESULT_CANT_RESOLVE,0,StringArray(),ByteArray());
return true;
} break;
@@ -258,7 +300,7 @@ bool HTTPRequest::_update_connection() {
} break; //connecting to ip
case HTTPClient::STATUS_CANT_CONNECT: {
- call_deferred("emit_signal","request_completed",RESULT_CANT_CONNECT,0,StringArray(),ByteArray());
+ call_deferred("_request_done",RESULT_CANT_CONNECT,0,StringArray(),ByteArray());
return true;
} break;
@@ -276,17 +318,17 @@ bool HTTPRequest::_update_connection() {
return ret_value;
- call_deferred("emit_signal","request_completed",RESULT_SUCCESS,response_code,response_headers,ByteArray());
+ call_deferred("_request_done",RESULT_SUCCESS,response_code,response_headers,ByteArray());
return true;
}
if (got_response && body_len<0) {
//chunked transfer is done
- call_deferred("emit_signal","request_completed",RESULT_SUCCESS,response_code,response_headers,body);
+ call_deferred("_request_done",RESULT_SUCCESS,response_code,response_headers,body);
return true;
}
- call_deferred("emit_signal","request_completed",RESULT_CHUNKED_BODY_SIZE_MISMATCH,response_code,response_headers,ByteArray());
+ call_deferred("_request_done",RESULT_CHUNKED_BODY_SIZE_MISMATCH,response_code,response_headers,ByteArray());
return true;
//request migh have been done
} else {
@@ -294,7 +336,7 @@ bool HTTPRequest::_update_connection() {
Error err = client->request(HTTPClient::METHOD_GET,request_string,headers);
if (err!=OK) {
- call_deferred("emit_signal","request_completed",RESULT_CONNECTION_ERROR,0,StringArray(),ByteArray());
+ call_deferred("_request_done",RESULT_CONNECTION_ERROR,0,StringArray(),ByteArray());
return true;
}
@@ -320,7 +362,7 @@ bool HTTPRequest::_update_connection() {
if (!client->is_response_chunked() && client->get_response_body_length()==0) {
- call_deferred("emit_signal","request_completed",RESULT_SUCCESS,response_code,response_headers,ByteArray());
+ call_deferred("_request_done",RESULT_SUCCESS,response_code,response_headers,ByteArray());
return true;
}
@@ -331,7 +373,7 @@ bool HTTPRequest::_update_connection() {
body_len=client->get_response_body_length();
if (body_size_limit>=0 && body_len>body_size_limit) {
- call_deferred("emit_signal","request_completed",RESULT_BODY_SIZE_LIMIT_EXCEEDED,response_code,response_headers,ByteArray());
+ call_deferred("_request_done",RESULT_BODY_SIZE_LIMIT_EXCEEDED,response_code,response_headers,ByteArray());
return true;
}
}
@@ -340,7 +382,8 @@ bool HTTPRequest::_update_connection() {
file=FileAccess::open(download_to_file,FileAccess::WRITE);
if (!file) {
- call_deferred("emit_signal","request_completed",RESULT_DOWNLOAD_FILE_CANT_OPEN,response_code,response_headers,ByteArray());
+ call_deferred("_request_done",RESULT_DOWNLOAD_FILE_CANT_OPEN,response_code,response_headers,ByteArray());
+ return true;
}
}
}
@@ -356,7 +399,7 @@ bool HTTPRequest::_update_connection() {
ByteArray::Read r=chunk.read();
file->store_buffer(r.ptr(),chunk.size());
if (file->get_error()!=OK) {
- call_deferred("emit_signal","request_completed",RESULT_DOWNLOAD_FILE_WRITE_ERROR,response_code,response_headers,ByteArray());
+ call_deferred("_request_done",RESULT_DOWNLOAD_FILE_WRITE_ERROR,response_code,response_headers,ByteArray());
return true;
}
} else {
@@ -364,18 +407,18 @@ bool HTTPRequest::_update_connection() {
}
if (body_size_limit>=0 && downloaded>body_size_limit) {
- call_deferred("emit_signal","request_completed",RESULT_BODY_SIZE_LIMIT_EXCEEDED,response_code,response_headers,ByteArray());
+ call_deferred("_request_done",RESULT_BODY_SIZE_LIMIT_EXCEEDED,response_code,response_headers,ByteArray());
return true;
}
if (body_len>=0) {
if (downloaded==body_len) {
- call_deferred("emit_signal","request_completed",RESULT_SUCCESS,response_code,response_headers,body);
+ call_deferred("_request_done",RESULT_SUCCESS,response_code,response_headers,body);
return true;
}
/*if (body.size()>=body_len) {
- call_deferred("emit_signal","request_completed",RESULT_BODY_SIZE_MISMATCH,response_code,response_headers,ByteArray());
+ call_deferred("_request_done",RESULT_BODY_SIZE_MISMATCH,response_code,response_headers,ByteArray());
return true;
}*/
}
@@ -384,11 +427,11 @@ bool HTTPRequest::_update_connection() {
} break; // request resulted in body: { } break which must be read
case HTTPClient::STATUS_CONNECTION_ERROR: {
- call_deferred("emit_signal","request_completed",RESULT_CONNECTION_ERROR,0,StringArray(),ByteArray());
+ call_deferred("_request_done",RESULT_CONNECTION_ERROR,0,StringArray(),ByteArray());
return true;
} break;
case HTTPClient::STATUS_SSL_HANDSHAKE_ERROR: {
- call_deferred("emit_signal","request_completed",RESULT_SSL_HANDSHAKE_ERROR,0,StringArray(),ByteArray());
+ call_deferred("_request_done",RESULT_SSL_HANDSHAKE_ERROR,0,StringArray(),ByteArray());
return true;
} break;
@@ -397,17 +440,35 @@ bool HTTPRequest::_update_connection() {
ERR_FAIL_V(false);
}
+
+void HTTPRequest::_request_done(int p_status, int p_code, const StringArray& headers, const ByteArray& p_data) {
+
+
+ cancel_request();
+ emit_signal("request_completed",p_status,p_code,headers,p_data);
+}
+
+
void HTTPRequest::_notification(int p_what) {
if (p_what==NOTIFICATION_PROCESS) {
+ if (use_threads)
+ return;
bool done = _update_connection();
if (done) {
set_process(false);
+ //cancel_request(); called from _request done now
+ }
+ }
+
+ if (p_what==NOTIFICATION_EXIT_TREE) {
+ if (requesting) {
cancel_request();
}
}
+
}
void HTTPRequest::set_use_threads(bool p_use) {
@@ -491,6 +552,7 @@ void HTTPRequest::_bind_methods() {
ObjectTypeDB::bind_method(_MD("get_body_size"),&HTTPRequest::get_body_size);
ObjectTypeDB::bind_method(_MD("_redirect_request"),&HTTPRequest::_redirect_request);
+ ObjectTypeDB::bind_method(_MD("_request_done"),&HTTPRequest::_request_done);
ADD_PROPERTY(PropertyInfo(Variant::BOOL,"use_threads"),_SCS("set_use_threads"),_SCS("is_using_threads"));
ADD_PROPERTY(PropertyInfo(Variant::INT,"body_size_limit",PROPERTY_HINT_RANGE,"-1,2000000000"),_SCS("set_body_size_limit"),_SCS("get_body_size_limit"));
@@ -517,6 +579,7 @@ void HTTPRequest::_bind_methods() {
HTTPRequest::HTTPRequest()
{
+ thread=NULL;
port=80;
redirections=0;
@@ -530,6 +593,7 @@ HTTPRequest::HTTPRequest()
requesting=false;
client.instance();
use_threads=false;
+ thread_done=false;
body_size_limit=-1;
file=NULL;
status=HTTPClient::STATUS_DISCONNECTED;
diff --git a/scene/main/http_request.h b/scene/main/http_request.h
index 7c3ccb2eb9..8dd433982b 100644
--- a/scene/main/http_request.h
+++ b/scene/main/http_request.h
@@ -32,6 +32,7 @@
#include "node.h"
#include "io/http_client.h"
#include "os/file_access.h"
+#include "os/thread.h"
class HTTPRequest : public Node {
@@ -69,7 +70,7 @@ private:
bool request_sent;
Ref<HTTPClient> client;
ByteArray body;
- bool use_threads;
+ volatile bool use_threads;
bool got_response;
int response_code;
@@ -80,7 +81,7 @@ private:
FileAccess *file;
int body_len;
- int downloaded;
+ volatile int downloaded;
int body_size_limit;
int redirections;
@@ -93,11 +94,19 @@ private:
void _redirect_request(const String& p_new_url);
+
bool _handle_response(bool *ret_value);
Error _parse_url(const String& p_url);
Error _request();
+ volatile bool thread_done;
+ volatile bool thread_request_quit;
+
+ Thread *thread;
+
+ void _request_done(int p_status, int p_code, const StringArray& headers, const ByteArray& p_data);
+ static void _thread_func(void *p_userdata);
protected:
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index bdb2754e5e..7970229c06 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -1782,7 +1782,6 @@ void Viewport::_gui_input_event(InputEvent p_event) {
if (top->data.modal_exclusive || top->data.modal_frame==OS::get_singleton()->get_frames_drawn()) {
//cancel event, sorry, modal exclusive EATS UP ALL
//alternative, you can't pop out a window the same frame it was made modal (fixes many issues)
- //get_tree()->call_group(SceneTree::GROUP_CALL_REALTIME,"windows","_cancel_input_ID",p_event.ID);
get_tree()->set_input_as_handled();
return; // no one gets the event if exclusive NO ONE
}
@@ -2034,8 +2033,22 @@ void Viewport::_gui_input_event(InputEvent p_event) {
}
+ bool is_tooltip_shown = false;
- if (can_tooltip) {
+ if (gui.tooltip_popup) {
+ if (can_tooltip) {
+ String tooltip = over->get_tooltip(gui.tooltip->get_global_transform().xform_inv(mpos));
+
+ if (tooltip.length() == 0)
+ _gui_cancel_tooltip();
+ else if (tooltip == gui.tooltip_label->get_text())
+ is_tooltip_shown = true;
+ }
+ else
+ _gui_cancel_tooltip();
+ }
+
+ if (can_tooltip && !is_tooltip_shown) {
gui.tooltip=over;
gui.tooltip_pos=mpos;//(parent_xform * get_transform()).affine_inverse().xform(pos);
@@ -2062,7 +2075,6 @@ void Viewport::_gui_input_event(InputEvent p_event) {
- //get_tree()->call_group(SceneTree::GROUP_CALL_REALTIME,"windows","_cancel_input_ID",p_event.ID);
get_tree()->set_input_as_handled();
@@ -2083,6 +2095,7 @@ void Viewport::_gui_input_event(InputEvent p_event) {
} break;
case InputEvent::ACTION:
case InputEvent::JOYSTICK_BUTTON:
+ case InputEvent::JOYSTICK_MOTION:
case InputEvent::KEY: {
@@ -2102,7 +2115,7 @@ void Viewport::_gui_input_event(InputEvent p_event) {
if (gui.key_event_accepted) {
- get_tree()->call_group(SceneTree::GROUP_CALL_REALTIME,"windows","_cancel_input_ID",p_event.ID);
+ get_tree()->set_input_as_handled();
break;
}
}
@@ -2162,7 +2175,7 @@ void Viewport::_gui_input_event(InputEvent p_event) {
if (next) {
next->grab_focus();
- get_tree()->call_group(SceneTree::GROUP_CALL_REALTIME,"windows","_cancel_input_ID",p_event.ID);
+ get_tree()->set_input_as_handled();
}
}
@@ -2355,8 +2368,7 @@ void Viewport::_gui_control_grab_focus(Control* p_control) {
if (gui.key_focus && gui.key_focus==p_control)
return;
- _gui_remove_focus();
- get_tree()->call_group(SceneTree::GROUP_CALL_REALTIME,"windows","_gui_remove_focus");
+ get_tree()->call_group(SceneTree::GROUP_CALL_REALTIME,"_viewports","_gui_remove_focus");
gui.key_focus=p_control;
p_control->notification(Control::NOTIFICATION_FOCUS_ENTER);
p_control->update();
@@ -2664,6 +2676,7 @@ void Viewport::_bind_methods() {
ObjectTypeDB::bind_method(_MD("is_input_disabled"), &Viewport::is_input_disabled);
ObjectTypeDB::bind_method(_MD("_gui_show_tooltip"), &Viewport::_gui_show_tooltip);
+ ObjectTypeDB::bind_method(_MD("_gui_remove_focus"), &Viewport::_gui_remove_focus);
ADD_PROPERTY( PropertyInfo(Variant::RECT2,"rect"), _SCS("set_rect"), _SCS("get_rect") );
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"own_world"), _SCS("set_use_own_world"), _SCS("is_using_own_world") );
diff --git a/scene/resources/curve.cpp b/scene/resources/curve.cpp
index 88ff09e961..29460790ff 100644
--- a/scene/resources/curve.cpp
+++ b/scene/resources/curve.cpp
@@ -644,7 +644,7 @@ Vector2 Curve2D::interpolate_baked(float p_offset,bool p_cubic) const{
if (p_offset>=baked_max_ofs)
return r[bpc-1];
- int idx = Math::floor(p_offset/bake_interval);
+ int idx = Math::floor((double)p_offset/(double)bake_interval);
float frac = Math::fmod(p_offset,bake_interval);
if (idx>=bpc-1) {
@@ -1117,7 +1117,7 @@ Vector3 Curve3D::interpolate_baked(float p_offset,bool p_cubic) const{
if (p_offset>=baked_max_ofs)
return r[bpc-1];
- int idx = Math::floor(p_offset/bake_interval);
+ int idx = Math::floor((double)p_offset/(double)bake_interval);
float frac = Math::fmod(p_offset,bake_interval);
if (idx>=bpc-1) {
@@ -1161,7 +1161,7 @@ float Curve3D::interpolate_baked_tilt(float p_offset) const{
if (p_offset>=baked_max_ofs)
return r[bpc-1];
- int idx = Math::floor(p_offset/bake_interval);
+ int idx = Math::floor((double)p_offset/(double)bake_interval);
float frac = Math::fmod(p_offset,bake_interval);
if (idx>=bpc-1) {
diff --git a/scene/resources/dynamic_font.cpp b/scene/resources/dynamic_font.cpp
index 67587a8f8b..679c8a000c 100644
--- a/scene/resources/dynamic_font.cpp
+++ b/scene/resources/dynamic_font.cpp
@@ -30,13 +30,22 @@
#include "dynamic_font.h"
#include "os/file_access.h"
+bool DynamicFontData::CacheID::operator< (CacheID right) const{
+
+ if (size<right.size)
+ return true;
+ if (mipmaps != right.mipmaps)
+ return right.mipmaps;
+ if (filter != right.filter)
+ return right.filter;
+ return false;
+}
-
-Ref<DynamicFontAtSize> DynamicFontData::_get_dynamic_font_at_size(int p_size) {
+Ref<DynamicFontAtSize> DynamicFontData::_get_dynamic_font_at_size(CacheID p_id){
- if (size_cache.has(p_size)) {
- return Ref<DynamicFontAtSize>( size_cache[p_size] );
+ if (size_cache.has(p_id)) {
+ return Ref<DynamicFontAtSize>( size_cache[p_id] );
}
@@ -46,9 +55,8 @@ Ref<DynamicFontAtSize> DynamicFontData::_get_dynamic_font_at_size(int p_size) {
dfas->font=Ref<DynamicFontData>( this );
- size_cache[p_size]=dfas.ptr();
-
- dfas->size=p_size;
+ size_cache[p_id]=dfas.ptr();
+ dfas->id=p_id;
dfas->_load();
return dfas;
@@ -169,11 +177,16 @@ Error DynamicFontAtSize::_load() {
ERR_FAIL_COND_V( error, ERR_INVALID_PARAMETER );
}*/
- error = FT_Set_Pixel_Sizes(face,0,size);
+ error = FT_Set_Pixel_Sizes(face,0,id.size);
ascent=face->size->metrics.ascender>>6;
descent=-face->size->metrics.descender>>6;
linegap=0;
+ texture_flags=0;
+ if (id.mipmaps)
+ texture_flags|=Texture::FLAG_MIPMAPS;
+ if (id.filter)
+ texture_flags|=Texture::FLAG_FILTER;
//print_line("ASCENT: "+itos(ascent)+" descent "+itos(descent)+" hinted: "+itos(face->face_flags&FT_FACE_FLAG_HINTER));
@@ -270,6 +283,15 @@ Size2 DynamicFontAtSize::get_char_size(CharType p_char,CharType p_next,const Vec
return ret;
}
+void DynamicFontAtSize::set_texture_flags(uint32_t p_flags){
+
+ texture_flags=p_flags;
+ for(int i=0;i<textures.size();i++) {
+ Ref<ImageTexture> &tex = textures[i].texture;
+ if (!tex.is_null())
+ tex->set_flags(p_flags);
+ }
+}
float DynamicFontAtSize::draw_char(RID p_canvas_item, const Point2& p_pos, CharType p_char,CharType p_next,const Color& p_modulate,const Vector<Ref<DynamicFontAtSize> >& p_fallbacks) const {
@@ -496,7 +518,7 @@ void DynamicFontAtSize::_update_char(CharType p_char) {
tex_x = 0;
tex_y = 0;
- int texsize = MAX(size*8,256);
+ int texsize = MAX(id.size*8,256);
if (mw>texsize)
texsize=mw; //special case, adapt to it?
if (mh>texsize)
@@ -555,7 +577,7 @@ void DynamicFontAtSize::_update_char(CharType p_char) {
if (tex.texture.is_null()) {
tex.texture.instance();
- tex.texture->create_from_image(img,Texture::FLAG_VIDEO_SURFACE);
+ tex.texture->create_from_image(img,Texture::FLAG_VIDEO_SURFACE|texture_flags);
} else {
tex.texture->set_data(img); //update
}
@@ -595,25 +617,39 @@ DynamicFontAtSize::DynamicFontAtSize() {
ascent=1;
descent=1;
linegap=1;
+ texture_flags=0;
}
DynamicFontAtSize::~DynamicFontAtSize(){
if (valid) {
FT_Done_FreeType( library );
- font->size_cache.erase(size);
+ font->size_cache.erase(id);
}
}
/////////////////////////
+void DynamicFont::_reload_cache(){
+
+ ERR_FAIL_COND(cache_id.size<1);
+ if (!data.is_valid())
+ return;
+ data_at_size=data->_get_dynamic_font_at_size(cache_id);
+ for (int i=0;i<fallbacks.size();i++){
+ fallback_data_at_size[i]=fallbacks[i]->_get_dynamic_font_at_size(cache_id);
+ }
+
+ emit_changed();
+ _change_notify();
+}
void DynamicFont::set_font_data(const Ref<DynamicFontData>& p_data) {
data=p_data;
if (data.is_valid())
- data_at_size=data->_get_dynamic_font_at_size(size);
+ data_at_size=data->_get_dynamic_font_at_size(cache_id);
else
data_at_size=Ref<DynamicFontAtSize>();
@@ -628,23 +664,72 @@ Ref<DynamicFontData> DynamicFont::get_font_data() const{
void DynamicFont::set_size(int p_size){
- if (size==p_size)
+ if (cache_id.size==p_size)
return;
- size=p_size;
- ERR_FAIL_COND(p_size<1);
- if (!data.is_valid())
+ cache_id.size=p_size;
+ _reload_cache();
+}
+
+int DynamicFont::get_size() const{
+
+ return cache_id.size;
+}
+
+bool DynamicFont::get_use_mipmaps() const{
+
+ return cache_id.mipmaps;
+}
+
+void DynamicFont::set_use_mipmaps(bool p_enable){
+
+ if (cache_id.mipmaps==p_enable)
return;
- data_at_size=data->_get_dynamic_font_at_size(size);
- for(int i=0;i<fallbacks.size();i++) {
- fallback_data_at_size[i]=fallbacks[i]->_get_dynamic_font_at_size(size);
+ cache_id.mipmaps=p_enable;
+ _reload_cache();
+}
+
+bool DynamicFont::get_use_filter() const{
+
+ return cache_id.filter;
+}
+
+void DynamicFont::set_use_filter(bool p_enable){
+
+ if (cache_id.filter==p_enable)
+ return;
+ cache_id.filter=p_enable;
+ _reload_cache();
+}
+
+int DynamicFont::get_spacing(int p_type) const{
+
+ if (p_type == SPACING_TOP){
+ return spacing_top;
+ }else if (p_type == SPACING_BOTTOM){
+ return spacing_bottom;
+ }else if (p_type == SPACING_CHAR){
+ return spacing_char;
+ }else if (p_type == SPACING_SPACE){
+ return spacing_space;
}
- emit_changed();
- _change_notify();
+ return 0;
}
-int DynamicFont::get_size() const{
- return size;
+void DynamicFont::set_spacing(int p_type, int p_value){
+
+ if (p_type == SPACING_TOP){
+ spacing_top=p_value;
+ }else if (p_type == SPACING_BOTTOM){
+ spacing_bottom=p_value;
+ }else if (p_type == SPACING_CHAR){
+ spacing_char=p_value;
+ }else if (p_type == SPACING_SPACE){
+ spacing_space=p_value;
+ }
+
+ emit_changed();
+ _change_notify();
}
float DynamicFont::get_height() const{
@@ -652,7 +737,7 @@ float DynamicFont::get_height() const{
if (!data_at_size.is_valid())
return 1;
- return data_at_size->get_height();
+ return data_at_size->get_height()+spacing_top+spacing_bottom;
}
float DynamicFont::get_ascent() const{
@@ -660,7 +745,7 @@ float DynamicFont::get_ascent() const{
if (!data_at_size.is_valid())
return 1;
- return data_at_size->get_ascent();
+ return data_at_size->get_ascent()+spacing_top;
}
float DynamicFont::get_descent() const{
@@ -668,7 +753,7 @@ float DynamicFont::get_descent() const{
if (!data_at_size.is_valid())
return 1;
- return data_at_size->get_descent();
+ return data_at_size->get_descent()+spacing_bottom;
}
@@ -677,7 +762,13 @@ Size2 DynamicFont::get_char_size(CharType p_char,CharType p_next) const{
if (!data_at_size.is_valid())
return Size2(1,1);
- return data_at_size->get_char_size(p_char,p_next,fallback_data_at_size);
+ Size2 ret=data_at_size->get_char_size(p_char,p_next,fallback_data_at_size);
+ if (p_char==' ')
+ ret.width+=spacing_space+spacing_char;
+ else if (p_next)
+ ret.width+=spacing_char;
+
+ return ret;
}
@@ -691,7 +782,7 @@ float DynamicFont::draw_char(RID p_canvas_item, const Point2& p_pos, CharType p_
if (!data_at_size.is_valid())
return 0;
- return data_at_size->draw_char(p_canvas_item,p_pos,p_char,p_next,p_modulate,fallback_data_at_size);
+ return data_at_size->draw_char(p_canvas_item,p_pos,p_char,p_next,p_modulate,fallback_data_at_size)+spacing_char;
}
void DynamicFont::set_fallback(int p_idx,const Ref<DynamicFontData>& p_data) {
@@ -699,7 +790,7 @@ void DynamicFont::set_fallback(int p_idx,const Ref<DynamicFontData>& p_data) {
ERR_FAIL_COND(p_data.is_null());
ERR_FAIL_INDEX(p_idx,fallbacks.size());
fallbacks[p_idx]=p_data;
- fallback_data_at_size[p_idx]=fallbacks[p_idx]->_get_dynamic_font_at_size(size);
+ fallback_data_at_size[p_idx]=fallbacks[p_idx]->_get_dynamic_font_at_size(cache_id);
}
@@ -707,7 +798,7 @@ void DynamicFont::add_fallback(const Ref<DynamicFontData>& p_data) {
ERR_FAIL_COND(p_data.is_null());
fallbacks.push_back(p_data);
- fallback_data_at_size.push_back(fallbacks[fallbacks.size()-1]->_get_dynamic_font_at_size(size)); //const..
+ fallback_data_at_size.push_back(fallbacks[fallbacks.size()-1]->_get_dynamic_font_at_size(cache_id)); //const..
_change_notify();
emit_changed();
@@ -794,6 +885,13 @@ void DynamicFont::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_size","data"),&DynamicFont::set_size);
ObjectTypeDB::bind_method(_MD("get_size"),&DynamicFont::get_size);
+ ObjectTypeDB::bind_method(_MD("set_use_mipmaps","enable"),&DynamicFont::set_use_mipmaps);
+ ObjectTypeDB::bind_method(_MD("get_use_mipmaps"),&DynamicFont::get_use_mipmaps);
+ ObjectTypeDB::bind_method(_MD("set_use_filter","enable"),&DynamicFont::set_use_filter);
+ ObjectTypeDB::bind_method(_MD("get_use_filter"),&DynamicFont::get_use_filter);
+ ObjectTypeDB::bind_method(_MD("set_spacing","type","value"),&DynamicFont::set_spacing);
+ ObjectTypeDB::bind_method(_MD("get_spacing","type"),&DynamicFont::get_spacing);
+
ObjectTypeDB::bind_method(_MD("add_fallback","data:DynamicFontData"),&DynamicFont::add_fallback);
ObjectTypeDB::bind_method(_MD("set_fallback","idx","data:DynamicFontData"),&DynamicFont::set_fallback);
ObjectTypeDB::bind_method(_MD("get_fallback:DynamicFontData","idx"),&DynamicFont::get_fallback);
@@ -802,12 +900,26 @@ void DynamicFont::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT,"font/size"),_SCS("set_size"),_SCS("get_size"));
+ ADD_PROPERTYINZ(PropertyInfo(Variant::INT,"extra_spacing/top"),_SCS("set_spacing"),_SCS("get_spacing"),SPACING_TOP);
+ ADD_PROPERTYINZ(PropertyInfo(Variant::INT,"extra_spacing/bottom"),_SCS("set_spacing"),_SCS("get_spacing"),SPACING_BOTTOM);
+ ADD_PROPERTYINZ(PropertyInfo(Variant::INT,"extra_spacing/char"),_SCS("set_spacing"),_SCS("get_spacing"),SPACING_CHAR);
+ ADD_PROPERTYINZ(PropertyInfo(Variant::INT,"extra_spacing/space"),_SCS("set_spacing"),_SCS("get_spacing"),SPACING_SPACE);
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL,"font/use_mipmaps"),_SCS("set_use_mipmaps"),_SCS("get_use_mipmaps"));
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL,"font/use_filter"),_SCS("set_use_filter"),_SCS("get_use_filter"));
ADD_PROPERTY(PropertyInfo(Variant::OBJECT,"font/font",PROPERTY_HINT_RESOURCE_TYPE,"DynamicFontData"),_SCS("set_font_data"),_SCS("get_font_data"));
+
+ BIND_CONSTANT( SPACING_TOP );
+ BIND_CONSTANT( SPACING_BOTTOM );
+ BIND_CONSTANT( SPACING_CHAR );
+ BIND_CONSTANT( SPACING_SPACE );
}
DynamicFont::DynamicFont() {
- size=16;
+ spacing_top=0;
+ spacing_bottom=0;
+ spacing_char=0;
+ spacing_space=0;
}
DynamicFont::~DynamicFont() {
diff --git a/scene/resources/dynamic_font.h b/scene/resources/dynamic_font.h
index 9ad1b4edbf..4ae58ab0dd 100644
--- a/scene/resources/dynamic_font.h
+++ b/scene/resources/dynamic_font.h
@@ -45,21 +45,32 @@ class DynamicFontData : public Resource {
OBJ_TYPE(DynamicFontData,Resource);
+public:
+
+ struct CacheID{
+
+ int size;
+ bool mipmaps;
+ bool filter;
+
+ bool operator< (CacheID right) const;
+ CacheID() { size=16; mipmaps=false; filter=false; }
+ };
+private:
const uint8_t *font_mem;
int font_mem_size;
bool force_autohinter;
String font_path;
- Map<int,DynamicFontAtSize*> size_cache;
+ Map<CacheID,DynamicFontAtSize*> size_cache;
friend class DynamicFontAtSize;
friend class DynamicFont;
-
- Ref<DynamicFontAtSize> _get_dynamic_font_at_size(int p_size);
+ Ref<DynamicFontAtSize> _get_dynamic_font_at_size(CacheID p_cache);
protected:
static void _bind_methods();
@@ -90,6 +101,8 @@ class DynamicFontAtSize : public Reference {
int linegap;
int rect_margin;
+ uint32_t texture_flags;
+
bool valid;
struct CharTexture {
@@ -124,7 +137,7 @@ class DynamicFontAtSize : public Reference {
friend class DynamicFontData;
Ref<DynamicFontData> font;
- int size;
+ DynamicFontData::CacheID id;
@@ -145,7 +158,7 @@ public:
float draw_char(RID p_canvas_item, const Point2& p_pos, CharType p_char,CharType p_next,const Color& p_modulate,const Vector<Ref<DynamicFontAtSize> >& p_fallbacks) const;
-
+ void set_texture_flags(uint32_t p_flags);
DynamicFontAtSize();
~DynamicFontAtSize();
@@ -157,18 +170,35 @@ class DynamicFont : public Font {
OBJ_TYPE( DynamicFont, Font );
- Ref<DynamicFontData> data;
+public:
+
+ enum SpacingType{
+ SPACING_TOP,
+ SPACING_BOTTOM,
+ SPACING_CHAR,
+ SPACING_SPACE
+ };
+
+private:
+
+ Ref<DynamicFontData> data;
Ref<DynamicFontAtSize> data_at_size;
Vector< Ref<DynamicFontData> > fallbacks;
Vector< Ref<DynamicFontAtSize> > fallback_data_at_size;
- int size;
+ DynamicFontData::CacheID cache_id;
bool valid;
+ int spacing_top;
+ int spacing_bottom;
+ int spacing_char;
+ int spacing_space;
protected:
+ void _reload_cache();
+
bool _set(const StringName& p_name, const Variant& p_value);
bool _get(const StringName& p_name,Variant &r_ret) const;
void _get_property_list( List<PropertyInfo> *p_list) const;
@@ -183,6 +213,14 @@ public:
void set_size(int p_size);
int get_size() const;
+ bool get_use_mipmaps() const;
+ void set_use_mipmaps(bool p_enable);
+
+ bool get_use_filter() const;
+ void set_use_filter(bool p_enable);
+
+ int get_spacing(int p_type) const;
+ void set_spacing(int p_type, int p_value);
void add_fallback(const Ref<DynamicFontData>& p_data);
void set_fallback(int p_idx,const Ref<DynamicFontData>& p_data);
diff --git a/scene/resources/world_2d.cpp b/scene/resources/world_2d.cpp
index 6b329a1a73..4c963da5b4 100644
--- a/scene/resources/world_2d.cpp
+++ b/scene/resources/world_2d.cpp
@@ -407,7 +407,7 @@ World2D::World2D() {
Physics2DServer::get_singleton()->area_set_param(space,Physics2DServer::AREA_PARAM_GRAVITY,GLOBAL_DEF("physics_2d/default_gravity",98));
Physics2DServer::get_singleton()->area_set_param(space,Physics2DServer::AREA_PARAM_GRAVITY_VECTOR,GLOBAL_DEF("physics_2d/default_gravity_vector",Vector2(0,1)));
// TODO: Remove this deprecation warning and compatibility code for 2.2 or 3.0
- if (Globals::get_singleton()->get("physics_2d/default_density") && !Globals::get_singleton()->get("physics_2d/default_linear_damp)")) {
+ if (Globals::get_singleton()->get("physics_2d/default_density") && !Globals::get_singleton()->get("physics_2d/default_linear_damp")) {
WARN_PRINT("Deprecated parameter 'physics_2d/default_density'. It was renamed to 'physics_2d/default_linear_damp', adjusting your project settings accordingly (make sure to adjust scripts that potentially rely on 'physics_2d/default_density'.");
Globals::get_singleton()->set("physics_2d/default_linear_damp", Globals::get_singleton()->get("physics_2d/default_density"));
Globals::get_singleton()->set_persisting("physics_2d/default_linear_damp", true);