Index: base/applications/fontview/display.c
===================================================================
--- base/applications/fontview/display.c	(revision 73482)
+++ base/applications/fontview/display.c	(working copy)
@@ -162,7 +162,7 @@
 }
 
 static LRESULT
-Display_SetTypeFace(HWND hwnd, PEXTLOGFONTW pExtLogFont)
+Display_SetTypeFace(HWND hwnd, PLOGFONTW pLogFont)
 {
 	DISPLAYDATA* pData;
 	TEXTMETRIC tm;
@@ -174,13 +174,13 @@
 
 	/* Set the new type face name */
 	pData = (DISPLAYDATA*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
-	_snwprintf(pData->szTypeFaceName, LF_FULLFACESIZE, pExtLogFont->elfFullName);
+	_snwprintf(pData->szTypeFaceName, LF_FULLFACESIZE, pLogFont->lfFaceName);
 
 	/* Create the new fonts */
 	hDC = GetDC(hwnd);
 	DeleteObject(pData->hCharSetFont);
 
-	logfont = pExtLogFont->elfLogFont;
+	logfont = *pLogFont;
 	logfont.lfHeight = -MulDiv(16, GetDeviceCaps(GetDC(NULL), LOGPIXELSY), 72);
 	pData->hCharSetFont = CreateFontIndirectW(&logfont);
 
@@ -252,11 +252,10 @@
 	DISPLAYDATA* pData;
 	const int nSizes[MAX_SIZES] = {8, 12, 18, 24, 36, 48, 60, 72};
 	int i;
-	EXTLOGFONTW ExtLogFont = {{50, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE,
-	                          ANSI_CHARSET, OUT_DEFAULT_PRECIS,
-	                          CLIP_DEFAULT_PRECIS, PROOF_QUALITY,
-	                          DEFAULT_PITCH , L"Ms Shell Dlg"},
-	                          L"Ms Shell Dlg"};
+	LOGFONTW LogFont = {50, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE,
+	                    ANSI_CHARSET, OUT_DEFAULT_PRECIS,
+	                    CLIP_DEFAULT_PRECIS, PROOF_QUALITY,
+	                    DEFAULT_PITCH , L"Ms Shell Dlg"};
 
 	/* Create data structure */
 	pData = malloc(sizeof(DISPLAYDATA));
@@ -270,13 +269,13 @@
 		pData->nSizes[i] = nSizes[i];
 	}
 
-	pData->hCaptionFont = CreateFontIndirectW(&ExtLogFont.elfLogFont);
-	ExtLogFont.elfLogFont.lfHeight = 12;
-	pData->hSizeFont = CreateFontIndirectW(&ExtLogFont.elfLogFont);
+	pData->hCaptionFont = CreateFontIndirectW(&LogFont);
+	LogFont.lfHeight = 12;
+	pData->hSizeFont = CreateFontIndirectW(&LogFont);
 
 	Display_SetString(hwnd, (LPARAM)L"Jackdaws love my big sphinx of quartz. 1234567890");
 
-	Display_SetTypeFace(hwnd, &ExtLogFont);
+	Display_SetTypeFace(hwnd, &LogFont);
 
 	return 0;
 }
@@ -520,7 +519,7 @@
 			return Display_OnVScroll(hwnd, wParam);
 
 		case FVM_SETTYPEFACE:
-			return Display_SetTypeFace(hwnd, (PEXTLOGFONTW)lParam);
+			return Display_SetTypeFace(hwnd, (PLOGFONTW)lParam);
 
 		case FVM_SETSTRING:
 			return Display_SetString(hwnd, lParam);
Index: base/applications/fontview/fontview.c
===================================================================
--- base/applications/fontview/fontview.c	(revision 73482)
+++ base/applications/fontview/fontview.c	(working copy)
@@ -29,9 +29,12 @@
 #include "fontview.h"
 #include "resource.h"
 
-HINSTANCE g_hInstance;
-EXTLOGFONTW g_ExtLogFontW;
-LPCWSTR g_fileName;
+HINSTANCE   g_hInstance;
+INT         g_FontIndex = 0;
+INT         g_NumFonts;
+LOGFONTW    g_LogFonts[16];
+const INT   g_MaxFonts = (INT)(sizeof(g_LogFonts) / sizeof(g_LogFonts[0]));
+LPCWSTR     g_fileName;
 
 static const WCHAR g_szFontViewClassName[] = L"FontViewWClass";
 
@@ -93,6 +96,7 @@
          int nCmdShow)
 {
 	int argc;
+    INT I;
 	WCHAR** argv;
 	WCHAR szFileName[MAX_PATH] = L"";
 	DWORD dwSize;
@@ -161,19 +165,26 @@
 	}
 
 	/* Get the font name */
-	dwSize = sizeof(g_ExtLogFontW.elfFullName);
-	if (!GetFontResourceInfoW(fileName, &dwSize, g_ExtLogFontW.elfFullName, 1))
-	{
-		ErrorMsgBox(0, IDS_ERROR_NOFONT, fileName);
-		return -1;
-	}
+    dwSize = sizeof(g_LogFonts);
+    ZeroMemory(g_LogFonts, sizeof(g_LogFonts));
+    if (!GetFontResourceInfoW(fileName, &dwSize, g_LogFonts, 2))
+    {
+        ErrorMsgBox(0, IDS_ERROR_NOFONT, fileName);
+        return -1;
+    }
+    g_NumFonts = 0;
+    for (I = 0; I < g_MaxFonts; ++I)
+    {
+        if (g_LogFonts[I].lfFaceName[0] == 0)
+            break;
 
-	dwSize = sizeof(LOGFONTW);
-	if (!GetFontResourceInfoW(fileName, &dwSize, &g_ExtLogFontW.elfLogFont, 2))
-	{
-		ErrorMsgBox(0, IDS_ERROR_NOFONT, fileName);
-		return -1;
-	}
+        ++g_NumFonts;
+    }
+    if (g_NumFonts == 0)
+    {
+        MessageBoxA(NULL, "No fonts", NULL, MB_ICONERROR);
+        return -2;
+    }
 
 	if (!Display_InitClass(hThisInstance))
 	{
@@ -206,7 +217,7 @@
 	hMainWnd = CreateWindowExW(
 				0,						/* Extended possibilities for variation */
 				g_szFontViewClassName,	/* Classname */
-				g_ExtLogFontW.elfFullName,/* Title Text */
+				g_LogFonts[0].lfFaceName, /* Title Text */
 				WS_OVERLAPPEDWINDOW,	/* default window */
 				CW_USEDEFAULT,			/* Windows decides the position */
 				CW_USEDEFAULT,			/* where the window ends up on the screen */
@@ -237,7 +248,9 @@
 	WCHAR szQuit[MAX_BUTTONNAME];
 	WCHAR szPrint[MAX_BUTTONNAME];
 	WCHAR szString[MAX_STRING];
-	HWND hDisplay, hButtonInstall, hButtonPrint;
+	WCHAR szPrevious[MAX_STRING];
+	WCHAR szNext[MAX_STRING];
+	HWND hDisplay, hButtonInstall, hButtonPrint, hButtonPrev, hButtonNext;
 
 	/* create the display window */
 	hDisplay = CreateWindowExW(
@@ -258,10 +271,6 @@
 	LoadStringW(g_hInstance, IDS_STRING, szString, MAX_STRING);
 	SendMessage(hDisplay, FVM_SETSTRING, 0, (LPARAM)szString);
 
-	/* Init the display window with the font name */
-	SendMessage(hDisplay, FVM_SETTYPEFACE, 0, (LPARAM)&g_ExtLogFontW);
-	ShowWindow(hDisplay, SW_SHOWNORMAL);
-
 	/* Create the install button */
 	LoadStringW(g_hInstance, IDS_INSTALL, szQuit, MAX_BUTTONNAME);
 	hButtonInstall = CreateWindowExW(
@@ -298,6 +307,51 @@
 			);
 	SendMessage(hButtonPrint, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), (LPARAM)TRUE);
 
+	/* Create the previous button */
+	LoadStringW(g_hInstance, IDS_PREVIOUS, szPrevious, MAX_BUTTONNAME);
+	hButtonPrev = CreateWindowExW(
+				0,						/* Extended style */
+				L"button",				/* Classname */
+				szPrevious,				/* Title text */
+				WS_CHILD | WS_VISIBLE,	/* Window style */
+				450,					/* X-pos */
+				BUTTON_POS_Y,			/* Y-Pos */
+				BUTTON_WIDTH,			/* Width */
+				BUTTON_HEIGHT,			/* Height */
+				hwnd,					/* Parent */
+				(HMENU)IDC_PREV,		/* Identifier */
+				g_hInstance,			/* Program Instance handler */
+				NULL					/* Window Creation data */
+			);
+	SendMessage(hButtonPrev, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), (LPARAM)TRUE);
+
+	/* Create the next button */
+	LoadStringW(g_hInstance, IDS_NEXT, szNext, MAX_BUTTONNAME);
+	hButtonNext = CreateWindowExW(
+				0,						/* Extended style */
+				L"button",				/* Classname */
+				szNext,					/* Title text */
+				WS_CHILD | WS_VISIBLE,	/* Window style */
+				450,					/* X-pos */
+				BUTTON_POS_Y,			/* Y-Pos */
+				BUTTON_WIDTH,			/* Width */
+				BUTTON_HEIGHT,			/* Height */
+				hwnd,					/* Parent */
+				(HMENU)IDC_NEXT,		/* Identifier */
+				g_hInstance,			/* Program Instance handler */
+				NULL					/* Window Creation data */
+			);
+	SendMessage(hButtonNext, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), (LPARAM)TRUE);
+
+    EnableWindow(hButtonPrev, FALSE);
+    if (g_NumFonts <= 1)
+        EnableWindow(hButtonNext, FALSE);
+
+    /* Init the display window with the font name */
+    g_FontIndex = 0;
+    SendMessage(hDisplay, FVM_SETTYPEFACE, 0, (LPARAM)&g_LogFonts[g_FontIndex]);
+    ShowWindow(hDisplay, SW_SHOWNORMAL);
+
 	return 0;
 }
 
@@ -304,12 +358,26 @@
 static LRESULT
 MainWnd_OnSize(HWND hwnd)
 {
-	RECT rc;
+    RECT rc;
+    HWND hInstall, hPrint, hPrev, hNext, hDisplay;
 
-	GetClientRect(hwnd, &rc);
-	MoveWindow(GetDlgItem(hwnd, IDC_PRINT), rc.right - BUTTON_WIDTH - BUTTON_POS_X, BUTTON_POS_Y, BUTTON_WIDTH, BUTTON_HEIGHT, TRUE);
-	MoveWindow(GetDlgItem(hwnd, IDC_DISPLAY), 0, HEADER_SIZE, rc.right, rc.bottom - HEADER_SIZE, TRUE);
+    GetClientRect(hwnd, &rc);
 
+    hInstall = GetDlgItem(hwnd, IDC_INSTALL);
+    MoveWindow(hInstall, BUTTON_POS_X, BUTTON_POS_Y, BUTTON_WIDTH, BUTTON_HEIGHT, TRUE);
+
+    hPrint = GetDlgItem(hwnd, IDC_PRINT);
+    MoveWindow(hPrint, BUTTON_POS_X + BUTTON_WIDTH + BUTTON_PADDING, BUTTON_POS_Y, BUTTON_WIDTH, BUTTON_HEIGHT, TRUE);
+
+    hPrev = GetDlgItem(hwnd, IDC_PREV);
+    MoveWindow(hPrev, rc.right - (BUTTON_WIDTH * 2 + BUTTON_PADDING + BUTTON_POS_X), BUTTON_POS_Y, BUTTON_WIDTH, BUTTON_HEIGHT, TRUE);
+
+    hNext = GetDlgItem(hwnd, IDC_NEXT);
+    MoveWindow(hNext, rc.right - (BUTTON_WIDTH + BUTTON_POS_X), BUTTON_POS_Y, BUTTON_WIDTH, BUTTON_HEIGHT, TRUE);
+
+    hDisplay = GetDlgItem(hwnd, IDC_DISPLAY);
+    MoveWindow(hDisplay, 0, HEADER_SIZE, rc.right, rc.bottom - HEADER_SIZE, TRUE);
+
 	return 0;
 }
 
@@ -349,6 +417,42 @@
 	return 0;
 }
 
