[WIN32K/GDI32]

- rewrite GetObject again :)
- simplify and fix FontGetObject
- remove some pointless code

svn path=/trunk/; revision=56407
This commit is contained in:
Timo Kreuzer 2012-04-24 14:49:09 +00:00
parent d8580d250c
commit e4b20ac135
4 changed files with 98 additions and 145 deletions

View file

@ -422,7 +422,7 @@ GetCurrentObject(
_In_ HDC hdc, _In_ HDC hdc,
_In_ UINT uObjectType) _In_ UINT uObjectType)
{ {
PDC_ATTR pdcattr; PDC_ATTR pdcattr = NULL;
/* Check if this is a user mode object */ /* Check if this is a user mode object */
if ((uObjectType == OBJ_PEN) || if ((uObjectType == OBJ_PEN) ||
@ -762,45 +762,102 @@ GetDCOrg(
return(MAKELONG(Pt.x, Pt.y)); return(MAKELONG(Pt.x, Pt.y));
} }
ULONG
/*
* @implemented
*/
int
WINAPI WINAPI
GetFontObjectW(HGDIOBJ hfont, ULONG cbSize, LPVOID lpBuffer) GetObjectW(HGDIOBJ hGdiObj, int cbSize, LPVOID lpBuffer)
{ {
ENUMLOGFONTEXDVW elfedvW; DWORD dwType;
ULONG cbResult, cbMaxSize; INT cbResult = 0;
/* Check if size only is requested */ /* Fixup handles with upper 16 bits masked */
if (!lpBuffer) return sizeof(LOGFONTW); hGdiObj = GdiFixUpHandle(hGdiObj);
/* Check for size 0 */ /* Get the object type */
if (cbSize == 0) dwType = GDI_HANDLE_GET_TYPE(hGdiObj);
/* Check what kind of object we have */
switch (dwType)
{ {
/* Windows does not SetLastError() */ case GDI_OBJECT_TYPE_PEN:
return 0; if (!lpBuffer) return sizeof(LOGPEN);
break;
case GDI_OBJECT_TYPE_BRUSH:
if (!lpBuffer || !cbSize) return sizeof(LOGBRUSH);
break;
case GDI_OBJECT_TYPE_BITMAP:
if (!lpBuffer) return sizeof(BITMAP);
break;
case GDI_OBJECT_TYPE_PALETTE:
if (!lpBuffer) return sizeof(WORD);
break;
case GDI_OBJECT_TYPE_FONT:
if (!lpBuffer) return sizeof(LOGFONTW);
break;
case GDI_OBJECT_TYPE_EXTPEN:
/* we don't know the size, ask win32k */
break;
case GDI_OBJECT_TYPE_COLORSPACE:
if ((cbSize < 328) || !lpBuffer)
{
SetLastError(ERROR_INSUFFICIENT_BUFFER);
return 0;
}
break;
case GDI_OBJECT_TYPE_DC:
case GDI_OBJECT_TYPE_REGION:
case GDI_OBJECT_TYPE_EMF:
case GDI_OBJECT_TYPE_METAFILE:
case GDI_OBJECT_TYPE_ENHMETAFILE:
SetLastError(ERROR_INVALID_HANDLE);
default:
return 0;
} }
/* Call win32k to get the logfont (widechar) */ /* Call win32k */
cbResult = NtGdiExtGetObjectW(hfont, sizeof(ENUMLOGFONTEXDVW), &elfedvW); cbResult = NtGdiExtGetObjectW(hGdiObj, cbSize, lpBuffer);
/* Handle error */
if (cbResult == 0) if (cbResult == 0)
{ {
return 0; if (!GdiIsHandleValid(hGdiObj))
{
if ((dwType == GDI_OBJECT_TYPE_PEN) ||
(dwType == GDI_OBJECT_TYPE_EXTPEN) ||
(dwType == GDI_OBJECT_TYPE_BRUSH) ||
(dwType == GDI_OBJECT_TYPE_COLORSPACE))
{
SetLastError(ERROR_INVALID_PARAMETER);
}
}
else
{
if ((dwType == GDI_OBJECT_TYPE_PEN) ||
(dwType == GDI_OBJECT_TYPE_BRUSH) ||
(dwType == GDI_OBJECT_TYPE_COLORSPACE) ||
( (dwType == GDI_OBJECT_TYPE_EXTPEN) &&
( (cbSize >= sizeof(EXTLOGPEN)) || (cbSize == 0) ) ) ||
( (dwType == GDI_OBJECT_TYPE_BITMAP) && (cbSize >= sizeof(BITMAP)) ))
{
SetLastError(ERROR_NOACCESS);
}
}
} }
/* Calculate the maximum size according to number of axes */ return cbResult;
cbMaxSize = FIELD_OFFSET(ENUMLOGFONTEXDVW,
elfDesignVector.dvValues[elfedvW.elfDesignVector.dvNumAxes]);
/* Don't copy more than the maximum */
if (cbSize > cbMaxSize) cbSize = cbMaxSize;
if (cbSize > cbResult) cbSize = cbResult;
/* Copy the number of bytes requested */
memcpy(lpBuffer, &elfedvW, cbSize);
/* Return the number of bytes copied */
return cbSize;
} }
ULONG ULONG
WINAPI WINAPI
GetFontObjectA(HGDIOBJ hfont, ULONG cbSize, LPVOID lpBuffer) GetFontObjectA(HGDIOBJ hfont, ULONG cbSize, LPVOID lpBuffer)
@ -843,84 +900,6 @@ GetFontObjectA(HGDIOBJ hfont, ULONG cbSize, LPVOID lpBuffer)
return cbSize; return cbSize;
} }
/*
* @implemented
*/
int
WINAPI
GetObjectW(HGDIOBJ hGdiObj, int cbSize, LPVOID lpBuffer)
{
DWORD dwType;
INT cbResult = 0;
hGdiObj = GdiFixUpHandle(hGdiObj);
/* Get the object type */
dwType = GDI_HANDLE_GET_TYPE(hGdiObj);
/* Check what kind of object we have */
switch(dwType)
{
case GDI_OBJECT_TYPE_PEN:
if (!lpBuffer) return sizeof(LOGPEN);
cbResult = NtGdiExtGetObjectW(hGdiObj, cbSize, lpBuffer);
if (cbResult == 0)
SetLastError(ERROR_INVALID_PARAMETER);
return cbResult;
case GDI_OBJECT_TYPE_BRUSH:
if (!lpBuffer) return sizeof(LOGBRUSH);
cbResult = NtGdiExtGetObjectW(hGdiObj, cbSize, lpBuffer);
if (cbResult == 0)
SetLastError(ERROR_INVALID_PARAMETER);
return cbResult;
case GDI_OBJECT_TYPE_BITMAP:
if (!lpBuffer) return sizeof(BITMAP);
return NtGdiExtGetObjectW(hGdiObj, cbSize, lpBuffer);
case GDI_OBJECT_TYPE_PALETTE:
if (!lpBuffer) return sizeof(WORD);
return NtGdiExtGetObjectW(hGdiObj, cbSize, lpBuffer);
case GDI_OBJECT_TYPE_FONT:
return GetFontObjectW(hGdiObj, cbSize, lpBuffer);
case GDI_OBJECT_TYPE_EXTPEN:
/* we don't know the size, ask win32k */
cbResult = NtGdiExtGetObjectW(hGdiObj, cbSize, lpBuffer);
if (cbResult == 0)
{
if (!GdiIsHandleValid(hGdiObj))
SetLastError(ERROR_INVALID_PARAMETER);
else if (cbSize == 0)
SetLastError(ERROR_NOACCESS);
}
return cbResult;
case GDI_OBJECT_TYPE_COLORSPACE:
if ((cbSize < 328) || !lpBuffer)
{
SetLastError(ERROR_INSUFFICIENT_BUFFER);
return 0;
}
cbResult = NtGdiExtGetObjectW(hGdiObj, cbSize, lpBuffer);
if (cbResult == 0)
SetLastError(ERROR_INVALID_PARAMETER);
return cbResult;
case GDI_OBJECT_TYPE_DC:
case GDI_OBJECT_TYPE_REGION:
case GDI_OBJECT_TYPE_EMF:
case GDI_OBJECT_TYPE_METAFILE:
case GDI_OBJECT_TYPE_ENHMETAFILE:
SetLastError(ERROR_INVALID_HANDLE);
default:
return 0;
}
return 0;
}
/* /*
* @implemented * @implemented

View file

@ -260,43 +260,23 @@ GreGetCharacterPlacementW(
} }
#endif #endif
INT ULONG
FASTCALL FASTCALL
FontGetObject(PTEXTOBJ TFont, INT cjBuffer, PVOID pvBuffer) FontGetObject(PTEXTOBJ plfont, ULONG cjBuffer, PVOID pvBuffer)
{ {
ULONG cjMaxSize;
ENUMLOGFONTEXDVW *plf = &plfont->logfont;
/* If buffer is NULL, only the size is requested */
if (pvBuffer == NULL) return sizeof(LOGFONTW); if (pvBuffer == NULL) return sizeof(LOGFONTW);
switch (cjBuffer) /* Calculate the maximum size according to number of axes */
{ cjMaxSize = FIELD_OFFSET(ENUMLOGFONTEXDVW,
case sizeof(ENUMLOGFONTEXDVW): elfDesignVector.dvValues[plf->elfDesignVector.dvNumAxes]);
RtlCopyMemory(pvBuffer,
&TFont->logfont,
sizeof(ENUMLOGFONTEXDVW));
break;
case sizeof(ENUMLOGFONTEXW): if (cjBuffer > cjMaxSize) cjBuffer = cjMaxSize;
RtlCopyMemory(pvBuffer,
&TFont->logfont.elfEnumLogfontEx,
sizeof(ENUMLOGFONTEXW));
break;
case sizeof(EXTLOGFONTW): RtlCopyMemory(pvBuffer, plf, cjBuffer);
case sizeof(ENUMLOGFONTW):
RtlCopyMemory((LPENUMLOGFONTW) pvBuffer,
&TFont->logfont.elfEnumLogfontEx.elfLogFont,
sizeof(ENUMLOGFONTW));
break;
case sizeof(LOGFONTW):
RtlCopyMemory((LPLOGFONTW) pvBuffer,
&TFont->logfont.elfEnumLogfontEx.elfLogFont,
sizeof(LOGFONTW));
break;
default:
EngSetLastError(ERROR_BUFFER_OVERFLOW);
return 0;
}
return cjBuffer; return cjBuffer;
} }

