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 /** Internal ******************************************************************/
23 LPKERNINGPAIR krnpair
)
35 EngSetLastError(ERROR_INVALID_HANDLE
);
39 pdcattr
= dc
->pdcattr
;
40 TextObj
= RealizeFontInit(pdcattr
->hlfntNew
);
45 EngSetLastError(ERROR_INVALID_HANDLE
);
49 FontGDI
= ObjToGDI(TextObj
->Font
, FONT
);
50 TEXTOBJ_UnlockText(TextObj
);
52 Count
= ftGdiGetKerningPairs(FontGDI
,0,NULL
);
54 if ( Count
&& krnpair
)
58 EngSetLastError(ERROR_INSUFFICIENT_BUFFER
);
61 pKP
= ExAllocatePoolWithTag(PagedPool
, Count
* sizeof(KERNINGPAIR
), GDITAG_TEXT
);
64 EngSetLastError(ERROR_NOT_ENOUGH_MEMORY
);
67 ftGdiGetKerningPairs(FontGDI
,Count
,pKP
);
69 RtlCopyMemory(krnpair
, pKP
, Count
* sizeof(KERNINGPAIR
));
71 ExFreePoolWithTag(pKP
,GDITAG_TEXT
);
78 It is recommended that an application use the GetFontLanguageInfo function
79 to determine whether the GCP_DIACRITIC, GCP_DBCS, GCP_USEKERNING, GCP_LIGATE,
80 GCP_REORDER, GCP_GLYPHSHAPE, and GCP_KASHIDA values are valid for the
81 currently selected font. If not valid, GetCharacterPlacement ignores the
84 M$ must use a preset "compiled in" support for each language based releases.
85 ReactOS uses FreeType, this will need to be supported. ATM this is hard coded
92 GreGetCharacterPlacementW(
100 GCP_RESULTSW gcpwSave
;
106 DPRINT1("GreGCPW Start\n");
110 if (GreGetTextExtentW( hdc
, pwsz
, nCount
, &Size
, 1))
111 return MAKELONG(Size
.cx
, Size
.cy
);
115 DPRINT1("GreGCPW 1\n");
117 RtlCopyMemory(&gcpwSave
, pgcpw
, sizeof(GCP_RESULTSW
));
119 cSet
= nSet
= nCount
;
121 if ( nCount
> gcpwSave
.nGlyphs
) cSet
= gcpwSave
.nGlyphs
;
123 /* GCP_JUSTIFY may only be used in conjunction with GCP_MAXEXTENT. */
124 if ( dwFlags
& GCP_JUSTIFY
) dwFlags
|= GCP_MAXEXTENT
;
126 if ( !gcpwSave
.lpDx
&& gcpwSave
.lpCaretPos
)
127 tmpDxCaretPos
= gcpwSave
.lpCaretPos
;
129 tmpDxCaretPos
= gcpwSave
.lpDx
;
131 if ( !GreGetTextExtentExW( hdc
,
135 ((dwFlags
& GCP_MAXEXTENT
) ? (PULONG
) &cSet
: NULL
),
136 (PULONG
) tmpDxCaretPos
,
143 DPRINT1("GreGCPW 2\n");
147 if ( tmpDxCaretPos
&& nSet
> 0)
149 for (i
= (nSet
- 1); i
> 0; i
--)
151 tmpDxCaretPos
[i
] -= tmpDxCaretPos
[i
- 1];
155 if ( !(dwFlags
& GCP_MAXEXTENT
) || nSet
)
157 if ( (dwFlags
& GCP_USEKERNING
) &&
159 gcpwSave
.lpCaretPos
) &&
165 Count
= GreGetKerningPairs( hdc
, 0, NULL
);
168 pKP
= ExAllocatePoolWithTag(PagedPool
, Count
* sizeof(KERNINGPAIR
), GDITAG_TEXT
);
171 if ( GreGetKerningPairs( hdc
, Count
, pKP
) != Count
)
173 ExFreePoolWithTag( pKP
, GDITAG_TEXT
);
177 if ( (ULONG_PTR
)(pKP
) < ((ULONG_PTR
)(pKP
) + (ULONG_PTR
)(Count
* sizeof(KERNINGPAIR
))) )
179 DPRINT1("We Need to Do Something HERE!\n");
182 ExFreePoolWithTag( pKP
, GDITAG_TEXT
);
184 if ( dwFlags
& GCP_MAXEXTENT
)
186 if ( Size
.cx
> nMaxExtent
)
188 for (Cx
= Size
.cx
; nSet
> 0; nSet
--)
190 Cx
-= tmpDxCaretPos
[nSet
- 1];
192 if ( Cx
<= nMaxExtent
) break;
206 if ( (dwFlags
& GCP_JUSTIFY
) &&
208 gcpwSave
.lpCaretPos
) &&
211 DPRINT1("We Need to Do Something HERE 2!\n");
214 if ( gcpwSave
.lpDx
&& gcpwSave
.lpCaretPos
)
215 RtlCopyMemory( gcpwSave
.lpCaretPos
, gcpwSave
.lpDx
, nSet
* sizeof(LONG
));
217 if ( gcpwSave
.lpCaretPos
)
225 Cx
= gcpwSave
.lpCaretPos
[i
];
226 gcpwSave
.lpCaretPos
[i
] = pos
;
234 if ( gcpwSave
.lpOutString
)
235 RtlCopyMemory(gcpwSave
.lpOutString
, pwsz
, nSet
* sizeof(WCHAR
));
237 if ( gcpwSave
.lpClass
)
238 RtlFillMemory(gcpwSave
.lpClass
, nSet
, GCPCLASS_LATIN
);
240 if ( gcpwSave
.lpOrder
)
242 for (i
= 0; i
< nSet
; i
++)
243 gcpwSave
.lpOrder
[i
] = i
;
246 if ( gcpwSave
.lpGlyphs
)
248 if ( GreGetGlyphIndicesW( hdc
, pwsz
, nSet
, gcpwSave
.lpGlyphs
, 0, 0) == GDI_ERROR
)
255 pgcpw
->nGlyphs
= nSet
;
256 pgcpw
->nMaxFit
= nSet
;
258 DPRINT1("GreGCPW Exit\n");
259 return MAKELONG(Size
.cx
, Size
.cy
);
265 FontGetObject(PTEXTOBJ TFont
, INT Count
, PVOID Buffer
)
267 if( Buffer
== NULL
) return sizeof(LOGFONTW
);
271 case sizeof(ENUMLOGFONTEXDVW
):
272 RtlCopyMemory( (LPENUMLOGFONTEXDVW
) Buffer
,
274 sizeof(ENUMLOGFONTEXDVW
));
276 case sizeof(ENUMLOGFONTEXW
):
277 RtlCopyMemory( (LPENUMLOGFONTEXW
) Buffer
,
278 &TFont
->logfont
.elfEnumLogfontEx
,
279 sizeof(ENUMLOGFONTEXW
));
282 case sizeof(EXTLOGFONTW
):
283 case sizeof(ENUMLOGFONTW
):
284 RtlCopyMemory((LPENUMLOGFONTW
) Buffer
,
285 &TFont
->logfont
.elfEnumLogfontEx
.elfLogFont
,
286 sizeof(ENUMLOGFONTW
));
289 case sizeof(LOGFONTW
):
290 RtlCopyMemory((LPLOGFONTW
) Buffer
,
291 &TFont
->logfont
.elfEnumLogfontEx
.elfLogFont
,
296 EngSetLastError(ERROR_BUFFER_OVERFLOW
);
304 IntGetCharDimensions(HDC hdc
, PTEXTMETRICW ptm
, PDWORD height
)
313 static const WCHAR alphabet
[] = {
314 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q',
315 'r','s','t','u','v','w','x','y','z','A','B','C','D','E','F','G','H',
316 'I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',0};
318 if(!ftGdiGetTextMetricsW(hdc
, &tmwi
)) return 0;
320 pdc
= DC_LockDc(hdc
);
324 pdcattr
= pdc
->pdcattr
;
326 TextObj
= RealizeFontInit(pdcattr
->hlfntNew
);
332 Good
= TextIntGetTextExtentPoint(pdc
, TextObj
, alphabet
, 52, 0, NULL
, 0, &sz
, 0);
333 TEXTOBJ_UnlockText(TextObj
);
337 if (ptm
) *ptm
= tmwi
.TextMetric
;
338 if (height
) *height
= tmwi
.TextMetric
.tmHeight
;
340 return (sz
.cx
/ 26 + 1) / 2;
346 IntGetFontLanguageInfo(PDC Dc
)
349 FONTSIGNATURE fontsig
;
350 static const DWORD GCP_DBCS_MASK
=0x003F0000,
351 GCP_DIACRITIC_MASK
=0x00000000,
352 FLI_GLYPHS_MASK
=0x00000000,
353 GCP_GLYPHSHAPE_MASK
=0x00000040,
354 GCP_KASHIDA_MASK
=0x00000000,
355 GCP_LIGATE_MASK
=0x00000000,
356 GCP_USEKERNING_MASK
=0x00000000,
357 GCP_REORDER_MASK
=0x00000060;
361 ftGdiGetTextCharsetInfo( Dc
, &fontsig
, 0 );
363 /* We detect each flag we return using a bitmask on the Codepage Bitfields */
364 if( (fontsig
.fsCsb
[0]&GCP_DBCS_MASK
)!=0 )
367 if( (fontsig
.fsCsb
[0]&GCP_DIACRITIC_MASK
)!=0 )
368 result
|=GCP_DIACRITIC
;
370 if( (fontsig
.fsCsb
[0]&FLI_GLYPHS_MASK
)!=0 )
373 if( (fontsig
.fsCsb
[0]&GCP_GLYPHSHAPE_MASK
)!=0 )
374 result
|=GCP_GLYPHSHAPE
;
376 if( (fontsig
.fsCsb
[0]&GCP_KASHIDA_MASK
)!=0 )
379 if( (fontsig
.fsCsb
[0]&GCP_LIGATE_MASK
)!=0 )
382 if( (fontsig
.fsCsb
[0]&GCP_USEKERNING_MASK
)!=0 )
383 result
|=GCP_USEKERNING
;
385 pdcattr
= Dc
->pdcattr
;
387 /* This might need a test for a HEBREW- or ARABIC_CHARSET as well */
388 if ( pdcattr
->lTextAlign
& TA_RTLREADING
)
389 if( (fontsig
.fsCsb
[0]&GCP_REORDER_MASK
)!=0 )
397 RealizeFontInit(HFONT hFont
)
399 NTSTATUS Status
= STATUS_SUCCESS
;
402 pTextObj
= TEXTOBJ_LockText(hFont
);
404 if ( pTextObj
&& !(pTextObj
->fl
& TEXTOBJECT_INIT
))
406 Status
= TextIntRealizeFont(hFont
, pTextObj
);
407 if (!NT_SUCCESS(Status
))
409 TEXTOBJ_UnlockText(pTextObj
);
418 GreSelectFont( HDC hDC
, HFONT hFont
)
422 PTEXTOBJ pOrgFnt
, pNewFnt
= NULL
;
423 HFONT hOrgFont
= NULL
;
425 if (!hDC
|| !hFont
) return NULL
;
427 pdc
= DC_LockDc(hDC
);
433 if (NT_SUCCESS(TextIntRealizeFont((HFONT
)hFont
,NULL
)))
435 /* LFONTOBJ use share and locking. */
436 pNewFnt
= TEXTOBJ_LockText(hFont
);
437 pdcattr
= pdc
->pdcattr
;
438 pOrgFnt
= pdc
->dclevel
.plfnt
;
441 hOrgFont
= pOrgFnt
->BaseObject
.hHmgr
;
445 hOrgFont
= pdcattr
->hlfntNew
;
447 pdc
->dclevel
.plfnt
= pNewFnt
;
448 pdc
->hlfntCur
= hFont
;
449 pdcattr
->hlfntNew
= hFont
;
450 pdcattr
->ulDirty_
|= DIRTY_CHARSET
;
451 pdcattr
->ulDirty_
&= ~SLOW_WIDTHS
;
454 if (pNewFnt
) TEXTOBJ_UnlockText(pNewFnt
);
459 /** Functions ******************************************************************/
463 NtGdiAddFontResourceW(
469 IN OPTIONAL DESIGNVECTOR
*pdv
)
471 UNICODE_STRING SafeFileName
;
476 /* FIXME: Protect with SEH? */
477 RtlInitUnicodeString(&SafeFileName
, pwszFiles
);
479 /* Reserve for prepending '\??\' */
480 SafeFileName
.Length
+= 4 * sizeof(WCHAR
);
481 SafeFileName
.MaximumLength
+= 4 * sizeof(WCHAR
);
483 src
= SafeFileName
.Buffer
;
484 SafeFileName
.Buffer
= (PWSTR
)ExAllocatePoolWithTag(PagedPool
, SafeFileName
.MaximumLength
, TAG_STRING
);
485 if(!SafeFileName
.Buffer
)
487 EngSetLastError(ERROR_NOT_ENOUGH_MEMORY
);
492 RtlCopyMemory(SafeFileName
.Buffer
, L
"\\??\\", 4 * sizeof(WCHAR
));
494 Status
= MmCopyFromCaller(SafeFileName
.Buffer
+ 4, src
, SafeFileName
.MaximumLength
- (4 * sizeof(WCHAR
)));
495 if(!NT_SUCCESS(Status
))
497 ExFreePoolWithTag(SafeFileName
.Buffer
, TAG_STRING
);
498 SetLastNtError(Status
);
502 Ret
= IntGdiAddFontResource(&SafeFileName
, (DWORD
)fl
);
504 ExFreePoolWithTag(SafeFileName
.Buffer
, TAG_STRING
);
513 NtGdiGetCharacterPlacementW(
518 IN OUT LPGCP_RESULTSW pgcpw
,
524 return GreGetCharacterPlacementW( hdc
,
547 DWORD Result
= GDI_ERROR
;
548 NTSTATUS Status
= STATUS_SUCCESS
;
554 ProbeForRead(Buffer
, Size
, 1);
556 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
558 Status
= _SEH2_GetExceptionCode();
563 if (!NT_SUCCESS(Status
)) return Result
;
568 EngSetLastError(ERROR_INVALID_HANDLE
);
571 pdcattr
= Dc
->pdcattr
;
573 hFont
= pdcattr
->hlfntNew
;
574 TextObj
= RealizeFontInit(hFont
);
579 EngSetLastError(ERROR_INVALID_HANDLE
);
583 FontGdi
= ObjToGDI(TextObj
->Font
, FONT
);
585 Result
= ftGdiGetFontData(FontGdi
, Table
, Offset
, Buffer
, Size
);
587 TEXTOBJ_UnlockText(TextObj
);
597 NtGdiGetFontUnicodeRanges(
599 OUT OPTIONAL LPGLYPHSET pgs
)
608 NTSTATUS Status
= STATUS_SUCCESS
;
610 pDc
= DC_LockDc(hdc
);
613 EngSetLastError(ERROR_INVALID_HANDLE
);
617 pdcattr
= pDc
->pdcattr
;
619 hFont
= pdcattr
->hlfntNew
;
620 TextObj
= RealizeFontInit(hFont
);
622 if ( TextObj
== NULL
)
624 EngSetLastError(ERROR_INVALID_HANDLE
);
627 FontGdi
= ObjToGDI(TextObj
->Font
, FONT
);
629 Size
= ftGetFontUnicodeRanges( FontGdi
, NULL
);
633 pgsSafe
= ExAllocatePoolWithTag(PagedPool
, Size
, GDITAG_TEXT
);
636 EngSetLastError(ERROR_NOT_ENOUGH_MEMORY
);
641 Size
= ftGetFontUnicodeRanges( FontGdi
, pgsSafe
);
647 ProbeForWrite(pgs
, Size
, 1);
648 RtlCopyMemory(pgs
, pgsSafe
, Size
);
650 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
652 Status
= _SEH2_GetExceptionCode();
656 if (!NT_SUCCESS(Status
)) Size
= 0;
658 ExFreePoolWithTag(pgsSafe
, GDITAG_TEXT
);
661 TEXTOBJ_UnlockText(TextObj
);
668 NtGdiGetGlyphOutline(
672 OUT LPGLYPHMETRICS pgm
,
674 OUT OPTIONAL PVOID UnsafeBuf
,
676 IN BOOL bIgnoreRotation
)
678 ULONG Ret
= GDI_ERROR
;
682 NTSTATUS Status
= STATUS_SUCCESS
;
687 EngSetLastError(ERROR_INVALID_HANDLE
);
691 if (UnsafeBuf
&& cjBuf
)
693 pvBuf
= ExAllocatePoolWithTag(PagedPool
, cjBuf
, GDITAG_TEXT
);
696 EngSetLastError(ERROR_NOT_ENOUGH_MEMORY
);
701 Ret
= ftGdiGetGlyphOutline( dc
,
714 ProbeForWrite(UnsafeBuf
, cjBuf
, 1);
715 RtlCopyMemory(UnsafeBuf
, pvBuf
, cjBuf
);
717 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
719 Status
= _SEH2_GetExceptionCode();
723 ExFreePoolWithTag(pvBuf
, GDITAG_TEXT
);
730 ProbeForWrite(pgm
, sizeof(GLYPHMETRICS
), 1);
731 RtlCopyMemory(pgm
, &gm
, sizeof(GLYPHMETRICS
));
733 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
735 Status
= _SEH2_GetExceptionCode();
740 if (! NT_SUCCESS(Status
))
742 EngSetLastError(ERROR_INVALID_PARAMETER
);
753 NtGdiGetKerningPairs(HDC hDC
,
755 LPKERNINGPAIR krnpair
)
763 NTSTATUS Status
= STATUS_SUCCESS
;
768 EngSetLastError(ERROR_INVALID_HANDLE
);
772 pdcattr
= dc
->pdcattr
;
773 TextObj
= RealizeFontInit(pdcattr
->hlfntNew
);
778 EngSetLastError(ERROR_INVALID_HANDLE
);
782 FontGDI
= ObjToGDI(TextObj
->Font
, FONT
);
783 TEXTOBJ_UnlockText(TextObj
);
785 Count
= ftGdiGetKerningPairs(FontGDI
,0,NULL
);
787 if ( Count
&& krnpair
)
789 if (Count
> NumPairs
)
791 EngSetLastError(ERROR_INSUFFICIENT_BUFFER
);
794 pKP
= ExAllocatePoolWithTag(PagedPool
, Count
* sizeof(KERNINGPAIR
), GDITAG_TEXT
);
797 EngSetLastError(ERROR_NOT_ENOUGH_MEMORY
);
800 ftGdiGetKerningPairs(FontGDI
,Count
,pKP
);
803 ProbeForWrite(krnpair
, Count
* sizeof(KERNINGPAIR
), 1);
804 RtlCopyMemory(krnpair
, pKP
, Count
* sizeof(KERNINGPAIR
));
806 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
808 Status
= _SEH2_GetExceptionCode();
811 if (!NT_SUCCESS(Status
))
813 EngSetLastError(ERROR_INVALID_PARAMETER
);
816 ExFreePoolWithTag(pKP
,GDITAG_TEXT
);
822 From "Undocumented Windows 2000 Secrets" Appendix B, Table B-2, page
823 472, this is NtGdiGetOutlineTextMetricsInternalW.
827 NtGdiGetOutlineTextMetricsInternalW (HDC hDC
,
829 OUTLINETEXTMETRICW
*otm
,
838 OUTLINETEXTMETRICW
*potm
;
839 NTSTATUS Status
= STATUS_SUCCESS
;
844 EngSetLastError(ERROR_INVALID_HANDLE
);
847 pdcattr
= dc
->pdcattr
;
848 hFont
= pdcattr
->hlfntNew
;
849 TextObj
= RealizeFontInit(hFont
);
853 EngSetLastError(ERROR_INVALID_HANDLE
);
856 FontGDI
= ObjToGDI(TextObj
->Font
, FONT
);
857 TEXTOBJ_UnlockText(TextObj
);
858 Size
= IntGetOutlineTextMetrics(FontGDI
, 0, NULL
);
859 if (!otm
) return Size
;
862 EngSetLastError(ERROR_INSUFFICIENT_BUFFER
);
865 potm
= ExAllocatePoolWithTag(PagedPool
, Size
, GDITAG_TEXT
);
868 EngSetLastError(ERROR_NOT_ENOUGH_MEMORY
);
871 IntGetOutlineTextMetrics(FontGDI
, Size
, potm
);
876 ProbeForWrite(otm
, Size
, 1);
877 RtlCopyMemory(otm
, potm
, Size
);
879 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
881 Status
= _SEH2_GetExceptionCode();
885 if (!NT_SUCCESS(Status
))
887 EngSetLastError(ERROR_INVALID_PARAMETER
);
891 ExFreePoolWithTag(potm
,GDITAG_TEXT
);
898 NtGdiGetFontResourceInfoInternalW(
903 OUT LPDWORD pdwBytes
,
907 NTSTATUS Status
= STATUS_SUCCESS
;
909 UNICODE_STRING SafeFileNames
;
916 WCHAR FullName
[LF_FULLFACESIZE
];
919 /* FIXME: Handle cFiles > 0 */
921 /* Check for valid dwType values
922 dwType == 4 seems to be handled by gdi32 only */
923 if (dwType
== 4 || dwType
> 5)
925 EngSetLastError(ERROR_INVALID_PARAMETER
);
929 /* Allocate a safe unicode string buffer */
930 cbStringSize
= cwc
* sizeof(WCHAR
);
931 SafeFileNames
.MaximumLength
= SafeFileNames
.Length
= cbStringSize
- sizeof(WCHAR
);
932 SafeFileNames
.Buffer
= ExAllocatePoolWithTag(PagedPool
,
935 if (!SafeFileNames
.Buffer
)
937 EngSetLastError(ERROR_NOT_ENOUGH_MEMORY
);
941 /* Check buffers and copy pwszFiles to safe unicode string */
944 ProbeForRead(pwszFiles
, cbStringSize
, 1);
945 ProbeForWrite(pdwBytes
, sizeof(DWORD
), 1);
946 ProbeForWrite(pvBuf
, cjIn
, 1);
948 RtlCopyMemory(SafeFileNames
.Buffer
, pwszFiles
, cbStringSize
);
950 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
952 Status
= _SEH2_GetExceptionCode();
956 if(!NT_SUCCESS(Status
))
958 SetLastNtError(Status
);
959 /* Free the string buffer for the safe filename */
960 ExFreePoolWithTag(SafeFileNames
.Buffer
,'RTSU');
964 /* Do the actual call */
965 bRet
= IntGdiGetFontResourceInfo(&SafeFileNames
, &Buffer
, &dwBytes
, dwType
);
967 /* Check if succeeded and the buffer is big enough */
968 if (bRet
&& cjIn
>= dwBytes
)
970 /* Copy the data back to caller */
973 /* Buffers are already probed */
974 RtlCopyMemory(pvBuf
, &Buffer
, dwBytes
);
977 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
979 Status
= _SEH2_GetExceptionCode();
983 if(!NT_SUCCESS(Status
))
985 SetLastNtError(Status
);
990 /* Free the string for the safe filenames */
991 ExFreePoolWithTag(SafeFileNames
.Buffer
,'RTSU');
1001 NtGdiGetRealizationInfo(
1003 OUT PREALIZATION_INFO pri
,
1012 REALIZATION_INFO ri
;
1014 pDc
= DC_LockDc(hdc
);
1017 EngSetLastError(ERROR_INVALID_HANDLE
);
1020 pdcattr
= pDc
->pdcattr
;
1021 pTextObj
= RealizeFontInit(pdcattr
->hlfntNew
);
1022 pFontGdi
= ObjToGDI(pTextObj
->Font
, FONT
);
1023 TEXTOBJ_UnlockText(pTextObj
);
1026 Ret
= ftGdiRealizationInfo(pFontGdi
, &ri
);
1031 NTSTATUS Status
= STATUS_SUCCESS
;
1034 ProbeForWrite(pri
, sizeof(REALIZATION_INFO
), 1);
1035 RtlCopyMemory(pri
, &ri
, sizeof(REALIZATION_INFO
));
1037 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1039 Status
= _SEH2_GetExceptionCode();
1043 if(!NT_SUCCESS(Status
))
1045 SetLastNtError(Status
);
1051 if (GdiHandleTable
->cfPublic
[i
].hf
== hf
)
1053 GdiHandleTable
->cfPublic
[i
].iTechnology
= ri
.iTechnology
;
1054 GdiHandleTable
->cfPublic
[i
].iUniq
= ri
.iUniq
;
1055 GdiHandleTable
->cfPublic
[i
].dwUnknown
= ri
.dwUnknown
;
1056 GdiHandleTable
->cfPublic
[i
].dwCFCount
= GdiHandleTable
->dwCFCount
;
1057 GdiHandleTable
->cfPublic
[i
].fl
|= CFONT_REALIZATION
;
1061 while ( i
< GDI_CFONT_MAX
);
1069 IN PENUMLOGFONTEXDVW pelfw
,
1073 IN PVOID pvCliData
)
1075 ENUMLOGFONTEXDVW SafeLogfont
;
1078 NTSTATUS Status
= STATUS_SUCCESS
;
1080 /* Silence GCC warnings */
1081 SafeLogfont
.elfEnumLogfontEx
.elfLogFont
.lfEscapement
= 0;
1082 SafeLogfont
.elfEnumLogfontEx
.elfLogFont
.lfOrientation
= 0;
1091 ProbeForRead(pelfw
, sizeof(ENUMLOGFONTEXDVW
), 1);
1092 RtlCopyMemory(&SafeLogfont
, pelfw
, sizeof(ENUMLOGFONTEXDVW
));
1094 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1096 Status
= _SEH2_GetExceptionCode();
1100 if (!NT_SUCCESS(Status
))
1105 TextObj
= TEXTOBJ_AllocTextWithHandle();
1110 hNewFont
= TextObj
->BaseObject
.hHmgr
;
1114 RtlCopyMemory (&TextObj
->logfont
, &SafeLogfont
, sizeof(ENUMLOGFONTEXDVW
));
1116 if (SafeLogfont
.elfEnumLogfontEx
.elfLogFont
.lfEscapement
!=
1117 SafeLogfont
.elfEnumLogfontEx
.elfLogFont
.lfOrientation
)
1119 /* This should really depend on whether GM_ADVANCED is set */
1120 TextObj
->logfont
.elfEnumLogfontEx
.elfLogFont
.lfOrientation
=
1121 TextObj
->logfont
.elfEnumLogfontEx
.elfLogFont
.lfEscapement
;
1123 TEXTOBJ_UnlockText(TextObj
);
1125 if (pvCliData
&& hNewFont
)
1127 // FIXME: Use GDIOBJ_InsertUserData
1128 KeEnterCriticalRegion();
1130 INT Index
= GDI_HANDLE_GET_INDEX((HGDIOBJ
)hNewFont
);
1131 PGDI_TABLE_ENTRY Entry
= &GdiHandleTable
->Entries
[Index
];
1132 Entry
->UserData
= pvCliData
;
1134 KeLeaveCriticalRegion();
1149 return GreSelectFont(hDC
, hFont
);