+static LRESULT
+MainWnd_OnPrev(HWND hwnd)
+{
+    HWND hDisplay;
+    if (g_FontIndex > 0)
+    {
+        --g_FontIndex;
+        EnableWindow(GetDlgItem(hwnd, IDC_NEXT), TRUE);
+        if (g_FontIndex == 0)
+            EnableWindow(GetDlgItem(hwnd, IDC_PREV), FALSE);
+
+        hDisplay = GetDlgItem(hwnd, IDC_DISPLAY);
+        SendMessage(hDisplay, FVM_SETTYPEFACE, 0, (LPARAM)&g_LogFonts[g_FontIndex]);
+        InvalidateRect(hDisplay, NULL, TRUE);
+    }
+    return 0;
+}
+
+static LRESULT
+MainWnd_OnNext(HWND hwnd)
+{
+    HWND hDisplay;
+    if (g_FontIndex + 1 < g_NumFonts)
+    {
+        ++g_FontIndex;
+        EnableWindow(GetDlgItem(hwnd, IDC_PREV), TRUE);
+        if (g_FontIndex == g_NumFonts - 1)
+            EnableWindow(GetDlgItem(hwnd, IDC_NEXT), FALSE);
+
+        hDisplay = GetDlgItem(hwnd, IDC_DISPLAY);
+        SendMessage(hDisplay, FVM_SETTYPEFACE, 0, (LPARAM)&g_LogFonts[g_FontIndex]);
+        InvalidateRect(hDisplay, NULL, TRUE);
+    }
+    return 0;
+}
+
 LRESULT CALLBACK
 MainWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 {
@@ -368,11 +472,15 @@
 			{
 				case IDC_INSTALL:
 					return MainWnd_OnInstall(hwnd);
-					break;
 
 				case IDC_PRINT:
 					return Display_OnPrint(hwnd);
-					break;
+
+    			case IDC_PREV:
+    			    return MainWnd_OnPrev(hwnd);
+
+			    case IDC_NEXT:
+    			    return MainWnd_OnNext(hwnd);
 			}
 			break;
 
Index: base/applications/fontview/fontview.h
===================================================================
--- base/applications/fontview/fontview.h	(revision 73482)
+++ base/applications/fontview/fontview.h	(working copy)
@@ -8,11 +8,17 @@
 #define BUTTON_POS_Y 8
 #define BUTTON_WIDTH 72
 #define BUTTON_HEIGHT 21
+#define BUTTON_PADDING 8
 
 #define IDC_INSTALL 1001
 #define IDC_PRINT 1002
 #define IDC_DISPLAY 1003
+#define IDC_PREV 1004
+#define IDC_NEXT 1005
 
 LRESULT CALLBACK MainWndProc(HWND, UINT, WPARAM, LPARAM);
 
 BOOL LoadFont(LPWSTR lpCmdLine);
+
+extern INT       g_FontIndex;
+extern INT       g_NumFonts;
Index: base/applications/fontview/lang/bg-BG.rc
===================================================================
--- base/applications/fontview/lang/bg-BG.rc	(revision 73482)
+++ base/applications/fontview/lang/bg-BG.rc	(working copy)
@@ -10,9 +10,12 @@
     IDS_ERROR_NOMEM "Няма достатъчно място за завършване на действието."
     IDS_ERROR_NOFONT "%1 не е редовен шрифтов файл."
     IDS_ERROR_NOCLASS "Неуспешно изпълнение на класа на прозореца."
-    IDS_FILTER_LIST "All Supported Fonts (*.ttf;*.fon;*.otf)\0*.ttf;*.fon;*.otf\0\
+    IDS_FILTER_LIST "All Supported Fonts (*.ttf;*.ttc;*.fon;*.fnt;*.otf)\0*.ttf;*.ttc;*.fon;*.fnt;*.otf\0\
 TrueType Font (*.ttf)\0*.ttf\0\
+TrueType Font Collection (*.ttc)\0*.ttc\0\
 OpenType Font (*.otf)\0*.otf\0\
-Font File (*.fon)\0*.fon\0\
+Font File (*.fon;*.fnt)\0*.fon;*.fnt\0\
 All Files (*.*)\0*.*\0"
+    IDS_PREVIOUS "< Previous"
+    IDS_NEXT "Next >"
 END
Index: base/applications/fontview/lang/cs-CZ.rc
===================================================================
--- base/applications/fontview/lang/cs-CZ.rc	(revision 73482)
+++ base/applications/fontview/lang/cs-CZ.rc	(working copy)
@@ -10,9 +10,12 @@
     IDS_ERROR_NOMEM "K dokončení operace není dostatek paměti."
     IDS_ERROR_NOFONT "Soubor %1 není platným souborem písma."
     IDS_ERROR_NOCLASS "Inicializace okna aplikace selhala."
-    IDS_FILTER_LIST "All Supported Fonts (*.ttf;*.fon;*.otf)\0*.ttf;*.fon;*.otf\0\
+    IDS_FILTER_LIST "All Supported Fonts (*.ttf;*.ttc;*.fon;*.fnt;*.otf)\0*.ttf;*.ttc;*.fon;*.fnt;*.otf\0\
 TrueType Font (*.ttf)\0*.ttf\0\
+TrueType Font Collection (*.ttc)\0*.ttc\0\
 OpenType Font (*.otf)\0*.otf\0\
-Font File (*.fon)\0*.fon\0\
+Font File (*.fon;*.fnt)\0*.fon;*.fnt\0\
 All Files (*.*)\0*.*\0"
+    IDS_PREVIOUS "< Previous"
+    IDS_NEXT "Next >"
 END
Index: base/applications/fontview/lang/de-DE.rc
===================================================================
--- base/applications/fontview/lang/de-DE.rc	(revision 73482)
+++ base/applications/fontview/lang/de-DE.rc	(working copy)
@@ -10,9 +10,12 @@
     IDS_ERROR_NOMEM "Es steht nicht genügend Speicher zur Verfügung."
     IDS_ERROR_NOFONT "Die angegebene Datei %1 ist keine gültige Schriftartendatei."
     IDS_ERROR_NOCLASS "Fehler beim Initialisieren der Fensterklasse."
-    IDS_FILTER_LIST "All Supported Fonts (*.ttf;*.fon;*.otf)\0*.ttf;*.fon;*.otf\0\
+    IDS_FILTER_LIST "All Supported Fonts (*.ttf;*.ttc;*.fon;*.fnt;*.otf)\0*.ttf;*.ttc;*.fon;*.fnt;*.otf\0\
 TrueType Font (*.ttf)\0*.ttf\0\
+TrueType Font Collection (*.ttc)\0*.ttc\0\
 OpenType Font (*.otf)\0*.otf\0\
-Font File (*.fon)\0*.fon\0\
+Font File (*.fon;*.fnt)\0*.fon;*.fnt\0\
 All Files (*.*)\0*.*\0"
+    IDS_PREVIOUS "< Previous"
+    IDS_NEXT "Next >"
 END
Index: base/applications/fontview/lang/en-US.rc
===================================================================
--- base/applications/fontview/lang/en-US.rc	(revision 73482)
+++ base/applications/fontview/lang/en-US.rc	(working copy)
@@ -10,9 +10,12 @@
     IDS_ERROR_NOMEM "There's not enough memory to complete the operation."
     IDS_ERROR_NOFONT "The file %1 is not a valid font file."
     IDS_ERROR_NOCLASS "Could not initialize window class."
-    IDS_FILTER_LIST "All Supported Fonts (*.ttf;*.fon;*.otf)\0*.ttf;*.fon;*.otf\0\
+    IDS_FILTER_LIST "All Supported Fonts (*.ttf;*.ttc;*.fon;*.fnt;*.otf)\0*.ttf;*.ttc;*.fon;*.fnt;*.otf\0\
 TrueType Font (*.ttf)\0*.ttf\0\
+TrueType Font Collection (*.ttc)\0*.ttc\0\
 OpenType Font (*.otf)\0*.otf\0\
-Font File (*.fon)\0*.fon\0\
+Font File (*.fon;*.fnt)\0*.fon;*.fnt\0\
 All Files (*.*)\0*.*\0"
+    IDS_PREVIOUS "< Previous"
+    IDS_NEXT "Next >"
 END
Index: base/applications/fontview/lang/es-ES.rc
===================================================================
--- base/applications/fontview/lang/es-ES.rc	(revision 73482)
+++ base/applications/fontview/lang/es-ES.rc	(working copy)
@@ -12,9 +12,12 @@
     IDS_ERROR_NOMEM "No hay memoria suficiente para completar la operación."
     IDS_ERROR_NOFONT "El archivo %1 no es un archivo de fuente válido."
     IDS_ERROR_NOCLASS "No es posible iniciar la clase de ventana."
-    IDS_FILTER_LIST "All Supported Fonts (*.ttf;*.fon;*.otf)\0*.ttf;*.fon;*.otf\0\
+    IDS_FILTER_LIST "All Supported Fonts (*.ttf;*.ttc;*.fon;*.fnt;*.otf)\0*.ttf;*.ttc;*.fon;*.fnt;*.otf\0\
 TrueType Font (*.ttf)\0*.ttf\0\
+TrueType Font Collection (*.ttc)\0*.ttc\0\
 OpenType Font (*.otf)\0*.otf\0\
-Font File (*.fon)\0*.fon\0\
+Font File (*.fon;*.fnt)\0*.fon;*.fnt\0\
 All Files (*.*)\0*.*\0"
+    IDS_PREVIOUS "< Previous"
+    IDS_NEXT "Next >"
 END
Index: base/applications/fontview/lang/fr-FR.rc
===================================================================
--- base/applications/fontview/lang/fr-FR.rc	(revision 73482)
+++ base/applications/fontview/lang/fr-FR.rc	(working copy)
@@ -10,9 +10,12 @@
     IDS_ERROR_NOMEM "Mémoire insuffisante pour terminer l'opération."
     IDS_ERROR_NOFONT "Le fichier %1 n'est pas un fichier police valide."
     IDS_ERROR_NOCLASS "Impossible d'initialiser la classe de fenêtre."
-    IDS_FILTER_LIST "All Supported Fonts (*.ttf;*.fon;*.otf)\0*.ttf;*.fon;*.otf\0\
+    IDS_FILTER_LIST "All Supported Fonts (*.ttf;*.ttc;*.fon;*.fnt;*.otf)\0*.ttf;*.ttc;*.fon;*.fnt;*.otf\0\
 TrueType Font (*.ttf)\0*.ttf\0\
+TrueType Font Collection (*.ttc)\0*.ttc\0\
 OpenType Font (*.otf)\0*.otf\0\
-Font File (*.fon)\0*.fon\0\
+Font File (*.fon;*.fnt)\0*.fon;*.fnt\0\
 All Files (*.*)\0*.*\0"
+    IDS_PREVIOUS "< Previous"
+    IDS_NEXT "Next >"
 END
Index: base/applications/fontview/lang/he-IL.rc
===================================================================
--- base/applications/fontview/lang/he-IL.rc	(revision 73482)
+++ base/applications/fontview/lang/he-IL.rc	(working copy)
@@ -12,9 +12,12 @@
     IDS_ERROR_NOMEM "אין מספיק זיכרון כדי להשלים את הפעולה."
     IDS_ERROR_NOFONT "הקובץ %1 אינו קובץ גופנים חוקי."
     IDS_ERROR_NOCLASS "Could not initialize window class."
-    IDS_FILTER_LIST "All Supported Fonts (*.ttf;*.fon;*.otf)\0*.ttf;*.fon;*.otf\0\
+    IDS_FILTER_LIST "All Supported Fonts (*.ttf;*.ttc;*.fon;*.fnt;*.otf)\0*.ttf;*.ttc;*.fon;*.fnt;*.otf\0\
 TrueType Font (*.ttf)\0*.ttf\0\
+TrueType Font Collection (*.ttc)\0*.ttc\0\
 OpenType Font (*.otf)\0*.otf\0\
-Font File (*.fon)\0*.fon\0\
+Font File (*.fon;*.fnt)\0*.fon;*.fnt\0\
 All Files (*.*)\0*.*\0"
+    IDS_PREVIOUS "< Previous"
+    IDS_NEXT "Next >"
 END
Index: base/applications/fontview/lang/it-IT.rc
===================================================================
--- base/applications/fontview/lang/it-IT.rc	(revision 73482)
+++ base/applications/fontview/lang/it-IT.rc	(working copy)
@@ -10,9 +10,12 @@
     IDS_ERROR_NOMEM "Memoria insufficiente per completare l'operazione."
     IDS_ERROR_NOFONT "Il file% 1 non è un file di origine valido."
     IDS_ERROR_NOCLASS "Impossibile avviare la classe."
-    IDS_FILTER_LIST "All Supported Fonts (*.ttf;*.fon;*.otf)\0*.ttf;*.fon;*.otf\0\
+    IDS_FILTER_LIST "All Supported Fonts (*.ttf;*.ttc;*.fon;*.fnt;*.otf)\0*.ttf;*.ttc;*.fon;*.fnt;*.otf\0\
 TrueType Font (*.ttf)\0*.ttf\0\
+TrueType Font Collection (*.ttc)\0*.ttc\0\
 OpenType Font (*.otf)\0*.otf\0\
-Font File (*.fon)\0*.fon\0\
+Font File (*.fon;*.fnt)\0*.fon;*.fnt\0\
 All Files (*.*)\0*.*\0"
+    IDS_PREVIOUS "< Previous"
+    IDS_NEXT "Next >"
 END
Index: base/applications/fontview/lang/lt-LT.rc
===================================================================
--- base/applications/fontview/lang/lt-LT.rc	(revision 73482)
+++ base/applications/fontview/lang/lt-LT.rc	(working copy)
@@ -12,9 +12,12 @@
     IDS_ERROR_NOMEM "Užduočiai užbaigti, nepakanka atminties."
     IDS_ERROR_NOFONT "%1 nėra teisinga šrifto byla."
     IDS_ERROR_NOCLASS "Nepavyko inicijuoti lango klasės."
-    IDS_FILTER_LIST "All Supported Fonts (*.ttf;*.fon;*.otf)\0*.ttf;*.fon;*.otf\0\
+    IDS_FILTER_LIST "All Supported Fonts (*.ttf;*.ttc;*.fon;*.fnt;*.otf)\0*.ttf;*.ttc;*.fon;*.fnt;*.otf\0\
 TrueType Font (*.ttf)\0*.ttf\0\
+TrueType Font Collection (*.ttc)\0*.ttc\0\
 OpenType Font (*.otf)\0*.otf\0\
-Font File (*.fon)\0*.fon\0\
+Font File (*.fon;*.fnt)\0*.fon;*.fnt\0\
 All Files (*.*)\0*.*\0"
+    IDS_PREVIOUS "< Previous"
+    IDS_NEXT "Next >"
 END
Index: base/applications/fontview/lang/ms-MY.rc
===================================================================
--- base/applications/fontview/lang/ms-MY.rc	(revision 73482)
+++ base/applications/fontview/lang/ms-MY.rc	(working copy)
@@ -12,9 +12,12 @@
     IDS_ERROR_NOMEM "Terdapat tidak cukup ingatan untuk melengkapkan operasi ini."
     IDS_ERROR_NOFONT "Fail %1 bukanlah fail fon yang sah."
     IDS_ERROR_NOCLASS "Tidak dapat mengawalkan kelas tetingkap."
-    IDS_FILTER_LIST "Semuanya disokong fon (*.ttf;*.fon;*.otf)\0*.ttf;*.fon;*.otf\0\
-Fon TrueType (*.ttf)\0*.ttf\0\
-Fon OpenType (*.otf)\0*.otf\0\
-Fail fon (*.fon)\0*.fon\0\
-Semua fail (*.*)\0*.*\0"
+    IDS_FILTER_LIST "Semuanya disokong fon (*.ttf;*.ttc;*.fon;*.fnt;*.otf)\0*.ttf;*.ttc;*.fon;*.fnt;*.otf\0\
+TrueType Font (*.ttf)\0*.ttf\0\
+TrueType Font Collection (*.ttc)\0*.ttc\0\
+OpenType Font (*.otf)\0*.otf\0\
+Font File (*.fon;*.fnt)\0*.fon;*.fnt\0\
+All Files (*.*)\0*.*\0"
+    IDS_PREVIOUS "< Previous"
+    IDS_NEXT "Next >"
 END
Index: base/applications/fontview/lang/no-NO.rc
===================================================================
--- base/applications/fontview/lang/no-NO.rc	(revision 73482)
+++ base/applications/fontview/lang/no-NO.rc	(working copy)
@@ -10,9 +10,12 @@
     IDS_ERROR_NOMEM "Det er ikke nok minne for å fullføre oppgaven."
     IDS_ERROR_NOFONT "Filen %1 er ikke et gyldig skriftfil."
     IDS_ERROR_NOCLASS "Kunne ikke initialise vindu klassen."
-    IDS_FILTER_LIST "All Supported Fonts (*.ttf;*.fon;*.otf)\0*.ttf;*.fon;*.otf\0\
+    IDS_FILTER_LIST "All Supported Fonts (*.ttf;*.ttc;*.fon;*.fnt;*.otf)\0*.ttf;*.ttc;*.fon;*.fnt;*.otf\0\
 TrueType Font (*.ttf)\0*.ttf\0\
+TrueType Font Collection (*.ttc)\0*.ttc\0\
 OpenType Font (*.otf)\0*.otf\0\
-Font File (*.fon)\0*.fon\0\
+Font File (*.fon;*.fnt)\0*.fon;*.fnt\0\
 All Files (*.*)\0*.*\0"
+    IDS_PREVIOUS "< Previous"
+    IDS_NEXT "Next >"
 END
Index: base/applications/fontview/lang/pl-PL.rc
===================================================================
--- base/applications/fontview/lang/pl-PL.rc	(revision 73482)
+++ base/applications/fontview/lang/pl-PL.rc	(working copy)
@@ -18,9 +18,12 @@
     IDS_ERROR_NOMEM "Brakuje pamięci do ukończenia tej operacji."
     IDS_ERROR_NOFONT "Plik %1 nie jest poprawnym plikiem czcionki."
     IDS_ERROR_NOCLASS "Nie udało się zainicjować klasy window."
-    IDS_FILTER_LIST "All Supported Fonts (*.ttf;*.fon;*.otf)\0*.ttf;*.fon;*.otf\0\
+    IDS_FILTER_LIST "All Supported Fonts (*.ttf;*.ttc;*.fon;*.fnt;*.otf)\0*.ttf;*.ttc;*.fon;*.fnt;*.otf\0\
 TrueType Font (*.ttf)\0*.ttf\0\
+TrueType Font Collection (*.ttc)\0*.ttc\0\
 OpenType Font (*.otf)\0*.otf\0\
-Font File (*.fon)\0*.fon\0\
+Font File (*.fon;*.fnt)\0*.fon;*.fnt\0\
 All Files (*.*)\0*.*\0"
+    IDS_PREVIOUS "< Previous"
+    IDS_NEXT "Next >"
 END
Index: base/applications/fontview/lang/pt-BR.rc
===================================================================
--- base/applications/fontview/lang/pt-BR.rc	(revision 73482)
+++ base/applications/fontview/lang/pt-BR.rc	(working copy)
@@ -12,9 +12,12 @@
     IDS_ERROR_NOMEM "Não há memória suficiente para completar a operação."
     IDS_ERROR_NOFONT "O arquivo %1 não é um arquivo de fonte válida."
     IDS_ERROR_NOCLASS "Não foi possível inicializar a janela."
-    IDS_FILTER_LIST "All Supported Fonts (*.ttf;*.fon;*.otf)\0*.ttf;*.fon;*.otf\0\
+    IDS_FILTER_LIST "All Supported Fonts (*.ttf;*.ttc;*.fon;*.fnt;*.otf)\0*.ttf;*.ttc;*.fon;*.fnt;*.otf\0\
 TrueType Font (*.ttf)\0*.ttf\0\
+TrueType Font Collection (*.ttc)\0*.ttc\0\
 OpenType Font (*.otf)\0*.otf\0\
-Font File (*.fon)\0*.fon\0\
+Font File (*.fon;*.fnt)\0*.fon;*.fnt\0\
 All Files (*.*)\0*.*\0"
+    IDS_PREVIOUS "< Previous"
+    IDS_NEXT "Next >"
 END
Index: base/applications/fontview/lang/ro-RO.rc
===================================================================
--- base/applications/fontview/lang/ro-RO.rc	(revision 73482)
+++ base/applications/fontview/lang/ro-RO.rc	(working copy)
@@ -12,9 +12,12 @@
     IDS_ERROR_NOMEM "Nu e destulă memorie pentru a încheia operația."
     IDS_ERROR_NOFONT "Fișierul «%1» este un fișier font deteriorat."
     IDS_ERROR_NOCLASS "Clasa de ferestre nu a putut fi inițializată."
-    IDS_FILTER_LIST "Toate fonturile recunoscute (*.ttf;*.fon;*.otf)\0*.ttf;*.fon;*.otf\0\
+    IDS_FILTER_LIST "Toate fonturile recunoscute (*.ttf;*.ttc;*.fon;*.fnt;*.otf)\0*.ttf;.ttc;*.fon;*.otf\0\
 Fonturi de tip TrueType (*.ttf)\0*.ttf\0\
+TrueType Font Collection (*.ttc)\0*.ttc\0\
 Fonturi de tip OpenType (*.otf)\0*.otf\0\
-Fișiere de tip Font (*.fon)\0*.fon\0\
+Fișiere de tip Font (*.fon;*.fnt)\0*.fon;*.fnt\0\
 Orice fișier (*.*)\0*.*\0"
+    IDS_PREVIOUS "< Previous"
+    IDS_NEXT "Next >"
 END
Index: base/applications/fontview/lang/ru-RU.rc
===================================================================
--- base/applications/fontview/lang/ru-RU.rc	(revision 73482)
+++ base/applications/fontview/lang/ru-RU.rc	(working copy)
@@ -12,9 +12,12 @@
     IDS_ERROR_NOMEM "Недостаточно памяти для выполнения операции."
     IDS_ERROR_NOFONT "%1 не является корректным файлом шрифта."
     IDS_ERROR_NOCLASS "Невозможно инициализировать класс окна."
-    IDS_FILTER_LIST "Все поддерживаемые шрифты (*.ttf;*.fon;*.otf)\0*.ttf;*.fon;*.otf\0\
+    IDS_FILTER_LIST "Все поддерживаемые шрифты (*.ttf;*.ttc;*.fon;*.fnt;*.otf)\0*.ttf;*.ttc;*.fon;*.fnt;*.otf\0\
 TrueType шрифты (*.ttf)\0*.ttf\0\
+TrueType Font Collection (*.ttc)\0*.ttc\0\
 OpenType шрифты (*.otf)\0*.otf\0\
-Файлы шрифтов (*.fon)\0*.fon\0\
+Файлы шрифтов (*.fon;*.fnt)\0*.fon;*.fnt\0\
 Все файлы (*.*)\0*.*\0"
+    IDS_PREVIOUS "< Previous"
+    IDS_NEXT "Next >"
 END
Index: base/applications/fontview/lang/sk-SK.rc
===================================================================
--- base/applications/fontview/lang/sk-SK.rc	(revision 73482)
+++ base/applications/fontview/lang/sk-SK.rc	(working copy)
@@ -15,9 +15,12 @@
     IDS_ERROR_NOMEM "Na vykonanie tejto operácie nie je dostatok voľnej pamäte."
     IDS_ERROR_NOFONT "Požadovaný súbor %1 nie je platným súborom písiem."
     IDS_ERROR_NOCLASS "Nepodarilo sa inicializovať triedu window."
-    IDS_FILTER_LIST "All Supported Fonts (*.ttf;*.fon;*.otf)\0*.ttf;*.fon;*.otf\0\
+    IDS_FILTER_LIST "All Supported Fonts (*.ttf;*.ttc;*.fon;*.fnt;*.otf)\0*.ttf;*.ttc;*.fon;*.fnt;*.otf\0\
 TrueType Font (*.ttf)\0*.ttf\0\
+TrueType Font Collection (*.ttc)\0*.ttc\0\
 OpenType Font (*.otf)\0*.otf\0\
-Font File (*.fon)\0*.fon\0\
+Font File (*.fon;*.fnt)\0*.fon;*.fnt\0\
 All Files (*.*)\0*.*\0"
+    IDS_PREVIOUS "< Previous"
+    IDS_NEXT "Next >"
 END
Index: base/applications/fontview/lang/sq-AL.rc
===================================================================
--- base/applications/fontview/lang/sq-AL.rc	(revision 73482)
+++ base/applications/fontview/lang/sq-AL.rc	(working copy)
@@ -14,9 +14,12 @@
     IDS_ERROR_NOMEM "Nuk ka memorie të mjaftueshme për të përfunduar operacionin."
     IDS_ERROR_NOFONT "Dokumenti %1 nuk është një font i vlefshem."
     IDS_ERROR_NOCLASS "Nuk mund të fillojë dritaren e klases."
-    IDS_FILTER_LIST "All Supported Fonts (*.ttf;*.fon;*.otf)\0*.ttf;*.fon;*.otf\0\
+    IDS_FILTER_LIST "All Supported Fonts (*.ttf;*.ttc;*.fon;*.fnt;*.otf)\0*.ttf;*.ttc;*.fon;*.fnt;*.otf\0\
 TrueType Font (*.ttf)\0*.ttf\0\
+TrueType Font Collection (*.ttc)\0*.ttc\0\
 OpenType Font (*.otf)\0*.otf\0\
-Font File (*.fon)\0*.fon\0\
+Font File (*.fon;*.fnt)\0*.fon;*.fnt\0\
 All Files (*.*)\0*.*\0"
+    IDS_PREVIOUS "< Previous"
+    IDS_NEXT "Next >"
 END
Index: base/applications/fontview/lang/sv-SE.rc
===================================================================
--- base/applications/fontview/lang/sv-SE.rc	(revision 73482)
+++ base/applications/fontview/lang/sv-SE.rc	(working copy)
@@ -17,9 +17,12 @@
     IDS_ERROR_NOMEM "Det er inte nog minne för att slutföre operationen."
     IDS_ERROR_NOFONT "Filen %1 är inte en giltig typsnittsfil."
     IDS_ERROR_NOCLASS "Kunde inte initialisera Windows klassen."
-    IDS_FILTER_LIST "All Supported Fonts (*.ttf;*.fon;*.otf)\0*.ttf;*.fon;*.otf\0\
+    IDS_FILTER_LIST "All Supported Fonts (*.ttf;*.ttc;*.fon;*.fnt;*.otf)\0*.ttf;*.ttc;*.fon;*.fnt;*.otf\0\
 TrueType Font (*.ttf)\0*.ttf\0\
+TrueType Font Collection (*.ttc)\0*.ttc\0\
 OpenType Font (*.otf)\0*.otf\0\
-Font File (*.fon)\0*.fon\0\
+Font File (*.fon;*.fnt)\0*.fon;*.fnt\0\
 All Files (*.*)\0*.*\0"
+    IDS_PREVIOUS "< Previous"
+    IDS_NEXT "Next >"
 END
Index: base/applications/fontview/lang/tr-TR.rc
===================================================================
--- base/applications/fontview/lang/tr-TR.rc	(revision 73482)
+++ base/applications/fontview/lang/tr-TR.rc	(working copy)
@@ -11,9 +11,12 @@
     IDS_ERROR_NOMEM "Bu işlemi bitirmek için yeterli bellek yok."
     IDS_ERROR_NOFONT "%1 kütüğü, geçerli bir yazı tipi kütüğü değil."
     IDS_ERROR_NOCLASS "Pencere sınıfı başlatılamadı."
-    IDS_FILTER_LIST "Tüm Desteklenen Yazı Tipleri (*.ttf, *.fon, *.otf)\0*.ttf;*.fon;*.otf\0\
+    IDS_FILTER_LIST "Tüm Desteklenen Yazı Tipleri (*.ttf;*.ttc;*.fon;*.fnt;*.otf)\0*.ttf;*.ttc;*.fon;*.fnt;*.otf\0\
 TrueType Yazı Tipi (*.ttf)\0*.ttf\0\
+TrueType Font Collection (*.ttc)\0*.ttc\0\
 OpenType Yazı Tipi (*.otf)\0*.otf\0\
-Yazı Tipi Kütüğü (*.fon)\0*.fon\0\
+Yazı Tipi Kütüğü (*.fon;*.fnt)\0*.fon;*.fnt\0\
 Tüm Kütükler (*.*)\0*.*\0"
+    IDS_PREVIOUS "< Previous"
+    IDS_NEXT "Next >"
 END
Index: base/applications/fontview/lang/uk-UA.rc
===================================================================
--- base/applications/fontview/lang/uk-UA.rc	(revision 73482)
+++ base/applications/fontview/lang/uk-UA.rc	(working copy)
@@ -18,9 +18,12 @@
     IDS_ERROR_NOMEM "Недостатньо пам'яті для завершення операції."
     IDS_ERROR_NOFONT "Файл %1 не є коректним файлом шрифту."
     IDS_ERROR_NOCLASS "Неможливо ініціалізувати віконний клас."
-    IDS_FILTER_LIST "All Supported Fonts (*.ttf;*.fon;*.otf)\0*.ttf;*.fon;*.otf\0\
+    IDS_FILTER_LIST "All Supported Fonts (*.ttf;*.ttc;*.fon;*.fnt;*.otf)\0*.ttf;*.ttc;*.fon;*.fnt;*.otf\0\
 TrueType Font (*.ttf)\0*.ttf\0\
+TrueType Font Collection (*.ttc)\0*.ttc\0\
 OpenType Font (*.otf)\0*.otf\0\
-Font File (*.fon)\0*.fon\0\
+Font File (*.fon;*.fnt)\0*.fon;*.fnt\0\
 All Files (*.*)\0*.*\0"
+    IDS_PREVIOUS "< Previous"
+    IDS_NEXT "Next >"
 END
Index: base/applications/fontview/lang/zh-CN.rc
===================================================================
--- base/applications/fontview/lang/zh-CN.rc	(revision 73482)
+++ base/applications/fontview/lang/zh-CN.rc	(working copy)
@@ -18,9 +18,12 @@
     IDS_ERROR_NOMEM "没有足够的内存来完成操作。"
     IDS_ERROR_NOFONT "％1不是一个有效的字体档案。"
     IDS_ERROR_NOCLASS "窗口无法初始化。"
-    IDS_FILTER_LIST "支持所有的字体 (*.ttf;*.fon;*.otf)\0*.ttf;*.fon;*.otf\0\
+    IDS_FILTER_LIST "支持所有的字体 (*.ttf;*.ttc;*.fon;*.fnt;*.otf)\0*.ttf;*.ttc;*.fon;*.fnt;*.otf\0\
 TrueType 字体 (*.ttf)\0*.ttf\0\
+TrueType Font Collection (*.ttc)\0*.ttc\0\
 OpenType 字体 (*.otf)\0*.otf\0\
-字体文件 (*.fon)\0*.fon\0\
+字体文件 (*.fon;*.fnt)\0*.fon;*.fnt\0\
 所有文件 (*.*)\0*.*\0"
+    IDS_PREVIOUS "< Previous"
+    IDS_NEXT "Next >"
 END
Index: base/applications/fontview/lang/zh-TW.rc
===================================================================
--- base/applications/fontview/lang/zh-TW.rc	(revision 73482)
+++ base/applications/fontview/lang/zh-TW.rc	(working copy)
@@ -18,9 +18,12 @@
     IDS_ERROR_NOMEM "沒有足夠的記憶體來完成操作。"
     IDS_ERROR_NOFONT "%1 不是一個有效的字體檔案。"
     IDS_ERROR_NOCLASS "窗口無法初始化。"
-    IDS_FILTER_LIST "所有支援的字體 (*.ttf;*.fon;*.otf)\0*.ttf;*.fon;*.otf\0\
+    IDS_FILTER_LIST "所有支援的字體 (*.ttf;*.ttc;*.fon;*.fnt;*.otf)\0*.ttf;*.ttc;*.fon;*.fnt;*.otf\0\
 TrueType 字體 (*.ttf)\0*.ttf\0\
+TrueType Font Collection (*.ttc)\0*.ttc\0\
 OpenType 字體 (*.otf)\0*.otf\0\
-字體檔 (*.fon)\0*.fon\0\
+字體檔 (*.fon;*.fnt)\0*.fon;*.fnt\0\
 所有檔 (*.*)\0*.*\0"
+    IDS_PREVIOUS "< Previous"
+    IDS_NEXT "Next >"
 END
Index: base/applications/fontview/resource.h
===================================================================
--- base/applications/fontview/resource.h	(revision 73482)
+++ base/applications/fontview/resource.h	(working copy)
@@ -15,4 +15,7 @@
 #define IDS_CHARSUPPER   701
 #define IDS_SPECIALCHARS 702
 
+#define IDS_PREVIOUS   800
+#define IDS_NEXT       801
+
 #define IDI_TT 800
Index: boot/bootdata/hivecls.inf
===================================================================
--- boot/bootdata/hivecls.inf	(revision 73482)
+++ boot/bootdata/hivecls.inf	(working copy)
@@ -121,19 +121,25 @@
 HKCR,"fonfile","",0x00000000,"Font file"
 HKCR,"fonfile","FriendlyTypeName",0x00020000,"@%SystemRoot%\system32\shell32.dll,-209"
 HKCR,"fonfile\DefaultIcon","",0x00020000,"%SystemRoot%\system32\shell32.dll,-155"
-HKCR,"fonfile\shell\open\command","",0x00020000,"%SystemRoot%\system32\fontview.exe %1"
+HKCR,"fonfile\shell\open\command","",0x00020000,"%SystemRoot%\system32\fontview.exe ""%1"""
 
 HKCR,".ttf","",0x00000000,"ttffile"
 HKCR,"ttffile","",0x00000000,"TrueType Font file"
 HKCR,"ttffile","FriendlyTypeName",0x00020000,"@%SystemRoot%\system32\shell32.dll,-210"
 HKCR,"ttffile\DefaultIcon","",0x00020000,"%SystemRoot%\system32\shell32.dll,-156"
-HKCR,"ttffile\shell\open\command","",0x00020000,"%SystemRoot%\system32\fontview.exe %1"
+HKCR,"ttffile\shell\open\command","",0x00020000,"%SystemRoot%\system32\fontview.exe ""%1"""
 
+HKCR,".ttc","",0x00000000,"ttcfile"
+HKCR,"ttcfile","",0x00000000,"TrueType Font Collection file"
+HKCR,"ttcfile","FriendlyTypeName",0x00020000,"@%SystemRoot%\system32\shell32.dll,-210"
+HKCR,"ttcfile\DefaultIcon","",0x00020000,"%SystemRoot%\system32\shell32.dll,-156"
+HKCR,"ttcfile\shell\open\command","",0x00020000,"%SystemRoot%\system32\fontview.exe ""%1"""
+
 HKCR,".otf","",0x00000000,"otffile"
 HKCR,"otffile","",0x00000000,"OpenType Font file"
 HKCR,"otffile","FriendlyTypeName",0x00020000,"@%SystemRoot%\system32\shell32.dll,-211"
 HKCR,"otffile\DefaultIcon","",0x00020000,"%SystemRoot%\system32\shell32.dll,-156"
-HKCR,"otffile\shell\open\command","",0x00020000,"%SystemRoot%\system32\fontview.exe %1"
+HKCR,"otffile\shell\open\command","",0x00020000,"%SystemRoot%\system32\fontview.exe ""%1"""
 
 ; Help Files
 HKCR,".hlp","",0x00000000,"hlpfile"
Index: sdk/include/psdk/ntgdi.h
===================================================================
--- sdk/include/psdk/ntgdi.h	(revision 73482)
+++ sdk/include/psdk/ntgdi.h	(working copy)
@@ -156,7 +156,7 @@
     _In_ ULONG cFiles,
     _In_ UINT cjBuf,
     _Out_ LPDWORD pdwBytes,
-    _Out_writes_bytes_(cjBuf) LPVOID pvBuf,
+    _Inout_opt_ LPVOID pvBuf,
     _In_ DWORD iType);
 
 __kernel_entry
