- Merge from trunk up to r45543
[reactos.git] / 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 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 if (nameW == NULL)
399 {
400 return 0;
401 }
402 GetTextFaceW( hdc, res, nameW );
403
404 if (name)
405 {
406 if (count && !WideCharToMultiByte( CP_ACP, 0, nameW, -1, name, count, NULL, NULL))
407 name[count-1] = 0;
408 res = strlen(name);
409 }
410 else
411 res = WideCharToMultiByte( CP_ACP, 0, nameW, -1, NULL, 0, NULL, NULL);
412 HeapFree( GetProcessHeap(), 0, nameW );
413 return res;
414 }
415
416
417 /*
418 * @implemented
419 */
420 INT
421 WINAPI
422 GetTextFaceAliasW(HDC hdc,
423 int cChar,
424 LPWSTR pszOut)
425 {
426 if ( pszOut && !cChar )
427 {
428 GdiSetLastError(ERROR_INVALID_PARAMETER);
429 return 0;
430 }
431 return NtGdiGetTextFaceW(hdc,cChar,pszOut,TRUE);
432 }
433
434
435 BOOL
436 WINAPI
437 GetFontResourceInfoW(
438 LPCWSTR lpFileName,
439 DWORD *pdwBufSize,
440 void* lpBuffer,
441 DWORD dwType
442 )
443 {
444 BOOL bRet;
445 UNICODE_STRING NtFileName;
446
447 if (!lpFileName || !pdwBufSize || !lpBuffer)
448 {
449 SetLastError(ERROR_INVALID_PARAMETER);
450 return FALSE;
451 }
452
453 if (!RtlDosPathNameToNtPathName_U(lpFileName,
454 &NtFileName,
455 NULL,
456 NULL))
457 {
458 SetLastError(ERROR_PATH_NOT_FOUND);
459 return FALSE;
460 }
461
462 bRet = NtGdiGetFontResourceInfoInternalW(
463 NtFileName.Buffer,
464 (NtFileName.Length / sizeof(WCHAR)) + 1,
465 1,
466 *pdwBufSize,
467 pdwBufSize,
468 lpBuffer,
469 dwType);
470
471 RtlFreeHeap(RtlGetProcessHeap(), 0, NtFileName.Buffer);
472
473 if (!bRet)
474 {
475 return FALSE;
476 }
477
478 return TRUE;
479 }
480
481
482 /*
483 * @unimplemented
484 */
485 int
486 WINAPI
487 SetTextCharacterExtra(
488 HDC hDC,
489 int CharExtra
490 )
491 {
492 INT cExtra = 0x80000000;
493 PDC_ATTR Dc_Attr;
494
495 if (CharExtra == cExtra)
496 {
497 SetLastError(ERROR_INVALID_PARAMETER);
498 return cExtra;
499 }
500 #if 0
501 if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC)
502 {
503 return MFDRV_SetTextCharacterExtra( hDC, CharExtra ); // Wine port.
504 }
505 #endif
506 if (!GdiGetHandleUserData((HGDIOBJ) hDC, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return cExtra;
507
508 if (NtCurrentTeb()->GdiTebBatch.HDC == hDC)
509 {
510 if (Dc_Attr->ulDirty_ & DC_FONTTEXT_DIRTY)
511 {
512 NtGdiFlush(); // Sync up Dc_Attr from Kernel space.
513 Dc_Attr->ulDirty_ &= ~(DC_MODE_DIRTY|DC_FONTTEXT_DIRTY);
514 }
515 }
516 cExtra = Dc_Attr->lTextExtra;
517 Dc_Attr->lTextExtra = CharExtra;
518 return cExtra;
519 // return GetAndSetDCDWord( hDC, GdiGetSetTextCharExtra, CharExtra, 0, 0, 0 );
520 }
521
522 /*
523 * @implemented
524 *
525 */
526 UINT
527 WINAPI
528 GetTextAlign(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->lTextAlign;
533 }
534
535
536 /*
537 * @implemented
538 *
539 */
540 COLORREF
541 WINAPI
542 GetTextColor(HDC hdc)
543 {
544 PDC_ATTR Dc_Attr;
545 if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return 0;
546 return Dc_Attr->ulForegroundClr;
547 }
548
549
550
551 /*
552 * @unimplemented
553 */
554 UINT
555 WINAPI
556 SetTextAlign(HDC hdc,
557 UINT fMode)
558 {
559 PDC_ATTR Dc_Attr;
560 INT OldMode = 0;
561 #if 0
562 if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC)
563 {
564 if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC)
565 return MFDRV_SetTextAlign( hdc, fMode )
566 else
567 {
568 PLDC pLDC = Dc_Attr->pvLDC;
569 if ( !pLDC )
570 {
571 SetLastError(ERROR_INVALID_HANDLE);
572 return FALSE;
573 }
574 if (pLDC->iType == LDC_EMFLDC)
575 {
576 if return EMFDRV_SetTextAlign( hdc, fMode )
577 }
578 }
579 }
580 #endif
581 if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return OldMode;
582
583 OldMode = Dc_Attr->lTextAlign;
584 Dc_Attr->lTextAlign = fMode; // Raw
585 if (Dc_Attr->dwLayout & LAYOUT_RTL)
586 {
587 if(!(fMode & TA_CENTER)) fMode |= TA_RIGHT;
588 }
589 Dc_Attr->flTextAlign = fMode & (TA_BASELINE|TA_UPDATECP|TA_CENTER);
590 return OldMode;
591
592 }
593
594
595 /*
596 * @implemented
597 */
598 COLORREF
599 WINAPI
600 SetTextColor(
601 HDC hdc,
602 COLORREF crColor
603 )
604 {
605 PDC_ATTR Dc_Attr;
606 COLORREF OldColor = CLR_INVALID;
607 #if 0
608 if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC)
609 {
610 if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC)
611 return MFDRV_SetTextColor( hDC, crColor );
612 else
613 {
614 PLDC pLDC = Dc_Attr->pvLDC;
615 if ( !pLDC )
616 {
617 SetLastError(ERROR_INVALID_HANDLE);
618 return FALSE;
619 }
620 if (pLDC->iType == LDC_EMFLDC)
621 {
622 if return EMFDRV_SetTextColor( hDC, crColor );
623 }
624 }
625 }
626 #endif
627 if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return OldColor;
628
629 OldColor = (COLORREF) Dc_Attr->ulForegroundClr;
630 Dc_Attr->ulForegroundClr = (ULONG) crColor;
631
632 if ( Dc_Attr->crForegroundClr != crColor )
633 {
634 Dc_Attr->ulDirty_ |= (DIRTY_TEXT|DIRTY_LINE|DIRTY_FILL);
635 Dc_Attr->crForegroundClr = crColor;
636 }
637 return OldColor;
638 }
639
640 /*
641 * @implemented
642 */
643 BOOL
644 WINAPI
645 SetTextJustification(
646 HDC hdc,
647 int extra,
648 int breaks
649 )
650 {
651 PDC_ATTR Dc_Attr;
652 #if 0
653 if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC)
654 {
655 if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC)
656 return MFDRV_SetTextJustification( hdc, extra, breaks )
657 else
658 {
659 SetLastError(ERROR_INVALID_HANDLE);
660 return FALSE;
661 }
662 #endif
663 if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return FALSE;
664
665 if (NtCurrentTeb()->GdiTebBatch.HDC == hdc)
666 {
667 if (Dc_Attr->ulDirty_ & DC_FONTTEXT_DIRTY)
668 {
669 NtGdiFlush(); // Sync up Dc_Attr from Kernel space.
670 Dc_Attr->ulDirty_ &= ~(DC_MODE_DIRTY|DC_FONTTEXT_DIRTY);
671 }
672 }
673 Dc_Attr->cBreak = breaks;
674 Dc_Attr->lBreakExtra = extra;
675 return TRUE;
676 }