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 */