Rewrite png2c.pl in C++.
This allows us to always generate icons during build, and in the future remove a Perl dependency.
This commit is contained in:
parent
b23336b589
commit
f76f76ff60
|
@ -141,9 +141,6 @@ endif()
|
|||
|
||||
# components
|
||||
|
||||
if(WIN32)
|
||||
add_subdirectory(tools)
|
||||
endif()
|
||||
|
||||
add_subdirectory(tools)
|
||||
add_subdirectory(src)
|
||||
add_subdirectory(exposed)
|
||||
|
|
|
@ -51,10 +51,10 @@ for use due to bugs in this toolkit.
|
|||
|
||||
### Building for Windows
|
||||
|
||||
You will need CMake and a Windows cross-compiler.
|
||||
You will need CMake, a Windows cross-compiler, and Wine with binfmt support.
|
||||
On a Debian derivative (e.g. Ubuntu) these can be installed with:
|
||||
|
||||
apt-get install mingw-w64 cmake
|
||||
apt-get install cmake mingw-w64 wine-binfmt
|
||||
|
||||
Before building, check out the submodules:
|
||||
|
||||
|
|
|
@ -79,26 +79,30 @@ endif()
|
|||
|
||||
# generated files
|
||||
|
||||
# `$<TARGET_FILE:tool>` allows us to use binfmt support on Linux
|
||||
# without special-casing anything; running `tool.exe` would succeed
|
||||
# but unlike Windows, Linux does not have the machinery to map
|
||||
# an invocation of `tool` to an executable `tool.exe` in $PATH.
|
||||
|
||||
file(GLOB icons "${CMAKE_CURRENT_SOURCE_DIR}/icons/*.png")
|
||||
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/generated")
|
||||
add_custom_command(
|
||||
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/generated/icons.cpp"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/generated/icons.h"
|
||||
COMMAND $<TARGET_FILE:png2c>
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/generated/icons.cpp"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/generated/icons.h"
|
||||
${icons}
|
||||
DEPENDS png2c ${icons})
|
||||
|
||||
if(PERL_FOUND AND PERLMODULES_FOUND)
|
||||
add_custom_command(
|
||||
OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/built/icons.h"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/built/icons-proto.h"
|
||||
COMMAND "${PERL_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/png2c.pl"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/built/icons.h"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/built/icons-proto.h"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
MAIN_DEPENDENCY "${CMAKE_CURRENT_SOURCE_DIR}/png2c.pl"
|
||||
DEPENDENCIES ${icons})
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/built/bitmapextra.table.h"
|
||||
COMMAND "${PERL_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/pngchar2c.pl"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/built/bitmapextra.table.h"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
MAIN_DEPENDENCY "${CMAKE_CURRENT_SOURCE_DIR}/pngchar2c.pl"
|
||||
DEPENDENCIES ${icons})
|
||||
DEPENDS ${icons})
|
||||
endif()
|
||||
|
||||
if(WIN32 AND NOT DISABLE_TTF2C)
|
||||
|
@ -110,8 +114,10 @@ endif()
|
|||
set(generated_HEADERS
|
||||
built/bitmapextra.table.h
|
||||
built/bitmapfont.table.h
|
||||
built/icons-proto.h
|
||||
built/icons.h)
|
||||
${CMAKE_CURRENT_BINARY_DIR}/generated/icons.h)
|
||||
|
||||
set(generated_SOURCES
|
||||
${CMAKE_CURRENT_BINARY_DIR}/generated/icons.cpp)
|
||||
|
||||
set_source_files_properties(${generated_HEADERS}
|
||||
PROPERTIES GENERATED TRUE)
|
||||
|
@ -306,6 +312,7 @@ add_executable(solvespace WIN32 MACOSX_BUNDLE
|
|||
${platform_HEADERS}
|
||||
${platform_SOURCES}
|
||||
${platform_BUNDLED_RESOURCES}
|
||||
${generated_SOURCES}
|
||||
${generated_HEADERS}
|
||||
${solvespace_HEADERS}
|
||||
${solvespace_SOURCES})
|
||||
|
|
|
@ -1,40 +0,0 @@
|
|||
/**** This is a generated file - do not edit ****/
|
||||
|
||||
extern unsigned char Icon_angle[24*24*3];
|
||||
extern unsigned char Icon_arc[24*24*3];
|
||||
extern unsigned char Icon_assemble[24*24*3];
|
||||
extern unsigned char Icon_bezier[24*24*3];
|
||||
extern unsigned char Icon_circle[24*24*3];
|
||||
extern unsigned char Icon_constraint[24*24*3];
|
||||
extern unsigned char Icon_construction[24*24*3];
|
||||
extern unsigned char Icon_edges[24*24*3];
|
||||
extern unsigned char Icon_equal[24*24*3];
|
||||
extern unsigned char Icon_extrude[24*24*3];
|
||||
extern unsigned char Icon_faces[24*24*3];
|
||||
extern unsigned char Icon_hidden_lines[24*24*3];
|
||||
extern unsigned char Icon_horiz[24*24*3];
|
||||
extern unsigned char Icon_in3d[24*24*3];
|
||||
extern unsigned char Icon_length[24*24*3];
|
||||
extern unsigned char Icon_line[24*24*3];
|
||||
extern unsigned char Icon_mesh[24*24*3];
|
||||
extern unsigned char Icon_normal[24*24*3];
|
||||
extern unsigned char Icon_ontoworkplane[24*24*3];
|
||||
extern unsigned char Icon_other_supp[24*24*3];
|
||||
extern unsigned char Icon_parallel[24*24*3];
|
||||
extern unsigned char Icon_perpendicular[24*24*3];
|
||||
extern unsigned char Icon_point[24*24*3];
|
||||
extern unsigned char Icon_pointonx[24*24*3];
|
||||
extern unsigned char Icon_rectangle[24*24*3];
|
||||
extern unsigned char Icon_ref[24*24*3];
|
||||
extern unsigned char Icon_same_orientation[24*24*3];
|
||||
extern unsigned char Icon_shaded[24*24*3];
|
||||
extern unsigned char Icon_sketch_in_3d[24*24*3];
|
||||
extern unsigned char Icon_sketch_in_plane[24*24*3];
|
||||
extern unsigned char Icon_step_rotate[24*24*3];
|
||||
extern unsigned char Icon_step_translate[24*24*3];
|
||||
extern unsigned char Icon_symmetric[24*24*3];
|
||||
extern unsigned char Icon_tangent_arc[24*24*3];
|
||||
extern unsigned char Icon_text[24*24*3];
|
||||
extern unsigned char Icon_trim[24*24*3];
|
||||
extern unsigned char Icon_vert[24*24*3];
|
||||
extern unsigned char Icon_workplane[24*24*3];
|
22004
src/built/icons.h
22004
src/built/icons.h
File diff suppressed because it is too large
Load Diff
52
src/png2c.pl
52
src/png2c.pl
|
@ -1,52 +0,0 @@
|
|||
#!/usr/bin/env perl
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use GD;
|
||||
|
||||
my ($out, $proto, $srcdir) = @ARGV;
|
||||
defined($srcdir) or $srcdir = '.';
|
||||
-d "$srcdir/icons" || die "$srcdir/icons/: directory not found";
|
||||
|
||||
open(OUT, ">$out") or die "$out: $!";
|
||||
open(PROTO, ">$proto") or die "$proto: $!";
|
||||
|
||||
print OUT "/**** This is a generated file - do not edit ****/\n\n";
|
||||
print PROTO "/**** This is a generated file - do not edit ****/\n\n";
|
||||
|
||||
for my $file (<$srcdir/icons/*.png>) {
|
||||
next if $file =~ m#/char-[^/]+$#;
|
||||
|
||||
$file =~ m#/([^/]+)\.png$#;
|
||||
my $base = "Icon_$1";
|
||||
$base =~ y/-/_/;
|
||||
|
||||
open(PNG, $file) or die "$file: $!\n";
|
||||
my $img = newFromPng GD::Image(\*PNG) or die;
|
||||
$img->trueColor(1);
|
||||
|
||||
close PNG;
|
||||
|
||||
my ($width, $height) = $img->getBounds();
|
||||
die "$file: $width, $height" if ($width != 24) or ($height != 24);
|
||||
|
||||
print PROTO "extern unsigned char $base\[24*24*3\];\n";
|
||||
print OUT "unsigned char $base\[24*24*3] = {\n";
|
||||
|
||||
for(my $y = 0; $y < 24; $y++) {
|
||||
for(my $x = 0; $x < 24; $x++) {
|
||||
my $index = $img->getPixel($x, 23-$y);
|
||||
my ($r, $g, $b) = $img->rgb($index);
|
||||
if($r + $g + $b < 11) {
|
||||
($r, $g, $b) = (30, 30, 30);
|
||||
}
|
||||
printf OUT " 0x%02x, 0x%02x, 0x%02x,\n", $r, $g, $b;
|
||||
}
|
||||
}
|
||||
|
||||
print OUT "};\n\n";
|
||||
}
|
||||
|
||||
close PROTO;
|
||||
close OUT;
|
|
@ -4,7 +4,7 @@
|
|||
// Copyright 2008-2013 Jonathan Westhues.
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "solvespace.h"
|
||||
#include <icons-proto.h>
|
||||
#include "generated/icons.h"
|
||||
|
||||
const TextWindow::Color TextWindow::fgColors[] = {
|
||||
{ 'd', RGBi(255, 255, 255) },
|
||||
|
|
|
@ -6,8 +6,7 @@
|
|||
// Copyright 2008-2013 Jonathan Westhues.
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "solvespace.h"
|
||||
#include <icons-proto.h>
|
||||
#include <icons.h>
|
||||
#include "generated/icons.h"
|
||||
|
||||
static uint8_t SPACER[1];
|
||||
static const struct {
|
||||
|
|
|
@ -1,4 +1,19 @@
|
|||
add_executable(ttf2c
|
||||
include_directories(
|
||||
${PNG_INCLUDE_DIRS})
|
||||
|
||||
link_directories(
|
||||
${PNG_LIBRARY_DIRS})
|
||||
|
||||
if(WIN32)
|
||||
add_executable(ttf2c
|
||||
ttf2c.cpp)
|
||||
target_link_libraries(ttf2c
|
||||
|
||||
target_link_libraries(ttf2c
|
||||
comctl32)
|
||||
endif()
|
||||
|
||||
add_executable(png2c
|
||||
png2c.cpp)
|
||||
|
||||
target_link_libraries(png2c
|
||||
${PNG_LIBRARIES})
|
||||
|
|
125
tools/png2c.cpp
Normal file
125
tools/png2c.cpp
Normal file
|
@ -0,0 +1,125 @@
|
|||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <png.h>
|
||||
|
||||
#define die(msg) do { fprintf(stderr, "%s\n", msg); abort(); } while(0)
|
||||
|
||||
void write_png(FILE *out, const char *filename) {
|
||||
FILE *fp = fopen(filename, "rb");
|
||||
if (!fp)
|
||||
die("png fopen failed");
|
||||
|
||||
png_byte header[8] = {};
|
||||
if(fread(header, 1, 8, fp) != 8)
|
||||
die("png fread failed");
|
||||
|
||||
if(png_sig_cmp(header, 0, 8))
|
||||
die("png_sig_cmp failed");
|
||||
|
||||
png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||
if(!png)
|
||||
die("png_create_read_struct failed");
|
||||
|
||||
png_set_expand(png);
|
||||
png_set_strip_alpha(png);
|
||||
|
||||
png_infop png_info = png_create_info_struct(png);
|
||||
if (!png_info)
|
||||
die("png_create_info_struct failed");
|
||||
|
||||
if (setjmp(png_jmpbuf(png)))
|
||||
die("png_init_io failed");
|
||||
|
||||
png_init_io(png, fp);
|
||||
png_set_sig_bytes(png, 8);
|
||||
|
||||
png_read_info(png, png_info);
|
||||
|
||||
int width = png_get_image_width(png, png_info);
|
||||
int height = png_get_image_height(png, png_info);
|
||||
if(width != 24 || height != 24)
|
||||
die("not a 24x24 png");
|
||||
|
||||
png_read_update_info(png, png_info);
|
||||
|
||||
if (setjmp(png_jmpbuf(png)))
|
||||
die("png_read_image failed");
|
||||
|
||||
png_bytepp image = (png_bytepp) malloc(sizeof(png_bytep) * height);
|
||||
for (int y = 0; y < height; y++)
|
||||
image[y] = (png_bytep) malloc(png_get_rowbytes(png, png_info));
|
||||
|
||||
png_read_image(png, (png_bytepp) image);
|
||||
|
||||
for(int y = height - 1; y >= 0; y--) {
|
||||
for(int x = 0; x < (int)png_get_rowbytes(png, png_info); x += 3) {
|
||||
unsigned char r = image[y][x + 0],
|
||||
g = image[y][x + 1],
|
||||
b = image[y][x + 2];
|
||||
|
||||
if(r + g + b < 11)
|
||||
r = g = b = 30;
|
||||
fprintf(out, " 0x%02x, 0x%02x, 0x%02x,\n", r, g, b);
|
||||
}
|
||||
}
|
||||
|
||||
for (int y = 0; y < height; y++)
|
||||
free(image[y]);
|
||||
free(image);
|
||||
|
||||
fclose(fp);
|
||||
|
||||
png_destroy_read_struct(&png, &png_info, NULL);
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
if(argc < 3) {
|
||||
fprintf(stderr, "Usage: %s <source out> <header out> <png in>...\n",
|
||||
argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
FILE *source = fopen(argv[1], "wt");
|
||||
if(!source)
|
||||
die("source fopen failed");
|
||||
|
||||
FILE *header = fopen(argv[2], "wt");
|
||||
if(!header)
|
||||
die("header fopen failed");
|
||||
|
||||
fprintf(source, "/**** This is a generated file - do not edit ****/\n\n");
|
||||
fprintf(header, "/**** This is a generated file - do not edit ****/\n\n");
|
||||
|
||||
for(int i = 3; i < argc; i++) {
|
||||
const char *filename = argv[i];
|
||||
if(strstr(filename, "char-"))
|
||||
continue;
|
||||
|
||||
const char *basename = strrchr(filename, '/'); /* cmake uses / even on Windows */
|
||||
if(basename == NULL) {
|
||||
basename = filename;
|
||||
} else {
|
||||
basename++; // skip separator
|
||||
}
|
||||
|
||||
char *stemname = (char*) calloc(strlen(basename), 1);
|
||||
strncpy(stemname, basename, strchr(basename, '.') - basename);
|
||||
for(size_t j = 0; j < strlen(stemname); j++) {
|
||||
if(!isalnum(stemname[j]))
|
||||
stemname[j] = '_';
|
||||
}
|
||||
|
||||
fprintf(header, "extern unsigned char Icon_%s[24*24*3];\n", stemname);
|
||||
|
||||
fprintf(source, "unsigned char Icon_%s[24*24*3] = {\n", stemname);
|
||||
write_png(source, filename);
|
||||
fprintf(source, "};\n\n");
|
||||
|
||||
free(stemname);
|
||||
}
|
||||
|
||||
fclose(source);
|
||||
fclose(header);
|
||||
}
|
Loading…
Reference in New Issue
Block a user