changeset 1251:7809be48de7d

Enable GDI Plus on Windows to see how well it works. Had to include a bunch of stuff in the source... since the shipped headers are not compatible with C (only C++).
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Mon, 24 Oct 2011 03:10:27 +0000
parents ed2119fc210d
children 575663435272
files makefile.vc win/dw.c
diffstat 2 files changed, 145 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/makefile.vc	Sun Oct 23 19:54:09 2011 +0000
+++ b/makefile.vc	Mon Oct 24 03:10:27 2011 +0000
@@ -57,8 +57,8 @@
 !endif
 
 CC = cl
-CFLAGS = -c $(PLATFORM_DEF) -D__WIN32__ -DMSVC -DBUILD_DLL -I$(SRCDIR)\platform -I$(SRCDIR) $(SVNVERSION)
-LIBS = wsock32.lib kernel32.lib user32.lib comctl32.lib gdi32.lib advapi32.lib shell32.lib comdlg32.lib ole32.lib oleaut32.lib userenv.lib msimg32.lib
+CFLAGS = -c $(PLATFORM_DEF) -D__WIN32__ -DMSVC -DGDIPLUS -DBUILD_DLL -I$(SRCDIR)\platform -I$(SRCDIR) $(SVNVERSION)
+LIBS = wsock32.lib kernel32.lib user32.lib comctl32.lib gdi32.lib advapi32.lib shell32.lib comdlg32.lib ole32.lib oleaut32.lib userenv.lib msimg32.lib gdiplus.lib
 RES =
 LINKFLAGS = -machine:$(TARGET_CPU) -manifest $(LINK_DEBUG)
 DLLLINKFLAGS = -dll
--- a/win/dw.c	Sun Oct 23 19:54:09 2011 +0000
+++ b/win/dw.c	Mon Oct 24 03:10:27 2011 +0000
@@ -19,13 +19,83 @@
 #include <stdio.h>
 #include <process.h>
 #include <time.h>
-#ifdef GDIPLUS
-#include <gdiplustypes.h>
-#include <gdiplusflat.h>
-#endif
 #include "dw.h"
 #include "XBrowseForFolder.h"
 
