Author: tkreuzer
Date: Wed Aug  3 19:49:13 2011
New Revision: 53053

URL: http://svn.reactos.org/svn/reactos?rev=53053&view=rev
Log:
[GDI FONT DRIVER]
- Rewrite GreAddFontResourceW
- slightly refactor EngLoadFontFileFD
- Implement basic font table handling (insert and search physical fonts using a 
file name hash)
- Implement FONTOBJ_pifi and FONTOBJ_vGetInfo
- Implement NtGdiGetTextExtentExW and stubplement GreGetTextExtentExW

Modified:
    branches/GSoC_2011/GdiFontDriver/subsystems/win32/win32k/font/dcfont.c
    branches/GSoC_2011/GdiFontDriver/subsystems/win32/win32k/font/fntdrvsup.c
    branches/GSoC_2011/GdiFontDriver/subsystems/win32/win32k/font/fontrsrc.c
    branches/GSoC_2011/GdiFontDriver/subsystems/win32/win32k/font/rfont.c
    branches/GSoC_2011/GdiFontDriver/subsystems/win32/win32k/font/strobj.c
    branches/GSoC_2011/GdiFontDriver/subsystems/win32/win32k/font/textmetric.c
    branches/GSoC_2011/GdiFontDriver/subsystems/win32/win32k/font/textout.c

Modified: branches/GSoC_2011/GdiFontDriver/subsystems/win32/win32k/font/dcfont.c
URL: 
http://svn.reactos.org/svn/reactos/branches/GSoC_2011/GdiFontDriver/subsystems/win32/win32k/font/dcfont.c?rev=53053&r1=53052&r2=53053&view=diff
==============================================================================
--- branches/GSoC_2011/GdiFontDriver/subsystems/win32/win32k/font/dcfont.c 
[iso-8859-1] (original)
+++ branches/GSoC_2011/GdiFontDriver/subsystems/win32/win32k/font/dcfont.c 
[iso-8859-1] Wed Aug  3 19:49:13 2011
@@ -58,6 +58,7 @@
     /* Check if font is already realized */
     if (pdc->hlfntCur != pdc->dclevel.plfnt->baseobj.hHmgr)
     {
+        __debugbreak();
         //prfnt = LFONT_prfntRealizeFont(pdc->dclevel.plfnt);
 
         /* Dereference the old RFONT */

Modified: 
branches/GSoC_2011/GdiFontDriver/subsystems/win32/win32k/font/fntdrvsup.c
URL: 
http://svn.reactos.org/svn/reactos/branches/GSoC_2011/GdiFontDriver/subsystems/win32/win32k/font/fntdrvsup.c?rev=53053&r1=53052&r2=53053&view=diff
==============================================================================
--- branches/GSoC_2011/GdiFontDriver/subsystems/win32/win32k/font/fntdrvsup.c 
[iso-8859-1] (original)
+++ branches/GSoC_2011/GdiFontDriver/subsystems/win32/win32k/font/fntdrvsup.c 
[iso-8859-1] Wed Aug  3 19:49:13 2011
@@ -30,15 +30,16 @@
 HSEMAPHORE ghsemFontDriver;
 LIST_ENTRY gleFontDriverList = {&gleFontDriverList, &gleFontDriverList};
 
-extern HSEMAPHORE ghsemPFFList;
+extern PFT gpftPublic;
 
 BOOL FASTCALL
 InitFontSupport(VOID)
 {
     ghsemFontDriver = EngCreateSemaphore();
     if (!ghsemFontDriver) return FALSE;
-    ghsemPFFList = EngCreateSemaphore();
-    if (!ghsemPFFList) return FALSE;
+
+    if (!PFT_bInit(&gpftPublic)) return FALSE;
+
     return TRUE;
 }
 
@@ -76,7 +77,8 @@
                                       sizeof(FD_DEVICEMETRICS));
 }
 
-static void
+static
+VOID
 PFE_vInitialize(
     PPFE ppfe,
     PPFF ppff,
@@ -122,23 +124,72 @@
 
 }
 
