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
|
# components
|
||||||
|
|
||||||
if(WIN32)
|
add_subdirectory(tools)
|
||||||
add_subdirectory(tools)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
add_subdirectory(src)
|
add_subdirectory(src)
|
||||||
add_subdirectory(exposed)
|
add_subdirectory(exposed)
|
||||||
|
|
|
@ -51,10 +51,10 @@ for use due to bugs in this toolkit.
|
||||||
|
|
||||||
### Building for Windows
|
### 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:
|
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:
|
Before building, check out the submodules:
|
||||||
|
|
||||||
|
|
|
@ -79,26 +79,30 @@ endif()
|
||||||
|
|
||||||
# generated files
|
# 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(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)
|
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(
|
add_custom_command(
|
||||||
OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/built/bitmapextra.table.h"
|
OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/built/bitmapextra.table.h"
|
||||||
COMMAND "${PERL_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/pngchar2c.pl"
|
COMMAND "${PERL_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/pngchar2c.pl"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/built/bitmapextra.table.h"
|
"${CMAKE_CURRENT_SOURCE_DIR}/built/bitmapextra.table.h"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}"
|
"${CMAKE_CURRENT_SOURCE_DIR}"
|
||||||
MAIN_DEPENDENCY "${CMAKE_CURRENT_SOURCE_DIR}/pngchar2c.pl"
|
MAIN_DEPENDENCY "${CMAKE_CURRENT_SOURCE_DIR}/pngchar2c.pl"
|
||||||
DEPENDENCIES ${icons})
|
DEPENDS ${icons})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(WIN32 AND NOT DISABLE_TTF2C)
|
if(WIN32 AND NOT DISABLE_TTF2C)
|
||||||
|
@ -110,8 +114,10 @@ endif()
|
||||||
set(generated_HEADERS
|
set(generated_HEADERS
|
||||||
built/bitmapextra.table.h
|
built/bitmapextra.table.h
|
||||||
built/bitmapfont.table.h
|
built/bitmapfont.table.h
|
||||||
built/icons-proto.h
|
${CMAKE_CURRENT_BINARY_DIR}/generated/icons.h)
|
||||||
built/icons.h)
|
|
||||||
|
set(generated_SOURCES
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/generated/icons.cpp)
|
||||||
|
|
||||||
set_source_files_properties(${generated_HEADERS}
|
set_source_files_properties(${generated_HEADERS}
|
||||||
PROPERTIES GENERATED TRUE)
|
PROPERTIES GENERATED TRUE)
|
||||||
|
@ -306,6 +312,7 @@ add_executable(solvespace WIN32 MACOSX_BUNDLE
|
||||||
${platform_HEADERS}
|
${platform_HEADERS}
|
||||||
${platform_SOURCES}
|
${platform_SOURCES}
|
||||||
${platform_BUNDLED_RESOURCES}
|
${platform_BUNDLED_RESOURCES}
|
||||||
|
${generated_SOURCES}
|
||||||
${generated_HEADERS}
|
${generated_HEADERS}
|
||||||
${solvespace_HEADERS}
|
${solvespace_HEADERS}
|
||||||
${solvespace_SOURCES})
|
${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.
|
// Copyright 2008-2013 Jonathan Westhues.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
#include "solvespace.h"
|
#include "solvespace.h"
|
||||||
#include <icons-proto.h>
|
#include "generated/icons.h"
|
||||||
|
|
||||||
const TextWindow::Color TextWindow::fgColors[] = {
|
const TextWindow::Color TextWindow::fgColors[] = {
|
||||||
{ 'd', RGBi(255, 255, 255) },
|
{ 'd', RGBi(255, 255, 255) },
|
||||||
|
|
|
@ -6,8 +6,7 @@
|
||||||
// Copyright 2008-2013 Jonathan Westhues.
|
// Copyright 2008-2013 Jonathan Westhues.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
#include "solvespace.h"
|
#include "solvespace.h"
|
||||||
#include <icons-proto.h>
|
#include "generated/icons.h"
|
||||||
#include <icons.h>
|
|
||||||
|
|
||||||
static uint8_t SPACER[1];
|
static uint8_t SPACER[1];
|
||||||
static const struct {
|
static const struct {
|
||||||
|
|
|
@ -1,4 +1,19 @@
|
||||||
add_executable(ttf2c
|
include_directories(
|
||||||
ttf2c.cpp)
|
${PNG_INCLUDE_DIRS})
|
||||||
target_link_libraries(ttf2c
|
|
||||||
comctl32)
|
link_directories(
|
||||||
|
${PNG_LIBRARY_DIRS})
|
||||||
|
|
||||||
|
if(WIN32)
|
||||||
|
add_executable(ttf2c
|
||||||
|
ttf2c.cpp)
|
||||||
|
|
||||||
|
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