wineconsole patch (1/3)

Eric Pouech eric.pouech at wanadoo.fr
Fri Mar 22 13:57:56 CST 2002


this patch implements the support for scalable fonts
(including TrueType)
there is a bit of hacking because of freetype issues (Huw
is aware of them), but I'll let him to the right fix
in the font engine (except the one I just sent about
family names)

A+
-------------- next part --------------
This patched is released under the X11 license.

Name: wc_scale
ChangeLog: wineconsole is now able to handle non raster fonts (vector, true type)
GenDate: 2002/03/22 19:37:43 UTC
ModifiedFiles: programs/wineconsole/dialog.c programs/wineconsole/user.c programs/wineconsole/winecon_private.h programs/wineconsole/winecon_user.h
AddedFiles: 
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/programs/wineconsole/dialog.c,v
retrieving revision 1.6
diff -u -u -r1.6 dialog.c
--- programs/wineconsole/dialog.c	10 Mar 2002 00:21:20 -0000	1.6
+++ programs/wineconsole/dialog.c	15 Mar 2002 05:49:04 -0000
@@ -42,8 +42,9 @@
     int			nFont;		/* number of font size in size LB */
     struct font_info 
     {
-	TEXTMETRIC		tm;
-	LOGFONT			lf;
+        UINT                    height;
+        UINT                    weight;
+        WCHAR                   faceName[LF_FACESIZE];
     } 			*font;		/* array of nFont. index sync'ed with SIZE LB */
     void        (*apply)(struct dialog_info*, HWND, enum WCUSER_ApplyTo, DWORD);
 };
@@ -71,7 +72,15 @@
         di->config->quick_edit = val;
         break;
     case WCUSER_ApplyToFont:
-        WCUSER_CopyFont(di->config, &di->font[val].lf);
+        {
+            LOGFONT     lf;
+            HFONT       hFont;
+
+            WCUSER_FillLogFont(&lf, di->font[val].faceName, 
+                               di->font[val].height, di->font[val].weight);
+            hFont = WCUSER_CopyFont(di->config, PRIVATE(di->data)->hWnd, &lf);
+            DeleteObject(hFont);
+        }
         break;
     case WCUSER_ApplyToAttribute:
         di->config->def_attr = val;
@@ -112,7 +121,12 @@
         di->config->quick_edit = val;
         break;
     case WCUSER_ApplyToFont:
-        WCUSER_SetFont(di->data, &di->font[val].lf);
+        {
+            LOGFONT lf;
+            WCUSER_FillLogFont(&lf, di->font[val].faceName, 
+                               di->font[val].height, di->font[val].weight);
+            WCUSER_SetFont(di->data, &lf);
+        }
         break;
     case WCUSER_ApplyToAttribute:
         di->config->def_attr = val;
