[WIN32SS] Fix font names not including style info (Bold etc). Patch by Katayama Hirof...
[reactos.git] / reactos / win32ss / gdi / ntgdi / freetype.c
index 7c7f526..9479b3b 100644 (file)
@@ -75,7 +75,7 @@ static BOOL RenderingEnabled = TRUE;
   ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(FontListLock)
 
 #define ASSERT_GLOBALFONTS_LOCK_HELD() \
-  ASSERT(FreeTypeLock->Owner == KeGetCurrentThread())
+  ASSERT(FontListLock->Owner == KeGetCurrentThread())
 
 #define IntLockFreeType \
   ExEnterCriticalRegionAndAcquireFastMutexUnsafe(FreeTypeLock)
@@ -1738,6 +1738,10 @@ FillTM(TEXTMETRICW *TM, PFONTGDI FontGDI,
     FillTMEx(TM, FontGDI, pOS2, pHori, pFNT, FALSE);
 }
 
+static NTSTATUS
+IntGetFontLocalizedName(PUNICODE_STRING pNameW, FT_Face Face,
+                        FT_UShort NameID, FT_UShort LangID);
+
 /*************************************************************
  * IntGetOutlineTextMetrics
  *
@@ -1752,57 +1756,40 @@ IntGetOutlineTextMetrics(PFONTGDI FontGDI,
     TT_HoriHeader *pHori;
     TT_Postscript *pPost;
     FT_Fixed XScale, YScale;
-    ANSI_STRING FamilyNameA, StyleNameA;
-    UNICODE_STRING FamilyNameW, StyleNameW, Regular;
     FT_WinFNT_HeaderRec Win;
     FT_Error Error;
     char *Cp;
-    NTSTATUS status;
     FT_Face Face = FontGDI->SharedFace->Face;
+    UNICODE_STRING FamilyNameW, FaceNameW, StyleNameW, FullNameW;
 
-    Needed = sizeof(OUTLINETEXTMETRICW);
+    /* family name */
+    RtlInitUnicodeString(&FamilyNameW, NULL);
+    IntGetFontLocalizedName(&FamilyNameW, Face, TT_NAME_ID_FONT_FAMILY, gusLanguageID);
 
-    RtlInitAnsiString(&FamilyNameA, Face->family_name);
-    status = RtlAnsiStringToUnicodeString(&FamilyNameW, &FamilyNameA, TRUE);
-    if (!NT_SUCCESS(status))
-    {
-        return 0;
-    }
+    /* face name */
+    RtlInitUnicodeString(&FaceNameW, NULL);
+    IntGetFontLocalizedName(&FaceNameW, Face, TT_NAME_ID_FULL_NAME, gusLanguageID);
 
-    RtlInitAnsiString(&StyleNameA, Face->style_name);
-    status = RtlAnsiStringToUnicodeString(&StyleNameW, &StyleNameA, TRUE);
-    if (!NT_SUCCESS(status))
-    {
-        RtlFreeUnicodeString(&FamilyNameW);
-        return 0;
-    }
+    /* style name */
+    RtlInitUnicodeString(&StyleNameW, NULL);
+    IntGetFontLocalizedName(&StyleNameW, Face, TT_NAME_ID_FONT_SUBFAMILY, gusLanguageID);
 
-    /* These names should be read from the TT name table */
+    /* unique name (full name) */
+    RtlInitUnicodeString(&FullNameW, NULL);
+    IntGetFontLocalizedName(&FullNameW, Face, TT_NAME_ID_UNIQUE_ID, gusLanguageID);
 
-    /* Length of otmpFamilyName */
+    Needed = sizeof(OUTLINETEXTMETRICW);
     Needed += FamilyNameW.Length + sizeof(WCHAR);
-
-    RtlInitUnicodeString(&Regular, L"Regular");
-    /* Length of otmpFaceName */
-    if (RtlEqualUnicodeString(&StyleNameW, &Regular, TRUE))
-    {
-        Needed += FamilyNameW.Length + sizeof(WCHAR); /* Just the family name */
-    }
-    else
-    {
-        Needed += FamilyNameW.Length + StyleNameW.Length + (sizeof(WCHAR) << 1); /* family + " " + style */
-    }
-
-    /* Length of otmpStyleName */
+    Needed += FaceNameW.Length + sizeof(WCHAR);
     Needed += StyleNameW.Length + sizeof(WCHAR);
