gdi32, winex11: Add support for subpixel font rendering.
This commit is contained in:
parent
33f6b46fd2
commit
028617b90b
|
@ -14591,6 +14591,7 @@ for ac_header in ft2build.h \
|
|||
freetype/ftoutln.h \
|
||||
freetype/ftwinfnt.h \
|
||||
freetype/ftmodapi.h \
|
||||
freetype/ftlcdfil.h \
|
||||
freetype/internal/sfnt.h
|
||||
do
|
||||
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
|
||||
|
|
|
@ -1040,6 +1040,7 @@ then
|
|||
freetype/ftoutln.h \
|
||||
freetype/ftwinfnt.h \
|
||||
freetype/ftmodapi.h \
|
||||
freetype/ftlcdfil.h \
|
||||
freetype/internal/sfnt.h,,,
|
||||
[#ifdef HAVE_FT2BUILD_H
|
||||
# include <ft2build.h>
|
||||
|
|
|
@ -132,6 +132,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(font);
|
|||
#ifdef HAVE_FREETYPE_FTMODAPI_H
|
||||
#include <freetype/ftmodapi.h>
|
||||
#endif
|
||||
#ifdef HAVE_FREETYPE_FTLCDFIL_H
|
||||
#include <freetype/ftlcdfil.h>
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_FT_TRUETYPEENGINETYPE
|
||||
typedef enum
|
||||
|
@ -179,7 +182,9 @@ MAKE_FUNCPTR(FT_Select_Charmap);
|
|||
MAKE_FUNCPTR(FT_Set_Charmap);
|
||||
MAKE_FUNCPTR(FT_Set_Pixel_Sizes);
|
||||
MAKE_FUNCPTR(FT_Vector_Transform);
|
||||
MAKE_FUNCPTR(FT_Render_Glyph);
|
||||
static void (*pFT_Library_Version)(FT_Library,FT_Int*,FT_Int*,FT_Int*);
|
||||
static FT_Error (*pFT_Library_SetLcdFilter)(FT_Library, FT_LcdFilter);
|
||||
static FT_Error (*pFT_Load_Sfnt_Table)(FT_Face,FT_ULong,FT_Long,FT_Byte*,FT_ULong*);
|
||||
static FT_ULong (*pFT_Get_First_Char)(FT_Face,FT_UInt*);
|
||||
static FT_ULong (*pFT_Get_Next_Char)(FT_Face,FT_ULong,FT_UInt*);
|
||||
|
@ -2481,10 +2486,12 @@ static BOOL init_freetype(void)
|
|||
LOAD_FUNCPTR(FT_Set_Charmap)
|
||||
LOAD_FUNCPTR(FT_Set_Pixel_Sizes)
|
||||
LOAD_FUNCPTR(FT_Vector_Transform)
|
||||
LOAD_FUNCPTR(FT_Render_Glyph)
|
||||
|
||||
#undef LOAD_FUNCPTR
|
||||
/* Don't warn if these ones are missing */
|
||||
pFT_Library_Version = wine_dlsym(ft_handle, "FT_Library_Version", NULL, 0);
|
||||
pFT_Library_SetLcdFilter = wine_dlsym(ft_handle, "FT_Library_SetLcdFilter", NULL, 0);
|
||||
pFT_Load_Sfnt_Table = wine_dlsym(ft_handle, "FT_Load_Sfnt_Table", NULL, 0);
|
||||
pFT_Get_First_Char = wine_dlsym(ft_handle, "FT_Get_First_Char", NULL, 0);
|
||||
pFT_Get_Next_Char = wine_dlsym(ft_handle, "FT_Get_Next_Char", NULL, 0);
|
||||
|
@ -4491,8 +4498,12 @@ DWORD WineEngGetGlyphOutline(GdiFont *incoming_font, UINT glyph, UINT format,
|
|||
needsTransform = TRUE;
|
||||
}
|
||||
|
||||
if (needsTransform || (format != GGO_METRICS && format != GGO_BITMAP && format != WINE_GGO_GRAY16_BITMAP))
|
||||
if (needsTransform || (format == GGO_NATIVE || format == GGO_BEZIER ||
|
||||
format == GGO_GRAY2_BITMAP || format == GGO_GRAY4_BITMAP ||
|
||||
format == GGO_GRAY8_BITMAP))
|
||||
{
|
||||
load_flags |= FT_LOAD_NO_BITMAP;
|
||||
}
|
||||
|
||||
err = pFT_Load_Glyph(ft_face, glyph_index, load_flags);
|
||||
|
||||
|
@ -4563,7 +4574,9 @@ DWORD WineEngGetGlyphOutline(GdiFont *incoming_font, UINT glyph, UINT format,
|
|||
wine_dbgstr_point(&lpgm->gmptGlyphOrigin),
|
||||
lpgm->gmCellIncX, lpgm->gmCellIncY);
|
||||
|
||||
if ((format == GGO_METRICS || format == GGO_BITMAP || format == WINE_GGO_GRAY16_BITMAP) &&
|
||||
if ((format == GGO_METRICS || format == GGO_BITMAP || format == WINE_GGO_GRAY16_BITMAP ||
|
||||
format == WINE_GGO_HRGB_BITMAP || format == WINE_GGO_HBGR_BITMAP ||
|
||||
format == WINE_GGO_VRGB_BITMAP || format == WINE_GGO_VBGR_BITMAP ) &&
|
||||
(!lpmat || is_identity_MAT2(lpmat))) /* don't cache custom transforms */
|
||||
{
|
||||
FONT_GM(font,original_index)->gm = *lpgm;
|
||||
|
@ -4579,7 +4592,11 @@ DWORD WineEngGetGlyphOutline(GdiFont *incoming_font, UINT glyph, UINT format,
|
|||
return 1; /* FIXME */
|
||||
}
|
||||
|
||||
if(ft_face->glyph->format != ft_glyph_format_outline && format != GGO_BITMAP && format != WINE_GGO_GRAY16_BITMAP) {
|
||||
if(ft_face->glyph->format != ft_glyph_format_outline &&
|
||||
(needsTransform || format == GGO_NATIVE || format == GGO_BEZIER ||
|
||||
format == GGO_GRAY2_BITMAP || format == GGO_GRAY4_BITMAP ||
|
||||
format == GGO_GRAY8_BITMAP))
|
||||
{
|
||||
TRACE("loaded a bitmap\n");
|
||||
LeaveCriticalSection( &freetype_cs );
|
||||
return GDI_ERROR;
|
||||
|
@ -4714,6 +4731,112 @@ DWORD WineEngGetGlyphOutline(GdiFont *incoming_font, UINT glyph, UINT format,
|
|||
break;
|
||||
}
|
||||
|
||||
case WINE_GGO_HRGB_BITMAP:
|
||||
case WINE_GGO_HBGR_BITMAP:
|
||||
case WINE_GGO_VRGB_BITMAP:
|
||||
case WINE_GGO_VBGR_BITMAP:
|
||||
{
|
||||
width = lpgm->gmBlackBoxX;
|
||||
height = lpgm->gmBlackBoxY;
|
||||
pitch = width * 4;
|
||||
needed = pitch * height;
|
||||
|
||||
if (!buf || !buflen) break;
|
||||
|
||||
memset(buf, 0, buflen);
|
||||
|
||||
switch (ft_face->glyph->format)
|
||||
{
|
||||
case FT_GLYPH_FORMAT_BITMAP:
|
||||
{
|
||||
BYTE *src = ft_face->glyph->bitmap.buffer, *dst = buf;
|
||||
INT src_pitch = ft_face->glyph->bitmap.pitch;
|
||||
INT x;
|
||||
|
||||
while ( height-- )
|
||||
{
|
||||
for (x = 0; x < width; x++)
|
||||
{
|
||||
if ( src[x / 8] & (1 << ( (7 - (x % 8)))) )
|
||||
((unsigned int *)dst)[x] = ~0u;
|
||||
}
|
||||
src += src_pitch;
|
||||
dst += pitch;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case FT_GLYPH_FORMAT_OUTLINE:
|
||||
{
|
||||
unsigned int *dst = (unsigned int *) buf;
|
||||
BYTE *src;
|
||||
INT x, src_pitch, rgb_interval, hmul, vmul;
|
||||
BOOL rgb = (format == WINE_GGO_HRGB_BITMAP || format == WINE_GGO_VRGB_BITMAP);
|
||||
FT_LcdFilter lcdfilter = FT_LCD_FILTER_DEFAULT;
|
||||
FT_Render_Mode render_mode =
|
||||
(format == WINE_GGO_HRGB_BITMAP || format == WINE_GGO_HBGR_BITMAP)?
|
||||
FT_RENDER_MODE_LCD: FT_RENDER_MODE_LCD_V;
|
||||
|
||||
if ( needsTransform )
|
||||
pFT_Outline_Transform (&ft_face->glyph->outline, &transMat);
|
||||
pFT_Outline_Translate (&ft_face->glyph->outline, -left, -bottom );
|
||||
if ( pFT_Library_SetLcdFilter )
|
||||
pFT_Library_SetLcdFilter( library, lcdfilter );
|
||||
pFT_Render_Glyph (ft_face->glyph, render_mode);
|
||||
|
||||
src = ft_face->glyph->bitmap.buffer;
|
||||
src_pitch = ft_face->glyph->bitmap.pitch;
|
||||
if ( render_mode == FT_RENDER_MODE_LCD)
|
||||
{
|
||||
rgb_interval = 1;
|
||||
hmul = 3;
|
||||
vmul = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
rgb_interval = src_pitch;
|
||||
hmul = 1;
|
||||
vmul = 3;
|
||||
}
|
||||
|
||||
if ( lcdfilter == FT_LCD_FILTER_DEFAULT || lcdfilter == FT_LCD_FILTER_LIGHT )
|
||||
src += rgb_interval * 3;
|
||||
while ( height-- )
|
||||
{
|
||||
for ( x = 0; x < width; x++ )
|
||||
{
|
||||
if ( rgb )
|
||||
{
|
||||
dst[x] = ((unsigned int)src[hmul * x + rgb_interval * 0] << 16) |
|
||||
((unsigned int)src[hmul * x + rgb_interval * 1] << 8) |
|
||||
((unsigned int)src[hmul * x + rgb_interval * 2] << 0) |
|
||||
((unsigned int)src[hmul * x + rgb_interval * 1] << 24) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[x] = ((unsigned int)src[hmul * x + rgb_interval * 2] << 16) |
|
||||
((unsigned int)src[hmul * x + rgb_interval * 1] << 8) |
|
||||
((unsigned int)src[hmul * x + rgb_interval * 0] << 0) |
|
||||
((unsigned int)src[hmul * x + rgb_interval * 1] << 24) ;
|
||||
}
|
||||
}
|
||||
src += src_pitch * vmul;
|
||||
dst += pitch / 4;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
FIXME ("loaded glyph format %x\n", ft_face->glyph->format);
|
||||
LeaveCriticalSection ( &freetype_cs );
|
||||
return GDI_ERROR;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case GGO_NATIVE:
|
||||
{
|
||||
int contour, point = 0, first_pt;
|
||||
|
@ -5792,12 +5915,24 @@ static BOOL is_hinting_enabled(void)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
static BOOL is_subpixel_rendering_enabled( void )
|
||||
{
|
||||
if ( !pFT_Library_SetLcdFilter )
|
||||
return FALSE;
|
||||
|
||||
if ( pFT_Library_SetLcdFilter ( NULL, 0 ) == FT_Err_Unimplemented_Feature )
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* GetRasterizerCaps (GDI32.@)
|
||||
*/
|
||||
BOOL WINAPI GetRasterizerCaps( LPRASTERIZER_STATUS lprs, UINT cbNumBytes)
|
||||
{
|
||||
static int hinting = -1;
|
||||
static int subpixel = -1;
|
||||
|
||||
if(hinting == -1)
|
||||
{
|
||||
|
@ -5805,8 +5940,16 @@ BOOL WINAPI GetRasterizerCaps( LPRASTERIZER_STATUS lprs, UINT cbNumBytes)
|
|||
TRACE("hinting is %senabled\n", hinting ? "" : "NOT ");
|
||||
}
|
||||
|
||||
if ( subpixel == -1 )
|
||||
{
|
||||
subpixel = is_subpixel_rendering_enabled();
|
||||
TRACE("subpixel rendering is %senabled\n", subpixel ? "" : "NOT ");
|
||||
}
|
||||
|
||||
lprs->nSize = sizeof(RASTERIZER_STATUS);
|
||||
lprs->wFlags = TT_AVAILABLE | TT_ENABLED | (hinting ? WINE_TT_HINTER_ENABLED : 0);
|
||||
if ( subpixel )
|
||||
lprs->wFlags |= WINE_TT_SUBPIXEL_RENDERING_ENABLED;
|
||||
lprs->nLanguageID = 0;
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -142,8 +142,10 @@ static CRITICAL_SECTION xrender_cs = { &critsect_debug, -1, 0, 0, 0, 0 };
|
|||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
#define get_be_word(x) (x)
|
||||
#define NATIVE_BYTE_ORDER MSBFirst
|
||||
#else
|
||||
#define get_be_word(x) RtlUshortByteSwap(x)
|
||||
#define NATIVE_BYTE_ORDER LSBFirst
|
||||
#endif
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -456,6 +458,7 @@ static int GetCacheEntry(X11DRV_PDEVICE *physDev, LFANDSIZE *plfsz)
|
|||
gsCacheEntry *entry;
|
||||
WORD flags;
|
||||
static int hinter = -1;
|
||||
static int subpixel = -1;
|
||||
|
||||
if((ret = LookupEntry(plfsz)) != -1) return ret;
|
||||
|
||||
|
@ -468,13 +471,24 @@ static int GetCacheEntry(X11DRV_PDEVICE *physDev, LFANDSIZE *plfsz)
|
|||
|
||||
if(antialias && plfsz->lf.lfQuality != NONANTIALIASED_QUALITY)
|
||||
{
|
||||
if(hinter == -1)
|
||||
if(hinter == -1 || subpixel == -1)
|
||||
{
|
||||
RASTERIZER_STATUS status;
|
||||
GetRasterizerCaps(&status, sizeof(status));
|
||||
hinter = status.wFlags & WINE_TT_HINTER_ENABLED;
|
||||
subpixel = status.wFlags & WINE_TT_SUBPIXEL_RENDERING_ENABLED;
|
||||
}
|
||||
if(!hinter || !get_gasp_flags(physDev, &flags) || flags & GASP_DOGRAY)
|
||||
|
||||
/* FIXME: Use the following registry information
|
||||
[HKEY_CURRENT_USER\Control Panel\Desktop]
|
||||
"FontSmoothing"="2" ; 0=>Off, 2=>On
|
||||
"FontSmoothingType"=dword:00000002 ; 1=>Standard, 2=>Cleartype
|
||||
"FontSmoothingOrientation"=dword:00000001 ; 0=>BGR, 1=>RGB
|
||||
"FontSmoothingGamma"=dword:00000578
|
||||
*/
|
||||
if ( subpixel && X11DRV_XRender_Installed)
|
||||
entry->aa_default = AA_RGB;
|
||||
else if(!hinter || !get_gasp_flags(physDev, &flags) || flags & GASP_DOGRAY)
|
||||
entry->aa_default = AA_Grey;
|
||||
else
|
||||
entry->aa_default = AA_None;
|
||||
|
@ -610,12 +624,25 @@ static BOOL UploadGlyph(X11DRV_PDEVICE *physDev, int glyph, AA_Type format)
|
|||
gsCacheEntryFormat *formatEntry;
|
||||
UINT ggo_format = GGO_GLYPH_INDEX;
|
||||
XRenderPictFormat pf;
|
||||
unsigned long pf_mask;
|
||||
static const char zero[4];
|
||||
|
||||
switch(format) {
|
||||
case AA_Grey:
|
||||
ggo_format |= WINE_GGO_GRAY16_BITMAP;
|
||||
break;
|
||||
case AA_RGB:
|
||||
ggo_format |= WINE_GGO_HRGB_BITMAP;
|
||||
break;
|
||||
case AA_BGR:
|
||||
ggo_format |= WINE_GGO_HBGR_BITMAP;
|
||||
break;
|
||||
case AA_VRGB:
|
||||
ggo_format |= WINE_GGO_VRGB_BITMAP;
|
||||
break;
|
||||
case AA_VBGR:
|
||||
ggo_format |= WINE_GGO_VBGR_BITMAP;
|
||||
break;
|
||||
|
||||
default:
|
||||
ERR("aa = %d - not implemented\n", format);
|
||||
|
@ -630,8 +657,7 @@ static BOOL UploadGlyph(X11DRV_PDEVICE *physDev, int glyph, AA_Type format)
|
|||
if(format != AA_None) {
|
||||
format = AA_None;
|
||||
entry->aa_default = AA_None;
|
||||
ggo_format &= ~WINE_GGO_GRAY16_BITMAP;
|
||||
ggo_format |= GGO_BITMAP;
|
||||
ggo_format = GGO_GLYPH_INDEX | GGO_BITMAP;
|
||||
buflen = GetGlyphOutlineW(physDev->hdc, glyph, ggo_format, &gm, 0, NULL,
|
||||
NULL);
|
||||
}
|
||||
|
@ -689,29 +715,45 @@ static BOOL UploadGlyph(X11DRV_PDEVICE *physDev, int glyph, AA_Type format)
|
|||
if(formatEntry->glyphset == 0 && X11DRV_XRender_Installed) {
|
||||
switch(format) {
|
||||
case AA_Grey:
|
||||
pf_mask = PictFormatType | PictFormatDepth | PictFormatAlpha | PictFormatAlphaMask,
|
||||
pf.type = PictTypeDirect;
|
||||
pf.depth = 8;
|
||||
pf.direct.alpha = 0;
|
||||
pf.direct.alphaMask = 0xff;
|
||||
break;
|
||||
|
||||
case AA_RGB:
|
||||
case AA_BGR:
|
||||
case AA_VRGB:
|
||||
case AA_VBGR:
|
||||
pf_mask = PictFormatType | PictFormatDepth | PictFormatRed | PictFormatRedMask |
|
||||
PictFormatGreen | PictFormatGreenMask | PictFormatBlue |
|
||||
PictFormatBlueMask | PictFormatAlpha | PictFormatAlphaMask;
|
||||
pf.type = PictTypeDirect;
|
||||
pf.depth = 32;
|
||||
pf.direct.red = 16;
|
||||
pf.direct.redMask = 0xff;
|
||||
pf.direct.green = 8;
|
||||
pf.direct.greenMask = 0xff;
|
||||
pf.direct.blue = 0;
|
||||
pf.direct.blueMask = 0xff;
|
||||
pf.direct.alpha = 24;
|
||||
pf.direct.alphaMask = 0xff;
|
||||
break;
|
||||
|
||||
default:
|
||||
ERR("aa = %d - not implemented\n", format);
|
||||
case AA_None:
|
||||
pf_mask = PictFormatType | PictFormatDepth | PictFormatAlpha | PictFormatAlphaMask,
|
||||
pf.type = PictTypeDirect;
|
||||
pf.depth = 1;
|
||||
pf.direct.alpha = 0;
|
||||
pf.direct.alphaMask = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
pf.type = PictTypeDirect;
|
||||
pf.direct.alpha = 0;
|
||||
|
||||
wine_tsx11_lock();
|
||||
formatEntry->font_format = pXRenderFindFormat(gdi_display,
|
||||
PictFormatType |
|
||||
PictFormatDepth |
|
||||
PictFormatAlpha |
|
||||
PictFormatAlphaMask,
|
||||
&pf, 0);
|
||||
|
||||
formatEntry->font_format = pXRenderFindFormat(gdi_display, pf_mask, &pf, 0);
|
||||
formatEntry->glyphset = pXRenderCreateGlyphSet(gdi_display, formatEntry->font_format);
|
||||
wine_tsx11_unlock();
|
||||
}
|
||||
|
@ -783,6 +825,12 @@ static BOOL UploadGlyph(X11DRV_PDEVICE *physDev, int glyph, AA_Type format)
|
|||
*byte++ = c;
|
||||
}
|
||||
}
|
||||
else if ( format != AA_Grey &&
|
||||
ImageByteOrder (gdi_display) != NATIVE_BYTE_ORDER)
|
||||
{
|
||||
unsigned int i, *data = (unsigned int *)buf;
|
||||
for (i = buflen / sizeof(int); i; i--, data++) *data = RtlUlongByteSwap(*data);
|
||||
}
|
||||
gid = glyph;
|
||||
|
||||
/*
|
||||
|
|
|
@ -117,6 +117,9 @@
|
|||
/* Define to 1 if you have the <freetype/ftglyph.h> header file. */
|
||||
#undef HAVE_FREETYPE_FTGLYPH_H
|
||||
|
||||
/* Define to 1 if you have the <freetype/ftlcdfil.h> header file. */
|
||||
#undef HAVE_FREETYPE_FTLCDFIL_H
|
||||
|
||||
/* Define to 1 if you have the <freetype/ftmodapi.h> header file. */
|
||||
#undef HAVE_FREETYPE_FTMODAPI_H
|
||||
|
||||
|
|
|
@ -1297,7 +1297,11 @@ typedef struct
|
|||
#define GGO_UNHINTED 0x100
|
||||
|
||||
#ifdef __WINESRC__
|
||||
#define WINE_GGO_GRAY16_BITMAP 0x7f
|
||||
#define WINE_GGO_GRAY16_BITMAP 0x10
|
||||
#define WINE_GGO_HRGB_BITMAP 0x11
|
||||
#define WINE_GGO_HBGR_BITMAP 0x12
|
||||
#define WINE_GGO_VRGB_BITMAP 0x13
|
||||
#define WINE_GGO_VBGR_BITMAP 0x14
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
|
@ -1424,6 +1428,7 @@ typedef struct
|
|||
#define TT_ENABLED 0x0002
|
||||
|
||||
#ifdef __WINESRC__
|
||||
#define WINE_TT_SUBPIXEL_RENDERING_ENABLED 0x4000
|
||||
#define WINE_TT_HINTER_ENABLED 0x8000
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Reference in New Issue