@@ -228,12 +242,32 @@
 {
     switch (msg)
     {
+    case WM_CREATE:
+        SetWindowLong(hWnd, 0, 0);
+        break;
+    case WM_GETFONT:
+        return GetWindowLong(hWnd, 0);
+    case WM_SETFONT:
+        SetWindowLong(hWnd, 0, wParam);
+        if (LOWORD(lParam))
+        {
+            InvalidateRect(hWnd, NULL, TRUE);
+            UpdateWindow(hWnd);
+        }
+        break;
+    case WM_DESTROY:
+        {
+            HFONT hFont = (HFONT)GetWindowLong(hWnd, 0L);
+            if (hFont) DeleteObject(hFont);
+        }
+        break;
     case WM_PAINT:
         {
             PAINTSTRUCT	        ps;
             int		        font_idx;
             int		        size_idx;
             struct dialog_info*	di;
+            HFONT	        hFont, hOldFont;
             
             di = (struct dialog_info*)GetWindowLong(GetParent(hWnd), DWL_USER);
             BeginPaint(hWnd, &ps);
@@ -241,29 +275,27 @@
             font_idx = SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_FONT, LB_GETCURSEL, 0L, 0L);
             size_idx = SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_SIZE, LB_GETCURSEL, 0L, 0L);
             
-            if (font_idx >= 0 && size_idx >= 0 && size_idx < di->nFont)
+            hFont = (HFONT)GetWindowLong(hWnd, 0L);
+            if (hFont)
             {
-                HFONT	hFont, hOldFont;
                 WCHAR	buf1[256];
                 WCHAR	buf2[256];
                 int	len1, len2;
-                
-                hFont = CreateFontIndirect(&di->font[size_idx].lf);
+
                 len1 = LoadString(GetModuleHandle(NULL), IDS_FNT_PREVIEW_1, 
                                   buf1, sizeof(buf1) / sizeof(WCHAR));
                 len2 = LoadString(GetModuleHandle(NULL), IDS_FNT_PREVIEW_2,
                                   buf2, sizeof(buf2) / sizeof(WCHAR));
                 buf1[len1] = buf2[len2] = 0;
-                if (hFont && len1)
+                if (len1) 
                 {
                     hOldFont = SelectObject(ps.hdc, hFont);
                     SetBkColor(ps.hdc, WCUSER_ColorMap[GetWindowLong(GetDlgItem(di->hDlg, IDC_FNT_COLOR_BK), 0)]);
                     SetTextColor(ps.hdc, WCUSER_ColorMap[GetWindowLong(GetDlgItem(di->hDlg, IDC_FNT_COLOR_FG), 0)]);
                     TextOut(ps.hdc, 0, 0, buf1, len1);
                     if (len2)
-                        TextOut(ps.hdc, 0, di->font[size_idx].tm.tmHeight, buf2, len2);
+                        TextOut(ps.hdc, 0, di->font[size_idx].height, buf2, len2);
                     SelectObject(ps.hdc, hOldFont);
-                    DeleteObject(hFont);
                 }
             }
             EndPaint(hWnd, &ps);
@@ -360,10 +392,11 @@
 {
     struct dialog_info*	di = (struct dialog_info*)lParam;
 
-    if (WCUSER_ValidateFontMetric(di->data, tm))
+    if (WCUSER_ValidateFontMetric(di->data, tm, FontType))
     {
 	di->nFont++;
     }
+
     return 1;
 }
 
@@ -375,16 +408,22 @@
 
     if (WCUSER_ValidateFont(di->data, lf) && (hdc = GetDC(di->hDlg)))
     {
-	di->nFont = 0;
-	EnumFontFamilies(hdc, lf->lfFaceName, font_enum_size2, (LPARAM)di);
-	if (di->nFont)
+        if (FontType & RASTER_FONTTYPE)
+        {
+            di->nFont = 0;
+            EnumFontFamilies(hdc, lf->lfFaceName, font_enum_size2, (LPARAM)di);
+        }
+        else
+            di->nFont = 1;
+        
+        if (di->nFont)
 	{
-	    int idx;
-	    idx = SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_FONT, LB_ADDSTRING, 
-				     0, (LPARAM)lf->lfFaceName);
-	}
+	    SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_FONT, LB_ADDSTRING, 
+                               0, (LPARAM)lf->lfFaceName);
+        }
 	ReleaseDC(di->hDlg, hdc);
     }
+
     return 1;
 }
 
