2 * PROJECT: ReactOS win32 kernel mode subsystem
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: win32ss/gdi/ntgdi/font.c
6 * PROGRAMMERS: James Tabor <james.tabor@reactos.org>
7 * Timo Kreuzer <timo.kreuzer@reactos.org>
8 * Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
11 /** Includes ******************************************************************/
18 HFONT APIENTRY
HfontCreate( IN PENUMLOGFONTEXDVW pelfw
,IN ULONG cjElfw
,IN LFTYPE lft
,IN FLONG fl
,IN PVOID pvCliData
);
20 /** Internal ******************************************************************/
23 GreCreateFontIndirectW( LOGFONTW
*lplf
)
27 ENUMLOGFONTEXDVW Logfont
;
29 RtlCopyMemory( &Logfont
.elfEnumLogfontEx
.elfLogFont
, lplf
, sizeof(LOGFONTW
));
30 RtlZeroMemory( &Logfont
.elfEnumLogfontEx
.elfFullName
,
31 sizeof(Logfont
.elfEnumLogfontEx
.elfFullName
));
32 RtlZeroMemory( &Logfont
.elfEnumLogfontEx
.elfStyle
,
33 sizeof(Logfont
.elfEnumLogfontEx
.elfStyle
));
34 RtlZeroMemory( &Logfont
.elfEnumLogfontEx
.elfScript
,
35 sizeof(Logfont
.elfEnumLogfontEx
.elfScript
));
37 Logfont
.elfDesignVector
.dvNumAxes
= 0;
39 RtlZeroMemory( &Logfont
.elfDesignVector
, sizeof(DESIGNVECTOR
));
41 return HfontCreate((PENUMLOGFONTEXDVW
)&Logfont
, 0, 0, 0, NULL
);
51 LPKERNINGPAIR krnpair
)
63 EngSetLastError(ERROR_INVALID_HANDLE
);
67 pdcattr
= dc
->pdcattr
;
68 TextObj
= RealizeFontInit(pdcattr
->hlfntNew
);
73 EngSetLastError(ERROR_INVALID_HANDLE
);
77 FontGDI
= ObjToGDI(TextObj
->Font
, FONT
);
78 TEXTOBJ_UnlockText(TextObj
);
80 Count
= ftGdiGetKerningPairs(FontGDI
,0,NULL
);
82 if ( Count
&& krnpair
)
86 EngSetLastError(ERROR_INSUFFICIENT_BUFFER
);
89 pKP
= ExAllocatePoolWithTag(PagedPool
, Count
* sizeof(KERNINGPAIR
), GDITAG_TEXT
);
92 EngSetLastError(ERROR_NOT_ENOUGH_MEMORY
);
95 ftGdiGetKerningPairs(FontGDI
,Count
,pKP
);
97 RtlCopyMemory(krnpair
, pKP
, Count
* sizeof(KERNINGPAIR
));
99 ExFreePoolWithTag(pKP
,GDITAG_TEXT
);
106 It is recommended that an application use the GetFontLanguageInfo function
107 to determine whether the GCP_DIACRITIC, GCP_DBCS, GCP_USEKERNING, GCP_LIGATE,
108 GCP_REORDER, GCP_GLYPHSHAPE, and GCP_KASHIDA values are valid for the
109 currently selected font. If not valid, GetCharacterPlacement ignores the
112 M$ must use a preset "compiled in" support for each language based releases.
113 ReactOS uses FreeType, this will need to be supported. ATM this is hard coded
120 GreGetCharacterPlacementW(
125 LPGCP_RESULTSW pgcpw
,
128 GCP_RESULTSW gcpwSave
;
134 DPRINT1("GreGCPW Start\n");
138 if (GreGetTextExtentW( hdc
, pwsz
, nCount
, &Size
, 1))
139 return MAKELONG(Size
.cx
, Size
.cy
);
143 DPRINT1("GreGCPW 1\n");
145 RtlCopyMemory(&gcpwSave
, pgcpw
, sizeof(GCP_RESULTSW
));
147 cSet
= nSet
= nCount
;
149 if ( nCount
> gcpwSave
.nGlyphs
) cSet
= gcpwSave
.nGlyphs
;
151 /* GCP_JUSTIFY may only be used in conjunction with GCP_MAXEXTENT. */
152 if ( dwFlags
& GCP_JUSTIFY
) dwFlags
|= GCP_MAXEXTENT
;
154 if ( !gcpwSave
.lpDx
&& gcpwSave
.lpCaretPos
)
155 tmpDxCaretPos
= gcpwSave
.lpCaretPos
;
157 tmpDxCaretPos
= gcpwSave
.lpDx
;
159 if ( !GreGetTextExtentExW( hdc
,
163 ((dwFlags
& GCP_MAXEXTENT
) ? (PULONG
) &cSet
: NULL
),
164 (PULONG
) tmpDxCaretPos
,
171 DPRINT1("GreGCPW 2\n");
175 if ( tmpDxCaretPos
&& nSet
> 0)
177 for (i
= (nSet
- 1); i
> 0; i
--)
179 tmpDxCaretPos
[i
] -= tmpDxCaretPos
[i
- 1];
183 if ( !(dwFlags
& GCP_MAXEXTENT
) || nSet
)
185 if ( (dwFlags
& GCP_USEKERNING
) &&
187 gcpwSave
.lpCaretPos
) &&
193 Count
= GreGetKerningPairs( hdc
, 0, NULL
);
196 pKP
= ExAllocatePoolWithTag(PagedPool
, Count
* sizeof(KERNINGPAIR
), GDITAG_TEXT
);
199 if ( GreGetKerningPairs( hdc
, Count
, pKP
) != Count
)
201 ExFreePoolWithTag( pKP
, GDITAG_TEXT
);
205 if ( (ULONG_PTR
)(pKP
) < ((ULONG_PTR
)(pKP
) + (ULONG_PTR
)(Count
* sizeof(KERNINGPAIR
))) )
207 DPRINT1("We Need to Do Something HERE!\n");
210 ExFreePoolWithTag( pKP
, GDITAG_TEXT
);
212 if ( dwFlags
& GCP_MAXEXTENT
)
214 if ( Size
.cx
> nMaxExtent
)
216 for (Cx
= Size
.cx
; nSet
> 0; nSet
--)
218 Cx
-= tmpDxCaretPos
[nSet
- 1];
220 if ( Cx
<= nMaxExtent
) break;
234 if ( (dwFlags
& GCP_JUSTIFY
) &&
236 gcpwSave
.lpCaretPos
) &&
239 DPRINT1("We Need to Do Something HERE 2!\n");
242 if ( gcpwSave
.lpDx
&& gcpwSave
.lpCaretPos
)
243 RtlCopyMemory( gcpwSave
.lpCaretPos
, gcpwSave
.lpDx
, nSet
* sizeof(LONG
));
245 if ( gcpwSave
.lpCaretPos
)
253 Cx
= gcpwSave
.lpCaretPos
[i
];
254 gcpwSave
.lpCaretPos
[i
] = pos
;
262 if ( gcpwSave
.lpOutString
)
263 RtlCopyMemory(gcpwSave
.lpOutString
, pwsz
, nSet
* sizeof(WCHAR
));
265 if ( gcpwSave
.lpClass
)
266 RtlFillMemory(gcpwSave
.lpClass
, nSet
, GCPCLASS_LATIN
);
268 if ( gcpwSave
.lpOrder
)
270 for (i
= 0; i
< nSet
; i
++)
271 gcpwSave
.lpOrder
[i
] = i
;
274 if ( gcpwSave
.lpGlyphs
)
276 if ( GreGetGlyphIndicesW( hdc
, pwsz
, nSet
, gcpwSave
.lpGlyphs
, 0, 0) == GDI_ERROR
)
283 pgcpw
->nGlyphs
= nSet
;
284 pgcpw
->nMaxFit
= nSet
;
286 DPRINT1("GreGCPW Exit\n");
287 return MAKELONG(Size
.cx
, Size
.cy
);
293 FontGetObject(PTEXTOBJ plfont
, ULONG cjBuffer
, PVOID pvBuffer
)
296 ENUMLOGFONTEXDVW
*plf
= &plfont
->logfont
;
298 /* If buffer is NULL, only the size is requested */
299 if (pvBuffer
== NULL
) return sizeof(LOGFONTW
);
301 /* Calculate the maximum size according to number of axes */
302 cjMaxSize
= FIELD_OFFSET(ENUMLOGFONTEXDVW
,
303 elfDesignVector
.dvValues
[plf
->elfDesignVector
.dvNumAxes
]);
305 if (cjBuffer
> cjMaxSize
) cjBuffer
= cjMaxSize
;
307 RtlCopyMemory(pvBuffer
, plf
, cjBuffer
);
314 IntGetCharDimensions(HDC hdc
, PTEXTMETRICW ptm
, PDWORD height
)
323 static const WCHAR alphabet
[] = {
324 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q',
325 'r','s','t','u','v','w','x','y','z','A','B','C','D','E','F','G','H',
326 'I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',0};
328 if(!ftGdiGetTextMetricsW(hdc
, &tmwi
)) return 0;
330 pdc
= DC_LockDc(hdc
);
334 pdcattr
= pdc
->pdcattr
;
336 TextObj
= RealizeFontInit(pdcattr
->hlfntNew
);
342 Good
= TextIntGetTextExtentPoint(pdc
, TextObj
, alphabet
, 52, 0, NULL
, 0, &sz
, 0);
343 TEXTOBJ_UnlockText(TextObj
);
347 if (ptm
) *ptm
= tmwi
.TextMetric
;
348 if (height
) *height
= tmwi
.TextMetric
.tmHeight
;
350 return (sz
.cx
/ 26 + 1) / 2;
356 IntGetFontLanguageInfo(PDC Dc
)
359 FONTSIGNATURE fontsig
;
360 static const DWORD GCP_DBCS_MASK
=0x003F0000,
361 GCP_DIACRITIC_MASK
=0x00000000,
362 FLI_GLYPHS_MASK
=0x00000000,
363 GCP_GLYPHSHAPE_MASK
=0x00000040,
364 GCP_KASHIDA_MASK
=0x00000000,
365 GCP_LIGATE_MASK
=0x00000000,
366 GCP_USEKERNING_MASK
=0x00000000,
367 GCP_REORDER_MASK
=0x00000060;
371 ftGdiGetTextCharsetInfo( Dc
, &fontsig
, 0 );
373 /* We detect each flag we return using a bitmask on the Codepage Bitfields */
374 if( (fontsig
.fsCsb
[0]&GCP_DBCS_MASK
)!=0 )
377 if( (fontsig
.fsCsb
[0]&GCP_DIACRITIC_MASK
)!=0 )
378 result
|=GCP_DIACRITIC
;
380 if( (fontsig
.fsCsb
[0]&FLI_GLYPHS_MASK
)!=0 )
383 if( (fontsig
.fsCsb
[0]&GCP_GLYPHSHAPE_MASK
)!=0 )
384 result
|=GCP_GLYPHSHAPE
;
386 if( (fontsig
.fsCsb
[0]&GCP_KASHIDA_MASK
)!=0 )
389 if( (fontsig
.fsCsb
[0]&GCP_LIGATE_MASK
)!=0 )
392 if( (fontsig
.fsCsb
[0]&GCP_USEKERNING_MASK
)!=0 )
393 result
|=GCP_USEKERNING
;
395 pdcattr
= Dc
->pdcattr
;
397 /* This might need a test for a HEBREW- or ARABIC_CHARSET as well */
398 if ( pdcattr
->lTextAlign
& TA_RTLREADING
)
399 if( (fontsig
.fsCsb
[0]&GCP_REORDER_MASK
)!=0 )
407 RealizeFontInit(HFONT hFont
)
409 NTSTATUS Status
= STATUS_SUCCESS
;
412 pTextObj
= TEXTOBJ_LockText(hFont
);
414 if ( pTextObj
&& !(pTextObj
->fl
& TEXTOBJECT_INIT
))
416 Status
= TextIntRealizeFont(hFont
, pTextObj
);
417 if (!NT_SUCCESS(Status
))
419 TEXTOBJ_UnlockText(pTextObj
);
427 /** Functions ******************************************************************/
431 NtGdiAddFontResourceW(
437 IN OPTIONAL DESIGNVECTOR
*pdv
)
439 UNICODE_STRING SafeFileName
;
442 DBG_UNREFERENCED_PARAMETER(cFiles
);
443 DBG_UNREFERENCED_PARAMETER(dwPidTid
);
444 DBG_UNREFERENCED_PARAMETER(pdv
);
446 DPRINT("NtGdiAddFontResourceW\n");
448 /* cwc = Length + trailing zero. */
449 if (cwc
<= 1 || cwc
> UNICODE_STRING_MAX_CHARS
)
452 SafeFileName
.MaximumLength
= cwc
* sizeof(WCHAR
);
453 SafeFileName
.Length
= SafeFileName
.MaximumLength
- sizeof(UNICODE_NULL
);
454 SafeFileName
.Buffer
= ExAllocatePoolWithTag(PagedPool
,
455 SafeFileName
.MaximumLength
,
457 if (!SafeFileName
.Buffer
)
464 ProbeForRead(pwcFiles
, cwc
* sizeof(WCHAR
), sizeof(WCHAR
));
465 RtlCopyMemory(SafeFileName
.Buffer
, pwcFiles
, SafeFileName
.Length
);
467 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
469 ExFreePoolWithTag(SafeFileName
.Buffer
, TAG_STRING
);
470 _SEH2_YIELD(return 0);
474 SafeFileName
.Buffer
[SafeFileName
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
475 Ret
= IntGdiAddFontResource(&SafeFileName
, fl
);
477 ExFreePoolWithTag(SafeFileName
.Buffer
, TAG_STRING
);
483 NtGdiAddFontMemResourceEx(
486 IN DESIGNVECTOR
*pdv
,
488 OUT DWORD
*pNumFonts
)
490 _SEH2_VOLATILE PVOID Buffer
= NULL
;
494 DPRINT("NtGdiAddFontMemResourceEx\n");
495 DBG_UNREFERENCED_PARAMETER(pdv
);
496 DBG_UNREFERENCED_PARAMETER(cjDV
);
498 if (!pvBuffer
|| !cjBuffer
)
503 ProbeForRead(pvBuffer
, cjBuffer
, sizeof(BYTE
));
504 Buffer
= ExAllocatePoolWithQuotaTag(PagedPool
, cjBuffer
, TAG_FONT
);
505 RtlCopyMemory(Buffer
, pvBuffer
, cjBuffer
);
507 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
511 ExFreePoolWithTag(Buffer
, TAG_FONT
);
513 _SEH2_YIELD(return NULL
);
517 Ret
= IntGdiAddFontMemResource(Buffer
, cjBuffer
, &NumFonts
);
518 ExFreePoolWithTag(Buffer
, TAG_FONT
);
522 ProbeForWrite(pNumFonts
, sizeof(NumFonts
), 1);
523 *pNumFonts
= NumFonts
;
525 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
528 _SEH2_YIELD(return NULL
);
539 NtGdiRemoveFontMemResourceEx(
542 return IntGdiRemoveFontMemResource(hMMFont
);
551 NtGdiGetCharacterPlacementW(
556 IN OUT LPGCP_RESULTSW pgcpw
,
562 return GreGetCharacterPlacementW( hdc
,
585 DWORD Result
= GDI_ERROR
;
586 NTSTATUS Status
= STATUS_SUCCESS
;
592 ProbeForRead(Buffer
, Size
, 1);
594 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
596 Status
= _SEH2_GetExceptionCode();
601 if (!NT_SUCCESS(Status
)) return Result
;
606 EngSetLastError(ERROR_INVALID_HANDLE
);
609 pdcattr
= Dc
->pdcattr
;
611 hFont
= pdcattr
->hlfntNew
;
612 TextObj
= RealizeFontInit(hFont
);
617 EngSetLastError(ERROR_INVALID_HANDLE
);
621 FontGdi
= ObjToGDI(TextObj
->Font
, FONT
);
623 Result
= ftGdiGetFontData(FontGdi
, Table
, Offset
, Buffer
, Size
);
625 TEXTOBJ_UnlockText(TextObj
);
635 NtGdiGetFontUnicodeRanges(
637 OUT OPTIONAL LPGLYPHSET pgs
)
646 NTSTATUS Status
= STATUS_SUCCESS
;
648 pDc
= DC_LockDc(hdc
);
651 EngSetLastError(ERROR_INVALID_HANDLE
);
655 pdcattr
= pDc
->pdcattr
;
657 hFont
= pdcattr
->hlfntNew
;
658 TextObj
= RealizeFontInit(hFont
);
660 if ( TextObj
== NULL
)
662 EngSetLastError(ERROR_INVALID_HANDLE
);
665 FontGdi
= ObjToGDI(TextObj
->Font
, FONT
);
667 Size
= ftGetFontUnicodeRanges( FontGdi
, NULL
);
671 pgsSafe
= ExAllocatePoolWithTag(PagedPool
, Size
, GDITAG_TEXT
);
674 EngSetLastError(ERROR_NOT_ENOUGH_MEMORY
);
679 Size
= ftGetFontUnicodeRanges( FontGdi
, pgsSafe
);
685 ProbeForWrite(pgs
, Size
, 1);
686 RtlCopyMemory(pgs
, pgsSafe
, Size
);
688 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
690 Status
= _SEH2_GetExceptionCode();
694 if (!NT_SUCCESS(Status
)) Size
= 0;
696 ExFreePoolWithTag(pgsSafe
, GDITAG_TEXT
);
699 TEXTOBJ_UnlockText(TextObj
);
706 NtGdiGetGlyphOutline(
710 OUT LPGLYPHMETRICS pgm
,
712 OUT OPTIONAL PVOID UnsafeBuf
,
714 IN BOOL bIgnoreRotation
)
716 ULONG Ret
= GDI_ERROR
;
720 NTSTATUS Status
= STATUS_SUCCESS
;
725 EngSetLastError(ERROR_INVALID_HANDLE
);
729 if (UnsafeBuf
&& cjBuf
)
731 pvBuf
= ExAllocatePoolWithTag(PagedPool
, cjBuf
, GDITAG_TEXT
);
734 EngSetLastError(ERROR_NOT_ENOUGH_MEMORY
);
739 Ret
= ftGdiGetGlyphOutline( dc
,
752 ProbeForWrite(UnsafeBuf
, cjBuf
, 1);
753 RtlCopyMemory(UnsafeBuf
, pvBuf
, cjBuf
);
755 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
757 Status
= _SEH2_GetExceptionCode();
761 ExFreePoolWithTag(pvBuf
, GDITAG_TEXT
);
768 ProbeForWrite(pgm
, sizeof(GLYPHMETRICS
), 1);
769 RtlCopyMemory(pgm
, &gm
, sizeof(GLYPHMETRICS
));
771 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
773 Status
= _SEH2_GetExceptionCode();
778 if (! NT_SUCCESS(Status
))
780 EngSetLastError(ERROR_INVALID_PARAMETER
);
791 NtGdiGetKerningPairs(HDC hDC
,
793 LPKERNINGPAIR krnpair
)
801 NTSTATUS Status
= STATUS_SUCCESS
;
806 EngSetLastError(ERROR_INVALID_HANDLE
);
810 pdcattr
= dc
->pdcattr
;
811 TextObj
= RealizeFontInit(pdcattr
->hlfntNew
);
816 EngSetLastError(ERROR_INVALID_HANDLE
);
820 FontGDI
= ObjToGDI(TextObj
->Font
, FONT
);
821 TEXTOBJ_UnlockText(TextObj
);
823 Count
= ftGdiGetKerningPairs(FontGDI
,0,NULL
);
825 if ( Count
&& krnpair
)
827 if (Count
> NumPairs
)
829 EngSetLastError(ERROR_INSUFFICIENT_BUFFER
);
832 pKP
= ExAllocatePoolWithTag(PagedPool
, Count
* sizeof(KERNINGPAIR
), GDITAG_TEXT
);
835 EngSetLastError(ERROR_NOT_ENOUGH_MEMORY
);
838 ftGdiGetKerningPairs(FontGDI
,Count
,pKP
);
841 ProbeForWrite(krnpair
, Count
* sizeof(KERNINGPAIR
), 1);
842 RtlCopyMemory(krnpair
, pKP
, Count
* sizeof(KERNINGPAIR
));
844 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
846 Status
= _SEH2_GetExceptionCode();
849 if (!NT_SUCCESS(Status
))
851 EngSetLastError(ERROR_INVALID_PARAMETER
);
854 ExFreePoolWithTag(pKP
,GDITAG_TEXT
);
860 From "Undocumented Windows 2000 Secrets" Appendix B, Table B-2, page
861 472, this is NtGdiGetOutlineTextMetricsInternalW.
865 NtGdiGetOutlineTextMetricsInternalW (HDC hDC
,
867 OUTLINETEXTMETRICW
*otm
,
876 OUTLINETEXTMETRICW
*potm
;
877 NTSTATUS Status
= STATUS_SUCCESS
;
882 EngSetLastError(ERROR_INVALID_HANDLE
);
885 pdcattr
= dc
->pdcattr
;
886 hFont
= pdcattr
->hlfntNew
;
887 TextObj
= RealizeFontInit(hFont
);
891 EngSetLastError(ERROR_INVALID_HANDLE
);
894 FontGDI
= ObjToGDI(TextObj
->Font
, FONT
);
895 TextIntUpdateSize(dc
, TextObj
, FontGDI
, TRUE
);
896 TEXTOBJ_UnlockText(TextObj
);
897 Size
= IntGetOutlineTextMetrics(FontGDI
, 0, NULL
);
898 if (!otm
) return Size
;
901 EngSetLastError(ERROR_INSUFFICIENT_BUFFER
);
904 potm
= ExAllocatePoolWithTag(PagedPool
, Size
, GDITAG_TEXT
);
907 EngSetLastError(ERROR_NOT_ENOUGH_MEMORY
);
910 IntGetOutlineTextMetrics(FontGDI
, Size
, potm
);
915 ProbeForWrite(otm
, Size
, 1);
916 RtlCopyMemory(otm
, potm
, Size
);
918 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
920 Status
= _SEH2_GetExceptionCode();
924 if (!NT_SUCCESS(Status
))
926 EngSetLastError(ERROR_INVALID_PARAMETER
);
930 ExFreePoolWithTag(potm
,GDITAG_TEXT
);
937 NtGdiGetFontResourceInfoInternalW(
942 IN OUT LPDWORD pdwBytes
,
946 NTSTATUS Status
= STATUS_SUCCESS
;
947 DWORD dwBytes
, dwBytesRequested
;
948 UNICODE_STRING SafeFileNames
;
953 /* FIXME: Handle cFiles > 0 */
955 /* Check for valid dwType values */
958 EngSetLastError(ERROR_INVALID_PARAMETER
);
962 /* Allocate a safe unicode string buffer */
963 cbStringSize
= cwc
* sizeof(WCHAR
);
964 SafeFileNames
.MaximumLength
= SafeFileNames
.Length
= (USHORT
)cbStringSize
- sizeof(WCHAR
);
965 SafeFileNames
.Buffer
= ExAllocatePoolWithTag(PagedPool
,
968 if (!SafeFileNames
.Buffer
)
970 EngSetLastError(ERROR_NOT_ENOUGH_MEMORY
);
973 RtlZeroMemory(SafeFileNames
.Buffer
, SafeFileNames
.MaximumLength
);
975 /* Check buffers and copy pwszFiles to safe unicode string */
978 ProbeForRead(pwszFiles
, cbStringSize
, 1);
979 ProbeForWrite(pdwBytes
, sizeof(DWORD
), 1);
981 ProbeForWrite(pvBuf
, cjIn
, 1);
984 dwBytesRequested
= dwBytes
;
986 RtlCopyMemory(SafeFileNames
.Buffer
, pwszFiles
, cbStringSize
);
989 Buffer
= ExAllocatePoolWithTag(PagedPool
, dwBytes
, TAG_FINF
);
993 Buffer
= ExAllocatePoolWithTag(PagedPool
, sizeof(DWORD
), TAG_FINF
);
996 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
998 Status
= _SEH2_GetExceptionCode();
1002 if(!NT_SUCCESS(Status
))
1004 SetLastNtError(Status
);
1005 /* Free the string buffer for the safe filename */
1006 ExFreePoolWithTag(SafeFileNames
.Buffer
, TAG_USTR
);
1010 /* Do the actual call */
1011 bRet
= IntGdiGetFontResourceInfo(&SafeFileNames
,
1012 (pvBuf
? Buffer
: NULL
),
1015 /* Check if succeeded */
1018 /* Copy the data back to caller */
1021 /* Buffers are already probed */
1022 if (pvBuf
&& dwBytesRequested
> 0)
1023 RtlCopyMemory(pvBuf
, Buffer
, min(dwBytesRequested
, dwBytes
));
1024 *pdwBytes
= dwBytes
;
1026 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1028 Status
= _SEH2_GetExceptionCode();
1032 if(!NT_SUCCESS(Status
))
1034 SetLastNtError(Status
);
1039 ExFreePoolWithTag(Buffer
, TAG_FINF
);
1040 /* Free the string for the safe filenames */
1041 ExFreePoolWithTag(SafeFileNames
.Buffer
, TAG_USTR
);
1051 NtGdiGetRealizationInfo(
1053 OUT PREALIZATION_INFO pri
,
1062 REALIZATION_INFO ri
;
1064 pDc
= DC_LockDc(hdc
);
1067 EngSetLastError(ERROR_INVALID_HANDLE
);
1070 pdcattr
= pDc
->pdcattr
;
1071 pTextObj
= RealizeFontInit(pdcattr
->hlfntNew
);
1072 pFontGdi
= ObjToGDI(pTextObj
->Font
, FONT
);
1073 TEXTOBJ_UnlockText(pTextObj
);
1076 Ret
= ftGdiRealizationInfo(pFontGdi
, &ri
);
1081 NTSTATUS Status
= STATUS_SUCCESS
;
1084 ProbeForWrite(pri
, sizeof(REALIZATION_INFO
), 1);
1085 RtlCopyMemory(pri
, &ri
, sizeof(REALIZATION_INFO
));
1087 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1089 Status
= _SEH2_GetExceptionCode();
1093 if(!NT_SUCCESS(Status
))
1095 SetLastNtError(Status
);
1101 if (GdiHandleTable
->cfPublic
[i
].hf
== hf
)
1103 GdiHandleTable
->cfPublic
[i
].iTechnology
= ri
.iTechnology
;
1104 GdiHandleTable
->cfPublic
[i
].iUniq
= ri
.iUniq
;
1105 GdiHandleTable
->cfPublic
[i
].dwUnknown
= ri
.dwUnknown
;
1106 GdiHandleTable
->cfPublic
[i
].dwCFCount
= GdiHandleTable
->dwCFCount
;
1107 GdiHandleTable
->cfPublic
[i
].fl
|= CFONT_REALIZATION
;
1111 while ( i
< GDI_CFONT_MAX
);
1120 IN PENUMLOGFONTEXDVW pelfw
,
1124 IN PVOID pvCliData
)
1134 plfont
= LFONT_AllocFontWithHandle();
1139 hNewFont
= plfont
->BaseObject
.hHmgr
;
1143 RtlCopyMemory (&plfont
->logfont
, pelfw
, sizeof(ENUMLOGFONTEXDVW
));
1144 ExInitializePushLock(&plfont
->lock
);
1146 if (pelfw
->elfEnumLogfontEx
.elfLogFont
.lfEscapement
!=
1147 pelfw
->elfEnumLogfontEx
.elfLogFont
.lfOrientation
)
1149 /* This should really depend on whether GM_ADVANCED is set */
1150 plfont
->logfont
.elfEnumLogfontEx
.elfLogFont
.lfOrientation
=
1151 plfont
->logfont
.elfEnumLogfontEx
.elfLogFont
.lfEscapement
;
1153 LFONT_UnlockFont(plfont
);
1155 if (pvCliData
&& hNewFont
)
1157 // FIXME: Use GDIOBJ_InsertUserData
1158 KeEnterCriticalRegion();
1160 INT Index
= GDI_HANDLE_GET_INDEX((HGDIOBJ
)hNewFont
);
1161 PGDI_TABLE_ENTRY Entry
= &GdiHandleTable
->Entries
[Index
];
1162 Entry
->UserData
= pvCliData
;
1164 KeLeaveCriticalRegion();
1174 IN PENUMLOGFONTEXDVW pelfw
,
1178 IN PVOID pvCliData
)
1180 ENUMLOGFONTEXDVW SafeLogfont
;
1181 NTSTATUS Status
= STATUS_SUCCESS
;
1183 /* Silence GCC warnings */
1184 SafeLogfont
.elfEnumLogfontEx
.elfLogFont
.lfEscapement
= 0;
1185 SafeLogfont
.elfEnumLogfontEx
.elfLogFont
.lfOrientation
= 0;
1194 ProbeForRead(pelfw
, sizeof(ENUMLOGFONTEXDVW
), 1);
1195 RtlCopyMemory(&SafeLogfont
, pelfw
, sizeof(ENUMLOGFONTEXDVW
));
1197 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1199 Status
= _SEH2_GetExceptionCode();
1203 if (!NT_SUCCESS(Status
))
1208 return HfontCreate(&SafeLogfont
, cjElfw
, lft
, fl
, pvCliData
);