-
-    /* Length of otmpFullName */
-    Needed += FamilyNameW.Length + StyleNameW.Length + (sizeof(WCHAR) << 1);
+    Needed += FullNameW.Length + sizeof(WCHAR);
 
     if (Size < Needed)
     {
         RtlFreeUnicodeString(&FamilyNameW);
+        RtlFreeUnicodeString(&FaceNameW);
         RtlFreeUnicodeString(&StyleNameW);
+        RtlFreeUnicodeString(&FullNameW);
         return Needed;
     }
 
@@ -1815,8 +1802,10 @@ IntGetOutlineTextMetrics(PFONTGDI FontGDI,
     {
         IntUnLockFreeType;
         DPRINT1("Can't find OS/2 table - not TT font?\n");
-        RtlFreeUnicodeString(&StyleNameW);
         RtlFreeUnicodeString(&FamilyNameW);
+        RtlFreeUnicodeString(&FaceNameW);
+        RtlFreeUnicodeString(&StyleNameW);
+        RtlFreeUnicodeString(&FullNameW);
         return 0;
     }
 
@@ -1825,8 +1814,10 @@ IntGetOutlineTextMetrics(PFONTGDI FontGDI,
     {
         IntUnLockFreeType;
         DPRINT1("Can't find HHEA table - not TT font?\n");
-        RtlFreeUnicodeString(&StyleNameW);
         RtlFreeUnicodeString(&FamilyNameW);
+        RtlFreeUnicodeString(&FaceNameW);
+        RtlFreeUnicodeString(&StyleNameW);
+        RtlFreeUnicodeString(&FullNameW);
         return 0;
     }
 
@@ -1882,33 +1873,34 @@ IntGetOutlineTextMetrics(PFONTGDI FontGDI,
 
     IntUnLockFreeType;
 
-    /* otmp* members should clearly have type ptrdiff_t, but M$ knows best */
     Cp = (char*) Otm + sizeof(OUTLINETEXTMETRICW);
+
+    /* family name */
     Otm->otmpFamilyName = (LPSTR)(Cp - (char*) Otm);
     wcscpy((WCHAR*) Cp, FamilyNameW.Buffer);
     Cp += FamilyNameW.Length + sizeof(WCHAR);
+
+    /* face name */
+    Otm->otmpFaceName = (LPSTR)(Cp - (char*) Otm);
+    wcscpy((WCHAR*) Cp, FaceNameW.Buffer);
+    Cp += FaceNameW.Length + sizeof(WCHAR);
+
+    /* style name */
     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);
-    }
+
+    /* unique name (full name) */
     Otm->otmpFullName = (LPSTR)(Cp - (char*) Otm);
-    wcscpy((WCHAR*) Cp, FamilyNameW.Buffer);
-    wcscat((WCHAR*) Cp, L" ");
-    wcscat((WCHAR*) Cp, StyleNameW.Buffer);
+    wcscpy((WCHAR*) Cp, FullNameW.Buffer);
+    Cp += FullNameW.Length + sizeof(WCHAR);
+
+    ASSERT(Cp - (char*)Otm == Needed);
 
-    RtlFreeUnicodeString(&StyleNameW);
     RtlFreeUnicodeString(&FamilyNameW);
+    RtlFreeUnicodeString(&FaceNameW);
+    RtlFreeUnicodeString(&StyleNameW);
+    RtlFreeUnicodeString(&FullNameW);
 
     return Needed;
 }
@@ -2090,7 +2082,8 @@ IntGetFontLocalizedName(PUNICODE_STRING pNameW, FT_Face Face,
         /* Convert UTF-16 big endian to little endian */
         SwapEndian(Buf, Name.string_len);
 
-        Status = RtlCreateUnicodeString(pNameW, Buf);
+        RtlCreateUnicodeString(pNameW, Buf);
+        Status = STATUS_SUCCESS;
         break;
     }
 
@@ -2098,20 +2091,27 @@ IntGetFontLocalizedName(PUNICODE_STRING pNameW, FT_Face Face,
     {
         if (LangID != gusEnglishUS)
         {
+            /* Retry with English US */
             Status = IntGetFontLocalizedName(pNameW, Face, NameID, gusEnglishUS);
         }
-    }
-    if (Status == STATUS_NOT_FOUND)
-    {
-        RtlInitAnsiString(&AnsiName, Face->family_name);
-        Status = RtlAnsiStringToUnicodeString(pNameW, &AnsiName, TRUE);
+        else if (NameID == TT_NAME_ID_FONT_SUBFAMILY)
+        {
+            RtlInitAnsiString(&AnsiName, Face->style_name);
+            Status = RtlAnsiStringToUnicodeString(pNameW, &AnsiName, TRUE);
+        }
+        else
+        {
+            RtlInitAnsiString(&AnsiName, Face->family_name);
+            Status = RtlAnsiStringToUnicodeString(pNameW, &AnsiName, TRUE);
+        }
     }
 
     return Status;
 }
 
 static void FASTCALL
