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