Index: win32ss/gdi/eng/engobjects.h
===================================================================
--- win32ss/gdi/eng/engobjects.h	(revision 73482)
+++ win32ss/gdi/eng/engobjects.h	(working copy)
@@ -107,15 +107,19 @@
   ULONG Dummy;
 } FLOATGDI;
 
+typedef struct _SHARED_FACE {
+    FT_Face     Face;
+    LONG        RefCount;
+} SHARED_FACE, *PSHARED_FACE;
+
 typedef struct _FONTGDI {
   FONTOBJ     FontObj;
   ULONG       iUnique;
   FLONG       flType;
-  union{
-  DHPDEV      dhpdev;
-  FT_Face     face;
-  };
 
+  DHPDEV        dhpdev;
+  PSHARED_FACE  SharedFace;
+
   LONG        lMaxNegA;
   LONG        lMaxNegC;
   LONG        lMinWidthD;
@@ -123,6 +127,9 @@
   LPWSTR      Filename;
   BYTE        Underline;
   BYTE        StrikeOut;
+  BYTE        Italic;
+  LONG        Weight;
+  BYTE        CharSet;
 } FONTGDI, *PFONTGDI;
 
 typedef struct _PATHGDI {
Index: win32ss/gdi/gdi32/objects/text.c
===================================================================
--- win32ss/gdi/gdi32/objects/text.c	(revision 73482)
+++ win32ss/gdi/gdi32/objects/text.c	(working copy)
@@ -584,7 +584,7 @@
 GetFontResourceInfoW(
     _In_z_ LPCWSTR lpFileName,
     _Inout_ DWORD *pdwBufSize,
-    _Out_writes_to_(*pdwBufSize, *pdwBufSize) PVOID lpBuffer,
+    _Inout_opt_ PVOID lpBuffer,
     _In_ DWORD dwType)
 {
     BOOL bRet;
Index: win32ss/gdi/ntgdi/font.c
===================================================================
--- win32ss/gdi/ntgdi/font.c	(revision 73482)
+++ win32ss/gdi/ntgdi/font.c	(working copy)
@@ -10,7 +10,7 @@
 
 #include <win32k.h>
 
-#define NDEBUG
+//#define NDEBUG
 #include <debug.h>
 
 HFONT APIENTRY HfontCreate( IN PENUMLOGFONTEXDVW pelfw,IN ULONG cjElfw,IN LFTYPE lft,IN FLONG fl,IN PVOID pvCliData );
@@ -865,13 +865,13 @@
 BOOL
 APIENTRY
 NtGdiGetFontResourceInfoInternalW(
-    IN LPWSTR   pwszFiles,
-    IN ULONG    cwc,
-    IN ULONG    cFiles,
-    IN UINT     cjIn,
-    OUT LPDWORD pdwBytes,
-    OUT LPVOID  pvBuf,
-    IN DWORD    dwType)
+    IN LPWSTR       pwszFiles,
+    IN ULONG        cwc,
+    IN ULONG        cFiles,
+    IN UINT         cjIn,
+    IN OUT LPDWORD  pdwBytes,
+    OUT LPVOID      pvBuf,
+    IN DWORD        dwType)
 {
     NTSTATUS Status = STATUS_SUCCESS;
     DWORD dwBytes;
@@ -879,12 +879,6 @@
     BOOL bRet = FALSE;
     ULONG cbStringSize;
 
-    union
-    {
-        LOGFONTW logfontw;
-        WCHAR FullName[LF_FULLFACESIZE];
-    } Buffer;
-
     /* FIXME: Handle cFiles > 0 */
 
     /* Check for valid dwType values
@@ -911,6 +905,7 @@
     _SEH2_TRY
     {
         ProbeForRead(pwszFiles, cbStringSize, 1);
+        ProbeForRead(pdwBytes, sizeof(DWORD), 1);
         ProbeForWrite(pdwBytes, sizeof(DWORD), 1);
         ProbeForWrite(pvBuf, cjIn, 1);
 
@@ -931,7 +926,7 @@
     }
 
     /* Do the actual call */
-    bRet = IntGdiGetFontResourceInfo(&SafeFileNames, &Buffer, &dwBytes, dwType);
+    bRet = IntGdiGetFontResourceInfo(&SafeFileNames, pvBuf, &dwBytes, dwType);
 
     /* Check if succeeded and the buffer is big enough */
     if (bRet && cjIn >= dwBytes)
@@ -939,8 +934,6 @@
         /* Copy the data back to caller */
         _SEH2_TRY
         {
-            /* Buffers are already probed */
-            RtlCopyMemory(pvBuf, &Buffer, dwBytes);
             *pdwBytes = dwBytes;
         }
         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
Index: win32ss/gdi/ntgdi/freetype.c
===================================================================
--- win32ss/gdi/ntgdi/freetype.c	(revision 73482)
+++ win32ss/gdi/ntgdi/freetype.c	(working copy)
@@ -3,8 +3,9 @@
  * LICENSE:         GPL - See COPYING in the top level directory
  * FILE:            win32ss/gdi/ntgdi/freetype.c
  * PURPOSE:         FreeType font engine interface
- * PROGRAMMER:      Copyright 2001 Huw D M Davies for CodeWeavers.
+ * PROGRAMMERS:     Copyright 2001 Huw D M Davies for CodeWeavers.
  *                  Copyright 2006 Dmitry Timoshkov for CodeWeavers.
+ *                  Copyright 2016 Katayama Hirofumi MZ.
  */
 
 /** Includes ******************************************************************/
@@ -19,6 +20,12 @@
 #include FT_OUTLINE_H
 #include FT_WINFONTS_H
 
+#ifndef FT_INTERNAL_INTERNAL_H
+    #define  FT_INTERNAL_INTERNAL_H  <freetype/internal/internal.h>
+    #include FT_INTERNAL_INTERNAL_H
+#endif
+#include FT_INTERNAL_TRUETYPE_TYPES_H
+
 #include <gdi/eng/floatobj.h>
 
 #define NDEBUG
@@ -30,6 +37,11 @@
        ((DWORD)(BYTE)(ch2) << 8) | (DWORD)(BYTE)(ch3) )
 #endif
 
+/* TPMF_FIXED_PITCH is confusing; braindead api */
+#ifndef _TMPF_VARIABLE_PITCH
+    #define _TMPF_VARIABLE_PITCH    TMPF_FIXED_PITCH
+#endif
+
 extern const MATRIX gmxWorldToDeviceDefault;
 extern const MATRIX gmxWorldToPageDefault;
 
@@ -38,6 +50,40 @@
 
 FT_Library  library;
 
+static PSHARED_FACE
+SharedFace_Create(FT_Face Face)
+{
+    PSHARED_FACE Ptr;
+    Ptr = (PSHARED_FACE)ExAllocatePoolWithTag(PagedPool,
+                                              sizeof(SHARED_FACE), TAG_FONT);
+    if (Ptr)
+    {
+        Ptr->Face = Face;
+        Ptr->RefCount = 1;
+    }
+    return Ptr;
+}
+
+static void
+SharedFace_AddRef(PSHARED_FACE Ptr)
+{
+    ++Ptr->RefCount;
+}
+
+static void
+SharedFace_Release(PSHARED_FACE Ptr)
+{
+    if (Ptr->RefCount <= 0)
+        return;
+
+    --Ptr->RefCount;
+    if (Ptr->RefCount == 0)
+    {
+        FT_Done_Face(Ptr->Face);
+        ExFreePoolWithTag(Ptr, TAG_FONT);
+    }
+}
+
 typedef struct _FONT_ENTRY
 {
     LIST_ENTRY ListEntry;
@@ -223,7 +269,7 @@
 IntLoadSystemFonts(VOID)
 {
     OBJECT_ATTRIBUTES ObjectAttributes;
-    UNICODE_STRING Directory, SearchPattern, FileName, TempString;
+    UNICODE_STRING Directory, SearchPatterns[5], FileName, TempString;
     IO_STATUS_BLOCK Iosb;
     HANDLE hDirectory;
     BYTE *DirInfoBuffer;
@@ -230,11 +276,17 @@
     PFILE_DIRECTORY_INFORMATION DirInfo;
     BOOLEAN bRestartScan = TRUE;
     NTSTATUS Status;
+    INT I;
+    const INT NUM_PATTERNS = (INT)_countof(SearchPatterns);
 
     RtlInitUnicodeString(&Directory, L"\\SystemRoot\\Fonts\\");
-    /* FIXME: Add support for other font types */
-    RtlInitUnicodeString(&SearchPattern, L"*.ttf");
 
+    RtlInitUnicodeString(&SearchPatterns[0], L"*.ttf");
+    RtlInitUnicodeString(&SearchPatterns[1], L"*.ttc");
+    RtlInitUnicodeString(&SearchPatterns[2], L"*.otf");
+    RtlInitUnicodeString(&SearchPatterns[3], L"*.fon");
+    RtlInitUnicodeString(&SearchPatterns[4], L"*.fnt");
+
     InitializeObjectAttributes(
         &ObjectAttributes,
         &Directory,
@@ -252,198 +304,241 @@
 
     if (NT_SUCCESS(Status))
     {
-        DirInfoBuffer = ExAllocatePoolWithTag(PagedPool, 0x4000, TAG_FONT);
-        if (DirInfoBuffer == NULL)
+        for (I = 0; I < NUM_PATTERNS; ++I)
         {
-            ZwClose(hDirectory);
-            return;
-        }
+            DirInfoBuffer = ExAllocatePoolWithTag(PagedPool, 0x4000, TAG_FONT);
+            if (DirInfoBuffer == NULL)
+            {
+                ZwClose(hDirectory);
+                return;
+            }
 
-        FileName.Buffer = ExAllocatePoolWithTag(PagedPool, MAX_PATH * sizeof(WCHAR), TAG_FONT);
-        if (FileName.Buffer == NULL)
-        {
-            ExFreePoolWithTag(DirInfoBuffer, TAG_FONT);
-            ZwClose(hDirectory);
-            return;
-        }
-        FileName.Length = 0;
-        FileName.MaximumLength = MAX_PATH * sizeof(WCHAR);
-
-        while (1)
-        {
-            Status = ZwQueryDirectoryFile(
-                         hDirectory,
-                         NULL,
-                         NULL,
-                         NULL,
-                         &Iosb,
-                         DirInfoBuffer,
-                         0x4000,
-                         FileDirectoryInformation,
-                         FALSE,
-                         &SearchPattern,
-                         bRestartScan);
-
-            if (!NT_SUCCESS(Status) || Status == STATUS_NO_MORE_FILES)
+            FileName.Buffer = ExAllocatePoolWithTag(PagedPool, MAX_PATH * sizeof(WCHAR), TAG_FONT);
+            if (FileName.Buffer == NULL)
             {
-                break;
+                ExFreePoolWithTag(DirInfoBuffer, TAG_FONT);
+                ZwClose(hDirectory);
+                return;
             }
+            FileName.Length = 0;
+            FileName.MaximumLength = MAX_PATH * sizeof(WCHAR);
 
-            DirInfo = (PFILE_DIRECTORY_INFORMATION)DirInfoBuffer;
             while (1)
             {
-                TempString.Buffer = DirInfo->FileName;
-                TempString.Length =
-                    TempString.MaximumLength = DirInfo->FileNameLength;
-                RtlCopyUnicodeString(&FileName, &Directory);
-                RtlAppendUnicodeStringToString(&FileName, &TempString);
-                IntGdiAddFontResource(&FileName, 0);
-                if (DirInfo->NextEntryOffset == 0)
+                Status = ZwQueryDirectoryFile(
+                             hDirectory,
+                             NULL,
+                             NULL,
+                             NULL,
+                             &Iosb,
+                             DirInfoBuffer,
+                             0x4000,
+                             FileDirectoryInformation,
+                             FALSE,
+                             &SearchPatterns[I],
+                             bRestartScan);
+
+                if (!NT_SUCCESS(Status) || Status == STATUS_NO_MORE_FILES)
+                {
                     break;
-                DirInfo = (PFILE_DIRECTORY_INFORMATION)((ULONG_PTR)DirInfo + DirInfo->NextEntryOffset);
+                }
+
+                DirInfo = (PFILE_DIRECTORY_INFORMATION)DirInfoBuffer;
+                while (1)
+                {
+                    TempString.Buffer = DirInfo->FileName;
+                    TempString.Length =
+                        TempString.MaximumLength = DirInfo->FileNameLength;
+                    RtlCopyUnicodeString(&FileName, &Directory);
+                    RtlAppendUnicodeStringToString(&FileName, &TempString);
+                    IntGdiAddFontResource(&FileName, 0);
+                    if (DirInfo->NextEntryOffset == 0)
+                        break;
+                    DirInfo = (PFILE_DIRECTORY_INFORMATION)((ULONG_PTR)DirInfo + DirInfo->NextEntryOffset);
+                }
+
+                bRestartScan = FALSE;
             }
 
-            bRestartScan = FALSE;
+            ExFreePoolWithTag(FileName.Buffer, TAG_FONT);
+            ExFreePoolWithTag(DirInfoBuffer, TAG_FONT);
         }
-
-        ExFreePoolWithTag(FileName.Buffer, TAG_FONT);
-        ExFreePoolWithTag(DirInfoBuffer, TAG_FONT);
         ZwClose(hDirectory);
     }
 }
 
-
-/*
- * IntGdiAddFontResource
- *
- * Adds the font resource from the specified file to the system.
- */
-
-INT FASTCALL
-IntGdiAddFontResource(PUNICODE_STRING FileName, DWORD Characteristics)
+static INT FASTCALL
+IntGdiLoadFontsFromMemory(PUNICODE_STRING FileName, PVOID Buffer, ULONG BufferSize,
+                          PVOID SectionObject, DWORD Characteristics,
+                          PSHARED_FACE SharedFace, FT_Long FontIndex, INT CharSetIndex)
 {
-    FONTGDI *FontGDI;
-    NTSTATUS Status;
-    HANDLE FileHandle, KeyHandle;
-    OBJECT_ATTRIBUTES ObjectAttributes;
-    PVOID Buffer = NULL;
-    IO_STATUS_BLOCK Iosb;
-    INT Error;
-    FT_Face Face;
-    ANSI_STRING AnsiFaceName;
-    PFONT_ENTRY Entry;
-    PVOID SectionObject;
-    ULONG ViewSize = 0;
-    LARGE_INTEGER SectionSize;
-    UNICODE_STRING FontRegPath = RTL_CONSTANT_STRING(L"\\REGISTRY\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts");
+    FT_Error            Error;
+    PFONT_ENTRY         Entry;
+    FONTGDI *           FontGDI;
+    NTSTATUS            Status;
+    HANDLE              KeyHandle;
+    FT_Face             Face;
+    ANSI_STRING         AnsiFaceName;
+    ANSI_STRING         FaceNameA;
+    UNICODE_STRING      FaceNameW;
+    OBJECT_ATTRIBUTES   ObjectAttributes;
+    FT_WinFNT_HeaderRec WinFNT;
+    TT_OS2 *            pOS2;
+    INT                 Count = 0, CharSetCount = 0;
+    static const UNICODE_STRING MarlettW = RTL_CONSTANT_STRING(L"Marlett");
+    static UNICODE_STRING FontRegPath =
+        RTL_CONSTANT_STRING(L"\\REGISTRY\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts");
 
-    /* Open the font file */
-
-    InitializeObjectAttributes(&ObjectAttributes, FileName, 0, NULL, NULL);
-    Status = ZwOpenFile(
-                 &FileHandle,
-                 FILE_GENERIC_READ | SYNCHRONIZE,
-                 &ObjectAttributes,
-                 &Iosb,
-                 FILE_SHARE_READ,
-                 FILE_SYNCHRONOUS_IO_NONALERT);
-
-    if (!NT_SUCCESS(Status))
+    if (SharedFace == NULL && CharSetIndex == -1)
     {
-        DPRINT("Could not load font file: %wZ\n", FileName);
-        return 0;
-    }
+        /* load a face from memory */
+        IntLockFreeType;
+        Error = FT_New_Memory_Face(
+                    library,
+                    Buffer,
+                    BufferSize,
+                    ((FontIndex != -1) ? FontIndex : 0),
+                    &Face);
+        IntUnLockFreeType;
 
-    SectionSize.QuadPart = 0LL;
-    Status = MmCreateSection(&SectionObject, SECTION_ALL_ACCESS,
-                             NULL, &SectionSize, PAGE_READONLY,
-                             SEC_COMMIT, FileHandle, NULL);
-    if (!NT_SUCCESS(Status))
-    {
-        DPRINT("Could not map file: %wZ\n", FileName);
-        ZwClose(FileHandle);
-        return 0;
+        if (!Error)
+            SharedFace = SharedFace_Create(Face);
+        if (Error || SharedFace == NULL)
+        {
+            if (Error == FT_Err_Unknown_File_Format)
+                DPRINT("Unknown font file format\n");
+            else
+                DPRINT("Error reading font file (error code: %d)\n", Error);
+            if (SectionObject)
+                ObDereferenceObject(SectionObject);
+            return 0;   /* failure */
+        }
     }
-
-    ZwClose(FileHandle);
-
-    Status = MmMapViewInSystemSpace(SectionObject, &Buffer, &ViewSize);
-    if (!NT_SUCCESS(Status))
+    else
     {
-        DPRINT("Could not map file: %wZ\n", FileName);
-        ObDereferenceObject(SectionObject);
-        return 0;
+        Face = SharedFace->Face;
+        SharedFace_AddRef(SharedFace);
     }
 
-    IntLockFreeType;
-    Error = FT_New_Memory_Face(
-                library,
-                Buffer,
-                ViewSize,
-                0,
-                &Face);
-    IntUnLockFreeType;
-    ObDereferenceObject(SectionObject);
-
-    if (Error)
-    {
-        if (Error == FT_Err_Unknown_File_Format)
-            DPRINT("Unknown font file format\n");
-        else
-            DPRINT("Error reading font file (error code: %d)\n", Error);
-        return 0;
-    }
-
+    /* allocate a FONT_ENTRY */
     Entry = ExAllocatePoolWithTag(PagedPool, sizeof(FONT_ENTRY), TAG_FONT);
     if (!Entry)
     {
-        FT_Done_Face(Face);
+        SharedFace_Release(SharedFace);
         EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
-        return 0;
+        if (SectionObject)
+            ObDereferenceObject(SectionObject);
+        return 0;   /* failure */
     }
 
+    /* allocate a FONTGDI */
     FontGDI = EngAllocMem(FL_ZERO_MEMORY, sizeof(FONTGDI), GDITAG_RFONT);
     if (FontGDI == NULL)
     {
-        FT_Done_Face(Face);
+        SharedFace_Release(SharedFace);
         ExFreePoolWithTag(Entry, TAG_FONT);
         EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
-        return 0;
+        if (SectionObject)
+            ObDereferenceObject(SectionObject);
+        return 0;   /* failure */
     }
 
-    FontGDI->Filename = ExAllocatePoolWithTag(PagedPool, FileName->Length + sizeof(WCHAR), GDITAG_PFF);
+    /* set file name */
+    FontGDI->Filename = ExAllocatePoolWithTag(PagedPool,
+                                              FileName->Length + sizeof(WCHAR),
+                                              GDITAG_PFF);
     if (FontGDI->Filename == NULL)
     {
         EngFreeMem(FontGDI);
-        FT_Done_Face(Face);
+        SharedFace_Release(SharedFace);
         ExFreePoolWithTag(Entry, TAG_FONT);
         EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
-        return 0;
+        if (SectionObject)
+            ObDereferenceObject(SectionObject);
+        return 0;   /* failure */
     }
     RtlCopyMemory(FontGDI->Filename, FileName->Buffer, FileName->Length);
     FontGDI->Filename[FileName->Length / sizeof(WCHAR)] = L'\0';
-    FontGDI->face = Face;
 
+    /* set face */
+    FontGDI->SharedFace = SharedFace;
+    FontGDI->CharSet = ANSI_CHARSET;
+
+    /* check if Marlett */
+    RtlInitAnsiString(&FaceNameA, Face->family_name);
+    Status = RtlAnsiStringToUnicodeString(&FaceNameW, &FaceNameA, TRUE);
+    if (NT_SUCCESS(Status))
+    {
+        if (RtlEqualUnicodeString(&FaceNameW, &MarlettW, TRUE))
+        {
+            FontGDI->CharSet = SYMBOL_CHARSET;
+        }
+        RtlFreeUnicodeString(&FaceNameW);
+    }
+
+    if (FontGDI->CharSet == ANSI_CHARSET)
+    {
+        /* get charset from OS/2 header */
+        IntLockFreeType;
+        pOS2 = (TT_OS2 *)FT_Get_Sfnt_Table(Face, FT_SFNT_OS2);
+        IntUnLockFreeType;
+        if (pOS2 && pOS2->version >= 1)
+        {
+            INT BitIndex;
+            for (BitIndex = 0; BitIndex < MAXTCIINDEX; ++BitIndex)
+            {
+                if (pOS2->ulCodePageRange1 & (1 << BitIndex))
+                {
+                    if (FontTci[BitIndex].ciCharset == DEFAULT_CHARSET)
+                        continue;
+
+                    if ((CharSetIndex == -1 && CharSetCount == 0) ||
+                        CharSetIndex == CharSetCount)
+                    {
+                        FontGDI->CharSet = FontTci[BitIndex].ciCharset;
+                    }
+
+                    ++CharSetCount;
+                }
+            }
+        }
+        else
+        {
+            /* get charset from WinFNT header */
+            IntLockFreeType;
+            Error = FT_Get_WinFNT_Header(Face, &WinFNT);
+            IntUnLockFreeType;
+            if (!Error)
+            {
+                FontGDI->CharSet = WinFNT.charset;
+            }
+        }
+    }
+
+    ++Count;
     DPRINT("Font loaded: %s (%s)\n", Face->family_name, Face->style_name);
     DPRINT("Num glyphs: %d\n", Face->num_glyphs);
+    DPRINT("CharSet: %d\n", FontGDI->CharSet);
 
     /* Add this font resource to the font table */
-
     Entry->Font = FontGDI;
     Entry->NotEnum = (Characteristics & FR_NOT_ENUM);
-    RtlInitAnsiString(&AnsiFaceName, (LPSTR)Face->family_name);
+    RtlInitAnsiString(&AnsiFaceName, Face->family_name);
     Status = RtlAnsiStringToUnicodeString(&Entry->FaceName, &AnsiFaceName, TRUE);
     if (!NT_SUCCESS(Status))
     {
         ExFreePoolWithTag(FontGDI->Filename, GDITAG_PFF);
         EngFreeMem(FontGDI);
-        FT_Done_Face(Face);
+        SharedFace_Release(SharedFace);
         ExFreePoolWithTag(Entry, TAG_FONT);
+        if (SectionObject)
+            ObDereferenceObject(SectionObject);
         return 0;
     }
 
     if (Characteristics & FR_PRIVATE)
     {
+        /* private font */
         PPROCESSINFO Win32Process = PsGetCurrentProcessWin32Process();
         IntLockProcessPrivateFonts(Win32Process);
         InsertTailList(&Win32Process->PrivateFontListHead, &Entry->ListEntry);
@@ -451,25 +546,135 @@
     }
     else
     {
+        /* global font */
         IntLockGlobalFonts;
         InsertTailList(&FontListHead, &Entry->ListEntry);
-        InitializeObjectAttributes(&ObjectAttributes, &FontRegPath, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
+
+        /* registry */
+        /* FIXME: For *.ttc, please concatnate names by " & ". */
+        /* FIXME: For TrueType, please add " (TrueType)" to the end of name. */
+        /* NOTE: We can write registry later, not here */
+        InitializeObjectAttributes(&ObjectAttributes, &FontRegPath,
+                                   OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+                                   NULL, NULL);
         Status = ZwOpenKey(&KeyHandle, KEY_WRITE, &ObjectAttributes);
         if (NT_SUCCESS(Status))
         {
+            ULONG DataSize;
             LPWSTR pName = wcsrchr(FileName->Buffer, L'\\');
             if (pName)
             {
                 pName++;
-                ZwSetValueKey(KeyHandle, &Entry->FaceName, 0, REG_SZ, pName, (wcslen(pName) + 1) * sizeof(WCHAR));
+                DataSize = (wcslen(pName) + 1) * sizeof(WCHAR);
+                ZwSetValueKey(KeyHandle, &Entry->FaceName, 0, REG_SZ, pName, DataSize);
             }
             ZwClose(KeyHandle);
         }
         IntUnLockGlobalFonts;
     }
-    return 1;
+
+    if (FontIndex == -1)
+    {
+        if (FT_IS_SFNT(Face))
+        {
+            TT_Face TrueType = (TT_Face)Face;
+            if (TrueType->ttc_header.count > 1)
+            {
+                FT_Long I;
+                for (I = 1; I < TrueType->ttc_header.count; ++I)
+                {
+                    Count += IntGdiLoadFontsFromMemory(
+                        FileName, Buffer, BufferSize, NULL, Characteristics,
+                        NULL, I, -1);
+                }
+            }
+        }
+        FontIndex = 0;
+    }
+
+    if (CharSetIndex == -1)
+    {
+        INT I;
+        for (I = 1; I < CharSetCount; ++I)
+        {
+            Count += IntGdiLoadFontsFromMemory(
+                FileName, Buffer, BufferSize, NULL, Characteristics,
+                SharedFace, FontIndex, I);
+        }
+    }
+
+    if (SectionObject)
+    {
+        /* now release the section */
+        ObDereferenceObject(SectionObject);
+    }
+
+    return Count;   /* number of loaded fonts */
 }
 
+/*
+ * IntGdiAddFontResource
+ *
+ * Adds the font resource from the specified file to the system.
+ */
+
+INT FASTCALL
+IntGdiAddFontResource(PUNICODE_STRING FileName, DWORD Characteristics)
+{
+    NTSTATUS Status;
+    HANDLE FileHandle;
+    PVOID Buffer = NULL;
+    IO_STATUS_BLOCK Iosb;
+    PVOID SectionObject;
+    ULONG ViewSize = 0;
+    LARGE_INTEGER SectionSize;
+    OBJECT_ATTRIBUTES ObjectAttributes;
+
+    /* Open the font file */
+
+    InitializeObjectAttributes(&ObjectAttributes, FileName, 0, NULL, NULL);
+    Status = ZwOpenFile(
+                 &FileHandle,
+                 FILE_GENERIC_READ | SYNCHRONIZE,
+                 &ObjectAttributes,
+                 &Iosb,
+                 FILE_SHARE_READ,
+                 FILE_SYNCHRONOUS_IO_NONALERT);
+
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT("Could not load font file: %wZ\n", FileName);
+        return 0;
+    }
+
+    SectionSize.QuadPart = 0LL;
+    Status = MmCreateSection(&SectionObject, SECTION_ALL_ACCESS,
+                             NULL, &SectionSize, PAGE_READONLY,
+                             SEC_COMMIT, FileHandle, NULL);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT("Could not map file: %wZ\n", FileName);
+        ZwClose(FileHandle);
+        return 0;
+    }
+
+    ZwClose(FileHandle);
+
+    Status = MmMapViewInSystemSpace(SectionObject, &Buffer, &ViewSize);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT("Could not map file: %wZ\n", FileName);
+        ObDereferenceObject(SectionObject);
+        return 0;
+    }
+
+    return IntGdiLoadFontsFromMemory(FileName, Buffer, ViewSize,
+                                     SectionObject, Characteristics,
+                                     NULL, -1, -1);
+}
+
+// FIXME: Add RemoveFontResource
+
 BOOL FASTCALL
 IntIsFontRenderingEnabled(VOID)
 {
@@ -603,12 +808,13 @@
     return FALSE;
 }
 
+
 static void FASTCALL
 FillTM(TEXTMETRICW *TM, PFONTGDI FontGDI, TT_OS2 *pOS2, TT_HoriHeader *pHori, FT_WinFNT_HeaderRec *pWin)
 {
     FT_Fixed XScale, YScale;
     int Ascent, Descent;
-    FT_Face Face = FontGDI->face;
+    FT_Face Face = FontGDI->SharedFace->Face;
 
     XScale = Face->size->metrics.x_scale;
     YScale = Face->size->metrics.y_scale;
@@ -622,7 +828,7 @@
         TM->tmExternalLeading  = pWin->external_leading;
         TM->tmAveCharWidth     = pWin->avg_width;
         TM->tmMaxCharWidth     = pWin->max_width;
-        TM->tmWeight           = pWin->weight;
+        TM->tmWeight           = FontGDI->Weight;
         TM->tmOverhang         = 0;
         TM->tmDigitizedAspectX = pWin->horizontal_resolution;
         TM->tmDigitizedAspectY = pWin->vertical_resolution;
@@ -630,11 +836,11 @@
         TM->tmLastChar         = pWin->last_char;
         TM->tmDefaultChar      = pWin->default_char + pWin->first_char;
         TM->tmBreakChar        = pWin->break_char + pWin->first_char;
-        TM->tmItalic           = pWin->italic;
+        TM->tmItalic           = FontGDI->Italic;
         TM->tmUnderlined       = FontGDI->Underline;
         TM->tmStruckOut        = FontGDI->StrikeOut;
         TM->tmPitchAndFamily   = pWin->pitch_and_family;
-        TM->tmCharSet          = pWin->charset;
+        TM->tmCharSet          = FontGDI->CharSet;
         return;
     }
 
@@ -677,7 +883,7 @@
     /* Correct forumla to get the maxcharwidth from unicode and ansi font */
     TM->tmMaxCharWidth = (FT_MulFix(Face->max_advance_width, XScale) + 32) >> 6;
 
-    TM->tmWeight = pOS2->usWeightClass;
+    TM->tmWeight = FontGDI->Weight;
     TM->tmOverhang = 0;
     TM->tmDigitizedAspectX = 96;
     TM->tmDigitizedAspectY = 96;
@@ -711,14 +917,13 @@
             TM->tmBreakChar = pOS2->usFirstCharIndex;
         TM->tmDefaultChar = TM->tmBreakChar - 1;
     }
