Index: reactos/base/applications/fontview/display.c =================================================================== --- reactos/base/applications/fontview/display.c (revision 74405) +++ reactos/base/applications/fontview/display.c (working copy) @@ -195,20 +195,15 @@ /* Get font format */ SelectObject(hDC, pData->hCharSetFont); GetTextMetrics(hDC, &tm); + if (GetOutlineTextMetricsW(hDC, sizeof(Buffer), pOTM)) + { + LPBYTE pb; + pb = Buffer + (WORD)(DWORD_PTR)pOTM->otmpFaceName; + pch = (LPWSTR)pb; + lstrcpyW(pData->szTypeFaceName, pch); + } if (tm.tmPitchAndFamily & TMPF_TRUETYPE) { - if (GetOutlineTextMetricsW(hDC, sizeof(Buffer), pOTM)) - { - LPBYTE pb = Buffer; - pb += (WORD)(DWORD_PTR)pOTM->otmpStyleName; - pch = (LPWSTR)pb; - if (*pch) - { - lstrcatW(pData->szTypeFaceName, L" "); - lstrcatW(pData->szTypeFaceName, pch); - } - } - fOpenType = FALSE; EnumFontFamiliesExW(hDC, &logfont, EnumFontFamProcW, (LPARAM)&fOpenType, 0); @@ -295,8 +290,6 @@ Display_SetString(hwnd, L"Jackdaws love my big sphinx of quartz. 1234567890"); - Display_SetTypeFace(hwnd, &LogFont); - return 0; } Index: reactos/win32ss/gdi/ntgdi/freetype.c =================================================================== --- reactos/win32ss/gdi/ntgdi/freetype.c (revision 74405) +++ reactos/win32ss/gdi/ntgdi/freetype.c (working copy) @@ -1738,6 +1738,10 @@ FillTMEx(TM, FontGDI, pOS2, pHori, pFNT, FALSE); } +static NTSTATUS +IntGetFontName(PUNICODE_STRING pNameW, FT_Face Face, + FT_UShort NameID, FT_UShort LangID); + /************************************************************* * IntGetOutlineTextMetrics * @@ -1747,62 +1751,56 @@ UINT Size, OUTLINETEXTMETRICW *Otm) { - unsigned Needed; - TT_OS2 *pOS2; - TT_HoriHeader *pHori; - TT_Postscript *pPost; - FT_Fixed XScale, YScale; - ANSI_STRING FamilyNameA, StyleNameA; - UNICODE_STRING FamilyNameW, StyleNameW, Regular; + UINT Needed; + TT_OS2 * pOS2; + TT_HoriHeader * pHori; + TT_Postscript * pPost; + FT_Fixed XScale, YScale; FT_WinFNT_HeaderRec Win; - FT_Error Error; - char *Cp; - NTSTATUS status; - FT_Face Face = FontGDI->SharedFace->Face; + FT_Error Error; + LPBYTE BytePtr; + NTSTATUS status; + UNICODE_STRING FamilyNameW, StyleNameW, FullNameW; + FT_Face Face = FontGDI->SharedFace->Face; - Needed = sizeof(OUTLINETEXTMETRICW); - - RtlInitAnsiString(&FamilyNameA, Face->family_name); - status = RtlAnsiStringToUnicodeString(&FamilyNameW, &FamilyNameA, TRUE); + /* family name */ + RtlInitUnicodeString(&FamilyNameW, NULL); + status = IntGetFontName(&FamilyNameW, Face, TT_NAME_ID_FONT_FAMILY, gusLanguageID); if (!NT_SUCCESS(status)) { - return 0; + return 0; /* failure */ } - RtlInitAnsiString(&StyleNameA, Face->style_name); - status = RtlAnsiStringToUnicodeString(&StyleNameW, &StyleNameA, TRUE); + /* style name (subfamily) */ + RtlInitUnicodeString(&StyleNameW, NULL); + status = IntGetFontName(&StyleNameW, Face, TT_NAME_ID_FONT_SUBFAMILY, gusLanguageID); if (!NT_SUCCESS(status)) { RtlFreeUnicodeString(&FamilyNameW); - return 0; + return 0; /* failure */ } - /* These names should be read from the TT name table */ - - /* Length of otmpFamilyName */ - Needed += FamilyNameW.Length + sizeof(WCHAR); - - RtlInitUnicodeString(&Regular, L"Regular"); - /* Length of otmpFaceName */ - if (RtlEqualUnicodeString(&StyleNameW, &Regular, TRUE)) + /* full name */ + RtlInitUnicodeString(&FullNameW, NULL); + status = IntGetFontName(&FullNameW, Face, TT_NAME_ID_FULL_NAME, gusLanguageID); + if (!NT_SUCCESS(status)) { - Needed += FamilyNameW.Length + sizeof(WCHAR); /* Just the family name */ + RtlFreeUnicodeString(&FamilyNameW); + RtlFreeUnicodeString(&StyleNameW); + return 0; /* failure */ } - else - { - Needed += FamilyNameW.Length + StyleNameW.Length + (sizeof(WCHAR) << 1); /* family + " " + style */ - } - /* Length of otmpStyleName */ + Needed = sizeof(OUTLINETEXTMETRICW); + Needed += FamilyNameW.Length + sizeof(WCHAR); + Needed += FullNameW.Length + sizeof(WCHAR); Needed += StyleNameW.Length + sizeof(WCHAR); + Needed += FullNameW.Length + sizeof(WCHAR); - /* Length of otmpFullName */ - Needed += FamilyNameW.Length + StyleNameW.Length + (sizeof(WCHAR) << 1); - if (Size < Needed) { RtlFreeUnicodeString(&FamilyNameW); RtlFreeUnicodeString(&StyleNameW); + RtlFreeUnicodeString(&FullNameW); return Needed; } @@ -1815,8 +1813,9 @@ { IntUnLockFreeType; DPRINT1("Can't find OS/2 table - not TT font?\n"); + RtlFreeUnicodeString(&FamilyNameW); RtlFreeUnicodeString(&StyleNameW); - RtlFreeUnicodeString(&FamilyNameW); + RtlFreeUnicodeString(&FullNameW); return 0; } @@ -1825,8 +1824,9 @@ { IntUnLockFreeType; DPRINT1("Can't find HHEA table - not TT font?\n"); + RtlFreeUnicodeString(&FamilyNameW); RtlFreeUnicodeString(&StyleNameW); - RtlFreeUnicodeString(&FamilyNameW); + RtlFreeUnicodeString(&FullNameW); return 0; } @@ -1883,32 +1883,35 @@ IntUnLockFreeType; /* otmp* members should clearly have type ptrdiff_t, but M$ knows best */ - Cp = (char*) Otm + sizeof(OUTLINETEXTMETRICW); - Otm->otmpFamilyName = (LPSTR)(Cp - (char*) Otm); - wcscpy((WCHAR*) Cp, FamilyNameW.Buffer); - Cp += FamilyNameW.Length + sizeof(WCHAR); - Otm->otmpStyleName = (LPSTR)(Cp - (char*) Otm); - wcscpy((WCHAR*) Cp, StyleNameW.Buffer); - Cp += StyleNameW.Length + sizeof(WCHAR); - Otm->otmpFaceName = (LPSTR)(Cp - (char*) Otm); - wcscpy((WCHAR*) Cp, FamilyNameW.Buffer); - if (!RtlEqualUnicodeString(&StyleNameW, &Regular, TRUE)) - { - wcscat((WCHAR*) Cp, L" "); - wcscat((WCHAR*) Cp, StyleNameW.Buffer); - Cp += FamilyNameW.Length + StyleNameW.Length + (sizeof(WCHAR) << 1); - } - else - { - Cp += FamilyNameW.Length + sizeof(WCHAR); - } - Otm->otmpFullName = (LPSTR)(Cp - (char*) Otm); - wcscpy((WCHAR*) Cp, FamilyNameW.Buffer); - wcscat((WCHAR*) Cp, L" "); - wcscat((WCHAR*) Cp, StyleNameW.Buffer); + BytePtr = (LPBYTE)Otm; + BytePtr += sizeof(OUTLINETEXTMETRICW); + /* family name */ + Otm->otmpFamilyName = (PSTR)(BytePtr - (LPBYTE)Otm); + wcscpy((LPWSTR)BytePtr, FamilyNameW.Buffer); + BytePtr += FamilyNameW.Length + sizeof(WCHAR); + + /* face name */ + Otm->otmpFaceName = (PSTR)(BytePtr - (LPBYTE)Otm); + wcscpy((LPWSTR)BytePtr, FullNameW.Buffer); + BytePtr += FullNameW.Length + sizeof(WCHAR); + + /* style name */ + Otm->otmpStyleName = (PSTR)(BytePtr - (LPBYTE)Otm); + wcscpy((LPWSTR)BytePtr, StyleNameW.Buffer); + BytePtr += StyleNameW.Length + sizeof(WCHAR); + + /* full name */ + Otm->otmpFullName = (PSTR)(BytePtr - (LPBYTE)Otm); + wcscpy((LPWSTR)BytePtr, FullNameW.Buffer); + BytePtr += FullNameW.Length + sizeof(WCHAR); + + ASSERT(BytePtr - (LPBYTE)Otm == Needed); + BytePtr = BytePtr; + + RtlFreeUnicodeString(&FamilyNameW); RtlFreeUnicodeString(&StyleNameW); - RtlFreeUnicodeString(&FamilyNameW); + RtlFreeUnicodeString(&FullNameW); return Needed; } @@ -1918,40 +1921,36 @@ { PLIST_ENTRY Entry; PFONT_ENTRY CurrentEntry; - ANSI_STRING EntryFaceNameA; UNICODE_STRING EntryFaceNameW; FONTGDI *FontGDI; - NTSTATUS status; + FT_Face Face; - Entry = Head->Flink; - while (Entry != Head) + for (Entry = Head->Flink; Entry != Head; Entry = Entry->Flink) { CurrentEntry = CONTAINING_RECORD(Entry, FONT_ENTRY, ListEntry); - FontGDI = CurrentEntry->Font; ASSERT(FontGDI); + Face = FontGDI->SharedFace->Face; - RtlInitAnsiString(&EntryFaceNameA, FontGDI->SharedFace->Face->family_name); - status = RtlAnsiStringToUnicodeString(&EntryFaceNameW, &EntryFaceNameA, TRUE); - if (!NT_SUCCESS(status)) + /* family name */ + RtlInitUnicodeString(&EntryFaceNameW, NULL); + IntGetFontName(&EntryFaceNameW, Face, TT_NAME_ID_FONT_FAMILY, gusLanguageID); + if (RtlEqualUnicodeString(FaceName, &EntryFaceNameW, TRUE)) { - break; + RtlFreeUnicodeString(&EntryFaceNameW); + return FontGDI; } + RtlFreeUnicodeString(&EntryFaceNameW); - if ((LF_FACESIZE - 1) * sizeof(WCHAR) < EntryFaceNameW.Length) - { - EntryFaceNameW.Length = (LF_FACESIZE - 1) * sizeof(WCHAR); - EntryFaceNameW.Buffer[LF_FACESIZE - 1] = L'\0'; - } - + /* full name */ + RtlInitUnicodeString(&EntryFaceNameW, NULL); + IntGetFontName(&EntryFaceNameW, Face, TT_NAME_ID_FULL_NAME, gusLanguageID); if (RtlEqualUnicodeString(FaceName, &EntryFaceNameW, TRUE)) { RtlFreeUnicodeString(&EntryFaceNameW); return FontGDI; } - RtlFreeUnicodeString(&EntryFaceNameW); - Entry = Entry->Flink; } return NULL; @@ -2042,16 +2041,31 @@ } static NTSTATUS -IntGetFontLocalizedName(PUNICODE_STRING pNameW, FT_Face Face, - FT_UShort NameID, FT_UShort LangID) +IntGetFontName(PUNICODE_STRING pNameW, FT_Face Face, + FT_UShort NameID, FT_UShort LangID) { FT_SfntName Name; INT i, Count; WCHAR Buf[LF_FULLFACESIZE]; FT_Error Error; - NTSTATUS Status = STATUS_NOT_FOUND; - ANSI_STRING AnsiName; + ANSI_STRING NameA; + NTSTATUS Status; + /* use preferred name if any */ + if (NameID == TT_NAME_ID_FONT_FAMILY) + { + Status = IntGetFontName(pNameW, Face, TT_NAME_ID_PREFERRED_FAMILY, gusEnglishUS); + if (NT_SUCCESS(Status)) + return Status; + } + else if (NameID == TT_NAME_ID_FONT_SUBFAMILY) + { + Status = IntGetFontName(pNameW, Face, TT_NAME_ID_PREFERRED_SUBFAMILY, gusEnglishUS); + if (NT_SUCCESS(Status)) + return Status; + } + + Status = STATUS_NOT_FOUND; RtlFreeUnicodeString(pNameW); Count = FT_Get_Sfnt_Name_Count(Face); @@ -2090,23 +2104,27 @@ /* Convert UTF-16 big endian to little endian */ SwapEndian(Buf, Name.string_len); - RtlCreateUnicodeString(pNameW, Buf); - Status = STATUS_SUCCESS; + Status = RtlCreateUnicodeString(pNameW, Buf); break; } - if (Status == STATUS_NOT_FOUND) + if (!NT_SUCCESS(Status)) { if (LangID != gusEnglishUS) { - Status = IntGetFontLocalizedName(pNameW, Face, NameID, gusEnglishUS); + Status = IntGetFontName(pNameW, Face, NameID, gusEnglishUS); } + else if (NameID == TT_NAME_ID_FONT_FAMILY || NameID == TT_NAME_ID_FULL_NAME) + { + RtlInitAnsiString(&NameA, Face->family_name); + Status = RtlAnsiStringToUnicodeString(pNameW, &NameA, TRUE); + } + else if (NameID == TT_NAME_ID_FONT_SUBFAMILY) + { + RtlInitAnsiString(&NameA, Face->style_name); + Status = RtlAnsiStringToUnicodeString(pNameW, &NameA, TRUE); + } } - if (Status == STATUS_NOT_FOUND) - { - RtlInitAnsiString(&AnsiName, Face->family_name); - Status = RtlAnsiStringToUnicodeString(pNameW, &AnsiName, TRUE); - } return Status; } @@ -2115,8 +2133,6 @@ FontFamilyFillInfo(PFONTFAMILYINFO Info, LPCWSTR FaceName, LPCWSTR FullName, PFONTGDI FontGDI) { - ANSI_STRING StyleA; - UNICODE_STRING StyleW; TT_OS2 *pOS2; FONTSIGNATURE fs; CHARSETINFO CharSetInfo; @@ -2130,7 +2146,6 @@ FT_Face Face = FontGDI->SharedFace->Face; UNICODE_STRING NameW; - RtlInitUnicodeString(&NameW, NULL); RtlZeroMemory(Info, sizeof(FONTFAMILYINFO)); Size = IntGetOutlineTextMetrics(FontGDI, 0, NULL); Otm = ExAllocatePoolWithTag(PagedPool, Size, GDITAG_TEXT); @@ -2192,6 +2207,8 @@ ExFreePoolWithTag(Otm, GDITAG_TEXT); + RtlInitUnicodeString(&NameW, NULL); + /* face name */ if (FaceName) { @@ -2199,8 +2216,7 @@ } else { - status = IntGetFontLocalizedName(&NameW, Face, TT_NAME_ID_FONT_FAMILY, - gusLanguageID); + status = IntGetFontName(&NameW, Face, TT_NAME_ID_FONT_FAMILY, gusLanguageID); if (NT_SUCCESS(status)) { /* store it */ @@ -2219,8 +2235,7 @@ } else { - status = IntGetFontLocalizedName(&NameW, Face, TT_NAME_ID_FULL_NAME, - gusLanguageID); + status = IntGetFontName(&NameW, Face, TT_NAME_ID_FULL_NAME, gusLanguageID); if (NT_SUCCESS(status)) { /* store it */ @@ -2231,14 +2246,17 @@ } } - RtlInitAnsiString(&StyleA, Face->style_name); - StyleW.Buffer = Info->EnumLogFontEx.elfStyle; - StyleW.MaximumLength = sizeof(Info->EnumLogFontEx.elfStyle); - status = RtlAnsiStringToUnicodeString(&StyleW, &StyleA, FALSE); - if (!NT_SUCCESS(status)) + /* style name (subfamily) */ + status = IntGetFontName(&NameW, Face, TT_NAME_ID_FONT_SUBFAMILY, gusLanguageID); + if (NT_SUCCESS(status)) { - return; + /* store it */ + RtlStringCbCopyW(Info->EnumLogFontEx.elfStyle, + sizeof(Info->EnumLogFontEx.elfStyle), NameW.Buffer); + RtlFreeUnicodeString(&NameW); } + + /* FIXME: elfScript */ Info->EnumLogFontEx.elfScript[0] = UNICODE_NULL; IntLockFreeType; @@ -2354,32 +2372,44 @@ { PLIST_ENTRY Entry; PFONT_ENTRY CurrentEntry; - ANSI_STRING EntryFaceNameA; UNICODE_STRING EntryFaceNameW; FONTGDI *FontGDI; - NTSTATUS status; + FT_Face Face; - Entry = Head->Flink; - while (Entry != Head) + RtlInitUnicodeString(&EntryFaceNameW, NULL); + + for (Entry = Head->Flink; Entry != Head; Entry = Entry->Flink) { CurrentEntry = (PFONT_ENTRY) CONTAINING_RECORD(Entry, FONT_ENTRY, ListEntry); - FontGDI = CurrentEntry->Font; ASSERT(FontGDI); + Face = FontGDI->SharedFace->Face; + ASSERT(Face); - RtlInitAnsiString(&EntryFaceNameA, FontGDI->SharedFace->Face->family_name); - status = RtlAnsiStringToUnicodeString(&EntryFaceNameW, &EntryFaceNameA, TRUE); - if (!NT_SUCCESS(status)) + /* font family names */ + IntGetFontName(&EntryFaceNameW, Face, TT_NAME_ID_FONT_FAMILY, gusLanguageID); + if (FontFamilyInclude(LogFont, &EntryFaceNameW, Info, min(*Count, Size))) { - return FALSE; + if (*Count < Size) + { + FontFamilyFillInfo(Info + *Count, EntryFaceNameW.Buffer, + NULL, FontGDI); + } + (*Count)++; } - - if ((LF_FACESIZE - 1) * sizeof(WCHAR) < EntryFaceNameW.Length) + IntGetFontName(&EntryFaceNameW, Face, TT_NAME_ID_FONT_FAMILY, gusEnglishUS); + if (FontFamilyInclude(LogFont, &EntryFaceNameW, Info, min(*Count, Size))) { - EntryFaceNameW.Length = (LF_FACESIZE - 1) * sizeof(WCHAR); - EntryFaceNameW.Buffer[LF_FACESIZE - 1] = L'\0'; + if (*Count < Size) + { + FontFamilyFillInfo(Info + *Count, EntryFaceNameW.Buffer, + NULL, FontGDI); + } + (*Count)++; } + /* full names */ + IntGetFontName(&EntryFaceNameW, Face, TT_NAME_ID_FULL_NAME, gusLanguageID); if (FontFamilyInclude(LogFont, &EntryFaceNameW, Info, min(*Count, Size))) { if (*Count < Size) @@ -2389,10 +2419,20 @@ } (*Count)++; } - RtlFreeUnicodeString(&EntryFaceNameW); - Entry = Entry->Flink; + IntGetFontName(&EntryFaceNameW, Face, TT_NAME_ID_FULL_NAME, gusEnglishUS); + if (FontFamilyInclude(LogFont, &EntryFaceNameW, Info, min(*Count, Size))) + { + if (*Count < Size) + { + FontFamilyFillInfo(Info + *Count, EntryFaceNameW.Buffer, + NULL, FontGDI); + } + (*Count)++; + } } + RtlFreeUnicodeString(&EntryFaceNameW); + return TRUE; } @@ -4081,8 +4121,7 @@ /* localized family name */ if (!Found) { - Status = IntGetFontLocalizedName(ActualNameW, Face, TT_NAME_ID_FONT_FAMILY, - gusLanguageID); + Status = IntGetFontName(ActualNameW, Face, TT_NAME_ID_FONT_FAMILY, gusLanguageID); if (NT_SUCCESS(Status)) { Found = RtlEqualUnicodeString(RequestedNameW, ActualNameW, TRUE); @@ -4091,8 +4130,7 @@ /* localized full name */ if (!Found) { - Status = IntGetFontLocalizedName(ActualNameW, Face, TT_NAME_ID_FULL_NAME, - gusLanguageID); + Status = IntGetFontName(ActualNameW, Face, TT_NAME_ID_FULL_NAME, gusLanguageID); if (NT_SUCCESS(Status)) { Found = RtlEqualUnicodeString(RequestedNameW, ActualNameW, TRUE); @@ -4103,8 +4141,7 @@ /* English family name */ if (!Found) { - Status = IntGetFontLocalizedName(ActualNameW, Face, TT_NAME_ID_FONT_FAMILY, - gusEnglishUS); + Status = IntGetFontName(ActualNameW, Face, TT_NAME_ID_FONT_FAMILY, gusEnglishUS); if (NT_SUCCESS(Status)) { Found = RtlEqualUnicodeString(RequestedNameW, ActualNameW, TRUE); @@ -4113,8 +4150,7 @@ /* English full name */ if (!Found) { - Status = IntGetFontLocalizedName(ActualNameW, Face, TT_NAME_ID_FULL_NAME, - gusEnglishUS); + Status = IntGetFontName(ActualNameW, Face, TT_NAME_ID_FULL_NAME, gusEnglishUS); if (NT_SUCCESS(Status)) { Found = RtlEqualUnicodeString(RequestedNameW, ActualNameW, TRUE); @@ -4625,20 +4661,8 @@ RtlInitUnicodeString(&Str1, pLog1->elfLogFont.lfFaceName); RtlInitUnicodeString(&Str2, pLog2->elfLogFont.lfFaceName); if (!RtlEqualUnicodeString(&Str1, &Str2, TRUE)) - { return FALSE; - } - if ((pLog1->elfStyle != NULL) != (pLog2->elfStyle != NULL)) - return FALSE; - if (pLog1->elfStyle != NULL) - { - RtlInitUnicodeString(&Str1, pLog1->elfStyle); - RtlInitUnicodeString(&Str2, pLog2->elfStyle); - if (!RtlEqualUnicodeString(&Str1, &Str2, TRUE)) - { - return FALSE; - } - } + return TRUE; } @@ -4710,6 +4734,7 @@ EngSetLastError(ERROR_NOT_ENOUGH_MEMORY); return FALSE; } + /* Try to find the pathname in the global font list */ Count = 0; IntLockGlobalFonts; @@ -4728,8 +4753,7 @@ continue; IsEqual = FALSE; - FontFamilyFillInfo(&FamInfo[Count], FontEntry->FaceName.Buffer, - NULL, FontEntry->Font); + FontFamilyFillInfo(&FamInfo[Count], NULL, NULL, FontEntry->Font); for (i = 0; i < Count; ++i) { if (EqualFamilyInfo(&FamInfo[i], &FamInfo[Count]))