comparison src/glyphs-msw.c @ 269:b2472a1930f2 r20-5b33

Import from CVS: tag r20-5b33
author cvs
date Mon, 13 Aug 2007 10:27:19 +0200
parents 966663fcf606
children c5d627a313b1
comparison
equal deleted inserted replaced
268:6ced69ccd85f 269:b2472a1930f2
52 52
53 static void 53 static void
54 mswindows_initialize_dibitmap_image_instance (struct Lisp_Image_Instance *ii, 54 mswindows_initialize_dibitmap_image_instance (struct Lisp_Image_Instance *ii,
55 enum image_instance_type type); 55 enum image_instance_type type);
56 56
57 COLORREF mswindows_string_to_color(CONST char *name); 57 COLORREF mswindows_string_to_color (CONST char *name);
58 58
59 /************************************************************************/ 59 /************************************************************************/
60 /* 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*/
61 /* proper display */ 61 /* proper display */
62 /************************************************************************/ 62 /************************************************************************/
63 BITMAPINFO* EImage2DIBitmap(Lisp_Object device, int width, int height, 63 BITMAPINFO* EImage2DIBitmap (Lisp_Object device, int width, int height,
64 unsigned char *pic, 64 unsigned char *pic,
65 int *bit_count, 65 int *bit_count,
66 unsigned char** bmp_data) 66 unsigned char** bmp_data)
67 { 67 {
68 struct device *d = XDEVICE (device); 68 struct device *d = XDEVICE (device);
69 int i; 69 int i,j;
70 RGBQUAD* colortbl; 70 RGBQUAD* colortbl;
71 int ncolors; 71 int ncolors;
72 BITMAPINFO* bmp_info; 72 BITMAPINFO* bmp_info;
73 73 unsigned char *ip, *dp;
74 if (DEVICE_MSWINDOWS_BITSPIXEL(d) > 16) 74
75 { 75 if (DEVICE_MSWINDOWS_BITSPIXEL (d) > 0)
76 {
77 int bpline=(int)(~3UL & (unsigned long)((width*3) +3));
76 /* FIXME: we can do this because 24bpp implies no colour table, once 78 /* FIXME: we can do this because 24bpp implies no colour table, once
77 * we start paletizing this is no longer true. The X versions of 79 * we start paletizing this is no longer true. The X versions of
78 * this function quantises to 256 colours or bit masks down to a 80 * this function quantises to 256 colours or bit masks down to a
79 * long. Windows can actually handle rgb triples in the raw so I 81 * long. Windows can actually handle rgb triples in the raw so I
80 * don't see much point trying to optimise down to the best 82 * don't see much point trying to optimise down to the best
81 * structure - unless it has memory / color allocation implications 83 * structure - unless it has memory / color allocation implications
82 * .... */ 84 * .... */
83 bmp_info=xnew_and_zero(BITMAPINFO); 85 bmp_info=xnew_and_zero (BITMAPINFO);
84 86
85 if (!bmp_info) 87 if (!bmp_info)
86 { 88 {
87 return NULL; 89 return NULL;
88 } 90 }
115 unsigned char *ip, *dp; 117 unsigned char *ip, *dp;
116 quant_table *qtable; 118 quant_table *qtable;
117 int bpline= (int)(~3UL & (unsigned long)(width +3)); 119 int bpline= (int)(~3UL & (unsigned long)(width +3));
118 /* Quantize the image and get a histogram while we're at it. 120 /* Quantize the image and get a histogram while we're at it.
119 Do this first to save memory */ 121 Do this first to save memory */
120 qtable = EImage_build_quantable(pic, width, height, 256); 122 qtable = build_EImage_quantable(pic, width, height, 256);
121 if (qtable == NULL) return NULL; 123 if (qtable == NULL) return NULL;
122 124
123 /* use our quantize table to allocate the colors */ 125 /* use our quantize table to allocate the colors */
124 ncolors = qtable->num_active_colors; 126 ncolors = qtable->num_active_colors;
125 bmp_info=(BITMAPINFO*)xmalloc_and_zero(sizeof(BITMAPINFOHEADER) + 127 bmp_info=(BITMAPINFO*)xmalloc_and_zero(sizeof(BITMAPINFOHEADER) +
141 *bmp_data = (unsigned char *) xmalloc_and_zero (bpline * height); 143 *bmp_data = (unsigned char *) xmalloc_and_zero (bpline * height);
142 *bit_count = bpline * height; 144 *bit_count = bpline * height;
143 145
144 if (!*bmp_data) 146 if (!*bmp_data)
145 { 147 {
146 xfree(qtable); 148 xfree (qtable);
147 xfree(bmp_info); 149 xfree (bmp_info);
148 return NULL; 150 return NULL;
149 } 151 }
150 152
151 /* build up an RGBQUAD colortable */ 153 /* build up an RGBQUAD colortable */
152 for (i = 0; i < qtable->num_active_colors; i++) { 154 for (i = 0; i < qtable->num_active_colors; i++) {
163 dp = (*bmp_data) + (i * bpline); 165 dp = (*bmp_data) + (i * bpline);
164 for (j = 0; j < width; j++) { 166 for (j = 0; j < width; j++) {
165 rd = *ip++; 167 rd = *ip++;
166 gr = *ip++; 168 gr = *ip++;
167 bl = *ip++; 169 bl = *ip++;
168 *dp++ = QUANT_GET_COLOR(qtable,rd,gr,bl); 170 *dp++ = QUANT_GET_COLOR (qtable,rd,gr,bl);
169 } 171 }
170 } 172 }
171 xfree(qtable); 173 xfree (qtable);
172 } 174 }
173 /* fix up the standard stuff */ 175 /* fix up the standard stuff */
174 bmp_info->bmiHeader.biWidth=width; 176 bmp_info->bmiHeader.biWidth=width;
175 bmp_info->bmiHeader.biHeight=height; 177 bmp_info->bmiHeader.biHeight=height;
176 bmp_info->bmiHeader.biPlanes=1; 178 bmp_info->bmiHeader.biPlanes=1;
177 bmp_info->bmiHeader.biSize=sizeof(BITMAPINFOHEADER); 179 bmp_info->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
178 bmp_info->bmiHeader.biXPelsPerMeter=3779; /* unless you know better */ 180 bmp_info->bmiHeader.biXPelsPerMeter=0; /* unless you know better */
179 bmp_info->bmiHeader.biYPelsPerMeter=3779; 181 bmp_info->bmiHeader.biYPelsPerMeter=0;
180 182
181 return bmp_info; 183 return bmp_info;
182 } 184 }
183 185
184 /* Given a pixmap filename, look through all of the "standard" places 186 /* Given a pixmap filename, look through all of the "standard" places
190 { 192 {
191 /* This function can GC if IN_REDISPLAY is false */ 193 /* This function can GC if IN_REDISPLAY is false */
192 194
193 /* Check non-absolute pathnames with a directory component relative to 195 /* Check non-absolute pathnames with a directory component relative to
194 the search path; that's the way Xt does it. */ 196 the search path; that's the way Xt does it. */
195 /* #### Unix-specific */ 197 if (IS_DIRECTORY_SEP(XSTRING_BYTE (name, 0)) ||
196 if (XSTRING_BYTE (name, 0) == '/' ||
197 (XSTRING_BYTE (name, 0) == '.' && 198 (XSTRING_BYTE (name, 0) == '.' &&
198 (XSTRING_BYTE (name, 1) == '/' || 199 (IS_DIRECTORY_SEP(XSTRING_BYTE (name, 1)) ||
199 (XSTRING_BYTE (name, 1) == '.' && 200 (XSTRING_BYTE (name, 1) == '.' &&
200 (XSTRING_BYTE (name, 2) == '/'))))) 201 (IS_DIRECTORY_SEP(XSTRING_BYTE (name, 2)))))))
201 { 202 {
202 if (!NILP (Ffile_readable_p (name))) 203 if (!NILP (Ffile_readable_p (name)))
203 return name; 204 return name;
204 else 205 else
205 return Qnil; 206 return Qnil;
206 } 207 }
207 208
208 if (!NILP(Vmswindows_bitmap_file_path)) 209 if (!NILP (Vmswindows_bitmap_file_path))
209 { 210 {
210 Lisp_Object found; 211 Lisp_Object found;
211 if (locate_file (Vmswindows_bitmap_file_path, name, "", &found, R_OK) < 0) 212 if (locate_file (Vmswindows_bitmap_file_path, name, "", &found, R_OK) < 0)
212 { 213 {
213 Lisp_Object temp = list1 (Vdata_directory); 214 Lisp_Object temp = list1 (Vdata_directory);
246 data = find_keyword_in_vector (instantiator, data_keyword); 247 data = find_keyword_in_vector (instantiator, data_keyword);
247 file = find_keyword_in_vector (instantiator, file_keyword); 248 file = find_keyword_in_vector (instantiator, file_keyword);
248 249
249 if (!NILP (file) && NILP (data)) 250 if (!NILP (file) && NILP (data))
250 { 251 {
251 Lisp_Object retval = locate_pixmap_file (file); 252 Lisp_Object retval = locate_pixmap_file(file);
252 if (!NILP (retval)) 253 if (!NILP (retval))
253 return retval; 254 return retval;
254 else 255 else
255 return Fcons (file, Qnil); /* should have been file */ 256 return Fcons (file, Qnil); /* should have been file */
256 } 257 }
320 int bmp_bits, 321 int bmp_bits,
321 Lisp_Object instantiator) 322 Lisp_Object instantiator)
322 { 323 {
323 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii); 324 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
324 struct device *d = XDEVICE (device); 325 struct device *d = XDEVICE (device);
325 struct frame *f = XFRAME (DEVICE_SELECTED_FRAME(d)); 326 struct frame *f = XFRAME (DEVICE_SELECTED_FRAME (d));
326 void* bmp_buf=0; 327 void* bmp_buf=0;
327 HBITMAP bitmap; 328 HBITMAP bitmap;
328 HDC hdc, cdc; 329 HDC hdc;
329 330
330 if (!DEVICE_MSWINDOWS_P (d)) 331 if (!DEVICE_MSWINDOWS_P (d))
331 signal_simple_error ("Not an mswindows device", device); 332 signal_simple_error ("Not an mswindows device", device);
332 333
333 if (NILP (DEVICE_SELECTED_FRAME (d))) 334 if (NILP (DEVICE_SELECTED_FRAME (d)))
336 if (!(dest_mask & IMAGE_COLOR_PIXMAP_MASK)) 337 if (!(dest_mask & IMAGE_COLOR_PIXMAP_MASK))
337 incompatible_image_types (instantiator, dest_mask, 338 incompatible_image_types (instantiator, dest_mask,
338 IMAGE_COLOR_PIXMAP_MASK); 339 IMAGE_COLOR_PIXMAP_MASK);
339 hdc = FRAME_MSWINDOWS_DC (f); 340 hdc = FRAME_MSWINDOWS_DC (f);
340 341
341 bitmap=CreateDIBSection(hdc, 342 bitmap=CreateDIBSection (hdc,
342 bmp_info, 343 bmp_info,
343 DIB_RGB_COLORS, 344 DIB_RGB_COLORS,
344 &bmp_buf, 345 &bmp_buf,
345 0,0); 346 0,0);
346 347
347 if (!bitmap || !bmp_buf) 348 if (!bitmap || !bmp_buf)
348 signal_simple_error ("Unable to create bitmap", instantiator); 349 signal_simple_error ("Unable to create bitmap", instantiator);
349 350
350 /* copy in the actual bitmap */ 351 /* copy in the actual bitmap */
351 memcpy(bmp_buf, bmp_data, bmp_bits); 352 memcpy (bmp_buf, bmp_data, bmp_bits);
352
353 /* create a memory dc */
354 cdc = CreateCompatibleDC(hdc);
355 353
356 mswindows_initialize_dibitmap_image_instance (ii, IMAGE_COLOR_PIXMAP); 354 mswindows_initialize_dibitmap_image_instance (ii, IMAGE_COLOR_PIXMAP);
357 355
358 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) = 356 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) =
359 find_keyword_in_vector (instantiator, Q_file); 357 find_keyword_in_vector (instantiator, Q_file);
360 358
361 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = bitmap; 359 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = bitmap;
362 IMAGE_INSTANCE_MSWINDOWS_DC (ii) = cdc;
363 IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = bmp_info->bmiHeader.biWidth; 360 IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = bmp_info->bmiHeader.biWidth;
364 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) = bmp_info->bmiHeader.biHeight; 361 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) = bmp_info->bmiHeader.biHeight;
365 IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = bmp_info->bmiHeader.biBitCount; 362 IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = bmp_info->bmiHeader.biBitCount;
366 } 363 }
367 364
368 /********************************************************************** 365 /**********************************************************************
369 * XPM * 366 * XPM *
370 **********************************************************************/ 367 **********************************************************************/
371 368
372 #ifdef HAVE_XPM 369 #ifdef HAVE_XPM
373 static int xpm_to_eimage(Lisp_Object image, CONST Extbyte *buffer, 370 static int xpm_to_eimage (Lisp_Object image, CONST Extbyte *buffer,
374 unsigned char** data, 371 unsigned char** data,
375 int* width, int* height, 372 int* width, int* height,
376 COLORREF bg) 373 COLORREF bg)
377 { 374 {
378 XpmImage xpmimage; 375 XpmImage xpmimage;
384 COLORREF* colortbl; 381 COLORREF* colortbl;
385 382
386 memset (&xpmimage, 0, sizeof (xpmimage)); 383 memset (&xpmimage, 0, sizeof (xpmimage));
387 memset (&xpminfo, 0, sizeof (xpmimage)); 384 memset (&xpminfo, 0, sizeof (xpmimage));
388 385
389 result = XpmCreateXpmImageFromBuffer((char*)buffer, 386 result = XpmCreateXpmImageFromBuffer ((char*)buffer,
390 &xpmimage, 387 &xpmimage,
391 &xpminfo); 388 &xpminfo);
392 switch(result) 389 switch (result)
393 { 390 {
394 case XpmSuccess: 391 case XpmSuccess:
395 break; 392 break;
396 case XpmFileInvalid: 393 case XpmFileInvalid:
397 { 394 {
414 *height = xpmimage.height; 411 *height = xpmimage.height;
415 412
416 *data = xnew_array_and_zero (unsigned char, *width * *height * 3); 413 *data = xnew_array_and_zero (unsigned char, *width * *height * 3);
417 if (!*data) 414 if (!*data)
418 { 415 {
419 XpmFreeXpmImage(&xpmimage); 416 XpmFreeXpmImage (&xpmimage);
420 XpmFreeXpmInfo(&xpminfo); 417 XpmFreeXpmInfo (&xpminfo);
421 return 0; 418 return 0;
422 } 419 }
423 420
424 /* build a color table to speed things up */ 421 /* build a color table to speed things up */
425 colortbl = xnew_array_and_zero (COLORREF, xpmimage.ncolors); 422 colortbl = xnew_array_and_zero (COLORREF, xpmimage.ncolors);
426 if (!colortbl) 423 if (!colortbl)
427 { 424 {
428 xfree(*data); 425 xfree (*data);
429 XpmFreeXpmImage(&xpmimage); 426 XpmFreeXpmImage (&xpmimage);
430 XpmFreeXpmInfo(&xpminfo); 427 XpmFreeXpmInfo (&xpminfo);
431 return 0; 428 return 0;
432 } 429 }
433 430
434 for (i=0; i<xpmimage.ncolors; i++) 431 for (i=0; i<xpmimage.ncolors; i++)
435 { 432 {
436 /* pick up transparencies */ 433 /* pick up transparencies */
437 if (!strcmp(xpmimage.colorTable[i].c_color,"None")) 434 if (!strcmp (xpmimage.colorTable[i].c_color,"None"))
438 { 435 {
439 colortbl[i]=bg; 436 colortbl[i]=bg;
440 } 437 }
441 else 438 else
442 { 439 {
443 colortbl[i]= 440 colortbl[i]=
444 mswindows_string_to_color(xpmimage.colorTable[i].c_color); 441 mswindows_string_to_color (xpmimage.colorTable[i].c_color);
445 } 442 }
446 } 443 }
447 444
448 /* convert the image */ 445 /* convert the image */
449 sptr=xpmimage.data; 446 sptr=xpmimage.data;
451 for (i = 0; i< *width * *height; i++) 448 for (i = 0; i< *width * *height; i++)
452 { 449 {
453 color = colortbl[*sptr++]; 450 color = colortbl[*sptr++];
454 451
455 /* split out the 0x02bbggrr colorref into an rgb triple */ 452 /* split out the 0x02bbggrr colorref into an rgb triple */
456 *dptr++=GetRValue(color); /* red */ 453 *dptr++=GetRValue (color); /* red */
457 *dptr++=GetGValue(color); /* green */ 454 *dptr++=GetGValue (color); /* green */
458 *dptr++=GetBValue(color); /* blue */ 455 *dptr++=GetBValue (color); /* blue */
459 } 456 }
460 457
461 XpmFreeXpmImage(&xpmimage); 458 XpmFreeXpmImage (&xpmimage);
462 XpmFreeXpmInfo(&xpminfo); 459 XpmFreeXpmInfo (&xpminfo);
463 xfree(colortbl); 460 xfree (colortbl);
464 return TRUE; 461 return TRUE;
465 } 462 }
466 463
467 void 464 void
468 mswindows_xpm_instantiate (Lisp_Object image_instance, 465 mswindows_xpm_instantiate (Lisp_Object image_instance,
491 GET_STRING_BINARY_DATA_ALLOCA (data, bytes, len); 488 GET_STRING_BINARY_DATA_ALLOCA (data, bytes, len);
492 489
493 /* this is a hack but MaskBlt and TransparentBlt are not supported 490 /* this is a hack but MaskBlt and TransparentBlt are not supported
494 on most windows variants */ 491 on most windows variants */
495 bkcolor = COLOR_INSTANCE_MSWINDOWS_COLOR 492 bkcolor = COLOR_INSTANCE_MSWINDOWS_COLOR
496 (XCOLOR_INSTANCE (FACE_BACKGROUND(Vdefault_face, domain))); 493 (XCOLOR_INSTANCE (FACE_BACKGROUND (Vdefault_face, domain)));
497 494
498 /* convert to an eimage to make processing easier */ 495 /* convert to an eimage to make processing easier */
499 if (!xpm_to_eimage(image_instance, bytes, &eimage, &width, &height, 496 if (!xpm_to_eimage (image_instance, bytes, &eimage, &width, &height,
500 bkcolor)) 497 bkcolor))
501 { 498 {
502 signal_simple_error ("XPM to EImage conversion failed", 499 signal_simple_error ("XPM to EImage conversion failed",
503 image_instance); 500 image_instance);
504 } 501 }
505 502
506 /* build a bitmap from the eimage */ 503 /* build a bitmap from the eimage */
507 if (!(bmp_info=EImage2DIBitmap(device, width, height, eimage, 504 if (!(bmp_info=EImage2DIBitmap (device, width, height, eimage,
508 &bmp_bits, &bmp_data))) 505 &bmp_bits, &bmp_data)))
509 { 506 {
507 xfree (eimage);
510 signal_simple_error ("XPM to EImage conversion failed", 508 signal_simple_error ("XPM to EImage conversion failed",
511 image_instance); 509 image_instance);
512 } 510 }
513 xfree(eimage); 511 xfree (eimage);
514 512
515 /* Now create the pixmap and set up the image instance */ 513 /* Now create the pixmap and set up the image instance */
516 init_image_instance_from_dibitmap (ii, bmp_info, dest_mask, 514 init_image_instance_from_dibitmap (ii, bmp_info, dest_mask,
517 bmp_data, bmp_bits, instantiator); 515 bmp_data, bmp_bits, instantiator);
518 516
519 xfree(bmp_info); 517 xfree (bmp_info);
520 xfree(bmp_data); 518 xfree (bmp_data);
521 } 519 }
522 #endif /* HAVE_XPM */ 520 #endif /* HAVE_XPM */
523 521
524 /********************************************************************** 522 /**********************************************************************
525 * BMP * 523 * BMP *
618 if (!p->data) 616 if (!p->data)
619 return; 617 return;
620 618
621 if (DEVICE_LIVE_P (XDEVICE (p->device))) 619 if (DEVICE_LIVE_P (XDEVICE (p->device)))
622 { 620 {
623 if (IMAGE_INSTANCE_MSWINDOWS_DC (p))
624 DeleteDC(IMAGE_INSTANCE_MSWINDOWS_DC (p));
625 if (IMAGE_INSTANCE_MSWINDOWS_BITMAP (p)) 621 if (IMAGE_INSTANCE_MSWINDOWS_BITMAP (p))
626 DeleteObject(IMAGE_INSTANCE_MSWINDOWS_BITMAP (p)); 622 DeleteObject (IMAGE_INSTANCE_MSWINDOWS_BITMAP (p));
627 IMAGE_INSTANCE_MSWINDOWS_BITMAP (p) = 0; 623 IMAGE_INSTANCE_MSWINDOWS_BITMAP (p) = 0;
628 IMAGE_INSTANCE_MSWINDOWS_DC (p) = 0;
629 } 624 }
630 625
631 xfree (p->data); 626 xfree (p->data);
632 p->data = 0; 627 p->data = 0;
633 } 628 }