Changeset View
Changeset View
Standalone View
Standalone View
source/blender/datatoc/datatoc_icon.py
| Show All 39 Lines | return b"".join([ | ||||
| png_pack(b'IHDR', struct.pack("!2I5B", width, height, 8, 6, 0, 0, 0)), | 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'IDAT', zlib.compress(raw_data, 9)), | ||||
| png_pack(b'IEND', b'')]) | png_pack(b'IEND', b'')]) | ||||
| def icon_decode_head(f_src): | def icon_decode_head(f_src): | ||||
| import struct | import struct | ||||
| # 2 ints | |||||
| temp_data = f_src.read(4 * 2) | temp_data = f_src.read(4 * 2) | ||||
| icon_w, icon_h = struct.unpack('<2I', temp_data) | icon_w, icon_h = struct.unpack('<2I', temp_data) | ||||
| temp_data = f_src.read(4 * 2) | svg_hash = f_src.read(16) | ||||
| 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, | return (icon_w, icon_h, svg_hash) | ||||
| orig_x, orig_y, | |||||
| canvas_w, canvas_h) | |||||
| def icon_decode(f_src): | def icon_decode(f_src): | ||||
| head = icon_decode_head(f_src) | head = icon_decode_head(f_src) | ||||
| (icon_w, icon_h, | (icon_w, icon_h, svg_hash) = head | ||||
| orig_x, orig_y, | |||||
| canvas_w, canvas_h) = head | |||||
| # pixels | # pixels | ||||
| import array | import array | ||||
| pixels = f_src.read(icon_w * icon_h * 4) | pixels = f_src.read(icon_w * icon_h * 4) | ||||
| pixels = array.array('I', pixels) | pixels = array.array('I', pixels) | ||||
| if _IS_BIG_ENDIAN: | if _IS_BIG_ENDIAN: | ||||
| pixels.byteswap() | pixels.byteswap() | ||||
| return head, pixels | return head, pixels | ||||
| def icon_read(file_src): | def icon_read(file_src): | ||||
| with open(file_src, 'rb') as f_src: | with open(file_src, 'rb') as f_src: | ||||
| head, pixels = icon_decode(f_src) | head, pixels = icon_decode(f_src) | ||||
| return head, pixels | return head, pixels | ||||
| def icon_merge(file_src, pixels_canvas, canvas_w, canvas_h): | def icon_merge(file_src, pixels_canvas, canvas_w, canvas_h, sub_x, sub_y): | ||||
| """ Takes an icon filepath and merges into a pixel array | """ Takes an icon filepath and merges into a pixel array | ||||
| """ | """ | ||||
| head, pixels = icon_read(file_src) | head, pixels = icon_read(file_src) | ||||
| (icon_w, icon_h, | (icon_w, icon_h, svg_hash) = head | ||||
| 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 x in range(icon_w): | ||||
| for y in range(icon_h): | for y in range(icon_h): | ||||
| # get pixel | # get pixel | ||||
| pixel = pixels[(y * icon_w) + x] | pixel = pixels[(y * icon_w) + x] | ||||
| # set pixel | # set pixel | ||||
| dst_x = orig_x + x | dst_x = sub_x + x | ||||
| dst_y = orig_y + y | dst_y = sub_y + y | ||||
| pixels_canvas[(dst_y * canvas_w) + dst_x] = pixel | pixels_canvas[(dst_y * canvas_w) + dst_x] = pixel | ||||
| def icondir_to_png(path_src, file_dst): | def get_icon_names(): | ||||
| import os | |||||
| import re | |||||
| # Search for, e.g. "DEF_ICON(BRUSH_NUDGE)" and get "BRUSH_NUDGE". | |||||
| re_icon = re.compile(r'^\s*DEF_ICON.*\(\s*([A-Za-z0-9_]+)\s*\).*$') | |||||
| icon_name_cache = {} | |||||
| count = 0 | |||||
| SOURCE_DIR = os.path.normpath(os.path.join(os.path.dirname(__file__), "..", "..", "..")) | |||||
| ui_icons_h = os.path.join(SOURCE_DIR, "source", "blender", "editors", "include", "UI_icons.h") | |||||
| 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) | |||||
| if icon_name not in ("none", "blank1"): | |||||
| icon_name_cache[count] = icon_name | |||||
| count += 1 | |||||
| return icon_name_cache | |||||
| def icondir_to_png(path_src, file_dst, icon_prefix): | |||||
| """ Takes a path full of 'dat' files and writes out | """ Takes a path full of 'dat' files and writes out | ||||
| """ | """ | ||||
| import os | import os | ||||
| import array | import array | ||||
| files = [os.path.join(path_src, f) for f in os.listdir(path_src) if f.endswith(".dat")] | 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. | # First check if we need to bother. | ||||
| if os.path.exists(file_dst): | if os.path.exists(file_dst): | ||||
| dst_time = os.path.getmtime(file_dst) | dst_time = os.path.getmtime(file_dst) | ||||
| has_newer = False | has_newer = False | ||||
| for f in files: | for f in files: | ||||
| if os.path.getmtime(f) > dst_time: | if os.path.getmtime(f) > dst_time: | ||||
| has_newer = True | has_newer = True | ||||
| break | break | ||||
| if not has_newer: | if not has_newer: | ||||
| return | return | ||||
| with open(files[0], 'rb') as f_src: | with open(files[0], 'rb') as f_src: | ||||
| (icon_w, icon_h, | (icon_w, icon_h, svg_hash) = icon_decode_head(f_src) | ||||
| orig_x, orig_y, | |||||
| canvas_w, canvas_h) = icon_decode_head(f_src) | # Match the definition in 'interface_icons.c'. | ||||
| ICON_GRID_COLS = 26 | |||||
| ICON_GRID_ROWS = 30 | |||||
| ICON_GRID_MARGIN = 10 | |||||
| ICON_GRID_W = 32 | |||||
| ICON_GRID_H = 32 | |||||
| resolution_divider = ICON_GRID_W // icon_w | |||||
| canvas_w = ICON_GRID_COLS * (ICON_GRID_W + ICON_GRID_MARGIN) + ICON_GRID_MARGIN | |||||
| canvas_h = ICON_GRID_ROWS * (ICON_GRID_H + ICON_GRID_MARGIN) + ICON_GRID_MARGIN | |||||
| canvas_w //= resolution_divider | |||||
| canvas_h //= resolution_divider | |||||
| # load in pixel data | |||||
| pixels_canvas = array.array('I', [0]) * (canvas_w * canvas_h) | pixels_canvas = array.array('I', [0]) * (canvas_w * canvas_h) | ||||
| for f in files: | |||||
| icon_merge(f, pixels_canvas, canvas_w, canvas_h) | icon_name_cache = get_icon_names() | ||||
| for y in range(ICON_GRID_ROWS): | |||||
| for x in range(ICON_GRID_COLS): | |||||
| i = y * ICON_GRID_COLS + x | |||||
| if i not in icon_name_cache: | |||||
| continue | |||||
| sub_x = x * (ICON_GRID_W + ICON_GRID_MARGIN) + ICON_GRID_MARGIN | |||||
| sub_y = y * (ICON_GRID_H + ICON_GRID_MARGIN) + ICON_GRID_MARGIN | |||||
| sub_x //= resolution_divider | |||||
| sub_y //= resolution_divider | |||||
| # Load in pixel data. | |||||
| file_src = os.path.join(path_src, "%s%s.dat" % (icon_prefix, icon_name_cache[i])) | |||||
| icon_merge(file_src, pixels_canvas, canvas_w, canvas_h, sub_x, sub_y) | |||||
| # write pixels | # write pixels | ||||
| with open(file_dst, 'wb') as f_dst: | with open(file_dst, 'wb') as f_dst: | ||||
| pixels_data = pixels_canvas.tobytes() | pixels_data = pixels_canvas.tobytes() | ||||
| image_data = write_png(pixels_data, canvas_w, canvas_h) | image_data = write_png(pixels_data, canvas_w, canvas_h) | ||||
| f_dst.write(image_data) | f_dst.write(image_data) | ||||
| def main_ex(argv): | def main_ex(argv): | ||||
| import os | import os | ||||
| path_src = argv[-2].rstrip(os.sep) | path_src = argv[-3].rstrip(os.sep) | ||||
| file_dst = argv[-1] | file_dst = argv[-2] | ||||
| icon_prefix = argv[-1] | |||||
| icondir_to_png(path_src, file_dst) | icondir_to_png(path_src, file_dst, icon_prefix) | ||||
| def main(): | def main(): | ||||
| import sys | import sys | ||||
| main_ex(sys.argv) | main_ex(sys.argv) | ||||
| if __name__ == "__main__": | if __name__ == "__main__": | ||||
| main() | main() | ||||