1 /* The routines in this file provide font control functions under
2    the Microsoft Windows environment on an IBM-PC or compatible
3    computer.
4 
5    Must be compiled with Borland C++ 2.0 or MSC 6.0 or later versions.
6 
7    It should not be compiled if the WINDOW_MSWIN symbol is not set */
8 
9 #include    "estruct.h"
10 #include    <stdio.h>
11 #include    "eproto.h"
12 #include    "edef.h"
13 
14 #include    "mswin.h"
15 
16 static TEXTMETRIC   Metrics;
17 static HFONT        hNewFont;
18 static char         FaceName[LF_FACESIZE];
19 
20 /* SelectFont:  Selects the emacs-chosen font in the Device Context */
21 /* ==========                                                       */
22 
SelectFont(HDC hDC,HFONT hFont)23 HFONT FAR PASCAL SelectFont (HDC hDC, HFONT hFont)
24 
25 /* just like SelectObject, this function returns the previously selected
26    font handle */
27 {
28     HFONT   hPrevFont;
29 
30     SetMapMode (hDC, MM_TEXT);
31     hPrevFont= SelectObject (hDC, hFont ?
32 				  hFont :
33                                   GetStockObject (SYSTEM_FIXED_FONT));
34     return hPrevFont;
35 } /* SelectFont */
36 
37 /* GetFontMetrics:  retrieves the TEXTMETRIC and face name of a given font */
38 /* ==============                                                          */
39 
GetFontMetrics(HFONT hFont,TEXTMETRIC * Metrics,char * FaceName)40 static void PASCAL GetFontMetrics (HFONT hFont, TEXTMETRIC *Metrics,
41                                         char *FaceName)
42 /* If either Metrics of FaceName is NULL, the corresponding value is not
43    returned. If not NULL, FaceName must point to a string containing at
44    least LF_FACESIZE characters */
45 {
46     HDC     hDC;
47     HFONT   hPrevFont;
48 
49     hDC = GetDC (hFrameWnd);
50     hPrevFont = SelectFont (hDC, hFont);
51     if (Metrics) GetTextMetrics (hDC, Metrics);
52     if (FaceName) GetTextFace (hDC, LF_FACESIZE, FaceName);
53     SelectObject (hDC, hPrevFont);
54     ReleaseDC (hFrameWnd, hDC);
55 } /* GetFontMetrics */
56 
57 /* UpdateMaxRowCol: update the maximas displayed on the dialog box */
58 /* ===============                                                 */
59 
UpdateMaxRowCol(HWND hDlg,HFONT hFont)60 static void PASCAL UpdateMaxRowCol (HWND hDlg, HFONT hFont)
61 {
62     CellMetrics cm;
63     char    text[17];
64 
65     BuildCellMetrics (&cm, hFont);
66     SetDlgItemText (hDlg, ID_MAXROWS,
67 		    itoa (DisplayableRows (hFrameWnd, -1, &cm), text, 10));
68     SetDlgItemText (hDlg, ID_MAXCOLUMNS,
69 		    itoa (DisplayableColumns (hFrameWnd, -1, &cm), text, 10));
70 } /* UpdateMaxRowCol */
71 
72 /* UpdateSample:    Update the sample text displayed on the dialog box */
73 /* ============                                                        */
74 
UpdateSample(HWND hDlg,HFONT hFont,TEXTMETRIC * m,char * FaceName)75 static void PASCAL UpdateSample (HWND hDlg, HFONT hFont,
76                                       TEXTMETRIC *m, char *FaceName)
77 {
78 #define FONTSAMPLESIZE  LF_FACESIZE+40+(26*3)
79     char    SampleText[FONTSAMPLESIZE];
80     int     i;
81     char    c;
82 
83     strcpy (SampleText, FaceName);
84     i = strlen (SampleText);
85     strcpy (&SampleText[i], " (Height=");
86     i += strlen (&SampleText[i]);
87     itoa (m->tmHeight, &SampleText[i], 10);
88     i += strlen (&SampleText[i]);
89     strcpy (&SampleText[i], ", Width=");
90     i += strlen (&SampleText[i]);
91     itoa (m->tmAveCharWidth, &SampleText[i], 10);
92     i += strlen (&SampleText[i]);
93     strcpy (&SampleText[i], ") sample:");
94     i += strlen (&SampleText[i]);
95     for (c = 'A'; c <= 'Z'; c++) {
96 	SampleText[i++] = ' ';
97 	SampleText[i++] = c;
98 	SampleText[i++] = lowerc (c);
99     }
100     SampleText[i] = '\0';
101     SendDlgItemMessage (hDlg, ID_SAMPLE, WM_SETFONT, (UINT)hFont, (long)FALSE);
102     SetDlgItemText (hDlg, ID_SAMPLE, SampleText);
103 } /* UpdateSample */
104 
105 /* NewFont: creates a font matching the user's selections */
106 /* =======                                                */
107 
NewFont(HWND hDlg,BOOL TrustSizeEdit)108 static void PASCAL    NewFont (HWND hDlg, BOOL TrustSizeEdit)
109 /* setting TrustSizeEdit to FALSE indicates that the contents of the
110    ID_FONTSIZE edit box should not be used (this is used when this
111    function is called for a size list-selection change, at which time
112    the edit box has not been updated yet) */
113 {
114     DWORD   d;
115     int     i;
116     BOOL    FontSizeOK;
117     LOGFONT lf;
118     HFONT   hOldFont;
119 
120     hOldFont = hNewFont;
121     i = SendDlgItemMessage (hDlg, ID_FONT, LB_GETCURSEL, 0, 0L);
122     if (i == LB_ERR) lf.lfFaceName[0] = 0;
123     else {
124 	SendDlgItemMessage (hDlg, ID_FONT, LB_GETTEXT, i,
125 	                    (DWORD)(LPSTR)lf.lfFaceName);
126     }
127     if (TrustSizeEdit) {
128         i = GetDlgItemInt (hDlg, ID_FONTSIZE, &FontSizeOK, FALSE);
129     }
130     else FontSizeOK = FALSE;
131     if (FontSizeOK) {
132 	lf.lfHeight = i;
133 	lf.lfWidth = 0;
134     }
135     else {
136 	i = SendDlgItemMessage (hDlg, ID_FONTSIZE, CB_GETCURSEL, 0, 0L);
137 	if (i == CB_ERR) i = 0;
138 	d = SendDlgItemMessage (hDlg, ID_FONTSIZE, CB_GETITEMDATA, i, 0L);
139 	lf.lfHeight = HIWORD(d);
140 	lf.lfWidth = LOWORD(d);
141     }
142     lf.lfEscapement = 0;
143     lf.lfOrientation = 0;
144     lf.lfWeight = IsDlgButtonChecked (hDlg, ID_BOLD) ? 700 : 400;
145     lf.lfItalic = 0;
146     lf.lfUnderline = 0;
147     lf.lfStrikeOut = 0;
148     lf.lfCharSet = IsDlgButtonChecked (hDlg, ID_ANSI) ?
149                    ANSI_CHARSET : OEM_CHARSET;
150     lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
151     lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
152     lf.lfQuality = DEFAULT_QUALITY;
153     lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
154 
155     hNewFont = CreateFontIndirect (&lf);
156     GetFontMetrics (hNewFont, &Metrics, FaceName);
157     UpdateMaxRowCol (hDlg, hNewFont);
158     UpdateSample (hDlg, hNewFont, &Metrics, FaceName);
159     if (hOldFont) DeleteObject (hOldFont);
160 } /* NewFont */
161 
162 /* AddSize: Add a font size into the font size list (used by EnumSizesProc) */
163 /* =======                                                                  */
164 
AddSize(HWND hDlg,short int Height,short int Width)165 static void PASCAL AddSize (HWND hDlg, short int Height, short int Width)
166 {
167     char    ItemText[17];
168     int     i;
169 
170     itoa (Height, ItemText, 10);
171     i = SendDlgItemMessage (hDlg, ID_FONTSIZE, CB_ADDSTRING, 0,
172 			    (DWORD)(LPSTR)ItemText);
173     SendDlgItemMessage (hDlg, ID_FONTSIZE, CB_SETITEMDATA, i,
174 			MAKELONG(Width,Height));
175 
176 } /* AddSize */
177 
178 /* EnumSizesProc:   font enumeration function used by BuildSizeList */
179 /* =============                                                    */
EnumSizesProc(LPLOGFONT lf,LPTEXTMETRIC tm,short FontType,LPSTR Data)180 int EXPORT FAR PASCAL EnumSizesProc (LPLOGFONT lf, LPTEXTMETRIC tm,
181                                      short FontType, LPSTR Data)
182 
183 /* Data should point to a handle to the dialog box */
184 {
185     if ((lf->lfWeight > 400) || lf->lfItalic || lf->lfUnderline ||
186         lf->lfStrikeOut) return 1;
187 #if WIN30SDK
188     if (FontType & 0x04) {
189 #else
190     if (FontType & TRUETYPE_FONTTYPE) {
191 #endif
192         /* make a size list up */
193         short int h;
194 
195         for (h = lf->lfHeight / 4; h <= (3 * lf->lfHeight) / 2; h += 2) {
196             AddSize (*(HWND FAR *)Data, h, 0);
197         }
198         return 0;   /* no need to list this one further */
199     }
200     else {  /* non-scalable font */
201         /* list it only if it has a proper aspect ratio */
202         HFONT   hFont;
203         LOGFONT Font;
204         TEXTMETRIC Metrics;
205 
206 	Font = *lf;
207 	Font.lfWidth = 0;
208 	hFont = CreateFontIndirect (&Font);
209 	GetFontMetrics (hFont, &Metrics, NULL);
210 	DeleteObject (hFont);
211 	if (tm->tmAveCharWidth == Metrics.tmAveCharWidth) {
212 	    AddSize (*(HWND FAR *)Data,
213                      (short int)lf->lfHeight, (short int)lf->lfWidth);
214 	}
215     }
216     return 1;
217 } /* EnumSizesProc */
218 
219 /* BuildSizeList:   initializes the FontSize list box */
220 /* =============                                      */
221 
222 static void PASCAL BuildSizeList (HWND hDlg, TEXTMETRIC *Metrics)
223 
224 /* This function initializes the FontSize list box with the sizes
225    available for the face name currently selected in the Font list box.
226    The sizes are written in the format: CXxCY. Also, the sizes are
227    stored in the 32 bit values retrievable by LB_GETITEMDATA: width in
228    the low-order word and height in the high order word */
229 {
230     SendDlgItemMessage (hDlg, ID_FONTSIZE, WM_SETREDRAW, FALSE, 0L);
231     SendDlgItemMessage (hDlg, ID_FONTSIZE, CB_RESETCONTENT, 0, 0L);
232     {
233 	HDC     hDC;
234 	FARPROC ProcInstance;
235 	char    FaceName[LF_FACESIZE];
236 
237 	SendDlgItemMessage (hDlg, ID_FONT, LB_GETTEXT,
238 			    (UINT)SendDlgItemMessage (hDlg, ID_FONT,
239 						      LB_GETCURSEL, 0, 0L),
240 			    (DWORD)(LPSTR)&FaceName[0]);
241 	    /* FaceName now contains the currently selected face name */
242 	hDC = GetDC (hDlg);
243 	ProcInstance = MakeProcInstance ((FARPROC)EnumSizesProc,
244 					 hEmacsInstance);
245 	EnumFonts (hDC, FaceName, ProcInstance, LPDATA(&hDlg));
246 	FreeProcInstance (ProcInstance);
247 	ReleaseDC (hDlg, hDC);
248 	if (SendDlgItemMessage (hDlg, ID_FONTSIZE, CB_GETCOUNT, 0, 0L) == 0) {
249 	    /* no size at all in the size list (ATM, for instance, does that!).
250                Let's fill it with a few sample sizes... */
251             short int h;
252 
253             for (h = 6; h <= 40; h += 2) AddSize (hDlg, h, 0);
254 	}
255     }
256     SendDlgItemMessage (hDlg, ID_FONTSIZE, WM_SETREDRAW, TRUE, 0L);
257     InvalidateRect (GetDlgItem (hDlg, ID_FONTSIZE), NULL, TRUE);
258     {   /*-Select the larger height that is smaller or equal to the
259 	   current Metrics (assumed to be the ones of the previous font)
260 	   */
261 	int     i;
262 	int     BestIndex = 0;
263 	short int h, w, BestHeight = 0, BestWidth = 0;
264 	DWORD   ItemData;
265 
266 	for (i = 0;; i++) {
267 	    ItemData = SendDlgItemMessage (hDlg, ID_FONTSIZE,
268 					   CB_GETITEMDATA, i, 0L);
269 	    if (ItemData == CB_ERR) break;  /* end of list hit */
270 	    if ((h = HIWORD(ItemData)) > Metrics->tmHeight) continue;
271 	    if (BestHeight > h) continue;
272 	    w = LOWORD(ItemData);
273 	    if (BestHeight == h) {  /* use the width to optimize */
274 		if (w > Metrics->tmAveCharWidth) continue;
275 		if (BestWidth > w) continue;
276 	    }
277 	    BestHeight = h;
278 	    BestWidth = w;
279 	    BestIndex = i;
280 	}
281 	SendDlgItemMessage (hDlg, ID_FONTSIZE, CB_SETCURSEL, BestIndex, 0L);
282     }
283     NewFont (hDlg, TRUE);
284 } /* BuildSizeList */
285 
286 /* AddFace: Adds a face to the FONT list box if it begets a proper font */
287 /* =======                                                              */
288 
289 static void PASCAL AddFace (HWND hDlg, char *CandidateFace)
290 {
291     BYTE    CharSet;
292     int     From, At;   /* indexes for list box searches */
293     HFONT   hFixedFont;
294     char    FaceName [LF_FACESIZE];
295     TEXTMETRIC tm;
296 
297     CharSet = (IsDlgButtonChecked (hDlg, ID_ANSI) ?
298                ANSI_CHARSET : OEM_CHARSET);
299     /*-try to identify a fixed-pitch font of set CharSet, with the
300        specified face name */
301     hFixedFont = CreateFont (0, 0, 0, 0, 0, FALSE, FALSE, FALSE,
302 			     CharSet, OUT_DEFAULT_PRECIS,
303 			     CLIP_DEFAULT_PRECIS, DRAFT_QUALITY,
304 			     FF_DONTCARE+FIXED_PITCH,
305 			     CandidateFace);
306     GetFontMetrics (hFixedFont, &tm, FaceName);
307     DeleteObject (hFixedFont);
308     if ((tm.tmPitchAndFamily & 0x01) || /* =1 if variable pitch */
309 	(tm.tmCharSet != CharSet) ||
310 	(strcmp (FaceName, CandidateFace) != 0)) {
311 	/* flunked the exam! */
312 	return;     /* skip that face */
313     }
314     /* the candidate face has at least one fixed-pitch font with the
315        right charset */
316     /*- scan the list box to make sure this face is not a duplicate */
317     At = -1;    /* start at beginning of list box */
318     do {
319 	From = At;
320 	At = SendDlgItemMessage (hDlg, ID_FONT, LB_FINDSTRING, From,
321                                  (DWORD)CandidateFace);
322         if (At == LB_ERR) break;    /* no match, implies not duplicate */
323 	if (SendDlgItemMessage (hDlg, ID_FONT, LB_GETTEXTLEN, At, 0L) ==
324             strlen(CandidateFace)) {
325             /* the lengths match, that means the strings match so it is
326 	       indeed a duplicate */
327 	    return;
328 	}
329     } while (At > From);    /* exit if search has gone through the
330 			       bottom of the list box */
331 
332     /*-it is a brand new face, let's add it to the list */
333     SendDlgItemMessage (hDlg, ID_FONT, LB_ADDSTRING, 0, (DWORD)CandidateFace);
334     return;
335 } /* AddFace */
336 
337 /* EnumFacesProc:   face enumeration function used by BuildFaceList */
338 /* =============                                                    */
339 int EXPORT FAR PASCAL EnumFacesProc (LPLOGFONT lf, LPTEXTMETRIC tm,
340                                      short FontType, LPSTR Data)
341 
342 /* Data should point to a handle to the dialog box */
343 /* lists only fixed pitch fonts that match the selected charset */
344 {
345     AddFace (*(HWND FAR *)Data, lf->lfFaceName);
346     return 1;
347 } /* EnumFacesProc */
348 
349 /* BuildFaceList:   initialize the FONT list box */
350 /* =============                                 */
351 
352 static void PASCAL BuildFaceList (HWND hDlg, char *FaceName)
353 
354 /* This function initializes the Font list box with fixed fonts matching
355    the current charset selection and then selects an item */
356 {
357     SendDlgItemMessage (hDlg, ID_FONTSIZE, WM_SETREDRAW, FALSE, 0L);
358     SendDlgItemMessage (hDlg, ID_FONT, LB_RESETCONTENT, 0, 0L);
359     {
360 	HDC     hDC;
361 	FARPROC ProcInstance;
362 
363 	hDC = GetDC (hDlg);
364 	ProcInstance = MakeProcInstance ((FARPROC)EnumFacesProc,
365 					 hEmacsInstance);
366 	EnumFonts (hDC, NULL, ProcInstance, LPDATA(&hDlg));
367 	FreeProcInstance (ProcInstance);
368 	ReleaseDC (hDlg, hDC);
369     }
370     SendDlgItemMessage (hDlg, ID_FONT, WM_SETREDRAW, TRUE, 0L);
371     InvalidateRect (GetDlgItem (hDlg, ID_FONT), NULL, TRUE);
372     /*-select the same facename as before or default to the first item */
373     if (SendDlgItemMessage (hDlg, ID_FONT, LB_SELECTSTRING, -1,
374                             (DWORD)FaceName) == LB_ERR) {
375 	SendDlgItemMessage (hDlg, ID_FONT, LB_SETCURSEL, 0, 0L);
376     }
377     BuildSizeList (hDlg, &Metrics);
378 } /* BuildFaceList */
379 
380 /* FontDlgProc: Emacs Font dialog box function */
381 /* ===========                                 */
382 int EXPORT FAR PASCAL  FontDlgProc (HWND hDlg, UINT wMsg, UINT wParam,
383 				    LONG lParam)
384 {
385     switch (wMsg) {
386 
387     case WM_INITDIALOG:
388         hNewFont = NULL;
389 	{   /*-setup the dialog box's caption */
390 	    char    s[40];
391 
392 	    strcpy (s, ProgName);
393 	    strcat (s, " - Font selection");
394 	    SetWindowText (hDlg, s);
395 	}
396 	/*-set the Bold button */
397 	GetFontMetrics (hEmacsFont, &Metrics, FaceName);
398 	CheckDlgButton (hDlg, ID_BOLD, (Metrics.tmWeight > 550));
399 	{   /*-simulate a mouse click on the appropriate charset
400 	       radiobutton. This will initialize all the other controls
401 	       */
402 	    WORD    id;
403 
404 	    id = (Metrics.tmCharSet == ANSI_CHARSET ? ID_ANSI : ID_OEM);
405 	    SendMessage (hDlg, WM_COMMAND,
406 #if WINDOW_MSWIN32
407                          MAKELONG(id, BN_CLICKED), (long)GetDlgItem (hDlg, id));
408 #else
409                          id, MAKELONG(GetDlgItem (hDlg, id), BN_CLICKED));
410 #endif
411 	}
412         return TRUE;
413 
414     case WM_COMMAND:
415 	switch (LOWORD(wParam)) {
416 	case 1:     /* OK button */
417 	    if (NOTIFICATION_CODE == BN_CLICKED) {
418 AcceptFont:
419 		if (hEmacsFont) DeleteObject (hEmacsFont);
420 		hEmacsFont = hNewFont;
421 		EndDialog (hDlg, TRUE);
422 		/* no need to unhook the SAMPLE's font, it is not
423 		   destroyed since it will be used by emacs */
424 	    }
425 	    else return FALSE;
426 	    break;
427 	case 2:     /* Cancel button */
428 	    if (NOTIFICATION_CODE == BN_CLICKED) goto CancelFont;
429 	    else return FALSE;
430 	case ID_SAVEFONT:
431 	    if (NOTIFICATION_CODE == BN_CLICKED) {
432 		/*-save the facename, bold status and size into EMACS.INI,
433 		   then perform as the OK button */
434 		char    NumText[17];
435 
436 		GetFontMetrics (hNewFont, &Metrics, FaceName);
437 
438 		WritePrivateProfileString (ProgName, "FontName", FaceName, IniFile);
439 		WritePrivateProfileString (ProgName, "CharSet",
440 		                    itoa (Metrics.tmCharSet, NumText, 10), IniFile);
441 		WritePrivateProfileString (ProgName, "FontHeight",
442 		                    itoa (Metrics.tmHeight, NumText, 10), IniFile);
443 		WritePrivateProfileString (ProgName, "FontWidth",
444 		                    itoa (Metrics.tmAveCharWidth,
445                                           NumText, 10), IniFile);
446 		WritePrivateProfileString (ProgName, "FontWeight",
447 		                    itoa (Metrics.tmWeight, NumText, 10), IniFile);
448             }
449 	    else
450 		return FALSE;
451 	    goto AcceptFont;
452 	case ID_ANSI:
453 	case ID_OEM:
454 	    if (NOTIFICATION_CODE == BN_CLICKED) {
455 	        CheckRadioButton (hDlg, ID_1ST_CHARSET, ID_LAST_CHARSET,
456                                   LOWORD(wParam));
457 		BuildFaceList (hDlg, FaceName);
458 	    }
459 	    else return FALSE;
460 	    break;
461 	case ID_BOLD:
462 	    if (NOTIFICATION_CODE == BN_CLICKED) NewFont (hDlg, TRUE);
463 	    else return FALSE;
464 	    break;
465 	case ID_FONT:
466 	    switch (NOTIFICATION_CODE) {
467 	    case LBN_SELCHANGE:
468 		BuildSizeList (hDlg, &Metrics);
469 		break;
470 	    case LBN_DBLCLK:    /* treated as OK */
471 		goto AcceptFont;
472 	    default:
473 		return FALSE;
474 	    }
475 	    break;
476 	case ID_FONTSIZE:
477 	    switch (NOTIFICATION_CODE) {
478 	    case CBN_SELCHANGE:
479 		NewFont (hDlg, FALSE);
480 		break;
481 	    case CBN_EDITCHANGE:
482 	        {
483 		    BOOL    FontSizeOK;
484 
485 		    GetDlgItemInt (hDlg, ID_FONTSIZE, &FontSizeOK, FALSE);
486 		    if (FontSizeOK) NewFont (hDlg, TRUE);
487 		    else MessageBeep (0);
488 		}
489 		break;
490 	    case CBN_DBLCLK:    /* treated as OK */
491 		goto AcceptFont;
492 	    default:
493 		return FALSE;
494 	    }
495 	    break;
496 	default:
497 	    return FALSE;
498         }
499 	break;
500     case WM_SYSCOMMAND:
501 	if ((wParam & 0xFFF0) == SC_CLOSE) {
502 CancelFont:
503 	    EndDialog (hDlg, FALSE);
504 	    if (hNewFont) {
505 		SendDlgItemMessage (hDlg, ID_SAMPLE, WM_SETFONT, 0, FALSE);
506 		    /* reset to SYSTEM_FONT before deleting the font */
507 		DeleteObject (hNewFont);
508 	    }
509 	    return TRUE;
510 	}
511 	return FALSE;
512     default:
513 	return FALSE;
514     }
515     return FALSE;
516 } /* FontDlgProc */
517 
518 /* ChangeFont:  effects the font change on the screen & message line */
519 /* ==========                                                         */
520 static void PASCAL ChangeFont (void)
521 
522 {
523     SCREEN  *sp, *fsp;
524     RECT    Rect;
525 
526     /*-loop through all the screens, resizing the vision that emacs has
527        of them, processing the current ("first") screen last */
528     InternalRequest = TRUE;
529     fsp = first_screen;
530     do {
531 	sp = first_screen;
532 	while (sp->s_next_screen != (SCREEN *)NULL) sp = sp->s_next_screen;
533         select_screen (sp, FALSE);
534         GetClientRect (sp->s_drvhandle, &Rect);
535         newwidth (TRUE, DisplayableColumns (sp->s_drvhandle,
536                                             Rect.right, &EmacsCM));
537         newsize (TRUE, DisplayableRows (sp->s_drvhandle,
538                                         Rect.bottom, &EmacsCM));
539     } while (sp != fsp);
540     InternalRequest = FALSE;
541 
542     /*-update the frame's client area and the MDIClient's size */
543     InvalidateRect (hFrameWnd, NULL, TRUE);
544     GetClientRect (hFrameWnd, &Rect);
545     MoveWindow (hMDIClientWnd, 0, 0,
546                 Rect.right, Rect.bottom - EmacsCM.MLHeight,
547                 TRUE);
548 } /* ChangeFont */
549 
550 /* PickEmacsFont:   calls-up the FONTS dialog box */
551 /* =============                                  */
552 
553 BOOL FAR PASCAL PickEmacsFont (void)
554 
555 /* returns TRUE is a new font has been picked */
556 {
557     BOOL    FontChanged;
558     FARPROC ProcInstance;
559 
560     ProcInstance = MakeProcInstance ((FARPROC)FontDlgProc,
561 				     hEmacsInstance);
562     FontChanged = DialogBox (hEmacsInstance, "FONTS",
563 			     hFrameWnd, ProcInstance);
564     FreeProcInstance (ProcInstance);
565 
566     if (FontChanged) {
567 	BuildCellMetrics (&EmacsCM, hEmacsFont);
568         ChangeFont ();
569 	return TRUE;
570     }
571     else return FALSE;
572 } /* PickEmacsFont */
573 
574 /* FontInit:    initialize a font description from WIN.INI */
575 /* ========                                                */
576 
577 void FAR PASCAL FontInit (void)
578 {
579     LOGFONT lf;
580     char    text[20];
581 
582     if (GetPrivateProfileString (ProgName, "CharSet", "", text, 20, IniFile)) {
583 
584         if (isdigit(text[0])) { /* pure numeric value */
585             lf.lfCharSet = atoi (text);
586         }
587         else {  /* menmonic value */
588 	    if (strncmp (text, "OEM", 3) == 0) {
589 		lf.lfCharSet = OEM_CHARSET;
590 	    }
591 	    else lf.lfCharSet = ANSI_CHARSET;
592 	}
593 
594 	lf.lfHeight = GetPrivateProfileInt (ProgName, "FontHeight", 0, IniFile);
595 	lf.lfWidth = GetPrivateProfileInt (ProgName, "FontWidth", 0, IniFile);
596 	lf.lfWeight = GetPrivateProfileInt (ProgName, "FontWeight", 400, IniFile);
597 
598 	lf.lfEscapement = 0;
599 	lf.lfOrientation = 0;
600 	lf.lfItalic = 0;
601 	lf.lfUnderline = 0;
602 	lf.lfStrikeOut = 0;
603 	lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
604 	lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
605 	lf.lfQuality = DEFAULT_QUALITY;
606 	lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
607 
608         GetPrivateProfileString (ProgName, "FontName", "",
609                           lf.lfFaceName, LF_FACESIZE, IniFile);
610 
611         hEmacsFont = CreateFontIndirect (&lf);
612     }
613     else {  /* no CharSet entry, default to SYSTEM_FIXED_FONT */
614 	hEmacsFont = 0;
615     }
616     BuildCellMetrics (&EmacsCM, hEmacsFont);
617 } /* FontInit */
618