-FontFamilyFillInfo(PFONTFAMILYINFO Info, PCWSTR FaceName, PFONTGDI FontGDI)
+FontFamilyFillInfo(PFONTFAMILYINFO Info, LPCWSTR FaceName,
+                   LPCWSTR FullName, PFONTGDI FontGDI)
 {
     ANSI_STRING StyleA;
     UNICODE_STRING StyleW;
@@ -2126,7 +2126,9 @@ FontFamilyFillInfo(PFONTFAMILYINFO Info, PCWSTR FaceName, PFONTGDI FontGDI)
     DWORD fs0;
     NTSTATUS status;
     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);
@@ -2189,28 +2191,37 @@ FontFamilyFillInfo(PFONTFAMILYINFO Info, PCWSTR FaceName, PFONTGDI FontGDI)
     ExFreePoolWithTag(Otm, GDITAG_TEXT);
 
     /* face name */
-    /* TODO: full name */
     if (FaceName)
     {
-        RtlStringCbCopyW(Info->EnumLogFontEx.elfLogFont.lfFaceName,
-                         sizeof(Info->EnumLogFontEx.elfLogFont.lfFaceName),
-                         FaceName);
-        RtlStringCbCopyW(Info->EnumLogFontEx.elfFullName,
-                         sizeof(Info->EnumLogFontEx.elfFullName),
-                         FaceName);
+        RtlStringCbCopyW(Lf->lfFaceName, sizeof(Lf->lfFaceName), FaceName);
     }
     else
     {
-        UNICODE_STRING NameW;
-        RtlInitUnicodeString(&NameW, NULL);
         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),
+            RtlStringCbCopyW(Lf->lfFaceName, sizeof(Lf->lfFaceName),
                              NameW.Buffer);
+            RtlFreeUnicodeString(&NameW);
+        }
+    }
+
+    /* full name */
+    if (FullName)
+    {
+        RtlStringCbCopyW(Info->EnumLogFontEx.elfFullName,
+                         sizeof(Info->EnumLogFontEx.elfFullName),
+                         FullName);
+    }
+    else
+    {
+        status = IntGetFontLocalizedName(&NameW, Face, TT_NAME_ID_FULL_NAME,
+                                         gusLanguageID);
+        if (NT_SUCCESS(status))
+        {
+            /* store it */
             RtlStringCbCopyW(Info->EnumLogFontEx.elfFullName,
                              sizeof(Info->EnumLogFontEx.elfFullName),
                              NameW.Buffer);
@@ -2371,7 +2382,8 @@ GetFontFamilyInfoForList(LPLOGFONTW LogFont,
         {
             if (*Count < Size)
             {
-                FontFamilyFillInfo(Info + *Count, EntryFaceNameW.Buffer, FontGDI);
+                FontFamilyFillInfo(Info + *Count, EntryFaceNameW.Buffer,
+                                   NULL, FontGDI);
             }
             (*Count)++;
         }
@@ -2442,7 +2454,7 @@ FontFamilyInfoQueryRegistryCallback(IN PWSTR ValueName, IN ULONG ValueType,
         if (InfoContext->Count < InfoContext->Size)
         {
             FontFamilyFillInfo(InfoContext->Info + InfoContext->Count,
-                               RegistryName.Buffer, FontGDI);
+                               RegistryName.Buffer, NULL, FontGDI);
         }
         InfoContext->Count++;
         return STATUS_SUCCESS;
@@ -4715,7 +4727,7 @@ IntGdiGetFontResourceInfo(
 
         IsEqual = FALSE;
         FontFamilyFillInfo(&FamInfo[Count], FontEntry->FaceName.Buffer,
-                           FontEntry->Font);
+                           NULL, FontEntry->Font);
         for (i = 0; i < Count; ++i)
         {
             if (EqualFamilyInfo(&FamInfo[i], &FamInfo[Count]))