Commit a6f0349e authored by Alexandre Julliard's avatar Alexandre Julliard

gdi32: Add a helper function to create a face.

parent 19d13d00
......@@ -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,22 +959,23 @@ 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;
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,
face->size.x_ppem >> 6, face->size.y_ppem >> 6);
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 (!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,
face->size.x_ppem >> 6, face->size.y_ppem >> 6);
TRACE("fsCsb = %08x %08x/%08x %08x %08x %08x\n",
face->fs.fsCsb[0], face->fs.fsCsb[1],
face->fs.fsUsb[0], face->fs.fsUsb[1],
face->fs.fsUsb[2], face->fs.fsUsb[3]);
TRACE("fsCsb = %08x %08x/%08x %08x %08x %08x\n",
face->fs.fsCsb[0], face->fs.fsCsb[1],
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 );
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,
......
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