[GDI32]
[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 StringA.Buffer = (LPSTR)lpString;
265 StringA.Length = cchString;
266 RtlAnsiStringToUnicodeString(&StringU, &StringA, TRUE);
267
268 ret = GetTextExtentPoint32W(hdc, StringU.Buffer, cchString, lpSize);
269
270 RtlFreeUnicodeString(&StringU);
271
272 return ret;
273 }
274
275
276 /*
277 * @implemented
278 */
279 BOOL
280 APIENTRY
281 GetTextExtentPoint32W(
282 HDC hdc,
283 LPCWSTR lpString,
284 int cchString,
285 LPSIZE lpSize
286 )
287 {
288 return NtGdiGetTextExtent(hdc, (LPWSTR)lpString, cchString, lpSize, 0);
289 }
290
291 /*
292 * @implemented
293 */
294 BOOL
295 WINAPI
296 GetTextExtentExPointI(HDC hdc,
297 LPWORD pgiIn,
298 int cgi,
299 int nMaxExtent,
300 LPINT lpnFit,
301 LPINT alpDx,
302 LPSIZE lpSize)
303 {
304 return NtGdiGetTextExtentExW(hdc,pgiIn,cgi,nMaxExtent,(ULONG *)lpnFit, (PULONG) alpDx,lpSize,GTEF_INDICES);
305 }
306
307 /*
308 * @implemented
309 */
310 BOOL
311 WINAPI
312 GetTextExtentPointI(HDC hdc,
313 LPWORD pgiIn,
314 int cgi,
315 LPSIZE lpSize)
316 {
317 return NtGdiGetTextExtent(hdc,pgiIn,cgi,lpSize,GTEF_INDICES);
318 }
319
320 /*
321 * @implemented
322 */
323 BOOL
324 WINAPI
325 ExtTextOutA(
326 HDC hdc,
327 int X,
328 int Y,
329 UINT fuOptions,
330 CONST RECT *lprc,
331 LPCSTR lpString,
332 UINT cchString,
333 CONST INT *lpDx
334 )
335 {
336 ANSI_STRING StringA;
337 UNICODE_STRING StringU;
338 BOOL ret;
339
340 RtlInitAnsiString(&StringA, (LPSTR)lpString);
341 RtlAnsiStringToUnicodeString(&StringU, &StringA, TRUE);
342
343 ret = ExtTextOutW(hdc, X, Y, fuOptions, lprc, StringU.Buffer, cchString, lpDx);
344
345 RtlFreeUnicodeString(&StringU);
346
347 return ret;
348 }
349
350
351 /*
352 * @implemented
353 */
354 BOOL
355 WINAPI
356 ExtTextOutW(
357 HDC hdc,
358 int X,
359 int Y,
360 UINT fuOptions,
361 CONST RECT *lprc,
362 LPCWSTR lpString,
363 UINT cchString,
364 CONST INT *lpDx
365 )
366 {
367 return NtGdiExtTextOutW(hdc, X, Y, fuOptions, (LPRECT)lprc, (LPWSTR)lpString, cchString, (LPINT)lpDx, 0);
368 }
369
370
371 /*
372 * @implemented
373 */
374 INT
375 WINAPI
376 GetTextFaceW(HDC hDC,
377 INT nCount,
378 PWSTR pFaceName)
379 {
380 /* Validate parameters */
381 if (pFaceName && nCount <= 0)
382 {
383 /* Set last error and return failure */
384 GdiSetLastError(ERROR_INVALID_PARAMETER);
385 return 0;
386 }
387
388 /* Forward to kernel */
389 return NtGdiGetTextFaceW(hDC, nCount, pFaceName, FALSE);
390 }
391
392
393 /*
394 * @implemented
395 */
396 int
397 WINAPI
398 GetTextFaceA( HDC hdc, INT count, LPSTR name )
399 {
400 INT res;
401 LPWSTR nameW;
402
403 /* Validate parameters */
404 if (name && count <= 0)
405 {
406 /* Set last error and return failure */
407 GdiSetLastError(ERROR_INVALID_PARAMETER);
408 return 0;
409 }
410
411 res = GetTextFaceW(hdc, 0, NULL);
412 nameW = HeapAlloc( GetProcessHeap(), 0, res * 2 );
413 if (nameW == NULL)
414 {
415 return 0;
416 }
417 GetTextFaceW( hdc, res, nameW );
418
419 if (name)
420 {
421 if (count && !WideCharToMultiByte( CP_ACP, 0, nameW, -1, name, count, NULL, NULL))
422 name[count-1] = 0;
423 res = strlen(name);
424 }
425 else
426 res = WideCharToMultiByte( CP_ACP, 0, nameW, -1, NULL, 0, NULL, NULL);
427 HeapFree( GetProcessHeap(), 0, nameW );
428 return res;
429 }
430
431
432 /*
433 * @implemented
434 */
435 INT
436 WINAPI
437 GetTextFaceAliasW(HDC hdc,
438 int cChar,
439 LPWSTR pszOut)
440 {
441 if ( pszOut && !cChar )
442 {
443 GdiSetLastError(ERROR_INVALID_PARAMETER);
444 return 0;
445 }
446 return NtGdiGetTextFaceW(hdc,cChar,pszOut,TRUE);
447 }
448
449
450 BOOL
451 WINAPI
452 GetFontResourceInfoW(
453 LPCWSTR lpFileName,
454 DWORD *pdwBufSize,
455 void* lpBuffer,
456 DWORD dwType
457 )
458 {
459 BOOL bRet;
460 UNICODE_STRING NtFileName;
461
462 if (!lpFileName || !pdwBufSize || !lpBuffer)
463 {
464 SetLastError(ERROR_INVALID_PARAMETER);
465 return FALSE;
466 }
467
468 if (!RtlDosPathNameToNtPathName_U(lpFileName,
469 &NtFileName,
470 NULL,
471 NULL))
472 {
473 SetLastError(ERROR_PATH_NOT_FOUND);
474 return FALSE;
475 }
476
477 bRet = NtGdiGetFontResourceInfoInternalW(
478 NtFileName.Buffer,
479 (NtFileName.Length / sizeof(WCHAR)) + 1,
480 1,
481 *pdwBufSize,
482 pdwBufSize,
483 lpBuffer,
484 dwType);
485
486 RtlFreeHeap(RtlGetProcessHeap(), 0, NtFileName.Buffer);
487
488 if (!bRet)
489 {
490 return FALSE;
491 }
492
493 return TRUE;
494 }
495
496
497 /*
498 * @unimplemented
499 */
500 int
501 WINAPI
502 SetTextCharacterExtra(
503 HDC hDC,
504 int CharExtra
505 )
506 {
507 INT cExtra = 0x80000000;
508 PDC_ATTR Dc_Attr;
509
510 if (CharExtra == cExtra)
511 {
512 SetLastError(ERROR_INVALID_PARAMETER);
513 return cExtra;
514 }
515 #if 0
516 if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC)
517 {
518 return MFDRV_SetTextCharacterExtra( hDC, CharExtra ); // Wine port.
519 }
520 #endif
521 if (!GdiGetHandleUserData((HGDIOBJ) hDC, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return cExtra;
522
523 if (NtCurrentTeb()->GdiTebBatch.HDC == hDC)
524 {
525 if (Dc_Attr->ulDirty_ & DC_FONTTEXT_DIRTY)
526 {
527 NtGdiFlush(); // Sync up Dc_Attr from Kernel space.
528 Dc_Attr->ulDirty_ &= ~(DC_MODE_DIRTY|DC_FONTTEXT_DIRTY);
529 }
530 }
531 cExtra = Dc_Attr->lTextExtra;
532 Dc_Attr->lTextExtra = CharExtra;
533 return cExtra;
534 // return GetAndSetDCDWord( hDC, GdiGetSetTextCharExtra, CharExtra, 0, 0, 0 );
535 }
536
537 /*
538 * @implemented
539 *
540 */
541 UINT
542 WINAPI
543 GetTextAlign(HDC hdc)
544 {
545 PDC_ATTR Dc_Attr;
546 if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return 0;
547 return Dc_Attr->lTextAlign;
548 }
549
550
551 /*
552 * @implemented
553 *
554 */
555 COLORREF
556 WINAPI
557 GetTextColor(HDC hdc)
558 {
559 PDC_ATTR Dc_Attr;
560 if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return 0;
561 return Dc_Attr->ulForegroundClr;
562 }
563
564
565
566 /*
567 * @unimplemented
568 */
569 UINT
570 WINAPI
571 SetTextAlign(HDC hdc,
572 UINT fMode)
573 {
574 PDC_ATTR Dc_Attr;
575 INT OldMode = 0;
576 #if 0
577 if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC)
578 {
579 if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC)
580 return MFDRV_SetTextAlign( hdc, fMode )
581 else
582 {
583 PLDC pLDC = Dc_Attr->pvLDC;
584 if ( !pLDC )
585 {
586 SetLastError(ERROR_INVALID_HANDLE);
587 return FALSE;
588 }
589 if (pLDC->iType == LDC_EMFLDC)
590 {
591 if return EMFDRV_SetTextAlign( hdc, fMode )
592 }
593 }
594 }
595 #endif
596 if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return OldMode;
597
598 OldMode = Dc_Attr->lTextAlign;
599 Dc_Attr->lTextAlign = fMode; // Raw
600 if (Dc_Attr->dwLayout & LAYOUT_RTL)
601 {
602 if(!(fMode & TA_CENTER)) fMode |= TA_RIGHT;
603 }
604 Dc_Attr->flTextAlign = fMode & (TA_BASELINE|TA_UPDATECP|TA_CENTER);
605 return OldMode;
606
607 }
608
609
610 /*
611 * @implemented
612 */
613 COLORREF
614 WINAPI
615 SetTextColor(
616 HDC hdc,
617 COLORREF crColor
618 )
619 {
620 PDC_ATTR Dc_Attr;
621 COLORREF OldColor = CLR_INVALID;
622 #if 0
623 if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC)
624 {
625 if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC)
626 return MFDRV_SetTextColor( hDC, crColor );
627 else
628 {
629 PLDC pLDC = Dc_Attr->pvLDC;
630 if ( !pLDC )
631 {
632 SetLastError(ERROR_INVALID_HANDLE);
633 return FALSE;
634 }
635 if (pLDC->iType == LDC_EMFLDC)
636 {
637 if return EMFDRV_SetTextColor( hDC, crColor );
638 }
639 }
640 }
641 #endif
642 if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return OldColor;
643
644 OldColor = (COLORREF) Dc_Attr->ulForegroundClr;
645 Dc_Attr->ulForegroundClr = (ULONG) crColor;
646
647 if ( Dc_Attr->crForegroundClr != crColor )
648 {
649 Dc_Attr->ulDirty_ |= (DIRTY_TEXT|DIRTY_LINE|DIRTY_FILL);
650 Dc_Attr->crForegroundClr = crColor;
651 }
652 return OldColor;
653 }
654
655 /*
656 * @implemented
657 */
658 BOOL
659 WINAPI
660 SetTextJustification(
661 HDC hdc,
662 int extra,
663 int breaks
664 )
665 {
666 PDC_ATTR Dc_Attr;
667 #if 0
668 if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC)
669 {
670 if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC)
671 return MFDRV_SetTextJustification( hdc, extra, breaks )
672 else
673 {
674 SetLastError(ERROR_INVALID_HANDLE);
675 return FALSE;
676 }
677 #endif
678 if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return FALSE;
679
680 if (NtCurrentTeb()->GdiTebBatch.HDC == hdc)
681 {
682 if (Dc_Attr->ulDirty_ & DC_FONTTEXT_DIRTY)
683 {
684 NtGdiFlush(); // Sync up Dc_Attr from Kernel space.
685 Dc_Attr->ulDirty_ &= ~(DC_MODE_DIRTY|DC_FONTTEXT_DIRTY);
686 }
687 }
688 Dc_Attr->cBreak = breaks;
689 Dc_Attr->lBreakExtra = extra;
690 return TRUE;
691 }