+static
+VOID
+CopyFileName(
+    OUT PWCHAR pwcDest,
+    ULONG cwcBufSize,
+    IN OUT PWCHAR *ppwcSource)
+{
+    PWCHAR pwcSource = *ppwcSource;
+    ULONG cwc = 0;
+    WCHAR wc;
+
+    while (++cwc < cwcBufSize)
+    {
+        wc = *pwcSource++;
+
+        if ((wc == '|') || (wc == 0)) break;
+
+        *pwcDest++ = wc;
+    }
+
+    /* Zero terminate the destination string */
+    *pwcDest = 0;
+
+    *ppwcSource = pwcSource;
+}
+
 PPFF
 NTAPI
 EngLoadFontFileFD(
-    ULONG cFiles,
-    PFONTFILEVIEW *ppffv,
+    IN WCHAR *pwszFiles,
+    IN ULONG cwc,
+    IN ULONG cFiles,
     DESIGNVECTOR *pdv,
     ULONG ulCheckSum)
 {
-    PULONG_PTR piFiles = (PULONG_PTR)ppffv;
     PVOID apvView[FD_MAX_FILES];
     ULONG acjView[FD_MAX_FILES];
+    PFONTFILEVIEW apffv[FD_MAX_FILES];
+    PULONG_PTR piFiles = (PULONG_PTR)apffv;
+    WCHAR awcFileName[MAX_PATH];
+    PWCHAR pwcCurrent;
     KAPC_STATE ApcState;
     PLIST_ENTRY ple;
     PFONTDEV pfntdev = NULL;
     HFF hff = 0;
     ULONG cFaces, cjSize, i, ulLangID = 0;
     PPFF ppff = NULL;
+
+    pwcCurrent = pwszFiles;
+
+    /* Loop the files */
+    for (i = 0; i < cFiles; i++)
+    {
+        /* Extract a file name */
+        CopyFileName(awcFileName, MAX_PATH, &pwcCurrent);
+
+        /* Try to load the file */
+        apffv[i] = (PVOID)EngLoadModuleEx(awcFileName, 0, FVF_FONTFILE);
+        if (!apffv[i])
+        {
+            DPRINT1("Failed to load file: '%ls'\n", awcFileName);
+            /* Cleanup and return */
+            while (i--) EngFreeModule(apffv[i]);
+            return NULL;
+        }
+    }
 
     /* Attach to CSRSS */
     AttachCSRSS(&ApcState);
@@ -203,7 +254,7 @@
     ppff->hff = hff;
 
     /* Copy the FONTFILEVIEW pointers */
-    for (i = 0; i < cFiles; i++) ppff->apffv[i] = ppffv[i];
+    for (i = 0; i < cFiles; i++) ppff->apffv[i] = apffv[i];
 
     /* Loop all faces in the font file */
     for (i = 0; i < cFaces; i++)
@@ -231,7 +282,7 @@
     pldev = EngLoadImageEx(pwszDriverName, LDEV_FONT);
     if (!pldev)
     {
-        DPRINT1("Failed to load freetype font driver\n");
+        DPRINT1("Failed to load font driver: %ls\n", pwszDriverName);
         return FALSE;
     }
 
@@ -292,7 +343,7 @@
     DPRINT1("############ Started font drivers\n");
 
     // lets load some fonts
-    cFonts = GreAddFontResourceInternal(&pwszFile, 1, 0, 0, NULL);
+    cFonts = GreAddFontResourceW(pwszFile, 31, 1, 0, 0, NULL);
     ASSERT(cFonts > 0);
 
 }

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=53053&r1=53052&r2=53053&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] Wed Aug  3 19:49:13 2011
@@ -11,7 +11,7 @@
 #define NDEBUG
 #include <debug.h>
 
-HSEMAPHORE ghsemPFFList;
+PFT gpftPublic;
 static LIST_ENTRY glePrivatePFFList = {&glePrivatePFFList, &glePrivatePFFList};
 static LIST_ENTRY glePublicPFFList = {&glePublicPFFList, &glePublicPFFList};
 
@@ -20,7 +20,7 @@
 PFF_bCompareFiles(
     PPFF ppff,
     ULONG cFiles,
-    PFONTFILEVIEW pffv[])
+    PFONTFILEVIEW apffv[])
 {
     ULONG i;
 
@@ -31,66 +31,178 @@
     for (i = 0; i < cFiles; i++)
     {
         /* Check if the files match */
-        if (pffv[i] != ppff->apffv[i]) return FALSE;
+        if (apffv[i] != ppff->apffv[i]) return FALSE;
     }
 
     return TRUE;
 }