@@ -397,46 +436,61 @@
 				   DWORD FontType, LPARAM lParam)
 {
     struct dialog_info*	di = (struct dialog_info*)lParam;
+    WCHAR	        buf[32];
+    static const WCHAR  fmt[] = {'%','l','d',0};
 
-    if (WCUSER_ValidateFontMetric(di->data, tm))
+    if (di->nFont == 0 && !(FontType & RASTER_FONTTYPE))
+    {
+        static const int sizes[] = {8,9,10,11,12,14,16,18,20,22,24,26,28,36,48,72};
+        int i;
+
+        di->nFont = sizeof(sizes) / sizeof(sizes[0]);
+        di->font = HeapAlloc(GetProcessHeap(), 0, di->nFont * sizeof(di->font[0]));
+        for (i = 0; i < di->nFont; i++)
+        {
+            /* drop sizes where window size wouldn't fit on screen */
+            if (sizes[i] * di->data->curcfg.win_height > GetSystemMetrics(SM_CYSCREEN))
+            {
+                di->nFont = i;
+                break;
+            }
+            di->font[i].height = sizes[i];
+            di->font[i].weight = 400;
+            lstrcpy(di->font[i].faceName, lf->lfFaceName);
+            wsprintf(buf, fmt, sizes[i]);
+            SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_SIZE, LB_INSERTSTRING, i, (LPARAM)buf);
+        }
+        /* don't need to enumerate other */
+        return 0;
+    }
+
+    if (WCUSER_ValidateFontMetric(di->data, tm, FontType))
     {
-	WCHAR	buf[32];
-        static const WCHAR fmt[] = {'%','l','d',0};
 	int	idx;
 
 	/* we want the string to be sorted with a numeric order, not a lexicographic...
 	 * do the job by hand... get where to insert the new string
 	 */
-	for (idx = 0; idx < di->nFont && tm->tmHeight > di->font[idx].tm.tmHeight; idx++);
-        if (idx < di->nFont &&
-            tm->tmHeight == di->font[idx].tm.tmHeight && 
-            tm->tmMaxCharWidth == di->font[idx].tm.tmMaxCharWidth)
-        {
-            /* we already have an entry with the same width & height...
-             * try to see which TEXTMETRIC (old or new) we should keep... 
-             */
-            if (di->font[idx].tm.tmWeight != tm->tmWeight)
-            {
-                /* get the weight closer to 400, the default value */
-                if (abs(tm->tmWeight - 400) < abs(di->font[idx].tm.tmWeight - 400))
-                {
-                    di->font[idx].tm = *tm;
-                }
-            }
-            /* else FIXME: skip the new tm for now */
-        }
-        else
+	for (idx = 0; idx < di->nFont && tm->tmHeight > di->font[idx].height; idx++);
+        while (idx < di->nFont && 
+               tm->tmHeight == di->font[idx].height && 
+               tm->tmWeight > di->font[idx].weight)
+            idx++;
+        if (idx == di->nFont || 
+            tm->tmHeight != di->font[idx].height ||
+            tm->tmWeight < di->font[idx].weight)
         {
             /* here we need to add the new entry */
-            wsprintfW(buf, fmt, tm->tmHeight);
+            wsprintf(buf, fmt, tm->tmHeight);
             SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_SIZE, LB_INSERTSTRING, idx, (LPARAM)buf);
 
-            /* now grow our arrays and insert to values at the same index than in the list box */
+            /* now grow our arrays and insert the values at the same index than in the list box */
             di->font = HeapReAlloc(GetProcessHeap(), 0, di->font, sizeof(*di->font) * (di->nFont + 1));
             if (idx != di->nFont)
                 memmove(&di->font[idx + 1], &di->font[idx], (di->nFont - idx) * sizeof(*di->font));
-            di->font[idx].tm = *tm;
-            di->font[idx].lf = *lf;
+            di->font[idx].height = tm->tmHeight;
+            di->font[idx].weight = tm->tmWeight;
+            lstrcpy(di->font[idx].faceName, lf->lfFaceName);
             di->nFont++;
         }
     }
@@ -450,19 +504,37 @@
  */
 static BOOL  select_font(struct dialog_info* di)
 {
-    int		idx = SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_SIZE, LB_GETCURSEL, 0L, 0L);
+    int		font_idx, size_idx;
     WCHAR	buf[256];
     WCHAR	fmt[128];
+    LOGFONT     lf;
+    HFONT       hFont, hOldFont;
+    struct config_data config;
 
-    if (idx < 0 || idx >= di->nFont)
+    font_idx = SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_FONT, LB_GETCURSEL, 0L, 0L);
+    size_idx = SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_SIZE, LB_GETCURSEL, 0L, 0L);
+
+    if (font_idx < 0 || size_idx < 0 || size_idx >= di->nFont)
 	return FALSE;
