93896d45f5c8fcc9efe9a419c0c495eae78dc793
[reactos.git] / reactos / dll / win32 / gdi32 / objects / text.c
1 #include "precomp.h"
2
3
4
5 /*
6 * @implemented
7 */
8 BOOL
9 WINAPI
10 TextOutA(
11 HDC hdc,
12 int nXStart,
13 int nYStart,
14 LPCSTR lpString,
15 int cchString)
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, 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 /*
96 * @implemented
97 */
98 BOOL
99 WINAPI
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 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 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 cchString,
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, cchString, 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 cchString,
271 LPSIZE lpSize
272 )
273 {
274 return NtGdiGetTextExtent(hdc, (LPWSTR)lpString, cchString, lpSize, 0);
275 }
276
277 /*
278 * @implemented
279 */
280 BOOL
281 WINAPI
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 WINAPI
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 WINAPI
311 ExtTextOutA(
312 HDC hdc,
313 int X,
314 int Y,
315 UINT fuOptions,
316 CONST RECT *lprc,
317 LPCSTR lpString,
318 UINT cchString,
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, cchString, lpDx);
330
331 RtlFreeUnicodeString(&StringU);
332
333 return ret;
334 }
335
336
337 /*
338 * @implemented
339 */
340 BOOL
341 WINAPI
342 ExtTextOutW(
343 HDC hdc,
344 int X,
345 int Y,
346 UINT fuOptions,
347 CONST RECT *lprc,
348 LPCWSTR lpString,
349 UINT cchString,
350 CONST INT *lpDx
351 )
352 {
353 return NtGdiExtTextOutW(hdc, X, Y, fuOptions, (LPRECT)lprc, (LPWSTR)lpString, cchString, (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 WINAPI
384 GetTextFaceA( HDC hdc, INT count, LPSTR name )
385 {
386 INT res;
387 LPWSTR nameW;
388
389 /* Validate parameters */
390 if (name && count <= 0)
391 {
392 /* Set last error and return failure */
393 GdiSetLastError(ERROR_INVALID_PARAMETER);
394 return 0;
395 }
396
397 res = GetTextFaceW(hdc, 0, NULL);
398 nameW = HeapAlloc( GetProcessHeap(), 0, res * 2 );
399 GetTextFaceW( hdc, res, nameW );
400
401 if (name)
402 {
403 if (count && !WideCharToMultiByte( CP_ACP, 0, nameW, -1, name, count, NULL, NULL))
404 name[count-1] = 0;
405 res = strlen(name);
406 }
407 else
408 res = WideCharToMultiByte( CP_ACP, 0, nameW, -1, NULL, 0, NULL, NULL);
409 HeapFree( GetProcessHeap(), 0, nameW );
410 return res;
411 }
412
413
414 /*
415 * @implemented
416 */
417 INT
418 WINAPI
419 GetTextFaceAliasW(HDC hdc,
420 int cChar,
421 LPWSTR pszOut)
422 {
423 if ( pszOut && !cChar )
424 {
425 GdiSetLastError(ERROR_INVALID_PARAMETER);
426 return 0;
427 }
428 return NtGdiGetTextFaceW(hdc,cChar,pszOut,TRUE);
429 }
430
431
432 BOOL
433 WINAPI
434 GetFontResourceInfoW(
435 LPCWSTR lpFileName,
436 DWORD *pdwBufSize,
437 void* lpBuffer,
438 DWORD dwType
439 )
440 {
441 BOOL bRet;
442 UNICODE_STRING NtFileName;
443
444 if (!lpFileName || !pdwBufSize || !lpBuffer)
445 {
446 SetLastError(ERROR_INVALID_PARAMETER);
447 return FALSE;
448 }
449
450 if (!RtlDosPathNameToNtPathName_U(lpFileName,
451 &NtFileName,
452 NULL,
453 NULL))
454 {
455 SetLastError(ERROR_PATH_NOT_FOUND);
456 return FALSE;
457 }
458
459 bRet = NtGdiGetFontResourceInfoInternalW(
460 NtFileName.Buffer,
461 (NtFileName.Length / sizeof(WCHAR)) + 1,
462 1,
463 *pdwBufSize,
464 pdwBufSize,
465 lpBuffer,
466 dwType);
467
468 RtlFreeHeap(RtlGetProcessHeap(), 0, NtFileName.Buffer);
469
470 if (!bRet)
471 {
472 return FALSE;
473 }
474
475 return TRUE;
476 }
477
478
479 /*
480 * @unimplemented
481 */
482 int
483 WINAPI
484 SetTextCharacterExtra(
485 HDC hDC,
486 int CharExtra
487 )
488 {
489 INT cExtra = 0x80000000;
490 PDC_ATTR Dc_Attr;
491
492 if (CharExtra == cExtra)
493 {
494 SetLastError(ERROR_INVALID_PARAMETER);
495 return cExtra;
496 }
497 #if 0
498 if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC)
499 {
500 return MFDRV_SetTextCharacterExtra( hDC, CharExtra ); // Wine port.
501 }
502 #endif
503 if (!GdiGetHandleUserData((HGDIOBJ) hDC, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return cExtra;
504
505 if (NtCurrentTeb()->GdiTebBatch.HDC == hDC)
506 {
507 if (Dc_Attr->ulDirty_ & DC_FONTTEXT_DIRTY)
508 {
509 NtGdiFlush(); // Sync up Dc_Attr from Kernel space.
510 Dc_Attr->ulDirty_ &= ~(DC_MODE_DIRTY|DC_FONTTEXT_DIRTY);
511 }
512 }
513 cExtra = Dc_Attr->lTextExtra;
514 Dc_Attr->lTextExtra = CharExtra;
515 return cExtra;
516 // return GetAndSetDCDWord( hDC, GdiGetSetTextCharExtra, CharExtra, 0, 0, 0 );
517 }
518
519 /*
520 * @implemented
521 *
522 */
523 UINT
524 WINAPI
525 GetTextAlign(HDC hdc)
526 {
527 PDC_ATTR Dc_Attr;
528 if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return 0;
529 return Dc_Attr->lTextAlign;
530 }
531
532
533 /*
534 * @implemented
535 *
536 */
537 COLORREF
538 WINAPI
539 GetTextColor(HDC hdc)
540 {
541 PDC_ATTR Dc_Attr;
542 if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return 0;
543 return Dc_Attr->ulForegroundClr;
544 }
545
546
547
548 /*
549 * @unimplemented
550 */
551 UINT
552 WINAPI
553 SetTextAlign(HDC hdc,
554 UINT fMode)
555 {
556 PDC_ATTR Dc_Attr;
557 INT OldMode = 0;
558 #if 0
559 if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC)
560 {
561 if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC)
562 return MFDRV_SetTextAlign( hdc, fMode )
563 else
564 {
565 PLDC pLDC = Dc_Attr->pvLDC;
566 if ( !pLDC )
567 {
568 SetLastError(ERROR_INVALID_HANDLE);
569 return FALSE;
570 }
571 if (pLDC->iType == LDC_EMFLDC)
572 {
573 if return EMFDRV_SetTextAlign( hdc, fMode )
574 }
575 }
576 }
577 #endif
578 if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return OldMode;
579
580 OldMode = Dc_Attr->lTextAlign;
581 Dc_Attr->lTextAlign = fMode; // Raw
582 if (Dc_Attr->dwLayout & LAYOUT_RTL)
583 {
584 if(!(fMode & TA_CENTER)) fMode |= TA_RIGHT;
585 }
586 Dc_Attr->flTextAlign = fMode & (TA_BASELINE|TA_UPDATECP|TA_CENTER);
587 return OldMode;
588
589 }
590
591
592 /*
593 * @implemented
594 */
595 COLORREF
596 WINAPI
597 SetTextColor(
598 HDC hdc,
599 COLORREF crColor
600 )
601 {
602 PDC_ATTR Dc_Attr;
603 COLORREF OldColor = CLR_INVALID;
604 #if 0
605 if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC)
606 {
607 if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC)
608 return MFDRV_SetTextColor( hDC, crColor );
609 else
610 {
611 PLDC pLDC = Dc_Attr->pvLDC;
612 if ( !pLDC )
613 {
614 SetLastError(ERROR_INVALID_HANDLE);
615 return FALSE;
616 }
617 if (pLDC->iType == LDC_EMFLDC)
618 {
619 if return EMFDRV_SetTextColor( hDC, crColor );
620 }
621 }
622 }
623 #endif
624 if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return OldColor;
625
626 OldColor = (COLORREF) Dc_Attr->ulForegroundClr;
627 Dc_Attr->ulForegroundClr = (ULONG) crColor;
628
629 if ( Dc_Attr->crForegroundClr != crColor )
630 {
631 Dc_Attr->ulDirty_ |= (DIRTY_TEXT|DIRTY_LINE|DIRTY_FILL);
632 Dc_Attr->crForegroundClr = crColor;
633 }
634 return OldColor;
635 }
636
637 /*
638 * @implemented
639 */
640 BOOL
641 WINAPI
642 SetTextJustification(
643 HDC hdc,
644 int extra,
645 int breaks
646 )
647 {
648 PDC_ATTR Dc_Attr;
649 #if 0
650 if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC)
651 {
652 if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC)
653 return MFDRV_SetTextJustification( hdc, extra, breaks )
654 else
655 {
656 SetLastError(ERROR_INVALID_HANDLE);
657 return FALSE;
658 }
659 #endif
660 if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return FALSE;
661
662 if (NtCurrentTeb()->GdiTebBatch.HDC == hdc)
663 {
664 if (Dc_Attr->ulDirty_ & DC_FONTTEXT_DIRTY)
665 {
666 NtGdiFlush(); // Sync up Dc_Attr from Kernel space.
667 Dc_Attr->ulDirty_ &= ~(DC_MODE_DIRTY|DC_FONTTEXT_DIRTY);
668 }
669 }
670 Dc_Attr->cBreak = breaks;
671 Dc_Attr->lBreakExtra = extra;
672 return TRUE;
673 }