+
+BOOL
+NTAPI
+PFT_bInit(
+    PFT *ppft)
+{
+
+    RtlZeroMemory(ppft, sizeof(PFT));
+
+    ppft->hsem = EngCreateSemaphore();
+    if (!ppft->hsem) return FALSE;
+
+    return TRUE;
+}
+
+static
+PPFF
+PFT_pffFindFont(
+    PFT *ppft,
+    PWSTR pwszFiles,
+    ULONG cwc,
+    ULONG cFiles,
+    ULONG iFileNameHash)
+{
+    ULONG iListIndex = iFileNameHash % MAX_FONT_LIST;
+    PPFF ppff = NULL;
+
+    /* Acquire PFT lock */
+    EngAcquireSemaphore(ppft->hsem);
+
+    /* Loop all PFFs in the slot */
+    for (ppff = ppft->apPFF[iListIndex]; ppff; ppff = ppff->pPFFNext)
+    {
+        /* Quick check */
+        if (ppff->iFileNameHash != iFileNameHash) continue;
+
+        /* Do a full check */
+        if (!wcsncmp(ppff->pwszPathname, pwszFiles, cwc)) break;
+    }
+
+    /* Release PFT lock */
+    EngReleaseSemaphore(ppft->hsem);
+
+    return ppff;
+}
+
+static
+VOID
+PFT_vInsertPFE(
+    PPFT ppft,
+    PPFE ppfe)
+{
+    UCHAR ajWinChatSet[2] = {0, DEFAULT_CHARSET};
+    UCHAR *pjCharSets;
+    PIFIMETRICS pifi = ppfe->pifi;
+
+    if (pifi->dpCharSets)
+    {
+        pjCharSets = (PUCHAR)pifi + pifi->dpCharSets;
+    }
+    else
+    {
+        ajWinChatSet[0] = pifi->jWinCharSet;
+        pjCharSets = ajWinChatSet;
+    }
+
+
+}
+
+static
+VOID
+PFT_vInsertPFF(
+    PPFT ppft,
+    PPFF ppff,
+    ULONG iFileNameHash)
+{
+    ULONG i, iListIndex = iFileNameHash % MAX_FONT_LIST;
+
+    ppff->iFileNameHash = iFileNameHash;
+
+    /* Acquire PFT lock */
+    EngAcquireSemaphore(ppft->hsem);
+
+    /* Insert the font file into the hash bucket */
+    ppff->pPFFPrev = NULL;
+    ppff->pPFFNext = ppft->apPFF[iListIndex];
+    ppft->apPFF[iListIndex] = ppff;
+
+    /* Loop all PFE's */
+    for (i = 0; i < ppff->cFonts; i++)
+    {
+        PFT_vInsertPFE(ppft, &ppff->apfe[i]);
+    }
+
+    /* Release PFT lock */
+    EngReleaseSemaphore(ppft->hsem);
+}
+
+static
+ULONG
+CalculateNameHash(PWSTR pwszName)
+{
+    ULONG iHash = 0;
+    WCHAR wc;
+
+    while ((wc = *pwszName++) != 0)
+    {
+        iHash = _rotl(iHash, 7);
+        iHash += wc;
+    }
+
+    return iHash;
+}
+
+
 
 INT
 NTAPI
