diff --git a/reactos/include/win32k/text.h b/reactos/include/win32k/text.h index 47b21697765..96e650734f3 100644 --- a/reactos/include/win32k/text.h +++ b/reactos/include/win32k/text.h @@ -14,15 +14,12 @@ typedef struct #define TEXTOBJ_AllocText() \ ((HFONT) GDIOBJ_AllocObj (sizeof (TEXTOBJ), GO_FONT_MAGIC)) #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_UnlockText(hBMObj) GDIOBJ_UnlockObj ((HGDIOBJ) hBMObj, GO_FONT_MAGIC) +NTSTATUS TextIntRealizeFont(HFONT FontHandle); +NTSTATUS TextIntCreateFontIndirect(CONST LPLOGFONTW lf, HFONT *NewFont); + int STDCALL W32kAddFontResource(LPCWSTR Filename); diff --git a/reactos/subsys/win32k/main/dllmain.c b/reactos/subsys/win32k/main/dllmain.c index 90719b0f930..2341c014700 100644 --- a/reactos/subsys/win32k/main/dllmain.c +++ b/reactos/subsys/win32k/main/dllmain.c @@ -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 */ @@ -109,12 +109,12 @@ W32kInitialize (VOID) // Create surface used to draw the internal font onto CreateCellCharSurface(); - // Create stock objects, ie. precreated objects commonly used by win32 applications - CreateStockObjects(); - // Initialize FreeType library if(!InitFontSupport()) return FALSE; + // Create stock objects, ie. precreated objects commonly used by win32 applications + CreateStockObjects(); + return TRUE; } diff --git a/reactos/subsys/win32k/objects/dc.c b/reactos/subsys/win32k/objects/dc.c index 220bcc4b54a..ac83642e27d 100644 --- a/reactos/subsys/win32k/objects/dc.c +++ b/reactos/subsys/win32k/objects/dc.c @@ -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 * @@ -1075,6 +1075,7 @@ HGDIOBJ STDCALL W32kSelectObject(HDC hDC, HGDIOBJ hGDIObj) case GO_FONT_MAGIC: objOrg = (HGDIOBJ)dc->w.hFont; dc->w.hFont = (HFONT) hGDIObj; + TextIntRealizeFont(dc->w.hFont); break; case GO_BITMAP_MAGIC: diff --git a/reactos/subsys/win32k/objects/gdiobj.c b/reactos/subsys/win32k/objects/gdiobj.c index d145c116d99..6da2accb09e 100644 --- a/reactos/subsys/win32k/objects/gdiobj.c +++ b/reactos/subsys/win32k/objects/gdiobj.c @@ -1,7 +1,7 @@ /* * 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); GDIOBJ_MarkObjectGlobal(StockObjects[NULL_PEN]); - StockObjects[OEM_FIXED_FONT] = W32kCreateFontIndirect(&OEMFixedFont); + (void) TextIntCreateFontIndirect(&OEMFixedFont, &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]); - StockObjects[SYSTEM_FONT] = W32kCreateFontIndirect(&SystemFont); + (void) TextIntCreateFontIndirect(&SystemFont, &StockObjects[SYSTEM_FONT]); GDIOBJ_MarkObjectGlobal(StockObjects[SYSTEM_FONT]); - StockObjects[DEVICE_DEFAULT_FONT] = - W32kCreateFontIndirect(&DeviceDefaultFont); + (void) TextIntCreateFontIndirect(&DeviceDefaultFont, &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]); - StockObjects[DEFAULT_GUI_FONT] = W32kCreateFontIndirect(&DefaultGuiFont); + (void) TextIntCreateFontIndirect(&DefaultGuiFont, &StockObjects[DEFAULT_GUI_FONT]); GDIOBJ_MarkObjectGlobal(StockObjects[DEFAULT_GUI_FONT]); StockObjects[DEFAULT_PALETTE] = (HGDIOBJ*)PALETTE_Init(); diff --git a/reactos/subsys/win32k/objects/text.c b/reactos/subsys/win32k/objects/text.c index 2f73029841c..a8fc0f619f0 100644 --- a/reactos/subsys/win32k/objects/text.c +++ b/reactos/subsys/win32k/objects/text.c @@ -3,6 +3,7 @@ #undef WIN32_LEAN_AND_MEAN #include #include +#include #include #include #include @@ -36,14 +37,57 @@ BOOL InitFontSupport() return FALSE; } +#ifndef TODO + W32kAddFontResource(L"\\SystemRoot\\media\\fonts\\arial.ttf"); +#endif W32kAddFontResource(L"\\SystemRoot\\media\\fonts\\helb____.ttf"); W32kAddFontResource(L"\\SystemRoot\\media\\fonts\\timr____.ttf"); - DbgPrint("All fonts loaded\n"); + DPRINT("All fonts loaded\n"); 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 STDCALL W32kAddFontResource(LPCWSTR Filename) @@ -65,8 +109,8 @@ W32kAddFontResource(LPCWSTR Filename) IO_STATUS_BLOCK Iosb; NewFont = (HFONT)CreateGDIHandle(sizeof( FONTGDI ), sizeof( FONTOBJ )); - FontObj = (PFONTOBJ) AccessUserObject( NewFont ); - FontGDI = (PFONTGDI) AccessInternalObject( NewFont ); + FontObj = (PFONTOBJ) AccessUserObject( (ULONG) NewFont ); + FontGDI = (PFONTGDI) AccessInternalObject( (ULONG) NewFont ); RtlCreateUnicodeString(&uFileName, (LPWSTR)Filename); @@ -77,7 +121,7 @@ W32kAddFontResource(LPCWSTR Filename) if (!NT_SUCCESS(Status)) { - DbgPrint("Could not open module file: %S\n", Filename); + DPRINT1("Could not open module file: %S\n", Filename); return 0; } @@ -85,7 +129,7 @@ W32kAddFontResource(LPCWSTR Filename) Status = NtQueryInformationFile(FileHandle, &Iosb, &FileStdInfo, sizeof(FileStdInfo), FileStandardInformation); if (!NT_SUCCESS(Status)) { - DbgPrint("Could not get file size\n"); + DPRINT1("Could not get file size\n"); return 0; } @@ -95,7 +139,7 @@ W32kAddFontResource(LPCWSTR Filename) if (buffer == NULL) { - DbgPrint("could not allocate memory for module"); + DPRINT1("could not allocate memory for module"); return 0; } @@ -103,7 +147,7 @@ W32kAddFontResource(LPCWSTR Filename) Status = NtReadFile(FileHandle, 0, 0, 0, &Iosb, buffer, FileStdInfo.EndOfFile.u.LowPart, 0, 0); if (!NT_SUCCESS(Status)) { - DbgPrint("could not read module file into memory"); + DPRINT1("could not read module file into memory"); ExFreePool(buffer); return 0; } @@ -113,12 +157,12 @@ W32kAddFontResource(LPCWSTR Filename) error = FT_New_Memory_Face(library, buffer, size, 0, &face); if (error == FT_Err_Unknown_File_Format) { - DbgPrint("Unknown font file format\n"); + DPRINT1("Unknown font file format\n"); return 0; } 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; } @@ -130,7 +174,7 @@ W32kAddFontResource(LPCWSTR Filename) FontGDI->TextMetric.tmDescent = face->size->metrics.descender; // units below baseline 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); // Add this font resource to the font table @@ -147,24 +191,60 @@ W32kAddFontResource(LPCWSTR Filename) 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 STDCALL W32kCreateFont(int Height, - int Width, - int Escapement, - int Orientation, - int Weight, - DWORD Italic, - DWORD Underline, - DWORD StrikeOut, - DWORD CharSet, - DWORD OutputPrecision, - DWORD ClipPrecision, - DWORD Quality, - DWORD PitchAndFamily, - LPCWSTR Face) + int Width, + int Escapement, + int Orientation, + int Weight, + DWORD Italic, + DWORD Underline, + DWORD StrikeOut, + DWORD CharSet, + DWORD OutputPrecision, + DWORD ClipPrecision, + DWORD Quality, + DWORD PitchAndFamily, + LPCWSTR Face) { LOGFONTW logfont; + HFONT NewFont; + NTSTATUS Status = STATUS_SUCCESS; logfont.lfHeight = Height; logfont.lfWidth = Width; @@ -180,40 +260,45 @@ W32kCreateFont(int Height, logfont.lfQuality = Quality; logfont.lfPitchAndFamily = PitchAndFamily; - if(Face) - memcpy(logfont.lfFaceName, Face, sizeof(logfont.lfFaceName)); + if (NULL != Face) + { + Status = MmCopyFromCaller(logfont.lfFaceName, Face, sizeof(logfont.lfFaceName)); + } else + { logfont.lfFaceName[0] = L'\0'; + } - return W32kCreateFontIndirect(&logfont); + if (NT_SUCCESS(Status)) + { + Status = TextIntCreateFontIndirect(&logfont, &NewFont); + } + + return NT_SUCCESS(Status) ? NewFont : NULL; } HFONT STDCALL -W32kCreateFontIndirect(CONST LPLOGFONTW lf) +W32kCreateFontIndirect(CONST LPLOGFONTW lf) { - HFONT hFont = 0; - PTEXTOBJ fontPtr; + LOGFONTW SafeLogfont; + 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 ); - 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 ); - } + Status = TextIntCreateFontIndirect(&SafeLogfont, &NewFont); } } + else + { + Status = STATUS_INVALID_PARAMETER; + } - return hFont; + return NT_SUCCESS(Status) ? NewFont : NULL; } BOOL @@ -425,26 +510,26 @@ W32kGetTextExtentPoint(HDC hDC, int Count, LPSIZE Size) { - PDC dc = (PDC)AccessUserObject(hDC); + PDC dc = (PDC)AccessUserObject((ULONG) hDC); PFONTGDI FontGDI; FT_Face face; FT_GlyphSlot glyph; INT error, pitch, glyph_index, i; 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; iglyph; if (glyph->format == ft_glyph_format_outline) { 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; } else { pitch = glyph->bitmap.width; @@ -484,16 +569,59 @@ W32kGetTextFace(HDC hDC, BOOL STDCALL -W32kGetTextMetrics(HDC hDC, - LPTEXTMETRICW tm) +W32kGetTextMetrics(HDC hDC, + LPTEXTMETRICW tm) { - PDC dc = (PDC)AccessUserObject(hDC); + PDC dc; + PTEXTOBJ TextObj; PFONTGDI FontGDI; + NTSTATUS Status = STATUS_SUCCESS; + TEXTMETRICW SafeTm; + FT_Face Face; + ULONG Error; - FontGDI = (PFONTGDI)AccessInternalObject(dc->w.hFont); - memcpy(tm, &FontGDI->TextMetric, sizeof(TEXTMETRICW)); + dc = DC_HandleToPtr(hDC); + 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 @@ -578,11 +706,11 @@ W32kTextOut(HDC hDC, // Fixme: Call EngTextOut, which does the real work (calling DrvTextOut where appropriate) DC *dc = DC_HandleToPtr(hDC); - SURFOBJ *SurfObj = (SURFOBJ*)AccessUserObject(dc->Surface); - int error, glyph_index, n, load_flags = FT_LOAD_RENDER, i, j, sx, sy, scc; + SURFOBJ *SurfObj = (SURFOBJ*)AccessUserObject((ULONG) dc->Surface); + int error, glyph_index, n, i; FT_Face face; FT_GlyphSlot glyph; - ULONG TextLeft, TextTop, SpaceBetweenChars = 2, pitch, previous; + ULONG TextLeft, TextTop, pitch, previous; FT_Bool use_kerning; RECTL DestRect, MaskRect; POINTL SourcePoint, BrushOrigin; @@ -593,7 +721,6 @@ W32kTextOut(HDC hDC, SIZEL bitSize; FT_CharMap found = 0, charmap; INT yoff; - HFONT hFont = 0; PFONTOBJ FontObj; PFONTGDI FontGDI; PTEXTOBJ TextObj; @@ -610,50 +737,40 @@ W32kTextOut(HDC hDC, TextObj = TEXTOBJ_LockText(dc->w.hFont); - for(i=0; ilogfont.lfFaceName) == 0) - hFont = FontTable[i].hFont; + goto fail; } - - 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; if (face->charmap == NULL) { - DbgPrint("WARNING: No charmap selected!\n"); - DbgPrint("This font face has %d charmaps\n", face->num_charmaps); + DPRINT("WARNING: No charmap selected!\n"); + DPRINT("This font face has %d charmaps\n", face->num_charmaps); for (n = 0; n < face->num_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) { found = charmap; 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); - 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); if(error) { - DbgPrint("Error in setting pixel sizes: %u\n", error); + DPRINT1("Error in setting pixel sizes: %u\n", error); goto fail; } // 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); hBrush = W32kCreateSolidBrush(XLATEOBJ_iXlate(XlateObj, dc->w.textColor)); Brush = BRUSHOBJ_LockBrush(hBrush); @@ -686,7 +803,7 @@ W32kTextOut(HDC hDC, glyph_index = FT_Get_Char_Index(face, *String); 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); + DPRINT1("WARNING: Failed to load and render glyph! [index: %u]\n", glyph_index); goto fail; } glyph = face->glyph; @@ -703,7 +820,7 @@ W32kTextOut(HDC hDC, { error = FT_Render_Glyph(glyph, ft_render_mode_mono); if(error) { - DbgPrint("WARNING: Failed to render glyph!\n"); + DPRINT1("WARNING: Failed to render glyph!\n"); goto fail; } 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 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 IntEngBitBlt(SurfObj, NULL, SourceGlyphSurf, NULL, NULL, &DestRect, &SourcePoint, &MaskRect, Brush, &BrushOrigin, 0xAACC); @@ -760,3 +877,50 @@ W32kTranslateCharsetInfo(PDWORD Src, { 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; +}