|
@@ -1443,23 +1443,81 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
|
|
|
//printf("end\n");
|
|
|
}
|
|
|
|
|
|
- void _process_launcher_icons(const String &p_processing_file_name, const Ref<Image> &p_source_image, const LauncherIcon p_icon, Vector<uint8_t> &p_data) {
|
|
|
- if (p_processing_file_name == p_icon.export_path) {
|
|
|
- Ref<Image> working_image = p_source_image;
|
|
|
+ void _process_launcher_icons(const String &p_file_name, const Ref<Image> &p_source_image, int dimension, Vector<uint8_t> &p_data) {
|
|
|
+ Ref<Image> working_image = p_source_image;
|
|
|
|
|
|
- if (p_source_image->get_width() != p_icon.dimensions || p_source_image->get_height() != p_icon.dimensions) {
|
|
|
- working_image = p_source_image->duplicate();
|
|
|
- working_image->resize(p_icon.dimensions, p_icon.dimensions, Image::Interpolation::INTERPOLATE_LANCZOS);
|
|
|
+ if (p_source_image->get_width() != dimension || p_source_image->get_height() != dimension) {
|
|
|
+ working_image = p_source_image->duplicate();
|
|
|
+ working_image->resize(dimension, dimension, Image::Interpolation::INTERPOLATE_LANCZOS);
|
|
|
+ }
|
|
|
+
|
|
|
+ PoolVector<uint8_t> png_buffer;
|
|
|
+ Error err = PNGDriverCommon::image_to_png(working_image, png_buffer);
|
|
|
+ if (err == OK) {
|
|
|
+ p_data.resize(png_buffer.size());
|
|
|
+ memcpy(p_data.ptrw(), png_buffer.read().ptr(), p_data.size());
|
|
|
+ } else {
|
|
|
+ String err_str = String("Failed to convert resized icon (") + p_file_name + ") to png.";
|
|
|
+ WARN_PRINT(err_str.utf8().get_data());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ void load_icon_refs(const Ref<EditorExportPreset> &p_preset, Ref<Image> &icon, Ref<Image> &foreground, Ref<Image> &background) {
|
|
|
+ String project_icon_path = ProjectSettings::get_singleton()->get("application/config/icon");
|
|
|
+
|
|
|
+ icon.instance();
|
|
|
+ foreground.instance();
|
|
|
+ background.instance();
|
|
|
+
|
|
|
+ // Regular icon: user selection -> project icon -> default.
|
|
|
+ String path = static_cast<String>(p_preset->get(launcher_icon_option)).strip_edges();
|
|
|
+ if (path.empty() || ImageLoader::load_image(path, icon) != OK) {
|
|
|
+ ImageLoader::load_image(project_icon_path, icon);
|
|
|
+ }
|
|
|
+
|
|
|
+ // Adaptive foreground: user selection -> regular icon (user selection -> project icon -> default).
|
|
|
+ path = static_cast<String>(p_preset->get(launcher_adaptive_icon_foreground_option)).strip_edges();
|
|
|
+ if (path.empty() || ImageLoader::load_image(path, foreground) != OK) {
|
|
|
+ foreground = icon;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Adaptive background: user selection -> default.
|
|
|
+ path = static_cast<String>(p_preset->get(launcher_adaptive_icon_background_option)).strip_edges();
|
|
|
+ if (!path.empty()) {
|
|
|
+ ImageLoader::load_image(path, background);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ void store_image(const LauncherIcon launcher_icon, const Vector<uint8_t> &data) {
|
|
|
+ String img_path = launcher_icon.export_path;
|
|
|
+ img_path = img_path.insert(0, "res://android/build/");
|
|
|
+ store_file_at_path(img_path, data);
|
|
|
+ }
|
|
|
+
|
|
|
+ void _copy_icons_to_gradle_project(const Ref<EditorExportPreset> &p_preset, const Ref<Image> &main_image,
|
|
|
+ const Ref<Image> &foreground, const Ref<Image> &background) {
|
|
|
+ // Prepare images to be resized for the icons. If some image ends up being uninitialized,
|
|
|
+ // the default image from the export template will be used.
|
|
|
+
|
|
|
+ for (int i = 0; i < icon_densities_count; ++i) {
|
|
|
+ if (main_image.is_valid() && !main_image->empty()) {
|
|
|
+ Vector<uint8_t> data;
|
|
|
+ _process_launcher_icons(launcher_icons[i].export_path, main_image, launcher_icons[i].dimensions, data);
|
|
|
+ store_image(launcher_icons[i], data);
|
|
|
}
|
|
|
|
|
|
- PoolVector<uint8_t> png_buffer;
|
|
|
- Error err = PNGDriverCommon::image_to_png(working_image, png_buffer);
|
|
|
- if (err == OK) {
|
|
|
- p_data.resize(png_buffer.size());
|
|
|
- memcpy(p_data.ptrw(), png_buffer.read().ptr(), p_data.size());
|
|
|
- } else {
|
|
|
- String err_str = String("Failed to convert resized icon (") + p_processing_file_name + ") to png.";
|
|
|
- WARN_PRINT(err_str.utf8().get_data());
|
|
|
+ if (foreground.is_valid() && !foreground->empty()) {
|
|
|
+ Vector<uint8_t> data;
|
|
|
+ _process_launcher_icons(launcher_adaptive_icon_foregrounds[i].export_path, foreground,
|
|
|
+ launcher_adaptive_icon_foregrounds[i].dimensions, data);
|
|
|
+ store_image(launcher_adaptive_icon_foregrounds[i], data);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (background.is_valid() && !background->empty()) {
|
|
|
+ Vector<uint8_t> data;
|
|
|
+ _process_launcher_icons(launcher_adaptive_icon_backgrounds[i].export_path, background,
|
|
|
+ launcher_adaptive_icon_backgrounds[i].dimensions, data);
|
|
|
+ store_image(launcher_adaptive_icon_backgrounds[i], data);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -2366,6 +2424,12 @@ public:
|
|
|
|
|
|
bool use_custom_build = bool(p_preset->get("custom_template/use_custom_build"));
|
|
|
|
|
|
+ Ref<Image> main_image;
|
|
|
+ Ref<Image> foreground;
|
|
|
+ Ref<Image> background;
|
|
|
+
|
|
|
+ load_icon_refs(p_preset, main_image, foreground, background);
|
|
|
+
|
|
|
if (use_custom_build) {
|
|
|
//re-generate build.gradle and AndroidManifest.xml
|
|
|
{ //test that installed build version is alright
|
|
@@ -2388,6 +2452,9 @@ public:
|
|
|
if (err != OK) {
|
|
|
EditorNode::add_io_error("Unable to overwrite res://android/build/res/*.xml files with project name");
|
|
|
}
|
|
|
+ // Copies the project icon files into the appropriate Gradle project directory
|
|
|
+ _copy_icons_to_gradle_project(p_preset, main_image, foreground, background);
|
|
|
+
|
|
|
//build project if custom build is enabled
|
|
|
String sdk_path = EDITOR_GET("export/android/custom_build_sdk_path");
|
|
|
|
|
@@ -2520,34 +2587,7 @@ public:
|
|
|
|
|
|
Vector<String> enabled_abis = get_enabled_abis(p_preset);
|
|
|
|
|
|
- String project_icon_path = ProjectSettings::get_singleton()->get("application/config/icon");
|
|
|
-
|
|
|
// Prepare images to be resized for the icons. If some image ends up being uninitialized, the default image from the export template will be used.
|
|
|
- Ref<Image> launcher_icon_image;
|
|
|
- Ref<Image> launcher_adaptive_icon_foreground_image;
|
|
|
- Ref<Image> launcher_adaptive_icon_background_image;
|
|
|
-
|
|
|
- launcher_icon_image.instance();
|
|
|
- launcher_adaptive_icon_foreground_image.instance();
|
|
|
- launcher_adaptive_icon_background_image.instance();
|
|
|
-
|
|
|
- // Regular icon: user selection -> project icon -> default.
|
|
|
- String path = static_cast<String>(p_preset->get(launcher_icon_option)).strip_edges();
|
|
|
- if (path.empty() || ImageLoader::load_image(path, launcher_icon_image) != OK) {
|
|
|
- ImageLoader::load_image(project_icon_path, launcher_icon_image);
|
|
|
- }
|
|
|
-
|
|
|
- // Adaptive foreground: user selection -> regular icon (user selection -> project icon -> default).
|
|
|
- path = static_cast<String>(p_preset->get(launcher_adaptive_icon_foreground_option)).strip_edges();
|
|
|
- if (path.empty() || ImageLoader::load_image(path, launcher_adaptive_icon_foreground_image) != OK) {
|
|
|
- launcher_adaptive_icon_foreground_image = launcher_icon_image;
|
|
|
- }
|
|
|
-
|
|
|
- // Adaptive background: user selection -> default.
|
|
|
- path = static_cast<String>(p_preset->get(launcher_adaptive_icon_background_option)).strip_edges();
|
|
|
- if (!path.empty()) {
|
|
|
- ImageLoader::load_image(path, launcher_adaptive_icon_background_image);
|
|
|
- }
|
|
|
|
|
|
Vector<String> invalid_abis(enabled_abis);
|
|
|
while (ret == UNZ_OK) {
|
|
@@ -2575,21 +2615,26 @@ public:
|
|
|
_fix_manifest(p_preset, data, p_flags & (DEBUG_FLAG_DUMB_CLIENT | DEBUG_FLAG_REMOTE_DEBUG));
|
|
|
}
|
|
|
|
|
|
- if (file == "resources.arsc") {
|
|
|
- if (!use_custom_build) {
|
|
|
+ if (!use_custom_build) {
|
|
|
+ if (file == "resources.arsc") {
|
|
|
_fix_resources(p_preset, data);
|
|
|
}
|
|
|
- }
|
|
|
-
|
|
|
- for (int i = 0; i < icon_densities_count; ++i) {
|
|
|
- if (launcher_icon_image.is_valid() && !launcher_icon_image->empty()) {
|
|
|
- _process_launcher_icons(file, launcher_icon_image, launcher_icons[i], data);
|
|
|
- }
|
|
|
- if (launcher_adaptive_icon_foreground_image.is_valid() && !launcher_adaptive_icon_foreground_image->empty()) {
|
|
|
- _process_launcher_icons(file, launcher_adaptive_icon_foreground_image, launcher_adaptive_icon_foregrounds[i], data);
|
|
|
- }
|
|
|
- if (launcher_adaptive_icon_background_image.is_valid() && !launcher_adaptive_icon_background_image->empty()) {
|
|
|
- _process_launcher_icons(file, launcher_adaptive_icon_background_image, launcher_adaptive_icon_backgrounds[i], data);
|
|
|
+ for (int i = 0; i < icon_densities_count; ++i) {
|
|
|
+ if (main_image.is_valid() && !main_image->empty()) {
|
|
|
+ if (file == launcher_icons[i].export_path) {
|
|
|
+ _process_launcher_icons(file, main_image, launcher_icons[i].dimensions, data);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (foreground.is_valid() && !foreground->empty()) {
|
|
|
+ if (file == launcher_adaptive_icon_foregrounds[i].export_path) {
|
|
|
+ _process_launcher_icons(file, foreground, launcher_adaptive_icon_foregrounds[i].dimensions, data);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (background.is_valid() && !background->empty()) {
|
|
|
+ if (file == launcher_adaptive_icon_backgrounds[i].export_path) {
|
|
|
+ _process_launcher_icons(file, background, launcher_adaptive_icon_backgrounds[i].dimensions, data);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|