Support OPAQUE text background

svn path=/trunk/; revision=6042
This commit is contained in:
Gé van Geldorp 2003-09-10 23:16:13 +00:00
parent 5bdf0b7486
commit 755c84cde3
2 changed files with 81 additions and 29 deletions

View file

@ -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: dc.c,v 1.79 2003/09/10 21:06:26 fireball Exp $ /* $Id: dc.c,v 1.80 2003/09/10 23:16:13 gvg Exp $
* *
* DC.C - Device context functions * DC.C - Device context functions
* *
@ -37,6 +37,7 @@
#include <win32k/print.h> #include <win32k/print.h>
#include <win32k/region.h> #include <win32k/region.h>
#include <win32k/gdiobj.h> #include <win32k/gdiobj.h>
#include <win32k/paint.h>
#include <win32k/pen.h> #include <win32k/pen.h>
#include <win32k/text.h> #include <win32k/text.h>
#include "../eng/clip.h" #include "../eng/clip.h"
@ -124,20 +125,25 @@ NtGdiCancelDC(HDC hDC)
HDC STDCALL HDC STDCALL
NtGdiCreateCompatableDC(HDC hDC) NtGdiCreateCompatableDC(HDC hDC)
{ {
PDC NewDC, OrigDC = NULL; PDC NewDC, OrigDC;
HBITMAP hBitmap; HBITMAP hBitmap;
HDC hNewDC; HDC hNewDC;
HRGN hVisRgn; HRGN hVisRgn;
BITMAPOBJ *pb; BITMAPOBJ *pb;
OrigDC = DC_LockDc(hDC); if (hDC == NULL)
if (OrigDC == NULL)
{ {
OrigDC = NULL;
hNewDC = DC_AllocDC(L"DISPLAY"); hNewDC = DC_AllocDC(L"DISPLAY");
} }
else else
{ {
/* Allocate a new DC based on the original DC's device */ /* Allocate a new DC based on the original DC's device */
OrigDC = DC_LockDc(hDC);
if (NULL == OrigDC)
{
return NULL;
}
hNewDC = DC_AllocDC(OrigDC->DriverName); hNewDC = DC_AllocDC(OrigDC->DriverName);
} }
@ -213,8 +219,13 @@ NtGdiCreateCompatableDC(HDC hDC)
NewDC->w.hPalette = OrigDC->w.hPalette; NewDC->w.hPalette = OrigDC->w.hPalette;
NewDC->w.textColor = OrigDC->w.textColor; NewDC->w.textColor = OrigDC->w.textColor;
NewDC->w.textAlign = OrigDC->w.textAlign; NewDC->w.textAlign = OrigDC->w.textAlign;
NewDC->w.backgroundColor = OrigDC->w.backgroundColor;
NewDC->w.backgroundMode = OrigDC->w.backgroundMode;
}
if (NULL != hDC)
{
DC_UnlockDc( hDC );
} }
DC_UnlockDc( hDC );
DC_UnlockDc( hNewDC ); DC_UnlockDc( hNewDC );
hVisRgn = NtGdiCreateRectRgn(0, 0, 1, 1); hVisRgn = NtGdiCreateRectRgn(0, 0, 1, 1);
@ -491,6 +502,8 @@ NtGdiCreateDC(LPCWSTR Driver,
DC_InitDC(hNewDC); DC_InitDC(hNewDC);
NtGdiSetTextColor(hNewDC, RGB(0, 0, 0)); NtGdiSetTextColor(hNewDC, RGB(0, 0, 0));
NtGdiSetTextAlign(hNewDC, TA_TOP); NtGdiSetTextAlign(hNewDC, TA_TOP);
NtGdiSetBkColor(hNewDC, RGB(255, 255, 255));
NtGdiSetBkMode(hNewDC, OPAQUE);
return hNewDC; return hNewDC;
} }

View file

