/*
* 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 ******************************************************************/
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);
pdcattr = Dc->pdcattr;
/* This might need a test for a HEBREW- or ARABIC_CHARSET as well */
- if ( pdcattr->lTextAlign & TA_RTLREADING )
+ if ( pdcattr->flTextAlign & TA_RTLREADING )
if( (fontsig.fsCsb[0]&GCP_REORDER_MASK)!=0 )
result|=GCP_REORDER;
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;
+}
+
+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;
- Ret = IntGdiAddFontResource(&SafeFileName, (DWORD)fl);
+ DPRINT("NtGdiAddFontMemResourceEx\n");
+ DBG_UNREFERENCED_PARAMETER(pdv);
+ DBG_UNREFERENCED_PARAMETER(cjDV);
- ExFreePoolWithTag(SafeFileName.Buffer, TAG_STRING);
- return Ret;
+ 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);