Mercurial > hg > xemacs-beta
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 { |