Commit 7ac623f3 authored by Huw Davies's avatar Huw Davies Committed by Alexandre Julliard

gdi32: Add a helper to create a new FreeType face.

parent a179b50c
...@@ -1789,99 +1789,115 @@ static void AddFaceToList(FT_Face ft_face, const char *file, void *font_data_ptr ...@@ -1789,99 +1789,115 @@ static void AddFaceToList(FT_Face ft_face, const char *file, void *font_data_ptr
debugstr_w(face->StyleName)); debugstr_w(face->StyleName));
} }
static INT AddFontToList(const char *file, void *font_data_ptr, DWORD font_data_size, DWORD flags) static FT_Face new_ft_face( const char *file, void *font_data_ptr, DWORD font_data_size,
FT_Long face_index, BOOL allow_bitmap )
{ {
FT_Face ft_face;
TT_OS2 *pOS2;
FT_Error err; FT_Error err;
FT_Long face_index = 0, num_faces; TT_OS2 *pOS2;
INT ret = 0; FT_Face ft_face;
/* we always load external fonts from files - otherwise we would get a crash in update_reg_entries */
assert(file || !(flags & ADDFONT_EXTERNAL_FONT));
#ifdef HAVE_CARBON_CARBON_H
if(file)
{
char **mac_list = expand_mac_font(file);
if(mac_list)
{
BOOL had_one = FALSE;
char **cursor;
for(cursor = mac_list; *cursor; cursor++)
{
had_one = TRUE;
AddFontToList(*cursor, NULL, 0, flags);
HeapFree(GetProcessHeap(), 0, *cursor);
}
HeapFree(GetProcessHeap(), 0, mac_list);
if(had_one)
return 1;
}
}
#endif /* HAVE_CARBON_CARBON_H */
do {
if (file) if (file)
{ {
TRACE("Loading font file %s index %ld\n", debugstr_a(file), face_index); TRACE("Loading font file %s index %ld\n", debugstr_a(file), face_index);
err = pFT_New_Face(library, file, face_index, &ft_face); err = pFT_New_Face(library, file, face_index, &ft_face);
} else }
else
{ {
TRACE("Loading font from ptr %p size %d, index %ld\n", font_data_ptr, font_data_size, face_index); TRACE("Loading font from ptr %p size %d, index %ld\n", font_data_ptr, font_data_size, face_index);
err = pFT_New_Memory_Face(library, font_data_ptr, font_data_size, face_index, &ft_face); err = pFT_New_Memory_Face(library, font_data_ptr, font_data_size, face_index, &ft_face);
} }
if(err != 0) { if (err != 0)
{
WARN("Unable to load font %s/%p err = %x\n", debugstr_a(file), font_data_ptr, err); WARN("Unable to load font %s/%p err = %x\n", debugstr_a(file), font_data_ptr, err);
return 0; return NULL;
}
if(!FT_IS_SFNT(ft_face) && (FT_IS_SCALABLE(ft_face) || !(flags & ADDFONT_FORCE_BITMAP))) { /* for now we'll accept TT/OT or bitmap fonts*/
WARN("Ignoring font %s/%p\n", debugstr_a(file), font_data_ptr);
pFT_Done_Face(ft_face);
return 0;
} }
/* There are too many bugs in FreeType < 2.1.9 for bitmap font support */ /* There are too many bugs in FreeType < 2.1.9 for bitmap font support */
if(!FT_IS_SCALABLE(ft_face) && FT_SimpleVersion < ((2 << 16) | (1 << 8) | (9 << 0))) { if (!FT_IS_SCALABLE( ft_face ) && FT_SimpleVersion < ((2 << 16) | (1 << 8) | (9 << 0)))
{
WARN("FreeType version < 2.1.9, skipping bitmap font %s/%p\n", debugstr_a(file), font_data_ptr); WARN("FreeType version < 2.1.9, skipping bitmap font %s/%p\n", debugstr_a(file), font_data_ptr);
pFT_Done_Face(ft_face); goto fail;
return 0;
} }
if(FT_IS_SFNT(ft_face)) if (!FT_IS_SFNT( ft_face ))
{
if (FT_IS_SCALABLE( ft_face ) || !allow_bitmap )
{ {
if(!(pOS2 = pFT_Get_Sfnt_Table(ft_face, ft_sfnt_os2)) || WARN("Ignoring font %s/%p\n", debugstr_a(file), font_data_ptr);
!pFT_Get_Sfnt_Table(ft_face, ft_sfnt_hhea) || goto fail;
!pFT_Get_Sfnt_Table(ft_face, ft_sfnt_head)) }
}
else
{
if (!(pOS2 = pFT_Get_Sfnt_Table( ft_face, ft_sfnt_os2 )) ||
!pFT_Get_Sfnt_Table( ft_face, ft_sfnt_hhea ) ||
!pFT_Get_Sfnt_Table( ft_face, ft_sfnt_head ))
{ {
TRACE("Font %s/%p lacks either an OS2, HHEA or HEAD table.\n" TRACE("Font %s/%p lacks either an OS2, HHEA or HEAD table.\n"
"Skipping this font.\n", debugstr_a(file), font_data_ptr); "Skipping this font.\n", debugstr_a(file), font_data_ptr);
pFT_Done_Face(ft_face); goto fail;
return 0;
} }
/* Wine uses ttfs as an intermediate step in building its bitmap fonts; /* Wine uses ttfs as an intermediate step in building its bitmap fonts;
we don't want to load these. */ we don't want to load these. */
if(!memcmp(pOS2->achVendID, "Wine", sizeof(pOS2->achVendID))) if (!memcmp( pOS2->achVendID, "Wine", sizeof(pOS2->achVendID) ))
{ {
FT_ULong len = 0; FT_ULong len = 0;
if(!pFT_Load_Sfnt_Table(ft_face, FT_MAKE_TAG('E','B','S','C'), 0, NULL, &len)) if (!pFT_Load_Sfnt_Table( ft_face, FT_MAKE_TAG('E','B','S','C'), 0, NULL, &len ))
{ {
TRACE("Skipping Wine bitmap-only TrueType font %s\n", debugstr_a(file)); TRACE("Skipping Wine bitmap-only TrueType font %s\n", debugstr_a(file));
pFT_Done_Face(ft_face); goto fail;
return 0;
} }
} }
} }
if(!ft_face->family_name || !ft_face->style_name) { if (!ft_face->family_name || !ft_face->style_name)
{
TRACE("Font %s/%p lacks either a family or style name\n", debugstr_a(file), font_data_ptr); TRACE("Font %s/%p lacks either a family or style name\n", debugstr_a(file), font_data_ptr);
pFT_Done_Face(ft_face); goto fail;
return 0; }
return ft_face;
fail:
pFT_Done_Face( ft_face );
return NULL;
}
static INT AddFontToList(const char *file, void *font_data_ptr, DWORD font_data_size, DWORD flags)
{
FT_Face ft_face;
FT_Long face_index = 0, num_faces;
INT ret = 0;
/* we always load external fonts from files - otherwise we would get a crash in update_reg_entries */
assert(file || !(flags & ADDFONT_EXTERNAL_FONT));
#ifdef HAVE_CARBON_CARBON_H
if(file)
{
char **mac_list = expand_mac_font(file);
if(mac_list)
{
BOOL had_one = FALSE;
char **cursor;
for(cursor = mac_list; *cursor; cursor++)
{
had_one = TRUE;
AddFontToList(*cursor, NULL, 0, flags);
HeapFree(GetProcessHeap(), 0, *cursor);
}
HeapFree(GetProcessHeap(), 0, mac_list);
if(had_one)
return 1;
}
} }
#endif /* HAVE_CARBON_CARBON_H */
do {
ft_face = new_ft_face( file, font_data_ptr, font_data_size, face_index, flags & ADDFONT_FORCE_BITMAP );
if (!ft_face) return 0;
if(ft_face->family_name[0] == '.') /* Ignore fonts with names beginning with a dot */ if(ft_face->family_name[0] == '.') /* Ignore fonts with names beginning with a dot */
{ {
......
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