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