gdi32: Store the pattern brush information for geometric pens.
This commit is contained in:
parent
ee89ce2982
commit
a1fdd5856f
|
@ -36,8 +36,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(gdi);
|
||||||
/* GDI logical pen object */
|
/* GDI logical pen object */
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
GDIOBJHDR header;
|
GDIOBJHDR header;
|
||||||
EXTLOGPEN logpen;
|
struct brush_pattern pattern;
|
||||||
|
EXTLOGPEN logpen;
|
||||||
} PENOBJ;
|
} PENOBJ;
|
||||||
|
|
||||||
|
|
||||||
|
@ -87,15 +88,12 @@ HPEN WINAPI CreatePenIndirect( const LOGPEN * pen )
|
||||||
if (hpen) return hpen;
|
if (hpen) return hpen;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(penPtr = HeapAlloc( GetProcessHeap(), 0, sizeof(*penPtr) ))) return 0;
|
if (!(penPtr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*penPtr) ))) return 0;
|
||||||
|
|
||||||
penPtr->logpen.elpPenStyle = pen->lopnStyle;
|
penPtr->logpen.elpPenStyle = pen->lopnStyle;
|
||||||
penPtr->logpen.elpWidth = abs(pen->lopnWidth.x);
|
penPtr->logpen.elpWidth = abs(pen->lopnWidth.x);
|
||||||
penPtr->logpen.elpColor = pen->lopnColor;
|
penPtr->logpen.elpColor = pen->lopnColor;
|
||||||
penPtr->logpen.elpBrushStyle = BS_SOLID;
|
penPtr->logpen.elpBrushStyle = BS_SOLID;
|
||||||
penPtr->logpen.elpHatch = 0;
|
|
||||||
penPtr->logpen.elpNumEntries = 0;
|
|
||||||
penPtr->logpen.elpStyleEntry[0] = 0;
|
|
||||||
|
|
||||||
switch (pen->lopnStyle)
|
switch (pen->lopnStyle)
|
||||||
{
|
{
|
||||||
|
@ -128,14 +126,12 @@ HPEN WINAPI ExtCreatePen( DWORD style, DWORD width,
|
||||||
const LOGBRUSH * brush, DWORD style_count,
|
const LOGBRUSH * brush, DWORD style_count,
|
||||||
const DWORD *style_bits )
|
const DWORD *style_bits )
|
||||||
{
|
{
|
||||||
PENOBJ * penPtr;
|
PENOBJ *penPtr = NULL;
|
||||||
HPEN hpen;
|
HPEN hpen;
|
||||||
|
LOGBRUSH logbrush;
|
||||||
|
|
||||||
if ((style_count || style_bits) && (style & PS_STYLE_MASK) != PS_USERSTYLE)
|
if ((style_count || style_bits) && (style & PS_STYLE_MASK) != PS_USERSTYLE)
|
||||||
{
|
goto invalid;
|
||||||
SetLastError(ERROR_INVALID_PARAMETER);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (style & PS_STYLE_MASK)
|
switch (style & PS_STYLE_MASK)
|
||||||
{
|
{
|
||||||
|
@ -152,11 +148,7 @@ HPEN WINAPI ExtCreatePen( DWORD style, DWORD width,
|
||||||
case PS_USERSTYLE:
|
case PS_USERSTYLE:
|
||||||
if (((INT)style_count) <= 0) return 0;
|
if (((INT)style_count) <= 0) return 0;
|
||||||
|
|
||||||
if ((style_count > 16) || !style_bits)
|
if ((style_count > 16) || !style_bits) goto invalid;
|
||||||
{
|
|
||||||
SetLastError(ERROR_INVALID_PARAMETER);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((style & PS_TYPE_MASK) == PS_GEOMETRIC)
|
if ((style & PS_TYPE_MASK) == PS_GEOMETRIC)
|
||||||
{
|
{
|
||||||
|
@ -169,28 +161,16 @@ HPEN WINAPI ExtCreatePen( DWORD style, DWORD width,
|
||||||
all_zero = all_zero && (style_bits[i] == 0);
|
all_zero = all_zero && (style_bits[i] == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(all_zero || has_neg)
|
if (all_zero || has_neg) goto invalid;
|
||||||
{
|
|
||||||
SetLastError(ERROR_INVALID_PARAMETER);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PS_INSIDEFRAME: /* applicable only for geometric pens */
|
case PS_INSIDEFRAME: /* applicable only for geometric pens */
|
||||||
if ((style & PS_TYPE_MASK) != PS_GEOMETRIC)
|
if ((style & PS_TYPE_MASK) != PS_GEOMETRIC) goto invalid;
|
||||||
{
|
|
||||||
SetLastError(ERROR_INVALID_PARAMETER);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PS_ALTERNATE: /* applicable only for cosmetic pens */
|
case PS_ALTERNATE: /* applicable only for cosmetic pens */
|
||||||
if ((style & PS_TYPE_MASK) == PS_GEOMETRIC)
|
if ((style & PS_TYPE_MASK) == PS_GEOMETRIC) goto invalid;
|
||||||
{
|
|
||||||
SetLastError(ERROR_INVALID_PARAMETER);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -200,35 +180,40 @@ HPEN WINAPI ExtCreatePen( DWORD style, DWORD width,
|
||||||
|
|
||||||
if ((style & PS_TYPE_MASK) == PS_GEOMETRIC)
|
if ((style & PS_TYPE_MASK) == PS_GEOMETRIC)
|
||||||
{
|
{
|
||||||
if (brush->lbHatch && ((brush->lbStyle != BS_SOLID) && (brush->lbStyle != BS_HOLLOW)))
|
if (brush->lbStyle == BS_NULL) return CreatePen( PS_NULL, 0, 0 );
|
||||||
{
|
|
||||||
static int fixme_hatches_shown;
|
|
||||||
if (!fixme_hatches_shown++) FIXME("Hatches not implemented\n");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (width != 1)
|
if (width != 1) goto invalid;
|
||||||
{
|
if (brush->lbStyle != BS_SOLID) goto invalid;
|
||||||
SetLastError(ERROR_INVALID_PARAMETER);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(penPtr = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(PENOBJ,logpen.elpStyleEntry[style_count]))))
|
if (!(penPtr = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(PENOBJ,logpen.elpStyleEntry[style_count]))))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
logbrush = *brush;
|
||||||
|
if (!store_brush_pattern( &logbrush, &penPtr->pattern )) goto invalid;
|
||||||
|
if (logbrush.lbStyle == BS_DIBPATTERN) logbrush.lbStyle = BS_DIBPATTERNPT;
|
||||||
|
|
||||||
penPtr->logpen.elpPenStyle = style;
|
penPtr->logpen.elpPenStyle = style;
|
||||||
penPtr->logpen.elpWidth = abs(width);
|
penPtr->logpen.elpWidth = abs(width);
|
||||||
penPtr->logpen.elpBrushStyle = brush->lbStyle;
|
penPtr->logpen.elpBrushStyle = logbrush.lbStyle;
|
||||||
penPtr->logpen.elpColor = brush->lbColor;
|
penPtr->logpen.elpColor = logbrush.lbColor;
|
||||||
penPtr->logpen.elpHatch = brush->lbHatch;
|
penPtr->logpen.elpHatch = brush->lbHatch;
|
||||||
penPtr->logpen.elpNumEntries = style_count;
|
penPtr->logpen.elpNumEntries = style_count;
|
||||||
memcpy(penPtr->logpen.elpStyleEntry, style_bits, style_count * sizeof(DWORD));
|
memcpy(penPtr->logpen.elpStyleEntry, style_bits, style_count * sizeof(DWORD));
|
||||||
|
|
||||||
if (!(hpen = alloc_gdi_handle( &penPtr->header, OBJ_EXTPEN, &pen_funcs )))
|
if (!(hpen = alloc_gdi_handle( &penPtr->header, OBJ_EXTPEN, &pen_funcs )))
|
||||||
|
{
|
||||||
|
free_brush_pattern( &penPtr->pattern );
|
||||||
HeapFree( GetProcessHeap(), 0, penPtr );
|
HeapFree( GetProcessHeap(), 0, penPtr );
|
||||||
|
}
|
||||||
return hpen;
|
return hpen;
|
||||||
|
|
||||||
|
invalid:
|
||||||
|
HeapFree( GetProcessHeap(), 0, penPtr );
|
||||||
|
SetLastError( ERROR_INVALID_PARAMETER );
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
@ -276,6 +261,7 @@ static BOOL PEN_DeleteObject( HGDIOBJ handle )
|
||||||
PENOBJ *pen = free_gdi_handle( handle );
|
PENOBJ *pen = free_gdi_handle( handle );
|
||||||
|
|
||||||
if (!pen) return FALSE;
|
if (!pen) return FALSE;
|
||||||
|
free_brush_pattern( &pen->pattern );
|
||||||
return HeapFree( GetProcessHeap(), 0, pen );
|
return HeapFree( GetProcessHeap(), 0, pen );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -570,9 +570,130 @@ static void test_ps_userstyle(void)
|
||||||
DeleteObject(pen);
|
DeleteObject(pen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_brush_pens(void)
|
||||||
|
{
|
||||||
|
char buffer[sizeof(EXTLOGPEN) + 15 * sizeof(DWORD)];
|
||||||
|
EXTLOGPEN *elp = (EXTLOGPEN *)buffer;
|
||||||
|
LOGBRUSH lb;
|
||||||
|
HPEN pen = 0;
|
||||||
|
DWORD size;
|
||||||
|
HBITMAP bmp = CreateBitmap( 8, 8, 1, 1, NULL );
|
||||||
|
BITMAPINFO *info;
|
||||||
|
HGLOBAL hmem;
|
||||||
|
|
||||||
|
hmem = GlobalAlloc( GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof(*info) + 16 * 16 * 4 );
|
||||||
|
info = GlobalLock( hmem );
|
||||||
|
info->bmiHeader.biSize = sizeof(info->bmiHeader);
|
||||||
|
info->bmiHeader.biWidth = 16;
|
||||||
|
info->bmiHeader.biHeight = 16;
|
||||||
|
info->bmiHeader.biPlanes = 1;
|
||||||
|
info->bmiHeader.biBitCount = 32;
|
||||||
|
info->bmiHeader.biCompression = BI_RGB;
|
||||||
|
|
||||||
|
for (lb.lbStyle = BS_SOLID; lb.lbStyle <= BS_MONOPATTERN + 1; lb.lbStyle++)
|
||||||
|
{
|
||||||
|
SetLastError( 0xdeadbeef );
|
||||||
|
memset( buffer, 0xcc, sizeof(buffer) );
|
||||||
|
trace( "testing brush style %u\n", lb.lbStyle );
|
||||||
|
|
||||||
|
switch (lb.lbStyle)
|
||||||
|
{
|
||||||
|
case BS_SOLID:
|
||||||
|
case BS_HATCHED:
|
||||||
|
lb.lbColor = RGB(12,34,56);
|
||||||
|
lb.lbHatch = HS_CROSS;
|
||||||
|
pen = ExtCreatePen( PS_DOT | PS_GEOMETRIC, 3, &lb, 0, NULL );
|
||||||
|
ok( pen != 0, "ExtCreatePen failed err %u\n", GetLastError() );
|
||||||
|
size = GetObject( pen, sizeof(buffer), elp );
|
||||||
|
ok( size == FIELD_OFFSET( EXTLOGPEN, elpStyleEntry ), "wrong size %u\n", size );
|
||||||
|
ok( elp->elpPenStyle == (PS_DOT | PS_GEOMETRIC), "wrong pen style %x\n", elp->elpPenStyle );
|
||||||
|
ok( elp->elpBrushStyle == lb.lbStyle, "wrong brush style %x\n", elp->elpBrushStyle );
|
||||||
|
ok( elp->elpColor == RGB(12,34,56), "wrong color %x\n", elp->elpColor );
|
||||||
|
ok( elp->elpHatch == HS_CROSS, "wrong hatch %lx\n", elp->elpHatch );
|
||||||
|
ok( elp->elpNumEntries == 0, "wrong entries %x\n", elp->elpNumEntries );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BS_NULL:
|
||||||
|
pen = ExtCreatePen( PS_SOLID | PS_GEOMETRIC, 3, &lb, 0, NULL );
|
||||||
|
ok( pen != 0, "ExtCreatePen failed err %u\n", GetLastError() );
|
||||||
|
size = GetObject( pen, sizeof(buffer), elp );
|
||||||
|
ok( size == sizeof(LOGPEN), "wrong size %u\n", size );
|
||||||
|
ok( ((LOGPEN *)elp)->lopnStyle == PS_NULL,
|
||||||
|
"wrong pen style %x\n", ((LOGPEN *)elp)->lopnStyle );
|
||||||
|
ok( ((LOGPEN *)elp)->lopnColor == 0,
|
||||||
|
"wrong color %x\n", ((LOGPEN *)elp)->lopnColor );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BS_PATTERN:
|
||||||
|
lb.lbColor = RGB(12,34,56);
|
||||||
|
lb.lbHatch = (ULONG_PTR)bmp;
|
||||||
|
pen = ExtCreatePen( PS_DOT | PS_GEOMETRIC, 3, &lb, 0, NULL );
|
||||||
|
ok( pen != 0, "ExtCreatePen failed err %u\n", GetLastError() );
|
||||||
|
size = GetObject( pen, sizeof(buffer), elp );
|
||||||
|
ok( size == FIELD_OFFSET( EXTLOGPEN, elpStyleEntry ), "wrong size %u\n", size );
|
||||||
|
ok( elp->elpPenStyle == (PS_DOT | PS_GEOMETRIC), "wrong pen style %x\n", elp->elpPenStyle );
|
||||||
|
ok( elp->elpBrushStyle == BS_PATTERN, "wrong brush style %x\n", elp->elpBrushStyle );
|
||||||
|
ok( elp->elpColor == 0, "wrong color %x\n", elp->elpColor );
|
||||||
|
ok( elp->elpHatch == (ULONG_PTR)bmp, "wrong hatch %lx/%p\n", elp->elpHatch, bmp );
|
||||||
|
ok( elp->elpNumEntries == 0, "wrong entries %x\n", elp->elpNumEntries );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BS_DIBPATTERN:
|
||||||
|
case BS_DIBPATTERNPT:
|
||||||
|
lb.lbColor = DIB_PAL_COLORS;
|
||||||
|
lb.lbHatch = lb.lbStyle == BS_DIBPATTERN ? (ULONG_PTR)hmem : (ULONG_PTR)info;
|
||||||
|
pen = ExtCreatePen( PS_DOT | PS_GEOMETRIC, 3, &lb, 0, NULL );
|
||||||
|
ok( pen != 0, "ExtCreatePen failed err %u\n", GetLastError() );
|
||||||
|
size = GetObject( pen, sizeof(buffer), elp );
|
||||||
|
ok( size == FIELD_OFFSET( EXTLOGPEN, elpStyleEntry ), "wrong size %u\n", size );
|
||||||
|
ok( elp->elpPenStyle == (PS_DOT | PS_GEOMETRIC), "wrong pen style %x\n", elp->elpPenStyle );
|
||||||
|
ok( elp->elpBrushStyle == BS_DIBPATTERNPT, "wrong brush style %x\n", elp->elpBrushStyle );
|
||||||
|
ok( elp->elpColor == 0, "wrong color %x\n", elp->elpColor );
|
||||||
|
ok( elp->elpHatch == lb.lbHatch || broken(elp->elpHatch != lb.lbHatch), /* <= w2k */
|
||||||
|
"wrong hatch %lx/%lx\n", elp->elpHatch, lb.lbHatch );
|
||||||
|
ok( elp->elpNumEntries == 0, "wrong entries %x\n", elp->elpNumEntries );
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
pen = ExtCreatePen( PS_DOT | PS_GEOMETRIC, 3, &lb, 0, NULL );
|
||||||
|
ok( !pen, "ExtCreatePen succeeded\n" );
|
||||||
|
ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pen) DeleteObject( pen );
|
||||||
|
else continue;
|
||||||
|
|
||||||
|
/* cosmetic pens require BS_SOLID */
|
||||||
|
SetLastError( 0xdeadbeef );
|
||||||
|
pen = ExtCreatePen( PS_DOT, 1, &lb, 0, NULL );
|
||||||
|
if (lb.lbStyle == BS_SOLID)
|
||||||
|
{
|
||||||
|
ok( pen != 0, "ExtCreatePen failed err %u\n", GetLastError() );
|
||||||
|
size = GetObject( pen, sizeof(buffer), elp );
|
||||||
|
ok( size == FIELD_OFFSET( EXTLOGPEN, elpStyleEntry ), "wrong size %u\n", size );
|
||||||
|
ok( elp->elpPenStyle == PS_DOT, "wrong pen style %x\n", elp->elpPenStyle );
|
||||||
|
ok( elp->elpBrushStyle == BS_SOLID, "wrong brush style %x\n", elp->elpBrushStyle );
|
||||||
|
ok( elp->elpColor == RGB(12,34,56), "wrong color %x\n", elp->elpColor );
|
||||||
|
ok( elp->elpHatch == HS_CROSS, "wrong hatch %lx\n", elp->elpHatch );
|
||||||
|
DeleteObject( pen );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ok( !pen, "ExtCreatePen succeeded\n" );
|
||||||
|
ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GlobalUnlock( hmem );
|
||||||
|
GlobalFree( hmem );
|
||||||
|
DeleteObject( bmp );
|
||||||
|
}
|
||||||
|
|
||||||
START_TEST(pen)
|
START_TEST(pen)
|
||||||
{
|
{
|
||||||
test_logpen();
|
test_logpen();
|
||||||
|
test_brush_pens();
|
||||||
test_ps_alternate();
|
test_ps_alternate();
|
||||||
test_ps_userstyle();
|
test_ps_userstyle();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue