[ros-diffs] [cwittich] 45831: [GDIPLUS] sync gdiplus to wine 1.1.39

cwittich at svn.reactos.org cwittich at svn.reactos.org
Thu Mar 4 14:34:06 CET 2010


Author: cwittich
Date: Thu Mar  4 14:34:05 2010
New Revision: 45831

URL: http://svn.reactos.org/svn/reactos?rev=45831&view=rev
Log:
[GDIPLUS]
sync gdiplus to wine 1.1.39

Modified:
    trunk/reactos/dll/win32/gdiplus/brush.c
    trunk/reactos/dll/win32/gdiplus/customlinecap.c
    trunk/reactos/dll/win32/gdiplus/font.c
    trunk/reactos/dll/win32/gdiplus/gdiplus.c
    trunk/reactos/dll/win32/gdiplus/gdiplus.spec
    trunk/reactos/dll/win32/gdiplus/gdiplus_private.h
    trunk/reactos/dll/win32/gdiplus/graphics.c
    trunk/reactos/dll/win32/gdiplus/graphicspath.c
    trunk/reactos/dll/win32/gdiplus/image.c
    trunk/reactos/dll/win32/gdiplus/imageattributes.c
    trunk/reactos/dll/win32/gdiplus/pen.c
    trunk/reactos/dll/win32/gdiplus/stringformat.c

Modified: trunk/reactos/dll/win32/gdiplus/brush.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/gdiplus/brush.c?rev=45831&r1=45830&r2=45831&view=diff
==============================================================================
--- trunk/reactos/dll/win32/gdiplus/brush.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/gdiplus/brush.c [iso-8859-1] Thu Mar  4 14:34:05 2010
@@ -87,13 +87,11 @@
             break;
         }
         case BrushTypeHatchFill:
-            *clone = GdipAlloc(sizeof(GpHatch));
-            if (!*clone) return OutOfMemory;
-
-            memcpy(*clone, brush, sizeof(GpHatch));
-
-            (*clone)->gdibrush = CreateBrushIndirect(&(*clone)->lb);
-            break;
+        {
+            GpHatch *hatch = (GpHatch*)brush;
+
+            return GdipCreateHatchBrush(hatch->hatchstyle, hatch->forecol, hatch->backcol, (GpHatch**)clone);
+        }
         case BrushTypePathGradient:{
             GpPathGradient *src, *dest;
             INT count;
@@ -189,18 +187,29 @@
             break;
         }
         case BrushTypeTextureFill:
-            *clone = GdipAlloc(sizeof(GpTexture));
-            if(!*clone)    return OutOfMemory;
-
-            memcpy(*clone, brush, sizeof(GpTexture));
-
-            (*clone)->gdibrush = CreateBrushIndirect(&(*clone)->lb);
-            break;
+        {
+            GpStatus stat;
+            GpTexture *texture = (GpTexture*)brush;
+            GpTexture *new_texture;
+
+            stat = GdipCreateTexture(texture->image, texture->wrap, &new_texture);
+
+            if (stat == Ok)
+            {
+                memcpy(new_texture->transform, texture->transform, sizeof(GpMatrix));
+                *clone = (GpBrush*)new_texture;
+            }
+            else
+                *clone = NULL;
+
+            return stat;
+        }
         default:
             ERR("not implemented for brush type %d\n", brush->bt);
             return NotImplemented;
     }
 
+    TRACE("<-- %p\n", *clone);
     return Ok;
 }
 
@@ -317,6 +326,7 @@
         (*brush)->forecol = forecol;
         (*brush)->backcol = backcol;
         (*brush)->hatchstyle = hatchstyle;
+        TRACE("<-- %p\n", *brush);
     }
     else
     {
@@ -336,8 +346,8 @@
 {
     COLORREF col = ARGB2COLORREF(startcolor);
 
-    TRACE("(%p, %p, %x, %x, %d, %p)\n", startpoint, endpoint,
-          startcolor, endcolor, wrap, line);
+    TRACE("(%s, %s, %x, %x, %d, %p)\n", debugstr_pointf(startpoint),
+          debugstr_pointf(endpoint), startcolor, endcolor, wrap, line);
 
     if(!line || !startpoint || !endpoint || wrap == WrapModeClamp)
         return InvalidParameter;
@@ -396,6 +406,8 @@
     (*line)->pblendcolor = NULL;
     (*line)->pblendpos = NULL;
     (*line)->pblendcount = 0;
+
+    TRACE("<-- %p\n", *line);
 
     return Ok;
 }
@@ -491,20 +503,74 @@
 
 /******************************************************************************
  * GdipCreateLineBrushFromRectWithAngle [GDIPLUS.@]
- *
- * FIXME: angle value completely ignored. Don't know how to use it since native
- *        always set Brush rectangle to rect (independetly of this angle).
- *        Maybe it's used only on drawing.
  */
 GpStatus WINGDIPAPI GdipCreateLineBrushFromRectWithAngle(GDIPCONST GpRectF* rect,
     ARGB startcolor, ARGB endcolor, REAL angle, BOOL isAngleScalable, GpWrapMode wrap,
     GpLineGradient **line)
 {
+    GpStatus stat;
+    LinearGradientMode mode;
+    REAL width, height, exofs, eyofs;
+    REAL sin_angle, cos_angle, sin_cos_angle;
+
     TRACE("(%p, %x, %x, %.2f, %d, %d, %p)\n", rect, startcolor, endcolor, angle, isAngleScalable,
           wrap, line);
 
-    return GdipCreateLineBrushFromRect(rect, startcolor, endcolor, LinearGradientModeForwardDiagonal,
-                                       wrap, line);
+    sin_angle = sinf(deg2rad(angle));
+    cos_angle = cosf(deg2rad(angle));
+    sin_cos_angle = sin_angle * cos_angle;
+
+    if (isAngleScalable)
+    {
+        width = height = 1.0;
+    }
+    else
+    {
+        width = rect->Width;
+        height = rect->Height;
+    }
+
+    if (sin_cos_angle >= 0)
+        mode = LinearGradientModeForwardDiagonal;
+    else
+        mode = LinearGradientModeBackwardDiagonal;
+
+    stat = GdipCreateLineBrushFromRect(rect, startcolor, endcolor, mode, wrap, line);
+
+    if (stat == Ok)
+    {
+        if (sin_cos_angle >= 0)
+        {
+            exofs = width * sin_cos_angle + height * cos_angle * cos_angle;
+            eyofs = width * sin_angle * sin_angle + height * sin_cos_angle;
+        }
+        else
+        {
+            exofs = width * sin_angle * sin_angle + height * sin_cos_angle;
+            eyofs = -width * sin_cos_angle + height * sin_angle * sin_angle;
+        }
+
+        if (isAngleScalable)
+        {
+            exofs = exofs * rect->Width;
+            eyofs = eyofs * rect->Height;
+        }
+
+        if (sin_angle >= 0)
+        {
+            (*line)->endpoint.X = rect->X + exofs;
+            (*line)->endpoint.Y = rect->Y + eyofs;
+        }
+        else
+        {
+            (*line)->endpoint.X = (*line)->startpoint.X;
+            (*line)->endpoint.Y = (*line)->startpoint.Y;
+            (*line)->startpoint.X = rect->X + exofs;
+            (*line)->startpoint.Y = rect->Y + eyofs;
+        }
+    }
+
+    return stat;
 }
 
 GpStatus WINGDIPAPI GdipCreateLineBrushFromRectWithAngleI(GDIPCONST GpRect* rect,
@@ -570,6 +636,8 @@
     (*grad)->center.Y = 0.0;
     (*grad)->focus.X = 0.0;
     (*grad)->focus.Y = 0.0;
+
+    TRACE("<-- %p\n", *grad);
 
     return Ok;
 }
@@ -661,6 +729,8 @@
     (*grad)->focus.X = 0.0;
     (*grad)->focus.Y = 0.0;
 
+    TRACE("<-- %p\n", *grad);
+
     return Ok;
 }
 
@@ -686,6 +756,8 @@
     (*sf)->brush.bt = BrushTypeSolidColor;
     (*sf)->color = color;
     (*sf)->bmp = ARGB2BMP(color);
+
+    TRACE("<-- %p\n", *sf);
 
     return Ok;
 }
