summary refs log tree commit diff
diff options
context:
space:
mode:
authorJune McEnroe <june@causal.agency>2022-01-23 21:11:00 -0500
committerJune McEnroe <june@causal.agency>2022-01-23 21:11:00 -0500
commit519ec0b62450e2d4eb5adb04fe72f18a83aad564 (patch)
tree34a32e042d3dadbab00b75eb83ad7642a4b0ea02
parentAdd icons to Windows and macOS apps (diff)
downloadwep-519ec0b62450e2d4eb5adb04fe72f18a83aad564.tar.gz
wep-519ec0b62450e2d4eb5adb04fe72f18a83aad564.zip
Upscale icons for macOS
-rw-r--r--CMakeLists.txt30
-rw-r--r--tools/ico2png.c29
2 files changed, 36 insertions, 23 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7cbdc2e..bc9e0d6 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -90,23 +90,27 @@ foreach(game ${games})
 		VERBATIM
 	)
 	if(APPLE)
-		add_custom_command(
-			OUTPUT ${shouting}.PNG
-			COMMAND ico2png ${shouting}.ICO
-			DEPENDS ${shouting}.ICO
-			VERBATIM
-		)
 		file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${game}.iconset)
-		add_custom_command(
-			OUTPUT ${game}.iconset/icon_32x32.png
-			COMMAND cp ${shouting}.PNG ${game}.iconset/icon_32x32.png
-			DEPENDS ${shouting}.PNG
-			VERBATIM
-		)
+		foreach(scale 1 2 4 8 16)
+			math(EXPR size "32 * ${scale}")
+			add_custom_command(
+				OUTPUT ${game}.iconset/icon_${size}x${size}.png
+				COMMAND ico2png
+					${shouting}.ICO ${scale}x
+					${game}.iconset/icon_${size}x${size}.png
+				DEPENDS ${shouting}.ICO
+				VERBATIM
+			)
+		endforeach()
 		add_custom_command(
 			OUTPUT ${game}.icns
 			COMMAND iconutil -c icns ${game}.iconset
-			DEPENDS ${game}.iconset/icon_32x32.png
+			DEPENDS
+				${game}.iconset/icon_32x32.png
+				${game}.iconset/icon_64x64.png
+				${game}.iconset/icon_128x128.png
+				${game}.iconset/icon_256x256.png
+				${game}.iconset/icon_512x512.png
 			VERBATIM
 		)
 		target_sources(${game} PRIVATE ${game}.icns)
diff --git a/tools/ico2png.c b/tools/ico2png.c
index 6e79ed7..9065f6f 100644
--- a/tools/ico2png.c
+++ b/tools/ico2png.c
@@ -90,14 +90,11 @@ static void pngData(SDL_RWops *rw, const Uint8 *data, Uint32 len) {
 }
 
 int main(int argc, char *argv[]) {
-	if (argc < 2) return 1;
+	if (argc < 4) return 1;
 	const char *icoPath = argv[1];
-	const char *name = strrchr(icoPath, '/');
-	name = (name ? &name[1] : icoPath);
-	char pngPath[256];
-	snprintf(
-		pngPath, sizeof(pngPath), "%.*s.PNG", (int)strcspn(name, "."), name
-	);
+	const char *pngPath = argv[3];
+	Uint32 scale = strtoul(argv[2], NULL, 10);
+	if (!scale) return 1;
 
 	SDL_RWops *ico = SDL_RWFromFile(icoPath, "rb");
 	if (!ico) err(1, "%s", icoPath);
@@ -148,8 +145,8 @@ int main(int argc, char *argv[]) {
 	// Write the PNG header
 	SDL_RWwrite(png, "\x89PNG\r\n\x1A\n", 8, 1);
 	pngChunk(png, "IHDR", 13);
-	pngUint32(png, bestIcon.width);
-	pngUint32(png, bestIcon.height);
+	pngUint32(png, bestIcon.width * scale);
+	pngUint32(png, bestIcon.height * scale);
 	Uint8 depth = 8;
 	Uint8 color = 3; // indexed
 	Uint8 zero[3] = {0};
@@ -232,10 +229,22 @@ int main(int argc, char *argv[]) {
 		}
 	}
 
-	pngData(png, lines, bestIcon.height * pngStride);
+	// Upscale with nearest neighbor
+	Uint32 scaledWidth = bestIcon.width * scale;
+	Uint32 scaledHeight = bestIcon.height * scale;
+	Uint32 scaledStride = 1 + scaledWidth;
+	Uint8 *scaled = calloc(scaledHeight, scaledStride);
+	for (Uint32 y = 0; y < scaledHeight; ++y) {
+		for (Uint32 x = 0; x < scaledWidth; ++x) {
+			scaled[y * scaledStride + 1 + x] =
+				lines[(y / scale) * pngStride + 1 + (x / scale)];
+		}
+	}
+	pngData(png, scaled, scaledHeight * scaledStride);
 	pngChunk(png, "IEND", 0);
 	pngUint32(png, ~pngCRC);
 
+	free(scaled);
 	free(lines);
 	SDL_RWclose(png);
 	SDL_RWclose(ico);