795b94086cbeff5754b942e391f8a92b3f96f92d
[reactos.git] / reactos / subsystems / win32 / win32k / objects / pen.c
1 /*
2 * ReactOS Win32 Subsystem
3 *
4 * Copyright (C) 1998 - 2004 ReactOS Team
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 * $Id$
21 */
22
23 #include <w32k.h>
24
25 #define NDEBUG
26 #include <debug.h>
27
28 /* PRIVATE FUNCTIONS **********************************************************/
29
30 HPEN FASTCALL
31 IntGdiCreatePenIndirect(PLOGPEN LogPen)
32 {
33 HPEN hPen;
34 PGDIBRUSHOBJ PenObject;
35 static const WORD wPatternAlternate[] = {0x5555};
36 static const WORD wPatternDash[] = {0x0F0F};
37 static const WORD wPatternDot[] = {0x3333};
38
39 if (LogPen->lopnStyle > PS_INSIDEFRAME)
40 return 0;
41
42 hPen = PENOBJ_AllocPen();
43 if (!hPen)
44 {
45 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
46 DPRINT("Can't allocate pen\n");
47 return 0;
48 }
49
50 PenObject = PENOBJ_LockPen(hPen);
51 /* FIXME - Handle PenObject == NULL!!! */
52 PenObject->ptPenWidth = LogPen->lopnWidth;
53 PenObject->ulPenStyle = LogPen->lopnStyle;
54 PenObject->BrushAttr.lbColor = LogPen->lopnColor;
55 PenObject->flAttrs = GDIBRUSH_IS_OLDSTYLEPEN;
56 switch (LogPen->lopnStyle)
57 {
58 case PS_NULL:
59 PenObject->flAttrs |= GDIBRUSH_IS_NULL;
60 break;
61
62 case PS_SOLID:
63 PenObject->flAttrs |= GDIBRUSH_IS_SOLID;
64 break;
65
66 case PS_ALTERNATE:
67 PenObject->flAttrs |= GDIBRUSH_IS_BITMAP;
68 PenObject->hbmPattern = NtGdiCreateBitmap(8, 1, 1, 1, (LPBYTE)wPatternAlternate);
69 break;
70
71 case PS_DOT:
72 PenObject->flAttrs |= GDIBRUSH_IS_BITMAP;
73 PenObject->hbmPattern = NtGdiCreateBitmap(8, 1, 1, 1, (LPBYTE)wPatternDot);
74 break;
75
76 case PS_DASH:
77 PenObject->flAttrs |= GDIBRUSH_IS_BITMAP;
78 PenObject->hbmPattern = NtGdiCreateBitmap(8, 1, 1, 1, (LPBYTE)wPatternDash);
79 break;
80
81 case PS_INSIDEFRAME:
82 /* FIXME: does it need some additional work? */
83 PenObject->flAttrs |= GDIBRUSH_IS_SOLID;
84 break;
85
86 default:
87 DPRINT1("FIXME: IntGdiCreatePenIndirect is UNIMPLEMENTED pen %x\n",LogPen->lopnStyle);
88 }
89
90 PENOBJ_UnlockPen(PenObject);
91
92 return hPen;
93 }
94
95 INT STDCALL
96 PEN_GetObject(PGDIBRUSHOBJ PenObject, INT Count, PLOGPEN Buffer)
97 {
98
99 LOGPEN LogPen;
100
101 if( Buffer == NULL ) return sizeof(LOGPEN);
102
103 LogPen.lopnWidth = PenObject->ptPenWidth;
104 LogPen.lopnStyle = PenObject->ulPenStyle;
105 LogPen.lopnColor = PenObject->BrushAttr.lbColor;
106 memcpy(Buffer, &LogPen, Count);
107
108 return Count;
109
110 }
111
112 /* PUBLIC FUNCTIONS ***********************************************************/
113
114 HPEN STDCALL
115 NtGdiCreatePen(
116 INT PenStyle,
117 INT Width,
118 COLORREF Color,
119 IN HBRUSH hbr)
120 {
121 LOGPEN LogPen;
122
123 LogPen.lopnStyle = PenStyle;
124 LogPen.lopnWidth.x = Width;
125 LogPen.lopnWidth.y = 0;
126 LogPen.lopnColor = Color;
127
128 return IntGdiCreatePenIndirect(&LogPen);
129 }
130
131 HPEN STDCALL
132 NtGdiCreatePenIndirect(CONST PLOGPEN LogPen)
133 {
134 LOGPEN SafeLogPen;
135 NTSTATUS Status = STATUS_SUCCESS;
136
137 _SEH_TRY
138 {
139 ProbeForRead(LogPen,
140 sizeof(LOGPEN),
141 1);
142 SafeLogPen = *LogPen;
143 }
144 _SEH_HANDLE
145 {
146 Status = _SEH_GetExceptionCode();
147 }
148 _SEH_END;
149
150 if (!NT_SUCCESS(Status))
151 {
152 SetLastNtError(Status);
153 return 0;
154 }
155
156 return IntGdiCreatePenIndirect(&SafeLogPen);
157 }
158
159 HPEN STDCALL
160 NtGdiExtCreatePen(
161 DWORD PenStyle,
162 DWORD Width,
163 IN ULONG iBrushStyle,
164 IN ULONG ulColor,
165 IN ULONG_PTR lClientHatch,
166 IN ULONG_PTR lHatch,
167 DWORD StyleCount,
168 PULONG Style,
169 IN ULONG cjDIB,
170 IN BOOL bOldStylePen,
171 IN OPTIONAL HBRUSH hbrush)
172 {
173 LOGPEN LogPen;
174
175 if (PenStyle & PS_USERSTYLE)
176 PenStyle = (PenStyle & ~PS_STYLE_MASK) | PS_SOLID;
177
178 LogPen.lopnStyle = PenStyle & PS_STYLE_MASK;
179 LogPen.lopnWidth.x = Width;
180 LogPen.lopnColor = ulColor;
181
182 return IntGdiCreatePenIndirect(&LogPen);
183 }
184
185 /* EOF */