Mercurial > hg > xemacs-beta
comparison src/glyphs-msw.c @ 282:c42ec1d1cded r21-0b39
Import from CVS: tag r21-0b39
author | cvs |
---|---|
date | Mon, 13 Aug 2007 10:33:18 +0200 |
parents | 7df0dd720c89 |
children | 558f606b08ae |
comparison
equal
deleted
inserted
replaced
281:090b52736db2 | 282:c42ec1d1cded |
---|---|
1 /* mswindows-specific Lisp objects. | 1 /* mswindows-specific Lisp objects. |
2 Copyright (C) 1993, 1994 Free Software Foundation, Inc. | |
3 Copyright (C) 1995 Board of Trustees, University of Illinois. | |
4 Copyright (C) 1995 Tinker Systems | |
5 Copyright (C) 1995, 1996 Ben Wing | |
6 Copyright (C) 1995 Sun Microsystems | |
7 Copyright (C) 1998 Andy Piper. | 2 Copyright (C) 1998 Andy Piper. |
8 | 3 |
9 This file is part of XEmacs. | 4 This file is part of XEmacs. |
10 | 5 |
11 XEmacs is free software; you can redistribute it and/or modify it | 6 XEmacs is free software; you can redistribute it and/or modify it |
48 #endif | 43 #endif |
49 | 44 |
50 DEFINE_IMAGE_INSTANTIATOR_FORMAT (bmp); | 45 DEFINE_IMAGE_INSTANTIATOR_FORMAT (bmp); |
51 Lisp_Object Qbmp; | 46 Lisp_Object Qbmp; |
52 Lisp_Object Vmswindows_bitmap_file_path; | 47 Lisp_Object Vmswindows_bitmap_file_path; |
48 static COLORREF transparent_color = RGB (1,1,1); | |
53 | 49 |
54 static void | 50 static void |
55 mswindows_initialize_dibitmap_image_instance (struct Lisp_Image_Instance *ii, | 51 mswindows_initialize_dibitmap_image_instance (struct Lisp_Image_Instance *ii, |
56 enum image_instance_type type); | 52 enum image_instance_type type); |
53 static void | |
54 mswindows_initialize_image_instance_mask (struct Lisp_Image_Instance* image, | |
55 struct frame* f); | |
57 | 56 |
58 COLORREF mswindows_string_to_color (CONST char *name); | 57 COLORREF mswindows_string_to_color (CONST char *name); |
59 | 58 |
60 /************************************************************************/ | 59 /************************************************************************/ |
61 /* convert from a series of RGB triples to a BITMAPINFO formated for the*/ | 60 /* convert from a series of RGB triples to a BITMAPINFO formated for the*/ |
237 init_image_instance_from_dibitmap (struct Lisp_Image_Instance *ii, | 236 init_image_instance_from_dibitmap (struct Lisp_Image_Instance *ii, |
238 BITMAPINFO *bmp_info, | 237 BITMAPINFO *bmp_info, |
239 int dest_mask, | 238 int dest_mask, |
240 void *bmp_data, | 239 void *bmp_data, |
241 int bmp_bits, | 240 int bmp_bits, |
242 Lisp_Object instantiator) | 241 Lisp_Object instantiator, |
242 int x_hot, int y_hot, | |
243 int create_mask) | |
243 { | 244 { |
244 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii); | 245 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii); |
245 struct device *d = XDEVICE (device); | 246 struct device *d = XDEVICE (device); |
246 struct frame *f = XFRAME (DEVICE_SELECTED_FRAME (d)); | 247 struct frame *f = XFRAME (DEVICE_SELECTED_FRAME (d)); |
247 void* bmp_buf=0; | 248 void* bmp_buf=0; |
249 int type; | |
248 HBITMAP bitmap; | 250 HBITMAP bitmap; |
249 HDC hdc; | 251 HDC hdc; |
250 | 252 |
251 if (!DEVICE_MSWINDOWS_P (d)) | 253 if (!DEVICE_MSWINDOWS_P (d)) |
252 signal_simple_error ("Not an mswindows device", device); | 254 signal_simple_error ("Not an mswindows device", device); |
253 | 255 |
254 if (NILP (DEVICE_SELECTED_FRAME (d))) | 256 if (NILP (DEVICE_SELECTED_FRAME (d))) |
255 signal_simple_error ("No selected frame on mswindows device", device); | 257 signal_simple_error ("No selected frame on mswindows device", device); |
256 | 258 |
257 if (!(dest_mask & IMAGE_COLOR_PIXMAP_MASK)) | 259 if (dest_mask & IMAGE_COLOR_PIXMAP_MASK) |
260 type = IMAGE_COLOR_PIXMAP; | |
261 else if (dest_mask & IMAGE_POINTER_MASK) | |
262 type = IMAGE_POINTER; | |
263 else | |
258 incompatible_image_types (instantiator, dest_mask, | 264 incompatible_image_types (instantiator, dest_mask, |
259 IMAGE_COLOR_PIXMAP_MASK); | 265 IMAGE_COLOR_PIXMAP_MASK | IMAGE_POINTER_MASK); |
260 hdc = FRAME_MSWINDOWS_DC (f); | 266 hdc = FRAME_MSWINDOWS_DC (f); |
261 | 267 |
262 bitmap=CreateDIBSection (hdc, | 268 bitmap=CreateDIBSection (hdc, |
263 bmp_info, | 269 bmp_info, |
264 DIB_RGB_COLORS, | 270 DIB_RGB_COLORS, |
269 signal_simple_error ("Unable to create bitmap", instantiator); | 275 signal_simple_error ("Unable to create bitmap", instantiator); |
270 | 276 |
271 /* copy in the actual bitmap */ | 277 /* copy in the actual bitmap */ |
272 memcpy (bmp_buf, bmp_data, bmp_bits); | 278 memcpy (bmp_buf, bmp_data, bmp_bits); |
273 | 279 |
274 mswindows_initialize_dibitmap_image_instance (ii, IMAGE_COLOR_PIXMAP); | 280 mswindows_initialize_dibitmap_image_instance (ii, type); |
275 | 281 |
276 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) = | 282 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) = |
277 find_keyword_in_vector (instantiator, Q_file); | 283 find_keyword_in_vector (instantiator, Q_file); |
278 | 284 |
279 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = bitmap; | 285 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = bitmap; |
280 IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = bitmap; | 286 IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = NULL; |
281 IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = bmp_info->bmiHeader.biWidth; | 287 IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = bmp_info->bmiHeader.biWidth; |
282 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) = bmp_info->bmiHeader.biHeight; | 288 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) = bmp_info->bmiHeader.biHeight; |
283 IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = bmp_info->bmiHeader.biBitCount; | 289 IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = bmp_info->bmiHeader.biBitCount; |
290 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii), x_hot); | |
291 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii), y_hot); | |
292 | |
293 if (create_mask) | |
294 { | |
295 mswindows_initialize_image_instance_mask (ii, f); | |
296 } | |
297 | |
298 if (type == IMAGE_POINTER) | |
299 { | |
300 mswindows_initialize_image_instance_icon(ii, TRUE); | |
301 } | |
284 } | 302 } |
285 | 303 |
286 static void | 304 static void |
287 mswindows_init_image_instance_from_eimage (struct Lisp_Image_Instance *ii, | 305 mswindows_init_image_instance_from_eimage (struct Lisp_Image_Instance *ii, |
288 int width, int height, | 306 int width, int height, |
313 instantiator); | 331 instantiator); |
314 } | 332 } |
315 | 333 |
316 /* Now create the pixmap and set up the image instance */ | 334 /* Now create the pixmap and set up the image instance */ |
317 init_image_instance_from_dibitmap (ii, bmp_info, dest_mask, | 335 init_image_instance_from_dibitmap (ii, bmp_info, dest_mask, |
318 bmp_data, bmp_bits, instantiator); | 336 bmp_data, bmp_bits, instantiator, |
337 0, 0, 0); | |
319 | 338 |
320 xfree (bmp_info); | 339 xfree (bmp_info); |
321 xfree (bmp_data); | 340 xfree (bmp_data); |
322 } | 341 } |
323 | 342 |
324 void | 343 static void set_mono_pixel ( unsigned char* bits, |
325 mswindows_create_icon_from_image(Lisp_Object image, struct frame* f, int size) | 344 int bpline, int height, |
345 int x, int y, int white ) | |
346 { | |
347 int index; | |
348 unsigned char bitnum; | |
349 /* Find the byte on which this scanline begins */ | |
350 index = (height - y - 1) * bpline; | |
351 /* Find the byte containing this pixel */ | |
352 index += (x >> 3); | |
353 /* Which bit is it? */ | |
354 bitnum = (unsigned char)( 7 - (x % 8) ); | |
355 if( white ) /* Turn it on */ | |
356 bits[index] |= (1<<bitnum); | |
357 else /* Turn it off */ | |
358 bits[index] &= ~(1<<bitnum); | |
359 } | |
360 | |
361 static void | |
362 mswindows_initialize_image_instance_mask (struct Lisp_Image_Instance* image, | |
363 struct frame* f) | |
326 { | 364 { |
327 HBITMAP mask, bmp; | 365 HBITMAP mask, bmp; |
328 HDC hcdc = FRAME_MSWINDOWS_CDC (f); | 366 HDC hcdc = FRAME_MSWINDOWS_CDC (f); |
329 HDC hdcDst = CreateCompatibleDC (hcdc); | 367 BITMAPINFO* bmp_info = |
368 xmalloc_and_zero (sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)); | |
369 int i, j; | |
370 int height = IMAGE_INSTANCE_PIXMAP_HEIGHT (image); | |
371 | |
372 void* and_bits; | |
373 int bpline= (int)(~3UL & (unsigned long) | |
374 (((IMAGE_INSTANCE_PIXMAP_WIDTH (image)+7)/8) +3)); | |
375 | |
376 bmp_info->bmiHeader.biWidth=IMAGE_INSTANCE_PIXMAP_WIDTH (image); | |
377 bmp_info->bmiHeader.biHeight = height; | |
378 bmp_info->bmiHeader.biPlanes=1; | |
379 bmp_info->bmiHeader.biSize=sizeof(BITMAPINFOHEADER); | |
380 bmp_info->bmiHeader.biBitCount=1; | |
381 bmp_info->bmiHeader.biCompression=BI_RGB; | |
382 bmp_info->bmiHeader.biClrUsed = 2; | |
383 bmp_info->bmiHeader.biClrImportant = 2; | |
384 bmp_info->bmiHeader.biSizeImage = height * bpline; | |
385 bmp_info->bmiColors[0].rgbRed = 0; | |
386 bmp_info->bmiColors[0].rgbGreen = 0; | |
387 bmp_info->bmiColors[0].rgbBlue = 0; | |
388 bmp_info->bmiColors[0].rgbReserved = 0; | |
389 bmp_info->bmiColors[1].rgbRed = 255; | |
390 bmp_info->bmiColors[1].rgbGreen = 255; | |
391 bmp_info->bmiColors[1].rgbBlue = 255; | |
392 bmp_info->bmiColors[0].rgbReserved = 0; | |
393 | |
394 if (!(mask = CreateDIBSection (hcdc, | |
395 bmp_info, | |
396 DIB_RGB_COLORS, | |
397 &and_bits, | |
398 0,0))) | |
399 { | |
400 xfree (bmp_info); | |
401 return; | |
402 } | |
403 | |
404 xfree (bmp_info); | |
405 SelectObject (hcdc, IMAGE_INSTANCE_MSWINDOWS_BITMAP (image)); | |
406 | |
407 for(i=0; i<IMAGE_INSTANCE_PIXMAP_WIDTH (image); i++) | |
408 { | |
409 for(j=0; j<height; j++) | |
410 { | |
411 if( GetPixel( hcdc, i, j ) == transparent_color ) | |
412 { | |
413 SetPixel( hcdc, i, j, RGB (0,0,0)); | |
414 set_mono_pixel( and_bits, bpline, height, i, j, TRUE ); | |
415 } | |
416 else | |
417 { | |
418 set_mono_pixel( and_bits, bpline, height, i, j, FALSE ); | |
419 } | |
420 } | |
421 } | |
422 | |
423 GdiFlush(); | |
424 SelectObject(hcdc, 0); | |
425 | |
426 IMAGE_INSTANCE_MSWINDOWS_MASK (image) = mask; | |
427 } | |
428 | |
429 void | |
430 mswindows_initialize_image_instance_icon (struct Lisp_Image_Instance* image, | |
431 int cursor) | |
432 { | |
330 ICONINFO x_icon; | 433 ICONINFO x_icon; |
331 | 434 |
332 if (size!=16 && size!=32) | 435 /* we rely on windows to do any resizing necessary */ |
333 { | 436 x_icon.fIcon=cursor ? FALSE : TRUE; |
334 signal_simple_error("Icons must be 16x16 or 32x32", image); | 437 x_icon.xHotspot=XINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (image)); |
335 } | 438 x_icon.yHotspot=XINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (image)); |
336 | 439 x_icon.hbmMask=IMAGE_INSTANCE_MSWINDOWS_MASK (image); |
337 #if 0 | 440 x_icon.hbmColor=IMAGE_INSTANCE_MSWINDOWS_BITMAP (image); |
338 iIconWidth = GetSystemMetrics(SM_CXICON); | 441 |
339 iIconHeight = GetSystemMetrics(SM_CYICON); | 442 IMAGE_INSTANCE_MSWINDOWS_ICON (image)= |
340 #endif | |
341 | |
342 SelectObject(hcdc, XIMAGE_INSTANCE_MSWINDOWS_BITMAP (image)); | |
343 | |
344 bmp = CreateCompatibleBitmap(hcdc, size, size); | |
345 DeleteObject( SelectObject(hdcDst, bmp) ); | |
346 | |
347 if (!StretchBlt(hdcDst, 0, 0, size, size, | |
348 hcdc, 0, 0, | |
349 XIMAGE_INSTANCE_PIXMAP_WIDTH (image), | |
350 XIMAGE_INSTANCE_PIXMAP_HEIGHT (image), | |
351 SRCCOPY)) | |
352 { | |
353 printf("StretchBlt failed\n"); | |
354 } | |
355 | |
356 if (!(mask = CreateBitmap(size, size, 1, 1, NULL))) | |
357 { | |
358 printf("CreateBitmap() failed\n"); | |
359 } | |
360 if (!SelectObject(hdcDst, mask) | |
361 || | |
362 !SelectObject(hcdc, bmp)) | |
363 { | |
364 printf("SelectObject() failed\n"); | |
365 } | |
366 | |
367 if (!BitBlt(hdcDst, 0, 0, size, size, | |
368 hcdc, 0, 0, | |
369 NOTSRCCOPY)) | |
370 { | |
371 printf("BitBlt failed\n"); | |
372 } | |
373 | |
374 SelectObject(hdcDst, 0); | |
375 SelectObject(hcdc, 0); | |
376 /* PatBlt(hdcDst, 0, 0, size, size, WHITENESS);*/ | |
377 | |
378 x_icon.fIcon=TRUE; | |
379 x_icon.xHotspot=XINT (XIMAGE_INSTANCE_PIXMAP_HOTSPOT_X (image)); | |
380 x_icon.yHotspot=XINT (XIMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (image)); | |
381 x_icon.hbmMask=mask; | |
382 x_icon.hbmColor=bmp; | |
383 | |
384 XIMAGE_INSTANCE_MSWINDOWS_ICON (image)= | |
385 CreateIconIndirect (&x_icon); | 443 CreateIconIndirect (&x_icon); |
386 XIMAGE_INSTANCE_MSWINDOWS_MASK (image)=mask; | |
387 | |
388 DeleteDC(hdcDst); | |
389 } | 444 } |
390 | 445 |
391 int | 446 int |
392 mswindows_resize_dibitmap_instance (struct Lisp_Image_Instance* ii, | 447 mswindows_resize_dibitmap_instance (struct Lisp_Image_Instance* ii, |
393 struct frame* f, | 448 struct frame* f, |
506 | 561 |
507 static int xpm_to_eimage (Lisp_Object image, CONST Extbyte *buffer, | 562 static int xpm_to_eimage (Lisp_Object image, CONST Extbyte *buffer, |
508 unsigned char** data, | 563 unsigned char** data, |
509 int* width, int* height, | 564 int* width, int* height, |
510 int* x_hot, int* y_hot, | 565 int* x_hot, int* y_hot, |
511 COLORREF bg, struct color_symbol* color_symbols, | 566 int* transp, |
567 struct color_symbol* color_symbols, | |
512 int nsymbols) | 568 int nsymbols) |
513 { | 569 { |
514 XpmImage xpmimage; | 570 XpmImage xpmimage; |
515 XpmInfo xpminfo; | 571 XpmInfo xpminfo; |
516 int result, i, j, transp_idx, maskbpline; | 572 int result, i, j, transp_idx, maskbpline; |
520 COLORREF* colortbl; | 576 COLORREF* colortbl; |
521 | 577 |
522 xzero (xpmimage); | 578 xzero (xpmimage); |
523 xzero (xpminfo); | 579 xzero (xpminfo); |
524 xpminfo.valuemask=XpmHotspot; | 580 xpminfo.valuemask=XpmHotspot; |
581 *transp=FALSE; | |
525 | 582 |
526 result = XpmCreateXpmImageFromBuffer ((char*)buffer, | 583 result = XpmCreateXpmImageFromBuffer ((char*)buffer, |
527 &xpmimage, | 584 &xpmimage, |
528 &xpminfo); | 585 &xpminfo); |
529 switch (result) | 586 switch (result) |
594 colortbl[i]=color_symbols[j].color; | 651 colortbl[i]=color_symbols[j].color; |
595 } | 652 } |
596 } | 653 } |
597 } | 654 } |
598 /* pick up transparencies */ | 655 /* pick up transparencies */ |
599 else if (!strcmp (xpmimage.colorTable[i].c_color,"None")) | 656 else if (!strcasecmp (xpmimage.colorTable[i].c_color,"None") |
657 || | |
658 xpmimage.colorTable[i].symbolic | |
659 && | |
660 (!strcasecmp (xpmimage.colorTable[i].symbolic,"BgColor") | |
661 || | |
662 !strcasecmp (xpmimage.colorTable[i].symbolic,"None"))) | |
600 { | 663 { |
601 colortbl[i]=bg; /* PALETTERGB(0,0,0); */ | 664 *transp=TRUE; |
665 colortbl[i]=transparent_color; | |
602 transp_idx=i; | 666 transp_idx=i; |
603 } | 667 } |
604 else | 668 else |
605 { | 669 { |
606 colortbl[i]= | 670 colortbl[i]= |
644 int width, height, x_hot, y_hot; | 708 int width, height, x_hot, y_hot; |
645 BITMAPINFO* bmp_info; | 709 BITMAPINFO* bmp_info; |
646 unsigned char* bmp_data; | 710 unsigned char* bmp_data; |
647 int bmp_bits; | 711 int bmp_bits; |
648 COLORREF bkcolor; | 712 COLORREF bkcolor; |
649 int nsymbols=0; | 713 int nsymbols=0, transp; |
650 struct color_symbol* color_symbols=NULL; | 714 struct color_symbol* color_symbols=NULL; |
651 | 715 |
652 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data); | 716 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data); |
653 Lisp_Object color_symbol_alist = find_keyword_in_vector (instantiator, | 717 Lisp_Object color_symbol_alist = find_keyword_in_vector (instantiator, |
654 Q_color_symbols); | 718 Q_color_symbols); |
658 | 722 |
659 assert (!NILP (data)); | 723 assert (!NILP (data)); |
660 | 724 |
661 GET_STRING_BINARY_DATA_ALLOCA (data, bytes, len); | 725 GET_STRING_BINARY_DATA_ALLOCA (data, bytes, len); |
662 | 726 |
663 /* this is a hack but MaskBlt and TransparentBlt are not supported | |
664 on most windows variants */ | |
665 bkcolor = COLOR_INSTANCE_MSWINDOWS_COLOR | |
666 (XCOLOR_INSTANCE (FACE_BACKGROUND (Vdefault_face, domain))); | |
667 | |
668 /* in case we have color symbols */ | 727 /* in case we have color symbols */ |
669 color_symbols = extract_xpm_color_names (device, domain, | 728 color_symbols = extract_xpm_color_names (device, domain, |
670 color_symbol_alist, &nsymbols); | 729 color_symbol_alist, &nsymbols); |
671 | 730 |
672 /* convert to an eimage to make processing easier */ | 731 /* convert to an eimage to make processing easier */ |
673 if (!xpm_to_eimage (image_instance, bytes, &eimage, &width, &height, | 732 if (!xpm_to_eimage (image_instance, bytes, &eimage, &width, &height, |
674 &x_hot, &y_hot, bkcolor, color_symbols, nsymbols)) | 733 &x_hot, &y_hot, &transp, color_symbols, nsymbols)) |
675 { | 734 { |
676 signal_simple_error ("XPM to EImage conversion failed", | 735 signal_simple_error ("XPM to EImage conversion failed", |
677 image_instance); | 736 image_instance); |
678 } | 737 } |
679 | 738 |
689 } | 748 } |
690 xfree (eimage); | 749 xfree (eimage); |
691 | 750 |
692 /* Now create the pixmap and set up the image instance */ | 751 /* Now create the pixmap and set up the image instance */ |
693 init_image_instance_from_dibitmap (ii, bmp_info, dest_mask, | 752 init_image_instance_from_dibitmap (ii, bmp_info, dest_mask, |
694 bmp_data, bmp_bits, instantiator); | 753 bmp_data, bmp_bits, instantiator, |
695 | 754 x_hot, y_hot, transp); |
696 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii), x_hot); | 755 |
697 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii), y_hot); | |
698 | |
699 xfree (bmp_info); | 756 xfree (bmp_info); |
700 xfree (bmp_data); | 757 xfree (bmp_data); |
701 } | 758 } |
702 #endif /* HAVE_XPM */ | 759 #endif /* HAVE_XPM */ |
703 | 760 |
754 bmp_data = (Extbyte*)bytes + bmp_file_header->bfOffBits; | 811 bmp_data = (Extbyte*)bytes + bmp_file_header->bfOffBits; |
755 bmp_bits = bmp_file_header->bfSize - bmp_file_header->bfOffBits; | 812 bmp_bits = bmp_file_header->bfSize - bmp_file_header->bfOffBits; |
756 | 813 |
757 /* Now create the pixmap and set up the image instance */ | 814 /* Now create the pixmap and set up the image instance */ |
758 init_image_instance_from_dibitmap (ii, bmp_info, dest_mask, | 815 init_image_instance_from_dibitmap (ii, bmp_info, dest_mask, |
759 bmp_data, bmp_bits, instantiator); | 816 bmp_data, bmp_bits, instantiator, |
817 0, 0, 0); | |
760 } | 818 } |
761 | 819 |
762 | 820 |
763 /************************************************************************/ | 821 /************************************************************************/ |
764 /* image instance methods */ | 822 /* image instance methods */ |