+#ifdef GDIPLUS
+/* GDI+ Headers are not C compatible... so define what we need here instead */
+struct GdiplusStartupInput
+{
+    UINT32 GdiplusVersion;
+    void *DebugEventCallback;
+    BOOL SuppressBackgroundThread;
+    BOOL SuppressExternalCodecs;       
+};
+
+typedef enum  {
+  Ok                          = 0,
+  GenericError                = 1,
+  InvalidParameter            = 2,
+  OutOfMemory                 = 3,
+  ObjectBusy                  = 4,
+  InsufficientBuffer          = 5,
+  NotImplemented              = 6,
+  Win32Error                  = 7,
+  WrongState                  = 8,
+  Aborted                     = 9,
+  FileNotFound                = 10,
+  ValueOverflow               = 11,
+  AccessDenied                = 12,
+  UnknownImageFormat          = 13,
+  FontFamilyNotFound          = 14,
+  FontStyleNotFound           = 15,
+  NotTrueTypeFont             = 16,
+  UnsupportedGdiplusVersion   = 17,
+  GdiplusNotInitialized       = 18,
+  PropertyNotFound            = 19,
+  PropertyNotSupported        = 20,
+  ProfileNotFound             = 21 
+} Status;
+
+Status WINAPI GdipCreateBitmapFromFile(const WCHAR* filename, void **bitmap);
+Status WINAPI GdipCreateHBITMAPFromBitmap(void *bitmap, HBITMAP* hbmReturn, DWORD background);
+Status WINAPI GdipCreateHICONFromBitmap(void *bitmap, HICON *hbmReturn);
+Status WINAPI GdipDisposeImage(void *image);
+Status WINAPI GdipGetImagePixelFormat(void *image, INT *format);
+Status WINAPI GdiplusStartup(ULONG_PTR *token, const struct GdiplusStartupInput *input, void *output);
+VOID WINAPI GdiplusShutdown(ULONG_PTR token);
+
+/* Pixel format information */
+#define    PixelFormatIndexed      0x00010000 
+#define    PixelFormatGDI          0x00020000
+#define    PixelFormatAlpha        0x00040000
+#define    PixelFormatPAlpha       0x00080000
+#define    PixelFormatExtended     0x00100000
+#define    PixelFormatCanonical    0x00200000 
+
+#define    PixelFormatUndefined       0
+#define    PixelFormatDontCare        0
+
+#define    PixelFormat1bppIndexed     (1 | ( 1 << 8) | PixelFormatIndexed | PixelFormatGDI)
+#define    PixelFormat4bppIndexed     (2 | ( 4 << 8) | PixelFormatIndexed | PixelFormatGDI)
+#define    PixelFormat8bppIndexed     (3 | ( 8 << 8) | PixelFormatIndexed | PixelFormatGDI)
+#define    PixelFormat16bppGrayScale  (4 | (16 << 8) | PixelFormatExtended)
+#define    PixelFormat16bppRGB555     (5 | (16 << 8) | PixelFormatGDI)
+#define    PixelFormat16bppRGB565     (6 | (16 << 8) | PixelFormatGDI)
+#define    PixelFormat16bppARGB1555   (7 | (16 << 8) | PixelFormatAlpha | PixelFormatGDI)
+#define    PixelFormat24bppRGB        (8 | (24 << 8) | PixelFormatGDI)
+#define    PixelFormat32bppRGB        (9 | (32 << 8) | PixelFormatGDI)
+#define    PixelFormat32bppARGB       (10 | (32 << 8) | PixelFormatAlpha | PixelFormatGDI | PixelFormatCanonical)
+#define    PixelFormat32bppPARGB      (11 | (32 << 8) | PixelFormatAlpha | PixelFormatPAlpha | PixelFormatGDI)
+#define    PixelFormat48bppRGB        (12 | (48 << 8) | PixelFormatExtended)
+#define    PixelFormat64bppARGB       (13 | (64 << 8) | PixelFormatAlpha  | PixelFormatCanonical | PixelFormatExtended)
+#define    PixelFormat64bppPARGB      (14 | (64 << 8) | PixelFormatAlpha  | PixelFormatPAlpha | PixelFormatExtended)
+#define    PixelFormat32bppCMYK       (15 | (32 << 8))
+
+/* Token to the GDI+ Instance */
+ULONG_PTR gdiplusToken; 
+#endif
+
 /*
  * MinGW (as at 3.2.3) doesn't have MIM_MENUDATA
  * so #define it here
@@ -317,12 +387,12 @@
 };
 
 /* Section for loading files of types besides BMP and ICO and return HBITMAP or HICON */
-GpBitmap *_dw_load_gpbitmap( char *filename )
+void *_dw_load_gpbitmap( char *filename )
 {
    int found_ext = 0,i, wclen = (strlen(filename) + 6) * sizeof(wchar_t);
    char *file = _alloca(strlen(filename) + 6);
    wchar_t *wfile = _alloca(wclen);
-   GpBitmap *image;
+   void *image;
 
    /* Try various extentions */
    for ( i = 0; i < NUM_EXTS; i++ )
@@ -333,7 +403,7 @@
       {
          /* Convert to wide format */
          MultiByteToWideChar(CP_ACP, 0, file, strlen(file), wfile, wclen);
-         if(GdipCreateBitmapFromFile(wfile, &image))
+         if(!GdipCreateBitmapFromFile(wfile, &image))
              return image;
       }
    }
