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