2 * PROJECT: ReactOS win32 kernel mode subsystem
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: subsystems/win32/win32k/objects/font.c
9 /** Includes ******************************************************************/
16 HFONT APIENTRY
HfontCreate( IN PENUMLOGFONTEXDVW pelfw
,IN ULONG cjElfw
,IN LFTYPE lft
,IN FLONG fl
,IN PVOID pvCliData
);
18 /** Internal ******************************************************************/
21 GreCreateFontIndirectW( LOGFONTW
*lplf
)
25 ENUMLOGFONTEXDVW Logfont
;
27 RtlCopyMemory( &Logfont
.elfEnumLogfontEx
.elfLogFont
, lplf
, sizeof(LOGFONTW
));
28 RtlZeroMemory( &Logfont
.elfEnumLogfontEx
.elfFullName
,
29 sizeof(Logfont
.elfEnumLogfontEx
.elfFullName
));
30 RtlZeroMemory( &Logfont
.elfEnumLogfontEx
.elfStyle
,
31 sizeof(Logfont
.elfEnumLogfontEx
.elfStyle
));
32 RtlZeroMemory( &Logfont
.elfEnumLogfontEx
.elfScript
,
33 sizeof(Logfont
.elfEnumLogfontEx
.elfScript
));
35 Logfont
.elfDesignVector
.dvNumAxes
= 0;
37 RtlZeroMemory( &Logfont
.elfDesignVector
, sizeof(DESIGNVECTOR
));
39 return HfontCreate((PENUMLOGFONTEXDVW
)&Logfont
, 0, 0, 0, NULL
);
49 LPKERNINGPAIR krnpair
)
61 EngSetLastError(ERROR_INVALID_HANDLE
);
65 pdcattr
= dc
->pdcattr
;
66 TextObj
= RealizeFontInit(pdcattr
->hlfntNew
);
71 EngSetLastError(ERROR_INVALID_HANDLE
);
75 FontGDI
= ObjToGDI(TextObj
->Font
, FONT
);
76 TEXTOBJ_UnlockText(TextObj
);
78 Count
= ftGdiGetKerningPairs(FontGDI
,0,NULL
);
80 if ( Count
&& krnpair
)
84 EngSetLastError(ERROR_INSUFFICIENT_BUFFER
);
87 pKP
= ExAllocatePoolWithTag(PagedPool
, Count
* sizeof(KERNINGPAIR
), GDITAG_TEXT
);
90 EngSetLastError(ERROR_NOT_ENOUGH_MEMORY
);
93 ftGdiGetKerningPairs(FontGDI
,Count
,pKP
);
95 RtlCopyMemory(krnpair
, pKP
, Count
* sizeof(KERNINGPAIR
));
97 ExFreePoolWithTag(pKP
,GDITAG_TEXT
);
104 It is recommended that an application use the GetFontLanguageInfo function
105 to determine whether the GCP_DIACRITIC, GCP_DBCS, GCP_USEKERNING, GCP_LIGATE,
106 GCP_REORDER, GCP_GLYPHSHAPE, and GCP_KASHIDA values are valid for the
107 currently selected font. If not valid, GetCharacterPlacement ignores the
110 M$ must use a preset "compiled in" support for each language based releases.
111 ReactOS uses FreeType, this will need to be supported. ATM this is hard coded
118 GreGetCharacterPlacementW(
123 LPGCP_RESULTSW pgcpw
,
126 GCP_RESULTSW gcpwSave
;
132 DPRINT1("GreGCPW Start\n");
136 if (GreGetTextExtentW( hdc
, pwsz
, nCount
, &Size
, 1))
137 return MAKELONG(Size
.cx
, Size
.cy
);
141 DPRINT1("GreGCPW 1\n");
143 RtlCopyMemory(&gcpwSave
, pgcpw
, sizeof(GCP_RESULTSW
));
145 cSet
= nSet
= nCount
;
147 if ( nCount
> gcpwSave
.nGlyphs
) cSet
= gcpwSave
.nGlyphs
;
149 /* GCP_JUSTIFY may only be used in conjunction with GCP_MAXEXTENT. */
150 if ( dwFlags
& GCP_JUSTIFY
) dwFlags
|= GCP_MAXEXTENT
;
152 if ( !gcpwSave
.lpDx
&& gcpwSave
.lpCaretPos
)
153 tmpDxCaretPos
= gcpwSave
.lpCaretPos
;
155 tmpDxCaretPos
= gcpwSave
.lpDx
;
157 if ( !GreGetTextExtentExW( hdc
,
161 ((dwFlags
& GCP_MAXEXTENT
) ? (PULONG
) &cSet
: NULL
),
162 (PULONG
) tmpDxCaretPos
,
169 DPRINT1("GreGCPW 2\n");
173 if ( tmpDxCaretPos
&& nSet
> 0)
175 for (i
= (nSet
- 1); i
> 0; i
--)
177 tmpDxCaretPos
[i
] -= tmpDxCaretPos
[i
- 1];
181 if ( !(dwFlags
& GCP_MAXEXTENT
) || nSet
)
183 if ( (dwFlags
& GCP_USEKERNING
) &&
185 gcpwSave
.lpCaretPos
) &&
191 Count
= GreGetKerningPairs( hdc
, 0, NULL
);
194 pKP
= ExAllocatePoolWithTag(PagedPool
, Count
* sizeof(KERNINGPAIR
), GDITAG_TEXT
);
197 if ( GreGetKerningPairs( hdc
, Count
, pKP
) != Count
)
199 ExFreePoolWithTag( pKP
, GDITAG_TEXT
);
203 if ( (ULONG_PTR
)(pKP
) < ((ULONG_PTR
)(pKP
) + (ULONG_PTR
)(Count
* sizeof(KERNINGPAIR
))) )
205 DPRINT1("We Need to Do Something HERE!\n");
208 ExFreePoolWithTag( pKP
, GDITAG_TEXT
);
210 if ( dwFlags
& GCP_MAXEXTENT
)
212 if ( Size
.cx
> nMaxExtent
)
214 for (Cx
= Size
.cx
; nSet
> 0; nSet
--)
216 Cx
-= tmpDxCaretPos
[nSet
- 1];
218 if ( Cx
<= nMaxExtent
) break;
232 if ( (dwFlags
& GCP_JUSTIFY
) &&
234 gcpwSave
.lpCaretPos
) &&
237 DPRINT1("We Need to Do Something HERE 2!\n");
240 if ( gcpwSave
.lpDx
&& gcpwSave
.lpCaretPos
)
241 RtlCopyMemory( gcpwSave
.lpCaretPos
, gcpwSave
.lpDx
, nSet
* sizeof(LONG
));
243 if ( gcpwSave
.lpCaretPos
)
251 Cx
= gcpwSave
.lpCaretPos
[i
];
252 gcpwSave
.lpCaretPos
[i
] = pos
;
260 if ( gcpwSave
.lpOutString
)
261 RtlCopyMemory(gcpwSave
.lpOutString
, pwsz
, nSet
* sizeof(WCHAR
));
263 if ( gcpwSave
.lpClass
)
264 RtlFillMemory(gcpwSave
.lpClass
, nSet
, GCPCLASS_LATIN
);
266 if ( gcpwSave
.lpOrder
)
268 for (i
= 0; i
< nSet
; i
++)
269 gcpwSave
.lpOrder
[i
] = i
;
272 if ( gcpwSave
.lpGlyphs
)
274 if ( GreGetGlyphIndicesW( hdc
, pwsz
, nSet
, gcpwSave
.lpGlyphs
, 0, 0) == GDI_ERROR
)
281 pgcpw
->nGlyphs
= nSet
;
282 pgcpw
->nMaxFit
= nSet
;
284 DPRINT1("GreGCPW Exit\n");
285 return MAKELONG(Size
.cx
, Size
.cy
);
291 FontGetObject(PTEXTOBJ plfont
, ULONG cjBuffer
, PVOID pvBuffer
)
294 ENUMLOGFONTEXDVW
*plf
= &plfont
->logfont
;
296 /* If buffer is NULL, only the size is requested */
297 if (pvBuffer
== NULL
) return sizeof(LOGFONTW
);
299 /* Calculate the maximum size according to number of axes */
300 cjMaxSize
= FIELD_OFFSET(ENUMLOGFONTEXDVW
,
301 elfDesignVector
.dvValues
[plf
->elfDesignVector
.dvNumAxes
]);
303 if (cjBuffer
> cjMaxSize
) cjBuffer
= cjMaxSize
;
305 RtlCopyMemory(pvBuffer
, plf
, cjBuffer
);
312 IntGetCharDimensions(HDC hdc
, PTEXTMETRICW ptm
, PDWORD height
)
321 static const WCHAR alphabet
[] = {
322 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q',
323 'r','s','t','u','v','w','x','y','z','A','B','C','D','E','F','G','H',
324 'I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',0};
326 if(!ftGdiGetTextMetricsW(hdc
, &tmwi
)) return 0;
328 pdc
= DC_LockDc(hdc
);
332 pdcattr
= pdc
->pdcattr
;
334 TextObj
= RealizeFontInit(pdcattr
->hlfntNew
);
340 Good
= TextIntGetTextExtentPoint(pdc
, TextObj
, alphabet
, 52, 0, NULL
, 0, &sz
, 0);
341 TEXTOBJ_UnlockText(TextObj
);
345 if (ptm
) *ptm
= tmwi
.TextMetric
;
346 if (height
) *height
= tmwi
.TextMetric
.tmHeight
;
348 return (sz
.cx
/ 26 + 1) / 2;
354 IntGetFontLanguageInfo(PDC Dc
)
357 FONTSIGNATURE fontsig
;
358 static const DWORD GCP_DBCS_MASK
=0x003F0000,
359 GCP_DIACRITIC_MASK
=0x00000000,
360 FLI_GLYPHS_MASK
=0x00000000,
361 GCP_GLYPHSHAPE_MASK
=0x00000040,
362 GCP_KASHIDA_MASK
=0x00000000,
363 GCP_LIGATE_MASK
=0x00000000,
364 GCP_USEKERNING_MASK
=0x00000000,
365 GCP_REORDER_MASK
=0x00000060;
369 ftGdiGetTextCharsetInfo( Dc
, &fontsig
, 0 );
371 /* We detect each flag we return using a bitmask on the Codepage Bitfields */
372 if( (fontsig
.fsCsb
[0]&GCP_DBCS_MASK
)!=0 )
375 if( (fontsig
.fsCsb
[0]&GCP_DIACRITIC_MASK
)!=0 )
376 result
|=GCP_DIACRITIC
;
378 if( (fontsig
.fsCsb
[0]&FLI_GLYPHS_MASK
)!=0 )
381 if( (fontsig
.fsCsb
[0]&GCP_GLYPHSHAPE_MASK
)!=0 )
382 result
|=GCP_GLYPHSHAPE
;
384 if( (fontsig
.fsCsb
[0]&GCP_KASHIDA_MASK
)!=0 )
387 if( (fontsig
.fsCsb
[0]&GCP_LIGATE_MASK
)!=0 )
390 if( (fontsig
.fsCsb
[0]&GCP_USEKERNING_MASK
)!=0 )
391 result
|=GCP_USEKERNING
;
393 pdcattr
= Dc
->pdcattr
;
395 /* This might need a test for a HEBREW- or ARABIC_CHARSET as well */
396 if ( pdcattr
->lTextAlign
& TA_RTLREADING
)
397 if( (fontsig
.fsCsb
[0]&GCP_REORDER_MASK
)!=0 )
405 RealizeFontInit(HFONT hFont
)
407 NTSTATUS Status
= STATUS_SUCCESS
;
410 pTextObj
= TEXTOBJ_LockText(hFont
);
412 if ( pTextObj
&& !(pTextObj
->fl
& TEXTOBJECT_INIT
))
414 Status
= TextIntRealizeFont(hFont
, pTextObj
);
415 if (!NT_SUCCESS(Status
))
417 TEXTOBJ_UnlockText(pTextObj
);
425 /** Functions ******************************************************************/
429 NtGdiAddFontResourceW(
435 IN OPTIONAL DESIGNVECTOR
*pdv
)
437 UNICODE_STRING SafeFileName
;
440 DBG_UNREFERENCED_PARAMETER(cFiles
);
441 DBG_UNREFERENCED_PARAMETER(dwPidTid
);
442 DBG_UNREFERENCED_PARAMETER(pdv
);
444 /* cwc = Length + trailing zero. */
445 if (cwc
<= 1 || cwc
> UNICODE_STRING_MAX_CHARS
)
448 SafeFileName
.MaximumLength
= cwc
* sizeof(WCHAR
);
449 SafeFileName
.Length
= SafeFileName
.MaximumLength
- sizeof(UNICODE_NULL
);
450 SafeFileName
.Buffer
= ExAllocatePoolWithTag(PagedPool
,
451 SafeFileName
.MaximumLength
,
453 if (!SafeFileName
.Buffer
)
460 ProbeForRead(pwcFiles
, cwc
* sizeof(WCHAR
), sizeof(WCHAR
));
461 RtlCopyMemory(SafeFileName
.Buffer
, pwcFiles
, SafeFileName
.Length
);
463 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
465 ExFreePoolWithTag(SafeFileName
.Buffer
, TAG_STRING
);
466 _SEH2_YIELD(return 0);
470 SafeFileName
.Buffer
[SafeFileName
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
471 Ret
= IntGdiAddFontResource(&SafeFileName
, fl
);
473 ExFreePoolWithTag(SafeFileName
.Buffer
, TAG_STRING
);
482 NtGdiGetCharacterPlacementW(
487 IN OUT LPGCP_RESULTSW pgcpw
,
493 return GreGetCharacterPlacementW( hdc
,
516 DWORD Result
= GDI_ERROR
;
517 NTSTATUS Status
= STATUS_SUCCESS
;
523 ProbeForRead(Buffer
, Size
, 1);
525 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
527 Status
= _SEH2_GetExceptionCode();
532 if (!NT_SUCCESS(Status
)) return Result
;
537 EngSetLastError(ERROR_INVALID_HANDLE
);
540 pdcattr
= Dc
->pdcattr
;
542 hFont
= pdcattr
->hlfntNew
;
543 TextObj
= RealizeFontInit(hFont
);
548 EngSetLastError(ERROR_INVALID_HANDLE
);
552 FontGdi
= ObjToGDI(TextObj
->Font
, FONT
);
554 Result
= ftGdiGetFontData(FontGdi
, Table
, Offset
, Buffer
, Size
);
556 TEXTOBJ_UnlockText(TextObj
);
566 NtGdiGetFontUnicodeRanges(
568 OUT OPTIONAL LPGLYPHSET pgs
)
577 NTSTATUS Status
= STATUS_SUCCESS
;
579 pDc
= DC_LockDc(hdc
);
582 EngSetLastError(ERROR_INVALID_HANDLE
);
586 pdcattr
= pDc
->pdcattr
;
588 hFont
= pdcattr
->hlfntNew
;
589 TextObj
= RealizeFontInit(hFont
);
591 if ( TextObj
== NULL
)
593 EngSetLastError(ERROR_INVALID_HANDLE
);
596 FontGdi
= ObjToGDI(TextObj
->Font
, FONT
);
598 Size
= ftGetFontUnicodeRanges( FontGdi
, NULL
);
602 pgsSafe
= ExAllocatePoolWithTag(PagedPool
, Size
, GDITAG_TEXT
);
605 EngSetLastError(ERROR_NOT_ENOUGH_MEMORY
);
610 Size
= ftGetFontUnicodeRanges( FontGdi
, pgsSafe
);
616 ProbeForWrite(pgs
, Size
, 1);
617 RtlCopyMemory(pgs
, pgsSafe
, Size
);
619 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
621 Status
= _SEH2_GetExceptionCode();
625 if (!NT_SUCCESS(Status
)) Size
= 0;
627 ExFreePoolWithTag(pgsSafe
, GDITAG_TEXT
);
630 TEXTOBJ_UnlockText(TextObj
);
637 NtGdiGetGlyphOutline(
641 OUT LPGLYPHMETRICS pgm
,
643 OUT OPTIONAL PVOID UnsafeBuf
,
645 IN BOOL bIgnoreRotation
)
647 ULONG Ret
= GDI_ERROR
;
651 NTSTATUS Status
= STATUS_SUCCESS
;
656 EngSetLastError(ERROR_INVALID_HANDLE
);
660 if (UnsafeBuf
&& cjBuf
)
662 pvBuf
= ExAllocatePoolWithTag(PagedPool
, cjBuf
, GDITAG_TEXT
);
665 EngSetLastError(ERROR_NOT_ENOUGH_MEMORY
);
670 Ret
= ftGdiGetGlyphOutline( dc
,
683 ProbeForWrite(UnsafeBuf
, cjBuf
, 1);
684 RtlCopyMemory(UnsafeBuf
, pvBuf
, cjBuf
);
686 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
688 Status
= _SEH2_GetExceptionCode();
692 ExFreePoolWithTag(pvBuf
, GDITAG_TEXT
);
699 ProbeForWrite(pgm
, sizeof(GLYPHMETRICS
), 1);
700 RtlCopyMemory(pgm
, &gm
, sizeof(GLYPHMETRICS
));
702 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
704 Status
= _SEH2_GetExceptionCode();
709 if (! NT_SUCCESS(Status
))
711 EngSetLastError(ERROR_INVALID_PARAMETER
);
722 NtGdiGetKerningPairs(HDC hDC
,
724 LPKERNINGPAIR krnpair
)
732 NTSTATUS Status
= STATUS_SUCCESS
;
737 EngSetLastError(ERROR_INVALID_HANDLE
);
741 pdcattr
= dc
->pdcattr
;
742 TextObj
= RealizeFontInit(pdcattr
->hlfntNew
);
747 EngSetLastError(ERROR_INVALID_HANDLE
);
751 FontGDI
= ObjToGDI(TextObj
->Font
, FONT
);
752 TEXTOBJ_UnlockText(TextObj
);
754 Count
= ftGdiGetKerningPairs(FontGDI
,0,NULL
);
756 if ( Count
&& krnpair
)
758 if (Count
> NumPairs
)
760 EngSetLastError(ERROR_INSUFFICIENT_BUFFER
);
763 pKP
= ExAllocatePoolWithTag(PagedPool
, Count
* sizeof(KERNINGPAIR
), GDITAG_TEXT
);
766 EngSetLastError(ERROR_NOT_ENOUGH_MEMORY
);
769 ftGdiGetKerningPairs(FontGDI
,Count
,pKP
);
772 ProbeForWrite(krnpair
, Count
* sizeof(KERNINGPAIR
), 1);
773 RtlCopyMemory(krnpair
, pKP
, Count
* sizeof(KERNINGPAIR
));
775 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
777 Status
= _SEH2_GetExceptionCode();
780 if (!NT_SUCCESS(Status
))
782 EngSetLastError(ERROR_INVALID_PARAMETER
);
785 ExFreePoolWithTag(pKP
,GDITAG_TEXT
);
791 From "Undocumented Windows 2000 Secrets" Appendix B, Table B-2, page
792 472, this is NtGdiGetOutlineTextMetricsInternalW.
796 NtGdiGetOutlineTextMetricsInternalW (HDC hDC
,
798 OUTLINETEXTMETRICW
*otm
,
807 OUTLINETEXTMETRICW
*potm
;
808 NTSTATUS Status
= STATUS_SUCCESS
;
813 EngSetLastError(ERROR_INVALID_HANDLE
);
816 pdcattr
= dc
->pdcattr
;
817 hFont
= pdcattr
->hlfntNew
;
818 TextObj
= RealizeFontInit(hFont
);
822 EngSetLastError(ERROR_INVALID_HANDLE
);
825 FontGDI
= ObjToGDI(TextObj
->Font
, FONT
);
826 TEXTOBJ_UnlockText(TextObj
);
827 Size
= IntGetOutlineTextMetrics(FontGDI
, 0, NULL
);
828 if (!otm
) return Size
;
831 EngSetLastError(ERROR_INSUFFICIENT_BUFFER
);
834 potm
= ExAllocatePoolWithTag(PagedPool
, Size
, GDITAG_TEXT
);
837 EngSetLastError(ERROR_NOT_ENOUGH_MEMORY
);
840 IntGetOutlineTextMetrics(FontGDI
, Size
, potm
);
845 ProbeForWrite(otm
, Size
, 1);
846 RtlCopyMemory(otm
, potm
, Size
);
848 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
850 Status
= _SEH2_GetExceptionCode();
854 if (!NT_SUCCESS(Status
))
856 EngSetLastError(ERROR_INVALID_PARAMETER
);
860 ExFreePoolWithTag(potm
,GDITAG_TEXT
);
867 NtGdiGetFontResourceInfoInternalW(
872 OUT LPDWORD pdwBytes
,
876 NTSTATUS Status
= STATUS_SUCCESS
;
878 UNICODE_STRING SafeFileNames
;
885 WCHAR FullName
[LF_FULLFACESIZE
];
888 /* FIXME: Handle cFiles > 0 */
890 /* Check for valid dwType values
891 dwType == 4 seems to be handled by gdi32 only */
892 if (dwType
== 4 || dwType
> 5)
894 EngSetLastError(ERROR_INVALID_PARAMETER
);
898 /* Allocate a safe unicode string buffer */
899 cbStringSize
= cwc
* sizeof(WCHAR
);
900 SafeFileNames
.MaximumLength
= SafeFileNames
.Length
= (USHORT
)cbStringSize
- sizeof(WCHAR
);
901 SafeFileNames
.Buffer
= ExAllocatePoolWithTag(PagedPool
,
904 if (!SafeFileNames
.Buffer
)
906 EngSetLastError(ERROR_NOT_ENOUGH_MEMORY
);
910 /* Check buffers and copy pwszFiles to safe unicode string */
913 ProbeForRead(pwszFiles
, cbStringSize
, 1);
914 ProbeForWrite(pdwBytes
, sizeof(DWORD
), 1);
915 ProbeForWrite(pvBuf
, cjIn
, 1);
917 RtlCopyMemory(SafeFileNames
.Buffer
, pwszFiles
, cbStringSize
);
919 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
921 Status
= _SEH2_GetExceptionCode();
925 if(!NT_SUCCESS(Status
))
927 SetLastNtError(Status
);
928 /* Free the string buffer for the safe filename */
929 ExFreePoolWithTag(SafeFileNames
.Buffer
,'RTSU');
933 /* Do the actual call */
934 bRet
= IntGdiGetFontResourceInfo(&SafeFileNames
, &Buffer
, &dwBytes
, dwType
);
936 /* Check if succeeded and the buffer is big enough */
937 if (bRet
&& cjIn
>= dwBytes
)
939 /* Copy the data back to caller */
942 /* Buffers are already probed */
943 RtlCopyMemory(pvBuf
, &Buffer
, dwBytes
);
946 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
948 Status
= _SEH2_GetExceptionCode();
952 if(!NT_SUCCESS(Status
))
954 SetLastNtError(Status
);
959 /* Free the string for the safe filenames */
960 ExFreePoolWithTag(SafeFileNames
.Buffer
,'RTSU');
970 NtGdiGetRealizationInfo(
972 OUT PREALIZATION_INFO pri
,
983 pDc
= DC_LockDc(hdc
);
986 EngSetLastError(ERROR_INVALID_HANDLE
);
989 pdcattr
= pDc
->pdcattr
;
990 pTextObj
= RealizeFontInit(pdcattr
->hlfntNew
);
991 pFontGdi
= ObjToGDI(pTextObj
->Font
, FONT
);
992 TEXTOBJ_UnlockText(pTextObj
);
995 Ret
= ftGdiRealizationInfo(pFontGdi
, &ri
);
1000 NTSTATUS Status
= STATUS_SUCCESS
;
1003 ProbeForWrite(pri
, sizeof(REALIZATION_INFO
), 1);
1004 RtlCopyMemory(pri
, &ri
, sizeof(REALIZATION_INFO
));
1006 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1008 Status
= _SEH2_GetExceptionCode();
1012 if(!NT_SUCCESS(Status
))
1014 SetLastNtError(Status
);
1020 if (GdiHandleTable
->cfPublic
[i
].hf
== hf
)
1022 GdiHandleTable
->cfPublic
[i
].iTechnology
= ri
.iTechnology
;
1023 GdiHandleTable
->cfPublic
[i
].iUniq
= ri
.iUniq
;
1024 GdiHandleTable
->cfPublic
[i
].dwUnknown
= ri
.dwUnknown
;
1025 GdiHandleTable
->cfPublic
[i
].dwCFCount
= GdiHandleTable
->dwCFCount
;
1026 GdiHandleTable
->cfPublic
[i
].fl
|= CFONT_REALIZATION
;
1030 while ( i
< GDI_CFONT_MAX
);
1039 IN PENUMLOGFONTEXDVW pelfw
,
1043 IN PVOID pvCliData
)
1053 plfont
= LFONT_AllocFontWithHandle();
1058 hNewFont
= plfont
->BaseObject
.hHmgr
;
1062 RtlCopyMemory (&plfont
->logfont
, pelfw
, sizeof(ENUMLOGFONTEXDVW
));
1063 ExInitializePushLock(&plfont
->lock
);
1065 if (pelfw
->elfEnumLogfontEx
.elfLogFont
.lfEscapement
!=
1066 pelfw
->elfEnumLogfontEx
.elfLogFont
.lfOrientation
)
1068 /* This should really depend on whether GM_ADVANCED is set */
1069 plfont
->logfont
.elfEnumLogfontEx
.elfLogFont
.lfOrientation
=
1070 plfont
->logfont
.elfEnumLogfontEx
.elfLogFont
.lfEscapement
;
1072 LFONT_UnlockFont(plfont
);
1074 if (pvCliData
&& hNewFont
)
1076 // FIXME: Use GDIOBJ_InsertUserData
1077 KeEnterCriticalRegion();
1079 INT Index
= GDI_HANDLE_GET_INDEX((HGDIOBJ
)hNewFont
);
1080 PGDI_TABLE_ENTRY Entry
= &GdiHandleTable
->Entries
[Index
];
1081 Entry
->UserData
= pvCliData
;
1083 KeLeaveCriticalRegion();
1093 IN PENUMLOGFONTEXDVW pelfw
,
1097 IN PVOID pvCliData
)
1099 ENUMLOGFONTEXDVW SafeLogfont
;
1100 NTSTATUS Status
= STATUS_SUCCESS
;
1102 /* Silence GCC warnings */
1103 SafeLogfont
.elfEnumLogfontEx
.elfLogFont
.lfEscapement
= 0;
1104 SafeLogfont
.elfEnumLogfontEx
.elfLogFont
.lfOrientation
= 0;
1113 ProbeForRead(pelfw
, sizeof(ENUMLOGFONTEXDVW
), 1);
1114 RtlCopyMemory(&SafeLogfont
, pelfw
, sizeof(ENUMLOGFONTEXDVW
));
1116 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1118 Status
= _SEH2_GetExceptionCode();
1122 if (!NT_SUCCESS(Status
))
1127 return HfontCreate(&SafeLogfont
, cjElfw
, lft
, fl
, pvCliData
);