Patch by Stefan100 stefan__100__ at hotmail.com. Remove NtGdiGetTextExtentPoint32...
[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 STDCALL
362 GetTextFaceW(HDC hDC,
363 int nCount,
364 LPWSTR lpFaceName)
365 {
366 INT retValue = 0;
367 if ((!lpFaceName) || (nCount))
368 {
369 retValue = NtGdiGetTextFaceW(hDC,nCount,lpFaceName,0);
370 }
371 else
372 {
373 SetLastError(ERROR_INVALID_PARAMETER);
374 }
375 return retValue;
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 BOOL
403 STDCALL
404 GetFontResourceInfoW(
405 LPCWSTR lpFileName,
406 DWORD *pdwBufSize,
407 void* lpBuffer,
408 DWORD dwType
409 )
410 {
411 BOOL bRet;
412 UNICODE_STRING NtFileName;
413
414 if (!lpFileName || !pdwBufSize || !lpBuffer)
415 {
416 SetLastError(ERROR_INVALID_PARAMETER);
417 return FALSE;
418 }
419
420 if (!RtlDosPathNameToNtPathName_U(lpFileName,
421 &NtFileName,
422 NULL,
423 NULL))
424 {
425 SetLastError(ERROR_PATH_NOT_FOUND);
426 return FALSE;
427 }
428
429 bRet = NtGdiGetFontResourceInfoInternalW(
430 NtFileName.Buffer,
431 NtFileName.Length,
432 1,
433 *pdwBufSize,
434 pdwBufSize,
435 lpBuffer,
436 dwType);
437
438 RtlFreeHeap(RtlGetProcessHeap(), 0, NtFileName.Buffer);
439
440 if (!bRet)
441 {
442 return FALSE;
443 }
444
445 return TRUE;
446 }
447
448
449 /*
450 * @unimplemented
451 */
452 int
453 STDCALL
454 SetTextCharacterExtra(
455 HDC hDC,
456 int CharExtra
457 )
458 {
459 INT cExtra = 0x80000000;
460 PDC_ATTR Dc_Attr;
461
462 if (CharExtra == cExtra)
463 {
464 SetLastError(ERROR_INVALID_PARAMETER);
465 return cExtra;
466 }
467 #if 0
468 if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC)
469 {
470 return MFDRV_SetTextCharacterExtra( hDC, CharExtra ); // Wine port.
471 }
472 #endif
473 if (!GdiGetHandleUserData((HGDIOBJ) hDC, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return cExtra;
474
475 if (NtCurrentTeb()->GdiTebBatch.HDC == (ULONG)hDC)
476 {
477 if (Dc_Attr->ulDirty_ & DC_FONTTEXT_DIRTY)
478 {
479 NtGdiFlush(); // Sync up Dc_Attr from Kernel space.
480 Dc_Attr->ulDirty_ &= ~(DC_MODE_DIRTY|DC_FONTTEXT_DIRTY);
481 }
482 }
483 cExtra = Dc_Attr->lTextExtra;
484 Dc_Attr->lTextExtra = CharExtra;
485 return cExtra;
486 // return GetAndSetDCDWord( hDC, GdiGetSetTextCharExtra, CharExtra, 0, 0, 0 );
487 }
488
489 /*
490 * @implemented
491 *
492 */
493 UINT
494 STDCALL
495 GetTextAlign(HDC hdc)
496 {
497 PDC_ATTR Dc_Attr;
498 if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return 0;
499 return Dc_Attr->lTextAlign;
500 }
501
502
503 /*
504 * @implemented
505 *
506 */
507 COLORREF
508 STDCALL
509 GetTextColor(HDC hdc)
510 {
511 PDC_ATTR Dc_Attr;
512 if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return 0;
513 return Dc_Attr->ulForegroundClr;
514 }
515
516
517
518 /*
519 * @unimplemented
520 */
521 UINT
522 STDCALL
523 SetTextAlign(HDC hdc,
524 UINT fMode)
525 {
526 PDC_ATTR Dc_Attr;
527 INT OldMode = 0;
528 #if 0
529 if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC)
530 {
531 if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC)
532 return MFDRV_SetTextAlign( hdc, fMode )
533 else
534 {
535 PLDC pLDC = Dc_Attr->pvLDC;
536 if ( !pLDC )
537 {
538 SetLastError(ERROR_INVALID_HANDLE);
539 return FALSE;
540 }
541 if (pLDC->iType == LDC_EMFLDC)
542 {
543 if return EMFDRV_SetTextAlign( hdc, fMode )
544 }
545 }
546 }
547 #endif
548 if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return OldMode;
549
550 OldMode = Dc_Attr->lTextAlign;
551 Dc_Attr->lTextAlign = fMode; // Raw
552 if (Dc_Attr->dwLayout & LAYOUT_RTL)
553 {
554 if(!(fMode & TA_CENTER)) fMode |= TA_RIGHT;
555 }
556 Dc_Attr->flTextAlign = fMode & (TA_BASELINE|TA_UPDATECP|TA_CENTER);
557 return OldMode;
558
559 }
560
561
562 /*
563 * @implemented
564 */
565 COLORREF
566 STDCALL
567 SetTextColor(
568 HDC hdc,
569 COLORREF crColor
570 )
571 {
572 PDC_ATTR Dc_Attr;
573 COLORREF OldColor = CLR_INVALID;
574 #if 0
575 if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC)
576 {
577 if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC)
578 return MFDRV_SetTextColor( hDC, crColor );
579 else
580 {
581 PLDC pLDC = Dc_Attr->pvLDC;
582 if ( !pLDC )
583 {
584 SetLastError(ERROR_INVALID_HANDLE);
585 return FALSE;
586 }
587 if (pLDC->iType == LDC_EMFLDC)
588 {
589 if return EMFDRV_SetTextColor( hDC, crColor );
590 }
591 }
592 }
593 #endif
594 if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return OldColor;
595
596 OldColor = (COLORREF) Dc_Attr->ulForegroundClr;
597 Dc_Attr->ulForegroundClr = (ULONG) crColor;
598
599 if ( Dc_Attr->crForegroundClr != crColor )
600 {
601 Dc_Attr->ulDirty_ |= DIRTY_TEXT;
602 Dc_Attr->crForegroundClr = crColor;
603 }
604 return OldColor;
605 }
606
607 /*
608 * @implemented
609 */
610 BOOL
611 STDCALL
612 SetTextJustification(
613 HDC hdc,
614 int extra,
615 int breaks
616 )
617 {
618 PDC_ATTR Dc_Attr;
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_SetTextJustification( hdc, extra, breaks )
624 else
625 {
626 SetLastError(ERROR_INVALID_HANDLE);
627 return FALSE;
628 }
629 #endif
630 if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return FALSE;
631
632 if (NtCurrentTeb()->GdiTebBatch.HDC == (ULONG)hdc)
633 {
634 if (Dc_Attr->ulDirty_ & DC_FONTTEXT_DIRTY)
635 {
636 NtGdiFlush(); // Sync up Dc_Attr from Kernel space.
637 Dc_Attr->ulDirty_ &= ~(DC_MODE_DIRTY|DC_FONTTEXT_DIRTY);
638 }
639 }
640 Dc_Attr->cBreak = breaks;
641 Dc_Attr->lBreakExtra = extra;
642 return TRUE;
643 }
644
645