@@ -749,139 +821,71 @@
     GDIPCONST GpImageAttributes *imageattr, REAL x, REAL y, REAL width,
     REAL height, GpTexture **texture)
 {
-    HDC hdc;
-    HBITMAP hbm, old = NULL;
-    BITMAPINFO *pbmi;
-    BITMAPINFOHEADER *bmih;
-    INT n_x, n_y, n_width, n_height, abs_height, stride, image_stride, i, bytespp;
-    BOOL bm_is_selected;
-    BYTE *dibits, *buff, *textbits;
+    HBITMAP hbm;
     GpStatus status;
+    GpImage *new_image=NULL;
 
     TRACE("(%p, %p, %.2f, %.2f, %.2f, %.2f, %p)\n", image, imageattr, x, y, width, height,
            texture);
 
     if(!image || !texture || x < 0.0 || y < 0.0 || width < 0.0 || height < 0.0)
         return InvalidParameter;
+
+    *texture = NULL;
 
     if(image->type != ImageTypeBitmap){
         FIXME("not implemented for image type %d\n", image->type);
         return NotImplemented;
     }
 
-    n_x = roundr(x);
-    n_y = roundr(y);
-    n_width = roundr(width);
-    n_height = roundr(height);
-
-    if(n_x + n_width > ((GpBitmap*)image)->width ||
-       n_y + n_height > ((GpBitmap*)image)->height)
-        return InvalidParameter;
-
-    hbm = ((GpBitmap*)image)->hbitmap;
-    if(!hbm)   return GenericError;
-    hdc = ((GpBitmap*)image)->hdc;
-    bm_is_selected = (hdc != 0);
-
-    pbmi = GdipAlloc(sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
-    if (!pbmi)
-        return OutOfMemory;
-    pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
-    pbmi->bmiHeader.biBitCount = 0;
-
-    if(!bm_is_selected){
-        hdc = CreateCompatibleDC(0);
-        old = SelectObject(hdc, hbm);
-    }
-
-    /* fill out bmi */
-    GetDIBits(hdc, hbm, 0, 0, NULL, pbmi, DIB_RGB_COLORS);
-
-    bytespp = pbmi->bmiHeader.biBitCount / 8;
-    abs_height = abs(pbmi->bmiHeader.biHeight);
-
-    if(n_x > pbmi->bmiHeader.biWidth || n_x + n_width > pbmi->bmiHeader.biWidth ||
-       n_y > abs_height || n_y + n_height > abs_height){
-        GdipFree(pbmi);
-        return InvalidParameter;
-    }
-
-    dibits = GdipAlloc(pbmi->bmiHeader.biSizeImage);
-
-    if(dibits)  /* this is not a good place to error out */
-        GetDIBits(hdc, hbm, 0, abs_height, dibits, pbmi, DIB_RGB_COLORS);
-
-    if(!bm_is_selected){
-        SelectObject(hdc, old);
-        DeleteDC(hdc);
-    }
-
-    if(!dibits){
-        GdipFree(pbmi);
-        return OutOfMemory;
-    }
-
-    image_stride = (pbmi->bmiHeader.biWidth * bytespp + 3) & ~3;
-    stride = (n_width * bytespp + 3) & ~3;
-    buff = GdipAlloc(sizeof(BITMAPINFOHEADER) + stride * n_height);
-    if(!buff){
-        GdipFree(pbmi);
-        GdipFree(dibits);
-        return OutOfMemory;
-    }
-
-    bmih = (BITMAPINFOHEADER*)buff;
-    textbits = (BYTE*) (bmih + 1);
-    bmih->biSize = sizeof(BITMAPINFOHEADER);
-    bmih->biWidth = n_width;
-    bmih->biHeight = n_height;
-    bmih->biCompression = BI_RGB;
-    bmih->biSizeImage = stride * n_height;
-    bmih->biBitCount = pbmi->bmiHeader.biBitCount;
-    bmih->biClrUsed = 0;
-    bmih->biPlanes = 1;
-
-    /* image is flipped */
-    if(pbmi->bmiHeader.biHeight > 0){
-        dibits += image_stride * (pbmi->bmiHeader.biHeight - 1);
-        image_stride *= -1;
-        textbits += stride * (n_height - 1);
-        stride *= -1;
-    }
-
-    GdipFree(pbmi);
-
-    for(i = 0; i < n_height; i++)
-        memcpy(&textbits[i * stride],
-               &dibits[n_x * bytespp + (n_y + i) * image_stride],
-               abs(stride));
+    status = GdipCloneBitmapArea(x, y, width, height, PixelFormatDontCare, (GpBitmap*)image, (GpBitmap**)&new_image);
+    if (status != Ok)
+        return status;
+
+    hbm = ((GpBitmap*)new_image)->hbitmap;
+    if(!hbm)
+    {
+        status = GenericError;
+        goto exit;
+    }
 
     *texture = GdipAlloc(sizeof(GpTexture));
     if (!*texture){
-        GdipFree(dibits);
-        GdipFree(buff);
-        return OutOfMemory;
+        status = OutOfMemory;
+        goto exit;
     }
 
     if((status = GdipCreateMatrix(&(*texture)->transform)) != Ok){
-        GdipFree(*texture);
-        GdipFree(dibits);
-        GdipFree(buff);
-        return status;
-    }
-
-    (*texture)->brush.lb.lbStyle = BS_DIBPATTERNPT;
-    (*texture)->brush.lb.lbColor = DIB_RGB_COLORS;
-    (*texture)->brush.lb.lbHatch = (ULONG_PTR)buff;
+        goto exit;
+    }
+
+    (*texture)->brush.lb.lbStyle = BS_PATTERN;
+    (*texture)->brush.lb.lbColor = 0;
+    (*texture)->brush.lb.lbHatch = (ULONG_PTR)hbm;
 
     (*texture)->brush.gdibrush = CreateBrushIndirect(&(*texture)->brush.lb);
     (*texture)->brush.bt = BrushTypeTextureFill;
     (*texture)->wrap = imageattr->wrap;
-
-    GdipFree(dibits);
-    GdipFree(buff);
-
-    return Ok;
+    (*texture)->image = new_image;
+
+exit:
+    if (status == Ok)
+    {
+        TRACE("<-- %p\n", *texture);
+    }
+    else
+    {
+        if (*texture)
+        {
+            GdipDeleteMatrix((*texture)->transform);
+            GdipFree(*texture);
+            *texture = NULL;
+        }
+        GdipDisposeImage(new_image);
+        TRACE("<-- error %u\n", status);
+    }
+
+    return status;
 }
 
 /******************************************************************************
@@ -979,6 +983,7 @@
             break;
         case BrushTypeTextureFill:
             GdipDeleteMatrix(((GpTexture*)brush)->transform);
+            GdipDisposeImage(((GpTexture*)brush)->image);
             break;
         default:
             break;
@@ -1175,6 +1180,8 @@
 {
     static int calls;
 
+    TRACE("(%p,%p,%p)\n", grad, argb, count);
+
     if(!grad || !argb || !count || (*count < grad->pathdata.Count))
         return InvalidParameter;
 
@@ -1207,6 +1214,19 @@
     *argb = sf->color;
 
     return Ok;
+}
+
+/******************************************************************************
+ * GdipGetTextureImage [GDIPLUS.@]
+ */
+GpStatus WINGDIPAPI GdipGetTextureImage(GpTexture *brush, GpImage **image)
+{
+    TRACE("(%p, %p)\n", brush, image);
+
+    if(!brush || !image)
+        return InvalidParameter;
+
+    return GdipCloneImage(brush->image, image);
 }
 
 /******************************************************************************
@@ -1430,6 +1450,8 @@
 {
     static int calls;
 
+    TRACE("(%p,%p,%p,%i)\n", brush, blend, pos, count);
+
     if(!(calls++))
         FIXME("not implemented\n");
 
@@ -1463,7 +1485,7 @@
 GpStatus WINGDIPAPI GdipSetPathGradientCenterPoint(GpPathGradient *grad,
     GpPointF *point)
 {
-    TRACE("(%p, %p)\n", grad, point);
+    TRACE("(%p, %s)\n", grad, debugstr_pointf(point));
 
     if(!grad || !point)
         return InvalidParameter;
@@ -1522,6 +1544,8 @@
 {
     static int calls;
 
+    TRACE("(%p,%0.2f,%0.2f)\n", grad, focus, scale);
+
     if(!grad || focus < 0.0 || focus > 1.0 || scale < 0.0 || scale > 1.0)
         return InvalidParameter;
 
@@ -1535,6 +1559,8 @@
     *grad, ARGB *argb, INT *count)
 {
     static int calls;
+
+    TRACE("(%p,%p,%p)\n", grad, argb, count);
 
     if(!grad || !argb || !count || (*count <= 0) ||
         (*count > grad->pathdata.Count))
@@ -1749,6 +1775,8 @@
 {
     static int calls;
 
+    TRACE("(%p)\n", brush);
+
     if(!(calls++))
         FIXME("not implemented\n");
 
@@ -1760,6 +1788,8 @@
 {
     static int calls;
 
+    TRACE("(%p,%p)\n", brush,  matrix);
+
     if(!(calls++))
         FIXME("not implemented\n");
 
@@ -1770,6 +1800,8 @@
     GpMatrixOrder order)
 {
     static int calls;
+
+    TRACE("(%p,%0.2f,%0.2f,%u)\n", brush, sx, sy, order);
 
     if(!(calls++))
         FIXME("not implemented\n");
@@ -1838,6 +1870,8 @@
 {
     static int calls;
 
+    TRACE("(%p,%0.2f,%u)\n", brush, angle, order);
+
     if(!brush)
         return InvalidParameter;
 

Modified: trunk/reactos/dll/win32/gdiplus/customlinecap.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/gdiplus/customlinecap.c?rev=45831&r1=45830&r2=45831&view=diff
==============================================================================
--- trunk/reactos/dll/win32/gdiplus/customlinecap.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/gdiplus/customlinecap.c [iso-8859-1] Thu Mar  4 14:34:05 2010
@@ -57,6 +57,8 @@
            * sizeof(PointF));
     memcpy((*to)->pathdata.Types, from->pathdata.Types, from->pathdata.Count);
 
+    TRACE("<-- %p\n", *to);
+
     return Ok;
 }
 
@@ -105,6 +107,8 @@
     (*customCap)->join = LineJoinMiter;
     (*customCap)->scale = 1.0;
 
+    TRACE("<-- %p\n", *customCap);
+
     return Ok;
 }
 
@@ -153,6 +157,8 @@
 {
     static int calls;
 
+    TRACE("(%p,%u,%u)\n", custom, start, end);
+
     if(!custom)
         return InvalidParameter;
 
@@ -167,6 +173,8 @@
 {
     static int calls;
 
+    TRACE("(%p,%u)\n", custom, base);
+
     if(!(calls++))
         FIXME("not implemented\n");
 
@@ -190,6 +198,8 @@
     REAL inset)
 {
     static int calls;
+
+    TRACE("(%p,%0.2f)\n", custom, inset);
 
     if(!(calls++))
         FIXME("not implemented\n");
@@ -216,6 +226,8 @@
 {
     static int calls;
 
+    TRACE("(%p,%0.2f)\n", custom, width);
+
     if(!(calls++))
         FIXME("not implemented\n");
 
@@ -239,6 +251,8 @@
 {
     static int calls;
 
+    TRACE("(%0.2f,%0.2f,%i,%p)\n", height, width, fill, cap);
+
     if(!(calls++))
         FIXME("not implemented\n");
 
@@ -249,6 +263,8 @@
 {
     static int calls;
 
+    TRACE("(%p,%p)\n", cap, fill);
+
     if(!(calls++))
         FIXME("not implemented\n");
 
@@ -259,6 +275,8 @@
 {
     static int calls;
 
+    TRACE("(%p,%p)\n", cap, height);
+
     if(!(calls++))
         FIXME("not implemented\n");
 
@@ -269,6 +287,8 @@
 {
     static int calls;
 
+    TRACE("(%p,%p)\n", cap, middle);
+
     if(!(calls++))
         FIXME("not implemented\n");
 
@@ -279,6 +299,8 @@
 {
     static int calls;
 
+    TRACE("(%p,%p)\n", cap, width);
+
     if(!(calls++))
         FIXME("not implemented\n");
 
@@ -289,6 +311,8 @@
 {
     static int calls;
 
+    TRACE("(%p,%i)\n", cap, fill);
+
     if(!(calls++))
         FIXME("not implemented\n");
 
@@ -299,6 +323,8 @@
 {
     static int calls;
 
+    TRACE("(%p,%0.2f)\n", cap, height);
+
     if(!(calls++))
         FIXME("not implemented\n");
 
@@ -309,6 +335,8 @@
 {
     static int calls;
 
+    TRACE("(%p,%0.2f)\n", cap, middle);
+
     if(!(calls++))
         FIXME("not implemented\n");
 
@@ -319,8 +347,10 @@
 {
     static int calls;
 
-    if(!(calls++))
-        FIXME("not implemented\n");
-
-    return NotImplemented;
-}
+    TRACE("(%p,%0.2f)\n", cap, width);
+
+    if(!(calls++))
+        FIXME("not implemented\n");
+
+    return NotImplemented;
+}

Modified: trunk/reactos/dll/win32/gdiplus/font.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/gdiplus/font.c?rev=45831&r1=45830&r2=45831&view=diff
==============================================================================
--- trunk/reactos/dll/win32/gdiplus/font.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/gdiplus/font.c [iso-8859-1] Thu Mar  4 14:34:05 2010
@@ -158,6 +158,8 @@
     (*font)->height = tmw->ntmSizeEM;
     (*font)->line_spacing = tmw->tmAscent + tmw->tmDescent + tmw->tmExternalLeading;
 
+    TRACE("<-- %p\n", *font);
+
     return Ok;
 }
 
@@ -204,6 +206,8 @@
 
     SelectObject(hdc, oldfont);
     DeleteObject(hfont);
+
+    TRACE("<-- %p\n", *font);
 
     return Ok;
 }
@@ -583,6 +587,8 @@
 
     *FontFamily = ffamily;
 
+    TRACE("<-- %p\n", ffamily);
+
     return Ok;
 }
 
@@ -610,6 +616,8 @@
 
     (*clonedFontFamily)->tmw = FontFamily->tmw;
     lstrcpyW((*clonedFontFamily)->FamilyName, FontFamily->FamilyName);
+
+    TRACE("<-- %p\n", *clonedFontFamily);
 
     return Ok;
 }
@@ -845,6 +853,9 @@
     (*fontCollection)->FontFamilies = NULL;
     (*fontCollection)->count = 0;
     (*fontCollection)->allocated = 0;
+
+    TRACE("<-- %p\n", *fontCollection);
+
     return Ok;
 }
 

Modified: trunk/reactos/dll/win32/gdiplus/gdiplus.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/gdiplus/gdiplus.c?rev=45831&r1=45830&r2=45831&view=diff
==============================================================================
--- trunk/reactos/dll/win32/gdiplus/gdiplus.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/gdiplus/gdiplus.c [iso-8859-1] Thu Mar  4 14:34:05 2010
@@ -58,9 +58,6 @@
 
     switch(reason)
     {
-    case DLL_WINE_PREATTACH:
-        return FALSE;  /* prefer native version */
-
     case DLL_PROCESS_ATTACH:
         DisableThreadLibraryCalls( hinst );
         break;
