[ros-diffs] [tkreuzer] 56006: [WIN32K] - Calculate font name hash in GreHfontCreate - Partly implement LFONT_ppfe, which finds a matching PFE for an LFONT - Implement PFE_ulPenalty, that calculates a penalty v...

tkreuzer at svn.reactos.org tkreuzer at svn.reactos.org
Sun Mar 4 19:08:47 UTC 2012


Author: tkreuzer
Date: Sun Mar  4 19:08:47 2012
New Revision: 56006

URL: http://svn.reactos.org/svn/reactos?rev=56006&view=rev
Log:
[WIN32K]
- Calculate font name hash in GreHfontCreate
- Partly implement LFONT_ppfe, which finds a matching PFE for an LFONT
- Implement PFE_ulPenalty, that calculates a penalty value from a PFE based on a LOGFONT
- Implement HASHBUCKET_ppfeFindBestMatch, that finds the best matching PFE from within a HASHBUCKET
- Implement PFT_ppfeFindBestMatch, that finds the best matching PFE from a PFT
- Rename PFT_pffFindFont to PFT_pffFindFontByFile
- Use bitfields instead of BOOLs in RFONT structure
- Add a name hash value to the LFONT structure
- Add a FONTSUBSTITUTE structure that will be used for font substitutions

Modified:
    branches/GSoC_2011/GdiFontDriver/subsystems/win32/win32k/font/fontrsrc.c
    branches/GSoC_2011/GdiFontDriver/subsystems/win32/win32k/font/lfont.c
    branches/GSoC_2011/GdiFontDriver/subsystems/win32/win32k/include/font.h

Modified: branches/GSoC_2011/GdiFontDriver/subsystems/win32/win32k/font/fontrsrc.c
URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2011/GdiFontDriver/subsystems/win32/win32k/font/fontrsrc.c?rev=56006&r1=56005&r2=56006&view=diff
==============================================================================
--- branches/GSoC_2011/GdiFontDriver/subsystems/win32/win32k/font/fontrsrc.c [iso-8859-1] (original)
+++ branches/GSoC_2011/GdiFontDriver/subsystems/win32/win32k/font/fontrsrc.c [iso-8859-1] Sun Mar  4 19:08:47 2012
@@ -7,12 +7,19 @@
 
 #include <win32k.h>
 #include <include/font.h>
-
-#define NDEBUG
-#include <debug.h>
+DBG_DEFAULT_CHANNEL(GdiFont);
 
 PFT gpftPublic;
 ULONG gulHashBucketId = 0;
+
+static
+PFONTSUBSTITUTE
+GetFontSubstitute(PWSTR pwszFace)
+{
+    // HACK
+    WARN("GetFontSubstitute is unimplemented.\n");
+    return NULL;
+}
 
 VOID
 NTAPI
@@ -34,8 +41,8 @@
 }
 
 
-static
 ULONG
