From a8fae77f10306584db3b62127defc618481c17cd Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 27 Jun 2024 18:28:32 +0200 Subject: [PATCH] Cleanup: remove unused icon utilities and make convenience target Remove utilities to assist in creation of the now removed `*.dat` icons. Pull Request: https://projects.blender.org/blender/blender/pulls/123837 --- GNUmakefile | 14 - build_files/cmake/macros.cmake | 85 --- build_files/windows/icons.cmd | 32 -- build_files/windows/parse_arguments.cmd | 3 - make.bat | 5 - release/datafiles/blender_icons_update.py | 106 ---- source/blender/datatoc/CMakeLists.txt | 39 -- source/blender/datatoc/datatoc_icon.cc | 496 ------------------ source/blender/datatoc/datatoc_icon.py | 146 ------ source/blender/datatoc/datatoc_icon_split.py | 302 ----------- .../datatoc/datatoc_icon_split_to_png.py | 60 --- 11 files changed, 1288 deletions(-) delete mode 100644 build_files/windows/icons.cmd delete mode 100755 release/datafiles/blender_icons_update.py delete mode 100644 source/blender/datatoc/datatoc_icon.cc delete mode 100755 source/blender/datatoc/datatoc_icon.py delete mode 100755 source/blender/datatoc/datatoc_icon_split.py delete mode 100755 source/blender/datatoc/datatoc_icon_split_to_png.py diff --git a/GNUmakefile b/GNUmakefile index 22839ecbbae..991fa37f07e 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -96,15 +96,6 @@ Spell Checkers Utilities Not associated with building Blender. - * icons: - Updates PNG icons from SVG files. - - Optionally pass in variables: 'BLENDER_BIN', 'INKSCAPE_BIN' - otherwise default paths are used. - - Example - make icons INKSCAPE_BIN=/path/to/inkscape - * icons_geom: Updates Geometry icons from BLEND file. @@ -565,11 +556,6 @@ source_archive_complete: .FORCE # This assumes CMake is still using a default `PACKAGE_DIR` variable: @$(PYTHON) ./build_files/utils/make_source_archive.py --include-packages "$(BUILD_DIR)/source_archive/packages" -icons: .FORCE - @BLENDER_BIN=$(BLENDER_BIN) "$(BLENDER_DIR)/release/datafiles/blender_icons_update.py" - "$(BLENDER_DIR)/release/datafiles/prvicons_update.py" - "$(BLENDER_DIR)/release/datafiles/alert_icons_update.py" - icons_geom: .FORCE @BLENDER_BIN=$(BLENDER_BIN) \ "$(BLENDER_DIR)/release/datafiles/blender_icons_geom_update.py" diff --git a/build_files/cmake/macros.cmake b/build_files/cmake/macros.cmake index f78aa93c27d..efd5e19fa27 100644 --- a/build_files/cmake/macros.cmake +++ b/build_files/cmake/macros.cmake @@ -1040,91 +1040,6 @@ function(data_to_c_simple set_source_files_properties(${_file_to} PROPERTIES GENERATED TRUE) endfunction() -# Function for converting pixmap directory to a '.png' and then a '.c' file. -function(data_to_c_simple_icons - path_from icon_prefix icon_names - list_to_add - ) - - # Conversion steps - # path_from -> _file_from -> _file_to - # foo/*.dat -> foo.png -> foo.png.c - - get_filename_component(_path_from_abs ${path_from} ABSOLUTE) - # remove ../'s - get_filename_component(_file_from ${CMAKE_CURRENT_BINARY_DIR}/${path_from}.png REALPATH) - get_filename_component(_file_to ${CMAKE_CURRENT_BINARY_DIR}/${path_from}.png.c REALPATH) - - list(APPEND ${list_to_add} ${_file_to}) - set(${list_to_add} ${${list_to_add}} PARENT_SCOPE) - - get_filename_component(_file_to_path ${_file_to} PATH) - - # Construct a list of absolute paths from input - set(_icon_files) - foreach(_var ${icon_names}) - list(APPEND _icon_files "${_path_from_abs}/${icon_prefix}${_var}.dat") - endforeach() - - add_custom_command( - OUTPUT ${_file_from} ${_file_to} - COMMAND ${CMAKE_COMMAND} -E make_directory ${_file_to_path} - # COMMAND python3 ${CMAKE_SOURCE_DIR}/source/blender/datatoc/datatoc_icon.py - # ${_path_from_abs} ${_file_from} - COMMAND "$" ${_path_from_abs} ${_file_from} - COMMAND "$" ${_file_from} ${_file_to} - DEPENDS - ${_icon_files} - datatoc_icon - datatoc - # could be an arg but for now we only create icons depending on UI_icons.hh - ${CMAKE_SOURCE_DIR}/source/blender/editors/include/UI_icons.hh - ) - - set_source_files_properties(${_file_from} ${_file_to} PROPERTIES GENERATED TRUE) -endfunction() - -# XXX Not used for now... -function(svg_to_png - file_from - file_to - dpi - list_to_add - ) - - # remove ../'s - get_filename_component(_file_from ${CMAKE_CURRENT_SOURCE_DIR}/${file_from} REALPATH) - get_filename_component(_file_to ${CMAKE_CURRENT_SOURCE_DIR}/${file_to} REALPATH) - - list(APPEND ${list_to_add} ${_file_to}) - set(${list_to_add} ${${list_to_add}} PARENT_SCOPE) - - find_program(INKSCAPE_EXE inkscape) - mark_as_advanced(INKSCAPE_EXE) - - if(INKSCAPE_EXE) - if(APPLE) - # in OS X app bundle, the binary is a shim that doesn't take any - # command line arguments, replace it with the actual binary - string(REPLACE "MacOS/Inkscape" "Resources/bin/inkscape" INKSCAPE_REAL_EXE ${INKSCAPE_EXE}) - if(EXISTS "${INKSCAPE_REAL_EXE}") - set(INKSCAPE_EXE ${INKSCAPE_REAL_EXE}) - endif() - endif() - - add_custom_command( - OUTPUT ${_file_to} - - COMMAND ${INKSCAPE_EXE} - ${_file_from} --export-dpi=${dpi} --without-gui --export-png=${_file_to} - - DEPENDS ${_file_from} ${INKSCAPE_EXE} - ) - else() - message(WARNING "Inkscape not found, could not re-generate ${_file_to} from ${_file_from}!") - endif() -endfunction() - function(msgfmt_simple file_from list_to_add diff --git a/build_files/windows/icons.cmd b/build_files/windows/icons.cmd deleted file mode 100644 index 9390ccf827c..00000000000 --- a/build_files/windows/icons.cmd +++ /dev/null @@ -1,32 +0,0 @@ -if NOT EXIST %PYTHON% ( - echo python not found, required for this operation - exit /b 1 -) - -call "%~dp0\find_inkscape.cmd" - -if EXIST "%INKSCAPE_BIN%" ( - goto detect_inkscape_done -) - -echo unable to locate inkscape, run "set inkscape_BIN=full_path_to_inkscape.exe" -exit /b 1 - -:detect_inkscape_done - -call "%~dp0\find_blender.cmd" - -if EXIST "%BLENDER_BIN%" ( - goto detect_blender_done -) - -echo unable to locate blender, run "set BLENDER_BIN=full_path_to_blender.exe" -exit /b 1 - -:detect_blender_done - -%PYTHON% -B %BLENDER_DIR%\release\datafiles\blender_icons_update.py -%PYTHON% -B %BLENDER_DIR%\release\datafiles\prvicons_update.py -%PYTHON% -B %BLENDER_DIR%\release\datafiles\alert_icons_update.py - -:EOF diff --git a/build_files/windows/parse_arguments.cmd b/build_files/windows/parse_arguments.cmd index 937c56768a5..ec22ed8e48a 100644 --- a/build_files/windows/parse_arguments.cmd +++ b/build_files/windows/parse_arguments.cmd @@ -103,9 +103,6 @@ if NOT "%1" == "" ( set FORMAT=1 set FORMAT_ARGS=%2 %3 %4 %5 %6 %7 %8 %9 goto EOF - ) else if "%1" == "icons" ( - set ICONS=1 - goto EOF ) else if "%1" == "icons_geom" ( set ICONS_GEOM=1 goto EOF diff --git a/make.bat b/make.bat index aee1876a0c1..acf792ee571 100644 --- a/make.bat +++ b/make.bat @@ -78,11 +78,6 @@ call "%BLENDER_DIR%\build_files\windows\set_build_dir.cmd" :convenience_targets -if "%ICONS%" == "1" ( - call "%BLENDER_DIR%\build_files\windows\icons.cmd" - goto EOF -) - if "%ICONS_GEOM%" == "1" ( call "%BLENDER_DIR%\build_files\windows\icons_geom.cmd" goto EOF diff --git a/release/datafiles/blender_icons_update.py b/release/datafiles/blender_icons_update.py deleted file mode 100755 index 397aaa93749..00000000000 --- a/release/datafiles/blender_icons_update.py +++ /dev/null @@ -1,106 +0,0 @@ -#!/usr/bin/env python3 -# SPDX-FileCopyrightText: 2014-2022 Blender Authors -# -# SPDX-License-Identifier: GPL-2.0-or-later - -# This script updates icons from the SVG file -import os -import subprocess -import sys - -from typing import ( - Dict, - List, - Optional, - Sequence, - Tuple, -) - - -def run(cmd: Sequence[str], *, env: Optional[Dict[str, str]] = None) -> None: - print(" ", " ".join(cmd)) - subprocess.check_call(cmd, env=env) - - -BASEDIR = os.path.abspath(os.path.dirname(__file__)) - -env = {} -# Developers may have ASAN enabled, avoid non-zero exit codes. -env["ASAN_OPTIONS"] = "exitcode=0:" + os.environ.get("ASAN_OPTIONS", "") - -# These NEED to be set on windows for python to initialize properly. -if sys.platform[:3] == "win": - env["PATHEXT"] = os.environ.get("PATHEXT", "") - env["SystemDrive"] = os.environ.get("SystemDrive", "") - env["SystemRoot"] = os.environ.get("SystemRoot", "") - -if not (inkscape_bin := os.environ.get("INKSCAPE_BIN")): - if sys.platform == 'darwin': - inkscape_bin = '/Applications/Inkscape.app/Contents/MacOS/inkscape' - else: - inkscape_bin = "inkscape" - -blender_bin = os.environ.get("BLENDER_BIN", "blender") - -cmd: Tuple[str, ...] = ( - inkscape_bin, - os.path.join(BASEDIR, "blender_icons.svg"), - "--export-width=602", - "--export-height=640", - "--export-type=png", - "--export-filename=" + os.path.join(BASEDIR, "blender_icons16.png"), -) -run(cmd, env=env) - -cmd = ( - inkscape_bin, - os.path.join(BASEDIR, "blender_icons.svg"), - "--export-width=1204", - "--export-height=1280", - "--export-type=png", - "--export-filename=" + os.path.join(BASEDIR, "blender_icons32.png"), -) -run(cmd, env=env) - - -# For testing it can be good to clear all old -# rm ./blender_icons16/*.dat -# rm ./blender_icons32/*.dat - -datatoc_icon_split_py = os.path.join(BASEDIR, "..", "..", "source", "blender", "datatoc", "datatoc_icon_split.py") - -# create .dat pixmaps (which are stored in git) -cmd = ( - blender_bin, "--background", "--factory-startup", - "--python", datatoc_icon_split_py, "--", - "--image=" + os.path.join(BASEDIR, "blender_icons16.png"), - "--output=" + os.path.join(BASEDIR, "blender_icons16"), - "--output_prefix=icon16_", - "--name_style=UI_ICONS", - "--parts_x", "26", "--parts_y", "30", - "--minx", "3", "--maxx", "53", "--miny", "3", "--maxy", "8", - "--minx_icon", "2", "--maxx_icon", "2", "--miny_icon", "2", "--maxy_icon", "2", - "--spacex_icon", "1", "--spacey_icon", "1", -) -run(cmd, env=env) - -cmd = ( - blender_bin, "--background", "--factory-startup", - "--python", datatoc_icon_split_py, "--", - "--image=" + os.path.join(BASEDIR, "blender_icons32.png"), - "--output=" + os.path.join(BASEDIR, "blender_icons32"), - "--output_prefix=icon32_", - "--name_style=UI_ICONS", - "--parts_x", "26", "--parts_y", "30", - "--minx", "6", "--maxx", "106", "--miny", "6", "--maxy", "16", - "--minx_icon", "4", "--maxx_icon", "4", "--miny_icon", "4", "--maxy_icon", "4", - "--spacex_icon", "2", "--spacey_icon", "2", -) -run(cmd, env=env) - -os.remove(os.path.join(BASEDIR, "blender_icons16.png")) -os.remove(os.path.join(BASEDIR, "blender_icons32.png")) - -# For testing, if we want the PNG of each image -# ./datatoc_icon_split_to_png.py ./blender_icons16/*.dat -# ./datatoc_icon_split_to_png.py ./blender_icons32/*.dat diff --git a/source/blender/datatoc/CMakeLists.txt b/source/blender/datatoc/CMakeLists.txt index 3abd3601792..0351d39c337 100644 --- a/source/blender/datatoc/CMakeLists.txt +++ b/source/blender/datatoc/CMakeLists.txt @@ -11,42 +11,3 @@ set(SRC # SRC_DNA_INC is defined in the parent dir add_executable(datatoc ${SRC}) - - -# ----------------------------------------------------------------------------- -# Build datatoc_icon executable - -if(NOT WITH_HEADLESS) - - set(SRC - datatoc_icon.cc - ) - setup_platform_linker_flags(datatoc) - if(WIN32) - include_directories( - ../blenlib - ../../../intern/utfconv - ) - - # for winstuff_dir.cc - add_definitions(-DUSE_STANDALONE) - - list(APPEND SRC - ../blenlib/intern/winstuff_dir.cc - ../../../intern/utfconv/utfconv.cc - ) - - endif() - - include_directories(${PNG_INCLUDE_DIRS}) - - add_executable(datatoc_icon ${SRC}) - setup_platform_linker_flags(datatoc_icon) - - target_link_libraries(datatoc_icon ${PNG_LIBRARIES} ${ZLIB_LIBRARIES}) - # PNG library uses pow() and floow(), so seems -lm is required for proper - # working binary. - if(UNIX AND NOT APPLE) - target_link_libraries(datatoc_icon m) - endif() -endif() diff --git a/source/blender/datatoc/datatoc_icon.cc b/source/blender/datatoc/datatoc_icon.cc deleted file mode 100644 index 2749cfe8496..00000000000 --- a/source/blender/datatoc/datatoc_icon.cc +++ /dev/null @@ -1,496 +0,0 @@ -/* SPDX-FileCopyrightText: 2023 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -/** \file - * \ingroup datatoc - */ - -#include -#include -#include -#include -#include - -/* for bool */ -#include "../blenlib/BLI_sys_types.h" - -/* for DIR */ -#if !defined(WIN32) || defined(FREEWINDOWS) -# include -#endif - -#include - -/* for Win32 DIR functions */ -#ifdef WIN32 -# include "../blenlib/BLI_winstuff.h" -#endif - -#ifdef WIN32 -# define SEP '\\' -#else -# define SEP '/' -#endif - -/* -------------------------------------------------------------------- */ -/** \name Endian Defines - * \{ */ - -#define L_ENDIAN 1 -#define B_ENDIAN 0 -#ifdef __BIG_ENDIAN__ -# define ENDIAN_ORDER B_ENDIAN -#else -# define ENDIAN_ORDER L_ENDIAN -#endif - -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name Utility Functions - * \{ */ - -static bool path_test_extension(const char *filepath, const char *ext) -{ - const size_t a = strlen(filepath); - const size_t b = strlen(ext); - return !(a == 0 || b == 0 || b >= a) && (strcmp(ext, filepath + a - b) == 0); -} - -static void endian_switch_uint32(uint *val) -{ - uint tval = *val; - *val = (tval >> 24) | ((tval << 8) & 0x00ff0000) | ((tval >> 8) & 0x0000ff00) | (tval << 24); -} - -static const char *path_slash_rfind(const char *path) -{ - const char *const lfslash = strrchr(path, '/'); - const char *const lbslash = strrchr(path, '\\'); - - if (!lfslash) { - return lbslash; - } - if (!lbslash) { - return lfslash; - } - - return (lfslash > lbslash) ? lfslash : lbslash; -} - -static const char *path_basename(const char *path) -{ - const char *const filename = path_slash_rfind(path); - return filename ? filename + 1 : path; -} - -static bool path_join(char *filepath, - size_t filepath_maxncpy, - const char *dirpath, - const char *filename) -{ - int dirpath_len = strlen(dirpath); - if (dirpath_len && dirpath[dirpath_len - 1] == SEP) { - dirpath_len--; - } - const int filename_len = strlen(filename); - if (dirpath_len + 1 + filename_len + 1 > filepath_maxncpy) { - return false; - } - memcpy(filepath, dirpath, dirpath_len); - filepath[dirpath_len] = SEP; - memcpy(filepath + dirpath_len + 1, filename, filename_len + 1); - return true; -} - -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name Write a PNG from RGBA Pixels - * \{ */ - -static bool write_png(const char *filepath, const uint *pixels, const int width, const int height) -{ - png_structp png_ptr; - png_infop info_ptr; - png_bytepp row_pointers = nullptr; - - FILE *fp; - - const int bytesperpixel = 4; - const int compression = 9; - int i; - - fp = fopen(filepath, "wb"); - if (fp == nullptr) { - printf("%s: Cannot open file for writing '%s'\n", __func__, filepath); - return false; - } - - png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr); - if (png_ptr == nullptr) { - printf("%s: Cannot png_create_write_struct for file: '%s'\n", __func__, filepath); - fclose(fp); - return false; - } - - info_ptr = png_create_info_struct(png_ptr); - if (info_ptr == nullptr) { - png_destroy_write_struct(&png_ptr, (png_infopp) nullptr); - printf("%s: Cannot png_create_info_struct for file: '%s'\n", __func__, filepath); - fclose(fp); - return false; - } - - if (setjmp(png_jmpbuf(png_ptr))) { - png_destroy_write_struct(&png_ptr, &info_ptr); - printf("%s: Cannot setjmp for file: '%s'\n", __func__, filepath); - fclose(fp); - return false; - } - - /* write the file */ - png_init_io(png_ptr, fp); - - png_set_compression_level(png_ptr, compression); - - /* png image settings */ - png_set_IHDR(png_ptr, - info_ptr, - width, - height, - 8, - PNG_COLOR_TYPE_RGBA, - PNG_INTERLACE_NONE, - PNG_COMPRESSION_TYPE_DEFAULT, - PNG_FILTER_TYPE_DEFAULT); - - /* write the file header information */ - png_write_info(png_ptr, info_ptr); - - if (ENDIAN_ORDER == L_ENDIAN) { - png_set_swap(png_ptr); - } - - /* allocate memory for an array of row-pointers */ - row_pointers = (png_bytepp)malloc(height * sizeof(png_bytep)); - if (row_pointers == nullptr) { - printf("%s: Cannot allocate row-pointers array for file '%s'\n", __func__, filepath); - png_destroy_write_struct(&png_ptr, &info_ptr); - if (fp) { - fclose(fp); - } - return false; - } - - /* set the individual row-pointers to point at the correct offsets */ - for (i = 0; i < height; i++) { - row_pointers[height - 1 - i] = (png_bytep)(((const uchar *)pixels) + - (i * width) * bytesperpixel * sizeof(uchar)); - } - - /* write out the entire image data in one call */ - png_write_image(png_ptr, row_pointers); - - /* write the additional chunks to the PNG file (not really needed) */ - png_write_end(png_ptr, info_ptr); - - /* clean up */ - free(row_pointers); - png_destroy_write_struct(&png_ptr, &info_ptr); - - fflush(fp); - fclose(fp); - - return true; -} - -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name Merge Icon-Data from Files - * \{ */ - -struct IconHead { - uint icon_w, icon_h; - uint orig_x, orig_y; - uint canvas_w, canvas_h; -}; - -struct IconInfo { - IconHead head; - char *file_name; -}; - -struct IconMergeContext { - /* Information about all icons read from disk. - * Is used for sanity checks like prevention of two files defining icon for - * the same position on canvas. */ - int num_read_icons; - IconInfo *read_icons; -}; - -static void icon_merge_context_init(IconMergeContext *context) -{ - context->num_read_icons = 0; - context->read_icons = nullptr; -} - -/* Get icon information from the context which matches given icon head. - * Is used to check whether icon is re-defined, and to provide useful information about which - * files are conflicting. */ -static IconInfo *icon_merge_context_info_for_icon_head(IconMergeContext *context, - const IconHead *icon_head) -{ - if (context->read_icons == nullptr) { - return nullptr; - } - - for (int i = 0; i < context->num_read_icons; i++) { - IconInfo *read_icon_info = &context->read_icons[i]; - const IconHead *read_icon_head = &read_icon_info->head; - if (read_icon_head->orig_x == icon_head->orig_x && read_icon_head->orig_y == icon_head->orig_y) - { - return read_icon_info; - } - } - - return nullptr; -} - -static void icon_merge_context_register_icon(IconMergeContext *context, - const char *file_name, - const IconHead *icon_head) -{ - context->read_icons = static_cast( - realloc(context->read_icons, sizeof(IconInfo) * (context->num_read_icons + 1))); - - IconInfo *icon_info = &context->read_icons[context->num_read_icons]; - icon_info->head = *icon_head; - icon_info->file_name = strdup(path_basename(file_name)); - - context->num_read_icons++; -} - -static void icon_merge_context_free(IconMergeContext *context) -{ - if (context->read_icons != nullptr) { - for (int i = 0; i < context->num_read_icons; i++) { - free(context->read_icons[i].file_name); - } - free(context->read_icons); - } -} - -static bool icon_decode_head(FILE *f_src, IconHead *r_head) -{ - if (fread(r_head, 1, sizeof(*r_head), f_src) == sizeof(*r_head)) { - if (ENDIAN_ORDER == B_ENDIAN) { - endian_switch_uint32(&r_head->icon_w); - endian_switch_uint32(&r_head->icon_h); - endian_switch_uint32(&r_head->orig_x); - endian_switch_uint32(&r_head->orig_y); - endian_switch_uint32(&r_head->canvas_w); - endian_switch_uint32(&r_head->canvas_h); - } - return true; - } - - return false; -} - -static bool icon_decode(FILE *f_src, IconHead *r_head, uint **r_pixels) -{ - uint *pixels; - uint pixels_size; - - if (!icon_decode_head(f_src, r_head)) { - printf("%s: failed to read header\n", __func__); - return false; - } - - pixels_size = sizeof(char[4]) * r_head->icon_w * r_head->icon_h; - pixels = static_cast(malloc(pixels_size)); - if (pixels == nullptr) { - printf("%s: failed to allocate pixels\n", __func__); - return false; - } - - if (fread(pixels, 1, pixels_size, f_src) != pixels_size) { - printf("%s: failed to read pixels\n", __func__); - free(pixels); - return false; - } - - *r_pixels = pixels; - return true; -} - -static bool icon_read(const char *file_src, IconHead *r_head, uint **r_pixels) -{ - FILE *f_src; - bool success; - - f_src = fopen(file_src, "rb"); - if (f_src == nullptr) { - printf("%s: failed to open '%s'\n", __func__, file_src); - return false; - } - - success = icon_decode(f_src, r_head, r_pixels); - - fclose(f_src); - return success; -} - -static bool icon_merge(IconMergeContext *context, - const char *file_src, - uint32_t **r_pixels_canvas, - uint *r_canvas_w, - uint *r_canvas_h) -{ - IconHead head; - uint *pixels; - - uint x, y; - - /* canvas */ - uint32_t *pixels_canvas; - uint canvas_w, canvas_h; - - if (!icon_read(file_src, &head, &pixels)) { - return false; - } - - const IconInfo *read_icon_info = icon_merge_context_info_for_icon_head(context, &head); - if (read_icon_info != nullptr) { - printf( - "Conflicting icon files %s and %s\n", path_basename(file_src), read_icon_info->file_name); - free(pixels); - return false; - } - icon_merge_context_register_icon(context, file_src, &head); - - if (*r_canvas_w == 0) { - /* init once */ - *r_canvas_w = head.canvas_w; - *r_canvas_h = head.canvas_h; - *r_pixels_canvas = static_cast( - calloc(1, (head.canvas_w * head.canvas_h) * sizeof(uint32_t))); - } - - canvas_w = *r_canvas_w; - canvas_h = *r_canvas_h; - pixels_canvas = *r_pixels_canvas; - - assert(head.canvas_w == canvas_w); - assert(head.canvas_h == canvas_h); - - for (x = 0; x < head.icon_w; x++) { - for (y = 0; y < head.icon_h; y++) { - uint pixel; - uint dst_x, dst_y; - uint pixel_xy_dst; - - /* get pixel */ - pixel = pixels[(y * head.icon_w) + x]; - - /* set pixel */ - dst_x = head.orig_x + x; - dst_y = head.orig_y + y; - pixel_xy_dst = (dst_y * canvas_w) + dst_x; - assert(pixel_xy_dst < (canvas_w * canvas_h)); - pixels_canvas[pixel_xy_dst] = pixel; - } - } - - free(pixels); - - /* only for bounds check */ - (void)canvas_h; - - return true; -} - -static bool icondir_to_png(const char *path_src, const char *file_dst) -{ - /* Takes a path full of 'dat' files and writes out */ - DIR *dir; - const dirent *fname; - char filepath[1024]; - int found = 0, fail = 0; - - IconMergeContext context; - - uint32_t *pixels_canvas = nullptr; - uint canvas_w = 0, canvas_h = 0; - - icon_merge_context_init(&context); - - errno = 0; - dir = opendir(path_src); - if (dir == nullptr) { - printf( - "%s: failed to dir '%s', (%s)\n", __func__, path_src, errno ? strerror(errno) : "unknown"); - return false; - } - - while ((fname = readdir(dir)) != nullptr) { - if (path_test_extension(fname->d_name, ".dat")) { - if (!path_join(filepath, sizeof(filepath), path_src, fname->d_name)) { - printf("%s: path is too long (%s, %s)\n", __func__, path_src, fname->d_name); - return false; - } - if (icon_merge(&context, filepath, &pixels_canvas, &canvas_w, &canvas_h)) { - found++; - } - else { - fail++; - } - } - } - - icon_merge_context_free(&context); - - closedir(dir); - - if (found == 0) { - printf("%s: dir '%s' has no icons\n", __func__, path_src); - } - - if (fail != 0) { - printf("%s: dir '%s' failed %d icons\n", __func__, path_src, fail); - } - - /* Write pixels. */ - write_png(file_dst, pixels_canvas, canvas_w, canvas_h); - - free(pixels_canvas); - - return (fail == 0); -} - -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name Main & Parse Arguments - * \{ */ - -int main(int argc, char **argv) -{ - const char *path_src; - const char *file_dst; - - if (argc < 3) { - printf("Usage: datatoc_icon \n"); - exit(1); - } - - path_src = argv[1]; - file_dst = argv[2]; - - return (icondir_to_png(path_src, file_dst) == true) ? 0 : 1; -} - -/** \} */ diff --git a/source/blender/datatoc/datatoc_icon.py b/source/blender/datatoc/datatoc_icon.py deleted file mode 100755 index f7c839839b4..00000000000 --- a/source/blender/datatoc/datatoc_icon.py +++ /dev/null @@ -1,146 +0,0 @@ -#!/usr/bin/env python3 -# SPDX-FileCopyrightText: 2014-2022 Blender Authors -# -# SPDX-License-Identifier: GPL-2.0-or-later - -_IS_BIG_ENDIAN = (__import__("sys").byteorder != 'little') - - -def write_png(buf, width, height): - import zlib - import struct - # reverse the vertical line order and add null bytes at the start - width_byte_4 = width * 4 - raw_data = b"".join( - b'\x00' + buf[span:span + width_byte_4] - for span in range((height - 1) * width * 4, -1, - width_byte_4) - ) - - def png_pack(png_tag, data): - chunk_head = png_tag + data - return struct.pack("!I", len(data)) + chunk_head + struct.pack("!I", 0xFFFFFFFF & zlib.crc32(chunk_head)) - - return b"".join([ - b'\x89PNG\r\n\x1a\n', - png_pack(b'IHDR', struct.pack("!2I5B", width, height, 8, 6, 0, 0, 0)), - png_pack(b'IDAT', zlib.compress(raw_data, 9)), - png_pack(b'IEND', b'')]) - - -def icon_decode_head(f_src): - import struct - - # 2 ints - temp_data = f_src.read(4 * 2) - icon_w, icon_h = struct.unpack('<2I', temp_data) - - temp_data = f_src.read(4 * 2) - orig_x, orig_y = struct.unpack('<2I', temp_data) - - temp_data = f_src.read(4 * 2) - canvas_w, canvas_h = struct.unpack('<2I', temp_data) - - return (icon_w, icon_h, - orig_x, orig_y, - canvas_w, canvas_h) - - -def icon_decode(f_src): - head = icon_decode_head(f_src) - - (icon_w, icon_h, - orig_x, orig_y, - canvas_w, canvas_h) = head - - # pixels - import array - - pixels = f_src.read(icon_w * icon_h * 4) - pixels = array.array('I', pixels) - if _IS_BIG_ENDIAN: - pixels.byteswap() - - return head, pixels - - -def icon_read(file_src): - with open(file_src, 'rb') as f_src: - head, pixels = icon_decode(f_src) - return head, pixels - - -def icon_merge(file_src, pixels_canvas, canvas_w, canvas_h): - """ Takes an icon filepath and merges into a pixel array - """ - head, pixels = icon_read(file_src) - - (icon_w, icon_h, - orig_x, orig_y, - w_canvas_test, h_canvas_test) = head - - assert w_canvas_test == canvas_w - assert h_canvas_test == canvas_h - - for x in range(icon_w): - for y in range(icon_h): - # get pixel - pixel = pixels[(y * icon_w) + x] - - # set pixel - dst_x = orig_x + x - dst_y = orig_y + y - pixels_canvas[(dst_y * canvas_w) + dst_x] = pixel - - -def icondir_to_png(path_src, file_dst): - """ Takes a path full of 'dat' files and writes out - """ - import os - import array - - files = [os.path.join(path_src, f) for f in os.listdir(path_src) if f.endswith(".dat")] - - # First check if we need to bother. - if os.path.exists(file_dst): - dst_time = os.path.getmtime(file_dst) - has_newer = False - for f in files: - if os.path.getmtime(f) > dst_time: - has_newer = True - break - if not has_newer: - return - - with open(files[0], 'rb') as f_src: - (icon_w, icon_h, - orig_x, orig_y, - canvas_w, canvas_h) = icon_decode_head(f_src) - - # load in pixel data - pixels_canvas = array.array('I', [0]) * (canvas_w * canvas_h) - for f in files: - icon_merge(f, pixels_canvas, canvas_w, canvas_h) - - # write pixels - with open(file_dst, 'wb') as f_dst: - pixels_data = pixels_canvas.tobytes() - image_data = write_png(pixels_data, canvas_w, canvas_h) - f_dst.write(image_data) - - -def main_ex(argv): - import os - - path_src = argv[-2].rstrip(os.sep) - file_dst = argv[-1] - - icondir_to_png(path_src, file_dst) - - -def main(): - import sys - main_ex(sys.argv) - - -if __name__ == "__main__": - main() diff --git a/source/blender/datatoc/datatoc_icon_split.py b/source/blender/datatoc/datatoc_icon_split.py deleted file mode 100755 index 177314b048d..00000000000 --- a/source/blender/datatoc/datatoc_icon_split.py +++ /dev/null @@ -1,302 +0,0 @@ -# SPDX-FileCopyrightText: 2014-2022 Blender Authors -# -# SPDX-License-Identifier: GPL-2.0-or-later - -""" -This script dices up PNG into small files to store in version control. - -Example: - -./blender.bin \ - --background \ - --python ./release/datafiles/icon_dice.py -- \ - --image=./release/datafiles/blender_icons16.png \ - --output=./release/datafiles/blender_icons16 - --output_prefix=icon16_ - --name_style=UI_ICONS - --parts_x 26 --parts_y 32 \ - --minx=10 --maxx 10 --miny 10 --maxy 10 - --minx_icon 2 --maxx_icon 2 --miny_icon 2 --maxy_icon 2 \ - --spacex_icon 1 --spacey_icon 1 - -""" - -import os - -SOURCE_DIR = os.path.normpath(os.path.join(os.path.dirname(__file__), "..", "..", "..")) -VERBOSE = False - - -def image_from_file__bpy(filepath): - import bpy - - image = bpy.data.images.load(filepath) - image.reload() - - pixel_w, pixel_h = image.size - pixels = image.pixels[:] - return pixels, pixel_w, pixel_h - - -def image_from_file(filepath): - """ - Return pixels, w, h from an image. - - note: bpy import is ONLY used here. - """ - - try: - import bpy - except ImportError: - bpy = None - - if bpy is not None: - pixels, pixel_w, pixel_h = image_from_file__bpy(filepath) - # else: - # pixels, pixel_w, pixel_h = image_from_file__py(filepath) - - return pixels, pixel_w, pixel_h - - -def write_subimage(sub_x, sub_y, sub_w, sub_h, - filepath, - pixels, pixel_w, pixel_h): - import struct - - # first check if the icon is worth writing - is_fill = False - for y in range(sub_h): - for x in range(sub_w): - i = (sub_x + x) + ((sub_y + y) * pixel_w) - a = pixels[(i * 4) + 3] - if a != 0.0: - is_fill = True - break - - if not is_fill: - # print("skipping:", filepath) - return - - with open(filepath, 'wb') as f: - - f.write( - struct.pack( - '<6I', - sub_w, sub_h, - sub_x, sub_y, - # redundant but including to maintain consistency - pixel_w, pixel_h, - )) - - for y in range(sub_h): - for x in range(sub_w): - i = (sub_x + x) + ((sub_y + y) * pixel_w) - rgba = pixels[(i * 4):(i * 4) + 4] - c = sum((int(p * 255) << (8 * i)) for i, p in enumerate(rgba)) - f.write(struct.pack(" BRUSH_NUDGE - re_icon = re.compile(r'^\s*DEF_ICON.*\(\s*([A-Za-z0-9_]+)\s*\).*$') - - ui_icons_h = os.path.join(SOURCE_DIR, "source", "blender", "editors", "include", "UI_icons.hh") - with open(ui_icons_h, 'r', encoding="utf-8") as f: - for l in f: - match = re_icon.search(l) - if match: - if l.find('DEF_ICON_BLANK') == -1: - icon_name = match.group(1).lower() - print(icon_name) - _dice_icon_name_cache[count] = icon_name - count += 1 - # ---- Done with icon cache - - index = (y * parts_x) + x - if index not in _dice_icon_name_cache: - return None - - icon_name = _dice_icon_name_cache[index] - - # for debugging its handy to sort by number - # ~ id_str = "%03d_%s%s.dat" % (index, prefix, icon_name) - - id_str = "%s%s.dat" % (prefix, icon_name) - - elif name_style == "": - # flip so icons are numbered from top-left - # because new icons will be added at the bottom - y_flip = parts_y - (y + 1) - id_str = "%s%02xx%02x.dat" % (prefix, x, y_flip) - else: - raise Exception("Invalid '--name_style' arg") - - return id_str - - -def dice( - filepath, output, output_prefix, name_style, - parts_x, parts_y, - minx, miny, maxx, maxy, - minx_icon, miny_icon, maxx_icon, maxy_icon, - spacex_icon, spacey_icon, -): - - is_simple = (max( - minx, miny, maxx, maxy, - minx_icon, miny_icon, maxx_icon, maxy_icon, - spacex_icon, spacey_icon) == 0) - - pixels, pixel_w, pixel_h = image_from_file(filepath) - - if not (pixel_w and pixel_h): - print("Image not found %r!" % filepath) - return - - if not os.path.exists(output): - os.mkdir(output) - - if is_simple: - pixels_w_clip = pixel_w - pixels_h_clip = pixel_h - - icon_w = pixels_w_clip // parts_x - icon_h = pixels_h_clip // parts_y - icon_w_clip = icon_w - icon_h_clip = icon_h - else: - pixels_w_clip = pixel_w - (minx + maxx) - pixels_h_clip = pixel_h - (miny + maxy) - - icon_w = (pixels_w_clip - ((parts_x - 1) * spacex_icon)) // parts_x - icon_h = (pixels_h_clip - ((parts_y - 1) * spacey_icon)) // parts_y - icon_w_clip = icon_w - (minx_icon + maxx_icon) - icon_h_clip = icon_h - (miny_icon + maxy_icon) - - print(pixel_w, pixel_h, icon_w, icon_h) - - for x in range(parts_x): - for y in range(parts_y): - id_str = dice_icon_name( - x, y, - parts_x, parts_y, - name_style=name_style, prefix=output_prefix, - ) - if not id_str: - continue - - filepath = os.path.join(output, id_str) - if VERBOSE: - print(" writing:", filepath) - - # simple, no margins - if is_simple: - sub_x = x * icon_w - sub_y = y * icon_h - else: - sub_x = minx + ((x * (icon_w + spacex_icon)) + minx_icon) - sub_y = miny + ((y * (icon_h + spacey_icon)) + miny_icon) - - write_subimage(sub_x, sub_y, icon_w_clip, icon_h_clip, - filepath, - pixels, pixel_w, pixel_h) - - -def main(): - import sys - import argparse - - epilog = "Run this after updating the SVG file" - - argv = sys.argv - - if "--" not in argv: - argv = [] - else: - argv = argv[argv.index("--") + 1:] - - parser = argparse.ArgumentParser(description=__doc__, epilog=epilog) - - # File path options - parser.add_argument( - "--image", dest="image", metavar='FILE', - help="Image file", - ) - parser.add_argument( - "--output", dest="output", metavar='DIR', - help="Output directory", - ) - parser.add_argument( - "--output_prefix", dest="output_prefix", metavar='STRING', - help="Output prefix", - ) - - # Icon naming option - parser.add_argument( - "--name_style", dest="name_style", metavar='ENUM', type=str, - choices=('', 'UI_ICONS'), - help="The method used for naming output data", - ) - - # Options for dicing up the image - parser.add_argument( - "--parts_x", dest="parts_x", metavar='INT', type=int, - help="Grid X parts", - ) - parser.add_argument( - "--parts_y", dest="parts_y", metavar='INT', type=int, - help="Grid Y parts", - ) - - _help = "Inset from the outer edge (in pixels)" - parser.add_argument("--minx", dest="minx", metavar='INT', type=int, help=_help) - parser.add_argument("--miny", dest="miny", metavar='INT', type=int, help=_help) - parser.add_argument("--maxx", dest="maxx", metavar='INT', type=int, help=_help) - parser.add_argument("--maxy", dest="maxy", metavar='INT', type=int, help=_help) - - _help = "Inset from each icons bounds (in pixels)" - parser.add_argument("--minx_icon", dest="minx_icon", metavar='INT', type=int, help=_help) - parser.add_argument("--miny_icon", dest="miny_icon", metavar='INT', type=int, help=_help) - parser.add_argument("--maxx_icon", dest="maxx_icon", metavar='INT', type=int, help=_help) - parser.add_argument("--maxy_icon", dest="maxy_icon", metavar='INT', type=int, help=_help) - - _help = "Empty space between icons" - parser.add_argument("--spacex_icon", dest="spacex_icon", metavar='INT', type=int, help=_help) - parser.add_argument("--spacey_icon", dest="spacey_icon", metavar='INT', type=int, help=_help) - - del _help - - args = parser.parse_args(argv) - - if not argv: - print("No args given!") - parser.print_help() - return - - dice(args.image, args.output, args.output_prefix, args.name_style, - args.parts_x, args.parts_y, - args.minx, args.miny, args.maxx, args.maxy, - args.minx_icon, args.miny_icon, args.maxx_icon, args.maxy_icon, - args.spacex_icon, args.spacey_icon, - ) - - -if __name__ == "__main__": - main() diff --git a/source/blender/datatoc/datatoc_icon_split_to_png.py b/source/blender/datatoc/datatoc_icon_split_to_png.py deleted file mode 100755 index 6278befa7f7..00000000000 --- a/source/blender/datatoc/datatoc_icon_split_to_png.py +++ /dev/null @@ -1,60 +0,0 @@ -#!/usr/bin/env python3 -# SPDX-FileCopyrightText: 2014-2022 Blender Authors -# -# SPDX-License-Identifier: GPL-2.0-or-later - -# This script is just to view the icons - - -def write_png(buf, width, height): - import zlib - import struct - # reverse the vertical line order and add null bytes at the start - width_byte_4 = width * 4 - raw_data = b"".join( - b'\x00' + buf[span:span + width_byte_4] - for span in range((height - 1) * width * 4, -1, - width_byte_4) - ) - - def png_pack(png_tag, data): - chunk_head = png_tag + data - return struct.pack("!I", len(data)) + chunk_head + struct.pack("!I", 0xFFFFFFFF & zlib.crc32(chunk_head)) - - return b"".join([ - b'\x89PNG\r\n\x1a\n', - png_pack(b'IHDR', struct.pack("!2I5B", width, height, 8, 6, 0, 0, 0)), - png_pack(b'IDAT', zlib.compress(raw_data, 9)), - png_pack(b'IEND', b'')]) - - -def icondata_to_png(file_src, file_dst): - import struct - - with open(file_src, 'rb') as f_src: - # 2 ints - temp_data = f_src.read(4 * 2) - w, h = struct.unpack('<2I', temp_data) - temp_data = f_src.read(4 * 2) # (x, y) - ignored - temp_data = f_src.read(4 * 2) # (xfrom, yfrom) - ignored - # pixels - temp_data = f_src.read(w * h * 4) - - buf = write_png(temp_data, w, h) - - with open(file_dst, 'wb') as f_dst: - f_dst.write(buf) - - -def main(): - import sys - import os - - for arg in sys.argv[1:]: - file_src = arg - file_dst = os.path.splitext(arg)[0] + ".png" - - icondata_to_png(file_src, file_dst) - - -if __name__ == "__main__": - main()