[GDI32]
[reactos.git] / reactos / win32ss / gdi / 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 * @unimplemented
54 */
55 BOOL
56 WINAPI
57 PolyTextOutA( HDC hdc, const POLYTEXTA *pptxt, INT cStrings )
58 {
59 for (; cStrings>0; cStrings--, pptxt++)
60 if (!ExtTextOutA( hdc, pptxt->x, pptxt->y, pptxt->uiFlags, &pptxt->rcl, pptxt->lpstr, pptxt->n, pptxt->pdx ))
61 return FALSE;
62 return TRUE;
63 }
64
65
66 /*
67 * @unimplemented
68 */
69 BOOL
70 WINAPI
71 PolyTextOutW( HDC hdc, const POLYTEXTW *pptxt, INT cStrings )
72 {
73 for (; cStrings>0; cStrings--, pptxt++)
74 if (!ExtTextOutW( hdc, pptxt->x, pptxt->y, pptxt->uiFlags, &pptxt->rcl, pptxt->lpstr, pptxt->n, pptxt->pdx ))
75 return FALSE;
76 return TRUE;
77 }
78
79
80 /*
81 * @implemented
82 */
83 DWORD
84 WINAPI
85 GdiGetCodePage(HDC hdc)
86 {
87 PDC_ATTR Dc_Attr;
88 if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return 0;
89 if (Dc_Attr->ulDirty_ & DIRTY_CHARSET) return LOWORD(NtGdiGetCharSet(hdc));
90 return LOWORD(Dc_Attr->iCS_CP);
91 }
92
93
94 /*
95 * @unimplemented
96 */
97 int
98 WINAPI
99 GetTextCharacterExtra(
100 HDC hDc
101 )
102 {
103 PDC_ATTR Dc_Attr;
104
105 if (!GdiGetHandleUserData((HGDIOBJ) hDc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return 0;
106 return Dc_Attr->lTextExtra;
107 // return GetDCDWord( hDc, GdiGetTextCharExtra, 0);
108 }
109
110
111 /*
112 * @implemented
113 */
114 int
115 WINAPI
116 GetTextCharset(HDC hdc)
117 {
118 /* MSDN docs say this is equivalent */
119 return NtGdiGetTextCharsetInfo(hdc,NULL,0);
120 }
121
122
123
124 /*
125 * @implemented
126 */
127 BOOL
128 WINAPI
129 GetTextMetricsA(
130 HDC hdc,
131 LPTEXTMETRICA lptm
132 )
133 {
134 TMW_INTERNAL tmwi;
135
136 if (! NtGdiGetTextMetricsW(hdc, &tmwi, sizeof(TMW_INTERNAL)))
137 {
138 return FALSE;
139 }
140
141 FONT_TextMetricWToA(&tmwi.TextMetric, lptm);
142 return TRUE;
143 }
144
145
146 /*
147 * @implemented
148 */
149 BOOL
150 WINAPI
151 GetTextMetricsW(
152 HDC hdc,
153 LPTEXTMETRICW lptm
154 )
155 {
156 TMW_INTERNAL tmwi;
157
158 if (! NtGdiGetTextMetricsW(hdc, &tmwi, sizeof(TMW_INTERNAL)))
159 {
160 return FALSE;
161 }
162
163 *lptm = tmwi.TextMetric;
164 return TRUE;
165 }
166
167
168 /*
169 * @implemented
170 */
171 BOOL
172 APIENTRY
173 GetTextExtentPointA(
174 HDC hdc,
175 LPCSTR lpString,
176 int cchString,
177 LPSIZE lpSize
178 )
179 {
180 ANSI_STRING StringA;
181 UNICODE_STRING StringU;
182 BOOL ret;
183
184 RtlInitAnsiString(&StringA, (LPSTR)lpString);
185 RtlAnsiStringToUnicodeString(&StringU, &StringA, TRUE);
186
187 ret = GetTextExtentPointW(hdc, StringU.Buffer, cchString, lpSize);
188
189 RtlFreeUnicodeString(&StringU);
190
191 return ret;
192 }
193
194
195 /*
196 * @implemented
197 */
198 BOOL
199 APIENTRY
200 GetTextExtentPointW(
201 HDC hdc,
202 LPCWSTR lpString,
203 int cchString,
204 LPSIZE lpSize
205 )
206 {
207 return NtGdiGetTextExtent(hdc, (LPWSTR)lpString, cchString, lpSize, 0);
208 }
209
210
211 /*
212 * @implemented
213 */
214 BOOL
215 APIENTRY
216 GetTextExtentExPointW(
217 HDC hdc,
218 LPCWSTR lpszStr,
219 int cchString,
220 int nMaxExtent,
221 LPINT lpnFit,
222 LPINT alpDx,
223 LPSIZE lpSize
224 )
225 {
226
227 /* Windows doesn't check nMaxExtent validity in unicode version */
228 if(nMaxExtent < -1)
229 DPRINT("nMaxExtent is invalid: %d\n", nMaxExtent);
230
231 return NtGdiGetTextExtentExW (
232 hdc, (LPWSTR)lpszStr, cchString, nMaxExtent, (PULONG)lpnFit, (PULONG)alpDx, lpSize, 0 );
233 }
234
235
236 /*
237 * @implemented
238 */
239 BOOL
240 WINAPI
241 GetTextExtentExPointWPri(HDC hdc,
242 LPWSTR lpwsz,
243 ULONG cwc,
244 ULONG dxMax,
245 ULONG *pcCh,
246 PULONG pdxOut,
247 LPSIZE psize)
248 {
249 return NtGdiGetTextExtentExW(hdc,lpwsz,cwc,dxMax,pcCh,pdxOut,psize,0);
250 }
251
252 /*
253 * @implemented
254 */
255 BOOL
256 APIENTRY
257 GetTextExtentExPointA(
258 HDC hdc,
259 LPCSTR lpszStr,
260 int cchString,
261 int nMaxExtent,
262 LPINT lpnFit,
263 LPINT alpDx,
264 LPSIZE lpSize
265 )
266 {
267 NTSTATUS Status;
268 LPWSTR lpszStrW;
269 BOOL rc = 0;
270
271 if(nMaxExtent < -1)
272 {
273 SetLastError(ERROR_INVALID_PARAMETER);
274 return FALSE;
275 }
276
277 Status = HEAP_strdupA2W ( &lpszStrW, lpszStr );
278 if (!NT_SUCCESS (Status))
279 SetLastError (RtlNtStatusToDosError(Status));
280 else
281 {
282 rc = NtGdiGetTextExtentExW (
283 hdc, lpszStrW, cchString, nMaxExtent, (PULONG)lpnFit, (PULONG)alpDx, lpSize, 0 );
284
285 HEAP_free ( lpszStrW );
286 }
287
288 return rc;
289 }
290
291
292 /*
293 * @implemented
294 */
295 BOOL
296 APIENTRY
297 GetTextExtentPoint32A(
298 HDC hdc,
299 LPCSTR lpString,
300 int cchString,
301 LPSIZE lpSize
302 )
303 {
304 ANSI_STRING StringA;
305 UNICODE_STRING StringU;
306 BOOL ret;
307
308 StringA.Buffer = (LPSTR)lpString;
309 StringA.Length = cchString;
310 RtlAnsiStringToUnicodeString(&StringU, &StringA, TRUE);
311
312 ret = GetTextExtentPoint32W(hdc, StringU.Buffer, cchString, lpSize);
313
314 RtlFreeUnicodeString(&StringU);
315
316 return ret;
317 }
318
319
320 /*
321 * @implemented
322 */
323 BOOL
324 APIENTRY
325 GetTextExtentPoint32W(
326 HDC hdc,
327 LPCWSTR lpString,
328 int cchString,
329 LPSIZE lpSize
330 )
331 {
332 return NtGdiGetTextExtent(hdc, (LPWSTR)lpString, cchString, lpSize, 0);
333 }
334
335 /*
336 * @implemented
337 */
338 BOOL
339 WINAPI
340 GetTextExtentExPointI(HDC hdc,
341 LPWORD pgiIn,
342 int cgi,
343 int nMaxExtent,
344 LPINT lpnFit,
345 LPINT alpDx,
346 LPSIZE lpSize)
347 {
348 return NtGdiGetTextExtentExW(hdc,pgiIn,cgi,nMaxExtent,(ULONG *)lpnFit, (PULONG) alpDx,lpSize,GTEF_INDICES);
349 }
350
351 /*
352 * @implemented
353 */
354 BOOL
355 WINAPI
356 GetTextExtentPointI(HDC hdc,
357 LPWORD pgiIn,
358 int cgi,
359 LPSIZE lpSize)
360 {
361 return NtGdiGetTextExtent(hdc,pgiIn,cgi,lpSize,GTEF_INDICES);
362 }
363
364 /*
365 * @implemented
366 */
367 BOOL
368 WINAPI
369 ExtTextOutA(
370 HDC hdc,
371 int X,
372 int Y,
373 UINT fuOptions,
374 CONST RECT *lprc,
375 LPCSTR lpString,
376 UINT cchString,
377 CONST INT *lpDx
378 )
379 {
380 ANSI_STRING StringA;
381 UNICODE_STRING StringU;
382 BOOL ret;
383
384 RtlInitAnsiString(&StringA, (LPSTR)lpString);
385 RtlAnsiStringToUnicodeString(&StringU, &StringA, TRUE);
386
387 ret = ExtTextOutW(hdc, X, Y, fuOptions, lprc, StringU.Buffer, cchString, lpDx);
388
389 RtlFreeUnicodeString(&StringU);
390
391 return ret;
392 }
393
394
395 /*
396 * @implemented
397 */
398 BOOL
399 WINAPI
400 ExtTextOutW(
401 HDC hdc,
402 int X,
403 int Y,
404 UINT fuOptions,
405 CONST RECT *lprc,
406 LPCWSTR lpString,
407 UINT cchString,
408 CONST INT *lpDx
409 )
410 {
411 return NtGdiExtTextOutW(hdc, X, Y, fuOptions, (LPRECT)lprc, (LPWSTR)lpString, cchString, (LPINT)lpDx, 0);
412 }
413
414
415 /*
416 * @implemented
417 */
418 INT
419 WINAPI
420 GetTextFaceW(HDC hDC,
421 INT nCount,
422 PWSTR pFaceName)
423 {
424 /* Validate parameters */
425 if (pFaceName && nCount <= 0)
426 {
427 /* Set last error and return failure */
428 GdiSetLastError(ERROR_INVALID_PARAMETER);
429 return 0;
430 }
431
432 /* Forward to kernel */
433 return NtGdiGetTextFaceW(hDC, nCount, pFaceName, FALSE);
434 }
435
436
437 /*
438 * @implemented
439 */
440 int
441 WINAPI
442 GetTextFaceA( HDC hdc, INT count, LPSTR name )
443 {
444 INT res;
445 LPWSTR nameW;
446
447 /* Validate parameters */
448 if (name && count <= 0)
449 {
450 /* Set last error and return failure */
451 GdiSetLastError(ERROR_INVALID_PARAMETER);
452 return 0;
453 }
454
455 res = GetTextFaceW(hdc, 0, NULL);
456 nameW = HeapAlloc( GetProcessHeap(), 0, res * 2 );
457 if (nameW == NULL)
458 {
459 return 0;
460 }
461 GetTextFaceW( hdc, res, nameW );
462
463 if (name)
464 {
465 if (count && !WideCharToMultiByte( CP_ACP, 0, nameW, -1, name, count, NULL, NULL))
466 name[count-1] = 0;
467 res = strlen(name);
468 }
469 else
470 res = WideCharToMultiByte( CP_ACP, 0, nameW, -1, NULL, 0, NULL, NULL);
471 HeapFree( GetProcessHeap(), 0, nameW );
472 return res;
473 }
474
475
476 /*
477 * @implemented
478 */
479 INT
480 WINAPI
481 GetTextFaceAliasW(HDC hdc,
482 int cChar,
483 LPWSTR pszOut)
484 {
485 if ( pszOut && !cChar )
486 {
487 GdiSetLastError(ERROR_INVALID_PARAMETER);
488 return 0;
489 }
490 return NtGdiGetTextFaceW(hdc,cChar,pszOut,TRUE);
491 }
492
493
494 BOOL
495 WINAPI
496 GetFontResourceInfoW(
497 LPCWSTR lpFileName,
498 DWORD *pdwBufSize,
499 void* lpBuffer,
500 DWORD dwType
501 )
502 {
503 BOOL bRet;
504 UNICODE_STRING NtFileName;
505
506 if (!lpFileName || !pdwBufSize || !lpBuffer)
507 {
508 SetLastError(ERROR_INVALID_PARAMETER);
509 return FALSE;
510 }
511
512 if (!RtlDosPathNameToNtPathName_U(lpFileName,
513 &NtFileName,
514 NULL,
515 NULL))
516 {
517 SetLastError(ERROR_PATH_NOT_FOUND);
518 return FALSE;
519 }
520
521 bRet = NtGdiGetFontResourceInfoInternalW(
522 NtFileName.Buffer,
523 (NtFileName.Length / sizeof(WCHAR)) + 1,
524 1,
525 *pdwBufSize,
526 pdwBufSize,
527 lpBuffer,
528 dwType);
529
530 RtlFreeHeap(RtlGetProcessHeap(), 0, NtFileName.Buffer);
531
532 if (!bRet)
533 {
534 return FALSE;
535 }
536
537 return TRUE;
538 }
539
540
541 /*
542 * @unimplemented
543 */
544 int
545 WINAPI
546 SetTextCharacterExtra(
547 HDC hDC,
548 int CharExtra
549 )
550 {
551 INT cExtra = 0x80000000;
552 PDC_ATTR Dc_Attr;
553
554 if (CharExtra == cExtra)
555 {
556 SetLastError(ERROR_INVALID_PARAMETER);
557 return cExtra;
558 }
559 #if 0
560 if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC)
561 {
562 return MFDRV_SetTextCharacterExtra( hDC, CharExtra ); // Wine port.
563 }
564 #endif
565 if (!GdiGetHandleUserData((HGDIOBJ) hDC, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return cExtra;
566
567 if (NtCurrentTeb()->GdiTebBatch.HDC == hDC)
568 {
569 if (Dc_Attr->ulDirty_ & DC_FONTTEXT_DIRTY)
570 {
571 NtGdiFlush(); // Sync up Dc_Attr from Kernel space.
572 Dc_Attr->ulDirty_ &= ~(DC_MODE_DIRTY|DC_FONTTEXT_DIRTY);
573 }
574 }
575 cExtra = Dc_Attr->lTextExtra;
576 Dc_Attr->lTextExtra = CharExtra;
577 return cExtra;
578 // return GetAndSetDCDWord( hDC, GdiGetSetTextCharExtra, CharExtra, 0, 0, 0 );
579 }
580
581 /*
582 * @implemented
583 *
584 */
585 UINT
586 WINAPI
587 GetTextAlign(HDC hdc)
588 {
589 PDC_ATTR Dc_Attr;
590 if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return 0;
591 return Dc_Attr->lTextAlign;
592 }
593
594
595 /*
596 * @implemented
597 *
598 */
599 COLORREF
600 WINAPI
601 GetTextColor(HDC hdc)
602 {
603 PDC_ATTR Dc_Attr;
604 if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return 0;
605 return Dc_Attr->ulForegroundClr;
606 }
607
608
609
610 /*
611 * @unimplemented
612 */
613 UINT
614 WINAPI
615 SetTextAlign(HDC hdc,
616 UINT fMode)
617 {
618 PDC_ATTR Dc_Attr;
619 INT OldMode;
620 #if 0
621 if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC)
622 {
623 if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC)
624 return MFDRV_SetTextAlign( hdc, fMode )
625 else
626 {
627 PLDC pLDC = Dc_Attr->pvLDC;
628 if ( !pLDC )
629 {
630 SetLastError(ERROR_INVALID_HANDLE);
631 return FALSE;
632 }
633 if (pLDC->iType == LDC_EMFLDC)
634 {
635 if return EMFDRV_SetTextAlign( hdc, fMode )
636 }
637 }
638 }
639 #endif
640 if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return GDI_ERROR;
641
642 OldMode = Dc_Attr->lTextAlign;
643 Dc_Attr->lTextAlign = fMode; // Raw
644 if (Dc_Attr->dwLayout & LAYOUT_RTL)
645 {
646 if ((fMode & TA_CENTER) != TA_CENTER) fMode ^= TA_RIGHT;
647 }
648 Dc_Attr->flTextAlign = fMode & TA_MASK;
649 return OldMode;
650 }
651
652
653 /*
654 * @implemented
655 */
656 COLORREF
657 WINAPI
658 SetTextColor(
659 HDC hdc,
660 COLORREF crColor
661 )
662 {
663 PDC_ATTR Dc_Attr;
664 COLORREF OldColor = CLR_INVALID;
665 #if 0
666 if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC)
667 {
668 if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC)
669 return MFDRV_SetTextColor( hDC, crColor );
670 else
671 {
672 PLDC pLDC = Dc_Attr->pvLDC;
673 if ( !pLDC )
674 {
675 SetLastError(ERROR_INVALID_HANDLE);
676 return FALSE;
677 }
678 if (pLDC->iType == LDC_EMFLDC)
679 {
680 if return EMFDRV_SetTextColor( hDC, crColor );
681 }
682 }
683 }
684 #endif
685 if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return OldColor;
686
687 OldColor = (COLORREF) Dc_Attr->ulForegroundClr;
688 Dc_Attr->ulForegroundClr = (ULONG) crColor;
689
690 if ( Dc_Attr->crForegroundClr != crColor )
691 {
692 Dc_Attr->ulDirty_ |= (DIRTY_TEXT|DIRTY_LINE|DIRTY_FILL);
693 Dc_Attr->crForegroundClr = crColor;
694 }
695 return OldColor;
696 }
697
698 /*
699 * @implemented
700 */
701 BOOL
702 WINAPI
703 SetTextJustification(
704 HDC hdc,
705 int extra,
706 int breaks
707 )
708 {
709 PDC_ATTR Dc_Attr;
710 #if 0
711 if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC)
712 {
713 if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC)
714 return MFDRV_SetTextJustification( hdc, extra, breaks )
715 else
716 {
717 SetLastError(ERROR_INVALID_HANDLE);
718 return FALSE;
719 }
720 #endif
721 if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return FALSE;
722
723 if (NtCurrentTeb()->GdiTebBatch.HDC == hdc)
724 {
725 if (Dc_Attr->ulDirty_ & DC_FONTTEXT_DIRTY)
726 {
727 NtGdiFlush(); // Sync up Dc_Attr from Kernel space.
728 Dc_Attr->ulDirty_ &= ~(DC_MODE_DIRTY|DC_FONTTEXT_DIRTY);
729 }
730 }
731 Dc_Attr->cBreak = breaks;
732 Dc_Attr->lBreakExtra = extra;
733 return TRUE;
734 }
735
736 /*
737 * @implemented
738 */
739 UINT
740 WINAPI
741 GetStringBitmapA(HDC hdc,
742 LPSTR psz,
743 BOOL DoCall,
744 UINT cj,
745 BYTE *lpSB)
746 {
747
748 NTSTATUS Status;
749 PWSTR pwsz;
750 UINT retValue = 0;
751
752 if (DoCall)
753 {
754 Status = HEAP_strdupA2W ( &pwsz, psz );
755 if ( !NT_SUCCESS (Status) )
756 {
757 SetLastError (RtlNtStatusToDosError(Status));
758 }
759 else
760 {
761 retValue = NtGdiGetStringBitmapW(hdc, pwsz, 1, lpSB, cj);
762 HEAP_free ( pwsz );
763 }
764 }
765
766 return retValue;
767
768 }
769
770 /*
771 * @implemented
772 */
773 UINT
774 WINAPI
775 GetStringBitmapW(HDC hdc,
776 LPWSTR pwsz,
777 BOOL doCall,
778 UINT cj,
779 BYTE *lpSB)
780 {
781 UINT retValue = 0;
782
783 if (doCall)
784 {
785 retValue = NtGdiGetStringBitmapW(hdc, pwsz, 1, lpSB, cj);
786 }
787
788 return retValue;
789
790 }
791
792 /*
793 * @implemented
794 */
795 BOOL
796 WINAPI
797 GetETM(HDC hdc,
798 EXTTEXTMETRIC *petm)
799 {
800 BOOL Ret = NtGdiGetETM(hdc, petm);
801
802 if (Ret && petm)
803 petm->emKernPairs = (WORD)GetKerningPairsA(hdc, 0, 0);
804
805 return Ret;
806 }