fonts: linking #1
Huw D M Davies
h.davies1 at physics.ox.ac.uk
Mon Sep 5 06:44:03 CDT 2005
Breaking down the font linking stuff into more manageable chunks
Huw Davies <huw at codeweavers.com>
Build a list of font links read in from the registry.
--
Huw Davies
huw at codeweavers.com
Index: dlls/gdi/freetype.c
===================================================================
RCS file: /home/wine/wine/dlls/gdi/freetype.c,v
retrieving revision 1.92
diff -u -p -r1.92 freetype.c
--- dlls/gdi/freetype.c 19 Aug 2005 09:58:32 -0000 1.92
+++ dlls/gdi/freetype.c 5 Sep 2005 11:41:24 -0000
@@ -182,6 +182,7 @@ typedef struct tagFace {
BOOL Italic;
BOOL Bold;
FONTSIGNATURE fs;
+ FONTSIGNATURE fs_links;
FT_Fixed font_version;
BOOL scalable;
Bitmap_Size size; /* set if face is a bitmap */
@@ -219,6 +220,13 @@ typedef struct tagHFONTLIST {
HFONT hfont;
} HFONTLIST;
+typedef struct {
+ struct list entry;
+ char *file_name;
+ INT index;
+ GdiFont font;
+} CHILD_FONT;
+
struct tagGdiFont {
struct list entry;
FT_Face ft_face;
@@ -241,11 +249,18 @@ struct tagGdiFont {
FONTSIGNATURE fs;
};
+typedef struct {
+ struct list entry;
+ WCHAR *font_name;
+ struct list links;
+} SYSTEM_LINKS;
+
#define INIT_GM_SIZE 128
static struct list gdi_font_list = LIST_INIT(gdi_font_list);
static struct list unused_gdi_font_list = LIST_INIT(unused_gdi_font_list);
#define UNUSED_CACHE_SIZE 10
+static struct list system_links = LIST_INIT(system_links);
static struct list font_list = LIST_INIT(font_list);
@@ -564,6 +579,7 @@ static BOOL AddFontFileToList(const char
face->family = family;
face->external = (flags & ADDFONT_EXTERNAL_FONT) ? TRUE : FALSE;
memcpy(&face->fs, &fs, sizeof(face->fs));
+ memset(&face->fs_links, 0, sizeof(face->fs_links));
if(FT_IS_SCALABLE(ft_face)) {
memset(&face->size, 0, sizeof(face->size));
@@ -635,6 +651,49 @@ static void DumpFontList(void)
return;
}
+static Face *find_face_from_filename(WCHAR *name)
+{
+ Family *family;
+ Face *face;
+ char *file;
+ DWORD len = WideCharToMultiByte(CP_UNIXCP, 0, name, -1, NULL, 0, NULL, NULL);
+ char *nameA = HeapAlloc(GetProcessHeap(), 0, len);
+ Face *ret = NULL;
+
+ WideCharToMultiByte(CP_UNIXCP, 0, name, -1, nameA, len, NULL, NULL);
+ TRACE("looking for %s\n", debugstr_a(nameA));
+
+ LIST_FOR_EACH_ENTRY(family, &font_list, Family, entry)
+ {
+ LIST_FOR_EACH_ENTRY(face, &family->faces, Face, entry)
+ {
+ file = strrchr(face->file, '/');
+ if(!file)
+ file = face->file;
+ else
+ file++;
+ if(!strcmp(file, nameA))
+ ret = face;
+ break;
+ }
+ }
+ HeapFree(GetProcessHeap(), 0, nameA);
+ return ret;
+}
+
+static Family *find_family_from_name(WCHAR *name)
+{
+ Family *family;
+
+ LIST_FOR_EACH_ENTRY(family, &font_list, Family, entry)
+ {
+ if(!strcmpiW(family->FamilyName, name))
+ return family;
+ }
+
+ return NULL;
+}
+
static void DumpSubstList(void)
{
FontSubst *psub;
@@ -649,7 +708,7 @@ static void DumpSubstList(void)
return;
}
-static LPWSTR strdupW(LPWSTR p)
+static LPWSTR strdupW(LPCWSTR p)
{
LPWSTR ret;
DWORD len = (strlenW(p) + 1) * sizeof(WCHAR);
@@ -658,6 +717,15 @@ static LPWSTR strdupW(LPWSTR p)
return ret;
}
+static LPSTR strdupA(LPCSTR p)
+{
+ LPSTR ret;
+ DWORD len = (strlen(p) + 1);
+ ret = HeapAlloc(GetProcessHeap(), 0, len);
+ memcpy(ret, p, len);
+ return ret;
+}
+
static void split_subst_info(NameCs *nc, LPSTR str)
{
CHAR *p = strrchr(str, ',');
@@ -804,6 +872,129 @@ static void LoadReplaceList(void)
}
}
+/*************************************************************
+ * init_system_links
+ */
+static BOOL init_system_links(void)
+{
+ static const WCHAR system_link[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
+ 'W','i','n','d','o','w','s',' ','N','T','\\',
+ 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\','F','o','n','t','L','i','n','k','\\',
+ 'S','y','s','t','e','m','L','i','n','k',0};
+ HKEY hkey;
+ BOOL ret = FALSE;
+ DWORD type, max_val, max_data, val_len, data_len, index;
+ WCHAR *value, *data;
+ WCHAR *entry, *next;
+ SYSTEM_LINKS *font_link, *system_font_link;
+ CHILD_FONT *child_font;
+ static const WCHAR Tahoma[] = {'T','a','h','o','m','a',0};
+ static const WCHAR System[] = {'S','y','s','t','e','m',0};
+ FONTSIGNATURE fs;
+ Family *family;
+ Face *face;
+
+ if(RegOpenKeyW(HKEY_LOCAL_MACHINE, system_link, &hkey) == ERROR_SUCCESS)
+ {
+ RegQueryInfoKeyW(hkey, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &max_val, &max_data, NULL, NULL);
+ value = HeapAlloc(GetProcessHeap(), 0, (max_val + 1) * sizeof(WCHAR));
+ data = HeapAlloc(GetProcessHeap(), 0, max_data);
+ val_len = max_val + 1;
+ data_len = max_data;
+ index = 0;
+ while(RegEnumValueW(hkey, index++, value, &val_len, NULL, &type, (LPBYTE)data, &data_len) == ERROR_SUCCESS)
+ {
+ TRACE("%s:\n", debugstr_w(value));
+
+ memset(&fs, 0, sizeof(fs));
+ font_link = HeapAlloc(GetProcessHeap(), 0, sizeof(*font_link));
+ font_link->font_name = strdupW(value);
+ list_init(&font_link->links);
+ for(entry = data; (char*)entry < (char*)data + data_len && *entry != 0; entry = next)
+ {
+ WCHAR *face_name;
+ INT index;
+ CHILD_FONT *child_font;
+
+ TRACE("\t%s\n", debugstr_w(entry));
+
+ next = entry + strlenW(entry) + 1;
+
+ face_name = strchrW(entry, ',');
+ if(!face_name)
+ index = 0;
+ else
+ {
+ FIXME("don't yet handle ttc's correctly in linking. Assuming index 0\n");
+ *face_name++ = 0;
+ while(isspaceW(*face_name))
+ face_name++;
+
+ index = 0;
+ }
+ face = find_face_from_filename(entry);
+ if(!face)
+ {
+ TRACE("Unable to find file %s\n", debugstr_w(entry));
+ continue;
+ }
+
+ child_font = HeapAlloc(GetProcessHeap(), 0, sizeof(*child_font));
+ child_font->file_name = strdupA(face->file);
+ child_font->index = index;
+ child_font->font = NULL;
+ fs.fsCsb[0] |= face->fs.fsCsb[0];
+ fs.fsCsb[1] |= face->fs.fsCsb[1];
+ list_add_tail(&font_link->links, &child_font->entry);
+ }
+ family = find_family_from_name(font_link->font_name);
+ if(family)
+ {
+ LIST_FOR_EACH_ENTRY(face, &family->faces, Face, entry)
+ {
+ memcpy(&face->fs_links, &fs, sizeof(fs));
+ }
+ }
+ list_add_tail(&system_links, &font_link->entry);
+ val_len = max_val + 1;
+ data_len = max_data;
+ }
+
+ HeapFree(GetProcessHeap(), 0, value);
+ HeapFree(GetProcessHeap(), 0, data);
+ RegCloseKey(hkey);
+ }
+
+ /* Explicitly add an entry for the system font, this links to Tahoma and any links
+ that Tahoma has */
+ system_font_link = HeapAlloc(GetProcessHeap(), 0, sizeof(*system_font_link));
+ system_font_link->font_name = strdupW(System);
+ list_init(&system_font_link->links);
+ child_font = HeapAlloc(GetProcessHeap(), 0, sizeof(*child_font));
+ child_font->file_name = strdupA("Tahoma.ttf");
+ child_font->index = 0;
+ child_font->font = NULL;
+ list_add_tail(&system_font_link->links, &child_font->entry);
+ LIST_FOR_EACH_ENTRY(font_link, &system_links, SYSTEM_LINKS, entry)
+ {
+ if(!strcmpW(font_link->font_name, Tahoma))
+ {
+ CHILD_FONT *font_link_entry;
+ LIST_FOR_EACH_ENTRY(font_link_entry, &font_link->links, CHILD_FONT, entry)
+ {
+ CHILD_FONT *new_child;
+ new_child = HeapAlloc(GetProcessHeap(), 0, sizeof(*new_child));
+ new_child->file_name = strdupA(font_link_entry->file_name);
+ new_child->index = font_link_entry->index;
+ new_child->font = NULL;
+ list_add_tail(&system_font_link->links, &new_child->entry);
+ }
+ break;
+ }
+ }
+ list_add_tail(&system_links, &system_font_link->entry);
+ return ret;
+}
static BOOL ReadFontDir(const char *dirname, BOOL external_fonts)
{
@@ -1263,6 +1454,8 @@ BOOL WineEngInit(void)
LoadReplaceList();
update_reg_entries();
+ init_system_links();
+
ReleaseMutex(font_mutex);
return TRUE;
sym_not_found:
More information about the wine-patches
mailing list