comparison win/dw.c @ 1250:ed2119fc210d

Initial commit of GDI+ image loader for Windows to allow use of other image formats... not finished nor enabled by default currently but hopefully soon.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Sun, 23 Oct 2011 19:54:09 +0000
parents c191a562c14a
children 7809be48de7d
comparison
equal deleted inserted replaced
1249:b31056c321a2 1250:ed2119fc210d
17 #include <stdlib.h> 17 #include <stdlib.h>
18 #include <string.h> 18 #include <string.h>
19 #include <stdio.h> 19 #include <stdio.h>
20 #include <process.h> 20 #include <process.h>
21 #include <time.h> 21 #include <time.h>
22 #ifdef GDIPLUS
23 #include <gdiplustypes.h>
24 #include <gdiplusflat.h>
25 #endif
22 #include "dw.h" 26 #include "dw.h"
23 #include "XBrowseForFolder.h" 27 #include "XBrowseForFolder.h"
24 28
25 /* 29 /*
26 * MinGW (as at 3.2.3) doesn't have MIM_MENUDATA 30 * MinGW (as at 3.2.3) doesn't have MIM_MENUDATA
291 295
292 FreeLibrary(hinstDll); 296 FreeLibrary(hinstDll);
293 } 297 }
294 return dwVersion; 298 return dwVersion;
295 } 299 }
300
301 #ifdef GDIPLUS
302 /*
303 * List those icons that have transparency first
304 * GDI+ List of supported formats: BMP, ICON, GIF, JPEG, Exif, PNG, TIFF, WMF, and EMF.
305 * Not sure if we should include all these or not... maybe we should add TIFF and GIF?
306 */
307 #define NUM_EXTS 7
308 char *image_exts[NUM_EXTS] =
309 {
310 ".png",
311 ".ico",
312 ".gif",
313 ".jpg",
314 ".jpeg",
315 ".tiff",
316 ".bmp"
317 };
318
319 /* Section for loading files of types besides BMP and ICO and return HBITMAP or HICON */
320 GpBitmap *_dw_load_gpbitmap( char *filename )
321 {
322 int found_ext = 0,i, wclen = (strlen(filename) + 6) * sizeof(wchar_t);
323 char *file = _alloca(strlen(filename) + 6);
324 wchar_t *wfile = _alloca(wclen);
325 GpBitmap *image;
326
327 /* Try various extentions */
328 for ( i = 0; i < NUM_EXTS; i++ )
329 {
330 strcpy( file, filename );
331 strcat( file, image_exts[i] );
332 if ( access( file, 04 ) == 0 )
333 {
334 /* Convert to wide format */
335 MultiByteToWideChar(CP_ACP, 0, file, strlen(file), wfile, wclen);
336 if(GdipCreateBitmapFromFile(wfile, &image))
337 return image;
338 }
339 }
340 return NULL;
341 }
342
343 /* Try to load the appropriate image and return the HBITMAP handle */
344 HBITMAP _dw_load_bitmap(char *filename, unsigned long *depth)
345 {
346 GpBitmap *bitmap = _dw_load_gpbitmap(filename);
347 if(bitmap)
348 {
349 HBITMAP hbm;
350
351 if(GdipCreateHBITMAPFromBitmap(bitmap, &hbm, 0))
352 {
353 if(depth)
354 {
355 /* TODO: Actually query the color depth here */
356 *depth = 32;
357 }
358 return hbm;
359 }
360 }
361 return NULL;
362 }
363
364 /* Try to load the appropriate image and return the HICON handle */
365 HICON _dw_load_icon(char *filename)
366 {
367 GpBitmap *bitmap = _dw_load_gpbitmap(filename);
368 if(bitmap)
369 {
370 HICON hicon;
371
372 if(GdipCreateHICONFromBitmap(bitmap, &hicon))
373 return hicon;
374 }
375 return NULL;
376 }
377 #endif
296 378
297 /* This function adds a signal handler callback into the linked list. 379 /* This function adds a signal handler callback into the linked list.
298 */ 380 */
299 void _new_signal(ULONG message, HWND window, int id, void *signalfunction, void *data) 381 void _new_signal(ULONG message, HWND window, int id, void *signalfunction, void *data)
300 { 382 {
3330 3412
3331 /* Associate the tooltip with the "tool" window. */ 3413 /* Associate the tooltip with the "tool" window. */
3332 SendMessage(hwndTT, TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO) &ti); 3414 SendMessage(hwndTT, TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO) &ti);
3333 } 3415 }
3334 3416
3335 3417 #ifndef GDIPLUS
3336 /* This function determines the handle for a supplied image filename 3418 /* This function determines the handle for a supplied image filename
3337 */ 3419 */
3338 int _dw_get_image_handle(char *filename, HANDLE *icon, HBITMAP *hbitmap) 3420 int _dw_get_image_handle(char *filename, HANDLE *icon, HBITMAP *hbitmap)
3339 { 3421 {
3340 int len, windowtype = 0; 3422 int len, windowtype = 0;
3397 } 3479 }
3398 free(file); 3480 free(file);
3399 } 3481 }
3400 return windowtype; 3482 return windowtype;
3401 } 3483 }
3484 #endif
3402 3485
3403 /* Initialize thread local values to the defaults */ 3486 /* Initialize thread local values to the defaults */
3404 void _init_thread(void) 3487 void _init_thread(void)
3405 { 3488 {
3406 COLORREF foreground = RGB(128,128,128); 3489 COLORREF foreground = RGB(128,128,128);
5259 int windowtype = 0, len; 5342 int windowtype = 0, len;
5260 5343
5261 if (!(bubble = calloc(1, sizeof(BubbleButton)))) 5344 if (!(bubble = calloc(1, sizeof(BubbleButton))))
5262 return 0; 5345 return 0;
5263 5346
5347 #ifdef GDIPLUS
5348 windowtype = BS_BITMAP;
5349 hbitmap = _dw_load_bitmap(filename, NULL);
5350 #else
5264 windowtype = _dw_get_image_handle(filename, &icon, &hbitmap); 5351 windowtype = _dw_get_image_handle(filename, &icon, &hbitmap);
5352 #endif
5265 5353
5266 tmp = CreateWindow( BUTTONCLASSNAME, 5354 tmp = CreateWindow( BUTTONCLASSNAME,
5267 "", 5355 "",
5268 windowtype | WS_CHILD | BS_PUSHBUTTON | WS_CLIPCHILDREN | WS_VISIBLE, 5356 windowtype | WS_CHILD | BS_PUSHBUTTON | WS_CLIPCHILDREN | WS_VISIBLE,
5269 0,0,2000,1000, 5357 0,0,2000,1000,
5277 5365
5278 SetWindowLongPtr(tmp, GWLP_USERDATA, (LONG_PTR)bubble); 5366 SetWindowLongPtr(tmp, GWLP_USERDATA, (LONG_PTR)bubble);
5279 5367
5280 _create_tooltip(tmp, text); 5368 _create_tooltip(tmp, text);
5281 5369
5370 #ifndef GDIPLUS
5282 if (icon) 5371 if (icon)
5283 { 5372 {
5284 SendMessage(tmp, BM_SETIMAGE,(WPARAM) IMAGE_ICON,(LPARAM) icon); 5373 SendMessage(tmp, BM_SETIMAGE,(WPARAM) IMAGE_ICON,(LPARAM) icon);
5285 } 5374 }
5286 else if (hbitmap) 5375 else
5376 #endif
5377 if (hbitmap)
5287 { 5378 {
5288 SendMessage(tmp, BM_SETIMAGE,(WPARAM) IMAGE_BITMAP, (LPARAM) hbitmap); 5379 SendMessage(tmp, BM_SETIMAGE,(WPARAM) IMAGE_BITMAP, (LPARAM) hbitmap);
5289 } 5380 }
5290 return tmp; 5381 return tmp;
5291 } 5382 }
5317 fp = fopen( file, "wb" ); 5408 fp = fopen( file, "wb" );
5318 if ( fp != NULL ) 5409 if ( fp != NULL )
5319 { 5410 {
5320 fwrite( data, 1, len, fp ); 5411 fwrite( data, 1, len, fp );
5321 fclose( fp ); 5412 fclose( fp );
5413 #ifdef GDIPLUS
5414 windowtype = BS_BITMAP;
5415 hbitmap = _dw_load_bitmap(file, NULL);
5416 #else
5322 if ( len > 1 && data[0] == 'B' && data[1] == 'M' ) /* first 2 chars of data is BM, then its a BMP */ 5417 if ( len > 1 && data[0] == 'B' && data[1] == 'M' ) /* first 2 chars of data is BM, then its a BMP */
5323 { 5418 {
5324 hbitmap = (HBITMAP)LoadImage( NULL, file, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ); 5419 hbitmap = (HBITMAP)LoadImage( NULL, file, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );
5325 windowtype = BS_BITMAP; 5420 windowtype = BS_BITMAP;
5326 } 5421 }
5327 else /* otherwise its assumed to be an ico */ 5422 else /* otherwise its assumed to be an ico */
5328 { 5423 {
5329 icon = LoadImage( NULL, file, IMAGE_ICON, 0, 0, LR_LOADFROMFILE ); 5424 icon = LoadImage( NULL, file, IMAGE_ICON, 0, 0, LR_LOADFROMFILE );
5330 windowtype = BS_ICON; 5425 windowtype = BS_ICON;
5331 } 5426 }
5427 #endif
5332 } 5428 }
5333 else 5429 else
5334 { 5430 {
5335 unlink( file ); 5431 unlink( file );
5336 free( file ); 5432 free( file );
5624 hbitmap = LoadImage(DWInstance, MAKEINTRESOURCE(id), IMAGE_BITMAP, 0, 0, LR_LOADMAP3DCOLORS | LR_SHARED); 5720 hbitmap = LoadImage(DWInstance, MAKEINTRESOURCE(id), IMAGE_BITMAP, 0, 0, LR_LOADMAP3DCOLORS | LR_SHARED);
5625 icon = LoadImage(DWInstance, MAKEINTRESOURCE(id), IMAGE_ICON, 0, 0, LR_SHARED); 5721 icon = LoadImage(DWInstance, MAKEINTRESOURCE(id), IMAGE_ICON, 0, 0, LR_SHARED);
5626 } 5722 }
5627 else if(filename) 5723 else if(filename)
5628 { 5724 {
5725 #ifdef GDIPLUS
5726 hbitmap = _dw_load_bitmap(filename, NULL);
5727 #else
5629 _dw_get_image_handle(filename, &icon, &hbitmap); 5728 _dw_get_image_handle(filename, &icon, &hbitmap);
5729 #endif
5630 if (icon == 0 && hbitmap == 0) 5730 if (icon == 0 && hbitmap == 0)
5631 return; 5731 return;
5632 } 5732 }
5633 5733
5634 if(icon) 5734 if(icon)
5689 fp = fopen( file, "wb" ); 5789 fp = fopen( file, "wb" );
5690 if ( fp != NULL ) 5790 if ( fp != NULL )
5691 { 5791 {
5692 fwrite( data, 1, len, fp ); 5792 fwrite( data, 1, len, fp );
5693 fclose( fp ); 5793 fclose( fp );
5794 #ifdef GDIPLUS
5795 hbitmap = _dw_load_bitmap(file, NULL);
5796 #else
5694 if ( len > 1 && data[0] == 'B' && data[1] == 'M' ) /* first 2 chars of data is BM, then its a BMP */ 5797 if ( len > 1 && data[0] == 'B' && data[1] == 'M' ) /* first 2 chars of data is BM, then its a BMP */
5695 hbitmap = (HBITMAP)LoadImage( NULL, file, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ); 5798 hbitmap = (HBITMAP)LoadImage( NULL, file, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );
5696 else /* otherwise its assumed to be an ico */ 5799 else /* otherwise its assumed to be an ico */
5697 icon = LoadImage( NULL, file, IMAGE_ICON, 0, 0, LR_LOADFROMFILE ); 5800 icon = LoadImage( NULL, file, IMAGE_ICON, 0, 0, LR_LOADFROMFILE );
5801 #endif
5698 } 5802 }
5699 else 5803 else
5700 { 5804 {
5701 unlink( file ); 5805 unlink( file );
5702 free( file ); 5806 free( file );
7542 * DW pick the appropriate file extension. 7646 * DW pick the appropriate file extension.
7543 * (ICO on OS/2 or Windows, XPM on Unix) 7647 * (ICO on OS/2 or Windows, XPM on Unix)
7544 */ 7648 */
7545 HICN API dw_icon_load_from_file(char *filename) 7649 HICN API dw_icon_load_from_file(char *filename)
7546 { 7650 {
7651 #ifdef GDIPLUS
7652 return _dw_load_icon(filename);
7653 #else
7547 char *file = malloc(strlen(filename) + 5); 7654 char *file = malloc(strlen(filename) + 5);
7548 HANDLE icon; 7655 HANDLE icon;
7549 7656
7550 if(!file) 7657 if(!file)
7551 return 0; 7658 return 0;
7564 } 7671 }
7565 } 7672 }
7566 icon = LoadImage(NULL, file, IMAGE_ICON, 0, 0, LR_LOADFROMFILE); 7673 icon = LoadImage(NULL, file, IMAGE_ICON, 0, 0, LR_LOADFROMFILE);
7567 free(file); 7674 free(file);
7568 return (HICN)icon; 7675 return (HICN)icon;
7676 #endif
7569 } 7677 }
7570 7678
7571 /* 7679 /*
7572 * Obtains an icon from data 7680 * Obtains an icon from data
7573 * Parameters: 7681 * Parameters:
7589 fp = fopen( file, "wb" ); 7697 fp = fopen( file, "wb" );
7590 if ( fp != NULL ) 7698 if ( fp != NULL )
7591 { 7699 {
7592 fwrite( data, 1, len, fp ); 7700 fwrite( data, 1, len, fp );
7593 fclose( fp ); 7701 fclose( fp );
7702 #ifdef GDIPLUS
7703 icon = _dw_load_icon(file);
7704 #else
7594 icon = LoadImage( NULL, file, IMAGE_ICON, 0, 0, LR_LOADFROMFILE ); 7705 icon = LoadImage( NULL, file, IMAGE_ICON, 0, 0, LR_LOADFROMFILE );
7706 #endif
7595 } 7707 }
7596 else 7708 else
7597 { 7709 {
7598 unlink( file ); 7710 unlink( file );
7599 free( file ); 7711 free( file );
8727 ReleaseDC(handle, hdc); 8839 ReleaseDC(handle, hdc);
8728 8840
8729 return pixmap; 8841 return pixmap;
8730 } 8842 }
8731 8843
8844 #ifndef GDIPLUS
8732 /* Read the file bitmap header ourselves... 8845 /* Read the file bitmap header ourselves...
8733 * apparently we can't check the depth once loaded... 8846 * apparently we can't check the depth once loaded...
8734 * since it seems to normalize it to our screen depth. 8847 * since it seems to normalize it to our screen depth.
8735 */ 8848 */
8736 unsigned long _read_bitmap_header(char *file) 8849 unsigned long _read_bitmap_header(char *file)
8775 } 8888 }
8776 free(info); 8889 free(info);
8777 fclose(fp); 8890 fclose(fp);
8778 return depth; 8891 return depth;
8779 } 8892 }
8893 #endif
8780 8894
8781 /* 8895 /*
8782 * Creates a pixmap from a file. 8896 * Creates a pixmap from a file.
8783 * Parameters: 8897 * Parameters:
8784 * handle: Window handle the pixmap is associated with. 8898 * handle: Window handle the pixmap is associated with.
8792 { 8906 {
8793 HPIXMAP pixmap; 8907 HPIXMAP pixmap;
8794 BITMAP bm; 8908 BITMAP bm;
8795 HDC hdc; 8909 HDC hdc;
8796 ULONG cx, cy; 8910 ULONG cx, cy;
8797 char *file = malloc(strlen(filename) + 5);
8798 BITMAPINFO *info; 8911 BITMAPINFO *info;
8799 8912 #ifndef GDIPLUS
8800 if (!file || !(pixmap = calloc(1,sizeof(struct _hpixmap)))) 8913 char *file;
8801 { 8914 #endif
8802 if(file) 8915
8803 free(file); 8916 if (!filename || !(pixmap = calloc(1,sizeof(struct _hpixmap))))
8804 return NULL; 8917 return NULL;
8805 } 8918
8806 8919 #ifdef GDIPLUS
8920 pixmap->hbm = _dw_load_bitmap(filename, &pixmap->depth);
8921 #else
8922 file = _alloca(strlen(filename) + 5);
8807 strcpy(file, filename); 8923 strcpy(file, filename);
8808 8924
8809 /* check if we can read from this file (it exists and read permission) */ 8925 /* check if we can read from this file (it exists and read permission) */
8810 if(access(file, 04) != 0) 8926 if(access(file, 04) != 0)
8811 { 8927 {
8817 free(file); 8933 free(file);
8818 return NULL; 8934 return NULL;
8819 } 8935 }
8820 } 8936 }
8821 8937
8822 hdc = GetDC(handle);
8823
8824 pixmap->handle = handle;
8825 pixmap->hbm = (HBITMAP)LoadImage(NULL, file, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); 8938 pixmap->hbm = (HBITMAP)LoadImage(NULL, file, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
8826 pixmap->depth = _read_bitmap_header(file); 8939 pixmap->depth = _read_bitmap_header(file);
8940 #endif
8941
8942 pixmap->handle = handle;
8827 8943
8828 if ( !pixmap->hbm ) 8944 if ( !pixmap->hbm )
8829 { 8945 {
8830 free(file);
8831 free(pixmap); 8946 free(pixmap);
8832 ReleaseDC(handle, hdc);
8833 return NULL; 8947 return NULL;
8834 } 8948 }
8949
8950 hdc = GetDC(handle);
8835 8951
8836 pixmap->hdc = CreateCompatibleDC( hdc ); 8952 pixmap->hdc = CreateCompatibleDC( hdc );
8837 GetObject( pixmap->hbm, sizeof(bm), &bm ); 8953 GetObject( pixmap->hbm, sizeof(bm), &bm );
8838 pixmap->width = bm.bmWidth; pixmap->height = bm.bmHeight; 8954 pixmap->width = bm.bmWidth; pixmap->height = bm.bmHeight;
8839 SelectObject( pixmap->hdc, pixmap->hbm ); 8955 SelectObject( pixmap->hdc, pixmap->hbm );
8840 ReleaseDC( handle, hdc ); 8956 ReleaseDC( handle, hdc );
8841 free( file );
8842 pixmap->transcolor = DW_RGB_TRANSPARENT; 8957 pixmap->transcolor = DW_RGB_TRANSPARENT;
8843 8958
8844 return pixmap; 8959 return pixmap;
8845 } 8960 }
8846 8961
8878 fp = fopen( file, "wb" ); 8993 fp = fopen( file, "wb" );
8879 if ( fp != NULL ) 8994 if ( fp != NULL )
8880 { 8995 {
8881 fwrite( data, 1, len, fp ); 8996 fwrite( data, 1, len, fp );
8882 fclose( fp ); 8997 fclose( fp );
8998 #ifdef GDIPLUS
8999 pixmap->hbm = _dw_load_bitmap(file);
9000 #else
8883 pixmap->hbm = (HBITMAP)LoadImage( NULL, file, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ); 9001 pixmap->hbm = (HBITMAP)LoadImage( NULL, file, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );
8884 pixmap->depth = _read_bitmap_header(file); 9002 pixmap->depth = _read_bitmap_header(file);
9003 #endif
8885 } 9004 }
8886 else 9005 else
8887 { 9006 {
8888 unlink( file ); 9007 unlink( file );
8889 free( file ); 9008 free( file );