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