mirror of
https://github.com/reactos/reactos.git
synced 2024-10-05 08:54:40 +00:00
Fix crash in W32kGetTextMetrics
svn path=/trunk/; revision=4448
This commit is contained in:
parent
34aacc4e6b
commit
5fff73db86
|
@ -14,15 +14,12 @@ typedef struct
|
||||||
#define TEXTOBJ_AllocText() \
|
#define TEXTOBJ_AllocText() \
|
||||||
((HFONT) GDIOBJ_AllocObj (sizeof (TEXTOBJ), GO_FONT_MAGIC))
|
((HFONT) GDIOBJ_AllocObj (sizeof (TEXTOBJ), GO_FONT_MAGIC))
|
||||||
#define TEXTOBJ_FreeText(hBMObj) GDIOBJ_FreeObj((HGDIOBJ) hBMObj, GO_FONT_MAGIC, GDIOBJFLAG_DEFAULT)
|
#define TEXTOBJ_FreeText(hBMObj) GDIOBJ_FreeObj((HGDIOBJ) hBMObj, GO_FONT_MAGIC, GDIOBJFLAG_DEFAULT)
|
||||||
/*
|
|
||||||
#define TEXTOBJ_HandleToPtr(hBMObj) \
|
|
||||||
((PTEXTOBJ) GDIOBJ_HandleToPtr ((HGDIOBJ) hBMObj, GO_FONT_MAGIC))
|
|
||||||
#define TEXTOBJ_PtrToHandle(hBMObj) \
|
|
||||||
((HFONT) GDIOBJ_PtrToHandle ((PGDIOBJ) hBMObj, GO_FONT_MAGIC))
|
|
||||||
*/
|
|
||||||
#define TEXTOBJ_LockText(hBMObj) ((PTEXTOBJ) GDIOBJ_LockObj ((HGDIOBJ) hBMObj, GO_FONT_MAGIC))
|
#define TEXTOBJ_LockText(hBMObj) ((PTEXTOBJ) GDIOBJ_LockObj ((HGDIOBJ) hBMObj, GO_FONT_MAGIC))
|
||||||
#define TEXTOBJ_UnlockText(hBMObj) GDIOBJ_UnlockObj ((HGDIOBJ) hBMObj, GO_FONT_MAGIC)
|
#define TEXTOBJ_UnlockText(hBMObj) GDIOBJ_UnlockObj ((HGDIOBJ) hBMObj, GO_FONT_MAGIC)
|
||||||
|
|
||||||
|
NTSTATUS TextIntRealizeFont(HFONT FontHandle);
|
||||||
|
NTSTATUS TextIntCreateFontIndirect(CONST LPLOGFONTW lf, HFONT *NewFont);
|
||||||
|
|
||||||
int
|
int
|
||||||
STDCALL
|
STDCALL
|
||||||
W32kAddFontResource(LPCWSTR Filename);
|
W32kAddFontResource(LPCWSTR Filename);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: dllmain.c,v 1.31 2003/03/11 00:21:41 gvg Exp $
|
/* $Id: dllmain.c,v 1.32 2003/03/28 16:20:50 gvg Exp $
|
||||||
*
|
*
|
||||||
* Entry Point for win32k.sys
|
* Entry Point for win32k.sys
|
||||||
*/
|
*/
|
||||||
|
@ -109,12 +109,12 @@ W32kInitialize (VOID)
|
||||||
// Create surface used to draw the internal font onto
|
// Create surface used to draw the internal font onto
|
||||||
CreateCellCharSurface();
|
CreateCellCharSurface();
|
||||||
|
|
||||||
// Create stock objects, ie. precreated objects commonly used by win32 applications
|
|
||||||
CreateStockObjects();
|
|
||||||
|
|
||||||
// Initialize FreeType library
|
// Initialize FreeType library
|
||||||
if(!InitFontSupport()) return FALSE;
|
if(!InitFontSupport()) return FALSE;
|
||||||
|
|
||||||
|
// Create stock objects, ie. precreated objects commonly used by win32 applications
|
||||||
|
CreateStockObjects();
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: dc.c,v 1.56 2003/03/28 15:27:02 gvg Exp $
|
/* $Id: dc.c,v 1.57 2003/03/28 16:20:51 gvg Exp $
|
||||||
*
|
*
|
||||||
* DC.C - Device context functions
|
* DC.C - Device context functions
|
||||||
*
|
*
|
||||||
|
@ -1075,6 +1075,7 @@ HGDIOBJ STDCALL W32kSelectObject(HDC hDC, HGDIOBJ hGDIObj)
|
||||||
case GO_FONT_MAGIC:
|
case GO_FONT_MAGIC:
|
||||||
objOrg = (HGDIOBJ)dc->w.hFont;
|
objOrg = (HGDIOBJ)dc->w.hFont;
|
||||||
dc->w.hFont = (HFONT) hGDIObj;
|
dc->w.hFont = (HFONT) hGDIObj;
|
||||||
|
TextIntRealizeFont(dc->w.hFont);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GO_BITMAP_MAGIC:
|
case GO_BITMAP_MAGIC:
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* GDIOBJ.C - GDI object manipulation routines
|
* GDIOBJ.C - GDI object manipulation routines
|
||||||
*
|
*
|
||||||
* $Id: gdiobj.c,v 1.22 2003/03/26 08:11:53 gvg Exp $
|
* $Id: gdiobj.c,v 1.23 2003/03/28 16:20:51 gvg Exp $
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -525,18 +525,17 @@ VOID CreateStockObjects(void)
|
||||||
StockObjects[NULL_PEN] = W32kCreatePenIndirect(&NullPen);
|
StockObjects[NULL_PEN] = W32kCreatePenIndirect(&NullPen);
|
||||||
GDIOBJ_MarkObjectGlobal(StockObjects[NULL_PEN]);
|
GDIOBJ_MarkObjectGlobal(StockObjects[NULL_PEN]);
|
||||||
|
|
||||||
StockObjects[OEM_FIXED_FONT] = W32kCreateFontIndirect(&OEMFixedFont);
|
(void) TextIntCreateFontIndirect(&OEMFixedFont, &StockObjects[OEM_FIXED_FONT]);
|
||||||
GDIOBJ_MarkObjectGlobal(StockObjects[OEM_FIXED_FONT]);
|
GDIOBJ_MarkObjectGlobal(StockObjects[OEM_FIXED_FONT]);
|
||||||
StockObjects[ANSI_FIXED_FONT] = W32kCreateFontIndirect(&AnsiFixedFont);
|
(void) TextIntCreateFontIndirect(&AnsiFixedFont, &StockObjects[ANSI_FIXED_FONT]);
|
||||||
GDIOBJ_MarkObjectGlobal(StockObjects[ANSI_FIXED_FONT]);
|
GDIOBJ_MarkObjectGlobal(StockObjects[ANSI_FIXED_FONT]);
|
||||||
StockObjects[SYSTEM_FONT] = W32kCreateFontIndirect(&SystemFont);
|
(void) TextIntCreateFontIndirect(&SystemFont, &StockObjects[SYSTEM_FONT]);
|
||||||
GDIOBJ_MarkObjectGlobal(StockObjects[SYSTEM_FONT]);
|
GDIOBJ_MarkObjectGlobal(StockObjects[SYSTEM_FONT]);
|
||||||
StockObjects[DEVICE_DEFAULT_FONT] =
|
(void) TextIntCreateFontIndirect(&DeviceDefaultFont, &StockObjects[DEVICE_DEFAULT_FONT]);
|
||||||
W32kCreateFontIndirect(&DeviceDefaultFont);
|
|
||||||
GDIOBJ_MarkObjectGlobal(StockObjects[DEVICE_DEFAULT_FONT]);
|
GDIOBJ_MarkObjectGlobal(StockObjects[DEVICE_DEFAULT_FONT]);
|
||||||
StockObjects[SYSTEM_FIXED_FONT] = W32kCreateFontIndirect(&SystemFixedFont);
|
(void) TextIntCreateFontIndirect(&SystemFixedFont, &StockObjects[SYSTEM_FIXED_FONT]);
|
||||||
GDIOBJ_MarkObjectGlobal(StockObjects[SYSTEM_FIXED_FONT]);
|
GDIOBJ_MarkObjectGlobal(StockObjects[SYSTEM_FIXED_FONT]);
|
||||||
StockObjects[DEFAULT_GUI_FONT] = W32kCreateFontIndirect(&DefaultGuiFont);
|
(void) TextIntCreateFontIndirect(&DefaultGuiFont, &StockObjects[DEFAULT_GUI_FONT]);
|
||||||
GDIOBJ_MarkObjectGlobal(StockObjects[DEFAULT_GUI_FONT]);
|
GDIOBJ_MarkObjectGlobal(StockObjects[DEFAULT_GUI_FONT]);
|
||||||
|
|
||||||
StockObjects[DEFAULT_PALETTE] = (HGDIOBJ*)PALETTE_Init();
|
StockObjects[DEFAULT_PALETTE] = (HGDIOBJ*)PALETTE_Init();
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#undef WIN32_LEAN_AND_MEAN
|
#undef WIN32_LEAN_AND_MEAN
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <ddk/ntddk.h>
|
#include <ddk/ntddk.h>
|
||||||
|
#include <internal/safe.h>
|
||||||
#include <win32k/brush.h>
|
#include <win32k/brush.h>
|
||||||
#include <win32k/dc.h>
|
#include <win32k/dc.h>
|
||||||
#include <win32k/text.h>
|
#include <win32k/text.h>
|
||||||
|
@ -36,14 +37,57 @@ BOOL InitFontSupport()
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef TODO
|
||||||
|
W32kAddFontResource(L"\\SystemRoot\\media\\fonts\\arial.ttf");
|
||||||
|
#endif
|
||||||
W32kAddFontResource(L"\\SystemRoot\\media\\fonts\\helb____.ttf");
|
W32kAddFontResource(L"\\SystemRoot\\media\\fonts\\helb____.ttf");
|
||||||
W32kAddFontResource(L"\\SystemRoot\\media\\fonts\\timr____.ttf");
|
W32kAddFontResource(L"\\SystemRoot\\media\\fonts\\timr____.ttf");
|
||||||
|
|
||||||
DbgPrint("All fonts loaded\n");
|
DPRINT("All fonts loaded\n");
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static NTSTATUS
|
||||||
|
GetFontObjectsFromTextObj(PTEXTOBJ TextObj, HFONT *FontHandle, PFONTOBJ *FontObj, PFONTGDI *FontGDI)
|
||||||
|
{
|
||||||
|
UINT i;
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
ASSERT(NULL != TextObj && NULL != TextObj->GDIFontHandle);
|
||||||
|
if (NULL != TextObj && NULL != TextObj->GDIFontHandle)
|
||||||
|
{
|
||||||
|
if (NT_SUCCESS(Status) && NULL != FontHandle)
|
||||||
|
{
|
||||||
|
*FontHandle = TextObj->GDIFontHandle;
|
||||||
|
}
|
||||||
|
if (NT_SUCCESS(Status) && NULL != FontObj)
|
||||||
|
{
|
||||||
|
*FontObj = AccessUserObject((ULONG) TextObj->GDIFontHandle);
|
||||||
|
if (NULL == *FontObj)
|
||||||
|
{
|
||||||
|
ASSERT(FALSE);
|
||||||
|
Status = STATUS_INVALID_HANDLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (NT_SUCCESS(Status) && NULL != FontGDI)
|
||||||
|
{
|
||||||
|
*FontGDI = AccessInternalObject((ULONG) TextObj->GDIFontHandle);
|
||||||
|
if (NULL == *FontGDI)
|
||||||
|
{
|
||||||
|
ASSERT(FALSE);
|
||||||
|
Status = STATUS_INVALID_HANDLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Status = STATUS_INVALID_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
STDCALL
|
STDCALL
|
||||||
W32kAddFontResource(LPCWSTR Filename)
|
W32kAddFontResource(LPCWSTR Filename)
|
||||||
|
@ -65,8 +109,8 @@ W32kAddFontResource(LPCWSTR Filename)
|
||||||
IO_STATUS_BLOCK Iosb;
|
IO_STATUS_BLOCK Iosb;
|
||||||
|
|
||||||
NewFont = (HFONT)CreateGDIHandle(sizeof( FONTGDI ), sizeof( FONTOBJ ));
|
NewFont = (HFONT)CreateGDIHandle(sizeof( FONTGDI ), sizeof( FONTOBJ ));
|
||||||
FontObj = (PFONTOBJ) AccessUserObject( NewFont );
|
FontObj = (PFONTOBJ) AccessUserObject( (ULONG) NewFont );
|
||||||
FontGDI = (PFONTGDI) AccessInternalObject( NewFont );
|
FontGDI = (PFONTGDI) AccessInternalObject( (ULONG) NewFont );
|
||||||
|
|
||||||
RtlCreateUnicodeString(&uFileName, (LPWSTR)Filename);
|
RtlCreateUnicodeString(&uFileName, (LPWSTR)Filename);
|
||||||
|
|
||||||
|
@ -77,7 +121,7 @@ W32kAddFontResource(LPCWSTR Filename)
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DbgPrint("Could not open module file: %S\n", Filename);
|
DPRINT1("Could not open module file: %S\n", Filename);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,7 +129,7 @@ W32kAddFontResource(LPCWSTR Filename)
|
||||||
Status = NtQueryInformationFile(FileHandle, &Iosb, &FileStdInfo, sizeof(FileStdInfo), FileStandardInformation);
|
Status = NtQueryInformationFile(FileHandle, &Iosb, &FileStdInfo, sizeof(FileStdInfo), FileStandardInformation);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DbgPrint("Could not get file size\n");
|
DPRINT1("Could not get file size\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,7 +139,7 @@ W32kAddFontResource(LPCWSTR Filename)
|
||||||
|
|
||||||
if (buffer == NULL)
|
if (buffer == NULL)
|
||||||
{
|
{
|
||||||
DbgPrint("could not allocate memory for module");
|
DPRINT1("could not allocate memory for module");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,7 +147,7 @@ W32kAddFontResource(LPCWSTR Filename)
|
||||||
Status = NtReadFile(FileHandle, 0, 0, 0, &Iosb, buffer, FileStdInfo.EndOfFile.u.LowPart, 0, 0);
|
Status = NtReadFile(FileHandle, 0, 0, 0, &Iosb, buffer, FileStdInfo.EndOfFile.u.LowPart, 0, 0);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DbgPrint("could not read module file into memory");
|
DPRINT1("could not read module file into memory");
|
||||||
ExFreePool(buffer);
|
ExFreePool(buffer);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -113,12 +157,12 @@ W32kAddFontResource(LPCWSTR Filename)
|
||||||
error = FT_New_Memory_Face(library, buffer, size, 0, &face);
|
error = FT_New_Memory_Face(library, buffer, size, 0, &face);
|
||||||
if (error == FT_Err_Unknown_File_Format)
|
if (error == FT_Err_Unknown_File_Format)
|
||||||
{
|
{
|
||||||
DbgPrint("Unknown font file format\n");
|
DPRINT1("Unknown font file format\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else if (error)
|
else if (error)
|
||||||
{
|
{
|
||||||
DbgPrint("Error reading font file (error code: %u)\n", error); // 48
|
DPRINT1("Error reading font file (error code: %u)\n", error); // 48
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,7 +174,7 @@ W32kAddFontResource(LPCWSTR Filename)
|
||||||
FontGDI->TextMetric.tmDescent = face->size->metrics.descender; // units below baseline
|
FontGDI->TextMetric.tmDescent = face->size->metrics.descender; // units below baseline
|
||||||
FontGDI->TextMetric.tmHeight = FontGDI->TextMetric.tmAscent + FontGDI->TextMetric.tmDescent;
|
FontGDI->TextMetric.tmHeight = FontGDI->TextMetric.tmAscent + FontGDI->TextMetric.tmDescent;
|
||||||
|
|
||||||
DbgPrint("Win32k: Font loaded: %s (%s)\n", face->family_name, face->style_name);
|
DPRINT("Font loaded: %s (%s)\n", face->family_name, face->style_name);
|
||||||
DPRINT("Num glyphs: %u\n", face->num_glyphs);
|
DPRINT("Num glyphs: %u\n", face->num_glyphs);
|
||||||
|
|
||||||
// Add this font resource to the font table
|
// Add this font resource to the font table
|
||||||
|
@ -147,24 +191,60 @@ W32kAddFontResource(LPCWSTR Filename)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
TextIntCreateFontIndirect(CONST LPLOGFONTW lf, HFONT *NewFont)
|
||||||
|
{
|
||||||
|
PTEXTOBJ TextObj;
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
*NewFont = TEXTOBJ_AllocText();
|
||||||
|
if (NULL != *NewFont)
|
||||||
|
{
|
||||||
|
TextObj = TEXTOBJ_LockText(*NewFont);
|
||||||
|
if (NULL != TextObj)
|
||||||
|
{
|
||||||
|
memcpy(&TextObj->logfont, lf, sizeof(LOGFONTW));
|
||||||
|
if (lf->lfEscapement != lf->lfOrientation)
|
||||||
|
{
|
||||||
|
/* this should really depend on whether GM_ADVANCED is set */
|
||||||
|
TextObj->logfont.lfOrientation = TextObj->logfont.lfEscapement;
|
||||||
|
}
|
||||||
|
TEXTOBJ_UnlockText(*NewFont);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ASSERT(FALSE);
|
||||||
|
Status = STATUS_INVALID_HANDLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Status = STATUS_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
HFONT
|
HFONT
|
||||||
STDCALL
|
STDCALL
|
||||||
W32kCreateFont(int Height,
|
W32kCreateFont(int Height,
|
||||||
int Width,
|
int Width,
|
||||||
int Escapement,
|
int Escapement,
|
||||||
int Orientation,
|
int Orientation,
|
||||||
int Weight,
|
int Weight,
|
||||||
DWORD Italic,
|
DWORD Italic,
|
||||||
DWORD Underline,
|
DWORD Underline,
|
||||||
DWORD StrikeOut,
|
DWORD StrikeOut,
|
||||||
DWORD CharSet,
|
DWORD CharSet,
|
||||||
DWORD OutputPrecision,
|
DWORD OutputPrecision,
|
||||||
DWORD ClipPrecision,
|
DWORD ClipPrecision,
|
||||||
DWORD Quality,
|
DWORD Quality,
|
||||||
DWORD PitchAndFamily,
|
DWORD PitchAndFamily,
|
||||||
LPCWSTR Face)
|
LPCWSTR Face)
|
||||||
{
|
{
|
||||||
LOGFONTW logfont;
|
LOGFONTW logfont;
|
||||||
|
HFONT NewFont;
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
logfont.lfHeight = Height;
|
logfont.lfHeight = Height;
|
||||||
logfont.lfWidth = Width;
|
logfont.lfWidth = Width;
|
||||||
|
@ -180,40 +260,45 @@ W32kCreateFont(int Height,
|
||||||
logfont.lfQuality = Quality;
|
logfont.lfQuality = Quality;
|
||||||
logfont.lfPitchAndFamily = PitchAndFamily;
|
logfont.lfPitchAndFamily = PitchAndFamily;
|
||||||
|
|
||||||
if(Face)
|
if (NULL != Face)
|
||||||
memcpy(logfont.lfFaceName, Face, sizeof(logfont.lfFaceName));
|
{
|
||||||
|
Status = MmCopyFromCaller(logfont.lfFaceName, Face, sizeof(logfont.lfFaceName));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
logfont.lfFaceName[0] = L'\0';
|
logfont.lfFaceName[0] = L'\0';
|
||||||
|
}
|
||||||
|
|
||||||
return W32kCreateFontIndirect(&logfont);
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
Status = TextIntCreateFontIndirect(&logfont, &NewFont);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NT_SUCCESS(Status) ? NewFont : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
HFONT
|
HFONT
|
||||||
STDCALL
|
STDCALL
|
||||||
W32kCreateFontIndirect(CONST LPLOGFONTW lf)
|
W32kCreateFontIndirect(CONST LPLOGFONTW lf)
|
||||||
{
|
{
|
||||||
HFONT hFont = 0;
|
LOGFONTW SafeLogfont;
|
||||||
PTEXTOBJ fontPtr;
|
HFONT NewFont;
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
if (lf)
|
if (NULL != lf)
|
||||||
{
|
{
|
||||||
if(hFont = TEXTOBJ_AllocText())
|
Status = MmCopyFromCaller(&SafeLogfont, lf, sizeof(LOGFONTW));
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
fontPtr = TEXTOBJ_LockText( hFont );
|
Status = TextIntCreateFontIndirect(&SafeLogfont, &NewFont);
|
||||||
ASSERT( fontPtr ); //I want to know when this happens
|
|
||||||
if( fontPtr ){
|
|
||||||
memcpy(&fontPtr->logfont, lf, sizeof(LOGFONTW));
|
|
||||||
|
|
||||||
if (lf->lfEscapement != lf->lfOrientation) {
|
|
||||||
/* this should really depend on whether GM_ADVANCED is set */
|
|
||||||
fontPtr->logfont.lfOrientation = fontPtr->logfont.lfEscapement;
|
|
||||||
}
|
|
||||||
TEXTOBJ_UnlockText( hFont );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Status = STATUS_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
return hFont;
|
return NT_SUCCESS(Status) ? NewFont : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
|
@ -425,26 +510,26 @@ W32kGetTextExtentPoint(HDC hDC,
|
||||||
int Count,
|
int Count,
|
||||||
LPSIZE Size)
|
LPSIZE Size)
|
||||||
{
|
{
|
||||||
PDC dc = (PDC)AccessUserObject(hDC);
|
PDC dc = (PDC)AccessUserObject((ULONG) hDC);
|
||||||
PFONTGDI FontGDI;
|
PFONTGDI FontGDI;
|
||||||
FT_Face face;
|
FT_Face face;
|
||||||
FT_GlyphSlot glyph;
|
FT_GlyphSlot glyph;
|
||||||
INT error, pitch, glyph_index, i;
|
INT error, pitch, glyph_index, i;
|
||||||
ULONG TotalWidth = 0, MaxHeight = 0, CurrentChar = 0, SpaceBetweenChars = 5;
|
ULONG TotalWidth = 0, MaxHeight = 0, CurrentChar = 0, SpaceBetweenChars = 5;
|
||||||
|
|
||||||
FontGDI = (PFONTGDI)AccessInternalObject(dc->w.hFont);
|
FontGDI = (PFONTGDI)AccessInternalObject((ULONG) dc->w.hFont);
|
||||||
|
|
||||||
for(i=0; i<Count; i++)
|
for(i=0; i<Count; i++)
|
||||||
{
|
{
|
||||||
glyph_index = FT_Get_Char_Index(face, *String);
|
glyph_index = FT_Get_Char_Index(face, *String);
|
||||||
error = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT);
|
error = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT);
|
||||||
if(error) DbgPrint("WARNING: Failed to load and render glyph! [index: %u]\n", glyph_index);
|
if(error) DPRINT1("WARNING: Failed to load and render glyph! [index: %u]\n", glyph_index);
|
||||||
glyph = face->glyph;
|
glyph = face->glyph;
|
||||||
|
|
||||||
if (glyph->format == ft_glyph_format_outline)
|
if (glyph->format == ft_glyph_format_outline)
|
||||||
{
|
{
|
||||||
error = FT_Render_Glyph(glyph, ft_render_mode_mono);
|
error = FT_Render_Glyph(glyph, ft_render_mode_mono);
|
||||||
if(error) DbgPrint("WARNING: Failed to render glyph!\n");
|
if(error) DPRINT1("WARNING: Failed to render glyph!\n");
|
||||||
pitch = glyph->bitmap.pitch;
|
pitch = glyph->bitmap.pitch;
|
||||||
} else {
|
} else {
|
||||||
pitch = glyph->bitmap.width;
|
pitch = glyph->bitmap.width;
|
||||||
|
@ -484,16 +569,59 @@ W32kGetTextFace(HDC hDC,
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
STDCALL
|
STDCALL
|
||||||
W32kGetTextMetrics(HDC hDC,
|
W32kGetTextMetrics(HDC hDC,
|
||||||
LPTEXTMETRICW tm)
|
LPTEXTMETRICW tm)
|
||||||
{
|
{
|
||||||
PDC dc = (PDC)AccessUserObject(hDC);
|
PDC dc;
|
||||||
|
PTEXTOBJ TextObj;
|
||||||
PFONTGDI FontGDI;
|
PFONTGDI FontGDI;
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
TEXTMETRICW SafeTm;
|
||||||
|
FT_Face Face;
|
||||||
|
ULONG Error;
|
||||||
|
|
||||||
FontGDI = (PFONTGDI)AccessInternalObject(dc->w.hFont);
|
dc = DC_HandleToPtr(hDC);
|
||||||
memcpy(tm, &FontGDI->TextMetric, sizeof(TEXTMETRICW));
|
if (NULL == dc || NULL == tm)
|
||||||
|
{
|
||||||
|
Status = STATUS_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TextObj = TEXTOBJ_LockText(dc->w.hFont);
|
||||||
|
if (NULL != TextObj)
|
||||||
|
{
|
||||||
|
Status = GetFontObjectsFromTextObj(TextObj, NULL, NULL, &FontGDI);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
Face = FontGDI->face;
|
||||||
|
Error = FT_Set_Pixel_Sizes(Face, TextObj->logfont.lfHeight,
|
||||||
|
TextObj->logfont.lfWidth);
|
||||||
|
if (0 != Error)
|
||||||
|
{
|
||||||
|
DPRINT1("Error in setting pixel sizes: %u\n", Error);
|
||||||
|
Status = STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memcpy(&SafeTm, &FontGDI->TextMetric, sizeof(TEXTMETRICW));
|
||||||
|
SafeTm.tmAscent = (Face->size->metrics.ascender + 32) / 64; // units above baseline
|
||||||
|
SafeTm.tmDescent = (Face->size->metrics.descender + 32) / 64; // units below baseline
|
||||||
|
SafeTm.tmHeight = (Face->size->metrics.ascender +
|
||||||
|
Face->size->metrics.descender + 32) / 64;
|
||||||
|
Status = MmCopyToCaller(tm, &SafeTm, sizeof(TEXTMETRICW));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TEXTOBJ_UnlockText(dc->w.hFont);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ASSERT(FALSE);
|
||||||
|
Status = STATUS_INVALID_HANDLE;
|
||||||
|
}
|
||||||
|
DC_ReleasePtr(hDC);
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return NT_SUCCESS(Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
|
@ -578,11 +706,11 @@ W32kTextOut(HDC hDC,
|
||||||
// Fixme: Call EngTextOut, which does the real work (calling DrvTextOut where appropriate)
|
// Fixme: Call EngTextOut, which does the real work (calling DrvTextOut where appropriate)
|
||||||
|
|
||||||
DC *dc = DC_HandleToPtr(hDC);
|
DC *dc = DC_HandleToPtr(hDC);
|
||||||
SURFOBJ *SurfObj = (SURFOBJ*)AccessUserObject(dc->Surface);
|
SURFOBJ *SurfObj = (SURFOBJ*)AccessUserObject((ULONG) dc->Surface);
|
||||||
int error, glyph_index, n, load_flags = FT_LOAD_RENDER, i, j, sx, sy, scc;
|
int error, glyph_index, n, i;
|
||||||
FT_Face face;
|
FT_Face face;
|
||||||
FT_GlyphSlot glyph;
|
FT_GlyphSlot glyph;
|
||||||
ULONG TextLeft, TextTop, SpaceBetweenChars = 2, pitch, previous;
|
ULONG TextLeft, TextTop, pitch, previous;
|
||||||
FT_Bool use_kerning;
|
FT_Bool use_kerning;
|
||||||
RECTL DestRect, MaskRect;
|
RECTL DestRect, MaskRect;
|
||||||
POINTL SourcePoint, BrushOrigin;
|
POINTL SourcePoint, BrushOrigin;
|
||||||
|
@ -593,7 +721,6 @@ W32kTextOut(HDC hDC,
|
||||||
SIZEL bitSize;
|
SIZEL bitSize;
|
||||||
FT_CharMap found = 0, charmap;
|
FT_CharMap found = 0, charmap;
|
||||||
INT yoff;
|
INT yoff;
|
||||||
HFONT hFont = 0;
|
|
||||||
PFONTOBJ FontObj;
|
PFONTOBJ FontObj;
|
||||||
PFONTGDI FontGDI;
|
PFONTGDI FontGDI;
|
||||||
PTEXTOBJ TextObj;
|
PTEXTOBJ TextObj;
|
||||||
|
@ -610,50 +737,40 @@ W32kTextOut(HDC hDC,
|
||||||
|
|
||||||
TextObj = TEXTOBJ_LockText(dc->w.hFont);
|
TextObj = TEXTOBJ_LockText(dc->w.hFont);
|
||||||
|
|
||||||
for(i=0; i<FontsLoaded; i++)
|
if (! NT_SUCCESS(GetFontObjectsFromTextObj(TextObj, NULL, &FontObj, &FontGDI)))
|
||||||
{
|
{
|
||||||
if(wcscmp(FontTable[i].FaceName, TextObj->logfont.lfFaceName) == 0)
|
goto fail;
|
||||||
hFont = FontTable[i].hFont;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(hFont == 0)
|
|
||||||
{
|
|
||||||
DbgPrint("Specified font %s is not loaded\n", TextObj->logfont.lfFaceName);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
FontObj = (PFONTOBJ)AccessUserObject(hFont);
|
|
||||||
FontGDI = (PFONTGDI)AccessInternalObject(hFont);
|
|
||||||
face = FontGDI->face;
|
face = FontGDI->face;
|
||||||
|
|
||||||
if (face->charmap == NULL)
|
if (face->charmap == NULL)
|
||||||
{
|
{
|
||||||
DbgPrint("WARNING: No charmap selected!\n");
|
DPRINT("WARNING: No charmap selected!\n");
|
||||||
DbgPrint("This font face has %d charmaps\n", face->num_charmaps);
|
DPRINT("This font face has %d charmaps\n", face->num_charmaps);
|
||||||
|
|
||||||
for (n = 0; n < face->num_charmaps; n++)
|
for (n = 0; n < face->num_charmaps; n++)
|
||||||
{
|
{
|
||||||
charmap = face->charmaps[n];
|
charmap = face->charmaps[n];
|
||||||
DbgPrint("found charmap encoding: %u\n", charmap->encoding);
|
DPRINT("found charmap encoding: %u\n", charmap->encoding);
|
||||||
if (charmap->encoding != 0)
|
if (charmap->encoding != 0)
|
||||||
{
|
{
|
||||||
found = charmap;
|
found = charmap;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!found) DbgPrint("WARNING: Could not find desired charmap!\n");
|
if (!found) DPRINT1("WARNING: Could not find desired charmap!\n");
|
||||||
error = FT_Set_Charmap(face, found);
|
error = FT_Set_Charmap(face, found);
|
||||||
if (error) DbgPrint("WARNING: Could not set the charmap!\n");
|
if (error) DPRINT1("WARNING: Could not set the charmap!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
error = FT_Set_Pixel_Sizes(face, TextObj->logfont.lfHeight, TextObj->logfont.lfWidth);
|
error = FT_Set_Pixel_Sizes(face, TextObj->logfont.lfHeight, TextObj->logfont.lfWidth);
|
||||||
if(error) {
|
if(error) {
|
||||||
DbgPrint("Error in setting pixel sizes: %u\n", error);
|
DPRINT1("Error in setting pixel sizes: %u\n", error);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the brush
|
// Create the brush
|
||||||
PalDestGDI = (PPALGDI)AccessInternalObject(dc->w.hPalette);
|
PalDestGDI = (PPALGDI)AccessInternalObject((ULONG) dc->w.hPalette);
|
||||||
XlateObj = (PXLATEOBJ)IntEngCreateXlate(PalDestGDI->Mode, PAL_RGB, dc->w.hPalette, NULL);
|
XlateObj = (PXLATEOBJ)IntEngCreateXlate(PalDestGDI->Mode, PAL_RGB, dc->w.hPalette, NULL);
|
||||||
hBrush = W32kCreateSolidBrush(XLATEOBJ_iXlate(XlateObj, dc->w.textColor));
|
hBrush = W32kCreateSolidBrush(XLATEOBJ_iXlate(XlateObj, dc->w.textColor));
|
||||||
Brush = BRUSHOBJ_LockBrush(hBrush);
|
Brush = BRUSHOBJ_LockBrush(hBrush);
|
||||||
|
@ -686,7 +803,7 @@ W32kTextOut(HDC hDC,
|
||||||
glyph_index = FT_Get_Char_Index(face, *String);
|
glyph_index = FT_Get_Char_Index(face, *String);
|
||||||
error = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT);
|
error = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT);
|
||||||
if(error) {
|
if(error) {
|
||||||
DbgPrint("WARNING: Failed to load and render glyph! [index: %u]\n", glyph_index);
|
DPRINT1("WARNING: Failed to load and render glyph! [index: %u]\n", glyph_index);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
glyph = face->glyph;
|
glyph = face->glyph;
|
||||||
|
@ -703,7 +820,7 @@ W32kTextOut(HDC hDC,
|
||||||
{
|
{
|
||||||
error = FT_Render_Glyph(glyph, ft_render_mode_mono);
|
error = FT_Render_Glyph(glyph, ft_render_mode_mono);
|
||||||
if(error) {
|
if(error) {
|
||||||
DbgPrint("WARNING: Failed to render glyph!\n");
|
DPRINT1("WARNING: Failed to render glyph!\n");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
pitch = glyph->bitmap.pitch;
|
pitch = glyph->bitmap.pitch;
|
||||||
|
@ -724,7 +841,7 @@ W32kTextOut(HDC hDC,
|
||||||
// Then use memset with 0 to clear it and sourcerect to limit the work of the transbitblt
|
// Then use memset with 0 to clear it and sourcerect to limit the work of the transbitblt
|
||||||
|
|
||||||
HSourceGlyph = EngCreateBitmap(bitSize, pitch, BMF_1BPP, 0, glyph->bitmap.buffer);
|
HSourceGlyph = EngCreateBitmap(bitSize, pitch, BMF_1BPP, 0, glyph->bitmap.buffer);
|
||||||
SourceGlyphSurf = (PSURFOBJ)AccessUserObject(HSourceGlyph);
|
SourceGlyphSurf = (PSURFOBJ)AccessUserObject((ULONG) HSourceGlyph);
|
||||||
|
|
||||||
// Use the font data as a mask to paint onto the DCs surface using a brush
|
// Use the font data as a mask to paint onto the DCs surface using a brush
|
||||||
IntEngBitBlt(SurfObj, NULL, SourceGlyphSurf, NULL, NULL, &DestRect, &SourcePoint, &MaskRect, Brush, &BrushOrigin, 0xAACC);
|
IntEngBitBlt(SurfObj, NULL, SourceGlyphSurf, NULL, NULL, &DestRect, &SourcePoint, &MaskRect, Brush, &BrushOrigin, 0xAACC);
|
||||||
|
@ -760,3 +877,50 @@ W32kTranslateCharsetInfo(PDWORD Src,
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
UNIMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
TextIntRealizeFont(HFONT FontHandle)
|
||||||
|
{
|
||||||
|
UINT i;
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
PTEXTOBJ TextObj;
|
||||||
|
|
||||||
|
TextObj = TEXTOBJ_LockText(FontHandle);
|
||||||
|
ASSERT(TextObj);
|
||||||
|
if (NULL != TextObj)
|
||||||
|
{
|
||||||
|
for(i = 0; NULL == TextObj->GDIFontHandle && i < FontsLoaded; i++)
|
||||||
|
{
|
||||||
|
if (0 == wcscmp(FontTable[i].FaceName, TextObj->logfont.lfFaceName))
|
||||||
|
{
|
||||||
|
TextObj->GDIFontHandle = FontTable[i].hFont;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NULL == TextObj->GDIFontHandle)
|
||||||
|
{
|
||||||
|
if (0 != FontsLoaded)
|
||||||
|
{
|
||||||
|
DPRINT("Requested font %S not found, using first available font\n",
|
||||||
|
TextObj->logfont.lfFaceName)
|
||||||
|
TextObj->GDIFontHandle = FontTable[0].hFont;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DPRINT1("Requested font %S not found, no fonts loaded at all\n",
|
||||||
|
TextObj->logfont.lfFaceName)
|
||||||
|
Status = STATUS_NOT_FOUND;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSERT(! NT_SUCCESS(Status) || NULL != TextObj->GDIFontHandle);
|
||||||
|
|
||||||
|
TEXTOBJ_UnlockText(FontHandle);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Status = STATUS_INVALID_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue