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/subsyste... ============================================================================== --- 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/subsyste... ============================================================================== --- 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/subsyste... ============================================================================== --- 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/subsyste... ============================================================================== --- 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/subsyste... ============================================================================== --- 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/subsyste... ============================================================================== --- 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/subsyste... ============================================================================== --- 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,