]> git.lyx.org Git - lyx.git/blob - src/FontInfo.C
38579ce2eadd0bdd0c046ac6ce98e30276f831dc
[lyx.git] / src / FontInfo.C
1 // -*- C++ -*-
2 /* This file is part of
3  * ====================================================== 
4  * 
5  *           LyX, The Document Processor
6  *       
7  *          Copyright 1997 Asger Alstrup
8  *           and the LyX Team.
9  *
10  * ====================================================== */
11
12 #include <config.h>
13 #include <cmath>        // fabs()
14
15 #include FORMS_H_LOCATION
16
17 #ifdef __GNUG__
18 #pragma implementation "FontInfo.h"
19 #endif
20
21 #include "FontInfo.h"
22 #include "debug.h"
23 #include "lyxrc.h"      // lyxrc.use_scalable_fonts
24 #include "support/lstrings.h"
25
26 using std::endl;
27
28 #ifndef CXX_GLOBAL_CSTD
29 using std::fabs;
30 #endif
31
32 /// Load font close to this size
33 string const FontInfo::getFontname(int size)
34 {
35         if (!exist())
36                 return string();
37
38         int closestind = -1;
39         double error = 100000.0;
40
41         for (int i = 0; i < matches; ++i) {
42                 if (sizes[i] == 0) {
43                         // Scalable font should not be considered close
44                 } else if (sizes[i] == size) {
45                         lyxerr[Debug::FONT] << "Exact font match with\n"
46                                             << strings[i] << endl;
47                         return strings[i];
48                 } else if (fabs(sizes[i] - size - 0.1) < error) {
49                         error = fabs(sizes[i] - size - 0.1);
50                         closestind = i;
51                 }
52         }
53
54         if (scalable && lyxrc.use_scalable_fonts) {
55                 // We can use scalable
56                 string const font = resize(strings[scaleindex], size);
57                 lyxerr[Debug::FONT] << "Using scalable font to get\n"
58                                     << font << endl;
59                 return font;
60         }
61
62         // Did any fonts get close?
63         if (closestind == -1) {
64                 // No, and we are not allowed to use scalables, so...
65                 return string();
66         }
67
68         // We use the closest match
69         lyxerr[Debug::FONT] << "Using closest font match to get size "
70                             << size 
71                             << " with\n" << strings[closestind] << endl;
72         return strings[closestind];
73 }
74
75
76 /// Build newly sized font string 
77 string const FontInfo::resize(string const & font, int size) const
78 {
79         string ret(font);
80         // Find the position of the size spec
81         int cut = 0;
82         string::iterator before = string::iterator(0);
83         string::iterator after = string::iterator(0);
84         for (string::iterator sit = ret.begin();
85              sit != ret.end(); ++sit)
86                 if ((*sit) == '-') {
87                         ++cut;
88                         if (cut == 7) before = sit + 1;
89                         else if (cut == 8) {
90                                 after = sit;
91                                 break;
92                         }
93                 }
94         ret.replace(before, after, tostr(size));
95         return ret;
96 }
97
98
99 /// Set new pattern
100 void FontInfo::setPattern(string const & pat)
101 {
102         release();
103         init();
104         pattern = pat;
105 }
106
107
108 /// Query font in X11
109 void FontInfo::query()
110 {
111         if (queried)
112                 return;
113
114         if (pattern.empty()) {
115                 lyxerr << "Can not use empty font name for font query."
116                        << endl;
117                 queried = true;
118                 return;
119         }
120
121         char ** list = 0;
122         if (lyxrc.use_gui)
123                 list = XListFonts(fl_get_display(), pattern.c_str(), 100, &matches);
124
125         if (list == 0) {
126                 // No fonts matched
127                 scalable = false;
128                 sizes = 0;
129         } else {
130                 release();
131                 sizes = new int[matches];
132                 strings = new string[matches];
133
134                 // We have matches. Run them through
135                 for (int i = 0; i < matches; ++i) {
136                         string name(list[i]);
137                         sizes[i] = lyx::atoi(token(name, '-', 7));
138                         strings[i] = name;
139                         if (sizes[i] == 0) {
140                                 if (scaleindex == -1) {
141                                         scaleindex = i;
142                                 }
143                                 scalable = true;
144                         };
145                 };
146                 XFreeFontNames(list);
147         }
148         queried = true;
149 }
150
151
152 void FontInfo::init()
153 {
154         sizes = 0;
155         strings = 0;
156         matches = 0;
157         queried = false;
158         scalable = false;
159         scaleindex = -1;
160 }
161
162
163 /// Release allocated stuff
164 void FontInfo::release()
165 {
166         if (sizes) {
167                 delete [] sizes;
168                 sizes = 0;
169         }
170         if (strings) {
171                 delete [] strings;
172                 strings = 0;
173         }
174 }