X-Git-Url: http://git.jankratochvil.net/?p=reactos.git;a=blobdiff_plain;f=subsys%2Fwin32k%2Fobjects%2Ftext.c;fp=subsys%2Fwin32k%2Fobjects%2Ftext.c;h=0950c5d282d4dd3f7309d814f39aaa057c9e413c;hp=b5e7026ad1e9c05c1b95203ee8310ad811ded39e;hb=a3df8bf1429570e0bd6c6428f6ed80073578cf4b;hpb=7c0db166f81fbe8c8b913d7f26048e337d383605 diff --git a/subsys/win32k/objects/text.c b/subsys/win32k/objects/text.c index b5e7026..0950c5d 100644 --- a/subsys/win32k/objects/text.c +++ b/subsys/win32k/objects/text.c @@ -1,3 +1,22 @@ +/* + * ReactOS W32 Subsystem + * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/* $Id$ */ #undef WIN32_LEAN_AND_MEAN @@ -8,12 +27,16 @@ #include #include #include +#include #include #include FT_FREETYPE_H #include "../eng/handle.h" #include +#include +#include +#include #define NDEBUG #include @@ -28,9 +51,25 @@ typedef struct _FONTTABLE { FONTTABLE FontTable[256]; INT FontsLoaded = 0; -BOOL InitFontSupport() +BOOL FASTCALL InitFontSupport(VOID) { ULONG error; + UINT File; + static WCHAR *FontFiles[] = + { + L"\\SystemRoot\\media\\fonts\\Vera.ttf", + L"\\SystemRoot\\media\\fonts\\helb____.ttf", + L"\\SystemRoot\\media\\fonts\\timr____.ttf", + L"\\SystemRoot\\media\\fonts\\VeraBd.ttf", + L"\\SystemRoot\\media\\fonts\\VeraBI.ttf", + L"\\SystemRoot\\media\\fonts\\VeraIt.ttf", + L"\\SystemRoot\\media\\fonts\\VeraMoBd.ttf", + L"\\SystemRoot\\media\\fonts\\VeraMoBI.ttf", + L"\\SystemRoot\\media\\fonts\\VeraMoIt.ttf", + L"\\SystemRoot\\media\\fonts\\VeraMono.ttf", + L"\\SystemRoot\\media\\fonts\\VeraSe.ttf", + L"\\SystemRoot\\media\\fonts\\VeraSeBd.ttf" + }; error = FT_Init_FreeType(&library); if(error) @@ -38,21 +77,21 @@ 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"); + for (File = 0; File < sizeof(FontFiles) / sizeof(WCHAR *); File++) + { + DPRINT("Loading font %S\n", FontFiles[File]); + + NtGdiAddFontResource(FontFiles[File]); + } DPRINT("All fonts loaded\n"); return TRUE; } -static NTSTATUS +static NTSTATUS STDCALL GetFontObjectsFromTextObj(PTEXTOBJ TextObj, HFONT *FontHandle, PFONTOBJ *FontObj, PFONTGDI *FontGDI) { - UINT i; NTSTATUS Status = STATUS_SUCCESS; ASSERT(NULL != TextObj && NULL != TextObj->GDIFontHandle); @@ -91,7 +130,7 @@ GetFontObjectsFromTextObj(PTEXTOBJ TextObj, HFONT *FontHandle, PFONTOBJ *FontObj int STDCALL -W32kAddFontResource(LPCWSTR Filename) +NtGdiAddFontResource(LPCWSTR Filename) { HFONT NewFont; PFONTOBJ FontObj; @@ -171,8 +210,8 @@ W32kAddFontResource(LPCWSTR Filename) FontGDI->face = face; // FIXME: Complete text metrics - FontGDI->TextMetric.tmAscent = face->size->metrics.ascender; // units above baseline - FontGDI->TextMetric.tmDescent = face->size->metrics.descender; // units below baseline + FontGDI->TextMetric.tmAscent = (face->size->metrics.ascender + 32) / 64; // units above baseline + FontGDI->TextMetric.tmDescent = (- face->size->metrics.descender + 32) / 64; // units below baseline FontGDI->TextMetric.tmHeight = FontGDI->TextMetric.tmAscent + FontGDI->TextMetric.tmDescent; DPRINT("Font loaded: %s (%s)\n", face->family_name, face->style_name); @@ -192,7 +231,7 @@ W32kAddFontResource(LPCWSTR Filename) return 1; } -NTSTATUS +NTSTATUS FASTCALL TextIntCreateFontIndirect(CONST LPLOGFONTW lf, HFONT *NewFont) { PTEXTOBJ TextObj; @@ -214,8 +253,9 @@ TextIntCreateFontIndirect(CONST LPLOGFONTW lf, HFONT *NewFont) } else { - ASSERT(FALSE); - Status = STATUS_INVALID_HANDLE; +/* FIXME */ +/* ASSERT(FALSE);*/ + Status = STATUS_INVALID_HANDLE; } } else @@ -228,7 +268,7 @@ TextIntCreateFontIndirect(CONST LPLOGFONTW lf, HFONT *NewFont) HFONT STDCALL -W32kCreateFont(int Height, +NtGdiCreateFont(int Height, int Width, int Escapement, int Orientation, @@ -263,7 +303,10 @@ W32kCreateFont(int Height, if (NULL != Face) { - Status = MmCopyFromCaller(logfont.lfFaceName, Face, sizeof(logfont.lfFaceName)); + int Size = sizeof(logfont.lfFaceName) / sizeof(WCHAR); + wcsncpy((wchar_t *)logfont.lfFaceName, Face, Size - 1); + /* Be 101% sure to have '\0' at end of string */ + logfont.lfFaceName[Size - 1] = '\0'; } else { @@ -280,7 +323,7 @@ W32kCreateFont(int Height, HFONT STDCALL -W32kCreateFontIndirect(CONST LPLOGFONTW lf) +NtGdiCreateFontIndirect(CONST LPLOGFONTW lf) { LOGFONTW SafeLogfont; HFONT NewFont; @@ -304,7 +347,7 @@ W32kCreateFontIndirect(CONST LPLOGFONTW lf) BOOL STDCALL -W32kCreateScalableFontResource(DWORD Hidden, +NtGdiCreateScalableFontResource(DWORD Hidden, LPCWSTR FontRes, LPCWSTR FontFile, LPCWSTR CurrentPath) @@ -314,7 +357,7 @@ W32kCreateScalableFontResource(DWORD Hidden, int STDCALL -W32kEnumFontFamilies(HDC hDC, +NtGdiEnumFontFamilies(HDC hDC, LPCWSTR Family, FONTENUMPROCW EnumFontFamProc, LPARAM lParam) @@ -324,9 +367,9 @@ W32kEnumFontFamilies(HDC hDC, int STDCALL -W32kEnumFontFamiliesEx(HDC hDC, +NtGdiEnumFontFamiliesEx(HDC hDC, LPLOGFONTW Logfont, - FONTENUMPROCW EnumFontFamExProc, + FONTENUMEXPROCW EnumFontFamExProc, LPARAM lParam, DWORD Flags) { @@ -335,7 +378,7 @@ W32kEnumFontFamiliesEx(HDC hDC, int STDCALL -W32kEnumFonts(HDC hDC, +NtGdiEnumFonts(HDC hDC, LPCWSTR FaceName, FONTENUMPROCW FontFunc, LPARAM lParam) @@ -345,7 +388,7 @@ W32kEnumFonts(HDC hDC, BOOL STDCALL -W32kExtTextOut(HDC hDC, +NtGdiExtTextOut(HDC hDC, int X, int Y, UINT Options, @@ -359,7 +402,7 @@ W32kExtTextOut(HDC hDC, BOOL STDCALL -W32kGetAspectRatioFilterEx(HDC hDC, +NtGdiGetAspectRatioFilterEx(HDC hDC, LPSIZE AspectRatio) { UNIMPLEMENTED; @@ -367,7 +410,7 @@ W32kGetAspectRatioFilterEx(HDC hDC, BOOL STDCALL -W32kGetCharABCWidths(HDC hDC, +NtGdiGetCharABCWidths(HDC hDC, UINT FirstChar, UINT LastChar, LPABC abc) @@ -377,7 +420,7 @@ W32kGetCharABCWidths(HDC hDC, BOOL STDCALL -W32kGetCharABCWidthsFloat(HDC hDC, +NtGdiGetCharABCWidthsFloat(HDC hDC, UINT FirstChar, UINT LastChar, LPABCFLOAT abcF) @@ -387,11 +430,11 @@ W32kGetCharABCWidthsFloat(HDC hDC, DWORD STDCALL -W32kGetCharacterPlacement(HDC hDC, +NtGdiGetCharacterPlacement(HDC hDC, LPCWSTR String, int Count, int MaxExtent, - LPGCP_RESULTS Results, + LPGCP_RESULTSW Results, DWORD Flags) { UNIMPLEMENTED; @@ -399,7 +442,7 @@ W32kGetCharacterPlacement(HDC hDC, BOOL STDCALL -W32kGetCharWidth(HDC hDC, +NtGdiGetCharWidth(HDC hDC, UINT FirstChar, UINT LastChar, LPINT Buffer) @@ -409,7 +452,7 @@ W32kGetCharWidth(HDC hDC, BOOL STDCALL -W32kGetCharWidth32(HDC hDC, +NtGdiGetCharWidth32(HDC hDC, UINT FirstChar, UINT LastChar, LPINT Buffer) @@ -419,7 +462,7 @@ W32kGetCharWidth32(HDC hDC, BOOL STDCALL -W32kGetCharWidthFloat(HDC hDC, +NtGdiGetCharWidthFloat(HDC hDC, UINT FirstChar, UINT LastChar, PFLOAT Buffer) @@ -429,14 +472,14 @@ W32kGetCharWidthFloat(HDC hDC, DWORD STDCALL -W32kGetFontLanguageInfo(HDC hDC) +NtGdiGetFontLanguageInfo(HDC hDC) { UNIMPLEMENTED; } DWORD STDCALL -W32kGetGlyphOutline(HDC hDC, +NtGdiGetGlyphOutline(HDC hDC, UINT Char, UINT Format, LPGLYPHMETRICS gm, @@ -451,7 +494,7 @@ W32kGetGlyphOutline(HDC hDC, DWORD STDCALL -W32kGetKerningPairs(HDC hDC, +NtGdiGetKerningPairs(HDC hDC, DWORD NumPairs, LPKERNINGPAIR krnpair) { @@ -460,7 +503,7 @@ W32kGetKerningPairs(HDC hDC, UINT STDCALL -W32kGetOutlineTextMetrics(HDC hDC, +NtGdiGetOutlineTextMetrics(HDC hDC, UINT Data, LPOUTLINETEXTMETRICW otm) { @@ -469,7 +512,7 @@ W32kGetOutlineTextMetrics(HDC hDC, BOOL STDCALL -W32kGetRasterizerCaps(LPRASTERIZER_STATUS rs, +NtGdiGetRasterizerCaps(LPRASTERIZER_STATUS rs, UINT Size) { UNIMPLEMENTED; @@ -477,91 +520,371 @@ W32kGetRasterizerCaps(LPRASTERIZER_STATUS rs, UINT STDCALL -W32kGetTextCharset(HDC hDC) +NtGdiGetTextCharset(HDC hDC) { UNIMPLEMENTED; } UINT STDCALL -W32kGetTextCharsetInfo(HDC hDC, +NtGdiGetTextCharsetInfo(HDC hDC, LPFONTSIGNATURE Sig, DWORD Flags) { UNIMPLEMENTED; } -BOOL -STDCALL -W32kGetTextExtentExPoint(HDC hDC, - LPCWSTR String, - int Count, - int MaxExtent, - LPINT Fit, - LPINT Dx, - LPSIZE Size) +static BOOL +FASTCALL +TextIntGetTextExtentPoint(PTEXTOBJ TextObj, + LPCWSTR String, + int Count, + int MaxExtent, + LPINT Fit, + LPINT Dx, + LPSIZE Size) { - UNIMPLEMENTED; + PFONTGDI FontGDI; + FT_Face face; + FT_GlyphSlot glyph; + INT error, n, glyph_index, i, previous; + LONG TotalWidth = 0, MaxHeight = 0; + FT_CharMap charmap, found = NULL; + BOOL use_kerning; + + GetFontObjectsFromTextObj(TextObj, NULL, NULL, &FontGDI); + face = FontGDI->face; + if (NULL != Fit) + { + *Fit = 0; + } + + if (face->charmap == NULL) + { + 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]; + DPRINT("found charmap encoding: %u\n", charmap->encoding); + if (charmap->encoding != 0) + { + found = charmap; + break; + } + } + + if (! found) + { + DPRINT1("WARNING: Could not find desired charmap!\n"); + } + + error = FT_Set_Charmap(face, found); + if (error) + { + DPRINT1("WARNING: Could not set the charmap!\n"); + } + } + + error = FT_Set_Pixel_Sizes(face, + /* FIXME should set character height if neg */ + (TextObj->logfont.lfHeight < 0 ? + - TextObj->logfont.lfHeight : + TextObj->logfont.lfHeight), + TextObj->logfont.lfWidth); + if (error) + { + DPRINT1("Error in setting pixel sizes: %u\n", error); + } + + use_kerning = FT_HAS_KERNING(face); + previous = 0; + + for (i = 0; i < Count; i++) + { + glyph_index = FT_Get_Char_Index(face, *String); + error = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT); + if (error) + { + DPRINT1("WARNING: Failed to load and render glyph! [index: %u]\n", glyph_index); + } + glyph = face->glyph; + + /* retrieve kerning distance */ + if (use_kerning && previous && glyph_index) + { + FT_Vector delta; + FT_Get_Kerning(face, previous, glyph_index, 0, &delta); + TotalWidth += delta.x >> 6; + } + + TotalWidth += glyph->advance.x >> 6; + if (glyph->format == ft_glyph_format_outline) + { + error = FT_Render_Glyph(glyph, ft_render_mode_mono); + if (error) + { + DPRINT1("WARNING: Failed to render glyph!\n"); + } + + if (0 != glyph->bitmap.rows && MaxHeight < (glyph->bitmap.rows - 1)) + { + MaxHeight = glyph->bitmap.rows - 1; + } + } + + if (TotalWidth <= MaxExtent && NULL != Fit) + { + *Fit = i + 1; + } + if (NULL != Dx) + { + Dx[i] = TotalWidth; + } + + previous = glyph_index; + String++; + } + + Size->cx = TotalWidth; + Size->cy = MaxHeight; + + return TRUE; } BOOL STDCALL -W32kGetTextExtentPoint(HDC hDC, - LPCWSTR String, - int Count, - LPSIZE Size) +NtGdiGetTextExtentExPoint(HDC hDC, + LPCWSTR UnsafeString, + int Count, + int MaxExtent, + LPINT UnsafeFit, + LPINT UnsafeDx, + LPSIZE UnsafeSize) { - 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; + PDC dc; + LPWSTR String; + SIZE Size; + NTSTATUS Status; + BOOLEAN Result; + INT Fit; + LPINT Dx; + PTEXTOBJ TextObj; - FontGDI = (PFONTGDI)AccessInternalObject((ULONG) dc->w.hFont); + if (Count < 0) + { + SetLastWin32Error(ERROR_INVALID_PARAMETER); + return FALSE; + } + if (0 == Count) + { + Size.cx = 0; + Size.cy = 0; + Status = MmCopyToCaller(UnsafeSize, &Size, sizeof(SIZE)); + if (! NT_SUCCESS(Status)) + { + SetLastNtError(Status); + return FALSE; + } + return TRUE; + } - for(i=0; iglyph; + String = ExAllocatePool(PagedPool, Count * sizeof(WCHAR)); + if (NULL == String) + { + SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; + } - if (glyph->format == ft_glyph_format_outline) + if (NULL != UnsafeDx) { - error = FT_Render_Glyph(glyph, ft_render_mode_mono); - if(error) DPRINT1("WARNING: Failed to render glyph!\n"); - pitch = glyph->bitmap.pitch; - } else { - pitch = glyph->bitmap.width; + Dx = ExAllocatePool(PagedPool, Count * sizeof(INT)); + if (NULL == Dx) + { + ExFreePool(String); + SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; + } + } + else + { + Dx = NULL; } - TotalWidth += pitch-1; - if((glyph->bitmap.rows-1) > MaxHeight) MaxHeight = glyph->bitmap.rows-1; + Status = MmCopyFromCaller(String, UnsafeString, Count * sizeof(WCHAR)); + if (! NT_SUCCESS(Status)) + { + if (NULL != Dx) + { + ExFreePool(Dx); + } + ExFreePool(String); + SetLastNtError(Status); + return FALSE; + } - CurrentChar++; + dc = DC_LockDc(hDC); + if (NULL == dc) + { + if (NULL != Dx) + { + ExFreePool(Dx); + } + ExFreePool(String); + SetLastWin32Error(ERROR_INVALID_HANDLE); + return FALSE; + } + TextObj = TEXTOBJ_LockText(dc->w.hFont); + DC_UnlockDc(hDC); + Result = TextIntGetTextExtentPoint(TextObj, String, Count, MaxExtent, + NULL == UnsafeFit ? NULL : &Fit, Dx, &Size); + TEXTOBJ_UnlockText(dc->w.hFont); - if(CurrentChar < Size->cx) TotalWidth += SpaceBetweenChars; - String++; - } + ExFreePool(String); + if (! Result) + { + if (NULL != Dx) + { + ExFreePool(Dx); + } + return FALSE; + } - Size->cx = TotalWidth; - Size->cy = MaxHeight; + if (NULL != UnsafeFit) + { + Status = MmCopyToCaller(UnsafeFit, &Fit, sizeof(INT)); + if (! NT_SUCCESS(Status)) + { + if (NULL != Dx) + { + ExFreePool(Dx); + } + SetLastNtError(Status); + return FALSE; + } + } + + if (NULL != UnsafeDx) + { + Status = MmCopyToCaller(UnsafeDx, Dx, Count * sizeof(INT)); + if (! NT_SUCCESS(Status)) + { + if (NULL != Dx) + { + ExFreePool(Dx); + } + SetLastNtError(Status); + return FALSE; + } + } + if (NULL != Dx) + { + ExFreePool(Dx); + } + + Status = MmCopyToCaller(UnsafeSize, &Size, sizeof(SIZE)); + if (! NT_SUCCESS(Status)) + { + SetLastNtError(Status); + return FALSE; + } + + return TRUE; } BOOL STDCALL -W32kGetTextExtentPoint32(HDC hDC, - LPCWSTR String, - int Count, - LPSIZE Size) +NtGdiGetTextExtentPoint(HDC hDC, + LPCWSTR String, + int Count, + LPSIZE Size) { - UNIMPLEMENTED; + return NtGdiGetTextExtentExPoint(hDC, String, Count, 0, NULL, NULL, Size); +} + +BOOL +STDCALL +NtGdiGetTextExtentPoint32(HDC hDC, + LPCWSTR UnsafeString, + int Count, + LPSIZE UnsafeSize) +{ + PDC dc; + LPWSTR String; + SIZE Size; + NTSTATUS Status; + BOOLEAN Result; + PTEXTOBJ TextObj; + + if (Count < 0) + { + SetLastWin32Error(ERROR_INVALID_PARAMETER); + return FALSE; + } + if (0 == Count) + { + Size.cx = 0; + Size.cy = 0; + Status = MmCopyToCaller(UnsafeSize, &Size, sizeof(SIZE)); + if (! NT_SUCCESS(Status)) + { + SetLastNtError(Status); + return FALSE; + } + return TRUE; + } + + String = ExAllocatePool(PagedPool, Count * sizeof(WCHAR)); + if (NULL == String) + { + SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; + } + + Status = MmCopyFromCaller(String, UnsafeString, Count * sizeof(WCHAR)); + if (! NT_SUCCESS(Status)) + { + ExFreePool(String); + SetLastNtError(Status); + return FALSE; + } + + dc = DC_LockDc(hDC); + if (NULL == dc) + { + ExFreePool(String); + SetLastWin32Error(ERROR_INVALID_HANDLE); + return FALSE; + } + TextObj = TEXTOBJ_LockText(dc->w.hFont); + DC_UnlockDc(hDC); + Result = TextIntGetTextExtentPoint ( + TextObj, String, Count, 0, NULL, NULL, &Size); + dc = DC_LockDc(hDC); + ASSERT(dc); // it succeeded earlier, it should now, too + TEXTOBJ_UnlockText(dc->w.hFont); + DC_UnlockDc(hDC); + + ExFreePool(String); + if (! Result) + { + return FALSE; + } + + Status = MmCopyToCaller(UnsafeSize, &Size, sizeof(SIZE)); + if (! NT_SUCCESS(Status)) + { + SetLastNtError(Status); + return FALSE; + } + + return TRUE; } int STDCALL -W32kGetTextFace(HDC hDC, +NtGdiGetTextFace(HDC hDC, int Count, LPWSTR FaceName) { @@ -570,7 +893,7 @@ W32kGetTextFace(HDC hDC, BOOL STDCALL -W32kGetTextMetrics(HDC hDC, +NtGdiGetTextMetrics(HDC hDC, LPTEXTMETRICW tm) { PDC dc; @@ -581,7 +904,7 @@ W32kGetTextMetrics(HDC hDC, FT_Face Face; ULONG Error; - dc = DC_HandleToPtr(hDC); + dc = DC_LockDc(hDC); if (NULL == dc || NULL == tm) { Status = STATUS_INVALID_PARAMETER; @@ -595,7 +918,11 @@ W32kGetTextMetrics(HDC hDC, if (NT_SUCCESS(Status)) { Face = FontGDI->face; - Error = FT_Set_Pixel_Sizes(Face, TextObj->logfont.lfHeight, + Error = FT_Set_Pixel_Sizes(Face, + /* FIXME should set character height if neg */ + (TextObj->logfont.lfHeight < 0 ? + - TextObj->logfont.lfHeight : + TextObj->logfont.lfHeight), TextObj->logfont.lfWidth); if (0 != Error) { @@ -606,9 +933,8 @@ W32kGetTextMetrics(HDC hDC, { 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; + SafeTm.tmDescent = (- Face->size->metrics.descender + 32) / 64; // units below baseline + SafeTm.tmHeight = SafeTm.tmAscent + SafeTm.tmDescent; Status = MmCopyToCaller(tm, &SafeTm, sizeof(TEXTMETRICW)); } } @@ -619,7 +945,7 @@ W32kGetTextMetrics(HDC hDC, ASSERT(FALSE); Status = STATUS_INVALID_HANDLE; } - DC_ReleasePtr(hDC); + DC_UnlockDc(hDC); } return NT_SUCCESS(Status); @@ -627,8 +953,8 @@ W32kGetTextMetrics(HDC hDC, BOOL STDCALL -W32kPolyTextOut(HDC hDC, - CONST LPPOLYTEXT txt, +NtGdiPolyTextOut(HDC hDC, + CONST LPPOLYTEXTW txt, int Count) { UNIMPLEMENTED; @@ -636,14 +962,14 @@ W32kPolyTextOut(HDC hDC, BOOL STDCALL -W32kRemoveFontResource(LPCWSTR FileName) +NtGdiRemoveFontResource(LPCWSTR FileName) { UNIMPLEMENTED; } DWORD STDCALL -W32kSetMapperFlags(HDC hDC, +NtGdiSetMapperFlags(HDC hDC, DWORD Flag) { UNIMPLEMENTED; @@ -651,30 +977,30 @@ W32kSetMapperFlags(HDC hDC, UINT STDCALL -W32kSetTextAlign(HDC hDC, +NtGdiSetTextAlign(HDC hDC, UINT Mode) { UINT prevAlign; DC *dc; - dc = DC_HandleToPtr(hDC); + dc = DC_LockDc(hDC); if (!dc) { return 0; } prevAlign = dc->w.textAlign; dc->w.textAlign = Mode; - DC_ReleasePtr( hDC ); + DC_UnlockDc( hDC ); return prevAlign; } COLORREF STDCALL -W32kSetTextColor(HDC hDC, +NtGdiSetTextColor(HDC hDC, COLORREF color) { COLORREF oldColor; - PDC dc = DC_HandleToPtr(hDC); + PDC dc = DC_LockDc(hDC); if (!dc) { @@ -683,13 +1009,13 @@ W32kSetTextColor(HDC hDC, oldColor = dc->w.textColor; dc->w.textColor = color; - DC_ReleasePtr( hDC ); + DC_UnlockDc( hDC ); return oldColor; } BOOL STDCALL -W32kSetTextJustification(HDC hDC, +NtGdiSetTextJustification(HDC hDC, int BreakExtra, int BreakCount) { @@ -698,7 +1024,7 @@ W32kSetTextJustification(HDC hDC, BOOL STDCALL -W32kTextOut(HDC hDC, +NtGdiTextOut(HDC hDC, int XStart, int YStart, LPCWSTR String, @@ -706,17 +1032,19 @@ W32kTextOut(HDC hDC, { // Fixme: Call EngTextOut, which does the real work (calling DrvTextOut where appropriate) - DC *dc = DC_HandleToPtr(hDC); - SURFOBJ *SurfObj = (SURFOBJ*)AccessUserObject((ULONG) dc->Surface); + DC *dc = DC_LockDc(hDC); + SURFOBJ *SurfObj; int error, glyph_index, n, i; FT_Face face; FT_GlyphSlot glyph; - ULONG TextLeft, TextTop, pitch, previous; + ULONG TextLeft, TextTop, pitch, previous, BackgroundLeft; FT_Bool use_kerning; RECTL DestRect, MaskRect; POINTL SourcePoint, BrushOrigin; - HBRUSH hBrush = NULL; - PBRUSHOBJ Brush = NULL; + HBRUSH hBrushFg = NULL; + PBRUSHOBJ BrushFg = NULL; + HBRUSH hBrushBg = NULL; + PBRUSHOBJ BrushBg = NULL; HBITMAP HSourceGlyph; PSURFOBJ SourceGlyphSurf; SIZEL bitSize; @@ -727,14 +1055,17 @@ W32kTextOut(HDC hDC, PTEXTOBJ TextObj; PPALGDI PalDestGDI; PXLATEOBJ XlateObj; + ULONG Mode; if( !dc ) return FALSE; + SurfObj = (SURFOBJ*)AccessUserObject((ULONG) dc->Surface); XStart += dc->w.DCOrgX; YStart += dc->w.DCOrgY; TextLeft = XStart; TextTop = YStart; + BackgroundLeft = XStart; TextObj = TEXTOBJ_LockText(dc->w.hFont); @@ -764,17 +1095,29 @@ W32kTextOut(HDC hDC, 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, + /* FIXME should set character height if neg */ + (TextObj->logfont.lfHeight < 0 ? + - TextObj->logfont.lfHeight : + TextObj->logfont.lfHeight), + TextObj->logfont.lfWidth); if(error) { DPRINT1("Error in setting pixel sizes: %u\n", error); goto fail; } - // Create the brush - 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); + // Create the brushes + PalDestGDI = PALETTE_LockPalette(dc->w.hPalette); + Mode = PalDestGDI->Mode; + PALETTE_UnlockPalette(dc->w.hPalette); + XlateObj = (PXLATEOBJ)IntEngCreateXlate(Mode, PAL_RGB, dc->w.hPalette, NULL); + hBrushFg = NtGdiCreateSolidBrush(XLATEOBJ_iXlate(XlateObj, dc->w.textColor)); + BrushFg = BRUSHOBJ_LockBrush(hBrushFg); + if (OPAQUE == dc->w.backgroundMode) + { + hBrushBg = NtGdiCreateSolidBrush(XLATEOBJ_iXlate(XlateObj, dc->w.backgroundColor)); + BrushBg = BRUSHOBJ_LockBrush(hBrushBg); + } EngDeleteXlate(XlateObj); SourcePoint.x = 0; @@ -829,11 +1172,32 @@ W32kTextOut(HDC hDC, pitch = glyph->bitmap.width; } + if (OPAQUE == dc->w.backgroundMode) + { + DestRect.left = BackgroundLeft; + DestRect.right = TextLeft + (glyph->advance.x + 32) / 64; + DestRect.top = TextTop + yoff - (face->size->metrics.ascender + 32) / 64; + DestRect.bottom = TextTop + yoff + (- face->size->metrics.descender + 32) / 64; + IntEngBitBlt(SurfObj, + NULL, + NULL, + dc->CombinedClip, + NULL, + &DestRect, + &SourcePoint, + &SourcePoint, + BrushBg, + &BrushOrigin, + PATCOPY); + BackgroundLeft = DestRect.right; + } + DestRect.left = TextLeft; - DestRect.top = TextTop + yoff - glyph->bitmap_top; DestRect.right = TextLeft + glyph->bitmap.width; + DestRect.top = TextTop + yoff - glyph->bitmap_top; DestRect.bottom = DestRect.top + glyph->bitmap.rows; - bitSize.cx = pitch; + + bitSize.cx = glyph->bitmap.width; bitSize.cy = glyph->bitmap.rows; MaskRect.right = glyph->bitmap.width; MaskRect.bottom = glyph->bitmap.rows; @@ -845,44 +1209,66 @@ W32kTextOut(HDC hDC, 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); + IntEngBitBlt ( + SurfObj, + NULL, + SourceGlyphSurf, + dc->CombinedClip, + NULL, + &DestRect, + &SourcePoint, + (PPOINTL)&MaskRect, + BrushFg, + &BrushOrigin, + 0xAACC ); EngDeleteSurface(HSourceGlyph); - TextLeft += glyph->advance.x >> 6; + TextLeft += (glyph->advance.x + 32) / 64; previous = glyph_index; String++; } - TEXTOBJ_UnlockText( dc->w.hFont ); - BRUSHOBJ_UnlockBrush(hBrush); - W32kDeleteObject( hBrush ); - DC_ReleasePtr( hDC ); + TEXTOBJ_UnlockText(dc->w.hFont); + if (NULL != hBrushBg) + { + BRUSHOBJ_UnlockBrush(hBrushBg); + NtGdiDeleteObject(hBrushBg); + } + BRUSHOBJ_UnlockBrush(hBrushFg); + NtGdiDeleteObject(hBrushFg); + DC_UnlockDc(hDC); return TRUE; fail: TEXTOBJ_UnlockText( dc->w.hFont ); - if( hBrush ){ - BRUSHOBJ_UnlockBrush(hBrush); - W32kDeleteObject( hBrush ); - } - DC_ReleasePtr( hDC ); + if (NULL != hBrushBg) + { + BRUSHOBJ_UnlockBrush(hBrushBg); + NtGdiDeleteObject(hBrushBg); + } + if (NULL != hBrushFg) + { + BRUSHOBJ_UnlockBrush(hBrushFg); + NtGdiDeleteObject(hBrushFg); + } + DC_UnlockDc( hDC ); return FALSE; } UINT STDCALL -W32kTranslateCharsetInfo(PDWORD Src, +NtGdiTranslateCharsetInfo(PDWORD Src, LPCHARSETINFO CSI, DWORD Flags) { UNIMPLEMENTED; } -NTSTATUS +NTSTATUS FASTCALL TextIntRealizeFont(HFONT FontHandle) { - UINT i; + LONG i; NTSTATUS Status = STATUS_SUCCESS; PTEXTOBJ TextObj; @@ -925,3 +1311,5 @@ TextIntRealizeFont(HFONT FontHandle) return Status; } + +/* EOF */