]> git.lyx.org Git - lyx.git/blob - src/FontInfo.C
7ac5e6bb29ab99701e765aa1f267425599e223bb
[lyx.git] / src / FontInfo.C
1 // -*- C++ -*-
2 /* This file is part of
3  * ======================================================
4  * 
5  *           LyX, The Document Processor
6  *       
7  *          Copyright (C) 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 /// Build newly sized font string 
71 string FontInfo::resize(string const & font, int size) const {
72         // Find the position of the size spec
73 #ifdef WITH_WARNINGS
74 #warning rewrite to use std::string constructs
75 #endif
76         int cut = 0, before = 0, after = 0;
77         for (string::size_type i = 0; i < font.length(); ++i) {
78                 if (font[i] == '-') {
79                         ++cut;
80                         if (cut == 7) {
81                                 before = i;
82                         } else if (cut == 8) {
83                                 after = i;
84                                 break;
85                         }
86                 }
87         }
88
89         string head = font;
90         head.erase(before + 1, string::npos);
91         string tail = font;
92         tail.erase(0, after);
93         return head + tostr(size) + tail;
94 }
95
96 /// Set new pattern
97 void FontInfo::setPattern(string const & pat)
98 {
99         release();
100         init();
101         pattern = pat;
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." << 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 /// 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 }