diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 5305b889e..5a49416e2 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -56,6 +56,7 @@ Other changes: - Misc: changed embedded ProggyClean encoding to save a bit of binary space (~12kb to 9.5kb). - Misc: added IMGUI_DISABLE_DEFAULT_FONT to strip embedded font from binary. (#8161) [@demonese] +- Tools: binary_to_compressed_c: added -u8/-u32/-base85 export options. - Demo: example tree used by Property Editor & Selection demos properly freed on application closure. (#8158) [@Legulysse] - Examples: Win32+DX12: Using a basic free-list allocator to manage multiple diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 0f74a98b3..5647f53fd 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -4583,11 +4583,11 @@ static unsigned int stb_decompress(unsigned char *output, const unsigned char *i // MIT license (see License.txt in http://www.proggyfonts.net/index.php?menu=download) // Download and more information at http://www.proggyfonts.net or http://upperboundsinteractive.com/fonts.php //----------------------------------------------------------------------------- -// File: 'ProggyClean.ttf' (41208 bytes) -// Exported using "misc/fonts/binary_to_compressed_c.exe ../ProggyClean.ttf proggy_clean_ttf_compressed (with compression, no base85 encoding). -//----------------------------------------------------------------------------- #ifndef IMGUI_DISABLE_DEFAULT_FONT + +// File: 'ProggyClean.ttf' (41208 bytes) +// Exported using binary_to_compressed_c.exe -u8 "ProggyClean.ttf" proggy_clean_ttf static const unsigned int proggy_clean_ttf_compressed_size = 9583; static const unsigned char proggy_clean_ttf_compressed_data[9583] = { diff --git a/misc/fonts/binary_to_compressed_c.cpp b/misc/fonts/binary_to_compressed_c.cpp index f16c3b2c3..b0a243a71 100644 --- a/misc/fonts/binary_to_compressed_c.cpp +++ b/misc/fonts/binary_to_compressed_c.cpp @@ -2,10 +2,11 @@ // (binary_to_compressed_c.cpp) // Helper tool to turn a file into a C array, if you want to embed font data in your source code. -// The data is first compressed with stb_compress() to reduce source code size, -// then encoded in Base85 to fit in a string so we can fit roughly 4 bytes of compressed data into 5 bytes of source code (suggested by @mmalex) -// (If we used 32-bit constants it would require take 11 bytes of source code to encode 4 bytes, and be endianness dependent) -// Note that even with compression, the output array is likely to be bigger than the binary file.. +// The data is first compressed with stb_compress() to reduce source code size. +// Then stored in a C array: +// - Base85: ~5 bytes of source code for 4 bytes of input data. 5 bytes stored in binary (suggested by @mmalex). +// - As int: ~11 bytes of source code for 4 bytes of input data. 4 bytes stored in binary. Endianness dependant, need swapping on big-endian CPU. +// - As char: ~12 bytes of source code for 4 bytes of input data. 4 bytes stored in binary. Not endianness dependant. // Load compressed TTF fonts with ImGui::GetIO().Fonts->AddFontFromMemoryCompressedTTF() // Build with, e.g: @@ -15,10 +16,12 @@ // You can also find a precompiled Windows binary in the binary/demo package available from https://github.com/ocornut/imgui // Usage: -// binary_to_compressed_c.exe [-base85] [-nocompress] [-nostatic] +// binary_to_compressed_c.exe [-nocompress] [-nostatic] [-base85] // Usage example: // # binary_to_compressed_c.exe myfont.ttf MyFont > myfont.cpp // # binary_to_compressed_c.exe -base85 myfont.ttf MyFont > myfont.cpp +// Note: +// Base85 encoding will be obsoleted by future version of Dear ImGui! #define _CRT_SECURE_NO_WARNINGS #include @@ -31,23 +34,36 @@ typedef unsigned int stb_uint; typedef unsigned char stb_uchar; stb_uint stb_compress(stb_uchar* out, stb_uchar* in, stb_uint len); -static bool binary_to_compressed_c(const char* filename, const char* symbol, bool use_base85_encoding, bool use_compression, bool use_static); +enum SourceEncoding +{ + SourceEncoding_U8, // New default since 2024/11 + SourceEncoding_U32, + SourceEncoding_Base85, +}; + +static bool binary_to_compressed_c(const char* filename, const char* symbol, SourceEncoding source_encoding, bool use_compression, bool use_static); int main(int argc, char** argv) { if (argc < 3) { - printf("Syntax: %s [-base85] [-nocompress] [-nostatic] \n", argv[0]); + printf("Syntax: %s [-u8|-u32|-base85] [-nocompress] [-nostatic] \n", argv[0]); + printf("Source encoding types:\n"); + printf(" -u8 = ~12 bytes of source per 4 bytes of data. 4 bytes in binary.\n"); + printf(" -u32 = ~11 bytes of source per 4 bytes of data. 4 bytes in binary. Need endianness swapping on big-endian.\n"); + printf(" -base85 = ~5 bytes of source per 4 bytes of data. 5 bytes in binary. Need decoder.\n"); return 0; } int argn = 1; - bool use_base85_encoding = false; bool use_compression = true; bool use_static = true; + SourceEncoding source_encoding = SourceEncoding_U8; // New default while (argn < (argc - 2) && argv[argn][0] == '-') { - if (strcmp(argv[argn], "-base85") == 0) { use_base85_encoding = true; argn++; } + if (strcmp(argv[argn], "-u8") == 0) { source_encoding = SourceEncoding_U8; argn++; } + else if (strcmp(argv[argn], "-u32") == 0) { source_encoding = SourceEncoding_U32; argn++; } + else if (strcmp(argv[argn], "-base85") == 0) { source_encoding = SourceEncoding_Base85; argn++; } else if (strcmp(argv[argn], "-nocompress") == 0) { use_compression = false; argn++; } else if (strcmp(argv[argn], "-nostatic") == 0) { use_static = false; argn++; } else @@ -57,7 +73,7 @@ int main(int argc, char** argv) } } - bool ret = binary_to_compressed_c(argv[argn], argv[argn + 1], use_base85_encoding, use_compression, use_static); + bool ret = binary_to_compressed_c(argv[argn], argv[argn + 1], source_encoding, use_compression, use_static); if (!ret) fprintf(stderr, "Error opening or reading file: '%s'\n", argv[argn]); return ret ? 0 : 1; @@ -69,7 +85,7 @@ char Encode85Byte(unsigned int x) return (char)((x >= '\\') ? x + 1 : x); } -bool binary_to_compressed_c(const char* filename, const char* symbol, bool use_base85_encoding, bool use_compression, bool use_static) +bool binary_to_compressed_c(const char* filename, const char* symbol, SourceEncoding source_encoding, bool use_compression, bool use_static) { // Read file FILE* f = fopen(filename, "rb"); @@ -91,11 +107,11 @@ bool binary_to_compressed_c(const char* filename, const char* symbol, bool use_b // Output as Base85 encoded FILE* out = stdout; fprintf(out, "// File: '%s' (%d bytes)\n", filename, (int)data_sz); - fprintf(out, "// Exported using binary_to_compressed_c.cpp\n"); const char* static_str = use_static ? "static " : ""; const char* compressed_str = use_compression ? "compressed_" : ""; - if (use_base85_encoding) + if (source_encoding == SourceEncoding_Base85) { + fprintf(out, "// Exported using binary_to_compressed_c.exe -base85 \"%s\" %s\n", filename, symbol); fprintf(out, "%sconst char %s_%sdata_base85[%d+1] =\n \"", static_str, symbol, compressed_str, (int)((compressed_sz + 3) / 4)*5); char prev_c = 0; for (int src_i = 0; src_i < compressed_sz; src_i += 4) @@ -113,10 +129,10 @@ bool binary_to_compressed_c(const char* filename, const char* symbol, bool use_b } fprintf(out, "\";\n\n"); } -#if 0 - else + else if (source_encoding == SourceEncoding_U8) { // As individual bytes, not subject to endianness issues. + fprintf(out, "// Exported using binary_to_compressed_c.exe -u8 \"%s\" %s\n", filename, symbol); fprintf(out, "%sconst unsigned int %s_%ssize = %d;\n", static_str, symbol, compressed_str, (int)compressed_sz); fprintf(out, "%sconst unsigned char %s_%sdata[%d] =\n{", static_str, symbol, compressed_str, (int)compressed_sz); int column = 0; @@ -131,10 +147,10 @@ bool binary_to_compressed_c(const char* filename, const char* symbol, bool use_b } fprintf(out, "\n};\n\n"); } -#else - else + else if (source_encoding == SourceEncoding_U32) { // As integers + fprintf(out, "// Exported using binary_to_compressed_c.exe -u32 \"%s\" %s\n", filename, symbol); fprintf(out, "%sconst unsigned int %s_%ssize = %d;\n", static_str, symbol, compressed_str, (int)compressed_sz); fprintf(out, "%sconst unsigned int %s_%sdata[%d/4] =\n{", static_str, symbol, compressed_str, (int)((compressed_sz + 3) / 4)*4); int column = 0; @@ -148,7 +164,6 @@ bool binary_to_compressed_c(const char* filename, const char* symbol, bool use_b } fprintf(out, "\n};\n\n"); } -#endif // Cleanup delete[] data;