Merge pull request #69288 from bruvzg/gde_low_level_funcs

[GDExtension] Expose some low level functions and String operators.
This commit is contained in:
Rémi Verschelde 2023-01-19 13:23:45 +01:00
commit f6c662264e
No known key found for this signature in database
GPG key ID: C3336907360768E1
16 changed files with 246 additions and 262 deletions

View file

@ -31,8 +31,11 @@
#include "gdextension_interface.h"
#include "core/config/engine.h"
#include "core/io/file_access.h"
#include "core/io/xml_parser.h"
#include "core/object/class_db.h"
#include "core/object/script_language_extension.h"
#include "core/object/worker_thread_pool.h"
#include "core/os/memory.h"
#include "core/variant/variant.h"
#include "core/version.h"
@ -678,6 +681,59 @@ static const char32_t *gdextension_string_operator_index_const(GDExtensionConstS
return &self->ptr()[p_index];
}
static void gdextension_string_operator_plus_eq_string(GDExtensionStringPtr p_self, GDExtensionConstStringPtr p_b) {
String *self = (String *)p_self;
const String *b = (const String *)p_b;
*self += *b;
}
static void gdextension_string_operator_plus_eq_char(GDExtensionStringPtr p_self, char32_t p_b) {
String *self = (String *)p_self;
*self += p_b;
}
static void gdextension_string_operator_plus_eq_cstr(GDExtensionStringPtr p_self, const char *p_b) {
String *self = (String *)p_self;
*self += p_b;
}
static void gdextension_string_operator_plus_eq_wcstr(GDExtensionStringPtr p_self, const wchar_t *p_b) {
String *self = (String *)p_self;
*self += p_b;
}
static void gdextension_string_operator_plus_eq_c32str(GDExtensionStringPtr p_self, const char32_t *p_b) {
String *self = (String *)p_self;
*self += p_b;
}
static GDExtensionInt gdextension_xml_parser_open_buffer(GDExtensionObjectPtr p_instance, const uint8_t *p_buffer, size_t p_size) {
XMLParser *xml = (XMLParser *)p_instance;
return (GDExtensionInt)xml->_open_buffer(p_buffer, p_size);
}
static void gdextension_file_access_store_buffer(GDExtensionObjectPtr p_instance, const uint8_t *p_src, uint64_t p_length) {
FileAccess *fa = (FileAccess *)p_instance;
fa->store_buffer(p_src, p_length);
}
static uint64_t gdextension_file_access_get_buffer(GDExtensionConstObjectPtr p_instance, uint8_t *p_dst, uint64_t p_length) {
const FileAccess *fa = (FileAccess *)p_instance;
return fa->get_buffer(p_dst, p_length);
}
static int64_t gdextension_worker_thread_pool_add_native_group_task(GDExtensionObjectPtr p_instance, void (*p_func)(void *, uint32_t), void *p_userdata, int p_elements, int p_tasks, bool p_high_priority, GDExtensionConstStringPtr p_description) {
WorkerThreadPool *p = (WorkerThreadPool *)p_instance;
const String *description = (const String *)p_description;
return (int64_t)p->add_native_group_task(p_func, p_userdata, p_elements, p_tasks, p_high_priority, *description);
}
static int64_t gdextension_worker_thread_pool_add_native_task(GDExtensionObjectPtr p_instance, void (*p_func)(void *), void *p_userdata, bool p_high_priority, GDExtensionConstStringPtr p_description) {
WorkerThreadPool *p = (WorkerThreadPool *)p_instance;
const String *description = (const String *)p_description;
return (int64_t)p->add_native_task(p_func, p_userdata, p_high_priority, *description);
}
/* Packed array functions */
static uint8_t *gdextension_packed_byte_array_operator_index(GDExtensionTypePtr p_self, GDExtensionInt p_index) {
@ -1025,6 +1081,25 @@ void gdextension_setup_interface(GDExtensionInterface *p_interface) {
gde_interface.string_to_wide_chars = gdextension_string_to_wide_chars;
gde_interface.string_operator_index = gdextension_string_operator_index;
gde_interface.string_operator_index_const = gdextension_string_operator_index_const;
gde_interface.string_operator_plus_eq_string = gdextension_string_operator_plus_eq_string;
gde_interface.string_operator_plus_eq_char = gdextension_string_operator_plus_eq_char;
gde_interface.string_operator_plus_eq_cstr = gdextension_string_operator_plus_eq_cstr;
gde_interface.string_operator_plus_eq_wcstr = gdextension_string_operator_plus_eq_wcstr;
gde_interface.string_operator_plus_eq_c32str = gdextension_string_operator_plus_eq_c32str;
/* XMLParser extra utilities */
gde_interface.xml_parser_open_buffer = gdextension_xml_parser_open_buffer;
/* FileAccess extra utilities */
gde_interface.file_access_store_buffer = gdextension_file_access_store_buffer;
gde_interface.file_access_get_buffer = gdextension_file_access_get_buffer;
/* WorkerThreadPool extra utilities */
gde_interface.worker_thread_pool_add_native_group_task = gdextension_worker_thread_pool_add_native_group_task;
gde_interface.worker_thread_pool_add_native_task = gdextension_worker_thread_pool_add_native_task;
/* Packed array functions */

View file

@ -503,6 +503,26 @@ typedef struct {
char32_t *(*string_operator_index)(GDExtensionStringPtr p_self, GDExtensionInt p_index);
const char32_t *(*string_operator_index_const)(GDExtensionConstStringPtr p_self, GDExtensionInt p_index);
void (*string_operator_plus_eq_string)(GDExtensionStringPtr p_self, GDExtensionConstStringPtr p_b);
void (*string_operator_plus_eq_char)(GDExtensionStringPtr p_self, char32_t p_b);
void (*string_operator_plus_eq_cstr)(GDExtensionStringPtr p_self, const char *p_b);
void (*string_operator_plus_eq_wcstr)(GDExtensionStringPtr p_self, const wchar_t *p_b);
void (*string_operator_plus_eq_c32str)(GDExtensionStringPtr p_self, const char32_t *p_b);
/* XMLParser extra utilities */
GDExtensionInt (*xml_parser_open_buffer)(GDExtensionObjectPtr p_instance, const uint8_t *p_buffer, size_t p_size);
/* FileAccess extra utilities */
void (*file_access_store_buffer)(GDExtensionObjectPtr p_instance, const uint8_t *p_src, uint64_t p_length);
uint64_t (*file_access_get_buffer)(GDExtensionConstObjectPtr p_instance, uint8_t *p_dst, uint64_t p_length);
/* WorkerThreadPool extra utilities */
int64_t (*worker_thread_pool_add_native_group_task)(GDExtensionObjectPtr p_instance, void (*p_func)(void *, uint32_t), void *p_userdata, int p_elements, int p_tasks, bool p_high_priority, GDExtensionConstStringPtr p_description);
int64_t (*worker_thread_pool_add_native_task)(GDExtensionObjectPtr p_instance, void (*p_func)(void *), void *p_userdata, bool p_high_priority, GDExtensionConstStringPtr p_description);
/* Packed array functions */
uint8_t *(*packed_byte_array_operator_index)(GDExtensionTypePtr p_self, GDExtensionInt p_index); // p_self should be a PackedByteArray

View file

@ -292,7 +292,7 @@ real_t FileAccess::get_real() const {
Variant FileAccess::get_var(bool p_allow_objects) const {
uint32_t len = get_32();
Vector<uint8_t> buff = _get_buffer(len);
Vector<uint8_t> buff = get_buffer(len);
ERR_FAIL_COND_V((uint32_t)buff.size() != len, Variant());
const uint8_t *r = buff.ptr();
@ -469,7 +469,7 @@ uint64_t FileAccess::get_buffer(uint8_t *p_dst, uint64_t p_length) const {
return i;
}
Vector<uint8_t> FileAccess::_get_buffer(int64_t p_length) const {
Vector<uint8_t> FileAccess::get_buffer(int64_t p_length) const {
Vector<uint8_t> data;
ERR_FAIL_COND_V_MSG(p_length < 0, data, "Length of buffer cannot be smaller than 0.");
@ -663,7 +663,7 @@ void FileAccess::store_buffer(const uint8_t *p_src, uint64_t p_length) {
}
}
void FileAccess::_store_buffer(const Vector<uint8_t> &p_buffer) {
void FileAccess::store_buffer(const Vector<uint8_t> &p_buffer) {
uint64_t len = p_buffer.size();
if (len == 0) {
return;
@ -687,7 +687,7 @@ void FileAccess::store_var(const Variant &p_var, bool p_full_objects) {
ERR_FAIL_COND_MSG(err != OK, "Error when trying to encode Variant.");
store_32(len);
_store_buffer(buff);
store_buffer(buff);
}
Vector<uint8_t> FileAccess::get_file_as_bytes(const String &p_path, Error *r_error) {
@ -829,7 +829,7 @@ void FileAccess::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_float"), &FileAccess::get_float);
ClassDB::bind_method(D_METHOD("get_double"), &FileAccess::get_double);
ClassDB::bind_method(D_METHOD("get_real"), &FileAccess::get_real);
ClassDB::bind_method(D_METHOD("get_buffer", "length"), &FileAccess::_get_buffer);
ClassDB::bind_method(D_METHOD("get_buffer", "length"), (Vector<uint8_t>(FileAccess::*)(int64_t) const) & FileAccess::get_buffer);
ClassDB::bind_method(D_METHOD("get_line"), &FileAccess::get_line);
ClassDB::bind_method(D_METHOD("get_csv_line", "delim"), &FileAccess::get_csv_line, DEFVAL(","));
ClassDB::bind_method(D_METHOD("get_as_text", "skip_cr"), &FileAccess::get_as_text, DEFVAL(false));
@ -847,7 +847,7 @@ void FileAccess::_bind_methods() {
ClassDB::bind_method(D_METHOD("store_float", "value"), &FileAccess::store_float);
ClassDB::bind_method(D_METHOD("store_double", "value"), &FileAccess::store_double);
ClassDB::bind_method(D_METHOD("store_real", "value"), &FileAccess::store_real);
ClassDB::bind_method(D_METHOD("store_buffer", "buffer"), &FileAccess::_store_buffer);
ClassDB::bind_method(D_METHOD("store_buffer", "buffer"), (void(FileAccess::*)(const Vector<uint8_t> &)) & FileAccess::store_buffer);
ClassDB::bind_method(D_METHOD("store_line", "line"), &FileAccess::store_line);
ClassDB::bind_method(D_METHOD("store_csv_line", "values", "delim"), &FileAccess::store_csv_line, DEFVAL(","));
ClassDB::bind_method(D_METHOD("store_string", "string"), &FileAccess::store_string);

View file

@ -127,7 +127,7 @@ public:
Variant get_var(bool p_allow_objects = false) const;
virtual uint64_t get_buffer(uint8_t *p_dst, uint64_t p_length) const; ///< get an array of bytes
Vector<uint8_t> _get_buffer(int64_t p_length) const;
Vector<uint8_t> get_buffer(int64_t p_length) const;
virtual String get_line() const;
virtual String get_token() const;
virtual Vector<String> get_csv_line(const String &p_delim = ",") const;
@ -162,7 +162,7 @@ public:
virtual String get_pascal_string();
virtual void store_buffer(const uint8_t *p_src, uint64_t p_length); ///< store an array of bytes
void _store_buffer(const Vector<uint8_t> &p_buffer);
void store_buffer(const Vector<uint8_t> &p_buffer);
void store_var(const Variant &p_var, bool p_full_objects = false);

View file

@ -354,10 +354,10 @@ void XMLParser::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_node_offset"), &XMLParser::get_node_offset);
ClassDB::bind_method(D_METHOD("get_attribute_count"), &XMLParser::get_attribute_count);
ClassDB::bind_method(D_METHOD("get_attribute_name", "idx"), &XMLParser::get_attribute_name);
ClassDB::bind_method(D_METHOD("get_attribute_value", "idx"), (String(XMLParser::*)(int) const) & XMLParser::get_attribute_value);
ClassDB::bind_method(D_METHOD("get_attribute_value", "idx"), &XMLParser::get_attribute_value);
ClassDB::bind_method(D_METHOD("has_attribute", "name"), &XMLParser::has_attribute);
ClassDB::bind_method(D_METHOD("get_named_attribute_value", "name"), (String(XMLParser::*)(const String &) const) & XMLParser::get_attribute_value);
ClassDB::bind_method(D_METHOD("get_named_attribute_value_safe", "name"), &XMLParser::get_attribute_value_safe);
ClassDB::bind_method(D_METHOD("get_named_attribute_value", "name"), &XMLParser::get_named_attribute_value);
ClassDB::bind_method(D_METHOD("get_named_attribute_value_safe", "name"), &XMLParser::get_named_attribute_value_safe);
ClassDB::bind_method(D_METHOD("is_empty"), &XMLParser::is_empty);
ClassDB::bind_method(D_METHOD("get_current_line"), &XMLParser::get_current_line);
ClassDB::bind_method(D_METHOD("skip_section"), &XMLParser::skip_section);
@ -422,7 +422,7 @@ bool XMLParser::has_attribute(const String &p_name) const {
return false;
}
String XMLParser::get_attribute_value(const String &p_name) const {
String XMLParser::get_named_attribute_value(const String &p_name) const {
int idx = -1;
for (int i = 0; i < attributes.size(); i++) {
if (attributes[i].name == p_name) {
@ -436,7 +436,7 @@ String XMLParser::get_attribute_value(const String &p_name) const {
return attributes[idx].value;
}
String XMLParser::get_attribute_value_safe(const String &p_name) const {
String XMLParser::get_named_attribute_value_safe(const String &p_name) const {
int idx = -1;
for (int i = 0; i < attributes.size(); i++) {
if (attributes[i].name == p_name) {

View file

@ -109,8 +109,8 @@ public:
String get_attribute_name(int p_idx) const;
String get_attribute_value(int p_idx) const;
bool has_attribute(const String &p_name) const;
String get_attribute_value(const String &p_name) const;
String get_attribute_value_safe(const String &p_name) const; // do not print error if doesn't exist
String get_named_attribute_value(const String &p_name) const;
String get_named_attribute_value_safe(const String &p_name) const; // do not print error if doesn't exist
bool is_empty() const;
int get_current_line() const;

View file

@ -1021,15 +1021,15 @@ static Error _parse_methods(Ref<XMLParser> &parser, Vector<DocData::MethodDoc> &
if (parser->get_node_name() == element) {
DocData::MethodDoc method;
ERR_FAIL_COND_V(!parser->has_attribute("name"), ERR_FILE_CORRUPT);
method.name = parser->get_attribute_value("name");
method.name = parser->get_named_attribute_value("name");
if (parser->has_attribute("qualifiers")) {
method.qualifiers = parser->get_attribute_value("qualifiers");
method.qualifiers = parser->get_named_attribute_value("qualifiers");
}
if (parser->has_attribute("is_deprecated")) {
method.is_deprecated = parser->get_attribute_value("is_deprecated").to_lower() == "true";
method.is_deprecated = parser->get_named_attribute_value("is_deprecated").to_lower() == "true";
}
if (parser->has_attribute("is_experimental")) {
method.is_experimental = parser->get_attribute_value("is_experimental").to_lower() == "true";
method.is_experimental = parser->get_named_attribute_value("is_experimental").to_lower() == "true";
}
while (parser->read() == OK) {
@ -1037,21 +1037,21 @@ static Error _parse_methods(Ref<XMLParser> &parser, Vector<DocData::MethodDoc> &
String name = parser->get_node_name();
if (name == "return") {
ERR_FAIL_COND_V(!parser->has_attribute("type"), ERR_FILE_CORRUPT);
method.return_type = parser->get_attribute_value("type");
method.return_type = parser->get_named_attribute_value("type");
if (parser->has_attribute("enum")) {
method.return_enum = parser->get_attribute_value("enum");
method.return_enum = parser->get_named_attribute_value("enum");
}
} else if (name == "returns_error") {
ERR_FAIL_COND_V(!parser->has_attribute("number"), ERR_FILE_CORRUPT);
method.errors_returned.push_back(parser->get_attribute_value("number").to_int());
method.errors_returned.push_back(parser->get_named_attribute_value("number").to_int());
} else if (name == "param") {
DocData::ArgumentDoc argument;
ERR_FAIL_COND_V(!parser->has_attribute("name"), ERR_FILE_CORRUPT);
argument.name = parser->get_attribute_value("name");
argument.name = parser->get_named_attribute_value("name");
ERR_FAIL_COND_V(!parser->has_attribute("type"), ERR_FILE_CORRUPT);
argument.type = parser->get_attribute_value("type");
argument.type = parser->get_named_attribute_value("type");
if (parser->has_attribute("enum")) {
argument.enumeration = parser->get_attribute_value("enum");
argument.enumeration = parser->get_named_attribute_value("enum");
}
method.arguments.push_back(argument);
@ -1153,21 +1153,21 @@ Error DocTools::_load(Ref<XMLParser> parser) {
ERR_FAIL_COND_V(parser->get_node_name() != "class", ERR_FILE_CORRUPT);
ERR_FAIL_COND_V(!parser->has_attribute("name"), ERR_FILE_CORRUPT);
String name = parser->get_attribute_value("name");
String name = parser->get_named_attribute_value("name");
class_list[name] = DocData::ClassDoc();
DocData::ClassDoc &c = class_list[name];
c.name = name;
if (parser->has_attribute("inherits")) {
c.inherits = parser->get_attribute_value("inherits");
c.inherits = parser->get_named_attribute_value("inherits");
}
if (parser->has_attribute("is_deprecated")) {
c.is_deprecated = parser->get_attribute_value("is_deprecated").to_lower() == "true";
c.is_deprecated = parser->get_named_attribute_value("is_deprecated").to_lower() == "true";
}
if (parser->has_attribute("is_experimental")) {
c.is_experimental = parser->get_attribute_value("is_experimental").to_lower() == "true";
c.is_experimental = parser->get_named_attribute_value("is_experimental").to_lower() == "true";
}
while (parser->read() == OK) {
@ -1193,7 +1193,7 @@ Error DocTools::_load(Ref<XMLParser> parser) {
if (name3 == "link") {
DocData::TutorialDoc tutorial;
if (parser->has_attribute("title")) {
tutorial.title = parser->get_attribute_value("title");
tutorial.title = parser->get_named_attribute_value("title");
}
parser->read();
if (parser->get_node_type() == XMLParser::NODE_TEXT) {
@ -1231,23 +1231,23 @@ Error DocTools::_load(Ref<XMLParser> parser) {
DocData::PropertyDoc prop2;
ERR_FAIL_COND_V(!parser->has_attribute("name"), ERR_FILE_CORRUPT);
prop2.name = parser->get_attribute_value("name");
prop2.name = parser->get_named_attribute_value("name");
ERR_FAIL_COND_V(!parser->has_attribute("type"), ERR_FILE_CORRUPT);
prop2.type = parser->get_attribute_value("type");
prop2.type = parser->get_named_attribute_value("type");
if (parser->has_attribute("setter")) {
prop2.setter = parser->get_attribute_value("setter");
prop2.setter = parser->get_named_attribute_value("setter");
}
if (parser->has_attribute("getter")) {
prop2.getter = parser->get_attribute_value("getter");
prop2.getter = parser->get_named_attribute_value("getter");
}
if (parser->has_attribute("enum")) {
prop2.enumeration = parser->get_attribute_value("enum");
prop2.enumeration = parser->get_named_attribute_value("enum");
}
if (parser->has_attribute("is_deprecated")) {
prop2.is_deprecated = parser->get_attribute_value("is_deprecated").to_lower() == "true";
prop2.is_deprecated = parser->get_named_attribute_value("is_deprecated").to_lower() == "true";
}
if (parser->has_attribute("is_experimental")) {
prop2.is_experimental = parser->get_attribute_value("is_experimental").to_lower() == "true";
prop2.is_experimental = parser->get_named_attribute_value("is_experimental").to_lower() == "true";
}
if (!parser->is_empty()) {
parser->read();
@ -1274,11 +1274,11 @@ Error DocTools::_load(Ref<XMLParser> parser) {
DocData::ThemeItemDoc prop2;
ERR_FAIL_COND_V(!parser->has_attribute("name"), ERR_FILE_CORRUPT);
prop2.name = parser->get_attribute_value("name");
prop2.name = parser->get_named_attribute_value("name");
ERR_FAIL_COND_V(!parser->has_attribute("type"), ERR_FILE_CORRUPT);
prop2.type = parser->get_attribute_value("type");
prop2.type = parser->get_named_attribute_value("type");
ERR_FAIL_COND_V(!parser->has_attribute("data_type"), ERR_FILE_CORRUPT);
prop2.data_type = parser->get_attribute_value("data_type");
prop2.data_type = parser->get_named_attribute_value("data_type");
if (!parser->is_empty()) {
parser->read();
if (parser->get_node_type() == XMLParser::NODE_TEXT) {
@ -1303,21 +1303,21 @@ Error DocTools::_load(Ref<XMLParser> parser) {
if (name3 == "constant") {
DocData::ConstantDoc constant2;
ERR_FAIL_COND_V(!parser->has_attribute("name"), ERR_FILE_CORRUPT);
constant2.name = parser->get_attribute_value("name");
constant2.name = parser->get_named_attribute_value("name");
ERR_FAIL_COND_V(!parser->has_attribute("value"), ERR_FILE_CORRUPT);
constant2.value = parser->get_attribute_value("value");
constant2.value = parser->get_named_attribute_value("value");
constant2.is_value_valid = true;
if (parser->has_attribute("enum")) {
constant2.enumeration = parser->get_attribute_value("enum");
constant2.enumeration = parser->get_named_attribute_value("enum");
}
if (parser->has_attribute("is_bitfield")) {
constant2.is_bitfield = parser->get_attribute_value("is_bitfield").to_lower() == "true";
constant2.is_bitfield = parser->get_named_attribute_value("is_bitfield").to_lower() == "true";
}
if (parser->has_attribute("is_deprecated")) {
constant2.is_deprecated = parser->get_attribute_value("is_deprecated").to_lower() == "true";
constant2.is_deprecated = parser->get_named_attribute_value("is_deprecated").to_lower() == "true";
}
if (parser->has_attribute("is_experimental")) {
constant2.is_experimental = parser->get_attribute_value("is_experimental").to_lower() == "true";
constant2.is_experimental = parser->get_named_attribute_value("is_experimental").to_lower() == "true";
}
if (!parser->is_empty()) {
parser->read();

View file

@ -262,7 +262,7 @@ void Collada::_parse_asset(XMLParser &parser) {
COLLADA_PRINT("up axis: " + parser.get_node_data());
} else if (name == "unit") {
state.unit_scale = parser.get_attribute_value("meter").to_float();
state.unit_scale = parser.get_named_attribute_value("meter").to_float();
COLLADA_PRINT("unit scale: " + rtos(state.unit_scale));
}
@ -273,7 +273,7 @@ void Collada::_parse_asset(XMLParser &parser) {
}
void Collada::_parse_image(XMLParser &parser) {
String id = parser.get_attribute_value("id");
String id = parser.get_named_attribute_value("id");
if (!(state.import_flags & IMPORT_FLAG_SCENE)) {
if (!parser.is_empty()) {
@ -286,7 +286,7 @@ void Collada::_parse_image(XMLParser &parser) {
if (state.version < State::Version(1, 4, 0)) {
/* <1.4 */
String path = parser.get_attribute_value("source").strip_edges();
String path = parser.get_named_attribute_value("source").strip_edges();
if (!path.contains("://") && path.is_relative_path()) {
// path is relative to file being loaded, so convert to a resource path
image.path = ProjectSettings::get_singleton()->localize_path(state.local_path.get_base_dir().path_join(path.uri_decode()));
@ -337,9 +337,9 @@ void Collada::_parse_material(XMLParser &parser) {
Material material;
String id = parser.get_attribute_value("id");
String id = parser.get_named_attribute_value("id");
if (parser.has_attribute("name")) {
material.name = parser.get_attribute_value("name");
material.name = parser.get_named_attribute_value("name");
}
if (state.version < State::Version(1, 4, 0)) {
@ -348,7 +348,7 @@ void Collada::_parse_material(XMLParser &parser) {
} else {
while (parser.read() == OK) {
if (parser.get_node_type() == XMLParser::NODE_ELEMENT && parser.get_node_name() == "instance_effect") {
material.instance_effect = _uri_to_id(parser.get_attribute_value("url"));
material.instance_effect = _uri_to_id(parser.get_named_attribute_value("url"));
} else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "material") {
break; //end of <asset>
}
@ -549,7 +549,7 @@ void Collada::_parse_effect_material(XMLParser &parser, Effect &effect, String &
_parse_effect_material(parser, effect, id); // try again
} else if (parser.get_node_name() == "newparam") {
String name = parser.get_attribute_value("sid");
String name = parser.get_named_attribute_value("sid");
Variant value = _parse_param(parser);
effect.params[name] = value;
COLLADA_PRINT("param: " + name + " value:" + String(value));
@ -591,7 +591,7 @@ void Collada::_parse_effect_material(XMLParser &parser, Effect &effect, String &
}
} else if (parser.get_node_name() == "texture") {
String sampler = parser.get_attribute_value("texture");
String sampler = parser.get_named_attribute_value("texture");
if (!effect.params.has(sampler)) {
ERR_PRINT(String("Couldn't find sampler: " + sampler + " in material:" + id).utf8().get_data());
} else {
@ -609,7 +609,7 @@ void Collada::_parse_effect_material(XMLParser &parser, Effect &effect, String &
} else if (what == "emission") {
effect.emission.texture = uri;
} else if (what == "bump") {
if (parser.has_attribute("bumptype") && parser.get_attribute_value("bumptype") != "NORMALMAP") {
if (parser.has_attribute("bumptype") && parser.get_named_attribute_value("bumptype") != "NORMALMAP") {
WARN_PRINT("'bump' texture type is not NORMALMAP, only NORMALMAP is supported.");
}
@ -654,7 +654,7 @@ void Collada::_parse_effect_material(XMLParser &parser, Effect &effect, String &
while (parser.read() == OK) {
if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
if (parser.get_node_name() == "texture") {
String sampler = parser.get_attribute_value("texture");
String sampler = parser.get_named_attribute_value("texture");
if (!effect.params.has(sampler)) {
ERR_PRINT(String("Couldn't find sampler: " + sampler + " in material:" + id).utf8().get_data());
} else {
@ -665,7 +665,7 @@ void Collada::_parse_effect_material(XMLParser &parser, Effect &effect, String &
} else {
String uri = effect.params[surface];
if (parser.has_attribute("bumptype") && parser.get_attribute_value("bumptype") != "NORMALMAP") {
if (parser.has_attribute("bumptype") && parser.get_named_attribute_value("bumptype") != "NORMALMAP") {
WARN_PRINT("'bump' texture type is not NORMALMAP, only NORMALMAP is supported.");
}
@ -703,11 +703,11 @@ void Collada::_parse_effect(XMLParser &parser) {
return;
}
String id = parser.get_attribute_value("id");
String id = parser.get_named_attribute_value("id");
Effect effect;
if (parser.has_attribute("name")) {
effect.name = parser.get_attribute_value("name");
effect.name = parser.get_named_attribute_value("name");
}
_parse_effect_material(parser, effect, id);
@ -724,7 +724,7 @@ void Collada::_parse_camera(XMLParser &parser) {
return;
}
String id = parser.get_attribute_value("id");
String id = parser.get_named_attribute_value("id");
state.camera_data_map[id] = CameraData();
CameraData &camera = state.camera_data_map[id];
@ -780,7 +780,7 @@ void Collada::_parse_light(XMLParser &parser) {
return;
}
String id = parser.get_attribute_value("id");
String id = parser.get_named_attribute_value("id");
state.light_data_map[id] = LightData();
LightData &light = state.light_data_map[id];
@ -848,7 +848,7 @@ void Collada::_parse_curve_geometry(XMLParser &parser, String p_id, String p_nam
CurveData &curvedata = state.curve_data_map[p_id];
curvedata.name = p_name;
String closed = parser.get_attribute_value_safe("closed").to_lower();
String closed = parser.get_named_attribute_value_safe("closed").to_lower();
curvedata.closed = closed == "true" || closed == "1";
COLLADA_PRINT("curve name: " + p_name);
@ -865,7 +865,7 @@ void Collada::_parse_curve_geometry(XMLParser &parser, String p_id, String p_nam
String section = parser.get_node_name();
if (section == "source") {
String id = parser.get_attribute_value("id");
String id = parser.get_named_attribute_value("id");
curvedata.sources[id] = CurveData::Source();
current_source = id;
COLLADA_PRINT("source data: " + id);
@ -888,15 +888,15 @@ void Collada::_parse_curve_geometry(XMLParser &parser, String p_id, String p_nam
} else if (section == "accessor") { // child of source (below a technique tag)
if (curvedata.sources.has(current_source)) {
curvedata.sources[current_source].stride = parser.get_attribute_value("stride").to_int();
curvedata.sources[current_source].stride = parser.get_named_attribute_value("stride").to_int();
COLLADA_PRINT("section: " + current_source + " stride " + itos(curvedata.sources[current_source].stride));
}
} else if (section == "control_vertices") {
while (parser.read() == OK) {
if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
if (parser.get_node_name() == "input") {
String semantic = parser.get_attribute_value("semantic");
String source = _uri_to_id(parser.get_attribute_value("source"));
String semantic = parser.get_named_attribute_value("semantic");
String source = _uri_to_id(parser.get_named_attribute_value("source"));
curvedata.control_vertices[semantic] = source;
@ -945,7 +945,7 @@ void Collada::_parse_mesh_geometry(XMLParser &parser, String p_id, String p_name
String section = parser.get_node_name();
if (section == "source") {
String id = parser.get_attribute_value("id");
String id = parser.get_named_attribute_value("id");
meshdata.sources[id] = MeshData::Source();
current_source = id;
COLLADA_PRINT("source data: " + id);
@ -961,19 +961,19 @@ void Collada::_parse_mesh_geometry(XMLParser &parser, String p_id, String p_name
} else if (section == "accessor") { // child of source (below a technique tag)
if (meshdata.sources.has(current_source)) {
meshdata.sources[current_source].stride = parser.get_attribute_value("stride").to_int();
meshdata.sources[current_source].stride = parser.get_named_attribute_value("stride").to_int();
COLLADA_PRINT("section: " + current_source + " stride " + itos(meshdata.sources[current_source].stride));
}
} else if (section == "vertices") {
MeshData::Vertices vert;
String id = parser.get_attribute_value("id");
String id = parser.get_named_attribute_value("id");
int last_ref = 0;
while (parser.read() == OK) {
if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
if (parser.get_node_name() == "input") {
String semantic = parser.get_attribute_value("semantic");
String source = _uri_to_id(parser.get_attribute_value("source"));
String semantic = parser.get_named_attribute_value("semantic");
String source = _uri_to_id(parser.get_named_attribute_value("source"));
if (semantic == "TEXCOORD") {
semantic = "TEXCOORD" + itos(last_ref++);
@ -998,22 +998,22 @@ void Collada::_parse_mesh_geometry(XMLParser &parser, String p_id, String p_name
MeshData::Primitives prim;
if (parser.has_attribute("material")) {
prim.material = parser.get_attribute_value("material");
prim.material = parser.get_named_attribute_value("material");
}
prim.count = parser.get_attribute_value("count").to_int();
prim.count = parser.get_named_attribute_value("count").to_int();
prim.vertex_size = 0;
int last_ref = 0;
while (parser.read() == OK) {
if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
if (parser.get_node_name() == "input") {
String semantic = parser.get_attribute_value("semantic");
String source = _uri_to_id(parser.get_attribute_value("source"));
String semantic = parser.get_named_attribute_value("semantic");
String source = _uri_to_id(parser.get_named_attribute_value("source"));
if (semantic == "TEXCOORD") {
semantic = "TEXCOORD" + itos(last_ref++);
}
int offset = parser.get_attribute_value("offset").to_int();
int offset = parser.get_named_attribute_value("offset").to_int();
MeshData::Primitives::SourceRef sref;
sref.source = source;
@ -1074,7 +1074,7 @@ void Collada::_parse_skin_controller(XMLParser &parser, String p_id) {
state.skin_controller_data_map[p_id] = SkinControllerData();
SkinControllerData &skindata = state.skin_controller_data_map[p_id];
skindata.base = _uri_to_id(parser.get_attribute_value("source"));
skindata.base = _uri_to_id(parser.get_named_attribute_value("source"));
String current_source;
@ -1091,7 +1091,7 @@ void Collada::_parse_skin_controller(XMLParser &parser, String p_id) {
COLLADA_PRINT("skeleton bind shape transform: " + skindata.bind_shape);
} else if (section == "source") {
String id = parser.get_attribute_value("id");
String id = parser.get_named_attribute_value("id");
skindata.sources[id] = SkinControllerData::Source();
current_source = id;
COLLADA_PRINT("source data: " + id);
@ -1125,7 +1125,7 @@ void Collada::_parse_skin_controller(XMLParser &parser, String p_id) {
if (skindata.sources.has(current_source)) {
int stride = 1;
if (parser.has_attribute("stride")) {
stride = parser.get_attribute_value("stride").to_int();
stride = parser.get_named_attribute_value("stride").to_int();
}
skindata.sources[current_source].stride = stride;
@ -1138,8 +1138,8 @@ void Collada::_parse_skin_controller(XMLParser &parser, String p_id) {
while (parser.read() == OK) {
if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
if (parser.get_node_name() == "input") {
String semantic = parser.get_attribute_value("semantic");
String source = _uri_to_id(parser.get_attribute_value("source"));
String semantic = parser.get_named_attribute_value("semantic");
String source = _uri_to_id(parser.get_named_attribute_value("source"));
joint.sources[semantic] = source;
@ -1155,15 +1155,15 @@ void Collada::_parse_skin_controller(XMLParser &parser, String p_id) {
} else if (section == "vertex_weights") {
SkinControllerData::Weights weights;
weights.count = parser.get_attribute_value("count").to_int();
weights.count = parser.get_named_attribute_value("count").to_int();
while (parser.read() == OK) {
if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
if (parser.get_node_name() == "input") {
String semantic = parser.get_attribute_value("semantic");
String source = _uri_to_id(parser.get_attribute_value("source"));
String semantic = parser.get_named_attribute_value("semantic");
String source = _uri_to_id(parser.get_named_attribute_value("source"));
int offset = parser.get_attribute_value("offset").to_int();
int offset = parser.get_named_attribute_value("offset").to_int();
SkinControllerData::Weights::SourceRef sref;
sref.source = source;
@ -1228,8 +1228,8 @@ void Collada::_parse_morph_controller(XMLParser &parser, String p_id) {
state.morph_controller_data_map[p_id] = MorphControllerData();
MorphControllerData &morphdata = state.morph_controller_data_map[p_id];
morphdata.mesh = _uri_to_id(parser.get_attribute_value("source"));
morphdata.mode = parser.get_attribute_value("method");
morphdata.mesh = _uri_to_id(parser.get_named_attribute_value("source"));
morphdata.mode = parser.get_named_attribute_value("method");
String current_source;
while (parser.read() == OK) {
@ -1237,7 +1237,7 @@ void Collada::_parse_morph_controller(XMLParser &parser, String p_id) {
String section = parser.get_node_name();
if (section == "source") {
String id = parser.get_attribute_value("id");
String id = parser.get_named_attribute_value("id");
morphdata.sources[id] = MorphControllerData::Source();
current_source = id;
COLLADA_PRINT("source data: " + id);
@ -1261,7 +1261,7 @@ void Collada::_parse_morph_controller(XMLParser &parser, String p_id) {
if (morphdata.sources.has(current_source)) {
int stride = 1;
if (parser.has_attribute("stride")) {
stride = parser.get_attribute_value("stride").to_int();
stride = parser.get_named_attribute_value("stride").to_int();
}
morphdata.sources[current_source].stride = stride;
@ -1272,8 +1272,8 @@ void Collada::_parse_morph_controller(XMLParser &parser, String p_id) {
while (parser.read() == OK) {
if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
if (parser.get_node_name() == "input") {
String semantic = parser.get_attribute_value("semantic");
String source = _uri_to_id(parser.get_attribute_value("source"));
String semantic = parser.get_named_attribute_value("semantic");
String source = _uri_to_id(parser.get_named_attribute_value("source"));
morphdata.targets[semantic] = source;
@ -1295,7 +1295,7 @@ void Collada::_parse_morph_controller(XMLParser &parser, String p_id) {
}
void Collada::_parse_controller(XMLParser &parser) {
String id = parser.get_attribute_value("id");
String id = parser.get_named_attribute_value("id");
if (parser.is_empty()) {
return;
@ -1320,7 +1320,7 @@ Collada::Node *Collada::_parse_visual_instance_geometry(XMLParser &parser) {
String type = parser.get_node_name();
NodeGeometry *geom = memnew(NodeGeometry);
geom->controller = type == "instance_controller";
geom->source = _uri_to_id(parser.get_attribute_value_safe("url"));
geom->source = _uri_to_id(parser.get_named_attribute_value_safe("url"));
if (parser.is_empty()) { //nothing else to parse...
return geom;
@ -1329,8 +1329,8 @@ Collada::Node *Collada::_parse_visual_instance_geometry(XMLParser &parser) {
while (parser.read() == OK) {
if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
if (parser.get_node_name() == "instance_material") {
String symbol = parser.get_attribute_value("symbol");
String target = _uri_to_id(parser.get_attribute_value("target"));
String symbol = parser.get_named_attribute_value("symbol");
String target = _uri_to_id(parser.get_named_attribute_value("target"));
NodeGeometry::Material mat;
mat.target = target;
@ -1370,7 +1370,7 @@ Collada::Node *Collada::_parse_visual_instance_geometry(XMLParser &parser) {
Collada::Node *Collada::_parse_visual_instance_camera(XMLParser &parser) {
NodeCamera *cam = memnew(NodeCamera);
cam->camera = _uri_to_id(parser.get_attribute_value_safe("url"));
cam->camera = _uri_to_id(parser.get_named_attribute_value_safe("url"));
if (state.up_axis == Vector3::AXIS_Z) { //collada weirdness
cam->post_transform.basis.rotate(Vector3(1, 0, 0), -Math_PI * 0.5);
@ -1391,7 +1391,7 @@ Collada::Node *Collada::_parse_visual_instance_camera(XMLParser &parser) {
Collada::Node *Collada::_parse_visual_instance_light(XMLParser &parser) {
NodeLight *cam = memnew(NodeLight);
cam->light = _uri_to_id(parser.get_attribute_value_safe("url"));
cam->light = _uri_to_id(parser.get_named_attribute_value_safe("url"));
if (state.up_axis == Vector3::AXIS_Z) { //collada weirdness
cam->post_transform.basis.rotate(Vector3(1, 0, 0), -Math_PI * 0.5);
@ -1437,7 +1437,7 @@ Collada::Node *Collada::_parse_visual_node_instance_data(XMLParser &parser) {
Collada::Node *Collada::_parse_visual_scene_node(XMLParser &parser) {
String name;
String id = parser.get_attribute_value_safe("id");
String id = parser.get_named_attribute_value_safe("id");
bool found_name = false;
@ -1455,25 +1455,25 @@ Collada::Node *Collada::_parse_visual_scene_node(XMLParser &parser) {
Node *node = nullptr;
name = parser.has_attribute("name") ? parser.get_attribute_value_safe("name") : parser.get_attribute_value_safe("id");
name = parser.has_attribute("name") ? parser.get_named_attribute_value_safe("name") : parser.get_named_attribute_value_safe("id");
if (name.is_empty()) {
name = id;
} else {
found_name = true;
}
if ((parser.has_attribute("type") && parser.get_attribute_value("type") == "JOINT") || state.idref_joints.has(name)) {
if ((parser.has_attribute("type") && parser.get_named_attribute_value("type") == "JOINT") || state.idref_joints.has(name)) {
// handle a bone
NodeJoint *joint = memnew(NodeJoint);
if (parser.has_attribute("sid")) { //bones may not have sid
joint->sid = parser.get_attribute_value("sid");
joint->sid = parser.get_named_attribute_value("sid");
//state.bone_map[joint->sid]=joint;
} else if (state.idref_joints.has(name)) {
joint->sid = name; //kind of a cheat but..
} else if (parser.has_attribute("name")) {
joint->sid = parser.get_attribute_value_safe("name");
joint->sid = parser.get_named_attribute_value_safe("name");
}
if (!joint->sid.is_empty()) {
@ -1490,7 +1490,7 @@ Collada::Node *Collada::_parse_visual_scene_node(XMLParser &parser) {
if (section == "translate") {
Node::XForm xf;
if (parser.has_attribute("sid")) {
xf.id = parser.get_attribute_value("sid");
xf.id = parser.get_named_attribute_value("sid");
}
xf.op = Node::XForm::OP_TRANSLATE;
@ -1501,7 +1501,7 @@ Collada::Node *Collada::_parse_visual_scene_node(XMLParser &parser) {
} else if (section == "rotate") {
Node::XForm xf;
if (parser.has_attribute("sid")) {
xf.id = parser.get_attribute_value("sid");
xf.id = parser.get_named_attribute_value("sid");
}
xf.op = Node::XForm::OP_ROTATE;
@ -1513,7 +1513,7 @@ Collada::Node *Collada::_parse_visual_scene_node(XMLParser &parser) {
} else if (section == "scale") {
Node::XForm xf;
if (parser.has_attribute("sid")) {
xf.id = parser.get_attribute_value("sid");
xf.id = parser.get_named_attribute_value("sid");
}
xf.op = Node::XForm::OP_SCALE;
@ -1527,7 +1527,7 @@ Collada::Node *Collada::_parse_visual_scene_node(XMLParser &parser) {
} else if (section == "matrix") {
Node::XForm xf;
if (parser.has_attribute("sid")) {
xf.id = parser.get_attribute_value("sid");
xf.id = parser.get_named_attribute_value("sid");
}
xf.op = Node::XForm::OP_MATRIX;
@ -1544,7 +1544,7 @@ Collada::Node *Collada::_parse_visual_scene_node(XMLParser &parser) {
} else if (section == "visibility") {
Node::XForm xf;
if (parser.has_attribute("sid")) {
xf.id = parser.get_attribute_value("sid");
xf.id = parser.get_named_attribute_value("sid");
}
xf.op = Node::XForm::OP_VISIBILITY;
@ -1609,7 +1609,7 @@ Collada::Node *Collada::_parse_visual_scene_node(XMLParser &parser) {
}
void Collada::_parse_visual_scene(XMLParser &parser) {
String id = parser.get_attribute_value("id");
String id = parser.get_named_attribute_value("id");
if (parser.is_empty()) {
return;
@ -1619,7 +1619,7 @@ void Collada::_parse_visual_scene(XMLParser &parser) {
VisualScene &vscene = state.visual_scene_map[id];
if (parser.has_attribute("name")) {
vscene.name = parser.get_attribute_value("name");
vscene.name = parser.get_named_attribute_value("name");
}
while (parser.read() == OK) {
@ -1656,7 +1656,7 @@ void Collada::_parse_animation(XMLParser &parser) {
String id = "";
if (parser.has_attribute("id")) {
id = parser.get_attribute_value("id");
id = parser.get_named_attribute_value("id");
}
String current_source;
@ -1668,7 +1668,7 @@ void Collada::_parse_animation(XMLParser &parser) {
if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
String name = parser.get_node_name();
if (name == "source") {
current_source = parser.get_attribute_value("id");
current_source = parser.get_named_attribute_value("id");
source_param_names[current_source] = Vector<String>();
source_param_types[current_source] = Vector<String>();
@ -1683,32 +1683,32 @@ void Collada::_parse_animation(XMLParser &parser) {
}
} else if (name == "accessor") {
if (!current_source.is_empty() && parser.has_attribute("stride")) {
source_strides[current_source] = parser.get_attribute_value("stride").to_int();
source_strides[current_source] = parser.get_named_attribute_value("stride").to_int();
}
} else if (name == "sampler") {
current_sampler = parser.get_attribute_value("id");
current_sampler = parser.get_named_attribute_value("id");
samplers[current_sampler] = HashMap<String, String>();
} else if (name == "param") {
if (parser.has_attribute("name")) {
source_param_names[current_source].push_back(parser.get_attribute_value("name"));
source_param_names[current_source].push_back(parser.get_named_attribute_value("name"));
} else {
source_param_names[current_source].push_back("");
}
if (parser.has_attribute("type")) {
source_param_types[current_source].push_back(parser.get_attribute_value("type"));
source_param_types[current_source].push_back(parser.get_named_attribute_value("type"));
} else {
source_param_types[current_source].push_back("");
}
} else if (name == "input") {
if (!current_sampler.is_empty()) {
samplers[current_sampler][parser.get_attribute_value("semantic")] = parser.get_attribute_value("source");
samplers[current_sampler][parser.get_named_attribute_value("semantic")] = parser.get_named_attribute_value("source");
}
} else if (name == "channel") {
channel_sources.push_back(parser.get_attribute_value("source"));
channel_targets.push_back(parser.get_attribute_value("target"));
channel_sources.push_back(parser.get_named_attribute_value("source"));
channel_targets.push_back(parser.get_named_attribute_value("target"));
}
} else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "animation") {
@ -1857,22 +1857,22 @@ void Collada::_parse_animation_clip(XMLParser &parser) {
AnimationClip clip;
if (parser.has_attribute("name")) {
clip.name = parser.get_attribute_value("name");
clip.name = parser.get_named_attribute_value("name");
} else if (parser.has_attribute("id")) {
clip.name = parser.get_attribute_value("id");
clip.name = parser.get_named_attribute_value("id");
}
if (parser.has_attribute("start")) {
clip.begin = parser.get_attribute_value("start").to_float();
clip.begin = parser.get_named_attribute_value("start").to_float();
}
if (parser.has_attribute("end")) {
clip.end = parser.get_attribute_value("end").to_float();
clip.end = parser.get_named_attribute_value("end").to_float();
}
while (parser.read() == OK) {
if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
String name = parser.get_node_name();
if (name == "instance_animation") {
String url = _uri_to_id(parser.get_attribute_value("url"));
String url = _uri_to_id(parser.get_named_attribute_value("url"));
clip.tracks.push_back(url);
}
@ -1894,9 +1894,9 @@ void Collada::_parse_scene(XMLParser &parser) {
String name = parser.get_node_name();
if (name == "instance_visual_scene") {
state.root_visual_scene = _uri_to_id(parser.get_attribute_value("url"));
state.root_visual_scene = _uri_to_id(parser.get_named_attribute_value("url"));
} else if (name == "instance_physics_scene") {
state.root_physics_scene = _uri_to_id(parser.get_attribute_value("url"));
state.root_physics_scene = _uri_to_id(parser.get_named_attribute_value("url"));
}
} else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "scene") {
@ -1925,8 +1925,8 @@ void Collada::_parse_library(XMLParser &parser) {
} else if (name == "light") {
_parse_light(parser);
} else if (name == "geometry") {
String id = parser.get_attribute_value("id");
String name2 = parser.get_attribute_value_safe("name");
String id = parser.get_named_attribute_value("id");
String name2 = parser.get_named_attribute_value_safe("name");
while (parser.read() == OK) {
if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
if (parser.get_node_name() == "mesh") {
@ -2346,7 +2346,7 @@ Error Collada::load(const String &p_path, int p_flags) {
{
//version
String version = parser.get_attribute_value("version");
String version = parser.get_named_attribute_value("version");
state.version.major = version.get_slice(".", 0).to_int();
state.version.minor = version.get_slice(".", 1).to_int();
state.version.rev = version.get_slice(".", 2).to_int();

View file

@ -423,11 +423,7 @@ bool TextServerAdvanced::_load_support_data(const String &p_filename) {
return false;
}
uint64_t len = f->get_length();
#ifdef GDEXTENSION
PackedByteArray icu_data = f->get_buffer(len);
#else
PackedByteArray icu_data = f->_get_buffer(len);
#endif
UErrorCode err = U_ZERO_ERROR;
udata_setCommonData(icu_data.ptr(), &err);
@ -476,11 +472,7 @@ bool TextServerAdvanced::_save_support_data(const String &p_filename) const {
PackedByteArray icu_data;
icu_data.resize(U_ICUDATA_SIZE);
memcpy(icu_data.ptrw(), U_ICUDATA_ENTRY_POINT, U_ICUDATA_SIZE);
#ifdef GDEXTENSION
f->store_buffer(icu_data);
#else
f->_store_buffer(icu_data);
#endif
return true;
#else
@ -824,29 +816,17 @@ _FORCE_INLINE_ TextServerAdvanced::FontTexturePosition TextServerAdvanced::find_
// Could not find texture to fit, create one.
int texsize = MAX(p_data->size.x * p_data->oversampling * 8, 256);
#ifdef GDEXTENSION
texsize = Math::next_power_of_2(texsize);
#else
texsize = next_power_of_2(texsize);
#endif
if (p_msdf) {
texsize = MIN(texsize, 2048);
} else {
texsize = MIN(texsize, 1024);
}
if (mw > texsize) { // Special case, adapt to it?
#ifdef GDEXTENSION
texsize = Math::next_power_of_2(mw);
#else
texsize = next_power_of_2(mw);
#endif
}
if (mh > texsize) { // Special case, adapt to it?
#ifdef GDEXTENSION
texsize = Math::next_power_of_2(mh);
#else
texsize = next_power_of_2(mh);
#endif
}
ShelfPackTexture tex = ShelfPackTexture(texsize, texsize);
@ -949,14 +929,14 @@ static int ft_cubic_to(const FT_Vector *control1, const FT_Vector *control2, con
return 0;
}
void TextServerAdvanced::_generateMTSDF_threaded(uint32_t y, void *p_td) const {
void TextServerAdvanced::_generateMTSDF_threaded(void *p_td, uint32_t p_y) {
MSDFThreadData *td = static_cast<MSDFThreadData *>(p_td);
msdfgen::ShapeDistanceFinder<msdfgen::OverlappingContourCombiner<msdfgen::MultiAndTrueDistanceSelector>> distanceFinder(*td->shape);
int row = td->shape->inverseYAxis ? td->output->height() - y - 1 : y;
int row = td->shape->inverseYAxis ? td->output->height() - p_y - 1 : p_y;
for (int col = 0; col < td->output->width(); ++col) {
int x = (y % 2) ? td->output->width() - col - 1 : col;
msdfgen::Point2 p = td->projection->unproject(msdfgen::Point2(x + .5, y + .5));
int x = (p_y % 2) ? td->output->width() - col - 1 : col;
msdfgen::Point2 p = td->projection->unproject(msdfgen::Point2(x + .5, p_y + .5));
msdfgen::MultiAndTrueDistance distance = distanceFinder.distance(p);
td->distancePixelConversion->operator()(td->output->operator()(x, row), distance);
}
@ -1026,14 +1006,8 @@ _FORCE_INLINE_ TextServerAdvanced::FontGlyph TextServerAdvanced::rasterize_msdf(
td.projection = &projection;
td.distancePixelConversion = &distancePixelConversion;
#ifdef GDEXTENSION
for (int i = 0; i < h; i++) {
_generateMTSDF_threaded(i, &td);
}
#else
WorkerThreadPool::GroupID group_task = WorkerThreadPool::get_singleton()->add_template_group_task(this, &TextServerAdvanced::_generateMTSDF_threaded, &td, h, -1, true, SNAME("FontServerRasterizeMSDF"));
WorkerThreadPool::GroupID group_task = WorkerThreadPool::get_singleton()->add_native_group_task(&TextServerAdvanced::_generateMTSDF_threaded, &td, h, -1, true, String("FontServerRasterizeMSDF"));
WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group_task);
#endif
msdfgen::msdfErrorCorrection(image, shape, projection, p_pixel_range, config);

View file

@ -72,7 +72,6 @@
#include <godot_cpp/templates/hash_map.hpp>
#include <godot_cpp/templates/hash_set.hpp>
#include <godot_cpp/templates/rid_owner.hpp>
#include <godot_cpp/templates/vector.hpp>
using namespace godot;
@ -350,7 +349,7 @@ class TextServerAdvanced : public TextServerExtension {
_FORCE_INLINE_ bool _ensure_glyph(FontAdvanced *p_font_data, const Vector2i &p_size, int32_t p_glyph) const;
_FORCE_INLINE_ bool _ensure_cache_for_size(FontAdvanced *p_font_data, const Vector2i &p_size) const;
_FORCE_INLINE_ void _font_clear_cache(FontAdvanced *p_font_data);
void _generateMTSDF_threaded(uint32_t y, void *p_td) const;
static void _generateMTSDF_threaded(void *p_td, uint32_t p_y);
_FORCE_INLINE_ Vector2i _get_size(const FontAdvanced *p_font_data, int p_size) const {
if (p_font_data->msdf) {

View file

@ -88,24 +88,13 @@ FT_Error tvg_svg_in_ot_preset_slot(FT_GlyphSlot p_slot, FT_Bool p_cache, FT_Poin
if (!gl_state.ready) {
Ref<XMLParser> parser;
parser.instantiate();
#ifdef GDEXTENSION
PackedByteArray data;
data.resize(document->svg_document_length);
memcpy(data.ptrw(), document->svg_document, document->svg_document_length);
parser->open_buffer(data);
#else
parser->_open_buffer((const uint8_t *)document->svg_document, document->svg_document_length);
#endif
float aspect = 1.0f;
String xml_body;
while (parser->read() == OK) {
if (parser->has_attribute("id")) {
#ifdef GDEXTENSION
const String &gl_name = parser->get_named_attribute_value("id");
#else
const String &gl_name = parser->get_attribute_value("id");
#endif
if (gl_name.begins_with("glyph")) {
int dot_pos = gl_name.find(".");
int64_t gl_idx = gl_name.substr(5, (dot_pos > 0) ? dot_pos - 5 : -1).to_int();
@ -117,11 +106,7 @@ FT_Error tvg_svg_in_ot_preset_slot(FT_GlyphSlot p_slot, FT_Bool p_cache, FT_Poin
}
if (parser->get_node_type() == XMLParser::NODE_ELEMENT && parser->get_node_name() == "svg") {
if (parser->has_attribute("viewBox")) {
#ifdef GDEXTENSION
PackedStringArray vb = parser->get_named_attribute_value("viewBox").split(" ");
#else
Vector<String> vb = parser->get_attribute_value("viewBox").split(" ");
#endif
if (vb.size() == 4) {
aspect = vb[2].to_float() / vb[3].to_float();
@ -129,19 +114,6 @@ FT_Error tvg_svg_in_ot_preset_slot(FT_GlyphSlot p_slot, FT_Bool p_cache, FT_Poin
}
continue;
}
#ifdef GDEXTENSION
if (parser->get_node_type() == XMLParser::NODE_ELEMENT) {
xml_body = xml_body + "<" + parser->get_node_name();
for (int i = 0; i < parser->get_attribute_count(); i++) {
xml_body = xml_body + " " + parser->get_attribute_name(i) + "=\"" + parser->get_attribute_value(i) + "\"";
}
xml_body = xml_body + ">";
} else if (parser->get_node_type() == XMLParser::NODE_TEXT) {
xml_body = xml_body + parser->get_node_data();
} else if (parser->get_node_type() == XMLParser::NODE_ELEMENT_END) {
xml_body = xml_body + "</" + parser->get_node_name() + ">";
}
#else
if (parser->get_node_type() == XMLParser::NODE_ELEMENT) {
xml_body += vformat("<%s", parser->get_node_name());
for (int i = 0; i < parser->get_attribute_count(); i++) {
@ -153,7 +125,6 @@ FT_Error tvg_svg_in_ot_preset_slot(FT_GlyphSlot p_slot, FT_Bool p_cache, FT_Poin
} else if (parser->get_node_type() == XMLParser::NODE_ELEMENT_END) {
xml_body += vformat("</%s>", parser->get_node_name());
}
#endif
}
String temp_xml = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 0 0\">" + xml_body;
@ -175,11 +146,7 @@ FT_Error tvg_svg_in_ot_preset_slot(FT_GlyphSlot p_slot, FT_Bool p_cache, FT_Poin
new_h = (new_w / aspect);
}
#ifdef GDEXTENSION
gl_state.xml_code = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"" + rtos(min_x) + " " + rtos(min_y) + " " + rtos(new_w) + " " + rtos(new_h) + "\">" + xml_body;
#else
gl_state.xml_code = vformat("<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"%f %f %f %f\">", min_x, min_y, new_w, new_h) + xml_body;
#endif
picture = tvg::Picture::gen();
result = picture->load(gl_state.xml_code.utf8().get_data(), gl_state.xml_code.utf8().length(), "svg+xml", false);

View file

@ -248,11 +248,7 @@ _FORCE_INLINE_ TextServerFallback::FontTexturePosition TextServerFallback::find_
// Could not find texture to fit, create one.
int texsize = MAX(p_data->size.x * p_data->oversampling * 8, 256);
#ifdef GDEXTENSION
texsize = Math::next_power_of_2(texsize);
#else
texsize = next_power_of_2(texsize);
#endif
if (p_msdf) {
texsize = MIN(texsize, 2048);
@ -260,18 +256,10 @@ _FORCE_INLINE_ TextServerFallback::FontTexturePosition TextServerFallback::find_
texsize = MIN(texsize, 1024);
}
if (mw > texsize) { // Special case, adapt to it?
#ifdef GDEXTENSION
texsize = Math::next_power_of_2(mw);
#else
texsize = next_power_of_2(mw);
#endif
}
if (mh > texsize) { // Special case, adapt to it?
#ifdef GDEXTENSION
texsize = Math::next_power_of_2(mh);
#else
texsize = next_power_of_2(mh);
#endif
}
ShelfPackTexture tex = ShelfPackTexture(texsize, texsize);
@ -374,14 +362,14 @@ static int ft_cubic_to(const FT_Vector *control1, const FT_Vector *control2, con
return 0;
}
void TextServerFallback::_generateMTSDF_threaded(uint32_t y, void *p_td) const {
void TextServerFallback::_generateMTSDF_threaded(void *p_td, uint32_t p_y) {
MSDFThreadData *td = static_cast<MSDFThreadData *>(p_td);
msdfgen::ShapeDistanceFinder<msdfgen::OverlappingContourCombiner<msdfgen::MultiAndTrueDistanceSelector>> distanceFinder(*td->shape);
int row = td->shape->inverseYAxis ? td->output->height() - y - 1 : y;
int row = td->shape->inverseYAxis ? td->output->height() - p_y - 1 : p_y;
for (int col = 0; col < td->output->width(); ++col) {
int x = (y % 2) ? td->output->width() - col - 1 : col;
msdfgen::Point2 p = td->projection->unproject(msdfgen::Point2(x + .5, y + .5));
int x = (p_y % 2) ? td->output->width() - col - 1 : col;
msdfgen::Point2 p = td->projection->unproject(msdfgen::Point2(x + .5, p_y + .5));
msdfgen::MultiAndTrueDistance distance = distanceFinder.distance(p);
td->distancePixelConversion->operator()(td->output->operator()(x, row), distance);
}
@ -451,14 +439,8 @@ _FORCE_INLINE_ TextServerFallback::FontGlyph TextServerFallback::rasterize_msdf(
td.projection = &projection;
td.distancePixelConversion = &distancePixelConversion;
#ifdef GDEXTENSION
for (int i = 0; i < h; i++) {
_generateMTSDF_threaded(i, &td);
}
#else
WorkerThreadPool::GroupID group_id = WorkerThreadPool::get_singleton()->add_template_group_task(this, &TextServerFallback::_generateMTSDF_threaded, &td, h, -1, true, SNAME("TextServerFBRenderMSDF"));
WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group_id);
#endif
WorkerThreadPool::GroupID group_task = WorkerThreadPool::get_singleton()->add_native_group_task(&TextServerFallback::_generateMTSDF_threaded, &td, h, -1, true, String("TextServerFBRenderMSDF"));
WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group_task);
msdfgen::msdfErrorCorrection(image, shape, projection, p_pixel_range, config);

View file

@ -67,11 +67,11 @@
#include <godot_cpp/classes/image.hpp>
#include <godot_cpp/classes/image_texture.hpp>
#include <godot_cpp/classes/ref.hpp>
#include <godot_cpp/classes/worker_thread_pool.hpp>
#include <godot_cpp/templates/hash_map.hpp>
#include <godot_cpp/templates/hash_set.hpp>
#include <godot_cpp/templates/rid_owner.hpp>
#include <godot_cpp/templates/thread_work_pool.hpp>
#include <godot_cpp/templates/vector.hpp>
using namespace godot;
@ -303,7 +303,7 @@ class TextServerFallback : public TextServerExtension {
_FORCE_INLINE_ bool _ensure_glyph(FontFallback *p_font_data, const Vector2i &p_size, int32_t p_glyph) const;
_FORCE_INLINE_ bool _ensure_cache_for_size(FontFallback *p_font_data, const Vector2i &p_size) const;
_FORCE_INLINE_ void _font_clear_cache(FontFallback *p_font_data);
void _generateMTSDF_threaded(uint32_t y, void *p_td) const;
static void _generateMTSDF_threaded(void *p_td, uint32_t p_y);
_FORCE_INLINE_ Vector2i _get_size(const FontFallback *p_font_data, int p_size) const {
if (p_font_data->msdf) {

View file

@ -88,24 +88,13 @@ FT_Error tvg_svg_in_ot_preset_slot(FT_GlyphSlot p_slot, FT_Bool p_cache, FT_Poin
if (!gl_state.ready) {
Ref<XMLParser> parser;
parser.instantiate();
#ifdef GDEXTENSION
PackedByteArray data;
data.resize(document->svg_document_length);
memcpy(data.ptrw(), document->svg_document, document->svg_document_length);
parser->open_buffer(data);
#else
parser->_open_buffer((const uint8_t *)document->svg_document, document->svg_document_length);
#endif
float aspect = 1.0f;
String xml_body;
while (parser->read() == OK) {
if (parser->has_attribute("id")) {
#ifdef GDEXTENSION
const String &gl_name = parser->get_named_attribute_value("id");
#else
const String &gl_name = parser->get_attribute_value("id");
#endif
if (gl_name.begins_with("glyph")) {
int dot_pos = gl_name.find(".");
int64_t gl_idx = gl_name.substr(5, (dot_pos > 0) ? dot_pos - 5 : -1).to_int();
@ -117,11 +106,7 @@ FT_Error tvg_svg_in_ot_preset_slot(FT_GlyphSlot p_slot, FT_Bool p_cache, FT_Poin
}
if (parser->get_node_type() == XMLParser::NODE_ELEMENT && parser->get_node_name() == "svg") {
if (parser->has_attribute("viewBox")) {
#ifdef GDEXTENSION
PackedStringArray vb = parser->get_named_attribute_value("viewBox").split(" ");
#else
Vector<String> vb = parser->get_attribute_value("viewBox").split(" ");
#endif
if (vb.size() == 4) {
aspect = vb[2].to_float() / vb[3].to_float();
@ -129,19 +114,6 @@ FT_Error tvg_svg_in_ot_preset_slot(FT_GlyphSlot p_slot, FT_Bool p_cache, FT_Poin
}
continue;
}
#ifdef GDEXTENSION
if (parser->get_node_type() == XMLParser::NODE_ELEMENT) {
xml_body = xml_body + "<" + parser->get_node_name();
for (int i = 0; i < parser->get_attribute_count(); i++) {
xml_body = xml_body + " " + parser->get_attribute_name(i) + "=\"" + parser->get_attribute_value(i) + "\"";
}
xml_body = xml_body + ">";
} else if (parser->get_node_type() == XMLParser::NODE_TEXT) {
xml_body = xml_body + parser->get_node_data();
} else if (parser->get_node_type() == XMLParser::NODE_ELEMENT_END) {
xml_body = xml_body + "</" + parser->get_node_name() + ">";
}
#else
if (parser->get_node_type() == XMLParser::NODE_ELEMENT) {
xml_body += vformat("<%s", parser->get_node_name());
for (int i = 0; i < parser->get_attribute_count(); i++) {
@ -153,7 +125,6 @@ FT_Error tvg_svg_in_ot_preset_slot(FT_GlyphSlot p_slot, FT_Bool p_cache, FT_Poin
} else if (parser->get_node_type() == XMLParser::NODE_ELEMENT_END) {
xml_body += vformat("</%s>", parser->get_node_name());
}
#endif
}
String temp_xml = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 0 0\">" + xml_body;
@ -175,11 +146,7 @@ FT_Error tvg_svg_in_ot_preset_slot(FT_GlyphSlot p_slot, FT_Bool p_cache, FT_Poin
new_h = (new_w / aspect);
}
#ifdef GDEXTENSION
gl_state.xml_code = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"" + rtos(min_x) + " " + rtos(min_y) + " " + rtos(new_w) + " " + rtos(new_h) + "\">" + xml_body;
#else
gl_state.xml_code = vformat("<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"%f %f %f %f\">", min_x, min_y, new_w, new_h) + xml_body;
#endif
picture = tvg::Picture::gen();
result = picture->load(gl_state.xml_code.utf8().get_data(), gl_state.xml_code.utf8().length(), "svg+xml", false);

View file

@ -355,20 +355,20 @@ void OS_Android::_load_system_font_config() {
if (parser->get_node_type() == XMLParser::NODE_ELEMENT) {
in_font_node = false;
if (parser->get_node_name() == "familyset") {
int ver = parser->has_attribute("version") ? parser->get_attribute_value("version").to_int() : 0;
int ver = parser->has_attribute("version") ? parser->get_named_attribute_value("version").to_int() : 0;
if (ver < 21) {
ERR_PRINT(vformat("Unsupported font config version %s", ver));
break;
}
} else if (parser->get_node_name() == "alias") {
String name = parser->has_attribute("name") ? parser->get_attribute_value("name").strip_edges() : String();
String to = parser->has_attribute("to") ? parser->get_attribute_value("to").strip_edges() : String();
String name = parser->has_attribute("name") ? parser->get_named_attribute_value("name").strip_edges() : String();
String to = parser->has_attribute("to") ? parser->get_named_attribute_value("to").strip_edges() : String();
if (!name.is_empty() && !to.is_empty()) {
font_aliases[name] = to;
}
} else if (parser->get_node_name() == "family") {
fn = parser->has_attribute("name") ? parser->get_attribute_value("name").strip_edges() : String();
String lang_code = parser->has_attribute("lang") ? parser->get_attribute_value("lang").strip_edges() : String();
fn = parser->has_attribute("name") ? parser->get_named_attribute_value("name").strip_edges() : String();
String lang_code = parser->has_attribute("lang") ? parser->get_named_attribute_value("lang").strip_edges() : String();
Vector<String> lang_codes = lang_code.split(",");
for (int i = 0; i < lang_codes.size(); i++) {
Vector<String> lang_code_elements = lang_codes[i].split("-");
@ -412,9 +412,9 @@ void OS_Android::_load_system_font_config() {
}
} else if (parser->get_node_name() == "font") {
in_font_node = true;
fb = parser->has_attribute("fallbackFor") ? parser->get_attribute_value("fallbackFor").strip_edges() : String();
fi.weight = parser->has_attribute("weight") ? parser->get_attribute_value("weight").to_int() : 400;
fi.italic = parser->has_attribute("style") && parser->get_attribute_value("style").strip_edges() == "italic";
fb = parser->has_attribute("fallbackFor") ? parser->get_named_attribute_value("fallbackFor").strip_edges() : String();
fi.weight = parser->has_attribute("weight") ? parser->get_named_attribute_value("weight").to_int() : 400;
fi.italic = parser->has_attribute("style") && parser->get_named_attribute_value("style").strip_edges() == "italic";
}
}
if (parser->get_node_type() == XMLParser::NODE_TEXT) {

View file

@ -54,7 +54,7 @@ TEST_CASE("[XMLParser] End-to-end") {
CHECK(parser.get_node_type() == XMLParser::NodeType::NODE_ELEMENT);
CHECK(parser.get_node_name() == "top");
CHECK(parser.has_attribute("attr"));
CHECK(parser.get_attribute_value("attr") == "attr value");
CHECK(parser.get_named_attribute_value("attr") == "attr value");
CHECK(parser.read() == OK);
CHECK(parser.get_node_type() == XMLParser::NodeType::NODE_TEXT);