Commit 123da6f8 authored by Alexandre Julliard's avatar Alexandre Julliard

gdi32: Move checking of the subpixel support and gasp flags to freetype.c.

parent 9cdb0e1c
......@@ -39,12 +39,6 @@
#include "wine/unicode.h"
#include "wine/debug.h"
#ifdef WORDS_BIGENDIAN
#define get_be_word(x) (x)
#else
#define get_be_word(x) RtlUshortByteSwap(x)
#endif
WINE_DEFAULT_DEBUG_CHANNEL(font);
/* Device -> World size conversion */
......@@ -266,69 +260,6 @@ static void FONT_NewTextMetricExWToA(const NEWTEXTMETRICEXW *ptmW, NEWTEXTMETRIC
memcpy(&ptmA->ntmFontSig, &ptmW->ntmFontSig, sizeof(FONTSIGNATURE));
}
static DWORD get_font_ppem( HDC hdc )
{
TEXTMETRICW tm;
DWORD ppem;
DC *dc = get_dc_ptr( hdc );
if (!dc) return GDI_ERROR;
GetTextMetricsW( hdc, &tm );
ppem = abs( INTERNAL_YWSTODS( dc, tm.tmAscent + tm.tmDescent - tm.tmInternalLeading ) );
release_dc_ptr( dc );
return ppem;
}
#define GASP_GRIDFIT 0x01
#define GASP_DOGRAY 0x02
static BOOL get_gasp_flags( HDC hdc, WORD *flags )
{
DWORD size, gasp_tag = 0x70736167;
WORD buf[16]; /* Enough for seven ranges before we need to alloc */
WORD *alloced = NULL, *ptr = buf;
WORD num_recs, version;
DWORD ppem = get_font_ppem( hdc );
BOOL ret = FALSE;
*flags = 0;
if (ppem == GDI_ERROR) return FALSE;
size = GetFontData( hdc, gasp_tag, 0, NULL, 0 );
if (size == GDI_ERROR) return FALSE;
if (size < 4 * sizeof(WORD)) return FALSE;
if (size > sizeof(buf))
{
ptr = alloced = HeapAlloc( GetProcessHeap(), 0, size );
if (!ptr) return FALSE;
}
GetFontData( hdc, gasp_tag, 0, ptr, size );
version = get_be_word( *ptr++ );
num_recs = get_be_word( *ptr++ );
if (version > 1 || size < (num_recs * 2 + 2) * sizeof(WORD))
{
FIXME( "Unsupported gasp table: ver %d size %d recs %d\n", version, size, num_recs );
goto done;
}
while (num_recs--)
{
*flags = get_be_word( *(ptr + 1) );
if (ppem <= get_be_word( *ptr )) break;
ptr += 2;
}
TRACE( "got flags %04x for ppem %d\n", *flags, ppem );
ret = TRUE;
done:
HeapFree( GetProcessHeap(), 0, alloced );
return ret;
}
enum smoothing { no_smoothing, aa_smoothing, subpixel_smoothing };
static DWORD get_desktop_value( const WCHAR *name, DWORD *value )
......@@ -392,19 +323,8 @@ static UINT get_subpixel_orientation( void )
UINT get_font_aa_flags( HDC hdc, const LOGFONTW *lf )
{
WORD gasp_flags;
static int hinter = -1;
static int subpixel_enabled = -1;
enum smoothing smoothing;
if (hinter == -1 || subpixel_enabled == -1)
{
RASTERIZER_STATUS status;
GetRasterizerCaps(&status, sizeof(status));
hinter = status.wFlags & WINE_TT_HINTER_ENABLED;
subpixel_enabled = status.wFlags & WINE_TT_SUBPIXEL_RENDERING_ENABLED;
}
switch (lf->lfQuality)
{
case NONANTIALIASED_QUALITY:
......@@ -423,24 +343,15 @@ UINT get_font_aa_flags( HDC hdc, const LOGFONTW *lf )
smoothing = get_default_smoothing();
}
if (smoothing == subpixel_smoothing)
{
if (subpixel_enabled)
{
UINT ret = get_subpixel_orientation();
if (ret != GGO_GRAY4_BITMAP) return ret;
}
smoothing = aa_smoothing;
}
if (smoothing == aa_smoothing)
switch (smoothing)
{
if (hinter && get_gasp_flags( hdc, &gasp_flags ) && !(gasp_flags & GASP_DOGRAY))
return GGO_BITMAP;
case subpixel_smoothing:
return get_subpixel_orientation();
case aa_smoothing:
return GGO_GRAY4_BITMAP;
default:
return GGO_BITMAP;
}
return GGO_BITMAP;
}
/***********************************************************************
......
......@@ -894,6 +894,44 @@ static inline FT_Fixed FT_FixedFromFIXED(FIXED f)
return (FT_Fixed)((int)f.value << 16 | (unsigned int)f.fract);
}
static BOOL is_hinting_enabled(void)
{
static int enabled = -1;
if (enabled == -1)
{
/* Use the >= 2.2.0 function if available */
if (pFT_Get_TrueType_Engine_Type)
{
FT_TrueTypeEngineType type = pFT_Get_TrueType_Engine_Type(library);
enabled = (type == FT_TRUETYPE_ENGINE_TYPE_PATENTED);
}
#ifdef FT_DRIVER_HAS_HINTER
else
{
/* otherwise if we've been compiled with < 2.2.0 headers use the internal macro */
FT_Module mod = pFT_Get_Module(library, "truetype");
enabled = (mod && FT_DRIVER_HAS_HINTER(mod));
}
#endif
else enabled = FALSE;
}
return enabled;
}
static BOOL is_subpixel_rendering_enabled( void )
{
#ifdef HAVE_FREETYPE_FTLCDFIL_H
static int enabled = -1;
if (enabled == -1)
enabled = (pFT_Library_SetLcdFilter &&
pFT_Library_SetLcdFilter( NULL, 0 ) != FT_Err_Unimplemented_Feature);
return enabled;
#else
return FALSE;
#endif
}
static const struct list *get_face_list_from_family(const Family *family)
{
......@@ -4426,6 +4464,53 @@ static FT_Encoding pick_charmap( FT_Face face, int charset )
return *encs;
}
#define GASP_GRIDFIT 0x01
#define GASP_DOGRAY 0x02
#define GASP_TAG MS_MAKE_TAG('g','a','s','p')
static BOOL get_gasp_flags( GdiFont *font, WORD *flags )
{
DWORD size;
WORD buf[16]; /* Enough for seven ranges before we need to alloc */
WORD *alloced = NULL, *ptr = buf;
WORD num_recs, version;
BOOL ret = FALSE;
*flags = 0;
size = get_font_data( font, GASP_TAG, 0, NULL, 0 );
if (size == GDI_ERROR) return FALSE;
if (size < 4 * sizeof(WORD)) return FALSE;
if (size > sizeof(buf))
{
ptr = alloced = HeapAlloc( GetProcessHeap(), 0, size );
if (!ptr) return FALSE;
}
get_font_data( font, GASP_TAG, 0, ptr, size );
version = GET_BE_WORD( *ptr++ );
num_recs = GET_BE_WORD( *ptr++ );
if (version > 1 || size < (num_recs * 2 + 2) * sizeof(WORD))
{
FIXME( "Unsupported gasp table: ver %d size %d recs %d\n", version, size, num_recs );
goto done;
}
while (num_recs--)
{
*flags = GET_BE_WORD( *(ptr + 1) );
if (font->ft_face->size->metrics.y_ppem <= GET_BE_WORD( *ptr )) break;
ptr += 2;
}
TRACE( "got flags %04x for ppem %d\n", *flags, font->ft_face->size->metrics.y_ppem );
ret = TRUE;
done:
HeapFree( GetProcessHeap(), 0, alloced );
return ret;
}
/*************************************************************
* freetype_SelectFont
*/
......@@ -4868,6 +4953,25 @@ found_face:
done:
if (ret)
{
/* 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_GRAY4_BITMAP:
if (is_hinting_enabled())
{
WORD gasp_flags;
if (get_gasp_flags( ret, &gasp_flags ) && !(gasp_flags & GASP_DOGRAY))
*aa_flags = GGO_BITMAP;
}
break;
}
dc->gdiFont = ret;
physdev->font = ret;
}
......@@ -7430,40 +7534,6 @@ static BOOL freetype_FontIsLinked( PHYSDEV dev )
return ret;
}
static BOOL is_hinting_enabled(void)
{
/* Use the >= 2.2.0 function if available */
if(pFT_Get_TrueType_Engine_Type)
{
FT_TrueTypeEngineType type = pFT_Get_TrueType_Engine_Type(library);
return type == FT_TRUETYPE_ENGINE_TYPE_PATENTED;
}
#ifdef FT_DRIVER_HAS_HINTER
else
{
FT_Module mod;
/* otherwise if we've been compiled with < 2.2.0 headers
use the internal macro */
mod = pFT_Get_Module(library, "truetype");
if(mod && FT_DRIVER_HAS_HINTER(mod))
return TRUE;
}
#endif
return FALSE;
}
static BOOL is_subpixel_rendering_enabled( void )
{
#ifdef HAVE_FREETYPE_FTLCDFIL_H
return pFT_Library_SetLcdFilter &&
pFT_Library_SetLcdFilter( NULL, 0 ) != FT_Err_Unimplemented_Feature;
#else
return FALSE;
#endif
}
/*************************************************************************
* GetRasterizerCaps (GDI32.@)
*/
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment