mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 17:34:57 +00:00
[WIN32SS] Initial fixes for localized font enumeration. Patch by Katayama Hirofumi MZ. CORE-10876
svn path=/trunk/; revision=74312
This commit is contained in:
parent
05ad12aa18
commit
8b3bb3c44c
1 changed files with 102 additions and 67 deletions
|
@ -48,6 +48,7 @@ extern const MATRIX gmxWorldToPageDefault;
|
||||||
#define gmxWorldToDeviceDefault gmxWorldToPageDefault
|
#define gmxWorldToDeviceDefault gmxWorldToPageDefault
|
||||||
|
|
||||||
FT_Library library;
|
FT_Library library;
|
||||||
|
static const WORD gusEnglishUS = MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US);
|
||||||
|
|
||||||
/* special font names */
|
/* special font names */
|
||||||
static const UNICODE_STRING MarlettW = RTL_CONSTANT_STRING(L"Marlett");
|
static const UNICODE_STRING MarlettW = RTL_CONSTANT_STRING(L"Marlett");
|
||||||
|
@ -2041,30 +2042,40 @@ SwapEndian(LPVOID pvData, DWORD Size)
|
||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS
|
static NTSTATUS
|
||||||
IntGetFontLocalizedName(PUNICODE_STRING pLocalNameW, FT_Face Face)
|
IntGetFontLocalizedName(PUNICODE_STRING pNameW, FT_Face Face,
|
||||||
|
FT_UShort NameID, FT_UShort LangID)
|
||||||
{
|
{
|
||||||
FT_SfntName Name;
|
FT_SfntName Name;
|
||||||
INT i, Count;
|
INT i, Count;
|
||||||
WCHAR Buf[LF_FACESIZE];
|
WCHAR Buf[LF_FULLFACESIZE];
|
||||||
|
FT_Error Error;
|
||||||
NTSTATUS Status = STATUS_NOT_FOUND;
|
NTSTATUS Status = STATUS_NOT_FOUND;
|
||||||
|
ANSI_STRING AnsiName;
|
||||||
|
|
||||||
RtlInitUnicodeString(pLocalNameW, NULL);
|
RtlInitUnicodeString(pNameW, NULL);
|
||||||
|
|
||||||
Count = FT_Get_Sfnt_Name_Count(Face);
|
Count = FT_Get_Sfnt_Name_Count(Face);
|
||||||
for (i = 0; i < Count; ++i)
|
for (i = 0; i < Count; ++i)
|
||||||
{
|
{
|
||||||
FT_Get_Sfnt_Name(Face, i, &Name);
|
Error = FT_Get_Sfnt_Name(Face, i, &Name);
|
||||||
|
if (Error)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (Name.platform_id != TT_PLATFORM_MICROSOFT ||
|
if (Name.platform_id != TT_PLATFORM_MICROSOFT ||
|
||||||
Name.encoding_id != TT_MS_ID_UNICODE_CS)
|
Name.encoding_id != TT_MS_ID_UNICODE_CS)
|
||||||
{
|
{
|
||||||
continue; /* not Microsoft Unicode name */
|
continue; /* not Microsoft Unicode name */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Name.name_id != TT_NAME_ID_FONT_FAMILY ||
|
if (Name.name_id != NameID || Name.language_id != LangID)
|
||||||
Name.string == NULL || Name.string_len == 0 ||
|
{
|
||||||
|
continue; /* mismatched */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Name.string == NULL || Name.string_len == 0 ||
|
||||||
(Name.string[0] == 0 && Name.string[1] == 0))
|
(Name.string[0] == 0 && Name.string[1] == 0))
|
||||||
{
|
{
|
||||||
continue; /* not family name */
|
continue; /* invalid string */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sizeof(Buf) < Name.string_len + sizeof(UNICODE_NULL))
|
if (sizeof(Buf) < Name.string_len + sizeof(UNICODE_NULL))
|
||||||
|
@ -2078,14 +2089,24 @@ IntGetFontLocalizedName(PUNICODE_STRING pLocalNameW, FT_Face Face)
|
||||||
|
|
||||||
/* Convert UTF-16 big endian to little endian */
|
/* Convert UTF-16 big endian to little endian */
|
||||||
SwapEndian(Buf, Name.string_len);
|
SwapEndian(Buf, Name.string_len);
|
||||||
#if 0
|
|
||||||
DPRINT("IntGetFontLocalizedName: %S (%d)\n", Buf, Name.string_len);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Status = RtlCreateUnicodeString(pLocalNameW, Buf);
|
Status = RtlCreateUnicodeString(pNameW, Buf);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Status == STATUS_NOT_FOUND)
|
||||||
|
{
|
||||||
|
if (LangID != gusEnglishUS)
|
||||||
|
{
|
||||||
|
Status = IntGetFontLocalizedName(pNameW, Face, NameID, gusEnglishUS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (Status == STATUS_NOT_FOUND)
|
||||||
|
{
|
||||||
|
RtlInitAnsiString(&AnsiName, Face->family_name);
|
||||||
|
Status = RtlAnsiStringToUnicodeString(pNameW, &AnsiName, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2167,30 +2188,10 @@ FontFamilyFillInfo(PFONTFAMILYINFO Info, PCWSTR FaceName, PFONTGDI FontGDI)
|
||||||
|
|
||||||
ExFreePoolWithTag(Otm, GDITAG_TEXT);
|
ExFreePoolWithTag(Otm, GDITAG_TEXT);
|
||||||
|
|
||||||
/* try the localized name */
|
/* face name */
|
||||||
status = STATUS_UNSUCCESSFUL;
|
/* TODO: full name */
|
||||||
if (CharSetFromLangID(gusLanguageID) == FontGDI->CharSet)
|
if (FaceName)
|
||||||
{
|
{
|
||||||
/* get localized name */
|
|
||||||
UNICODE_STRING LocalNameW;
|
|
||||||
status = IntGetFontLocalizedName(&LocalNameW, Face);
|
|
||||||
if (NT_SUCCESS(status))
|
|
||||||
{
|
|
||||||
/* store it */
|
|
||||||
RtlStringCbCopyW(Info->EnumLogFontEx.elfLogFont.lfFaceName,
|
|
||||||
sizeof(Info->EnumLogFontEx.elfLogFont.lfFaceName),
|
|
||||||
LocalNameW.Buffer);
|
|
||||||
RtlStringCbCopyW(Info->EnumLogFontEx.elfFullName,
|
|
||||||
sizeof(Info->EnumLogFontEx.elfFullName),
|
|
||||||
LocalNameW.Buffer);
|
|
||||||
}
|
|
||||||
RtlFreeUnicodeString(&LocalNameW);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if localized name was unavailable */
|
|
||||||
if (!NT_SUCCESS(status))
|
|
||||||
{
|
|
||||||
/* store English name */
|
|
||||||
RtlStringCbCopyW(Info->EnumLogFontEx.elfLogFont.lfFaceName,
|
RtlStringCbCopyW(Info->EnumLogFontEx.elfLogFont.lfFaceName,
|
||||||
sizeof(Info->EnumLogFontEx.elfLogFont.lfFaceName),
|
sizeof(Info->EnumLogFontEx.elfLogFont.lfFaceName),
|
||||||
FaceName);
|
FaceName);
|
||||||
|
@ -2198,6 +2199,23 @@ FontFamilyFillInfo(PFONTFAMILYINFO Info, PCWSTR FaceName, PFONTGDI FontGDI)
|
||||||
sizeof(Info->EnumLogFontEx.elfFullName),
|
sizeof(Info->EnumLogFontEx.elfFullName),
|
||||||
FaceName);
|
FaceName);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UNICODE_STRING NameW;
|
||||||
|
status = IntGetFontLocalizedName(&NameW, Face, TT_NAME_ID_FONT_FAMILY,
|
||||||
|
gusLanguageID);
|
||||||
|
if (NT_SUCCESS(status))
|
||||||
|
{
|
||||||
|
/* store it */
|
||||||
|
RtlStringCbCopyW(Info->EnumLogFontEx.elfLogFont.lfFaceName,
|
||||||
|
sizeof(Info->EnumLogFontEx.elfLogFont.lfFaceName),
|
||||||
|
NameW.Buffer);
|
||||||
|
RtlStringCbCopyW(Info->EnumLogFontEx.elfFullName,
|
||||||
|
sizeof(Info->EnumLogFontEx.elfFullName),
|
||||||
|
NameW.Buffer);
|
||||||
|
RtlFreeUnicodeString(&NameW);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
RtlInitAnsiString(&StyleA, Face->style_name);
|
RtlInitAnsiString(&StyleA, Face->style_name);
|
||||||
StyleW.Buffer = Info->EnumLogFontEx.elfStyle;
|
StyleW.Buffer = Info->EnumLogFontEx.elfStyle;
|
||||||
|
@ -2207,19 +2225,9 @@ FontFamilyFillInfo(PFONTFAMILYINFO Info, PCWSTR FaceName, PFONTGDI FontGDI)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (StyleW.Length)
|
|
||||||
{
|
|
||||||
if (wcslen(Info->EnumLogFontEx.elfFullName) +
|
|
||||||
StyleW.Length / sizeof(WCHAR) + 1 <=
|
|
||||||
sizeof(Info->EnumLogFontEx.elfFullName))
|
|
||||||
{
|
|
||||||
wcscat(Info->EnumLogFontEx.elfFullName, L" ");
|
|
||||||
wcscat(Info->EnumLogFontEx.elfFullName, StyleW.Buffer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Info->EnumLogFontEx.elfLogFont.lfCharSet = DEFAULT_CHARSET;
|
Info->EnumLogFontEx.elfLogFont.lfCharSet = DEFAULT_CHARSET;
|
||||||
Info->EnumLogFontEx.elfScript[0] = L'\0';
|
Info->EnumLogFontEx.elfScript[0] = UNICODE_NULL;
|
||||||
|
|
||||||
IntLockFreeType;
|
IntLockFreeType;
|
||||||
pOS2 = FT_Get_Sfnt_Table(Face, ft_sfnt_os2);
|
pOS2 = FT_Get_Sfnt_Table(Face, ft_sfnt_os2);
|
||||||
|
|
||||||
|
@ -3917,6 +3925,7 @@ GetFontPenalty(LOGFONTW * LogFont,
|
||||||
LONG Long;
|
LONG Long;
|
||||||
BOOL fFixedSys = FALSE, fNeedScaling = FALSE;
|
BOOL fFixedSys = FALSE, fNeedScaling = FALSE;
|
||||||
const BYTE UserCharSet = CharSetFromLangID(gusLanguageID);
|
const BYTE UserCharSet = CharSetFromLangID(gusLanguageID);
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
/* FIXME: Aspect Penalty 30 */
|
/* FIXME: Aspect Penalty 30 */
|
||||||
/* FIXME: IntSizeSynth Penalty 20 */
|
/* FIXME: IntSizeSynth Penalty 20 */
|
||||||
|
@ -4052,32 +4061,58 @@ GetFontPenalty(LOGFONTW * LogFont,
|
||||||
|
|
||||||
if (RequestedNameW->Buffer[0])
|
if (RequestedNameW->Buffer[0])
|
||||||
{
|
{
|
||||||
if (RtlEqualUnicodeString(RequestedNameW, FullFaceNameW, TRUE))
|
BOOL Found = FALSE;
|
||||||
|
FT_Face Face = FontGDI->SharedFace->Face;
|
||||||
|
|
||||||
|
/* localized family name */
|
||||||
|
if (!Found)
|
||||||
{
|
{
|
||||||
/* matched with full face name */
|
Status = IntGetFontLocalizedName(ActualNameW, Face, TT_NAME_ID_FONT_FAMILY,
|
||||||
}
|
gusLanguageID);
|
||||||
else if (RtlEqualUnicodeString(RequestedNameW, ActualNameW, TRUE))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
|
||||||
/* matched with actual name */
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* try the localized name */
|
|
||||||
UNICODE_STRING LocalNameW;
|
|
||||||
FT_Face Face = FontGDI->SharedFace->Face;
|
|
||||||
IntGetFontLocalizedName(&LocalNameW, Face);
|
|
||||||
if (RtlEqualUnicodeString(RequestedNameW, &LocalNameW, TRUE))
|
|
||||||
{
|
{
|
||||||
/* matched with localizied name */
|
Found = RtlEqualUnicodeString(RequestedNameW, ActualNameW, TRUE);
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
|
/* localized full name */
|
||||||
|
if (!Found)
|
||||||
|
{
|
||||||
|
Status = IntGetFontLocalizedName(ActualNameW, Face, TT_NAME_ID_FULL_NAME,
|
||||||
|
gusLanguageID);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
/* FaceName Penalty 10000 */
|
Found = RtlEqualUnicodeString(RequestedNameW, ActualNameW, TRUE);
|
||||||
/* Requested a face name, but the candidate's face name
|
|
||||||
does not match. */
|
|
||||||
Penalty += 10000;
|
|
||||||
}
|
}
|
||||||
RtlFreeUnicodeString(&LocalNameW);
|
}
|
||||||
|
if (gusLanguageID != gusEnglishUS)
|
||||||
|
{
|
||||||
|
/* English family name */
|
||||||
|
if (!Found)
|
||||||
|
{
|
||||||
|
Status = IntGetFontLocalizedName(ActualNameW, Face, TT_NAME_ID_FONT_FAMILY,
|
||||||
|
gusEnglishUS);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
Found = RtlEqualUnicodeString(RequestedNameW, ActualNameW, TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* English full name */
|
||||||
|
if (!Found)
|
||||||
|
{
|
||||||
|
Status = IntGetFontLocalizedName(ActualNameW, Face, TT_NAME_ID_FULL_NAME,
|
||||||
|
gusEnglishUS);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
Found = RtlEqualUnicodeString(RequestedNameW, ActualNameW, TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!Found)
|
||||||
|
{
|
||||||
|
/* FaceName Penalty 10000 */
|
||||||
|
/* Requested a face name, but the candidate's face name
|
||||||
|
does not match. */
|
||||||
|
Penalty += 10000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue