ReactOS  0.4.15-dev-5109-g2469ce2
text.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS GDI32
3  * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4  * PURPOSE: Text drawing API.
5  * COPYRIGHT: Copyright 2014 Timo Kreuzer
6  * Copyright 2017 Katayama Hirofumi MZ
7  */
8 
9 #include <precomp.h>
10 
11 #define NDEBUG
12 #include <debug.h>
13 
14 /*
15  * @implemented
16  */
17 BOOL
18 WINAPI
20  _In_ HDC hdc,
21  _In_ INT nXStart,
22  _In_ INT nYStart,
23  _In_reads_(cchString) LPCSTR lpString,
24  _In_ INT cchString)
25 {
26  ANSI_STRING StringA;
27  UNICODE_STRING StringU;
28  BOOL bResult;
30 
31  if (lpString != NULL && cchString > 0)
32  {
33  if (cchString > MAXUSHORT)
34  cchString = MAXUSHORT;
35 
36  StringA.Length = (USHORT)cchString;
37  StringA.MaximumLength = (USHORT)cchString;
38  StringA.Buffer = (PCHAR)lpString;
39 
40  Status = RtlAnsiStringToUnicodeString(&StringU, &StringA, TRUE);
41  if (!NT_SUCCESS(Status))
42  {
43  StringU.Buffer = NULL;
44  StringU.Length = 0;
45  }
46  }
47  else
48  {
49  StringU.Buffer = NULL;
50  StringU.Length = 0;
51  }
52 
53  bResult = TextOutW(hdc, nXStart, nYStart,
54  StringU.Buffer, StringU.Length / sizeof(WCHAR));
55 
56  RtlFreeUnicodeString(&StringU);
57  return bResult;
58 }
59 
60 
61 /*
62  * @implemented
63  */
64 BOOL
65 WINAPI
67  _In_ HDC hdc,
68  _In_ INT nXStart,
69  _In_ INT nYStart,
70  _In_reads_(cchString) LPCWSTR lpString,
71  _In_ INT cchString)
72 {
73  return ExtTextOutW(hdc, nXStart, nYStart, 0, NULL, (LPWSTR)lpString, cchString, NULL);
74 }
75 
76 
77 /*
78  * @unimplemented
79  */
80 BOOL
81 WINAPI
83  _In_ HDC hdc,
84  _In_reads_(cStrings) const POLYTEXTA *pptxt,
85  _In_ INT cStrings)
86 {
87  for (; cStrings>0; cStrings--, pptxt++)
88  {
89  if (!ExtTextOutA(hdc,
90  pptxt->x,
91  pptxt->y,
92  pptxt->uiFlags,
93  &pptxt->rcl,
94  pptxt->lpstr,
95  pptxt->n,
96  pptxt->pdx))
97  {
98  return FALSE;
99  }
100  }
101 
102  return TRUE;
103 }
104 
105 
106 /*
107  * @unimplemented
108  */
109 BOOL
110 WINAPI
112  _In_ HDC hdc,
113  _In_reads_(cStrings) const POLYTEXTW *pptxt,
114  _In_ INT cStrings)
115 {
116  for (; cStrings>0; cStrings--, pptxt++)
117  {
118  if (!ExtTextOutW(hdc,
119  pptxt->x,
120  pptxt->y,
121  pptxt->uiFlags,
122  &pptxt->rcl,
123  pptxt->lpstr,
124  pptxt->n,
125  pptxt->pdx))
126  {
127  return FALSE;
128  }
129  }
130 
131  return TRUE;
132 }
133 
134 
135 /*
136  * @implemented
137  */
138 DWORD
139 WINAPI
141  _In_ HDC hdc)
142 {
143  PDC_ATTR pdcattr;
144 
145  /* Get the DC attribute */
146  pdcattr = GdiGetDcAttr(hdc);
147  if (pdcattr == NULL)
148  {
150  return 0;
151  }
152 
153  if (pdcattr->ulDirty_ & DIRTY_CHARSET)
154  return LOWORD(NtGdiGetCharSet(hdc));
155 
156  return LOWORD(pdcattr->iCS_CP);
157 }
158 
159 
160 /*
161  * @unimplemented
162  */
163 INT
164 WINAPI
166  _In_ HDC hdc)
167 {
168  PDC_ATTR pdcattr;
169 
170  /* Get the DC attribute */
171  pdcattr = GdiGetDcAttr(hdc);
172  if (pdcattr == NULL)
173  {
174  /* Do not set LastError here! */
175  return 0x8000000;
176  }
177 
178  return pdcattr->lTextExtra;
179 }
180 
181 
182 /*
183  * @implemented
184  */
185 INT
186 WINAPI
188  _In_ HDC hdc)
189 {
190  /* MSDN docs say this is equivalent */
191  return NtGdiGetTextCharsetInfo(hdc,NULL,0);
192 }
193 
194 
195 /*
196  * @implemented
197  */
198 BOOL
199 WINAPI
201  _In_ HDC hdc,
203 {
204  TMW_INTERNAL tmwi;
205 
206  if (!NtGdiGetTextMetricsW(hdc, &tmwi, sizeof(TMW_INTERNAL)))
207  {
208  return FALSE;
209  }
210 
212  return TRUE;
213 }
214 
215 
216 /*
217  * @implemented
218  */
219 BOOL
220 WINAPI
222  _In_ HDC hdc,
224 {
225  TMW_INTERNAL tmwi;
226 
227  if (!NtGdiGetTextMetricsW(hdc, &tmwi, sizeof(TMW_INTERNAL)))
228  {
229  return FALSE;
230  }
231 
232  *lptm = tmwi.TextMetric;
233  return TRUE;
234 }
235 
236 
237 /*
238  * @implemented
239  */
240 BOOL
241 APIENTRY
243  _In_ HDC hdc,
244  _In_reads_(cchString) LPCSTR lpString,
245  _In_ INT cchString,
246  _Out_ LPSIZE lpsz)
247 {
248  ANSI_STRING StringA;
249  UNICODE_STRING StringU;
250  BOOL ret;
251 
252  RtlInitAnsiString(&StringA, (LPSTR)lpString);
253  RtlAnsiStringToUnicodeString(&StringU, &StringA, TRUE);
254 
255  ret = GetTextExtentPointW(hdc, StringU.Buffer, cchString, lpsz);
256 
257  RtlFreeUnicodeString(&StringU);
258 
259  return ret;
260 }
261 
262 
263 /*
264  * @implemented
265  */
266 BOOL
267 APIENTRY
269  _In_ HDC hdc,
270  _In_reads_(cchString) LPCWSTR lpString,
271  _In_ INT cchString,
272  _Out_ LPSIZE lpsz)
273 {
274  return NtGdiGetTextExtent(hdc, (LPWSTR)lpString, cchString, lpsz, 0);
275 }
276 
277 
278 /*
279  * @implemented
280  */
281 BOOL
282 WINAPI
284  _In_ HDC hdc,
285  _In_reads_(cchString) LPCWSTR lpszString,
286  _In_ INT cchString,
287  _In_ INT nMaxExtent,
288  _Out_opt_ LPINT lpnFit,
289  _Out_writes_to_opt_(cchString, *lpnFit) LPINT lpnDx,
290  _Out_ LPSIZE lpSize)
291 {
292 
293  /* Windows doesn't check nMaxExtent validity in unicode version */
294  if (nMaxExtent < -1)
295  {
296  DPRINT("nMaxExtent is invalid: %d\n", nMaxExtent);
297  }
298 
299  if (LoadLPK(LPK_GTEP))
300  return LpkGetTextExtentExPoint(hdc, lpszString, cchString, nMaxExtent, lpnFit, lpnDx, lpSize, 0, 0);
301 
302  return NtGdiGetTextExtentExW (
303  hdc, (LPWSTR)lpszString, cchString, nMaxExtent, (PULONG)lpnFit, (PULONG)lpnDx, lpSize, 0 );
304 }
305 
306 
307 /*
308  * @implemented
309  */
310 BOOL
311 WINAPI
313  _In_ HDC hdc,
314  _In_reads_(cwc) LPCWSTR lpwsz,
315  _In_ INT cwc,
316  _In_ INT dxMax,
317  _Out_opt_ LPINT pcCh,
318  _Out_writes_to_opt_(cwc, *pcCh) LPINT pdxOut,
319  _In_ LPSIZE psize)
320 {
321  return NtGdiGetTextExtentExW(hdc, (LPWSTR)lpwsz, cwc, dxMax, (PULONG)pcCh, (PULONG)pdxOut, psize, 0);
322 }
323 
324 /*
325  * @implemented
326  */
327 BOOL
328 WINAPI
330  _In_ HDC hdc,
331  _In_reads_(cchString) LPCSTR lpszStr,
332  _In_ INT cchString,
333  _In_ INT nMaxExtent,
334  _Out_opt_ LPINT lpnFit,
335  _Out_writes_to_opt_ (cchString, *lpnFit) LPINT lpnDx,
336  _Out_ LPSIZE lpSize)
337 {
339  LPWSTR lpszStrW;
340  BOOL bResult = FALSE;
341 
342  if (nMaxExtent < -1)
343  {
345  return FALSE;
346  }
347 
348  Status = HEAP_strdupA2W(&lpszStrW, lpszStr);
349  if (!NT_SUCCESS (Status))
350  {
352  return FALSE;
353  }
354 
355  bResult = NtGdiGetTextExtentExW(hdc,
356  lpszStrW,
357  cchString,
358  nMaxExtent,
359  (PULONG)lpnFit,
360  (PULONG)lpnDx,
361  lpSize,
362  0);
363 
364  HEAP_free(lpszStrW);
365 
366  return bResult;
367 }
368 
369 
370 /*
371  * @implemented
372  */
373 BOOL
374 WINAPI
376  _In_ HDC hdc,
377  _In_reads_(cchString) LPCSTR lpString,
378  _In_ INT cchString,
379  _Out_ LPSIZE lpSize)
380 {
381  ANSI_STRING StringA;
382  UNICODE_STRING StringU;
383  BOOL ret;
384 
385  StringA.Buffer = (LPSTR)lpString;
386  StringA.Length = cchString;
387  RtlAnsiStringToUnicodeString(&StringU, &StringA, TRUE);
388 
389  ret = GetTextExtentPoint32W(hdc, StringU.Buffer, cchString, lpSize);
390 
391  RtlFreeUnicodeString(&StringU);
392 
393  return ret;
394 }
395 
396 
397 /*
398  * @implemented
399  */
400 BOOL
401 WINAPI
403  _In_ HDC hdc,
404  _In_reads_(cchString) LPCWSTR lpString,
405  _In_ int cchString,
406  _Out_ LPSIZE lpSize)
407 {
408  return NtGdiGetTextExtent(hdc, (LPWSTR)lpString, cchString, lpSize, 0);
409 }
410 
411 /*
412  * @implemented
413  */
414 BOOL
415 WINAPI
417  _In_ HDC hdc,
418  _In_reads_(cgi) LPWORD pgiIn,
419  _In_ INT cgi,
420  _In_ INT nMaxExtent,
421  _Out_opt_ LPINT lpnFit,
422  _Out_writes_to_opt_(cwchString, *lpnFit) LPINT lpnDx,
423  _Out_ LPSIZE lpSize)
424 {
425  return NtGdiGetTextExtentExW(hdc,
426  pgiIn,
427  cgi,
428  nMaxExtent,
429  (PULONG)lpnFit,
430  (PULONG)lpnDx,
431  lpSize,
432  GTEF_INDICES);
433 }
434 
435 /*
436  * @implemented
437  */
438 BOOL
439 WINAPI
441  _In_ HDC hdc,
442  _In_reads_(cgi) LPWORD pgiIn,
443  _In_ int cgi,
444  _Out_ LPSIZE lpSize)
445 {
446  return NtGdiGetTextExtent(hdc, pgiIn, cgi, lpSize, GTEF_INDICES);
447 }
448 
449 /*
450  * @implemented
451  */
452 BOOL
453 WINAPI
455  _In_ HDC hdc,
456  _In_ INT x,
457  _In_ INT y,
458  _In_ UINT fuOptions,
459  _In_opt_ const RECT *lprc,
460  _In_reads_opt_(cch) LPCSTR lpString,
461  _In_ UINT cch,
462  _In_reads_opt_(cch) const INT *lpDx)
463 {
464  ANSI_STRING StringA;
465  UNICODE_STRING StringU;
466  BOOL ret;
467 
468  if (fuOptions & ETO_GLYPH_INDEX)
469  return ExtTextOutW(hdc, x, y, fuOptions, lprc, (LPCWSTR)lpString, cch, lpDx);
470 
471  StringA.Buffer = (PCHAR)lpString;
472  StringA.Length = StringA.MaximumLength = cch;
473  RtlAnsiStringToUnicodeString(&StringU, &StringA, TRUE);
474 
475  if (StringU.Length != StringA.Length * sizeof(WCHAR))
476  DPRINT1("ERROR: Should convert lpDx properly!\n");
477 
478  ret = ExtTextOutW(hdc, x, y, fuOptions, lprc, StringU.Buffer, cch, lpDx);
479 
480  RtlFreeUnicodeString(&StringU);
481 
482  return ret;
483 }
484 
486 
487 /*
488  * @implemented
489  */
490 BOOL
491 WINAPI
493  _In_ HDC hdc,
494  _In_ INT x,
495  _In_ INT y,
496  _In_ UINT fuOptions,
497  _In_opt_ const RECT *lprc,
498  _In_reads_opt_(cwc) LPCWSTR lpString,
499  _In_ UINT cwc,
500  _In_reads_opt_(cwc) const INT *lpDx)
501 {
502  PDC_ATTR pdcattr;
503 
504  // Need both, should return a parameter error? No they don't!
505  if ( !lpDx && fuOptions & ETO_PDY )
506  return FALSE;
507 
508  // Now sorting out rectangle.
509 
510  // Here again, need both.
511  if ( lprc && !(fuOptions & (ETO_CLIPPED|ETO_OPAQUE)) )
512  {
513  lprc = NULL; // No flags, no rectangle.
514  }
515  else if (!lprc) // No rectangle, force clear flags if set and continue.
516  {
517  fuOptions &= ~(ETO_CLIPPED|ETO_OPAQUE);
518  }
519 
520  if ( !bBypassETOWMF )
521  {
523  ExtTextOut,
524  FALSE,
525  hdc,
526  x,
527  y,
528  fuOptions,
529  lprc,
530  lpString,
531  cwc,
532  lpDx);
533  }
534 
535  if ( GdiConvertAndCheckDC(hdc) == NULL ) return FALSE;
536 
537  if (!(fuOptions & (ETO_GLYPH_INDEX | ETO_IGNORELANGUAGE)))
538  {
540 
541  if (LoadLPK(LPK_ETO))
542  return LpkExtTextOut(hdc, x, y, fuOptions, lprc, lpString, cwc , lpDx, 0);
543  }
544  else
545  {
547  }
548 
549  /* Get the DC attribute */
550  pdcattr = GdiGetDcAttr(hdc);
551  if ( pdcattr &&
552  !(pdcattr->ulDirty_ & DC_DIBSECTION) &&
553  !(pdcattr->lTextAlign & TA_UPDATECP))
554  {
555  if ( lprc && !cwc )
556  {
557  if ( fuOptions & ETO_OPAQUE )
558  {
559  PGDIBSEXTTEXTOUT pgO;
560 
562  if (pgO)
563  {
564  pdcattr->ulDirty_ |= DC_MODE_DIRTY;
565  pgO->Count = cwc;
566  pgO->Rect = *lprc;
567  pgO->Options = fuOptions;
568  /* Snapshot attribute */
569  pgO->ulBackgroundClr = pdcattr->ulBackgroundClr;
570  pgO->ptlViewportOrg = pdcattr->ptlViewportOrg;
571  return TRUE;
572  }
573  }
574  else // Do nothing, old explorer pops this off.
575  {
576  DPRINT1("GdiBCExtTextOut nothing\n");
577  return TRUE;
578  }
579  } // Max 580 wchars, if offset 0
580  else if ( cwc <= ((GDIBATCHBUFSIZE - sizeof(GDIBSTEXTOUT)) / sizeof(WCHAR)) )
581  {
582  PGDIBSTEXTOUT pgO;
583  PTEB pTeb = NtCurrentTeb();
584 
586  if (pgO)
587  {
588  USHORT cjSize = 0;
589  ULONG DxSize = 0;
590 
591  if (cwc > 2) cjSize = (cwc * sizeof(WCHAR)) - sizeof(pgO->String);
592 
593  /* Calculate buffer size for string and Dx values */
594  if (lpDx)
595  {
596  /* If ETO_PDY is specified, we have pairs of INTs */
597  DxSize = (cwc * sizeof(INT)) * (fuOptions & ETO_PDY ? 2 : 1);
598  cjSize += DxSize;
599  // The structure buffer holds 4 bytes. Store Dx data then string.
600  // Result one wchar -> Buf[ Dx ]Str[wC], [4][2][X] one extra unused wchar
601  // to assure alignment of 4.
602  }
603 
604  if ((pTeb->GdiTebBatch.Offset + cjSize ) <= GDIBATCHBUFSIZE)
605  {
607  pgO->cbCount = cwc;
608  pgO->x = x;
609  pgO->y = y;
610  pgO->Options = fuOptions;
611  pgO->iCS_CP = 0;
612 
613  if (lprc) pgO->Rect = *lprc;
614  else
615  {
616  pgO->Options |= GDIBS_NORECT; // Tell the other side lprc is nill.
617  }
618 
619  /* Snapshot attributes */
620  pgO->crForegroundClr = pdcattr->crForegroundClr;
621  pgO->crBackgroundClr = pdcattr->crBackgroundClr;
622  pgO->ulForegroundClr = pdcattr->ulForegroundClr;
623  pgO->ulBackgroundClr = pdcattr->ulBackgroundClr;
624  pgO->lBkMode = pdcattr->lBkMode == OPAQUE ? OPAQUE : TRANSPARENT;
625  pgO->hlfntNew = pdcattr->hlfntNew;
626  pgO->flTextAlign = pdcattr->flTextAlign;
627  pgO->ptlViewportOrg = pdcattr->ptlViewportOrg;
628 
629  pgO->Size = DxSize; // of lpDx then string after.
630  /* Put the Dx before the String to assure alignment of 4 */
631  if (lpDx) RtlCopyMemory( &pgO->Buffer, lpDx, DxSize);
632 
633  if (cwc) RtlCopyMemory( &pgO->String[DxSize/sizeof(WCHAR)], lpString, cwc * sizeof(WCHAR));
634 
635  // Recompute offset and return size
636  pTeb->GdiTebBatch.Offset += cjSize;
637  ((PGDIBATCHHDR)pgO)->Size += cjSize;
638  return TRUE;
639  }
640  // Reset offset and count then fall through
641  pTeb->GdiTebBatch.Offset -= sizeof(GDIBSTEXTOUT);
642  pTeb->GdiBatchCount--;
643  }
644  }
645  }
646  return NtGdiExtTextOutW(hdc,
647  x,
648  y,
649  fuOptions,
650  (LPRECT)lprc,
651  (LPWSTR)lpString,
652  cwc,
653  (LPINT)lpDx,
654  0);
655 }
656 
657 
658 /*
659  * @implemented
660  */
661 INT
662 WINAPI
664  _In_ HDC hdc,
665  _In_ INT cwcMax,
666  _Out_writes_to_opt_(cwcMax, return) LPWSTR pFaceName)
667 {
668  /* Validate parameters */
669  if (pFaceName && cwcMax <= 0)
670  {
671  /* Set last error and return failure */
673  return 0;
674  }
675 
676  /* Forward to kernel */
677  return NtGdiGetTextFaceW(hdc, cwcMax, pFaceName, FALSE);
678 }
679 
680 
681 /*
682  * @implemented
683  */
684 INT
685 WINAPI
687  _In_ HDC hdc,
688  _In_ INT cchMax,
690 {
691  INT res;
692  LPWSTR nameW;
693 
694  /* Validate parameters */
695  if (lpName && cchMax <= 0)
696  {
697  /* Set last error and return failure */
699  return 0;
700  }
701 
702  res = GetTextFaceW(hdc, 0, NULL);
703  nameW = HeapAlloc( GetProcessHeap(), 0, res * 2 );
704  if (nameW == NULL)
705  {
706  return 0;
707  }
708 
709  GetTextFaceW( hdc, res, nameW );
710 
711  if (lpName)
712  {
714  lpName[cchMax-1] = 0;
715  res = strlen(lpName);
716  }
717  else
718  {
719  res = WideCharToMultiByte( CP_ACP, 0, nameW, -1, NULL, 0, NULL, NULL);
720  }
721 
722  HeapFree( GetProcessHeap(), 0, nameW );
723  return res;
724 }
725 
726 
727 /*
728  * @implemented
729  */
730 INT
731 WINAPI
733  _In_ HDC hdc,
734  _In_ INT cwcMax,
735  _Out_writes_to_opt_(cwcMax, return) LPWSTR pszOut)
736 {
737  if (pszOut && !cwcMax)
738  {
740  return 0;
741  }
742 
743  return NtGdiGetTextFaceW(hdc, cwcMax, pszOut, TRUE);
744 }
745 
746 
747 BOOL
748 WINAPI
751  _Inout_ DWORD *pdwBufSize,
752  _Out_writes_to_opt_(*pdwBufSize, 1) PVOID lpBuffer,
753  _In_ DWORD dwType)
754 {
755  BOOL bRet;
756  UNICODE_STRING NtFileName;
757 
758  DPRINT("GetFontResourceInfoW: dwType = %lu\n", dwType);
759 
760  if (!lpFileName || !pdwBufSize)
761  {
763  return FALSE;
764  }
765 
767  &NtFileName,
768  NULL,
769  NULL))
770  {
772  return FALSE;
773  }
774 
776  NtFileName.Buffer,
777  (NtFileName.Length / sizeof(WCHAR)) + 1,
778  1,
779  *pdwBufSize,
780  pdwBufSize,
781  lpBuffer,
782  dwType);
783 
784  RtlFreeHeap(RtlGetProcessHeap(), 0, NtFileName.Buffer);
785 
786  return bRet;
787 }
788 
789 
790 /*
791  * @unimplemented
792  */
793 INT
794 WINAPI
796  _In_ HDC hdc,
797  _In_ INT nCharExtra)
798 {
799  PDC_ATTR pdcattr;
800  INT nOldCharExtra;
801 
802  if (nCharExtra == 0x80000000)
803  {
805  return 0x80000000;
806  }
807 
808  HANDLE_METADC16(INT, SetTextCharacterExtra, 0x80000000, hdc, nCharExtra);
809 
810  /* Get the DC attribute */
811  pdcattr = GdiGetDcAttr(hdc);
812  if (pdcattr == NULL)
813  {
815  return 0x8000000;
816  }
817 
818  if (NtCurrentTeb()->GdiTebBatch.HDC == hdc)
819  {
820  if (pdcattr->ulDirty_ & DC_FONTTEXT_DIRTY)
821  {
822  NtGdiFlush(); // Sync up pdcattr from Kernel space.
824  }
825  }
826 
827  nOldCharExtra = pdcattr->lTextExtra;
828  pdcattr->lTextExtra = nCharExtra;
829  return nOldCharExtra;
830 }
831 
832 /*
833  * @implemented
834  *
835  */
836 UINT
837 WINAPI
839  _In_ HDC hdc)
840 {
841  PDC_ATTR pdcattr;
842 
843  /* Get the DC attribute */
844  pdcattr = GdiGetDcAttr(hdc);
845  if (pdcattr == NULL)
846  {
847  /* Do not set LastError here! */
848  return GDI_ERROR;
849  }
850 
851  return pdcattr->lTextAlign;
852 }
853 
854 
855 /*
856  * @implemented
857  *
858  */
859 COLORREF
860 WINAPI
862  _In_ HDC hdc)
863 {
864  PDC_ATTR pdcattr;
865 
866  /* Get the DC attribute */
867  pdcattr = GdiGetDcAttr(hdc);
868  if (pdcattr == NULL)
869  {
870  /* Do not set LastError here! */
871  return CLR_INVALID;
872  }
873 
874  return pdcattr->ulForegroundClr;
875 }
876 
877 
878 /*
879  * @unimplemented
880  */
881 UINT
882 WINAPI
884  _In_ HDC hdc,
885  _In_ UINT fMode)
886 {
887  PDC_ATTR pdcattr;
888  UINT fOldMode;
889 
891 
892  /* Get the DC attribute */
893  pdcattr = GdiGetDcAttr(hdc);
894  if (pdcattr == NULL)
895  {
897  return GDI_ERROR;
898  }
899 
900 
901  fOldMode = pdcattr->lTextAlign;
902  pdcattr->lTextAlign = fMode; // Raw
903  if (pdcattr->dwLayout & LAYOUT_RTL)
904  {
905  if ((fMode & TA_CENTER) != TA_CENTER) fMode ^= TA_RIGHT;
906  }
907 
908  pdcattr->flTextAlign = fMode & TA_MASK;
909  return fOldMode;
910 }
911 
912 
913 /*
914  * @implemented
915  */
916 COLORREF
917 WINAPI
919  _In_ HDC hdc,
920  _In_ COLORREF crColor)
921 {
922  PDC_ATTR pdcattr;
923  COLORREF crOldColor;
924 
926 
927  pdcattr = GdiGetDcAttr(hdc);
928  if (pdcattr == NULL)
929  {
931  return CLR_INVALID;
932  }
933 
934  crOldColor = (COLORREF) pdcattr->ulForegroundClr;
935  pdcattr->ulForegroundClr = (ULONG)crColor;
936 
937  if (pdcattr->crForegroundClr != crColor)
938  {
940  pdcattr->crForegroundClr = crColor;
941  }
942 
943  return crOldColor;
944 }
945 
946 /*
947  * @implemented
948  */
949 BOOL
950 WINAPI
952  _In_ HDC hdc,
953  _In_ INT nBreakExtra,
954  _In_ INT nBreakCount)
955 {
956  PDC_ATTR pdcattr;
957 
958  HANDLE_METADC16(BOOL, SetTextJustification, FALSE, hdc, nBreakExtra, nBreakCount);
959 
960  /* Get the DC attribute */
961  pdcattr = GdiGetDcAttr(hdc);
962  if (pdcattr == NULL)
963  {
964  /* Do not set LastError here! */
965  return GDI_ERROR;
966  }
967 
968 
969  if (NtCurrentTeb()->GdiTebBatch.HDC == hdc)
970  {
971  if (pdcattr->ulDirty_ & DC_FONTTEXT_DIRTY)
972  {
973  NtGdiFlush(); // Sync up pdcattr from Kernel space.
975  }
976  }
977 
978  pdcattr->cBreak = nBreakCount;
979  pdcattr->lBreakExtra = nBreakExtra;
980  return TRUE;
981 }
982 
983 /*
984  * @implemented
985  */
986 UINT
987 WINAPI
989  _In_ HDC hdc,
990  _In_ LPSTR psz,
991  _In_ BOOL bDoCall,
992  _In_ UINT cj,
993  _Out_writes_(cj) BYTE *lpSB)
994 {
995 
997  PWSTR pwsz;
998  UINT uResult = 0;
999 
1000  if (!bDoCall)
1001  {
1002  return 0;
1003  }
1004 
1005  Status = HEAP_strdupA2W(&pwsz, psz);
1006  if (!NT_SUCCESS(Status))
1007  {
1009  }
1010  else
1011  {
1012  uResult = NtGdiGetStringBitmapW(hdc, pwsz, 1, lpSB, cj);
1013  HEAP_free(pwsz);
1014  }
1015 
1016  return uResult;
1017 
1018 }
1019 
1020 /*
1021  * @implemented
1022  */
1023 UINT
1024 WINAPI
1026  _In_ HDC hdc,
1027  _In_ LPWSTR pwsz,
1028  _In_ BOOL bDoCall,
1029  _In_ UINT cj,
1030  _Out_writes_(cj) BYTE *lpSB)
1031 {
1032  if (!bDoCall)
1033  {
1034  return 0;
1035  }
1036 
1037  return NtGdiGetStringBitmapW(hdc, pwsz, 1, lpSB, cj);
1038 
1039 }
1040 
1041 /*
1042  * @implemented
1043  */
1044 BOOL
1045 WINAPI
1047  _In_ HDC hdc,
1048  _Out_ EXTTEXTMETRIC *petm)
1049 {
1050  BOOL bResult;
1051 
1052  bResult = NtGdiGetETM(hdc, petm);
1053 
1054  if (bResult && petm)
1055  {
1056  petm->emKernPairs = (WORD)GetKerningPairsA(hdc, 0, 0);
1057  }
1058 
1059  return bResult;
1060 }
ULONG Buffer[1]
Definition: ntgdityp.h:529
TEXTMETRICW TextMetric
Definition: ntgdityp.h:370
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
BOOL WINAPI GetTextExtentExPointI(_In_ HDC hdc, _In_reads_(cgi) LPWORD pgiIn, _In_ INT cgi, _In_ INT nMaxExtent, _Out_opt_ LPINT lpnFit, _Out_writes_to_opt_(cwchString, *lpnFit) LPINT lpnDx, _Out_ LPSIZE lpSize)
Definition: text.c:416
VOID HEAP_free(LPVOID memory)
Definition: heap.c:63
HDC WINAPI GdiConvertAndCheckDC(HDC hdc)
Definition: dc.c:403
POINTL ptlViewportOrg
Definition: ntgdihdl.h:339
ULONG ulBackgroundClr
Definition: ntgdityp.h:540
_In_ ULONG cj
Definition: winddi.h:3540
INT WINAPI SetTextCharacterExtra(_In_ HDC hdc, _In_ INT nCharExtra)
Definition: text.c:795
_Must_inspect_result_ _Out_ LPSIZE psize
Definition: ntgdi.h:1569
_In_ int _Inout_ LPRECT lprc
Definition: winuser.h:4455
BOOL WINAPI GetETM(_In_ HDC hdc, _Out_ EXTTEXTMETRIC *petm)
Definition: text.c:1046
#define _In_opt_
Definition: ms_sal.h:309
BOOL WINAPI GetTextExtentPointI(_In_ HDC hdc, _In_reads_(cgi) LPWORD pgiIn, _In_ int cgi, _Out_ LPSIZE lpSize)
Definition: text.c:440
#define LAYOUT_RTL
Definition: wingdi.h:1371
#define _Inout_
Definition: ms_sal.h:378
BOOL WINAPI TextOutW(_In_ HDC hdc, _In_ INT nXStart, _In_ INT nYStart, _In_reads_(cchString) LPCWSTR lpString, _In_ INT cchString)
Definition: text.c:66
#define WideCharToMultiByte
Definition: compat.h:111
BOOL APIENTRY GetTextExtentPointA(_In_ HDC hdc, _In_reads_(cchString) LPCSTR lpString, _In_ INT cchString, _Out_ LPSIZE lpsz)
Definition: text.c:242
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
#define _Out_
Definition: ms_sal.h:345
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define TRUE
Definition: types.h:120
LONG lBreakExtra
Definition: ntgdihdl.h:324
uint16_t * PWSTR
Definition: typedefs.h:56
__kernel_entry W32KAPI BOOL APIENTRY NtGdiExtTextOutW(_In_ HDC hdc, _In_ INT x, _In_ INT y, _In_ UINT flOpts, _In_opt_ LPRECT prcl, _In_reads_opt_(cwc) LPWSTR pwsz, _In_range_(0, 0xffff) INT cwc, _In_reads_opt_(_Inexpressible_(cwc)) LPINT pdx, _In_ DWORD dwCodePage)
#define CP_ACP
Definition: compat.h:109
#define DIRTY_CHARSET
Definition: ntgdihdl.h:127
BOOL WINAPI GetTextExtentExPointWPri(_In_ HDC hdc, _In_reads_(cwc) LPCWSTR lpwsz, _In_ INT cwc, _In_ INT dxMax, _Out_opt_ LPINT pcCh, _Out_writes_to_opt_(cwc, *pcCh) LPINT pdxOut, _In_ LPSIZE psize)
Definition: text.c:312
FORCEINLINE PDC_ATTR GdiGetDcAttr(HDC hdc)
Definition: gdi32p.h:451
LONG NTSTATUS
Definition: precomp.h:26
#define HANDLE_METADC16(_RetType, _Func, dwError, hdc,...)
Definition: gdi32p.h:613
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
#define INT
Definition: polytest.cpp:20
static HDC
Definition: imagelist.c:92
_In_ LPCSTR lpName
Definition: winbase.h:2773
#define CLR_INVALID
Definition: wingdi.h:883
#define DC_DIBSECTION
Definition: ntgdihdl.h:137
struct _GDIBATCHHDR * PGDIBATCHHDR
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
LONG lTextExtra
Definition: ntgdihdl.h:322
VOID FASTCALL FONT_TextMetricWToA(const TEXTMETRICW *ptmW, LPTEXTMETRICA ptmA)
Definition: font.c:79
char * LPSTR
Definition: xmlstorage.h:182
static BOOL bBypassETOWMF
Definition: text.c:485
#define _In_reads_opt_(size)
Definition: ms_sal.h:320
int32_t INT
Definition: typedefs.h:58
#define HANDLE_METADC(_RetType, _Func, dwError, hdc,...)
Definition: gdi32p.h:589
LONG lBkMode
Definition: ntgdityp.h:514
ULONG ulBackgroundClr
Definition: ntgdihdl.h:294
INT WINAPI GetTextCharacterExtra(_In_ HDC hdc)
Definition: text.c:165
FLONG flTextAlign
Definition: ntgdityp.h:525
NTSYSAPI VOID NTAPI RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString)
#define _Out_writes_to_opt_(size, count)
Definition: ms_sal.h:356
DWORD WINAPI GetKerningPairsA(_In_ HDC hdc, _In_ DWORD nPairs, _Out_writes_to_opt_(nPairs, return) LPKERNINGPAIR lpKernPair)
NTSYSAPI ULONG WINAPI RtlNtStatusToDosError(NTSTATUS)
BOOL WINAPI LoadLPK(INT LpkFunctionID)
Definition: utils.c:423
#define FALSE
Definition: types.h:117
#define ETO_OPAQUE
Definition: wingdi.h:647
unsigned int BOOL
Definition: ntddk_ex.h:94
HANDLE hlfntNew
Definition: ntgdihdl.h:326
static TAGREF LPCWSTR LPDWORD LPVOID lpBuffer
Definition: db.cpp:175
BOOL WINAPI PolyTextOutW(_In_ HDC hdc, _In_reads_(cStrings) const POLYTEXTW *pptxt, _In_ INT cStrings)
Definition: text.c:111
BOOL WINAPI ExtTextOutW(_In_ HDC hdc, _In_ INT x, _In_ INT y, _In_ UINT fuOptions, _In_opt_ const RECT *lprc, _In_reads_opt_(cwc) LPCWSTR lpString, _In_ UINT cwc, _In_reads_opt_(cwc) const INT *lpDx)
Definition: text.c:492
#define TRANSPARENT
Definition: wingdi.h:950
#define GDIBATCHBUFSIZE
Definition: ntgdityp.h:200
COLORREF crBackgroundClr
Definition: ntgdityp.h:513
NTSTATUS HEAP_strdupA2W(LPWSTR *ppszW, LPCSTR lpszA)
Definition: heap.c:43
#define _In_
Definition: ms_sal.h:308
#define _In_z_
Definition: ms_sal.h:313
#define ETO_CLIPPED
Definition: wingdi.h:648
const char * LPCSTR
Definition: xmlstorage.h:183
UINT Options
Definition: ntgdityp.h:519
INT WINAPI GetTextFaceAliasW(_In_ HDC hdc, _In_ INT cwcMax, _Out_writes_to_opt_(cwcMax, return) LPWSTR pszOut)
Definition: text.c:732
#define TA_UPDATECP
Definition: wingdi.h:936
ULONG ulDirty_
Definition: ntgdihdl.h:290
#define PCHAR
Definition: match.c:90
static const WCHAR nameW[]
Definition: main.c:46
__kernel_entry W32KAPI NTSTATUS APIENTRY NtGdiFlush(VOID)
Definition: gdibatch.c:471
#define TA_RIGHT
Definition: wingdi.h:933
Status
Definition: gdiplustypes.h:24
USHORT MaximumLength
Definition: env_spec_w32.h:377
ULONG ulBackgroundClr
Definition: ntgdityp.h:516
BOOL WINAPI SetTextJustification(_In_ HDC hdc, _In_ INT nBreakExtra, _In_ INT nBreakCount)
Definition: text.c:951
INT WINAPI GetTextFaceA(_In_ HDC hdc, _In_ INT cchMax, _Out_writes_to_opt_(cchMax, return) LPSTR lpName)
Definition: text.c:686
COLORREF crBackgroundClr
Definition: ntgdihdl.h:293
#define GetProcessHeap()
Definition: compat.h:595
__kernel_entry W32KAPI BOOL APIENTRY NtGdiGetFontResourceInfoInternalW(_In_reads_z_(cwc) LPWSTR pwszFiles, _In_ ULONG cwc, _In_ ULONG cFiles, _In_ UINT cjBuf, _Out_ LPDWORD pdwBytes, _Out_writes_bytes_(cjBuf) LPVOID pvBuf, _In_ DWORD iType)
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
__wchar_t WCHAR
Definition: xmlstorage.h:180
COLORREF crForegroundClr
Definition: ntgdityp.h:512
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
INT WINAPI GetTextFaceW(_In_ HDC hdc, _In_ INT cwcMax, _Out_writes_to_opt_(cwcMax, return) LPWSTR pFaceName)
Definition: text.c:663
DWORD COLORREF
Definition: windef.h:300
struct _GDIBSTEXTOUT GDIBSTEXTOUT
W32KAPI BOOL APIENTRY NtGdiGetTextMetricsW(IN HDC hDC, OUT TMW_INTERNAL *pUnsafeTmwi, IN ULONG cj)
Definition: text.c:590
#define WINAPI
Definition: msvc.h:6
unsigned short WORD
Definition: ntddk_ex.h:93
#define LPK_GTEP
Definition: gdi32p.h:84
DWORD iCS_CP
Definition: ntgdihdl.h:301
unsigned long DWORD
Definition: ntddk_ex.h:95
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
LONG cBreak
Definition: ntgdihdl.h:325
#define GDIBS_NORECT
Definition: ntgdityp.h:507
#define SetLastError(x)
Definition: compat.h:611
POINTL ptlViewportOrg
Definition: ntgdityp.h:539
UINT cchMax
#define DIRTY_TEXT
Definition: ntgdihdl.h:125
#define ExtTextOut
Definition: wingdi.h:4454
GDI_TEB_BATCH GdiTebBatch
Definition: compat.h:716
int ret
#define DIRTY_FILL
Definition: ntgdihdl.h:123
ULONG GdiBatchCount
Definition: compat.h:746
UINT WINAPI GetStringBitmapW(_In_ HDC hdc, _In_ LPWSTR pwsz, _In_ BOOL bDoCall, _In_ UINT cj, _Out_writes_(cj) BYTE *lpSB)
Definition: text.c:1025
#define OPAQUE
Definition: wingdi.h:949
BOOL WINAPI GetTextMetricsW(_In_ HDC hdc, _Out_ LPTEXTMETRICW lptm)
Definition: text.c:221
HDC hdc
Definition: main.c:9
HANDLE hlfntNew
Definition: ntgdityp.h:524
#define DC_MODE_DIRTY
Definition: ntgdihdl.h:144
BOOL WINAPI GetTextExtentPoint32A(_In_ HDC hdc, _In_reads_(cchString) LPCSTR lpString, _In_ INT cchString, _Out_ LPSIZE lpSize)
Definition: text.c:375
BOOL APIENTRY GetTextExtentPointW(_In_ HDC hdc, _In_reads_(cchString) LPCWSTR lpString, _In_ INT cchString, _Out_ LPSIZE lpsz)
Definition: text.c:268
BOOL WINAPI GetTextExtentPoint32W(_In_ HDC hdc, _In_reads_(cchString) LPCWSTR lpString, _In_ int cchString, _Out_ LPSIZE lpSize)
Definition: text.c:402
#define DC_FONTTEXT_DIRTY
Definition: ntgdihdl.h:145
#define TA_MASK
Definition: wingdi.h:937
UINT WINAPI GetTextAlign(_In_ HDC hdc)
Definition: text.c:838
BOOL APIENTRY NtGdiGetTextExtent(HDC hdc, LPWSTR lpwsz, INT cwc, LPSIZE psize, UINT flOpts)
Definition: text.c:492
#define _In_reads_(size)
Definition: ms_sal.h:319
unsigned char BYTE
Definition: xxhash.c:193
WCHAR String[2]
Definition: ntgdityp.h:528
POINTL ptlViewportOrg
Definition: ntgdityp.h:526
uint16_t * LPWORD
Definition: typedefs.h:56
COLORREF WINAPI GetTextColor(_In_ HDC hdc)
Definition: text.c:861
DWORD iCS_CP
Definition: ntgdityp.h:521
#define LPK_ETO
Definition: gdi32p.h:82
VOID WINAPI GdiSetLastError(DWORD dwErrCode)
Definition: misc.c:873
Definition: compat.h:694
ULONG Offset
Definition: compat.h:690
BOOL WINAPI GetTextExtentExPointA(_In_ HDC hdc, _In_reads_(cchString) LPCSTR lpszStr, _In_ INT cchString, _In_ INT nMaxExtent, _Out_opt_ LPINT lpnFit, _Out_writes_to_opt_(cchString, *lpnFit) LPINT lpnDx, _Out_ LPSIZE lpSize)
Definition: text.c:329
BOOL WINAPI ExtTextOutA(_In_ HDC hdc, _In_ INT x, _In_ INT y, _In_ UINT fuOptions, _In_opt_ const RECT *lprc, _In_reads_opt_(cch) LPCSTR lpString, _In_ UINT cch, _In_reads_opt_(cch) const INT *lpDx)
Definition: text.c:454
FORCEINLINE struct _TEB * NtCurrentTeb(VOID)
Definition: psfuncs.h:420
unsigned short USHORT
Definition: pedump.c:61
ULONG ulForegroundClr
Definition: ntgdihdl.h:296
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
#define _Out_opt_
Definition: ms_sal.h:346
unsigned int * PULONG
Definition: retypes.h:1
unsigned int UINT
Definition: ndis.h:50
BOOL WINAPI GetFontResourceInfoW(_In_z_ LPCWSTR lpFileName, _Inout_ DWORD *pdwBufSize, _Out_writes_to_opt_(*pdwBufSize, 1) PVOID lpBuffer, _In_ DWORD dwType)
Definition: text.c:749
#define NULL
Definition: types.h:112
W32KAPI INT APIENTRY NtGdiGetTextFaceW(IN HDC hDC, IN INT Count, OUT OPTIONAL LPWSTR FaceName, IN BOOL bAliasName)
Definition: text.c:530
DWORD APIENTRY NtGdiGetCharSet(HDC hDC)
Definition: text.c:206
W32KAPI BOOL APIENTRY NtGdiGetTextExtentExW(IN HDC hDC, IN OPTIONAL LPWSTR UnsafeString, IN ULONG Count, IN ULONG MaxExtent, OUT OPTIONAL PULONG UnsafeFit, OUT OPTIONAL PULONG UnsafeDx, OUT LPSIZE UnsafeSize, IN FLONG fl)
Definition: text.c:326
DWORD WINAPI GdiGetCodePage(_In_ HDC hdc)
Definition: text.c:140
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
#define MAXUSHORT
Definition: typedefs.h:83
#define ETO_PDY
Definition: wingdi.h:657
FLONG flTextAlign
Definition: ntgdihdl.h:320
#define DPRINT1
Definition: precomp.h:8
LONG lBkMode
Definition: ntgdihdl.h:309
BOOL WINAPI PolyTextOutA(_In_ HDC hdc, _In_reads_(cStrings) const POLYTEXTA *pptxt, _In_ INT cStrings)
Definition: text.c:82
COLORREF crForegroundClr
Definition: ntgdihdl.h:295
BOOL WINAPI GetTextExtentExPointW(_In_ HDC hdc, _In_reads_(cchString) LPCWSTR lpszString, _In_ INT cchString, _In_ INT nMaxExtent, _Out_opt_ LPINT lpnFit, _Out_writes_to_opt_(cchString, *lpnFit) LPINT lpnDx, _Out_ LPSIZE lpSize)
Definition: text.c:283
INT WINAPI GetTextCharset(_In_ HDC hdc)
Definition: text.c:187
BOOL WINAPI TextOutA(_In_ HDC hdc, _In_ INT nXStart, _In_ INT nYStart, _In_reads_(cchString) LPCSTR lpString, _In_ INT cchString)
Definition: text.c:19
GLuint res
Definition: glext.h:9613
unsigned int ULONG
Definition: retypes.h:1
_In_ ULONG cjSize
Definition: winddi.h:3634
UINT cbCount
Definition: ntgdityp.h:522
#define DIRTY_LINE
Definition: ntgdihdl.h:124
DWORD dwLayout
Definition: ntgdihdl.h:335
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
INT APIENTRY NtGdiGetTextCharsetInfo(IN HDC hdc, OUT OPTIONAL LPFONTSIGNATURE lpSig, IN DWORD dwFlags)
Definition: text.c:267
COLORREF WINAPI SetTextColor(_In_ HDC hdc, _In_ COLORREF crColor)
Definition: text.c:918
#define ERROR_PATH_NOT_FOUND
Definition: winerror.h:106
#define TA_CENTER
Definition: wingdi.h:931
ULONG ulForegroundClr
Definition: ntgdityp.h:515
FORCEINLINE PVOID GdiAllocBatchCommand(HDC hdc, USHORT Cmd)
Definition: gdi32p.h:381
#define DPRINT
Definition: sndvol32.h:71
BOOL WINAPI GetTextMetricsA(_In_ HDC hdc, _Out_ LPTEXTMETRICA lptm)
Definition: text.c:200
WCHAR * LPWSTR
Definition: xmlstorage.h:184
IN PCTCH IN DWORD cch
Definition: pager.h:36
LPKETO LpkExtTextOut
Definition: utils.c:5
#define GDI_ERROR
Definition: wingdi.h:1309
#define LOWORD(l)
Definition: pedump.c:82
#define HeapFree(x, y, z)
Definition: compat.h:594
#define GTEF_INDICES
Definition: ntgdityp.h:213
static LPTEXTMETRICW lptm
Definition: font.c:42
#define APIENTRY
Definition: api.h:79
NTSYSAPI BOOLEAN NTAPI RtlDosPathNameToNtPathName_U(_In_opt_z_ PCWSTR DosPathName, _Out_ PUNICODE_STRING NtPathName, _Out_opt_ PCWSTR *NtFileNamePart, _Out_opt_ PRTL_RELATIVE_NAME_U DirectoryInfo)
_In_ LPCSTR lpFileName
Definition: winbase.h:3055
LONG lTextAlign
Definition: ntgdihdl.h:321
__kernel_entry W32KAPI BOOL APIENTRY NtGdiGetETM(_In_ HDC hdc, _Out_opt_ EXTTEXTMETRIC *petm)
UINT WINAPI GetStringBitmapA(_In_ HDC hdc, _In_ LPSTR psz, _In_ BOOL bDoCall, _In_ UINT cj, _Out_writes_(cj) BYTE *lpSB)
Definition: text.c:988
__kernel_entry W32KAPI UINT APIENTRY NtGdiGetStringBitmapW(_In_ HDC hdc, _In_ LPWSTR pwsz, _In_ UINT cwc, _Out_writes_bytes_(cj) BYTE *lpSB, _In_ UINT cj)
LPKGTEP LpkGetTextExtentExPoint
Definition: utils.c:7
int * LPINT
Definition: windef.h:178
UINT WINAPI SetTextAlign(_In_ HDC hdc, _In_ UINT fMode)
Definition: text.c:883
#define _Out_writes_(size)
Definition: ms_sal.h:348