[3.x] Windows icon export improvements.
Regenerate Windows icon on export to ensure correct icon size order. Add support for using PNG/WebP/SVG files as an icon for Windows exports. Allow using WebP/SVG files as icon for macOS exports. Add option to select generated icons interpolation, and set default interpolation to Lanczos.
This commit is contained in:
parent
0803b4168d
commit
44739a121e
3 changed files with 160 additions and 15 deletions
|
@ -373,6 +373,9 @@ void EditorExportPlatformIOS::get_export_options(List<ExportOption> *r_options)
|
||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/version"), "1.0"));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/version"), "1.0"));
|
||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/copyright"), ""));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/copyright"), ""));
|
||||||
|
|
||||||
|
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "application/icon_interpolation", PROPERTY_HINT_ENUM, "Nearest neighbor,Bilinear,Cubic,Trilinear,Lanczos"), 4));
|
||||||
|
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "application/launch_screens_interpolation", PROPERTY_HINT_ENUM, "Nearest neighbor,Bilinear,Cubic,Trilinear,Lanczos"), 4));
|
||||||
|
|
||||||
Vector<PluginConfigIOS> found_plugins = get_plugins();
|
Vector<PluginConfigIOS> found_plugins = get_plugins();
|
||||||
for (int i = 0; i < found_plugins.size(); i++) {
|
for (int i = 0; i < found_plugins.size(); i++) {
|
||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, vformat("%s/%s", PNAME("plugins"), found_plugins[i].name)), false));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, vformat("%s/%s", PNAME("plugins"), found_plugins[i].name)), false));
|
||||||
|
@ -872,7 +875,7 @@ Error EditorExportPlatformIOS::_export_icons(const Ref<EditorExportPreset> &p_pr
|
||||||
add_message(EXPORT_MESSAGE_ERROR, TTR("Export Icons"), vformat("Icon (%s) must be opaque.", info.preset_key));
|
add_message(EXPORT_MESSAGE_ERROR, TTR("Export Icons"), vformat("Icon (%s) must be opaque.", info.preset_key));
|
||||||
return ERR_UNCONFIGURED;
|
return ERR_UNCONFIGURED;
|
||||||
}
|
}
|
||||||
img->resize(side_size, side_size);
|
img->resize(side_size, side_size, (Image::Interpolation)(p_preset->get("application/icon_interpolation").operator int()));
|
||||||
err = img->save_png(p_iconset_dir + info.export_name);
|
err = img->save_png(p_iconset_dir + info.export_name);
|
||||||
if (err) {
|
if (err) {
|
||||||
memdelete(da);
|
memdelete(da);
|
||||||
|
@ -895,7 +898,7 @@ Error EditorExportPlatformIOS::_export_icons(const Ref<EditorExportPreset> &p_pr
|
||||||
}
|
}
|
||||||
if (img->get_width() != side_size || img->get_height() != side_size) {
|
if (img->get_width() != side_size || img->get_height() != side_size) {
|
||||||
add_message(EXPORT_MESSAGE_WARNING, TTR("Export Icons"), vformat("Icon (%s): '%s' has incorrect size %s and was automatically resized to %s.", info.preset_key, icon_path, img->get_size(), Vector2(side_size, side_size)));
|
add_message(EXPORT_MESSAGE_WARNING, TTR("Export Icons"), vformat("Icon (%s): '%s' has incorrect size %s and was automatically resized to %s.", info.preset_key, icon_path, img->get_size(), Vector2(side_size, side_size)));
|
||||||
img->resize(side_size, side_size);
|
img->resize(side_size, side_size, (Image::Interpolation)(p_preset->get("application/icon_interpolation").operator int()));
|
||||||
err = img->save_png(p_iconset_dir + info.export_name);
|
err = img->save_png(p_iconset_dir + info.export_name);
|
||||||
} else {
|
} else {
|
||||||
err = da->copy(icon_path, p_iconset_dir + info.export_name);
|
err = da->copy(icon_path, p_iconset_dir + info.export_name);
|
||||||
|
@ -1029,9 +1032,9 @@ Error EditorExportPlatformIOS::_export_loading_screen_images(const Ref<EditorExp
|
||||||
float aspect_ratio = (float)img->get_width() / (float)img->get_height();
|
float aspect_ratio = (float)img->get_width() / (float)img->get_height();
|
||||||
if (boot_logo_scale) {
|
if (boot_logo_scale) {
|
||||||
if (info.height * aspect_ratio <= info.width) {
|
if (info.height * aspect_ratio <= info.width) {
|
||||||
img->resize(info.height * aspect_ratio, info.height);
|
img->resize(info.height * aspect_ratio, info.height, (Image::Interpolation)(p_preset->get("application/launch_screens_interpolation").operator int()));
|
||||||
} else {
|
} else {
|
||||||
img->resize(info.width, info.width / aspect_ratio);
|
img->resize(info.width, info.width / aspect_ratio, (Image::Interpolation)(p_preset->get("application/launch_screens_interpolation").operator int()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ref<Image> new_img = memnew(Image);
|
Ref<Image> new_img = memnew(Image);
|
||||||
|
@ -1068,17 +1071,17 @@ Error EditorExportPlatformIOS::_export_loading_screen_images(const Ref<EditorExp
|
||||||
if (info.rotate) {
|
if (info.rotate) {
|
||||||
if (boot_logo_scale) {
|
if (boot_logo_scale) {
|
||||||
if (info.width * aspect_ratio <= info.height) {
|
if (info.width * aspect_ratio <= info.height) {
|
||||||
img_bs->resize(info.width * aspect_ratio, info.width);
|
img_bs->resize(info.width * aspect_ratio, info.width, (Image::Interpolation)(p_preset->get("application/launch_screens_interpolation").operator int()));
|
||||||
} else {
|
} else {
|
||||||
img_bs->resize(info.height, info.height / aspect_ratio);
|
img_bs->resize(info.height, info.height / aspect_ratio, (Image::Interpolation)(p_preset->get("application/launch_screens_interpolation").operator int()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (boot_logo_scale) {
|
if (boot_logo_scale) {
|
||||||
if (info.height * aspect_ratio <= info.width) {
|
if (info.height * aspect_ratio <= info.width) {
|
||||||
img_bs->resize(info.height * aspect_ratio, info.height);
|
img_bs->resize(info.height * aspect_ratio, info.height, (Image::Interpolation)(p_preset->get("application/launch_screens_interpolation").operator int()));
|
||||||
} else {
|
} else {
|
||||||
img_bs->resize(info.width, info.width / aspect_ratio);
|
img_bs->resize(info.width, info.width / aspect_ratio, (Image::Interpolation)(p_preset->get("application/launch_screens_interpolation").operator int()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,7 +55,7 @@ class EditorExportPlatformOSX : public EditorExportPlatform {
|
||||||
Ref<ImageTexture> logo;
|
Ref<ImageTexture> logo;
|
||||||
|
|
||||||
void _fix_plist(const Ref<EditorExportPreset> &p_preset, Vector<uint8_t> &plist, const String &p_binary);
|
void _fix_plist(const Ref<EditorExportPreset> &p_preset, Vector<uint8_t> &plist, const String &p_binary);
|
||||||
void _make_icon(const Ref<Image> &p_icon, Vector<uint8_t> &p_data);
|
void _make_icon(const Ref<EditorExportPreset> &p_preset, const Ref<Image> &p_icon, Vector<uint8_t> &p_data);
|
||||||
|
|
||||||
Error _notarize(const Ref<EditorExportPreset> &p_preset, const String &p_path);
|
Error _notarize(const Ref<EditorExportPreset> &p_preset, const String &p_path);
|
||||||
Error _code_sign(const Ref<EditorExportPreset> &p_preset, const String &p_path, const String &p_ent_path);
|
Error _code_sign(const Ref<EditorExportPreset> &p_preset, const String &p_path, const String &p_ent_path);
|
||||||
|
@ -213,7 +213,8 @@ void EditorExportPlatformOSX::get_export_options(List<ExportOption> *r_options)
|
||||||
|
|
||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/name", PROPERTY_HINT_PLACEHOLDER_TEXT, "Game Name"), ""));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/name", PROPERTY_HINT_PLACEHOLDER_TEXT, "Game Name"), ""));
|
||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/info"), "Made with Godot Engine"));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/info"), "Made with Godot Engine"));
|
||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/icon", PROPERTY_HINT_FILE, "*.png,*.icns"), ""));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/icon", PROPERTY_HINT_FILE, "*.icns,*.png,*.webp,*.svg"), ""));
|
||||||
|
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "application/icon_interpolation", PROPERTY_HINT_ENUM, "Nearest neighbor,Bilinear,Cubic,Trilinear,Lanczos"), 4));
|
||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/identifier", PROPERTY_HINT_PLACEHOLDER_TEXT, "com.example.game"), ""));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/identifier", PROPERTY_HINT_PLACEHOLDER_TEXT, "com.example.game"), ""));
|
||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/signature"), ""));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/signature"), ""));
|
||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/app_category", PROPERTY_HINT_ENUM, "Business,Developer-tools,Education,Entertainment,Finance,Games,Action-games,Adventure-games,Arcade-games,Board-games,Card-games,Casino-games,Dice-games,Educational-games,Family-games,Kids-games,Music-games,Puzzle-games,Racing-games,Role-playing-games,Simulation-games,Sports-games,Strategy-games,Trivia-games,Word-games,Graphics-design,Healthcare-fitness,Lifestyle,Medical,Music,News,Photography,Productivity,Reference,Social-networking,Sports,Travel,Utilities,Video,Weather"), "Games"));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/app_category", PROPERTY_HINT_ENUM, "Business,Developer-tools,Education,Entertainment,Finance,Games,Action-games,Adventure-games,Arcade-games,Board-games,Card-games,Casino-games,Dice-games,Educational-games,Family-games,Kids-games,Music-games,Puzzle-games,Racing-games,Role-playing-games,Simulation-games,Sports-games,Strategy-games,Trivia-games,Word-games,Graphics-design,Healthcare-fitness,Lifestyle,Medical,Music,News,Photography,Productivity,Reference,Social-networking,Sports,Travel,Utilities,Video,Weather"), "Games"));
|
||||||
|
@ -352,7 +353,7 @@ void _rgba8_to_packbits_encode(int p_ch, int p_size, PoolVector<uint8_t> &p_sour
|
||||||
memcpy(&p_dest.write[ofs], result.ptr(), res_size);
|
memcpy(&p_dest.write[ofs], result.ptr(), res_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorExportPlatformOSX::_make_icon(const Ref<Image> &p_icon, Vector<uint8_t> &p_data) {
|
void EditorExportPlatformOSX::_make_icon(const Ref<EditorExportPreset> &p_preset, const Ref<Image> &p_icon, Vector<uint8_t> &p_data) {
|
||||||
Ref<ImageTexture> it = memnew(ImageTexture);
|
Ref<ImageTexture> it = memnew(ImageTexture);
|
||||||
|
|
||||||
Vector<uint8_t> data;
|
Vector<uint8_t> data;
|
||||||
|
@ -386,7 +387,7 @@ void EditorExportPlatformOSX::_make_icon(const Ref<Image> &p_icon, Vector<uint8_
|
||||||
for (uint64_t i = 0; i < (sizeof(icon_infos) / sizeof(icon_infos[0])); ++i) {
|
for (uint64_t i = 0; i < (sizeof(icon_infos) / sizeof(icon_infos[0])); ++i) {
|
||||||
Ref<Image> copy = p_icon; // does this make sense? doesn't this just increase the reference count instead of making a copy? Do we even need a copy?
|
Ref<Image> copy = p_icon; // does this make sense? doesn't this just increase the reference count instead of making a copy? Do we even need a copy?
|
||||||
copy->convert(Image::FORMAT_RGBA8);
|
copy->convert(Image::FORMAT_RGBA8);
|
||||||
copy->resize(icon_infos[i].size, icon_infos[i].size);
|
copy->resize(icon_infos[i].size, icon_infos[i].size, (Image::Interpolation)(p_preset->get("application/icon_interpolation").operator int()));
|
||||||
|
|
||||||
if (icon_infos[i].is_png) {
|
if (icon_infos[i].is_png) {
|
||||||
// Encode PNG icon.
|
// Encode PNG icon.
|
||||||
|
@ -1181,7 +1182,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
|
||||||
icon.instance();
|
icon.instance();
|
||||||
icon->load(iconpath);
|
icon->load(iconpath);
|
||||||
if (!icon->empty()) {
|
if (!icon->empty()) {
|
||||||
_make_icon(icon, data);
|
_make_icon(p_preset, icon, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
|
|
||||||
#include "export.h"
|
#include "export.h"
|
||||||
|
|
||||||
|
#include "core/io/image_loader.h"
|
||||||
#include "core/os/file_access.h"
|
#include "core/os/file_access.h"
|
||||||
#include "core/os/os.h"
|
#include "core/os/os.h"
|
||||||
#include "editor/editor_export.h"
|
#include "editor/editor_export.h"
|
||||||
|
@ -38,6 +39,7 @@
|
||||||
#include "platform/windows/logo.gen.h"
|
#include "platform/windows/logo.gen.h"
|
||||||
|
|
||||||
class EditorExportPlatformWindows : public EditorExportPlatformPC {
|
class EditorExportPlatformWindows : public EditorExportPlatformPC {
|
||||||
|
Error _process_icon(const Ref<EditorExportPreset> &p_preset, const String &p_src_path, const String &p_dst_path);
|
||||||
Error _rcedit_add_data(const Ref<EditorExportPreset> &p_preset, const String &p_path);
|
Error _rcedit_add_data(const Ref<EditorExportPreset> &p_preset, const String &p_path);
|
||||||
Error _code_sign(const Ref<EditorExportPreset> &p_preset, const String &p_path);
|
Error _code_sign(const Ref<EditorExportPreset> &p_preset, const String &p_path);
|
||||||
|
|
||||||
|
@ -52,6 +54,131 @@ public:
|
||||||
virtual bool has_valid_project_configuration(const Ref<EditorExportPreset> &p_preset, String &r_error) const;
|
virtual bool has_valid_project_configuration(const Ref<EditorExportPreset> &p_preset, String &r_error) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Error EditorExportPlatformWindows::_process_icon(const Ref<EditorExportPreset> &p_preset, const String &p_src_path, const String &p_dst_path) {
|
||||||
|
static const uint8_t icon_size[] = { 16, 32, 48, 64, 128, 0 /*256*/ };
|
||||||
|
|
||||||
|
struct IconData {
|
||||||
|
PoolVector<uint8_t> data;
|
||||||
|
uint8_t pal_colors = 0;
|
||||||
|
uint16_t planes = 0;
|
||||||
|
uint16_t bpp = 32;
|
||||||
|
};
|
||||||
|
|
||||||
|
HashMap<uint8_t, IconData> images;
|
||||||
|
Error err;
|
||||||
|
|
||||||
|
if (p_src_path.get_extension() == "ico") {
|
||||||
|
FileAccess *f = FileAccess::open(p_src_path, FileAccess::READ, &err);
|
||||||
|
if (err != OK) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read ICONDIR.
|
||||||
|
f->get_16(); // Reserved.
|
||||||
|
uint16_t icon_type = f->get_16(); // Image type: 1 - ICO.
|
||||||
|
uint16_t icon_count = f->get_16(); // Number of images.
|
||||||
|
if (icon_type != 1) {
|
||||||
|
f->close();
|
||||||
|
memdelete(f);
|
||||||
|
|
||||||
|
ERR_FAIL_V(ERR_CANT_OPEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint16_t i = 0; i < icon_count; i++) {
|
||||||
|
// Read ICONDIRENTRY.
|
||||||
|
uint16_t w = f->get_8(); // Width in pixels.
|
||||||
|
uint16_t h = f->get_8(); // Height in pixels.
|
||||||
|
uint8_t pal_colors = f->get_8(); // Number of colors in the palette (0 - no palette).
|
||||||
|
f->get_8(); // Reserved.
|
||||||
|
uint16_t planes = f->get_16(); // Number of color planes.
|
||||||
|
uint16_t bpp = f->get_16(); // Bits per pixel.
|
||||||
|
uint32_t img_size = f->get_32(); // Image data size in bytes.
|
||||||
|
uint32_t img_offset = f->get_32(); // Image data offset.
|
||||||
|
if (w != h) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read image data.
|
||||||
|
uint64_t prev_offset = f->get_position();
|
||||||
|
images[w].pal_colors = pal_colors;
|
||||||
|
images[w].planes = planes;
|
||||||
|
images[w].bpp = bpp;
|
||||||
|
images[w].data.resize(img_size);
|
||||||
|
PoolVector<uint8_t>::Write wr = images[w].data.write();
|
||||||
|
f->seek(img_offset);
|
||||||
|
f->get_buffer(wr.ptr(), img_size);
|
||||||
|
f->seek(prev_offset);
|
||||||
|
}
|
||||||
|
f->close();
|
||||||
|
memdelete(f);
|
||||||
|
} else {
|
||||||
|
Ref<Image> src_image;
|
||||||
|
src_image.instance();
|
||||||
|
err = ImageLoader::load_image(p_src_path, src_image.ptr());
|
||||||
|
ERR_FAIL_COND_V(err != OK || src_image->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];
|
||||||
|
|
||||||
|
Ref<Image> res_image = src_image->duplicate();
|
||||||
|
ERR_FAIL_COND_V(res_image.is_null() || res_image->empty(), ERR_CANT_OPEN);
|
||||||
|
res_image->resize(size, size, (Image::Interpolation)(p_preset->get("application/icon_interpolation").operator int()));
|
||||||
|
images[icon_size[i]].data = res_image->save_png_to_buffer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t valid_icon_count = 0;
|
||||||
|
for (size_t i = 0; i < sizeof(icon_size) / sizeof(icon_size[0]); ++i) {
|
||||||
|
if (images.has(icon_size[i])) {
|
||||||
|
valid_icon_count++;
|
||||||
|
} else {
|
||||||
|
int size = (icon_size[i] == 0) ? 256 : icon_size[i];
|
||||||
|
add_message(EXPORT_MESSAGE_WARNING, TTR("Resources Modification"), vformat(TTR("Icon size \"%d\" is missing."), size));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ERR_FAIL_COND_V(valid_icon_count == 0, ERR_CANT_OPEN);
|
||||||
|
|
||||||
|
FileAccess *fw = FileAccess::open(p_dst_path, FileAccess::WRITE, &err);
|
||||||
|
if (err != OK) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write ICONDIR.
|
||||||
|
fw->store_16(0); // Reserved.
|
||||||
|
fw->store_16(1); // Image type: 1 - ICO.
|
||||||
|
fw->store_16(valid_icon_count); // Number of images.
|
||||||
|
|
||||||
|
// Write ICONDIRENTRY.
|
||||||
|
uint32_t img_offset = 6 + 16 * valid_icon_count;
|
||||||
|
for (size_t i = 0; i < sizeof(icon_size) / sizeof(icon_size[0]); ++i) {
|
||||||
|
if (images.has(icon_size[i])) {
|
||||||
|
const IconData &di = images[icon_size[i]];
|
||||||
|
fw->store_8(icon_size[i]); // Width in pixels.
|
||||||
|
fw->store_8(icon_size[i]); // Height in pixels.
|
||||||
|
fw->store_8(di.pal_colors); // Number of colors in the palette (0 - no palette).
|
||||||
|
fw->store_8(0); // Reserved.
|
||||||
|
fw->store_16(di.planes); // Number of color planes.
|
||||||
|
fw->store_16(di.bpp); // Bits per pixel.
|
||||||
|
fw->store_32(di.data.size()); // Image data size in bytes.
|
||||||
|
fw->store_32(img_offset); // Image data offset.
|
||||||
|
|
||||||
|
img_offset += di.data.size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write image data.
|
||||||
|
for (size_t i = 0; i < sizeof(icon_size) / sizeof(icon_size[0]); ++i) {
|
||||||
|
if (images.has(icon_size[i])) {
|
||||||
|
const IconData &di = images[icon_size[i]];
|
||||||
|
PoolVector<uint8_t>::Read r = di.data.read();
|
||||||
|
fw->store_buffer(r.ptr(), di.data.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fw->close();
|
||||||
|
memdelete(fw);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
Error EditorExportPlatformWindows::sign_shared_object(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path) {
|
Error EditorExportPlatformWindows::sign_shared_object(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path) {
|
||||||
if (p_preset->get("codesign/enable")) {
|
if (p_preset->get("codesign/enable")) {
|
||||||
return _code_sign(p_preset, p_path);
|
return _code_sign(p_preset, p_path);
|
||||||
|
@ -111,7 +238,8 @@ void EditorExportPlatformWindows::get_export_options(List<ExportOption> *r_optio
|
||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::POOL_STRING_ARRAY, "codesign/custom_options"), PoolStringArray()));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::POOL_STRING_ARRAY, "codesign/custom_options"), PoolStringArray()));
|
||||||
|
|
||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "application/modify_resources"), true));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "application/modify_resources"), true));
|
||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/icon", PROPERTY_HINT_FILE, "*.ico"), ""));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/icon", PROPERTY_HINT_FILE, "*.ico,*.png,*.webp,*.svg"), ""));
|
||||||
|
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "application/icon_interpolation", PROPERTY_HINT_ENUM, "Nearest neighbor,Bilinear,Cubic,Trilinear,Lanczos"), 4));
|
||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/file_version", PROPERTY_HINT_PLACEHOLDER_TEXT, "1.0.0.0"), ""));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/file_version", PROPERTY_HINT_PLACEHOLDER_TEXT, "1.0.0.0"), ""));
|
||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/product_version", PROPERTY_HINT_PLACEHOLDER_TEXT, "1.0.0.0"), ""));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/product_version", PROPERTY_HINT_PLACEHOLDER_TEXT, "1.0.0.0"), ""));
|
||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/company_name", PROPERTY_HINT_PLACEHOLDER_TEXT, "Company Name"), ""));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/company_name", PROPERTY_HINT_PLACEHOLDER_TEXT, "Company Name"), ""));
|
||||||
|
@ -148,6 +276,14 @@ Error EditorExportPlatformWindows::_rcedit_add_data(const Ref<EditorExportPreset
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
String icon_path = ProjectSettings::get_singleton()->globalize_path(p_preset->get("application/icon"));
|
String icon_path = ProjectSettings::get_singleton()->globalize_path(p_preset->get("application/icon"));
|
||||||
|
String tmp_icon_path = EditorSettings::get_singleton()->get_cache_dir().plus_file("_rcedit.ico");
|
||||||
|
if (!icon_path.empty()) {
|
||||||
|
if (_process_icon(p_preset, icon_path, tmp_icon_path) != OK) {
|
||||||
|
add_message(EXPORT_MESSAGE_WARNING, TTR("Resources Modification"), vformat(TTR("Invalid icon file \"%s\"."), icon_path));
|
||||||
|
icon_path = String();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
String file_verion = p_preset->get("application/file_version");
|
String file_verion = p_preset->get("application/file_version");
|
||||||
String product_version = p_preset->get("application/product_version");
|
String product_version = p_preset->get("application/product_version");
|
||||||
String company_name = p_preset->get("application/company_name");
|
String company_name = p_preset->get("application/company_name");
|
||||||
|
@ -161,7 +297,7 @@ Error EditorExportPlatformWindows::_rcedit_add_data(const Ref<EditorExportPreset
|
||||||
args.push_back(p_path);
|
args.push_back(p_path);
|
||||||
if (icon_path != String()) {
|
if (icon_path != String()) {
|
||||||
args.push_back("--set-icon");
|
args.push_back("--set-icon");
|
||||||
args.push_back(icon_path);
|
args.push_back(tmp_icon_path);
|
||||||
}
|
}
|
||||||
if (file_verion != String()) {
|
if (file_verion != String()) {
|
||||||
args.push_back("--set-file-version");
|
args.push_back("--set-file-version");
|
||||||
|
@ -205,6 +341,11 @@ Error EditorExportPlatformWindows::_rcedit_add_data(const Ref<EditorExportPreset
|
||||||
|
|
||||||
String str;
|
String str;
|
||||||
Error err = OS::get_singleton()->execute(rcedit_path, args, true, nullptr, &str, nullptr, true);
|
Error err = OS::get_singleton()->execute(rcedit_path, args, true, nullptr, &str, nullptr, true);
|
||||||
|
|
||||||
|
if (FileAccess::exists(tmp_icon_path)) {
|
||||||
|
DirAccess::remove_file_or_error(tmp_icon_path);
|
||||||
|
}
|
||||||
|
|
||||||
if (err != OK || (str.find("not found") != -1) || (str.find("not recognized") != -1)) {
|
if (err != OK || (str.find("not found") != -1) || (str.find("not recognized") != -1)) {
|
||||||
add_message(EXPORT_MESSAGE_WARNING, TTR("Resources Modification"), TTR("Could not start rcedit executable. Configure rcedit path in the Editor Settings (Export > Windows > rcedit), or disable \"Application > Modify Resources\" in the export preset."));
|
add_message(EXPORT_MESSAGE_WARNING, TTR("Resources Modification"), TTR("Could not start rcedit executable. Configure rcedit path in the Editor Settings (Export > Windows > rcedit), or disable \"Application > Modify Resources\" in the export preset."));
|
||||||
return err;
|
return err;
|
||||||
|
|
Loading…
Reference in a new issue