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