Revert the sync.
[reactos.git] / 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 /*
19 flOpts :
20 GetTextExtentPoint32W = 0
21 GetTextExtentPointW = 1
22 */
23 BOOL
24 FASTCALL
25 GreGetTextExtentW(
26 HDC hDC,
27 LPWSTR lpwsz,
28 INT cwc,
29 LPSIZE psize,
30 UINT flOpts)
31 {
32 PDC pdc;
33 PDC_ATTR pdcattr;
34 BOOL Result;
35 PTEXTOBJ TextObj;
36
37 if (!cwc)
38 {
39 psize->cx = 0;
40 psize->cy = 0;
41 return TRUE;
42 }
43
44 pdc = DC_LockDc(hDC);
45 if (!pdc)
46 {
47 SetLastWin32Error(ERROR_INVALID_HANDLE);
48 return FALSE;
49 }
50
51 pdcattr = pdc->pdcattr;
52
53 TextObj = RealizeFontInit(pdcattr->hlfntNew);
54 if ( TextObj )
55 {
56 Result = TextIntGetTextExtentPoint( pdc,
57 TextObj,
58 lpwsz,
59 cwc,
60 0,
61 NULL,
62 0,
63 psize);
64 TEXTOBJ_UnlockText(TextObj);
65 }
66 else
67 Result = FALSE;
68
69 DC_UnlockDc(pdc);
70 return Result;
71 }
72
73
74 /*
75 fl :
76 GetTextExtentExPointW = 0 and everything else that uses this.
77 GetTextExtentExPointI = 1
78 */
79 BOOL
80 FASTCALL
81 GreGetTextExtentExW(
82 HDC hDC,
83 LPWSTR String,
84 ULONG Count,
85 ULONG MaxExtent,
86 PULONG Fit,
87 PULONG Dx,
88 LPSIZE pSize,
89 FLONG fl)
90 {
91 PDC pdc;
92 PDC_ATTR pdcattr;
93 BOOL Result;
94 PTEXTOBJ TextObj;
95
96 if ( (!String && Count ) || !pSize )
97 {
98 SetLastWin32Error(ERROR_INVALID_PARAMETER);
99 return FALSE;
100 }
101
102 if ( !Count )
103 {
104 if ( Fit ) Fit = 0;
105 return TRUE;
106 }
107
108 pdc = DC_LockDc(hDC);
109 if (NULL == pdc)
110 {
111 SetLastWin32Error(ERROR_INVALID_HANDLE);
112 return FALSE;
113 }
114 pdcattr = pdc->pdcattr;
115
116 TextObj = RealizeFontInit(pdcattr->hlfntNew);
117 if ( TextObj )
118 {
119 Result = TextIntGetTextExtentPoint( pdc,
120 TextObj,
121 String,
122 Count,
123 MaxExtent,
124 (LPINT)Fit,
125 (LPINT)Dx,
126 pSize);
127 TEXTOBJ_UnlockText(TextObj);
128 }
129 else
130 Result = FALSE;
131
132 DC_UnlockDc(pdc);
133 return Result;
134 }
135
136 DWORD
137 APIENTRY
138 NtGdiGetCharSet(HDC hDC)
139 {
140 PDC Dc;
141 PDC_ATTR pdcattr;
142 DWORD cscp;
143 // If here, update everything!
144 Dc = DC_LockDc(hDC);
145 if (!Dc)
146 {
147 SetLastWin32Error(ERROR_INVALID_HANDLE);
148 return 0;
149 }
150 cscp = ftGdiGetTextCharsetInfo(Dc,NULL,0);
151 pdcattr = Dc->pdcattr;
152 pdcattr->iCS_CP = cscp;
153 pdcattr->ulDirty_ &= ~DIRTY_CHARSET;
154 DC_UnlockDc( Dc );
155 return cscp;
156 }
157
158 BOOL
159 APIENTRY
160 NtGdiGetRasterizerCaps(
161 OUT LPRASTERIZER_STATUS praststat,
162 IN ULONG cjBytes)
163 {
164 NTSTATUS Status = STATUS_SUCCESS;
165 RASTERIZER_STATUS rsSafe;
166
167 if (praststat && cjBytes)
168 {
169 if ( cjBytes >= sizeof(RASTERIZER_STATUS) ) cjBytes = sizeof(RASTERIZER_STATUS);
170 if ( ftGdiGetRasterizerCaps(&rsSafe))
171 {
172 _SEH2_TRY
173 {
174 ProbeForWrite( praststat,
175 sizeof(RASTERIZER_STATUS),
176 1);
177 RtlCopyMemory(praststat, &rsSafe, cjBytes );
178 }
179 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
180 {
181 Status = _SEH2_GetExceptionCode();
182 }
183 _SEH2_END;
184
185 if (!NT_SUCCESS(Status))
186 {
187 SetLastNtError(Status);
188 return FALSE;
189 }
190
191 return TRUE;
192 }
193 }
194 return FALSE;
195 }
196
197 INT
198 APIENTRY
199 NtGdiGetTextCharsetInfo(
200 IN HDC hdc,
201 OUT OPTIONAL LPFONTSIGNATURE lpSig,
202 IN DWORD dwFlags)
203 {
204 PDC Dc;
205 INT Ret;
206 FONTSIGNATURE fsSafe;
207 PFONTSIGNATURE pfsSafe = &fsSafe;
208 NTSTATUS Status = STATUS_SUCCESS;
209
210 Dc = DC_LockDc(hdc);
211 if (!Dc)
212 {
213 SetLastWin32Error(ERROR_INVALID_HANDLE);
214 return DEFAULT_CHARSET;
215 }
216
217 if (!lpSig) pfsSafe = NULL;
218
219 Ret = HIWORD(ftGdiGetTextCharsetInfo( Dc, pfsSafe, dwFlags));
220
221 if (lpSig)
222 {
223 if (Ret == DEFAULT_CHARSET)
224 RtlZeroMemory(pfsSafe, sizeof(FONTSIGNATURE));
225
226 _SEH2_TRY
227 {
228 ProbeForWrite( lpSig,
229 sizeof(FONTSIGNATURE),
230 1);
231 RtlCopyMemory(lpSig, pfsSafe, sizeof(FONTSIGNATURE));
232 }
233 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
234 {
235 Status = _SEH2_GetExceptionCode();
236 }
237 _SEH2_END;
238
239 if (!NT_SUCCESS(Status))
240 {
241 SetLastNtError(Status);
242 return DEFAULT_CHARSET;
243 }
244 }
245 DC_UnlockDc(Dc);
246 return Ret;
247 }
248
249
250 /*
251 fl :
252 GetTextExtentExPointW = 0 and everything else that uses this.
253 GetTextExtentExPointI = 1
254 */
255 W32KAPI
256 BOOL
257 APIENTRY
258 NtGdiGetTextExtentExW(
259 IN HDC hDC,
260 IN OPTIONAL LPWSTR UnsafeString,
261 IN ULONG Count,
262 IN ULONG MaxExtent,
263 OUT OPTIONAL PULONG UnsafeFit,
264 OUT OPTIONAL PULONG UnsafeDx,
265 OUT LPSIZE UnsafeSize,
266 IN FLONG fl
267 )
268 {
269 PDC dc;
270 PDC_ATTR pdcattr;
271 LPWSTR String;
272 SIZE Size;
273 NTSTATUS Status;
274 BOOLEAN Result;
275 INT Fit;
276 LPINT Dx;
277 PTEXTOBJ TextObj;
278
279 /* FIXME: Handle fl */
280
281 if (0 == Count)
282 {
283 Size.cx = 0;
284 Size.cy = 0;
285 Status = MmCopyToCaller(UnsafeSize, &Size, sizeof(SIZE));
286 if (! NT_SUCCESS(Status))
287 {
288 SetLastNtError(Status);
289 return FALSE;
290 }
291 return TRUE;
292 }
293
294 String = ExAllocatePoolWithTag(PagedPool, Count * sizeof(WCHAR), TAG_GDITEXT);
295 if (NULL == String)
296 {
297 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
298 return FALSE;
299 }
300
301 if (NULL != UnsafeDx)
302 {
303 Dx = ExAllocatePoolWithTag(PagedPool, Count * sizeof(INT), TAG_GDITEXT);
304 if (NULL == Dx)
305 {
306 ExFreePoolWithTag(String, TAG_GDITEXT);
307 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
308 return FALSE;
309 }
310 }
311 else
312 {
313 Dx = NULL;
314 }
315
316 Status = MmCopyFromCaller(String, UnsafeString, Count * sizeof(WCHAR));
317 if (! NT_SUCCESS(Status))
318 {
319 if (NULL != Dx)
320 {
321 ExFreePoolWithTag(Dx, TAG_GDITEXT);
322 }
323 ExFreePoolWithTag(String, TAG_GDITEXT);
324 SetLastNtError(Status);
325 return FALSE;
326 }
327
328 dc = DC_LockDc(hDC);
329 if (NULL == dc)
330 {
331 if (NULL != Dx)
332 {
333 ExFreePoolWithTag(Dx, TAG_GDITEXT);
334 }
335 ExFreePoolWithTag(String, TAG_GDITEXT);
336 SetLastWin32Error(ERROR_INVALID_HANDLE);
337 return FALSE;
338 }
339 pdcattr = dc->pdcattr;
340 TextObj = RealizeFontInit(pdcattr->hlfntNew);
341 if ( TextObj )
342 {
343 Result = TextIntGetTextExtentPoint( dc,
344 TextObj,
345 String,
346 Count,
347 MaxExtent,
348 NULL == UnsafeFit ? NULL : &Fit,
349 Dx,
350 &Size);
351 TEXTOBJ_UnlockText(TextObj);
352 }
353 else
354 Result = FALSE;
355 DC_UnlockDc(dc);
356
357 ExFreePoolWithTag(String, TAG_GDITEXT);
358 if (! Result)
359 {
360 if (NULL != Dx)
361 {
362 ExFreePoolWithTag(Dx, TAG_GDITEXT);
363 }
364 return FALSE;
365 }
366
367 if (NULL != UnsafeFit)
368 {
369 Status = MmCopyToCaller(UnsafeFit, &Fit, sizeof(INT));
370 if (! NT_SUCCESS(Status))
371 {
372 if (NULL != Dx)
373 {
374 ExFreePoolWithTag(Dx, TAG_GDITEXT);
375 }
376 SetLastNtError(Status);
377 return FALSE;
378 }
379 }
380
381 if (NULL != UnsafeDx)
382 {
383 Status = MmCopyToCaller(UnsafeDx, Dx, Count * sizeof(INT));
384 if (! NT_SUCCESS(Status))
385 {
386 if (NULL != Dx)
387 {
388 ExFreePoolWithTag(Dx, TAG_GDITEXT);
389 }
390 SetLastNtError(Status);
391 return FALSE;
392 }
393 }
394 if (NULL != Dx)
395 {
396 ExFreePoolWithTag(Dx,TAG_GDITEXT);
397 }
398
399 Status = MmCopyToCaller(UnsafeSize, &Size, sizeof(SIZE));
400 if (! NT_SUCCESS(Status))
401 {
402 SetLastNtError(Status);
403 return FALSE;
404 }
405
406 return TRUE;
407 }
408
409
410 /*
411 flOpts :
412 GetTextExtentPoint32W = 0
413 GetTextExtentPointW = 1
414 */
415 BOOL
416 APIENTRY
417 NtGdiGetTextExtent(HDC hdc,
418 LPWSTR lpwsz,
419 INT cwc,
420 LPSIZE psize,
421 UINT flOpts)
422 {
423 return NtGdiGetTextExtentExW(hdc, lpwsz, cwc, 0, NULL, NULL, psize, 0);
424 }
425
426 BOOL
427 APIENTRY
428 NtGdiSetTextJustification(HDC hDC,
429 int BreakExtra,
430 int BreakCount)
431 {
432 PDC pDc;
433 PDC_ATTR pdcattr;
434
435 pDc = DC_LockDc(hDC);
436 if (!pDc)
437 {
438 SetLastWin32Error(ERROR_INVALID_HANDLE);
439 return FALSE;
440 }
441
442 pdcattr = pDc->pdcattr;
443
444 pdcattr->lBreakExtra = BreakExtra;
445 pdcattr->cBreak = BreakCount;
446
447 DC_UnlockDc(pDc);
448 return TRUE;
449 }
450
451
452 W32KAPI
453 INT
454 APIENTRY
455 NtGdiGetTextFaceW(
456 IN HDC hDC,
457 IN INT Count,
458 OUT OPTIONAL LPWSTR FaceName,
459 IN BOOL bAliasName
460 )
461 {
462 PDC Dc;
463 PDC_ATTR pdcattr;
464 HFONT hFont;
465 PTEXTOBJ TextObj;
466 NTSTATUS Status;
467 INT fLen, ret;
468
469 /* FIXME: Handle bAliasName */
470
471 Dc = DC_LockDc(hDC);
472 if (Dc == NULL)
473 {
474 SetLastWin32Error(ERROR_INVALID_HANDLE);
475 return FALSE;
476 }
477 pdcattr = Dc->pdcattr;
478 hFont = pdcattr->hlfntNew;
479 DC_UnlockDc(Dc);
480
481 TextObj = RealizeFontInit(hFont);
482 ASSERT(TextObj != NULL);
483 fLen = wcslen(TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfFaceName) + 1;
484
485 if (FaceName != NULL)
486 {
487 Count = min(Count, fLen);
488 Status = MmCopyToCaller(FaceName, TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfFaceName, Count * sizeof(WCHAR));
489 if (!NT_SUCCESS(Status))
490 {
491 TEXTOBJ_UnlockText(TextObj);
492 SetLastNtError(Status);
493 return 0;
494 }
495 /* Terminate if we copied only part of the font name */
496 if (Count > 0 && Count < fLen)
497 {
498 FaceName[Count - 1] = '\0';
499 }
500 ret = Count;
501 }
502 else
503 {
504 ret = fLen;
505 }
506
507 TEXTOBJ_UnlockText(TextObj);
508 return ret;
509 }
510
511 W32KAPI
512 BOOL
513 APIENTRY
514 NtGdiGetTextMetricsW(
515 IN HDC hDC,
516 OUT TMW_INTERNAL * pUnsafeTmwi,
517 IN ULONG cj
518 )
519 {
520 TMW_INTERNAL Tmwi;
521 NTSTATUS Status = STATUS_SUCCESS;
522
523 if ( cj <= sizeof(TMW_INTERNAL) )
524 {
525 if (ftGdiGetTextMetricsW(hDC,&Tmwi))
526 {
527 _SEH2_TRY
528 {
529 ProbeForWrite(pUnsafeTmwi, cj, 1);
530 RtlCopyMemory(pUnsafeTmwi,&Tmwi,cj);
531 }
532 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
533 {
534 Status = _SEH2_GetExceptionCode();
535 }
536 _SEH2_END
537
538 if (!NT_SUCCESS(Status))
539 {
540 SetLastNtError(Status);
541 return FALSE;
542 }
543 return TRUE;
544 }
545 }
546 return FALSE;
547 }
548
549 /* EOF */