gdi32: Move the SelectFont() implementation out of freetype.c.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
3b87839ec9
commit
53acdd5a8a
|
@ -472,7 +472,7 @@ static void dump_gdi_font_subst(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const WCHAR *get_gdi_font_subst( const WCHAR *from_name, int from_charset, int *to_charset )
|
static const WCHAR *get_gdi_font_subst( const WCHAR *from_name, int from_charset, int *to_charset )
|
||||||
{
|
{
|
||||||
struct gdi_font_subst *subst;
|
struct gdi_font_subst *subst;
|
||||||
|
|
||||||
|
@ -1162,7 +1162,7 @@ static void remove_face_from_cache( struct gdi_font_face *face )
|
||||||
|
|
||||||
static struct list font_links = LIST_INIT(font_links);
|
static struct list font_links = LIST_INIT(font_links);
|
||||||
|
|
||||||
struct gdi_font_link *find_gdi_font_link( const WCHAR *name )
|
static struct gdi_font_link *find_gdi_font_link( const WCHAR *name )
|
||||||
{
|
{
|
||||||
struct gdi_font_link *link;
|
struct gdi_font_link *link;
|
||||||
|
|
||||||
|
@ -1525,7 +1525,7 @@ static struct gdi_font_face *find_any_face( const LOGFONTW *lf, FONTSIGNATURE fs
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct gdi_font_face *find_matching_face( LOGFONTW *lf, CHARSETINFO *csi, BOOL can_use_bitmap,
|
static struct gdi_font_face *find_matching_face( const LOGFONTW *lf, CHARSETINFO *csi, BOOL can_use_bitmap,
|
||||||
const WCHAR **orig_name )
|
const WCHAR **orig_name )
|
||||||
{
|
{
|
||||||
BOOL want_vertical = (lf->lfFaceName[0] == '@');
|
BOOL want_vertical = (lf->lfFaceName[0] == '@');
|
||||||
|
@ -1546,7 +1546,8 @@ struct gdi_font_face *find_matching_face( LOGFONTW *lf, CHARSETINFO *csi, BOOL c
|
||||||
{
|
{
|
||||||
TRACE( "substituting %s,%d -> %s,%d\n", debugstr_w(lf->lfFaceName), lf->lfCharSet,
|
TRACE( "substituting %s,%d -> %s,%d\n", debugstr_w(lf->lfFaceName), lf->lfCharSet,
|
||||||
debugstr_w(subst), (subst_charset != -1) ? subst_charset : lf->lfCharSet );
|
debugstr_w(subst), (subst_charset != -1) ? subst_charset : lf->lfCharSet );
|
||||||
if (subst_charset != -1) lf->lfCharSet = subst_charset;
|
if (subst_charset != -1)
|
||||||
|
TranslateCharsetInfo( (DWORD *)(INT_PTR)subst_charset, csi, TCI_SRCCHARSET );
|
||||||
*orig_name = lf->lfFaceName;
|
*orig_name = lf->lfFaceName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1565,7 +1566,6 @@ struct gdi_font_face *find_matching_face( LOGFONTW *lf, CHARSETINFO *csi, BOOL c
|
||||||
FIXME( "TCI failed on codepage %d\n", acp );
|
FIXME( "TCI failed on codepage %d\n", acp );
|
||||||
csi->fs.fsCsb[0] = 0;
|
csi->fs.fsCsb[0] = 0;
|
||||||
}
|
}
|
||||||
else lf->lfCharSet = csi->ciCharset;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((face = find_any_face( lf, csi->fs, can_use_bitmap, want_vertical ))) return face;
|
if ((face = find_any_face( lf, csi->fs, can_use_bitmap, want_vertical ))) return face;
|
||||||
|
@ -1681,7 +1681,7 @@ static struct gdi_font *alloc_gdi_font( const WCHAR *file, void *data_ptr, SIZE_
|
||||||
return font;
|
return font;
|
||||||
}
|
}
|
||||||
|
|
||||||
void free_gdi_font( struct gdi_font *font )
|
static void free_gdi_font( struct gdi_font *font )
|
||||||
{
|
{
|
||||||
DWORD i;
|
DWORD i;
|
||||||
struct gdi_font *child, *child_next;
|
struct gdi_font *child, *child_next;
|
||||||
|
@ -1712,7 +1712,7 @@ void set_gdi_font_names( struct gdi_font *font, const WCHAR *family_name, const
|
||||||
font->otm.otmpFaceName = (char *)strdupW( full_name );
|
font->otm.otmpFaceName = (char *)strdupW( full_name );
|
||||||
}
|
}
|
||||||
|
|
||||||
struct gdi_font *create_gdi_font( const struct gdi_font_face *face, const WCHAR *family_name,
|
static struct gdi_font *create_gdi_font( const struct gdi_font_face *face, const WCHAR *family_name,
|
||||||
const LOGFONTW *lf )
|
const LOGFONTW *lf )
|
||||||
{
|
{
|
||||||
struct gdi_font *font;
|
struct gdi_font *font;
|
||||||
|
@ -1979,7 +1979,7 @@ static const char *get_opentype_script( const struct gdi_font *font )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void *get_GSUB_vert_feature( struct gdi_font *font )
|
static void *get_GSUB_vert_feature( struct gdi_font *font )
|
||||||
{
|
{
|
||||||
GSUB_Header *header;
|
GSUB_Header *header;
|
||||||
GSUB_Script *script;
|
GSUB_Script *script;
|
||||||
|
@ -2132,7 +2132,7 @@ static void add_child_font( struct gdi_font *font, const WCHAR *family_name )
|
||||||
TRACE( "created child font %p for base %p\n", child, font );
|
TRACE( "created child font %p for base %p\n", child, font );
|
||||||
}
|
}
|
||||||
|
|
||||||
void create_child_font_list( struct gdi_font *font )
|
static void create_child_font_list( struct gdi_font *font )
|
||||||
{
|
{
|
||||||
static const WCHAR szDefaultFallbackLink[] = {'M','i','c','r','o','s','o','f','t',' ','S','a','n','s',' ','S','e','r','i','f',0};
|
static const WCHAR szDefaultFallbackLink[] = {'M','i','c','r','o','s','o','f','t',' ','S','a','n','s',' ','S','e','r','i','f',0};
|
||||||
struct gdi_font_link *font_link;
|
struct gdi_font_link *font_link;
|
||||||
|
@ -2206,7 +2206,7 @@ static DWORD hash_font( const LOGFONTW *lf, const FMAT2 *matrix, BOOL can_use_bi
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cache_gdi_font( struct gdi_font *font )
|
static void cache_gdi_font( struct gdi_font *font )
|
||||||
{
|
{
|
||||||
static DWORD cache_num = 1;
|
static DWORD cache_num = 1;
|
||||||
|
|
||||||
|
@ -2216,7 +2216,7 @@ void cache_gdi_font( struct gdi_font *font )
|
||||||
TRACE( "font %p\n", font );
|
TRACE( "font %p\n", font );
|
||||||
}
|
}
|
||||||
|
|
||||||
struct gdi_font *find_cached_gdi_font( const LOGFONTW *lf, const FMAT2 *matrix, BOOL can_use_bitmap )
|
static struct gdi_font *find_cached_gdi_font( const LOGFONTW *lf, const FMAT2 *matrix, BOOL can_use_bitmap )
|
||||||
{
|
{
|
||||||
struct gdi_font *font;
|
struct gdi_font *font;
|
||||||
DWORD hash = hash_font( lf, matrix, can_use_bitmap );
|
DWORD hash = hash_font( lf, matrix, can_use_bitmap );
|
||||||
|
@ -3534,6 +3534,133 @@ static BOOL CDECL font_GetTextMetrics( PHYSDEV dev, TEXTMETRICW *metrics )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void get_nearest_charset( const WCHAR *family_name, struct gdi_font_face *face, CHARSETINFO *csi )
|
||||||
|
{
|
||||||
|
/* Only get here if lfCharSet == DEFAULT_CHARSET or we couldn't find
|
||||||
|
a single face with the requested charset. The idea is to check if
|
||||||
|
the selected font supports the current ANSI codepage, if it does
|
||||||
|
return the corresponding charset, else return the first charset */
|
||||||
|
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (TranslateCharsetInfo( (DWORD*)(INT_PTR)GetACP(), csi, TCI_SRCCODEPAGE ))
|
||||||
|
{
|
||||||
|
const struct gdi_font_link *font_link;
|
||||||
|
|
||||||
|
if (csi->fs.fsCsb[0] & face->fs.fsCsb[0]) return;
|
||||||
|
font_link = find_gdi_font_link(family_name);
|
||||||
|
if (font_link && (csi->fs.fsCsb[0] & font_link->fs.fsCsb[0])) return;
|
||||||
|
}
|
||||||
|
for (i = 0; i < 32; i++)
|
||||||
|
{
|
||||||
|
DWORD fs0 = 1u << i;
|
||||||
|
if (face->fs.fsCsb[0] & fs0)
|
||||||
|
{
|
||||||
|
if (TranslateCharsetInfo(&fs0, csi, TCI_SRCFONTSIG)) return;
|
||||||
|
FIXME("TCI failing on %x\n", fs0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FIXME("returning DEFAULT_CHARSET face->fs.fsCsb[0] = %08x file = %s\n",
|
||||||
|
face->fs.fsCsb[0], debugstr_w(face->file));
|
||||||
|
csi->ciACP = GetACP();
|
||||||
|
csi->ciCharset = DEFAULT_CHARSET;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct gdi_font *select_font( LOGFONTW *lf, FMAT2 dcmat, BOOL can_use_bitmap )
|
||||||
|
{
|
||||||
|
static const WCHAR SymbolW[] = {'S','y','m','b','o','l',0};
|
||||||
|
struct gdi_font *font;
|
||||||
|
struct gdi_font_face *face;
|
||||||
|
INT height;
|
||||||
|
CHARSETINFO csi;
|
||||||
|
const WCHAR *orig_name = NULL;
|
||||||
|
|
||||||
|
/* If lfFaceName is "Symbol" then Windows fixes up lfCharSet to
|
||||||
|
SYMBOL_CHARSET so that Symbol gets picked irrespective of the
|
||||||
|
original value lfCharSet. Note this is a special case for
|
||||||
|
Symbol and doesn't happen at least for "Wingdings*" */
|
||||||
|
if (!strcmpiW( lf->lfFaceName, SymbolW )) lf->lfCharSet = SYMBOL_CHARSET;
|
||||||
|
|
||||||
|
/* check the cache first */
|
||||||
|
if ((font = find_cached_gdi_font( lf, &dcmat, can_use_bitmap )))
|
||||||
|
{
|
||||||
|
TRACE( "returning cached gdiFont(%p)\n", font );
|
||||||
|
return font;
|
||||||
|
}
|
||||||
|
if (!(face = find_matching_face( lf, &csi, can_use_bitmap, &orig_name )))
|
||||||
|
{
|
||||||
|
FIXME( "can't find a single appropriate font - bailing\n" );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
height = lf->lfHeight;
|
||||||
|
|
||||||
|
font = create_gdi_font( face, orig_name, lf );
|
||||||
|
font->matrix = dcmat;
|
||||||
|
font->can_use_bitmap = can_use_bitmap;
|
||||||
|
if (!csi.fs.fsCsb[0]) get_nearest_charset( face->family->family_name, face, &csi );
|
||||||
|
font->charset = csi.ciCharset;
|
||||||
|
font->codepage = csi.ciACP;
|
||||||
|
|
||||||
|
TRACE( "Chosen: %s (%s/%p:%u)\n", debugstr_w(face->full_name), debugstr_w(face->file),
|
||||||
|
face->data_ptr, face->face_index );
|
||||||
|
|
||||||
|
font->aveWidth = height ? lf->lfWidth : 0;
|
||||||
|
if (!face->scalable)
|
||||||
|
{
|
||||||
|
/* Windows uses integer scaling factors for bitmap fonts */
|
||||||
|
INT scale, scaled_height, diff;
|
||||||
|
struct gdi_font *cachedfont;
|
||||||
|
|
||||||
|
if (height > 0)
|
||||||
|
diff = height - (signed int)face->size.height;
|
||||||
|
else
|
||||||
|
diff = -height - ((signed int)face->size.height - face->size.internal_leading);
|
||||||
|
|
||||||
|
/* FIXME: rotation of bitmap fonts is ignored */
|
||||||
|
height = abs(GDI_ROUND( (double)height * font->matrix.eM22 ));
|
||||||
|
if (font->aveWidth)
|
||||||
|
font->aveWidth = (double)font->aveWidth * font->matrix.eM11;
|
||||||
|
font->matrix.eM11 = font->matrix.eM22 = 1.0;
|
||||||
|
dcmat.eM11 = dcmat.eM22 = 1.0;
|
||||||
|
/* As we changed the matrix, we need to search the cache for the font again,
|
||||||
|
* otherwise we might explode the cache. */
|
||||||
|
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 );
|
||||||
|
return cachedfont;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (height != 0) height = diff;
|
||||||
|
height += face->size.height;
|
||||||
|
|
||||||
|
scale = (height + face->size.height - 1) / face->size.height;
|
||||||
|
scaled_height = scale * face->size.height;
|
||||||
|
/* Only jump to the next height if the difference <= 25% original height */
|
||||||
|
if (scale > 2 && scaled_height - height > face->size.height / 4) scale--;
|
||||||
|
/* The jump between unscaled and doubled is delayed by 1 */
|
||||||
|
else if (scale == 2 && scaled_height - height > (face->size.height / 4 - 1)) scale--;
|
||||||
|
font->scale_y = scale;
|
||||||
|
}
|
||||||
|
TRACE("font scale y: %f\n", font->scale_y);
|
||||||
|
|
||||||
|
if (!font_funcs->load_font( font ))
|
||||||
|
{
|
||||||
|
free_gdi_font( font );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (face->flags & ADDFONT_VERTICAL_FONT) /* We need to try to load the GSUB table */
|
||||||
|
font->vert_feature = get_GSUB_vert_feature( font );
|
||||||
|
|
||||||
|
create_child_font_list( font );
|
||||||
|
|
||||||
|
TRACE( "caching: gdiFont=%p\n", font );
|
||||||
|
cache_gdi_font( font );
|
||||||
|
return font;
|
||||||
|
}
|
||||||
|
|
||||||
/*************************************************************
|
/*************************************************************
|
||||||
* font_SelectFont
|
* font_SelectFont
|
||||||
*/
|
*/
|
||||||
|
@ -3546,6 +3673,8 @@ static HFONT CDECL font_SelectFont( PHYSDEV dev, HFONT hfont, UINT *aa_flags )
|
||||||
if (hfont)
|
if (hfont)
|
||||||
{
|
{
|
||||||
LOGFONTW lf;
|
LOGFONTW lf;
|
||||||
|
FMAT2 dcmat;
|
||||||
|
BOOL can_use_bitmap = !!(GetDeviceCaps( dc->hSelf, TEXTCAPS ) & TC_RA_ABLE);
|
||||||
|
|
||||||
GetObjectW( hfont, sizeof(lf), &lf );
|
GetObjectW( hfont, sizeof(lf), &lf );
|
||||||
switch (lf.lfQuality)
|
switch (lf.lfQuality)
|
||||||
|
@ -3558,9 +3687,44 @@ static HFONT CDECL font_SelectFont( PHYSDEV dev, HFONT hfont, UINT *aa_flags )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lf.lfWidth = abs(lf.lfWidth);
|
||||||
|
|
||||||
|
TRACE( "%s, h=%d, it=%d, weight=%d, PandF=%02x, charset=%d orient %d escapement %d\n",
|
||||||
|
debugstr_w(lf.lfFaceName), lf.lfHeight, lf.lfItalic,
|
||||||
|
lf.lfWeight, lf.lfPitchAndFamily, lf.lfCharSet, lf.lfOrientation,
|
||||||
|
lf.lfEscapement );
|
||||||
|
|
||||||
|
if (dc->GraphicsMode == GM_ADVANCED)
|
||||||
|
{
|
||||||
|
memcpy( &dcmat, &dc->xformWorld2Vport, sizeof(FMAT2) );
|
||||||
|
/* try to avoid not necessary glyph transformations */
|
||||||
|
if (dcmat.eM21 == 0.0 && dcmat.eM12 == 0.0 && dcmat.eM11 == dcmat.eM22)
|
||||||
|
{
|
||||||
|
lf.lfHeight *= fabs(dcmat.eM11);
|
||||||
|
lf.lfWidth *= fabs(dcmat.eM11);
|
||||||
|
dcmat.eM11 = dcmat.eM22 = dcmat.eM11 < 0 ? -1 : 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Windows 3.1 compatibility mode GM_COMPATIBLE has only limited font scaling abilities */
|
||||||
|
dcmat.eM11 = dcmat.eM22 = 1.0;
|
||||||
|
dcmat.eM21 = dcmat.eM12 = 0;
|
||||||
|
lf.lfOrientation = lf.lfEscapement;
|
||||||
|
if (dc->vport2WorldValid)
|
||||||
|
{
|
||||||
|
if (dc->xformWorld2Vport.eM11 * dc->xformWorld2Vport.eM22 < 0)
|
||||||
|
lf.lfOrientation = -lf.lfOrientation;
|
||||||
|
lf.lfHeight *= fabs(dc->xformWorld2Vport.eM22);
|
||||||
|
lf.lfWidth *= fabs(dc->xformWorld2Vport.eM22);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TRACE( "DC transform %f %f %f %f\n", dcmat.eM11, dcmat.eM12, dcmat.eM21, dcmat.eM22 );
|
||||||
|
|
||||||
EnterCriticalSection( &font_cs );
|
EnterCriticalSection( &font_cs );
|
||||||
|
|
||||||
font = font_funcs->pSelectFont( dc, hfont );
|
font = select_font( &lf, dcmat, can_use_bitmap );
|
||||||
|
|
||||||
if (font && !*aa_flags)
|
if (font && !*aa_flags)
|
||||||
{
|
{
|
||||||
*aa_flags = font->aa_flags;
|
*aa_flags = font->aa_flags;
|
||||||
|
|
|
@ -250,8 +250,6 @@ static inline FT_Face get_ft_face( struct gdi_font *font )
|
||||||
|
|
||||||
static const struct font_backend_funcs font_funcs;
|
static const struct font_backend_funcs font_funcs;
|
||||||
|
|
||||||
static const WCHAR SymbolW[] = {'S','y','m','b','o','l','\0'};
|
|
||||||
|
|
||||||
struct font_mapping
|
struct font_mapping
|
||||||
{
|
{
|
||||||
struct list entry;
|
struct list entry;
|
||||||
|
@ -1714,48 +1712,6 @@ static void unmap_font_file( struct font_mapping *mapping )
|
||||||
|
|
||||||
static LONG load_VDMX(struct gdi_font *font, LONG height);
|
static LONG load_VDMX(struct gdi_font *font, LONG height);
|
||||||
|
|
||||||
static UINT get_nearest_charset(const WCHAR *family_name, Face *face, UINT *cp)
|
|
||||||
{
|
|
||||||
/* Only get here if lfCharSet == DEFAULT_CHARSET or we couldn't find
|
|
||||||
a single face with the requested charset. The idea is to check if
|
|
||||||
the selected font supports the current ANSI codepage, if it does
|
|
||||||
return the corresponding charset, else return the first charset */
|
|
||||||
|
|
||||||
CHARSETINFO csi;
|
|
||||||
int acp = GetACP(), i;
|
|
||||||
DWORD fs0;
|
|
||||||
|
|
||||||
*cp = acp;
|
|
||||||
if(TranslateCharsetInfo((DWORD*)(INT_PTR)acp, &csi, TCI_SRCCODEPAGE))
|
|
||||||
{
|
|
||||||
const struct gdi_font_link *font_link;
|
|
||||||
|
|
||||||
if (csi.fs.fsCsb[0] & face->fs.fsCsb[0])
|
|
||||||
return csi.ciCharset;
|
|
||||||
|
|
||||||
font_link = find_gdi_font_link(family_name);
|
|
||||||
if (font_link != NULL && csi.fs.fsCsb[0] & font_link->fs.fsCsb[0])
|
|
||||||
return csi.ciCharset;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(i = 0; i < 32; i++) {
|
|
||||||
fs0 = 1L << i;
|
|
||||||
if(face->fs.fsCsb[0] & fs0) {
|
|
||||||
if(TranslateCharsetInfo(&fs0, &csi, TCI_SRCFONTSIG)) {
|
|
||||||
*cp = csi.ciACP;
|
|
||||||
return csi.ciCharset;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
FIXME("TCI failing on %x\n", fs0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FIXME("returning DEFAULT_CHARSET face->fs.fsCsb[0] = %08x file = %s\n",
|
|
||||||
face->fs.fsCsb[0], debugstr_w(face->file));
|
|
||||||
*cp = acp;
|
|
||||||
return DEFAULT_CHARSET;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*************************************************************
|
/*************************************************************
|
||||||
* freetype_destroy_font
|
* freetype_destroy_font
|
||||||
*/
|
*/
|
||||||
|
@ -2210,152 +2166,6 @@ static BOOL CDECL freetype_load_font( struct gdi_font *font )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************
|
|
||||||
* freetype_SelectFont
|
|
||||||
*/
|
|
||||||
static struct gdi_font * CDECL freetype_SelectFont( DC *dc, HFONT hfont )
|
|
||||||
{
|
|
||||||
struct gdi_font *font;
|
|
||||||
Face *face;
|
|
||||||
INT height;
|
|
||||||
BOOL can_use_bitmap;
|
|
||||||
LOGFONTW lf;
|
|
||||||
CHARSETINFO csi;
|
|
||||||
FMAT2 dcmat;
|
|
||||||
const WCHAR *orig_name = NULL;
|
|
||||||
|
|
||||||
GetObjectW( hfont, sizeof(lf), &lf );
|
|
||||||
lf.lfWidth = abs(lf.lfWidth);
|
|
||||||
|
|
||||||
can_use_bitmap = !!(GetDeviceCaps(dc->hSelf, TEXTCAPS) & TC_RA_ABLE);
|
|
||||||
|
|
||||||
TRACE("%s, h=%d, it=%d, weight=%d, PandF=%02x, charset=%d orient %d escapement %d\n",
|
|
||||||
debugstr_w(lf.lfFaceName), lf.lfHeight, lf.lfItalic,
|
|
||||||
lf.lfWeight, lf.lfPitchAndFamily, lf.lfCharSet, lf.lfOrientation,
|
|
||||||
lf.lfEscapement);
|
|
||||||
|
|
||||||
if(dc->GraphicsMode == GM_ADVANCED)
|
|
||||||
{
|
|
||||||
memcpy(&dcmat, &dc->xformWorld2Vport, sizeof(FMAT2));
|
|
||||||
/* Try to avoid not necessary glyph transformations */
|
|
||||||
if (dcmat.eM21 == 0.0 && dcmat.eM12 == 0.0 && dcmat.eM11 == dcmat.eM22)
|
|
||||||
{
|
|
||||||
lf.lfHeight *= fabs(dcmat.eM11);
|
|
||||||
lf.lfWidth *= fabs(dcmat.eM11);
|
|
||||||
dcmat.eM11 = dcmat.eM22 = dcmat.eM11 < 0 ? -1 : 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Windows 3.1 compatibility mode GM_COMPATIBLE has only limited
|
|
||||||
font scaling abilities. */
|
|
||||||
dcmat.eM11 = dcmat.eM22 = 1.0;
|
|
||||||
dcmat.eM21 = dcmat.eM12 = 0;
|
|
||||||
lf.lfOrientation = lf.lfEscapement;
|
|
||||||
if (dc->vport2WorldValid)
|
|
||||||
{
|
|
||||||
if (dc->xformWorld2Vport.eM11 * dc->xformWorld2Vport.eM22 < 0)
|
|
||||||
lf.lfOrientation = -lf.lfOrientation;
|
|
||||||
lf.lfHeight *= fabs(dc->xformWorld2Vport.eM22);
|
|
||||||
lf.lfWidth *= fabs(dc->xformWorld2Vport.eM22);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TRACE("DC transform %f %f %f %f\n", dcmat.eM11, dcmat.eM12,
|
|
||||||
dcmat.eM21, dcmat.eM22);
|
|
||||||
|
|
||||||
/* 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);
|
|
||||||
return font;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If lfFaceName is "Symbol" then Windows fixes up lfCharSet to
|
|
||||||
SYMBOL_CHARSET so that Symbol gets picked irrespective of the
|
|
||||||
original value lfCharSet. Note this is a special case for
|
|
||||||
Symbol and doesn't happen at least for "Wingdings*" */
|
|
||||||
|
|
||||||
if(!strcmpiW(lf.lfFaceName, SymbolW))
|
|
||||||
lf.lfCharSet = SYMBOL_CHARSET;
|
|
||||||
|
|
||||||
if (!(face = find_matching_face( &lf, &csi, can_use_bitmap, &orig_name )))
|
|
||||||
{
|
|
||||||
FIXME("can't find a single appropriate font - bailing\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
height = lf.lfHeight;
|
|
||||||
|
|
||||||
TRACE("not in cache\n");
|
|
||||||
font = create_gdi_font( face, orig_name, &lf );
|
|
||||||
|
|
||||||
font->matrix = dcmat;
|
|
||||||
font->can_use_bitmap = can_use_bitmap;
|
|
||||||
if(csi.fs.fsCsb[0]) {
|
|
||||||
font->charset = lf.lfCharSet;
|
|
||||||
font->codepage = csi.ciACP;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
font->charset = get_nearest_charset( face->family->family_name, face, &font->codepage );
|
|
||||||
|
|
||||||
TRACE( "Chosen: %s (%s/%p:%u)\n", debugstr_w(face->full_name), debugstr_w(face->file),
|
|
||||||
face->data_ptr, face->face_index );
|
|
||||||
|
|
||||||
font->aveWidth = height ? lf.lfWidth : 0;
|
|
||||||
|
|
||||||
if(!face->scalable) {
|
|
||||||
/* Windows uses integer scaling factors for bitmap fonts */
|
|
||||||
INT scale, scaled_height, diff;
|
|
||||||
struct gdi_font *cachedfont;
|
|
||||||
|
|
||||||
if (height > 0)
|
|
||||||
diff = height - (signed int)face->size.height;
|
|
||||||
else
|
|
||||||
diff = -height - ((signed int)face->size.height - face->size.internal_leading);
|
|
||||||
|
|
||||||
/* FIXME: rotation of bitmap fonts is ignored */
|
|
||||||
height = abs(GDI_ROUND( (double)height * font->matrix.eM22 ));
|
|
||||||
if (font->aveWidth)
|
|
||||||
font->aveWidth = (double)font->aveWidth * font->matrix.eM11;
|
|
||||||
font->matrix.eM11 = font->matrix.eM22 = 1.0;
|
|
||||||
dcmat.eM11 = dcmat.eM22 = 1.0;
|
|
||||||
/* As we changed the matrix, we need to search the cache for the font again,
|
|
||||||
* otherwise we might explode the cache. */
|
|
||||||
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 );
|
|
||||||
return cachedfont;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (height != 0) height = diff;
|
|
||||||
height += face->size.height;
|
|
||||||
|
|
||||||
scale = (height + face->size.height - 1) / face->size.height;
|
|
||||||
scaled_height = scale * face->size.height;
|
|
||||||
/* Only jump to the next height if the difference <= 25% original height */
|
|
||||||
if (scale > 2 && scaled_height - height > face->size.height / 4) scale--;
|
|
||||||
/* The jump between unscaled and doubled is delayed by 1 */
|
|
||||||
else if (scale == 2 && scaled_height - height > (face->size.height / 4 - 1)) scale--;
|
|
||||||
font->scale_y = scale;
|
|
||||||
}
|
|
||||||
TRACE("font scale y: %f\n", font->scale_y);
|
|
||||||
|
|
||||||
if (!freetype_load_font( font ))
|
|
||||||
{
|
|
||||||
free_gdi_font( font );
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (face->flags & ADDFONT_VERTICAL_FONT) /* We need to try to load the GSUB table */
|
|
||||||
font->vert_feature = get_GSUB_vert_feature( font );
|
|
||||||
|
|
||||||
create_child_font_list( font );
|
|
||||||
|
|
||||||
TRACE("caching: gdiFont=%p hfont=%p\n", font, hfont);
|
|
||||||
|
|
||||||
cache_gdi_font( font );
|
|
||||||
return font;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*************************************************************
|
/*************************************************************
|
||||||
* freetype_get_aa_flags
|
* freetype_get_aa_flags
|
||||||
*/
|
*/
|
||||||
|
@ -4142,7 +3952,6 @@ static DWORD CDECL freetype_get_kerning_pairs( struct gdi_font *font, KERNINGPAI
|
||||||
|
|
||||||
static const struct font_backend_funcs font_funcs =
|
static const struct font_backend_funcs font_funcs =
|
||||||
{
|
{
|
||||||
freetype_SelectFont,
|
|
||||||
freetype_load_fonts,
|
freetype_load_fonts,
|
||||||
fontconfig_enum_family_fallbacks,
|
fontconfig_enum_family_fallbacks,
|
||||||
freetype_add_font,
|
freetype_add_font,
|
||||||
|
|
|
@ -425,8 +425,6 @@ struct gdi_font
|
||||||
|
|
||||||
struct font_backend_funcs
|
struct font_backend_funcs
|
||||||
{
|
{
|
||||||
struct gdi_font * (CDECL *pSelectFont)( DC *dc, HFONT hfont );
|
|
||||||
|
|
||||||
void (CDECL *load_fonts)(void);
|
void (CDECL *load_fonts)(void);
|
||||||
BOOL (CDECL *enum_family_fallbacks)( DWORD pitch_and_family, int index, WCHAR buffer[LF_FACESIZE] );
|
BOOL (CDECL *enum_family_fallbacks)( DWORD pitch_and_family, int index, WCHAR buffer[LF_FACESIZE] );
|
||||||
INT (CDECL *add_font)( const WCHAR *file, DWORD flags );
|
INT (CDECL *add_font)( const WCHAR *file, DWORD flags );
|
||||||
|
@ -449,29 +447,15 @@ struct font_backend_funcs
|
||||||
void (CDECL *destroy_font)( struct gdi_font *font );
|
void (CDECL *destroy_font)( struct gdi_font *font );
|
||||||
};
|
};
|
||||||
|
|
||||||
extern const WCHAR *get_gdi_font_subst( const WCHAR *from_name, int from_charset, int *to_charset ) DECLSPEC_HIDDEN;
|
|
||||||
|
|
||||||
extern int add_gdi_face( const WCHAR *family_name, const WCHAR *second_name,
|
extern int add_gdi_face( const WCHAR *family_name, const WCHAR *second_name,
|
||||||
const WCHAR *style, const WCHAR *fullname, const WCHAR *file,
|
const WCHAR *style, const WCHAR *fullname, const WCHAR *file,
|
||||||
void *data_ptr, SIZE_T data_size, UINT index, FONTSIGNATURE fs,
|
void *data_ptr, SIZE_T data_size, UINT index, FONTSIGNATURE fs,
|
||||||
DWORD ntmflags, DWORD version, DWORD flags,
|
DWORD ntmflags, DWORD version, DWORD flags,
|
||||||
const struct bitmap_font_size *size ) DECLSPEC_HIDDEN;
|
const struct bitmap_font_size *size ) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
extern struct gdi_font_link *find_gdi_font_link( const WCHAR *name ) DECLSPEC_HIDDEN;
|
|
||||||
extern void create_child_font_list( struct gdi_font *font ) DECLSPEC_HIDDEN;
|
|
||||||
extern struct gdi_font_face *find_matching_face( LOGFONTW *lf, CHARSETINFO *csi, BOOL can_use_bitmap,
|
|
||||||
const WCHAR **orig_name ) DECLSPEC_HIDDEN;
|
|
||||||
|
|
||||||
extern void free_gdi_font( struct gdi_font *font ) DECLSPEC_HIDDEN;
|
|
||||||
extern void cache_gdi_font( struct gdi_font *font ) DECLSPEC_HIDDEN;
|
|
||||||
extern struct gdi_font *find_cached_gdi_font( const LOGFONTW *lf, const FMAT2 *matrix,
|
|
||||||
BOOL can_use_bitmap ) DECLSPEC_HIDDEN;
|
|
||||||
static inline const WCHAR *get_gdi_font_name( struct gdi_font *font ) { return (WCHAR *)font->otm.otmpFamilyName; }
|
static inline const WCHAR *get_gdi_font_name( struct gdi_font *font ) { return (WCHAR *)font->otm.otmpFamilyName; }
|
||||||
extern void set_gdi_font_names( struct gdi_font *font, const WCHAR *family_name, const WCHAR *style_name,
|
extern void set_gdi_font_names( struct gdi_font *font, const WCHAR *family_name, const WCHAR *style_name,
|
||||||
const WCHAR *full_name ) DECLSPEC_HIDDEN;
|
const WCHAR *full_name ) DECLSPEC_HIDDEN;
|
||||||
extern struct gdi_font *create_gdi_font( const struct gdi_font_face *face, const WCHAR *family_name,
|
|
||||||
const LOGFONTW *lf ) DECLSPEC_HIDDEN;
|
|
||||||
extern void *get_GSUB_vert_feature( struct gdi_font *font ) DECLSPEC_HIDDEN;
|
|
||||||
extern void font_init(void) DECLSPEC_HIDDEN;
|
extern void font_init(void) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
/* freetype.c */
|
/* freetype.c */
|
||||||
|
|
Loading…
Reference in New Issue