- Implemented: GetFontLanguageInfo based on wine. GetLanguageID, it reads the registry for default language type.

- Move more function in and out of freetype.c. Minor code fixes too.


svn path=/trunk/; revision=37090
This commit is contained in:
James Tabor 2008-10-30 10:46:27 +00:00
parent b645f2b87e
commit b70d5a56a4
10 changed files with 381 additions and 258 deletions

View file

@ -518,6 +518,8 @@ EngDeleteXlate(XLATEOBJ *XlateObj)
XlateGDI = ObjToGDI(XlateObj, XLATE);
if (!XlateGDI) return;
if ((XlateObj->flXlate & XO_TABLE) &&
XlateObj->pulXlate != NULL)
{

View file

@ -31,6 +31,9 @@
#define W32PF_CREATEDWINORDC (0x04000000)
extern SHORT gusLanguageID;
SHORT FASTCALL IntGdiGetLanguageID();
ULONG FASTCALL IntSystemParametersInfo(UINT uiAction, UINT uiParam, PVOID pvParam, UINT fWinIni);
DWORD STDCALL IntGetQueueStatus(BOOL ClearChanges);
VOID FASTCALL IntUserManualGuiCheck(LONG Check);

View file

@ -84,6 +84,14 @@ VOID FASTCALL IntEnableFontRendering(BOOL Enable);
INT FASTCALL FontGetObject(PTEXTOBJ TextObj, INT Count, PVOID Buffer);
VOID FASTCALL IntLoadSystemFonts(VOID);
INT FASTCALL IntGdiAddFontResource(PUNICODE_STRING FileName, DWORD Characteristics);
ULONG FASTCALL ftGdiGetGlyphOutline(PDC,WCHAR,UINT,LPGLYPHMETRICS,ULONG,PVOID,LPMAT2,BOOL);
INT FASTCALL IntGetOutlineTextMetrics(PFONTGDI,UINT,OUTLINETEXTMETRICW *);
BOOL FASTCALL ftGdiGetRasterizerCaps(LPRASTERIZER_STATUS);
BOOL FASTCALL TextIntGetTextExtentPoint(PDC,PTEXTOBJ,LPCWSTR,int,int,LPINT,LPINT,LPSIZE);
DWORD FASTCALL IntGdiGetCharSet(HDC);
BOOL FASTCALL ftGdiGetTextMetricsW(HDC,PTMW_INTERNAL);
DWORD FASTCALL ftGetFontLanguageInfo(PDC);
INT FASTCALL ftGdiGetTextCharsetInfo(PDC,PFONTSIGNATURE,DWORD);
#define IntLockProcessPrivateFonts(W32Process) \
ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&W32Process->PrivateFontListLock)

View file