-    TM->tmItalic = (Face->style_flags & FT_STYLE_FLAG_ITALIC) ? 255 : 0;
+    TM->tmItalic = FontGDI->Italic;
     TM->tmUnderlined = FontGDI->Underline;
     TM->tmStruckOut  = FontGDI->StrikeOut;
 
-    /* Yes TPMF_FIXED_PITCH is correct; braindead api */
-    if (! FT_IS_FIXED_WIDTH(Face))
+    if (!FT_IS_FIXED_WIDTH(Face))
     {
-        TM->tmPitchAndFamily = TMPF_FIXED_PITCH;
+        TM->tmPitchAndFamily = _TMPF_VARIABLE_PITCH;
     }
     else
     {
@@ -788,7 +993,7 @@
         TM->tmPitchAndFamily |= TMPF_TRUETYPE;
     }
 
-    TM->tmCharSet = DEFAULT_CHARSET;
+    TM->tmCharSet = FontGDI->CharSet;
 }
 
 /*************************************************************
@@ -811,10 +1016,11 @@
     FT_Error Error;
     char *Cp;
     NTSTATUS status;
+    FT_Face Face = FontGDI->SharedFace->Face;
 
     Needed = sizeof(OUTLINETEXTMETRICW);
 
-    RtlInitAnsiString(&FamilyNameA, FontGDI->face->family_name);
+    RtlInitAnsiString(&FamilyNameA, Face->family_name);
     status = RtlAnsiStringToUnicodeString(&FamilyNameW, &FamilyNameA, TRUE);
     if (!NT_SUCCESS(status))
     {
@@ -821,7 +1027,7 @@
         return 0;
     }
 
-    RtlInitAnsiString(&StyleNameA, FontGDI->face->style_name);
+    RtlInitAnsiString(&StyleNameA, Face->style_name);
     status = RtlAnsiStringToUnicodeString(&StyleNameW, &StyleNameA, TRUE);
     if (!NT_SUCCESS(status))
     {
@@ -836,7 +1042,7 @@
 
     RtlInitUnicodeString(&Regular, L"regular");
     /* Length of otmpFaceName */