View file

@ -1038,15 +1038,9 @@ GreGetObject(
case GDILoObjType_LO_BITMAP_TYPE: case GDILoObjType_LO_BITMAP_TYPE:
iResult = BITMAP_GetObject(pvObj, cbCount, pvBuffer); iResult = BITMAP_GetObject(pvObj, cbCount, pvBuffer);
break; break;
case GDILoObjType_LO_FONT_TYPE: case GDILoObjType_LO_FONT_TYPE:
iResult = FontGetObject(pvObj, cbCount, pvBuffer); iResult = FontGetObject(pvObj, cbCount, pvBuffer);
#if 0
// Fix the LOGFONT structure for the stock fonts
if (FIRST_STOCK_HANDLE <= hobj && hobj <= LAST_STOCK_HANDLE)
{
FixStockFontSizeW(hobj, cbCount, pvBuffer);
}
#endif
break; break;
case GDILoObjType_LO_PALETTE_TYPE: case GDILoObjType_LO_PALETTE_TYPE:
@ -1096,7 +1090,7 @@ NtGdiExtGetObjectW(
/* Enter SEH for buffer transfer */ /* Enter SEH for buffer transfer */
_SEH2_TRY _SEH2_TRY
{ {
// Probe the buffer and copy it /* Probe the buffer and copy it */
ProbeForWrite(lpBuffer, cbCopyCount, sizeof(WORD)); ProbeForWrite(lpBuffer, cbCopyCount, sizeof(WORD));
RtlCopyMemory(lpBuffer, &object, cbCopyCount); RtlCopyMemory(lpBuffer, &object, cbCopyCount);
} }

View file

@ -88,7 +88,7 @@ BOOL FASTCALL InitFontSupport(VOID);
BOOL FASTCALL IntIsFontRenderingEnabled(VOID); BOOL FASTCALL IntIsFontRenderingEnabled(VOID);
BOOL FASTCALL IntIsFontRenderingEnabled(VOID); BOOL FASTCALL IntIsFontRenderingEnabled(VOID);
VOID FASTCALL IntEnableFontRendering(BOOL Enable); VOID FASTCALL IntEnableFontRendering(BOOL Enable);
INT FASTCALL FontGetObject(PTEXTOBJ TextObj, INT Count, PVOID Buffer); ULONG FASTCALL FontGetObject(PTEXTOBJ TextObj, ULONG Count, PVOID Buffer);
VOID FASTCALL IntLoadSystemFonts(VOID); VOID FASTCALL IntLoadSystemFonts(VOID);
INT FASTCALL IntGdiAddFontResource(PUNICODE_STRING FileName, DWORD Characteristics); INT FASTCALL IntGdiAddFontResource(PUNICODE_STRING FileName, DWORD Characteristics);
ULONG FASTCALL ftGdiGetGlyphOutline(PDC,WCHAR,UINT,LPGLYPHMETRICS,ULONG,PVOID,LPMAT2,BOOL); ULONG FASTCALL ftGdiGetGlyphOutline(PDC,WCHAR,UINT,LPGLYPHMETRICS,ULONG,PVOID,LPMAT2,BOOL);