From 2dbb21aecd2cf3e5fedd2fed8d3e5613cdc9aea6 Mon Sep 17 00:00:00 2001 From: Jonathan Westhues Date: Sat, 8 May 2010 17:20:02 -0800 Subject: [PATCH] Add special characters to font, to represent checkboxes and radio buttons. This requires some tools to convert .png images to that, and that I put the characters in a two-dimensional grid in the texture (since one-dimensional strip gets wider than the hardware supports). [git-p4: depot-paths = "//depot/solvespace/": change = 2138] --- bitmapextra.table | 68 +++++++++++++++++++++++++++++++++++ bitmapfont.table | 3 +- glhelper.cpp | 43 +++++++++++++++++----- icons/char-0-check-false.png | Bin 0 -> 218 bytes icons/char-1-check-true.png | Bin 0 -> 243 bytes icons/char-2-radio-false.png | Bin 0 -> 228 bytes icons/char-3-radio-true.png | Bin 0 -> 231 bytes png2c.pl | 3 +- pngchar2c.pl | 28 +++++++++++++++ tools/ttf2c.cpp | 4 +-- ui.h | 5 +++ wishlist.txt | 3 +- 12 files changed, 142 insertions(+), 15 deletions(-) create mode 100644 bitmapextra.table create mode 100644 icons/char-0-check-false.png create mode 100644 icons/char-1-check-true.png create mode 100644 icons/char-2-radio-false.png create mode 100644 icons/char-3-radio-true.png create mode 100644 pngchar2c.pl diff --git a/bitmapextra.table b/bitmapextra.table new file mode 100644 index 0000000..338290d --- /dev/null +++ b/bitmapextra.table @@ -0,0 +1,68 @@ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, + 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, + 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, + 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, + 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, + 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, + 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, + 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, + 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, + 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, + 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, + 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, + 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, + 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, + 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, + 0, 0, 255, 255, 0, 0, 0, 255, 255, 255, 0, 0, 0, 255, 255, 0, + 0, 0, 255, 255, 0, 0, 0, 0, 255, 255, 255, 0, 0, 255, 255, 0, + 0, 0, 255, 255, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 0, + 0, 0, 255, 255, 0, 0, 0, 0, 255, 255, 255, 0, 0, 255, 255, 0, + 0, 0, 255, 255, 0, 0, 0, 255, 255, 255, 0, 0, 0, 255, 255, 0, + 0, 0, 255, 255, 0, 0, 255, 255, 255, 0, 0, 0, 0, 255, 255, 0, + 0, 0, 255, 255, 0, 255, 255, 255, 0, 0, 0, 0, 0, 255, 255, 0, + 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, + 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, + 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, + 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, + 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, + 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, + 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, + 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, + 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, + 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, + 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, + 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, + 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, + 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, + 0, 0, 255, 255, 0, 0, 0, 255, 255, 0, 0, 0, 255, 255, 0, 0, + 0, 0, 255, 255, 0, 0, 255, 255, 255, 255, 0, 0, 255, 255, 0, 0, + 0, 0, 255, 255, 0, 0, 255, 255, 255, 255, 0, 0, 255, 255, 0, 0, + 0, 0, 255, 255, 0, 0, 0, 255, 255, 0, 0, 0, 255, 255, 0, 0, + 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, + 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, + 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + diff --git a/bitmapfont.table b/bitmapfont.table index bdbb371..d444070 100644 --- a/bitmapfont.table +++ b/bitmapfont.table @@ -1,4 +1,4 @@ -static const BYTE FontTexture[] = { +static const BYTE FontTexture[256*16*16] = { 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, @@ -2175,4 +2175,5 @@ static const BYTE FontTexture[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +#include "bitmapextra.table" }; diff --git a/glhelper.cpp b/glhelper.cpp index dd3b613..1d7088a 100644 --- a/glhelper.cpp +++ b/glhelper.cpp @@ -480,6 +480,21 @@ void glxDepthRangeLockToFront(bool yes) void glxCreateBitmapFont(void) { + // Place the font in our texture in a two-dimensional grid; 1d would + // be simpler, but long skinny textures (256*16 = 4096 pixels wide) + // won't work. + static BYTE MappedTexture[4*16*64*16]; + int a, i; + for(a = 0; a < 256; a++) { + int row = a / 4, col = a % 4; + + for(i = 0; i < 16; i++) { + memcpy(MappedTexture + row*4*16*16 + col*16 + i*4*16, + FontTexture + a*16*16 + i*16, + 16); + } + } + glBindTexture(GL_TEXTURE_2D, TEXTURE_BITMAP_FONT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); @@ -487,22 +502,32 @@ void glxCreateBitmapFont(void) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, - 16, 128*16, + 16*4, 64*16, 0, GL_ALPHA, GL_UNSIGNED_BYTE, - FontTexture); + MappedTexture); } void glxBitmapCharQuad(char c, double x, double y) { - int w = SS.TW.CHAR_WIDTH, + BYTE b = (BYTE)c; + int w, h; + + if(b & 0x80) { + // Special character, like a checkbox or a radio button + w = h = 16; + } else { + // Normal character from our font + w = SS.TW.CHAR_WIDTH, h = SS.TW.CHAR_HEIGHT; - - if(c != ' ' && c != 0 && c < 128) { - double s0 = 0, - s1 = h/16.0, - t0 = c/128.0, - t1 = t0 + (w/16.0)/128; + } + + if(b != ' ' && b != 0) { + int row = b / 4, col = b % 4; + double s0 = col/4.0, + s1 = (col+1)/4.0, + t0 = row/64.0, + t1 = t0 + (w/16.0)/64; glTexCoord2d(s1, t0); glVertex2d(x, y); diff --git a/icons/char-0-check-false.png b/icons/char-0-check-false.png new file mode 100644 index 0000000000000000000000000000000000000000..b9020c33b8c437c8617a537d3b03c173e421b2f0 GIT binary patch literal 218 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl%OyKpTSt fL*frHg#!$+84N28+$Y-tZDH_q^>bP0l+XkK*)B9y literal 0 HcmV?d00001 diff --git a/icons/char-1-check-true.png b/icons/char-1-check-true.png new file mode 100644 index 0000000000000000000000000000000000000000..7f6a42c554193d2abbd2b4a8023009fb8864be24 GIT binary patch literal 243 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLlS!3>*qfc7zXy85}S Ib4q9e0Hf$QhX4Qo literal 0 HcmV?d00001 diff --git a/icons/char-3-radio-true.png b/icons/char-3-radio-true.png new file mode 100644 index 0000000000000000000000000000000000000000..5322f587264a18b394550c53b8803bc5038d9612 GIT binary patch literal 231 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl#%q#+J&w=`!859mMBwb+G8Fuk* Q570^mPgg&ebxsLQ0A3F|lmGw# literal 0 HcmV?d00001 diff --git a/png2c.pl b/png2c.pl index 3552e45..b6092ef 100644 --- a/png2c.pl +++ b/png2c.pl @@ -7,7 +7,8 @@ open(OUT, ">$out") or die "$out: $!"; open(PROTO, ">$proto") or die "$proto: $!"; for $file () { - + next if $file =~ /char-/; + $file =~ m#.*/(.*)\.png#; $base = "Icon_$1"; $base =~ y/-/_/; diff --git a/pngchar2c.pl b/pngchar2c.pl new file mode 100644 index 0000000..99ce60f --- /dev/null +++ b/pngchar2c.pl @@ -0,0 +1,28 @@ +#!/usr/bin/perl + +use GD; + +for $file (sort ) { + open(PNG, $file) or die "$file: $!\n"; + $img = newFromPng GD::Image(\*PNG) or die; + $img->trueColor(1); + close PNG; + + ($width, $height) = $img->getBounds(); + die "$file: $width, $height" if ($width != 16) or ($height != 16); + + for($x = 0; $x < 16; $x++) { + for($y = 0; $y < 16; $y++) { + $index = $img->getPixel($x, $y); + ($r, $g, $b) = $img->rgb($index); + if($r + $g + $b < 11) { + print " 0, "; + } else { + print "255, "; + } + } + print "\n"; + } + print "\n"; +} + diff --git a/tools/ttf2c.cpp b/tools/ttf2c.cpp index 786be9d..2e11dfa 100644 --- a/tools/ttf2c.cpp +++ b/tools/ttf2c.cpp @@ -20,7 +20,7 @@ int main(void) SelectObject(hdc, bitmap); SelectObject(hdc, font); - printf("static const BYTE FontTexture[] = {\n"); + printf("static const BYTE FontTexture[256*16*16] = {\n"); int c; for(c = 0; c < 128; c++) { @@ -45,7 +45,7 @@ int main(void) } printf("\n"); } - + printf("#include \"bitmapextra.table\"\n"); printf("};\n"); return 0; diff --git a/ui.h b/ui.h index fa8f1a8..cf934ee 100644 --- a/ui.h +++ b/ui.h @@ -33,6 +33,11 @@ public: static const int LINE_HEIGHT = 20; static const int LEFT_MARGIN = 6; + static const int CHECK_FALSE = 0x80; + static const int CHECK_TRUE = 0x81; + static const int RADIO_FALSE = 0x82; + static const int RADIO_TRUE = 0x83; + int scrollPos; // The scrollbar position, in half-row units int halfRows; // The height of our window, in half-row units diff --git a/wishlist.txt b/wishlist.txt index a7a3416..3378709 100644 --- a/wishlist.txt +++ b/wishlist.txt @@ -1,8 +1,7 @@ add checked/unchecked checkbox and radio button fix bug with rotation in plane where green line stays displayed -expose transformed point stuff in library group option to make dimensions always reference? -more tangencies +more tangencies, and rounding (of requests, not parametric) ----- rounding, as a special group