1 | // |
---|
2 | // "$Id$" |
---|
3 | // |
---|
4 | // WIN32 font utilities for the Fast Light Tool Kit (FLTK). |
---|
5 | // |
---|
6 | // Copyright 1998-2005 by Bill Spitzak and others. |
---|
7 | // |
---|
8 | // This library is free software; you can redistribute it and/or |
---|
9 | // modify it under the terms of the GNU Library General Public |
---|
10 | // License as published by the Free Software Foundation; either |
---|
11 | // version 2 of the License, or (at your option) any later version. |
---|
12 | // |
---|
13 | // This library is distributed in the hope that it will be useful, |
---|
14 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
15 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
---|
16 | // Library General Public License for more details. |
---|
17 | // |
---|
18 | // You should have received a copy of the GNU Library General Public |
---|
19 | // License along with this7 library; if not, write to the Free Software |
---|
20 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 |
---|
21 | // USA. |
---|
22 | // |
---|
23 | // Please report all bugs and problems on the following page: |
---|
24 | // |
---|
25 | // http://www.fltk.org/str.php |
---|
26 | // |
---|
27 | |
---|
28 | // This function fills in the FLTK font table with all the fonts that |
---|
29 | // are found on the X server. It tries to place the fonts into families |
---|
30 | // and to sort them so the first 4 in a family are normal, bold, italic, |
---|
31 | // and bold italic. |
---|
32 | |
---|
33 | // Bug: older versions calculated the value for *ap as a side effect of |
---|
34 | // making the name, and then forgot about it. To avoid having to change |
---|
35 | // the header files I decided to store this value in the last character |
---|
36 | // of the font name array. |
---|
37 | #define ENDOFBUFFER 127 // sizeof(Fl_Font.fontname)-1 |
---|
38 | |
---|
39 | // turn a stored font name into a pretty name: |
---|
40 | const char* Fl::get_font_name(Fl_Font fnum, int* ap) { |
---|
41 | Fl_Fontdesc *f = fl_fonts + fnum; |
---|
42 | if (!f->fontname[0]) { |
---|
43 | const char* p = f->name; |
---|
44 | if (!p || !*p) {if (ap) *ap = 0; return "";} |
---|
45 | int type; |
---|
46 | switch (*p) { |
---|
47 | case 'B': type = FL_BOLD; break; |
---|
48 | case 'I': type = FL_ITALIC; break; |
---|
49 | case 'P': type = FL_BOLD | FL_ITALIC; break; |
---|
50 | default: type = 0; break; |
---|
51 | } |
---|
52 | strlcpy(f->fontname, p+1, ENDOFBUFFER); |
---|
53 | if (type & FL_BOLD) strlcat(f->fontname, " bold", ENDOFBUFFER); |
---|
54 | if (type & FL_ITALIC) strlcat(f->fontname, " italic", ENDOFBUFFER); |
---|
55 | f->fontname[ENDOFBUFFER] = (char)type; |
---|
56 | } |
---|
57 | if (ap) *ap = f->fontname[ENDOFBUFFER]; |
---|
58 | return f->fontname; |
---|
59 | } |
---|
60 | |
---|
61 | static int fl_free_font = FL_FREE_FONT; |
---|
62 | |
---|
63 | static int CALLBACK |
---|
64 | enumcb(CONST LOGFONT *lpelf, |
---|
65 | CONST TEXTMETRIC * /*lpntm*/, |
---|
66 | DWORD /*FontType*/, |
---|
67 | LPARAM p) { |
---|
68 | if (!p && lpelf->lfCharSet != ANSI_CHARSET) return 1; |
---|
69 | const char *n = lpelf->lfFaceName; |
---|
70 | for (int i=0; i<FL_FREE_FONT; i++) // skip if one of our built-in fonts |
---|
71 | if (!strcmp(Fl::get_font_name((Fl_Font)i),n)) return 1; |
---|
72 | char buffer[LF_FACESIZE + 1]; |
---|
73 | strcpy(buffer+1, n); |
---|
74 | buffer[0] = ' '; Fl::set_font((Fl_Font)(fl_free_font++), strdup(buffer)); |
---|
75 | if (lpelf->lfWeight <= 400) |
---|
76 | buffer[0] = 'B', Fl::set_font((Fl_Font)(fl_free_font++), strdup(buffer)); |
---|
77 | buffer[0] = 'I'; Fl::set_font((Fl_Font)(fl_free_font++), strdup(buffer)); |
---|
78 | if (lpelf->lfWeight <= 400) |
---|
79 | buffer[0] = 'P', Fl::set_font((Fl_Font)(fl_free_font++), strdup(buffer)); |
---|
80 | return 1; |
---|
81 | } |
---|
82 | |
---|
83 | Fl_Font Fl::set_fonts(const char* xstarname) { |
---|
84 | if (fl_free_font == FL_FREE_FONT) {// if not already been called |
---|
85 | if (!fl_gc) fl_GetDC(0); |
---|
86 | EnumFontFamilies(fl_gc, NULL, (FONTENUMPROC)enumcb, xstarname != 0); |
---|
87 | } |
---|
88 | return (Fl_Font)fl_free_font; |
---|
89 | } |
---|
90 | |
---|
91 | |
---|
92 | static int nbSize; |
---|
93 | static int cyPerInch; |
---|
94 | static int sizes[128]; |
---|
95 | |
---|
96 | static int CALLBACK |
---|
97 | EnumSizeCb(CONST LOGFONT * /*lpelf*/, |
---|
98 | CONST TEXTMETRIC *lpntm, |
---|
99 | DWORD fontType, |
---|
100 | LPARAM /*p*/) { |
---|
101 | if ((fontType & RASTER_FONTTYPE) == 0) { |
---|
102 | sizes[0] = 0; |
---|
103 | nbSize = 1; |
---|
104 | |
---|
105 | // Scalable font |
---|
106 | return 0; |
---|
107 | } |
---|
108 | |
---|
109 | int add = lpntm->tmHeight - lpntm->tmInternalLeading; |
---|
110 | add = MulDiv(add, 72, cyPerInch); |
---|
111 | |
---|
112 | int start = 0; |
---|
113 | while ((start < nbSize) && (sizes[start] < add)) { |
---|
114 | start++; |
---|
115 | } |
---|
116 | |
---|
117 | if ((start < nbSize) && (sizes[start] == add)) { |
---|
118 | return 1; |
---|
119 | } |
---|
120 | |
---|
121 | for (int i=nbSize; i>start; i--) sizes[i] = sizes[i - 1]; |
---|
122 | |
---|
123 | sizes[start] = add; |
---|
124 | nbSize++; |
---|
125 | |
---|
126 | // Stop enum if buffer overflow |
---|
127 | return nbSize < 128; |
---|
128 | } |
---|
129 | |
---|
130 | |
---|
131 | int |
---|
132 | Fl::get_font_sizes(Fl_Font fnum, int*& sizep) { |
---|
133 | nbSize = 0; |
---|
134 | Fl_Fontdesc *s = fl_fonts+fnum; |
---|
135 | if (!s->name) s = fl_fonts; // empty slot in table, use entry 0 |
---|
136 | |
---|
137 | if (!fl_gc) fl_GetDC(0); |
---|
138 | cyPerInch = GetDeviceCaps(fl_gc, LOGPIXELSY); |
---|
139 | if (cyPerInch < 1) cyPerInch = 1; |
---|
140 | EnumFontFamilies(fl_gc, s->name+1, (FONTENUMPROC)EnumSizeCb, 0); |
---|
141 | |
---|
142 | sizep = sizes; |
---|
143 | return nbSize; |
---|
144 | } |
---|
145 | |
---|
146 | |
---|
147 | // |
---|
148 | // End of "$Id$". |
---|
149 | // |
---|