x11_header header;
-unsigned char tile_bytes[TILE_X*TILE_Y*MAX_GLYPH];
+unsigned char tile_bytes[TILE_X*TILE_Y*(MAX_GLYPH+TILES_PER_ROW)];
unsigned char *curr_tb = tile_bytes;
unsigned char x11_colormap[MAXCOLORMAPSIZE][3];
/* Convert the tiles in the file to our format of bytes. */
static unsigned long
-convert_tiles(tb_ptr)
+convert_tiles(tb_ptr, total)
unsigned char **tb_ptr; /* pointer to a tile byte pointer */
+ unsigned long total; /* total tiles so far */
{
unsigned char *tb = *tb_ptr;
unsigned long count = 0;
while (read_text_tile(tile)) {
count++;
- for (y = 0; y < TILE_Y; y++)
+ total++;
+ for (y = 0; y < TILE_Y; y++) {
for (x = 0; x < TILE_X; x++)
- *tb++ = pix_to_colormap(tile[y][x]);
+ tb[x] = pix_to_colormap(tile[y][x]);
+ tb += TILE_X * header.per_row;
+ }
+
+ /* repoint at the upper-left corner of the next tile */
+ *tb_ptr += TILE_X;
+ if (header.per_row == 1 || (total % header.per_row) == 0)
+ *tb_ptr += TILE_X * (TILE_Y - 1) * header.per_row;
+ tb = *tb_ptr;
}
- *tb_ptr = tb; /* update return val */
return count;
}
if (!fopen_text_file(fname, RDTMODE)) {
Fprintf(stderr, "can't open file \"%s\"\n", fname);
exit(1);
- }
+ }
merge_text_colormap();
- count = convert_tiles(&curr_tb);
+ count = convert_tiles(&curr_tb, header.ntiles);
Fprintf(stderr, "%s: %lu tiles\n", fname, count);
header.ntiles += count;
fclose_text_file();
xpm_write(fp)
FILE *fp;
{
- int i,j,n;
+ int i, j, n;
if (header.ncolors > 64) {
Fprintf(stderr, "Sorry, only configured for up to 64 colors\n");
/* All you need to do is add more char per color - below */
}
- fprintf(fp, "/* XPM */\n");
- fprintf(fp, "static char* nhtiles[] = {\n");
- fprintf(fp, "\"%lu %lu %lu %d\",\n",
- header.tile_width,
- header.tile_height*header.ntiles,
+ Fprintf(fp, "/* XPM */\n");
+ Fprintf(fp, "static char* nhtiles[] = {\n");
+ Fprintf(fp, "\"%lu %lu %lu %d\",\n",
+ header.tile_width*header.per_row,
+ (header.tile_height*header.ntiles)/header.per_row,
header.ncolors,
1 /* char per color */);
for (i = 0; i < header.ncolors; i++)
- fprintf(fp, "\"%c c #%02x%02x%02x\",\n",
+ Fprintf(fp, "\"%c c #%02x%02x%02x\",\n",
i+'0', /* just one char per color */
x11_colormap[i][0],
x11_colormap[i][1],
x11_colormap[i][2]);
- n=0;
- for (i = 0; i < header.tile_height*header.ntiles; i++) {
- fprintf(fp, "\"");
- for (j = 0; j < header.tile_width; j++) {
+ n = 0;
+ for (i = 0; i < (header.tile_height*header.ntiles)/header.per_row; i++) {
+ Fprintf(fp, "\"");
+ for (j = 0; j < header.tile_width*header.per_row; j++) {
/* just one char per color */
fputc(tile_bytes[n++]+'0', fp);
}
- if (j==header.tile_width-1)
- fprintf(fp, "\"\n");
- else
- fprintf(fp, "\",\n");
+
+ Fprintf(fp, "\",\n");
}
- return fprintf(fp, "};\n")>=0;
+ return fprintf(fp, "};\n") >= 0;
}
#endif /* USE_XPM */
FILE *fp;
int i;
- header.version = 1;
+ header.version = 2; /* version 1 had no per_row field */
header.ncolors = 0;
header.tile_width = TILE_X;
header.tile_height = TILE_Y;
header.ntiles = 0; /* updated as we read in files */
+ header.per_row = TILES_PER_ROW;
if (argc == 1) {
Fprintf(stderr, "usage: %s txt_file1 [txt_file2 ...]\n", argv[0]);
if (!fp) {
Fprintf(stderr, "can't open output file\n");
exit(1);
- }
+ }
+
+ /* don't leave garbage at end of partial row */
+ (void) memset((genericptr_t)tile_bytes, 0, sizeof(tile_bytes));
for (i = 1; i < argc; i++)
process_file(argv[i]);
Fprintf(stderr, "Total tiles: %ld\n", header.ntiles);
+ /* round size up to the end of the row */
+ if ((header.ntiles % header.per_row) != 0) {
+ header.ntiles += header.per_row - (header.ntiles % header.per_row);
+ }
+
#ifdef USE_XPM
if (xpm_write(fp) == 0) {
Fprintf(stderr, "can't write XPM file\n");
if (fwrite((char *)&header, sizeof(x11_header), 1, fp) == 0) {
Fprintf(stderr, "can't open output header\n");
exit(1);
- }
+ }
if (fwrite((char *)x11_colormap, 1, header.ncolors*3, fp) == 0) {
Fprintf(stderr, "can't write output colormap\n");
Display *dpy = XtDisplay(toplevel);
unsigned int width, height;
- height = tile_height * tile_count;
- width = tile_width;
-
if (tile_image == 0) return; /* no tiles */
+ height = tile_image->height;
+ width = tile_image->width;
+
tile_pixmap = XCreatePixmap(dpy, XtWindow(toplevel),
width,
height,
init_tiles(wp)
struct xwindow *wp;
{
-#ifndef USE_XPM
+#ifdef USE_XPM
+ XpmAttributes attributes;
+ int errorcode;
+#else
FILE *fp = (FILE *)0;
x11_header header;
unsigned char *cp, *colormap = (unsigned char *)0;
XColor *colors = (XColor *)0;
int i, x, y;
int bitmap_pad;
- unsigned int image_height, image_width;
int ddepth;
#endif
+ char buf[BUFSZ];
Display *dpy = XtDisplay(toplevel);
Screen *screen = DefaultScreenOfDisplay(dpy);
struct map_info_t *map_info = (struct map_info_t *)0;
struct tile_map_info_t *tile_info = (struct tile_map_info_t *)0;
+ unsigned int image_height = 0, image_width = 0;
boolean result = TRUE;
XGCValues values;
XtGCMask mask;
sizeof(struct tile_map_info_t));
#ifdef USE_XPM
- {
- char buf[BUFSZ];
- XpmAttributes attributes;
- int errorcode;
+ attributes.valuemask = XpmCloseness;
+ attributes.closeness = 25000;
- attributes.valuemask = XpmCloseness;
- attributes.closeness = 25000;
+ errorcode = XpmReadFileToImage(dpy, appResources.tile_file,
+ &tile_image, 0, &attributes);
- errorcode=XpmReadFileToImage(dpy,appResources.tile_file,&tile_image,0,&attributes);
+ if (errorcode == XpmColorFailed) {
+ Sprintf(buf, "Insufficient colors available to load %s.",
+ appResources.tile_file);
+ X11_raw_print(buf);
+ X11_raw_print("Try closing other colorful applications and restart.");
+ X11_raw_print("Attempting to load with inferior colors.");
+ attributes.closeness = 50000;
+ errorcode = XpmReadFileToImage(dpy, appResources.tile_file,
+ &tile_image, 0, &attributes);
+ }
+ if (errorcode != XpmSuccess) {
if (errorcode == XpmColorFailed) {
- Sprintf(buf, "Insufficient colors available to load %s.",appResources.tile_file);
+ Sprintf(buf, "Insufficient colors available to load %s.",
+ appResources.tile_file);
+ X11_raw_print(buf);
+ } else {
+ Sprintf(buf, "Failed to load %s: %s", appResources.tile_file,
+ XpmGetErrorString(errorcode));
X11_raw_print(buf);
- X11_raw_print("Try closing other colorful applications and restart.");
- X11_raw_print("Attempting to load with inferior colors.");
- attributes.closeness = 50000;
- errorcode=XpmReadFileToImage(dpy,appResources.tile_file,&tile_image,0,&attributes);
}
+ result = FALSE;
+ X11_raw_print("Switching to text-based mode.");
+ goto tiledone;
+ }
- if (errorcode!=XpmSuccess) {
- if (errorcode == XpmColorFailed) {
- Sprintf(buf, "Insufficient colors available to load %s.",appResources.tile_file);
- X11_raw_print(buf);
- } else {
- Sprintf(buf, "Failed to load %s: %s",appResources.tile_file,
- XpmGetErrorString(errorcode));
- X11_raw_print(buf);
- }
- result = FALSE;
- X11_raw_print("Switching to text-based mode.");
- goto tiledone;
- }
+ /* assume a fixed number of tiles per row */
+ if (tile_image->width % TILES_PER_ROW != 0) {
+ Sprintf(buf,
+ "%s is not a multiple of %d (number of tiles/row) pixels wide",
+ appResources.tile_file, TILES_PER_ROW);
+ X11_raw_print(buf);
+ XDestroyImage(tile_image);
+ tile_image = 0;
+ result = FALSE;
+ goto tiledone;
+ }
- if (tile_image->height%total_tiles_used != 0) {
- Sprintf(buf,
- "%s is not a multiple of %d (the number of tiles) pixels high",
- appResources.tile_file, total_tiles_used);
- X11_raw_print(buf);
- XDestroyImage(tile_image);
- tile_image = 0;
- result = FALSE;
- goto tiledone;
- }
+ /* infer tile dimensions from image size, assume square tiles */
+ image_width = tile_image->width;
+ image_height = tile_image->height;
+ tile_width = image_width / TILES_PER_ROW;
+ tile_height = tile_width;
+ tile_count = (image_width * image_height) / (tile_width * tile_height);
- /* infer tile dimensions from image size */
- tile_count=total_tiles_used;
- tile_width=tile_image->width;
- tile_height=tile_image->height/tile_count;
+ if (tile_count < total_tiles_used) {
+ Sprintf(buf, "%s incomplete, expecting %d tiles, found %d",
+ appResources.tile_file, total_tiles_used, tile_count);
+ X11_raw_print(buf);
+ result = FALSE;
+ goto tiledone;
}
#else
/* any less than 16 colours makes tiles useless */
goto tiledone;
}
+ if (header.version != 2) {
+ Sprintf(buf, "Wrong tile file version, expected 2, got %lu",
+ header.version);
+ X11_raw_print(buf);
+ result = FALSE;
+ goto tiledone;
+ }
+
# ifdef VERBOSE
- fprintf(stderr, "X11 tile file:\n version %ld\n ncolors %ld\n tile width %ld\n tile height %ld\n ntiles %ld\n",
+ fprintf(stderr, "X11 tile file:\n version %ld\n ncolors %ld\n tile width %ld\n tile height %ld\n per row %ld\n ntiles %ld\n",
header.version,
header.ncolors,
header.tile_width,
header.tile_height,
+ header.per_row,
header.ntiles);
# endif
if (!XAllocColor(dpy, DefaultColormapOfScreen(screen), &colors[i]) &&
!nhApproxColor(screen, DefaultColormapOfScreen(screen),
(char *)0, &colors[i])) {
- char buf[BUFSZ];
Sprintf(buf, "%dth out of %ld color allocation failed",
- i, header.ncolors);
+ i, header.ncolors);
X11_raw_print(buf);
result = FALSE;
goto tiledone;
* This alloc() and the one below require 32-bit ints, since tile_bytes
* is currently ~200k and alloc() takes an int
*/
- tile_bytes = (unsigned char *) alloc((unsigned)header.ntiles*size);
tile_count = header.ntiles;
+ if ((tile_count % header.per_row) != 0) {
+ tile_count += header.per_row - (tile_count % header.per_row);
+ }
+ tile_bytes = (unsigned char *) alloc((unsigned)tile_count*size);
if (fread((char *) tile_bytes, size, tile_count, fp) != tile_count) {
X11_raw_print("read of tile bytes failed");
result = FALSE;
}
if (header.ntiles < total_tiles_used) {
- char buf[BUFSZ];
Sprintf(buf, "tile file incomplete, expecting %d tiles, found %lu",
total_tiles_used, header.ntiles);
X11_raw_print(buf);
tile_height = header.tile_height;
}
- image_height = tile_height * tile_count;
- image_width = tile_width;
+ image_height = tile_height * tile_count / header.per_row;
+ image_width = tile_width * header.per_row;
/* calculate bitmap_pad */
if (ddepth > 16)
if (appResources.double_tile_size) {
unsigned long *expanded_row =
- (unsigned long *)alloc(sizeof(unsigned long)*(unsigned)tile_width);
+ (unsigned long *)alloc(sizeof(unsigned long)*(unsigned)image_width);
tb = tile_bytes;
for (y = 0; y < image_height; y++) {
- for (x = 0; x < header.tile_width; x++)
+ for (x = 0; x < image_width/2; x++)
expanded_row[2*x] =
expanded_row[(2*x)+1] = colors[*tb++].pixel;
- for (x = 0; x < tile_width; x++)
+ for (x = 0; x < image_width; x++)
XPutPixel(tile_image, x, y, expanded_row[x]);
y++; /* duplicate row */
- for (x = 0; x < tile_width; x++)
+ for (x = 0; x < image_width; x++)
XPutPixel(tile_image, x, y, expanded_row[x]);
}
free((genericptr_t)expanded_row);
*/
mask = GCFunction | GCForeground | GCGraphicsExposures;
values.graphics_exposures = False;
-#if 1
values.foreground = WhitePixelOfScreen(screen) ^
XGetPixel(tile_image, 0, tile_height*glyph2tile[cmap_to_glyph(S_corr)]);
-#else
- values.foreground = ~((unsigned long) 0);
-#endif
values.function = GXxor;
tile_info->white_gc = XtGetGC(wp->w, mask, &values);
values.function = GXCopy;
values.graphics_exposures = False;
tile_info->black_gc = XtGetGC(wp->w, mask, &values);
-#endif
+#endif /* USE_WHITE */
tiledone:
#ifndef USE_XPM
map_info->square_width = tile_width;
map_info->square_ascent = 0;
map_info->square_lbearing = 0;
+ tile_info->image_width = image_width;
+ tile_info->image_height = image_height;
} else {
if (tile_info) free((genericptr_t)tile_info);
tile_info = 0;
#ifdef VERBOSE
printf("Font information:\n");
- printf("fid = %d, direction = %d\n", fs->fid, fs->direction);
+ printf("fid = %ld, direction = %d\n", fs->fid, fs->direction);
printf("first = %d, last = %d\n",
fs->min_char_or_byte2, fs->max_char_or_byte2);
printf("all chars exist? %s\n", fs->all_chars_exist?"yes":"no");
fs->max_bounds.lbearing, fs->max_bounds.rbearing,
fs->max_bounds.width, fs->max_bounds.ascent,
fs->max_bounds.descent, fs->max_bounds.attributes);
- printf("per_char = 0x%x\n", fs->per_char);
+ printf("per_char = 0x%lx\n", (unsigned long) fs->per_char);
printf("Text: (max) width = %d, height = %d\n",
map_info->square_width, map_info->square_height);
#endif
if (map_info->is_tile) {
struct tile_map_info_t *tile_map = map_info->mtype.tile_map;
int cur_col;
- Display* dpy=XtDisplay(wp->w);
- Screen* screen=DefaultScreenOfDisplay(dpy);
+ Display* dpy = XtDisplay(wp->w);
+ Screen* screen = DefaultScreenOfDisplay(dpy);
for (row = start_row; row <= stop_row; row++) {
for (cur_col = start_col; cur_col <= stop_col; cur_col++) {
int glyph = tile_map->glyphs[row][cur_col];
int tile = glyph2tile[glyph];
+ int src_x, src_y;
int dest_x = cur_col * map_info->square_width;
int dest_y = row * map_info->square_height;
+ src_x = (tile % TILES_PER_ROW) * tile_width;
+ src_y = (tile / TILES_PER_ROW) * tile_height;
XCopyArea(dpy, tile_pixmap, XtWindow(wp->w),
- tile_map->black_gc, /* no grapics_expose */
- 0,
- tile * map_info->square_height,
- tile_width, tile_height,
- dest_x,dest_y);
+ tile_map->black_gc, /* no grapics_expose */
+ src_x, src_y,
+ tile_width, tile_height,
+ dest_x, dest_y);
- if (glyph_is_pet(glyph)
-#ifdef TEXTCOLOR
- && iflags.hilite_pet
-#endif
- ) {
+ if (glyph_is_pet(glyph) && iflags.hilite_pet) {
/* draw pet annotation (a heart) */
XSetForeground(dpy, tile_map->black_gc, pet_annotation.foreground);
XSetClipOrigin(dpy, tile_map->black_gc, dest_x, dest_y);