gdi32: Move the default AA flags handling out of freetype.c.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2020-11-03 11:25:30 +01:00
parent e4df6f87ca
commit de63a647d5
4 changed files with 141 additions and 173 deletions

View File

@ -651,6 +651,11 @@ static HBRUSH CDECL nulldrv_SelectBrush( PHYSDEV dev, HBRUSH brush, const struct
return brush;
}
static HFONT CDECL nulldrv_SelectFont( PHYSDEV dev, HFONT font, UINT *aa_flags )
{
return font;
}
static HPALETTE CDECL nulldrv_SelectPalette( PHYSDEV dev, HPALETTE palette, BOOL bkgnd )
{
return palette;

View File

@ -60,6 +60,10 @@ static const struct font_backend_funcs *font_funcs;
static const MAT2 identity = { {0,1}, {0,0}, {0,0}, {0,1} };
static UINT font_smoothing = GGO_BITMAP;
static UINT subpixel_orientation = GGO_GRAY4_BITMAP;
static BOOL antialias_fakes = TRUE;
/* Device -> World size conversion */
/* Performs a device to world transformation on the specified width (which
@ -1636,6 +1640,7 @@ static void release_gdi_font( struct gdi_font *font )
TRACE( "font %p\n", font );
/* add it to the unused list */
EnterCriticalSection( &font_cs );
list_add_head( &unused_gdi_font_list, &font->unused_entry );
if (unused_font_count > UNUSED_CACHE_SIZE)
{
@ -1644,9 +1649,9 @@ static void release_gdi_font( struct gdi_font *font )
list_remove( &font->entry );
list_remove( &font->unused_entry );
free_gdi_font( font );
return;
}
unused_font_count++;
else unused_font_count++;
LeaveCriticalSection( &font_cs );
}
static void add_font_list(HKEY hkey, const struct nls_update_font_list *fl, int dpi)
@ -2929,27 +2934,46 @@ static BOOL CDECL font_GetTextMetrics( PHYSDEV dev, TEXTMETRICW *metrics )
*/
static HFONT CDECL font_SelectFont( PHYSDEV dev, HFONT hfont, UINT *aa_flags )
{
UINT default_aa_flags = *aa_flags;
struct font_physdev *physdev = get_font_dev( dev );
struct gdi_font *prev = physdev->font;
struct gdi_font *font = NULL, *prev = physdev->font;
DC *dc = get_physdev_dc( dev );
if (!default_aa_flags)
{
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSelectFont );
next->funcs->pSelectFont( next, hfont, &default_aa_flags );
}
if (hfont)
{
LOGFONTW lf;
GetObjectW( hfont, sizeof(lf), &lf );
switch (lf.lfQuality)
{
case NONANTIALIASED_QUALITY:
if (!*aa_flags) *aa_flags = GGO_BITMAP;
break;
case ANTIALIASED_QUALITY:
if (!*aa_flags) *aa_flags = GGO_GRAY4_BITMAP;
break;
}
EnterCriticalSection( &font_cs );
physdev->font = font_funcs->pSelectFont( dc, hfont, aa_flags, default_aa_flags );
font = font_funcs->pSelectFont( dc, hfont );
if (font && !*aa_flags)
{
*aa_flags = font->aa_flags;
if (!*aa_flags)
{
if (lf.lfQuality == CLEARTYPE_QUALITY || lf.lfQuality == CLEARTYPE_NATURAL_QUALITY)
*aa_flags = subpixel_orientation;
else
*aa_flags = font_smoothing;
}
*aa_flags = font_funcs->get_aa_flags( font, *aa_flags, antialias_fakes );
}
TRACE( "%p %s %d aa %x\n", hfont, debugstr_w(lf.lfFaceName), lf.lfHeight, *aa_flags );
LeaveCriticalSection( &font_cs );
}
else physdev->font = NULL; /* notification that the font has been changed by another driver */
physdev->font = font;
if (prev) release_gdi_font( prev );
return physdev->font ? hfont : 0;
return font ? hfont : 0;
}
@ -3089,6 +3113,68 @@ const struct gdi_dc_funcs font_driver =
GDI_PRIORITY_FONT_DRV /* priority */
};
static DWORD get_key_value( HKEY key, const WCHAR *name, DWORD *value )
{
WCHAR buf[12];
DWORD count = sizeof(buf), type, err;
err = RegQueryValueExW( key, name, NULL, &type, (BYTE *)buf, &count );
if (!err)
{
if (type == REG_DWORD) memcpy( value, buf, sizeof(*value) );
else *value = atoiW( buf );
}
return err;
}
static void init_font_options(void)
{
static const WCHAR antialias_fake_bold_or_italic[] = { 'A','n','t','i','a','l','i','a','s','F','a','k','e',
'B','o','l','d','O','r','I','t','a','l','i','c',0 };
static const WCHAR true_options[] = { 'y','Y','t','T','1',0 };
static const WCHAR desktopW[] = { 'C','o','n','t','r','o','l',' ','P','a','n','e','l','\\',
'D','e','s','k','t','o','p',0 };
static const WCHAR smoothing[] = {'F','o','n','t','S','m','o','o','t','h','i','n','g',0};
static const WCHAR smoothing_type[] = {'F','o','n','t','S','m','o','o','t','h','i','n','g','T','y','p','e',0};
static const WCHAR smoothing_orientation[] = {'F','o','n','t','S','m','o','o','t','h','i','n','g',
'O','r','i','e','n','t','a','t','i','o','n',0};
HKEY key;
DWORD type, size, val;
WCHAR buffer[20];
size = sizeof(buffer);
if (!RegQueryValueExW( wine_fonts_key, antialias_fake_bold_or_italic, NULL,
&type, (BYTE *)buffer, &size) && type == REG_SZ && size >= 1)
{
antialias_fakes = (strchrW(true_options, buffer[0]) != NULL);
}
if (!RegOpenKeyW( HKEY_CURRENT_USER, desktopW, &key ))
{
/* FIXME: handle vertical orientations even though Windows doesn't */
if (!get_key_value( key, smoothing_orientation, &val ))
{
switch (val)
{
case 0: /* FE_FONTSMOOTHINGORIENTATIONBGR */
subpixel_orientation = WINE_GGO_HBGR_BITMAP;
break;
case 1: /* FE_FONTSMOOTHINGORIENTATIONRGB */
subpixel_orientation = WINE_GGO_HRGB_BITMAP;
break;
}
}
if (!get_key_value( key, smoothing, &val ) && val /* enabled */)
{
if (!get_key_value( key, smoothing_type, &val ) && val == 2 /* FE_FONTSMOOTHINGCLEARTYPE */)
font_smoothing = subpixel_orientation;
else
font_smoothing = GGO_GRAY4_BITMAP;
}
RegCloseKey( key );
}
}
/***********************************************************************
* font_init
*/
@ -3098,6 +3184,7 @@ void font_init(void)
KEY_ALL_ACCESS, NULL, &wine_fonts_key, NULL ))
return;
init_font_options();
update_codepage();
WineEngInit( &font_funcs );
load_gdi_font_subst();
@ -3206,54 +3293,6 @@ static void FONT_NewTextMetricExWToA(const NEWTEXTMETRICEXW *ptmW, NEWTEXTMETRIC
memcpy(&ptmA->ntmFontSig, &ptmW->ntmFontSig, sizeof(FONTSIGNATURE));
}
static DWORD get_key_value( HKEY key, const WCHAR *name, DWORD *value )
{
WCHAR buf[12];
DWORD count = sizeof(buf), type, err;
err = RegQueryValueExW( key, name, NULL, &type, (BYTE *)buf, &count );
if (!err)
{
if (type == REG_DWORD) memcpy( value, buf, sizeof(*value) );
else *value = atoiW( buf );
}
return err;
}
static UINT get_subpixel_orientation( HKEY key )
{
static const WCHAR smoothing_orientation[] = {'F','o','n','t','S','m','o','o','t','h','i','n','g',
'O','r','i','e','n','t','a','t','i','o','n',0};
DWORD orient;
/* FIXME: handle vertical orientations even though Windows doesn't */
if (get_key_value( key, smoothing_orientation, &orient )) return GGO_GRAY4_BITMAP;
switch (orient)
{
case 0: /* FE_FONTSMOOTHINGORIENTATIONBGR */
return WINE_GGO_HBGR_BITMAP;
case 1: /* FE_FONTSMOOTHINGORIENTATIONRGB */
return WINE_GGO_HRGB_BITMAP;
}
return GGO_GRAY4_BITMAP;
}
static UINT get_default_smoothing( HKEY key )
{
static const WCHAR smoothing[] = {'F','o','n','t','S','m','o','o','t','h','i','n','g',0};
static const WCHAR smoothing_type[] = {'F','o','n','t','S','m','o','o','t','h','i','n','g','T','y','p','e',0};
DWORD enabled, type;
if (get_key_value( key, smoothing, &enabled )) return 0;
if (!enabled) return GGO_BITMAP;
if (!get_key_value( key, smoothing_type, &type ) && type == 2 /* FE_FONTSMOOTHINGCLEARTYPE */)
return get_subpixel_orientation( key );
return GGO_GRAY4_BITMAP;
}
/* compute positions for text rendering, in device coords */
static BOOL get_char_positions( DC *dc, const WCHAR *str, INT count, INT *dx, SIZE *size )
{
@ -3808,52 +3847,6 @@ static BOOL FONT_DeleteObject( HGDIOBJ handle )
}
/***********************************************************************
* nulldrv_SelectFont
*/
HFONT CDECL nulldrv_SelectFont( PHYSDEV dev, HFONT font, UINT *aa_flags )
{
static const WCHAR desktopW[] = { 'C','o','n','t','r','o','l',' ','P','a','n','e','l','\\',
'D','e','s','k','t','o','p',0 };
static int orientation = -1, smoothing = -1;
LOGFONTW lf;
HKEY key;
if (*aa_flags) return 0;
GetObjectW( font, sizeof(lf), &lf );
switch (lf.lfQuality)
{
case NONANTIALIASED_QUALITY:
*aa_flags = GGO_BITMAP;
break;
case ANTIALIASED_QUALITY:
*aa_flags = GGO_GRAY4_BITMAP;
break;
case CLEARTYPE_QUALITY:
case CLEARTYPE_NATURAL_QUALITY:
if (orientation == -1)
{
if (RegOpenKeyW( HKEY_CURRENT_USER, desktopW, &key )) break;
orientation = get_subpixel_orientation( key );
RegCloseKey( key );
}
*aa_flags = orientation;
break;
default:
if (smoothing == -1)
{
if (RegOpenKeyW( HKEY_CURRENT_USER, desktopW, &key )) break;
smoothing = get_default_smoothing( key );
RegCloseKey( key );
}
*aa_flags = smoothing;
break;
}
return 0;
}
/***********************************************************************
* FONT_EnumInstance
*

View File

@ -323,7 +323,6 @@ static struct list mappings_list = LIST_INIT( mappings_list );
static UINT default_aa_flags;
static HKEY hkey_font_cache;
static BOOL antialias_fakes = TRUE;
static const WCHAR font_mutex_nameW[] = {'_','_','W','I','N','E','_','F','O','N','T','_','M','U','T','E','X','_','_','\0'};
@ -2248,7 +2247,6 @@ static void reorder_font_list(void)
*/
BOOL WineEngInit( const struct font_backend_funcs **funcs )
{
HKEY hkey;
DWORD disposition;
HANDLE font_mutex;
@ -2260,23 +2258,6 @@ BOOL WineEngInit( const struct font_backend_funcs **funcs )
*funcs = &font_funcs;
if (!RegOpenKeyExW(HKEY_CURRENT_USER, wine_fonts_key, 0, KEY_READ, &hkey))
{
static const WCHAR antialias_fake_bold_or_italic[] = { 'A','n','t','i','a','l','i','a','s','F','a','k','e',
'B','o','l','d','O','r','I','t','a','l','i','c',0 };
static const WCHAR true_options[] = { 'y','Y','t','T','1',0 };
DWORD type, size;
WCHAR buffer[20];
size = sizeof(buffer);
if (!RegQueryValueExW(hkey, antialias_fake_bold_or_italic, NULL, &type, (BYTE*)buffer, &size) &&
type == REG_SZ && size >= 1)
{
antialias_fakes = (strchrW(true_options, buffer[0]) != NULL);
}
RegCloseKey(hkey);
}
if((font_mutex = CreateMutexW(NULL, FALSE, font_mutex_nameW)) == NULL)
{
ERR("Failed to create font mutex\n");
@ -2972,8 +2953,7 @@ static BOOL CDECL freetype_load_font( struct gdi_font *font )
/*************************************************************
* freetype_SelectFont
*/
static struct gdi_font * CDECL freetype_SelectFont( DC *dc, HFONT hfont, UINT *aa_flags,
UINT default_aa_flags )
static struct gdi_font * CDECL freetype_SelectFont( DC *dc, HFONT hfont )
{
struct gdi_font *font;
Face *face, *best, *best_bitmap;
@ -3032,7 +3012,7 @@ static struct gdi_font * CDECL freetype_SelectFont( DC *dc, HFONT hfont, UINT *a
/* check the cache first */
if ((font = find_cached_gdi_font( &lf, &dcmat, can_use_bitmap ))) {
TRACE("returning cached gdiFont(%p) for hFont %p\n", font, hfont);
goto done;
return font;
}
/* If lfFaceName is "Symbol" then Windows fixes up lfCharSet to
@ -3295,8 +3275,7 @@ found_face:
if((cachedfont = find_cached_gdi_font( &lf, &dcmat, can_use_bitmap ))) {
TRACE("Found cached font after non-scalable matrix rescale!\n");
free_gdi_font( font );
font = cachedfont;
goto done;
return cachedfont;
}
if (height != 0) height = diff;
@ -3326,50 +3305,40 @@ found_face:
TRACE("caching: gdiFont=%p hfont=%p\n", font, hfont);
cache_gdi_font( font );
done:
if (font)
{
switch (lf.lfQuality)
{
case NONANTIALIASED_QUALITY:
case ANTIALIASED_QUALITY:
if (!*aa_flags) *aa_flags = default_aa_flags;
break;
case CLEARTYPE_QUALITY:
case CLEARTYPE_NATURAL_QUALITY:
default:
if (!*aa_flags) *aa_flags = font->aa_flags;
if (!*aa_flags) *aa_flags = default_aa_flags;
return font;
}
/* fixup the antialiasing flags for that font */
switch (*aa_flags)
/*************************************************************
* freetype_get_aa_flags
*/
static UINT CDECL freetype_get_aa_flags( struct gdi_font *font, UINT aa_flags, BOOL antialias_fakes )
{
/* fixup the antialiasing flags for that font */
switch (aa_flags)
{
case WINE_GGO_HRGB_BITMAP:
case WINE_GGO_HBGR_BITMAP:
case WINE_GGO_VRGB_BITMAP:
case WINE_GGO_VBGR_BITMAP:
if (is_subpixel_rendering_enabled()) break;
aa_flags = GGO_GRAY4_BITMAP;
/* fall through */
case GGO_GRAY2_BITMAP:
case GGO_GRAY4_BITMAP:
case GGO_GRAY8_BITMAP:
case WINE_GGO_GRAY16_BITMAP:
if ((!antialias_fakes || (!font->fake_bold && !font->fake_italic)) && is_hinting_enabled())
{
WORD gasp_flags;
if (get_gasp_flags( font, &gasp_flags ) && !(gasp_flags & GASP_DOGRAY))
{
case WINE_GGO_HRGB_BITMAP:
case WINE_GGO_HBGR_BITMAP:
case WINE_GGO_VRGB_BITMAP:
case WINE_GGO_VBGR_BITMAP:
if (is_subpixel_rendering_enabled()) break;
*aa_flags = GGO_GRAY4_BITMAP;
/* fall through */
case GGO_GRAY2_BITMAP:
case GGO_GRAY4_BITMAP:
case GGO_GRAY8_BITMAP:
case WINE_GGO_GRAY16_BITMAP:
if ((!antialias_fakes || (!font->fake_bold && !font->fake_italic)) && is_hinting_enabled())
{
WORD gasp_flags;
if (get_gasp_flags( font, &gasp_flags ) && !(gasp_flags & GASP_DOGRAY))
{
TRACE( "font %s %d aa disabled by GASP\n",
debugstr_w(lf.lfFaceName), lf.lfHeight );
*aa_flags = GGO_BITMAP;
}
}
TRACE( "font %s %d aa disabled by GASP\n",
debugstr_w(font->lf.lfFaceName), font->lf.lfHeight );
aa_flags = GGO_BITMAP;
}
}
TRACE( "%p %s %d aa %x\n", hfont, debugstr_w(lf.lfFaceName), lf.lfHeight, *aa_flags );
}
return font;
return aa_flags;
}
static void FTVectorToPOINTFX(FT_Vector *vec, POINTFX *pt)
@ -5131,6 +5100,7 @@ static const struct font_backend_funcs font_funcs =
freetype_remove_font,
freetype_load_font,
freetype_get_font_data,
freetype_get_aa_flags,
freetype_get_glyph_index,
freetype_get_default_glyph,
freetype_get_glyph_outline,

View File

@ -425,7 +425,7 @@ struct gdi_font
struct font_backend_funcs
{
struct gdi_font * (CDECL *pSelectFont)( DC *dc, HFONT hfont, UINT *aa_flags, UINT default_aa_flags );
struct gdi_font * (CDECL *pSelectFont)( DC *dc, HFONT hfont );
INT (CDECL *add_font)( const WCHAR *file, DWORD flags );
INT (CDECL *add_mem_font)( void *ptr, SIZE_T size, DWORD flags );
@ -434,6 +434,7 @@ struct font_backend_funcs
BOOL (CDECL *load_font)( struct gdi_font *gdi_font );
DWORD (CDECL *get_font_data)( struct gdi_font *gdi_font, DWORD table, DWORD offset,
void *buf, DWORD count );
UINT (CDECL *get_aa_flags)( struct gdi_font *font, UINT aa_flags, BOOL antialias_fakes );
BOOL (CDECL *get_glyph_index)( struct gdi_font *gdi_font, UINT *glyph, BOOL use_encoding );
UINT (CDECL *get_default_glyph)( struct gdi_font *gdi_font );
DWORD (CDECL *get_glyph_outline)( struct gdi_font *font, UINT glyph, UINT format,
@ -644,7 +645,6 @@ extern INT CDECL nulldrv_SaveDC( PHYSDEV dev ) DECLSPEC_HIDDEN;
extern BOOL CDECL nulldrv_ScaleViewportExtEx( PHYSDEV dev, INT x_num, INT x_denom, INT y_num, INT y_denom, SIZE *size ) DECLSPEC_HIDDEN;
extern BOOL CDECL nulldrv_ScaleWindowExtEx( PHYSDEV dev, INT x_num, INT x_denom, INT y_num, INT y_denom, SIZE *size ) DECLSPEC_HIDDEN;
extern BOOL CDECL nulldrv_SelectClipPath( PHYSDEV dev, INT mode ) DECLSPEC_HIDDEN;
extern HFONT CDECL nulldrv_SelectFont( PHYSDEV dev, HFONT font, UINT *ggo_flags ) DECLSPEC_HIDDEN;
extern INT CDECL nulldrv_SetDIBitsToDevice( PHYSDEV dev, INT x_dst, INT y_dst, DWORD width, DWORD height,
INT x_src, INT y_src, UINT start, UINT lines,
const void *bits, BITMAPINFO *info, UINT coloruse ) DECLSPEC_HIDDEN;