-    if (0 == RtlCompareUnicodeString(&StyleNameW, &Regular, TRUE))
+    if (RtlEqualUnicodeString(&StyleNameW, &Regular, TRUE))
     {
         Needed += FamilyNameW.Length + sizeof(WCHAR); /* Just the family name */
     }
@@ -858,11 +1064,11 @@
         return Needed;
     }
 
-    XScale = FontGDI->face->size->metrics.x_scale;
-    YScale = FontGDI->face->size->metrics.y_scale;
+    XScale = Face->size->metrics.x_scale;
+    YScale = Face->size->metrics.y_scale;
 
     IntLockFreeType;
-    pOS2 = FT_Get_Sfnt_Table(FontGDI->face, ft_sfnt_os2);
+    pOS2 = FT_Get_Sfnt_Table(Face, ft_sfnt_os2);
     if (NULL == pOS2)
     {
         IntUnLockFreeType;
@@ -872,7 +1078,7 @@
         return 0;
     }
 
-    pHori = FT_Get_Sfnt_Table(FontGDI->face, ft_sfnt_hhea);
+    pHori = FT_Get_Sfnt_Table(Face, ft_sfnt_hhea);
     if (NULL == pHori)
     {
         IntUnLockFreeType;
@@ -882,9 +1088,9 @@
         return 0;
     }
 
-    pPost = FT_Get_Sfnt_Table(FontGDI->face, ft_sfnt_post); /* We can live with this failing */
+    pPost = FT_Get_Sfnt_Table(Face, ft_sfnt_post); /* We can live with this failing */
 
-    Error = FT_Get_WinFNT_Header(FontGDI->face , &Win);
+    Error = FT_Get_WinFNT_Header(Face , &Win);
 
     Otm->otmSize = Needed;
 
@@ -897,16 +1103,16 @@
     Otm->otmsCharSlopeRise = pHori->caret_Slope_Rise;
     Otm->otmsCharSlopeRun = pHori->caret_Slope_Run;
     Otm->otmItalicAngle = 0; /* POST table */
-    Otm->otmEMSquare = FontGDI->face->units_per_EM;
+    Otm->otmEMSquare = Face->units_per_EM;
     Otm->otmAscent = (FT_MulFix(pOS2->sTypoAscender, YScale) + 32) >> 6;
     Otm->otmDescent = (FT_MulFix(pOS2->sTypoDescender, YScale) + 32) >> 6;
     Otm->otmLineGap = (FT_MulFix(pOS2->sTypoLineGap, YScale) + 32) >> 6;
     Otm->otmsCapEmHeight = (FT_MulFix(pOS2->sCapHeight, YScale) + 32) >> 6;
     Otm->otmsXHeight = (FT_MulFix(pOS2->sxHeight, YScale) + 32) >> 6;
-    Otm->otmrcFontBox.left = (FT_MulFix(FontGDI->face->bbox.xMin, XScale) + 32) >> 6;
-    Otm->otmrcFontBox.right = (FT_MulFix(FontGDI->face->bbox.xMax, XScale) + 32) >> 6;
-    Otm->otmrcFontBox.top = (FT_MulFix(FontGDI->face->bbox.yMax, YScale) + 32) >> 6;
-    Otm->otmrcFontBox.bottom = (FT_MulFix(FontGDI->face->bbox.yMin, YScale) + 32) >> 6;
+    Otm->otmrcFontBox.left = (FT_MulFix(Face->bbox.xMin, XScale) + 32) >> 6;
+    Otm->otmrcFontBox.right = (FT_MulFix(Face->bbox.xMax, XScale) + 32) >> 6;
+    Otm->otmrcFontBox.top = (FT_MulFix(Face->bbox.yMax, YScale) + 32) >> 6;
+    Otm->otmrcFontBox.bottom = (FT_MulFix(Face->bbox.yMin, YScale) + 32) >> 6;
     Otm->otmMacAscent = Otm->otmTextMetrics.tmAscent;
     Otm->otmMacDescent = -Otm->otmTextMetrics.tmDescent;
     Otm->otmMacLineGap = Otm->otmLineGap;
@@ -944,7 +1150,7 @@
     Cp += StyleNameW.Length + sizeof(WCHAR);
     Otm->otmpFaceName = (LPSTR)(Cp - (char*) Otm);
     wcscpy((WCHAR*) Cp, FamilyNameW.Buffer);
