Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Export] Respect icon/splash screen import settings. #102109

Merged
merged 1 commit into from
Jan 31, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions editor/export/editor_export_platform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include "core/extension/gdextension.h"
#include "core/io/file_access_encrypted.h"
#include "core/io/file_access_pack.h" // PACK_HEADER_MAGIC, PACK_FORMAT_VERSION
#include "core/io/image_loader.h"
#include "core/io/resource_uid.h"
#include "core/io/zip_io.h"
#include "core/version.h"
Expand Down Expand Up @@ -82,6 +83,28 @@ static int _get_pad(int p_alignment, int p_n) {

#define PCK_PADDING 16

Ref<Image> EditorExportPlatform::_load_icon_or_splash_image(const String &p_path, Error *r_error) const {
Ref<Image> image;

if (!p_path.is_empty() && ResourceLoader::exists(p_path) && !ResourceLoader::get_resource_type(p_path).is_empty()) {
Ref<Texture2D> texture = ResourceLoader::load(p_path, "", ResourceFormatLoader::CACHE_MODE_REUSE, r_error);
if (texture.is_valid()) {
image = texture->get_image();
if (image.is_valid() && image->is_compressed()) {
image->decompress();
}
}
}
if (image.is_null()) {
image.instantiate();
Error err = ImageLoader::load_image(p_path, image);
if (r_error) {
*r_error = err;
}
}
return image;
}

bool EditorExportPlatform::fill_log_messages(RichTextLabel *p_log, Error p_err) {
bool has_messages = false;

Expand Down
2 changes: 2 additions & 0 deletions editor/export/editor_export_platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,8 @@ class EditorExportPlatform : public RefCounted {
Error _load_patches(const Vector<String> &p_patches);
void _unload_patches();

Ref<Image> _load_icon_or_splash_image(const String &p_path, Error *r_error) const;

public:
virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) const = 0;

Expand Down
21 changes: 12 additions & 9 deletions platform/android/export/export_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1723,18 +1723,18 @@ void EditorExportPlatformAndroid::_process_launcher_icons(const String &p_file_n
void EditorExportPlatformAndroid::load_icon_refs(const Ref<EditorExportPreset> &p_preset, Ref<Image> &icon, Ref<Image> &foreground, Ref<Image> &background, Ref<Image> &monochrome) {
String project_icon_path = GLOBAL_GET("application/config/icon");

icon.instantiate();
foreground.instantiate();
background.instantiate();
monochrome.instantiate();
Error err = OK;

// Regular icon: user selection -> project icon -> default.
String path = static_cast<String>(p_preset->get(LAUNCHER_ICON_OPTION)).strip_edges();
print_verbose("Loading regular icon from " + path);
if (path.is_empty() || ImageLoader::load_image(path, icon) != OK) {
if (!path.is_empty()) {
icon = _load_icon_or_splash_image(path, &err);
}
if (path.is_empty() || err != OK || icon.is_null() || icon->is_empty()) {
print_verbose("- falling back to project icon: " + project_icon_path);
if (!project_icon_path.is_empty()) {
ImageLoader::load_image(project_icon_path, icon);
icon = _load_icon_or_splash_image(project_icon_path, &err);
} else {
ERR_PRINT("No project icon specified. Please specify one in the Project Settings under Application -> Config -> Icon");
}
Expand All @@ -1743,7 +1743,10 @@ void EditorExportPlatformAndroid::load_icon_refs(const Ref<EditorExportPreset> &
// 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();
print_verbose("Loading adaptive foreground icon from " + path);
if (path.is_empty() || ImageLoader::load_image(path, foreground) != OK) {
if (!path.is_empty()) {
foreground = _load_icon_or_splash_image(path, &err);
}
if (path.is_empty() || err != OK || foreground.is_null() || foreground->is_empty()) {
print_verbose("- falling back to using the regular icon");
foreground = icon;
}
Expand All @@ -1752,14 +1755,14 @@ void EditorExportPlatformAndroid::load_icon_refs(const Ref<EditorExportPreset> &
path = static_cast<String>(p_preset->get(LAUNCHER_ADAPTIVE_ICON_BACKGROUND_OPTION)).strip_edges();
if (!path.is_empty()) {
print_verbose("Loading adaptive background icon from " + path);
ImageLoader::load_image(path, background);
background = _load_icon_or_splash_image(path, &err);
}

// Adaptive monochrome: user selection -> default.
path = static_cast<String>(p_preset->get(LAUNCHER_ADAPTIVE_ICON_MONOCHROME_OPTION)).strip_edges();
if (!path.is_empty()) {
print_verbose("Loading adaptive monochrome icon from " + path);
ImageLoader::load_image(path, monochrome);
monochrome = _load_icon_or_splash_image(path, &err);
}
}

Expand Down
36 changes: 14 additions & 22 deletions platform/ios/export/export_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -982,9 +982,9 @@ Error EditorExportPlatformIOS::_export_icons(const Ref<EditorExportPreset> &p_pr
}
// Resize main app icon.
icon_path = GLOBAL_GET("application/config/icon");
Ref<Image> img = memnew(Image);
Error err = ImageLoader::load_image(icon_path, img);
if (err != OK) {
Error err = OK;
Ref<Image> img = _load_icon_or_splash_image(icon_path, &err);
if (err != OK || img.is_null() || img->is_empty()) {
add_message(EXPORT_MESSAGE_ERROR, TTR("Export Icons"), vformat("Invalid icon (%s): '%s'.", info.preset_key, icon_path));
return ERR_UNCONFIGURED;
} else if (info.force_opaque && img->detect_alpha() != Image::ALPHA_NONE) {
Expand All @@ -1003,9 +1003,9 @@ Error EditorExportPlatformIOS::_export_icons(const Ref<EditorExportPreset> &p_pr
}
} else {
// Load custom icon and resize if required.
Ref<Image> img = memnew(Image);
Error err = ImageLoader::load_image(icon_path, img);
if (err != OK) {
Error err = OK;
Ref<Image> img = _load_icon_or_splash_image(icon_path, &err);
if (err != OK || img.is_null() || img->is_empty()) {
add_message(EXPORT_MESSAGE_ERROR, TTR("Export Icons"), vformat("Invalid icon (%s): '%s'.", info.preset_key, icon_path));
return ERR_UNCONFIGURED;
} else if (info.force_opaque && img->detect_alpha() != Image::ALPHA_NONE) {
Expand Down Expand Up @@ -1089,47 +1089,39 @@ Error EditorExportPlatformIOS::_export_loading_screen_file(const Ref<EditorExpor
const String custom_launch_image_3x = p_preset->get("storyboard/custom_image@3x");

if (custom_launch_image_2x.length() > 0 && custom_launch_image_3x.length() > 0) {
Ref<Image> image;
String image_path = p_dest_dir.path_join("splash@2x.png");
image.instantiate();
Error err = ImageLoader::load_image(custom_launch_image_2x, image);
Error err = OK;
Ref<Image> image = _load_icon_or_splash_image(custom_launch_image_2x, &err);

if (err) {
image.unref();
if (err != OK || image.is_null() || image->is_empty()) {
return err;
}

if (image->save_png(image_path) != OK) {
return ERR_FILE_CANT_WRITE;
}

image.unref();
image_path = p_dest_dir.path_join("splash@3x.png");
image.instantiate();
err = ImageLoader::load_image(custom_launch_image_3x, image);
image = _load_icon_or_splash_image(custom_launch_image_3x, &err);

if (err) {
image.unref();
if (err != OK || image.is_null() || image->is_empty()) {
return err;
}

if (image->save_png(image_path) != OK) {
return ERR_FILE_CANT_WRITE;
}
} else {
Error err = OK;
Ref<Image> splash;

const String splash_path = GLOBAL_GET("application/boot_splash/image");

if (!splash_path.is_empty()) {
splash.instantiate();
const Error err = ImageLoader::load_image(splash_path, splash);
if (err) {
splash.unref();
}
splash = _load_icon_or_splash_image(splash_path, &err);
}

if (splash.is_null()) {
if (err != OK || splash.is_null() || splash->is_empty()) {
splash.instantiate(boot_splash_png);
}

Expand Down
6 changes: 2 additions & 4 deletions platform/macos/export/export_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1883,10 +1883,8 @@ Error EditorExportPlatformMacOS::export_project(const Ref<EditorExportPreset> &p
icon->get_buffer(&data.write[0], icon->get_length());
}
} else {
Ref<Image> icon;
icon.instantiate();
err = ImageLoader::load_image(icon_path, icon);
if (err == OK && !icon->is_empty()) {
Ref<Image> icon = _load_icon_or_splash_image(icon_path, &err);
if (err == OK && icon.is_valid() && !icon->is_empty()) {
_make_icon(p_preset, icon, data);
}
}
Expand Down
6 changes: 3 additions & 3 deletions platform/web/export/export_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -192,9 +192,9 @@ Error EditorExportPlatformWeb::_add_manifest_icon(const String &p_path, const St

Ref<Image> icon;
if (!p_icon.is_empty()) {
icon.instantiate();
const Error err = ImageLoader::load_image(p_icon, icon);
if (err != OK) {
Error err = OK;
icon = _load_icon_or_splash_image(p_icon, &err);
if (err != OK || icon.is_null() || icon->is_empty()) {
add_message(EXPORT_MESSAGE_ERROR, TTR("Icon Creation"), vformat(TTR("Could not read file: \"%s\"."), p_icon));
return err;
}
Expand Down
12 changes: 10 additions & 2 deletions platform/web/export/export_plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,20 +77,28 @@ class EditorExportPlatformWeb : public EditorExportPlatform {
}

Ref<Image> _get_project_icon() const {
Error err = OK;
Ref<Image> icon;
icon.instantiate();
const String icon_path = String(GLOBAL_GET("application/config/icon")).strip_edges();
if (icon_path.is_empty() || ImageLoader::load_image(icon_path, icon) != OK) {
if (!icon_path.is_empty()) {
icon = _load_icon_or_splash_image(icon_path, &err);
}
if (icon_path.is_empty() || err != OK || icon.is_null() || icon->is_empty()) {
return EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("DefaultProjectIcon"), EditorStringName(EditorIcons))->get_image();
}
return icon;
}

Ref<Image> _get_project_splash() const {
Error err = OK;
Ref<Image> splash;
splash.instantiate();
const String splash_path = String(GLOBAL_GET("application/boot_splash/image")).strip_edges();
if (splash_path.is_empty() || ImageLoader::load_image(splash_path, splash) != OK) {
if (!splash_path.is_empty()) {
splash = _load_icon_or_splash_image(splash_path, &err);
}
if (splash_path.is_empty() || err != OK || splash.is_null() || splash->is_empty()) {
return Ref<Image>(memnew(Image(boot_splash_png)));
}
return splash;
Expand Down
7 changes: 3 additions & 4 deletions platform/windows/export/export_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,9 @@ Error EditorExportPlatformWindows::_process_icon(const Ref<EditorExportPreset> &
f->seek(prev_offset);
}
} else {
Ref<Image> src_image;
src_image.instantiate();
err = ImageLoader::load_image(p_src_path, src_image);
ERR_FAIL_COND_V(err != OK || src_image->is_empty(), ERR_CANT_OPEN);
Ref<Image> src_image = _load_icon_or_splash_image(p_src_path, &err);
ERR_FAIL_COND_V(err != OK || src_image.is_null() || src_image->is_empty(), ERR_CANT_OPEN);

for (size_t i = 0; i < sizeof(icon_size) / sizeof(icon_size[0]); ++i) {
int size = (icon_size[i] == 0) ? 256 : icon_size[i];

Expand Down