-GreAddFontResourceInternal(
-    IN PWCHAR apwszFiles[],
+GreAddFontResourceW(
+    IN WCHAR *pwszFiles,
+    IN ULONG cwc,
     IN ULONG cFiles,
     IN FLONG fl,
     IN DWORD dwPidTid,
     IN OPTIONAL DESIGNVECTOR *pdv)
 {
-    PFONTFILEVIEW apffv[FD_MAX_FILES];
+    PPFT ppft;
     PPFF ppff = NULL;
-    PLIST_ENTRY ple, pleListHead;
-    ULONG i, ulCheckSum = 0;
-
-    /* Loop the files */
-    for (i = 0; i < cFiles; i++)
-    {
-        /* Try to load the file */
-        apffv[i] = (PVOID)EngLoadModuleEx(apwszFiles[i], 0, FVF_FONTFILE);
-        if (!apffv[i])
-        {
-            DPRINT1("Failed to load file: '%ls'\n", apwszFiles[i]);
-            /* Cleanup and return */
-            while (i--) EngFreeModule(apffv[i]);
-            return 0;
-        }
-    }
-
-    pleListHead = fl & FR_PRIVATE ? &glePrivatePFFList : &glePublicPFFList;
-
-    /* Acquire PFF list lock */
-    EngAcquireSemaphore(ghsemPFFList);
-
-    /* Loop all physical font files (PFF) */
-    for (ple = pleListHead->Flink; ple != pleListHead; ple = ple->Flink)
-    {
-        ppff = CONTAINING_RECORD(ple, PFF, leLink);
-
-        /* Check if the files are already loaded */
-        if (PFF_bCompareFiles(ppff, cFiles, apffv)) break;
-    }
-
-    /* Release PFF list lock */
-    EngReleaseSemaphore(ghsemPFFList);
-
-    if (ple == pleListHead)
-    {
-        /* Cleanup loaded files, we don't need them anymore */
-        for (i = 0; i < cFiles; i++) EngFreeModule(apffv[i]);
+    ULONG ulCheckSum = 0;
+    PPROCESSINFO ppi;
+    ULONG iFileNameHash;
+
+    // HACK: only global list for now
+    fl &= ~FR_PRIVATE;
+
+    /* Add to private table? */
+    if (fl & FR_PRIVATE)
+    {
+        /* Use the process owned private font table */
+        ppi = PsGetCurrentProcessWin32Process();
+        ppft = ppi->ppftPrivate;
+    }
+    else
+    {
+        /* Use the global font table */
+        ppft = &gpftPublic;
+    }
+
+    /* Get a hash value for the path name */
+    iFileNameHash = CalculateNameHash(pwszFiles);
+
+    /* Try to find the font in the font table */
+    ppff = PFT_pffFindFont(ppft, pwszFiles, cwc, cFiles, iFileNameHash);
+
+    /* Did we find the font? */
+    if (ppff)
+    {
+        /* Return the number of faces */
         return ppff->cFonts;
     }
 
+    // FIXME: check other list, "copy" pft if found
+
+
+
     /* Load the font file with a font driver */
-    ppff = EngLoadFontFileFD(cFiles, apffv, pdv, ulCheckSum);
+    ppff = EngLoadFontFileFD(pwszFiles, cwc, cFiles, pdv, ulCheckSum);
     if (!ppff)
     {
         DPRINT1("Failed to load font with font driver\n");
@@ -98,59 +210,10 @@
     }
 
     /* Insert the PFF into the list */
-    EngAcquireSemaphore(ghsemPFFList);
-    InsertTailList(pleListHead, &ppff->leLink);
-    EngReleaseSemaphore(ghsemPFFList);
-
+    PFT_vInsertPFF(ppft, ppff, iFileNameHash);
+
+    /* Return the number of faces */
     return ppff->cFonts;
-}
-
-static
-BOOL
-SeperateFileNames(
-    PWCHAR apwszFiles[],
-    PWCHAR pwcDest,
-    PWCHAR pwszFiles,
-    ULONG cwc,
-    ULONG cFiles)
-{
-    PWCHAR pwszEnd = pwszFiles + cwc;
-    WCHAR wc;
-    ULONG i = 0;
-
-    apwszFiles[0] = pwcDest;
-
-    /* Loop the file name string */
-    while (pwszFiles < pwszEnd)
-    {
-        wc = *pwszFiles++;
-
-        /* Must not be terminated before the end */
-        if (wc == 0) return FALSE;
-
-        /* Check for a seperator */
-        if (wc == '|')
-        {
-            /* Zero terminate current path name */
-            *pwcDest++ = 0;
-
-            /* Go to next file name and check if its too many */
-            if (++i >= cFiles) return FALSE;
-            apwszFiles[i] = pwcDest;
-        }
-        else
-        {
-            *pwcDest++ = wc;
-        }
-    }
-
-    /* Must be terminated now */
-    if (*pwszFiles != 0 || i != cFiles - 1)
-    {
-        return FALSE;
-    }
-
-    return TRUE;
 }
 
 
@@ -165,11 +228,11 @@
     IN DWORD dwPidTid,
     IN OPTIONAL DESIGNVECTOR *pdv)
 {
-    PVOID pvBuffer;
-    PWCHAR apwszFiles[FD_MAX_FILES];
+    PWCHAR pwszUpcase;
     ULONG cjSize;
     DESIGNVECTOR dv;
     INT iRes = 0;
+    ULONG i;
 
     /* Check parameters */
     if (cFiles == 0 || cFiles > FD_MAX_FILES ||
@@ -180,8 +243,8 @@
     }
 
     /* Allocate a buffer */
-    pvBuffer = EngAllocMem(0, (cwc + 1) * sizeof(WCHAR), 'pmTG');
-    if (!pvBuffer)
+    pwszUpcase = EngAllocMem(0, (cwc + 1) * sizeof(WCHAR), 'pmTG');
+    if (!pwszUpcase)
     {
         EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
         return 0;
@@ -190,9 +253,17 @@
     _SEH2_TRY
     {
         ProbeForRead(pwszFiles, cwc * sizeof(WCHAR), 2);
-        if (!SeperateFileNames(apwszFiles, pvBuffer, pwszFiles, cwc, cFiles))
+
+        /* Verify zero termination */
+        if (pwszFiles[cwc] != 0)
         {
             _SEH2_YIELD(goto cleanup);
+        }
+
+        /* Convert the string to upper case */
+        for (i = 0; i < cwc; i++)
+        {
+            pwszUpcase[i] = RtlUpcaseUnicodeChar(pwszFiles[i]);
         }
 
         /* Check if we have a DESIGNVECTOR */
@@ -220,10 +291,10 @@
     _SEH2_END
 
     /* Call the internal function */
-    iRes = GreAddFontResourceInternal(apwszFiles, cFiles, fl, dwPidTid, pdv);
+    iRes = GreAddFontResourceW(pwszUpcase, cwc, cFiles, fl, dwPidTid, pdv);
 
 cleanup:
-    EngFreeMem(pvBuffer);
+    EngFreeMem(pwszUpcase);
 
     return iRes;
 }

Modified: branches/GSoC_2011/GdiFontDriver/subsystems/win32/win32k/font/rfont.c
URL: 
http://svn.reactos.org/svn/reactos/branches/GSoC_2011/GdiFontDriver/subsystems/win32/win32k/font/rfont.c?rev=53053&r1=53052&r2=53053&view=diff
==============================================================================
--- branches/GSoC_2011/GdiFontDriver/subsystems/win32/win32k/font/rfont.c 
[iso-8859-1] (original)
+++ branches/GSoC_2011/GdiFontDriver/subsystems/win32/win32k/font/rfont.c 
[iso-8859-1] Wed Aug  3 19:49:13 2011
@@ -11,12 +11,17 @@
 #define NDEBUG
 #include <debug.h>
 
+
+
+
+
+/* PUBLIC FUNCTIONS **********************************************************/
+
 ULONG
 APIENTRY
-FONTOBJ_cGetAllGlyphHandles (
-       IN FONTOBJ  *FontObj,
-       IN HGLYPH   *Glyphs
-       )
+FONTOBJ_cGetAllGlyphHandles(
+    IN FONTOBJ *pfo,
+    IN HGLYPH *phg)
 {
     ASSERT(FALSE);
     return 0;
@@ -25,11 +30,11 @@
 ULONG
 APIENTRY
 FONTOBJ_cGetGlyphs(
-       IN FONTOBJ *FontObj,
-       IN ULONG    Mode,
-       IN ULONG    NumGlyphs,
-       IN HGLYPH  *GlyphHandles,
-       IN PVOID   *OutGlyphs)
+    IN FONTOBJ *pfo,
+    IN ULONG iMode,
+    IN ULONG cGlyph,
+    IN HGLYPH *phg,
+    IN PVOID *ppvGlyph)
 {
     ASSERT(FALSE);
     return 0;
@@ -37,17 +42,19 @@
 
 IFIMETRICS*
 APIENTRY
-FONTOBJ_pifi(IN FONTOBJ *pfo)
+FONTOBJ_pifi(
+    IN FONTOBJ *pfo)
 {
-    ASSERT(FALSE);
-    return NULL;
+    PRFONT prfnt = CONTAINING_RECORD(pfo, RFONT, fobj);
+
+    return prfnt->ppfe->pifi;
 }
 
 PVOID
 APIENTRY
 FONTOBJ_pvTrueTypeFontFile(
-       IN FONTOBJ  *FontObj,
-       IN ULONG    *FileSize)
+    IN FONTOBJ  *FontObj,
+    IN ULONG    *FileSize)
 {
     ASSERT(FALSE);
     return NULL;
@@ -58,68 +65,84 @@
 XFORMOBJ*
 APIENTRY
 FONTOBJ_pxoGetXform(
-  IN FONTOBJ *pfo)
+    IN FONTOBJ *pfo)
 {
     ASSERT(FALSE);
     return NULL;
 }
 
-/*
- * @unimplemented
- */
+
 VOID
 APIENTRY
 FONTOBJ_vGetInfo(
-       IN  FONTOBJ   *FontObj,
-       IN  ULONG      InfoSize,
-       OUT PFONTINFO  FontInfo)
+    IN  FONTOBJ *pfo,
+    IN  ULONG cjSize,
+    OUT PFONTINFO pfi)
 {
-    ASSERT(FALSE);
+    PRFONT prfnt = CONTAINING_RECORD(pfo, RFONT, fobj);
+    FLONG flInfo = prfnt->ppfe->pifi->flInfo;
+
+    __debugbreak();
+
+    pfi->cjThis = sizeof(FONTINFO);
+    pfi->flCaps = 0;
+    if (pfo->flFontType & FO_TYPE_DEVICE) pfi->flCaps |= FO_DEVICE_FONT;
+    if (flInfo & FM_INFO_RETURNS_OUTLINES) pfi->flCaps |= FO_OUTLINE_CAPABLE;
+    pfi->cGlyphsSupported = prfnt->pfdg->cGlyphsSupported;
+
+    /* Reset all sizes to 0 */
+    pfi->cjMaxGlyph1 = 0;
+    pfi->cjMaxGlyph4 = 0;
+    pfi->cjMaxGlyph8 = 0;
+    pfi->cjMaxGlyph32 = 0;
+
+    /* Set the appropriate field */
+    switch (prfnt->cBitsPerPel)
+    {
+        case 1: pfi->cjMaxGlyph1 = prfnt->cache.cjGlyphMax; break;
+        case 4: pfi->cjMaxGlyph4 = prfnt->cache.cjGlyphMax; break;
+        case 8: pfi->cjMaxGlyph8 = prfnt->cache.cjGlyphMax; break;
+        case 32: pfi->cjMaxGlyph32 = prfnt->cache.cjGlyphMax; break;
+        default: ASSERT(FALSE); break;
+    }
+
 }
 
-/*
- * @unimplemented
- */
-FD_GLYPHSET * APIENTRY
+FD_GLYPHSET *
+APIENTRY
 FONTOBJ_pfdg(
-   IN FONTOBJ *FontObj)
+   IN FONTOBJ *pfo)
 {
    ASSERT(FALSE);
    return NULL;
 }
 
-/*
- * @unimplemented
- */
-PBYTE APIENTRY
+PBYTE
+APIENTRY
 FONTOBJ_pjOpenTypeTablePointer(
-   IN FONTOBJ *FontObj,
-   IN ULONG Tag,
-   OUT ULONG *Table)
+   IN FONTOBJ *pfo,
+   IN ULONG ulTag,
+   OUT ULONG *pcjTable)
 {
    ASSERT(FALSE);
    return NULL;
 }
 