+NTAPI
 CalculateNameHash(PWSTR pwszName)
 {
     ULONG iHash = 0;
@@ -121,7 +128,7 @@
 
             if (!ppfel)
             {
-                DPRINT1("PFE not found!\n");
+                ERR("PFE not found!\n");
                 ASSERT(FALSE);
             }
 
@@ -138,6 +145,185 @@
 
     /* Free the PFELINK */
     ExFreePoolWithTag(ppfel, GDITAG_PFE_LINK);
+}
+
+BYTE
+NTAPI
+GreGetDefaultCharset()
+{
+    USHORT usACP, usOEM;
+
+    RtlGetDefaultCodePage(&usACP, &usOEM);
+    WARN("GreGetDefaultCharset is unimplemented.\n");
+
+    // HACK!
+    return ANSI_CHARSET;
+}
+
+ULONG
+NTAPI
+PFE_ulPenalty(
+    PPFE ppfe,
+    LOGFONTW *plfw,
+    ULONG ulMargin)
+{
+    PIFIMETRICS pifi = ppfe->pifi;
+    ULONG i, ulPenalty = 0;
+    PBYTE pjCharSets;
+    BYTE jCharSet;
+
+    jCharSet = plfw->lfCharSet;
+    if (jCharSet == DEFAULT_CHARSET)
+    {
+        /* Get the default charset */
+        jCharSet = GreGetDefaultCharset();
+    }
+
+    /* Check charsets */
+    if (pifi->dpCharSets)
+    {
+        /* Get a pointer to the charset array */
+        pjCharSets = (PBYTE)pifi + pifi->dpCharSets;
+
+        /* Loop charsets, until the requeste one is found */
+        for (i = 0; pjCharSets[i] != jCharSet; i++)
+        {
+            /* Check if this is the last charset */
+            if ((i == 15) || (pjCharSets[i] == DEFAULT_CHARSET))
+            {
+                /* Charset wasn't found, add penalty */
+                ulPenalty += PENALTY_CharSet;
+                if (ulPenalty > ulMargin) return ulPenalty;
+                break;
+            }
+        }
+    }
+    else
+    {
+        /* Otherwise check if the win charset matches */
+        if (pifi->jWinCharSet != jCharSet)
+        {
+            /* Charset doesn't match, add penalty */
+            ulPenalty += PENALTY_CharSet;
+            if (ulPenalty > ulMargin) return ulPenalty;
+        }
+    }
+
+
+    /* There are contrary claims about the font mapper behaviour towards
+       different lfOutPrecision values between MS LOGFONT structure docs
+       and the font mapper article. */
+    if ((plfw->lfOutPrecision == OUT_DEVICE_PRECIS) &&
+        ((ppfe->flPFE & PFE_DEVICEFONT) == 0))
+    {
+        ulPenalty += PENALTY_OutputPrecision;
+    }
+
+    /* Check if pitch matches */
+    if (((plfw->lfPitchAndFamily & 0x0f) == FIXED_PITCH) &&
+        (pifi->jWinPitchAndFamily & 0x0f) != FIXED_PITCH)
+    {
+        ulPenalty += PENALTY_FixedPitch;
+        if (ulPenalty > ulMargin) return ulPenalty;
+    }
+    else if (((plfw->lfPitchAndFamily & 0x0f) == VARIABLE_PITCH) &&
+        (pifi->jWinPitchAndFamily & 0x0f) != VARIABLE_PITCH)
+    {
+        ulPenalty += PENALTY_PitchVariable;
+        if (ulPenalty > ulMargin) return ulPenalty;
+    }
+
+
+    if ((plfw->lfPitchAndFamily & 0xf0) != FF_DONTCARE)
+    {
+        if ((pifi->jWinPitchAndFamily & 0xf0) == FF_DONTCARE)
+        {
+            ulPenalty += PENALTY_FamilyUnknown;
+        }
+        else if ((plfw->lfPitchAndFamily & 0xf0) != (pifi->jWinPitchAndFamily & 0xf0))
+        {
+            ulPenalty += PENALTY_Family;
+        }
+    }
+
+// PENALTY_HeightSmaller            150
+// PENALTY_HeightBiggerDifference   150
+// PENALTY_FamilyUnlikely            50
+// PENALTY_Width                     50
+// PENALTY_SizeSynth                 50
+// PENALTY_Aspect                    30
+// PENALTY_IntSizeSynth              20
+// PENALTY_UnevenSizeSynth            4
+
+    if (!plfw->lfItalic && (pifi->fsSelection & FM_SEL_ITALIC))
+    {
+        ulPenalty += PENALTY_Italic;
+    }
+
+    if ((plfw->lfOutPrecision == OUT_TT_ONLY_PRECIS) &&
+        !(pifi->flInfo & FM_INFO_TECH_TRUETYPE))
+    {
+        ulPenalty += 500000; // more then can be accounted for
+    }
+
+    if ((plfw->lfOutPrecision == OUT_TT_PRECIS) &&
+        !(pifi->flInfo & FM_INFO_TECH_TRUETYPE))
+    {
+        ulPenalty += PENALTY_NotTrueType;
+    }
+
+
+    ulPenalty += (abs(plfw->lfWeight - pifi->usWinWeight) / 10) * PENALTY_Weight;
+
+    if (!plfw->lfUnderline && (pifi->fsSelection & FM_SEL_UNDERSCORE))
+    {
+        ulPenalty += PENALTY_Underline;
+    }
+
+    if (!plfw->lfStrikeOut && (pifi->fsSelection & FM_SEL_STRIKEOUT))
+    {
+        ulPenalty += PENALTY_StrikeOut;
+    }
+
+// PENALTY_VectorHeightSmaller        2
+// PENALTY_DeviceFavor                2
+// PENALTY_ItalicSim                  1
+
+    if (((plfw->lfPitchAndFamily & 0x0f) == DEFAULT_PITCH) &&
+        (pifi->jWinPitchAndFamily & 0x0f) != FIXED_PITCH)
+    {
+        ulPenalty += PENALTY_DefaultPitchFixed;
+    }
+
+// PENALTY_SmallPenalty               1
+// PENALTY_VectorHeightBigger         1
+    return ulPenalty;
+}
+
+
+static
+PPFE
+HASHBUCKET_ppfeFindBestMatch(
+    PHASHBUCKET pbkt,
+    LOGFONTW *plf,
+    ULONG *pulPenalty)
+{
+    PPFELINK ppfel;
+    ULONG ulPenalty, ulBestMatch = *pulPenalty;
+    PPFE ppfeBestMatch;
+
+    /* Loop all PFELINKs */
+    for (ppfel = pbkt->ppfelEnumHead; ppfel; ppfel = ppfel->ppfelNext)
+    {
+        ulPenalty = PFE_ulPenalty(ppfel->ppfe, plf, ulBestMatch);
+        if (ulPenalty < ulBestMatch)
+        {
+            ppfeBestMatch = ppfel->ppfe;
+            ulBestMatch = ulPenalty;
+        }
+    }
+
+    return ppfeBestMatch;
 }
 
 static
