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