@@ -343,20 +413,62 @@
 /* Try to load the appropriate image and return the HBITMAP handle */
 HBITMAP _dw_load_bitmap(char *filename, unsigned long *depth)
 {
-    GpBitmap *bitmap = _dw_load_gpbitmap(filename);
+    void *bitmap = _dw_load_gpbitmap(filename);
     if(bitmap)
     {
-        HBITMAP hbm;
-
-        if(GdipCreateHBITMAPFromBitmap(bitmap, &hbm, 0))
+        HBITMAP hbm = NULL;
+
+        if(!GdipCreateHBITMAPFromBitmap(bitmap, &hbm, 0))
         {
             if(depth)
             {
-                /* TODO: Actually query the color depth here */
-                *depth = 32;
+                INT pf;
+
+                /* Default to 0 */
+                *depth = 0;
+
+                /* Query the pixel format so we can determine the depth */
+                if(!GdipGetImagePixelFormat(bitmap, &pf))
+                {
+                    switch(pf)
+                    {
+                    case PixelFormat1bppIndexed:
+                        *depth = 1;
+                        break;
+                    case PixelFormat4bppIndexed:
+                        *depth = 4;
+                        break;
+                    case PixelFormat8bppIndexed:
+                        *depth = 8;
+                        break;
+                    case PixelFormat16bppGrayScale:
+                    case PixelFormat16bppRGB555:
+                    case PixelFormat16bppRGB565:
+                    case PixelFormat16bppARGB1555:
+                        *depth = 16;
+                        break;
+                    case PixelFormat24bppRGB:
+                        *depth = 24;
+                        break;
+                    case PixelFormat32bppRGB:
+                    case PixelFormat32bppARGB:
+                    case PixelFormat32bppPARGB:
+                    case PixelFormat32bppCMYK:
+                        *depth = 32;
+                        break;
+                    case PixelFormat48bppRGB:
+                        *depth = 48;
+                        break;
+                    case PixelFormat64bppARGB:
+                    case PixelFormat64bppPARGB:
+                        *depth = 64;
+                        break;
+                    }
+                }
             }
-            return hbm;
         }
+        GdipDisposeImage(bitmap);
+        return hbm;
     }
     return NULL;
 }
@@ -364,13 +476,14 @@
 /* Try to load the appropriate image and return the HICON handle */
 HICON _dw_load_icon(char *filename)
 {
-    GpBitmap *bitmap = _dw_load_gpbitmap(filename);
+    void *bitmap = _dw_load_gpbitmap(filename);
     if(bitmap)
     {
-        HICON hicon;
-
-        if(GdipCreateHICONFromBitmap(bitmap, &hicon))
-            return hicon;
+        HICON hicon = NULL;
+
+        GdipCreateHICONFromBitmap(bitmap, &hicon);
+        GdipDisposeImage(bitmap);
+        return hicon;
     }
     return NULL;
 }
@@ -3507,6 +3620,7 @@
    INITCOMMONCONTROLSEX icc;
    char *fname, *alttmpdir;
    HFONT oldfont;
+   struct GdiplusStartupInput si; 
 
    /* Initialize our thread local storage */
    _foreground = TlsAlloc();
@@ -3648,6 +3762,15 @@
     */
    screenx = GetSystemMetrics(SM_CXSCREEN);
    screeny = GetSystemMetrics(SM_CYSCREEN);
+
+#ifdef GDIPLUS
+   /* Setup GDI+ */
+   si.GdiplusVersion = 1;
+   si.DebugEventCallback = NULL;
+   si.SuppressBackgroundThread = FALSE;
+   si.SuppressExternalCodecs = FALSE;
+   GdiplusStartup(&gdiplusToken, &si, NULL);
+#endif
    return 0;
 }
 
@@ -8996,7 +9119,7 @@
          fwrite( data, 1, len, fp );
          fclose( fp );
 #ifdef GDIPLUS
-         pixmap->hbm = _dw_load_bitmap(file);
+         pixmap->hbm = _dw_load_bitmap(file, NULL);
 #else
          pixmap->hbm = (HBITMAP)LoadImage( NULL, file, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );
          pixmap->depth = _read_bitmap_header(file);