/*********************************************************************** * CreatePenIndirect (GDI32.@) */ HPEN WINAPI CreatePenIndirect( const LOGPEN * pen ) { PENOBJ * penPtr; HPEN hpen; 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.elpPenStyle = PS_SOLID; else penPtr->logpen.elpPenStyle = pen->lopnStyle; if (pen->lopnStyle == PS_NULL) { penPtr->logpen.elpWidth = 1; penPtr->logpen.elpColor = RGB(0, 0, 0); } else { 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; }
/****************************************************************************** * CreateBitmapIndirect [GDI32.@] * * Creates a bitmap with the specified info. * * PARAMS * bmp [I] Pointer to the bitmap info describing the bitmap * * RETURNS * Success: Handle to bitmap * Failure: NULL. Use GetLastError() to determine the cause. * * NOTES * If a width or height of 0 are given, a 1x1 monochrome bitmap is returned. */ HBITMAP WINAPI CreateBitmapIndirect( const BITMAP *bmp ) { BITMAP bm; BITMAPOBJ *bmpobj; HBITMAP hbitmap; if (!bmp || bmp->bmType) { SetLastError( ERROR_INVALID_PARAMETER ); return NULL; } if (bmp->bmWidth > 0x7ffffff || bmp->bmHeight > 0x7ffffff) { SetLastError( ERROR_INVALID_PARAMETER ); return 0; } bm = *bmp; if (!bm.bmWidth || !bm.bmHeight) { return GetStockObject( DEFAULT_BITMAP ); } else { if (bm.bmHeight < 0) bm.bmHeight = -bm.bmHeight; if (bm.bmWidth < 0) bm.bmWidth = -bm.bmWidth; } if (bm.bmPlanes != 1) { FIXME("planes = %d\n", bm.bmPlanes); SetLastError( ERROR_INVALID_PARAMETER ); return NULL; } /* Windows only uses 1, 4, 8, 16, 24 and 32 bpp */ if(bm.bmBitsPixel == 1) bm.bmBitsPixel = 1; else if(bm.bmBitsPixel <= 4) bm.bmBitsPixel = 4; else if(bm.bmBitsPixel <= 8) bm.bmBitsPixel = 8; else if(bm.bmBitsPixel <= 16) bm.bmBitsPixel = 16; else if(bm.bmBitsPixel <= 24) bm.bmBitsPixel = 24; else if(bm.bmBitsPixel <= 32) bm.bmBitsPixel = 32; else { WARN("Invalid bmBitsPixel %d, returning ERROR_INVALID_PARAMETER\n", bm.bmBitsPixel); SetLastError(ERROR_INVALID_PARAMETER); return NULL; } /* Windows ignores the provided bm.bmWidthBytes */ bm.bmWidthBytes = BITMAP_GetWidthBytes( bm.bmWidth, bm.bmBitsPixel ); /* XP doesn't allow to create bitmaps larger than 128 Mb */ if (bm.bmHeight > 128 * 1024 * 1024 / bm.bmWidthBytes) { SetLastError( ERROR_NOT_ENOUGH_MEMORY ); return 0; } /* Create the BITMAPOBJ */ bmpobj = GDI_AllocObject( sizeof(BITMAPOBJ), BITMAP_MAGIC, (HGDIOBJ *)&hbitmap, &bitmap_funcs ); if (!bmpobj) { SetLastError( ERROR_NOT_ENOUGH_MEMORY ); return NULL; } TRACE("%dx%d, %d colors returning %p\n", bm.bmWidth, bm.bmHeight, 1 << (bm.bmPlanes * bm.bmBitsPixel), hbitmap); bmpobj->size.cx = 0; bmpobj->size.cy = 0; bmpobj->bitmap = bm; bmpobj->bitmap.bmBits = NULL; bmpobj->funcs = NULL; bmpobj->dib = NULL; bmpobj->segptr_bits = 0; bmpobj->color_table = NULL; bmpobj->nb_colors = 0; if (bm.bmBits) SetBitmapBits( hbitmap, bm.bmHeight * bm.bmWidthBytes, bm.bmBits ); GDI_ReleaseObj( hbitmap ); return hbitmap; }
HPEN WINAPI ExtCreatePen( DWORD style, DWORD width, const LOGBRUSH * brush, DWORD style_count, const DWORD *style_bits ) { PENOBJ * penPtr; HPEN hpen; if ((style & PS_STYLE_MASK) == PS_USERSTYLE) { if(((INT)style_count) <= 0) return 0; if ((style_count > 16) || !style_bits) { SetLastError(ERROR_INVALID_PARAMETER); return 0; } if ((style & PS_TYPE_MASK) == PS_COSMETIC) { /* FIXME: PS_USERSTYLE workaround */ FIXME("PS_COSMETIC | PS_USERSTYLE not handled\n"); style = (style & ~PS_STYLE_MASK) | PS_SOLID; } else { UINT i; BOOL has_neg = FALSE, all_zero = TRUE; for(i = 0; (i < style_count) && !has_neg; i++) { has_neg = has_neg || (((INT)(style_bits[i])) < 0); all_zero = all_zero && (style_bits[i] == 0); } if(all_zero || has_neg) { SetLastError(ERROR_INVALID_PARAMETER); return 0; } } } 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))) { static int fixme_hatches_shown; if (!fixme_hatches_shown++) FIXME("Hatches not implemented\n"); } } else { /* PS_INSIDEFRAME is applicable only for geometric pens */ if ((style & PS_STYLE_MASK) == PS_INSIDEFRAME || width != 1) { SetLastError(ERROR_INVALID_PARAMETER); return 0; } } 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.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; }