@@ -444,3 +441,9 @@
     if (!rc) return "(null)";
     return wine_dbg_sprintf("(%0.2f,%0.2f,%0.2f,%0.2f)", rc->X, rc->Y, rc->Width, rc->Height);
 }
+
+const char *debugstr_pointf(CONST PointF* pt)
+{
+    if (!pt) return "(null)";
+    return wine_dbg_sprintf("(%0.2f,%0.2f)", pt->X, pt->Y);
+}

Modified: trunk/reactos/dll/win32/gdiplus/gdiplus.spec
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/gdiplus/gdiplus.spec?rev=45831&r1=45830&r2=45831&view=diff
==============================================================================
--- trunk/reactos/dll/win32/gdiplus/gdiplus.spec [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/gdiplus/gdiplus.spec [iso-8859-1] Thu Mar  4 14:34:05 2010
@@ -397,7 +397,7 @@
 @ stdcall GdipGetStringFormatTrimming(ptr ptr)
 @ stdcall GdipGetTextContrast(ptr ptr)
 @ stdcall GdipGetTextRenderingHint(ptr ptr)
-@ stub GdipGetTextureImage
+@ stdcall GdipGetTextureImage(ptr ptr)
 @ stdcall GdipGetTextureTransform(ptr ptr)
 @ stdcall GdipGetTextureWrapMode(ptr ptr)
 @ stdcall GdipGetVisibleClipBounds(ptr ptr)
@@ -424,7 +424,7 @@
 @ stdcall GdipIsOutlineVisiblePathPoint(ptr long long ptr ptr ptr)
 @ stdcall GdipIsOutlineVisiblePathPointI(ptr long long ptr ptr ptr)
 @ stdcall GdipIsStyleAvailable(ptr long ptr)
-@ stub GdipIsVisibleClipEmpty
+@ stdcall GdipIsVisibleClipEmpty(ptr ptr)
 @ stdcall GdipIsVisiblePathPoint(ptr long long ptr ptr)
 @ stdcall GdipIsVisiblePathPointI(ptr long long ptr ptr)
 @ stdcall GdipIsVisiblePoint(ptr long long ptr)

Modified: trunk/reactos/dll/win32/gdiplus/gdiplus_private.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/gdiplus/gdiplus_private.h?rev=45831&r1=45830&r2=45831&view=diff
==============================================================================
--- trunk/reactos/dll/win32/gdiplus/gdiplus_private.h [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/gdiplus/gdiplus_private.h [iso-8859-1] Thu Mar  4 14:34:05 2010
@@ -80,8 +80,14 @@
 
 extern const char *debugstr_rectf(CONST RectF* rc);
 
+extern const char *debugstr_pointf(CONST PointF* pt);
+
 extern void convert_32bppARGB_to_32bppPARGB(UINT width, UINT height,
     BYTE *dst_bits, INT dst_stride, const BYTE *src_bits, INT src_stride);
+
+extern GpStatus convert_pixels(UINT width, UINT height,
+    INT dst_stride, BYTE *dst_bits, PixelFormat dst_format,
+    INT src_stride, const BYTE *src_bits, PixelFormat src_format, ARGB *src_palette);
 
 struct GpPen{
     UINT style;
@@ -174,6 +180,7 @@
 struct GpTexture{
     GpBrush brush;
     GpMatrix *transform;
+    GpImage *image;
     WrapMode wrap;  /* not used yet */
 };
 
@@ -217,6 +224,7 @@
     UINT palette_count;
     UINT palette_size;
     ARGB *palette_entries;
+    REAL xres, yres;
 };
 
 struct GpMetafile{
@@ -249,9 +257,19 @@
     ARGB high;
 };
 
+struct color_matrix{
+    BOOL enabled;
+    ColorMatrixFlags flags;
+    ColorMatrix colormatrix;
+    ColorMatrix graymatrix;
+};
+
 struct GpImageAttributes{
     WrapMode wrap;
     struct color_key colorkeys[ColorAdjustTypeCount];
+    struct color_matrix colormatrices[ColorAdjustTypeCount];
+    BOOL gamma_enabled[ColorAdjustTypeCount];
+    REAL gamma[ColorAdjustTypeCount];
 };
 
 struct GpFont{
@@ -274,6 +292,8 @@
     INT tabcount;
     REAL firsttab;
     REAL *tabs;
+    CharacterRange *character_ranges;
+    INT range_count;
 };
 
 struct GpFontCollection{

Modified: trunk/reactos/dll/win32/gdiplus/graphics.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/gdiplus/graphics.c?rev=45831&r1=45830&r2=45831&view=diff
==============================================================================
--- trunk/reactos/dll/win32/gdiplus/graphics.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/gdiplus/graphics.c [iso-8859-1] Thu Mar  4 14:34:05 2010
@@ -1162,6 +1162,8 @@
     list_init(&(*graphics)->containers);
     (*graphics)->contid = 0;
 
+    TRACE("<-- %p\n", *graphics);
+
     return Ok;
 }
 
@@ -1199,6 +1201,8 @@
 {
     static int calls;
 
+    TRACE("(%p,%i,%p)\n", hemf, delete, metafile);
+
     if(!hemf || !metafile)
         return InvalidParameter;
 
@@ -1215,7 +1219,7 @@
     UINT read;
     BYTE* copy;
     HENHMETAFILE hemf;
-    GpStatus retval = GenericError;
+    GpStatus retval = Ok;
 
     TRACE("(%p, %d, %p, %p)\n", hwmf, delete, placeable, metafile);
 
@@ -1240,6 +1244,7 @@
     if(CreateStreamOnHGlobal(copy, TRUE, &stream) != S_OK){
         ERR("could not make stream\n");
         GdipFree(copy);
+        retval = GenericError;
         goto err;
     }
 
@@ -1251,7 +1256,10 @@
 
     if(OleLoadPicture(stream, 0, FALSE, &IID_IPicture,
         (LPVOID*) &((*metafile)->image.picture)) != S_OK)
+    {
+        retval = GenericError;
         goto err;
+    }
 
 
     (*metafile)->image.type = ImageTypeMetafile;
@@ -1260,8 +1268,10 @@
     (*metafile)->image.palette_count = 0;
     (*metafile)->image.palette_size = 0;
     (*metafile)->image.palette_entries = NULL;
+    (*metafile)->image.xres = (REAL)placeable->Inch;
+    (*metafile)->image.yres = (REAL)placeable->Inch;
     (*metafile)->bounds.X = ((REAL) placeable->BoundingBox.Left) / ((REAL) placeable->Inch);
-    (*metafile)->bounds.Y = ((REAL) placeable->BoundingBox.Right) / ((REAL) placeable->Inch);
+    (*metafile)->bounds.Y = ((REAL) placeable->BoundingBox.Top) / ((REAL) placeable->Inch);
     (*metafile)->bounds.Width = ((REAL) (placeable->BoundingBox.Right
                     - placeable->BoundingBox.Left)) / ((REAL) placeable->Inch);
     (*metafile)->bounds.Height = ((REAL) (placeable->BoundingBox.Bottom
@@ -1271,10 +1281,11 @@
     if(delete)
         DeleteMetaFile(hwmf);
 
-    return Ok;
+    TRACE("<-- %p\n", *metafile);
 
 err:
-    GdipFree(*metafile);
+    if (retval != Ok)
+        GdipFree(*metafile);
     IStream_Release(stream);
     return retval;
 }
@@ -1871,6 +1882,9 @@
 
     if(!graphics || !image || !points || count != 3)
          return InvalidParameter;
+
+    TRACE("%s %s %s\n", debugstr_pointf(&points[0]), debugstr_pointf(&points[1]),
+        debugstr_pointf(&points[2]));
 
     memcpy(ptf, points, 3 * sizeof(GpPointF));
     transform_and_round_points(graphics, pti, ptf, 3);
@@ -1912,12 +1926,16 @@
         else
             return NotImplemented;
 
-        if (bitmap->format == PixelFormat32bppARGB)
+        if (!(bitmap->format == PixelFormat16bppRGB555 ||
+              bitmap->format == PixelFormat24bppRGB ||
+              bitmap->format == PixelFormat32bppRGB ||
+              bitmap->format == PixelFormat32bppPARGB))
         {
             BITMAPINFOHEADER bih;
             BYTE *temp_bits;
-
-            /* we need a bitmap with premultiplied alpha */
+            PixelFormat dst_format;
+
+            /* we can't draw a bitmap of this format directly */
             hdc = CreateCompatibleDC(0);
             temp_hdc = 1;
             temp_bitmap = 1;
@@ -1937,8 +1955,14 @@
             hbitmap = CreateDIBSection(hdc, (BITMAPINFO*)&bih, DIB_RGB_COLORS,
                 (void**)&temp_bits, NULL, 0);
 
-            convert_32bppARGB_to_32bppPARGB(bitmap->width, bitmap->height,
-                temp_bits, bitmap->width*4, bitmap->bits, bitmap->stride);
+            if (bitmap->format & (PixelFormatAlpha|PixelFormatPAlpha))
+                dst_format = PixelFormat32bppPARGB;
+            else
+                dst_format = PixelFormat32bppRGB;
+
+            convert_pixels(bitmap->width, bitmap->height,
+                bitmap->width*4, temp_bits, dst_format,
+                bitmap->stride, bitmap->bits, bitmap->format, bitmap->image.palette_entries);
         }
         else
         {
@@ -1953,7 +1977,7 @@
             old_hbm = SelectObject(hdc, hbitmap);
         }
 
-        if (bitmap->format == PixelFormat32bppARGB || bitmap->format == PixelFormat32bppPARGB)
+        if (bitmap->format & (PixelFormatAlpha|PixelFormatPAlpha))
         {
             BLENDFUNCTION bf;
 
@@ -3052,6 +3076,8 @@
 {
     static int calls;
 
+    TRACE("(%p,%u)\n", graphics, intention);
+
     if(!graphics)
         return InvalidParameter;
 
@@ -3149,13 +3175,13 @@
 
 GpStatus WINGDIPAPI GdipGetNearestColor(GpGraphics *graphics, ARGB* argb)
 {
+    FIXME("(%p, %p): stub\n", graphics, argb);
+
     if(!graphics || !argb)
         return InvalidParameter;
 
     if(graphics->busy)
         return ObjectBusy;
-
-    FIXME("(%p, %p): stub\n", graphics, argb);
 
     return NotImplemented;
 }
@@ -3443,11 +3469,11 @@
         GDIPCONST RectF* layoutRect, GDIPCONST GpStringFormat *stringFormat,
         INT regionCount, GpRegion** regions)
 {
-    if (!(graphics && string && font && layoutRect && stringFormat && regions))
-        return InvalidParameter;
-
     FIXME("stub: %p %s %d %p %p %p %d %p\n", graphics, debugstr_w(string),
             length, font, layoutRect, stringFormat, regionCount, regions);
+
+    if (!(graphics && string && font && layoutRect && stringFormat && regions))
+        return InvalidParameter;
 
     return NotImplemented;
 }
@@ -4000,6 +4026,8 @@
     UINT limitDpi)
 {
     static int calls;
+
+    TRACE("(%p,%u)\n", metafile, limitDpi);
 
     if(!(calls++))
         FIXME("not implemented\n");
@@ -4341,3 +4369,26 @@
     FIXME("(%p %d %p %d %p %p): stub\n", hdc, type, frameRect, frameUnit, desc, metafile);
     return NotImplemented;
 }
+
+/*****************************************************************************
+ * GdipIsVisibleClipEmpty [GDIPLUS.@]
+ */
+GpStatus WINGDIPAPI GdipIsVisibleClipEmpty(GpGraphics *graphics, BOOL *res)
+{
+    GpStatus stat;
+    GpRegion* rgn;
+
+    TRACE("(%p, %p)\n", graphics, res);
+
+    if((stat = GdipCreateRegion(&rgn)) != Ok)
+        return stat;
+
+    if((stat = get_visible_clip_region(graphics, rgn)) != Ok)
+        goto cleanup;
+
+    stat = GdipIsEmptyRegion(rgn, graphics, res);
+
+cleanup:
+    GdipDeleteRegion(rgn);
+    return stat;
+}

Modified: trunk/reactos/dll/win32/gdiplus/graphicspath.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/gdiplus/graphicspath.c?rev=45831&r1=45830&r2=45831&view=diff
==============================================================================
--- trunk/reactos/dll/win32/gdiplus/graphicspath.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/gdiplus/graphicspath.c [iso-8859-1] Thu Mar  4 14:34:05 2010
@@ -1380,6 +1380,8 @@
 {
     static int calls;
 
+    TRACE("(%p,%0.2f,%0.2f,%p,%p,%p)\n", path, x, y, pen, graphics, result);
+
     if(!path || !pen)
         return InvalidParameter;
 

Modified: trunk/reactos/dll/win32/gdiplus/image.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/gdiplus/image.c?rev=45831&r1=45830&r2=45831&view=diff
==============================================================================
--- trunk/reactos/dll/win32/gdiplus/image.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/gdiplus/image.c [iso-8859-1] Thu Mar  4 14:34:05 2010
@@ -94,6 +94,24 @@
     return NotImplemented;
 }
 
+static inline void getpixel_1bppIndexed(BYTE *index, const BYTE *row, UINT x)
+{
+    *index = (row[x/8]>>(7-x%8)) & 1;
+}
+
+static inline void getpixel_4bppIndexed(BYTE *index, const BYTE *row, UINT x)
+{
+    if (x & 1)
+        *index = row[x/2]&0xf;
+    else
+        *index = row[x/2]>>4;
+}
+
+static inline void getpixel_8bppIndexed(BYTE *index, const BYTE *row, UINT x)
+{
+    *index = row[x];
+}
+
 static inline void getpixel_16bppGrayScale(BYTE *r, BYTE *g, BYTE *b, BYTE *a,
     const BYTE *row, UINT x)
 {
@@ -211,6 +229,7 @@
     ARGB *color)
 {
     BYTE r, g, b, a;
+    BYTE index;
     BYTE *row;
     TRACE("%p %d %d %p\n", bitmap, x, y, color);
 
@@ -222,6 +241,15 @@
 
     switch (bitmap->format)
     {
+        case PixelFormat1bppIndexed:
+            getpixel_1bppIndexed(&index,row,x);
+            break;
+        case PixelFormat4bppIndexed:
+            getpixel_4bppIndexed(&index,row,x);
+            break;
+        case PixelFormat8bppIndexed:
+            getpixel_8bppIndexed(&index,row,x);
+            break;
         case PixelFormat16bppGrayScale:
             getpixel_16bppGrayScale(&r,&g,&b,&a,row,x);
             break;
@@ -260,7 +288,10 @@
             return NotImplemented;
     }
 
-    *color = a<<24|r<<16|g<<8|b;
+    if (bitmap->format & PixelFormatIndexed)
+        *color = bitmap->image.palette_entries[index];
+    else
+        *color = a<<24|r<<16|g<<8|b;
 
     return Ok;
 }
@@ -409,6 +440,412 @@
     }
 
     return Ok;
+}
+
+GpStatus convert_pixels(UINT width, UINT height,
+    INT dst_stride, BYTE *dst_bits, PixelFormat dst_format,
+    INT src_stride, const BYTE *src_bits, PixelFormat src_format, ARGB *src_palette)
+{
+    UINT x, y;
+
+    if (src_format == dst_format ||
+        (dst_format == PixelFormat32bppRGB && PIXELFORMATBPP(src_format) == 32))
+    {
+        UINT widthbytes = PIXELFORMATBPP(src_format) * width / 8;
+        for (y=0; y<height; y++)
+            memcpy(dst_bits+dst_stride*y, src_bits+src_stride*y, widthbytes);
+        return Ok;
+    }
+
+#define convert_indexed_to_rgb(getpixel_function, setpixel_function) do { \
+    for (x=0; x<width; x++) \
+        for (y=0; y<height; y++) { \
+            BYTE index; \
+            BYTE *color; \
+            getpixel_function(&index, src_bits+src_stride*y, x); \
+            color = (BYTE*)(&src_palette[index]); \
+            setpixel_function(color[2], color[1], color[0], color[3], dst_bits+dst_stride*y, x); \
+        } \
+    return Ok; \
+} while (0);
+
+#define convert_rgb_to_rgb(getpixel_function, setpixel_function) do { \
+    for (x=0; x<width; x++) \
+        for (y=0; y<height; y++) { \
+            BYTE r, g, b, a; \
+            getpixel_function(&r, &g, &b, &a, src_bits+src_stride*y, x); \
+            setpixel_function(r, g, b, a, dst_bits+dst_stride*y, x); \
+        } \
+    return Ok; \
+} while (0);
+
+    switch (src_format)
+    {
+    case PixelFormat1bppIndexed:
+        switch (dst_format)
+        {
+        case PixelFormat16bppGrayScale:
+            convert_indexed_to_rgb(getpixel_1bppIndexed, setpixel_16bppGrayScale);
+        case PixelFormat16bppRGB555:
+            convert_indexed_to_rgb(getpixel_1bppIndexed, setpixel_16bppRGB555);
+        case PixelFormat16bppRGB565:
+            convert_indexed_to_rgb(getpixel_1bppIndexed, setpixel_16bppRGB565);
+        case PixelFormat16bppARGB1555:
+            convert_indexed_to_rgb(getpixel_1bppIndexed, setpixel_16bppARGB1555);
+        case PixelFormat24bppRGB:
+            convert_indexed_to_rgb(getpixel_1bppIndexed, setpixel_24bppRGB);
+        case PixelFormat32bppRGB:
+            convert_indexed_to_rgb(getpixel_1bppIndexed, setpixel_32bppRGB);
+        case PixelFormat32bppARGB:
+            convert_indexed_to_rgb(getpixel_1bppIndexed, setpixel_32bppARGB);
+        case PixelFormat32bppPARGB:
+            convert_indexed_to_rgb(getpixel_1bppIndexed, setpixel_32bppPARGB);
+        case PixelFormat48bppRGB:
+            convert_indexed_to_rgb(getpixel_1bppIndexed, setpixel_48bppRGB);
+        case PixelFormat64bppARGB:
+            convert_indexed_to_rgb(getpixel_1bppIndexed, setpixel_64bppARGB);
+        default:
+            break;
+        }
+        break;
+    case PixelFormat4bppIndexed:
+        switch (dst_format)
+        {
+        case PixelFormat16bppGrayScale:
+            convert_indexed_to_rgb(getpixel_4bppIndexed, setpixel_16bppGrayScale);
+        case PixelFormat16bppRGB555:
+            convert_indexed_to_rgb(getpixel_4bppIndexed, setpixel_16bppRGB555);
+        case PixelFormat16bppRGB565:
+            convert_indexed_to_rgb(getpixel_4bppIndexed, setpixel_16bppRGB565);
+        case PixelFormat16bppARGB1555:
+            convert_indexed_to_rgb(getpixel_4bppIndexed, setpixel_16bppARGB1555);
+        case PixelFormat24bppRGB:
+            convert_indexed_to_rgb(getpixel_4bppIndexed, setpixel_24bppRGB);
+        case PixelFormat32bppRGB:
+            convert_indexed_to_rgb(getpixel_4bppIndexed, setpixel_32bppRGB);
+        case PixelFormat32bppARGB:
+            convert_indexed_to_rgb(getpixel_4bppIndexed, setpixel_32bppARGB);
+        case PixelFormat32bppPARGB:
+            convert_indexed_to_rgb(getpixel_4bppIndexed, setpixel_32bppPARGB);
+        case PixelFormat48bppRGB:
+            convert_indexed_to_rgb(getpixel_4bppIndexed, setpixel_48bppRGB);
+        case PixelFormat64bppARGB:
+            convert_indexed_to_rgb(getpixel_4bppIndexed, setpixel_64bppARGB);
+        default:
+            break;
+        }
+        break;
+    case PixelFormat8bppIndexed:
+        switch (dst_format)
+        {
+        case PixelFormat16bppGrayScale:
+            convert_indexed_to_rgb(getpixel_8bppIndexed, setpixel_16bppGrayScale);
+        case PixelFormat16bppRGB555:
+            convert_indexed_to_rgb(getpixel_8bppIndexed, setpixel_16bppRGB555);
+        case PixelFormat16bppRGB565:
+            convert_indexed_to_rgb(getpixel_8bppIndexed, setpixel_16bppRGB565);
+        case PixelFormat16bppARGB1555:
+            convert_indexed_to_rgb(getpixel_8bppIndexed, setpixel_16bppARGB1555);
+        case PixelFormat24bppRGB:
+            convert_indexed_to_rgb(getpixel_8bppIndexed, setpixel_24bppRGB);
+        case PixelFormat32bppRGB:
+            convert_indexed_to_rgb(getpixel_8bppIndexed, setpixel_32bppRGB);
+        case PixelFormat32bppARGB:
+            convert_indexed_to_rgb(getpixel_8bppIndexed, setpixel_32bppARGB);
+        case PixelFormat32bppPARGB:
+            convert_indexed_to_rgb(getpixel_8bppIndexed, setpixel_32bppPARGB);
+        case PixelFormat48bppRGB:
+            convert_indexed_to_rgb(getpixel_8bppIndexed, setpixel_48bppRGB);
+        case PixelFormat64bppARGB:
+            convert_indexed_to_rgb(getpixel_8bppIndexed, setpixel_64bppARGB);
+        default:
+            break;
+        }
+        break;
+    case PixelFormat16bppGrayScale:
+        switch (dst_format)
+        {
+        case PixelFormat16bppRGB555:
+            convert_rgb_to_rgb(getpixel_16bppGrayScale, setpixel_16bppRGB555);
+        case PixelFormat16bppRGB565:
+            convert_rgb_to_rgb(getpixel_16bppGrayScale, setpixel_16bppRGB565);
+        case PixelFormat16bppARGB1555:
+            convert_rgb_to_rgb(getpixel_16bppGrayScale, setpixel_16bppARGB1555);
+        case PixelFormat24bppRGB:
+            convert_rgb_to_rgb(getpixel_16bppGrayScale, setpixel_24bppRGB);
+        case PixelFormat32bppRGB:
+            convert_rgb_to_rgb(getpixel_16bppGrayScale, setpixel_32bppRGB);
+        case PixelFormat32bppARGB:
+            convert_rgb_to_rgb(getpixel_16bppGrayScale, setpixel_32bppARGB);
+        case PixelFormat32bppPARGB:
+            convert_rgb_to_rgb(getpixel_16bppGrayScale, setpixel_32bppPARGB);
+        case PixelFormat48bppRGB:
+            convert_rgb_to_rgb(getpixel_16bppGrayScale, setpixel_48bppRGB);
+        case PixelFormat64bppARGB:
+            convert_rgb_to_rgb(getpixel_16bppGrayScale, setpixel_64bppARGB);
+        default:
+            break;
+        }
+        break;
+    case PixelFormat16bppRGB555:
+        switch (dst_format)
+        {
+        case PixelFormat16bppGrayScale:
+            convert_rgb_to_rgb(getpixel_16bppRGB555, setpixel_16bppGrayScale);
+        case PixelFormat16bppRGB565:
+            convert_rgb_to_rgb(getpixel_16bppRGB555, setpixel_16bppRGB565);
+        case PixelFormat16bppARGB1555:
+            convert_rgb_to_rgb(getpixel_16bppRGB555, setpixel_16bppARGB1555);
+        case PixelFormat24bppRGB:
+            convert_rgb_to_rgb(getpixel_16bppRGB555, setpixel_24bppRGB);
+        case PixelFormat32bppRGB:
+            convert_rgb_to_rgb(getpixel_16bppRGB555, setpixel_32bppRGB);
+        case PixelFormat32bppARGB:
+            convert_rgb_to_rgb(getpixel_16bppRGB555, setpixel_32bppARGB);
+        case PixelFormat32bppPARGB:
+            convert_rgb_to_rgb(getpixel_16bppRGB555, setpixel_32bppPARGB);
+        case PixelFormat48bppRGB:
+            convert_rgb_to_rgb(getpixel_16bppRGB555, setpixel_48bppRGB);
+        case PixelFormat64bppARGB:
+            convert_rgb_to_rgb(getpixel_16bppRGB555, setpixel_64bppARGB);
+        default:
+            break;
+        }
+        break;
+    case PixelFormat16bppRGB565:
+        switch (dst_format)
+        {
+        case PixelFormat16bppGrayScale:
+            convert_rgb_to_rgb(getpixel_16bppRGB565, setpixel_16bppGrayScale);
+        case PixelFormat16bppRGB555:
+            convert_rgb_to_rgb(getpixel_16bppRGB565, setpixel_16bppRGB555);
+        case PixelFormat16bppARGB1555:
+            convert_rgb_to_rgb(getpixel_16bppRGB565, setpixel_16bppARGB1555);
+        case PixelFormat24bppRGB:
+            convert_rgb_to_rgb(getpixel_16bppRGB565, setpixel_24bppRGB);
+        case PixelFormat32bppRGB:
+            convert_rgb_to_rgb(getpixel_16bppRGB565, setpixel_32bppRGB);
+        case PixelFormat32bppARGB:
+            convert_rgb_to_rgb(getpixel_16bppRGB565, setpixel_32bppARGB);
+        case PixelFormat32bppPARGB:
+            convert_rgb_to_rgb(getpixel_16bppRGB565, setpixel_32bppPARGB);
+        case PixelFormat48bppRGB:
+            convert_rgb_to_rgb(getpixel_16bppRGB565, setpixel_48bppRGB);
+        case PixelFormat64bppARGB:
+            convert_rgb_to_rgb(getpixel_16bppRGB565, setpixel_64bppARGB);
+        default:
+            break;
+        }
+        break;
+    case PixelFormat16bppARGB1555:
+        switch (dst_format)
+        {
+        case PixelFormat16bppGrayScale:
+            convert_rgb_to_rgb(getpixel_16bppARGB1555, setpixel_16bppGrayScale);
+        case PixelFormat16bppRGB555:
+            convert_rgb_to_rgb(getpixel_16bppARGB1555, setpixel_16bppRGB555);
+        case PixelFormat16bppRGB565:
+            convert_rgb_to_rgb(getpixel_16bppARGB1555, setpixel_16bppRGB565);
+        case PixelFormat24bppRGB:
+            convert_rgb_to_rgb(getpixel_16bppARGB1555, setpixel_24bppRGB);
+        case PixelFormat32bppRGB:
+            convert_rgb_to_rgb(getpixel_16bppARGB1555, setpixel_32bppRGB);
+        case PixelFormat32bppARGB:
+            convert_rgb_to_rgb(getpixel_16bppARGB1555, setpixel_32bppARGB);
+        case PixelFormat32bppPARGB:
+            convert_rgb_to_rgb(getpixel_16bppARGB1555, setpixel_32bppPARGB);
+        case PixelFormat48bppRGB:
+            convert_rgb_to_rgb(getpixel_16bppARGB1555, setpixel_48bppRGB);
+        case PixelFormat64bppARGB:
+            convert_rgb_to_rgb(getpixel_16bppARGB1555, setpixel_64bppARGB);
+        default:
+            break;
+        }
+        break;
+    case PixelFormat24bppRGB:
+        switch (dst_format)
+        {
+        case PixelFormat16bppGrayScale:
+            convert_rgb_to_rgb(getpixel_24bppRGB, setpixel_16bppGrayScale);
+        case PixelFormat16bppRGB555:
+            convert_rgb_to_rgb(getpixel_24bppRGB, setpixel_16bppRGB555);
+        case PixelFormat16bppRGB565:
+            convert_rgb_to_rgb(getpixel_24bppRGB, setpixel_16bppRGB565);
+        case PixelFormat16bppARGB1555:
+            convert_rgb_to_rgb(getpixel_24bppRGB, setpixel_16bppARGB1555);
+        case PixelFormat32bppRGB:
+            convert_rgb_to_rgb(getpixel_24bppRGB, setpixel_32bppRGB);
+        case PixelFormat32bppARGB:
+            convert_rgb_to_rgb(getpixel_24bppRGB, setpixel_32bppARGB);
+        case PixelFormat32bppPARGB:
+            convert_rgb_to_rgb(getpixel_24bppRGB, setpixel_32bppPARGB);
+        case PixelFormat48bppRGB:
+            convert_rgb_to_rgb(getpixel_24bppRGB, setpixel_48bppRGB);
+        case PixelFormat64bppARGB:
+            convert_rgb_to_rgb(getpixel_24bppRGB, setpixel_64bppARGB);
+        default:
+            break;
+        }
+        break;
+    case PixelFormat32bppRGB:
+        switch (dst_format)
+        {
+        case PixelFormat16bppGrayScale:
+            convert_rgb_to_rgb(getpixel_32bppRGB, setpixel_16bppGrayScale);
+        case PixelFormat16bppRGB555:
+            convert_rgb_to_rgb(getpixel_32bppRGB, setpixel_16bppRGB555);
+        case PixelFormat16bppRGB565:
+            convert_rgb_to_rgb(getpixel_32bppRGB, setpixel_16bppRGB565);
+        case PixelFormat16bppARGB1555:
+            convert_rgb_to_rgb(getpixel_32bppRGB, setpixel_16bppARGB1555);
+        case PixelFormat24bppRGB:
+            convert_rgb_to_rgb(getpixel_32bppRGB, setpixel_24bppRGB);
+        case PixelFormat32bppARGB:
+            convert_rgb_to_rgb(getpixel_32bppRGB, setpixel_32bppARGB);
+        case PixelFormat32bppPARGB:
+            convert_rgb_to_rgb(getpixel_32bppRGB, setpixel_32bppPARGB);
+        case PixelFormat48bppRGB:
+            convert_rgb_to_rgb(getpixel_32bppRGB, setpixel_48bppRGB);
+        case PixelFormat64bppARGB:
+            convert_rgb_to_rgb(getpixel_32bppRGB, setpixel_64bppARGB);
+        default:
+            break;
+        }
+        break;
+    case PixelFormat32bppARGB:
+        switch (dst_format)
+        {
+        case PixelFormat16bppGrayScale:
+            convert_rgb_to_rgb(getpixel_32bppARGB, setpixel_16bppGrayScale);
+        case PixelFormat16bppRGB555:
+            convert_rgb_to_rgb(getpixel_32bppARGB, setpixel_16bppRGB555);
+        case PixelFormat16bppRGB565:
+            convert_rgb_to_rgb(getpixel_32bppARGB, setpixel_16bppRGB565);
+        case PixelFormat16bppARGB1555:
+            convert_rgb_to_rgb(getpixel_32bppARGB, setpixel_16bppARGB1555);
+        case PixelFormat24bppRGB:
+            convert_rgb_to_rgb(getpixel_32bppARGB, setpixel_24bppRGB);
+        case PixelFormat32bppPARGB:
+            convert_32bppARGB_to_32bppPARGB(width, height, dst_bits, dst_stride, src_bits, src_stride);
+            return Ok;
+        case PixelFormat48bppRGB:
+            convert_rgb_to_rgb(getpixel_32bppARGB, setpixel_48bppRGB);
+        case PixelFormat64bppARGB:
+            convert_rgb_to_rgb(getpixel_32bppARGB, setpixel_64bppARGB);
+        default:
+            break;
+        }
+        break;
+    case PixelFormat32bppPARGB:
+        switch (dst_format)
+        {
+        case PixelFormat16bppGrayScale:
+            convert_rgb_to_rgb(getpixel_32bppPARGB, setpixel_16bppGrayScale);
+        case PixelFormat16bppRGB555:
+            convert_rgb_to_rgb(getpixel_32bppPARGB, setpixel_16bppRGB555);
+        case PixelFormat16bppRGB565:
+            convert_rgb_to_rgb(getpixel_32bppPARGB, setpixel_16bppRGB565);
+        case PixelFormat16bppARGB1555:
+            convert_rgb_to_rgb(getpixel_32bppPARGB, setpixel_16bppARGB1555);
+        case PixelFormat24bppRGB:
+            convert_rgb_to_rgb(getpixel_32bppPARGB, setpixel_24bppRGB);
+        case PixelFormat32bppRGB:
+            convert_rgb_to_rgb(getpixel_32bppPARGB, setpixel_32bppRGB);
+        case PixelFormat32bppARGB:
+            convert_rgb_to_rgb(getpixel_32bppPARGB, setpixel_32bppARGB);
+        case PixelFormat48bppRGB:
+            convert_rgb_to_rgb(getpixel_32bppPARGB, setpixel_48bppRGB);
+        case PixelFormat64bppARGB:
+            convert_rgb_to_rgb(getpixel_32bppPARGB, setpixel_64bppARGB);
+        default:
+            break;
+        }
+        break;
+    case PixelFormat48bppRGB:
+        switch (dst_format)
+        {
+        case PixelFormat16bppGrayScale:
+            convert_rgb_to_rgb(getpixel_48bppRGB, setpixel_16bppGrayScale);
+        case PixelFormat16bppRGB555:
+            convert_rgb_to_rgb(getpixel_48bppRGB, setpixel_16bppRGB555);
+        case PixelFormat16bppRGB565:
+            convert_rgb_to_rgb(getpixel_48bppRGB, setpixel_16bppRGB565);
+        case PixelFormat16bppARGB1555:
+            convert_rgb_to_rgb(getpixel_48bppRGB, setpixel_16bppARGB1555);
+        case PixelFormat24bppRGB:
+            convert_rgb_to_rgb(getpixel_48bppRGB, setpixel_24bppRGB);
+        case PixelFormat32bppRGB:
+            convert_rgb_to_rgb(getpixel_48bppRGB, setpixel_32bppRGB);
+        case PixelFormat32bppARGB:
+            convert_rgb_to_rgb(getpixel_48bppRGB, setpixel_32bppARGB);
+        case PixelFormat32bppPARGB:
+            convert_rgb_to_rgb(getpixel_48bppRGB, setpixel_32bppPARGB);
+        case PixelFormat64bppARGB:
+            convert_rgb_to_rgb(getpixel_48bppRGB, setpixel_64bppARGB);
+        default:
+            break;
+        }
+        break;
+    case PixelFormat64bppARGB:
+        switch (dst_format)
+        {
+        case PixelFormat16bppGrayScale:
+            convert_rgb_to_rgb(getpixel_64bppARGB, setpixel_16bppGrayScale);
+        case PixelFormat16bppRGB555:
+            convert_rgb_to_rgb(getpixel_64bppARGB, setpixel_16bppRGB555);
+        case PixelFormat16bppRGB565:
+            convert_rgb_to_rgb(getpixel_64bppARGB, setpixel_16bppRGB565);
+        case PixelFormat16bppARGB1555:
+            convert_rgb_to_rgb(getpixel_64bppARGB, setpixel_16bppARGB1555);
+        case PixelFormat24bppRGB:
+            convert_rgb_to_rgb(getpixel_64bppARGB, setpixel_24bppRGB);
+        case PixelFormat32bppRGB:
+            convert_rgb_to_rgb(getpixel_64bppARGB, setpixel_32bppRGB);
+        case PixelFormat32bppARGB:
+            convert_rgb_to_rgb(getpixel_64bppARGB, setpixel_32bppARGB);
+        case PixelFormat32bppPARGB:
+            convert_rgb_to_rgb(getpixel_64bppARGB, setpixel_32bppPARGB);
+        case PixelFormat48bppRGB:
+            convert_rgb_to_rgb(getpixel_64bppARGB, setpixel_48bppRGB);
+        default:
+            break;
+        }
+        break;
+    case PixelFormat64bppPARGB:
+        switch (dst_format)
+        {
+        case PixelFormat16bppGrayScale:
+            convert_rgb_to_rgb(getpixel_64bppPARGB, setpixel_16bppGrayScale);
+        case PixelFormat16bppRGB555:
+            convert_rgb_to_rgb(getpixel_64bppPARGB, setpixel_16bppRGB555);
+        case PixelFormat16bppRGB565:
+            convert_rgb_to_rgb(getpixel_64bppPARGB, setpixel_16bppRGB565);
+        case PixelFormat16bppARGB1555:
+            convert_rgb_to_rgb(getpixel_64bppPARGB, setpixel_16bppARGB1555);
+        case PixelFormat24bppRGB:
+            convert_rgb_to_rgb(getpixel_64bppPARGB, setpixel_24bppRGB);
+        case PixelFormat32bppRGB:
+            convert_rgb_to_rgb(getpixel_64bppPARGB, setpixel_32bppRGB);
+        case PixelFormat32bppARGB:
+            convert_rgb_to_rgb(getpixel_64bppPARGB, setpixel_32bppARGB);
+        case PixelFormat32bppPARGB:
+            convert_rgb_to_rgb(getpixel_64bppPARGB, setpixel_32bppPARGB);
+        case PixelFormat48bppRGB:
+            convert_rgb_to_rgb(getpixel_64bppPARGB, setpixel_48bppRGB);
+        case PixelFormat64bppARGB:
+            convert_rgb_to_rgb(getpixel_64bppPARGB, setpixel_64bppARGB);
+        default:
+            break;
+        }
+        break;
+    default:
+        break;
+    }
+
+#undef convert_indexed_to_rgb
+#undef convert_rgb_to_rgb
+
+    return NotImplemented;
 }
 
 /* This function returns a pointer to an array of pixels that represents the
@@ -420,16 +857,13 @@
 GpStatus WINGDIPAPI GdipBitmapLockBits(GpBitmap* bitmap, GDIPCONST GpRect* rect,
     UINT flags, PixelFormat format, BitmapData* lockeddata)
 {
-    BOOL bm_is_selected;
     INT stride, bitspp = PIXELFORMATBPP(format);
-    HDC hdc;
-    HBITMAP hbm, old = NULL;
-    BITMAPINFO *pbmi;
     BYTE *buff = NULL;
     UINT abs_height;
     GpRect act_rect; /* actual rect to be used */