@ -42,6 +42,8 @@ PSERVERINFO gpsi = NULL; // Global User Server Information.
HSEMAPHORE hsemDriverMgmt = NULL;
SHORT gusLanguageID;
extern ULONG_PTR Win32kSSDT[];
extern UCHAR Win32kSSPT[];
extern ULONG Win32kNumberOfSysCalls;
@ -420,6 +422,13 @@ DriverEntry (
if(!hsemDriverMgmt) hsemDriverMgmt = EngCreateSemaphore();
GdiHandleTable = GDIOBJ_iAllocHandleTable(&GdiTableSection);
if (GdiHandleTable == NULL)
{
DPRINT1("Failed to initialize the GDI handle table.\n");
return STATUS_UNSUCCESSFUL;
}
Status = InitUserImpl();
if (!NT_SUCCESS(Status))
{
@ -511,13 +520,6 @@ DriverEntry (
return(Status);
}
GdiHandleTable = GDIOBJ_iAllocHandleTable(&GdiTableSection);
if (GdiHandleTable == NULL)
{
DPRINT1("Failed to initialize the GDI handle table.\n");
return STATUS_UNSUCCESSFUL;
}
Status = InitDcImpl();
if (!NT_SUCCESS(Status))
{
@ -537,6 +539,8 @@ DriverEntry (
CreateStockObjects();
CreateSysColorObjects();
gusLanguageID = IntGdiGetLanguageID();
return STATUS_SUCCESS;
}

View file

@ -14,6 +14,52 @@
#include <debug.h>
SHORT
FASTCALL
IntGdiGetLanguageID()
{
HANDLE KeyHandle;
ULONG Size = sizeof(WCHAR) * (MAX_PATH + 12);
OBJECT_ATTRIBUTES ObAttr;
// http://support.microsoft.com/kb/324097
ULONG Ret = 0x409; // English
PVOID KeyInfo;
UNICODE_STRING Language;
RtlInitUnicodeString( &Language,
L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Nls\\Language");
InitializeObjectAttributes( &ObAttr,
&Language,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
if ( NT_SUCCESS(ZwOpenKey(&KeyHandle, KEY_READ, &ObAttr)))
{
KeyInfo = ExAllocatePoolWithTag(PagedPool, Size, TAG_STRING);
if ( KeyInfo )
{
RtlInitUnicodeString(&Language, L"Default");
if ( NT_SUCCESS(ZwQueryValueKey( KeyHandle,
&Language,
KeyValuePartialInformation,
KeyInfo,
Size,
&Size)) )
{
RtlInitUnicodeString(&Language, (PVOID)((char *)KeyInfo + 12));
RtlUnicodeStringToInteger(&Language, 16, &Ret);
}
ExFreePoolWithTag(KeyInfo, TAG_STRING);
}
ZwClose(KeyHandle);
}
DPRINT1("Language ID = %x\n",Ret);
return (SHORT) Ret;
}
/*
* @unimplemented
*/

View file

@ -16,12 +16,11 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id$
*
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* PURPOSE: Message queues
* FILE: subsys/win32k/ntuser/msgqueue.c
* FILE: subsystems/win32/win32k/ntuser/msgqueue.c
* PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
* REVISION HISTORY:
* 06-06-2001 CSH Created

View file

@ -2411,6 +2411,7 @@ NtGdiGetDCDword(
case GdiGetEMFRestorDc:
break;
case GdiGetFontLanguageInfo:
SafeResult = ftGetFontLanguageInfo(dc);
break;
case GdiGetIsMemDc:
SafeResult = dc->DC_Type;

View file

@ -13,32 +13,54 @@
#define NDEBUG
#include <debug.h>
//
// FIXME PLEASE!!!!
// Why are these here? Well there is a problem with drivers/directx.
// 1st: It does not belong there.
// 2nd: Due to being placed outside Win32k build environment, it creates
// compiling issues.
// Until svn mv drivers/directx subsystem/win32/win32k/drivers/directx,
// it will not get fixed.
//
ULONG
FASTCALL
ftGdiGetGlyphOutline(
IN PDC pdc,
IN WCHAR wch,
IN UINT iFormat,
OUT LPGLYPHMETRICS pgm,
IN ULONG cjBuf,
OUT OPTIONAL PVOID UnsafeBuf,
IN LPMAT2 pmat2,
IN BOOL bIgnoreRotation);
/** Functions ******************************************************************/
INT
FASTCALL
IntGetOutlineTextMetrics(PFONTGDI FontGDI, UINT Size, OUTLINETEXTMETRICW *Otm);
APIENTRY
NtGdiAddFontResourceW(
IN WCHAR *pwszFiles,
IN ULONG cwc,
IN ULONG cFiles,
IN FLONG fl,
IN DWORD dwPidTid,
IN OPTIONAL DESIGNVECTOR *pdv)
{
UNICODE_STRING SafeFileName;
PWSTR src;
NTSTATUS Status;
int Ret;
/** Functions ******************************************************************/
/* FIXME - Protect with SEH? */
RtlInitUnicodeString(&SafeFileName, pwszFiles);
/* Reserve for prepending '\??\' */
SafeFileName.Length += 4 * sizeof(WCHAR);
SafeFileName.MaximumLength += 4 * sizeof(WCHAR);
src = SafeFileName.Buffer;
SafeFileName.Buffer = (PWSTR)ExAllocatePoolWithTag(PagedPool, SafeFileName.MaximumLength, TAG_STRING);
if(!SafeFileName.Buffer)
{
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
return 0;
}
/* Prepend '\??\' */
RtlCopyMemory(SafeFileName.Buffer, L"\\??\\", 4 * sizeof(WCHAR));
Status = MmCopyFromCaller(SafeFileName.Buffer + 4, src, SafeFileName.MaximumLength - (4 * sizeof(WCHAR)));
if(!NT_SUCCESS(Status))
{
ExFreePool(SafeFileName.Buffer);
SetLastNtError(Status);
return 0;
}
Ret = IntGdiAddFontResource(&SafeFileName, (DWORD)fl);
ExFreePool(SafeFileName.Buffer);
return Ret;
}
ULONG
APIENTRY
@ -148,4 +170,61 @@ NtGdiGetOutlineTextMetricsInternalW (HDC hDC,
return Size;
}
HFONT
STDCALL
NtGdiHfontCreate(
IN PENUMLOGFONTEXDVW pelfw,
IN ULONG cjElfw,
IN LFTYPE lft,
IN FLONG fl,
IN PVOID pvCliData )
{
ENUMLOGFONTEXDVW SafeLogfont;
HFONT hNewFont;
PTEXTOBJ TextObj;
NTSTATUS Status = STATUS_SUCCESS;
if (!pelfw)
{
return NULL;
}
_SEH_TRY
{
ProbeForRead(pelfw, sizeof(ENUMLOGFONTEXDVW), 1);
RtlCopyMemory(&SafeLogfont, pelfw, sizeof(ENUMLOGFONTEXDVW));
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END
if (!NT_SUCCESS(Status))
{
return NULL;
}
TextObj = TEXTOBJ_AllocTextWithHandle();
if (!TextObj)
{
return NULL;
}
hNewFont = TextObj->BaseObject.hHmgr;
RtlCopyMemory (&TextObj->logfont, &SafeLogfont, sizeof(ENUMLOGFONTEXDVW));
if (SafeLogfont.elfEnumLogfontEx.elfLogFont.lfEscapement !=
SafeLogfont.elfEnumLogfontEx.elfLogFont.lfOrientation)
{
/* this should really depend on whether GM_ADVANCED is set */
TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfOrientation =
TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfEscapement;
}
TEXTOBJ_UnlockText(TextObj);
return hNewFont;
}
/* EOF */

View file

@ -22,7 +22,6 @@
#define NDEBUG
#include <debug.h>
FT_Library library;
typedef struct _FONT_ENTRY {
@ -44,8 +43,6 @@ static BOOL RenderingEnabled = TRUE;
UINT Hits;
UINT Misses;
SHORT ftLanguageID = 0;
typedef struct _FONT_CACHE_ENTRY {
LIST_ENTRY ListEntry;
int GlyphIndex;
@ -244,6 +241,7 @@ IntLoadSystemFonts(VOID)
}
}
/*
* IntGdiAddFontResource
*
@ -446,52 +444,6 @@ IntGetFontRenderMode(LOGFONTW *logfont)
return FT_RENDER_MODE_NORMAL;
}
INT
APIENTRY
NtGdiAddFontResourceW(
IN WCHAR *pwszFiles,
IN ULONG cwc,
IN ULONG cFiles,
IN FLONG fl,
IN DWORD dwPidTid,
IN OPTIONAL DESIGNVECTOR *pdv)
{
UNICODE_STRING SafeFileName;
PWSTR src;
NTSTATUS Status;
int Ret;
/* FIXME - Protect with SEH? */
RtlInitUnicodeString(&SafeFileName, pwszFiles);
/* Reserve for prepending '\??\' */
SafeFileName.Length += 4 * sizeof(WCHAR);
SafeFileName.MaximumLength += 4 * sizeof(WCHAR);
src = SafeFileName.Buffer;
SafeFileName.Buffer = (PWSTR)ExAllocatePoolWithTag(PagedPool, SafeFileName.MaximumLength, TAG_STRING);
if(!SafeFileName.Buffer)
{
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
return 0;
}
/* Prepend '\??\' */
RtlCopyMemory(SafeFileName.Buffer, L"\\??\\", 4 * sizeof(WCHAR));
Status = MmCopyFromCaller(SafeFileName.Buffer + 4, src, SafeFileName.MaximumLength - (4 * sizeof(WCHAR)));
if(!NT_SUCCESS(Status))
{
ExFreePool(SafeFileName.Buffer);
SetLastNtError(Status);
return 0;
}
Ret = IntGdiAddFontResource(&SafeFileName, (DWORD)fl);
ExFreePool(SafeFileName.Buffer);
return Ret;
}
NTSTATUS FASTCALL
TextIntCreateFontIndirect(CONST LPLOGFONTW lf, HFONT *NewFont)
@ -517,63 +469,6 @@ TextIntCreateFontIndirect(CONST LPLOGFONTW lf, HFONT *NewFont)
return STATUS_SUCCESS;
}
HFONT
STDCALL
NtGdiHfontCreate(
IN PENUMLOGFONTEXDVW pelfw,
IN ULONG cjElfw,
IN LFTYPE lft,
IN FLONG fl,
IN PVOID pvCliData )
{
ENUMLOGFONTEXDVW SafeLogfont;
HFONT hNewFont;
PTEXTOBJ TextObj;
NTSTATUS Status = STATUS_SUCCESS;
if (!pelfw)
{
return NULL;
}
_SEH_TRY
{
ProbeForRead(pelfw, sizeof(ENUMLOGFONTEXDVW), 1);
RtlCopyMemory(&SafeLogfont, pelfw, sizeof(ENUMLOGFONTEXDVW));
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END
if (!NT_SUCCESS(Status))
{
return NULL;
}
TextObj = TEXTOBJ_AllocTextWithHandle();
if (!TextObj)
{
return NULL;
}
hNewFont = TextObj->BaseObject.hHmgr;
RtlCopyMemory (&TextObj->logfont, &SafeLogfont, sizeof(ENUMLOGFONTEXDVW));
if (SafeLogfont.elfEnumLogfontEx.elfLogFont.lfEscapement !=
SafeLogfont.elfEnumLogfontEx.elfLogFont.lfOrientation)
{
/* this should really depend on whether GM_ADVANCED is set */
TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfOrientation =
TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfEscapement;
}
TEXTOBJ_UnlockText(TextObj);
return hNewFont;
}
/*************************************************************************
* TranslateCharsetInfo
*
@ -1329,7 +1224,7 @@ ftGdiGetRasterizerCaps(LPRASTERIZER_STATUS lprs)
{
lprs->nSize = sizeof(RASTERIZER_STATUS);
lprs->wFlags = TT_AVAILABLE | TT_ENABLED;
lprs->nLanguageID = ftLanguageID;
lprs->nLanguageID = gusLanguageID;
return TRUE;
}
SetLastWin32Error(ERROR_INVALID_PARAMETER);
@ -1413,7 +1308,7 @@ NtGdiGetFontFamilyInfo(HDC Dc,
}
FT_Glyph STDCALL
NtGdiGlyphCacheGet(
ftGdiGlyphCacheGet(
FT_Face Face,
INT GlyphIndex,
INT Height)
@ -1462,7 +1357,7 @@ NtGdiGlyphCacheGet(
}
FT_Glyph STDCALL
NtGdiGlyphCacheSet(
ftGdiGlyphCacheSet(
FT_Face Face,
INT GlyphIndex,
INT Height,
@ -1842,7 +1737,7 @@ NtGdiExtTextOutW(
else
glyph_index = FT_Get_Char_Index(face, *TempText);
if (!(realglyph = NtGdiGlyphCacheGet(face, glyph_index,
if (!(realglyph = ftGdiGlyphCacheGet(face, glyph_index,
TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight)))
{
error = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT);
@ -1852,7 +1747,7 @@ NtGdiExtTextOutW(
}
glyph = face->glyph;
realglyph = NtGdiGlyphCacheSet(face, glyph_index,
realglyph = ftGdiGlyphCacheSet(face, glyph_index,
TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight, glyph, RenderMode);
if (!realglyph)
{
@ -1903,7 +1798,7 @@ NtGdiExtTextOutW(
else
glyph_index = FT_Get_Char_Index(face, *String);
if (!(realglyph = NtGdiGlyphCacheGet(face, glyph_index,
if (!(realglyph = ftGdiGlyphCacheGet(face, glyph_index,
TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight)))
{
error = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT);
@ -1914,7 +1809,7 @@ NtGdiExtTextOutW(
goto fail;
}
glyph = face->glyph;
realglyph = NtGdiGlyphCacheSet(face,
realglyph = ftGdiGlyphCacheSet(face,
glyph_index,
TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight,
glyph,
@ -2591,14 +2486,14 @@ static __inline FT_Fixed FT_FixedFromFIXED(FIXED f)
ULONG
FASTCALL
ftGdiGetGlyphOutline(
IN PDC dc,
IN WCHAR wch,
IN UINT iFormat,
OUT LPGLYPHMETRICS pgm,
IN ULONG cjBuf,
OUT OPTIONAL PVOID UnsafeBuf,
IN LPMAT2 pmat2,
IN BOOL bIgnoreRotation)
PDC dc,
WCHAR wch,
UINT iFormat,
LPGLYPHMETRICS pgm,
ULONG cjBuf,
OPTIONAL PVOID UnsafeBuf,
LPMAT2 pmat2,
BOOL bIgnoreRotation)
{
static const FT_Matrix identityMat = {(1 << 16), 0, 0, (1 << 16)};
PDC_ATTR Dc_Attr;
@ -3313,7 +3208,7 @@ TextIntGetTextExtentPoint(PDC dc,
for (i = 0; i < Count; i++)
{
glyph_index = FT_Get_Char_Index(face, *String);
if (!(realglyph = NtGdiGlyphCacheGet(face, glyph_index,
if (!(realglyph = ftGdiGlyphCacheGet(face, glyph_index,
TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight)))
{
error = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT);
@ -3324,7 +3219,7 @@ TextIntGetTextExtentPoint(PDC dc,
}
glyph = face->glyph;
realglyph = NtGdiGlyphCacheSet(face, glyph_index,
realglyph = ftGdiGlyphCacheSet(face, glyph_index,
TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight, glyph, RenderMode);
if (!realglyph)
{
@ -3364,7 +3259,6 @@ TextIntGetTextExtentPoint(PDC dc,
return TRUE;
}
DWORD
FASTCALL
IntGdiGetCharSet(HDC hDC)
@ -3393,38 +3287,13 @@ IntGdiGetCharSet(HDC hDC)
return (MAKELONG(cp, charset));
}
DWORD
APIENTRY
NtGdiGetCharSet(HDC hDC)
{
PDC Dc;
PDC_ATTR Dc_Attr;
DWORD cscp = IntGdiGetCharSet(hDC);
// If here, update everything!
Dc = DC_LockDc(hDC);
if (!Dc)
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
return 0;
}
Dc_Attr = Dc->pDc_Attr;
if (!Dc_Attr) Dc_Attr = &Dc->Dc_Attr;
Dc_Attr->iCS_CP = cscp;
Dc_Attr->ulDirty_ &= ~DIRTY_CHARSET;
DC_UnlockDc( Dc );
return cscp;
}
INT
APIENTRY
NtGdiGetTextCharsetInfo(
IN HDC hdc,
OUT OPTIONAL LPFONTSIGNATURE lpSig,
IN DWORD dwFlags)
FASTCALL
ftGdiGetTextCharsetInfo(
PDC Dc,
LPFONTSIGNATURE lpSig,
DWORD dwFlags)
{
PDC Dc;
PDC_ATTR Dc_Attr;
UINT Ret = DEFAULT_CHARSET, i = 0, fs_fsCsb0 = 0;
HFONT hFont;
@ -3433,19 +3302,12 @@ NtGdiGetTextCharsetInfo(
FONTSIGNATURE fs;
TT_OS2 *pOS2;
FT_Face Face;
NTSTATUS Status;
Dc = DC_LockDc(hdc);
if (!Dc)
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
return Ret;
}
Dc_Attr = Dc->pDc_Attr;
if(!Dc_Attr) Dc_Attr = &Dc->Dc_Attr;
hFont = Dc_Attr->hlfntNew;
TextObj = TEXTOBJ_LockText(hFont);
DC_UnlockDc( Dc );
if ( TextObj == NULL)
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
@ -3479,14 +3341,9 @@ NtGdiGetTextCharsetInfo(
}
DPRINT("Csb 1=%x 0=%x\n", fs.fsCsb[1],fs.fsCsb[0]);
if (lpSig)
{
Status = MmCopyToCaller(lpSig, &fs, sizeof(FONTSIGNATURE));
if (! NT_SUCCESS(Status))
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return Ret;
}
}
{
RtlCopyMemory(lpSig, &fs, sizeof(FONTSIGNATURE));
}
if (0 == fs_fsCsb0)
{ /* let's see if we can find any interesting cmaps */
for (i = 0; i < Face->num_charmaps; i++)
@ -3514,34 +3371,81 @@ NtGdiGetTextCharsetInfo(
return Ret;
}
W32KAPI
DWORD
FASTCALL
ftGetFontLanguageInfo(PDC Dc)
{
PDC_ATTR Dc_Attr;
FONTSIGNATURE fontsig;
static const DWORD GCP_DBCS_MASK=0x003F0000,
GCP_DIACRITIC_MASK=0x00000000,
FLI_GLYPHS_MASK=0x00000000,
GCP_GLYPHSHAPE_MASK=0x00000040,
GCP_KASHIDA_MASK=0x00000000,
GCP_LIGATE_MASK=0x00000000,
GCP_USEKERNING_MASK=0x00000000,
GCP_REORDER_MASK=0x00000060;
DWORD result=0;
ftGdiGetTextCharsetInfo( Dc, &fontsig, 0 );
/* We detect each flag we return using a bitmask on the Codepage Bitfields */
if( (fontsig.fsCsb[0]&GCP_DBCS_MASK)!=0 )
result|=GCP_DBCS;
if( (fontsig.fsCsb[0]&GCP_DIACRITIC_MASK)!=0 )
result|=GCP_DIACRITIC;
if( (fontsig.fsCsb[0]&FLI_GLYPHS_MASK)!=0 )
result|=FLI_GLYPHS;
if( (fontsig.fsCsb[0]&GCP_GLYPHSHAPE_MASK)!=0 )
result|=GCP_GLYPHSHAPE;
if( (fontsig.fsCsb[0]&GCP_KASHIDA_MASK)!=0 )
result|=GCP_KASHIDA;
if( (fontsig.fsCsb[0]&GCP_LIGATE_MASK)!=0 )
result|=GCP_LIGATE;
if( (fontsig.fsCsb[0]&GCP_USEKERNING_MASK)!=0 )
result|=GCP_USEKERNING;
Dc_Attr = Dc->pDc_Attr;
if(!Dc_Attr) Dc_Attr = &Dc->Dc_Attr;
/* this might need a test for a HEBREW- or ARABIC_CHARSET as well */
if ( Dc_Attr->lTextAlign & TA_RTLREADING )
if( (fontsig.fsCsb[0]&GCP_REORDER_MASK)!=0 )
result|=GCP_REORDER;
return result;
}
BOOL
APIENTRY
NtGdiGetTextMetricsW(
IN HDC hDC,
OUT TMW_INTERNAL * pUnsafeTmwi,
IN ULONG cj
)
FASTCALL
ftGdiGetTextMetricsW(
HDC hDC,
PTMW_INTERNAL ptmwi)
{
PDC dc;
PDC_ATTR Dc_Attr;
PTEXTOBJ TextObj;
PFONTGDI FontGDI;
NTSTATUS Status = STATUS_SUCCESS;
TMW_INTERNAL tmwi;
FT_Face Face;
TT_OS2 *pOS2;
TT_HoriHeader *pHori;
ULONG Error;
NTSTATUS Status = STATUS_SUCCESS;
if (NULL == pUnsafeTmwi)
if (!ptmwi)
{
SetLastWin32Error(STATUS_INVALID_PARAMETER);
return FALSE;
}
/* FIXME: check cj ? */
if(!(dc = DC_LockDc(hDC)))
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
@ -3570,9 +3474,9 @@ NtGdiGetTextMetricsW(
}
else
{
memcpy(&tmwi.TextMetric, &FontGDI->TextMetric, sizeof(TEXTMETRICW));
memcpy(&ptmwi->TextMetric, &FontGDI->TextMetric, sizeof(TEXTMETRICW));
/* FIXME: Fill Diff member */
RtlZeroMemory(&tmwi.Diff, sizeof(tmwi.Diff));
RtlZeroMemory(&ptmwi->Diff, sizeof(ptmwi->Diff));
Status = STATUS_SUCCESS;
IntLockFreeType;
@ -3594,38 +3498,22 @@ NtGdiGetTextMetricsW(
if (NT_SUCCESS(Status))
{
FillTM(&tmwi.TextMetric, FontGDI->face, pOS2, pHori);
if (cj > sizeof(TMW_INTERNAL))
cj = sizeof(TMW_INTERNAL);
Status = STATUS_SUCCESS;
_SEH_TRY
{
ProbeForWrite(pUnsafeTmwi, cj, 1);
RtlCopyMemory(pUnsafeTmwi,&tmwi,cj);
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END
FillTM(&ptmwi->TextMetric, FontGDI->face, pOS2, pHori);
}
}
TEXTOBJ_UnlockText(TextObj);
}
else
{
Status = STATUS_INVALID_HANDLE;
}
{
Status = STATUS_INVALID_HANDLE;
}
DC_UnlockDc(dc);
if(!NT_SUCCESS(Status))
{
SetLastNtError(Status);
return FALSE;
}
if (!NT_SUCCESS(Status))
{
SetLastNtError(Status);
return FALSE;
}
return TRUE;
}

View file

@ -13,24 +13,30 @@
#define NDEBUG
#include <debug.h>
BOOL
FASTCALL
ftGdiGetRasterizerCaps(LPRASTERIZER_STATUS lprs);
BOOL
FASTCALL
TextIntGetTextExtentPoint(PDC dc,
PTEXTOBJ TextObj,
LPCWSTR String,
int Count,
int MaxExtent,
LPINT Fit,
LPINT Dx,
LPSIZE Size);
/** Functions ******************************************************************/
DWORD
APIENTRY
NtGdiGetCharSet(HDC hDC)
{
PDC Dc;
PDC_ATTR Dc_Attr;
DWORD cscp = IntGdiGetCharSet(hDC);
// If here, update everything!
Dc = DC_LockDc(hDC);
if (!Dc)
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
return 0;
}
Dc_Attr = Dc->pDc_Attr;
if (!Dc_Attr) Dc_Attr = &Dc->Dc_Attr;
Dc_Attr->iCS_CP = cscp;
Dc_Attr->ulDirty_ &= ~DIRTY_CHARSET;
DC_UnlockDc( Dc );
return cscp;
}
BOOL
APIENTRY
NtGdiGetRasterizerCaps(
@ -68,6 +74,55 @@ NtGdiGetRasterizerCaps(
return FALSE;
}
INT
APIENTRY
NtGdiGetTextCharsetInfo(
IN HDC hdc,
OUT OPTIONAL LPFONTSIGNATURE lpSig,
IN DWORD dwFlags)
{
PDC Dc;
INT Ret;
FONTSIGNATURE fsSafe;
PFONTSIGNATURE pfsSafe = &fsSafe;
NTSTATUS Status = STATUS_SUCCESS;
Dc = DC_LockDc(hdc);
if (!Dc)
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
return DEFAULT_CHARSET;
}
if (!lpSig) pfsSafe = NULL;
Ret = ftGdiGetTextCharsetInfo( Dc, pfsSafe, dwFlags);
if (lpSig)
{
_SEH_TRY
{
ProbeForWrite( lpSig,
sizeof(FONTSIGNATURE),
1);
RtlCopyMemory(lpSig, pfsSafe, sizeof(FONTSIGNATURE));
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
if (!NT_SUCCESS(Status))
{
SetLastNtError(Status);
return DEFAULT_CHARSET;
}
}
DC_UnlockDc(Dc);
return Ret;
}
W32KAPI
BOOL
APIENTRY
@ -298,4 +353,42 @@ NtGdiGetTextFaceW(
return Count;
}
W32KAPI
BOOL
APIENTRY
NtGdiGetTextMetricsW(
IN HDC hDC,
OUT TMW_INTERNAL * pUnsafeTmwi,
IN ULONG cj
)
{
TMW_INTERNAL Tmwi;
NTSTATUS Status = STATUS_SUCCESS;
if ( cj <= sizeof(TMW_INTERNAL) )
{
if (ftGdiGetTextMetricsW(hDC,&Tmwi))
{
_SEH_TRY
{
ProbeForWrite(pUnsafeTmwi, cj, 1);
RtlCopyMemory(pUnsafeTmwi,&Tmwi,cj);
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END
if (!NT_SUCCESS(Status))
{
SetLastNtError(Status);
return FALSE;
}
return TRUE;
}
}
return FALSE;
}
/* EOF */