mirror of
https://github.com/reactos/reactos.git
synced 2025-06-04 00:40:31 +00:00
Bug fixes.
svn path=/trunk/; revision=7161
This commit is contained in:
parent
d8fdb7eddc
commit
f2c4bc3f8b
6 changed files with 350 additions and 49 deletions
|
@ -10,6 +10,15 @@ NtGdiCombineTransform (
|
||||||
CONST LPXFORM xform1,
|
CONST LPXFORM xform1,
|
||||||
CONST LPXFORM xform2
|
CONST LPXFORM xform2
|
||||||
);
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
FASTCALL
|
||||||
|
IntDPtoLP ( PDC dc, LPPOINT Points, INT Count );
|
||||||
|
|
||||||
|
VOID
|
||||||
|
FASTCALL
|
||||||
|
CoordDPtoLP ( PDC Dc, LPPOINT Point );
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
STDCALL
|
STDCALL
|
||||||
NtGdiDPtoLP (
|
NtGdiDPtoLP (
|
||||||
|
|
|
@ -293,7 +293,7 @@ const struct builtin_class_descr EDIT_builtin_class =
|
||||||
{
|
{
|
||||||
#ifdef __REACTOS__
|
#ifdef __REACTOS__
|
||||||
L"Edit", /* name */
|
L"Edit", /* name */
|
||||||
/*TODO: Fix ExtTextOut so that we can have the CS_PARENTDC style*/
|
/* FIXME: Add CS_PARENTDC when the handling of WM_ERASEBKGND will be fixed! */
|
||||||
CS_GLOBALCLASS | CS_DBLCLKS, /* style */
|
CS_GLOBALCLASS | CS_DBLCLKS, /* style */
|
||||||
(WNDPROC)EditWndProcW, /* procW */
|
(WNDPROC)EditWndProcW, /* procW */
|
||||||
(WNDPROC)EditWndProcA, /* procA */
|
(WNDPROC)EditWndProcA, /* procA */
|
||||||
|
|
|
@ -1095,6 +1095,8 @@ DrawCaption(HWND hWnd, HDC hDC, LPCRECT lprc, UINT uFlags)
|
||||||
r.top ++;
|
r.top ++;
|
||||||
r.left += 2;
|
r.left += 2;
|
||||||
|
|
||||||
|
r.bottom = r.top + Height;
|
||||||
|
|
||||||
if ((uFlags & DC_TEXT) && (GetWindowTextW( hWnd, buffer, sizeof(buffer)/sizeof(buffer[0]) )))
|
if ((uFlags & DC_TEXT) && (GetWindowTextW( hWnd, buffer, sizeof(buffer)/sizeof(buffer[0]) )))
|
||||||
{
|
{
|
||||||
if (!(uFlags & DC_SMALLCAP) && ((uFlags & DC_ICON) || (uFlags & DC_INBUTTON)))
|
if (!(uFlags & DC_SMALLCAP) && ((uFlags & DC_ICON) || (uFlags & DC_INBUTTON)))
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
/* $Id: cliprgn.c,v 1.28 2003/12/15 20:47:57 navaraf Exp $ */
|
/* $Id: cliprgn.c,v 1.29 2003/12/21 18:38:37 navaraf Exp $ */
|
||||||
|
|
||||||
#undef WIN32_LEAN_AND_MEAN
|
#undef WIN32_LEAN_AND_MEAN
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
@ -163,14 +163,13 @@ IntGdiGetClipBox(HDC hDC,
|
||||||
LPRECT rc)
|
LPRECT rc)
|
||||||
{
|
{
|
||||||
int retval;
|
int retval;
|
||||||
DC *dc;
|
PDC dc;
|
||||||
|
|
||||||
if (!(dc = DC_LockDc(hDC)))
|
if (!(dc = DC_LockDc(hDC)))
|
||||||
return ERROR;
|
return ERROR;
|
||||||
retval = UnsafeIntGetRgnBox(dc->w.hGCClipRgn, rc);
|
retval = UnsafeIntGetRgnBox(dc->w.hGCClipRgn, rc);
|
||||||
|
IntDPtoLP(dc, (LPPOINT)rc, 2);
|
||||||
DC_UnlockDc( hDC );
|
DC_UnlockDc( hDC );
|
||||||
NtGdiDPtoLP(hDC, (LPPOINT)rc, 2);
|
|
||||||
return(retval);
|
return(retval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -206,7 +205,42 @@ int STDCALL NtGdiIntersectClipRect(HDC hDC,
|
||||||
int RightRect,
|
int RightRect,
|
||||||
int BottomRect)
|
int BottomRect)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
INT Result;
|
||||||
|
RECT Rect;
|
||||||
|
HRGN NewRgn;
|
||||||
|
PDC dc = DC_LockDc(hDC);
|
||||||
|
|
||||||
|
if (!dc)
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
Rect.left = LeftRect;
|
||||||
|
Rect.top = TopRect;
|
||||||
|
Rect.right = RightRect;
|
||||||
|
Rect.bottom = BottomRect;
|
||||||
|
|
||||||
|
IntLPtoDP(dc, (LPPOINT)&Rect, 2);
|
||||||
|
|
||||||
|
NewRgn = UnsafeIntCreateRectRgnIndirect(&Rect);
|
||||||
|
if (!NewRgn)
|
||||||
|
{
|
||||||
|
Result = ERROR;
|
||||||
|
}
|
||||||
|
else if (!dc->w.hClipRgn)
|
||||||
|
{
|
||||||
|
dc->w.hClipRgn = NewRgn;
|
||||||
|
Result = SIMPLEREGION;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Result = NtGdiCombineRgn(dc->w.hClipRgn, dc->w.hClipRgn, NewRgn, RGN_AND);
|
||||||
|
NtGdiDeleteObject(NewRgn);
|
||||||
|
}
|
||||||
|
if (Result != ERROR)
|
||||||
|
CLIPPING_UpdateGCRegion(dc);
|
||||||
|
|
||||||
|
DC_UnlockDc(hDC);
|
||||||
|
|
||||||
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int STDCALL NtGdiOffsetClipRgn(HDC hDC,
|
int STDCALL NtGdiOffsetClipRgn(HDC hDC,
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
/* $Id: coord.c,v 1.19 2003/09/09 09:39:21 gvg Exp $
|
/* $Id: coord.c,v 1.20 2003/12/21 18:38:37 navaraf Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -69,7 +69,7 @@ BOOL STDCALL NtGdiCombineTransform(LPXFORM UnsafeXFormResult,
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID STATIC FASTCALL
|
VOID FASTCALL
|
||||||
CoordDPtoLP(PDC Dc, LPPOINT Point)
|
CoordDPtoLP(PDC Dc, LPPOINT Point)
|
||||||
{
|
{
|
||||||
FLOAT x, y;
|
FLOAT x, y;
|
||||||
|
@ -81,6 +81,18 @@ FLOAT x, y;
|
||||||
y * Dc->w.xformVport2World.eM22 + Dc->w.xformVport2World.eDy;
|
y * Dc->w.xformVport2World.eM22 + Dc->w.xformVport2World.eDy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
FASTCALL
|
||||||
|
IntDPtoLP ( PDC dc, LPPOINT Points, INT Count )
|
||||||
|
{
|
||||||
|
INT i;
|
||||||
|
|
||||||
|
ASSERT ( Points );
|
||||||
|
|
||||||
|
for ( i = 0; i < Count; i++ )
|
||||||
|
CoordDPtoLP ( dc, &Points[i] );
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Converts points from device coordinates into logical coordinates. Conversion depends on the mapping mode,
|
* Converts points from device coordinates into logical coordinates. Conversion depends on the mapping mode,
|
||||||
* world transfrom, viewport origin settings for the given device context.
|
* world transfrom, viewport origin settings for the given device context.
|
||||||
|
@ -94,38 +106,25 @@ NtGdiDPtoLP(HDC hDC,
|
||||||
LPPOINT UnsafePoints,
|
LPPOINT UnsafePoints,
|
||||||
int Count)
|
int Count)
|
||||||
{
|
{
|
||||||
PDC dc;
|
PDC dc;
|
||||||
INT i;
|
LPPOINT Points = (LPPOINT)ExAllocatePool(PagedPool, Count * sizeof(POINT));
|
||||||
LPPOINT Points = (LPPOINT) ExAllocatePool( PagedPool, Count*sizeof(POINT));
|
BOOL ret = FALSE; // default to failure
|
||||||
BOOL ret = FALSE; // default to failure
|
|
||||||
|
|
||||||
ASSERT(Points);
|
if (!Points)
|
||||||
if ( !Points )
|
return FALSE;
|
||||||
return ret;
|
|
||||||
|
|
||||||
MmCopyFromCaller( Points, UnsafePoints, Count*sizeof(POINT) );
|
dc = DC_LockDc(hDC);
|
||||||
|
if (dc)
|
||||||
|
{
|
||||||
|
ret = TRUE;
|
||||||
|
MmCopyFromCaller(Points, UnsafePoints, Count * sizeof(POINT));
|
||||||
|
IntDPtoLP(dc, Points, Count);
|
||||||
|
MmCopyToCaller(UnsafePoints, Points, Count * sizeof(POINT));
|
||||||
|
DC_UnlockDc(hDC);
|
||||||
|
}
|
||||||
|
ExFreePool(Points);
|
||||||
|
|
||||||
dc = DC_LockDc (hDC);
|
return ret;
|
||||||
if ( dc )
|
|
||||||
{
|
|
||||||
ret = TRUE;
|
|
||||||
if ( dc->w.vport2WorldValid )
|
|
||||||
{
|
|
||||||
for (i = 0; i < Count; i++)
|
|
||||||
{
|
|
||||||
CoordDPtoLP ( dc, &Points[i] );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DC_UnlockDc( hDC );
|
|
||||||
|
|
||||||
MmCopyToCaller( UnsafePoints, Points, Count*sizeof(POINT) );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
ExFreePool ( Points );
|
|
||||||
|
|
||||||
return(TRUE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
/* $Id: text.c,v 1.61 2003/12/13 10:34:13 weiden Exp $ */
|
/* $Id: text.c,v 1.62 2003/12/21 18:38:37 navaraf Exp $ */
|
||||||
|
|
||||||
|
|
||||||
#undef WIN32_LEAN_AND_MEAN
|
#undef WIN32_LEAN_AND_MEAN
|
||||||
|
@ -467,19 +467,276 @@ NtGdiEnumFonts(HDC hDC,
|
||||||
UNIMPLEMENTED;
|
UNIMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL
|
BOOL STDCALL
|
||||||
STDCALL
|
NtGdiExtTextOut(HDC hDC, int XStart, int YStart, UINT fuOptions,
|
||||||
NtGdiExtTextOut(HDC hdc,
|
CONST RECT *lprc, LPCWSTR String, UINT Count, CONST INT *lpDx)
|
||||||
int X,
|
|
||||||
int Y,
|
|
||||||
UINT fuOptions,
|
|
||||||
CONST RECT *lprc,
|
|
||||||
LPCWSTR lpString,
|
|
||||||
UINT cbCount,
|
|
||||||
CONST INT *lpDx)
|
|
||||||
{
|
{
|
||||||
/* FIXME: Implement */
|
/* FIXME: Implement */
|
||||||
return NtGdiTextOut(hdc, X, Y, lpString, cbCount);
|
// return NtGdiTextOut(hdc, X, Y, lpString, cbCount);
|
||||||
|
// Fixme: Call EngTextOut, which does the real work (calling DrvTextOut where appropriate)
|
||||||
|
|
||||||
|
DC *dc;
|
||||||
|
SURFOBJ *SurfObj;
|
||||||
|
int error, glyph_index, n, i;
|
||||||
|
FT_Face face;
|
||||||
|
FT_GlyphSlot glyph;
|
||||||
|
ULONG TextLeft, TextTop, pitch, previous, BackgroundLeft;
|
||||||
|
FT_Bool use_kerning;
|
||||||
|
RECTL DestRect, MaskRect;
|
||||||
|
POINTL SourcePoint, BrushOrigin;
|
||||||
|
HBRUSH hBrushFg = NULL;
|
||||||
|
PBRUSHOBJ BrushFg = NULL;
|
||||||
|
HBRUSH hBrushBg = NULL;
|
||||||
|
PBRUSHOBJ BrushBg = NULL;
|
||||||
|
HBITMAP HSourceGlyph;
|
||||||
|
PSURFOBJ SourceGlyphSurf;
|
||||||
|
SIZEL bitSize;
|
||||||
|
FT_CharMap found = 0, charmap;
|
||||||
|
INT yoff;
|
||||||
|
PFONTOBJ FontObj;
|
||||||
|
PFONTGDI FontGDI;
|
||||||
|
PTEXTOBJ TextObj;
|
||||||
|
PPALGDI PalDestGDI;
|
||||||
|
PXLATEOBJ XlateObj;
|
||||||
|
ULONG Mode;
|
||||||
|
|
||||||
|
dc = DC_LockDc(hDC);
|
||||||
|
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 (! NT_SUCCESS(GetFontObjectsFromTextObj(TextObj, NULL, &FontObj, &FontGDI)))
|
||||||
|
{
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
face = FontGDI->face;
|
||||||
|
|
||||||
|
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);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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));
|
||||||
|
if(hBrushBg)
|
||||||
|
{
|
||||||
|
BrushBg = BRUSHOBJ_LockBrush(hBrushBg);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EngDeleteXlate(XlateObj);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EngDeleteXlate(XlateObj);
|
||||||
|
|
||||||
|
SourcePoint.x = 0;
|
||||||
|
SourcePoint.y = 0;
|
||||||
|
MaskRect.left = 0;
|
||||||
|
MaskRect.top = 0;
|
||||||
|
BrushOrigin.x = 0;
|
||||||
|
BrushOrigin.y = 0;
|
||||||
|
|
||||||
|
// Determine the yoff from the dc's w.textAlign
|
||||||
|
if (dc->w.textAlign & TA_BASELINE) {
|
||||||
|
yoff = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (dc->w.textAlign & TA_BOTTOM) {
|
||||||
|
yoff = -face->size->metrics.descender / 64;
|
||||||
|
}
|
||||||
|
else { // TA_TOP
|
||||||
|
yoff = face->size->metrics.ascender / 64;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
glyph = face->glyph;
|
||||||
|
|
||||||
|
// retrieve kerning distance and move pen position
|
||||||
|
if (use_kerning && previous && glyph_index)
|
||||||
|
{
|
||||||
|
FT_Vector delta;
|
||||||
|
FT_Get_Kerning(face, previous, glyph_index, 0, &delta);
|
||||||
|
TextLeft += delta.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");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
pitch = glyph->bitmap.pitch;
|
||||||
|
} else {
|
||||||
|
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;
|
||||||
|
if (fuOptions & ETO_CLIPPED)
|
||||||
|
{
|
||||||
|
if (DestRect.left > lprc->right || DestRect.right < lprc->left ||
|
||||||
|
DestRect.top > lprc->bottom || DestRect.bottom < lprc->top)
|
||||||
|
{
|
||||||
|
DestRect.right = DestRect.left;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DestRect.left = max(DestRect.left, lprc->left);
|
||||||
|
DestRect.right = min(DestRect.right, lprc->right);
|
||||||
|
DestRect.top = max(DestRect.top, lprc->top);
|
||||||
|
DestRect.bottom = min(DestRect.bottom, lprc->bottom);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IntEngBitBlt(SurfObj,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
dc->CombinedClip,
|
||||||
|
NULL,
|
||||||
|
&DestRect,
|
||||||
|
&SourcePoint,
|
||||||
|
&SourcePoint,
|
||||||
|
BrushBg,
|
||||||
|
&BrushOrigin,
|
||||||
|
PATCOPY);
|
||||||
|
BackgroundLeft = DestRect.right;
|
||||||
|
}
|
||||||
|
|
||||||
|
DestRect.left = TextLeft;
|
||||||
|
DestRect.right = TextLeft + glyph->bitmap.width;
|
||||||
|
DestRect.top = TextTop + yoff - glyph->bitmap_top;
|
||||||
|
DestRect.bottom = DestRect.top + glyph->bitmap.rows;
|
||||||
|
|
||||||
|
if (fuOptions & ETO_CLIPPED)
|
||||||
|
{
|
||||||
|
if (DestRect.left > lprc->right || DestRect.right < lprc->left ||
|
||||||
|
DestRect.top > lprc->bottom || DestRect.bottom < lprc->top)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DestRect.left = max(DestRect.left, lprc->left);
|
||||||
|
DestRect.right = min(DestRect.right, lprc->right);
|
||||||
|
DestRect.top = max(DestRect.top, lprc->top);
|
||||||
|
DestRect.bottom = min(DestRect.bottom, lprc->bottom);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bitSize.cx = glyph->bitmap.width;
|
||||||
|
bitSize.cy = glyph->bitmap.rows;
|
||||||
|
MaskRect.right = glyph->bitmap.width;
|
||||||
|
MaskRect.bottom = glyph->bitmap.rows;
|
||||||
|
|
||||||
|
// We should create the bitmap out of the loop at the biggest possible glyph size
|
||||||
|
// 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((ULONG) HSourceGlyph);
|
||||||
|
|
||||||
|
// Use the font data as a mask to paint onto the DCs surface using a brush
|
||||||
|
IntEngBitBlt (
|
||||||
|
SurfObj,
|
||||||
|
NULL,
|
||||||
|
SourceGlyphSurf,
|
||||||
|
dc->CombinedClip,
|
||||||
|
NULL,
|
||||||
|
&DestRect,
|
||||||
|
&SourcePoint,
|
||||||
|
(PPOINTL)&MaskRect,
|
||||||
|
BrushFg,
|
||||||
|
&BrushOrigin,
|
||||||
|
0xAACC );
|
||||||
|
|
||||||
|
EngDeleteSurface(HSourceGlyph);
|
||||||
|
|
||||||
|
TextLeft += (glyph->advance.x + 32) / 64;
|
||||||
|
previous = glyph_index;
|
||||||
|
|
||||||
|
String++;
|
||||||
|
}
|
||||||
|
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 (NULL != hBrushBg)
|
||||||
|
{
|
||||||
|
BRUSHOBJ_UnlockBrush(hBrushBg);
|
||||||
|
NtGdiDeleteObject(hBrushBg);
|
||||||
|
}
|
||||||
|
if (NULL != hBrushFg)
|
||||||
|
{
|
||||||
|
BRUSHOBJ_UnlockBrush(hBrushFg);
|
||||||
|
NtGdiDeleteObject(hBrushFg);
|
||||||
|
}
|
||||||
|
DC_UnlockDc( hDC );
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
|
|
Loading…
Reference in a new issue