summaryrefslogtreecommitdiff
path: root/app/help/mkxpmbutt.c
diff options
context:
space:
mode:
Diffstat (limited to 'app/help/mkxpmbutt.c')
-rw-r--r--app/help/mkxpmbutt.c303
1 files changed, 303 insertions, 0 deletions
diff --git a/app/help/mkxpmbutt.c b/app/help/mkxpmbutt.c
new file mode 100644
index 0000000..4b09a80
--- /dev/null
+++ b/app/help/mkxpmbutt.c
@@ -0,0 +1,303 @@
+
+/* XTrkCad - Model Railroad CAD
+ * Copyright (C) 2005 Dave Bullis
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+typedef struct {
+ int w;
+ int h;
+ char * b;
+ } bitmap_t;
+
+#define RGB(R,G,B) (((R)<<16)|((G)<<8)|(B))
+
+static struct {
+ long rgb;
+ int key;
+ } mainColorMap[256];
+static int mainColorCnt;
+static int fileColorMap[256];
+
+static int sizeColorMap( void )
+{
+ return mainColorCnt;
+}
+
+static void printColorMap( FILE * fout )
+{
+ int inx, r, g, b;
+ long rgb;
+ for ( inx=0; inx<mainColorCnt; inx++ ) {
+ rgb = mainColorMap[inx].rgb;
+ r = (rgb>>16)&0xFF;
+ g = (rgb>>8)&0xFF;
+ b = (rgb)&0xFF;
+ fprintf( fout, "\"%c\tc #%2.2X%s%2.2X%s%2.2X%s\",\n",
+ mainColorMap[inx].key,
+ r, ((r&1)?"FF":"00"),
+ g, ((g&1)?"FF":"00"),
+ b, ((b&1)?"FF":"00") );
+ }
+}
+
+static int allocColor( long color )
+{
+ int inx;
+ for ( inx=0; inx<mainColorCnt; inx++ ) {
+ if ( mainColorMap[inx].rgb == color )
+ return mainColorMap[inx].key;
+ }
+ if ( mainColorCnt >= 256 ) {
+ fprintf( stderr, "too many colors\n" );
+ exit(1);
+ }
+ mainColorMap[mainColorCnt].rgb = color;
+ mainColorMap[mainColorCnt].key = mainColorCnt+'0';
+ return mainColorMap[mainColorCnt++].key;
+}
+
+static void resetColor( void )
+{
+ int inx;
+ for ( inx=0; inx<256; inx++ )
+ fileColorMap[inx] = -1;
+}
+
+static void mapColor( int inx, long rgb )
+{
+ fileColorMap[inx] = allocColor(rgb);
+}
+
+static int remapColor( int oldColor )
+{
+ int newColor;
+ newColor = fileColorMap[oldColor];
+ if ( newColor < 0 ) {
+ fprintf( stderr, "unknown color inx: %d\n", oldColor );
+ return ' ';
+ }
+ return newColor;
+}
+
+static int read_xpm(
+ char * filename,
+ int *rw,
+ int *rh,
+ int bx,
+ int by,
+ bitmap_t *bm )
+{
+ char line[1024], *cp, *cq, *buffer, color[5];
+ FILE * f;
+ int numcol, curcol, depth, linenum;
+ int col, row, len, r, g, b;
+ long rgb;
+
+ f = fopen( filename, "r" );
+ if ( !f ) {
+ perror( filename );
+ return 0;
+ }
+ numcol = -1;
+ curcol = 0;
+ linenum = 0;
+ resetColor();
+ row = by;
+ while (fgets( line, sizeof line, f ) ) {
+ linenum++;
+ if ( line[0] != '"' )
+ continue;
+ if ( numcol == -1 ) {
+ if ( sscanf( line+1, "%d%d%d%d", rw, rh, &numcol, &depth ) != 4 ) {
+ fprintf( stderr, "bogus XPM header: %s:%d\n", filename, linenum );
+ return 0;
+ }
+ if (!bm)
+ return 1;
+ } else if ( curcol < numcol ) {
+ if ( strncmp( line+2, "\tc #", 4 ) != 0 ) {
+ fprintf( stderr, "bogus XPM color line: %s:%d\n", filename, linenum );
+ return 0;
+ }
+ color[3] = 0;
+ memcpy( color, line+6, 2 );
+ r = strtol( color, &cp, 16 );
+ memcpy( color, line+10, 2 );
+ g = strtol( color, &cp, 16 );
+ memcpy( color, line+14, 2 );
+ b = strtol( color, &cp, 16 );
+ rgb = RGB(r,g,b);
+ if ( curcol == 0 )
+ fileColorMap[line[1]] = '0';
+ else
+ mapColor( line[1], rgb );
+ curcol++;
+ } else {
+ if ( row > by+*rh ) {
+ fprintf( stderr, "too many data lines: %s:%d\n", filename, linenum );
+ return 0;
+ }
+ if ( row > bm->h )
+ return 1;
+ cp = line+1;
+ for ( col=0; col<*rw; col++,cp++ ) {
+ if ( bx+col > bm->w )
+ break;
+ if ( *cp == '"' ) {
+ fprintf( stderr, "short data line: %s:%d\n", filename, linenum );
+ return 0;
+ }
+ bm->b[bx+col+bm->w*row] = remapColor( *cp );
+ }
+ row++;
+ }
+ }
+ fclose( f );
+ return 1;
+}
+
+static void drawVline(
+ bitmap_t * bm,
+ int col,
+ int x,
+ int y0,
+ int y1 )
+{
+ int jj;
+ if ( x > bm->w )
+ return;
+ for ( jj=y0; jj<=y1; jj++ ) {
+ if ( jj>=bm->h )
+ return;
+ bm->b[jj*bm->w+x] = col;
+ }
+}
+
+
+static void drawHline(
+ bitmap_t * bm,
+ int col,
+ int x0,
+ int x1,
+ int y )
+{
+ int ii;
+ if ( y > bm->h )
+ return;
+ for ( ii=x0; ii<=x1; ii++ ) {
+ if ( ii>=bm->w )
+ return;
+ bm->b[y*bm->w+ii] = col;
+ }
+}
+
+static void fillBlock(
+ bitmap_t * bm,
+ int col,
+ int x,
+ int y,
+ int w,
+ int h )
+{
+ int ii, jj;
+ for ( jj=y; jj<y+h; jj++ ) {
+ if ( jj>bm->h )
+ return;
+ for ( ii=x; ii<x+w; ii++ ) {
+ if ( ii>bm->w )
+ return;
+ bm->b[jj*bm->w+ii] = col;
+ }
+ }
+}
+
+
+int main ( int argc, char * argv[] )
+{
+ char * name;
+ int colWhite, colMdGray, colDkGray, colBlack;
+ int bx, w, h;
+ bitmap_t bm;
+ char ** filename;
+ int ii, jj;
+ char * cp;
+ int argn;
+
+ if ( argc < 3 ) {
+ fprintf( stderr, "usage: %s NAME FILE1.XPM...\n", argv[0] );
+ exit(1);
+ }
+
+ colMdGray = allocColor( RGB(0xC0,0xC0,0xC0) );
+ colWhite = allocColor( RGB(255,255,255) );
+ colDkGray = allocColor( RGB(0x80,0x80,0x80) );
+ colBlack = allocColor( RGB(0,0,0) );
+ allocColor( RGB(255,0,0) );
+
+ name = argv[1];
+ argc -= 2;
+ filename = &argv[2];
+
+ bm.w = 1;
+ bm.h = 0;
+ for ( argn=0; argn<argc; argn++ ) {
+ if ( !read_xpm( filename[argn], &w, &h, bx+5, 5, NULL ) )
+ return;
+ if ( h+10 > bm.h )
+ bm.h = h+10;
+ bm.w += w+9;
+ }
+
+ bm.b = (char*)malloc( bm.w*bm.h );
+ memset( bm.b, 0, bm.w*bm.h );
+ fillBlock( &bm, colMdGray, 0, 0, bm.w, bm.h );
+ bx = 0;
+ for ( argn=0; argn<argc; argn++ ) {
+ if ( !read_xpm( filename[argn], &w, &h, bx+5, 5, &bm ) )
+ return;
+ drawVline( &bm, colBlack, bx+0, 0, bm.h-1 );
+ drawVline( &bm, colWhite, bx+1, 1, bm.h-2 );
+ drawVline( &bm, colWhite, bx+2, 1, bm.h-3 );
+ drawVline( &bm, colDkGray, bx+5+w+2, 2, bm.h-2 );
+ drawVline( &bm, colDkGray, bx+5+w+3, 1, bm.h-2 );
+ drawVline( &bm, colBlack, bx+5+w+4, 0, bm.h-1 );
+
+ drawHline( &bm, colBlack, bx+1, bx+5+w+3, 0 );
+ drawHline( &bm, colWhite, bx+1, bx+5+w+2, 1 );
+ drawHline( &bm, colWhite, bx+1, bx+5+w+1, 2 );
+ drawHline( &bm, colDkGray, bx+2, bx+5+w+1, bm.h-3 );
+ drawHline( &bm, colDkGray, bx+1, bx+5+w+1, bm.h-2 );
+ drawHline( &bm, colBlack, bx+1, bx+5+w+3, bm.h-1 );
+
+ bx += w+9;
+ }
+
+ fprintf( stdout, "/* XPM */\n" );
+ fprintf( stdout, "static char * %s_xpm[] = {\n", name );
+ fprintf( stdout, "\"%d %d %d 1\",\n", bm.w, bm.h, sizeColorMap()+1 );
+ fprintf( stdout, "\"Z\tc #000000000000\",\n" );
+ printColorMap( stdout );
+ cp = bm.b;
+ for ( jj=0; jj<bm.h; jj++ ) {
+ fprintf(stdout, "\"%.*s\"%s\n", bm.w, cp, (jj<bm.h-1?",":"};") );
+ cp += bm.w;
+ }
+}