xref: /reactos/win32ss/gdi/ntgdi/font.c (revision 0f9e8897)
1c2c66affSColin Finck /*
2c2c66affSColin Finck  * PROJECT:         ReactOS win32 kernel mode subsystem
3c2c66affSColin Finck  * LICENSE:         GPL - See COPYING in the top level directory
4c2c66affSColin Finck  * FILE:            win32ss/gdi/ntgdi/font.c
5c2c66affSColin Finck  * PURPOSE:         Font
6c2c66affSColin Finck  * PROGRAMMERS:     James Tabor <james.tabor@reactos.org>
7c2c66affSColin Finck  *                  Timo Kreuzer <timo.kreuzer@reactos.org>
8c2c66affSColin Finck  *                  Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
9c2c66affSColin Finck  */
10c2c66affSColin Finck 
11c2c66affSColin Finck /** Includes ******************************************************************/
12c2c66affSColin Finck 
13c2c66affSColin Finck #include <win32k.h>
14c2c66affSColin Finck 
15c2c66affSColin Finck #define NDEBUG
16c2c66affSColin Finck #include <debug.h>
17c2c66affSColin Finck 
18c2c66affSColin Finck HFONT APIENTRY HfontCreate( IN PENUMLOGFONTEXDVW pelfw,IN ULONG cjElfw,IN LFTYPE lft,IN FLONG fl,IN PVOID pvCliData );
19c2c66affSColin Finck 
20c2c66affSColin Finck /** Internal ******************************************************************/
21c2c66affSColin Finck 
22c2c66affSColin Finck HFONT FASTCALL
GreCreateFontIndirectW(LOGFONTW * lplf)23c2c66affSColin Finck GreCreateFontIndirectW( LOGFONTW *lplf )
24c2c66affSColin Finck {
25c2c66affSColin Finck     if (lplf)
26c2c66affSColin Finck     {
27c2c66affSColin Finck         ENUMLOGFONTEXDVW Logfont;
28c2c66affSColin Finck 
29c2c66affSColin Finck         RtlCopyMemory( &Logfont.elfEnumLogfontEx.elfLogFont, lplf, sizeof(LOGFONTW));
30c2c66affSColin Finck         RtlZeroMemory( &Logfont.elfEnumLogfontEx.elfFullName,
31c2c66affSColin Finck                        sizeof(Logfont.elfEnumLogfontEx.elfFullName));
32c2c66affSColin Finck         RtlZeroMemory( &Logfont.elfEnumLogfontEx.elfStyle,
33c2c66affSColin Finck                        sizeof(Logfont.elfEnumLogfontEx.elfStyle));
34c2c66affSColin Finck         RtlZeroMemory( &Logfont.elfEnumLogfontEx.elfScript,
35c2c66affSColin Finck                        sizeof(Logfont.elfEnumLogfontEx.elfScript));
36c2c66affSColin Finck 
37c2c66affSColin Finck         Logfont.elfDesignVector.dvNumAxes = 0;
38c2c66affSColin Finck 
39c2c66affSColin Finck         RtlZeroMemory( &Logfont.elfDesignVector, sizeof(DESIGNVECTOR));
40c2c66affSColin Finck 
41c2c66affSColin Finck         return HfontCreate((PENUMLOGFONTEXDVW)&Logfont, 0, 0, 0, NULL );
42c2c66affSColin Finck     }
43c2c66affSColin Finck     else return NULL;
44c2c66affSColin Finck }
45c2c66affSColin Finck 
46c2c66affSColin Finck DWORD
47c2c66affSColin Finck FASTCALL
GreGetKerningPairs(HDC hDC,ULONG NumPairs,LPKERNINGPAIR krnpair)48c2c66affSColin Finck GreGetKerningPairs(
49c2c66affSColin Finck     HDC hDC,
50c2c66affSColin Finck     ULONG NumPairs,
51c2c66affSColin Finck     LPKERNINGPAIR krnpair)
52c2c66affSColin Finck {
53c2c66affSColin Finck   PDC dc;
54c2c66affSColin Finck   PDC_ATTR pdcattr;
55c2c66affSColin Finck   PTEXTOBJ TextObj;
56c2c66affSColin Finck   PFONTGDI FontGDI;
57c2c66affSColin Finck   DWORD Count;
58c2c66affSColin Finck   KERNINGPAIR *pKP;
59c2c66affSColin Finck 
60c2c66affSColin Finck   dc = DC_LockDc(hDC);
61c2c66affSColin Finck   if (!dc)
62c2c66affSColin Finck   {
63c2c66affSColin Finck      EngSetLastError(ERROR_INVALID_HANDLE);
64c2c66affSColin Finck      return 0;
65c2c66affSColin Finck   }
66c2c66affSColin Finck 
67c2c66affSColin Finck   pdcattr = dc->pdcattr;
68c2c66affSColin Finck   TextObj = RealizeFontInit(pdcattr->hlfntNew);
69c2c66affSColin Finck   DC_UnlockDc(dc);
70c2c66affSColin Finck 
71c2c66affSColin Finck   if (!TextObj)
72c2c66affSColin Finck   {
73c2c66affSColin Finck      EngSetLastError(ERROR_INVALID_HANDLE);
74c2c66affSColin Finck      return 0;
75c2c66affSColin Finck   }
76c2c66affSColin Finck 
77c2c66affSColin Finck   FontGDI = ObjToGDI(TextObj->Font, FONT);
78c2c66affSColin Finck   TEXTOBJ_UnlockText(TextObj);
79c2c66affSColin Finck 
80c2c66affSColin Finck   Count = ftGdiGetKerningPairs(FontGDI,0,NULL);
81c2c66affSColin Finck 
82c2c66affSColin Finck   if ( Count && krnpair )
83c2c66affSColin Finck   {
84c2c66affSColin Finck      if (Count > NumPairs)
85c2c66affSColin Finck      {
86c2c66affSColin Finck         EngSetLastError(ERROR_INSUFFICIENT_BUFFER);
87c2c66affSColin Finck         return 0;
88c2c66affSColin Finck      }
89c2c66affSColin Finck      pKP = ExAllocatePoolWithTag(PagedPool, Count * sizeof(KERNINGPAIR), GDITAG_TEXT);
90c2c66affSColin Finck      if (!pKP)
91c2c66affSColin Finck      {
92c2c66affSColin Finck         EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
93c2c66affSColin Finck         return 0;
94c2c66affSColin Finck      }
95c2c66affSColin Finck      ftGdiGetKerningPairs(FontGDI,Count,pKP);
96c2c66affSColin Finck 
97c2c66affSColin Finck      RtlCopyMemory(krnpair, pKP, Count * sizeof(KERNINGPAIR));
98c2c66affSColin Finck 
99c2c66affSColin Finck      ExFreePoolWithTag(pKP,GDITAG_TEXT);
100c2c66affSColin Finck   }
101c2c66affSColin Finck   return Count;
102c2c66affSColin Finck }
103c2c66affSColin Finck 
104c2c66affSColin Finck /*
105c2c66affSColin Finck 
106c2c66affSColin Finck   It is recommended that an application use the GetFontLanguageInfo function
107c2c66affSColin Finck   to determine whether the GCP_DIACRITIC, GCP_DBCS, GCP_USEKERNING, GCP_LIGATE,
108c2c66affSColin Finck   GCP_REORDER, GCP_GLYPHSHAPE, and GCP_KASHIDA values are valid for the
109c2c66affSColin Finck   currently selected font. If not valid, GetCharacterPlacement ignores the
110c2c66affSColin Finck   value.
111c2c66affSColin Finck 
1126b67ef6eSMark Jansen   MS must use a preset "compiled in" support for each language based releases.
113c2c66affSColin Finck   ReactOS uses FreeType, this will need to be supported. ATM this is hard coded
114c2c66affSColin Finck   for GCPCLASS_LATIN!
115c2c66affSColin Finck 
116c2c66affSColin Finck  */
117c2c66affSColin Finck #if 0
118c2c66affSColin Finck DWORD
119c2c66affSColin Finck FASTCALL
120c2c66affSColin Finck GreGetCharacterPlacementW(
121c2c66affSColin Finck     HDC hdc,
122c2c66affSColin Finck     LPCWSTR pwsz,
123c2c66affSColin Finck     INT nCount,
124c2c66affSColin Finck     INT nMaxExtent,
125c2c66affSColin Finck     LPGCP_RESULTSW pgcpw,
126c2c66affSColin Finck     DWORD dwFlags)
127c2c66affSColin Finck {
128c2c66affSColin Finck   GCP_RESULTSW gcpwSave;
129c2c66affSColin Finck   UINT i, nSet, cSet;
130c2c66affSColin Finck   INT *tmpDxCaretPos;
131c2c66affSColin Finck   LONG Cx;
132c2c66affSColin Finck   SIZE Size = {0,0};
133c2c66affSColin Finck 
134c2c66affSColin Finck   DPRINT1("GreGCPW Start\n");
135c2c66affSColin Finck 
136c2c66affSColin Finck    if (!pgcpw)
137c2c66affSColin Finck    {
138c2c66affSColin Finck       if (GreGetTextExtentW( hdc, pwsz, nCount, &Size, 1))
139c2c66affSColin Finck          return MAKELONG(Size.cx, Size.cy);
140c2c66affSColin Finck       return 0;
141c2c66affSColin Finck    }
142c2c66affSColin Finck 
143c2c66affSColin Finck   DPRINT1("GreGCPW 1\n");
144c2c66affSColin Finck 
145c2c66affSColin Finck   RtlCopyMemory(&gcpwSave, pgcpw, sizeof(GCP_RESULTSW));
146c2c66affSColin Finck 
147c2c66affSColin Finck   cSet = nSet = nCount;
148c2c66affSColin Finck 
149c2c66affSColin Finck   if ( nCount > gcpwSave.nGlyphs ) cSet = gcpwSave.nGlyphs;
150c2c66affSColin Finck 
151c2c66affSColin Finck   /* GCP_JUSTIFY may only be used in conjunction with GCP_MAXEXTENT. */
152c2c66affSColin Finck   if ( dwFlags & GCP_JUSTIFY) dwFlags |= GCP_MAXEXTENT;
153c2c66affSColin Finck 
154c2c66affSColin Finck   if ( !gcpwSave.lpDx && gcpwSave.lpCaretPos )
155c2c66affSColin Finck      tmpDxCaretPos = gcpwSave.lpCaretPos;
156c2c66affSColin Finck   else
157c2c66affSColin Finck      tmpDxCaretPos = gcpwSave.lpDx;
158c2c66affSColin Finck 
159c2c66affSColin Finck   if ( !GreGetTextExtentExW( hdc,
160c2c66affSColin Finck                              pwsz,
161c2c66affSColin Finck                              cSet,
162c2c66affSColin Finck                              nMaxExtent,
163c2c66affSColin Finck                             ((dwFlags & GCP_MAXEXTENT) ? (PULONG) &cSet : NULL),
164c2c66affSColin Finck                             (PULONG) tmpDxCaretPos,
165c2c66affSColin Finck                              &Size,
166c2c66affSColin Finck                              0) )
167c2c66affSColin Finck   {
168c2c66affSColin Finck      return 0;
169c2c66affSColin Finck   }
170c2c66affSColin Finck 
171c2c66affSColin Finck   DPRINT1("GreGCPW 2\n");
172c2c66affSColin Finck 
173c2c66affSColin Finck   nSet = cSet;
174c2c66affSColin Finck 
175c2c66affSColin Finck   if ( tmpDxCaretPos && nSet > 0)
176c2c66affSColin Finck   {
177c2c66affSColin Finck       for (i = (nSet - 1); i > 0; i--)
178c2c66affSColin Finck       {
179c2c66affSColin Finck           tmpDxCaretPos[i] -= tmpDxCaretPos[i - 1];
180c2c66affSColin Finck       }
181c2c66affSColin Finck   }
182c2c66affSColin Finck 
183c2c66affSColin Finck   if ( !(dwFlags & GCP_MAXEXTENT) || nSet )
184c2c66affSColin Finck   {
185c2c66affSColin Finck      if ( (dwFlags & GCP_USEKERNING) &&
186c2c66affSColin Finck            ( gcpwSave.lpDx ||
187c2c66affSColin Finck              gcpwSave.lpCaretPos ) &&
188c2c66affSColin Finck            nSet >= 2 )
189c2c66affSColin Finck      {
190c2c66affSColin Finck         DWORD Count;
191c2c66affSColin Finck         LPKERNINGPAIR pKP;
192c2c66affSColin Finck 
193c2c66affSColin Finck         Count = GreGetKerningPairs( hdc, 0, NULL);
194c2c66affSColin Finck         if (Count)
195c2c66affSColin Finck         {
196c2c66affSColin Finck            pKP = ExAllocatePoolWithTag(PagedPool, Count * sizeof(KERNINGPAIR), GDITAG_TEXT);
197c2c66affSColin Finck            if (pKP)
198c2c66affSColin Finck            {
199c2c66affSColin Finck               if ( GreGetKerningPairs( hdc, Count, pKP) != Count)
200c2c66affSColin Finck               {
201c2c66affSColin Finck                  ExFreePoolWithTag( pKP, GDITAG_TEXT);
202c2c66affSColin Finck                  return 0;
203c2c66affSColin Finck               }
204c2c66affSColin Finck 
205c2c66affSColin Finck               if ( (ULONG_PTR)(pKP) < ((ULONG_PTR)(pKP) + (ULONG_PTR)(Count * sizeof(KERNINGPAIR))) )
206c2c66affSColin Finck               {
207c2c66affSColin Finck                  DPRINT1("We Need to Do Something HERE!\n");
208c2c66affSColin Finck               }
209c2c66affSColin Finck 
210c2c66affSColin Finck               ExFreePoolWithTag( pKP, GDITAG_TEXT);
211c2c66affSColin Finck 
212c2c66affSColin Finck               if ( dwFlags & GCP_MAXEXTENT )
213c2c66affSColin Finck               {
214c2c66affSColin Finck                  if ( Size.cx > nMaxExtent )
215c2c66affSColin Finck                  {
216c2c66affSColin Finck                     for (Cx = Size.cx; nSet > 0; nSet--)
217c2c66affSColin Finck                     {
218c2c66affSColin Finck                         Cx -= tmpDxCaretPos[nSet - 1];
219c2c66affSColin Finck                         Size.cx = Cx;
220c2c66affSColin Finck                         if ( Cx <= nMaxExtent ) break;
221c2c66affSColin Finck                     }
222c2c66affSColin Finck                  }
223c2c66affSColin Finck                  if ( !nSet )
224c2c66affSColin Finck                  {
225c2c66affSColin Finck                     pgcpw->nGlyphs = 0;
226c2c66affSColin Finck                     pgcpw->nMaxFit = 0;
227c2c66affSColin Finck                     return 0;
228c2c66affSColin Finck                  }
229c2c66affSColin Finck               }
230c2c66affSColin Finck            }
231c2c66affSColin Finck         }
232c2c66affSColin Finck      }
233c2c66affSColin Finck 
234c2c66affSColin Finck      if ( (dwFlags & GCP_JUSTIFY) &&
235c2c66affSColin Finck            ( gcpwSave.lpDx ||
236c2c66affSColin Finck              gcpwSave.lpCaretPos ) &&
237c2c66affSColin Finck            nSet )
238c2c66affSColin Finck      {
239c2c66affSColin Finck          DPRINT1("We Need to Do Something HERE 2!\n");
240c2c66affSColin Finck      }
241c2c66affSColin Finck 
242c2c66affSColin Finck      if ( gcpwSave.lpDx && gcpwSave.lpCaretPos )
243c2c66affSColin Finck         RtlCopyMemory( gcpwSave.lpCaretPos, gcpwSave.lpDx, nSet * sizeof(LONG));
244c2c66affSColin Finck 
245c2c66affSColin Finck      if ( gcpwSave.lpCaretPos )
246c2c66affSColin Finck      {
247c2c66affSColin Finck         int pos = 0;
248c2c66affSColin Finck         i = 0;
249c2c66affSColin Finck         if ( nSet > 0 )
250c2c66affSColin Finck         {
251c2c66affSColin Finck            do
252c2c66affSColin Finck            {
253c2c66affSColin Finck               Cx = gcpwSave.lpCaretPos[i];
254c2c66affSColin Finck               gcpwSave.lpCaretPos[i] = pos;
255c2c66affSColin Finck               pos += Cx;
256c2c66affSColin Finck               ++i;
257c2c66affSColin Finck            }
258c2c66affSColin Finck            while ( i < nSet );
259c2c66affSColin Finck         }
260c2c66affSColin Finck      }
261c2c66affSColin Finck 
262c2c66affSColin Finck      if ( gcpwSave.lpOutString )
263c2c66affSColin Finck         RtlCopyMemory(gcpwSave.lpOutString, pwsz,  nSet * sizeof(WCHAR));
264c2c66affSColin Finck 
265c2c66affSColin Finck      if ( gcpwSave.lpClass )
266c2c66affSColin Finck         RtlFillMemory(gcpwSave.lpClass, nSet, GCPCLASS_LATIN);
267c2c66affSColin Finck 
268c2c66affSColin Finck      if ( gcpwSave.lpOrder )
269c2c66affSColin Finck      {
270c2c66affSColin Finck         for (i = 0; i < nSet; i++)
271c2c66affSColin Finck            gcpwSave.lpOrder[i] = i;
272c2c66affSColin Finck      }
273c2c66affSColin Finck 
274c2c66affSColin Finck      if ( gcpwSave.lpGlyphs )
275c2c66affSColin Finck      {
276c2c66affSColin Finck         if ( GreGetGlyphIndicesW( hdc, pwsz, nSet, gcpwSave.lpGlyphs, 0, 0) == GDI_ERROR )
277c2c66affSColin Finck         {
278c2c66affSColin Finck            nSet = 0;
279c2c66affSColin Finck            Size.cx = 0;
280c2c66affSColin Finck            Size.cy = 0;
281c2c66affSColin Finck         }
282c2c66affSColin Finck      }
283c2c66affSColin Finck      pgcpw->nGlyphs = nSet;
284c2c66affSColin Finck      pgcpw->nMaxFit = nSet;
285c2c66affSColin Finck   }
286c2c66affSColin Finck   DPRINT1("GreGCPW Exit\n");
287c2c66affSColin Finck   return MAKELONG(Size.cx, Size.cy);
288c2c66affSColin Finck }
289c2c66affSColin Finck #endif
290c2c66affSColin Finck 
291c2c66affSColin Finck ULONG
292c2c66affSColin Finck FASTCALL
FontGetObject(PTEXTOBJ plfont,ULONG cjBuffer,PVOID pvBuffer)293c2c66affSColin Finck FontGetObject(PTEXTOBJ plfont, ULONG cjBuffer, PVOID pvBuffer)
294c2c66affSColin Finck {
295c2c66affSColin Finck     ULONG cjMaxSize;
296e9095430SKatayama Hirofumi MZ     ENUMLOGFONTEXDVW *plf;
297e9095430SKatayama Hirofumi MZ 
298e9095430SKatayama Hirofumi MZ     ASSERT(plfont);
299e9095430SKatayama Hirofumi MZ     plf = &plfont->logfont;
300c2c66affSColin Finck 
3016b67ef6eSMark Jansen     if (!(plfont->fl & TEXTOBJECT_INIT))
3026b67ef6eSMark Jansen     {
3036b67ef6eSMark Jansen         NTSTATUS Status;
304a98bebb0SMark Jansen         DPRINT("FontGetObject font not initialized!\n");
3056b67ef6eSMark Jansen 
3066b67ef6eSMark Jansen         Status = TextIntRealizeFont(plfont->BaseObject.hHmgr, plfont);
3076b67ef6eSMark Jansen         if (!NT_SUCCESS(Status))
3086b67ef6eSMark Jansen         {
3096b67ef6eSMark Jansen             DPRINT1("FontGetObject(TextIntRealizeFont) Status = 0x%lx\n", Status);
3106b67ef6eSMark Jansen         }
3116b67ef6eSMark Jansen     }
3126b67ef6eSMark Jansen 
313c2c66affSColin Finck     /* If buffer is NULL, only the size is requested */
314c2c66affSColin Finck     if (pvBuffer == NULL) return sizeof(LOGFONTW);
315c2c66affSColin Finck 
316c2c66affSColin Finck     /* Calculate the maximum size according to number of axes */
317c2c66affSColin Finck     cjMaxSize = FIELD_OFFSET(ENUMLOGFONTEXDVW,
318c2c66affSColin Finck                     elfDesignVector.dvValues[plf->elfDesignVector.dvNumAxes]);
319c2c66affSColin Finck 
320c2c66affSColin Finck     if (cjBuffer > cjMaxSize) cjBuffer = cjMaxSize;
321c2c66affSColin Finck 
322c2c66affSColin Finck     RtlCopyMemory(pvBuffer, plf, cjBuffer);
323c2c66affSColin Finck 
324c2c66affSColin Finck     return cjBuffer;
325c2c66affSColin Finck }
326c2c66affSColin Finck 
327c2c66affSColin Finck DWORD
328c2c66affSColin Finck FASTCALL
IntGetCharDimensions(HDC hdc,PTEXTMETRICW ptm,PDWORD height)329c2c66affSColin Finck IntGetCharDimensions(HDC hdc, PTEXTMETRICW ptm, PDWORD height)
330c2c66affSColin Finck {
331c2c66affSColin Finck   PDC pdc;
332c2c66affSColin Finck   PDC_ATTR pdcattr;
333c2c66affSColin Finck   PTEXTOBJ TextObj;
334c2c66affSColin Finck   SIZE sz;
335c2c66affSColin Finck   TMW_INTERNAL tmwi;
336c2c66affSColin Finck   BOOL Good;
337c2c66affSColin Finck 
338c2c66affSColin Finck   static const WCHAR alphabet[] = {
339c2c66affSColin Finck         'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q',
340c2c66affSColin Finck         'r','s','t','u','v','w','x','y','z','A','B','C','D','E','F','G','H',
341c2c66affSColin Finck         'I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',0};
342c2c66affSColin Finck 
343c2c66affSColin Finck   if(!ftGdiGetTextMetricsW(hdc, &tmwi)) return 0;
344c2c66affSColin Finck 
345c2c66affSColin Finck   pdc = DC_LockDc(hdc);
346c2c66affSColin Finck 
347c2c66affSColin Finck   if (!pdc) return 0;
348c2c66affSColin Finck 
349c2c66affSColin Finck   pdcattr = pdc->pdcattr;
350c2c66affSColin Finck 
351c2c66affSColin Finck   TextObj = RealizeFontInit(pdcattr->hlfntNew);
352c2c66affSColin Finck   if ( !TextObj )
353c2c66affSColin Finck   {
354c2c66affSColin Finck      DC_UnlockDc(pdc);
355c2c66affSColin Finck      return 0;
356c2c66affSColin Finck   }
357c2c66affSColin Finck   Good = TextIntGetTextExtentPoint(pdc, TextObj, alphabet, 52, 0, NULL, 0, &sz, 0);
358c2c66affSColin Finck   TEXTOBJ_UnlockText(TextObj);
359c2c66affSColin Finck   DC_UnlockDc(pdc);
360c2c66affSColin Finck 
361c2c66affSColin Finck   if (!Good) return 0;
362c2c66affSColin Finck   if (ptm) *ptm = tmwi.TextMetric;
363c2c66affSColin Finck   if (height) *height = tmwi.TextMetric.tmHeight;
364c2c66affSColin Finck 
365c2c66affSColin Finck   return (sz.cx / 26 + 1) / 2;
366c2c66affSColin Finck }
367c2c66affSColin Finck 
368c2c66affSColin Finck 
369c2c66affSColin Finck DWORD
370c2c66affSColin Finck FASTCALL
IntGetFontLanguageInfo(PDC Dc)371c2c66affSColin Finck IntGetFontLanguageInfo(PDC Dc)
372c2c66affSColin Finck {
373c2c66affSColin Finck   PDC_ATTR pdcattr;
374c2c66affSColin Finck   FONTSIGNATURE fontsig;
375c2c66affSColin Finck   static const DWORD GCP_DBCS_MASK=0x003F0000,
376c2c66affSColin Finck 		GCP_DIACRITIC_MASK=0x00000000,
377c2c66affSColin Finck 		FLI_GLYPHS_MASK=0x00000000,
378c2c66affSColin Finck 		GCP_GLYPHSHAPE_MASK=0x00000040,
379c2c66affSColin Finck 		GCP_KASHIDA_MASK=0x00000000,
380c2c66affSColin Finck 		GCP_LIGATE_MASK=0x00000000,
381c2c66affSColin Finck 		GCP_USEKERNING_MASK=0x00000000,
382c2c66affSColin Finck 		GCP_REORDER_MASK=0x00000060;
383c2c66affSColin Finck 
384c2c66affSColin Finck   DWORD result=0;
385c2c66affSColin Finck 
386c2c66affSColin Finck   ftGdiGetTextCharsetInfo( Dc, &fontsig, 0 );
387c2c66affSColin Finck 
388c2c66affSColin Finck  /* We detect each flag we return using a bitmask on the Codepage Bitfields */
389c2c66affSColin Finck   if( (fontsig.fsCsb[0]&GCP_DBCS_MASK)!=0 )
390c2c66affSColin Finck 		result|=GCP_DBCS;
391c2c66affSColin Finck 
392c2c66affSColin Finck   if( (fontsig.fsCsb[0]&GCP_DIACRITIC_MASK)!=0 )
393c2c66affSColin Finck 		result|=GCP_DIACRITIC;
394c2c66affSColin Finck 
395c2c66affSColin Finck   if( (fontsig.fsCsb[0]&FLI_GLYPHS_MASK)!=0 )
396c2c66affSColin Finck 		result|=FLI_GLYPHS;
397c2c66affSColin Finck 
398c2c66affSColin Finck   if( (fontsig.fsCsb[0]&GCP_GLYPHSHAPE_MASK)!=0 )
399c2c66affSColin Finck 		result|=GCP_GLYPHSHAPE;
400c2c66affSColin Finck 
401c2c66affSColin Finck   if( (fontsig.fsCsb[0]&GCP_KASHIDA_MASK)!=0 )
402c2c66affSColin Finck 		result|=GCP_KASHIDA;
403c2c66affSColin Finck 
404c2c66affSColin Finck   if( (fontsig.fsCsb[0]&GCP_LIGATE_MASK)!=0 )
405c2c66affSColin Finck 		result|=GCP_LIGATE;
406c2c66affSColin Finck 
407c2c66affSColin Finck   if( (fontsig.fsCsb[0]&GCP_USEKERNING_MASK)!=0 )
408c2c66affSColin Finck 		result|=GCP_USEKERNING;
409c2c66affSColin Finck 
410c2c66affSColin Finck   pdcattr = Dc->pdcattr;
411c2c66affSColin Finck 
412c2c66affSColin Finck   /* This might need a test for a HEBREW- or ARABIC_CHARSET as well */
4133377fe18SJames Tabor   if ( pdcattr->flTextAlign & TA_RTLREADING )
414c2c66affSColin Finck      if( (fontsig.fsCsb[0]&GCP_REORDER_MASK)!=0 )
415c2c66affSColin Finck                     result|=GCP_REORDER;
416c2c66affSColin Finck 
417c2c66affSColin Finck   return result;
418c2c66affSColin Finck }
419c2c66affSColin Finck 
420c2c66affSColin Finck PTEXTOBJ
421c2c66affSColin Finck FASTCALL
RealizeFontInit(HFONT hFont)422c2c66affSColin Finck RealizeFontInit(HFONT hFont)
423c2c66affSColin Finck {
424c2c66affSColin Finck   NTSTATUS Status = STATUS_SUCCESS;
425c2c66affSColin Finck   PTEXTOBJ pTextObj;
426c2c66affSColin Finck 
427c2c66affSColin Finck   pTextObj = TEXTOBJ_LockText(hFont);
428c2c66affSColin Finck 
429c2c66affSColin Finck   if ( pTextObj && !(pTextObj->fl & TEXTOBJECT_INIT))
430c2c66affSColin Finck   {
431c2c66affSColin Finck      Status = TextIntRealizeFont(hFont, pTextObj);
432c2c66affSColin Finck      if (!NT_SUCCESS(Status))
433c2c66affSColin Finck      {
434c2c66affSColin Finck         TEXTOBJ_UnlockText(pTextObj);
435c2c66affSColin Finck         return NULL;
436c2c66affSColin Finck      }
437c2c66affSColin Finck   }
438c2c66affSColin Finck   return pTextObj;
439c2c66affSColin Finck }
440c2c66affSColin Finck 
441c2c66affSColin Finck 
442c2c66affSColin Finck /** Functions ******************************************************************/
443c2c66affSColin Finck 
444c2c66affSColin Finck INT
445c2c66affSColin Finck APIENTRY
NtGdiAddFontResourceW(IN WCHAR * pwcFiles,IN ULONG cwc,IN ULONG cFiles,IN FLONG fl,IN DWORD dwPidTid,IN OPTIONAL DESIGNVECTOR * pdv)446c2c66affSColin Finck NtGdiAddFontResourceW(
447c2c66affSColin Finck     IN WCHAR *pwcFiles,
448c2c66affSColin Finck     IN ULONG cwc,
449c2c66affSColin Finck     IN ULONG cFiles,
450c2c66affSColin Finck     IN FLONG fl,
451c2c66affSColin Finck     IN DWORD dwPidTid,
452c2c66affSColin Finck     IN OPTIONAL DESIGNVECTOR *pdv)
453c2c66affSColin Finck {
454c2c66affSColin Finck     UNICODE_STRING SafeFileName;
455c2c66affSColin Finck     INT Ret;
456c2c66affSColin Finck 
457c2c66affSColin Finck     DBG_UNREFERENCED_PARAMETER(cFiles);
458c2c66affSColin Finck     DBG_UNREFERENCED_PARAMETER(dwPidTid);
459c2c66affSColin Finck     DBG_UNREFERENCED_PARAMETER(pdv);
460c2c66affSColin Finck 
461c2c66affSColin Finck     DPRINT("NtGdiAddFontResourceW\n");
462c2c66affSColin Finck 
463c2c66affSColin Finck     /* cwc = Length + trailing zero. */
4642d9c88e0STimo Kreuzer     if ((cwc <= 1) || (cwc > UNICODE_STRING_MAX_CHARS))
465c2c66affSColin Finck         return 0;
466c2c66affSColin Finck 
4672d9c88e0STimo Kreuzer     SafeFileName.MaximumLength = (USHORT)(cwc * sizeof(WCHAR));
468c2c66affSColin Finck     SafeFileName.Length = SafeFileName.MaximumLength - sizeof(UNICODE_NULL);
469c2c66affSColin Finck     SafeFileName.Buffer = ExAllocatePoolWithTag(PagedPool,
470c2c66affSColin Finck                                                 SafeFileName.MaximumLength,
471c2c66affSColin Finck                                                 TAG_STRING);
472c2c66affSColin Finck     if (!SafeFileName.Buffer)
473c2c66affSColin Finck     {
474c2c66affSColin Finck         return 0;
475c2c66affSColin Finck     }
476c2c66affSColin Finck 
477c2c66affSColin Finck     _SEH2_TRY
478c2c66affSColin Finck     {
479c2c66affSColin Finck         ProbeForRead(pwcFiles, cwc * sizeof(WCHAR), sizeof(WCHAR));
480c2c66affSColin Finck         RtlCopyMemory(SafeFileName.Buffer, pwcFiles, SafeFileName.Length);
481c2c66affSColin Finck     }
482c2c66affSColin Finck     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
483c2c66affSColin Finck     {
484c2c66affSColin Finck         ExFreePoolWithTag(SafeFileName.Buffer, TAG_STRING);
485c2c66affSColin Finck         _SEH2_YIELD(return 0);
486c2c66affSColin Finck     }
487c2c66affSColin Finck     _SEH2_END;
488c2c66affSColin Finck 
489c2c66affSColin Finck     SafeFileName.Buffer[SafeFileName.Length / sizeof(WCHAR)] = UNICODE_NULL;
490c2c66affSColin Finck     Ret = IntGdiAddFontResource(&SafeFileName, fl);
491c2c66affSColin Finck 
492c2c66affSColin Finck     ExFreePoolWithTag(SafeFileName.Buffer, TAG_STRING);
493c2c66affSColin Finck     return Ret;
494c2c66affSColin Finck }
495c2c66affSColin Finck 
496c2c66affSColin Finck HANDLE
497c2c66affSColin Finck APIENTRY
NtGdiAddFontMemResourceEx(IN PVOID pvBuffer,IN DWORD cjBuffer,IN DESIGNVECTOR * pdv,IN ULONG cjDV,OUT DWORD * pNumFonts)498c2c66affSColin Finck NtGdiAddFontMemResourceEx(
499c2c66affSColin Finck     IN PVOID pvBuffer,
500c2c66affSColin Finck     IN DWORD cjBuffer,
501c2c66affSColin Finck     IN DESIGNVECTOR *pdv,
502c2c66affSColin Finck     IN ULONG cjDV,
503c2c66affSColin Finck     OUT DWORD *pNumFonts)
504c2c66affSColin Finck {
505c2c66affSColin Finck     _SEH2_VOLATILE PVOID Buffer = NULL;
506c2c66affSColin Finck     HANDLE Ret;
507c2c66affSColin Finck     DWORD NumFonts = 0;
508c2c66affSColin Finck 
509c2c66affSColin Finck     DPRINT("NtGdiAddFontMemResourceEx\n");
510c2c66affSColin Finck     DBG_UNREFERENCED_PARAMETER(pdv);
511c2c66affSColin Finck     DBG_UNREFERENCED_PARAMETER(cjDV);
512c2c66affSColin Finck 
513c2c66affSColin Finck     if (!pvBuffer || !cjBuffer)
514c2c66affSColin Finck         return NULL;
515c2c66affSColin Finck 
516c2c66affSColin Finck     _SEH2_TRY
517c2c66affSColin Finck     {
518c2c66affSColin Finck         ProbeForRead(pvBuffer, cjBuffer, sizeof(BYTE));
519c2c66affSColin Finck         Buffer = ExAllocatePoolWithQuotaTag(PagedPool, cjBuffer, TAG_FONT);
520c2c66affSColin Finck         RtlCopyMemory(Buffer, pvBuffer, cjBuffer);
521c2c66affSColin Finck     }
522c2c66affSColin Finck     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
523c2c66affSColin Finck     {
524c2c66affSColin Finck         if (Buffer != NULL)
525c2c66affSColin Finck         {
526c2c66affSColin Finck             ExFreePoolWithTag(Buffer, TAG_FONT);
527c2c66affSColin Finck         }
528c2c66affSColin Finck         _SEH2_YIELD(return NULL);
529c2c66affSColin Finck     }
530c2c66affSColin Finck     _SEH2_END;
531c2c66affSColin Finck 
532c2c66affSColin Finck     Ret = IntGdiAddFontMemResource(Buffer, cjBuffer, &NumFonts);
533c2c66affSColin Finck     ExFreePoolWithTag(Buffer, TAG_FONT);
534c2c66affSColin Finck 
535c2c66affSColin Finck     _SEH2_TRY
536c2c66affSColin Finck     {
537c2c66affSColin Finck         ProbeForWrite(pNumFonts, sizeof(NumFonts), 1);
538c2c66affSColin Finck         *pNumFonts = NumFonts;
539c2c66affSColin Finck     }
540c2c66affSColin Finck     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
541c2c66affSColin Finck     {
542c2c66affSColin Finck         /* Leak it? */
543c2c66affSColin Finck         _SEH2_YIELD(return NULL);
544c2c66affSColin Finck     }
545c2c66affSColin Finck     _SEH2_END;
546c2c66affSColin Finck 
547c2c66affSColin Finck 
548c2c66affSColin Finck     return Ret;
549c2c66affSColin Finck }
550c2c66affSColin Finck 
551c2c66affSColin Finck 
552c2c66affSColin Finck BOOL
553c2c66affSColin Finck APIENTRY
NtGdiRemoveFontMemResourceEx(IN HANDLE hMMFont)554c2c66affSColin Finck NtGdiRemoveFontMemResourceEx(
555c2c66affSColin Finck     IN HANDLE hMMFont)
556c2c66affSColin Finck {
557c2c66affSColin Finck     return IntGdiRemoveFontMemResource(hMMFont);
558c2c66affSColin Finck }
559c2c66affSColin Finck 
560c2c66affSColin Finck 
561c2c66affSColin Finck  /*
562c2c66affSColin Finck  * @unimplemented
563c2c66affSColin Finck  */
564c2c66affSColin Finck DWORD
565c2c66affSColin Finck APIENTRY
NtGdiGetCharacterPlacementW(IN HDC hdc,IN LPWSTR pwsz,IN INT nCount,IN INT nMaxExtent,IN OUT LPGCP_RESULTSW pgcpw,IN DWORD dwFlags)566c2c66affSColin Finck NtGdiGetCharacterPlacementW(
567c2c66affSColin Finck     IN HDC hdc,
568c2c66affSColin Finck     IN LPWSTR pwsz,
569c2c66affSColin Finck     IN INT nCount,
570c2c66affSColin Finck     IN INT nMaxExtent,
571c2c66affSColin Finck     IN OUT LPGCP_RESULTSW pgcpw,
572c2c66affSColin Finck     IN DWORD dwFlags)
573c2c66affSColin Finck {
574c2c66affSColin Finck     UNIMPLEMENTED;
575c2c66affSColin Finck     return 0;
576c2c66affSColin Finck #if 0
577c2c66affSColin Finck     return GreGetCharacterPlacementW( hdc,
578c2c66affSColin Finck                                       pwsz,
579c2c66affSColin Finck                                       nCount,
580c2c66affSColin Finck                                       nMaxExtent,
581c2c66affSColin Finck                                       pgcpw,
582c2c66affSColin Finck                                       dwFlags);
583c2c66affSColin Finck #endif
584c2c66affSColin Finck }
585c2c66affSColin Finck 
586c2c66affSColin Finck DWORD
587c2c66affSColin Finck APIENTRY
NtGdiGetFontData(HDC hDC,DWORD Table,DWORD Offset,LPVOID Buffer,DWORD Size)588c2c66affSColin Finck NtGdiGetFontData(
589c2c66affSColin Finck    HDC hDC,
590c2c66affSColin Finck    DWORD Table,
591c2c66affSColin Finck    DWORD Offset,
592c2c66affSColin Finck    LPVOID Buffer,
593c2c66affSColin Finck    DWORD Size)
594c2c66affSColin Finck {
595c2c66affSColin Finck   PDC Dc;
596c2c66affSColin Finck   PDC_ATTR pdcattr;
597c2c66affSColin Finck   HFONT hFont;
598c2c66affSColin Finck   PTEXTOBJ TextObj;
599c2c66affSColin Finck   PFONTGDI FontGdi;
600c2c66affSColin Finck   DWORD Result = GDI_ERROR;
601c2c66affSColin Finck   NTSTATUS Status = STATUS_SUCCESS;
602c2c66affSColin Finck 
603c2c66affSColin Finck   if (Buffer && Size)
604c2c66affSColin Finck   {
605c2c66affSColin Finck      _SEH2_TRY
606c2c66affSColin Finck      {
607c2c66affSColin Finck          ProbeForRead(Buffer, Size, 1);
608c2c66affSColin Finck      }
609c2c66affSColin Finck      _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
610c2c66affSColin Finck      {
611c2c66affSColin Finck          Status = _SEH2_GetExceptionCode();
612c2c66affSColin Finck      }
613c2c66affSColin Finck      _SEH2_END
614c2c66affSColin Finck   }
615c2c66affSColin Finck 
616c2c66affSColin Finck   if (!NT_SUCCESS(Status)) return Result;
617c2c66affSColin Finck 
618c2c66affSColin Finck   Dc = DC_LockDc(hDC);
619c2c66affSColin Finck   if (Dc == NULL)
620c2c66affSColin Finck   {
621c2c66affSColin Finck      EngSetLastError(ERROR_INVALID_HANDLE);
622c2c66affSColin Finck      return GDI_ERROR;
623c2c66affSColin Finck   }
624c2c66affSColin Finck   pdcattr = Dc->pdcattr;
625c2c66affSColin Finck 
626c2c66affSColin Finck   hFont = pdcattr->hlfntNew;
627c2c66affSColin Finck   TextObj = RealizeFontInit(hFont);
628c2c66affSColin Finck   DC_UnlockDc(Dc);
629c2c66affSColin Finck 
630c2c66affSColin Finck   if (TextObj == NULL)
631c2c66affSColin Finck   {
632c2c66affSColin Finck      EngSetLastError(ERROR_INVALID_HANDLE);
633c2c66affSColin Finck      return GDI_ERROR;
634c2c66affSColin Finck   }
635c2c66affSColin Finck 
636c2c66affSColin Finck   FontGdi = ObjToGDI(TextObj->Font, FONT);
637c2c66affSColin Finck 
638c2c66affSColin Finck   Result = ftGdiGetFontData(FontGdi, Table, Offset, Buffer, Size);
639c2c66affSColin Finck 
640c2c66affSColin Finck   TEXTOBJ_UnlockText(TextObj);
641c2c66affSColin Finck 
642c2c66affSColin Finck   return Result;
643c2c66affSColin Finck }
644c2c66affSColin Finck 
645c2c66affSColin Finck  /*
646c2c66affSColin Finck  * @implemented
647c2c66affSColin Finck  */
648c2c66affSColin Finck DWORD
649c2c66affSColin Finck APIENTRY
NtGdiGetFontUnicodeRanges(IN HDC hdc,OUT OPTIONAL LPGLYPHSET pgs)650c2c66affSColin Finck NtGdiGetFontUnicodeRanges(
651c2c66affSColin Finck     IN HDC hdc,
652c2c66affSColin Finck     OUT OPTIONAL LPGLYPHSET pgs)
653c2c66affSColin Finck {
654c2c66affSColin Finck   PDC pDc;
655c2c66affSColin Finck   PDC_ATTR pdcattr;
656c2c66affSColin Finck   HFONT hFont;
657c2c66affSColin Finck   PTEXTOBJ TextObj;
658c2c66affSColin Finck   PFONTGDI FontGdi;
659c2c66affSColin Finck   DWORD Size = 0;
660c2c66affSColin Finck   PGLYPHSET pgsSafe;
661c2c66affSColin Finck   NTSTATUS Status = STATUS_SUCCESS;
662c2c66affSColin Finck 
663c2c66affSColin Finck   pDc = DC_LockDc(hdc);
664c2c66affSColin Finck   if (!pDc)
665c2c66affSColin Finck   {
666c2c66affSColin Finck      EngSetLastError(ERROR_INVALID_HANDLE);
667c2c66affSColin Finck      return 0;
668c2c66affSColin Finck   }
669c2c66affSColin Finck 
670c2c66affSColin Finck   pdcattr = pDc->pdcattr;
671c2c66affSColin Finck 
672c2c66affSColin Finck   hFont = pdcattr->hlfntNew;
673c2c66affSColin Finck   TextObj = RealizeFontInit(hFont);
674c2c66affSColin Finck 
675c2c66affSColin Finck   if ( TextObj == NULL)
676c2c66affSColin Finck   {
677c2c66affSColin Finck      EngSetLastError(ERROR_INVALID_HANDLE);
678c2c66affSColin Finck      goto Exit;
679c2c66affSColin Finck   }
680c2c66affSColin Finck   FontGdi = ObjToGDI(TextObj->Font, FONT);
681c2c66affSColin Finck 
682c2c66affSColin Finck   Size = ftGetFontUnicodeRanges( FontGdi, NULL);
683c2c66affSColin Finck 
684c2c66affSColin Finck   if (Size && pgs)
685c2c66affSColin Finck   {
686c2c66affSColin Finck      pgsSafe = ExAllocatePoolWithTag(PagedPool, Size, GDITAG_TEXT);
687c2c66affSColin Finck      if (!pgsSafe)
688c2c66affSColin Finck      {
689c2c66affSColin Finck         EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
690c2c66affSColin Finck         Size = 0;
691c2c66affSColin Finck         goto Exit;
692c2c66affSColin Finck      }
693c2c66affSColin Finck 
694c2c66affSColin Finck      Size = ftGetFontUnicodeRanges( FontGdi, pgsSafe);
695c2c66affSColin Finck 
696c2c66affSColin Finck      if (Size)
697c2c66affSColin Finck      {
698c2c66affSColin Finck         _SEH2_TRY
699c2c66affSColin Finck         {
700c2c66affSColin Finck             ProbeForWrite(pgs, Size, 1);
701c2c66affSColin Finck             RtlCopyMemory(pgs, pgsSafe, Size);
702c2c66affSColin Finck         }
703c2c66affSColin Finck         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
704c2c66affSColin Finck         {
705c2c66affSColin Finck            Status = _SEH2_GetExceptionCode();
706c2c66affSColin Finck         }
707c2c66affSColin Finck         _SEH2_END
708c2c66affSColin Finck 
709c2c66affSColin Finck         if (!NT_SUCCESS(Status)) Size = 0;
710c2c66affSColin Finck      }
711c2c66affSColin Finck      ExFreePoolWithTag(pgsSafe, GDITAG_TEXT);
712c2c66affSColin Finck   }
713c2c66affSColin Finck Exit:
714c2c66affSColin Finck   TEXTOBJ_UnlockText(TextObj);
715c2c66affSColin Finck   DC_UnlockDc(pDc);
716c2c66affSColin Finck   return Size;
717c2c66affSColin Finck }
718c2c66affSColin Finck 
719c2c66affSColin Finck ULONG
720c2c66affSColin Finck APIENTRY
NtGdiGetGlyphOutline(IN HDC hdc,IN WCHAR wch,IN UINT iFormat,OUT LPGLYPHMETRICS pgm,IN ULONG cjBuf,OUT OPTIONAL PVOID UnsafeBuf,IN LPMAT2 pmat2,IN BOOL bIgnoreRotation)721c2c66affSColin Finck NtGdiGetGlyphOutline(
722c2c66affSColin Finck     IN HDC hdc,
723c2c66affSColin Finck     IN WCHAR wch,
724c2c66affSColin Finck     IN UINT iFormat,
725c2c66affSColin Finck     OUT LPGLYPHMETRICS pgm,
726c2c66affSColin Finck     IN ULONG cjBuf,
727c2c66affSColin Finck     OUT OPTIONAL PVOID UnsafeBuf,
728c2c66affSColin Finck     IN LPMAT2 pmat2,
729c2c66affSColin Finck     IN BOOL bIgnoreRotation)
730c2c66affSColin Finck {
731c2c66affSColin Finck   ULONG Ret = GDI_ERROR;
732c2c66affSColin Finck   PDC dc;
733c2c66affSColin Finck   PVOID pvBuf = NULL;
734c2c66affSColin Finck   GLYPHMETRICS gm;
735c2c66affSColin Finck   NTSTATUS Status = STATUS_SUCCESS;
736c2c66affSColin Finck 
737c2c66affSColin Finck   dc = DC_LockDc(hdc);
738c2c66affSColin Finck   if (!dc)
739c2c66affSColin Finck   {
740c2c66affSColin Finck      EngSetLastError(ERROR_INVALID_HANDLE);
741c2c66affSColin Finck      return GDI_ERROR;
742c2c66affSColin Finck   }
743c2c66affSColin Finck 
744c2c66affSColin Finck   if (UnsafeBuf && cjBuf)
745c2c66affSColin Finck   {
746a081e12fSNguyen Trung Khanh      pvBuf = ExAllocatePoolZero(PagedPool, cjBuf, GDITAG_TEXT);
747c2c66affSColin Finck      if (!pvBuf)
748c2c66affSColin Finck      {
749c2c66affSColin Finck         EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
750c2c66affSColin Finck         goto Exit;
751c2c66affSColin Finck      }
752c2c66affSColin Finck   }
753c2c66affSColin Finck 
754c2c66affSColin Finck   Ret = ftGdiGetGlyphOutline( dc,
755c2c66affSColin Finck                              wch,
756c2c66affSColin Finck                          iFormat,
757c2c66affSColin Finck                              pgm ? &gm : NULL,
758c2c66affSColin Finck                            cjBuf,
759c2c66affSColin Finck                            pvBuf,
760c2c66affSColin Finck                            pmat2,
761c2c66affSColin Finck                  bIgnoreRotation);
762c2c66affSColin Finck 
763c2c66affSColin Finck   if (pvBuf)
764c2c66affSColin Finck   {
765c2c66affSColin Finck      _SEH2_TRY
766c2c66affSColin Finck      {
767c2c66affSColin Finck          ProbeForWrite(UnsafeBuf, cjBuf, 1);
768c2c66affSColin Finck          RtlCopyMemory(UnsafeBuf, pvBuf, cjBuf);
769c2c66affSColin Finck      }
770c2c66affSColin Finck      _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
771c2c66affSColin Finck      {
772c2c66affSColin Finck          Status = _SEH2_GetExceptionCode();
773c2c66affSColin Finck      }
774c2c66affSColin Finck      _SEH2_END
775c2c66affSColin Finck 
776c2c66affSColin Finck      ExFreePoolWithTag(pvBuf, GDITAG_TEXT);
777c2c66affSColin Finck   }
778c2c66affSColin Finck 
779c2c66affSColin Finck   if (pgm)
780c2c66affSColin Finck   {
781c2c66affSColin Finck      _SEH2_TRY
782c2c66affSColin Finck      {
783c2c66affSColin Finck          ProbeForWrite(pgm, sizeof(GLYPHMETRICS), 1);
784c2c66affSColin Finck          RtlCopyMemory(pgm, &gm, sizeof(GLYPHMETRICS));
785c2c66affSColin Finck      }
786c2c66affSColin Finck      _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
787c2c66affSColin Finck      {
788c2c66affSColin Finck          Status = _SEH2_GetExceptionCode();
789c2c66affSColin Finck      }
790c2c66affSColin Finck      _SEH2_END
791c2c66affSColin Finck   }
792c2c66affSColin Finck 
793c2c66affSColin Finck   if (! NT_SUCCESS(Status))
794c2c66affSColin Finck   {
795c2c66affSColin Finck      EngSetLastError(ERROR_INVALID_PARAMETER);
796c2c66affSColin Finck      Ret = GDI_ERROR;
797c2c66affSColin Finck   }
798c2c66affSColin Finck 
799c2c66affSColin Finck Exit:
800c2c66affSColin Finck   DC_UnlockDc(dc);
801c2c66affSColin Finck   return Ret;
802c2c66affSColin Finck }
803c2c66affSColin Finck 
804c2c66affSColin Finck DWORD
805c2c66affSColin Finck APIENTRY
NtGdiGetKerningPairs(HDC hDC,ULONG NumPairs,LPKERNINGPAIR krnpair)806c2c66affSColin Finck NtGdiGetKerningPairs(HDC  hDC,
807c2c66affSColin Finck                      ULONG  NumPairs,
808c2c66affSColin Finck                      LPKERNINGPAIR  krnpair)
809c2c66affSColin Finck {
810c2c66affSColin Finck   PDC dc;
811c2c66affSColin Finck   PDC_ATTR pdcattr;
812c2c66affSColin Finck   PTEXTOBJ TextObj;
813c2c66affSColin Finck   PFONTGDI FontGDI;
814c2c66affSColin Finck   DWORD Count;
815c2c66affSColin Finck   KERNINGPAIR *pKP;
816c2c66affSColin Finck   NTSTATUS Status = STATUS_SUCCESS;
817c2c66affSColin Finck 
818c2c66affSColin Finck   dc = DC_LockDc(hDC);
819c2c66affSColin Finck   if (!dc)
820c2c66affSColin Finck   {
821c2c66affSColin Finck      EngSetLastError(ERROR_INVALID_HANDLE);
822c2c66affSColin Finck      return 0;
823c2c66affSColin Finck   }
824c2c66affSColin Finck 
825c2c66affSColin Finck   pdcattr = dc->pdcattr;
826c2c66affSColin Finck   TextObj = RealizeFontInit(pdcattr->hlfntNew);
827c2c66affSColin Finck   DC_UnlockDc(dc);
828c2c66affSColin Finck 
829c2c66affSColin Finck   if (!TextObj)
830c2c66affSColin Finck   {
831c2c66affSColin Finck      EngSetLastError(ERROR_INVALID_HANDLE);
832c2c66affSColin Finck      return 0;
833c2c66affSColin Finck   }
834c2c66affSColin Finck 
835c2c66affSColin Finck   FontGDI = ObjToGDI(TextObj->Font, FONT);
836c2c66affSColin Finck   TEXTOBJ_UnlockText(TextObj);
837c2c66affSColin Finck 
838c2c66affSColin Finck   Count = ftGdiGetKerningPairs(FontGDI,0,NULL);
839c2c66affSColin Finck 
840c2c66affSColin Finck   if ( Count && krnpair )
841c2c66affSColin Finck   {
842c2c66affSColin Finck      if (Count > NumPairs)
843c2c66affSColin Finck      {
844c2c66affSColin Finck         EngSetLastError(ERROR_INSUFFICIENT_BUFFER);
845c2c66affSColin Finck         return 0;
846c2c66affSColin Finck      }
847c2c66affSColin Finck      pKP = ExAllocatePoolWithTag(PagedPool, Count * sizeof(KERNINGPAIR), GDITAG_TEXT);
848c2c66affSColin Finck      if (!pKP)
849c2c66affSColin Finck      {
850c2c66affSColin Finck         EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
851c2c66affSColin Finck         return 0;
852c2c66affSColin Finck      }
853c2c66affSColin Finck      ftGdiGetKerningPairs(FontGDI,Count,pKP);
854c2c66affSColin Finck      _SEH2_TRY
855c2c66affSColin Finck      {
856c2c66affSColin Finck         ProbeForWrite(krnpair, Count * sizeof(KERNINGPAIR), 1);
857c2c66affSColin Finck         RtlCopyMemory(krnpair, pKP, Count * sizeof(KERNINGPAIR));
858c2c66affSColin Finck      }
859c2c66affSColin Finck      _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
860c2c66affSColin Finck      {
861c2c66affSColin Finck         Status = _SEH2_GetExceptionCode();
862c2c66affSColin Finck      }
863c2c66affSColin Finck      _SEH2_END
864c2c66affSColin Finck      if (!NT_SUCCESS(Status))
865c2c66affSColin Finck      {
866c2c66affSColin Finck         EngSetLastError(ERROR_INVALID_PARAMETER);
867c2c66affSColin Finck         Count = 0;
868c2c66affSColin Finck      }
869c2c66affSColin Finck      ExFreePoolWithTag(pKP,GDITAG_TEXT);
870c2c66affSColin Finck   }
871c2c66affSColin Finck   return Count;
872c2c66affSColin Finck }
873c2c66affSColin Finck 
874c2c66affSColin Finck /*
875c2c66affSColin Finck  From "Undocumented Windows 2000 Secrets" Appendix B, Table B-2, page
876c2c66affSColin Finck  472, this is NtGdiGetOutlineTextMetricsInternalW.
877c2c66affSColin Finck  */
878c2c66affSColin Finck ULONG
879c2c66affSColin Finck APIENTRY
NtGdiGetOutlineTextMetricsInternalW(HDC hDC,ULONG Data,OUTLINETEXTMETRICW * otm,TMDIFF * Tmd)880c2c66affSColin Finck NtGdiGetOutlineTextMetricsInternalW (HDC  hDC,
881c2c66affSColin Finck                                    ULONG  Data,
882c2c66affSColin Finck                       OUTLINETEXTMETRICW  *otm,
883c2c66affSColin Finck                                    TMDIFF *Tmd)
884c2c66affSColin Finck {
885c2c66affSColin Finck   PDC dc;
886c2c66affSColin Finck   PDC_ATTR pdcattr;
887c2c66affSColin Finck   PTEXTOBJ TextObj;
888c2c66affSColin Finck   PFONTGDI FontGDI;
889c2c66affSColin Finck   HFONT hFont = 0;
890c2c66affSColin Finck   ULONG Size;
891c2c66affSColin Finck   OUTLINETEXTMETRICW *potm;
892c2c66affSColin Finck   NTSTATUS Status = STATUS_SUCCESS;
893c2c66affSColin Finck 
894c2c66affSColin Finck   dc = DC_LockDc(hDC);
895c2c66affSColin Finck   if (!dc)
896c2c66affSColin Finck   {
897c2c66affSColin Finck      EngSetLastError(ERROR_INVALID_HANDLE);
898c2c66affSColin Finck      return 0;
899c2c66affSColin Finck   }
900c2c66affSColin Finck   pdcattr = dc->pdcattr;
901c2c66affSColin Finck   hFont = pdcattr->hlfntNew;
902c2c66affSColin Finck   TextObj = RealizeFontInit(hFont);
903c2c66affSColin Finck   DC_UnlockDc(dc);
904c2c66affSColin Finck   if (!TextObj)
905c2c66affSColin Finck   {
906c2c66affSColin Finck      EngSetLastError(ERROR_INVALID_HANDLE);
907c2c66affSColin Finck      return 0;
908c2c66affSColin Finck   }
909c2c66affSColin Finck   FontGDI = ObjToGDI(TextObj->Font, FONT);
910ae99df16SKatayama Hirofumi MZ   if (!(FontGDI->flType & FO_TYPE_TRUETYPE))
911ae99df16SKatayama Hirofumi MZ   {
912ae99df16SKatayama Hirofumi MZ      TEXTOBJ_UnlockText(TextObj);
913ae99df16SKatayama Hirofumi MZ      return 0;
914ae99df16SKatayama Hirofumi MZ   }
915c2c66affSColin Finck   TextIntUpdateSize(dc, TextObj, FontGDI, TRUE);
916c2c66affSColin Finck   TEXTOBJ_UnlockText(TextObj);
917*0f9e8897SKatayama Hirofumi MZ   Size = IntGetOutlineTextMetrics(FontGDI, 0, NULL, FALSE);
918c2c66affSColin Finck   if (!otm) return Size;
919c2c66affSColin Finck   if (Size > Data)
920c2c66affSColin Finck   {
921c2c66affSColin Finck       EngSetLastError(ERROR_INSUFFICIENT_BUFFER);
922c2c66affSColin Finck       return 0;
923c2c66affSColin Finck   }
924c2c66affSColin Finck   potm = ExAllocatePoolWithTag(PagedPool, Size, GDITAG_TEXT);
925c2c66affSColin Finck   if (!potm)
926c2c66affSColin Finck   {
927c2c66affSColin Finck       EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
928c2c66affSColin Finck       return 0;
929c2c66affSColin Finck   }
93050510538SNguyen Trung Khanh   RtlZeroMemory(potm, Size);
931*0f9e8897SKatayama Hirofumi MZ   IntGetOutlineTextMetrics(FontGDI, Size, potm, FALSE);
9321bf982ffSKatayama Hirofumi MZ 
933c2c66affSColin Finck   _SEH2_TRY
934c2c66affSColin Finck   {
935c2c66affSColin Finck       ProbeForWrite(otm, Size, 1);
936c2c66affSColin Finck       RtlCopyMemory(otm, potm, Size);
937c2c66affSColin Finck   }
938c2c66affSColin Finck   _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
939c2c66affSColin Finck   {
940c2c66affSColin Finck       Status = _SEH2_GetExceptionCode();
941c2c66affSColin Finck   }
942c2c66affSColin Finck   _SEH2_END
943c2c66affSColin Finck 
944c2c66affSColin Finck   if (!NT_SUCCESS(Status))
945c2c66affSColin Finck   {
946c2c66affSColin Finck      EngSetLastError(ERROR_INVALID_PARAMETER);
947c2c66affSColin Finck      Size = 0;
948c2c66affSColin Finck   }
9491bf982ffSKatayama Hirofumi MZ 
950c2c66affSColin Finck   ExFreePoolWithTag(potm,GDITAG_TEXT);
951c2c66affSColin Finck   return Size;
952c2c66affSColin Finck }
953c2c66affSColin Finck 
954c2c66affSColin Finck W32KAPI
955c2c66affSColin Finck BOOL
956c2c66affSColin Finck APIENTRY
NtGdiGetFontResourceInfoInternalW(IN LPWSTR pwszFiles,IN ULONG cwc,IN ULONG cFiles,IN UINT cjIn,IN OUT LPDWORD pdwBytes,OUT LPVOID pvBuf,IN DWORD dwType)957c2c66affSColin Finck NtGdiGetFontResourceInfoInternalW(
958c2c66affSColin Finck     IN LPWSTR       pwszFiles,
959c2c66affSColin Finck     IN ULONG        cwc,
960c2c66affSColin Finck     IN ULONG        cFiles,
961c2c66affSColin Finck     IN UINT         cjIn,
962c2c66affSColin Finck     IN OUT LPDWORD  pdwBytes,
963c2c66affSColin Finck     OUT LPVOID      pvBuf,
964c2c66affSColin Finck     IN DWORD        dwType)
965c2c66affSColin Finck {
966c2c66affSColin Finck     NTSTATUS Status = STATUS_SUCCESS;
967c2c66affSColin Finck     DWORD dwBytes, dwBytesRequested;
968c2c66affSColin Finck     UNICODE_STRING SafeFileNames;
969c2c66affSColin Finck     BOOL bRet = FALSE;
970c2c66affSColin Finck     ULONG cbStringSize;
971c2c66affSColin Finck     LPVOID Buffer;
972c2c66affSColin Finck 
973c2c66affSColin Finck     /* FIXME: Handle cFiles > 0 */
974c2c66affSColin Finck 
975c2c66affSColin Finck     /* Check for valid dwType values */
976c2c66affSColin Finck     if (dwType > 5)
977c2c66affSColin Finck     {
978c2c66affSColin Finck         EngSetLastError(ERROR_INVALID_PARAMETER);
979c2c66affSColin Finck         return FALSE;
980c2c66affSColin Finck     }
981c2c66affSColin Finck 
982c2c66affSColin Finck     /* Allocate a safe unicode string buffer */
983c2c66affSColin Finck     cbStringSize = cwc * sizeof(WCHAR);
984c2c66affSColin Finck     SafeFileNames.MaximumLength = SafeFileNames.Length = (USHORT)cbStringSize - sizeof(WCHAR);
985c2c66affSColin Finck     SafeFileNames.Buffer = ExAllocatePoolWithTag(PagedPool,
986c2c66affSColin Finck                                                  cbStringSize,
987c2c66affSColin Finck                                                  TAG_USTR);
988c2c66affSColin Finck     if (!SafeFileNames.Buffer)
989c2c66affSColin Finck     {
990c2c66affSColin Finck         EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
991c2c66affSColin Finck         return FALSE;
992c2c66affSColin Finck     }
993c2c66affSColin Finck     RtlZeroMemory(SafeFileNames.Buffer, SafeFileNames.MaximumLength);
994c2c66affSColin Finck 
995c2c66affSColin Finck     /* Check buffers and copy pwszFiles to safe unicode string */
996c2c66affSColin Finck     _SEH2_TRY
997c2c66affSColin Finck     {
998c2c66affSColin Finck         ProbeForRead(pwszFiles, cbStringSize, 1);
999c2c66affSColin Finck         ProbeForWrite(pdwBytes, sizeof(DWORD), 1);
1000c2c66affSColin Finck         if (pvBuf)
1001c2c66affSColin Finck             ProbeForWrite(pvBuf, cjIn, 1);
1002c2c66affSColin Finck 
1003c2c66affSColin Finck         dwBytes = *pdwBytes;
1004c2c66affSColin Finck         dwBytesRequested = dwBytes;
1005c2c66affSColin Finck 
1006c2c66affSColin Finck         RtlCopyMemory(SafeFileNames.Buffer, pwszFiles, cbStringSize);
1007c2c66affSColin Finck         if (dwBytes > 0)
1008c2c66affSColin Finck         {
1009c2c66affSColin Finck             Buffer = ExAllocatePoolWithTag(PagedPool, dwBytes, TAG_FINF);
1010c2c66affSColin Finck         }
1011c2c66affSColin Finck         else
1012c2c66affSColin Finck         {
1013c2c66affSColin Finck             Buffer = ExAllocatePoolWithTag(PagedPool, sizeof(DWORD), TAG_FINF);
1014c2c66affSColin Finck         }
1015c2c66affSColin Finck     }
1016c2c66affSColin Finck     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
1017c2c66affSColin Finck     {
1018c2c66affSColin Finck         Status = _SEH2_GetExceptionCode();
1019c2c66affSColin Finck     }
1020c2c66affSColin Finck     _SEH2_END
1021c2c66affSColin Finck 
1022c2c66affSColin Finck     if(!NT_SUCCESS(Status))
1023c2c66affSColin Finck     {
1024c2c66affSColin Finck         SetLastNtError(Status);
1025c2c66affSColin Finck         /* Free the string buffer for the safe filename */
1026c2c66affSColin Finck         ExFreePoolWithTag(SafeFileNames.Buffer, TAG_USTR);
1027c2c66affSColin Finck         return FALSE;
1028c2c66affSColin Finck     }
1029c2c66affSColin Finck 
1030c2c66affSColin Finck     /* Do the actual call */
1031c2c66affSColin Finck     bRet = IntGdiGetFontResourceInfo(&SafeFileNames,
1032c2c66affSColin Finck                                      (pvBuf ? Buffer : NULL),
1033c2c66affSColin Finck                                      &dwBytes, dwType);
1034c2c66affSColin Finck 
1035c2c66affSColin Finck     /* Check if succeeded */
1036c2c66affSColin Finck     if (bRet)
1037c2c66affSColin Finck     {
1038c2c66affSColin Finck         /* Copy the data back to caller */
1039c2c66affSColin Finck         _SEH2_TRY
1040c2c66affSColin Finck         {
1041c2c66affSColin Finck             /* Buffers are already probed */
1042c2c66affSColin Finck             if (pvBuf && dwBytesRequested > 0)
1043c2c66affSColin Finck                 RtlCopyMemory(pvBuf, Buffer, min(dwBytesRequested, dwBytes));
1044c2c66affSColin Finck             *pdwBytes = dwBytes;
1045c2c66affSColin Finck         }
1046c2c66affSColin Finck         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
1047c2c66affSColin Finck         {
1048c2c66affSColin Finck             Status = _SEH2_GetExceptionCode();
1049c2c66affSColin Finck         }
1050c2c66affSColin Finck         _SEH2_END
1051c2c66affSColin Finck 
1052c2c66affSColin Finck         if(!NT_SUCCESS(Status))
1053c2c66affSColin Finck         {
1054c2c66affSColin Finck             SetLastNtError(Status);
1055c2c66affSColin Finck             bRet = FALSE;
1056c2c66affSColin Finck         }
1057c2c66affSColin Finck     }
1058c2c66affSColin Finck 
1059c2c66affSColin Finck     ExFreePoolWithTag(Buffer, TAG_FINF);
1060c2c66affSColin Finck     /* Free the string for the safe filenames */
1061c2c66affSColin Finck     ExFreePoolWithTag(SafeFileNames.Buffer, TAG_USTR);
1062c2c66affSColin Finck 
1063c2c66affSColin Finck     return bRet;
1064c2c66affSColin Finck }
1065c2c66affSColin Finck 
1066c2c66affSColin Finck  /*
1067c2c66affSColin Finck  * @unimplemented
1068c2c66affSColin Finck  */
1069c2c66affSColin Finck BOOL
1070c2c66affSColin Finck APIENTRY
NtGdiGetRealizationInfo(IN HDC hdc,OUT PREALIZATION_INFO pri,IN HFONT hf)1071c2c66affSColin Finck NtGdiGetRealizationInfo(
1072c2c66affSColin Finck     IN HDC hdc,
1073c2c66affSColin Finck     OUT PREALIZATION_INFO pri,
1074c2c66affSColin Finck     IN HFONT hf)
1075c2c66affSColin Finck {
1076c2c66affSColin Finck   PDC pDc;
1077c2c66affSColin Finck   PTEXTOBJ pTextObj;
1078c2c66affSColin Finck   PFONTGDI pFontGdi;
1079c2c66affSColin Finck   PDC_ATTR pdcattr;
1080c2c66affSColin Finck   BOOL Ret = FALSE;
1081c2c66affSColin Finck   INT i = 0;
1082c2c66affSColin Finck   REALIZATION_INFO ri;
1083c2c66affSColin Finck 
1084c2c66affSColin Finck   pDc = DC_LockDc(hdc);
1085c2c66affSColin Finck   if (!pDc)
1086c2c66affSColin Finck   {
1087c2c66affSColin Finck      EngSetLastError(ERROR_INVALID_HANDLE);
1088c2c66affSColin Finck      return 0;
1089c2c66affSColin Finck   }
1090c2c66affSColin Finck   pdcattr = pDc->pdcattr;
1091c2c66affSColin Finck   pTextObj = RealizeFontInit(pdcattr->hlfntNew);
1092e9095430SKatayama Hirofumi MZ   ASSERT(pTextObj != NULL);
1093c2c66affSColin Finck   pFontGdi = ObjToGDI(pTextObj->Font, FONT);
1094c2c66affSColin Finck   TEXTOBJ_UnlockText(pTextObj);
1095c2c66affSColin Finck   DC_UnlockDc(pDc);
1096c2c66affSColin Finck 
1097c2c66affSColin Finck   Ret = ftGdiRealizationInfo(pFontGdi, &ri);
1098c2c66affSColin Finck   if (Ret)
1099c2c66affSColin Finck   {
1100c2c66affSColin Finck      if (pri)
1101c2c66affSColin Finck      {
1102c2c66affSColin Finck         NTSTATUS Status = STATUS_SUCCESS;
1103c2c66affSColin Finck         _SEH2_TRY
1104c2c66affSColin Finck         {
1105c2c66affSColin Finck             ProbeForWrite(pri, sizeof(REALIZATION_INFO), 1);
1106c2c66affSColin Finck             RtlCopyMemory(pri, &ri, sizeof(REALIZATION_INFO));
1107c2c66affSColin Finck         }
1108c2c66affSColin Finck         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
1109c2c66affSColin Finck         {
1110c2c66affSColin Finck             Status = _SEH2_GetExceptionCode();
1111c2c66affSColin Finck         }
1112c2c66affSColin Finck         _SEH2_END
1113c2c66affSColin Finck 
1114c2c66affSColin Finck         if(!NT_SUCCESS(Status))
1115c2c66affSColin Finck         {
1116c2c66affSColin Finck             SetLastNtError(Status);
1117c2c66affSColin Finck             return FALSE;
1118c2c66affSColin Finck         }
1119c2c66affSColin Finck      }
1120c2c66affSColin Finck      do
1121c2c66affSColin Finck      {
1122c2c66affSColin Finck         if (GdiHandleTable->cfPublic[i].hf == hf)
1123c2c66affSColin Finck         {
1124c2c66affSColin Finck            GdiHandleTable->cfPublic[i].iTechnology = ri.iTechnology;
1125c2c66affSColin Finck            GdiHandleTable->cfPublic[i].iUniq = ri.iUniq;
1126c2c66affSColin Finck            GdiHandleTable->cfPublic[i].dwUnknown = ri.dwUnknown;
1127c2c66affSColin Finck            GdiHandleTable->cfPublic[i].dwCFCount = GdiHandleTable->dwCFCount;
1128c2c66affSColin Finck            GdiHandleTable->cfPublic[i].fl |= CFONT_REALIZATION;
1129c2c66affSColin Finck         }
1130c2c66affSColin Finck         i++;
1131c2c66affSColin Finck      }
1132c2c66affSColin Finck      while ( i < GDI_CFONT_MAX );
1133c2c66affSColin Finck   }
1134c2c66affSColin Finck   return Ret;
1135c2c66affSColin Finck }
1136c2c66affSColin Finck 
1137c2c66affSColin Finck 
1138c2c66affSColin Finck HFONT
1139c2c66affSColin Finck APIENTRY
HfontCreate(IN PENUMLOGFONTEXDVW pelfw,IN ULONG cjElfw,IN LFTYPE lft,IN FLONG fl,IN PVOID pvCliData)1140c2c66affSColin Finck HfontCreate(
1141c2c66affSColin Finck   IN PENUMLOGFONTEXDVW pelfw,
1142c2c66affSColin Finck   IN ULONG cjElfw,
1143c2c66affSColin Finck   IN LFTYPE lft,
1144c2c66affSColin Finck   IN FLONG  fl,
1145c2c66affSColin Finck   IN PVOID pvCliData )
1146c2c66affSColin Finck {
1147c2c66affSColin Finck   HFONT hNewFont;
1148c2c66affSColin Finck   PLFONT plfont;
1149c2c66affSColin Finck 
1150c2c66affSColin Finck   if (!pelfw)
1151c2c66affSColin Finck   {
1152c2c66affSColin Finck       return NULL;
1153c2c66affSColin Finck   }
1154c2c66affSColin Finck 
1155c2c66affSColin Finck   plfont = LFONT_AllocFontWithHandle();
1156c2c66affSColin Finck   if (!plfont)
1157c2c66affSColin Finck   {
1158c2c66affSColin Finck       return NULL;
1159c2c66affSColin Finck   }
1160c2c66affSColin Finck   hNewFont = plfont->BaseObject.hHmgr;
1161c2c66affSColin Finck 
1162c2c66affSColin Finck   plfont->lft = lft;
1163c2c66affSColin Finck   plfont->fl  = fl;
1164c2c66affSColin Finck   RtlCopyMemory (&plfont->logfont, pelfw, sizeof(ENUMLOGFONTEXDVW));
1165c2c66affSColin Finck   ExInitializePushLock(&plfont->lock);
1166c2c66affSColin Finck 
1167c2c66affSColin Finck   if (pelfw->elfEnumLogfontEx.elfLogFont.lfEscapement !=
1168c2c66affSColin Finck       pelfw->elfEnumLogfontEx.elfLogFont.lfOrientation)
1169c2c66affSColin Finck   {
1170c2c66affSColin Finck     /* This should really depend on whether GM_ADVANCED is set */
1171c2c66affSColin Finck     plfont->logfont.elfEnumLogfontEx.elfLogFont.lfOrientation =
1172c2c66affSColin Finck     plfont->logfont.elfEnumLogfontEx.elfLogFont.lfEscapement;
1173c2c66affSColin Finck   }
1174c2c66affSColin Finck   LFONT_UnlockFont(plfont);
1175c2c66affSColin Finck 
1176c2c66affSColin Finck   if (pvCliData && hNewFont)
1177c2c66affSColin Finck   {
1178c2c66affSColin Finck     // FIXME: Use GDIOBJ_InsertUserData
1179c2c66affSColin Finck     KeEnterCriticalRegion();
1180c2c66affSColin Finck     {
1181c2c66affSColin Finck        INT Index = GDI_HANDLE_GET_INDEX((HGDIOBJ)hNewFont);
1182c2c66affSColin Finck        PGDI_TABLE_ENTRY Entry = &GdiHandleTable->Entries[Index];
1183c2c66affSColin Finck        Entry->UserData = pvCliData;
1184c2c66affSColin Finck     }
1185c2c66affSColin Finck     KeLeaveCriticalRegion();
1186c2c66affSColin Finck   }
1187c2c66affSColin Finck 
1188c2c66affSColin Finck   return hNewFont;
1189c2c66affSColin Finck }
1190c2c66affSColin Finck 
1191c2c66affSColin Finck 
1192c2c66affSColin Finck HFONT
1193c2c66affSColin Finck APIENTRY
NtGdiHfontCreate(IN PENUMLOGFONTEXDVW pelfw,IN ULONG cjElfw,IN LFTYPE lft,IN FLONG fl,IN PVOID pvCliData)1194c2c66affSColin Finck NtGdiHfontCreate(
1195c2c66affSColin Finck   IN PENUMLOGFONTEXDVW pelfw,
1196c2c66affSColin Finck   IN ULONG cjElfw,
1197c2c66affSColin Finck   IN LFTYPE lft,
1198c2c66affSColin Finck   IN FLONG  fl,
1199c2c66affSColin Finck   IN PVOID pvCliData )
1200c2c66affSColin Finck {
1201c2c66affSColin Finck   ENUMLOGFONTEXDVW SafeLogfont;
1202c2c66affSColin Finck   NTSTATUS Status = STATUS_SUCCESS;
1203c2c66affSColin Finck 
1204c2c66affSColin Finck   /* Silence GCC warnings */
1205c2c66affSColin Finck   SafeLogfont.elfEnumLogfontEx.elfLogFont.lfEscapement = 0;
1206c2c66affSColin Finck   SafeLogfont.elfEnumLogfontEx.elfLogFont.lfOrientation = 0;
1207c2c66affSColin Finck 
1208c2c66affSColin Finck   if (!pelfw)
1209c2c66affSColin Finck   {
1210c2c66affSColin Finck       return NULL;
1211c2c66affSColin Finck   }
1212c2c66affSColin Finck 
1213c2c66affSColin Finck   _SEH2_TRY
1214c2c66affSColin Finck   {
1215c2c66affSColin Finck       ProbeForRead(pelfw, sizeof(ENUMLOGFONTEXDVW), 1);
1216c2c66affSColin Finck       RtlCopyMemory(&SafeLogfont, pelfw, sizeof(ENUMLOGFONTEXDVW));
1217c2c66affSColin Finck   }
1218c2c66affSColin Finck   _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
1219c2c66affSColin Finck   {
1220c2c66affSColin Finck       Status = _SEH2_GetExceptionCode();
1221c2c66affSColin Finck   }
1222c2c66affSColin Finck   _SEH2_END
1223c2c66affSColin Finck 
1224c2c66affSColin Finck   if (!NT_SUCCESS(Status))
1225c2c66affSColin Finck   {
1226c2c66affSColin Finck       return NULL;
1227c2c66affSColin Finck   }
1228c2c66affSColin Finck 
1229c2c66affSColin Finck   return HfontCreate(&SafeLogfont, cjElfw, lft, fl, pvCliData);
1230c2c66affSColin Finck }
1231c2c66affSColin Finck 
1232c2c66affSColin Finck 
1233c2c66affSColin Finck /* EOF */
1234