]> git.lyx.org Git - lyx.git/blob - src/FontInfo.C
paragraph-spacing, redoparagraph in deleteemptyparagraphmechanism, got rid of some...
[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 #include FORMS_H_LOCATION
17
18 #ifdef __GNUG__
19 #pragma implementation "FontInfo.h"
20 #endif
21
22 #include "FontInfo.h"
23 #include "debug.h"
24 #include "lyxrc.h"      // lyxrc.use_scalable_fonts
25 #include "support/lstrings.h"
26
27 using std::endl;
28
29 /// Load font close to this size
30 string FontInfo::getFontname(int size)
31 {
32         if (!exist())
33                 return string();
34
35         int closestind = -1;
36         double error = 100000;
37
38         for (int i = 0; i < matches; ++i) {
39                 if (sizes[i] == 0) {
40                         // Scalable font should not be considered close
41                 } else if (sizes[i] == size) {
42                         lyxerr[Debug::FONT] << "Exact font match with\n"
43                                             << strings[i] << endl;
44                         return strings[i];
45                 } else if (fabs(sizes[i] - size - 0.1) < error) {
46                         error = fabs(sizes[i] - size - 0.1);
47                         closestind = i;
48                 }
49         }
50
51         if (scalable && lyxrc.use_scalable_fonts) {
52                 // We can use scalable
53                 string font = resize(strings[scaleindex], size);
54                 lyxerr[Debug::FONT] << "Using scalable font to get\n"
55                                     << font << endl;
56                 return font;
57         }
58
59         // Did any fonts get close?
60         if (closestind == -1) {
61                 // No, and we are not allowed to use scalables, so...
62                 return string();
63         }
64
65         // We use the closest match
66         lyxerr[Debug::FONT] << "Using closest font match to get size "
67                             << size 
68                             << " with\n" << strings[closestind] << endl;
69         return strings[closestind];
70 }
71
72
73 /// Build newly sized font string 
74 string FontInfo::resize(string const & font, int size) const
75 {
76         string ret(font);
77         // Find the position of the size spec
78         int cut = 0;
79         string::iterator before = string::iterator(0);
80         string::iterator after = string::iterator(0);
81         for (string::iterator sit = ret.begin();
82              sit != ret.end(); ++sit)
83                 if ((*sit) == '-') {
84                         ++cut;
85                         if (cut == 7) before = sit + 1;
86                         else if (cut == 8) {
87                                 after = sit;
88                                 break;
89                         }
90                 }
91         ret.replace(before, after, tostr(size));
92         return ret;
93 }
94
95
96 /// Set new pattern
97 void FontInfo::setPattern(string const & pat)
98 {
99         release();
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 << "Can not 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_display, pattern.c_str(), 100, &matches);
121
122         if (list == 0) {
123                 // No fonts matched
124                 scalable = false;
125                 sizes = 0;
126         } else {
127                 release();
128                 sizes = new int[matches];
129                 strings = 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                         sizes[i] = atoi(token(name, '-', 7).c_str());
135                         strings[i] = name;
136                         if (sizes[i] == 0) {
137                                 if (scaleindex == -1) {
138                                         scaleindex = i;
139                                 }
140                                 scalable = true;
141                         };
142                 };
143                 XFreeFontNames(list);
144         }
145         queried = true;
146 }
147
148
149 void FontInfo::init()
150 {
151         sizes = 0;
152         strings = 0;
153         matches = 0;
154         queried = false;
155         scalable = false;
156         scaleindex = -1;
157 }
158
159
160 /// Release allocated stuff
161 void FontInfo::release()
162 {
163         if (sizes) {
164                 delete [] sizes;
165                 sizes = 0;
166         }
167         if (strings) {
168                 delete [] strings;
169                 strings = 0;
170         }
171 }