comparison src/glyphs-msw.c @ 288:e11d67e05968 r21-0b42

Import from CVS: tag r21-0b42
author cvs
date Mon, 13 Aug 2007 10:35:54 +0200
parents 57709be46d1b
children c9fe270a4101
comparison
equal deleted inserted replaced
287:13a0bd77a29d 288:e11d67e05968
41 #include "imgproc.h" 41 #include "imgproc.h"
42 42
43 #ifdef FILE_CODING 43 #ifdef FILE_CODING
44 #include "file-coding.h" 44 #include "file-coding.h"
45 #endif 45 #endif
46 #include <stdio.h>
47 #include <ctype.h>
48
46 49
47 DEFINE_IMAGE_INSTANTIATOR_FORMAT (bmp); 50 DEFINE_IMAGE_INSTANTIATOR_FORMAT (bmp);
48 Lisp_Object Qbmp; 51 Lisp_Object Qbmp;
49 Lisp_Object Vmswindows_bitmap_file_path; 52 Lisp_Object Vmswindows_bitmap_file_path;
50 static COLORREF transparent_color = RGB (1,1,1); 53 static COLORREF transparent_color = RGB (1,1,1);
59 static void 62 static void
60 mswindows_initialize_image_instance_mask (struct Lisp_Image_Instance* image, 63 mswindows_initialize_image_instance_mask (struct Lisp_Image_Instance* image,
61 struct frame* f); 64 struct frame* f);
62 65
63 COLORREF mswindows_string_to_color (CONST char *name); 66 COLORREF mswindows_string_to_color (CONST char *name);
67
68 #define BPLINE(width) ((int)(~3UL & (unsigned long)((width) +3)))
64 69
65 /************************************************************************/ 70 /************************************************************************/
66 /* convert from a series of RGB triples to a BITMAPINFO formated for the*/ 71 /* convert from a series of RGB triples to a BITMAPINFO formated for the*/
67 /* proper display */ 72 /* proper display */
68 /************************************************************************/ 73 /************************************************************************/
79 BITMAPINFO* bmp_info; 84 BITMAPINFO* bmp_info;
80 unsigned char *ip, *dp; 85 unsigned char *ip, *dp;
81 86
82 if (DEVICE_MSWINDOWS_BITSPIXEL (d) > 0) 87 if (DEVICE_MSWINDOWS_BITSPIXEL (d) > 0)
83 { 88 {
84 int bpline=(int)(~3UL & (unsigned long)((width*3) +3)); 89 int bpline = BPLINE(width * 3);
85 /* FIXME: we can do this because 24bpp implies no colour table, once 90 /* FIXME: we can do this because 24bpp implies no colour table, once
86 * we start paletizing this is no longer true. The X versions of 91 * we start paletizing this is no longer true. The X versions of
87 * this function quantises to 256 colours or bit masks down to a 92 * this function quantises to 256 colours or bit masks down to a
88 * long. Windows can actually handle rgb triples in the raw so I 93 * long. Windows can actually handle rgb triples in the raw so I
89 * don't see much point trying to optimize down to the best 94 * don't see much point trying to optimize down to the best
124 } 129 }
125 else /* scale to 256 colors */ 130 else /* scale to 256 colors */
126 { 131 {
127 int rd,gr,bl; 132 int rd,gr,bl;
128 quant_table *qtable; 133 quant_table *qtable;
129 int bpline= (int)(~3UL & (unsigned long)(width +3)); 134 int bpline = BPLINE (width * 3);
130 /* Quantize the image and get a histogram while we're at it. 135 /* Quantize the image and get a histogram while we're at it.
131 Do this first to save memory */ 136 Do this first to save memory */
132 qtable = build_EImage_quantable(pic, width, height, 256); 137 qtable = build_EImage_quantable(pic, width, height, 256);
133 if (qtable == NULL) return NULL; 138 if (qtable == NULL) return NULL;
134 139
248 int x_hot, int y_hot, 253 int x_hot, int y_hot,
249 int create_mask) 254 int create_mask)
250 { 255 {
251 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii); 256 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
252 struct device *d = XDEVICE (device); 257 struct device *d = XDEVICE (device);
253 struct frame *f = XFRAME (DEVICE_SELECTED_FRAME (d)); 258 struct frame *f;
254 void* bmp_buf=0; 259 void* bmp_buf=0;
255 int type; 260 int type;
256 HBITMAP bitmap; 261 HBITMAP bitmap;
257 HDC hdc; 262 HDC hdc;
258 263
260 signal_simple_error ("Not an mswindows device", device); 265 signal_simple_error ("Not an mswindows device", device);
261 266
262 if (NILP (DEVICE_SELECTED_FRAME (d))) 267 if (NILP (DEVICE_SELECTED_FRAME (d)))
263 signal_simple_error ("No selected frame on mswindows device", device); 268 signal_simple_error ("No selected frame on mswindows device", device);
264 269
270 f = XFRAME (DEVICE_SELECTED_FRAME (d));
271
265 if (dest_mask & IMAGE_COLOR_PIXMAP_MASK) 272 if (dest_mask & IMAGE_COLOR_PIXMAP_MASK)
266 type = IMAGE_COLOR_PIXMAP; 273 type = IMAGE_COLOR_PIXMAP;
267 else if (dest_mask & IMAGE_POINTER_MASK) 274 else if (dest_mask & IMAGE_POINTER_MASK)
268 type = IMAGE_POINTER; 275 type = IMAGE_POINTER;
269 else 276 else
270 incompatible_image_types (instantiator, dest_mask, 277 incompatible_image_types (instantiator, dest_mask,
271 IMAGE_COLOR_PIXMAP_MASK | IMAGE_POINTER_MASK); 278 IMAGE_COLOR_PIXMAP_MASK | IMAGE_POINTER_MASK);
272 hdc = FRAME_MSWINDOWS_DC (f); 279 hdc = FRAME_MSWINDOWS_CDC (f);
273 280
274 bitmap=CreateDIBSection (hdc, 281 bitmap=CreateDIBSection (hdc,
275 bmp_info, 282 bmp_info,
276 DIB_RGB_COLORS, 283 DIB_RGB_COLORS,
277 &bmp_buf, 284 &bmp_buf,
369 struct frame* f) 376 struct frame* f)
370 { 377 {
371 HBITMAP mask; 378 HBITMAP mask;
372 HGDIOBJ old = NULL; 379 HGDIOBJ old = NULL;
373 HDC hcdc = FRAME_MSWINDOWS_CDC (f); 380 HDC hcdc = FRAME_MSWINDOWS_CDC (f);
381 unsigned char* dibits;
374 BITMAPINFO* bmp_info = 382 BITMAPINFO* bmp_info =
375 xmalloc_and_zero (sizeof(BITMAPINFO) + sizeof(RGBQUAD)); 383 xmalloc_and_zero (sizeof(BITMAPINFO) + sizeof(RGBQUAD));
376 int i, j; 384 int i, j;
377 int height = IMAGE_INSTANCE_PIXMAP_HEIGHT (image); 385 int height = IMAGE_INSTANCE_PIXMAP_HEIGHT (image);
378 386
379 void* and_bits; 387 void* and_bits;
380 int bpline= (int)(~3UL & (unsigned long) 388 int maskbpline = BPLINE (((IMAGE_INSTANCE_PIXMAP_WIDTH (image)+7)/8));
381 (((IMAGE_INSTANCE_PIXMAP_WIDTH (image)+7)/8) +3)); 389 int bpline = BPLINE (IMAGE_INSTANCE_PIXMAP_WIDTH (image) * 3);
390
391 if (!bmp_info)
392 return;
382 393
383 bmp_info->bmiHeader.biWidth=IMAGE_INSTANCE_PIXMAP_WIDTH (image); 394 bmp_info->bmiHeader.biWidth=IMAGE_INSTANCE_PIXMAP_WIDTH (image);
384 bmp_info->bmiHeader.biHeight = height; 395 bmp_info->bmiHeader.biHeight = height;
385 bmp_info->bmiHeader.biPlanes=1; 396 bmp_info->bmiHeader.biPlanes=1;
386 bmp_info->bmiHeader.biSize=sizeof(BITMAPINFOHEADER); 397 bmp_info->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
387 bmp_info->bmiHeader.biBitCount=1; 398 bmp_info->bmiHeader.biBitCount=1;
388 bmp_info->bmiHeader.biCompression=BI_RGB; 399 bmp_info->bmiHeader.biCompression=BI_RGB;
389 bmp_info->bmiHeader.biClrUsed = 2; 400 bmp_info->bmiHeader.biClrUsed = 2;
390 bmp_info->bmiHeader.biClrImportant = 2; 401 bmp_info->bmiHeader.biClrImportant = 2;
391 bmp_info->bmiHeader.biSizeImage = height * bpline; 402 bmp_info->bmiHeader.biSizeImage = height * maskbpline;
392 bmp_info->bmiColors[0].rgbRed = 0; 403 bmp_info->bmiColors[0].rgbRed = 0;
393 bmp_info->bmiColors[0].rgbGreen = 0; 404 bmp_info->bmiColors[0].rgbGreen = 0;
394 bmp_info->bmiColors[0].rgbBlue = 0; 405 bmp_info->bmiColors[0].rgbBlue = 0;
395 bmp_info->bmiColors[0].rgbReserved = 0; 406 bmp_info->bmiColors[0].rgbReserved = 0;
396 bmp_info->bmiColors[1].rgbRed = 255; 407 bmp_info->bmiColors[1].rgbRed = 255;
406 { 417 {
407 xfree (bmp_info); 418 xfree (bmp_info);
408 return; 419 return;
409 } 420 }
410 421
411 xfree (bmp_info);
412 old = SelectObject (hcdc, IMAGE_INSTANCE_MSWINDOWS_BITMAP (image)); 422 old = SelectObject (hcdc, IMAGE_INSTANCE_MSWINDOWS_BITMAP (image));
413 423 /* build up an in-memory set of bits to mess with */
424 xzero (*bmp_info);
425
426 bmp_info->bmiHeader.biWidth=IMAGE_INSTANCE_PIXMAP_WIDTH (image);
427 bmp_info->bmiHeader.biHeight = -height;
428 bmp_info->bmiHeader.biPlanes=1;
429 bmp_info->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
430 bmp_info->bmiHeader.biBitCount=24;
431 bmp_info->bmiHeader.biCompression=BI_RGB;
432 bmp_info->bmiHeader.biClrUsed = 0;
433 bmp_info->bmiHeader.biClrImportant = 0;
434 bmp_info->bmiHeader.biSizeImage = height * bpline;
435
436 dibits = xmalloc_and_zero (bpline * height);
437 if (GetDIBits (hcdc,
438 IMAGE_INSTANCE_MSWINDOWS_BITMAP (image),
439 0,
440 height,
441 dibits,
442 bmp_info,
443 DIB_RGB_COLORS) <= 0)
444 {
445 xfree (bmp_info);
446 return;
447 }
448
449 /* now set the colored bits in the mask and transparent ones to
450 black in the original */
414 for(i=0; i<IMAGE_INSTANCE_PIXMAP_WIDTH (image); i++) 451 for(i=0; i<IMAGE_INSTANCE_PIXMAP_WIDTH (image); i++)
415 { 452 {
416 for(j=0; j<height; j++) 453 for(j=0; j<height; j++)
417 { 454 {
418 if( GetPixel( hcdc, i, j ) == transparent_color ) 455 unsigned char* idx = &dibits[j * bpline + i * 3];
456
457 if( RGB (idx[2], idx[1], idx[0]) == transparent_color )
419 { 458 {
420 SetPixel( hcdc, i, j, RGB (0,0,0)); 459 idx[0] = idx[1] = idx[2] = 0;
421 set_mono_pixel( and_bits, bpline, height, i, j, TRUE ); 460 set_mono_pixel( and_bits, maskbpline, height, i, j, TRUE );
422 } 461 }
423 else 462 else
424 { 463 {
425 set_mono_pixel( and_bits, bpline, height, i, j, FALSE ); 464 set_mono_pixel( and_bits, maskbpline, height, i, j, FALSE );
426 } 465 }
427 } 466 }
428 } 467 }
429 468
430 GdiFlush(); 469 SetDIBits (hcdc,
470 IMAGE_INSTANCE_MSWINDOWS_BITMAP (image),
471 0,
472 height,
473 dibits,
474 bmp_info,
475 DIB_RGB_COLORS);
476
477 xfree (bmp_info);
478 xfree (dibits);
479
431 SelectObject(hcdc, old); 480 SelectObject(hcdc, old);
432 481
433 IMAGE_INSTANCE_MSWINDOWS_MASK (image) = mask; 482 IMAGE_INSTANCE_MSWINDOWS_MASK (image) = mask;
434 } 483 }
435 484
661 } 710 }
662 } 711 }
663 712
664 *width = xpmimage.width; 713 *width = xpmimage.width;
665 *height = xpmimage.height; 714 *height = xpmimage.height;
666 maskbpline = (int)(~3UL & (unsigned long) 715 maskbpline = BPLINE (((~7UL & (unsigned long)(*width + 7)) / 8));
667 (((~7UL & (unsigned long)(*width + 7)) / 8) + 3));
668 716
669 *data = xnew_array_and_zero (unsigned char, *width * *height * 3); 717 *data = xnew_array_and_zero (unsigned char, *width * *height * 3);
670 718
671 if (!*data) 719 if (!*data)
672 { 720 {
685 return 0; 733 return 0;
686 } 734 }
687 735
688 for (i=0; i<xpmimage.ncolors; i++) 736 for (i=0; i<xpmimage.ncolors; i++)
689 { 737 {
690 /* pick up symbolic colors */ 738 /* goto alert!!!! */
691 if (xpmimage.colorTable[i].c_color == 0 739 /* pick up symbolic colors in preference */
692 && 740 if (xpmimage.colorTable[i].symbolic)
693 xpmimage.colorTable[i].symbolic != 0)
694 { 741 {
695 if (!color_symbols) 742 if (!strcasecmp (xpmimage.colorTable[i].symbolic,"BgColor")
743 ||
744 !strcasecmp (xpmimage.colorTable[i].symbolic,"None"))
696 { 745 {
697 xfree (*data); 746 *transp=TRUE;
698 xfree (colortbl); 747 colortbl[i]=transparent_color;
699 XpmFreeXpmImage (&xpmimage); 748 transp_idx=i;
700 XpmFreeXpmInfo (&xpminfo); 749 goto label_found_color;
701 return 0;
702 } 750 }
703 for (j = 0; j<nsymbols; j++) 751 else if (color_symbols)
704 { 752 {
705 if (!strcmp (xpmimage.colorTable[i].symbolic, 753 for (j = 0; j<nsymbols; j++)
706 color_symbols[j].name ))
707 { 754 {
708 colortbl[i]=color_symbols[j].color; 755 if (!strcmp (xpmimage.colorTable[i].symbolic,
756 color_symbols[j].name ))
757 {
758 colortbl[i]=color_symbols[j].color;
759 goto label_found_color;
760 }
709 } 761 }
710 } 762 }
763 else if (xpmimage.colorTable[i].c_color == 0)
764 {
765 goto label_no_color;
766 }
711 } 767 }
712 /* pick up transparencies */ 768 /* pick up transparencies */
713 else if (!strcasecmp (xpmimage.colorTable[i].c_color,"None") 769 if (!strcasecmp (xpmimage.colorTable[i].c_color,"None"))
714 ||
715 (xpmimage.colorTable[i].symbolic
716 &&
717 (!strcasecmp (xpmimage.colorTable[i].symbolic,"BgColor")
718 ||
719 !strcasecmp (xpmimage.colorTable[i].symbolic,"None"))))
720 { 770 {
721 *transp=TRUE; 771 *transp=TRUE;
722 colortbl[i]=transparent_color; 772 colortbl[i]=transparent_color;
723 transp_idx=i; 773 transp_idx=i;
774 goto label_found_color;
724 } 775 }
725 else 776 /* finally pick up a normal color spec */
777 if (xpmimage.colorTable[i].c_color)
726 { 778 {
727 colortbl[i]= 779 colortbl[i]=
728 mswindows_string_to_color (xpmimage.colorTable[i].c_color); 780 mswindows_string_to_color (xpmimage.colorTable[i].c_color);
781 goto label_found_color;
729 } 782 }
783
784 label_no_color:
785 xfree (*data);
786 xfree (colortbl);
787 XpmFreeXpmImage (&xpmimage);
788 XpmFreeXpmInfo (&xpminfo);
789 return 0;
790
791 label_found_color:;
730 } 792 }
731 793
732 /* convert the image */ 794 /* convert the image */
733 sptr=xpmimage.data; 795 sptr=xpmimage.data;
734 dptr=*data; 796 dptr=*data;
1177 CHECK_STRING (data); 1239 CHECK_STRING (data);
1178 else 1240 else
1179 CHECK_INT (data); 1241 CHECK_INT (data);
1180 } 1242 }
1181 1243
1244 /**********************************************************************
1245 * XBM *
1246 **********************************************************************/
1247 #ifndef HAVE_X_WINDOWS
1248 /* $XConsortium: RdBitF.c,v 1.10 94/04/17 20:16:13 kaleb Exp $ */
1249
1250 /*
1251
1252 Copyright (c) 1988 X Consortium
1253
1254 Permission is hereby granted, free of charge, to any person obtaining a copy
1255 of this software and associated documentation files (the "Software"), to deal
1256 in the Software without restriction, including without limitation the rights
1257 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1258 copies of the Software, and to permit persons to whom the Software is
1259 furnished to do so, subject to the following conditions:
1260
1261 The above copyright notice and this permission notice shall be included in
1262 all copies or substantial portions of the Software.
1263
1264 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1265 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1266 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1267 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
1268 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
1269 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1270
1271 Except as contained in this notice, the name of the X Consortium shall not be
1272 used in advertising or otherwise to promote the sale, use or other dealings
1273 in this Software without prior written authorization from the X Consortium.
1274
1275 */
1276
1277 /*
1278 * This file contains miscellaneous utility routines and is not part of the
1279 * Xlib standard.
1280 *
1281 * Public entry points:
1282 *
1283 * XmuReadBitmapData read data from FILE descriptor
1284 * XmuReadBitmapDataFromFile read X10 or X11 format bitmap files
1285 * and return data
1286 *
1287 * Note that this file and ../X/XRdBitF.c look very similar.... Keep them
1288 * that way (but don't use common source code so that people can have one
1289 * without the other).
1290 */
1291
1292
1293 /*
1294 * Based on an optimized version provided by Jim Becker, Auguest 5, 1988.
1295 */
1296 #ifndef BitmapSuccess
1297 #define BitmapSuccess 0
1298 #define BitmapOpenFailed 1
1299 #define BitmapFileInvalid 2
1300 #define BitmapNoMemory 3
1301 #endif
1302 #define MAX_SIZE 255
1303
1304 /* shared data for the image read/parse logic */
1305 static short hexTable[256]; /* conversion value */
1306 static int initialized = FALSE; /* easier to fill in at run time */
1307
1308 /*
1309 * Table index for the hex values. Initialized once, first time.
1310 * Used for translation value or delimiter significance lookup.
1311 */
1312 static void initHexTable()
1313 {
1314 /*
1315 * We build the table at run time for several reasons:
1316 *
1317 * 1. portable to non-ASCII machines.
1318 * 2. still reentrant since we set the init flag after setting table.
1319 * 3. easier to extend.
1320 * 4. less prone to bugs.
1321 */
1322 hexTable['0'] = 0; hexTable['1'] = 1;
1323 hexTable['2'] = 2; hexTable['3'] = 3;
1324 hexTable['4'] = 4; hexTable['5'] = 5;
1325 hexTable['6'] = 6; hexTable['7'] = 7;
1326 hexTable['8'] = 8; hexTable['9'] = 9;
1327 hexTable['A'] = 10; hexTable['B'] = 11;
1328 hexTable['C'] = 12; hexTable['D'] = 13;
1329 hexTable['E'] = 14; hexTable['F'] = 15;
1330 hexTable['a'] = 10; hexTable['b'] = 11;
1331 hexTable['c'] = 12; hexTable['d'] = 13;
1332 hexTable['e'] = 14; hexTable['f'] = 15;
1333
1334 /* delimiters of significance are flagged w/ negative value */
1335 hexTable[' '] = -1; hexTable[','] = -1;
1336 hexTable['}'] = -1; hexTable['\n'] = -1;
1337 hexTable['\t'] = -1;
1338
1339 initialized = TRUE;
1340 }
1341
1342 /*
1343 * read next hex value in the input stream, return -1 if EOF
1344 */
1345 static int NextInt ( FILE *fstream )
1346 {
1347 int ch;
1348 int value = 0;
1349 int gotone = 0;
1350 int done = 0;
1351
1352 /* loop, accumulate hex value until find delimiter */
1353 /* skip any initial delimiters found in read stream */
1354
1355 while (!done) {
1356 ch = getc(fstream);
1357 if (ch == EOF) {
1358 value = -1;
1359 done++;
1360 } else {
1361 /* trim high bits, check type and accumulate */
1362 ch &= 0xff;
1363 if (isascii(ch) && isxdigit(ch)) {
1364 value = (value << 4) + hexTable[ch];
1365 gotone++;
1366 } else if ((hexTable[ch]) < 0 && gotone)
1367 done++;
1368 }
1369 }
1370 return value;
1371 }
1372
1373
1374 /*
1375 * The data returned by the following routine is always in left-most byte
1376 * first and left-most bit first. If it doesn't return BitmapSuccess then
1377 * its arguments won't have been touched. This routine should look as much
1378 * like the Xlib routine XReadBitmapfile as possible.
1379 */
1380 int read_bitmap_data (fstream, width, height, datap, x_hot, y_hot)
1381 FILE *fstream; /* handle on file */
1382 unsigned int *width, *height; /* RETURNED */
1383 unsigned char **datap; /* RETURNED */
1384 int *x_hot, *y_hot; /* RETURNED */
1385 {
1386 unsigned char *data = NULL; /* working variable */
1387 char line[MAX_SIZE]; /* input line from file */
1388 int size; /* number of bytes of data */
1389 char name_and_type[MAX_SIZE]; /* an input line */
1390 char *type; /* for parsing */
1391 int value; /* from an input line */
1392 int version10p; /* boolean, old format */
1393 int padding; /* to handle alignment */
1394 int bytes_per_line; /* per scanline of data */
1395 unsigned int ww = 0; /* width */
1396 unsigned int hh = 0; /* height */
1397 int hx = -1; /* x hotspot */
1398 int hy = -1; /* y hotspot */
1399
1400 #define Xmalloc(size) malloc(size)
1401
1402 /* first time initialization */
1403 if (initialized == FALSE) initHexTable();
1404
1405 /* error cleanup and return macro */
1406 #define RETURN(code) { if (data) free (data); return code; }
1407
1408 while (fgets(line, MAX_SIZE, fstream)) {
1409 if (strlen(line) == MAX_SIZE-1) {
1410 RETURN (BitmapFileInvalid);
1411 }
1412 if (sscanf(line,"#define %s %d",name_and_type,&value) == 2) {
1413 if (!(type = strrchr(name_and_type, '_')))
1414 type = name_and_type;
1415 else
1416 type++;
1417
1418 if (!strcmp("width", type))
1419 ww = (unsigned int) value;
1420 if (!strcmp("height", type))
1421 hh = (unsigned int) value;
1422 if (!strcmp("hot", type)) {
1423 if (type-- == name_and_type || type-- == name_and_type)
1424 continue;
1425 if (!strcmp("x_hot", type))
1426 hx = value;
1427 if (!strcmp("y_hot", type))
1428 hy = value;
1429 }
1430 continue;
1431 }
1432
1433 if (sscanf(line, "static short %s = {", name_and_type) == 1)
1434 version10p = 1;
1435 else if (sscanf(line,"static unsigned char %s = {",name_and_type) == 1)
1436 version10p = 0;
1437 else if (sscanf(line, "static char %s = {", name_and_type) == 1)
1438 version10p = 0;
1439 else
1440 continue;
1441
1442 if (!(type = strrchr(name_and_type, '_')))
1443 type = name_and_type;
1444 else
1445 type++;
1446
1447 if (strcmp("bits[]", type))
1448 continue;
1449
1450 if (!ww || !hh)
1451 RETURN (BitmapFileInvalid);
1452
1453 if ((ww % 16) && ((ww % 16) < 9) && version10p)
1454 padding = 1;
1455 else
1456 padding = 0;
1457
1458 bytes_per_line = (ww+7)/8 + padding;
1459
1460 size = bytes_per_line * hh;
1461 data = (unsigned char *) Xmalloc ((unsigned int) size);
1462 if (!data)
1463 RETURN (BitmapNoMemory);
1464
1465 if (version10p) {
1466 unsigned char *ptr;
1467 int bytes;
1468
1469 for (bytes=0, ptr=data; bytes<size; (bytes += 2)) {
1470 if ((value = NextInt(fstream)) < 0)
1471 RETURN (BitmapFileInvalid);
1472 *(ptr++) = value;
1473 if (!padding || ((bytes+2) % bytes_per_line))
1474 *(ptr++) = value >> 8;
1475 }
1476 } else {
1477 unsigned char *ptr;
1478 int bytes;
1479
1480 for (bytes=0, ptr=data; bytes<size; bytes++, ptr++) {
1481 if ((value = NextInt(fstream)) < 0)
1482 RETURN (BitmapFileInvalid);
1483 *ptr=value;
1484 }
1485 }
1486 break;
1487 } /* end while */
1488
1489 if (data == NULL) {
1490 RETURN (BitmapFileInvalid);
1491 }
1492
1493 *datap = data;
1494 data = NULL;
1495 *width = ww;
1496 *height = hh;
1497 if (x_hot) *x_hot = hx;
1498 if (y_hot) *y_hot = hy;
1499
1500 RETURN (BitmapSuccess);
1501 }
1502
1503
1504 int read_bitmap_data_from_file (CONST char *filename, unsigned int *width,
1505 unsigned int *height, unsigned char **datap,
1506 int *x_hot, int *y_hot)
1507 {
1508 FILE *fstream;
1509 int status;
1510
1511 if ((fstream = fopen (filename, "r")) == NULL) {
1512 return BitmapOpenFailed;
1513 }
1514 status = read_bitmap_data (fstream, width, height, datap, x_hot, y_hot);
1515 fclose (fstream);
1516 return status;
1517 }
1518 #endif /* HAVE_X_WINDOWS */
1519
1520 /* this table flips four bits around. */
1521 static int flip_table[] =
1522 {
1523 0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15
1524 };
1525
1526 /* the bitmap data comes in the following format: Widths are padded to
1527 a multiple of 8. Scan lines are stored in increasing byte order
1528 from left to right, little-endian within a byte. 0 = white, 1 =
1529 black. It must be converted to the following format: Widths are
1530 padded to a multiple of 16. Scan lines are stored in increasing
1531 byte order from left to right, big-endian within a byte. 0 =
1532 black, 1 = white. */
1533 static HBITMAP
1534 xbm_create_bitmap_from_data (char *data,
1535 unsigned int width, unsigned int height)
1536 {
1537 int old_width = (width + 7)/8;
1538 int new_width = 2*((width + 15)/16);
1539 unsigned char *offset;
1540 unsigned char *new_data, *new_offset;
1541 unsigned int i;
1542 int j;
1543 HBITMAP hb;
1544
1545 new_data = (unsigned char *) xmalloc (height*new_width);
1546 for (i=0; i<height; i++)
1547 {
1548 offset = data + i*old_width;
1549 new_offset = new_data + i*new_width;
1550 new_offset[new_width - 1] = 0; /* there may be an extra byte
1551 that needs to be padded */
1552 for (j=0; j<old_width; j++)
1553 {
1554 int byte = offset[j];
1555 new_offset[j] = ~ (unsigned char)
1556 ((flip_table[byte & 0xf] << 4) + flip_table[byte >> 4]);
1557 }
1558 }
1559 hb = CreateBitmap (width, height, 1, 1, new_data);
1560 xfree (new_data);
1561
1562 return hb;
1563 }
1564
1565 /* Given inline data for a mono pixmap, initialize the given
1566 image instance accordingly. */
1567
1568 static void
1569 init_image_instance_from_xbm_inline (struct Lisp_Image_Instance *ii,
1570 int width, int height,
1571 /* Note that data is in ext-format! */
1572 CONST char *bits,
1573 Lisp_Object instantiator,
1574 Lisp_Object pointer_fg,
1575 Lisp_Object pointer_bg,
1576 int dest_mask,
1577 HBITMAP mask,
1578 Lisp_Object mask_filename)
1579 {
1580 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
1581 Lisp_Object foreground = find_keyword_in_vector (instantiator, Q_foreground);
1582 Lisp_Object background = find_keyword_in_vector (instantiator, Q_background);
1583 enum image_instance_type type;
1584
1585 if (!DEVICE_MSWINDOWS_P (XDEVICE (device)))
1586 signal_simple_error ("Not an MS-Windows device", device);
1587
1588 if ((dest_mask & IMAGE_MONO_PIXMAP_MASK) &&
1589 (dest_mask & IMAGE_COLOR_PIXMAP_MASK))
1590 {
1591 if (!NILP (foreground) || !NILP (background))
1592 type = IMAGE_COLOR_PIXMAP;
1593 else
1594 type = IMAGE_MONO_PIXMAP;
1595 }
1596 else if (dest_mask & IMAGE_MONO_PIXMAP_MASK)
1597 type = IMAGE_MONO_PIXMAP;
1598 else if (dest_mask & IMAGE_COLOR_PIXMAP_MASK)
1599 type = IMAGE_COLOR_PIXMAP;
1600 else if (dest_mask & IMAGE_POINTER_MASK)
1601 type = IMAGE_POINTER;
1602 else
1603 incompatible_image_types (instantiator, dest_mask,
1604 IMAGE_MONO_PIXMAP_MASK | IMAGE_COLOR_PIXMAP_MASK
1605 | IMAGE_POINTER_MASK);
1606
1607 mswindows_initialize_dibitmap_image_instance (ii, type);
1608 IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = width;
1609 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) = height;
1610 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) =
1611 find_keyword_in_vector (instantiator, Q_file);
1612 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii), 0);
1613 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii), 0);
1614 IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = 1;
1615 IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = mask;
1616 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) =
1617 xbm_create_bitmap_from_data ((Extbyte *) bits, width, height);
1618
1619 switch (type)
1620 {
1621 case IMAGE_MONO_PIXMAP:
1622 break;
1623
1624 case IMAGE_COLOR_PIXMAP:
1625 {
1626 unsigned long fg = PALETTERGB (0,0,0);
1627 unsigned long bg = PALETTERGB (255,255,255);
1628
1629 if (!NILP (foreground) && !COLOR_INSTANCEP (foreground))
1630 foreground =
1631 Fmake_color_instance (foreground, device,
1632 encode_error_behavior_flag (ERROR_ME));
1633
1634 if (COLOR_INSTANCEP (foreground))
1635 fg = COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (foreground));
1636
1637 if (!NILP (background) && !COLOR_INSTANCEP (background))
1638 background =
1639 Fmake_color_instance (background, device,
1640 encode_error_behavior_flag (ERROR_ME));
1641
1642 if (COLOR_INSTANCEP (background))
1643 bg = COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (background));
1644
1645 IMAGE_INSTANCE_PIXMAP_FG (ii) = foreground;
1646 IMAGE_INSTANCE_PIXMAP_BG (ii) = background;
1647 }
1648 break;
1649
1650 case IMAGE_POINTER:
1651 {
1652 if (NILP (foreground))
1653 foreground = pointer_fg;
1654 if (NILP (background))
1655 background = pointer_bg;
1656
1657 IMAGE_INSTANCE_PIXMAP_FG (ii) = foreground;
1658 IMAGE_INSTANCE_PIXMAP_BG (ii) = background;
1659 IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii) =
1660 find_keyword_in_vector (instantiator, Q_hotspot_x);
1661 IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii) =
1662 find_keyword_in_vector (instantiator, Q_hotspot_y);
1663 }
1664 break;
1665
1666 default:
1667 abort ();
1668 }
1669 }
1670
1671 static void
1672 xbm_instantiate_1 (Lisp_Object image_instance, Lisp_Object instantiator,
1673 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1674 int dest_mask, int width, int height,
1675 /* Note that data is in ext-format! */
1676 CONST char *bits)
1677 {
1678 Lisp_Object mask_data = find_keyword_in_vector (instantiator, Q_mask_data);
1679 Lisp_Object mask_file = find_keyword_in_vector (instantiator, Q_mask_file);
1680 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
1681 HBITMAP mask = 0;
1682 CONST char *gcc_may_you_rot_in_hell;
1683
1684 if (!NILP (mask_data))
1685 {
1686 GET_C_STRING_BINARY_DATA_ALLOCA (XCAR (XCDR (XCDR (mask_data))),
1687 gcc_may_you_rot_in_hell);
1688 mask =
1689 xbm_create_bitmap_from_data ( (unsigned char *)
1690 gcc_may_you_rot_in_hell,
1691 XINT (XCAR (mask_data)),
1692 XINT (XCAR (XCDR (mask_data))));
1693 }
1694
1695 init_image_instance_from_xbm_inline (ii, width, height, bits,
1696 instantiator, pointer_fg, pointer_bg,
1697 dest_mask, mask, mask_file);
1698 }
1699
1700 /* Instantiate method for XBM's. */
1701
1702 static void
1703 mswindows_xbm_instantiate (Lisp_Object image_instance,
1704 Lisp_Object instantiator,
1705 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1706 int dest_mask, Lisp_Object domain)
1707 {
1708 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
1709 CONST char *gcc_go_home;
1710
1711 assert (!NILP (data));
1712
1713 GET_C_STRING_BINARY_DATA_ALLOCA (XCAR (XCDR (XCDR (data))),
1714 gcc_go_home);
1715
1716 xbm_instantiate_1 (image_instance, instantiator, pointer_fg,
1717 pointer_bg, dest_mask, XINT (XCAR (data)),
1718 XINT (XCAR (XCDR (data))), gcc_go_home);
1719 }
1720
1182 1721
1183 /************************************************************************/ 1722 /************************************************************************/
1184 /* image instance methods */ 1723 /* image instance methods */
1185 /************************************************************************/ 1724 /************************************************************************/
1186 1725
1313 CONSOLE_HAS_METHOD (mswindows, init_image_instance_from_eimage); 1852 CONSOLE_HAS_METHOD (mswindows, init_image_instance_from_eimage);
1314 CONSOLE_HAS_METHOD (mswindows, locate_pixmap_file); 1853 CONSOLE_HAS_METHOD (mswindows, locate_pixmap_file);
1315 #ifdef HAVE_XPM 1854 #ifdef HAVE_XPM
1316 CONSOLE_HAS_METHOD (mswindows, xpm_instantiate); 1855 CONSOLE_HAS_METHOD (mswindows, xpm_instantiate);
1317 #endif 1856 #endif
1857 CONSOLE_HAS_METHOD (mswindows, xbm_instantiate);
1318 } 1858 }
1319 1859
1320 void 1860 void
1321 image_instantiator_format_create_glyphs_mswindows (void) 1861 image_instantiator_format_create_glyphs_mswindows (void)
1322 { 1862 {