1 /*
2  * GraphApp - Cross-Platform Graphics Programming Library.
3  *
4  * File: fonts.c -- font selection functions.
5  * Platform: Windows  Version: 2.35  Date: 1998/04/04
6  *
7  * Version: 1.00  Changes: Original version by Lachlan Patrick.
8  * Version: 2.00  Changes: New object class system.
9  * Version: 2.30  Changes: Now uses font_base.
10  * Version: 2.35  Changes: New reference count technique.
11  */
12 
13 /* Copyright (C) 1993-1998 Lachlan Patrick
14 
15    This file is part of GraphApp, a cross-platform C graphics library.
16 
17    GraphApp is free software; you can redistribute it and/or modify it
18    under the terms of the GNU Library General Public License.
19    GraphApp is distributed in the hope that it will be useful, but
20    WITHOUT ANY WARRANTY.
21 
22    See the file COPYLIB.TXT for details.
23 */
24 
25 /* Changes for R:
26 
27    Use default GUI font
28    Do not delete FixedFont
29 
30  */
31 
32 #include "internal.h"
33 
34 /*
35  *  Pre-defined library fonts.
36  */
37 __declspec(dllexport)	font SystemFont = NULL;
38 __declspec(dllexport)	font FixedFont  = NULL;
39 __declspec(dllexport)	font Times      = NULL;
40 __declspec(dllexport)	font Helvetica  = NULL;
41 __declspec(dllexport)	font Courier    = NULL;
42 
43 /*
44  *  Dots per inch for the screen.
45  */
46 	static int screen_dpix = 96;	/* logical dpi for VGA */
47 	static int screen_dpiy = 96;	/* logical dpi for VGA */
48 
49 /*
50  *  Private font destructor. Calls the Windows functions needed
51  *  to free the object from GDI memory.
52  */
private_delfont(font f)53 static void private_delfont(font f)
54 {
55     if (f && (f != SystemFont) && (f != FixedFont) && (f->handle))
56 	DeleteObject(f->handle);
57 }
58 
59 /*
60  *  Private object constructor.
61  */
get_font_base(void)62 static object get_font_base(void)
63 {
64     static object font_base = NULL;
65 
66     if (! font_base)
67 	font_base = new_object(BaseObject, 0, NULL);
68     return font_base;
69 }
70 
new_font_object(HFONT hf)71 PROTECTED font new_font_object(HFONT hf)
72 {
73     TEXTMETRIC tm;
74     HDC dc;
75     HFONT old;
76     object obj;
77 
78     obj = new_object(FontObject, hf, get_font_base());
79     if (! obj) {
80 	DeleteObject(hf);
81 	return NULL;
82     }
83     obj->die = private_delfont;
84 
85     dc = GetDC(0);
86     old = SelectObject(dc, hf);
87     GetTextMetrics(dc, &tm);
88 
89     obj->depth = 1;
90     obj->rect.width = tm.tmAveCharWidth;
91     obj->rect.height = tm.tmHeight;
92     obj->rect.x = tm.tmAscent - tm.tmInternalLeading;
93     obj->rect.y = tm.tmDescent;
94 
95     SelectObject(dc, old);
96     ReleaseDC(0, dc);
97 
98     return (font) obj;
99 }
100 
getSysFontSize()101 rect getSysFontSize()
102 {
103     return  SystemFont->rect;
104 }
105 
106 
107 /*
108  *  Private font initialisation function.
109  */
110 PROTECTED
init_fonts(void)111 void init_fonts(void)
112 {
113     HDC info;
114     NONCLIENTMETRICS ncm;
115 
116     /* get system information */
117     info = CreateIC("DISPLAY", NULL, NULL, NULL);
118     screen_dpix = GetDeviceCaps(info, LOGPIXELSX);
119     screen_dpiy = GetDeviceCaps(info, LOGPIXELSY);
120     DeleteDC(info);
121 
122     /* set up standard fonts */
123     /* Claim that this was wrong:
124        http://blogs.msdn.com/oldnewthing/archive/2005/07/07/436435.aspx
125 
126        SystemFont = new_font_object(GetStockObject(DEFAULT_GUI_FONT));
127     */
128     ncm.cbSize = sizeof(NONCLIENTMETRICS);
129     SystemParametersInfo(SPI_GETNONCLIENTMETRICS, ncm.cbSize, &ncm, 0);
130     SystemFont = new_font_object(CreateFontIndirect(&ncm.lfMenuFont));
131     if (SystemFont) SystemFont->text = new_string("SystemFont");
132 
133     FixedFont = new_font_object(GetStockObject(OEM_FIXED_FONT));
134     Times = newfont("Times New Roman", Plain, -10);
135     Helvetica = newfont("Arial", SansSerif, -10);
136     Courier = newfont("Courier New", FixedWidth, -10);
137 
138     protect_object(SystemFont);
139     protect_object(FixedFont);
140     protect_object(Times);
141     protect_object(Helvetica);
142     protect_object(Courier);
143 }
144 
145 /*
146  *  Load a font by name.
147  */
newfont(const char * name,int style,int size)148 font newfont(const char *name, int style, int size)
149 {
150     font obj;
151     HFONT hf;
152     LOGFONT lf;
153 
154     initapp(0,NULL);
155 
156     /* This next calculation should convert from point size to
157        pixels.  We use this since we always use the MM_TEXT mode,
158        which is in pixels. */
159     /* Windows requires the lfHeight field must be negative
160        to specify point size, positive to specify pixel size. */
161 
162     if (size < 0) /* negative size indicates this is a point size */
163 	lf.lfHeight = ((screen_dpiy * size)/72);
164     else /* positive size indicates a pixel height for the font */
165 	lf.lfHeight = size;
166 
167     lf.lfWidth = lf.lfEscapement = lf.lfOrientation = 0;
168     lf.lfWeight = FW_NORMAL;
169     lf.lfItalic = lf.lfUnderline = lf.lfStrikeOut = 0;
170     lf.lfCharSet = ANSI_CHARSET;
171     if ((! string_diff(name, "Symbol"))
172 	|| (! string_diff(name, "Wingdings")))
173 	lf.lfCharSet = SYMBOL_CHARSET;
174     lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
175     lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
176     lf.lfQuality = DEFAULT_QUALITY;
177     lf.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
178     if ((name != 0) && (*name != '\0'))
179 	strncpy(lf.lfFaceName, name, LF_FACESIZE-1);
180 
181     if (style & Italic)
182 	lf.lfItalic = 1;
183     if (style & Bold)
184 	lf.lfWeight = FW_BOLD;
185     if (style & FixedWidth)
186 	lf.lfPitchAndFamily |= FIXED_PITCH;
187     if (style & SansSerif)
188 	lf.lfPitchAndFamily |= FF_SWISS;
189 
190     if ((hf = CreateFontIndirect(&lf)) == 0)
191 	return NULL;
192 
193     obj = new_font_object(hf);
194     if (obj)
195 	obj->text = new_string(name);
196 
197     return (font) obj;
198 }
199 
200 /*
201  *  Discover the sizes of a font.
202  */
fontwidth(font obj)203 int fontwidth(font obj)   { return obj->rect.width; }
fontheight(font obj)204 int fontheight(font obj)  { return obj->rect.height; }
fontascent(font obj)205 int fontascent(font obj)  { return obj->rect.x; }
fontdescent(font obj)206 int fontdescent(font obj) { return obj->rect.y; }
207