Fix spurious warning/error reported by GCC 4.4.0.
[reactos.git] / reactos / subsystems / win32 / win32k / objects / text.c
1 /*
2 * PROJECT: ReactOS win32 kernel mode subsystem
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: subsystems/win32/win32k/objects/text.c
5 * PURPOSE: Text/Font
6 * PROGRAMMER:
7 */
8
9 /** Includes ******************************************************************/
10
11 #include <w32k.h>
12
13 #define NDEBUG
14 #include <debug.h>
15
16 /** Functions ******************************************************************/
17
18 DWORD
19 APIENTRY
20 NtGdiGetCharSet(HDC hDC)
21 {
22 PDC Dc;
23 PDC_ATTR Dc_Attr;
24 DWORD cscp;
25 // If here, update everything!
26 Dc = DC_LockDc(hDC);
27 if (!Dc)
28 {
29 SetLastWin32Error(ERROR_INVALID_HANDLE);
30 return 0;
31 }
32 cscp = ftGdiGetTextCharsetInfo(Dc,NULL,0);
33 Dc_Attr = Dc->pDc_Attr;
34 if (!Dc_Attr) Dc_Attr = &Dc->Dc_Attr;
35 Dc_Attr->iCS_CP = cscp;
36 Dc_Attr->ulDirty_ &= ~DIRTY_CHARSET;
37 DC_UnlockDc( Dc );
38 return cscp;
39 }
40
41 BOOL
42 APIENTRY
43 NtGdiGetRasterizerCaps(
44 OUT LPRASTERIZER_STATUS praststat,
45 IN ULONG cjBytes)
46 {
47 NTSTATUS Status = STATUS_SUCCESS;
48 RASTERIZER_STATUS rsSafe;
49
50 if (praststat && cjBytes)
51 {
52 if ( cjBytes >= sizeof(RASTERIZER_STATUS) ) cjBytes = sizeof(RASTERIZER_STATUS);
53 if ( ftGdiGetRasterizerCaps(&rsSafe))
54 {
55 _SEH2_TRY
56 {
57 ProbeForWrite( praststat,
58 sizeof(RASTERIZER_STATUS),
59 1);
60 RtlCopyMemory(praststat, &rsSafe, cjBytes );
61 }
62 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
63 {
64 Status = _SEH2_GetExceptionCode();
65 }
66 _SEH2_END;
67
68 if (!NT_SUCCESS(Status))
69 {
70 SetLastNtError(Status);
71 return FALSE;
72 }
73 }
74 }
75 return FALSE;
76 }
77
78 INT
79 APIENTRY
80 NtGdiGetTextCharsetInfo(
81 IN HDC hdc,
82 OUT OPTIONAL LPFONTSIGNATURE lpSig,
83 IN DWORD dwFlags)
84 {
85 PDC Dc;
86 INT Ret;
87 FONTSIGNATURE fsSafe;
88 PFONTSIGNATURE pfsSafe = &fsSafe;
89 NTSTATUS Status = STATUS_SUCCESS;
90
91 Dc = DC_LockDc(hdc);
92 if (!Dc)
93 {
94 SetLastWin32Error(ERROR_INVALID_HANDLE);
95 return DEFAULT_CHARSET;
96 }
97
98 if (!lpSig) pfsSafe = NULL;
99
100 Ret = HIWORD(ftGdiGetTextCharsetInfo( Dc, pfsSafe, dwFlags));
101
102 if (lpSig)
103 {
104 if (Ret == DEFAULT_CHARSET)
105 RtlZeroMemory(pfsSafe, sizeof(FONTSIGNATURE));
106
107 _SEH2_TRY
108 {
109 ProbeForWrite( lpSig,
110 sizeof(FONTSIGNATURE),
111 1);
112 RtlCopyMemory(lpSig, pfsSafe, sizeof(FONTSIGNATURE));
113 }
114 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
115 {
116 Status = _SEH2_GetExceptionCode();
117 }
118 _SEH2_END;
119
120 if (!NT_SUCCESS(Status))
121 {
122 SetLastNtError(Status);
123 return DEFAULT_CHARSET;
124 }
125 }
126 DC_UnlockDc(Dc);
127 return Ret;
128 }
129
130 W32KAPI
131 BOOL
132 APIENTRY
133 NtGdiGetTextExtentExW(
134 IN HDC hDC,
135 IN OPTIONAL LPWSTR UnsafeString,
136 IN ULONG Count,
137 IN ULONG MaxExtent,
138 OUT OPTIONAL PULONG UnsafeFit,
139 OUT OPTIONAL PULONG UnsafeDx,
140 OUT LPSIZE UnsafeSize,
141 IN FLONG fl
142 )
143 {
144 PDC dc;
145 PDC_ATTR Dc_Attr;
146 LPWSTR String;
147 SIZE Size;
148 NTSTATUS Status;
149 BOOLEAN Result;
150 INT Fit;
151 LPINT Dx;
152 PTEXTOBJ TextObj;
153
154 /* FIXME: Handle fl */
155
156 if (0 == Count)
157 {
158 Size.cx = 0;
159 Size.cy = 0;
160 Status = MmCopyToCaller(UnsafeSize, &Size, sizeof(SIZE));
161 if (! NT_SUCCESS(Status))
162 {
163 SetLastNtError(Status);
164 return FALSE;
165 }
166 return TRUE;
167 }
168
169 String = ExAllocatePoolWithTag(PagedPool, Count * sizeof(WCHAR), TAG_GDITEXT);
170 if (NULL == String)
171 {
172 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
173 return FALSE;
174 }
175
176 if (NULL != UnsafeDx)
177 {
178 Dx = ExAllocatePoolWithTag(PagedPool, Count * sizeof(INT), TAG_GDITEXT);
179 if (NULL == Dx)
180 {
181 ExFreePoolWithTag(String, TAG_GDITEXT);
182 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
183 return FALSE;
184 }
185 }
186 else
187 {
188 Dx = NULL;
189 }
190
191 Status = MmCopyFromCaller(String, UnsafeString, Count * sizeof(WCHAR));
192 if (! NT_SUCCESS(Status))
193 {
194 if (NULL != Dx)
195 {
196 ExFreePoolWithTag(Dx, TAG_GDITEXT);
197 }
198 ExFreePoolWithTag(String, TAG_GDITEXT);
199 SetLastNtError(Status);
200 return FALSE;
201 }
202
203 dc = DC_LockDc(hDC);
204 if (NULL == dc)
205 {
206 if (NULL != Dx)
207 {
208 ExFreePoolWithTag(Dx, TAG_GDITEXT);
209 }
210 ExFreePoolWithTag(String, TAG_GDITEXT);
211 SetLastWin32Error(ERROR_INVALID_HANDLE);
212 return FALSE;
213 }
214 Dc_Attr = dc->pDc_Attr;
215 if(!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
216 TextObj = RealizeFontInit(Dc_Attr->hlfntNew);
217 if ( TextObj )
218 {
219 Result = TextIntGetTextExtentPoint(dc, TextObj, String, Count, MaxExtent,
220 NULL == UnsafeFit ? NULL : &Fit, Dx, &Size);
221 TEXTOBJ_UnlockText(TextObj);
222 }
223 else
224 Result = FALSE;
225 DC_UnlockDc(dc);
226
227 ExFreePoolWithTag(String, TAG_GDITEXT);
228 if (! Result)
229 {
230 if (NULL != Dx)
231 {
232 ExFreePoolWithTag(Dx, TAG_GDITEXT);
233 }
234 return FALSE;
235 }
236
237 if (NULL != UnsafeFit)
238 {
239 Status = MmCopyToCaller(UnsafeFit, &Fit, sizeof(INT));
240 if (! NT_SUCCESS(Status))
241 {
242 if (NULL != Dx)
243 {
244 ExFreePoolWithTag(Dx, TAG_GDITEXT);
245 }
246 SetLastNtError(Status);
247 return FALSE;
248 }
249 }
250
251 if (NULL != UnsafeDx)
252 {
253 Status = MmCopyToCaller(UnsafeDx, Dx, Count * sizeof(INT));
254 if (! NT_SUCCESS(Status))
255 {
256 if (NULL != Dx)
257 {
258 ExFreePoolWithTag(Dx, TAG_GDITEXT);
259 }
260 SetLastNtError(Status);
261 return FALSE;
262 }
263 }
264 if (NULL != Dx)
265 {
266 ExFreePoolWithTag(Dx,TAG_GDITEXT);
267 }
268
269 Status = MmCopyToCaller(UnsafeSize, &Size, sizeof(SIZE));
270 if (! NT_SUCCESS(Status))
271 {
272 SetLastNtError(Status);
273 return FALSE;
274 }
275
276 return TRUE;
277 }
278
279 BOOL
280 APIENTRY
281 NtGdiGetTextExtent(HDC hdc,
282 LPWSTR lpwsz,
283 INT cwc,
284 LPSIZE psize,
285 UINT flOpts)
286 {
287 return NtGdiGetTextExtentExW(hdc, lpwsz, cwc, 0, NULL, NULL, psize, 0);
288 }
289
290 BOOL
291 APIENTRY
292 NtGdiSetTextJustification(HDC hDC,
293 int BreakExtra,
294 int BreakCount)
295 {
296 PDC pDc;
297 PDC_ATTR pDc_Attr;
298
299 pDc = DC_LockDc(hDC);
300 if (!pDc)
301 {
302 SetLastWin32Error(ERROR_INVALID_HANDLE);
303 return FALSE;
304 }
305
306 pDc_Attr = pDc->pDc_Attr;
307 if(!pDc_Attr) pDc_Attr = &pDc->Dc_Attr;
308
309 pDc_Attr->lBreakExtra = BreakExtra;
310 pDc_Attr->cBreak = BreakCount;
311
312 DC_UnlockDc(pDc);
313 return TRUE;
314 }
315
316
317 W32KAPI
318 INT
319 APIENTRY
320 NtGdiGetTextFaceW(
321 IN HDC hDC,
322 IN INT Count,
323 OUT OPTIONAL LPWSTR FaceName,
324 IN BOOL bAliasName
325 )
326 {
327 PDC Dc;
328 PDC_ATTR Dc_Attr;
329 HFONT hFont;
330 PTEXTOBJ TextObj;
331 NTSTATUS Status;
332
333 /* FIXME: Handle bAliasName */
334
335 Dc = DC_LockDc(hDC);
336 if (Dc == NULL)
337 {
338 SetLastWin32Error(ERROR_INVALID_HANDLE);
339 return FALSE;
340 }
341 Dc_Attr = Dc->pDc_Attr;
342 if(!Dc_Attr) Dc_Attr = &Dc->Dc_Attr;
343 hFont = Dc_Attr->hlfntNew;
344 DC_UnlockDc(Dc);
345
346 TextObj = RealizeFontInit(hFont);
347 ASSERT(TextObj != NULL);
348 Count = min(Count, wcslen(TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfFaceName));
349 Status = MmCopyToCaller(FaceName, TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfFaceName, Count * sizeof(WCHAR));
350 TEXTOBJ_UnlockText(TextObj);
351 if (!NT_SUCCESS(Status))
352 {
353 SetLastNtError(Status);
354 return 0;
355 }
356
357 return Count;
358 }
359
360 W32KAPI
361 BOOL
362 APIENTRY
363 NtGdiGetTextMetricsW(
364 IN HDC hDC,
365 OUT TMW_INTERNAL * pUnsafeTmwi,
366 IN ULONG cj
367 )
368 {
369 TMW_INTERNAL Tmwi;
370 NTSTATUS Status = STATUS_SUCCESS;
371
372 if ( cj <= sizeof(TMW_INTERNAL) )
373 {
374 if (ftGdiGetTextMetricsW(hDC,&Tmwi))
375 {
376 _SEH2_TRY
377 {
378 ProbeForWrite(pUnsafeTmwi, cj, 1);
379 RtlCopyMemory(pUnsafeTmwi,&Tmwi,cj);
380 }
381 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
382 {
383 Status = _SEH2_GetExceptionCode();
384 }
385 _SEH2_END
386
387 if (!NT_SUCCESS(Status))
388 {
389 SetLastNtError(Status);
390 return FALSE;
391 }
392 return TRUE;
393 }
394 }
395 return FALSE;
396 }
397
398 /* EOF */