* LICENSE: GPL - See COPYING in the top level directory
* 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;
DBG_UNREFERENCED_PARAMETER(dwPidTid);
DBG_UNREFERENCED_PARAMETER(pdv);
+ DPRINT("NtGdiAddFontResourceW\n");
+
/* cwc = Length + trailing zero. */
- if (cwc <= 1 || cwc > UNICODE_STRING_MAX_CHARS)
+ if ((cwc <= 1) || (cwc > UNICODE_STRING_MAX_CHARS))
return 0;
- SafeFileName.MaximumLength = cwc * sizeof(WCHAR);
+ SafeFileName.MaximumLength = (USHORT)(cwc * sizeof(WCHAR));
SafeFileName.Length = SafeFileName.MaximumLength - sizeof(UNICODE_NULL);
SafeFileName.Buffer = ExAllocatePoolWithTag(PagedPool,
SafeFileName.MaximumLength,
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;
+
+ 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);