e434532fc4343cb5c414109a96ad3e4621d93287
[reactos.git] / reactos / dll / win32 / gdi32 / objects / text.c
1 #include "precomp.h"
2
3 #define NDEBUG
4 #include <debug.h>
5
6 /*
7 * @implemented
8 */
9 BOOL
10 WINAPI
11 TextOutA(
12 HDC hdc,
13 int nXStart,
14 int nYStart,
15 LPCSTR lpString,
16 int cchString)
17 {
18 ANSI_STRING StringA;
19 UNICODE_STRING StringU;
20 BOOL ret;
21
22 if (NULL != lpString)
23 {
24 RtlInitAnsiString(&StringA, (LPSTR)lpString);
25 RtlAnsiStringToUnicodeString(&StringU, &StringA, TRUE);
26 }
27 else
28 StringU.Buffer = NULL;
29
30 ret = TextOutW(hdc, nXStart, nYStart, StringU.Buffer, cchString);
31 RtlFreeUnicodeString(&StringU);
32 return ret;
33 }
34
35
36 /*
37 * @implemented
38 */
39 BOOL
40 WINAPI
41 TextOutW(
42 HDC hdc,
43 int nXStart,
44 int nYStart,
45 LPCWSTR lpString,
46 int cchString)
47 {
48 return NtGdiExtTextOutW(hdc, nXStart, nYStart, 0, NULL, (LPWSTR)lpString, cchString, NULL, 0);
49 }
50
51
52 /*
53 * @implemented
54 */
55 DWORD
56 WINAPI
57 GdiGetCodePage(HDC hdc)
58 {
59 PDC_ATTR Dc_Attr;
60 if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return 0;
61 if (Dc_Attr->ulDirty_ & DIRTY_CHARSET) return LOWORD(NtGdiGetCharSet(hdc));
62 return LOWORD(Dc_Attr->iCS_CP);
63 }
64
65
66 /*
67 * @unimplemented
68 */
69 int
70 WINAPI
71 GetTextCharacterExtra(
72 HDC hDc
73 )
74 {
75 PDC_ATTR Dc_Attr;
76
77 if (!GdiGetHandleUserData((HGDIOBJ) hDc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return 0;
78 return Dc_Attr->lTextExtra;
79 // return GetDCDWord( hDc, GdiGetTextCharExtra, 0);
80 }
81
82
83 /*
84 * @implemented
85 */
86 int
87 WINAPI
88 GetTextCharset(HDC hdc)
89 {
90 /* MSDN docs say this is equivalent */
91 return NtGdiGetTextCharsetInfo(hdc,NULL,0);
92 }
93
94
95
96 /*
97 * @implemented
98 */
99 BOOL
100 WINAPI
101 GetTextMetricsA(
102 HDC hdc,
103 LPTEXTMETRICA lptm
104 )
105 {
106 TMW_INTERNAL tmwi;
107
108 if (! NtGdiGetTextMetricsW(hdc, &tmwi, sizeof(TMW_INTERNAL)))
109 {
110 return FALSE;
111 }
112
113 FONT_TextMetricWToA(&tmwi.TextMetric, lptm);
114 return TRUE;
115 }
116
117
118 /*
119 * @implemented
120 */
121 BOOL
122 WINAPI
123 GetTextMetricsW(
124 HDC hdc,
125 LPTEXTMETRICW lptm
126 )
127 {
128 TMW_INTERNAL tmwi;
129
130 if (! NtGdiGetTextMetricsW(hdc, &tmwi, sizeof(TMW_INTERNAL)))
131 {
132 return FALSE;
133 }
134
135 *lptm = tmwi.TextMetric;
136 return TRUE;
137 }
138
139
140 /*
141 * @implemented
142 */
143 BOOL
144 APIENTRY
145 GetTextExtentPointA(
146 HDC hdc,
147 LPCSTR lpString,
148 int cchString,
149 LPSIZE lpSize
150 )
151 {
152 ANSI_STRING StringA;
153 UNICODE_STRING StringU;
154 BOOL ret;
155
156 RtlInitAnsiString(&StringA, (LPSTR)lpString);
157 RtlAnsiStringToUnicodeString(&StringU, &StringA, TRUE);
158
159 ret = GetTextExtentPointW(hdc, StringU.Buffer, cchString, lpSize);
160
161 RtlFreeUnicodeString(&StringU);
162
163 return ret;
164 }
165
166
167 /*
168 * @implemented
169 */
170 BOOL
171 APIENTRY
172 GetTextExtentPointW(
173 HDC hdc,
174 LPCWSTR lpString,
175 int cchString,
176 LPSIZE lpSize
177 )
178 {
179 return NtGdiGetTextExtent(hdc, (LPWSTR)lpString, cchString, lpSize, 0);
180 }
181
182
183 /*
184 * @implemented
185 */
186 BOOL
187 APIENTRY
188 GetTextExtentExPointW(
189 HDC hdc,
190 LPCWSTR lpszStr,
191 int cchString,
192 int nMaxExtent,
193 LPINT lpnFit,
194 LPINT alpDx,
195 LPSIZE lpSize
196 )
197 {
198
199 /* Windows doesn't check nMaxExtent validity in unicode version */
200 if(nMaxExtent < -1)
201 DPRINT("nMaxExtent is invalid: %d\n", nMaxExtent);
202
203 return NtGdiGetTextExtentExW (
204 hdc, (LPWSTR)lpszStr, cchString, nMaxExtent, (PULONG)lpnFit, (PULONG)alpDx, lpSize, 0 );
205 }
206
207
208 /*
209 * @implemented
210 */
211 BOOL
212 APIENTRY
213 GetTextExtentExPointA(
214 HDC hdc,
215 LPCSTR lpszStr,
216 int cchString,
217 int nMaxExtent,
218 LPINT lpnFit,
219 LPINT alpDx,
220 LPSIZE lpSize
221 )
222 {
223 NTSTATUS Status;
224 LPWSTR lpszStrW;
225 BOOL rc = 0;
226
227 if(nMaxExtent < -1)
228 {
229 SetLastError(ERROR_INVALID_PARAMETER);
230 return FALSE;
231 }
232
233 Status = HEAP_strdupA2W ( &lpszStrW, lpszStr );
234 if (!NT_SUCCESS (Status))
235 SetLastError (RtlNtStatusToDosError(Status));
236 else
237 {
238 rc = NtGdiGetTextExtentExW (
239 hdc, lpszStrW, cchString, nMaxExtent, (PULONG)lpnFit, (PULONG)alpDx, lpSize, 0 );
240
241 HEAP_free ( lpszStrW );
242 }
243
244 return rc;
245 }
246
247
248 /*
249 * @implemented
250 */
251 BOOL
252 APIENTRY
253 GetTextExtentPoint32A(
254 HDC hdc,
255 LPCSTR lpString,
256 int cchString,
257 LPSIZE lpSize
258 )
259 {
260 ANSI_STRING StringA;
261 UNICODE_STRING StringU;
262 BOOL ret;
263
264 RtlInitAnsiString(&StringA, (LPSTR)lpString);
265 RtlAnsiStringToUnicodeString(&StringU, &StringA, TRUE);
266
267 ret = GetTextExtentPoint32W(hdc, StringU.Buffer, cchString, lpSize);
268
269 RtlFreeUnicodeString(&StringU);
270
271 return ret;
272 }
273
274
275 /*
276 * @implemented
277 */
278 BOOL
279 APIENTRY
280 GetTextExtentPoint32W(
281 HDC hdc,
282 LPCWSTR lpString,
283 int cchString,
284 LPSIZE lpSize
285 )
286 {
287 return NtGdiGetTextExtent(hdc, (LPWSTR)lpString, cchString, lpSize, 0);
288 }
289
290 /*
291 * @implemented
292 */
293 BOOL
294 WINAPI
295 GetTextExtentExPointI(HDC hdc,
296 LPWORD pgiIn,
297 int cgi,
298 int nMaxExtent,
299 LPINT lpnFit,
300 LPINT alpDx,
301 LPSIZE lpSize)
302 {
303 return NtGdiGetTextExtentExW(hdc,pgiIn,cgi,nMaxExtent,(ULONG *)lpnFit, (PULONG) alpDx,lpSize,GTEF_INDICES);
304 }
305
306 /*
307 * @implemented
308 */
309 BOOL
310 WINAPI
311 GetTextExtentPointI(HDC hdc,
312 LPWORD pgiIn,
313 int cgi,
314 LPSIZE lpSize)
315 {
316 return NtGdiGetTextExtent(hdc,pgiIn,cgi,lpSize,GTEF_INDICES);
317 }
318
319 /*
320 * @implemented
321 */
322 BOOL
323 WINAPI
324 ExtTextOutA(
325 HDC hdc,
326 int X,
327 int Y,
328 UINT fuOptions,
329 CONST RECT *lprc,
330 LPCSTR lpString,
331 UINT cchString,
332 CONST INT *lpDx
333 )
334 {
335 ANSI_STRING StringA;
336 UNICODE_STRING StringU;
337 BOOL ret;
338
339 RtlInitAnsiString(&StringA, (LPSTR)lpString);
340 RtlAnsiStringToUnicodeString(&StringU, &StringA, TRUE);
341
342 ret = ExtTextOutW(hdc, X, Y, fuOptions, lprc, StringU.Buffer, cchString, lpDx);
343
344 RtlFreeUnicodeString(&StringU);
345
346 return ret;
347 }
348
349
350 /*
351 * @implemented
352 */
353 BOOL
354 WINAPI
355 ExtTextOutW(
356 HDC hdc,
357 int X,
358 int Y,
359 UINT fuOptions,
360 CONST RECT *lprc,
361 LPCWSTR lpString,
362 UINT cchString,
363 CONST INT *lpDx
364 )
365 {
366 return NtGdiExtTextOutW(hdc, X, Y, fuOptions, (LPRECT)lprc, (LPWSTR)lpString, cchString, (LPINT)lpDx, 0);
367 }
368
369
370 /*
371 * @implemented
372 */
373 INT
374 WINAPI
375 GetTextFaceW(HDC hDC,
376 INT nCount,
377 PWSTR pFaceName)
378 {
379 /* Validate parameters */
380 if (pFaceName && nCount <= 0)
381 {
382 /* Set last error and return failure */
383 GdiSetLastError(ERROR_INVALID_PARAMETER);
384 return 0;
385 }
386
387 /* Forward to kernel */
388 return NtGdiGetTextFaceW(hDC, nCount, pFaceName, FALSE);
389 }
390
391
392 /*
393 * @implemented
394 */
395 int
396 WINAPI
397 GetTextFaceA( HDC hdc, INT count, LPSTR name )
398 {
399 INT res;
400 LPWSTR nameW;
401
402 /* Validate parameters */
403 if (name && count <= 0)
404 {
405 /* Set last error and return failure */
406 GdiSetLastError(ERROR_INVALID_PARAMETER);
407 return 0;
408 }
409
410 res = GetTextFaceW(hdc, 0, NULL);
411 nameW = HeapAlloc( GetProcessHeap(), 0, res * 2 );
412 if (nameW == NULL)
413 {
414 return 0;
415 }
416 GetTextFaceW( hdc, res, nameW );
417
418 if (name)
419 {
420 if (count && !WideCharToMultiByte( CP_ACP, 0, nameW, -1, name, count, NULL, NULL))
421 name[count-1] = 0;
422 res = strlen(name);
423 }
424 else
425 res = WideCharToMultiByte( CP_ACP, 0, nameW, -1, NULL, 0, NULL, NULL);
426 HeapFree( GetProcessHeap(), 0, nameW );
427 return res;
428 }
429
430
431 /*
432 * @implemented
433 */
434 INT
435 WINAPI
436 GetTextFaceAliasW(HDC hdc,
437 int cChar,
438 LPWSTR pszOut)
439 {
440 if ( pszOut && !cChar )
441 {
442 GdiSetLastError(ERROR_INVALID_PARAMETER);
443 return 0;
444 }
445 return NtGdiGetTextFaceW(hdc,cChar,pszOut,TRUE);
446 }
447
448
449 BOOL
450 WINAPI
451 GetFontResourceInfoW(
452 LPCWSTR lpFileName,
453 DWORD *pdwBufSize,
454 void* lpBuffer,
455 DWORD dwType
456 )
457 {
458 BOOL bRet;
459 UNICODE_STRING NtFileName;
460
461 if (!lpFileName || !pdwBufSize || !lpBuffer)
462 {
463 SetLastError(ERROR_INVALID_PARAMETER);
464 return FALSE;
465 }
466
467 if (!RtlDosPathNameToNtPathName_U(lpFileName,
468 &NtFileName,
469 NULL,
470 NULL))
471 {
472 SetLastError(ERROR_PATH_NOT_FOUND);
473 return FALSE;
474 }
475
476 bRet = NtGdiGetFontResourceInfoInternalW(
477 NtFileName.Buffer,
478 (NtFileName.Length / sizeof(WCHAR)) + 1,
479 1,
480 *pdwBufSize,
481 pdwBufSize,
482 lpBuffer,
483 dwType);
484
485 RtlFreeHeap(RtlGetProcessHeap(), 0, NtFileName.Buffer);
486
487 if (!bRet)
488 {
489 return FALSE;
490 }
491
492 return TRUE;
493 }
494
495
496 /*
497 * @unimplemented
498 */
499 int
500 WINAPI
501 SetTextCharacterExtra(
502 HDC hDC,
503 int CharExtra
504 )
505 {
506 INT cExtra = 0x80000000;
507 PDC_ATTR Dc_Attr;
508
509 if (CharExtra == cExtra)
510 {
511 SetLastError(ERROR_INVALID_PARAMETER);
512 return cExtra;
513 }
514 #if 0
515 if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC)
516 {
517 return MFDRV_SetTextCharacterExtra( hDC, CharExtra ); // Wine port.
518 }
519 #endif
520 if (!GdiGetHandleUserData((HGDIOBJ) hDC, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return cExtra;
521
522 if (NtCurrentTeb()->GdiTebBatch.HDC == hDC)
523 {
524 if (Dc_Attr->ulDirty_ & DC_FONTTEXT_DIRTY)
525 {
526 NtGdiFlush(); // Sync up Dc_Attr from Kernel space.
527 Dc_Attr->ulDirty_ &= ~(DC_MODE_DIRTY|DC_FONTTEXT_DIRTY);
528 }
529 }
530 cExtra = Dc_Attr->lTextExtra;
531 Dc_Attr->lTextExtra = CharExtra;
532 return cExtra;
533 // return GetAndSetDCDWord( hDC, GdiGetSetTextCharExtra, CharExtra, 0, 0, 0 );
534 }
535
536 /*
537 * @implemented
538 *
539 */
540 UINT
541 WINAPI
542 GetTextAlign(HDC hdc)
543 {
544 PDC_ATTR Dc_Attr;
545 if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return 0;
546 return Dc_Attr->lTextAlign;
547 }
548
549
550 /*
551 * @implemented
552 *
553 */
554 COLORREF
555 WINAPI
556 GetTextColor(HDC hdc)
557 {
558 PDC_ATTR Dc_Attr;
559 if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return 0;
560 return Dc_Attr->ulForegroundClr;
561 }
562
563
564
565 /*
566 * @unimplemented
567 */
568 UINT
569 WINAPI
570 SetTextAlign(HDC hdc,
571 UINT fMode)
572 {
573 PDC_ATTR Dc_Attr;
574 INT OldMode = 0;
575 #if 0
576 if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC)
577 {
578 if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC)
579 return MFDRV_SetTextAlign( hdc, fMode )
580 else
581 {
582 PLDC pLDC = Dc_Attr->pvLDC;
583 if ( !pLDC )
584 {
585 SetLastError(ERROR_INVALID_HANDLE);
586 return FALSE;
587 }
588 if (pLDC->iType == LDC_EMFLDC)
589 {
590 if return EMFDRV_SetTextAlign( hdc, fMode )
591 }
592 }
593 }
594 #endif
595 if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return OldMode;
596
597 OldMode = Dc_Attr->lTextAlign;
598 Dc_Attr->lTextAlign = fMode; // Raw
599 if (Dc_Attr->dwLayout & LAYOUT_RTL)
600 {
601 if(!(fMode & TA_CENTER)) fMode |= TA_RIGHT;
602 }
603 Dc_Attr->flTextAlign = fMode & (TA_BASELINE|TA_UPDATECP|TA_CENTER);
604 return OldMode;
605
606 }
607
608
609 /*
610 * @implemented
611 */
612 COLORREF
613 WINAPI
614 SetTextColor(
615 HDC hdc,
616 COLORREF crColor
617 )
618 {
619 PDC_ATTR Dc_Attr;
620 COLORREF OldColor = CLR_INVALID;
621 #if 0
622 if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC)
623 {
624 if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC)
625 return MFDRV_SetTextColor( hDC, crColor );
626 else
627 {
628 PLDC pLDC = Dc_Attr->pvLDC;
629 if ( !pLDC )
630 {
631 SetLastError(ERROR_INVALID_HANDLE);
632 return FALSE;
633 }
634 if (pLDC->iType == LDC_EMFLDC)
635 {
636 if return EMFDRV_SetTextColor( hDC, crColor );
637 }
638 }
639 }
640 #endif
641 if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return OldColor;
642
643 OldColor = (COLORREF) Dc_Attr->ulForegroundClr;
644 Dc_Attr->ulForegroundClr = (ULONG) crColor;
645
646 if ( Dc_Attr->crForegroundClr != crColor )
647 {
648 Dc_Attr->ulDirty_ |= (DIRTY_TEXT|DIRTY_LINE|DIRTY_FILL);
649 Dc_Attr->crForegroundClr = crColor;
650 }
651 return OldColor;
652 }
653
654 /*
655 * @implemented
656 */
657 BOOL
658 WINAPI
659 SetTextJustification(
660 HDC hdc,
661 int extra,
662 int breaks
663 )
664 {
665 PDC_ATTR Dc_Attr;
666 #if 0
667 if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC)
668 {
669 if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC)
670 return MFDRV_SetTextJustification( hdc, extra, breaks )
671 else
672 {
673 SetLastError(ERROR_INVALID_HANDLE);
674 return FALSE;
675 }
676 #endif
677 if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return FALSE;
678
679 if (NtCurrentTeb()->GdiTebBatch.HDC == hdc)
680 {
681 if (Dc_Attr->ulDirty_ & DC_FONTTEXT_DIRTY)
682 {
683 NtGdiFlush(); // Sync up Dc_Attr from Kernel space.
684 Dc_Attr->ulDirty_ &= ~(DC_MODE_DIRTY|DC_FONTTEXT_DIRTY);
685 }
686 }
687 Dc_Attr->cBreak = breaks;
688 Dc_Attr->lBreakExtra = extra;
689 return TRUE;
690 }