-    if (0 != RtlCompareUnicodeString(&StyleNameW, &Regular, TRUE))
+    if (!RtlEqualUnicodeString(&StyleNameW, &Regular, TRUE))
     {
         wcscat((WCHAR*) Cp, L" ");
         wcscat((WCHAR*) Cp, StyleNameW.Buffer);
@@ -983,7 +1189,7 @@
         FontGDI = CurrentEntry->Font;
         ASSERT(FontGDI);
 
-        RtlInitAnsiString(&EntryFaceNameA, FontGDI->face->family_name);
+        RtlInitAnsiString(&EntryFaceNameA, FontGDI->SharedFace->Face->family_name);
         status = RtlAnsiStringToUnicodeString(&EntryFaceNameW, &EntryFaceNameA, TRUE);
         if (!NT_SUCCESS(status))
         {
@@ -996,7 +1202,7 @@
             EntryFaceNameW.Buffer[LF_FACESIZE - 1] = L'\0';
         }
 
-        if (0 == RtlCompareUnicodeString(FaceName, &EntryFaceNameW, TRUE))
+        if (RtlEqualUnicodeString(FaceName, &EntryFaceNameW, TRUE))
         {
             RtlFreeUnicodeString(&EntryFaceNameW);
             return FontGDI;
@@ -1048,6 +1254,7 @@
     NEWTEXTMETRICW *Ntm;
     DWORD fs0;
     NTSTATUS status;
+    FT_Face Face = FontGDI->SharedFace->Face;
 
     RtlZeroMemory(Info, sizeof(FONTFAMILYINFO));
     Size = IntGetOutlineTextMetrics(FontGDI, 0, NULL);
@@ -1116,7 +1323,7 @@
     RtlStringCbCopyW(Info->EnumLogFontEx.elfFullName,
                      sizeof(Info->EnumLogFontEx.elfFullName),
                      FaceName);
-    RtlInitAnsiString(&StyleA, FontGDI->face->style_name);
+    RtlInitAnsiString(&StyleA, Face->style_name);
     StyleW.Buffer = Info->EnumLogFontEx.elfStyle;
     StyleW.MaximumLength = sizeof(Info->EnumLogFontEx.elfStyle);
     status = RtlAnsiStringToUnicodeString(&StyleW, &StyleA, FALSE);
@@ -1128,7 +1335,7 @@
     Info->EnumLogFontEx.elfLogFont.lfCharSet = DEFAULT_CHARSET;
     Info->EnumLogFontEx.elfScript[0] = L'\0';
     IntLockFreeType;
-    pOS2 = FT_Get_Sfnt_Table(FontGDI->face, ft_sfnt_os2);
+    pOS2 = FT_Get_Sfnt_Table(Face, ft_sfnt_os2);
     IntUnLockFreeType;
     if (NULL != pOS2)
     {
@@ -1143,7 +1350,7 @@
         {
             FT_UInt Dummy;
 
-            if (FT_Get_First_Char(FontGDI->face, &Dummy) < 0x100)
+            if (FT_Get_First_Char(Face, &Dummy) < 0x100)
                 fs.fsCsb[0] |= FS_LATIN1;
             else
                 fs.fsCsb[0] |= FS_SYMBOL;
@@ -1150,9 +1357,9 @@
         }
         if (fs.fsCsb[0] == 0)
         { /* Let's see if we can find any interesting cmaps */
-            for (i = 0; i < (UINT)FontGDI->face->num_charmaps; i++)
+            for (i = 0; i < (UINT)Face->num_charmaps; i++)
             {
-                switch (FontGDI->face->charmaps[i]->encoding)
+                switch (Face->charmaps[i]->encoding)
                 {
                 case FT_ENCODING_UNICODE:
                 case FT_ENCODING_APPLE_ROMAN:
@@ -1200,7 +1407,7 @@
     for (i = 0; i < InfoEntries; i++)
     {
         RtlInitUnicodeString(&InfoFaceName, Info[i].EnumLogFontEx.elfLogFont.lfFaceName);
-        if (0 == RtlCompareUnicodeString(&InfoFaceName, FaceName, TRUE))
+        if (RtlEqualUnicodeString(&InfoFaceName, FaceName, TRUE))
         {
             return i;
         }
@@ -1216,8 +1423,8 @@
     UNICODE_STRING LogFontFaceName;
 
     RtlInitUnicodeString(&LogFontFaceName, LogFont->lfFaceName);
-    if (0 != LogFontFaceName.Length
-            && 0 != RtlCompareUnicodeString(&LogFontFaceName, FaceName, TRUE))
+    if (0 != LogFontFaceName.Length &&
+        !RtlEqualUnicodeString(&LogFontFaceName, FaceName, TRUE))
     {
         return FALSE;
     }
@@ -1247,7 +1454,7 @@
         FontGDI = CurrentEntry->Font;
         ASSERT(FontGDI);
 
-        RtlInitAnsiString(&EntryFaceNameA, FontGDI->face->family_name);
+        RtlInitAnsiString(&EntryFaceNameA, FontGDI->SharedFace->Face->family_name);
         status = RtlAnsiStringToUnicodeString(&EntryFaceNameW, &EntryFaceNameA, TRUE);
         if (!NT_SUCCESS(status))
         {
@@ -1802,7 +2009,7 @@
         return GDI_ERROR;
     }
     FontGDI = ObjToGDI(TextObj->Font, FONT);
-    ft_face = FontGDI->face;
+    ft_face = FontGDI->SharedFace->Face;
 
     aveWidth = FT_IS_SCALABLE(ft_face) ? TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfWidth: 0;
     orientation = FT_IS_SCALABLE(ft_face) ? TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfOrientation: 0;
@@ -2271,7 +2478,7 @@
 
     FontGDI = ObjToGDI(TextObj->Font, FONT);
 
-    face = FontGDI->face;
+    face = FontGDI->SharedFace->Face;
     if (NULL != Fit)
     {
         *Fit = 0;
@@ -2424,7 +2631,7 @@
         return Ret;
     }
     FontGdi = ObjToGDI(TextObj->Font, FONT);
-    Face = FontGdi->face;
+    Face = FontGdi->SharedFace->Face;
     TEXTOBJ_UnlockText(TextObj);
 
     IntLockFreeType;
@@ -2512,7 +2719,7 @@
 {
     DWORD size = 0;
     DWORD num_ranges = 0;
-    FT_Face face = Font->face;
+    FT_Face face = Font->SharedFace->Face;
 
     if (face->charmap->encoding == FT_ENCODING_UNICODE)
     {
@@ -2608,7 +2815,7 @@
     {
         FontGDI = ObjToGDI(TextObj->Font, FONT);
 
-        Face = FontGDI->face;
+        Face = FontGDI->SharedFace->Face;
         IntLockFreeType;
         Error = FT_Set_Pixel_Sizes(Face,
                                    TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfWidth,
@@ -2624,10 +2831,11 @@
         }
         else
         {
+            FT_Face Face = FontGDI->SharedFace->Face;
             Status = STATUS_SUCCESS;
 
             IntLockFreeType;
-            pOS2 = FT_Get_Sfnt_Table(FontGDI->face, ft_sfnt_os2);
+            pOS2 = FT_Get_Sfnt_Table(Face, ft_sfnt_os2);
             if (NULL == pOS2)
             {
                 DPRINT1("Can't find OS/2 table - not TT font?\n");
@@ -2634,7 +2842,7 @@
                 Status = STATUS_INTERNAL_ERROR;
             }
 
-            pHori = FT_Get_Sfnt_Table(FontGDI->face, ft_sfnt_hhea);
+            pHori = FT_Get_Sfnt_Table(Face, ft_sfnt_hhea);
             if (NULL == pHori)
             {
                 DPRINT1("Can't find HHEA table - not TT font?\n");
@@ -2641,7 +2849,7 @@
                 Status = STATUS_INTERNAL_ERROR;
             }
 
-            Error = FT_Get_WinFNT_Header(FontGDI->face , &Win);
+            Error = FT_Get_WinFNT_Header(Face, &Win);
 
             IntUnLockFreeType;
 
@@ -2680,10 +2888,11 @@
     DWORD Size)
 {
     DWORD Result = GDI_ERROR;
+    FT_Face Face = FontGdi->SharedFace->Face;
 
     IntLockFreeType;
 
-    if (FT_IS_SFNT(FontGdi->face))
+    if (FT_IS_SFNT(Face))
     {
         if (Table)
             Table = Table >> 24 | Table << 24 | (Table >> 8 & 0xFF00) |
@@ -2696,11 +2905,11 @@
             FT_Error Error;
             FT_ULong Needed = 0;
 
-            Error = FT_Load_Sfnt_Table(FontGdi->face, Table, Offset, NULL, &Needed);
+            Error = FT_Load_Sfnt_Table(Face, Table, Offset, NULL, &Needed);
 
             if ( !Error && Needed < Size) Size = Needed;
         }
-        if (!FT_Load_Sfnt_Table(FontGdi->face, Table, Offset, Buffer, &Size))
+        if (!FT_Load_Sfnt_Table(Face, Table, Offset, Buffer, &Size))
             Result = Size;
     }
 
@@ -2709,172 +2918,415 @@
     return Result;
 }
 
-static UINT FASTCALL
-GetFontScore(LOGFONTW *LogFont, PUNICODE_STRING FaceName, PFONTGDI FontGDI)
+static __inline BOOLEAN
+SubstituteFontNameByKey(PUNICODE_STRING FaceName,
+                        LPCWSTR Key)
 {
-    ANSI_STRING EntryFaceNameA;
-    UNICODE_STRING EntryFaceNameW;
-    unsigned Size;
-    OUTLINETEXTMETRICW *Otm;
-    LONG WeightDiff;
+    RTL_QUERY_REGISTRY_TABLE QueryTable[2] = {{0}};
     NTSTATUS Status;
-    UINT Score = 1;
+    UNICODE_STRING Value;
 
-    RtlInitAnsiString(&EntryFaceNameA, FontGDI->face->family_name);
-    Status = RtlAnsiStringToUnicodeString(&EntryFaceNameW, &EntryFaceNameA, TRUE);
+    RtlInitUnicodeString(&Value, NULL);
+
+    QueryTable[0].QueryRoutine = NULL;
+    QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_NOEXPAND |
+                          RTL_QUERY_REGISTRY_REQUIRED;
+    QueryTable[0].Name = FaceName->Buffer;
+    QueryTable[0].EntryContext = &Value;
+    QueryTable[0].DefaultType = REG_NONE;
+    QueryTable[0].DefaultData = NULL;
+    QueryTable[0].DefaultLength = 0;
+
+    QueryTable[1].QueryRoutine = NULL;
+    QueryTable[1].Name = NULL;
+
+    Status = RtlQueryRegistryValues(RTL_REGISTRY_WINDOWS_NT,
+                                    Key,
+                                    QueryTable,
+                                    NULL,
+                                    NULL);
     if (NT_SUCCESS(Status))
     {
-        static const UNICODE_STRING MarlettFaceNameW = RTL_CONSTANT_STRING(L"Marlett");
-        static const UNICODE_STRING SymbolFaceNameW = RTL_CONSTANT_STRING(L"Symbol");
-        static const UNICODE_STRING VGAFaceNameW = RTL_CONSTANT_STRING(L"VGA");
+        RtlFreeUnicodeString(FaceName);
+        *FaceName = Value;
 
-        if ((LF_FACESIZE - 1) * sizeof(WCHAR) < EntryFaceNameW.Length)
+        /* truncate */
+        if ((LF_FACESIZE - 1) * sizeof(WCHAR) < FaceName->Length)
         {
-            EntryFaceNameW.Length = (LF_FACESIZE - 1) * sizeof(WCHAR);
-            EntryFaceNameW.Buffer[LF_FACESIZE - 1] = L'\0';
+            FaceName->Length = (LF_FACESIZE - 1) * sizeof(WCHAR);
+            FaceName->Buffer[LF_FACESIZE - 1] = L'\0';
         }
+    }
 
-        if (!RtlCompareUnicodeString(FaceName, &EntryFaceNameW, TRUE))
+    return NT_SUCCESS(Status);
+}
+
+static __inline void
+SubstituteFontName(PUNICODE_STRING FaceName)
+{
+    UINT Level;
+    const UINT MaxLevel = 10;
+
+    if (FaceName->Buffer[0] == 0)
+        return;
+
+    for (Level = 0; Level < MaxLevel; ++Level)
+    {
+        /* NOTE: SubstituteFontNameByKey changes FaceName. Be careful... */
+        if (!SubstituteFontNameByKey(FaceName, L"FontSubstitutes"))
+            break;
+    }
+}
+
+static BYTE
+CharSetFromLangID(LANGID LangID)
+{
+    LangID = PRIMARYLANGID(LangID);
+    switch (LangID)
+    {
+        case LANG_ARABIC: return ARABIC_CHARSET;
+        case LANG_CHINESE:
+            switch (SUBLANGID(LangID))
+            {
+                case SUBLANG_CHINESE_SIMPLIFIED:
+                    return GB2312_CHARSET;
+                case SUBLANG_CHINESE_TRADITIONAL:
+                    return CHINESEBIG5_CHARSET;
+            }
+            break;
+        case LANG_ENGLISH: return ANSI_CHARSET;
+        case LANG_GREEK: return GREEK_CHARSET;
+        case LANG_HEBREW: return HEBREW_CHARSET;
+        case LANG_JAPANESE: return SHIFTJIS_CHARSET;
+        case LANG_KOREAN: return HANGUL_CHARSET;
+        case LANG_RUSSIAN:
+        case LANG_BULGARIAN:
+        case LANG_MACEDONIAN:
+        case LANG_SERBIAN:
+        case LANG_UKRAINIAN:
+            return RUSSIAN_CHARSET;
+        case LANG_CZECH:
+        case LANG_HUNGARIAN:
+        case LANG_POLISH:
+        case LANG_ROMANIAN:
+        case LANG_SLOVAK:
+        case LANG_SLOVENIAN:
+            return EASTEUROPE_CHARSET;
+        case LANG_THAI: return THAI_CHARSET;
+        case LANG_LATVIAN: return BALTIC_CHARSET;
+        case LANG_TURKISH: return TURKISH_CHARSET;
+        case LANG_VIETNAMESE: return VIETNAMESE_CHARSET;
+        /* FIXME: Add more and fix if wrong */
+        default: break;
+    }
+    return ANSI_CHARSET;
+}
+
+static UINT FASTCALL
+GetFontPenalty(LOGFONTW *               LogFont,
+               PUNICODE_STRING          RequestedNameW,
+               PUNICODE_STRING          ActualNameW,
+               PFONTGDI                 FontGDI,
+               OUTLINETEXTMETRICW *     Otm,
+               TEXTMETRICW *            TM)
+{
+    ULONG   Penalty = 0;
+    BYTE    Byte;
+    static const UNICODE_STRING SystemW = RTL_CONSTANT_STRING(L"System");
+
+    // is request "System" font?
+    if (RtlEqualUnicodeString(RequestedNameW, &SystemW, TRUE))
+    {
+        /* Penalty += 65000: lfCharSet: not current charset */
+        if (TM->tmCharSet != CharSetFromLangID(gusLanguageID))
+            Penalty += 65000;
+
+        /* Penalty += 10: system font should be fixed-pitch */
+        if (TM->tmPitchAndFamily & _TMPF_VARIABLE_PITCH)
+            Penalty += 10;
+    }
+    else    /* Request is non-"System" font */
+    {
+        if (LogFont->lfCharSet != DEFAULT_CHARSET &&
+            LogFont->lfCharSet != ANSI_CHARSET)
         {
-            Score += 49;
+            /* Penalty += 65000: lfCharSet: mismatched */
+            if (LogFont->lfCharSet != TM->tmCharSet)
+                Penalty += 65000;
         }
+    }
 
-        /* FIXME: this is a work around to counter weird fonts on weird places.
-           A proper fix would be to score fonts on more attributes than
-           the ones in this function */
-        if (!RtlCompareUnicodeString(&MarlettFaceNameW, &EntryFaceNameW, TRUE) &&
-            RtlCompareUnicodeString(&MarlettFaceNameW, FaceName, TRUE))
+    /* if face name is set */
+    if (RequestedNameW->Buffer[0])
+    {
+        if (!RtlEqualUnicodeString(RequestedNameW, ActualNameW, TRUE))
         {
-            Score = 0;
+            /* Penalty += 10000: lfFaceName: mismatched */
+            Penalty += 10000;
         }
+    }
 
-        if (!RtlCompareUnicodeString(&SymbolFaceNameW, &EntryFaceNameW, TRUE) &&
-            RtlCompareUnicodeString(&SymbolFaceNameW, FaceName, TRUE))
+    /* Penalty += 19000: lfOutPrecision: mismatched */
+    if (LogFont->lfOutPrecision != OUT_DEFAULT_PRECIS)
+    {
+        switch (LogFont->lfOutPrecision)
         {
-            Score = 0;
+            case OUT_DEVICE_PRECIS:
+                if (!(TM->tmPitchAndFamily & TMPF_DEVICE))
+                    Penalty += 19000;
+                break;
+            case OUT_TT_ONLY_PRECIS:
+                if (!(TM->tmPitchAndFamily & TMPF_TRUETYPE))
+                    Penalty += 19000;
+                break;
+            default:
+                break;
         }
+    }
 
-        if (!RtlCompareUnicodeString(&VGAFaceNameW, &EntryFaceNameW, TRUE) &&
-            RtlCompareUnicodeString(&VGAFaceNameW, FaceName, TRUE))
+    /* get the pitch */
+    Byte = (LogFont->lfPitchAndFamily & 0x0F);
+    if (Byte != DEFAULT_PITCH)
+    {
+        if (Byte == FIXED_PITCH)
         {
-            Score = 0;
+            /* Penalty += 15000: lfPitchAndFamily: variable pitch was set on fixed-pitch specified */
+            if (TM->tmPitchAndFamily & _TMPF_VARIABLE_PITCH)
+            {
+                Penalty += 15000;
+            }
         }
-
-        RtlFreeUnicodeString(&EntryFaceNameW);
+        /* Penalty += 350: lfPitchAndFamily: non-variable pitch on variable pitch */
+        if (Byte == VARIABLE_PITCH && !(TM->tmPitchAndFamily & _TMPF_VARIABLE_PITCH))
+        {
+            Penalty += 350;
+        }
     }
+    else
+    {
+        /* Penalty += 1: pitch is not normal */
+        if (!(TM->tmPitchAndFamily & _TMPF_VARIABLE_PITCH))
+        {
+            Penalty += 1;
+        }
+    }
 
-    Size = IntGetOutlineTextMetrics(FontGDI, 0, NULL);
-    Otm = ExAllocatePoolWithTag(PagedPool, Size, GDITAG_TEXT);
-    if (NULL == Otm)
+    /* get family */
+    Byte = (LogFont->lfPitchAndFamily & 0xF0);
+    if (Byte != FF_DONTCARE)
     {
-        return Score;
+        /* Penalty += 9000: lfPitchAndFamily: mismatched font family */
+        if (Byte != (TM->tmPitchAndFamily & 0xF0))
+        {
+            Penalty += 9000;
+        }
+        /* Penalty += 8000: lfPitchAndFamily: no family on family specified */
+        if ((TM->tmPitchAndFamily & 0xF0) == FF_DONTCARE)
+        {
+            Penalty += 8000;
+        }
     }
-    IntGetOutlineTextMetrics(FontGDI, Size, Otm);
 
-    if ((0 != LogFont->lfItalic && 0 != Otm->otmTextMetrics.tmItalic) ||
-            (0 == LogFont->lfItalic && 0 == Otm->otmTextMetrics.tmItalic))
+    /* if the target is not scalable */
+    if (!(TM->tmPitchAndFamily & (TMPF_TRUETYPE | TMPF_VECTOR)))
     {
-        Score += 25;
+        if (LogFont->lfHeight != 0)
+        {
+            /* Penalty += 600: lfHeight: non-vector font and height was higher */
+            if (labs(LogFont->lfHeight) < TM->tmHeight)
+            {
+                Penalty += 600;
+            }
+            /* Penalty += 600: lfHeight: non-vector font and height was higher */
+            if (LogFont->lfHeight < 0 && labs(LogFont->lfHeight) < TM->tmHeight)
+            {
+                Penalty += 600;
+            }
+            /* Penalty += 150 * Diff * K: lfHeight: mismatched */
+            if (labs(LogFont->lfHeight) != TM->tmHeight)
+            {
+                double K = 2;
+                /* lfHeight: avg. 16. */
+                /* 16 * K = 32. */
+                if (labs(LogFont->lfHeight) != TM->tmHeight)
+                {
+                    LONG Diff = labs(labs(LogFont->lfHeight) - TM->tmHeight);
+                    Penalty += (150 * Diff) * K;
+                }
+            }
+        }
+
+        /* Penalty += 50: height or width scaling required */
+        if ((LogFont->lfHeight != 0 && labs(LogFont->lfHeight) != TM->tmHeight) ||
+            (LogFont->lfWidth != 0 && LogFont->lfWidth != TM->tmAveCharWidth))
+        {
+            Penalty += 50;
+        }
+
+        /* Penalty += 50 * Diff * K: mismatched width */
+        if (LogFont->lfWidth != 0 && LogFont->lfWidth != TM->tmAveCharWidth)
+        {
+            double K = 0.2;
+            /* lfWidth: avg. 16. */
+            /* 16 * K = 3.2. */
+            if (LogFont->lfWidth != TM->tmAveCharWidth)
+            {
+                LONG Diff = labs(TM->tmAveCharWidth - LogFont->lfWidth);
+                Penalty += (50 * Diff) * K;
+            }
+        }
+
+        /* Penalty += 1: it needs to be adjusted to italic */
+        if (LogFont->lfItalic && !TM->tmItalic)
+        {
+            Penalty += 1;
+        }
+        /* Penalty += 1: it needs to be adjusted to underline */
+        if (LogFont->lfUnderline && !TM->tmUnderlined)
+        {
+            Penalty += 1;
+        }
+        /* Penalty += 1: it needs to be adjusted to struke-out */
+        if (LogFont->lfStrikeOut && !TM->tmStruckOut)
+        {
+            Penalty += 1;
+        }
     }
+
     if (LogFont->lfWeight != FW_DONTCARE)
     {
-        if (LogFont->lfWeight < Otm->otmTextMetrics.tmWeight)
+        /* Penalty += 3 * Diff * K: lfWeight: weight mismatched */
+        /* lfWeight: 100 to 900 */
+        double K = 0.5;
+        /* K * 300 * 3 = 450 */
+        if (LogFont->lfWeight != TM->tmWeight)
         {
-            WeightDiff = Otm->otmTextMetrics.tmWeight - LogFont->lfWeight;
+            LONG Diff = labs(LogFont->lfWeight - TM->tmWeight);
+            Penalty += (3 * Diff) * K;
         }
-        else
+    }
+    else
+    {
+        /* Penalty += 100: lfWeight: weight is not normal */
+        if (TM->tmWeight != FW_NORMAL)
         {
-            WeightDiff = LogFont->lfWeight - Otm->otmTextMetrics.tmWeight;
+            Penalty += 100;
         }
-        Score += (1000 - WeightDiff) / (1000 / 25);
     }
-    else
+
+    /* Penalty += 4: lfItalic: mismatched */
+    if (!!LogFont->lfItalic != !!TM->tmItalic)
     {
-        Score += 25;
+        Penalty += 4;
     }
+    /* Penalty += 4: lfUnderline: mismatched */
+    if (!!LogFont->lfUnderline != !!TM->tmUnderlined)
+    {
+        Penalty += 4;
+    }
+    /* Penalty += 4: lfStrikeOut: mismatched */
+    if (!!LogFont->lfStrikeOut != !!TM->tmStruckOut)
+    {
+        Penalty += 4;
+    }
 
-    ExFreePoolWithTag(Otm, GDITAG_TEXT);
+    /* Penalty += 4: lfOutPrecision: non-TrueType on TrueType specified */
+    if (LogFont->lfOutPrecision == OUT_TT_PRECIS)
+    {
+        if (!(TM->tmPitchAndFamily & TMPF_TRUETYPE))
+            Penalty += 4;
+    }
 
-    return Score;
+    /* Penalty += 2: not device font */
+    if (!(TM->tmPitchAndFamily & TMPF_DEVICE))
+    {
+        Penalty += 2;
+    }
+
+    if (Penalty < 500)
+    {
+        DPRINT("'%ls' -> '%ls' Penalty:%d, lfCharSet:%d, tmCharSet:%d, lfWeight:%d, tmWeight:%d\n",
+            RequestedNameW->Buffer, ActualNameW->Buffer, Penalty,
+            LogFont->lfCharSet, TM->tmCharSet, LogFont->lfWeight, TM->tmWeight);
+    }
+
+    return Penalty;     /* success */
 }
 
 static __inline VOID
-FindBestFontFromList(FONTOBJ **FontObj, UINT *MatchScore, LOGFONTW *LogFont,
-                     PUNICODE_STRING FaceName, PLIST_ENTRY Head)
+FindBestFontFromList(FONTOBJ **FontObj, ULONG *MatchPenalty, LOGFONTW *LogFont,
+                     PUNICODE_STRING pRequestedNameW,
+                     PUNICODE_STRING pActualNameW, PLIST_ENTRY Head)
 {
+    ULONG Penalty;
+    NTSTATUS Status;
     PLIST_ENTRY Entry;
     PFONT_ENTRY CurrentEntry;
     FONTGDI *FontGDI;
-    UINT Score;
-ASSERT(FontObj && MatchScore && LogFont && FaceName && Head);
+    ANSI_STRING ActualNameA;
+    UNICODE_STRING ActualNameW;
+    OUTLINETEXTMETRICW *Otm = NULL;
+    UINT OtmSize, OldOtmSize = 0;
+    TEXTMETRICW *TM;
+
+    ASSERT(FontObj && MatchPenalty && LogFont && pRequestedNameW && Head);
+
+    /* get the FontObj of lowest penalty */
     Entry = Head->Flink;
     while (Entry != Head)
     {
         CurrentEntry = (PFONT_ENTRY) CONTAINING_RECORD(Entry, FONT_ENTRY, ListEntry);
-
         FontGDI = CurrentEntry->Font;
         ASSERT(FontGDI);
 
-        Score = GetFontScore(LogFont, FaceName, FontGDI);
-        if (*MatchScore == 0 || *MatchScore < Score)
+        /* create actual name */
+        RtlInitAnsiString(&ActualNameA, FontGDI->SharedFace->Face->family_name);
+        Status = RtlAnsiStringToUnicodeString(&ActualNameW, &ActualNameA, TRUE);
+        if (!NT_SUCCESS(Status))
         {
-            *FontObj = GDIToObj(FontGDI, FONT);
-            *MatchScore = Score;
+            /* next entry */
+            Entry = Entry->Flink;
+            continue;
         }
-        Entry = Entry->Flink;
-    }
-}
 
-static __inline BOOLEAN
-SubstituteFontFamilyKey(PUNICODE_STRING FaceName,
-                        LPCWSTR Key)
-{
-    RTL_QUERY_REGISTRY_TABLE QueryTable[2] = {{0}};
-    NTSTATUS Status;
-    UNICODE_STRING Value;
+        /* get text metrics */
+        OtmSize = IntGetOutlineTextMetrics(FontGDI, 0, NULL);
+        if (OtmSize > OldOtmSize)
+        {
+            if (Otm)
+                ExFreePoolWithTag(Otm, GDITAG_TEXT);
+            Otm = ExAllocatePoolWithTag(PagedPool, OtmSize, GDITAG_TEXT);
+        }
 
-    RtlInitUnicodeString(&Value, NULL);
+        /* update FontObj if lowest penalty */
+        if (Otm)
+        {
+            IntGetOutlineTextMetrics(FontGDI, OtmSize, Otm);
+            TM = &Otm->otmTextMetrics;
+            OldOtmSize = OtmSize;
 
-    QueryTable[0].QueryRoutine = NULL;
-    QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_NOEXPAND |
-                          RTL_QUERY_REGISTRY_REQUIRED;
-    QueryTable[0].Name = FaceName->Buffer;
-    QueryTable[0].EntryContext = &Value;
-    QueryTable[0].DefaultType = REG_NONE;
-    QueryTable[0].DefaultData = NULL;
-    QueryTable[0].DefaultLength = 0;
+            Penalty = GetFontPenalty(LogFont, pRequestedNameW, &ActualNameW,
+                                     FontGDI, Otm, TM);
+            if (*MatchPenalty == 0xFFFFFFFF || Penalty < *MatchPenalty)
+            {
+                RtlFreeUnicodeString(pActualNameW);
+                RtlCreateUnicodeString(pActualNameW, ActualNameW.Buffer);
+                *FontObj = GDIToObj(FontGDI, FONT);
+                *MatchPenalty = Penalty;
+            }
+        }
 
-    QueryTable[1].QueryRoutine = NULL;
-    QueryTable[1].Name = NULL;
+        /* free strings */
+        RtlFreeUnicodeString(&ActualNameW);
 
-    Status = RtlQueryRegistryValues(RTL_REGISTRY_WINDOWS_NT,
-                                    Key,
-                                    QueryTable,
-                                    NULL,
-                                    NULL);
-    if (NT_SUCCESS(Status))
-    {
-        RtlFreeUnicodeString(FaceName);
-        *FaceName = Value;
+        /* next entry */
+        Entry = Entry->Flink;
     }
 
-    return NT_SUCCESS(Status);
+    if (Otm)
+        ExFreePoolWithTag(Otm, GDITAG_TEXT);
 }
 
-static __inline void
-SubstituteFontFamily(PUNICODE_STRING FaceName, UINT Level)
-{
-    if (10 < Level) /* Enough is enough */
-    {
-        return;
-    }
-
-    if (SubstituteFontFamilyKey(FaceName, L"FontSubstitutes"))
-    {
-        SubstituteFontFamily(FaceName, Level + 1);
-    }
-}
-
 static
 VOID
 FASTCALL
@@ -2882,25 +3334,26 @@
 {
     PS_FontInfoRec psfInfo;
     FT_ULong tmp_size = 0;
+    FT_Face Face = Font->SharedFace->Face;
 
-    if (FT_HAS_MULTIPLE_MASTERS(Font->face))
+    if (FT_HAS_MULTIPLE_MASTERS(Face))
         Font->FontObj.flFontType |= FO_MULTIPLEMASTER;
-    if (FT_HAS_VERTICAL( Font->face ))
+    if (FT_HAS_VERTICAL( Face ))
         Font->FontObj.flFontType |= FO_VERT_FACE;
-    if (FT_IS_SCALABLE( Font->face ))
+    if (FT_IS_SCALABLE( Face ))
         Font->FontObj.flFontType |= FO_TYPE_RASTER;
-    if (FT_IS_SFNT(Font->face))
+    if (FT_IS_SFNT(Face))
     {
         Font->FontObj.flFontType |= FO_TYPE_TRUETYPE;
-        if (FT_Get_Sfnt_Table(Font->face, ft_sfnt_post))
+        if (FT_Get_Sfnt_Table(Face, ft_sfnt_post))
             Font->FontObj.flFontType |= FO_POSTSCRIPT;
     }
-    if (!FT_Get_PS_Font_Info(Font->face, &psfInfo ))
+    if (!FT_Get_PS_Font_Info(Face, &psfInfo ))
     {
         Font->FontObj.flFontType |= FO_POSTSCRIPT;
     }
     /* Check for the presence of the 'CFF ' table to check if the font is Type1 */
-    if (!FT_Load_Sfnt_Table(Font->face, FT_MAKE_TAG('C','F','F',' '), 0, NULL, &tmp_size))
+    if (!FT_Load_Sfnt_Table(Face, FT_MAKE_TAG('C','F','F',' '), 0, NULL, &tmp_size))
     {
         Font->FontObj.flFontType |= (FO_CFF|FO_POSTSCRIPT);
     }
@@ -2912,9 +3365,10 @@
 {
     NTSTATUS Status = STATUS_SUCCESS;
     PTEXTOBJ TextObj;
-    UNICODE_STRING FaceName;
+    UNICODE_STRING ActualNameW, RequestedNameW;
     PPROCESSINFO Win32Process;
-    UINT MatchScore;
+    ULONG MatchPenalty;
+    LOGFONTW *pLogFont;
 
     if (!pTextObj)
     {
@@ -2931,35 +3385,46 @@
         }
     }
     else
+    {
         TextObj = pTextObj;
+    }
 
-    if (! RtlCreateUnicodeString(&FaceName, TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfFaceName))
+    RtlInitUnicodeString(&ActualNameW, NULL);
+
+    pLogFont = &TextObj->logfont.elfEnumLogfontEx.elfLogFont;
+    if (! RtlCreateUnicodeString(&RequestedNameW, pLogFont->lfFaceName))
     {
         if (!pTextObj) TEXTOBJ_UnlockText(TextObj);
         return STATUS_NO_MEMORY;
     }
-    SubstituteFontFamily(&FaceName, 0);
-    MatchScore = 0;
+
+    DPRINT("Font '%ls' is substituted by: ", RequestedNameW.Buffer);
+    SubstituteFontName(&RequestedNameW);
+    DPRINT("'%ls'.\n", RequestedNameW.Buffer);
+
+    MatchPenalty = 0xFFFFFFFF;
     TextObj->Font = NULL;
 
-    /* First search private fonts */
     Win32Process = PsGetCurrentProcessWin32Process();
+
+    /* Search private fonts */
     IntLockProcessPrivateFonts(Win32Process);
-    FindBestFontFromList(&TextObj->Font, &MatchScore,
-                         &TextObj->logfont.elfEnumLogfontEx.elfLogFont, &FaceName,
+    FindBestFontFromList(&TextObj->Font, &MatchPenalty, pLogFont,
+                         &RequestedNameW, &ActualNameW,
                          &Win32Process->PrivateFontListHead);
     IntUnLockProcessPrivateFonts(Win32Process);
 
     /* Search system fonts */
     IntLockGlobalFonts;
-    FindBestFontFromList(&TextObj->Font, &MatchScore,
-                         &TextObj->logfont.elfEnumLogfontEx.elfLogFont, &FaceName,
+    FindBestFontFromList(&TextObj->Font, &MatchPenalty, pLogFont,
+                         &RequestedNameW, &ActualNameW,
                          &FontListHead);
     IntUnLockGlobalFonts;
+
     if (NULL == TextObj->Font)
     {
         DPRINT1("Requested font %S not found, no fonts loaded at all\n",
-                TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfFaceName);
+                pLogFont->lfFaceName);
         Status = STATUS_NOT_FOUND;
     }
     else
@@ -2970,13 +3435,25 @@
         TextObj->Font->iUniq = 1; // Now it can be cached.
         IntFontType(FontGdi);
         FontGdi->flType = TextObj->Font->flFontType;
-        FontGdi->Underline = TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfUnderline ? 0xff : 0;
-        FontGdi->StrikeOut = TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfStrikeOut ? 0xff : 0;
+        FontGdi->Underline = pLogFont->lfUnderline ? 0xff : 0;
+        FontGdi->StrikeOut = pLogFont->lfStrikeOut ? 0xff : 0;
+        FontGdi->Italic = pLogFont->lfItalic ? 0xff : 0;
+        if (pLogFont->lfWeight != FW_DONTCARE)
+            FontGdi->Weight = pLogFont->lfWeight;
+        else
+            FontGdi->Weight = FW_NORMAL;
+        RtlCopyMemory(pLogFont->lfFaceName, ActualNameW.Buffer,
+                      ActualNameW.Length);
         TextObj->fl |= TEXTOBJECT_INIT;
         Status = STATUS_SUCCESS;
+
+        DPRINT("RequestedNameW: %ls (CharSet: %d) -> ActualNameW: %ls (CharSet: %d)\n",
+            RequestedNameW.Buffer, pLogFont->lfCharSet,
+            ActualNameW.Buffer, FontGdi->CharSet);
     }
 
-    RtlFreeUnicodeString(&FaceName);
+    RtlFreeUnicodeString(&RequestedNameW);
+    RtlFreeUnicodeString(&ActualNameW);
     if (!pTextObj) TEXTOBJ_UnlockText(TextObj);
 
     ASSERT((NT_SUCCESS(Status) ^ (NULL == TextObj->Font)) != 0);
@@ -3030,6 +3507,19 @@
     return TRUE;
 }
 
+static BOOL
+EqualFamilyInfo(FONTFAMILYINFO *pInfo1, FONTFAMILYINFO *pInfo2)
+{
+    BOOL Ret;
+    UNICODE_STRING Str1, Str2;
+    RtlCreateUnicodeString(&Str1, pInfo1->EnumLogFontEx.elfLogFont.lfFaceName);
+    RtlCreateUnicodeString(&Str2, pInfo2->EnumLogFontEx.elfLogFont.lfFaceName);
+    Ret = RtlEqualUnicodeString(&Str1, &Str2, TRUE);
+    RtlFreeUnicodeString(&Str2);
+    RtlFreeUnicodeString(&Str1);
+    return Ret;
+}
+
 BOOL
 FASTCALL
 IntGdiGetFontResourceInfo(
@@ -3042,9 +3532,9 @@
     POBJECT_NAME_INFORMATION NameInfo1, NameInfo2;
     PLIST_ENTRY ListEntry;
     PFONT_ENTRY FontEntry;
-    FONTFAMILYINFO Info;
-    ULONG Size;
-    BOOL bFound = FALSE;
+    FONTFAMILYINFO Info[10];
+    ULONG Size, I, Count, Count2;
+    LPBYTE pbBuffer;
 
     /* Create buffer for full path name */
     Size = sizeof(OBJECT_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR);
@@ -3072,6 +3562,7 @@
     }
 
     /* Try to find the pathname in the global font list */
+    Count = 0;
     IntLockGlobalFonts;
     for (ListEntry = FontListHead.Flink;
             ListEntry != &FontListHead;
@@ -3085,10 +3576,23 @@
             {
                 if (RtlEqualUnicodeString(&NameInfo1->Name, &NameInfo2->Name, FALSE))
                 {
-                    /* Found */
-                    FontFamilyFillInfo(&Info, FontEntry->FaceName.Buffer, FontEntry->Font);
-                    bFound = TRUE;
-                    break;
+                    BOOL IsEqual = FALSE;
+                    FontFamilyFillInfo(&Info[Count], FontEntry->FaceName.Buffer, FontEntry->Font);
+                    for (I = 0; I < Count; ++I)
+                    {
+                        if (EqualFamilyInfo(&Info[I], &Info[Count]))
+                        {
+                            IsEqual = TRUE;
+                            break;
+                        }
+                    }
+                    if (!IsEqual)
+                    {
+                        /* Found */
+                        ++Count;
+                        if (Count >= _countof(Info))
+                            break;
+                    }
                 }
             }
         }
@@ -3099,7 +3603,7 @@
     ExFreePoolWithTag(NameInfo1, TAG_FINF);
     ExFreePool(NameInfo2);
 
-    if (!bFound && dwType != 5)
+    if (Count == 0 && dwType != 5)
     {
         /* Font could not be found in system table
            dwType == 5 will still handle this */
@@ -3114,17 +3618,26 @@
         break;
 
     case 1: /* Copy the full font name */
-        Size = wcslen(Info.EnumLogFontEx.elfFullName) + 1;
+        Size = wcslen(Info[0].EnumLogFontEx.elfFullName) + 1;
         Size = min(Size , LF_FULLFACESIZE) * sizeof(WCHAR);
-        RtlCopyMemory(pBuffer, Info.EnumLogFontEx.elfFullName, Size);
+        RtlCopyMemory(pBuffer, Info[0].EnumLogFontEx.elfFullName, Size);
         // FIXME: Do we have to zeroterminate?
         *pdwBytes = Size;
         break;
 
     case 2: /* Copy a LOGFONTW structure */
-        Info.EnumLogFontEx.elfLogFont.lfWidth = 0;
-        RtlCopyMemory(pBuffer, &Info.EnumLogFontEx.elfLogFont, sizeof(LOGFONTW));
-        *pdwBytes = sizeof(LOGFONTW);
+        if (*pdwBytes < Count * sizeof(LOGFONTW))
+            Count2 = *pdwBytes / sizeof(LOGFONTW);
+        else
+            Count2 = Count;
+        pbBuffer = (LPBYTE)pBuffer;
+        for (I = 0; I < Count2; ++I)
+        {
+            Info[I].EnumLogFontEx.elfLogFont.lfWidth = 0;
+            RtlCopyMemory(pbBuffer, &Info[I].EnumLogFontEx.elfLogFont, sizeof(LOGFONTW));
+            pbBuffer += sizeof(LOGFONTW);
+        }
+        *pdwBytes = Count * sizeof(LOGFONTW);
         break;
 
     case 3: /* FIXME: What exactly is copied here? */
@@ -3133,7 +3646,7 @@
         break;
 
     case 5: /* Looks like a BOOL that is copied, TRUE, if the font was not found */
-        *(BOOL*)pBuffer = !bFound;
+        *(BOOL*)pBuffer = Count == 0;
         *pdwBytes = sizeof(BOOL);
         break;
 
@@ -3149,11 +3662,11 @@
 FASTCALL
 ftGdiRealizationInfo(PFONTGDI Font, PREALIZATION_INFO Info)
 {
-    if (FT_HAS_FIXED_SIZES(Font->face))
+    if (FT_HAS_FIXED_SIZES(Font->SharedFace->Face))
         Info->iTechnology = RI_TECH_BITMAP;
     else
     {
-        if (FT_IS_SCALABLE(Font->face))
+        if (FT_IS_SCALABLE(Font->SharedFace->Face))
             Info->iTechnology = RI_TECH_SCALABLE;
         else
             Info->iTechnology = RI_TECH_FIXED;
@@ -3172,7 +3685,7 @@
 {
     DWORD Count = 0;
     INT i = 0;
-    FT_Face face = Font->face;
+    FT_Face face = Font->SharedFace->Face;
 
     if (FT_HAS_KERNING(face) && face->charmap->encoding == FT_ENCODING_UNICODE)
     {
@@ -3492,7 +4005,7 @@
     ASSERT(FontGDI);
 
     IntLockFreeType;
-    face = FontGDI->face;
+    face = FontGDI->SharedFace->Face;
     if (face->charmap == NULL)
     {
         DPRINT("WARNING: No charmap selected!\n");
@@ -4120,7 +4633,7 @@
 
     FontGDI = ObjToGDI(TextObj->Font, FONT);
 
-    face = FontGDI->face;
+    face = FontGDI->SharedFace->Face;
     if (face->charmap == NULL)
     {
         for (i = 0; i < (UINT)face->num_charmaps; i++)
@@ -4318,7 +4831,7 @@
 
     FontGDI = ObjToGDI(TextObj->Font, FONT);
 
-    face = FontGDI->face;
+    face = FontGDI->SharedFace->Face;
     if (face->charmap == NULL)
     {
         for (i = 0; i < (UINT)face->num_charmaps; i++)
@@ -4456,10 +4969,11 @@
     }
     else
     {
-        if (FT_IS_SFNT(FontGDI->face))
+        FT_Face Face = FontGDI->SharedFace->Face;
+        if (FT_IS_SFNT(Face))
         {
-            TT_OS2 *pOS2 = FT_Get_Sfnt_Table(FontGDI->face, ft_sfnt_os2);
-            DefChar = (pOS2->usDefaultChar ? FT_Get_Char_Index(FontGDI->face, pOS2->usDefaultChar) : 0);
+            TT_OS2 *pOS2 = FT_Get_Sfnt_Table(Face, ft_sfnt_os2);
+            DefChar = (pOS2->usDefaultChar ? FT_Get_Char_Index(Face, pOS2->usDefaultChar) : 0);
         }
         else
         {
@@ -4502,7 +5016,7 @@
 
     for (i = 0; i < cwc; i++)
     {
-        Buffer[i] = FT_Get_Char_Index(FontGDI->face, Safepwc[i]);
+        Buffer[i] = FT_Get_Char_Index(FontGDI->SharedFace->Face, Safepwc[i]);
         if (Buffer[i] == 0)
         {
             Buffer[i] = DefChar;