+    
+    WCUSER_FillLogFont(&lf, di->font[size_idx].faceName, 
+                       di->font[size_idx].height, di->font[size_idx].weight);
+    hFont = WCUSER_CopyFont(&config, PRIVATE(di->data)->hWnd, &lf);
+    if (!hFont) return FALSE;
+
+    if (config.cell_height != di->font[size_idx].height)
+        Trace(0, "select_font: mismatched heights (%u<>%u)\n",
+              config.cell_height, di->font[size_idx].height);
+    hOldFont = (HFONT)SendDlgItemMessage(di->hDlg, IDC_FNT_PREVIEW, WM_GETFONT, 0L, 0L);
+
+    SendDlgItemMessage(di->hDlg, IDC_FNT_PREVIEW, WM_SETFONT, (DWORD)hFont, TRUE);
+    if (hOldFont) DeleteObject(hOldFont);
 
     LoadString(GetModuleHandle(NULL), IDS_FNT_DISPLAY, fmt, sizeof(fmt) / sizeof(WCHAR));
-    wsprintfW(buf, fmt, di->font[idx].tm.tmMaxCharWidth, di->font[idx].tm.tmHeight);
+    wsprintf(buf, fmt, config.cell_width, config.cell_height);
 
     SendDlgItemMessage(di->hDlg, IDC_FNT_FONT_INFO, WM_SETTEXT, 0, (LPARAM)buf);
-    InvalidateRect(GetDlgItem(di->hDlg, IDC_FNT_PREVIEW), NULL, TRUE);
-    UpdateWindow(GetDlgItem(di->hDlg, IDC_FNT_PREVIEW));
+
     return TRUE;
 }
 
@@ -494,12 +566,19 @@
 
     if (doInit)
     {
+        int     ref = -1;
+
 	for (idx = 0; idx < di->nFont; idx++)
 	{
-	    if (WCUSER_AreFontsEqual(di->config, &di->font[idx].lf))
-		break;
+            if (!lstrcmp(di->font[idx].faceName, di->config->face_name) &&
+                di->font[idx].height == di->config->cell_height &&
+                di->font[idx].weight == di->config->font_weight)
+            {
+                if (ref == -1) ref = idx;
+                else Trace(0, "Several matches found: ref=%d idx=%d\n", ref, idx);
+            }
 	}
-	if (idx == di->nFont) idx = 0;
+	idx = (ref == -1) ? 0 : ref;
     }
     else
 	idx = 0;
@@ -545,6 +624,8 @@
 	di = (struct dialog_info*)((PROPSHEETPAGEA*)lParam)->lParam;
 	di->hDlg = hDlg;
 	SetWindowLong(hDlg, DWL_USER, (DWORD)di);
+        /* remove dialog from this control, font will be reset when listboxes are filled */
+        SendDlgItemMessage(hDlg, IDC_FNT_PREVIEW, WM_SETFONT, 0L, 0L);
 	fill_list_font(di);
         SetWindowLong(GetDlgItem(hDlg, IDC_FNT_COLOR_BK), 0, (di->config->def_attr >> 4) & 0x0F);
         SetWindowLong(GetDlgItem(hDlg, IDC_FNT_COLOR_FG), 0, di->config->def_attr & 0x0F);
@@ -704,7 +785,7 @@
     wndclass.style         = 0;
     wndclass.lpfnWndProc   = WCUSER_FontPreviewProc;
     wndclass.cbClsExtra    = 0;
-    wndclass.cbWndExtra    = 0;
+    wndclass.cbWndExtra    = 4; /* for hFont */
     wndclass.hInstance     = GetModuleHandle(NULL);
     wndclass.hIcon         = 0;
     wndclass.hCursor       = LoadCursor(0, IDC_ARROW);
