Implement CreateBitmap using CreateBitmapIndirect so we can handle
authorJon Griffiths <jon_p_griffiths@yahoo.com>
Mon, 22 Nov 2004 18:18:21 +0000 (18:18 +0000)
committerAlexandre Julliard <julliard@winehq.org>
Mon, 22 Nov 2004 18:18:21 +0000 (18:18 +0000)
funky alignment paddings.
SetLastError() on failure, documentation cleanup.

dlls/gdi/bitmap.c

index 3a8e559907a90031e7b447c0dbccfe0779e5f899..56424a5bf6ca7a8d50d1e91c64bbcda39b473fd5 100644 (file)
@@ -52,7 +52,7 @@ static const struct gdi_obj_funcs bitmap_funcs =
  * Return number of bytes taken by a scanline of 16-bit aligned Windows DDB
  * data.
  */
-static INT BITMAP_GetWidthBytes( INT bmWidth, INT bpp )
+INT BITMAP_GetWidthBytes( INT bmWidth, INT bpp )
 {
     switch(bpp)
     {
@@ -98,60 +98,21 @@ static INT BITMAP_GetWidthBytes( INT bmWidth, INT bpp )
  *    Failure: 0
  */
 HBITMAP WINAPI CreateBitmap( INT width, INT height, UINT planes,
-                                 UINT bpp, LPCVOID bits )
+                             UINT bpp, LPCVOID bits )
 {
-    BITMAPOBJ *bmp;
-    HBITMAP hbitmap;
-
-    planes = (BYTE)planes;
-    bpp    = (BYTE)bpp;
-
-
-      /* Check parameters */
-    if (!height || !width)
-    {
-        height = 1;
-        width  = 1;
-        planes = 1;
-        bpp    = 1;
-    }
-    if (planes != 1) {
-        FIXME("planes = %d\n", planes);
-       return 0;
-    }
-    if (height < 0) height = -height;
-    if (width < 0) width = -width;
+    BITMAP bm;
 
-      /* Create the BITMAPOBJ */
-    if (!(bmp = GDI_AllocObject( sizeof(BITMAPOBJ), BITMAP_MAGIC,
-                                (HGDIOBJ *)&hbitmap, &bitmap_funcs )))
-        return 0;
+    bm.bmType = 0;
+    bm.bmWidth = width;
+    bm.bmHeight = height;
+    bm.bmWidthBytes = BITMAP_GetWidthBytes( width, bpp );
+    bm.bmPlanes = planes;
+    bm.bmBitsPixel = bpp;
+    bm.bmBits = (LPVOID)bits;
 
-    TRACE("%dx%d, %d colors returning %p\n", width, height, 1 << (planes*bpp), hbitmap);
-
-    bmp->size.cx = 0;
-    bmp->size.cy = 0;
-    bmp->bitmap.bmType = 0;
-    bmp->bitmap.bmWidth = width;
-    bmp->bitmap.bmHeight = height;
-    bmp->bitmap.bmPlanes = planes;
-    bmp->bitmap.bmBitsPixel = bpp;
-    bmp->bitmap.bmWidthBytes = BITMAP_GetWidthBytes( width, bpp );
-    bmp->bitmap.bmBits = NULL;
-
-    bmp->funcs = NULL;
-    bmp->physBitmap = NULL;
-    bmp->dib = NULL;
-    bmp->segptr_bits = 0;
-
-    if (bits) /* Set bitmap bits */
-       SetBitmapBits( hbitmap, height * bmp->bitmap.bmWidthBytes,
-                         bits );
-    GDI_ReleaseObj( hbitmap );
-    return hbitmap;
+    return CreateBitmapIndirect( &bm );
 }
 
-
 /******************************************************************************
  * CreateCompatibleBitmap [GDI32.@]
  *
@@ -223,7 +184,7 @@ HBITMAP WINAPI CreateCompatibleBitmap( HDC hdc, INT width, INT height)
                     bi->bmiHeader.biCompression   = bmp->dib->dsBmih.biCompression;
                     bi->bmiHeader.biSizeImage     = 0;
                     bi->bmiHeader.biXPelsPerMeter = bmp->dib->dsBmih.biXPelsPerMeter;
-                    bi->bmiHeader.biYPelsPerMeter = bmp->dib->dsBmih.biYPelsPerMeter;          
+                    bi->bmiHeader.biYPelsPerMeter = bmp->dib->dsBmih.biYPelsPerMeter;
                     bi->bmiHeader.biClrUsed       = bmp->dib->dsBmih.biClrUsed;
                     bi->bmiHeader.biClrImportant  = bmp->dib->dsBmih.biClrImportant;
 
@@ -255,17 +216,76 @@ HBITMAP WINAPI CreateCompatibleBitmap( HDC hdc, INT width, INT height)
 /******************************************************************************
  * CreateBitmapIndirect [GDI32.@]
  *
- * Creates a bitmap with the specifies info.
+ * Creates a bitmap with the specified info.
+ *
+ * PARAMS
+ *  bmp [I] Pointer to the bitmap info describing the bitmap
  *
  * RETURNS
  *    Success: Handle to bitmap
- *    Failure: NULL
+ *    Failure: NULL. Use GetLastError() to determine the cause.
+ *
+ * NOTES
+ *  If a width or height of 0 are given, a 1x1 monochrome bitmap is returned.
  */
-HBITMAP WINAPI CreateBitmapIndirect(
-    const BITMAP * bmp) /* [in] Pointer to the bitmap data */
+HBITMAP WINAPI CreateBitmapIndirect( const BITMAP *bmp )
 {
-    return CreateBitmap( bmp->bmWidth, bmp->bmHeight, bmp->bmPlanes,
-                           bmp->bmBitsPixel, bmp->bmBits );
+    BITMAP bm;
+    BITMAPOBJ *bmpobj;
+    HBITMAP hbitmap;
+
+    if (!bmp || bmp->bmType || bmp->bmPlanes != 1)
+    {
+        if (bmp && bmp->bmPlanes != 1)
+            FIXME("planes = %d\n", bmp->bmPlanes);
+        SetLastError( ERROR_INVALID_PARAMETER );
+        return NULL;
+    }
+
+    bm = *bmp;
+
+    if (!bm.bmWidth || !bm.bmHeight)
+    {
+        bm.bmWidth = bm.bmHeight = 1;
+        bm.bmPlanes = bm.bmBitsPixel = 1;
+        bm.bmWidthBytes = 2;
+        bm.bmBits = NULL;
+    }
+    else
+    {
+        if (bm.bmHeight < 0)
+            bm.bmHeight = -bm.bmHeight;
+        if (bm.bmWidth < 0)
+            bm.bmWidth = -bm.bmWidth;
+    }
+
+      /* Create the BITMAPOBJ */
+    bmpobj = GDI_AllocObject( sizeof(BITMAPOBJ), BITMAP_MAGIC,
+                              (HGDIOBJ *)&hbitmap, &bitmap_funcs );
+
+    if (!bmpobj)
+    {
+        SetLastError( ERROR_NOT_ENOUGH_MEMORY );
+        return NULL;
+    }
+
+    TRACE("%dx%d, %d colors returning %p\n", bm.bmWidth, bm.bmHeight,
+          1 << (bm.bmPlanes * bm.bmBitsPixel), hbitmap);
+
+    bmpobj->size.cx = 0;
+    bmpobj->size.cy = 0;
+    bmpobj->bitmap = bm;
+    bmpobj->bitmap.bmBits = NULL;
+    bmpobj->funcs = NULL;
+    bmpobj->physBitmap = NULL;
+    bmpobj->dib = NULL;
+    bmpobj->segptr_bits = 0;
+
+    if (bm.bmBits)
+        SetBitmapBits( hbitmap, bm.bmHeight * bm.bmWidthBytes, bm.bmBits );
+
+    GDI_ReleaseObj( hbitmap );
+    return hbitmap;
 }