gdi32: Add a helper function to create a face.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
19d13d0004
commit
a6f0349e84
|
@ -65,6 +65,7 @@ static UINT font_smoothing = GGO_BITMAP;
|
|||
static UINT subpixel_orientation = GGO_GRAY4_BITMAP;
|
||||
static BOOL antialias_fakes = TRUE;
|
||||
|
||||
static void add_face_to_cache( struct gdi_font_face *face );
|
||||
static void remove_face_from_cache( struct gdi_font_face *face );
|
||||
|
||||
/* Device -> World size conversion */
|
||||
|
@ -554,7 +555,7 @@ static void load_gdi_font_subst(void)
|
|||
|
||||
struct list font_list = LIST_INIT(font_list);
|
||||
|
||||
struct gdi_font_family *create_family( const WCHAR *name, const WCHAR *second_name )
|
||||
static struct gdi_font_family *create_family( const WCHAR *name, const WCHAR *second_name )
|
||||
{
|
||||
struct gdi_font_family *family = HeapAlloc( GetProcessHeap(), 0, sizeof(*family) );
|
||||
|
||||
|
@ -581,7 +582,7 @@ void release_family( struct gdi_font_family *family )
|
|||
HeapFree( GetProcessHeap(), 0, family );
|
||||
}
|
||||
|
||||
struct gdi_font_family *find_family_from_name( const WCHAR *name )
|
||||
static struct gdi_font_family *find_family_from_name( const WCHAR *name )
|
||||
{
|
||||
struct gdi_font_family *family;
|
||||
|
||||
|
@ -752,26 +753,6 @@ static void reorder_font_list(void)
|
|||
default_sans = set_default_family( default_sans_list );
|
||||
}
|
||||
|
||||
struct gdi_font_face *create_face( const WCHAR *style, const WCHAR *fullname, const WCHAR *file,
|
||||
UINT index, FONTSIGNATURE fs, DWORD ntmflags, DWORD version,
|
||||
DWORD flags, const struct bitmap_font_size *size )
|
||||
{
|
||||
struct gdi_font_face *face = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*face) );
|
||||
|
||||
face->refcount = 1;
|
||||
face->style_name = strdupW( style );
|
||||
face->full_name = strdupW( fullname );
|
||||
face->face_index = index;
|
||||
face->fs = fs;
|
||||
face->ntmFlags = ntmflags;
|
||||
face->version = version;
|
||||
face->flags = flags;
|
||||
if (file) face->file = strdupW( file );
|
||||
if (size) face->size = *size;
|
||||
else face->scalable = TRUE;
|
||||
return face;
|
||||
}
|
||||
|
||||
void release_face( struct gdi_font_face *face )
|
||||
{
|
||||
if (--face->refcount) return;
|
||||
|
@ -815,7 +796,7 @@ static inline int style_order( const struct gdi_font_face *face )
|
|||
}
|
||||
}
|
||||
|
||||
BOOL insert_face_in_family_list( struct gdi_font_face *face, struct gdi_font_family *family )
|
||||
static BOOL insert_face_in_family_list( struct gdi_font_face *face, struct gdi_font_family *family )
|
||||
{
|
||||
struct gdi_font_face *cursor;
|
||||
|
||||
|
@ -864,6 +845,90 @@ BOOL insert_face_in_family_list( struct gdi_font_face *face, struct gdi_font_fam
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static struct gdi_font_face *create_face( struct gdi_font_family *family, const WCHAR *style,
|
||||
const WCHAR *fullname, const WCHAR *file,
|
||||
void *data_ptr, SIZE_T data_size, UINT index, FONTSIGNATURE fs,
|
||||
DWORD ntmflags, DWORD version, DWORD flags,
|
||||
const struct bitmap_font_size *size )
|
||||
{
|
||||
struct gdi_font_face *face = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*face) );
|
||||
|
||||
face->refcount = 1;
|
||||
face->style_name = strdupW( style );
|
||||
face->full_name = strdupW( fullname );
|
||||
face->face_index = index;
|
||||
face->fs = fs;
|
||||
face->ntmFlags = ntmflags;
|
||||
face->version = version;
|
||||
face->flags = flags;
|
||||
face->data_ptr = data_ptr;
|
||||
face->data_size = data_size;
|
||||
if (file) face->file = strdupW( file );
|
||||
if (size) face->size = *size;
|
||||
else face->scalable = TRUE;
|
||||
if (insert_face_in_family_list( face, family )) return face;
|
||||
release_face( face );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int add_gdi_face( const WCHAR *family_name, const WCHAR *second_name,
|
||||
const WCHAR *style, const WCHAR *fullname, const WCHAR *file,
|
||||
void *data_ptr, SIZE_T data_size, UINT index, FONTSIGNATURE fs,
|
||||
DWORD ntmflags, DWORD version, DWORD flags,
|
||||
const struct bitmap_font_size *size )
|
||||
{
|
||||
struct gdi_font_face *face;
|
||||
struct gdi_font_family *family;
|
||||
int ret = 0;
|
||||
|
||||
if ((family = find_family_from_name( family_name ))) family->refcount++;
|
||||
else if (!(family = create_family( family_name, second_name ))) return ret;
|
||||
|
||||
if ((face = create_face( family, style, fullname, file, data_ptr, data_size,
|
||||
index, fs, ntmflags, version, flags, size )))
|
||||
{
|
||||
if (flags & ADDFONT_ADD_TO_CACHE) add_face_to_cache( face );
|
||||
release_face( face );
|
||||
}
|
||||
release_family( family );
|
||||
ret++;
|
||||
|
||||
if (fs.fsCsb[0] & FS_DBCS_MASK)
|
||||
{
|
||||
WCHAR vert_family[LF_FACESIZE], vert_second[LF_FACESIZE], vert_full[LF_FULLFACESIZE];
|
||||
|
||||
vert_family[0] = '@';
|
||||
lstrcpynW( vert_family + 1, family_name, LF_FACESIZE - 1 );
|
||||
|
||||
if (second_name && second_name[0])
|
||||
{
|
||||
vert_second[0] = '@';
|
||||
lstrcpynW( vert_second + 1, second_name, LF_FACESIZE - 1 );
|
||||
}
|
||||
else vert_second[0] = 0;
|
||||
|
||||
if (fullname)
|
||||
{
|
||||
vert_full[0] = '@';
|
||||
lstrcpynW( vert_full + 1, fullname, LF_FULLFACESIZE - 1 );
|
||||
fullname = vert_full;
|
||||
}
|
||||
|
||||
if ((family = find_family_from_name( vert_family ))) family->refcount++;
|
||||
else if (!(family = create_family( vert_family, vert_second ))) return ret;
|
||||
|
||||
if ((face = create_face( family, style, fullname, file, data_ptr, data_size,
|
||||
index, fs, ntmflags, version, flags | ADDFONT_VERTICAL_FONT, size )))
|
||||
{
|
||||
if (flags & ADDFONT_ADD_TO_CACHE) add_face_to_cache( face );
|
||||
release_face( face );
|
||||
}
|
||||
release_family( family );
|
||||
ret++;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* font cache */
|
||||
|
||||
struct cached_face
|
||||
|
@ -894,10 +959,11 @@ static void load_face_from_cache( HKEY hkey_family, struct gdi_font_family *fami
|
|||
if (type == REG_BINARY && needed > sizeof(*cached))
|
||||
{
|
||||
((DWORD *)buffer)[needed / sizeof(DWORD)] = 0;
|
||||
|
||||
face = create_face( name, cached->full_name, cached->full_name + strlenW(cached->full_name) + 1,
|
||||
cached->index, cached->fs, cached->ntmflags, cached->version,
|
||||
cached->flags, scalable ? NULL : &cached->size );
|
||||
if ((face = create_face( family, name, cached->full_name,
|
||||
cached->full_name + strlenW(cached->full_name) + 1,
|
||||
NULL, 0, cached->index, cached->fs, cached->ntmflags, cached->version,
|
||||
cached->flags, scalable ? NULL : &cached->size )))
|
||||
{
|
||||
if (!scalable)
|
||||
TRACE("Adding bitmap size h %d w %d size %d x_ppem %d y_ppem %d\n",
|
||||
face->size.height, face->size.width, face->size.size >> 6,
|
||||
|
@ -908,9 +974,9 @@ static void load_face_from_cache( HKEY hkey_family, struct gdi_font_family *fami
|
|||
face->fs.fsUsb[0], face->fs.fsUsb[1],
|
||||
face->fs.fsUsb[2], face->fs.fsUsb[3]);
|
||||
|
||||
insert_face_in_family_list( face, family );
|
||||
release_face( face );
|
||||
}
|
||||
}
|
||||
size = sizeof(name);
|
||||
needed = buffer_size - sizeof(DWORD);
|
||||
}
|
||||
|
@ -990,7 +1056,7 @@ static void load_font_list_from_cache(void)
|
|||
reorder_vertical_fonts();
|
||||
}
|
||||
|
||||
void add_face_to_cache( struct gdi_font_face *face )
|
||||
static void add_face_to_cache( struct gdi_font_face *face )
|
||||
{
|
||||
HKEY hkey_family, hkey_face;
|
||||
DWORD len, buffer[1024];
|
||||
|
|
|
@ -876,55 +876,6 @@ static WCHAR *ft_face_get_full_name( FT_Face ft_face, LANGID langid )
|
|||
return full_name;
|
||||
}
|
||||
|
||||
static WCHAR *get_vertical_name( WCHAR *name )
|
||||
{
|
||||
SIZE_T length;
|
||||
if (!name) return NULL;
|
||||
if (name[0] == '@') return name;
|
||||
|
||||
length = strlenW( name ) + 1;
|
||||
name = HeapReAlloc( GetProcessHeap(), 0, name, (length + 1) * sizeof(WCHAR) );
|
||||
memmove( name + 1, name, length * sizeof(WCHAR) );
|
||||
name[0] = '@';
|
||||
return name;
|
||||
}
|
||||
|
||||
static Family *get_family( FT_Face ft_face, BOOL vertical )
|
||||
{
|
||||
Family *family;
|
||||
WCHAR *family_name, *second_name;
|
||||
|
||||
family_name = ft_face_get_family_name( ft_face, GetSystemDefaultLCID() );
|
||||
second_name = ft_face_get_family_name( ft_face, MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT) );
|
||||
|
||||
/* try to find another secondary name, preferring the lowest langids */
|
||||
if (!strcmpiW( family_name, second_name ))
|
||||
{
|
||||
HeapFree( GetProcessHeap(), 0, second_name );
|
||||
second_name = ft_face_get_family_name( ft_face, MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL) );
|
||||
}
|
||||
|
||||
if (!strcmpiW( family_name, second_name ))
|
||||
{
|
||||
HeapFree( GetProcessHeap(), 0, second_name );
|
||||
second_name = NULL;
|
||||
}
|
||||
|
||||
if (vertical)
|
||||
{
|
||||
family_name = get_vertical_name( family_name );
|
||||
second_name = get_vertical_name( second_name );
|
||||
}
|
||||
|
||||
if ((family = find_family_from_name( family_name ))) family->refcount++;
|
||||
else family = create_family( family_name, second_name );
|
||||
|
||||
HeapFree( GetProcessHeap(), 0, family_name );
|
||||
HeapFree( GetProcessHeap(), 0, second_name );
|
||||
|
||||
return family;
|
||||
}
|
||||
|
||||
static inline FT_Fixed get_font_version( FT_Face ft_face )
|
||||
{
|
||||
FT_Fixed version = 0;
|
||||
|
@ -1045,54 +996,45 @@ static inline void get_fontsig( FT_Face ft_face, FONTSIGNATURE *fs )
|
|||
}
|
||||
}
|
||||
|
||||
static Face *create_face_from_ft_face( FT_Face ft_face, FT_Long face_index,
|
||||
const WCHAR *filename, DWORD flags )
|
||||
static int AddFaceToList(FT_Face ft_face, const WCHAR *file, void *data_ptr, SIZE_T data_size,
|
||||
FT_Long face_index, DWORD flags )
|
||||
{
|
||||
struct bitmap_font_size size;
|
||||
struct gdi_font_face *face;
|
||||
FONTSIGNATURE fs;
|
||||
int ret;
|
||||
WCHAR *family_name = ft_face_get_family_name( ft_face, GetSystemDefaultLCID() );
|
||||
WCHAR *second_name = ft_face_get_family_name( ft_face, MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT) );
|
||||
WCHAR *style_name = ft_face_get_style_name( ft_face, GetSystemDefaultLangID() );
|
||||
WCHAR *full_name = ft_face_get_full_name( ft_face, GetSystemDefaultLangID() );
|
||||
|
||||
if (flags & ADDFONT_VERTICAL_FONT) full_name = get_vertical_name( full_name );
|
||||
/* try to find another secondary name, preferring the lowest langids */
|
||||
if (!strcmpiW( family_name, second_name ))
|
||||
{
|
||||
HeapFree( GetProcessHeap(), 0, second_name );
|
||||
second_name = ft_face_get_family_name( ft_face, MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL) );
|
||||
}
|
||||
if (!strcmpiW( family_name, second_name ))
|
||||
{
|
||||
HeapFree( GetProcessHeap(), 0, second_name );
|
||||
second_name = NULL;
|
||||
}
|
||||
|
||||
get_fontsig( ft_face, &fs );
|
||||
if (!FT_IS_SCALABLE( ft_face )) get_bitmap_size( ft_face, &size );
|
||||
if (!HIWORD( flags )) flags |= ADDFONT_AA_FLAGS( default_aa_flags );
|
||||
|
||||
face = create_face( style_name, full_name, filename, face_index, fs,
|
||||
get_ntm_flags( ft_face ), get_font_version( ft_face ),
|
||||
ret = add_gdi_face( family_name, second_name, style_name, full_name, file, data_ptr, data_size,
|
||||
face_index, fs, get_ntm_flags( ft_face ), get_font_version( ft_face ),
|
||||
flags, FT_IS_SCALABLE(ft_face) ? NULL : &size );
|
||||
|
||||
TRACE("fsCsb = %08x %08x/%08x %08x %08x %08x\n",
|
||||
fs.fsCsb[0], fs.fsCsb[1], fs.fsUsb[0], fs.fsUsb[1], fs.fsUsb[2], fs.fsUsb[3]);
|
||||
|
||||
HeapFree( GetProcessHeap(), 0, family_name );
|
||||
HeapFree( GetProcessHeap(), 0, second_name );
|
||||
HeapFree( GetProcessHeap(), 0, style_name );
|
||||
HeapFree( GetProcessHeap(), 0, full_name );
|
||||
return face;
|
||||
}
|
||||
|
||||
static void AddFaceToList(FT_Face ft_face, const WCHAR *file, void *font_data_ptr, DWORD font_data_size,
|
||||
FT_Long face_index, DWORD flags )
|
||||
{
|
||||
Face *face;
|
||||
Family *family;
|
||||
|
||||
face = create_face_from_ft_face( ft_face, face_index, file, flags );
|
||||
if (face && !file)
|
||||
{
|
||||
face->data_ptr = font_data_ptr;
|
||||
face->data_size = font_data_size;
|
||||
}
|
||||
family = get_family( ft_face, flags & ADDFONT_VERTICAL_FONT );
|
||||
|
||||
if (insert_face_in_family_list( face, family ))
|
||||
{
|
||||
if (flags & ADDFONT_ADD_TO_CACHE)
|
||||
add_face_to_cache( face );
|
||||
TRACE( "Added face %s to family %s\n", debugstr_w(face->full_name), debugstr_w(family->family_name) );
|
||||
}
|
||||
release_face( face );
|
||||
release_family( family );
|
||||
return ret;
|
||||
}
|
||||
|
||||
static FT_Face new_ft_face( const char *file, void *font_data_ptr, DWORD font_data_size,
|
||||
|
@ -1206,8 +1148,6 @@ static INT AddFontToList(const WCHAR *dos_name, const char *unix_name, void *fon
|
|||
if (!dos_name && unix_name) dos_name = filename = wine_get_dos_file_name( unix_name );
|
||||
|
||||
do {
|
||||
FONTSIGNATURE fs;
|
||||
|
||||
ft_face = new_ft_face( unix_name, font_data_ptr, font_data_size, face_index, flags & ADDFONT_ALLOW_BITMAP );
|
||||
if (!ft_face) break;
|
||||
|
||||
|
@ -1218,16 +1158,7 @@ static INT AddFontToList(const WCHAR *dos_name, const char *unix_name, void *fon
|
|||
break;
|
||||
}
|
||||
|
||||
AddFaceToList(ft_face, dos_name, font_data_ptr, font_data_size, face_index, flags);
|
||||
++ret;
|
||||
|
||||
get_fontsig(ft_face, &fs);
|
||||
if (fs.fsCsb[0] & FS_DBCS_MASK)
|
||||
{
|
||||
AddFaceToList(ft_face, dos_name, font_data_ptr, font_data_size, face_index,
|
||||
flags | ADDFONT_VERTICAL_FONT);
|
||||
++ret;
|
||||
}
|
||||
ret += AddFaceToList(ft_face, dos_name, font_data_ptr, font_data_size, face_index, flags);
|
||||
|
||||
num_faces = ft_face->num_faces;
|
||||
pFT_Done_Face(ft_face);
|
||||
|
|
|
@ -456,16 +456,14 @@ extern void load_registry_fonts(void) DECLSPEC_HIDDEN;
|
|||
extern const WCHAR *get_gdi_font_subst( const WCHAR *from_name, int from_charset, int *to_charset ) DECLSPEC_HIDDEN;
|
||||
|
||||
extern struct list font_list DECLSPEC_HIDDEN;
|
||||
extern struct gdi_font_family *create_family( const WCHAR *name, const WCHAR *second_name ) DECLSPEC_HIDDEN;
|
||||
extern void release_family( struct gdi_font_family *family ) DECLSPEC_HIDDEN;
|
||||
extern struct gdi_font_family *find_family_from_name( const WCHAR *name ) DECLSPEC_HIDDEN;
|
||||
extern struct gdi_font_family *find_family_from_any_name( const WCHAR *name ) DECLSPEC_HIDDEN;
|
||||
extern struct gdi_font_face *create_face( const WCHAR *style, const WCHAR *fullname, const WCHAR *file,
|
||||
UINT index, FONTSIGNATURE fs, DWORD ntmflags,
|
||||
DWORD version, DWORD flags, const struct bitmap_font_size *size ) DECLSPEC_HIDDEN;
|
||||
extern void release_face( struct gdi_font_face *face ) DECLSPEC_HIDDEN;
|
||||
extern BOOL insert_face_in_family_list( struct gdi_font_face *face, struct gdi_font_family *family ) DECLSPEC_HIDDEN;
|
||||
extern void add_face_to_cache( struct gdi_font_face *face ) DECLSPEC_HIDDEN;
|
||||
extern int add_gdi_face( const WCHAR *family_name, const WCHAR *second_name,
|
||||
const WCHAR *style, const WCHAR *fullname, const WCHAR *file,
|
||||
void *data_ptr, SIZE_T data_size, UINT index, FONTSIGNATURE fs,
|
||||
DWORD ntmflags, DWORD version, DWORD flags,
|
||||
const struct bitmap_font_size *size ) DECLSPEC_HIDDEN;
|
||||
|
||||
extern struct gdi_font_link *find_gdi_font_link( const WCHAR *name ) DECLSPEC_HIDDEN;
|
||||
extern struct gdi_font_family *find_family_from_font_links( const WCHAR *name, const WCHAR *subst,
|
||||
|
|
Loading…
Reference in New Issue