Index: programs/wineconsole/user.c
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/programs/wineconsole/user.c,v
retrieving revision 1.7
diff -u -u -r1.7 user.c
--- programs/wineconsole/user.c	10 Mar 2002 00:21:20 -0000	1.7
+++ programs/wineconsole/user.c	16 Mar 2002 12:59:17 -0000
@@ -258,57 +258,166 @@
 BOOL WCUSER_AreFontsEqual(const struct config_data* config, const LOGFONT* lf)
 {
     return lf->lfHeight == config->cell_height &&
-        lf->lfWidth  == config->cell_width &&
         lf->lfWeight == config->font_weight &&
         !lf->lfItalic && !lf->lfUnderline && !lf->lfStrikeOut &&
-        !lstrcmpW(lf->lfFaceName, config->face_name);
+        !lstrcmp(lf->lfFaceName, config->face_name);
 }
 
+struct font_chooser {
+    struct inner_data*	data;
+    int			done;
+};
+
 /******************************************************************
- *		CopyFont
+ *		WCUSER_ValidateFontMetric
  *
+ * Returns true if the font described in tm is usable as a font for the renderer
+ */
+BOOL	WCUSER_ValidateFontMetric(const struct inner_data* data, const TEXTMETRIC* tm, DWORD fontType)
+{
+    BOOL        ret = TRUE;
+
+    if (fontType & RASTER_FONTTYPE)
+        ret = (tm->tmMaxCharWidth * data->curcfg.win_width < GetSystemMetrics(SM_CXSCREEN) &&
+               tm->tmHeight * data->curcfg.win_height < GetSystemMetrics(SM_CYSCREEN));
+    return ret && !tm->tmItalic && !tm->tmUnderlined && !tm->tmStruckOut &&
+        (tm->tmCharSet == DEFAULT_CHARSET /*|| tm->tmCharSet == ANSI_CHARSET*/);
+}
+
+/******************************************************************
+ *		WCUSER_ValidateFont
  *
+ * Returns true if the font family described in lf is usable as a font for the renderer
  */
-void WCUSER_CopyFont(struct config_data* config, const LOGFONT* lf)
+BOOL	WCUSER_ValidateFont(const struct inner_data* data, const LOGFONT* lf)
 {
-    config->cell_width  = lf->lfWidth;
-    config->cell_height = lf->lfHeight;
-    config->font_weight  = lf->lfWeight;
-    lstrcpyW(config->face_name, lf->lfFaceName);
+    return (lf->lfPitchAndFamily & 3) == FIXED_PITCH && 
+        /* (lf->lfPitchAndFamily & 0xF0) == FF_MODERN && */
+        (lf->lfCharSet == DEFAULT_CHARSET || lf->lfCharSet == ANSI_CHARSET);
 }
 
 /******************************************************************
- *		WCUSER_InitFont
+ *		get_first_font_enum_2
+ *		get_first_font_enum
  *
- * create a hFont from the settings saved in registry...
- * (called on init, assuming no font has been created before)
+ * Helper functions to get a decent font for the renderer
  */
