/*
* PROJECT: ReactOS win32 kernel mode subsystem
* LICENSE: GPL - See COPYING in the top level directory
- * FILE: subsystems/win32/win32k/objects/font.c
+ * FILE: win32ss/gdi/ntgdi/font.c
* PURPOSE: Font
- * PROGRAMMER:
+ * PROGRAMMERS: James Tabor <james.tabor@reactos.org>
+ * Timo Kreuzer <timo.kreuzer@reactos.org>
+ * Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
*/
/** Includes ******************************************************************/
#define NDEBUG
#include <debug.h>
+HFONT APIENTRY HfontCreate( IN PENUMLOGFONTEXDVW pelfw,IN ULONG cjElfw,IN LFTYPE lft,IN FLONG fl,IN PVOID pvCliData );
+
/** Internal ******************************************************************/
+HFONT FASTCALL
+GreCreateFontIndirectW( LOGFONTW *lplf )
+{
+ if (lplf)
+ {
+ ENUMLOGFONTEXDVW Logfont;
+
+ RtlCopyMemory( &Logfont.elfEnumLogfontEx.elfLogFont, lplf, sizeof(LOGFONTW));
+ RtlZeroMemory( &Logfont.elfEnumLogfontEx.elfFullName,
+ sizeof(Logfont.elfEnumLogfontEx.elfFullName));
+ RtlZeroMemory( &Logfont.elfEnumLogfontEx.elfStyle,
+ sizeof(Logfont.elfEnumLogfontEx.elfStyle));
+ RtlZeroMemory( &Logfont.elfEnumLogfontEx.elfScript,
+ sizeof(Logfont.elfEnumLogfontEx.elfScript));
+
+ Logfont.elfDesignVector.dvNumAxes = 0;
+
+ RtlZeroMemory( &Logfont.elfDesignVector, sizeof(DESIGNVECTOR));
+
+ return HfontCreate((PENUMLOGFONTEXDVW)&Logfont, 0, 0, 0, NULL );
+ }
+ else return NULL;
+}
+
DWORD
FASTCALL
GreGetKerningPairs(
currently selected font. If not valid, GetCharacterPlacement ignores the
value.
- M$ must use a preset "compiled in" support for each language based releases.
+ MS must use a preset "compiled in" support for each language based releases.
ReactOS uses FreeType, this will need to be supported. ATM this is hard coded
for GCPCLASS_LATIN!
FASTCALL
GreGetCharacterPlacementW(
HDC hdc,
- LPWSTR pwsz,
+ LPCWSTR pwsz,
INT nCount,
INT nMaxExtent,
LPGCP_RESULTSW pgcpw,
FontGetObject(PTEXTOBJ plfont, ULONG cjBuffer, PVOID pvBuffer)
{
ULONG cjMaxSize;
- ENUMLOGFONTEXDVW *plf = &plfont->logfont;
+ ENUMLOGFONTEXDVW *plf;
+
+ ASSERT(plfont);
+ plf = &plfont->logfont;
+
+ if (!(plfont->fl & TEXTOBJECT_INIT))
+ {
+ NTSTATUS Status;
+ DPRINT1("FontGetObject font not initialized!\n");
+
+ Status = TextIntRealizeFont(plfont->BaseObject.hHmgr, plfont);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("FontGetObject(TextIntRealizeFont) Status = 0x%lx\n", Status);
+ }
+ }
/* If buffer is NULL, only the size is requested */
if (pvBuffer == NULL) return sizeof(LOGFONTW);
return pTextObj;
}
-HFONT
-FASTCALL
-GreSelectFont( HDC hDC, HFONT hFont)
-{
- PDC pdc;
- PDC_ATTR pdcattr;
- PTEXTOBJ pOrgFnt, pNewFnt = NULL;
- HFONT hOrgFont = NULL;
-
- if (!hDC || !hFont) return NULL;
-
- pdc = DC_LockDc(hDC);
- if (!pdc)
- {
- return NULL;
- }
-
- if (NT_SUCCESS(TextIntRealizeFont((HFONT)hFont,NULL)))
- {
- /* LFONTOBJ use share and locking. */
- pNewFnt = TEXTOBJ_LockText(hFont);
- pdcattr = pdc->pdcattr;
- pOrgFnt = pdc->dclevel.plfnt;
- if (pOrgFnt)
- {
- hOrgFont = pOrgFnt->BaseObject.hHmgr;
- }
- else
- {
- hOrgFont = pdcattr->hlfntNew;
- }
- pdc->dclevel.plfnt = pNewFnt;
- pdc->hlfntCur = hFont;
- pdcattr->hlfntNew = hFont;
- pdcattr->ulDirty_ |= DIRTY_CHARSET;
- pdcattr->ulDirty_ &= ~SLOW_WIDTHS;
- }
-
- if (pNewFnt) TEXTOBJ_UnlockText(pNewFnt);
- DC_UnlockDc(pdc);
- return hOrgFont;
-}
/** Functions ******************************************************************/
INT
APIENTRY
NtGdiAddFontResourceW(
- IN WCHAR *pwszFiles,
+ IN WCHAR *pwcFiles,
IN ULONG cwc,
IN ULONG cFiles,
IN FLONG fl,
IN DWORD dwPidTid,
IN OPTIONAL DESIGNVECTOR *pdv)
{
- UNICODE_STRING SafeFileName;
- PWSTR src;
- NTSTATUS Status;
- int Ret;
+ UNICODE_STRING SafeFileName;
+ INT Ret;
- /* FIXME: Protect with SEH? */
- RtlInitUnicodeString(&SafeFileName, pwszFiles);
+ DBG_UNREFERENCED_PARAMETER(cFiles);
+ DBG_UNREFERENCED_PARAMETER(dwPidTid);
+ DBG_UNREFERENCED_PARAMETER(pdv);
- /* Reserve for prepending '\??\' */
- SafeFileName.Length += 4 * sizeof(WCHAR);
- SafeFileName.MaximumLength += 4 * sizeof(WCHAR);
+ DPRINT("NtGdiAddFontResourceW\n");
- src = SafeFileName.Buffer;
- SafeFileName.Buffer = (PWSTR)ExAllocatePoolWithTag(PagedPool, SafeFileName.MaximumLength, TAG_STRING);
- if(!SafeFileName.Buffer)
- {
- EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
- return 0;
- }
+ /* cwc = Length + trailing zero. */
+ if ((cwc <= 1) || (cwc > UNICODE_STRING_MAX_CHARS))
+ return 0;
- /* Prepend '\??\' */
- RtlCopyMemory(SafeFileName.Buffer, L"\\??\\", 4 * sizeof(WCHAR));
+ SafeFileName.MaximumLength = (USHORT)(cwc * sizeof(WCHAR));
+ SafeFileName.Length = SafeFileName.MaximumLength - sizeof(UNICODE_NULL);
+ SafeFileName.Buffer = ExAllocatePoolWithTag(PagedPool,
+ SafeFileName.MaximumLength,
+ TAG_STRING);
+ if (!SafeFileName.Buffer)
+ {
+ return 0;
+ }
+
+ _SEH2_TRY
+ {
+ ProbeForRead(pwcFiles, cwc * sizeof(WCHAR), sizeof(WCHAR));
+ RtlCopyMemory(SafeFileName.Buffer, pwcFiles, SafeFileName.Length);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ ExFreePoolWithTag(SafeFileName.Buffer, TAG_STRING);
+ _SEH2_YIELD(return 0);
+ }
+ _SEH2_END;
+
+ SafeFileName.Buffer[SafeFileName.Length / sizeof(WCHAR)] = UNICODE_NULL;
+ Ret = IntGdiAddFontResource(&SafeFileName, fl);
- Status = MmCopyFromCaller(SafeFileName.Buffer + 4, src, SafeFileName.MaximumLength - (4 * sizeof(WCHAR)));
- if(!NT_SUCCESS(Status))
- {
ExFreePoolWithTag(SafeFileName.Buffer, TAG_STRING);
- SetLastNtError(Status);
- return 0;
- }
+ return Ret;
+}
- Ret = IntGdiAddFontResource(&SafeFileName, (DWORD)fl);
+HANDLE
+APIENTRY
+NtGdiAddFontMemResourceEx(
+ IN PVOID pvBuffer,
+ IN DWORD cjBuffer,
+ IN DESIGNVECTOR *pdv,
+ IN ULONG cjDV,
+ OUT DWORD *pNumFonts)
+{
+ _SEH2_VOLATILE PVOID Buffer = NULL;
+ HANDLE Ret;
+ DWORD NumFonts = 0;
- ExFreePoolWithTag(SafeFileName.Buffer, TAG_STRING);
- return Ret;
+ DPRINT("NtGdiAddFontMemResourceEx\n");
+ DBG_UNREFERENCED_PARAMETER(pdv);
+ DBG_UNREFERENCED_PARAMETER(cjDV);
+
+ if (!pvBuffer || !cjBuffer)
+ return NULL;
+
+ _SEH2_TRY
+ {
+ ProbeForRead(pvBuffer, cjBuffer, sizeof(BYTE));
+ Buffer = ExAllocatePoolWithQuotaTag(PagedPool, cjBuffer, TAG_FONT);
+ RtlCopyMemory(Buffer, pvBuffer, cjBuffer);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ if (Buffer != NULL)
+ {
+ ExFreePoolWithTag(Buffer, TAG_FONT);
+ }
+ _SEH2_YIELD(return NULL);
+ }
+ _SEH2_END;
+
+ Ret = IntGdiAddFontMemResource(Buffer, cjBuffer, &NumFonts);
+ ExFreePoolWithTag(Buffer, TAG_FONT);
+
+ _SEH2_TRY
+ {
+ ProbeForWrite(pNumFonts, sizeof(NumFonts), 1);
+ *pNumFonts = NumFonts;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Leak it? */
+ _SEH2_YIELD(return NULL);
+ }
+ _SEH2_END;
+
+
+ return Ret;
}
+
+BOOL
+APIENTRY
+NtGdiRemoveFontMemResourceEx(
+ IN HANDLE hMMFont)
+{
+ return IntGdiRemoveFontMemResource(hMMFont);
+}
+
+
/*
* @unimplemented
*/
return 0;
}
FontGDI = ObjToGDI(TextObj->Font, FONT);
+ TextIntUpdateSize(dc, TextObj, FontGDI, TRUE);
TEXTOBJ_UnlockText(TextObj);
Size = IntGetOutlineTextMetrics(FontGDI, 0, NULL);
if (!otm) return Size;
BOOL
APIENTRY
NtGdiGetFontResourceInfoInternalW(
- IN LPWSTR pwszFiles,
- IN ULONG cwc,
- IN ULONG cFiles,
- IN UINT cjIn,
- OUT LPDWORD pdwBytes,
- OUT LPVOID pvBuf,
- IN DWORD dwType)
+ IN LPWSTR pwszFiles,
+ IN ULONG cwc,
+ IN ULONG cFiles,
+ IN UINT cjIn,
+ IN OUT LPDWORD pdwBytes,
+ OUT LPVOID pvBuf,
+ IN DWORD dwType)
{
NTSTATUS Status = STATUS_SUCCESS;
- DWORD dwBytes;
+ DWORD dwBytes, dwBytesRequested;
UNICODE_STRING SafeFileNames;
BOOL bRet = FALSE;
ULONG cbStringSize;
-
- union
- {
- LOGFONTW logfontw;
- WCHAR FullName[LF_FULLFACESIZE];
- } Buffer;
+ LPVOID Buffer;
/* FIXME: Handle cFiles > 0 */
- /* Check for valid dwType values
- dwType == 4 seems to be handled by gdi32 only */
- if (dwType == 4 || dwType > 5)
+ /* Check for valid dwType values */
+ if (dwType > 5)
{
EngSetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
SafeFileNames.MaximumLength = SafeFileNames.Length = (USHORT)cbStringSize - sizeof(WCHAR);
SafeFileNames.Buffer = ExAllocatePoolWithTag(PagedPool,
cbStringSize,
- 'RTSU');
+ TAG_USTR);
if (!SafeFileNames.Buffer)
{
EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
}
+ RtlZeroMemory(SafeFileNames.Buffer, SafeFileNames.MaximumLength);
/* Check buffers and copy pwszFiles to safe unicode string */
_SEH2_TRY
{
ProbeForRead(pwszFiles, cbStringSize, 1);
ProbeForWrite(pdwBytes, sizeof(DWORD), 1);
- ProbeForWrite(pvBuf, cjIn, 1);
+ if (pvBuf)
+ ProbeForWrite(pvBuf, cjIn, 1);
+
+ dwBytes = *pdwBytes;
+ dwBytesRequested = dwBytes;
RtlCopyMemory(SafeFileNames.Buffer, pwszFiles, cbStringSize);
+ if (dwBytes > 0)
+ {
+ Buffer = ExAllocatePoolWithTag(PagedPool, dwBytes, TAG_FINF);
+ }
+ else
+ {
+ Buffer = ExAllocatePoolWithTag(PagedPool, sizeof(DWORD), TAG_FINF);
+ }
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
{
SetLastNtError(Status);
/* Free the string buffer for the safe filename */
- ExFreePoolWithTag(SafeFileNames.Buffer,'RTSU');
+ ExFreePoolWithTag(SafeFileNames.Buffer, TAG_USTR);
return FALSE;
}
/* Do the actual call */
- bRet = IntGdiGetFontResourceInfo(&SafeFileNames, &Buffer, &dwBytes, dwType);
+ bRet = IntGdiGetFontResourceInfo(&SafeFileNames,
+ (pvBuf ? Buffer : NULL),
+ &dwBytes, dwType);
- /* Check if succeeded and the buffer is big enough */
- if (bRet && cjIn >= dwBytes)
+ /* Check if succeeded */
+ if (bRet)
{
/* Copy the data back to caller */
_SEH2_TRY
{
/* Buffers are already probed */
- RtlCopyMemory(pvBuf, &Buffer, dwBytes);
+ if (pvBuf && dwBytesRequested > 0)
+ RtlCopyMemory(pvBuf, Buffer, min(dwBytesRequested, dwBytes));
*pdwBytes = dwBytes;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
}
}
+ ExFreePoolWithTag(Buffer, TAG_FINF);
/* Free the string for the safe filenames */
- ExFreePoolWithTag(SafeFileNames.Buffer,'RTSU');
+ ExFreePoolWithTag(SafeFileNames.Buffer, TAG_USTR);
return bRet;
}
}
pdcattr = pDc->pdcattr;
pTextObj = RealizeFontInit(pdcattr->hlfntNew);
+ ASSERT(pTextObj != NULL);
pFontGdi = ObjToGDI(pTextObj->Font, FONT);
TEXTOBJ_UnlockText(pTextObj);
DC_UnlockDc(pDc);
return Ret;
}
+
HFONT
APIENTRY
-NtGdiHfontCreate(
+HfontCreate(
IN PENUMLOGFONTEXDVW pelfw,
IN ULONG cjElfw,
IN LFTYPE lft,
IN FLONG fl,
IN PVOID pvCliData )
{
- ENUMLOGFONTEXDVW SafeLogfont;
HFONT hNewFont;
PLFONT plfont;
- NTSTATUS Status = STATUS_SUCCESS;
-
- /* Silence GCC warnings */
- SafeLogfont.elfEnumLogfontEx.elfLogFont.lfEscapement = 0;
- SafeLogfont.elfEnumLogfontEx.elfLogFont.lfOrientation = 0;
if (!pelfw)
{
return NULL;
}
- _SEH2_TRY
- {
- ProbeForRead(pelfw, sizeof(ENUMLOGFONTEXDVW), 1);
- RtlCopyMemory(&SafeLogfont, pelfw, sizeof(ENUMLOGFONTEXDVW));
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- Status = _SEH2_GetExceptionCode();
- }
- _SEH2_END
-
- if (!NT_SUCCESS(Status))
- {
- return NULL;
- }
-
plfont = LFONT_AllocFontWithHandle();
if (!plfont)
{
plfont->lft = lft;
plfont->fl = fl;
- RtlCopyMemory (&plfont->logfont, &SafeLogfont, sizeof(ENUMLOGFONTEXDVW));
+ RtlCopyMemory (&plfont->logfont, pelfw, sizeof(ENUMLOGFONTEXDVW));
ExInitializePushLock(&plfont->lock);
- if (SafeLogfont.elfEnumLogfontEx.elfLogFont.lfEscapement !=
- SafeLogfont.elfEnumLogfontEx.elfLogFont.lfOrientation)
+ if (pelfw->elfEnumLogfontEx.elfLogFont.lfEscapement !=
+ pelfw->elfEnumLogfontEx.elfLogFont.lfOrientation)
{
/* This should really depend on whether GM_ADVANCED is set */
plfont->logfont.elfEnumLogfontEx.elfLogFont.lfOrientation =
return hNewFont;
}
-/*
- * @implemented
- */
+
HFONT
APIENTRY
-NtGdiSelectFont(
- IN HDC hDC,
- IN HFONT hFont)
+NtGdiHfontCreate(
+ IN PENUMLOGFONTEXDVW pelfw,
+ IN ULONG cjElfw,
+ IN LFTYPE lft,
+ IN FLONG fl,
+ IN PVOID pvCliData )
{
- return GreSelectFont(hDC, hFont);
+ ENUMLOGFONTEXDVW SafeLogfont;
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ /* Silence GCC warnings */
+ SafeLogfont.elfEnumLogfontEx.elfLogFont.lfEscapement = 0;
+ SafeLogfont.elfEnumLogfontEx.elfLogFont.lfOrientation = 0;
+
+ if (!pelfw)
+ {
+ return NULL;
+ }
+
+ _SEH2_TRY
+ {
+ ProbeForRead(pelfw, sizeof(ENUMLOGFONTEXDVW), 1);
+ RtlCopyMemory(&SafeLogfont, pelfw, sizeof(ENUMLOGFONTEXDVW));
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END
+
+ if (!NT_SUCCESS(Status))
+ {
+ return NULL;
+ }
+
+ return HfontCreate(&SafeLogfont, cjElfw, lft, fl, pvCliData);
}