@@ -218,6 +404,7 @@
     return pbkt;
 }
 
+
 static
 VOID
 FONTHASH_vInsertPFE(
@@ -303,9 +490,69 @@
     return FALSE;
 }
 
+PPFE
+NTAPI
+PFT_ppfeFindBestMatch(
+    _In_ PPFT ppft,
+    _In_ PWSTR pwszCapName,
+    _In_ ULONG iHashValue,
+    _In_ LOGFONTW *plf,
+    _Inout_ PULONG pulPenalty)
+{
+    PHASHBUCKET pbkt;
+    ULONG ulPenalty = *pulPenalty;
+    PFONTSUBSTITUTE pfs = NULL;
+    PPFE ppfe;
+
+    /* Acquire PFT lock for reading */
+    EngAcquireSemaphoreShared(ppft->hsem);
+
+    /* Try to find a HASHBUCKET by the face name */
+    pbkt = FONTHASH_pbktFindBucketByName(ppft->pfhFace, pwszCapName, iHashValue);
+
+    /* Check if we found the face name */
+    if (!pbkt)
+    {
+        /* Check if there is a font substitute */
+        pfs = GetFontSubstitute(pwszCapName);
+        if (pfs)
+        {
+            /* Try again with the substitute name */
+            pbkt = FONTHASH_pbktFindBucketByName(ppft->pfhFace,
+                                                 pfs->awcCapSubstName,
+                                                 pfs->iHashValue);
+        }
+    }
+
+    if (pbkt)
+    {
+        ppfe = HASHBUCKET_ppfeFindBestMatch(pbkt, plf, &ulPenalty);
+        if (pfs) ulPenalty += PENALTY_FaceNameSubst;
+
+    }
+    else
+    {
+        TRACE("Font with face name '%ls' was not found!\n", pwszCapName);
+        ulPenalty = PENALTY_FaceName;
+    }
+
+
+    if (ulPenalty >= PENALTY_FaceName)
+    {
+    }
+
+    /* Release PFT lock */
+    EngReleaseSemaphore(ppft->hsem);
+
+    *pulPenalty = ulPenalty;
+    return ppfe;
+}
+
+
+
 static
 PPFF
