static HPEN FASTCALL IntCreateStockPen(DWORD dwPenStyle, DWORD dwWidth, ULONG ulBrushStyle, ULONG ulColor) { HPEN hPen; PBRUSH pbrushPen; pbrushPen = PEN_AllocPenWithHandle(); if (pbrushPen == NULL) return NULL; if ((dwPenStyle & PS_STYLE_MASK) == PS_NULL) dwWidth = 1; pbrushPen->iHatch = 0; pbrushPen->lWidth = abs(dwWidth); pbrushPen->eWidth = (FLOAT)pbrushPen->lWidth; pbrushPen->ulPenStyle = dwPenStyle; pbrushPen->BrushAttr.lbColor = ulColor; pbrushPen->iBrushStyle = ulBrushStyle; pbrushPen->hbmClient = (HANDLE)NULL; pbrushPen->dwStyleCount = 0; pbrushPen->pStyle = 0; pbrushPen->flAttrs = BR_IS_OLDSTYLEPEN; switch (dwPenStyle & PS_STYLE_MASK) { case PS_NULL: pbrushPen->flAttrs |= BR_IS_NULL; break; case PS_SOLID: pbrushPen->flAttrs |= BR_IS_SOLID; break; } hPen = pbrushPen->BaseObject.hHmgr; PEN_UnlockPen(pbrushPen); return hPen; }
HPEN APIENTRY IntGdiExtCreatePen( DWORD dwPenStyle, DWORD dwWidth, IN ULONG ulBrushStyle, IN ULONG ulColor, IN ULONG_PTR ulClientHatch, IN ULONG_PTR ulHatch, DWORD dwStyleCount, PULONG pStyle, IN ULONG cjDIB, IN BOOL bOldStylePen, IN OPTIONAL HBRUSH hbrush) { HPEN hPen; PBRUSH pbrushPen; static const BYTE PatternAlternate[] = {0x55, 0x55, 0x55, 0}; static const BYTE PatternDash[] = {0xFF, 0xFF, 0xC0, 0}; static const BYTE PatternDot[] = {0xE3, 0x8E, 0x38, 0}; static const BYTE PatternDashDot[] = {0xFF, 0x81, 0xC0, 0}; static const BYTE PatternDashDotDot[] = {0xFF, 0x8E, 0x38, 0}; dwWidth = abs(dwWidth); if ( (dwPenStyle & PS_STYLE_MASK) == PS_NULL) { return StockObjects[NULL_PEN]; } if (bOldStylePen) { pbrushPen = PEN_AllocPenWithHandle(); } else { pbrushPen = PEN_AllocExtPenWithHandle(); } if (!pbrushPen) { EngSetLastError(ERROR_NOT_ENOUGH_MEMORY); DPRINT("Can't allocate pen\n"); return 0; } hPen = pbrushPen->BaseObject.hHmgr; // If nWidth is zero, the pen is a single pixel wide, regardless of the current transformation. if ((bOldStylePen) && (!dwWidth) && ((dwPenStyle & PS_STYLE_MASK) != PS_SOLID)) dwWidth = 1; pbrushPen->lWidth = dwWidth; pbrushPen->eWidth = (FLOAT)pbrushPen->lWidth; pbrushPen->ulPenStyle = dwPenStyle; pbrushPen->BrushAttr.lbColor = ulColor; pbrushPen->iBrushStyle = ulBrushStyle; // FIXME: Copy the bitmap first ? pbrushPen->hbmClient = (HANDLE)ulClientHatch; pbrushPen->dwStyleCount = dwStyleCount; pbrushPen->pStyle = pStyle; pbrushPen->flAttrs = bOldStylePen ? BR_IS_OLDSTYLEPEN : BR_IS_PEN; // If dwPenStyle is PS_COSMETIC, the width must be set to 1. if ( !(bOldStylePen) && ((dwPenStyle & PS_TYPE_MASK) == PS_COSMETIC) && ( dwWidth != 1) ) goto ExitCleanup; switch (dwPenStyle & PS_STYLE_MASK) { case PS_NULL: pbrushPen->flAttrs |= BR_IS_NULL; break; case PS_SOLID: pbrushPen->flAttrs |= BR_IS_SOLID; break; case PS_ALTERNATE: pbrushPen->flAttrs |= BR_IS_BITMAP; pbrushPen->hbmPattern = GreCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternAlternate); break; case PS_DOT: pbrushPen->flAttrs |= BR_IS_BITMAP; pbrushPen->hbmPattern = GreCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternDot); break; case PS_DASH: pbrushPen->flAttrs |= BR_IS_BITMAP; pbrushPen->hbmPattern = GreCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternDash); break; case PS_DASHDOT: pbrushPen->flAttrs |= BR_IS_BITMAP; pbrushPen->hbmPattern = GreCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternDashDot); break; case PS_DASHDOTDOT: pbrushPen->flAttrs |= BR_IS_BITMAP; pbrushPen->hbmPattern = GreCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternDashDotDot); break; case PS_INSIDEFRAME: pbrushPen->flAttrs |= (BR_IS_SOLID | BR_IS_INSIDEFRAME); break; case PS_USERSTYLE: if ((dwPenStyle & PS_TYPE_MASK) == PS_COSMETIC) { /* FIXME: PS_USERSTYLE workaround */ DPRINT1("PS_COSMETIC | PS_USERSTYLE not handled\n"); pbrushPen->flAttrs |= BR_IS_SOLID; break; } else { UINT i; BOOL has_neg = FALSE, all_zero = TRUE; for(i = 0; (i < dwStyleCount) && !has_neg; i++) { has_neg = has_neg || (((INT)(pStyle[i])) < 0); all_zero = all_zero && (pStyle[i] == 0); } if(all_zero || has_neg) { goto ExitCleanup; } } /* FIXME: What style here? */ pbrushPen->flAttrs |= 0; break; default: DPRINT1("IntGdiExtCreatePen unknown penstyle %x\n", dwPenStyle); } PEN_UnlockPen(pbrushPen); return hPen; ExitCleanup: EngSetLastError(ERROR_INVALID_PARAMETER); pbrushPen->pStyle = NULL; GDIOBJ_vDeleteObject(&pbrushPen->BaseObject); return NULL; }