diff --git a/.github/build.sh b/.github/build.sh index 357a9d0da..46830b453 100755 --- a/.github/build.sh +++ b/.github/build.sh @@ -354,10 +354,10 @@ if [[ $PACKAGE_MODE == appimage ]]; then mkdir -p $appdir/usr/share/icons cp $APP_EXE $appdir/usr/bin/$APP_EXE mv AppRun $appdir/AppRun - cp ../resources/icon/icon-128.png $appdir/$APP_VENDOR-$APP_EXE.png + cp ../resources/icon_exe.svg $appdir/$APP_VENDOR-$APP_EXE.svg cp resources/powder.desktop $appdir/$APP_ID.desktop cp appdata.xml $appdir/usr/share/metainfo/$APP_ID.appdata.xml - cp $appdir/$APP_VENDOR-$APP_EXE.png $appdir/usr/share/icons/$APP_VENDOR-$APP_EXE.png + cp $appdir/$APP_VENDOR-$APP_EXE.svg $appdir/usr/share/icons/$APP_VENDOR-$APP_EXE.svg cp $appdir/$APP_ID.desktop $appdir/usr/share/applications/$APP_ID.desktop ./appimagetool $appdir $ASSET_PATH fi diff --git a/android/res/meson.build b/android/res/meson.build index a0c2d91ff..7c6cfd88c 100644 --- a/android/res/meson.build +++ b/android/res/meson.build @@ -1,7 +1,7 @@ android_resources = files( - 'mipmap-mdpi/ic_launcher.png', 'values/colors.xml', 'values/styles.xml', ) subdir('values') +subdir('mipmap-mdpi') diff --git a/android/res/mipmap-mdpi/ic_launcher.png b/android/res/mipmap-mdpi/ic_launcher.png deleted file mode 100644 index 2f092750c..000000000 Binary files a/android/res/mipmap-mdpi/ic_launcher.png and /dev/null differ diff --git a/android/res/mipmap-mdpi/meson.build b/android/res/mipmap-mdpi/meson.build new file mode 100644 index 000000000..1e0a807bf --- /dev/null +++ b/android/res/mipmap-mdpi/meson.build @@ -0,0 +1,5 @@ +android_resources += configure_file( + input: rendered_icons['icon_exe'], + output: 'ic_launcher.png', + copy: true, +) diff --git a/meson.build b/meson.build index 49e8b3a7e..8f37927df 100644 --- a/meson.build +++ b/meson.build @@ -24,6 +24,9 @@ to_array = generator( arguments: [ '@OUTPUT0@', '@OUTPUT1@', '@INPUT@', '@EXTRA_ARGS@' ] ) +render_icons_with_inkscape = get_option('render_icons_with_inkscape') +inkscape = find_program('inkscape', required: render_icons_with_inkscape) + c_compiler = meson.get_compiler('c') is_x86 = host_machine.cpu_family() in [ 'x86', 'x86_64' ] diff --git a/meson_options.txt b/meson_options.txt index c7d6a5796..cfffdafee 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -213,3 +213,9 @@ option( value: false, description: 'Used by ghactions workflows, not useful otherwise' ) +option( + 'render_icons_with_inkscape', + type: 'feature', + value: 'disabled', + description: 'Render icons with Inkscape (inkscape binary needs to be in PATH)' +) diff --git a/resources/MakeIco.cpp b/resources/MakeIco.cpp new file mode 100644 index 000000000..19dfdfeb9 --- /dev/null +++ b/resources/MakeIco.cpp @@ -0,0 +1,67 @@ +#include +#include +#include + +int main(int argc, char *argv[]) +{ + if (argc < 3) + { + return 1; + } + auto *outputIcoPath = argv[1]; + std::ofstream outputIco(outputIcoPath, std::ios::binary); + if (!outputIco) + { + return 2; + } + auto images = argc - 2; + std::vector header(22 + images * 16); + auto *incondir = &header[0]; + *reinterpret_cast(&incondir[0]) = 0; // reserved + *reinterpret_cast(&incondir[2]) = 1; // icon + *reinterpret_cast(&incondir[4]) = uint16_t(images); + std::vector allData; + for (auto i = 0; i < images; ++i) + { + auto *inputAnyPath = argv[i + 2]; + std::ifstream inputAny(inputAnyPath, std::ios::binary); + std::vector data; + while (true) + { + char ch; + inputAny.read(&ch, 1); + if (inputAny.eof()) + { + break; + } + if (!inputAny) + { + return 3; + } + data.push_back(ch); + } + if (*reinterpret_cast(&data[0]) != UINT64_C(0x0A1A0A0D474E5089)) // png magic + { + return 5; + } + auto width = uint8_t(data[19]); + auto height = uint8_t(data[23]); + auto *incondirentry = &header[6 + i * 16]; + *reinterpret_cast(&incondirentry[0]) = width; + *reinterpret_cast(&incondirentry[1]) = height; + *reinterpret_cast(&incondirentry[2]) = 0; // no color palette + *reinterpret_cast(&incondirentry[3]) = 0; // reserved + *reinterpret_cast(&incondirentry[4]) = 1; // 1 color plane + *reinterpret_cast(&incondirentry[6]) = 32; // 32 bits per pixel + *reinterpret_cast(&incondirentry[8]) = uint32_t(data.size()); // data size + *reinterpret_cast(&incondirentry[12]) = uint32_t(header.size() + allData.size()); // data offset + allData.insert(allData.end(), data.begin(), data.end()); + } + outputIco.write(&header[0], header.size()); + outputIco.write(&allData[0], allData.size()); + if (!outputIco) + { + return 4; + } + return 0; +} diff --git a/resources/cps16.png b/resources/cps16.png deleted file mode 100644 index 5e43e8e27..000000000 Binary files a/resources/cps16.png and /dev/null differ diff --git a/resources/cps32.png b/resources/cps32.png deleted file mode 100644 index 6b93bdac0..000000000 Binary files a/resources/cps32.png and /dev/null differ diff --git a/resources/document.icns b/resources/document.icns deleted file mode 100644 index 2d6cd5c60..000000000 Binary files a/resources/document.icns and /dev/null differ diff --git a/resources/document.ico b/resources/document.ico deleted file mode 100644 index 83c57e784..000000000 Binary files a/resources/document.ico and /dev/null differ diff --git a/resources/exe48.png b/resources/exe48.png deleted file mode 100644 index 8a896e7f6..000000000 Binary files a/resources/exe48.png and /dev/null differ diff --git a/resources/generated_icons/README.md b/resources/generated_icons/README.md new file mode 100644 index 000000000..5eb4b4559 --- /dev/null +++ b/resources/generated_icons/README.md @@ -0,0 +1,9 @@ +We keep these icons here to make it possible to build TPT without Inkscape. If +you have Inkscape and want to change the game's icons, edit the SVGs in the +parent directory and configure your build sites with +`-Drender_icons_with_inkscape=true`. + +The GitHub Actions workflows currently do not use Inkscape and use these icons +instead, so once you are satisfied with the state of the SVGs, replace these +icons with the ones in your build site in the same subdirectory and make a new +commit. diff --git a/resources/generated_icons/icon_cps.png b/resources/generated_icons/icon_cps.png new file mode 100644 index 000000000..c1d26c1fc Binary files /dev/null and b/resources/generated_icons/icon_cps.png differ diff --git a/resources/generated_icons/icon_cps_16.png b/resources/generated_icons/icon_cps_16.png new file mode 100644 index 000000000..e5ce81cc8 Binary files /dev/null and b/resources/generated_icons/icon_cps_16.png differ diff --git a/resources/generated_icons/icon_cps_32.png b/resources/generated_icons/icon_cps_32.png new file mode 100644 index 000000000..fb3a2cca9 Binary files /dev/null and b/resources/generated_icons/icon_cps_32.png differ diff --git a/resources/generated_icons/icon_cps_48.png b/resources/generated_icons/icon_cps_48.png new file mode 100644 index 000000000..8e7397230 Binary files /dev/null and b/resources/generated_icons/icon_cps_48.png differ diff --git a/resources/generated_icons/icon_exe.png b/resources/generated_icons/icon_exe.png new file mode 100644 index 000000000..78695c114 Binary files /dev/null and b/resources/generated_icons/icon_exe.png differ diff --git a/resources/generated_icons/icon_exe_16.png b/resources/generated_icons/icon_exe_16.png new file mode 100644 index 000000000..596055948 Binary files /dev/null and b/resources/generated_icons/icon_exe_16.png differ diff --git a/resources/generated_icons/icon_exe_32.png b/resources/generated_icons/icon_exe_32.png new file mode 100644 index 000000000..d08fe5a04 Binary files /dev/null and b/resources/generated_icons/icon_exe_32.png differ diff --git a/resources/generated_icons/icon_exe_48.png b/resources/generated_icons/icon_exe_48.png new file mode 100644 index 000000000..f7e508620 Binary files /dev/null and b/resources/generated_icons/icon_exe_48.png differ diff --git a/resources/icon.icns b/resources/icon.icns deleted file mode 100755 index 56df7eb19..000000000 Binary files a/resources/icon.icns and /dev/null differ diff --git a/resources/icon.ico b/resources/icon.ico deleted file mode 100644 index eef39ce8a..000000000 Binary files a/resources/icon.ico and /dev/null differ diff --git a/resources/icon/icon-128.png b/resources/icon/icon-128.png deleted file mode 100644 index f0d925f65..000000000 Binary files a/resources/icon/icon-128.png and /dev/null differ diff --git a/resources/icon/icon-16.png b/resources/icon/icon-16.png deleted file mode 100644 index cc16ccdc7..000000000 Binary files a/resources/icon/icon-16.png and /dev/null differ diff --git a/resources/icon/icon-24.png b/resources/icon/icon-24.png deleted file mode 100644 index df91652a0..000000000 Binary files a/resources/icon/icon-24.png and /dev/null differ diff --git a/resources/icon/icon-256.png b/resources/icon/icon-256.png deleted file mode 100644 index 693f57f83..000000000 Binary files a/resources/icon/icon-256.png and /dev/null differ diff --git a/resources/icon/icon-32.png b/resources/icon/icon-32.png deleted file mode 100644 index ac03ec853..000000000 Binary files a/resources/icon/icon-32.png and /dev/null differ diff --git a/resources/icon/icon-48.png b/resources/icon/icon-48.png deleted file mode 100644 index bdaf952cd..000000000 Binary files a/resources/icon/icon-48.png and /dev/null differ diff --git a/resources/icon/new-unused/icon.icns b/resources/icon/new-unused/icon.icns deleted file mode 100644 index 7590c0fcb..000000000 Binary files a/resources/icon/new-unused/icon.icns and /dev/null differ diff --git a/resources/icon/new-unused/icon.svg b/resources/icon/new-unused/icon.svg deleted file mode 100644 index 9257f6b2b..000000000 --- a/resources/icon/new-unused/icon.svg +++ /dev/null @@ -1,117 +0,0 @@ - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - diff --git a/resources/icon/new-unused/icon_128.png b/resources/icon/new-unused/icon_128.png deleted file mode 100644 index 218d37d09..000000000 Binary files a/resources/icon/new-unused/icon_128.png and /dev/null differ diff --git a/resources/icon/new-unused/icon_256.ico b/resources/icon/new-unused/icon_256.ico deleted file mode 100644 index 7823a3f6f..000000000 Binary files a/resources/icon/new-unused/icon_256.ico and /dev/null differ diff --git a/resources/icon/new-unused/icon_256.png b/resources/icon/new-unused/icon_256.png deleted file mode 100644 index 0abf4cf54..000000000 Binary files a/resources/icon/new-unused/icon_256.png and /dev/null differ diff --git a/resources/icon/new-unused/icon_48.ico b/resources/icon/new-unused/icon_48.ico deleted file mode 100644 index bd67ada97..000000000 Binary files a/resources/icon/new-unused/icon_48.ico and /dev/null differ diff --git a/resources/icon/new-unused/icon_64.ico b/resources/icon/new-unused/icon_64.ico deleted file mode 100644 index 41617e0d8..000000000 Binary files a/resources/icon/new-unused/icon_64.ico and /dev/null differ diff --git a/resources/icon/new-unused/icon_96.ico b/resources/icon/new-unused/icon_96.ico deleted file mode 100644 index f5e1f1218..000000000 Binary files a/resources/icon/new-unused/icon_96.ico and /dev/null differ diff --git a/resources/icon/new-unused/icon_circle.png b/resources/icon/new-unused/icon_circle.png deleted file mode 100644 index 8a28ec087..000000000 Binary files a/resources/icon/new-unused/icon_circle.png and /dev/null differ diff --git a/resources/icon/new-unused/icon_circle.svg b/resources/icon/new-unused/icon_circle.svg deleted file mode 100644 index 749e31f48..000000000 --- a/resources/icon/new-unused/icon_circle.svg +++ /dev/null @@ -1,101 +0,0 @@ - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - diff --git a/resources/icon_cps.svg b/resources/icon_cps.svg new file mode 100644 index 000000000..5389db30d --- /dev/null +++ b/resources/icon_cps.svg @@ -0,0 +1,6920 @@ + + + +image/svg+xml diff --git a/resources/icon_exe.svg b/resources/icon_exe.svg new file mode 100644 index 000000000..cca13025d --- /dev/null +++ b/resources/icon_exe.svg @@ -0,0 +1,533 @@ + + + + diff --git a/resources/meson.build b/resources/meson.build index 90aef9d69..a37602eac 100644 --- a/resources/meson.build +++ b/resources/meson.build @@ -1,19 +1,72 @@ +rendered_icons_optionally_from_svg = { + 'icon_exe' : { 'png': 'icon_exe.png' , 'svg': 'icon_exe.svg', 'width': '256', 'height': '256' }, + 'icon_exe_48': { 'png': 'icon_exe_48.png', 'svg': 'icon_exe.svg', 'width': '48', 'height': '48' }, + 'icon_exe_32': { 'png': 'icon_exe_32.png', 'svg': 'icon_exe.svg', 'width': '32', 'height': '32' }, + 'icon_exe_16': { 'png': 'icon_exe_16.png', 'svg': 'icon_exe.svg', 'width': '16', 'height': '16' }, + 'icon_cps' : { 'png': 'icon_cps.png' , 'svg': 'icon_cps.svg', 'width': '256', 'height': '256' }, + 'icon_cps_48': { 'png': 'icon_cps_48.png', 'svg': 'icon_cps.svg', 'width': '48', 'height': '48' }, + 'icon_cps_32': { 'png': 'icon_cps_32.png', 'svg': 'icon_cps.svg', 'width': '32', 'height': '32' }, + 'icon_cps_16': { 'png': 'icon_cps_16.png', 'svg': 'icon_cps.svg', 'width': '16', 'height': '16' }, +} +rendered_icons = {} +if render_icons_with_inkscape.allowed() + foreach key, info : rendered_icons_optionally_from_svg + rendered_icons += { key: custom_target( + key + '-from-svg', + output: info['png'], + command: [ + inkscape, + '--export-area-page', + '--export-type', 'png', + '--export-filename', '@OUTPUT@', + '--export-width', info['width'], + '--export-height', info['height'], + files(info['svg']), + ], + ) } + endforeach +else + foreach key, info : rendered_icons_optionally_from_svg + rendered_icons += { key: files('generated_icons/' + info['png']) } + endforeach +endif + if host_platform == 'windows' + make_ico = executable('makeico', sources: 'MakeIco.cpp', native: true) + generated_win_icos = {} + win_icos = { + 'icon_exe': [ 'icon_exe', 'icon_exe_48', 'icon_exe_32', 'icon_exe_16' ], + 'icon_cps': [ 'icon_cps', 'icon_cps_48', 'icon_cps_32', 'icon_cps_16' ], + } + foreach key, icons : win_icos + command = [ + make_ico, + '@OUTPUT@', + ] + foreach ikey : icons + command += [ rendered_icons[ikey] ] + endforeach + generated_win_icos += { key: custom_target( + key + '-ico', + output: key + '.ico', + command: command, + ) } + endforeach powder_files += windows_mod.compile_resources( 'powder-res.rc', + depends: [ + generated_win_icos['icon_exe'], + generated_win_icos['icon_cps'], + ], depend_files: [ - 'icon.ico', - 'document.ico', 'resource.h', ], ) endif if host_platform == 'linux' - data_files += to_array.process('cps16.png', extra_args: 'cps16_png') - data_files += to_array.process('cps32.png', extra_args: 'cps32_png') - data_files += to_array.process('exe48.png', extra_args: 'exe48_png') - data_files += to_array.process('icon/icon-128.png', extra_args: 'icon_png') + data_files += to_array.process(rendered_icons['icon_exe'], extra_args: 'icon_exe_png') + data_files += to_array.process(rendered_icons['icon_cps'], extra_args: 'icon_cps_png') data_files += to_array.process('save.xml', extra_args: 'save_xml') data_files += to_array.process(configure_file( input: 'powder.template.desktop', diff --git a/resources/powder-res.rc b/resources/powder-res.rc index 153b01218..a591330f8 100644 --- a/resources/powder-res.rc +++ b/resources/powder-res.rc @@ -1,4 +1,4 @@ #include "resource.h" -IDI_ICON ICON DISCARDABLE "icon.ico" -IDI_DOC_ICON ICON DISCARDABLE "document.ico" +IDI_ICON ICON DISCARDABLE "icon_exe.ico" +IDI_DOC_ICON ICON DISCARDABLE "icon_cps.ico" diff --git a/src/PowderToyFontEditor.cpp b/src/PowderToyFontEditor.cpp index b5f4dcc50..326eba694 100644 --- a/src/PowderToyFontEditor.cpp +++ b/src/PowderToyFontEditor.cpp @@ -15,7 +15,7 @@ #include #if defined(LIN) -# include "icon-128.png.h" +# include "icon_exe.png.h" #endif #include @@ -151,15 +151,15 @@ int SDLOpen() // Use GetModuleHandle to get the Exe HMODULE/HINSTANCE HMODULE hModExe = GetModuleHandle(NULL); - HICON hIconSmall = (HICON)LoadImage(hModExe, MAKEINTRESOURCE(101), IMAGE_ICON, 16, 16, LR_SHARED); - HICON hIconBig = (HICON)LoadImage(hModExe, MAKEINTRESOURCE(101), IMAGE_ICON, 32, 32, LR_SHARED); + HICON hIconSmall = (HICON)LoadImage(hModExe, MAKEINTRESOURCE(IDI_ICON), IMAGE_ICON, 16, 16, LR_SHARED); + HICON hIconBig = (HICON)LoadImage(hModExe, MAKEINTRESOURCE(IDI_ICON), IMAGE_ICON, 32, 32, LR_SHARED); SendMessage(WindowHandle, WM_SETICON, ICON_SMALL, (LPARAM)hIconSmall); SendMessage(WindowHandle, WM_SETICON, ICON_BIG, (LPARAM)hIconBig); #endif #ifdef LIN std::vector imageData; int imgw, imgh; - if (PngDataToPixels(imageData, imgw, imgh, reinterpret_cast(icon_png), icon_png_size, false)) + if (PngDataToPixels(imageData, imgw, imgh, reinterpret_cast(icon_exe_png), icon_exe_png_size, false)) { SDL_Surface *icon = SDL_CreateRGBSurfaceFrom(&imageData[0], imgw, imgh, 32, imgw * sizeof(pixel), 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000); SDL_SetWindowIcon(sdl_window, icon); diff --git a/src/PowderToySDL.cpp b/src/PowderToySDL.cpp index 876f42cc9..b05b0337a 100644 --- a/src/PowderToySDL.cpp +++ b/src/PowderToySDL.cpp @@ -18,7 +18,7 @@ #include #if defined(LIN) -# include "icon-128.png.h" +# include "icon_exe.png.h" #endif #include #include @@ -215,7 +215,7 @@ void SDLOpen() #ifdef LIN std::vector imageData; int imgw, imgh; - if (PngDataToPixels(imageData, imgw, imgh, reinterpret_cast(icon_png), icon_png_size, false)) + if (PngDataToPixels(imageData, imgw, imgh, reinterpret_cast(icon_exe_png), icon_exe_png_size, false)) { SDL_Surface *icon = SDL_CreateRGBSurfaceFrom(&imageData[0], imgw, imgh, 32, imgw * sizeof(pixel), 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000); SDL_SetWindowIcon(sdl_window, icon); diff --git a/src/client/Client.cpp b/src/client/Client.cpp index ebc252850..1d68dcb1f 100644 --- a/src/client/Client.cpp +++ b/src/client/Client.cpp @@ -17,9 +17,8 @@ #endif #ifdef LIN -# include "cps16.png.h" -# include "cps32.png.h" -# include "exe48.png.h" +# include "icon_cps.png.h" +# include "icon_exe.png.h" # include "save.xml.h" # include "powder.desktop.h" #endif @@ -1665,23 +1664,16 @@ bool Client::DoInstallation() } if (ok) { - ByteString file = APPVENDOR "-cps32.png"; - ok = ok && Platform::WriteFile(std::vector(cps32_png, cps32_png + cps32_png_size), file); - ok = ok && !system(ByteString::Build("xdg-icon-resource install --noupdate --context mimetypes --size 32 ", file, " application-vnd.powdertoy.save").c_str()); + ByteString file = APPVENDOR "-cps.png"; + ok = ok && Platform::WriteFile(std::vector(icon_cps_png, icon_cps_png + icon_cps_png_size), file); + ok = ok && !system(ByteString::Build("xdg-icon-resource install --noupdate --context mimetypes --size 64 ", file, " application-vnd.powdertoy.save").c_str()); Platform::RemoveFile(file); } if (ok) { - ByteString file = APPVENDOR "-cps16.png"; - ok = ok && Platform::WriteFile(std::vector(cps16_png, cps16_png + cps16_png_size), file); - ok = ok && !system(ByteString::Build("xdg-icon-resource install --noupdate --context mimetypes --size 16 ", file, " application-vnd.powdertoy.save").c_str()); - Platform::RemoveFile(file); - } - if (ok) - { - ByteString file = APPVENDOR "-exe48.png"; - ok = ok && Platform::WriteFile(std::vector(exe48_png, exe48_png + exe48_png_size), file); - ok = ok && !system(ByteString::Build("xdg-icon-resource install --noupdate --size 48 ", file, " " APPVENDOR "-" APPEXE).c_str()); + ByteString file = APPVENDOR "-exe.png"; + ok = ok && Platform::WriteFile(std::vector(icon_exe_png, icon_exe_png + icon_exe_png_size), file); + ok = ok && !system(ByteString::Build("xdg-icon-resource install --noupdate --size 64 ", file, " " APPVENDOR "-" APPEXE).c_str()); Platform::RemoveFile(file); } if (ok)