-PFT_pffFindFont(
+PFT_pffFindFontByFile(
     PFT *ppft,
     PWSTR pwszFiles,
     ULONG cwc,
@@ -407,7 +654,7 @@
     iFileNameHash = CalculateNameHash(pwszFiles);
 
     /* Try to find the font in the font table */
-    ppff = PFT_pffFindFont(ppft, pwszFiles, cwc, cFiles, iFileNameHash);
+    ppff = PFT_pffFindFontByFile(ppft, pwszFiles, cwc, cFiles, iFileNameHash);
 
     /* Did we find the font? */
     if (ppff)
@@ -424,7 +671,7 @@
     ppff = EngLoadFontFileFD(pwszFiles, cwc, cFiles, pdv, ulCheckSum);
     if (!ppff)
     {
-        DPRINT1("Failed to load font with font driver\n");
+        ERR("Failed to load font with font driver\n");
         return 0;
     }
 

Modified: branches/GSoC_2011/GdiFontDriver/subsystems/win32/win32k/font/lfont.c
URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2011/GdiFontDriver/subsystems/win32/win32k/font/lfont.c?rev=56006&r1=56005&r2=56006&view=diff
==============================================================================
--- branches/GSoC_2011/GdiFontDriver/subsystems/win32/win32k/font/lfont.c [iso-8859-1] (original)
+++ branches/GSoC_2011/GdiFontDriver/subsystems/win32/win32k/font/lfont.c [iso-8859-1] Sun Mar  4 19:08:47 2012
@@ -18,6 +18,81 @@
     ASSERT(FALSE);
     return 0;
 }
+
+PPFE
+NTAPI
+LFONT_ppfe(PLFONT plfnt)
+{
+    PPFEOBJ ppfeobj;
+    PPFE ppfe, ppfeSave;
+    HGDIOBJ hPFE;
+    ULONG ulPenalty;
+
+    /* Check if the font has a PFE associated */
+    hPFE = plfnt->hPFE;
+    if (hPFE)
+    {
+        /* Try to lock the PFE */
+        ppfeobj = (PVOID)GDIOBJ_ReferenceObjectByHandle(hPFE, 0x0c);
+
+        /* If we succeeded, the font is still there and we can use it */
+        if (ppfeobj) return ppfeobj->ppfe;
+
+        /* The previous font is not loaded anymore, reset the handle */
+        InterlockedCompareExchangePointer((PVOID*)&plfnt->hPFE, hPFE, NULL);
+    }
+
+    ulPenalty = PENALTY_Max;
+#if 0
+    /* Search the private font table */
+    pti = PsGetCurrentThreadWin32Thread();
+    ppfe = PFT_ppfeFindBestMatch(pti->ppftPrivate,
+                                 plfnt->awchFace,
+                                 plfnt->iNameHash,
+                                 &plfnt->elfexw.elfEnumLogfontEx.elfLogFont,
+                                 &ulPenalty);
+#else
+    ppfe = 0;
+#endif
+    /* Check if we got an exact match */
+    if (ulPenalty != 0)
+    {
+        /* Not an exact match, save this PFE */
+        ppfeSave = ppfe;
+
+        /* Try to find a better match in the global table */
+        ppfe = PFT_ppfeFindBestMatch(&gpftPublic,
+                                     plfnt->awchFace,
+                                     plfnt->iNameHash,
+                                     &plfnt->elfexw.elfEnumLogfontEx.elfLogFont,
+                                     &ulPenalty);
+
+        /* If we didn't find a better one, use the old one */
+        if (!ppfe) ppfe = ppfeSave;
+    }
+
+    /* Check if we got an exact match now */
+    if (ulPenalty == 0)
+    {
+        __debugbreak();
+        // should create a PFEOBJ and save it
+    }
+
+    ASSERT(ppfe);
+    return ppfe;
+}
+
+PRFONT
+NTAPI
+LFONT_prfntFindRFONT(
+    IN PLFONT plfnt)
+{
+
+    __debugbreak();
+
+    return NULL;
+}
+
 
 HFONT
 NTAPI
@@ -51,6 +126,9 @@
     UpcaseString(plfnt->awchFace,
                  pelfw->elfEnumLogfontEx.elfLogFont.lfFaceName,
                  LF_FACESIZE);
+
+    /* Calculate the name hash value */
+    plfnt->iNameHash = CalculateNameHash(plfnt->awchFace);
 
     /* Set client data */
     GDIOBJ_vSetObjectAttr(&plfnt->baseobj, pvCliData);

Modified: branches/GSoC_2011/GdiFontDriver/subsystems/win32/win32k/include/font.h
URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2011/GdiFontDriver/subsystems/win32/win32k/include/font.h?rev=56006&r1=56005&r2=56006&view=diff
==============================================================================
--- branches/GSoC_2011/GdiFontDriver/subsystems/win32/win32k/include/font.h [iso-8859-1] (original)
+++ branches/GSoC_2011/GdiFontDriver/subsystems/win32/win32k/include/font.h [iso-8859-1] Sun Mar  4 19:08:47 2012
@@ -1,9 +1,17 @@
 #pragma once
 
+// FIXME: duplicated from ntoskrnl, should got to NDK or something
+#define InterlockedIncrementUL(Addend) \
+    (ULONG)InterlockedIncrement((PLONG)(Addend))
+
+#define InterlockedDecrementUL(Addend) \
+    (ULONG)InterlockedDecrement((PLONG)(Addend))
+
 #define LFONT_GetObject FontGetObject
 
 #define ENGAPI
 
+#define PENALTY_Max                    127979
 #define PENALTY_CharSet                65000
 #define PENALTY_OutputPrecision        19000
 #define PENALTY_FixedPitch             15000
@@ -38,6 +46,14 @@
 
 extern PEPROCESS gpepCSRSS;
 
+typedef struct _FONTSUBSTITUTE
+{
+    WCHAR awcSubstName[LF_FACESIZE];
+    WCHAR awcCapSubstName[LF_FACESIZE];
+    ULONG iHashValue;
+} FONTSUBSTITUTE, *PFONTSUBSTITUTE;
+
+
 typedef struct _POINTEF
 {
     FLOATOBJ x;
@@ -46,11 +62,24 @@
 
 typedef struct _RFONT *PRFONT;
 
+typedef enum _FLPFE
+{
+    PFE_DEVICEFONT  = 0x0001,
+    PFE_DEADSTATE   = 0x0002,
+    PFE_REMOTEFONT  = 0x0004,
+    PFE_EUDC        = 0x0008,
+    PFE_SBCS_SYSTEM = 0x0010,
+    PFE_UFIMATCH    = 0x0020,
+    PFE_MEMORYFONT  = 0x0040,
+    PFE_DBCS_FONT   = 0x0080,
+    PFE_VERT_FACE   = 0x0100,
+} FLPFE;
+
 typedef struct _PFE
 {
     struct _PFF * pPFF;
     ULONG_PTR iFont;
-    FLONG flPFE;
+    FLPFE flPFE;
     FD_GLYPHSET *pfdg;
     ULONG_PTR idfdg;
     IFIMETRICS * pifi;
@@ -71,6 +100,12 @@
     ULONG cPfdgRef;
     ULONG aiFamilyName[1];
 } PFE, *PPFE;
+
+typedef struct _PFEOBJ
+{
+    BASEOBJECT baseobj;
+    PPFE ppfe;
+} PFEOBJ, *PPFEOBJ;
 
 typedef struct _PFF
 {
@@ -215,11 +250,14 @@
     ULONG iGraphicsMode;
     ULONG ulOrientation;
     ULONG cBitsPerPel;
-    BOOL bVertical;
-    BOOL bDeviceFont;
-    BOOL bIsSystemFont;
-    BOOL bNeededPaths;
-    BOOL bFilledEudcArray;
+    struct
+    {
+        ULONG bVertical:1;
+        ULONG bDeviceFont:1;
+        ULONG bIsSystemFont:1;
+        ULONG bNeededPaths:1;
+        ULONG bFilledEudcArray:1;
+    };
 
 
     FD_XFORM fdx;
@@ -278,6 +316,7 @@
     FLONG fl;
     PPDEVOBJ ppdev;
     HGDIOBJ hPFE;
+    ULONG iNameHash;
     WCHAR awchFace[LF_FACESIZE];
     ENUMLOGFONTEXDVW elfexw;
 } LFONT, *PLFONT;
@@ -332,6 +371,27 @@
     ULONG     acFaceNameGlyphs[8];
 } ESTROBJ, *PESTROBJ;
 
+extern PRFONT gprfntSystemTT;
+extern PFT gpftPublic;
+
+FORCEINLINE
+PLFONT
+LFONT_ShareLockFont(HFONT hfont)
+{
+    return (PLFONT)GDIOBJ_ReferenceObjectByHandle(hfont, GDIObjType_LFONT_TYPE);
+}
+
+FORCEINLINE
+VOID
+LFONT_ShareUnlockFont(PLFONT plfnt)
+{
+    GDIOBJ_vDereferenceObject(&plfnt->baseobj);
+}
+
+PPFE
+NTAPI
+LFONT_ppfe(PLFONT plfnt);
+
 VOID
 NTAPI
 UpcaseString(
@@ -339,24 +399,24 @@
     IN PWSTR pwszSource,
     IN ULONG cwc);
 
-FORCEINLINE
-PLFONT
-LFONT_ShareLockFont(HFONT hfont)
-{
-    return (PLFONT)GDIOBJ_ReferenceObjectByHandle(hfont, GDIObjType_LFONT_TYPE);
-}
-
-FORCEINLINE
-VOID
-LFONT_ShareUnlockFont(PLFONT plfnt)
-{
-    GDIOBJ_vDereferenceObject(&plfnt->baseobj);
-}
+ULONG
+NTAPI
+CalculateNameHash(
+    PWSTR pwszName);
 
 BOOL
 NTAPI
 PFT_bInit(
     PFT *ppft);
+
+PPFE
+NTAPI
+PFT_ppfeFindBestMatch(
+    _In_ PPFT ppft,
+    _In_ PWSTR pwszCapName,
+    _In_ ULONG iHashValue,
+    _In_ LOGFONTW *plf,
+    _Inout_ PULONG pulPenalty);
 
 VOID
 NTAPI
@@ -423,3 +483,8 @@
     INT cwc,
     LPSIZE psize,
     UINT flOpts);
+
+PRFONT
+NTAPI
+RFONT_AllocRFONT(void);
+




More information about the Ros-diffs mailing list