gdi32: Move checking of the subpixel support and gasp flags to freetype.c.
This commit is contained in:
parent
9cdb0e1ca6
commit
123da6f888
@ -39,12 +39,6 @@
|
|||||||
#include "wine/unicode.h"
|
#include "wine/unicode.h"
|
||||||
#include "wine/debug.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);
|
WINE_DEFAULT_DEBUG_CHANNEL(font);
|
||||||
|
|
||||||
/* Device -> World size conversion */
|
/* Device -> World size conversion */
|
||||||
@ -266,69 +260,6 @@ static void FONT_NewTextMetricExWToA(const NEWTEXTMETRICEXW *ptmW, NEWTEXTMETRIC
|
|||||||
memcpy(&ptmA->ntmFontSig, &ptmW->ntmFontSig, sizeof(FONTSIGNATURE));
|
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 };
|
enum smoothing { no_smoothing, aa_smoothing, subpixel_smoothing };
|
||||||
|
|
||||||
static DWORD get_desktop_value( const WCHAR *name, DWORD *value )
|
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 )
|
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;
|
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)
|
switch (lf->lfQuality)
|
||||||
{
|
{
|
||||||
case NONANTIALIASED_QUALITY:
|
case NONANTIALIASED_QUALITY:
|
||||||
@ -423,25 +343,16 @@ UINT get_font_aa_flags( HDC hdc, const LOGFONTW *lf )
|
|||||||
smoothing = get_default_smoothing();
|
smoothing = get_default_smoothing();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (smoothing == subpixel_smoothing)
|
switch (smoothing)
|
||||||
{
|
{
|
||||||
if (subpixel_enabled)
|
case subpixel_smoothing:
|
||||||
{
|
return get_subpixel_orientation();
|
||||||
UINT ret = get_subpixel_orientation();
|
case aa_smoothing:
|
||||||
if (ret != GGO_GRAY4_BITMAP) return ret;
|
|
||||||
}
|
|
||||||
smoothing = aa_smoothing;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (smoothing == aa_smoothing)
|
|
||||||
{
|
|
||||||
if (hinter && get_gasp_flags( hdc, &gasp_flags ) && !(gasp_flags & GASP_DOGRAY))
|
|
||||||
return GGO_BITMAP;
|
|
||||||
return GGO_GRAY4_BITMAP;
|
return GGO_GRAY4_BITMAP;
|
||||||
}
|
default:
|
||||||
|
|
||||||
return GGO_BITMAP;
|
return GGO_BITMAP;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* GdiGetCodePage (GDI32.@)
|
* GdiGetCodePage (GDI32.@)
|
||||||
|
@ -894,6 +894,44 @@ static inline FT_Fixed FT_FixedFromFIXED(FIXED f)
|
|||||||
return (FT_Fixed)((int)f.value << 16 | (unsigned int)f.fract);
|
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)
|
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;
|
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
|
* freetype_SelectFont
|
||||||
*/
|
*/
|
||||||
@ -4868,6 +4953,25 @@ found_face:
|
|||||||
done:
|
done:
|
||||||
if (ret)
|
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;
|
dc->gdiFont = ret;
|
||||||
physdev->font = ret;
|
physdev->font = ret;
|
||||||
}
|
}
|
||||||
@ -7430,40 +7534,6 @@ static BOOL freetype_FontIsLinked( PHYSDEV dev )
|
|||||||
return ret;
|
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.@)
|
* GetRasterizerCaps (GDI32.@)
|
||||||
*/
|
*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user