+/*
+ * 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
#include <win32k/dc.h>
#include <win32k/text.h>
#include <win32k/kapi.h>
+#include <include/error.h>
#include <ft2build.h>
#include FT_FREETYPE_H
#include "../eng/handle.h"
#include <include/inteng.h>
+#include <include/text.h>
+#include <include/eng.h>
+#include <include/palette.h>
#define NDEBUG
#include <win32k/debug1.h>
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)
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);
int
STDCALL
-W32kAddFontResource(LPCWSTR Filename)
+NtGdiAddFontResource(LPCWSTR Filename)
{
HFONT NewFont;
PFONTOBJ FontObj;
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);
return 1;
}
-NTSTATUS
+NTSTATUS FASTCALL
TextIntCreateFontIndirect(CONST LPLOGFONTW lf, HFONT *NewFont)
{
PTEXTOBJ TextObj;
}
else
{
- ASSERT(FALSE);
- Status = STATUS_INVALID_HANDLE;
+/* FIXME */
+/* ASSERT(FALSE);*/
+ Status = STATUS_INVALID_HANDLE;
}
}
else
HFONT
STDCALL
-W32kCreateFont(int Height,
+NtGdiCreateFont(int Height,
int Width,
int Escapement,
int Orientation,
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
{
HFONT
STDCALL
-W32kCreateFontIndirect(CONST LPLOGFONTW lf)
+NtGdiCreateFontIndirect(CONST LPLOGFONTW lf)
{
LOGFONTW SafeLogfont;
HFONT NewFont;
BOOL
STDCALL
-W32kCreateScalableFontResource(DWORD Hidden,
+NtGdiCreateScalableFontResource(DWORD Hidden,
LPCWSTR FontRes,
LPCWSTR FontFile,
LPCWSTR CurrentPath)
int
STDCALL
-W32kEnumFontFamilies(HDC hDC,
+NtGdiEnumFontFamilies(HDC hDC,
LPCWSTR Family,
FONTENUMPROCW EnumFontFamProc,
LPARAM lParam)
int
STDCALL
-W32kEnumFontFamiliesEx(HDC hDC,
+NtGdiEnumFontFamiliesEx(HDC hDC,
LPLOGFONTW Logfont,
- FONTENUMPROCW EnumFontFamExProc,
+ FONTENUMEXPROCW EnumFontFamExProc,
LPARAM lParam,
DWORD Flags)
{
int
STDCALL
-W32kEnumFonts(HDC hDC,
+NtGdiEnumFonts(HDC hDC,
LPCWSTR FaceName,
FONTENUMPROCW FontFunc,
LPARAM lParam)
BOOL
STDCALL
-W32kExtTextOut(HDC hDC,
+NtGdiExtTextOut(HDC hDC,
int X,
int Y,
UINT Options,
BOOL
STDCALL
-W32kGetAspectRatioFilterEx(HDC hDC,
+NtGdiGetAspectRatioFilterEx(HDC hDC,
LPSIZE AspectRatio)
{
UNIMPLEMENTED;
BOOL
STDCALL
-W32kGetCharABCWidths(HDC hDC,
+NtGdiGetCharABCWidths(HDC hDC,
UINT FirstChar,
UINT LastChar,
LPABC abc)
BOOL
STDCALL
-W32kGetCharABCWidthsFloat(HDC hDC,
+NtGdiGetCharABCWidthsFloat(HDC hDC,
UINT FirstChar,
UINT LastChar,
LPABCFLOAT abcF)
DWORD
STDCALL
-W32kGetCharacterPlacement(HDC hDC,
+NtGdiGetCharacterPlacement(HDC hDC,
LPCWSTR String,
int Count,
int MaxExtent,
- LPGCP_RESULTS Results,
+ LPGCP_RESULTSW Results,
DWORD Flags)
{
UNIMPLEMENTED;
BOOL
STDCALL
-W32kGetCharWidth(HDC hDC,
+NtGdiGetCharWidth(HDC hDC,
UINT FirstChar,
UINT LastChar,
LPINT Buffer)
BOOL
STDCALL
-W32kGetCharWidth32(HDC hDC,
+NtGdiGetCharWidth32(HDC hDC,
UINT FirstChar,
UINT LastChar,
LPINT Buffer)
BOOL
STDCALL
-W32kGetCharWidthFloat(HDC hDC,
+NtGdiGetCharWidthFloat(HDC hDC,
UINT FirstChar,
UINT LastChar,
PFLOAT Buffer)
DWORD
STDCALL
-W32kGetFontLanguageInfo(HDC hDC)
+NtGdiGetFontLanguageInfo(HDC hDC)
{
UNIMPLEMENTED;
}
DWORD
STDCALL
-W32kGetGlyphOutline(HDC hDC,
+NtGdiGetGlyphOutline(HDC hDC,
UINT Char,
UINT Format,
LPGLYPHMETRICS gm,
DWORD
STDCALL
-W32kGetKerningPairs(HDC hDC,
+NtGdiGetKerningPairs(HDC hDC,
DWORD NumPairs,
LPKERNINGPAIR krnpair)
{
UINT
STDCALL
-W32kGetOutlineTextMetrics(HDC hDC,
+NtGdiGetOutlineTextMetrics(HDC hDC,
UINT Data,
LPOUTLINETEXTMETRICW otm)
{
BOOL
STDCALL
-W32kGetRasterizerCaps(LPRASTERIZER_STATUS rs,
+NtGdiGetRasterizerCaps(LPRASTERIZER_STATUS rs,
UINT Size)
{
UNIMPLEMENTED;
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; 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;
+ 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)
{
BOOL
STDCALL
-W32kGetTextMetrics(HDC hDC,
+NtGdiGetTextMetrics(HDC hDC,
LPTEXTMETRICW tm)
{
PDC dc;
FT_Face Face;
ULONG Error;
- dc = DC_HandleToPtr(hDC);
+ dc = DC_LockDc(hDC);
if (NULL == dc || NULL == tm)
{
Status = STATUS_INVALID_PARAMETER;
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)
{
{
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));
}
}
ASSERT(FALSE);
Status = STATUS_INVALID_HANDLE;
}
- DC_ReleasePtr(hDC);
+ DC_UnlockDc(hDC);
}
return NT_SUCCESS(Status);
BOOL
STDCALL
-W32kPolyTextOut(HDC hDC,
- CONST LPPOLYTEXT txt,
+NtGdiPolyTextOut(HDC hDC,
+ CONST LPPOLYTEXTW txt,
int Count)
{
UNIMPLEMENTED;
BOOL
STDCALL
-W32kRemoveFontResource(LPCWSTR FileName)
+NtGdiRemoveFontResource(LPCWSTR FileName)
{
UNIMPLEMENTED;
}
DWORD
STDCALL
-W32kSetMapperFlags(HDC hDC,
+NtGdiSetMapperFlags(HDC hDC,
DWORD Flag)
{
UNIMPLEMENTED;
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)
{
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)
{
BOOL
STDCALL
-W32kTextOut(HDC hDC,
+NtGdiTextOut(HDC hDC,
int XStart,
int YStart,
LPCWSTR String,
{
// 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;
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);
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;
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;
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;
return Status;
}
+
+/* EOF */