-BOOL	WCUSER_InitFont(struct inner_data* data)
+static int CALLBACK get_first_font_enum_2(const LOGFONT* lf, const TEXTMETRIC* tm, 
+					  DWORD FontType, LPARAM lParam)
 {
-    LOGFONT lf;
-        
-    lf.lfHeight        = -data->curcfg.cell_height;
-    lf.lfWidth         = data->curcfg.cell_width;
-    lf.lfEscapement    = 0;
-    lf.lfOrientation   = 0;
-    lf.lfWeight        = data->curcfg.font_weight;
-    lf.lfItalic        = FALSE;
-    lf.lfUnderline     = FALSE;
-    lf.lfStrikeOut     = FALSE;
-    lf.lfCharSet       = DEFAULT_CHARSET;
-    lf.lfOutPrecision  = OUT_DEFAULT_PRECIS;
-    lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; 
-    lf.lfQuality       = DEFAULT_QUALITY;
-    lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
-    lstrcpy(lf.lfFaceName, data->curcfg.face_name);
-    PRIVATE(data)->hFont = CreateFontIndirect(&lf);
-    if (!PRIVATE(data)->hFont) return FALSE;
+    struct font_chooser*	fc = (struct font_chooser*)lParam;
 
-    WCUSER_ComputePositions(data);
-    WCUSER_NewBitmap(data, TRUE);
-    InvalidateRect(PRIVATE(data)->hWnd, NULL, FALSE);
-    UpdateWindow(PRIVATE(data)->hWnd);
-    return TRUE;
+    if (WCUSER_ValidateFontMetric(fc->data, tm, FontType))
+    {
+	WCUSER_SetFont(fc->data, lf);
+	fc->done = 1;
+	return 0;
+    }
+    return 1;
+}
+
+static int CALLBACK get_first_font_enum(const LOGFONT* lf, const TEXTMETRIC* tm, 
+					DWORD FontType, LPARAM lParam)
+{
+    struct font_chooser*	fc = (struct font_chooser*)lParam;
+
+    if (WCUSER_ValidateFont(fc->data, lf))
+    {
+	EnumFontFamilies(PRIVATE(fc->data)->hMemDC, lf->lfFaceName, get_first_font_enum_2, lParam);
+	return !fc->done; /* we just need the first matching one... */
+    }
+    return 1;
+}
+
+/******************************************************************
+ *		CopyFont
+ *
+ * get the relevant information from the font described in lf and store them
+ * in config
+ */
+HFONT WCUSER_CopyFont(struct config_data* config, HWND hWnd, const LOGFONT* lf)
+{
+    TEXTMETRIC  tm;
+    HDC         hDC;
+    HFONT       hFont, hOldFont;
+    int         w, i, buf[256];
+
+    if (!(hDC = GetDC(hWnd))) return (HFONT)0;
+    if (!(hFont = CreateFontIndirect(lf))) goto err1;
+
+    hOldFont = SelectObject(hDC, hFont);
+    GetTextMetrics(hDC, &tm);
+
+    /* FIXME:
+     * the current freetype engine (at least 2.0.x with x <= 8) and its implementation
+     * in Wine don't return adequate values for fixed fonts
+     * In Windows, those fonts are expectes to return the same value for
+     *  - the average width
+     *  - the largest width
+     *  - the width of all characters in the font
+     * This isn't true in Wine. As a temporary workaound, we get as the width of the 
+     * cell, the width of the first character in the font, after checking that all
+     * characters in the font have the same width (I hear parano?a coming)
+     * when this gets fixed, the should be using tm.tmAveCharWidth or tm.tmMaxCharWidth
+     * as the cell width.
+     */
+    GetCharWidth32(hDC, tm.tmFirstChar, tm.tmFirstChar, &w);
+    for (i = tm.tmFirstChar + 1; i <= tm.tmLastChar; i += sizeof(buf) / sizeof(buf[0]))
+    {
+        int j, l;
+            
+        l = min(tm.tmLastChar - i, sizeof(buf) / sizeof(buf[0]) - 1);
+        GetCharWidth32(hDC, i, i + l, buf);
+        for (j = 0; j <= l; j++) 
+        {
+            if (buf[j] != w)
+            {
+                Trace(0, "Non uniform cell width: [%d]=%d [%d]=%d\n", 
+                      i + j, buf[j], tm.tmFirstChar, w);
+                goto err;
+            }
+        }
+    }
+
+    SelectObject(hDC, hOldFont);
+    ReleaseDC(hWnd, hDC);
+
+    config->cell_width  = w;
+    config->cell_height = tm.tmHeight;
+    config->font_weight = tm.tmWeight;
+    lstrcpy(config->face_name, lf->lfFaceName);
+
+    return hFont;
+ err:
+    if (hDC && hOldFont) SelectObject(hDC, hOldFont);
+    if (hFont) DeleteObject(hFont);
+ err1:
+    if (hDC) ReleaseDC(hWnd, hDC);
+
+    return (HFONT)0;
+}
+
+/******************************************************************
+ *		WCUSER_FillLogFont
+ *
+ *
+ */
+void    WCUSER_FillLogFont(LOGFONT* lf, const WCHAR* name, UINT height, UINT weight)
+{
+    lf->lfHeight        = height;
+    lf->lfWidth         = 0;
+    lf->lfEscapement    = 0;
+    lf->lfOrientation   = 0;
+    lf->lfWeight        = weight;
+    lf->lfItalic        = FALSE;
+    lf->lfUnderline     = FALSE;
+    lf->lfStrikeOut     = FALSE;
+    lf->lfCharSet       = DEFAULT_CHARSET;
+    lf->lfOutPrecision  = OUT_DEFAULT_PRECIS;
+    lf->lfClipPrecision = CLIP_DEFAULT_PRECIS; 
+    lf->lfQuality       = DEFAULT_QUALITY;
+    lf->lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
+    lstrcpy(lf->lfFaceName, name);
 }
 
 /******************************************************************
@@ -320,18 +429,45 @@
 {
     if (WCUSER_AreFontsEqual(&data->curcfg, logfont)) return TRUE;
     if (PRIVATE(data)->hFont) DeleteObject(PRIVATE(data)->hFont);
-    PRIVATE(data)->hFont = CreateFontIndirect(logfont);
+
+    PRIVATE(data)->hFont = WCUSER_CopyFont(&data->curcfg, PRIVATE(data)->hWnd, logfont);
     if (!PRIVATE(data)->hFont) {Trace(0, "wrong font\n");return FALSE;}
-    WCUSER_CopyFont(&data->curcfg, logfont);
 
     WCUSER_ComputePositions(data);
     WCUSER_NewBitmap(data, TRUE);
     InvalidateRect(PRIVATE(data)->hWnd, NULL, FALSE);
     UpdateWindow(PRIVATE(data)->hWnd);
+
     return TRUE;
 }
 
 /******************************************************************
+ *		WCUSER_InitFont
+ *
+ * create a hFont from the settings saved in registry...
+ * (called on init, assuming no font has been created before)
+ */
+static BOOL	WCUSER_InitFont(struct inner_data* data)
+{
+    LOGFONT             lf;
+    struct font_chooser fc;
+
+    WCUSER_FillLogFont(&lf, data->curcfg.face_name, 
+                       data->curcfg.cell_height, data->curcfg.font_weight);
+    data->curcfg.face_name[0] = 0;
+    data->curcfg.cell_height = data->curcfg.font_weight = 0;
+
+    if (WCUSER_SetFont(data, &lf)) return TRUE;
+
+    /* try to find an acceptable font */
+    Trace(0, "Couldn't match the font from registry... trying to find one\n");
+    fc.data = data;
+    fc.done = 0;
+    EnumFontFamilies(PRIVATE(data)->hMemDC, NULL, get_first_font_enum, (LPARAM)&fc);
+    return fc.done;
+}
+
+/******************************************************************
  *		WCUSER_GetCell
  *
  * Get a cell from the a relative coordinate in window (takes into
@@ -563,68 +699,6 @@
     InvalidateRect(PRIVATE(data)->hWnd, NULL, FALSE);
 }
 
-struct font_chooser {
-    struct inner_data*	data;
-    int			done;
-};
-
-/******************************************************************
- *		WCUSER_ValidateFontMetric
- *
- * Returns true if the font described in tm is usable as a font for the renderer
- */
-BOOL	WCUSER_ValidateFontMetric(const struct inner_data* data, const TEXTMETRIC* tm)
-{
-    return tm->tmMaxCharWidth * data->curcfg.win_width < GetSystemMetrics(SM_CXSCREEN) &&
-	tm->tmHeight * data->curcfg.win_height < GetSystemMetrics(SM_CYSCREEN) &&
-	!tm->tmItalic && !tm->tmUnderlined && !tm->tmStruckOut;
-}
-
-/******************************************************************
- *		WCUSER_ValidateFont
- *
- * Returns true if the font family described in lf is usable as a font for the renderer
- */
-BOOL	WCUSER_ValidateFont(const struct inner_data* data, const LOGFONT* lf)
-{
-    return (lf->lfPitchAndFamily & 3) == FIXED_PITCH && 
-        (lf->lfPitchAndFamily & 0xF0) == FF_MODERN &&
-        lf->lfCharSet != SYMBOL_CHARSET;
-}
-
-/******************************************************************
- *		get_first_font_enum_2
- *		get_first_font_enum
- *
- * Helper functions to get a decent font for the renderer
- */
-static int CALLBACK get_first_font_enum_2(const LOGFONT* lf, const TEXTMETRIC* tm, 
-					  DWORD FontType, LPARAM lParam)
-{
-    struct font_chooser*	fc = (struct font_chooser*)lParam;
-
-    if (WCUSER_ValidateFontMetric(fc->data, tm))
-    {
-	WCUSER_SetFont(fc->data, lf);
-	fc->done = 1;
-	return 0;
-    }
-    return 1;
-}
-
-static int CALLBACK get_first_font_enum(const LOGFONT* lf, const TEXTMETRIC* tm, 
-					DWORD FontType, LPARAM lParam)
-{
-    struct font_chooser*	fc = (struct font_chooser*)lParam;
-
-    if (WCUSER_ValidateFont(fc->data, lf))
-    {
-	EnumFontFamilies(PRIVATE(fc->data)->hMemDC, lf->lfFaceName, get_first_font_enum_2, lParam);
-	return !fc->done; /* we just need the first matching one... */
-    }
-    return 1;
-}
-
 /******************************************************************
  *		WCUSER_FillMenu
  *
@@ -1257,17 +1331,8 @@
     /* force update of current data */
     if (!WINECON_GrabChanges(data)) return FALSE;
 
