Commit 356ad03f authored by Alexandre Julliard's avatar Alexandre Julliard

gdi32: Move the font enumeration out of freetype.c.

parent c9b21a57
......@@ -35,6 +35,7 @@
#include "winternl.h"
#include "winreg.h"
#include "gdi_private.h"
#include "resource.h"
#include "wine/exception.h"
#include "wine/heap.h"
#include "wine/unicode.h"
......@@ -352,13 +353,14 @@ static inline BOOL is_dbcs_ansi_cp(UINT ansi_cp)
|| ansi_cp == 950 ); /* CP950 for Chinese Traditional */
}
static CRITICAL_SECTION font_cs;
static CRITICAL_SECTION_DEBUG critsect_debug =
{
0, 0, &font_cs,
{ &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
0, 0, { (DWORD_PTR)(__FILE__ ": font_cs") }
};
CRITICAL_SECTION font_cs = { &critsect_debug, -1, 0, 0, 0, 0 };
static CRITICAL_SECTION font_cs = { &critsect_debug, -1, 0, 0, 0, 0 };
#ifndef WINE_FONT_DIR
#define WINE_FONT_DIR "fonts"
......@@ -1918,12 +1920,306 @@ static BOOL CDECL font_DeleteDC( PHYSDEV dev )
}
struct gdi_font_enum_data
{
ENUMLOGFONTEXW elf;
NEWTEXTMETRICEXW ntm;
};
struct enum_charset
{
DWORD mask;
DWORD charset;
DWORD script;
};
static int load_script_name( UINT id, WCHAR buffer[LF_FACESIZE] )
{
HRSRC rsrc;
HGLOBAL hMem;
WCHAR *p;
int i;
id += IDS_FIRST_SCRIPT;
rsrc = FindResourceW( gdi32_module, (LPCWSTR)(ULONG_PTR)((id >> 4) + 1), (LPCWSTR)6 /*RT_STRING*/ );
if (!rsrc) return 0;
hMem = LoadResource( gdi32_module, rsrc );
if (!hMem) return 0;
p = LockResource( hMem );
id &= 0x000f;
while (id--) p += *p + 1;
i = min(LF_FACESIZE - 1, *p);
memcpy(buffer, p + 1, i * sizeof(WCHAR));
buffer[i] = 0;
return i;
}
static BOOL is_complex_script_ansi_cp( UINT ansi_cp )
{
return (ansi_cp == 874 /* Thai */
|| ansi_cp == 1255 /* Hebrew */
|| ansi_cp == 1256 /* Arabic */
);
}
/***************************************************
* create_enum_charset_list
*
* This function creates charset enumeration list because in DEFAULT_CHARSET
* case, the ANSI codepage's charset takes precedence over other charsets.
* Above rule doesn't apply if the ANSI codepage uses complex script (e.g. Thai).
* This function works as a filter other than DEFAULT_CHARSET case.
*/
static DWORD create_enum_charset_list(DWORD charset, struct enum_charset *list)
{
struct enum_charset *start = list;
CHARSETINFO csi;
int i;
if (TranslateCharsetInfo( ULongToPtr(charset), &csi, TCI_SRCCHARSET ) && csi.fs.fsCsb[0] != 0)
{
list->mask = csi.fs.fsCsb[0];
list->charset = csi.ciCharset;
for (i = 0; i < 32; i++) if (csi.fs.fsCsb[0] & (1u << i)) list->script = i;
list++;
}
else /* charset is DEFAULT_CHARSET or invalid. */
{
int acp = GetACP();
DWORD mask = 0;
/* Set the current codepage's charset as the first element. */
if (!is_complex_script_ansi_cp(acp) &&
TranslateCharsetInfo( (DWORD *)(INT_PTR)acp, &csi, TCI_SRCCODEPAGE ) &&
csi.fs.fsCsb[0] != 0)
{
list->mask = csi.fs.fsCsb[0];
list->charset = csi.ciCharset;
for (i = 0; i < 32; i++) if (csi.fs.fsCsb[0] & (1u << i)) list->script = i;
mask |= csi.fs.fsCsb[0];
list++;
}
/* Fill out left elements. */
for (i = 0; i < 32; i++)
{
FONTSIGNATURE fs;
fs.fsCsb[0] = 1u << i;
fs.fsCsb[1] = 0;
if (fs.fsCsb[0] & mask) continue; /* skip, already added. */
if (!TranslateCharsetInfo( fs.fsCsb, &csi, TCI_SRCFONTSIG ))
continue; /* skip, this is an invalid fsCsb bit. */
list->mask = fs.fsCsb[0];
list->charset = csi.ciCharset;
list->script = i;
mask |= fs.fsCsb[0];
list++;
}
/* add catch all mask for remaining bits */
if (~mask)
{
list->mask = ~mask;
list->charset = DEFAULT_CHARSET;
list->script = IDS_OTHER - IDS_FIRST_SCRIPT;
list++;
}
}
return list - start;
}
static UINT get_font_type( const NEWTEXTMETRICEXW *ntm )
{
UINT ret = 0;
if (ntm->ntmTm.tmPitchAndFamily & TMPF_TRUETYPE) ret |= TRUETYPE_FONTTYPE;
if (ntm->ntmTm.tmPitchAndFamily & TMPF_DEVICE) ret |= DEVICE_FONTTYPE;
if (!(ntm->ntmTm.tmPitchAndFamily & TMPF_VECTOR)) ret |= RASTER_FONTTYPE;
return ret;
}
static BOOL get_face_enum_data( struct gdi_font_face *face, ENUMLOGFONTEXW *elf, NEWTEXTMETRICEXW *ntm )
{
struct gdi_font *font;
LOGFONTW lf = { .lfHeight = 100 };
if (!(font = create_gdi_font( face, NULL, &lf ))) return FALSE;
if (!font_funcs->load_font( font ))
{
free_gdi_font( font );
return FALSE;
}
if (font_funcs->set_outline_text_metrics( font ))
{
memcpy( &ntm->ntmTm, &font->otm.otmTextMetrics, sizeof(TEXTMETRICW) );
ntm->ntmTm.ntmSizeEM = font->otm.otmEMSquare;
ntm->ntmTm.ntmCellHeight = font->ntmCellHeight;
ntm->ntmTm.ntmAvgWidth = font->ntmAvgWidth;
}
else if (font_funcs->set_bitmap_text_metrics( font ))
{
memcpy( &ntm->ntmTm, &font->otm.otmTextMetrics, sizeof(TEXTMETRICW) );
ntm->ntmTm.ntmSizeEM = ntm->ntmTm.tmHeight - ntm->ntmTm.tmInternalLeading;
ntm->ntmTm.ntmCellHeight = ntm->ntmTm.tmHeight;
ntm->ntmTm.ntmAvgWidth = ntm->ntmTm.tmAveCharWidth;
}
ntm->ntmTm.ntmFlags = font->ntmFlags;
ntm->ntmFontSig = font->fs;
elf->elfLogFont.lfEscapement = 0;
elf->elfLogFont.lfOrientation = 0;
elf->elfLogFont.lfHeight = ntm->ntmTm.tmHeight;
elf->elfLogFont.lfWidth = ntm->ntmTm.tmAveCharWidth;
elf->elfLogFont.lfWeight = ntm->ntmTm.tmWeight;
elf->elfLogFont.lfItalic = ntm->ntmTm.tmItalic;
elf->elfLogFont.lfUnderline = ntm->ntmTm.tmUnderlined;
elf->elfLogFont.lfStrikeOut = ntm->ntmTm.tmStruckOut;
elf->elfLogFont.lfCharSet = ntm->ntmTm.tmCharSet;
elf->elfLogFont.lfOutPrecision = OUT_STROKE_PRECIS;
elf->elfLogFont.lfClipPrecision = CLIP_STROKE_PRECIS;
elf->elfLogFont.lfQuality = DRAFT_QUALITY;
elf->elfLogFont.lfPitchAndFamily = (ntm->ntmTm.tmPitchAndFamily & 0xf1) + 1;
lstrcpynW( elf->elfLogFont.lfFaceName, (WCHAR *)font->otm.otmpFamilyName, LF_FACESIZE );
lstrcpynW( elf->elfFullName, (WCHAR *)font->otm.otmpFaceName, LF_FULLFACESIZE );
lstrcpynW( elf->elfStyle, (WCHAR *)font->otm.otmpStyleName, LF_FACESIZE );
free_gdi_font( font );
return TRUE;
}
static BOOL family_matches( struct gdi_font_family *family, const WCHAR *face_name )
{
struct gdi_font_face *face;
if (!strncmpiW( face_name, family->family_name, LF_FACESIZE - 1 )) return TRUE;
LIST_FOR_EACH_ENTRY( face, get_family_face_list(family), struct gdi_font_face, entry )
if (!strncmpiW( face_name, face->full_name, LF_FACESIZE - 1 )) return TRUE;
return FALSE;
}
static BOOL face_matches( const WCHAR *family_name, struct gdi_font_face *face, const WCHAR *face_name )
{
if (!strncmpiW( face_name, family_name, LF_FACESIZE - 1)) return TRUE;
return !strncmpiW( face_name, face->full_name, LF_FACESIZE - 1 );
}
static BOOL enum_face_charsets( const struct gdi_font_family *family, struct gdi_font_face *face,
struct enum_charset *list, DWORD count, FONTENUMPROCW proc, LPARAM lparam,
const WCHAR *subst )
{
ENUMLOGFONTEXW elf;
NEWTEXTMETRICEXW ntm;
DWORD type, i;
if (!face->cached_enum_data)
{
struct gdi_font_enum_data *data;
if (!(data = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*data) ))) return FALSE;
if (!get_face_enum_data( face, &data->elf, &data->ntm ))
{
HeapFree( GetProcessHeap(), 0, data );
return FALSE;
}
face->cached_enum_data = data;
}
elf = face->cached_enum_data->elf;
ntm = face->cached_enum_data->ntm;
type = get_font_type( &ntm );
/* font replacement */
if (family != face->family)
{
lstrcpynW( elf.elfLogFont.lfFaceName, family->family_name, LF_FACESIZE );
lstrcpynW( elf.elfFullName, face->full_name, LF_FULLFACESIZE );
}
if (subst) lstrcpynW( elf.elfLogFont.lfFaceName, subst, LF_FACESIZE );
for (i = 0; i < count; i++)
{
if (!face->scalable && face->fs.fsCsb[0] == 0) /* OEM bitmap */
{
elf.elfLogFont.lfCharSet = ntm.ntmTm.tmCharSet = OEM_CHARSET;
load_script_name( IDS_OEM_DOS - IDS_FIRST_SCRIPT, elf.elfScript );
i = count; /* break out of loop after enumeration */
}
else
{
if (!(face->fs.fsCsb[0] & list[i].mask)) continue;
/* use the DEFAULT_CHARSET case only if no other charset is present */
if (list[i].charset == DEFAULT_CHARSET && (face->fs.fsCsb[0] & ~list[i].mask)) continue;
elf.elfLogFont.lfCharSet = ntm.ntmTm.tmCharSet = list[i].charset;
load_script_name( list[i].script, elf.elfScript );
if (!elf.elfScript[0]) FIXME("Unknown elfscript for id %u\n", list[i].script);
}
TRACE( "face %s full %s style %s charset = %d type %d script %s it %d weight %d ntmflags %08x\n",
debugstr_w(elf.elfLogFont.lfFaceName), debugstr_w(elf.elfFullName), debugstr_w(elf.elfStyle),
elf.elfLogFont.lfCharSet, type, debugstr_w(elf.elfScript),
elf.elfLogFont.lfItalic, elf.elfLogFont.lfWeight, ntm.ntmTm.ntmFlags );
/* release section before callback (FIXME) */
LeaveCriticalSection( &font_cs );
if (!proc( &elf.elfLogFont, (TEXTMETRICW *)&ntm, type, lparam )) return FALSE;
EnterCriticalSection( &font_cs );
}
return TRUE;
}
/*************************************************************
* font_EnumFonts
*/
static BOOL CDECL font_EnumFonts( PHYSDEV dev, LOGFONTW *lf, FONTENUMPROCW proc, LPARAM lparam )
{
return font_funcs->pEnumFonts( lf, proc, lparam );
struct gdi_font_family *family;
struct gdi_font_face *face;
struct enum_charset enum_charsets[32];
DWORD count, charset;
charset = lf ? lf->lfCharSet : DEFAULT_CHARSET;
count = create_enum_charset_list( charset, enum_charsets );
EnterCriticalSection( &font_cs );
if (lf && lf->lfFaceName[0])
{
const WCHAR *face_name = get_gdi_font_subst( lf->lfFaceName, charset, NULL );
const WCHAR *orig_name = NULL;
TRACE( "facename = %s charset %d\n", debugstr_w(lf->lfFaceName), charset );
if (face_name)
{
orig_name = lf->lfFaceName;
TRACE( "substituting %s -> %s\n", debugstr_w(lf->lfFaceName), debugstr_w(face_name) );
}
else face_name = lf->lfFaceName;
LIST_FOR_EACH_ENTRY( family, &font_list, struct gdi_font_family, entry )
{
if (!family_matches(family, face_name)) continue;
LIST_FOR_EACH_ENTRY( face, get_family_face_list(family), struct gdi_font_face, entry )
{
if (!face_matches( family->family_name, face, face_name )) continue;
if (!enum_face_charsets( family, face, enum_charsets, count, proc, lparam, orig_name ))
return FALSE;
}
}
}
else
{
TRACE( "charset %d\n", charset );
LIST_FOR_EACH_ENTRY( family, &font_list, struct gdi_font_family, entry )
{
face = LIST_ENTRY( list_head(get_family_face_list(family)), struct gdi_font_face, entry );
if (!enum_face_charsets( family, face, enum_charsets, count, proc, lparam, NULL ))
return FALSE;
}
}
LeaveCriticalSection( &font_cs );
return TRUE;
}
......
......@@ -248,17 +248,6 @@ static inline FT_Face get_ft_face( struct gdi_font *font )
return ((struct font_private_data *)font->private)->ft_face;
}
struct enum_charset_element {
DWORD mask;
DWORD charset;
WCHAR name[LF_FACESIZE];
};
struct enum_charset_list {
DWORD total;
struct enum_charset_element element[32];
};
static const struct font_backend_funcs font_funcs;
static const WCHAR win9x_font_reg_key[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
......@@ -3383,313 +3372,6 @@ done:
return font;
}
static INT load_script_name( UINT id, WCHAR buffer[LF_FACESIZE] )
{
HRSRC rsrc;
HGLOBAL hMem;
WCHAR *p;
int i;
id += IDS_FIRST_SCRIPT;
rsrc = FindResourceW( gdi32_module, (LPCWSTR)(ULONG_PTR)((id >> 4) + 1), (LPCWSTR)6 /*RT_STRING*/ );
if (!rsrc) return 0;
hMem = LoadResource( gdi32_module, rsrc );
if (!hMem) return 0;
p = LockResource( hMem );
id &= 0x000f;
while (id--) p += *p + 1;
i = min(LF_FACESIZE - 1, *p);
memcpy(buffer, p + 1, i * sizeof(WCHAR));
buffer[i] = 0;
return i;
}
static inline BOOL is_complex_script_ansi_cp(UINT ansi_cp)
{
return (ansi_cp == 874 /* Thai */
|| ansi_cp == 1255 /* Hebrew */
|| ansi_cp == 1256 /* Arabic */
);
}
/***************************************************
* create_enum_charset_list
*
* This function creates charset enumeration list because in DEFAULT_CHARSET
* case, the ANSI codepage's charset takes precedence over other charsets.
* Above rule doesn't apply if the ANSI codepage uses complex script (e.g. Thai).
* This function works as a filter other than DEFAULT_CHARSET case.
*/
static DWORD create_enum_charset_list(DWORD charset, struct enum_charset_list *list)
{
CHARSETINFO csi;
DWORD n = 0;
if (TranslateCharsetInfo(ULongToPtr(charset), &csi, TCI_SRCCHARSET) &&
csi.fs.fsCsb[0] != 0) {
list->element[n].mask = csi.fs.fsCsb[0];
list->element[n].charset = csi.ciCharset;
load_script_name( ffs(csi.fs.fsCsb[0]) - 1, list->element[n].name );
n++;
}
else { /* charset is DEFAULT_CHARSET or invalid. */
INT acp, i;
DWORD mask = 0;
/* Set the current codepage's charset as the first element. */
acp = GetACP();
if (!is_complex_script_ansi_cp(acp) &&
TranslateCharsetInfo((DWORD*)(INT_PTR)acp, &csi, TCI_SRCCODEPAGE) &&
csi.fs.fsCsb[0] != 0) {
list->element[n].mask = csi.fs.fsCsb[0];
list->element[n].charset = csi.ciCharset;
load_script_name( ffs(csi.fs.fsCsb[0]) - 1, list->element[n].name );
mask |= csi.fs.fsCsb[0];
n++;
}
/* Fill out left elements. */
for (i = 0; i < 32; i++) {
FONTSIGNATURE fs;
fs.fsCsb[0] = 1L << i;
fs.fsCsb[1] = 0;
if (fs.fsCsb[0] & mask)
continue; /* skip, already added. */
if (!TranslateCharsetInfo(fs.fsCsb, &csi, TCI_SRCFONTSIG))
continue; /* skip, this is an invalid fsCsb bit. */
list->element[n].mask = fs.fsCsb[0];
list->element[n].charset = csi.ciCharset;
load_script_name( i, list->element[n].name );
mask |= fs.fsCsb[0];
n++;
}
/* add catch all mask for remaining bits */
if (~mask)
{
list->element[n].mask = ~mask;
list->element[n].charset = DEFAULT_CHARSET;
load_script_name( IDS_OTHER - IDS_FIRST_SCRIPT, list->element[n].name );
n++;
}
}
list->total = n;
return n;
}
static UINT get_font_type( const NEWTEXTMETRICEXW *ntm )
{
UINT ret = 0;
if (ntm->ntmTm.tmPitchAndFamily & TMPF_TRUETYPE) ret |= TRUETYPE_FONTTYPE;
if (ntm->ntmTm.tmPitchAndFamily & TMPF_DEVICE) ret |= DEVICE_FONTTYPE;
if (!(ntm->ntmTm.tmPitchAndFamily & TMPF_VECTOR)) ret |= RASTER_FONTTYPE;
return ret;
}
static void GetEnumStructs(Face *face, const WCHAR *family_name, LPENUMLOGFONTEXW pelf,
NEWTEXTMETRICEXW *pntm)
{
struct gdi_font *font;
LOGFONTW lf = { .lfHeight = 100 };
if (face->cached_enum_data)
{
TRACE("Cached\n");
*pelf = face->cached_enum_data->elf;
*pntm = face->cached_enum_data->ntm;
return;
}
if (!(font = create_gdi_font( face, family_name, &lf ))) return;
if (!freetype_load_font( font ))
{
free_gdi_font(font);
return;
}
if (freetype_set_outline_text_metrics(font))
{
memcpy(&pntm->ntmTm, &font->otm.otmTextMetrics, sizeof(TEXTMETRICW));
pntm->ntmTm.ntmSizeEM = font->otm.otmEMSquare;
pntm->ntmTm.ntmCellHeight = font->ntmCellHeight;
pntm->ntmTm.ntmAvgWidth = font->ntmAvgWidth;
lstrcpynW(pelf->elfLogFont.lfFaceName, (WCHAR *)font->otm.otmpFamilyName, LF_FACESIZE);
lstrcpynW(pelf->elfFullName, (WCHAR *)font->otm.otmpFaceName, LF_FULLFACESIZE);
lstrcpynW(pelf->elfStyle, (WCHAR *)font->otm.otmpStyleName, LF_FACESIZE);
}
else if (freetype_set_bitmap_text_metrics( font ))
{
memcpy(&pntm->ntmTm, &font->otm.otmTextMetrics, sizeof(TEXTMETRICW));
pntm->ntmTm.ntmSizeEM = pntm->ntmTm.tmHeight - pntm->ntmTm.tmInternalLeading;
pntm->ntmTm.ntmCellHeight = pntm->ntmTm.tmHeight;
pntm->ntmTm.ntmAvgWidth = pntm->ntmTm.tmAveCharWidth;
lstrcpynW(pelf->elfLogFont.lfFaceName, family_name, LF_FACESIZE);
lstrcpynW( pelf->elfFullName, face->full_name, LF_FULLFACESIZE );
lstrcpynW( pelf->elfStyle, face->style_name, LF_FACESIZE );
}
pntm->ntmTm.ntmFlags = face->ntmFlags;
pntm->ntmFontSig = face->fs;
pelf->elfScript[0] = '\0'; /* This will get set in WineEngEnumFonts */
pelf->elfLogFont.lfEscapement = 0;
pelf->elfLogFont.lfOrientation = 0;
pelf->elfLogFont.lfHeight = pntm->ntmTm.tmHeight;
pelf->elfLogFont.lfWidth = pntm->ntmTm.tmAveCharWidth;
pelf->elfLogFont.lfWeight = pntm->ntmTm.tmWeight;
pelf->elfLogFont.lfItalic = pntm->ntmTm.tmItalic;
pelf->elfLogFont.lfUnderline = pntm->ntmTm.tmUnderlined;
pelf->elfLogFont.lfStrikeOut = pntm->ntmTm.tmStruckOut;
pelf->elfLogFont.lfCharSet = pntm->ntmTm.tmCharSet;
pelf->elfLogFont.lfOutPrecision = OUT_STROKE_PRECIS;
pelf->elfLogFont.lfClipPrecision = CLIP_STROKE_PRECIS;
pelf->elfLogFont.lfQuality = DRAFT_QUALITY;
pelf->elfLogFont.lfPitchAndFamily = (pntm->ntmTm.tmPitchAndFamily & 0xf1) + 1;
face->cached_enum_data = HeapAlloc(GetProcessHeap(), 0, sizeof(*face->cached_enum_data));
if (face->cached_enum_data)
{
face->cached_enum_data->elf = *pelf;
face->cached_enum_data->ntm = *pntm;
}
free_gdi_font(font);
}
static BOOL family_matches(Family *family, const WCHAR *face_name)
{
Face *face;
const struct list *face_list;
if (!strncmpiW( face_name, family->family_name, LF_FACESIZE - 1 )) return TRUE;
face_list = get_face_list_from_family(family);
LIST_FOR_EACH_ENTRY(face, face_list, Face, entry)
if (!strncmpiW( face_name, face->full_name, LF_FACESIZE - 1 )) return TRUE;
return FALSE;
}
static BOOL face_matches(const WCHAR *family_name, Face *face, const WCHAR *face_name)
{
if (!strncmpiW(face_name, family_name, LF_FACESIZE - 1)) return TRUE;
return !strncmpiW( face_name, face->full_name, LF_FACESIZE - 1 );
}
static BOOL enum_face_charsets(const Family *family, Face *face, struct enum_charset_list *list,
FONTENUMPROCW proc, LPARAM lparam, const WCHAR *subst)
{
ENUMLOGFONTEXW elf;
NEWTEXTMETRICEXW ntm;
DWORD type, i;
GetEnumStructs( face, face->family->family_name, &elf, &ntm );
type = get_font_type( &ntm );
for(i = 0; i < list->total; i++) {
if(!face->scalable && face->fs.fsCsb[0] == 0) { /* OEM bitmap */
elf.elfLogFont.lfCharSet = ntm.ntmTm.tmCharSet = OEM_CHARSET;
load_script_name( IDS_OEM_DOS - IDS_FIRST_SCRIPT, elf.elfScript );
i = list->total; /* break out of loop after enumeration */
}
else
{
if(!(face->fs.fsCsb[0] & list->element[i].mask)) continue;
/* use the DEFAULT_CHARSET case only if no other charset is present */
if (list->element[i].charset == DEFAULT_CHARSET &&
(face->fs.fsCsb[0] & ~list->element[i].mask)) continue;
elf.elfLogFont.lfCharSet = ntm.ntmTm.tmCharSet = list->element[i].charset;
strcpyW(elf.elfScript, list->element[i].name);
if (!elf.elfScript[0])
FIXME("Unknown elfscript for bit %d\n", ffs(list->element[i].mask) - 1);
}
/* Font Replacement */
if (family != face->family)
{
lstrcpynW( elf.elfLogFont.lfFaceName, family->family_name, LF_FACESIZE );
lstrcpynW( elf.elfFullName, face->full_name, LF_FULLFACESIZE );
}
if (subst)
strcpyW(elf.elfLogFont.lfFaceName, subst);
TRACE("enuming face %s full %s style %s charset = %d type %d script %s it %d weight %d ntmflags %08x\n",
debugstr_w(elf.elfLogFont.lfFaceName),
debugstr_w(elf.elfFullName), debugstr_w(elf.elfStyle),
elf.elfLogFont.lfCharSet, type, debugstr_w(elf.elfScript),
elf.elfLogFont.lfItalic, elf.elfLogFont.lfWeight,
ntm.ntmTm.ntmFlags);
/* release section before callback (FIXME) */
LeaveCriticalSection( &font_cs );
if (!proc(&elf.elfLogFont, (TEXTMETRICW *)&ntm, type, lparam)) return FALSE;
EnterCriticalSection( &font_cs );
}
return TRUE;
}
/*************************************************************
* freetype_EnumFonts
*/
static BOOL CDECL freetype_EnumFonts( LPLOGFONTW plf, FONTENUMPROCW proc, LPARAM lparam )
{
Family *family;
Face *face;
const struct list *face_list;
LOGFONTW lf;
struct enum_charset_list enum_charsets;
if (!plf)
{
lf.lfCharSet = DEFAULT_CHARSET;
lf.lfPitchAndFamily = 0;
lf.lfFaceName[0] = 0;
plf = &lf;
}
TRACE("facename = %s charset %d\n", debugstr_w(plf->lfFaceName), plf->lfCharSet);
create_enum_charset_list(plf->lfCharSet, &enum_charsets);
EnterCriticalSection( &font_cs );
if(plf->lfFaceName[0]) {
const WCHAR *face_name = get_gdi_font_subst( plf->lfFaceName, plf->lfCharSet, NULL );
const WCHAR *orig_name = NULL;
if (face_name)
{
orig_name = plf->lfFaceName;
TRACE("substituting %s -> %s\n", debugstr_w(plf->lfFaceName), debugstr_w(face_name));
}
else face_name = plf->lfFaceName;
LIST_FOR_EACH_ENTRY( family, &font_list, Family, entry ) {
if (!family_matches(family, face_name)) continue;
face_list = get_face_list_from_family(family);
LIST_FOR_EACH_ENTRY( face, face_list, Face, entry ) {
if (!face_matches( family->family_name, face, face_name )) continue;
if (!enum_face_charsets(family, face, &enum_charsets, proc, lparam, orig_name)) return FALSE;
}
}
} else {
LIST_FOR_EACH_ENTRY( family, &font_list, Family, entry ) {
face_list = get_face_list_from_family(family);
face = LIST_ENTRY(list_head(face_list), Face, entry);
if (!enum_face_charsets(family, face, &enum_charsets, proc, lparam, NULL)) return FALSE;
}
}
LeaveCriticalSection( &font_cs );
return TRUE;
}
static void FTVectorToPOINTFX(FT_Vector *vec, POINTFX *pt)
{
pt->x.value = vec->x >> 6;
......@@ -5443,7 +5125,6 @@ static DWORD CDECL freetype_get_kerning_pairs( struct gdi_font *font, KERNINGPAI
static const struct font_backend_funcs font_funcs =
{
freetype_EnumFonts,
freetype_SelectFont,
freetype_add_font,
freetype_add_mem_font,
......
......@@ -325,12 +325,6 @@ struct bitmap_font_size
int internal_leading;
};
struct gdi_font_enum_data
{
ENUMLOGFONTEXW elf;
NEWTEXTMETRICEXW ntm;
};
struct gdi_font_face
{
struct list entry;
......@@ -431,7 +425,6 @@ struct gdi_font
struct font_backend_funcs
{
BOOL (CDECL *pEnumFonts)( LOGFONTW *lf, FONTENUMPROCW proc, LPARAM lparam );
struct gdi_font * (CDECL *pSelectFont)( DC *dc, HFONT hfont, UINT *aa_flags, UINT default_aa_flags );
INT (CDECL *add_font)( const WCHAR *file, DWORD flags );
......@@ -485,7 +478,6 @@ extern struct gdi_font *create_gdi_font( const struct gdi_font_face *face, const
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 CRITICAL_SECTION font_cs DECLSPEC_HIDDEN;
/* freetype.c */
......
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