Fix crash in W32kGetTextMetrics

svn path=/trunk/; revision=4448
This commit is contained in:
Gé van Geldorp 2003-03-28 16:20:51 +00:00
parent 34aacc4e6b
commit 5fff73db86
5 changed files with 259 additions and 98 deletions

View file

@ -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);

View file

@ -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;
} }

View file

@ -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:

View file

@ -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();

View file

@ -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;
}