]> git.lyx.org Git - lyx.git/blob - src/FontInfo.C
use more std::functors add some of my own, some change to fl_display etc. read the...
[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 /// Load font close to this size
29 string const FontInfo::getFontname(int size)
30 {
31         if (!exist())
32                 return string();
33
34         int closestind = -1;
35         double error = 100000;
36
37         for (int i = 0; i < matches; ++i) {
38                 if (sizes[i] == 0) {
39                         // Scalable font should not be considered close
40                 } else if (sizes[i] == size) {
41                         lyxerr[Debug::FONT] << "Exact font match with\n"
42                                             << strings[i] << endl;
43                         return strings[i];
44                 } else if (fabs(sizes[i] - size - 0.1) < error) {
45                         error = fabs(sizes[i] - size - 0.1);
46                         closestind = i;
47                 }
48         }
49
50         if (scalable && lyxrc.use_scalable_fonts) {
51                 // We can use scalable
52                 string font = resize(strings[scaleindex], size);
53                 lyxerr[Debug::FONT] << "Using scalable font to get\n"
54                                     << font << endl;
55                 return font;
56         }
57
58         // Did any fonts get close?
59         if (closestind == -1) {
60                 // No, and we are not allowed to use scalables, so...
61                 return string();
62         }
63
64         // We use the closest match
65         lyxerr[Debug::FONT] << "Using closest font match to get size "
66                             << size 
67                             << " with\n" << strings[closestind] << endl;
68         return strings[closestind];
69 }
70
71
72 /// Build newly sized font string 
73 string const FontInfo::resize(string const & font, int size) const
74 {
75         string ret(font);
76         // Find the position of the size spec
77         int cut = 0;
78         string::iterator before = string::iterator(0);
79         string::iterator after = string::iterator(0);
80         for (string::iterator sit = ret.begin();
81              sit != ret.end(); ++sit)
82                 if ((*sit) == '-') {
83                         ++cut;
84                         if (cut == 7) before = sit + 1;
85                         else if (cut == 8) {
86                                 after = sit;
87                                 break;
88                         }
89                 }
90         ret.replace(before, after, tostr(size));
91         return ret;
92 }
93
94
95 /// Set new pattern
96 void FontInfo::setPattern(string const & pat)
97 {
98         release();
99         init();
100         pattern = pat;
101 }
102
103
104 /// Query font in X11
105 void FontInfo::query()
106 {
107         if (queried)
108                 return;
109
110         if (pattern.empty()) {
111                 lyxerr << "Can not use empty font name for font query."
112                        << endl;
113                 queried = true;
114                 return;
115         }
116
117         char ** list = 0;
118         if (lyxrc.use_gui)
119                 list = XListFonts(fl_get_display(), pattern.c_str(), 100, &matches);
120
121         if (list == 0) {
122                 // No fonts matched
123                 scalable = false;
124                 sizes = 0;
125         } else {
126                 release();
127                 sizes = new int[matches];
128                 strings = new string[matches];
129
130                 // We have matches. Run them through
131                 for(int i = 0; i < matches; ++i) {
132                         string name(list[i]);
133                         sizes[i] = lyx::atoi(token(name, '-', 7));
134                         strings[i] = name;
135                         if (sizes[i] == 0) {
136                                 if (scaleindex == -1) {
137                                         scaleindex = i;
138                                 }
139                                 scalable = true;
140                         };
141                 };
142                 XFreeFontNames(list);
143         }
144         queried = true;
145 }
146
147
148 void FontInfo::init()
149 {
150         sizes = 0;
151         strings = 0;
152         matches = 0;
153         queried = false;
154         scalable = false;
155         scaleindex = -1;
156 }
157
158
159 /// Release allocated stuff
160 void FontInfo::release()
161 {
162         if (sizes) {
163                 delete [] sizes;
164                 sizes = 0;
165         }
166         if (strings) {
167                 delete [] strings;
168                 strings = 0;
169         }
170 }