@ -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.50 2003/08/31 13:24:38 gvg Exp $ */ /* $Id: text.c,v 1.51 2003/09/10 23:16:13 gvg Exp $ */
#undef WIN32_LEAN_AND_MEAN #undef WIN32_LEAN_AND_MEAN
@ -210,8 +210,8 @@ NtGdiAddFontResource(LPCWSTR Filename)
FontGDI->face = face; FontGDI->face = face;
// FIXME: Complete text metrics // FIXME: Complete text metrics
FontGDI->TextMetric.tmAscent = face->size->metrics.ascender; // units above baseline FontGDI->TextMetric.tmAscent = (face->size->metrics.ascender + 32) / 64; // units above baseline
FontGDI->TextMetric.tmDescent = face->size->metrics.descender; // units below baseline FontGDI->TextMetric.tmDescent = (- face->size->metrics.descender + 32) / 64; // units below baseline
FontGDI->TextMetric.tmHeight = FontGDI->TextMetric.tmAscent + FontGDI->TextMetric.tmDescent; FontGDI->TextMetric.tmHeight = FontGDI->TextMetric.tmAscent + FontGDI->TextMetric.tmDescent;
DPRINT("Font loaded: %s (%s)\n", face->family_name, face->style_name); DPRINT("Font loaded: %s (%s)\n", face->family_name, face->style_name);
@ -933,9 +933,8 @@ NtGdiGetTextMetrics(HDC hDC,
{ {
memcpy(&SafeTm, &FontGDI->TextMetric, sizeof(TEXTMETRICW)); memcpy(&SafeTm, &FontGDI->TextMetric, sizeof(TEXTMETRICW));
SafeTm.tmAscent = (Face->size->metrics.ascender + 32) / 64; // units above baseline SafeTm.tmAscent = (Face->size->metrics.ascender + 32) / 64; // units above baseline
SafeTm.tmDescent = (Face->size->metrics.descender + 32) / 64; // units below baseline SafeTm.tmDescent = (- Face->size->metrics.descender + 32) / 64; // units below baseline
SafeTm.tmHeight = (Face->size->metrics.ascender + SafeTm.tmHeight = SafeTm.tmAscent + SafeTm.tmDescent;
Face->size->metrics.descender + 32) / 64;
Status = MmCopyToCaller(tm, &SafeTm, sizeof(TEXTMETRICW)); Status = MmCopyToCaller(tm, &SafeTm, sizeof(TEXTMETRICW));
} }
} }
@ -1038,12 +1037,14 @@ NtGdiTextOut(HDC hDC,
int error, glyph_index, n, i; int error, glyph_index, n, i;
FT_Face face; FT_Face face;
FT_GlyphSlot glyph; FT_GlyphSlot glyph;
ULONG TextLeft, TextTop, pitch, previous; ULONG TextLeft, TextTop, pitch, previous, BackgroundLeft;
FT_Bool use_kerning; FT_Bool use_kerning;
RECTL DestRect, MaskRect; RECTL DestRect, MaskRect;
POINTL SourcePoint, BrushOrigin; POINTL SourcePoint, BrushOrigin;
HBRUSH hBrush = NULL; HBRUSH hBrushFg = NULL;
PBRUSHOBJ Brush = NULL; PBRUSHOBJ BrushFg = NULL;
HBRUSH hBrushBg = NULL;
PBRUSHOBJ BrushBg = NULL;
HBITMAP HSourceGlyph; HBITMAP HSourceGlyph;
PSURFOBJ SourceGlyphSurf; PSURFOBJ SourceGlyphSurf;
SIZEL bitSize; SIZEL bitSize;
@ -1064,6 +1065,7 @@ NtGdiTextOut(HDC hDC,
YStart += dc->w.DCOrgY; YStart += dc->w.DCOrgY;
TextLeft = XStart; TextLeft = XStart;
TextTop = YStart; TextTop = YStart;
BackgroundLeft = XStart;
TextObj = TEXTOBJ_LockText(dc->w.hFont); TextObj = TEXTOBJ_LockText(dc->w.hFont);
@ -1104,13 +1106,18 @@ NtGdiTextOut(HDC hDC,
goto fail; goto fail;
} }
// Create the brush // Create the brushes
PalDestGDI = PALETTE_LockPalette(dc->w.hPalette); PalDestGDI = PALETTE_LockPalette(dc->w.hPalette);
Mode = PalDestGDI->Mode; Mode = PalDestGDI->Mode;
PALETTE_UnlockPalette(dc->w.hPalette); PALETTE_UnlockPalette(dc->w.hPalette);
XlateObj = (PXLATEOBJ)IntEngCreateXlate(Mode, PAL_RGB, dc->w.hPalette, NULL); XlateObj = (PXLATEOBJ)IntEngCreateXlate(Mode, PAL_RGB, dc->w.hPalette, NULL);
hBrush = NtGdiCreateSolidBrush(XLATEOBJ_iXlate(XlateObj, dc->w.textColor)); hBrushFg = NtGdiCreateSolidBrush(XLATEOBJ_iXlate(XlateObj, dc->w.textColor));
Brush = BRUSHOBJ_LockBrush(hBrush); BrushFg = BRUSHOBJ_LockBrush(hBrushFg);
if (OPAQUE == dc->w.backgroundMode)
{
hBrushBg = NtGdiCreateSolidBrush(XLATEOBJ_iXlate(XlateObj, dc->w.backgroundColor));
BrushBg = BRUSHOBJ_LockBrush(hBrushBg);
}
EngDeleteXlate(XlateObj); EngDeleteXlate(XlateObj);
SourcePoint.x = 0; SourcePoint.x = 0;
@ -1165,11 +1172,32 @@ NtGdiTextOut(HDC hDC,
pitch = glyph->bitmap.width; 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.left = TextLeft;
DestRect.top = TextTop + yoff - glyph->bitmap_top;
DestRect.right = TextLeft + glyph->bitmap.width; DestRect.right = TextLeft + glyph->bitmap.width;
DestRect.top = TextTop + yoff - glyph->bitmap_top;
DestRect.bottom = DestRect.top + glyph->bitmap.rows; DestRect.bottom = DestRect.top + glyph->bitmap.rows;
bitSize.cx = pitch;
bitSize.cx = glyph->bitmap.width;
bitSize.cy = glyph->bitmap.rows; bitSize.cy = glyph->bitmap.rows;
MaskRect.right = glyph->bitmap.width; MaskRect.right = glyph->bitmap.width;
MaskRect.bottom = glyph->bitmap.rows; MaskRect.bottom = glyph->bitmap.rows;
@ -1190,29 +1218,40 @@ NtGdiTextOut(HDC hDC,
&DestRect, &DestRect,
&SourcePoint, &SourcePoint,
(PPOINTL)&MaskRect, (PPOINTL)&MaskRect,
Brush, BrushFg,
&BrushOrigin, &BrushOrigin,
0xAACC ); 0xAACC );
EngDeleteSurface(HSourceGlyph); EngDeleteSurface(HSourceGlyph);
TextLeft += glyph->advance.x >> 6; TextLeft += (glyph->advance.x + 32) / 64;
previous = glyph_index; previous = glyph_index;
String++; String++;
} }
TEXTOBJ_UnlockText( dc->w.hFont ); TEXTOBJ_UnlockText(dc->w.hFont);
BRUSHOBJ_UnlockBrush(hBrush); if (NULL != hBrushBg)
NtGdiDeleteObject( hBrush ); {
DC_UnlockDc( hDC ); BRUSHOBJ_UnlockBrush(hBrushBg);
NtGdiDeleteObject(hBrushBg);
}
BRUSHOBJ_UnlockBrush(hBrushFg);
NtGdiDeleteObject(hBrushFg);
DC_UnlockDc(hDC);
return TRUE; return TRUE;
fail: fail:
TEXTOBJ_UnlockText( dc->w.hFont ); TEXTOBJ_UnlockText( dc->w.hFont );
if( hBrush ){ if (NULL != hBrushBg)
BRUSHOBJ_UnlockBrush(hBrush); {
NtGdiDeleteObject( hBrush ); BRUSHOBJ_UnlockBrush(hBrushBg);
} NtGdiDeleteObject(hBrushBg);
}
if (NULL != hBrushFg)
{
BRUSHOBJ_UnlockBrush(hBrushFg);
NtGdiDeleteObject(hBrushFg);
}
DC_UnlockDc( hDC ); DC_UnlockDc( hDC );
return FALSE; return FALSE;
} }