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
|
@ -1,3 +1,4 @@
|
|||
usr/bin/solvespace
|
||||
usr/share/icons
|
||||
usr/share/applications
|
||||
usr/share/solvespace
|
||||
|
|
|
@ -96,6 +96,13 @@ else() # Unix
|
|||
endfunction()
|
||||
endif()
|
||||
|
||||
function(add_resources)
|
||||
foreach(name ${ARGN})
|
||||
add_resource(${name})
|
||||
set(resource_list "${resource_list}" PARENT_SCOPE)
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
# Second, register all resources.
|
||||
if(WIN32)
|
||||
add_resource(win32/icon.ico RT_ICON_GROUP APP_ICON)
|
||||
|
@ -117,7 +124,50 @@ else()
|
|||
RENAME application.x-solvespace.png)
|
||||
endforeach()
|
||||
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.
|
||||
add_custom_target(resources
|
||||
|
|
After Width: | Height: | Size: 819 B |
After Width: | Height: | Size: 686 B |
After Width: | Height: | Size: 454 B |
After Width: | Height: | Size: 710 B |
After Width: | Height: | Size: 801 B |
After Width: | Height: | Size: 739 B |
After Width: | Height: | Size: 920 B |
After Width: | Height: | Size: 620 B |
After Width: | Height: | Size: 418 B |
After Width: | Height: | Size: 512 B |
After Width: | Height: | Size: 401 B |
After Width: | Height: | Size: 480 B |
After Width: | Height: | Size: 511 B |
After Width: | Height: | Size: 412 B |
After Width: | Height: | Size: 916 B |
After Width: | Height: | Size: 531 B |
After Width: | Height: | Size: 427 B |
After Width: | Height: | Size: 394 B |
After Width: | Height: | Size: 596 B |
After Width: | Height: | Size: 418 B |
After Width: | Height: | Size: 413 B |
After Width: | Height: | Size: 673 B |
After Width: | Height: | Size: 597 B |
After Width: | Height: | Size: 507 B |
After Width: | Height: | Size: 871 B |
After Width: | Height: | Size: 411 B |
After Width: | Height: | Size: 515 B |
After Width: | Height: | Size: 666 B |
After Width: | Height: | Size: 784 B |
After Width: | Height: | Size: 575 B |
After Width: | Height: | Size: 515 B |
After Width: | Height: | Size: 557 B |
After Width: | Height: | Size: 703 B |
After Width: | Height: | Size: 683 B |
After Width: | Height: | Size: 539 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 639 B |
After Width: | Height: | Size: 733 B |
After Width: | Height: | Size: 394 B |
After Width: | Height: | Size: 403 B |
After Width: | Height: | Size: 462 B |
|
@ -84,17 +84,6 @@ endif()
|
|||
|
||||
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)
|
||||
list(SORT chars)
|
||||
add_custom_command(
|
||||
|
@ -119,11 +108,7 @@ add_custom_command(
|
|||
|
||||
set(generated_HEADERS
|
||||
${CMAKE_CURRENT_BINARY_DIR}/generated/vectorfont.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)
|
||||
${CMAKE_CURRENT_BINARY_DIR}/generated/bitmapfont.table.h)
|
||||
|
||||
# platform dependencies
|
||||
|
||||
|
@ -241,7 +226,6 @@ add_executable(solvespace WIN32 MACOSX_BUNDLE
|
|||
${libslvs_SOURCES}
|
||||
${util_SOURCES}
|
||||
${platform_SOURCES}
|
||||
${generated_SOURCES}
|
||||
${generated_HEADERS}
|
||||
${solvespace_HEADERS}
|
||||
${solvespace_SOURCES}
|
||||
|
|
|
@ -876,44 +876,31 @@ void ssglBitmapText(const std::string &str, Vector p)
|
|||
glDisable(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
void ssglDrawPixelsWithTexture(uint8_t *data, int w, int h)
|
||||
{
|
||||
#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];
|
||||
}
|
||||
}
|
||||
|
||||
void ssglDrawPixmap(const Pixmap &pixmap, bool flip) {
|
||||
glBindTexture(GL_TEXTURE_2D, TEXTURE_DRAW_PIXELS);
|
||||
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_WRAP_S, 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,
|
||||
GL_RGB, GL_UNSIGNED_BYTE, Texture);
|
||||
int format = pixmap.hasAlpha ? GL_RGBA : GL_RGB;
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, format, pixmap.width, pixmap.height, 0,
|
||||
format, GL_UNSIGNED_BYTE, pixmap.data.get());
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2d(0, 0);
|
||||
glVertex2d(0, h);
|
||||
glTexCoord2d(0.0, flip ? 0.0 : 1.0);
|
||||
glVertex2d(0.0, (double)pixmap.height);
|
||||
|
||||
glTexCoord2d(((double)w)/MAX_DIM, 0);
|
||||
glVertex2d(w, h);
|
||||
glTexCoord2d(1.0, flip ? 0.0 : 1.0);
|
||||
glVertex2d((double)pixmap.width, (double)pixmap.height);
|
||||
|
||||
glTexCoord2d(((double)w)/MAX_DIM, ((double)h)/MAX_DIM);
|
||||
glVertex2d(w, 0);
|
||||
glTexCoord2d(1.0, flip ? 1.0 : 0.0);
|
||||
glVertex2d((double)pixmap.width, 0.0);
|
||||
|
||||
glTexCoord2d(0, ((double)h)/MAX_DIM);
|
||||
glVertex2d(0, 0);
|
||||
glTexCoord2d(0.0, flip ? 1.0 : 0.0);
|
||||
glVertex2d(0.0, 0.0);
|
||||
glEnd();
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
}
|
||||
|
|
Before Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 609 B |
Before Width: | Height: | Size: 544 B |
Before Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 171 B |
Before Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 930 B |
Before Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 317 B |
Before Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 395 B |
106
src/resource.cpp
|
@ -4,9 +4,14 @@
|
|||
// Copyright 2016 whitequark
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "solvespace.h"
|
||||
#include <png.h>
|
||||
|
||||
namespace SolveSpace {
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Resource loading functions
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
std::string LoadString(const std::string &name) {
|
||||
size_t 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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
#ifndef __RESOURCE_H
|
||||
#define __RESOURCE_H
|
||||
|
||||
class Pixmap;
|
||||
|
||||
// Only the following function is platform-specific.
|
||||
// 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
|
||||
|
@ -14,5 +16,23 @@
|
|||
const void *LoadResource(const std::string &name, size_t *size);
|
||||
|
||||
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
|
||||
|
|
|
@ -356,7 +356,7 @@ void ssglColorRGB(RgbaColor rgb);
|
|||
void ssglColorRGBa(RgbaColor rgb, double a);
|
||||
void ssglDepthRangeOffset(int units);
|
||||
void ssglDepthRangeLockToFront(bool yes);
|
||||
void ssglDrawPixelsWithTexture(uint8_t *data, int w, int h);
|
||||
void ssglDrawPixmap(const Pixmap &pixmap, bool flip = false);
|
||||
void ssglInitializeBitmapFont();
|
||||
void ssglBitmapText(const std::string &str, Vector p);
|
||||
void ssglBitmapCharQuad(char32_t chr, double x, double y);
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
// Copyright 2008-2013 Jonathan Westhues.
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "solvespace.h"
|
||||
#include "generated/icons.h"
|
||||
|
||||
const TextWindow::Color TextWindow::fgColors[] = {
|
||||
{ 'd', RGBi(255, 255, 255) },
|
||||
|
@ -30,19 +29,19 @@ const TextWindow::Color TextWindow::bgColors[] = {
|
|||
|
||||
bool TextWindow::SPACER = false;
|
||||
TextWindow::HideShowIcon TextWindow::hideShowIcons[] = {
|
||||
{ &(SS.GW.showWorkplanes), Icon_workplane, "workplanes from inactive groups"},
|
||||
{ &(SS.GW.showNormals), Icon_normal, "normals" },
|
||||
{ &(SS.GW.showPoints), Icon_point, "points" },
|
||||
{ &(SS.GW.showConstraints), Icon_constraint, "constraints and dimensions" },
|
||||
{ &(SS.GW.showFaces), Icon_faces, "XXX - special cased" },
|
||||
{ &SPACER, 0, 0 },
|
||||
{ &(SS.GW.showShaded), Icon_shaded, "shaded view of solid model" },
|
||||
{ &(SS.GW.showEdges), Icon_edges, "edges of solid model" },
|
||||
{ &(SS.GW.showOutlines), Icon_outlines, "outline of solid model" },
|
||||
{ &(SS.GW.showMesh), Icon_mesh, "triangle mesh of solid model" },
|
||||
{ &SPACER, 0, 0 },
|
||||
{ &(SS.GW.showHdnLines), Icon_hidden_lines, "hidden lines" },
|
||||
{ 0, 0, 0 }
|
||||
{ &(SS.GW.showWorkplanes), "workplane", "workplanes from inactive groups", {} },
|
||||
{ &(SS.GW.showNormals), "normal", "normals", {} },
|
||||
{ &(SS.GW.showPoints), "point", "points", {} },
|
||||
{ &(SS.GW.showConstraints), "constraint", "constraints and dimensions", {} },
|
||||
{ &(SS.GW.showFaces), "faces", "XXX - special cased", {} },
|
||||
{ &SPACER, 0, 0, {} },
|
||||
{ &(SS.GW.showShaded), "shaded", "shaded view of solid model", {} },
|
||||
{ &(SS.GW.showEdges), "edges", "edges of solid model", {} },
|
||||
{ &(SS.GW.showOutlines), "outlines", "outline of solid model", {} },
|
||||
{ &(SS.GW.showMesh), "mesh", "triangle mesh of solid model", {} },
|
||||
{ &SPACER, 0, 0, {} },
|
||||
{ &(SS.GW.showHdnLines), "hidden-lines", "hidden lines", {} },
|
||||
{ 0, 0, 0, {} }
|
||||
};
|
||||
|
||||
void TextWindow::MakeColorTable(const Color *in, float *out) {
|
||||
|
@ -379,13 +378,15 @@ void TextWindow::DrawOrHitTestIcons(int how, double mx, double my)
|
|||
continue;
|
||||
}
|
||||
|
||||
if(hsi->icon.IsEmpty()) {
|
||||
hsi->icon = LoadPNG(ssprintf("icons/text-window/%s.png", hsi->iconName));
|
||||
}
|
||||
|
||||
if(how == PAINT) {
|
||||
glPushMatrix();
|
||||
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);
|
||||
ssglDrawPixelsWithTexture(hsi->icon, 24, 24);
|
||||
ssglDrawPixmap(hsi->icon);
|
||||
glPopMatrix();
|
||||
|
||||
if(hsi == hoveredIcon) {
|
||||
|
@ -433,7 +434,7 @@ void TextWindow::DrawOrHitTestIcons(int how, double mx, double my)
|
|||
if(how == PAINT) {
|
||||
std::string str;
|
||||
|
||||
if(tooltippedIcon->icon == Icon_faces) {
|
||||
if(tooltippedIcon->var == &(SS.GW.showFaces)) {
|
||||
if(SS.GW.showFaces) {
|
||||
str = "Don't make faces selectable with mouse";
|
||||
} else {
|
||||
|
|
|
@ -6,52 +6,52 @@
|
|||
// Copyright 2008-2013 Jonathan Westhues.
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "solvespace.h"
|
||||
#include "generated/icons.h"
|
||||
|
||||
static uint8_t SPACER[1];
|
||||
static const struct {
|
||||
uint8_t *image;
|
||||
static const char *SPACER = "";
|
||||
static struct {
|
||||
const char *iconName;
|
||||
int menu;
|
||||
const char *tip;
|
||||
Pixmap icon;
|
||||
} Toolbar[] = {
|
||||
{ Icon_line, GraphicsWindow::MNU_LINE_SEGMENT, "Sketch line segment" },
|
||||
{ Icon_rectangle, GraphicsWindow::MNU_RECTANGLE, "Sketch rectangle" },
|
||||
{ Icon_circle, GraphicsWindow::MNU_CIRCLE, "Sketch circle" },
|
||||
{ Icon_arc, GraphicsWindow::MNU_ARC, "Sketch arc of a circle" },
|
||||
{ Icon_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" },
|
||||
{ Icon_bezier, GraphicsWindow::MNU_CUBIC, "Sketch cubic Bezier spline" },
|
||||
{ Icon_point, GraphicsWindow::MNU_DATUM_POINT, "Sketch datum point" },
|
||||
{ Icon_construction, GraphicsWindow::MNU_CONSTRUCTION, "Toggle construction" },
|
||||
{ Icon_trim, GraphicsWindow::MNU_SPLIT_CURVES, "Split lines / curves where they intersect" },
|
||||
{ SPACER, 0, 0 },
|
||||
{ "line", GraphicsWindow::MNU_LINE_SEGMENT, "Sketch line segment", {} },
|
||||
{ "rectangle", GraphicsWindow::MNU_RECTANGLE, "Sketch rectangle", {} },
|
||||
{ "circle", GraphicsWindow::MNU_CIRCLE, "Sketch circle", {} },
|
||||
{ "arc", GraphicsWindow::MNU_ARC, "Sketch arc of a circle", {} },
|
||||
{ "text", GraphicsWindow::MNU_TTF_TEXT, "Sketch curves from text in a TrueType font", {} },
|
||||
{ "tangent-arc", GraphicsWindow::MNU_TANGENT_ARC, "Create tangent arc at selected point", {} },
|
||||
{ "bezier", GraphicsWindow::MNU_CUBIC, "Sketch cubic Bezier spline", {} },
|
||||
{ "point", GraphicsWindow::MNU_DATUM_POINT, "Sketch datum point", {} },
|
||||
{ "construction", GraphicsWindow::MNU_CONSTRUCTION, "Toggle construction", {} },
|
||||
{ "trim", GraphicsWindow::MNU_SPLIT_CURVES, "Split lines / curves where they intersect", {} },
|
||||
{ SPACER, 0, 0, {} },
|
||||
|
||||
{ Icon_length, GraphicsWindow::MNU_DISTANCE_DIA, "Constrain distance / diameter / length" },
|
||||
{ Icon_angle, GraphicsWindow::MNU_ANGLE, "Constrain angle" },
|
||||
{ Icon_horiz, GraphicsWindow::MNU_HORIZONTAL, "Constrain to be horizontal" },
|
||||
{ Icon_vert, GraphicsWindow::MNU_VERTICAL, "Constrain to be vertical" },
|
||||
{ Icon_parallel, GraphicsWindow::MNU_PARALLEL, "Constrain to be parallel or tangent" },
|
||||
{ Icon_perpendicular, GraphicsWindow::MNU_PERPENDICULAR, "Constrain to be perpendicular" },
|
||||
{ Icon_pointonx, GraphicsWindow::MNU_ON_ENTITY, "Constrain point on line / curve / plane / point" },
|
||||
{ Icon_symmetric, GraphicsWindow::MNU_SYMMETRIC, "Constrain symmetric" },
|
||||
{ Icon_equal, GraphicsWindow::MNU_EQUAL, "Constrain equal length / radius / angle" },
|
||||
{ Icon_same_orientation,GraphicsWindow::MNU_ORIENTED_SAME, "Constrain normals in same orientation" },
|
||||
{ Icon_other_supp, GraphicsWindow::MNU_OTHER_ANGLE, "Other supplementary angle" },
|
||||
{ Icon_ref, GraphicsWindow::MNU_REFERENCE, "Toggle reference dimension" },
|
||||
{ SPACER, 0, 0 },
|
||||
{ "length", GraphicsWindow::MNU_DISTANCE_DIA, "Constrain distance / diameter / length", {} },
|
||||
{ "angle", GraphicsWindow::MNU_ANGLE, "Constrain angle", {} },
|
||||
{ "horiz", GraphicsWindow::MNU_HORIZONTAL, "Constrain to be horizontal", {} },
|
||||
{ "vert", GraphicsWindow::MNU_VERTICAL, "Constrain to be vertical", {} },
|
||||
{ "parallel", GraphicsWindow::MNU_PARALLEL, "Constrain to be parallel or tangent", {} },
|
||||
{ "perpendicular", GraphicsWindow::MNU_PERPENDICULAR, "Constrain to be perpendicular", {} },
|
||||
{ "pointonx", GraphicsWindow::MNU_ON_ENTITY, "Constrain point on line / curve / plane / point", {} },
|
||||
{ "symmetric", GraphicsWindow::MNU_SYMMETRIC, "Constrain symmetric", {} },
|
||||
{ "equal", GraphicsWindow::MNU_EQUAL, "Constrain equal length / radius / angle", {} },
|
||||
{ "same-orientation",GraphicsWindow::MNU_ORIENTED_SAME, "Constrain normals in same orientation", {} },
|
||||
{ "other-supp", GraphicsWindow::MNU_OTHER_ANGLE, "Other supplementary angle", {} },
|
||||
{ "ref", GraphicsWindow::MNU_REFERENCE, "Toggle reference dimension", {} },
|
||||
{ SPACER, 0, 0, {} },
|
||||
|
||||
{ Icon_extrude, GraphicsWindow::MNU_GROUP_EXTRUDE, "New group extruding active sketch" },
|
||||
{ Icon_lathe, GraphicsWindow::MNU_GROUP_LATHE, "New group rotating active sketch" },
|
||||
{ Icon_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" },
|
||||
{ Icon_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" },
|
||||
{ Icon_assemble, GraphicsWindow::MNU_GROUP_LINK, "New group linking / assembling file" },
|
||||
{ SPACER, 0, 0 },
|
||||
{ "extrude", GraphicsWindow::MNU_GROUP_EXTRUDE, "New group extruding active sketch", {} },
|
||||
{ "lathe", GraphicsWindow::MNU_GROUP_LATHE, "New group rotating active sketch", {} },
|
||||
{ "step-rotate", GraphicsWindow::MNU_GROUP_ROT, "New group step and repeat rotating", {} },
|
||||
{ "step-translate", GraphicsWindow::MNU_GROUP_TRANS, "New group step and repeat translating", {} },
|
||||
{ "sketch-in-plane", GraphicsWindow::MNU_GROUP_WRKPL, "New group in new workplane (thru given entities)", {} },
|
||||
{ "sketch-in-3d", GraphicsWindow::MNU_GROUP_3D, "New group in 3d", {} },
|
||||
{ "assemble", GraphicsWindow::MNU_GROUP_LINK, "New group linking / assembling file", {} },
|
||||
{ SPACER, 0, 0, {} },
|
||||
|
||||
{ Icon_in3d, GraphicsWindow::MNU_NEAREST_ISO, "Nearest isometric view" },
|
||||
{ Icon_ontoworkplane, GraphicsWindow::MNU_ONTO_WORKPLANE, "Align view to active workplane" },
|
||||
{ NULL, 0, 0 }
|
||||
{ "in3d", GraphicsWindow::MNU_NEAREST_ISO, "Nearest isometric view", {} },
|
||||
{ "ontoworkplane", GraphicsWindow::MNU_ONTO_WORKPLANE, "Align view to active workplane", {} },
|
||||
{ NULL, 0, 0, {} }
|
||||
};
|
||||
|
||||
void GraphicsWindow::ToolbarDraw(void) {
|
||||
|
@ -141,8 +141,8 @@ bool GraphicsWindow::ToolbarDrawOrHitTest(int mx, int my,
|
|||
} toolTip = { false, NULL };
|
||||
|
||||
bool leftpos = true;
|
||||
for(i = 0; Toolbar[i].image; i++) {
|
||||
if(Toolbar[i].image == SPACER) {
|
||||
for(i = 0; Toolbar[i].iconName; i++) {
|
||||
if(Toolbar[i].iconName == SPACER) {
|
||||
if(!leftpos) {
|
||||
leftpos = true;
|
||||
y -= 32;
|
||||
|
@ -164,9 +164,17 @@ bool GraphicsWindow::ToolbarDrawOrHitTest(int mx, int my,
|
|||
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) {
|
||||
glRasterPos2i(x - 12, y - 12);
|
||||
glDrawPixels(24, 24, GL_RGB, GL_UNSIGNED_BYTE, Toolbar[i].image);
|
||||
glPushMatrix();
|
||||
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 ||
|
||||
pending.operation == Toolbar[i].menu) {
|
||||
|
|
3
src/ui.h
|
@ -62,8 +62,9 @@ public:
|
|||
// The row of icons at the top of the text window, to hide/show things
|
||||
typedef struct {
|
||||
bool *var;
|
||||
uint8_t *icon;
|
||||
const char *iconName;
|
||||
const char *tip;
|
||||
Pixmap icon;
|
||||
} HideShowIcon;
|
||||
static HideShowIcon hideShowIcons[];
|
||||
static bool SPACER;
|
||||
|
|
|
@ -4,12 +4,6 @@ include_directories(
|
|||
link_directories(
|
||||
${PNG_LIBRARY_DIRS})
|
||||
|
||||
add_executable(png2c
|
||||
png2c.cpp)
|
||||
|
||||
target_link_libraries(png2c
|
||||
${PNG_LIBRARIES})
|
||||
|
||||
add_executable(unifont2c
|
||||
unifont2c.cpp)
|
||||
|
||||
|
|
122
tools/png2c.cpp
|
@ -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);
|
||||
}
|