-/*
- * @unimplemented
- */
-PFD_GLYPHATTR APIENTRY
+PFD_GLYPHATTR
+APIENTRY
 FONTOBJ_pQueryGlyphAttrs(
-   IN FONTOBJ *FontObj,
-   IN ULONG Mode)
+   IN FONTOBJ *pfo,
+   IN ULONG iMode)
 {
    ASSERT(FALSE);
    return NULL;
 }
 
-/*
- * @unimplemented
- */
-LPWSTR APIENTRY
+LPWSTR
+APIENTRY
 FONTOBJ_pwszFontFilePaths(
-   IN FONTOBJ *FontObj,
-   OUT ULONG *PathLength)
+   IN FONTOBJ *pfo,
+   OUT ULONG *pcwc)
 {
    ASSERT(FALSE);
    return NULL;

Modified: branches/GSoC_2011/GdiFontDriver/subsystems/win32/win32k/font/strobj.c
URL: 
http://svn.reactos.org/svn/reactos/branches/GSoC_2011/GdiFontDriver/subsystems/win32/win32k/font/strobj.c?rev=53053&r1=53052&r2=53053&view=diff
==============================================================================
--- branches/GSoC_2011/GdiFontDriver/subsystems/win32/win32k/font/strobj.c 
[iso-8859-1] (original)
+++ branches/GSoC_2011/GdiFontDriver/subsystems/win32/win32k/font/strobj.c 
[iso-8859-1] Wed Aug  3 19:49:13 2011
@@ -11,6 +11,21 @@
 #define NDEBUG
 #include <debug.h>
 
+
+/* PRIVATE FUNCTIONS *********************************************************/
+
+VOID
+NTAPI
+ESTROBJ_vInit(
+    IN ESTROBJ *pestro,
+    IN PWSTR pwsz,
+    IN ULONG cwc)
+{
+
+}
+
+
+/* PUBLIC FUNCTIONS **********************************************************/
 
 BOOL
 APIENTRY

Modified: 
branches/GSoC_2011/GdiFontDriver/subsystems/win32/win32k/font/textmetric.c
URL: 
http://svn.reactos.org/svn/reactos/branches/GSoC_2011/GdiFontDriver/subsystems/win32/win32k/font/textmetric.c?rev=53053&r1=53052&r2=53053&view=diff
==============================================================================
--- branches/GSoC_2011/GdiFontDriver/subsystems/win32/win32k/font/textmetric.c 
[iso-8859-1] (original)
+++ branches/GSoC_2011/GdiFontDriver/subsystems/win32/win32k/font/textmetric.c 
[iso-8859-1] Wed Aug  3 19:49:13 2011
@@ -80,7 +80,7 @@
     petm->emDoubleLowerUnderlineWidth = 0; // FIXME
     petm->emStrikeOutOffset = 0; // FIXME
     petm->emStrikeOutWidth = 0; // FIXME
-    petm->emKernPairs = pifi->cKerningPairs;
+    petm->emKernPairs = (WORD)pifi->cKerningPairs;
     petm->emKernTracks = 0; // FIXME
 
 }
