From 96facf238918bc48d9b7c268c4c5e042aac28ca5 Mon Sep 17 00:00:00 2001 From: Jack Andersen Date: Sun, 17 Jan 2016 14:40:11 -1000 Subject: [PATCH] Initial icons build system --- Editor/CMakeLists.txt | 5 +- Editor/SplashScreen.cpp | 6 +- Editor/icons/CMakeLists.txt | 21 ++++ Editor/icons/icons.cpp | 0 Editor/icons/icons.hpp | 0 Editor/icons/icons.svg | 207 +++++++++++++++++++++++++++++++ Editor/icons/packicons.c | 241 ++++++++++++++++++++++++++++++++++++ hecl | 2 +- libSpecter | 2 +- 9 files changed, 478 insertions(+), 6 deletions(-) create mode 100644 Editor/icons/CMakeLists.txt create mode 100644 Editor/icons/icons.cpp create mode 100644 Editor/icons/icons.hpp create mode 100644 Editor/icons/icons.svg create mode 100644 Editor/icons/packicons.c diff --git a/Editor/CMakeLists.txt b/Editor/CMakeLists.txt index 0c3594666..a76383467 100644 --- a/Editor/CMakeLists.txt +++ b/Editor/CMakeLists.txt @@ -1,5 +1,6 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}) add_subdirectory(locale) +add_subdirectory(icons) if("${CMAKE_BUILD_TYPE}" STREQUAL "Release") option(RUDE_BINARY_CONFIGS @@ -17,18 +18,20 @@ endif() atdna(atdna_Space.cpp Space.hpp) atdna(atdna_ResourceBrowser.cpp ResourceBrowser.hpp) +atdna(atdna_ModelViewer.cpp ModelViewer.hpp) add_executable(urde WIN32 main.cpp Space.hpp Space.cpp atdna_Space.cpp SplashScreen.hpp SplashScreen.cpp ResourceBrowser.hpp ResourceBrowser.cpp atdna_ResourceBrowser.cpp - ModelViewer.hpp ModelViewer.cpp + ModelViewer.hpp ModelViewer.cpp atdna_ModelViewer.cpp ProjectManager.hpp ProjectManager.cpp ViewManager.hpp ViewManager.cpp) target_link_libraries(urde UrdeLocales + UrdeIcons RuntimeCommonCharacter RuntimeCommonInput RuntimeCommon diff --git a/Editor/SplashScreen.cpp b/Editor/SplashScreen.cpp index 4320ab179..78ab960e9 100644 --- a/Editor/SplashScreen.cpp +++ b/Editor/SplashScreen.cpp @@ -91,11 +91,11 @@ void SplashScreen::updateContentOpacity(float opacity) m_buildInfo->typesetGlyphs(m_buildInfoStr, clearColor); m_newButt.m_view.reset(new Specter::Button(res, *this, &m_newProjBind, m_newString, - Specter::Button::Style::Text)); + nullptr, Specter::Button::Style::Text)); m_openButt.m_view.reset(new Specter::Button(res, *this, &m_openProjBind, m_openString, - Specter::Button::Style::Text)); + nullptr, Specter::Button::Style::Text)); m_extractButt.m_view.reset(new Specter::Button(res, *this, &m_extractProjBind, m_extractString, - Specter::Button::Style::Text)); + nullptr, Specter::Button::Style::Text)); updateSize(); } diff --git a/Editor/icons/CMakeLists.txt b/Editor/icons/CMakeLists.txt new file mode 100644 index 000000000..efdd038c9 --- /dev/null +++ b/Editor/icons/CMakeLists.txt @@ -0,0 +1,21 @@ +include_directories(${LIBPNG_INCLUDE_DIR}) +add_executable(packicons packicons.c) +target_link_libraries(packicons ${PNG_LIB} ${ZLIB_LIBRARIES}) + +unset(INKSCAPE_BIN CACHE) +set(CMAKE_FIND_APPBUNDLE "NEVER") +find_program(INKSCAPE_BIN inkscape) +if(INKSCAPE_BIN STREQUAL "INKSCAPE_BIN-NOTFOUND") + message(STATUS "Inkscape not found; downloading icons") + file(DOWNLOAD "https://www.dropbox.com/s/wnj17dwgcsky0o9/icons.bin" + ${CMAKE_CURRENT_BINARY_DIR}/icons.bin SHOW_PROGRESS) +else() + message(STATUS "Inkscape found; will render icons locally") + add_custom_command(OUTPUT icons.bin COMMAND $ + ARGS ${INKSCAPE_BIN} ${CMAKE_CURRENT_SOURCE_DIR}/icons.svg + ${CMAKE_CURRENT_BINARY_DIR}/icons.bin + MAIN_DEPENDENCY icons.svg COMMENT "Generating icons.bin") +endif() + +bintoc(icons.c ${CMAKE_CURRENT_BINARY_DIR}/icons.bin URDE_ICONS) +add_library(UrdeIcons icons.cpp icons.hpp icons.bin icons.c) diff --git a/Editor/icons/icons.cpp b/Editor/icons/icons.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/Editor/icons/icons.hpp b/Editor/icons/icons.hpp new file mode 100644 index 000000000..e69de29bb diff --git a/Editor/icons/icons.svg b/Editor/icons/icons.svg new file mode 100644 index 000000000..c385489b6 --- /dev/null +++ b/Editor/icons/icons.svg @@ -0,0 +1,207 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Editor/icons/packicons.c b/Editor/icons/packicons.c new file mode 100644 index 000000000..eafada9cf --- /dev/null +++ b/Editor/icons/packicons.c @@ -0,0 +1,241 @@ +#include +#include +#include +#include +#include + +static int CountBits(uint32_t n) +{ + int ret = 0; + for (int i=0 ; i<32 ; ++i) + if (((n >> i) & 1) != 0) + ++ret; + return ret; +} + +int main(int argc, char* argv[]) +{ + if (argc < 4) + { + fprintf(stderr, "Usage: packicons \n"); + return 1; + } + + /* Validate inkscape */ + char command[2048]; + snprintf(command, 2048, "%s --version", argv[1]); + FILE* fp = popen(command, "r"); + if (!fp) + { + fprintf(stderr, "'%s' is not executable on this system\n", command); + return 1; + } + + char readback[8]; + if (fread(readback, 1, 8, fp) != 8 || strncmp(readback, "Inkscape", 8)) + { + fprintf(stderr, "'%s' did not return expected \"Inkscape\"\n", command); + pclose(fp); + return 1; + } + pclose(fp); + + /* Validate input */ + fp = fopen(argv[2], "rb"); + if (!fp) + { + fprintf(stderr, "'%s' is not able to be opened for reading as a regular file\n", argv[2]); + return 1; + } + fclose(fp); + +#ifdef _WIN32 + char* TMPDIR = getenv(L"TEMP"); + if (!TMPDIR) + TMPDIR = (char*)"\\Temp"; +#else + char* TMPDIR = getenv("TMPDIR"); + if (!TMPDIR) + TMPDIR = (char*)"/tmp"; +#endif + + FILE* ofp = fopen(argv[3], "wb"); + if (!ofp) + { + fprintf(stderr, "'%s' is not able to be opened for writing as a regular file\n", argv[3]); + return 1; + } + + int numMips = 0; + for (int i=512 ; i>=1 ; i/=2) + ++numMips; + + z_stream z = {}; + size_t rowSz = 0; + uLong rowSzC = 0; + png_bytep row; + png_bytep rowC; + + for (int i=512 ; i>=1 ; i/=2) + { + printf("Rendering icons @%dx%d\n", i, i); + fflush(stdout); + + snprintf(command, 2048, "%s --export-png=\"%s/icon_pack.png\" --export-width=%d --export-height=%d \"%s\"", + argv[1], TMPDIR, i, i, argv[2]); + fp = popen(command, "r"); + if (!fp) + { + fprintf(stderr, "'%s' is not executable on this system\n", command); + fclose(ofp); + return 1; + } + int status = pclose(fp); + if (WEXITSTATUS(status)) + { + fprintf(stderr, "'%s' failed\n", command); + fclose(ofp); + return 1; + } + + /* Get PNG data */ + snprintf(command, 2048, "%s/icon_pack.png", TMPDIR); + fp = fopen(command, "rb"); + if (!fp) + { + fprintf(stderr, "unable to open '%s' for reading\n", command); + fclose(ofp); + return 1; + } + + char header[8]; + fread(header, 1, 8, fp); + if (png_sig_cmp((png_const_bytep)header, 0, 8)) + { + fprintf(stderr, "invalid PNG signature in '%s'\n", command); + fclose(fp); + fclose(ofp); + return 1; + } + + png_structp pngRead = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + if (!pngRead) + { + fprintf(stderr, "unable to initialize libpng\n"); + fclose(fp); + fclose(ofp); + return 1; + } + png_infop info = png_create_info_struct(pngRead); + if (!info) + { + fprintf(stderr, "unable to initialize libpng info\n"); + fclose(fp); + fclose(ofp); + return 1; + } + + if (setjmp(png_jmpbuf(pngRead))) + { + fprintf(stderr, "unable to initialize libpng I/O for '%s'\n", command); + fclose(fp); + fclose(ofp); + return 1; + } + + png_init_io(pngRead, fp); + png_set_sig_bytes(pngRead, 8); + + png_read_info(pngRead, info); + + png_uint_32 width = png_get_image_width(pngRead, info); + png_uint_32 height = png_get_image_height(pngRead, info); + png_byte colorType = png_get_color_type(pngRead, info); + png_byte bitDepth = png_get_bit_depth(pngRead, info); + + if (CountBits(width) != 1 || CountBits(height) != 1) + { + fprintf(stderr, "'%s' is not power-of-2 in one or both dimensions\n", command); + fclose(fp); + fclose(ofp); + return 1; + } + + if (colorType != PNG_COLOR_TYPE_RGB_ALPHA) + { + fprintf(stderr, "'%s' is not in RGBA color mode\n", command); + fclose(fp); + fclose(ofp); + return 1; + } + + if (bitDepth != 8) + { + fprintf(stderr, "'%s' is not 8 bits-per-channel\n", command); + fclose(fp); + fclose(ofp); + return 1; + } + + if (setjmp(png_jmpbuf(pngRead))) + { + fprintf(stderr, "unable to read image in '%s'\n", command); + fclose(fp); + fclose(ofp); + return 1; + } + + if (i == 512) + { + uint32_t fmt = htonl(16); + uint16_t w = htons(width); + uint16_t h = htons(height); + uint32_t mips = htonl(numMips); + fwrite(&fmt, 1, 4, ofp); + fwrite(&w, 1, 2, ofp); + fwrite(&h, 1, 2, ofp); + fwrite(&mips, 1, 4, ofp); + + rowSz = width*4; + rowSzC = compressBound(rowSz); + deflateInit(&z, Z_DEFAULT_COMPRESSION); + row = malloc(rowSz); + rowC = malloc(rowSzC); + } + + for (int r=0 ; r