Move icons to res/icons/; remove png2c.

This commit integrates icons in the resource system so that they
can be loaded (or reloaded, without restarting) in @2x mode, which
will be added in a future commit. png2c is no longer necessary.

png2c used to perform the following transformation:
  if(r + g + b < 11) r = g = b = 11;

This is now achieved by switching the icons to RGBA mode and adding
alpha channel with the following imagemagick invocation, which is
equivalent to the transformation above:
  for i in *.png; do
    convert -fuzz 4% -channel rgba -matte \
            -fill "rgba(255,255,255,0)" -opaque black \
            $i $i
  done

The Debian package solvespace now includes /usr/share/solvespace;
this should be split out into solvespace-data later.
pull/10/head
whitequark 2016-04-22 13:35:22 +00:00
parent fa546af28f
commit a525f03371
93 changed files with 265 additions and 235 deletions

View File

@ -1,3 +1,4 @@
usr/bin/solvespace usr/bin/solvespace
usr/share/icons usr/share/icons
usr/share/applications usr/share/applications
usr/share/solvespace

View File

@ -96,6 +96,13 @@ else() # Unix
endfunction() endfunction()
endif() endif()
function(add_resources)
foreach(name ${ARGN})
add_resource(${name})
set(resource_list "${resource_list}" PARENT_SCOPE)
endforeach()
endfunction()
# Second, register all resources. # Second, register all resources.
if(WIN32) if(WIN32)
add_resource(win32/icon.ico RT_ICON_GROUP APP_ICON) add_resource(win32/icon.ico RT_ICON_GROUP APP_ICON)
@ -117,7 +124,50 @@ else()
RENAME application.x-solvespace.png) RENAME application.x-solvespace.png)
endforeach() endforeach()
endif() endif()
add_resource(banner.txt)
add_resources(
banner.txt
icons/graphics-window/angle.png
icons/graphics-window/arc.png
icons/graphics-window/assemble.png
icons/graphics-window/bezier.png
icons/graphics-window/circle.png
icons/graphics-window/construction.png
icons/graphics-window/equal.png
icons/graphics-window/extrude.png
icons/graphics-window/horiz.png
icons/graphics-window/in3d.png
icons/graphics-window/lathe.png
icons/graphics-window/length.png
icons/graphics-window/line.png
icons/graphics-window/ontoworkplane.png
icons/graphics-window/other-supp.png
icons/graphics-window/parallel.png
icons/graphics-window/perpendicular.png
icons/graphics-window/pointonx.png
icons/graphics-window/point.png
icons/graphics-window/rectangle.png
icons/graphics-window/ref.png
icons/graphics-window/same-orientation.png
icons/graphics-window/sketch-in-3d.png
icons/graphics-window/sketch-in-plane.png
icons/graphics-window/step-rotate.png
icons/graphics-window/step-translate.png
icons/graphics-window/symmetric.png
icons/graphics-window/tangent-arc.png
icons/graphics-window/text.png
icons/graphics-window/trim.png
icons/graphics-window/vert.png
icons/text-window/constraint.png
icons/text-window/edges.png
icons/text-window/faces.png
icons/text-window/hidden-lines.png
icons/text-window/mesh.png
icons/text-window/normal.png
icons/text-window/outlines.png
icons/text-window/point.png
icons/text-window/shaded.png
icons/text-window/workplane.png)
# Third, distribute the resources. # Third, distribute the resources.
add_custom_target(resources add_custom_target(resources

Binary file not shown.

After

Width:  |  Height:  |  Size: 819 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 686 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 454 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 710 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 801 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 739 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 920 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 620 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 418 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 512 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 401 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 480 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 511 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 412 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 916 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 531 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 427 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 394 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 596 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 418 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 413 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 673 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 597 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 507 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 871 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 411 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 515 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 666 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 784 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 575 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 515 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 557 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 703 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 683 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 539 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 639 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 733 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 394 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 403 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 462 B

View File

@ -84,17 +84,6 @@ endif()
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/generated) file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/generated)
file(GLOB icons ${CMAKE_CURRENT_SOURCE_DIR}/icons/*.png)
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}
VERBATIM)
file(GLOB chars ${CMAKE_CURRENT_SOURCE_DIR}/fonts/private/*.png) file(GLOB chars ${CMAKE_CURRENT_SOURCE_DIR}/fonts/private/*.png)
list(SORT chars) list(SORT chars)
add_custom_command( add_custom_command(
@ -119,11 +108,7 @@ add_custom_command(
set(generated_HEADERS set(generated_HEADERS
${CMAKE_CURRENT_BINARY_DIR}/generated/vectorfont.table.h ${CMAKE_CURRENT_BINARY_DIR}/generated/vectorfont.table.h
${CMAKE_CURRENT_BINARY_DIR}/generated/bitmapfont.table.h ${CMAKE_CURRENT_BINARY_DIR}/generated/bitmapfont.table.h)
${CMAKE_CURRENT_BINARY_DIR}/generated/icons.h)
set(generated_SOURCES
${CMAKE_CURRENT_BINARY_DIR}/generated/icons.cpp)
# platform dependencies # platform dependencies
@ -241,7 +226,6 @@ add_executable(solvespace WIN32 MACOSX_BUNDLE
${libslvs_SOURCES} ${libslvs_SOURCES}
${util_SOURCES} ${util_SOURCES}
${platform_SOURCES} ${platform_SOURCES}
${generated_SOURCES}
${generated_HEADERS} ${generated_HEADERS}
${solvespace_HEADERS} ${solvespace_HEADERS}
${solvespace_SOURCES} ${solvespace_SOURCES}

View File

@ -876,44 +876,31 @@ void ssglBitmapText(const std::string &str, Vector p)
glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_2D);
} }
void ssglDrawPixelsWithTexture(uint8_t *data, int w, int h) void ssglDrawPixmap(const Pixmap &pixmap, bool flip) {
{
#define MAX_DIM 32
static uint8_t Texture[MAX_DIM*MAX_DIM*3];
int i, j;
if(w > MAX_DIM || h > MAX_DIM) oops();
for(i = 0; i < w; i++) {
for(j = 0; j < h; j++) {
Texture[(j*MAX_DIM + i)*3 + 0] = data[(j*w + i)*3 + 0];
Texture[(j*MAX_DIM + i)*3 + 1] = data[(j*w + i)*3 + 1];
Texture[(j*MAX_DIM + i)*3 + 2] = data[(j*w + i)*3 + 2];
}
}
glBindTexture(GL_TEXTURE_2D, TEXTURE_DRAW_PIXELS); glBindTexture(GL_TEXTURE_2D, TEXTURE_DRAW_PIXELS);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, MAX_DIM, MAX_DIM, 0, int format = pixmap.hasAlpha ? GL_RGBA : GL_RGB;
GL_RGB, GL_UNSIGNED_BYTE, Texture); glTexImage2D(GL_TEXTURE_2D, 0, format, pixmap.width, pixmap.height, 0,
format, GL_UNSIGNED_BYTE, pixmap.data.get());
glEnable(GL_TEXTURE_2D); glEnable(GL_TEXTURE_2D);
glBegin(GL_QUADS); glBegin(GL_QUADS);
glTexCoord2d(0, 0); glTexCoord2d(0.0, flip ? 0.0 : 1.0);
glVertex2d(0, h); glVertex2d(0.0, (double)pixmap.height);
glTexCoord2d(((double)w)/MAX_DIM, 0); glTexCoord2d(1.0, flip ? 0.0 : 1.0);
glVertex2d(w, h); glVertex2d((double)pixmap.width, (double)pixmap.height);
glTexCoord2d(((double)w)/MAX_DIM, ((double)h)/MAX_DIM); glTexCoord2d(1.0, flip ? 1.0 : 0.0);
glVertex2d(w, 0); glVertex2d((double)pixmap.width, 0.0);
glTexCoord2d(0, ((double)h)/MAX_DIM); glTexCoord2d(0.0, flip ? 1.0 : 0.0);
glVertex2d(0, 0); glVertex2d(0.0, 0.0);
glEnd(); glEnd();
glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_2D);
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 609 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 544 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 171 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 930 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 317 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 395 B

View File

@ -4,9 +4,14 @@
// Copyright 2016 whitequark // Copyright 2016 whitequark
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "solvespace.h" #include "solvespace.h"
#include <png.h>
namespace SolveSpace { namespace SolveSpace {
//-----------------------------------------------------------------------------
// Resource loading functions
//-----------------------------------------------------------------------------
std::string LoadString(const std::string &name) { std::string LoadString(const std::string &name) {
size_t size; size_t size;
const void *data = LoadResource(name, &size); const void *data = LoadResource(name, &size);
@ -15,4 +20,105 @@ std::string LoadString(const std::string &name) {
return std::string(static_cast<const char *>(data), size); return std::string(static_cast<const char *>(data), size);
} }
Pixmap LoadPNG(const std::string &name) {
size_t size;
const void *data = LoadResource(name, &size);
if(data == NULL) oops();
Pixmap pixmap = Pixmap::FromPNG(static_cast<const uint8_t *>(data), size);
if(pixmap.IsEmpty()) oops();
return pixmap;
}
//-----------------------------------------------------------------------------
// Pixmap manipulation
//-----------------------------------------------------------------------------
void Pixmap::Clear() {
*this = {};
}
static Pixmap ReadPNGIntoPixmap(png_struct *png_ptr, png_info *info_ptr) {
png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_EXPAND | PNG_TRANSFORM_GRAY_TO_RGB, NULL);
Pixmap pixmap = {};
pixmap.width = png_get_image_width(png_ptr, info_ptr);
pixmap.height = png_get_image_height(png_ptr, info_ptr);
pixmap.hasAlpha = png_get_color_type(png_ptr, info_ptr) & PNG_COLOR_MASK_ALPHA;
size_t stride = pixmap.width * pixmap.GetBytesPerPixel();
if(stride % 4 != 0) stride += 4 - stride % 4;
pixmap.stride = stride;
pixmap.data = std::unique_ptr<uint8_t[]>(new uint8_t[pixmap.stride * pixmap.height]);
uint8_t **rows = png_get_rows(png_ptr, info_ptr);
for(size_t y = 0; y < pixmap.height; y++) {
memcpy(&pixmap.data[pixmap.stride * y], rows[y],
pixmap.width * pixmap.GetBytesPerPixel());
}
return pixmap;
}
Pixmap Pixmap::FromPNG(const uint8_t *data, size_t size) {
Pixmap pixmap = {};
struct Slice { const uint8_t *data; size_t size; };
Slice dataSlice = { data, size };
png_struct *png_ptr = NULL;
png_info *info_ptr = NULL;
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if(!png_ptr) goto exit;
info_ptr = png_create_info_struct(png_ptr);
if(!info_ptr) goto exit;
if(setjmp(png_jmpbuf(png_ptr))) goto exit;
png_set_read_fn(png_ptr, &dataSlice,
[](png_struct *png_ptr, uint8_t *data, size_t size) {
Slice *dataSlice = (Slice *)png_get_io_ptr(png_ptr);
if(size <= dataSlice->size) {
memcpy(data, dataSlice->data, size);
dataSlice->data += size;
dataSlice->size -= size;
} else {
png_error(png_ptr, "EOF");
}
});
pixmap = ReadPNGIntoPixmap(png_ptr, info_ptr);
exit:
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
return pixmap;
}
Pixmap Pixmap::FromPNG(FILE *f) {
Pixmap pixmap = {};
png_struct *png_ptr = NULL;
png_info *info_ptr = NULL;
uint8_t header[8];
if(fread(header, 1, sizeof(header), f) != sizeof(header)) goto exit;
if(png_sig_cmp(header, 0, sizeof(header))) goto exit;
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if(!png_ptr) goto exit;
info_ptr = png_create_info_struct(png_ptr);
if(!info_ptr) goto exit;
if(setjmp(png_jmpbuf(png_ptr))) goto exit;
png_init_io(png_ptr, f);
png_set_sig_bytes(png_ptr, sizeof(header));
pixmap = ReadPNGIntoPixmap(png_ptr, info_ptr);
exit:
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
return pixmap;
}
} }

View File

@ -7,6 +7,8 @@
#ifndef __RESOURCE_H #ifndef __RESOURCE_H
#define __RESOURCE_H #define __RESOURCE_H
class Pixmap;
// Only the following function is platform-specific. // Only the following function is platform-specific.
// It returns a pointer to resource contents that is aligned to at least // It returns a pointer to resource contents that is aligned to at least
// sizeof(void*) and has a global lifetime, or NULL if a resource with // sizeof(void*) and has a global lifetime, or NULL if a resource with
@ -14,5 +16,23 @@
const void *LoadResource(const std::string &name, size_t *size); const void *LoadResource(const std::string &name, size_t *size);
std::string LoadString(const std::string &name); std::string LoadString(const std::string &name);
Pixmap LoadPNG(const std::string &name);
class Pixmap {
public:
size_t width;
size_t height;
size_t stride;
bool hasAlpha;
std::unique_ptr<uint8_t[]> data;
static Pixmap FromPNG(const uint8_t *data, size_t size);
static Pixmap FromPNG(FILE *f);
bool IsEmpty() const { return width == 0 && height == 0; }
size_t GetBytesPerPixel() const { return hasAlpha ? 4 : 3; }
void Clear();
};
#endif #endif

View File

@ -356,7 +356,7 @@ void ssglColorRGB(RgbaColor rgb);
void ssglColorRGBa(RgbaColor rgb, double a); void ssglColorRGBa(RgbaColor rgb, double a);
void ssglDepthRangeOffset(int units); void ssglDepthRangeOffset(int units);
void ssglDepthRangeLockToFront(bool yes); void ssglDepthRangeLockToFront(bool yes);
void ssglDrawPixelsWithTexture(uint8_t *data, int w, int h); void ssglDrawPixmap(const Pixmap &pixmap, bool flip = false);
void ssglInitializeBitmapFont(); void ssglInitializeBitmapFont();
void ssglBitmapText(const std::string &str, Vector p); void ssglBitmapText(const std::string &str, Vector p);
void ssglBitmapCharQuad(char32_t chr, double x, double y); void ssglBitmapCharQuad(char32_t chr, double x, double y);

View File

@ -4,7 +4,6 @@
// Copyright 2008-2013 Jonathan Westhues. // Copyright 2008-2013 Jonathan Westhues.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "solvespace.h" #include "solvespace.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) },
@ -30,19 +29,19 @@ const TextWindow::Color TextWindow::bgColors[] = {
bool TextWindow::SPACER = false; bool TextWindow::SPACER = false;
TextWindow::HideShowIcon TextWindow::hideShowIcons[] = { TextWindow::HideShowIcon TextWindow::hideShowIcons[] = {
{ &(SS.GW.showWorkplanes), Icon_workplane, "workplanes from inactive groups"}, { &(SS.GW.showWorkplanes), "workplane", "workplanes from inactive groups", {} },
{ &(SS.GW.showNormals), Icon_normal, "normals" }, { &(SS.GW.showNormals), "normal", "normals", {} },
{ &(SS.GW.showPoints), Icon_point, "points" }, { &(SS.GW.showPoints), "point", "points", {} },
{ &(SS.GW.showConstraints), Icon_constraint, "constraints and dimensions" }, { &(SS.GW.showConstraints), "constraint", "constraints and dimensions", {} },
{ &(SS.GW.showFaces), Icon_faces, "XXX - special cased" }, { &(SS.GW.showFaces), "faces", "XXX - special cased", {} },
{ &SPACER, 0, 0 }, { &SPACER, 0, 0, {} },
{ &(SS.GW.showShaded), Icon_shaded, "shaded view of solid model" }, { &(SS.GW.showShaded), "shaded", "shaded view of solid model", {} },
{ &(SS.GW.showEdges), Icon_edges, "edges of solid model" }, { &(SS.GW.showEdges), "edges", "edges of solid model", {} },
{ &(SS.GW.showOutlines), Icon_outlines, "outline of solid model" }, { &(SS.GW.showOutlines), "outlines", "outline of solid model", {} },
{ &(SS.GW.showMesh), Icon_mesh, "triangle mesh of solid model" }, { &(SS.GW.showMesh), "mesh", "triangle mesh of solid model", {} },
{ &SPACER, 0, 0 }, { &SPACER, 0, 0, {} },
{ &(SS.GW.showHdnLines), Icon_hidden_lines, "hidden lines" }, { &(SS.GW.showHdnLines), "hidden-lines", "hidden lines", {} },
{ 0, 0, 0 } { 0, 0, 0, {} }
}; };
void TextWindow::MakeColorTable(const Color *in, float *out) { void TextWindow::MakeColorTable(const Color *in, float *out) {
@ -379,13 +378,15 @@ void TextWindow::DrawOrHitTestIcons(int how, double mx, double my)
continue; continue;
} }
if(hsi->icon.IsEmpty()) {
hsi->icon = LoadPNG(ssprintf("icons/text-window/%s.png", hsi->iconName));
}
if(how == PAINT) { if(how == PAINT) {
glPushMatrix(); glPushMatrix();
glTranslated(x, y-24, 0); glTranslated(x, y-24, 0);
// Only thing that matters about the color is the alpha,
// should be one for no transparency
glColor3d(0, 0, 0); glColor3d(0, 0, 0);
ssglDrawPixelsWithTexture(hsi->icon, 24, 24); ssglDrawPixmap(hsi->icon);
glPopMatrix(); glPopMatrix();
if(hsi == hoveredIcon) { if(hsi == hoveredIcon) {
@ -433,7 +434,7 @@ void TextWindow::DrawOrHitTestIcons(int how, double mx, double my)
if(how == PAINT) { if(how == PAINT) {
std::string str; std::string str;
if(tooltippedIcon->icon == Icon_faces) { if(tooltippedIcon->var == &(SS.GW.showFaces)) {
if(SS.GW.showFaces) { if(SS.GW.showFaces) {
str = "Don't make faces selectable with mouse"; str = "Don't make faces selectable with mouse";
} else { } else {

View File

@ -6,52 +6,52 @@
// Copyright 2008-2013 Jonathan Westhues. // Copyright 2008-2013 Jonathan Westhues.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "solvespace.h" #include "solvespace.h"
#include "generated/icons.h"
static uint8_t SPACER[1]; static const char *SPACER = "";
static const struct { static struct {
uint8_t *image; const char *iconName;
int menu; int menu;
const char *tip; const char *tip;
Pixmap icon;
} Toolbar[] = { } Toolbar[] = {
{ Icon_line, GraphicsWindow::MNU_LINE_SEGMENT, "Sketch line segment" }, { "line", GraphicsWindow::MNU_LINE_SEGMENT, "Sketch line segment", {} },
{ Icon_rectangle, GraphicsWindow::MNU_RECTANGLE, "Sketch rectangle" }, { "rectangle", GraphicsWindow::MNU_RECTANGLE, "Sketch rectangle", {} },
{ Icon_circle, GraphicsWindow::MNU_CIRCLE, "Sketch circle" }, { "circle", GraphicsWindow::MNU_CIRCLE, "Sketch circle", {} },
{ Icon_arc, GraphicsWindow::MNU_ARC, "Sketch arc of a circle" }, { "arc", GraphicsWindow::MNU_ARC, "Sketch arc of a circle", {} },
{ Icon_text, GraphicsWindow::MNU_TTF_TEXT, "Sketch curves from text in a TrueType font" }, { "text", GraphicsWindow::MNU_TTF_TEXT, "Sketch curves from text in a TrueType font", {} },
{ Icon_tangent_arc, GraphicsWindow::MNU_TANGENT_ARC, "Create tangent arc at selected point" }, { "tangent-arc", GraphicsWindow::MNU_TANGENT_ARC, "Create tangent arc at selected point", {} },
{ Icon_bezier, GraphicsWindow::MNU_CUBIC, "Sketch cubic Bezier spline" }, { "bezier", GraphicsWindow::MNU_CUBIC, "Sketch cubic Bezier spline", {} },
{ Icon_point, GraphicsWindow::MNU_DATUM_POINT, "Sketch datum point" }, { "point", GraphicsWindow::MNU_DATUM_POINT, "Sketch datum point", {} },
{ Icon_construction, GraphicsWindow::MNU_CONSTRUCTION, "Toggle construction" }, { "construction", GraphicsWindow::MNU_CONSTRUCTION, "Toggle construction", {} },
{ Icon_trim, GraphicsWindow::MNU_SPLIT_CURVES, "Split lines / curves where they intersect" }, { "trim", GraphicsWindow::MNU_SPLIT_CURVES, "Split lines / curves where they intersect", {} },
{ SPACER, 0, 0 }, { SPACER, 0, 0, {} },
{ Icon_length, GraphicsWindow::MNU_DISTANCE_DIA, "Constrain distance / diameter / length" }, { "length", GraphicsWindow::MNU_DISTANCE_DIA, "Constrain distance / diameter / length", {} },
{ Icon_angle, GraphicsWindow::MNU_ANGLE, "Constrain angle" }, { "angle", GraphicsWindow::MNU_ANGLE, "Constrain angle", {} },
{ Icon_horiz, GraphicsWindow::MNU_HORIZONTAL, "Constrain to be horizontal" }, { "horiz", GraphicsWindow::MNU_HORIZONTAL, "Constrain to be horizontal", {} },
{ Icon_vert, GraphicsWindow::MNU_VERTICAL, "Constrain to be vertical" }, { "vert", GraphicsWindow::MNU_VERTICAL, "Constrain to be vertical", {} },
{ Icon_parallel, GraphicsWindow::MNU_PARALLEL, "Constrain to be parallel or tangent" }, { "parallel", GraphicsWindow::MNU_PARALLEL, "Constrain to be parallel or tangent", {} },
{ Icon_perpendicular, GraphicsWindow::MNU_PERPENDICULAR, "Constrain to be perpendicular" }, { "perpendicular", GraphicsWindow::MNU_PERPENDICULAR, "Constrain to be perpendicular", {} },
{ Icon_pointonx, GraphicsWindow::MNU_ON_ENTITY, "Constrain point on line / curve / plane / point" }, { "pointonx", GraphicsWindow::MNU_ON_ENTITY, "Constrain point on line / curve / plane / point", {} },
{ Icon_symmetric, GraphicsWindow::MNU_SYMMETRIC, "Constrain symmetric" }, { "symmetric", GraphicsWindow::MNU_SYMMETRIC, "Constrain symmetric", {} },
{ Icon_equal, GraphicsWindow::MNU_EQUAL, "Constrain equal length / radius / angle" }, { "equal", GraphicsWindow::MNU_EQUAL, "Constrain equal length / radius / angle", {} },
{ Icon_same_orientation,GraphicsWindow::MNU_ORIENTED_SAME, "Constrain normals in same orientation" }, { "same-orientation",GraphicsWindow::MNU_ORIENTED_SAME, "Constrain normals in same orientation", {} },
{ Icon_other_supp, GraphicsWindow::MNU_OTHER_ANGLE, "Other supplementary angle" }, { "other-supp", GraphicsWindow::MNU_OTHER_ANGLE, "Other supplementary angle", {} },
{ Icon_ref, GraphicsWindow::MNU_REFERENCE, "Toggle reference dimension" }, { "ref", GraphicsWindow::MNU_REFERENCE, "Toggle reference dimension", {} },
{ SPACER, 0, 0 }, { SPACER, 0, 0, {} },
{ Icon_extrude, GraphicsWindow::MNU_GROUP_EXTRUDE, "New group extruding active sketch" }, { "extrude", GraphicsWindow::MNU_GROUP_EXTRUDE, "New group extruding active sketch", {} },
{ Icon_lathe, GraphicsWindow::MNU_GROUP_LATHE, "New group rotating active sketch" }, { "lathe", GraphicsWindow::MNU_GROUP_LATHE, "New group rotating active sketch", {} },
{ Icon_step_rotate, GraphicsWindow::MNU_GROUP_ROT, "New group step and repeat rotating" }, { "step-rotate", GraphicsWindow::MNU_GROUP_ROT, "New group step and repeat rotating", {} },
{ Icon_step_translate, GraphicsWindow::MNU_GROUP_TRANS, "New group step and repeat translating" }, { "step-translate", GraphicsWindow::MNU_GROUP_TRANS, "New group step and repeat translating", {} },
{ Icon_sketch_in_plane, GraphicsWindow::MNU_GROUP_WRKPL, "New group in new workplane (thru given entities)" }, { "sketch-in-plane", GraphicsWindow::MNU_GROUP_WRKPL, "New group in new workplane (thru given entities)", {} },
{ Icon_sketch_in_3d, GraphicsWindow::MNU_GROUP_3D, "New group in 3d" }, { "sketch-in-3d", GraphicsWindow::MNU_GROUP_3D, "New group in 3d", {} },
{ Icon_assemble, GraphicsWindow::MNU_GROUP_LINK, "New group linking / assembling file" }, { "assemble", GraphicsWindow::MNU_GROUP_LINK, "New group linking / assembling file", {} },
{ SPACER, 0, 0 }, { SPACER, 0, 0, {} },
{ Icon_in3d, GraphicsWindow::MNU_NEAREST_ISO, "Nearest isometric view" }, { "in3d", GraphicsWindow::MNU_NEAREST_ISO, "Nearest isometric view", {} },
{ Icon_ontoworkplane, GraphicsWindow::MNU_ONTO_WORKPLANE, "Align view to active workplane" }, { "ontoworkplane", GraphicsWindow::MNU_ONTO_WORKPLANE, "Align view to active workplane", {} },
{ NULL, 0, 0 } { NULL, 0, 0, {} }
}; };
void GraphicsWindow::ToolbarDraw(void) { void GraphicsWindow::ToolbarDraw(void) {
@ -141,8 +141,8 @@ bool GraphicsWindow::ToolbarDrawOrHitTest(int mx, int my,
} toolTip = { false, NULL }; } toolTip = { false, NULL };
bool leftpos = true; bool leftpos = true;
for(i = 0; Toolbar[i].image; i++) { for(i = 0; Toolbar[i].iconName; i++) {
if(Toolbar[i].image == SPACER) { if(Toolbar[i].iconName == SPACER) {
if(!leftpos) { if(!leftpos) {
leftpos = true; leftpos = true;
y -= 32; y -= 32;
@ -164,9 +164,17 @@ bool GraphicsWindow::ToolbarDrawOrHitTest(int mx, int my,
continue; continue;
} }
if(Toolbar[i].icon.IsEmpty()) {
std::string name = ssprintf("icons/graphics-window/%s.png", Toolbar[i].iconName);
Toolbar[i].icon = LoadPNG(name);
}
if(paint) { if(paint) {
glRasterPos2i(x - 12, y - 12); glPushMatrix();
glDrawPixels(24, 24, GL_RGB, GL_UNSIGNED_BYTE, Toolbar[i].image); glTranslated(x - Toolbar[i].icon.width / 2, y - Toolbar[i].icon.height / 2, 0);
glColor4d(0, 0, 0, 1.0);
ssglDrawPixmap(Toolbar[i].icon, /*flip=*/true);
glPopMatrix();
if(toolbarHovered == Toolbar[i].menu || if(toolbarHovered == Toolbar[i].menu ||
pending.operation == Toolbar[i].menu) { pending.operation == Toolbar[i].menu) {

View File

@ -62,8 +62,9 @@ public:
// The row of icons at the top of the text window, to hide/show things // The row of icons at the top of the text window, to hide/show things
typedef struct { typedef struct {
bool *var; bool *var;
uint8_t *icon; const char *iconName;
const char *tip; const char *tip;
Pixmap icon;
} HideShowIcon; } HideShowIcon;
static HideShowIcon hideShowIcons[]; static HideShowIcon hideShowIcons[];
static bool SPACER; static bool SPACER;

View File

@ -4,12 +4,6 @@ include_directories(
link_directories( link_directories(
${PNG_LIBRARY_DIRS}) ${PNG_LIBRARY_DIRS})
add_executable(png2c
png2c.cpp)
target_link_libraries(png2c
${PNG_LIBRARIES})
add_executable(unifont2c add_executable(unifont2c
unifont2c.cpp) unifont2c.cpp)

View File

@ -1,122 +0,0 @@
#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];
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);
}