@@ -253,20 +253,150 @@
     return FALSE;
 }
 
-W32KAPI
-BOOL
-APIENTRY
-NtGdiGetTextExtentExW(
+BOOL
+NTAPI
+GreGetTextExtentExW(
     IN HDC hdc,
     IN OPTIONAL LPWSTR lpwsz,
     IN ULONG cwc,
     IN ULONG dxMax,
-    OUT OPTIONAL ULONG *pcCh,
+    OUT OPTIONAL ULONG *pcch,
     OUT OPTIONAL PULONG pdxOut,
     OUT LPSIZE psize,
     IN FLONG fl)
 {
-    ASSERT(FALSE);
-    return FALSE;
-}
-
+    PDC pdc;
+    PRFONT prfnt;
+    BOOL bResult;
+    ESTROBJ estro;
+
+    DPRINT1("GreGetTextExtentExW()\n");
+
+    ESTROBJ_vInit(&estro, lpwsz, cwc);
+
+    /* Lock the DC */
+    pdc = DC_LockDc(hdc);
+    if (!pdc)
+    {
+        return FALSE;
+    }
+
+    /* Get pointer to RFONT */
+    prfnt = DC_prfnt(pdc);
+
+
+
+
+    /* Unlock the DC and return */
+    DC_UnlockDc(pdc);
+    return bResult;
+
+}
+
+W32KAPI
+BOOL
+APIENTRY
+NtGdiGetTextExtentExW(
+    IN HDC hdc,
+    IN OPTIONAL LPWSTR lpwsz,
+    IN ULONG cwc,
+    IN ULONG dxMax,
+    OUT OPTIONAL ULONG *pcch,
+    OUT OPTIONAL PULONG pdxOut,
+    OUT LPSIZE psize,
+    IN FLONG fl)
+{
+    ULONG aulBuffer[100];
+    ULONG cjBufSize;
+    PVOID pvBuffer;
+    SIZEL sizel;
+    PWSTR pwszSafe;
+    PULONG pcchSafe = NULL, pdxSafe = NULL;
+    BOOL bResult = TRUE;
+
+    DPRINT1("NtGdiGetTextExtentExW(%.*ls)\n", cwc, lpwsz);
+
+    /* Check parameters */
+    if ((cwc == 0) || (cwc > 1000)) return FALSE;
+
+    /* Calculate size of the safe buffer */
+    cjBufSize = cwc * sizeof(WCHAR);
+    if (pcch) cjBufSize += cwc * sizeof(ULONG);
+    if (pdxOut) cjBufSize += cwc * sizeof(ULONG);
+
+    if (cjBufSize <= sizeof(aulBuffer))
+    {
+        pvBuffer = aulBuffer;
+    }
+    else
+    {
+        pvBuffer = ExAllocatePoolWithTag(PagedPool, cjBufSize, GDITAG_TEXT);
+        if (!pvBuffer)
+        {
+            DPRINT1("Could not allocate buffer!\n");
+            return FALSE;
+        }
+    }
+
+    pwszSafe = pvBuffer;
+    if (pcch)
+    {
+        pcchSafe = (PULONG)pvBuffer;
+        pwszSafe = (PWCHAR)(pcchSafe + cwc);
+    }
+
+    if (pdxOut)
+    {
+        pdxSafe = (PULONG)pwszSafe;
+        pwszSafe = (PWCHAR)(pdxSafe + cwc);
+    }
+
+    /* Use SEH for buffer transfer */
+    _SEH2_TRY
+    {
+        ProbeForRead(lpwsz, cwc * sizeof(WCHAR), 1);
+        if (pcch) ProbeForWrite(pcch, cwc * sizeof(ULONG), sizeof(ULONG));
+        if (pdxOut) ProbeForWrite(pdxOut, cwc * sizeof(ULONG), sizeof(ULONG));
+        RtlCopyMemory(pwszSafe, lpwsz, cwc * sizeof(WCHAR));
+    }
+    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+    {
+        bResult = FALSE;
+    }
+    _SEH2_END
+
+    if (bResult)
+    {
+        /* Call the internal function */
+        bResult = GreGetTextExtentExW(hdc,
+                                      pwszSafe,
+                                      cwc,
+                                      dxMax,
+                                      pcchSafe,
+                                      pdxSafe,
+                                      &sizel,
+                                      fl);
+
+        /* Do we need to copy something back? */
+        if (bResult && (pcch || pdxOut))
+        {
+            _SEH2_TRY
+            {
+                /* Buffers are already probed */
+                if (pcch) RtlCopyMemory(pcch, pcchSafe, cwc * sizeof(ULONG));
+                if (pdxOut) RtlCopyMemory(pdxOut, pdxSafe, cwc * 
sizeof(ULONG));
+            }
+            _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+            {
+                bResult = FALSE;
+            }
+            _SEH2_END
+        }
+    }
+
+    /* Free temp buffer, if we allocated one */
+    if (pvBuffer != aulBuffer) ExFreePoolWithTag(pvBuffer, GDITAG_TEXT);
+
+    return bResult;
+}
+

Modified: 
branches/GSoC_2011/GdiFontDriver/subsystems/win32/win32k/font/textout.c
URL: 
http://svn.reactos.org/svn/reactos/branches/GSoC_2011/GdiFontDriver/subsystems/win32/win32k/font/textout.c?rev=53053&r1=53052&r2=53053&view=diff
==============================================================================
--- branches/GSoC_2011/GdiFontDriver/subsystems/win32/win32k/font/textout.c 
[iso-8859-1] (original)
+++ branches/GSoC_2011/GdiFontDriver/subsystems/win32/win32k/font/textout.c 
[iso-8859-1] Wed Aug  3 19:49:13 2011
@@ -34,7 +34,7 @@
 }
 
 BOOL
-APIENTRY
+NTAPI
 GreExtTextOutW(
     IN HDC hDC,
     IN INT XStart,


Reply via email to