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