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