-
-    TRACE("%p %p %d %d %p\n", bitmap, rect, flags, format, lockeddata);
+    GpStatus stat;
+
+    TRACE("%p %p %d 0x%x %p\n", bitmap, rect, flags, format, lockeddata);
 
     if(!lockeddata || !bitmap)
         return InvalidParameter;
@@ -448,10 +882,17 @@
     }
 
     if(flags & ImageLockModeUserInputBuf)
+    {
+        static int fixme=0;
+        if (!fixme++) FIXME("ImageLockModeUserInputBuf not implemented\n");
         return NotImplemented;
+    }
 
     if(bitmap->lockmode)
+    {
+        WARN("bitmap is already locked and cannot be locked again\n");
         return WrongState;
+    }
 
     if (bitmap->bits && bitmap->format == format)
     {
@@ -470,83 +911,77 @@
         return Ok;
     }
 
-    hbm = bitmap->hbitmap;
-    hdc = bitmap->hdc;
-    bm_is_selected = (hdc != 0);
-
-    pbmi = GdipAlloc(sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
-    if (!pbmi)
-        return OutOfMemory;
-    pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
-    pbmi->bmiHeader.biBitCount = 0;
-
-    if(!bm_is_selected){
-        hdc = CreateCompatibleDC(0);
-        old = SelectObject(hdc, hbm);
-    }
-
-    /* fill out bmi */
-    GetDIBits(hdc, hbm, 0, 0, NULL, pbmi, DIB_RGB_COLORS);
-
-    abs_height = abs(pbmi->bmiHeader.biHeight);
-    stride = pbmi->bmiHeader.biWidth * bitspp / 8;
+    /* Make sure we can convert to the requested format. */
+    stat = convert_pixels(0, 0, 0, NULL, format, 0, NULL, bitmap->format, NULL);
+    if (stat == NotImplemented)
+    {
+        FIXME("cannot read bitmap from %x to %x\n", bitmap->format, format);
+        return NotImplemented;
+    }
+
+    /* If we're opening for writing, make sure we'll be able to write back in
+     * the original format. */
+    if (flags & ImageLockModeWrite)
+    {
+        stat = convert_pixels(0, 0, 0, NULL, bitmap->format, 0, NULL, format, NULL);
+        if (stat == NotImplemented)
+        {
+            FIXME("cannot write bitmap from %x to %x\n", format, bitmap->format);
+            return NotImplemented;
+        }
+    }
+
+    abs_height = bitmap->height;
+    stride = (bitmap->width * bitspp + 7) / 8;
     stride = (stride + 3) & ~3;
 
     buff = GdipAlloc(stride * abs_height);
 
-    pbmi->bmiHeader.biBitCount = bitspp;
-
-    if(buff)
-        GetDIBits(hdc, hbm, 0, abs_height, buff, pbmi, DIB_RGB_COLORS);
-
-    if(!bm_is_selected){
-        SelectObject(hdc, old);
-        DeleteDC(hdc);
-    }
-
-    if(!buff){
-        GdipFree(pbmi);
-        return OutOfMemory;
+    if (!buff) return OutOfMemory;
+
+    stat = convert_pixels(bitmap->width, bitmap->height,
+        stride, buff, format,
+        bitmap->stride, bitmap->bits, bitmap->format, bitmap->image.palette_entries);
+
+    if (stat != Ok)
+    {
+        GdipFree(buff);
+        return stat;
     }
 
     lockeddata->Width  = act_rect.Width;
     lockeddata->Height = act_rect.Height;
     lockeddata->PixelFormat = format;
     lockeddata->Reserved = flags;
-
-    if(pbmi->bmiHeader.biHeight > 0){
-        lockeddata->Stride = -stride;
-        lockeddata->Scan0  = buff + (bitspp / 8) * act_rect.X +
-                             stride * (abs_height - 1 - act_rect.Y);
-    }
-    else{
-        lockeddata->Stride = stride;
-        lockeddata->Scan0  = buff + (bitspp / 8) * act_rect.X + stride * act_rect.Y;
-    }
+    lockeddata->Stride = stride;
+    lockeddata->Scan0  = buff + (bitspp / 8) * act_rect.X + stride * act_rect.Y;
 
     bitmap->lockmode = flags;
     bitmap->numlocks++;
-
     bitmap->bitmapbits = buff;
 
-    GdipFree(pbmi);
     return Ok;
 }
 
 GpStatus WINGDIPAPI GdipBitmapSetResolution(GpBitmap* bitmap, REAL xdpi, REAL ydpi)
 {
-    FIXME("(%p, %.2f, %.2f)\n", bitmap, xdpi, ydpi);
-
-    return NotImplemented;
+    TRACE("(%p, %.2f, %.2f)\n", bitmap, xdpi, ydpi);
+
+    if (!bitmap || xdpi == 0.0 || ydpi == 0.0)
+        return InvalidParameter;
+
+    bitmap->image.xres = xdpi;
+    bitmap->image.yres = ydpi;
+
+    return Ok;
 }
 
 GpStatus WINGDIPAPI GdipBitmapUnlockBits(GpBitmap* bitmap,
     BitmapData* lockeddata)
 {
-    HDC hdc;
-    HBITMAP hbm, old = NULL;
-    BOOL bm_is_selected;
-    BITMAPINFO *pbmi;
+    GpStatus stat;
+
+    TRACE("(%p,%p)\n", bitmap, lockeddata);
 
     if(!bitmap || !lockeddata)
         return InvalidParameter;
@@ -570,38 +1005,25 @@
     {
         /* we passed a direct reference; no need to do anything */
         bitmap->lockmode = 0;
+        bitmap->numlocks = 0;
         return Ok;
     }
 
-    hbm = bitmap->hbitmap;
-    hdc = bitmap->hdc;
-    bm_is_selected = (hdc != 0);
-
-    pbmi = GdipAlloc(sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
-    pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
-    pbmi->bmiHeader.biBitCount = 0;
-
-    if(!bm_is_selected){
-        hdc = CreateCompatibleDC(0);
-        old = SelectObject(hdc, hbm);
-    }
-
-    GetDIBits(hdc, hbm, 0, 0, NULL, pbmi, DIB_RGB_COLORS);
-    pbmi->bmiHeader.biBitCount = PIXELFORMATBPP(lockeddata->PixelFormat);
-    SetDIBits(hdc, hbm, 0, abs(pbmi->bmiHeader.biHeight),
-              bitmap->bitmapbits, pbmi, DIB_RGB_COLORS);
-
-    if(!bm_is_selected){
-        SelectObject(hdc, old);
-        DeleteDC(hdc);
-    }
-
-    GdipFree(pbmi);
+    stat = convert_pixels(bitmap->width, bitmap->height,
+        bitmap->stride, bitmap->bits, bitmap->format,
+        lockeddata->Stride, bitmap->bitmapbits, lockeddata->PixelFormat, NULL);
+
+    if (stat != Ok)
+    {
+        ERR("failed to convert pixels; this should never happen\n");
+    }
+
     GdipFree(bitmap->bitmapbits);
     bitmap->bitmapbits = NULL;
     bitmap->lockmode = 0;
-
-    return Ok;
+    bitmap->numlocks = 0;
+
+    return stat;
 }
 
 GpStatus WINGDIPAPI GdipCloneBitmapArea(REAL x, REAL y, REAL width, REAL height,
@@ -613,7 +1035,7 @@
     Rect area;
     GpStatus stat;
 
-    TRACE("(%f,%f,%f,%f,%i,%p,%p)\n", x, y, width, height, format, srcBitmap, dstBitmap);
+    TRACE("(%f,%f,%f,%f,0x%x,%p,%p)\n", x, y, width, height, format, srcBitmap, dstBitmap);
 
     if (!srcBitmap || !dstBitmap || srcBitmap->image.type != ImageTypeBitmap ||
         x < 0 || y < 0 ||
@@ -671,7 +1093,7 @@
 GpStatus WINGDIPAPI GdipCloneBitmapAreaI(INT x, INT y, INT width, INT height,
     PixelFormat format, GpBitmap* srcBitmap, GpBitmap** dstBitmap)
 {
-    TRACE("(%i,%i,%i,%i,%i,%p,%p)\n", x, y, width, height, format, srcBitmap, dstBitmap);
+    TRACE("(%i,%i,%i,%i,0x%x,%p,%p)\n", x, y, width, height, format, srcBitmap, dstBitmap);
 
     return GdipCloneBitmapArea(x, y, width, height, format, srcBitmap, dstBitmap);
 }
@@ -937,6 +1359,9 @@
 {
     static int calls;
 
+    TRACE("(%p,%p,%p,%u,%s,%p)\n", ref, metafile, succ, emfType,
+        debugstr_w(description), out_metafile);
+
     if(!ref || !metafile || !out_metafile)
         return InvalidParameter;
 
@@ -1172,6 +1597,20 @@
     }
 }
 
+static GpStatus get_screen_resolution(REAL *xres, REAL *yres)
+{
+    HDC screendc = GetDC(0);
+
+    if (!screendc) return GenericError;
+
+    *xres = (REAL)GetDeviceCaps(screendc, LOGPIXELSX);
+    *yres = (REAL)GetDeviceCaps(screendc, LOGPIXELSY);
+
+    ReleaseDC(0, screendc);
+
+    return Ok;
+}
+
 GpStatus WINGDIPAPI GdipCreateBitmapFromScan0(INT width, INT height, INT stride,
     PixelFormat format, BYTE* scan0, GpBitmap** bitmap)
 {
@@ -1181,8 +1620,10 @@
     HDC hdc;
     BYTE *bits;
     int i;
-
-    TRACE("%d %d %d %d %p %p\n", width, height, stride, format, scan0, bitmap);
+    REAL xres, yres;
+    GpStatus stat;
+
+    TRACE("%d %d %d 0x%x %p %p\n", width, height, stride, format, scan0, bitmap);
 
     if (!bitmap) return InvalidParameter;
 
@@ -1193,6 +1634,9 @@
 
     if(scan0 && !stride)
         return InvalidParameter;
+
+    stat = get_screen_resolution(&xres, &yres);
+    if (stat != Ok) return stat;
 
     row_size = (width * PIXELFORMATBPP(format)+7) / 8;
     dib_stride = (row_size + 3) & ~3;
@@ -1243,6 +1687,8 @@
     (*bitmap)->image.palette_count = 0;
     (*bitmap)->image.palette_size = 0;
     (*bitmap)->image.palette_entries = NULL;
+    (*bitmap)->image.xres = xres;
+    (*bitmap)->image.yres = yres;
     (*bitmap)->width = width;
     (*bitmap)->height = height;
     (*bitmap)->format = format;
@@ -1282,6 +1728,8 @@
         }
     }
 
+    TRACE("<-- %p\n", *bitmap);
+
     return Ok;
 }
 
@@ -1398,8 +1846,15 @@
 
 GpStatus WINGDIPAPI GdipFindFirstImageItem(GpImage *image, ImageItemData* item)
 {
+    static int calls;
+
+    TRACE("(%p,%p)\n", image, item);
+
     if(!image || !item)
         return InvalidParameter;
+
+    if (!(calls++))
+        FIXME("not implemented\n");
 
     return NotImplemented;
 }
@@ -1520,15 +1975,14 @@
 
 GpStatus WINGDIPAPI GdipGetImageHorizontalResolution(GpImage *image, REAL *res)
 {
-    static int calls;
-
     if(!image || !res)
         return InvalidParameter;
 
-    if(!(calls++))
-        FIXME("not implemented\n");
-
-    return NotImplemented;
+    *res = image->xres;
+
+    TRACE("(%p) <-- %0.2f\n", image, *res);
+
+    return Ok;
 }
 
 GpStatus WINGDIPAPI GdipGetImagePaletteSize(GpImage *image, INT *size)
@@ -1588,15 +2042,14 @@
 
 GpStatus WINGDIPAPI GdipGetImageVerticalResolution(GpImage *image, REAL *res)
 {
-    static int calls;
-
     if(!image || !res)
         return InvalidParameter;
 
-    if(!(calls++))
-        FIXME("not implemented\n");
-
-    return NotImplemented;
+    *res = image->yres;
+
+    TRACE("(%p) <-- %0.2f\n", image, *res);
+
+    return Ok;
 }
 
 GpStatus WINGDIPAPI GdipGetImageWidth(GpImage *image, UINT *width)
@@ -1700,17 +2153,34 @@
 {
     static int calls;
 
+    TRACE("(%p,%p,%p)\n", image, size, num);
+
     if(!(calls++))
         FIXME("not implemented\n");
 
     return InvalidParameter;
 }
 
+struct image_format_dimension
+{
+    const GUID *format;
+    const GUID *dimension;
+};
+
+struct image_format_dimension image_format_dimensions[] =
+{
+    {&ImageFormatGIF, &FrameDimensionTime},
+    {&ImageFormatIcon, &FrameDimensionResolution},
+    {NULL}
+};
+
 GpStatus WINGDIPAPI GdipImageGetFrameCount(GpImage *image,
     GDIPCONST GUID* dimensionID, UINT* count)
 {
     static int calls;
 
+    TRACE("(%p,%s,%p)\n", image, debugstr_guid(dimensionID), count);
+
     if(!image || !dimensionID || !count)
         return InvalidParameter;
 
@@ -1723,12 +2193,12 @@
 GpStatus WINGDIPAPI GdipImageGetFrameDimensionsCount(GpImage *image,
     UINT* count)
 {
+    /* Native gdiplus 1.1 does not yet support multiple frame dimensions. */
+
     if(!image || !count)
         return InvalidParameter;
 
     *count = 1;
-
-    FIXME("stub\n");
 
     return Ok;
 }
@@ -1736,13 +2206,27 @@
 GpStatus WINGDIPAPI GdipImageGetFrameDimensionsList(GpImage* image,
     GUID* dimensionIDs, UINT count)
 {
-    static int calls;
-
-    if(!image || !dimensionIDs)
-        return InvalidParameter;
-
-    if(!(calls++))
-        FIXME("not implemented\n");
+    int i;
+    const GUID *result=NULL;
+
+    TRACE("(%p,%p,%u)\n", image, dimensionIDs, count);
+
+    if(!image || !dimensionIDs || count != 1)
+        return InvalidParameter;
+
+    for (i=0; image_format_dimensions[i].format; i++)
+    {
+        if (IsEqualGUID(&image->format, image_format_dimensions[i].format))
+        {
+            result = image_format_dimensions[i].dimension;
+            break;
+        }
+    }
+
+    if (!result)
+        result = &FrameDimensionPage;
+
+    memcpy(dimensionIDs, result, sizeof(GUID));
 
     return Ok;
 }
@@ -1976,6 +2460,8 @@
     (*image)->palette_size = 0;
     (*image)->palette_entries = NULL;
 
+    TRACE("<-- %p\n", *image);
+
     return Ok;
 }
 
@@ -2084,6 +2570,8 @@
 {
     static int calls;
 
+    TRACE("(%p,%u)\n", image, propId);
+
     if(!image)
         return InvalidParameter;
 
@@ -2096,6 +2584,8 @@
 GpStatus WINGDIPAPI GdipSetPropertyItem(GpImage *image, GDIPCONST PropertyItem* item)
 {
     static int calls;
+
+    TRACE("(%p,%p)\n", image, item);
 
     if(!(calls++))
         FIXME("not implemented\n");
@@ -2790,6 +3280,8 @@
 {
     static int calls;
 
+    TRACE("(%p,%p,%u)\n", effect, params, size);
+
     if(!(calls++))
         FIXME("not implemented\n");
 

Modified: trunk/reactos/dll/win32/gdiplus/imageattributes.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/gdiplus/imageattributes.c?rev=45831&r1=45830&r2=45831&view=diff
==============================================================================
--- trunk/reactos/dll/win32/gdiplus/imageattributes.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/gdiplus/imageattributes.c [iso-8859-1] Thu Mar  4 14:34:05 2010
@@ -30,25 +30,30 @@
 GpStatus WINGDIPAPI GdipCloneImageAttributes(GDIPCONST GpImageAttributes *imageattr,
     GpImageAttributes **cloneImageattr)
 {
+    GpStatus stat;
+
     TRACE("(%p, %p)\n", imageattr, cloneImageattr);
 
     if(!imageattr || !cloneImageattr)
         return InvalidParameter;
 
-    **cloneImageattr = *imageattr;
-
-    return Ok;
+    stat = GdipCreateImageAttributes(cloneImageattr);
+
+    if (stat == Ok)
+        **cloneImageattr = *imageattr;
+
+    return stat;
 }
 
 GpStatus WINGDIPAPI GdipCreateImageAttributes(GpImageAttributes **imageattr)
 {
-    TRACE("(%p)\n", imageattr);
-
     if(!imageattr)
         return InvalidParameter;
 
     *imageattr = GdipAlloc(sizeof(GpImageAttributes));
     if(!*imageattr)    return OutOfMemory;
+
+    TRACE("<-- %p\n", *imageattr);
 
     return Ok;
 }
@@ -84,15 +89,32 @@
     ColorAdjustType type, BOOL enableFlag, GDIPCONST ColorMatrix* colorMatrix,
     GDIPCONST ColorMatrix* grayMatrix, ColorMatrixFlags flags)
 {
-    static int calls;
-
-    if(!imageattr || !colorMatrix || !grayMatrix)
-        return InvalidParameter;
-
-    if(!(calls++))
-        FIXME("not implemented\n");
-
-    return NotImplemented;
+    TRACE("(%p,%u,%i,%p,%p,%u)\n", imageattr, type, enableFlag, colorMatrix,
+        grayMatrix, flags);
+
+    if(!imageattr || type >= ColorAdjustTypeCount || flags > ColorMatrixFlagsAltGray)
+        return InvalidParameter;
+
+    if (enableFlag)
+    {
+        if (!colorMatrix)
+            return InvalidParameter;
+
+        if (flags == ColorMatrixFlagsAltGray)
+        {
+            if (!grayMatrix)
+                return InvalidParameter;
+
+            imageattr->colormatrices[type].graymatrix = *grayMatrix;
+        }
+
+        imageattr->colormatrices[type].colormatrix = *colorMatrix;
+        imageattr->colormatrices[type].flags = flags;
+    }
+
+    imageattr->colormatrices[type].enabled = enableFlag;
+
+    return Ok;
 }
 
 GpStatus WINGDIPAPI GdipSetImageAttributesWrapMode(GpImageAttributes *imageAttr,
@@ -100,6 +122,8 @@
 {
     static int calls;
 
+    TRACE("(%p,%u,%08x,%i)\n", imageAttr, wrap, argb, clamp);
+
     if(!imageAttr)
         return InvalidParameter;
 
@@ -114,6 +138,8 @@
 {
     static int calls;
 
+    TRACE("(%p,%i)\n", imageAttr, enableFlag);
+
     if(!(calls++))
         FIXME("not implemented\n");
 
@@ -123,12 +149,15 @@
 GpStatus WINGDIPAPI GdipSetImageAttributesGamma(GpImageAttributes *imageAttr,
     ColorAdjustType type, BOOL enableFlag, REAL gamma)
 {
-    static int calls;
-
-    if(!(calls++))
-        FIXME("not implemented\n");
-
-    return NotImplemented;
+    TRACE("(%p,%u,%i,%0.2f)\n", imageAttr, type, enableFlag, gamma);
+
+    if (!imageAttr || (enableFlag && gamma <= 0.0) || type >= ColorAdjustTypeCount)
+        return InvalidParameter;
+
+    imageAttr->gamma_enabled[type] = enableFlag;
+    imageAttr->gamma[type] = gamma;
+
+    return Ok;
 }
 
 GpStatus WINGDIPAPI GdipSetImageAttributesNoOp(GpImageAttributes *imageAttr,
@@ -136,6 +165,8 @@
 {
     static int calls;
 
+    TRACE("(%p,%u,%i)\n", imageAttr, type, enableFlag);
+
     if(!(calls++))
         FIXME("not implemented\n");
 
@@ -146,6 +177,8 @@
     ColorAdjustType type, BOOL enableFlag, ColorChannelFlags channelFlags)
 {
     static int calls;
+
+    TRACE("(%p,%u,%i,%x)\n", imageAttr, type, enableFlag, channelFlags);
 
     if(!(calls++))
         FIXME("not implemented\n");
@@ -159,6 +192,8 @@
 {
     static int calls;
 
+    TRACE("(%p,%u,%i,%s)\n", imageAttr, type, enableFlag, debugstr_w(colorProfileFilename));
+
     if(!(calls++))
         FIXME("not implemented\n");
 
@@ -171,6 +206,8 @@
 {
     static int calls;
 
+    TRACE("(%p,%u,%i,%u,%p)\n", imageAttr, type, enableFlag, mapSize, map);
+
     if(!(calls++))
         FIXME("not implemented\n");
 
@@ -182,6 +219,8 @@
 {
     static int calls;
 
+    TRACE("(%p,%u,%i,%0.2f)\n", imageAttr, type, enableFlag, threshold);
+
     if(!(calls++))
         FIXME("not implemented\n");
 
@@ -193,8 +232,10 @@
 {
     static int calls;
 
-    if(!(calls++))
-        FIXME("not implemented\n");
-
-    return NotImplemented;
-}
+    TRACE("(%p,%u)\n", imageAttr, type);
+
+    if(!(calls++))
+        FIXME("not implemented\n");
+
+    return NotImplemented;
+}

Modified: trunk/reactos/dll/win32/gdiplus/pen.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/gdiplus/pen.c?rev=45831&r1=45830&r2=45831&view=diff
==============================================================================
--- trunk/reactos/dll/win32/gdiplus/pen.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/gdiplus/pen.c [iso-8859-1] Thu Mar  4 14:34:05 2010
@@ -101,6 +101,8 @@
     GdipCloneCustomLineCap(pen->customend, &(*clonepen)->customend);
     GdipCloneBrush(pen->brush, &(*clonepen)->brush);
 
+    TRACE("<-- %p\n", *clonepen);
+
     return Ok;
 }
 
@@ -154,6 +156,8 @@
 
     *pen = gp_pen;
 
+    TRACE("<-- %p\n", *pen);
+
     return Ok;
 }
 
@@ -389,6 +393,8 @@
 {
     static int calls;
 
+    TRACE("(%p)\n", pen);
+
     if(!pen)
         return InvalidParameter;
 
@@ -401,6 +407,8 @@
 GpStatus WINGDIPAPI GdipScalePenTransform(GpPen *pen, REAL sx, REAL sy, GpMatrixOrder order)
 {
     static int calls;
+
+    TRACE("(%p,%0.2f,%0.2f,%u)\n", pen, sx, sy, order);
 
     if(!pen)
         return InvalidParameter;

Modified: trunk/reactos/dll/win32/gdiplus/stringformat.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/gdiplus/stringformat.c?rev=45831&r1=45830&r2=45831&view=diff
==============================================================================
--- trunk/reactos/dll/win32/gdiplus/stringformat.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/gdiplus/stringformat.c [iso-8859-1] Thu Mar  4 14:34:05 2010
@@ -48,11 +48,15 @@
     (*format)->digitlang = LANG_NEUTRAL;
     (*format)->trimming = StringTrimmingCharacter;
     (*format)->digitsub = StringDigitSubstituteUser;
+    (*format)->character_ranges = NULL;
+    (*format)->range_count = 0;
     /* tabstops */
     (*format)->tabcount = 0;
     (*format)->firsttab = 0.0;
     (*format)->tabs = NULL;
 
+    TRACE("<-- %p\n", *format);
+
     return Ok;
 }
 
@@ -61,6 +65,7 @@
     if(!format)
         return InvalidParameter;
 
+    GdipFree(format->character_ranges);
     GdipFree(format->tabs);
     GdipFree(format);
 
@@ -141,14 +146,16 @@
 }
 
 GpStatus WINGDIPAPI GdipGetStringFormatMeasurableCharacterRangeCount(
-        GDIPCONST GpStringFormat* format, INT* count)
+    GDIPCONST GpStringFormat *format, INT *count)
 {
     if (!(format && count))
         return InvalidParameter;
 
-    FIXME("stub: %p %p\n", format, count);
-
-    return NotImplemented;
+    TRACE("%p %p\n", format, count);
+
+    *count = format->range_count;
+
+    return Ok;
 }
 
 GpStatus WINGDIPAPI GdipGetStringFormatTabStopCount(GDIPCONST GpStringFormat *format,
@@ -242,15 +249,26 @@
     return Ok;
 }
 
-GpStatus WINGDIPAPI GdipSetStringFormatMeasurableCharacterRanges(GpStringFormat*
-        format, INT rangeCount, GDIPCONST CharacterRange* ranges)
-{
-    if (!(format && rangeCount && ranges))
-        return InvalidParameter;
-
-    FIXME("stub: %p, %d, %p\n", format, rangeCount, ranges);
-
-    return NotImplemented;
+GpStatus WINGDIPAPI GdipSetStringFormatMeasurableCharacterRanges(
+    GpStringFormat *format, INT rangeCount, GDIPCONST CharacterRange *ranges)
+{
+    CharacterRange *new_ranges;
+
+    if (!(format && ranges))
+        return InvalidParameter;
+
+    TRACE("%p, %d, %p\n", format, rangeCount, ranges);
+
+    new_ranges = GdipAlloc(rangeCount * sizeof(CharacterRange));
+    if (!new_ranges)
+        return OutOfMemory;
+
+    GdipFree(format->character_ranges);
+    format->character_ranges = new_ranges;
+    memcpy(format->character_ranges, ranges, sizeof(CharacterRange) * rangeCount);
+    format->range_count = rangeCount;
+
+    return Ok;
 }
 
 GpStatus WINGDIPAPI GdipSetStringFormatTabStops(GpStringFormat *format, REAL firsttab,
@@ -331,6 +349,19 @@
     else
         (*newFormat)->tabs = NULL;
 
+    if(format->range_count > 0){
+        (*newFormat)->character_ranges = GdipAlloc(sizeof(CharacterRange) * format->range_count);
+        if(!(*newFormat)->character_ranges){
+            GdipFree((*newFormat)->tabs);
+            GdipFree(*newFormat);
+            return OutOfMemory;
+        }
+        memcpy((*newFormat)->character_ranges, format->character_ranges,
+               sizeof(CharacterRange) * format->range_count);
+    }
+    else
+        (*newFormat)->character_ranges = NULL;
+
     TRACE("%p %p\n",format,newFormat);
 
     return Ok;




More information about the Ros-diffs mailing list