gdi: Add support for creating extended pens.
This commit is contained in:
parent
c1c3cc2a07
commit
eb893bdea3
|
@ -398,7 +398,20 @@ static HPEN EMFDRV_CreatePenIndirect(PHYSDEV dev, HPEN hPen )
|
|||
EMRCREATEPEN emr;
|
||||
DWORD index = 0;
|
||||
|
||||
if (!GetObjectA( hPen, sizeof(emr.lopn), &emr.lopn )) return 0;
|
||||
if (!GetObjectW( hPen, sizeof(emr.lopn), &emr.lopn ))
|
||||
{
|
||||
/* must be an extended pen */
|
||||
EXTLOGPEN elp;
|
||||
if (!GetObjectW( hPen, sizeof(elp), &elp ))
|
||||
{
|
||||
FIXME("extended pen %p not supported\n", hPen);
|
||||
return 0;
|
||||
}
|
||||
emr.lopn.lopnStyle = elp.elpPenStyle;
|
||||
emr.lopn.lopnWidth.x = elp.elpWidth;
|
||||
emr.lopn.lopnWidth.y = 0;
|
||||
emr.lopn.lopnColor = elp.elpColor;
|
||||
}
|
||||
|
||||
emr.emr.iType = EMR_CREATEPEN;
|
||||
emr.emr.nSize = sizeof(emr);
|
||||
|
|
|
@ -1033,6 +1033,9 @@ DWORD WINAPI GetObjectType( HGDIOBJ handle )
|
|||
case PEN_MAGIC:
|
||||
result = OBJ_PEN;
|
||||
break;
|
||||
case EXT_PEN_MAGIC:
|
||||
result = OBJ_EXTPEN;
|
||||
break;
|
||||
case BRUSH_MAGIC:
|
||||
result = OBJ_BRUSH;
|
||||
break;
|
||||
|
@ -1288,7 +1291,7 @@ BOOL16 WINAPI IsGDIObject16( HGDIOBJ16 handle16 )
|
|||
GDIOBJHDR *object = GDI_GetObjPtr( handle, MAGIC_DONTCARE );
|
||||
if (object)
|
||||
{
|
||||
magic = GDIMAGIC(object->wMagic) - PEN_MAGIC + 1;
|
||||
magic = GDIMAGIC(object->wMagic) - FIRST_MAGIC + 1;
|
||||
GDI_ReleaseObj( handle );
|
||||
}
|
||||
return magic;
|
||||
|
|
|
@ -404,7 +404,20 @@ HPEN MFDRV_SelectPen( PHYSDEV dev, HPEN hpen )
|
|||
if( index < 0 )
|
||||
{
|
||||
if (!GetObject16( HPEN_16(hpen), sizeof(logpen), &logpen ))
|
||||
return 0;
|
||||
{
|
||||
/* must be an extended pen */
|
||||
EXTLOGPEN elp;
|
||||
if (!GetObjectW( hpen, sizeof(elp), &elp ))
|
||||
{
|
||||
FIXME("extended pen %p not supported\n", hpen);
|
||||
return 0;
|
||||
}
|
||||
logpen.lopnStyle = elp.elpPenStyle;
|
||||
logpen.lopnWidth.x = elp.elpWidth;
|
||||
logpen.lopnWidth.y = 0;
|
||||
logpen.lopnColor = elp.elpColor;
|
||||
}
|
||||
|
||||
index = MFDRV_CreatePenIndirect( dev, hpen, &logpen );
|
||||
if( index < 0 )
|
||||
return 0;
|
||||
|
|
149
dlls/gdi/pen.c
149
dlls/gdi/pen.c
|
@ -23,6 +23,7 @@
|
|||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
|
@ -37,8 +38,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(gdi);
|
|||
/* GDI logical pen object */
|
||||
typedef struct
|
||||
{
|
||||
GDIOBJHDR header;
|
||||
LOGPEN logpen;
|
||||
GDIOBJHDR header;
|
||||
EXTLOGPEN logpen;
|
||||
} PENOBJ;
|
||||
|
||||
|
||||
|
@ -86,20 +87,24 @@ HPEN WINAPI CreatePenIndirect( const LOGPEN * pen )
|
|||
if (!(penPtr = GDI_AllocObject( sizeof(PENOBJ), PEN_MAGIC, (HGDIOBJ *)&hpen,
|
||||
&pen_funcs ))) return 0;
|
||||
if (pen->lopnStyle == PS_USERSTYLE || pen->lopnStyle == PS_ALTERNATE)
|
||||
penPtr->logpen.lopnStyle = PS_SOLID;
|
||||
penPtr->logpen.elpPenStyle = PS_SOLID;
|
||||
else
|
||||
penPtr->logpen.lopnStyle = pen->lopnStyle;
|
||||
penPtr->logpen.lopnWidth.y = 0;
|
||||
penPtr->logpen.elpPenStyle = pen->lopnStyle;
|
||||
if (pen->lopnStyle == PS_NULL)
|
||||
{
|
||||
penPtr->logpen.lopnWidth.x = 1;
|
||||
penPtr->logpen.lopnColor = RGB(0, 0, 0);
|
||||
penPtr->logpen.elpWidth = 1;
|
||||
penPtr->logpen.elpColor = RGB(0, 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
penPtr->logpen.lopnWidth.x = abs(pen->lopnWidth.x);
|
||||
penPtr->logpen.lopnColor = pen->lopnColor;
|
||||
penPtr->logpen.elpWidth = abs(pen->lopnWidth.x);
|
||||
penPtr->logpen.elpColor = pen->lopnColor;
|
||||
}
|
||||
penPtr->logpen.elpBrushStyle = BS_SOLID;
|
||||
penPtr->logpen.elpHatch = 0;
|
||||
penPtr->logpen.elpNumEntries = 0;
|
||||
penPtr->logpen.elpStyleEntry[0] = 0;
|
||||
|
||||
GDI_ReleaseObj( hpen );
|
||||
return hpen;
|
||||
}
|
||||
|
@ -118,23 +123,63 @@ HPEN WINAPI ExtCreatePen( DWORD style, DWORD width,
|
|||
HPEN hpen;
|
||||
|
||||
if ((style & PS_STYLE_MASK) == PS_USERSTYLE)
|
||||
FIXME("PS_USERSTYLE not handled\n");
|
||||
{
|
||||
if (!style_count || !style_bits)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
/* FIXME: PS_USERSTYLE workaround */
|
||||
FIXME("PS_USERSTYLE not handled\n");
|
||||
style = (style & ~PS_STYLE_MASK) | PS_SOLID;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (style_count || style_bits)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ((style & PS_STYLE_MASK) == PS_NULL)
|
||||
return CreatePen( PS_NULL, 0, brush->lbColor );
|
||||
|
||||
if ((style & PS_TYPE_MASK) == PS_GEOMETRIC)
|
||||
{
|
||||
/* PS_ALTERNATE is applicable only for cosmetic pens */
|
||||
if ((style & PS_STYLE_MASK) == PS_ALTERNATE)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (brush->lbHatch && ((brush->lbStyle == BS_SOLID) || (brush->lbStyle == BS_HOLLOW)))
|
||||
FIXME("Hatches not implemented\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
/* PS_INSIDEFRAME is applicable only for gemetric pens */
|
||||
if ((style & PS_STYLE_MASK) == PS_INSIDEFRAME || width != 1)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(penPtr = GDI_AllocObject( sizeof(PENOBJ), PEN_MAGIC, (HGDIOBJ *)&hpen,
|
||||
if (!(penPtr = GDI_AllocObject( sizeof(PENOBJ) +
|
||||
style_count * sizeof(DWORD) - sizeof(penPtr->logpen.elpStyleEntry),
|
||||
EXT_PEN_MAGIC, (HGDIOBJ *)&hpen,
|
||||
&pen_funcs ))) return 0;
|
||||
penPtr->logpen.lopnStyle = style & ~PS_TYPE_MASK;
|
||||
|
||||
/* PS_USERSTYLE workaround */
|
||||
if((penPtr->logpen.lopnStyle & PS_STYLE_MASK) == PS_USERSTYLE)
|
||||
penPtr->logpen.lopnStyle =
|
||||
(penPtr->logpen.lopnStyle & ~PS_STYLE_MASK) | PS_SOLID;
|
||||
|
||||
penPtr->logpen.lopnWidth.x = (style & PS_GEOMETRIC) ? width : 1;
|
||||
penPtr->logpen.lopnWidth.y = 0;
|
||||
penPtr->logpen.lopnColor = brush->lbColor;
|
||||
penPtr->logpen.elpPenStyle = style;
|
||||
penPtr->logpen.elpWidth = abs(width);
|
||||
penPtr->logpen.elpBrushStyle = brush->lbStyle;
|
||||
penPtr->logpen.elpColor = brush->lbColor;
|
||||
penPtr->logpen.elpHatch = brush->lbHatch;
|
||||
penPtr->logpen.elpNumEntries = style_count;
|
||||
memcpy(penPtr->logpen.elpStyleEntry, style_bits, style_count * sizeof(DWORD));
|
||||
|
||||
GDI_ReleaseObj( hpen );
|
||||
|
||||
return hpen;
|
||||
|
@ -165,15 +210,19 @@ static HGDIOBJ PEN_SelectObject( HGDIOBJ handle, void *obj, HDC hdc )
|
|||
static INT PEN_GetObject16( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
|
||||
{
|
||||
PENOBJ *pen = obj;
|
||||
LOGPEN16 logpen;
|
||||
LOGPEN16 *logpen;
|
||||
|
||||
logpen.lopnStyle = pen->logpen.lopnStyle;
|
||||
logpen.lopnColor = pen->logpen.lopnColor;
|
||||
logpen.lopnWidth.x = pen->logpen.lopnWidth.x;
|
||||
logpen.lopnWidth.y = pen->logpen.lopnWidth.y;
|
||||
if (count > sizeof(logpen)) count = sizeof(logpen);
|
||||
memcpy( buffer, &logpen, count );
|
||||
return count;
|
||||
if (!buffer) return sizeof(LOGPEN16);
|
||||
|
||||
if (count < sizeof(LOGPEN16)) return 0;
|
||||
|
||||
logpen = buffer;
|
||||
logpen->lopnStyle = pen->logpen.elpPenStyle;
|
||||
logpen->lopnColor = pen->logpen.elpColor;
|
||||
logpen->lopnWidth.x = pen->logpen.elpWidth;
|
||||
logpen->lopnWidth.y = 0;
|
||||
|
||||
return sizeof(LOGPEN16);
|
||||
}
|
||||
|
||||
|
||||
|
@ -184,21 +233,47 @@ static INT PEN_GetObject( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
|
|||
{
|
||||
PENOBJ *pen = obj;
|
||||
|
||||
if( !buffer )
|
||||
return sizeof(pen->logpen);
|
||||
|
||||
switch (count)
|
||||
switch (GDIMAGIC(pen->header.wMagic))
|
||||
{
|
||||
case sizeof(EXTLOGPEN):
|
||||
FIXME("extended pens not supported\n");
|
||||
return 0;
|
||||
case PEN_MAGIC:
|
||||
{
|
||||
LOGPEN *lp;
|
||||
|
||||
case sizeof(LOGPEN):
|
||||
memcpy( buffer, &pen->logpen, sizeof(LOGPEN) );
|
||||
if (!buffer) return sizeof(LOGPEN);
|
||||
|
||||
if (count < sizeof(LOGPEN)) return 0;
|
||||
|
||||
if ((pen->logpen.elpPenStyle & PS_STYLE_MASK) == PS_NULL &&
|
||||
count == sizeof(EXTLOGPEN))
|
||||
{
|
||||
EXTLOGPEN *elp = buffer;
|
||||
memcpy(elp, &pen->logpen, sizeof(EXTLOGPEN));
|
||||
elp->elpWidth = 0;
|
||||
return sizeof(EXTLOGPEN);
|
||||
}
|
||||
|
||||
lp = buffer;
|
||||
lp->lopnStyle = pen->logpen.elpPenStyle;
|
||||
lp->lopnColor = pen->logpen.elpColor;
|
||||
lp->lopnWidth.x = pen->logpen.elpWidth;
|
||||
lp->lopnWidth.y = 0;
|
||||
return sizeof(LOGPEN);
|
||||
}
|
||||
|
||||
case EXT_PEN_MAGIC:
|
||||
{
|
||||
INT size = sizeof(EXTLOGPEN) + pen->logpen.elpNumEntries * sizeof(DWORD) - sizeof(pen->logpen.elpStyleEntry);
|
||||
|
||||
if (!buffer) return size;
|
||||
|
||||
if (count < size) return 0;
|
||||
memcpy(buffer, &pen->logpen, size);
|
||||
return size;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -523,7 +523,7 @@ static void test_logpen(void)
|
|||
LOGPEN lp;
|
||||
EXTLOGPEN elp;
|
||||
LOGBRUSH lb;
|
||||
DWORD user_style[2] = { 1, 2 };
|
||||
DWORD obj_type, user_style[2] = { 0xabc, 0xdef };
|
||||
struct
|
||||
{
|
||||
EXTLOGPEN elp;
|
||||
|
@ -535,10 +535,38 @@ static void test_logpen(void)
|
|||
trace("testing style %u\n", pen[i].style);
|
||||
|
||||
/********************** cosmetic pens **********************/
|
||||
/* CreatePenIndirect behaviour */
|
||||
lp.lopnStyle = pen[i].style,
|
||||
lp.lopnWidth.x = pen[i].width;
|
||||
lp.lopnWidth.y = 11; /* just in case */
|
||||
lp.lopnColor = pen[i].color;
|
||||
SetLastError(0xdeadbeef);
|
||||
hpen = CreatePenIndirect(&lp);
|
||||
ok(hpen != 0, "CreatePen error %ld\n", GetLastError());
|
||||
|
||||
obj_type = GetObjectType(hpen);
|
||||
ok(obj_type == OBJ_PEN, "wrong object type %lu\n", obj_type);
|
||||
|
||||
memset(&lp, 0xb0, sizeof(lp));
|
||||
SetLastError(0xdeadbeef);
|
||||
size = GetObject(hpen, sizeof(lp), &lp);
|
||||
ok(size == sizeof(lp), "GetObject returned %d, error %ld\n", size, GetLastError());
|
||||
|
||||
ok(lp.lopnStyle == pen[i].ret_style, "expected %u, got %u\n", pen[i].ret_style, lp.lopnStyle);
|
||||
ok(lp.lopnWidth.x == pen[i].ret_width, "expected %u, got %ld\n", pen[i].ret_width, lp.lopnWidth.x);
|
||||
ok(lp.lopnWidth.y == 0, "expected 0, got %ld\n", lp.lopnWidth.y);
|
||||
ok(lp.lopnColor == pen[i].ret_color, "expected %08lx, got %08lx\n", pen[i].ret_color, lp.lopnColor);
|
||||
|
||||
DeleteObject(hpen);
|
||||
|
||||
/* CreatePen behaviour */
|
||||
SetLastError(0xdeadbeef);
|
||||
hpen = CreatePen(pen[i].style, pen[i].width, pen[i].color);
|
||||
ok(hpen != 0, "CreatePen error %ld\n", GetLastError());
|
||||
|
||||
obj_type = GetObjectType(hpen);
|
||||
ok(obj_type == OBJ_PEN, "wrong object type %lu\n", obj_type);
|
||||
|
||||
/* check what's the real size of the object */
|
||||
size = GetObject(hpen, 0, NULL);
|
||||
ok(size == sizeof(lp), "GetObject returned %d, error %ld\n", size, GetLastError());
|
||||
|
@ -549,6 +577,18 @@ static void test_logpen(void)
|
|||
size = GetObject(hpen, sizeof(lp.lopnStyle), &lp);
|
||||
ok(!size, "GetObject should fail: size %d, error %ld\n", size, GetLastError());
|
||||
|
||||
/* see how larger buffer sizes are handled */
|
||||
memset(&lp, 0xb0, sizeof(lp));
|
||||
SetLastError(0xdeadbeef);
|
||||
size = GetObject(hpen, sizeof(lp) * 2, &lp);
|
||||
ok(size == sizeof(lp), "GetObject returned %d, error %ld\n", size, GetLastError());
|
||||
|
||||
/* see how larger buffer sizes are handled */
|
||||
memset(&elp, 0xb0, sizeof(elp));
|
||||
SetLastError(0xdeadbeef);
|
||||
size = GetObject(hpen, sizeof(elp) * 2, &elp);
|
||||
ok(size == sizeof(lp), "GetObject returned %d, error %ld\n", size, GetLastError());
|
||||
|
||||
memset(&lp, 0xb0, sizeof(lp));
|
||||
SetLastError(0xdeadbeef);
|
||||
size = GetObject(hpen, sizeof(lp), &lp);
|
||||
|
@ -562,39 +602,159 @@ static void test_logpen(void)
|
|||
memset(&elp, 0xb0, sizeof(elp));
|
||||
SetLastError(0xdeadbeef);
|
||||
size = GetObject(hpen, sizeof(elp), &elp);
|
||||
/* todo_wine: Wine doesn't support extended pens at all, skip all other tests */
|
||||
if (!size) continue;
|
||||
|
||||
/* for some reason XP differentiates PS_NULL here */
|
||||
if (pen[i].style == PS_NULL)
|
||||
ok(size == sizeof(EXTLOGPEN), "GetObject returned %d, error %ld\n", size, GetLastError());
|
||||
else
|
||||
ok(size == sizeof(LOGPEN), "GetObject returned %d, error %ld\n", size, GetLastError());
|
||||
|
||||
ok(elp.elpPenStyle == pen[i].ret_style, "expected %u, got %lu\n", pen[i].ret_style, elp.elpPenStyle);
|
||||
if (pen[i].style == PS_NULL)
|
||||
ok(elp.elpWidth == 0, "expected %u, got %lu\n", pen[i].ret_width, elp.elpWidth);
|
||||
else
|
||||
ok(elp.elpWidth == pen[i].ret_width, "expected %u, got %lu\n", pen[i].ret_width, elp.elpWidth);
|
||||
ok(elp.elpColor == pen[i].ret_color, "expected %08lx, got %08lx\n", pen[i].ret_color, elp.elpColor);
|
||||
ok(elp.elpBrushStyle == BS_SOLID, "expected BS_SOLID, got %u\n", elp.elpBrushStyle);
|
||||
|
||||
/* for some reason XP differenciates PS_NULL here */
|
||||
if (pen[i].style == PS_NULL)
|
||||
{
|
||||
ok(size == sizeof(EXTLOGPEN), "GetObject returned %d, error %ld\n", size, GetLastError());
|
||||
ok(elp.elpPenStyle == pen[i].ret_style, "expected %u, got %lu\n", pen[i].ret_style, elp.elpPenStyle);
|
||||
ok(elp.elpWidth == 0, "expected 0, got %lu\n", elp.elpWidth);
|
||||
ok(elp.elpColor == pen[i].ret_color, "expected %08lx, got %08lx\n", pen[i].ret_color, elp.elpColor);
|
||||
ok(elp.elpBrushStyle == BS_SOLID, "expected BS_SOLID, got %u\n", elp.elpBrushStyle);
|
||||
ok(elp.elpHatch == 0, "expected 0, got %p\n", (void *)elp.elpHatch);
|
||||
ok(elp.elpNumEntries == 0, "expected 0, got %lx\n", elp.elpNumEntries);
|
||||
}
|
||||
else
|
||||
{
|
||||
ok(elp.elpHatch == 0xb0b0b0b0, "expected 0xb0b0b0b0, got %p\n", (void *)elp.elpHatch);
|
||||
ok(elp.elpNumEntries == 0xb0b0b0b0, "expected 0xb0b0b0b0, got %lx\n", elp.elpNumEntries);
|
||||
ok(size == sizeof(LOGPEN), "GetObject returned %d, error %ld\n", size, GetLastError());
|
||||
memcpy(&lp, &elp, sizeof(lp));
|
||||
ok(lp.lopnStyle == pen[i].ret_style, "expected %u, got %u\n", pen[i].ret_style, lp.lopnStyle);
|
||||
ok(lp.lopnWidth.x == pen[i].ret_width, "expected %u, got %ld\n", pen[i].ret_width, lp.lopnWidth.x);
|
||||
ok(lp.lopnWidth.y == 0, "expected 0, got %ld\n", lp.lopnWidth.y);
|
||||
ok(lp.lopnColor == pen[i].ret_color, "expected %08lx, got %08lx\n", pen[i].ret_color, lp.lopnColor);
|
||||
}
|
||||
#if 0 /* XP returns garbage here */
|
||||
ok(elp.elpStyleEntry[0] == 0xb0b0b0b0, "expected 0xb0b0b0b0, got %lx\n", elp.elpStyleEntry[0]);
|
||||
#endif
|
||||
|
||||
DeleteObject(hpen);
|
||||
|
||||
/********** cosmetic pens created by ExtCreatePen ***********/
|
||||
lb.lbStyle = BS_SOLID;
|
||||
lb.lbColor = pen[i].color;
|
||||
lb.lbHatch = HS_CROSS; /* just in case */
|
||||
SetLastError(0xdeadbeef);
|
||||
hpen = ExtCreatePen(pen[i].style, pen[i].width, &lb, 2, user_style);
|
||||
if (pen[i].style != PS_USERSTYLE)
|
||||
{
|
||||
ok(hpen == 0, "ExtCreatePen should fail\n");
|
||||
ok(GetLastError() == ERROR_INVALID_PARAMETER,
|
||||
"wrong last error value %ld\n", GetLastError());
|
||||
SetLastError(0xdeadbeef);
|
||||
hpen = ExtCreatePen(pen[i].style, pen[i].width, &lb, 0, NULL);
|
||||
if (pen[i].style != PS_NULL)
|
||||
{
|
||||
ok(hpen == 0, "ExtCreatePen with width != 1 should fail\n");
|
||||
ok(GetLastError() == ERROR_INVALID_PARAMETER,
|
||||
"wrong last error value %ld\n", GetLastError());
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
hpen = ExtCreatePen(pen[i].style, 1, &lb, 0, NULL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ok(hpen == 0, "ExtCreatePen with width != 1 should fail\n");
|
||||
ok(GetLastError() == ERROR_INVALID_PARAMETER,
|
||||
"wrong last error value %ld\n", GetLastError());
|
||||
SetLastError(0xdeadbeef);
|
||||
hpen = ExtCreatePen(pen[i].style, 1, &lb, 2, user_style);
|
||||
}
|
||||
if (pen[i].style == PS_INSIDEFRAME)
|
||||
{
|
||||
/* This style is applicable only for gemetric pens */
|
||||
ok(hpen == 0, "ExtCreatePen should fail\n");
|
||||
goto test_geometric_pens;
|
||||
}
|
||||
ok(hpen != 0, "ExtCreatePen error %ld\n", GetLastError());
|
||||
|
||||
obj_type = GetObjectType(hpen);
|
||||
/* for some reason XP differentiates PS_NULL here */
|
||||
if (pen[i].style == PS_NULL)
|
||||
ok(obj_type == OBJ_PEN, "wrong object type %lu\n", obj_type);
|
||||
else
|
||||
ok(obj_type == OBJ_EXTPEN, "wrong object type %lu\n", obj_type);
|
||||
|
||||
/* check what's the real size of the object */
|
||||
SetLastError(0xdeadbeef);
|
||||
size = GetObject(hpen, 0, NULL);
|
||||
switch (pen[i].style)
|
||||
{
|
||||
case PS_NULL:
|
||||
ok(size == sizeof(LOGPEN),
|
||||
"GetObject returned %d, error %ld\n", size, GetLastError());
|
||||
break;
|
||||
|
||||
case PS_USERSTYLE:
|
||||
ok(size == sizeof(EXTLOGPEN) - sizeof(elp.elpStyleEntry) + sizeof(user_style),
|
||||
"GetObject returned %d, error %ld\n", size, GetLastError());
|
||||
break;
|
||||
|
||||
default:
|
||||
ok(size == sizeof(EXTLOGPEN) - sizeof(elp.elpStyleEntry),
|
||||
"GetObject returned %d, error %ld\n", size, GetLastError());
|
||||
break;
|
||||
}
|
||||
|
||||
/* ask for truncated data */
|
||||
memset(&elp, 0xb0, sizeof(elp));
|
||||
SetLastError(0xdeadbeef);
|
||||
size = GetObject(hpen, sizeof(elp.elpPenStyle), &elp);
|
||||
ok(!size, "GetObject should fail: size %d, error %ld\n", size, GetLastError());
|
||||
|
||||
/* see how larger buffer sizes are handled */
|
||||
memset(&ext_pen, 0xb0, sizeof(ext_pen));
|
||||
SetLastError(0xdeadbeef);
|
||||
size = GetObject(hpen, sizeof(ext_pen), &ext_pen.elp);
|
||||
switch (pen[i].style)
|
||||
{
|
||||
case PS_NULL:
|
||||
ok(size == sizeof(LOGPEN),
|
||||
"GetObject returned %d, error %ld\n", size, GetLastError());
|
||||
memcpy(&lp, &ext_pen.elp, sizeof(lp));
|
||||
ok(lp.lopnStyle == pen[i].ret_style, "expected %u, got %u\n", pen[i].ret_style, lp.lopnStyle);
|
||||
ok(lp.lopnWidth.x == pen[i].ret_width, "expected %u, got %ld\n", pen[i].ret_width, lp.lopnWidth.x);
|
||||
ok(lp.lopnWidth.y == 0, "expected 0, got %ld\n", lp.lopnWidth.y);
|
||||
ok(lp.lopnColor == pen[i].ret_color, "expected %08lx, got %08lx\n", pen[i].ret_color, lp.lopnColor);
|
||||
|
||||
/* for PS_NULL it also works this way */
|
||||
memset(&elp, 0xb0, sizeof(elp));
|
||||
SetLastError(0xdeadbeef);
|
||||
size = GetObject(hpen, sizeof(elp), &elp);
|
||||
ok(size == sizeof(EXTLOGPEN),
|
||||
"GetObject returned %d, error %ld\n", size, GetLastError());
|
||||
ok(ext_pen.elp.elpHatch == 0xb0b0b0b0, "expected 0xb0b0b0b0, got %p\n", (void *)ext_pen.elp.elpHatch);
|
||||
ok(ext_pen.elp.elpNumEntries == 0xb0b0b0b0, "expected 0xb0b0b0b0, got %lx\n", ext_pen.elp.elpNumEntries);
|
||||
break;
|
||||
|
||||
case PS_USERSTYLE:
|
||||
ok(size == sizeof(EXTLOGPEN) - sizeof(elp.elpStyleEntry) + sizeof(user_style),
|
||||
"GetObject returned %d, error %ld\n", size, GetLastError());
|
||||
ok(ext_pen.elp.elpHatch == HS_CROSS, "expected HS_CROSS, got %p\n", (void *)ext_pen.elp.elpHatch);
|
||||
ok(ext_pen.elp.elpNumEntries == 2, "expected 0, got %lx\n", ext_pen.elp.elpNumEntries);
|
||||
ok(ext_pen.elp.elpStyleEntry[0] == 0xabc, "expected 0xabc, got %lx\n", ext_pen.elp.elpStyleEntry[0]);
|
||||
ok(ext_pen.elp.elpStyleEntry[1] == 0xdef, "expected 0xabc, got %lx\n", ext_pen.elp.elpStyleEntry[1]);
|
||||
break;
|
||||
|
||||
default:
|
||||
ok(size == sizeof(EXTLOGPEN) - sizeof(elp.elpStyleEntry),
|
||||
"GetObject returned %d, error %ld\n", size, GetLastError());
|
||||
ok(ext_pen.elp.elpHatch == HS_CROSS, "expected HS_CROSS, got %p\n", (void *)ext_pen.elp.elpHatch);
|
||||
ok(ext_pen.elp.elpNumEntries == 0, "expected 0, got %lx\n", ext_pen.elp.elpNumEntries);
|
||||
break;
|
||||
}
|
||||
|
||||
if (pen[i].style == PS_USERSTYLE)
|
||||
{
|
||||
todo_wine
|
||||
ok(ext_pen.elp.elpPenStyle == pen[i].style, "expected %x, got %lx\n", pen[i].style, ext_pen.elp.elpPenStyle);
|
||||
}
|
||||
else
|
||||
ok(ext_pen.elp.elpPenStyle == pen[i].style, "expected %x, got %lx\n", pen[i].style, ext_pen.elp.elpPenStyle);
|
||||
ok(ext_pen.elp.elpWidth == 1, "expected 1, got %lx\n", ext_pen.elp.elpWidth);
|
||||
ok(ext_pen.elp.elpColor == pen[i].ret_color, "expected %08lx, got %08lx\n", pen[i].ret_color, ext_pen.elp.elpColor);
|
||||
ok(ext_pen.elp.elpBrushStyle == BS_SOLID, "expected BS_SOLID, got %x\n", ext_pen.elp.elpBrushStyle);
|
||||
|
||||
DeleteObject(hpen);
|
||||
|
||||
test_geometric_pens:
|
||||
/********************** geometric pens **********************/
|
||||
lb.lbStyle = BS_SOLID;
|
||||
lb.lbColor = pen[i].color;
|
||||
|
@ -604,10 +764,23 @@ if (!size) continue;
|
|||
if (pen[i].style != PS_USERSTYLE)
|
||||
{
|
||||
ok(hpen == 0, "ExtCreatePen should fail\n");
|
||||
SetLastError(0xdeadbeef);
|
||||
hpen = ExtCreatePen(PS_GEOMETRIC | pen[i].style, pen[i].width, &lb, 0, NULL);
|
||||
}
|
||||
if (pen[i].style == PS_ALTERNATE)
|
||||
{
|
||||
/* This style is applicable only for cosmetic pens */
|
||||
ok(hpen == 0, "ExtCreatePen should fail\n");
|
||||
continue;
|
||||
}
|
||||
ok(hpen != 0, "ExtCreatePen error %ld\n", GetLastError());
|
||||
|
||||
obj_type = GetObjectType(hpen);
|
||||
/* for some reason XP differentiates PS_NULL here */
|
||||
if (pen[i].style == PS_NULL)
|
||||
ok(obj_type == OBJ_PEN, "wrong object type %lu\n", obj_type);
|
||||
else
|
||||
ok(hpen != 0, "ExtCreatePen error %ld\n", GetLastError());
|
||||
ok(obj_type == OBJ_EXTPEN, "wrong object type %lu\n", obj_type);
|
||||
|
||||
/* check what's the real size of the object */
|
||||
size = GetObject(hpen, 0, NULL);
|
||||
|
@ -618,11 +791,6 @@ if (!size) continue;
|
|||
"GetObject returned %d, error %ld\n", size, GetLastError());
|
||||
break;
|
||||
|
||||
case PS_ALTERNATE:
|
||||
ok(size == 0 /*&& GetLastError() == ERROR_INVALID_PARAMETER*/,
|
||||
"GetObject should fail: size %d, error %ld\n", size, GetLastError());
|
||||
break;
|
||||
|
||||
case PS_USERSTYLE:
|
||||
ok(size == sizeof(EXTLOGPEN) - sizeof(elp.elpStyleEntry) + sizeof(user_style),
|
||||
"GetObject returned %d, error %ld\n", size, GetLastError());
|
||||
|
@ -654,12 +822,13 @@ if (!size) continue;
|
|||
}
|
||||
else
|
||||
/* XP doesn't set last error here */
|
||||
ok(size == 0 /*&& GetLastError() == ERROR_INVALID_PARAMETER*/,
|
||||
ok(!size /*&& GetLastError() == ERROR_INVALID_PARAMETER*/,
|
||||
"GetObject should fail: size %d, error %ld\n", size, GetLastError());
|
||||
|
||||
memset(&elp, 0xb0, sizeof(elp));
|
||||
memset(&ext_pen, 0xb0, sizeof(ext_pen));
|
||||
SetLastError(0xdeadbeef);
|
||||
size = GetObject(hpen, sizeof(elp), &ext_pen);
|
||||
/* buffer is too small for user styles */
|
||||
size = GetObject(hpen, sizeof(elp), &ext_pen.elp);
|
||||
switch (pen[i].style)
|
||||
{
|
||||
case PS_NULL:
|
||||
|
@ -667,23 +836,28 @@ if (!size) continue;
|
|||
"GetObject returned %d, error %ld\n", size, GetLastError());
|
||||
ok(ext_pen.elp.elpHatch == 0, "expected 0, got %p\n", (void *)ext_pen.elp.elpHatch);
|
||||
ok(ext_pen.elp.elpNumEntries == 0, "expected 0, got %lx\n", ext_pen.elp.elpNumEntries);
|
||||
break;
|
||||
|
||||
case PS_ALTERNATE:
|
||||
ok(size == 0 /*&& GetLastError() == ERROR_INVALID_PARAMETER*/,
|
||||
"GetObject should fail: size %d, error %ld\n", size, GetLastError());
|
||||
size = GetObject(hpen, sizeof(ext_pen), &ext_pen);
|
||||
/* for PS_ALTERNATE it still fails under XP SP2 */
|
||||
ok(size == 0,
|
||||
"GetObject should fail: size %d, error %ld\n", size, GetLastError());
|
||||
/* for PS_NULL it also works this way */
|
||||
SetLastError(0xdeadbeef);
|
||||
size = GetObject(hpen, sizeof(ext_pen), &lp);
|
||||
ok(size == sizeof(LOGPEN),
|
||||
"GetObject returned %d, error %ld\n", size, GetLastError());
|
||||
ok(lp.lopnStyle == pen[i].ret_style, "expected %u, got %u\n", pen[i].ret_style, lp.lopnStyle);
|
||||
ok(lp.lopnWidth.x == pen[i].ret_width, "expected %u, got %ld\n", pen[i].ret_width, lp.lopnWidth.x);
|
||||
ok(lp.lopnWidth.y == 0, "expected 0, got %ld\n", lp.lopnWidth.y);
|
||||
ok(lp.lopnColor == pen[i].ret_color, "expected %08lx, got %08lx\n", pen[i].ret_color, lp.lopnColor);
|
||||
break;
|
||||
|
||||
case PS_USERSTYLE:
|
||||
ok(size == 0 /*&& GetLastError() == ERROR_INVALID_PARAMETER*/,
|
||||
ok(!size /*&& GetLastError() == ERROR_INVALID_PARAMETER*/,
|
||||
"GetObject should fail: size %d, error %ld\n", size, GetLastError());
|
||||
size = GetObject(hpen, sizeof(ext_pen), &ext_pen);
|
||||
size = GetObject(hpen, sizeof(ext_pen), &ext_pen.elp);
|
||||
ok(size == sizeof(EXTLOGPEN) - sizeof(elp.elpStyleEntry) + sizeof(user_style),
|
||||
"GetObject returned %d, error %ld\n", size, GetLastError());
|
||||
ok(ext_pen.elp.elpHatch == HS_CROSS, "expected HS_CROSS, got %p\n", (void *)ext_pen.elp.elpHatch);
|
||||
ok(ext_pen.elp.elpNumEntries == 2, "expected 0, got %lx\n", ext_pen.elp.elpNumEntries);
|
||||
ok(ext_pen.elp.elpStyleEntry[0] == 0xabc, "expected 0xabc, got %lx\n", ext_pen.elp.elpStyleEntry[0]);
|
||||
ok(ext_pen.elp.elpStyleEntry[1] == 0xdef, "expected 0xabc, got %lx\n", ext_pen.elp.elpStyleEntry[1]);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -694,24 +868,27 @@ if (!size) continue;
|
|||
break;
|
||||
}
|
||||
|
||||
if (size != 0)
|
||||
/* for some reason XP differenciates PS_NULL here */
|
||||
if (pen[i].style == PS_NULL)
|
||||
ok(ext_pen.elp.elpPenStyle == pen[i].ret_style, "expected %x, got %lx\n", pen[i].ret_style, ext_pen.elp.elpPenStyle);
|
||||
else
|
||||
{
|
||||
/* for some reason XP differenciates PS_NULL here */
|
||||
if (pen[i].style == PS_NULL)
|
||||
ok(ext_pen.elp.elpPenStyle == pen[i].ret_style, "expected %x, got %lx\n", pen[i].ret_style, ext_pen.elp.elpPenStyle);
|
||||
else if (pen[i].style == PS_USERSTYLE) /* this time it's really PS_USERSTYLE */
|
||||
ok(ext_pen.elp.elpPenStyle == (PS_GEOMETRIC | PS_USERSTYLE), "expected %x, got %lx\n", PS_GEOMETRIC | PS_USERSTYLE, ext_pen.elp.elpPenStyle);
|
||||
else
|
||||
ok(ext_pen.elp.elpPenStyle == (PS_GEOMETRIC | pen[i].ret_style), "expected %x, got %lx\n", PS_GEOMETRIC | pen[i].ret_style, ext_pen.elp.elpPenStyle);
|
||||
|
||||
if (pen[i].style == PS_NULL)
|
||||
ok(ext_pen.elp.elpWidth == 0, "expected %u, got %lx\n", pen[i].ret_width, ext_pen.elp.elpWidth);
|
||||
else
|
||||
ok(ext_pen.elp.elpWidth == pen[i].ret_width, "expected %u, got %lx\n", pen[i].ret_width, ext_pen.elp.elpWidth);
|
||||
ok(ext_pen.elp.elpColor == pen[i].ret_color, "expected %08lx, got %08lx\n", pen[i].ret_color, ext_pen.elp.elpColor);
|
||||
ok(ext_pen.elp.elpBrushStyle == BS_SOLID, "expected BS_SOLID, got %x\n", ext_pen.elp.elpBrushStyle);
|
||||
if (pen[i].style == PS_USERSTYLE)
|
||||
{
|
||||
todo_wine
|
||||
ok(ext_pen.elp.elpPenStyle == (PS_GEOMETRIC | pen[i].style), "expected %x, got %lx\n", PS_GEOMETRIC | pen[i].style, ext_pen.elp.elpPenStyle);
|
||||
}
|
||||
else
|
||||
ok(ext_pen.elp.elpPenStyle == (PS_GEOMETRIC | pen[i].style), "expected %x, got %lx\n", PS_GEOMETRIC | pen[i].style, ext_pen.elp.elpPenStyle);
|
||||
}
|
||||
|
||||
if (pen[i].style == PS_NULL)
|
||||
ok(ext_pen.elp.elpWidth == 0, "expected 0, got %lx\n", ext_pen.elp.elpWidth);
|
||||
else
|
||||
ok(ext_pen.elp.elpWidth == pen[i].ret_width, "expected %u, got %lx\n", pen[i].ret_width, ext_pen.elp.elpWidth);
|
||||
ok(ext_pen.elp.elpColor == pen[i].ret_color, "expected %08lx, got %08lx\n", pen[i].ret_color, ext_pen.elp.elpColor);
|
||||
ok(ext_pen.elp.elpBrushStyle == BS_SOLID, "expected BS_SOLID, got %x\n", ext_pen.elp.elpBrushStyle);
|
||||
|
||||
DeleteObject(hpen);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,7 +41,20 @@ HPEN PSDRV_SelectPen( PSDRV_PDEVICE *physDev, HPEN hpen )
|
|||
{
|
||||
LOGPEN logpen;
|
||||
|
||||
if (!GetObjectA( hpen, sizeof(logpen), &logpen )) return 0;
|
||||
if (!GetObjectW( hpen, sizeof(logpen), &logpen ))
|
||||
{
|
||||
/* must be an extended pen */
|
||||
EXTLOGPEN elp;
|
||||
if (!GetObjectW( hpen, sizeof(elp), &elp ))
|
||||
{
|
||||
FIXME("extended pen %p not supported\n", hpen);
|
||||
return 0;
|
||||
}
|
||||
logpen.lopnStyle = elp.elpPenStyle;
|
||||
logpen.lopnWidth.x = elp.elpWidth;
|
||||
logpen.lopnWidth.y = 0;
|
||||
logpen.lopnColor = elp.elpColor;
|
||||
}
|
||||
|
||||
TRACE("hpen = %p colour = %08lx\n", hpen, logpen.lopnColor);
|
||||
|
||||
|
|
|
@ -38,7 +38,20 @@ HPEN X11DRV_SelectPen( X11DRV_PDEVICE *physDev, HPEN hpen )
|
|||
{
|
||||
LOGPEN logpen;
|
||||
|
||||
if (!GetObjectA( hpen, sizeof(logpen), &logpen )) return 0;
|
||||
if (!GetObjectW( hpen, sizeof(logpen), &logpen ))
|
||||
{
|
||||
/* must be an extended pen */
|
||||
EXTLOGPEN elp;
|
||||
if (!GetObjectW( hpen, sizeof(elp), &elp ))
|
||||
{
|
||||
FIXME("extended pen %p not supported\n", hpen);
|
||||
return 0;
|
||||
}
|
||||
logpen.lopnStyle = elp.elpPenStyle;
|
||||
logpen.lopnWidth.x = elp.elpWidth;
|
||||
logpen.lopnWidth.y = 0;
|
||||
logpen.lopnColor = elp.elpColor;
|
||||
}
|
||||
|
||||
physDev->pen.style = logpen.lopnStyle & PS_STYLE_MASK;
|
||||
physDev->pen.type = logpen.lopnStyle & PS_TYPE_MASK;
|
||||
|
|
|
@ -44,7 +44,8 @@
|
|||
#define ENHMETAFILE_MAGIC 0x4f52
|
||||
#define ENHMETAFILE_DC_MAGIC 0x4f53
|
||||
#define MEMORY_DC_MAGIC 0x4f54
|
||||
#define LAST_MAGIC 0x4f54
|
||||
#define EXT_PEN_MAGIC 0x4f55
|
||||
#define LAST_MAGIC 0x4f55
|
||||
|
||||
#define MAGIC_DONTCARE 0xffff
|
||||
|
||||
|
|
Loading…
Reference in New Issue