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