- Unified indenting style in NtGdiExtTextOut and implemented support for right and centered text alignment.

- Don't render glyphs in TextIntGetTextExtentPoint.

svn path=/trunk/; revision=8297
This commit is contained in:
Filip Navara 2004-02-22 08:35:21 +00:00
parent e6ad1bc2c0
commit a7b989769f

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.76 2004/02/21 21:15:22 navaraf Exp $ */ /* $Id: text.c,v 1.77 2004/02/22 08:35:21 navaraf Exp $ */
#undef WIN32_LEAN_AND_MEAN #undef WIN32_LEAN_AND_MEAN
@ -560,8 +560,15 @@ NtGdiEnumFonts(HDC hDC,
} }
BOOL STDCALL BOOL STDCALL
NtGdiExtTextOut(HDC hDC, int XStart, int YStart, UINT fuOptions, NtGdiExtTextOut(
CONST RECT *lprc, LPCWSTR String, UINT Count, CONST INT *lpDx) HDC hDC,
INT XStart,
INT YStart,
UINT fuOptions,
CONST RECT *lprc,
LPCWSTR String,
UINT Count,
CONST INT *lpDx)
{ {
/* /*
* FIXME: * FIXME:
@ -604,9 +611,6 @@ NtGdiExtTextOut(HDC hDC, int XStart, int YStart, UINT fuOptions,
XStart += dc->w.DCOrgX; XStart += dc->w.DCOrgX;
YStart += dc->w.DCOrgY; YStart += dc->w.DCOrgY;
TextLeft = XStart;
TextTop = YStart;
BackgroundLeft = XStart;
TextObj = TEXTOBJ_LockText(dc->w.hFont); TextObj = TEXTOBJ_LockText(dc->w.hFont);
@ -719,36 +723,101 @@ NtGdiExtTextOut(HDC hDC, int XStart, int YStart, UINT fuOptions,
} }
} }
// Determine the yoff from the dc's w.textAlign /*
if (dc->w.textAlign & TA_BASELINE) { * Process the vertical alignment and determine the yoff.
*/
if (dc->w.textAlign & TA_BASELINE)
yoff = 0; yoff = 0;
} else if (dc->w.textAlign & TA_BOTTOM)
else
if (dc->w.textAlign & TA_BOTTOM) {
yoff = -face->size->metrics.descender / 64; yoff = -face->size->metrics.descender / 64;
} else /* TA_TOP */
else { // TA_TOP
yoff = face->size->metrics.ascender / 64; yoff = face->size->metrics.ascender / 64;
}
use_kerning = FT_HAS_KERNING(face); use_kerning = FT_HAS_KERNING(face);
previous = 0; previous = 0;
for(i=0; i<Count; i++) /*
* Process the horizontal alignment and modify XStart accordingly.
*/
if (dc->w.textAlign & (TA_RIGHT | TA_CENTER))
{
UINT TextWidth;
LPCWSTR TempText = String;
/*
* Calculate width of the text.
*/
for (i = 0; i < Count; i++)
{
ExAcquireFastMutex(&FreeTypeLock);
glyph_index = FT_Get_Char_Index(face, *TempText);
error = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT);
ExReleaseFastMutex(&FreeTypeLock);
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;
ExAcquireFastMutex(&FreeTypeLock);
FT_Get_Kerning(face, previous, glyph_index, 0, &delta);
ExReleaseFastMutex(&FreeTypeLock);
TextWidth += delta.x >> 6;
}
TextWidth += glyph->advance.x >> 6;
previous = glyph_index;
TempText++;
}
previous = 0;
if (dc->w.textAlign & TA_RIGHT)
{
XStart -= TextWidth;
}
else
{
XStart -= TextWidth >> 1;
}
}
TextLeft = XStart;
TextTop = YStart;
BackgroundLeft = XStart;
/*
* The main rendering loop.
*/
for (i = 0; i < Count; i++)
{ {
ExAcquireFastMutex(&FreeTypeLock); ExAcquireFastMutex(&FreeTypeLock);
glyph_index = FT_Get_Char_Index(face, *String); glyph_index = FT_Get_Char_Index(face, *String);
error = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT); error = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT);
ExReleaseFastMutex(&FreeTypeLock); ExReleaseFastMutex(&FreeTypeLock);
if(error) {
if (error)
{
EngDeleteXlate(XlateObj); EngDeleteXlate(XlateObj);
EngDeleteXlate(XlateObj2); EngDeleteXlate(XlateObj2);
DPRINT1("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; goto fail;
} }
glyph = face->glyph; glyph = face->glyph;
// retrieve kerning distance and move pen position /* retrieve kerning distance and move pen position */
if (use_kerning && previous && glyph_index) if (use_kerning && previous && glyph_index)
{ {
FT_Vector delta; FT_Vector delta;
@ -763,7 +832,8 @@ NtGdiExtTextOut(HDC hDC, int XStart, int YStart, UINT fuOptions,
ExAcquireFastMutex(&FreeTypeLock); ExAcquireFastMutex(&FreeTypeLock);
error = FT_Render_Glyph(glyph, RenderMode); error = FT_Render_Glyph(glyph, RenderMode);
ExReleaseFastMutex(&FreeTypeLock); ExReleaseFastMutex(&FreeTypeLock);
if(error) { if (error)
{
EngDeleteXlate(XlateObj); EngDeleteXlate(XlateObj);
EngDeleteXlate(XlateObj2); EngDeleteXlate(XlateObj2);
DPRINT1("WARNING: Failed to render glyph!\n"); DPRINT1("WARNING: Failed to render glyph!\n");
@ -780,7 +850,8 @@ NtGdiExtTextOut(HDC hDC, int XStart, int YStart, UINT fuOptions,
DestRect.right = TextLeft + (glyph->advance.x + 32) / 64; DestRect.right = TextLeft + (glyph->advance.x + 32) / 64;
DestRect.top = TextTop + yoff - (face->size->metrics.ascender + 32) / 64; DestRect.top = TextTop + yoff - (face->size->metrics.ascender + 32) / 64;
DestRect.bottom = TextTop + yoff + (- face->size->metrics.descender + 32) / 64; DestRect.bottom = TextTop + yoff + (- face->size->metrics.descender + 32) / 64;
IntEngBitBlt(SurfObj, IntEngBitBlt(
SurfObj,
NULL, NULL,
NULL, NULL,
dc->CombinedClip, dc->CombinedClip,
@ -804,13 +875,21 @@ NtGdiExtTextOut(HDC hDC, int XStart, int YStart, UINT fuOptions,
MaskRect.right = glyph->bitmap.width; MaskRect.right = glyph->bitmap.width;
MaskRect.bottom = glyph->bitmap.rows; 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 * 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, (glyph->bitmap.pixel_mode == ft_pixel_mode_grays) ? BMF_8BPP : BMF_1BPP, 0, glyph->bitmap.buffer); HSourceGlyph = EngCreateBitmap(bitSize, pitch, (glyph->bitmap.pixel_mode == ft_pixel_mode_grays) ? BMF_8BPP : BMF_1BPP, 0, glyph->bitmap.buffer);
SourceGlyphSurf = (PSURFOBJ)AccessUserObject((ULONG) HSourceGlyph); SourceGlyphSurf = (PSURFOBJ)AccessUserObject((ULONG) HSourceGlyph);
// Use the font data as a mask to paint onto the DCs surface using a brush /*
IntEngMaskBlt ( * Use the font data as a mask to paint onto the DCs surface using a
* brush.
*/
IntEngMaskBlt(
SurfObj, SurfObj,
SourceGlyphSurf, SourceGlyphSurf,
dc->CombinedClip, dc->CombinedClip,
@ -829,10 +908,11 @@ NtGdiExtTextOut(HDC hDC, int XStart, int YStart, UINT fuOptions,
String++; String++;
} }
EngDeleteXlate(XlateObj); EngDeleteXlate(XlateObj);
EngDeleteXlate(XlateObj2); EngDeleteXlate(XlateObj2);
TEXTOBJ_UnlockText(dc->w.hFont); TEXTOBJ_UnlockText(dc->w.hFont);
if (NULL != hBrushBg) if (hBrushBg != NULL)
{ {
BRUSHOBJ_UnlockBrush(hBrushBg); BRUSHOBJ_UnlockBrush(hBrushBg);
NtGdiDeleteObject(hBrushBg); NtGdiDeleteObject(hBrushBg);
@ -840,21 +920,23 @@ NtGdiExtTextOut(HDC hDC, int XStart, int YStart, UINT fuOptions,
BRUSHOBJ_UnlockBrush(hBrushFg); BRUSHOBJ_UnlockBrush(hBrushFg);
NtGdiDeleteObject(hBrushFg); NtGdiDeleteObject(hBrushFg);
DC_UnlockDc(hDC); DC_UnlockDc(hDC);
return TRUE; return TRUE;
fail: fail:
TEXTOBJ_UnlockText( dc->w.hFont ); TEXTOBJ_UnlockText(dc->w.hFont);
if (NULL != hBrushBg) if (hBrushBg != NULL)
{ {
BRUSHOBJ_UnlockBrush(hBrushBg); BRUSHOBJ_UnlockBrush(hBrushBg);
NtGdiDeleteObject(hBrushBg); NtGdiDeleteObject(hBrushBg);
} }
if (NULL != hBrushFg) if (hBrushFg != NULL)
{ {
BRUSHOBJ_UnlockBrush(hBrushFg); BRUSHOBJ_UnlockBrush(hBrushFg);
NtGdiDeleteObject(hBrushFg); NtGdiDeleteObject(hBrushFg);
} }
DC_UnlockDc( hDC ); DC_UnlockDc(hDC);
return FALSE; return FALSE;
} }
@ -1167,16 +1249,6 @@ TextIntGetTextExtentPoint(HDC hDC,
} }
TotalWidth += glyph->advance.x >> 6; TotalWidth += glyph->advance.x >> 6;
if (glyph->format == ft_glyph_format_outline)
{
ExAcquireFastMutex(&FreeTypeLock);
error = FT_Render_Glyph(glyph, FT_RENDER_MODE_MONO);
ExReleaseFastMutex(&FreeTypeLock);
if (error)
{
DPRINT1("WARNING: Failed to render glyph!\n");
}
}
if (TotalWidth <= MaxExtent && NULL != Fit) if (TotalWidth <= MaxExtent && NULL != Fit)
{ {