-    if (!WCUSER_InitFont(data))
-    {
-        struct font_chooser fc;
-        /* try to find an acceptable font */
-        fc.data = data;
-        fc.done = 0;
-        EnumFontFamilies(PRIVATE(data)->hMemDC, NULL, get_first_font_enum, (LPARAM)&fc);
-        return fc.done;
-    }
+    if (!WCUSER_InitFont(data)) return FALSE;
+
     return TRUE;
 }
-
-
 
Index: programs/wineconsole/winecon_user.h
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/programs/wineconsole/winecon_user.h,v
retrieving revision 1.3
diff -u -u -r1.3 winecon_user.h
--- programs/wineconsole/winecon_user.h	10 Mar 2002 00:21:20 -0000	1.3
+++ programs/wineconsole/winecon_user.h	10 Mar 2002 11:07:16 -0000
@@ -45,7 +45,11 @@
 extern BOOL WCUSER_GetProperties(struct inner_data*, BOOL);
 extern BOOL WCUSER_SetFont(struct inner_data* data, const LOGFONT* font);
 extern BOOL WCUSER_ValidateFont(const struct inner_data* data, const LOGFONT* lf);
-extern BOOL WCUSER_ValidateFontMetric(const struct inner_data* data, const TEXTMETRIC* tm);
-extern BOOL WCUSER_AreFontsEqual(const struct config_data* config, const LOGFONT* lf);
-extern void WCUSER_CopyFont(struct config_data* config, const LOGFONT* lf);
+extern BOOL WCUSER_ValidateFontMetric(const struct inner_data* data, 
+                                      const TEXTMETRIC* tm, DWORD fontType);
+extern BOOL WCUSER_AreFontsEqual(const struct config_data* config, 
+                                 const LOGFONT* lf);
+extern HFONT WCUSER_CopyFont(struct config_data* config, HWND hWnd, const LOGFONT* lf);
+extern void WCUSER_FillLogFont(LOGFONT* lf, const WCHAR* name, 
+                               UINT height, UINT weight);
 


More information about the wine-patches mailing list