- Fix code page and charector set support. More miscellaneous changes and fixes.

svn path=/trunk/; revision=37185
This commit is contained in:
James Tabor 2008-11-04 12:49:49 +00:00
parent 90115aa977
commit 122fb58d8f
9 changed files with 294 additions and 267 deletions

View file

@ -16,46 +16,45 @@
/* /*
* For TranslateCharsetInfo * For TranslateCharsetInfo
*/ */
#define FS(x) {{0,0,0,0},{0x1<<(x),0}}
#define MAXTCIINDEX 32 #define MAXTCIINDEX 32
static const CHARSETINFO FONT_tci[MAXTCIINDEX] = { static const CHARSETINFO FONT_tci[MAXTCIINDEX] = {
/* ANSI */ /* ANSI */
{ ANSI_CHARSET, 1252, FS(0)}, { ANSI_CHARSET, 1252, {{0,0,0,0},{FS_LATIN1,0}} },
{ EASTEUROPE_CHARSET, 1250, FS(1)}, { EASTEUROPE_CHARSET, 1250, {{0,0,0,0},{FS_LATIN2,0}} },
{ RUSSIAN_CHARSET, 1251, FS(2)}, { RUSSIAN_CHARSET, 1251, {{0,0,0,0},{FS_CYRILLIC,0}} },
{ GREEK_CHARSET, 1253, FS(3)}, { GREEK_CHARSET, 1253, {{0,0,0,0},{FS_GREEK,0}} },
{ TURKISH_CHARSET, 1254, FS(4)}, { TURKISH_CHARSET, 1254, {{0,0,0,0},{FS_TURKISH,0}} },
{ HEBREW_CHARSET, 1255, FS(5)}, { HEBREW_CHARSET, 1255, {{0,0,0,0},{FS_HEBREW,0}} },
{ ARABIC_CHARSET, 1256, FS(6)}, { ARABIC_CHARSET, 1256, {{0,0,0,0},{FS_ARABIC,0}} },
{ BALTIC_CHARSET, 1257, FS(7)}, { BALTIC_CHARSET, 1257, {{0,0,0,0},{FS_BALTIC,0}} },
{ VIETNAMESE_CHARSET, 1258, FS(8)}, { VIETNAMESE_CHARSET, 1258, {{0,0,0,0},{FS_VIETNAMESE,0}} },
/* reserved by ANSI */ /* reserved by ANSI */
{ DEFAULT_CHARSET, 0, FS(0)}, { DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
{ DEFAULT_CHARSET, 0, FS(0)}, { DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
{ DEFAULT_CHARSET, 0, FS(0)}, { DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
{ DEFAULT_CHARSET, 0, FS(0)}, { DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
{ DEFAULT_CHARSET, 0, FS(0)}, { DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
{ DEFAULT_CHARSET, 0, FS(0)}, { DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
{ DEFAULT_CHARSET, 0, FS(0)}, { DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
/* ANSI and OEM */ /* ANSI and OEM */
{ THAI_CHARSET, 874, FS(16)}, { THAI_CHARSET, 874, {{0,0,0,0},{FS_THAI,0}} },
{ SHIFTJIS_CHARSET, 932, FS(17)}, { SHIFTJIS_CHARSET, 932, {{0,0,0,0},{FS_JISJAPAN,0}} },
{ GB2312_CHARSET, 936, FS(18)}, { GB2312_CHARSET, 936, {{0,0,0,0},{FS_CHINESESIMP,0}} },
{ HANGEUL_CHARSET, 949, FS(19)}, { HANGEUL_CHARSET, 949, {{0,0,0,0},{FS_WANSUNG,0}} },
{ CHINESEBIG5_CHARSET, 950, FS(20)}, { CHINESEBIG5_CHARSET, 950, {{0,0,0,0},{FS_CHINESETRAD,0}} },
{ JOHAB_CHARSET, 1361, FS(21)}, { JOHAB_CHARSET, 1361, {{0,0,0,0},{FS_JOHAB,0}} },
/* reserved for alternate ANSI and OEM */ /* reserved for alternate ANSI and OEM */
{ DEFAULT_CHARSET, 0, FS(0)}, { DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
{ DEFAULT_CHARSET, 0, FS(0)}, { DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
{ DEFAULT_CHARSET, 0, FS(0)}, { DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
{ DEFAULT_CHARSET, 0, FS(0)}, { DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
{ DEFAULT_CHARSET, 0, FS(0)}, { DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
{ DEFAULT_CHARSET, 0, FS(0)}, { DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
{ DEFAULT_CHARSET, 0, FS(0)}, { DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
{ DEFAULT_CHARSET, 0, FS(0)}, { DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
/* reserved for system */ /* reserved for system */
{ DEFAULT_CHARSET, 0, FS(0)}, { DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
{ SYMBOL_CHARSET, CP_SYMBOL, FS(31)}, { SYMBOL_CHARSET, CP_SYMBOL, {{0,0,0,0},{FS_SYMBOL,0}} }
}; };
#define INITIAL_FAMILY_COUNT 64 #define INITIAL_FAMILY_COUNT 64

View file

@ -503,6 +503,7 @@ extern "C" {
#define FS_HEBREW 32 #define FS_HEBREW 32
#define FS_ARABIC 64 #define FS_ARABIC 64
#define FS_BALTIC 128 #define FS_BALTIC 128
#define FS_VIETNAMESE 256
#define FS_THAI 0x10000 #define FS_THAI 0x10000
#define FS_JISJAPAN 0x20000 #define FS_JISJAPAN 0x20000
#define FS_CHINESESIMP 0x40000 #define FS_CHINESESIMP 0x40000

View file

@ -390,6 +390,8 @@ typedef union
ULONG l; ULONG l;
} gxf_long; } gxf_long;
#define CFONT_REALIZATION 0x0080
typedef struct _CFONT typedef struct _CFONT
{ {
struct _CFONT *pcfNext; struct _CFONT *pcfNext;

View file

@ -96,9 +96,8 @@ ULONG FASTCALL ftGdiGetGlyphOutline(PDC,WCHAR,UINT,LPGLYPHMETRICS,ULONG,PVOID,LP
INT FASTCALL IntGetOutlineTextMetrics(PFONTGDI,UINT,OUTLINETEXTMETRICW *); INT FASTCALL IntGetOutlineTextMetrics(PFONTGDI,UINT,OUTLINETEXTMETRICW *);
BOOL FASTCALL ftGdiGetRasterizerCaps(LPRASTERIZER_STATUS); BOOL FASTCALL ftGdiGetRasterizerCaps(LPRASTERIZER_STATUS);
BOOL FASTCALL TextIntGetTextExtentPoint(PDC,PTEXTOBJ,LPCWSTR,int,int,LPINT,LPINT,LPSIZE); BOOL FASTCALL TextIntGetTextExtentPoint(PDC,PTEXTOBJ,LPCWSTR,int,int,LPINT,LPINT,LPSIZE);
DWORD FASTCALL IntGdiGetCharSet(HDC);
BOOL FASTCALL ftGdiGetTextMetricsW(HDC,PTMW_INTERNAL); BOOL FASTCALL ftGdiGetTextMetricsW(HDC,PTMW_INTERNAL);
DWORD FASTCALL ftGetFontLanguageInfo(PDC); DWORD FASTCALL IntGetFontLanguageInfo(PDC);
INT FASTCALL ftGdiGetTextCharsetInfo(PDC,PFONTSIGNATURE,DWORD); INT FASTCALL ftGdiGetTextCharsetInfo(PDC,PFONTSIGNATURE,DWORD);
DWORD FASTCALL ftGetFontUnicodeRanges(PFONTGDI, PGLYPHSET); DWORD FASTCALL ftGetFontUnicodeRanges(PFONTGDI, PGLYPHSET);
DWORD FASTCALL ftGdiGetFontData(PFONTGDI,DWORD,DWORD,PVOID,DWORD); DWORD FASTCALL ftGdiGetFontData(PFONTGDI,DWORD,DWORD,PVOID,DWORD);

View file

@ -849,6 +849,8 @@ IntGdiCreateDC(PUNICODE_STRING Driver,
NewDC->erclWindow.bottom = ((PGDIDEVICE)NewDC->pPDev)->GDIInfo.ulVertRes; NewDC->erclWindow.bottom = ((PGDIDEVICE)NewDC->pPDev)->GDIInfo.ulVertRes;
NewDC->DcLevel.flPath &= ~DCPATH_CLOCKWISE; // Default is CCW. NewDC->DcLevel.flPath &= ~DCPATH_CLOCKWISE; // Default is CCW.
nDc_Attr->iCS_CP = ftGdiGetTextCharsetInfo(NewDC,NULL,0);
DC_UnlockDc( NewDC ); DC_UnlockDc( NewDC );
hVisRgn = NtGdiCreateRectRgn(0, 0, ((PGDIDEVICE)NewDC->pPDev)->GDIInfo.ulHorzRes, hVisRgn = NtGdiCreateRectRgn(0, 0, ((PGDIDEVICE)NewDC->pPDev)->GDIInfo.ulHorzRes,
@ -877,7 +879,6 @@ IntGdiCreateDC(PUNICODE_STRING Driver,
NewDC->DC_Type = DC_TYPE_INFO; NewDC->DC_Type = DC_TYPE_INFO;
DC_UnlockDc( NewDC ); DC_UnlockDc( NewDC );
} }
nDc_Attr->iCS_CP = IntGdiGetCharSet(hNewDC);
return hNewDC; return hNewDC;
} }
@ -2413,7 +2414,7 @@ NtGdiGetDCDword(
case GdiGetEMFRestorDc: case GdiGetEMFRestorDc:
break; break;
case GdiGetFontLanguageInfo: case GdiGetFontLanguageInfo:
SafeResult = ftGetFontLanguageInfo(dc); SafeResult = IntGetFontLanguageInfo(dc);
break; break;
case GdiGetIsMemDc: case GdiGetIsMemDc:
SafeResult = dc->DC_Type; SafeResult = dc->DC_Type;

View file

@ -23,7 +23,6 @@ FontGetObject(PTEXTOBJ TFont, INT Count, PVOID Buffer)
switch (Count) switch (Count)
{ {
case sizeof(ENUMLOGFONTEXDVW): case sizeof(ENUMLOGFONTEXDVW):
RtlCopyMemory( (LPENUMLOGFONTEXDVW) Buffer, RtlCopyMemory( (LPENUMLOGFONTEXDVW) Buffer,
&TFont->logfont, &TFont->logfont,
@ -55,6 +54,58 @@ FontGetObject(PTEXTOBJ TFont, INT Count, PVOID Buffer)
return Count; return Count;
} }
DWORD
FASTCALL
IntGetFontLanguageInfo(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;
}
PTEXTOBJ PTEXTOBJ
FASTCALL FASTCALL
RealizeFontInit(HFONT hFont) RealizeFontInit(HFONT hFont)
@ -114,14 +165,14 @@ NtGdiAddFontResourceW(
Status = MmCopyFromCaller(SafeFileName.Buffer + 4, src, SafeFileName.MaximumLength - (4 * sizeof(WCHAR))); Status = MmCopyFromCaller(SafeFileName.Buffer + 4, src, SafeFileName.MaximumLength - (4 * sizeof(WCHAR)));
if(!NT_SUCCESS(Status)) if(!NT_SUCCESS(Status))
{ {
ExFreePool(SafeFileName.Buffer); ExFreePoolWithTag(SafeFileName.Buffer, TAG_STRING);
SetLastNtError(Status); SetLastNtError(Status);
return 0; return 0;
} }
Ret = IntGdiAddFontResource(&SafeFileName, (DWORD)fl); Ret = IntGdiAddFontResource(&SafeFileName, (DWORD)fl);
ExFreePool(SafeFileName.Buffer); ExFreePoolWithTag(SafeFileName.Buffer, TAG_STRING);
return Ret; return Ret;
} }
@ -223,8 +274,8 @@ NtGdiGetFontUnicodeRanges(
} }
FontGdi = ObjToGDI(TextObj->Font, FONT); FontGdi = ObjToGDI(TextObj->Font, FONT);
Size = ftGetFontUnicodeRanges( FontGdi, NULL); Size = ftGetFontUnicodeRanges( FontGdi, NULL);
if (Size && pgs) if (Size && pgs)
{ {
pgsSafe = ExAllocatePoolWithTag(PagedPool, Size, TAG_GDITEXT); pgsSafe = ExAllocatePoolWithTag(PagedPool, Size, TAG_GDITEXT);
@ -376,7 +427,7 @@ NtGdiGetOutlineTextMetricsInternalW (HDC hDC,
NTSTATUS Status; NTSTATUS Status;
dc = DC_LockDc(hDC); dc = DC_LockDc(hDC);
if (dc == NULL) if (!dc)
{ {
SetLastWin32Error(ERROR_INVALID_HANDLE); SetLastWin32Error(ERROR_INVALID_HANDLE);
return 0; return 0;
@ -386,7 +437,7 @@ NtGdiGetOutlineTextMetricsInternalW (HDC hDC,
hFont = Dc_Attr->hlfntNew; hFont = Dc_Attr->hlfntNew;
TextObj = RealizeFontInit(hFont); TextObj = RealizeFontInit(hFont);
DC_UnlockDc(dc); DC_UnlockDc(dc);
if (TextObj == NULL) if (!TextObj)
{ {
SetLastWin32Error(ERROR_INVALID_HANDLE); SetLastWin32Error(ERROR_INVALID_HANDLE);
return 0; return 0;
@ -401,7 +452,7 @@ NtGdiGetOutlineTextMetricsInternalW (HDC hDC,
return 0; return 0;
} }
potm = ExAllocatePoolWithTag(PagedPool, Size, TAG_GDITEXT); potm = ExAllocatePoolWithTag(PagedPool, Size, TAG_GDITEXT);
if (NULL == potm) if (!potm)
{ {
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY); SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
return 0; return 0;
@ -413,11 +464,11 @@ NtGdiGetOutlineTextMetricsInternalW (HDC hDC,
if (! NT_SUCCESS(Status)) if (! NT_SUCCESS(Status))
{ {
SetLastWin32Error(ERROR_INVALID_PARAMETER); SetLastWin32Error(ERROR_INVALID_PARAMETER);
ExFreePool(potm); ExFreePoolWithTag(potm,TAG_GDITEXT);
return 0; return 0;
} }
} }
ExFreePool(potm); ExFreePoolWithTag(potm,TAG_GDITEXT);
return Size; return Size;
} }
@ -486,7 +537,7 @@ NtGdiGetFontResourceInfoInternalW(
{ {
SetLastNtError(Status); SetLastNtError(Status);
/* Free the string buffer for the safe filename */ /* Free the string buffer for the safe filename */
ExFreePool(SafeFileNames.Buffer); ExFreePoolWithTag(SafeFileNames.Buffer,TAG('R','T','S','U'));
return FALSE; return FALSE;
} }
@ -517,11 +568,79 @@ NtGdiGetFontResourceInfoInternalW(
} }
/* Free the string for the safe filenames */ /* Free the string for the safe filenames */
ExFreePool(SafeFileNames.Buffer); ExFreePoolWithTag(SafeFileNames.Buffer,TAG('R','T','S','U'));
return bRet; return bRet;
} }
/*
* @unimplemented
*/
BOOL
APIENTRY
NtGdiGetRealizationInfo(
IN HDC hdc,
OUT PREALIZATION_INFO pri,
IN HFONT hf)
{
PDC pDc;
PTEXTOBJ pTextObj;
PFONTGDI pFontGdi;
BOOL Ret = FALSE;
INT i = 0;
REALIZATION_INFO ri;
pDc = DC_LockDc(hdc);
if (!pDc)
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
return 0;
}
pTextObj = RealizeFontInit(hf);
pFontGdi = ObjToGDI(pTextObj->Font, FONT);
TEXTOBJ_UnlockText(pTextObj);
DC_UnlockDc(pDc);
Ret = ftGdiRealizationInfo(pFontGdi, &ri);
if (Ret)
{
if (pri)
{
NTSTATUS Status = STATUS_SUCCESS;
_SEH_TRY
{
ProbeForWrite(pri, sizeof(REALIZATION_INFO), 1);
RtlCopyMemory(pri, &ri, sizeof(REALIZATION_INFO));
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END
if(!NT_SUCCESS(Status))
{
SetLastNtError(Status);
return FALSE;
}
}
do
{
if (GdiHandleTable->cfPublic[i].hf == hf)
{
GdiHandleTable->cfPublic[i].iTechnology = ri.iTechnology;
GdiHandleTable->cfPublic[i].iUniq = ri.iUniq;
GdiHandleTable->cfPublic[i].dwUnknown = ri.dwUnknown;
GdiHandleTable->cfPublic[i].dwCFCount = GdiHandleTable->dwCFCount;
GdiHandleTable->cfPublic[i].fl |= CFONT_REALIZATION;
}
i++;
}
while ( i < GDI_CFONT_MAX );
}
return Ret;
}
HFONT HFONT
STDCALL STDCALL
NtGdiHfontCreate( NtGdiHfontCreate(

View file

@ -50,6 +50,12 @@
#define NDEBUG #define NDEBUG
#include <debug.h> #include <debug.h>
#ifndef FT_MAKE_TAG
#define FT_MAKE_TAG( ch0, ch1, ch2, ch3 ) \
( ((DWORD)(BYTE)(ch0) << 24) | ((DWORD)(BYTE)(ch1) << 16) | \
((DWORD)(BYTE)(ch2) << 8) | (DWORD)(BYTE)(ch3) )
#endif
FT_Library library; FT_Library library;
typedef struct _FONT_ENTRY { typedef struct _FONT_ENTRY {
@ -107,7 +113,6 @@ static PWCHAR ElfScripts[32] = { /* these are in the order of the fsCsb[0] bits
* For TranslateCharsetInfo * For TranslateCharsetInfo
*/ */
#define CP_SYMBOL 42 #define CP_SYMBOL 42
#define FS_VIETNAMESE 0x00000100L
#define MAXTCIINDEX 32 #define MAXTCIINDEX 32
static const CHARSETINFO FontTci[MAXTCIINDEX] = { static const CHARSETINFO FontTci[MAXTCIINDEX] = {
/* ANSI */ /* ANSI */
@ -381,7 +386,7 @@ IntGdiAddFontResource(PUNICODE_STRING FileName, DWORD Characteristics)
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY); SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
return 0; return 0;
} }
memcpy(FontGDI->Filename, FileName->Buffer, FileName->Length); RtlCopyMemory(FontGDI->Filename, FileName->Buffer, FileName->Length);
FontGDI->Filename[FileName->Length / sizeof(WCHAR)] = L'\0'; FontGDI->Filename[FileName->Length / sizeof(WCHAR)] = L'\0';
FontGDI->face = Face; FontGDI->face = Face;
@ -486,7 +491,7 @@ TextIntCreateFontIndirect(CONST LPLOGFONTW lf, HFONT *NewFont)
} }
*NewFont = TextObj->BaseObject.hHmgr; *NewFont = TextObj->BaseObject.hHmgr;
memcpy(&TextObj->logfont.elfEnumLogfontEx.elfLogFont, lf, sizeof(LOGFONTW)); RtlCopyMemory(&TextObj->logfont.elfEnumLogfontEx.elfLogFont, lf, sizeof(LOGFONTW));
if (lf->lfEscapement != lf->lfOrientation) if (lf->lfEscapement != lf->lfOrientation)
{ {
/* this should really depend on whether GM_ADVANCED is set */ /* this should really depend on whether GM_ADVANCED is set */
@ -547,7 +552,7 @@ IntTranslateCharsetInfo(PDWORD Src, /* [in]
return FALSE; return FALSE;
} }
if (MAXTCIINDEX <= Index || DEFAULT_CHARSET == FontTci[Index].ciCharset) if (Index >= MAXTCIINDEX || DEFAULT_CHARSET == FontTci[Index].ciCharset)
{ {
return FALSE; return FALSE;
} }
@ -796,7 +801,7 @@ IntGetOutlineTextMetrics(PFONTGDI FontGDI,
RtlCopyMemory(&Otm->otmTextMetrics, &FontGDI->TextMetric, sizeof(TEXTMETRICW)); RtlCopyMemory(&Otm->otmTextMetrics, &FontGDI->TextMetric, sizeof(TEXTMETRICW));
Otm->otmFiller = 0; Otm->otmFiller = 0;
memcpy(&Otm->otmPanoseNumber, pOS2->panose, PANOSE_COUNT); RtlCopyMemory(&Otm->otmPanoseNumber, pOS2->panose, PANOSE_COUNT);
Otm->otmfsSelection = pOS2->fsSelection; Otm->otmfsSelection = pOS2->fsSelection;
Otm->otmfsType = pOS2->fsType; Otm->otmfsType = pOS2->fsType;
Otm->otmsCharSlopeRise = pHori->caret_Slope_Rise; Otm->otmsCharSlopeRise = pHori->caret_Slope_Rise;
@ -939,18 +944,18 @@ FontFamilyFillInfo(PFONTFAMILYINFO Info, PCWSTR FaceName, PFONTGDI FontGDI)
UNICODE_STRING StyleW; UNICODE_STRING StyleW;
TT_OS2 *pOS2; TT_OS2 *pOS2;
FONTSIGNATURE fs; FONTSIGNATURE fs;
DWORD fs_fsCsb0;
CHARSETINFO CharSetInfo; CHARSETINFO CharSetInfo;
unsigned i, Size; unsigned i, Size;
OUTLINETEXTMETRICW *Otm; OUTLINETEXTMETRICW *Otm;
LOGFONTW *Lf; LOGFONTW *Lf;
TEXTMETRICW *TM; TEXTMETRICW *TM;
NEWTEXTMETRICW *Ntm; NEWTEXTMETRICW *Ntm;
DWORD fs0;
RtlZeroMemory(Info, sizeof(FONTFAMILYINFO)); RtlZeroMemory(Info, sizeof(FONTFAMILYINFO));
Size = IntGetOutlineTextMetrics(FontGDI, 0, NULL); Size = IntGetOutlineTextMetrics(FontGDI, 0, NULL);
Otm = ExAllocatePoolWithTag(PagedPool, Size, TAG_GDITEXT); Otm = ExAllocatePoolWithTag(PagedPool, Size, TAG_GDITEXT);
if (NULL == Otm) if (!Otm)
{ {
return; return;
} }
@ -991,14 +996,10 @@ FontFamilyFillInfo(PFONTFAMILYINFO Info, PCWSTR FaceName, PFONTGDI FontGDI)
Ntm->tmPitchAndFamily = TM->tmPitchAndFamily; Ntm->tmPitchAndFamily = TM->tmPitchAndFamily;
Ntm->tmCharSet = TM->tmCharSet; Ntm->tmCharSet = TM->tmCharSet;
Ntm->ntmFlags = TM->tmItalic ? NTM_ITALIC : 0; Ntm->ntmFlags = TM->tmItalic ? NTM_ITALIC : 0;
if (550 < TM->tmWeight)
{ if (550 < TM->tmWeight) Ntm->ntmFlags |= NTM_BOLD;
Ntm->ntmFlags |= NTM_BOLD;
} if (0 == Ntm->ntmFlags) Ntm->ntmFlags = NTM_REGULAR;
if (0 == Ntm->ntmFlags)
{
Ntm->ntmFlags = NTM_REGULAR;
}
Ntm->ntmSizeEM = Otm->otmEMSquare; Ntm->ntmSizeEM = Otm->otmEMSquare;
Ntm->ntmCellHeight = 0; Ntm->ntmCellHeight = 0;
@ -1006,10 +1007,9 @@ FontFamilyFillInfo(PFONTFAMILYINFO Info, PCWSTR FaceName, PFONTGDI FontGDI)
Info->FontType = (0 != (TM->tmPitchAndFamily & TMPF_TRUETYPE) Info->FontType = (0 != (TM->tmPitchAndFamily & TMPF_TRUETYPE)
? TRUETYPE_FONTTYPE : 0); ? TRUETYPE_FONTTYPE : 0);
if (0 == (TM->tmPitchAndFamily & TMPF_VECTOR)) if (0 == (TM->tmPitchAndFamily & TMPF_VECTOR))
{
Info->FontType |= RASTER_FONTTYPE; Info->FontType |= RASTER_FONTTYPE;
}
ExFreePool(Otm); ExFreePool(Otm);
@ -1027,67 +1027,54 @@ FontFamilyFillInfo(PFONTFAMILYINFO Info, PCWSTR FaceName, PFONTGDI FontGDI)
IntUnLockFreeType; IntUnLockFreeType;
if (NULL != pOS2) if (NULL != pOS2)
{ {
Info->NewTextMetricEx.ntmFontSig.fsCsb[0] = pOS2->ulCodePageRange1; fs.fsCsb[0] = pOS2->ulCodePageRange1;
Info->NewTextMetricEx.ntmFontSig.fsCsb[1] = pOS2->ulCodePageRange2; fs.fsCsb[1] = pOS2->ulCodePageRange2;
Info->NewTextMetricEx.ntmFontSig.fsUsb[0] = pOS2->ulUnicodeRange1; fs.fsUsb[0] = pOS2->ulUnicodeRange1;
Info->NewTextMetricEx.ntmFontSig.fsUsb[1] = pOS2->ulUnicodeRange2; fs.fsUsb[1] = pOS2->ulUnicodeRange2;
Info->NewTextMetricEx.ntmFontSig.fsUsb[2] = pOS2->ulUnicodeRange3; fs.fsUsb[2] = pOS2->ulUnicodeRange3;
Info->NewTextMetricEx.ntmFontSig.fsUsb[3] = pOS2->ulUnicodeRange4; fs.fsUsb[3] = pOS2->ulUnicodeRange4;
fs_fsCsb0 = pOS2->ulCodePageRange1;
if (0 == pOS2->version) if (0 == pOS2->version)
{ {
FT_UInt Dummy; FT_UInt Dummy;
if (FT_Get_First_Char(FontGDI->face, &Dummy) < 0x100) if (FT_Get_First_Char(FontGDI->face, &Dummy) < 0x100)
{ fs.fsCsb[0] |= FS_LATIN1;
fs_fsCsb0 |= 1;
}
else else
{ fs.fsCsb[0] |= FS_SYMBOL;
fs_fsCsb0 |= 1L << 31;
} }
} if (fs.fsCsb[0] == 0)
if (0 == fs_fsCsb0)
{ /* let's see if we can find any interesting cmaps */ { /* let's see if we can find any interesting cmaps */
for (i = 0; i < FontGDI->face->num_charmaps; i++) for (i = 0; i < FontGDI->face->num_charmaps; i++)
{ {
switch (FontGDI->face->charmaps[i]->encoding) switch (FontGDI->face->charmaps[i]->encoding)
{ {
case ft_encoding_unicode: case FT_ENCODING_UNICODE:
case ft_encoding_apple_roman: case FT_ENCODING_APPLE_ROMAN:
fs_fsCsb0 |= 1; fs.fsCsb[0] |= FS_LATIN1;
break; break;
case ft_encoding_symbol: case FT_ENCODING_MS_SYMBOL:
fs_fsCsb0 |= 1L << 31; fs.fsCsb[0] |= FS_SYMBOL;
break; break;
default: default:
break; break;
} }
} }
} }
for (i = 0; i < MAXTCIINDEX; i++)
for(i = 0; i < 32; i++)
{ {
if (0 != (fs_fsCsb0 & (1L << i))) fs0 = 1L << i;
if (fs.fsCsb[0] & fs0)
{ {
fs.fsCsb[0] = 1L << i; if (!IntTranslateCharsetInfo(&fs0, &CharSetInfo, TCI_SRCFONTSIG))
fs.fsCsb[1] = 0;
if (! IntTranslateCharsetInfo(fs.fsCsb, &CharSetInfo, TCI_SRCFONTSIG))
{ {
CharSetInfo.ciCharset = DEFAULT_CHARSET; CharSetInfo.ciCharset = DEFAULT_CHARSET;
} }
if (31 == i)
{
CharSetInfo.ciCharset = SYMBOL_CHARSET;
}
if (DEFAULT_CHARSET != CharSetInfo.ciCharset) if (DEFAULT_CHARSET != CharSetInfo.ciCharset)
{ {
Info->EnumLogFontEx.elfLogFont.lfCharSet = CharSetInfo.ciCharset; Info->EnumLogFontEx.elfLogFont.lfCharSet = CharSetInfo.ciCharset;
if (NULL != ElfScripts[i]) if (NULL != ElfScripts[i])
{
wcscpy(Info->EnumLogFontEx.elfScript, ElfScripts[i]); wcscpy(Info->EnumLogFontEx.elfScript, ElfScripts[i]);
}
else else
{ {
DPRINT1("Unknown elfscript for bit %d\n", i); DPRINT1("Unknown elfscript for bit %d\n", i);
@ -1095,6 +1082,7 @@ FontFamilyFillInfo(PFONTFAMILYINFO Info, PCWSTR FaceName, PFONTGDI FontGDI)
} }
} }
} }
Info->NewTextMetricEx.ntmFontSig = fs;
} }
} }
@ -2203,35 +2191,6 @@ TextIntGetTextExtentPoint(PDC dc,
return TRUE; return TRUE;
} }
DWORD
FASTCALL
IntGdiGetCharSet(HDC hDC)
{
UINT cp = 0;
CHARSETINFO csi;
DWORD charset = NtGdiGetTextCharsetInfo(hDC,NULL,0);
if (IntTranslateCharsetInfo(&charset, &csi, TCI_SRCCHARSET))
cp = csi.ciACP;
else
{
switch(charset)
{
case ANSI_CHARSET:
break;
case OEM_CHARSET:
cp = 1;
break;
case DEFAULT_CHARSET:
cp = 0;
break;
default:
DPRINT1("Can't find codepage for charset %d\n", charset);
break;
}
}
DPRINT("charset %d => cp %d\n", charset, LOWORD(cp));
return (MAKELONG(cp, charset));
}
INT INT
FASTCALL FASTCALL
@ -2249,15 +2208,16 @@ ftGdiGetTextCharsetInfo(
TT_OS2 *pOS2; TT_OS2 *pOS2;
FT_Face Face; FT_Face Face;
CHARSETINFO csi; CHARSETINFO csi;
DWORD charset; DWORD cp;
DWORD fs0; DWORD fs0;
USHORT usACP, usOEM;
Dc_Attr = Dc->pDc_Attr; Dc_Attr = Dc->pDc_Attr;
if(!Dc_Attr) Dc_Attr = &Dc->Dc_Attr; if(!Dc_Attr) Dc_Attr = &Dc->Dc_Attr;
hFont = Dc_Attr->hlfntNew; hFont = Dc_Attr->hlfntNew;
TextObj = RealizeFontInit(hFont); TextObj = RealizeFontInit(hFont);
if ( TextObj == NULL) if (!TextObj)
{ {
SetLastWin32Error(ERROR_INVALID_HANDLE); SetLastWin32Error(ERROR_INVALID_HANDLE);
return Ret; return Ret;
@ -2312,7 +2272,10 @@ ftGdiGetTextCharsetInfo(
RtlCopyMemory(lpSig, &fs, sizeof(FONTSIGNATURE)); RtlCopyMemory(lpSig, &fs, sizeof(FONTSIGNATURE));
} }
if (IntTranslateCharsetInfo(&charset, &csi, TCI_SRCCODEPAGE)) RtlGetDefaultCodePage(&usACP, &usOEM);
cp = usACP;
if (IntTranslateCharsetInfo(&cp, &csi, TCI_SRCCODEPAGE))
if (csi.fs.fsCsb[0] & fs.fsCsb[0]) if (csi.fs.fsCsb[0] & fs.fsCsb[0])
{ {
DPRINT("Hit 1\n"); DPRINT("Hit 1\n");
@ -2333,12 +2296,12 @@ ftGdiGetTextCharsetInfo(
goto Exit; goto Exit;
} }
else else
DPRINT("TCI failing on %x\n", fs0); DPRINT1("TCI failing on %x\n", fs0);
} }
} }
Exit: Exit:
DPRINT("CharSet %d CodePage %d\n",Ret, csi.ciACP); DPRINT("CharSet %d CodePage %d\n",csi.ciCharset, csi.ciACP);
return Ret; return (MAKELONG(csi.ciACP, csi.ciCharset));
} }
@ -2409,59 +2372,6 @@ ftGetFontUnicodeRanges(PFONTGDI Font, PGLYPHSET glyphset)
} }
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 BOOL
FASTCALL FASTCALL
ftGdiGetTextMetricsW( ftGdiGetTextMetricsW(
@ -2749,6 +2659,7 @@ FASTCALL
IntFontType(PFONTGDI Font) IntFontType(PFONTGDI Font)
{ {
PS_FontInfoRec psfInfo; PS_FontInfoRec psfInfo;
FT_ULong tmp_size = 0;
if (FT_HAS_MULTIPLE_MASTERS(Font->face)) if (FT_HAS_MULTIPLE_MASTERS(Font->face))
Font->FontObj.flFontType |= FO_MULTIPLEMASTER; Font->FontObj.flFontType |= FO_MULTIPLEMASTER;
@ -2766,6 +2677,11 @@ IntFontType(PFONTGDI Font)
{ {
Font->FontObj.flFontType |= FO_POSTSCRIPT; Font->FontObj.flFontType |= FO_POSTSCRIPT;
} }
/* check for the presence of the 'CFF ' table to check if the font is Type1 */
if (!FT_Load_Sfnt_Table(Font->face, FT_MAKE_TAG('C','F','F',' '), 0, NULL, &tmp_size))
{
Font->FontObj.flFontType |= (FO_CFF|FO_POSTSCRIPT);
}
} }
NTSTATUS NTSTATUS
@ -2979,14 +2895,14 @@ IntGdiGetFontResourceInfo(
case 1: /* Copy the full font name */ case 1: /* Copy the full font name */
Size = wcslen(Info.EnumLogFontEx.elfFullName) + 1; Size = wcslen(Info.EnumLogFontEx.elfFullName) + 1;
Size = min(Size , LF_FULLFACESIZE) * sizeof(WCHAR); Size = min(Size , LF_FULLFACESIZE) * sizeof(WCHAR);
memcpy(pBuffer, Info.EnumLogFontEx.elfFullName, Size); RtlCopyMemory(pBuffer, Info.EnumLogFontEx.elfFullName, Size);
// FIXME: Do we have to zeroterminate? // FIXME: Do we have to zeroterminate?
*pdwBytes = Size; *pdwBytes = Size;
break; break;
case 2: /* Copy a LOGFONTW structure */ case 2: /* Copy a LOGFONTW structure */
Info.EnumLogFontEx.elfLogFont.lfWidth = 0; Info.EnumLogFontEx.elfLogFont.lfWidth = 0;
memcpy(pBuffer, &Info.EnumLogFontEx.elfLogFont, sizeof(LOGFONTW)); RtlCopyMemory(pBuffer, &Info.EnumLogFontEx.elfLogFont, sizeof(LOGFONTW));
*pdwBytes = sizeof(LOGFONTW); *pdwBytes = sizeof(LOGFONTW);
break; break;

View file

@ -21,7 +21,7 @@ NtGdiGetCharSet(HDC hDC)
{ {
PDC Dc; PDC Dc;
PDC_ATTR Dc_Attr; PDC_ATTR Dc_Attr;
DWORD cscp = IntGdiGetCharSet(hDC); DWORD cscp;
// If here, update everything! // If here, update everything!
Dc = DC_LockDc(hDC); Dc = DC_LockDc(hDC);
if (!Dc) if (!Dc)
@ -29,6 +29,7 @@ NtGdiGetCharSet(HDC hDC)
SetLastWin32Error(ERROR_INVALID_HANDLE); SetLastWin32Error(ERROR_INVALID_HANDLE);
return 0; return 0;
} }
cscp = ftGdiGetTextCharsetInfo(Dc,NULL,0);
Dc_Attr = Dc->pDc_Attr; Dc_Attr = Dc->pDc_Attr;
if (!Dc_Attr) Dc_Attr = &Dc->Dc_Attr; if (!Dc_Attr) Dc_Attr = &Dc->Dc_Attr;
Dc_Attr->iCS_CP = cscp; Dc_Attr->iCS_CP = cscp;
@ -96,10 +97,13 @@ NtGdiGetTextCharsetInfo(
if (!lpSig) pfsSafe = NULL; if (!lpSig) pfsSafe = NULL;
Ret = ftGdiGetTextCharsetInfo( Dc, pfsSafe, dwFlags); Ret = HIWORD(ftGdiGetTextCharsetInfo( Dc, pfsSafe, dwFlags));
if (lpSig) if (lpSig)
{ {
if (Ret == DEFAULT_CHARSET)
RtlZeroMemory(pfsSafe, sizeof(FONTSIGNATURE));
_SEH_TRY _SEH_TRY
{ {
ProbeForWrite( lpSig, ProbeForWrite( lpSig,

View file

@ -2125,20 +2125,6 @@ NtGdiGetMonitorID(
*/ */
BOOL BOOL
APIENTRY APIENTRY
NtGdiGetRealizationInfo(
IN HDC hdc,
OUT PREALIZATION_INFO pri,
IN HFONT hf)
{
UNIMPLEMENTED;
return FALSE;
}
/*
* @unimplemented
*/
BOOL
APIENTRY
NtGdiDrawStream( NtGdiDrawStream(
IN HDC hdcDst, IN HDC hdcDst,
IN ULONG cjIn, IN ULONG cjIn,