]> git.lyx.org Git - lyx.git/blob - src/FontInfo.C
fix typo that put too many include paths for most people
[lyx.git] / src / FontInfo.C
1 /* This file is part of
2  * ======================================================
3  *
4  *           LyX, The Document Processor
5  *
6  *          Copyright 1997 Asger Alstrup
7  *           and the LyX Team.
8  *
9  * ====================================================== */
10
11 #include <config.h>
12
13 #ifdef __GNUG__
14 #pragma implementation
15 #endif
16
17 #include "FontInfo.h"
18 #include "debug.h"
19 #include "lyxrc.h"      // lyxrc.use_scalable_fonts
20
21 #include "support/lstrings.h"
22 #include "support/lyxlib.h"
23
24 #include "frontends/GUIRunTime.h"
25
26 #include <cmath>        // abs()
27
28 using std::endl;
29 using std::abs;
30
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 (abs(sizes[i] - size - 0.1) < error) {
49                         error = abs(sizes[i] - size - 0.1);
50                         closestind = i;
51                 }
52         }
53
54         if (scalable && (lyxrc.use_scalable_fonts || closestind == -1)) {
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, 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         init();
103         pattern = pat;
104 }
105
106
107 /// Query font in X11
108 void FontInfo::query()
109 {
110         if (queried)
111                 return;
112
113         if (pattern.empty()) {
114                 lyxerr << "Cannot use empty font name for font query."
115                        << endl;
116                 queried = true;
117                 return;
118         }
119
120         char ** list = 0;
121         if (lyxrc.use_gui)
122                 list = XListFonts(GUIRunTime::x11Display(), pattern.c_str(),
123                                   100, &matches);
124
125         if (list == 0) {
126                 // No fonts matched
127                 scalable = false;
128                 sizes.reset();
129         } else {
130                 sizes.reset(new int[matches]);
131                 strings.reset(new string[matches]);
132
133                 // We have matches. Run them through
134                 for (int i = 0; i < matches; ++i) {
135                         string name(list[i]);
136                         lyxerr[Debug::FONT] << "match #" << i << " "
137                                             << name << endl;
138                         sizes[i] = lyx::atoi(token(name, '-', 7));
139                         strings[i] = name;
140                         if (sizes[i] == 0) {
141                                 if (scaleindex == -1) {
142                                         scaleindex = i;
143                                 }
144                                 scalable = true;
145                         };
146                 };
147                 XFreeFontNames(list);
148         }
149         queried = true;
150 }
151
152
153 void FontInfo::init()
154 {
155         sizes.reset();
156         strings.reset();
157         matches = 0;
158         queried = false;
159         scalable = false;
160         scaleindex = -1;
161 }