Mercurial > hg > xemacs-beta
diff 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 |
line wrap: on
line diff
--- a/src/glyphs-msw.c Mon Aug 13 10:32:23 2007 +0200 +++ b/src/glyphs-msw.c Mon Aug 13 10:33:18 2007 +0200 @@ -1,9 +1,4 @@ /* mswindows-specific Lisp objects. - Copyright (C) 1993, 1994 Free Software Foundation, Inc. - Copyright (C) 1995 Board of Trustees, University of Illinois. - Copyright (C) 1995 Tinker Systems - Copyright (C) 1995, 1996 Ben Wing - Copyright (C) 1995 Sun Microsystems Copyright (C) 1998 Andy Piper. This file is part of XEmacs. @@ -50,10 +45,14 @@ DEFINE_IMAGE_INSTANTIATOR_FORMAT (bmp); Lisp_Object Qbmp; Lisp_Object Vmswindows_bitmap_file_path; +static COLORREF transparent_color = RGB (1,1,1); static void mswindows_initialize_dibitmap_image_instance (struct Lisp_Image_Instance *ii, enum image_instance_type type); +static void +mswindows_initialize_image_instance_mask (struct Lisp_Image_Instance* image, + struct frame* f); COLORREF mswindows_string_to_color (CONST char *name); @@ -239,12 +238,15 @@ int dest_mask, void *bmp_data, int bmp_bits, - Lisp_Object instantiator) + Lisp_Object instantiator, + int x_hot, int y_hot, + int create_mask) { Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii); struct device *d = XDEVICE (device); struct frame *f = XFRAME (DEVICE_SELECTED_FRAME (d)); void* bmp_buf=0; + int type; HBITMAP bitmap; HDC hdc; @@ -254,9 +256,13 @@ if (NILP (DEVICE_SELECTED_FRAME (d))) signal_simple_error ("No selected frame on mswindows device", device); - if (!(dest_mask & IMAGE_COLOR_PIXMAP_MASK)) + if (dest_mask & IMAGE_COLOR_PIXMAP_MASK) + type = IMAGE_COLOR_PIXMAP; + else if (dest_mask & IMAGE_POINTER_MASK) + type = IMAGE_POINTER; + else incompatible_image_types (instantiator, dest_mask, - IMAGE_COLOR_PIXMAP_MASK); + IMAGE_COLOR_PIXMAP_MASK | IMAGE_POINTER_MASK); hdc = FRAME_MSWINDOWS_DC (f); bitmap=CreateDIBSection (hdc, @@ -271,16 +277,28 @@ /* copy in the actual bitmap */ memcpy (bmp_buf, bmp_data, bmp_bits); - mswindows_initialize_dibitmap_image_instance (ii, IMAGE_COLOR_PIXMAP); + mswindows_initialize_dibitmap_image_instance (ii, type); IMAGE_INSTANCE_PIXMAP_FILENAME (ii) = find_keyword_in_vector (instantiator, Q_file); IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = bitmap; - IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = bitmap; + IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = NULL; IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = bmp_info->bmiHeader.biWidth; IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) = bmp_info->bmiHeader.biHeight; IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = bmp_info->bmiHeader.biBitCount; + XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii), x_hot); + XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii), y_hot); + + if (create_mask) + { + mswindows_initialize_image_instance_mask (ii, f); + } + + if (type == IMAGE_POINTER) + { + mswindows_initialize_image_instance_icon(ii, TRUE); + } } static void @@ -315,77 +333,114 @@ /* Now create the pixmap and set up the image instance */ init_image_instance_from_dibitmap (ii, bmp_info, dest_mask, - bmp_data, bmp_bits, instantiator); + bmp_data, bmp_bits, instantiator, + 0, 0, 0); xfree (bmp_info); xfree (bmp_data); } -void -mswindows_create_icon_from_image(Lisp_Object image, struct frame* f, int size) +static void set_mono_pixel ( unsigned char* bits, + int bpline, int height, + int x, int y, int white ) +{ + int index; + unsigned char bitnum; + /* Find the byte on which this scanline begins */ + index = (height - y - 1) * bpline; + /* Find the byte containing this pixel */ + index += (x >> 3); + /* Which bit is it? */ + bitnum = (unsigned char)( 7 - (x % 8) ); + if( white ) /* Turn it on */ + bits[index] |= (1<<bitnum); + else /* Turn it off */ + bits[index] &= ~(1<<bitnum); +} + +static void +mswindows_initialize_image_instance_mask (struct Lisp_Image_Instance* image, + struct frame* f) { HBITMAP mask, bmp; HDC hcdc = FRAME_MSWINDOWS_CDC (f); - HDC hdcDst = CreateCompatibleDC (hcdc); - ICONINFO x_icon; + BITMAPINFO* bmp_info = + xmalloc_and_zero (sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)); + int i, j; + int height = IMAGE_INSTANCE_PIXMAP_HEIGHT (image); - if (size!=16 && size!=32) + void* and_bits; + int bpline= (int)(~3UL & (unsigned long) + (((IMAGE_INSTANCE_PIXMAP_WIDTH (image)+7)/8) +3)); + + bmp_info->bmiHeader.biWidth=IMAGE_INSTANCE_PIXMAP_WIDTH (image); + bmp_info->bmiHeader.biHeight = height; + bmp_info->bmiHeader.biPlanes=1; + bmp_info->bmiHeader.biSize=sizeof(BITMAPINFOHEADER); + bmp_info->bmiHeader.biBitCount=1; + bmp_info->bmiHeader.biCompression=BI_RGB; + bmp_info->bmiHeader.biClrUsed = 2; + bmp_info->bmiHeader.biClrImportant = 2; + bmp_info->bmiHeader.biSizeImage = height * bpline; + bmp_info->bmiColors[0].rgbRed = 0; + bmp_info->bmiColors[0].rgbGreen = 0; + bmp_info->bmiColors[0].rgbBlue = 0; + bmp_info->bmiColors[0].rgbReserved = 0; + bmp_info->bmiColors[1].rgbRed = 255; + bmp_info->bmiColors[1].rgbGreen = 255; + bmp_info->bmiColors[1].rgbBlue = 255; + bmp_info->bmiColors[0].rgbReserved = 0; + + if (!(mask = CreateDIBSection (hcdc, + bmp_info, + DIB_RGB_COLORS, + &and_bits, + 0,0))) { - signal_simple_error("Icons must be 16x16 or 32x32", image); + xfree (bmp_info); + return; } -#if 0 - iIconWidth = GetSystemMetrics(SM_CXICON); - iIconHeight = GetSystemMetrics(SM_CYICON); -#endif - - SelectObject(hcdc, XIMAGE_INSTANCE_MSWINDOWS_BITMAP (image)); - - bmp = CreateCompatibleBitmap(hcdc, size, size); - DeleteObject( SelectObject(hdcDst, bmp) ); + xfree (bmp_info); + SelectObject (hcdc, IMAGE_INSTANCE_MSWINDOWS_BITMAP (image)); - if (!StretchBlt(hdcDst, 0, 0, size, size, - hcdc, 0, 0, - XIMAGE_INSTANCE_PIXMAP_WIDTH (image), - XIMAGE_INSTANCE_PIXMAP_HEIGHT (image), - SRCCOPY)) - { - printf("StretchBlt failed\n"); - } - - if (!(mask = CreateBitmap(size, size, 1, 1, NULL))) - { - printf("CreateBitmap() failed\n"); - } - if (!SelectObject(hdcDst, mask) - || - !SelectObject(hcdc, bmp)) - { - printf("SelectObject() failed\n"); - } - - if (!BitBlt(hdcDst, 0, 0, size, size, - hcdc, 0, 0, - NOTSRCCOPY)) - { - printf("BitBlt failed\n"); + for(i=0; i<IMAGE_INSTANCE_PIXMAP_WIDTH (image); i++) + { + for(j=0; j<height; j++) + { + if( GetPixel( hcdc, i, j ) == transparent_color ) + { + SetPixel( hcdc, i, j, RGB (0,0,0)); + set_mono_pixel( and_bits, bpline, height, i, j, TRUE ); + } + else + { + set_mono_pixel( and_bits, bpline, height, i, j, FALSE ); + } + } } - SelectObject(hdcDst, 0); + GdiFlush(); SelectObject(hcdc, 0); - /* PatBlt(hdcDst, 0, 0, size, size, WHITENESS);*/ + + IMAGE_INSTANCE_MSWINDOWS_MASK (image) = mask; +} + +void +mswindows_initialize_image_instance_icon (struct Lisp_Image_Instance* image, + int cursor) +{ + ICONINFO x_icon; + + /* we rely on windows to do any resizing necessary */ + x_icon.fIcon=cursor ? FALSE : TRUE; + x_icon.xHotspot=XINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (image)); + x_icon.yHotspot=XINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (image)); + x_icon.hbmMask=IMAGE_INSTANCE_MSWINDOWS_MASK (image); + x_icon.hbmColor=IMAGE_INSTANCE_MSWINDOWS_BITMAP (image); - x_icon.fIcon=TRUE; - x_icon.xHotspot=XINT (XIMAGE_INSTANCE_PIXMAP_HOTSPOT_X (image)); - x_icon.yHotspot=XINT (XIMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (image)); - x_icon.hbmMask=mask; - x_icon.hbmColor=bmp; - - XIMAGE_INSTANCE_MSWINDOWS_ICON (image)= + IMAGE_INSTANCE_MSWINDOWS_ICON (image)= CreateIconIndirect (&x_icon); - XIMAGE_INSTANCE_MSWINDOWS_MASK (image)=mask; - - DeleteDC(hdcDst); } int @@ -508,7 +563,8 @@ unsigned char** data, int* width, int* height, int* x_hot, int* y_hot, - COLORREF bg, struct color_symbol* color_symbols, + int* transp, + struct color_symbol* color_symbols, int nsymbols) { XpmImage xpmimage; @@ -522,6 +578,7 @@ xzero (xpmimage); xzero (xpminfo); xpminfo.valuemask=XpmHotspot; + *transp=FALSE; result = XpmCreateXpmImageFromBuffer ((char*)buffer, &xpmimage, @@ -596,9 +653,16 @@ } } /* pick up transparencies */ - else if (!strcmp (xpmimage.colorTable[i].c_color,"None")) + else if (!strcasecmp (xpmimage.colorTable[i].c_color,"None") + || + xpmimage.colorTable[i].symbolic + && + (!strcasecmp (xpmimage.colorTable[i].symbolic,"BgColor") + || + !strcasecmp (xpmimage.colorTable[i].symbolic,"None"))) { - colortbl[i]=bg; /* PALETTERGB(0,0,0); */ + *transp=TRUE; + colortbl[i]=transparent_color; transp_idx=i; } else @@ -646,7 +710,7 @@ unsigned char* bmp_data; int bmp_bits; COLORREF bkcolor; - int nsymbols=0; + int nsymbols=0, transp; struct color_symbol* color_symbols=NULL; Lisp_Object data = find_keyword_in_vector (instantiator, Q_data); @@ -660,18 +724,13 @@ GET_STRING_BINARY_DATA_ALLOCA (data, bytes, len); - /* this is a hack but MaskBlt and TransparentBlt are not supported - on most windows variants */ - bkcolor = COLOR_INSTANCE_MSWINDOWS_COLOR - (XCOLOR_INSTANCE (FACE_BACKGROUND (Vdefault_face, domain))); - /* in case we have color symbols */ color_symbols = extract_xpm_color_names (device, domain, color_symbol_alist, &nsymbols); /* convert to an eimage to make processing easier */ if (!xpm_to_eimage (image_instance, bytes, &eimage, &width, &height, - &x_hot, &y_hot, bkcolor, color_symbols, nsymbols)) + &x_hot, &y_hot, &transp, color_symbols, nsymbols)) { signal_simple_error ("XPM to EImage conversion failed", image_instance); @@ -691,11 +750,9 @@ /* Now create the pixmap and set up the image instance */ init_image_instance_from_dibitmap (ii, bmp_info, dest_mask, - bmp_data, bmp_bits, instantiator); + bmp_data, bmp_bits, instantiator, + x_hot, y_hot, transp); - XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii), x_hot); - XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii), y_hot); - xfree (bmp_info); xfree (bmp_data); } @@ -756,7 +813,8 @@ /* Now create the pixmap and set up the image instance */ init_image_instance_from_dibitmap (ii, bmp_info, dest_mask, - bmp_data, bmp_bits, instantiator); + bmp_data, bmp_bits, instantiator, + 0, 0, 0); }