This commit was manufactured by cvs2svn to create tag
[lyx.git] / src / FontInfo.C
blobaba45bec468dc792cc326e77bc68125563268b98
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  * ======================================================*/
12 #include <config.h>
13 #include <cmath>        // fabs()
14 #include <cstdlib>      // atoi()
16 #ifdef __GNUG__
17 #pragma implementation "FontInfo.h"
18 #endif
20 #include "FontInfo.h"
21 #include "debug.h"
22 #include "lyxrc.h"      // lyxrc.use_scalable_fonts
23 #include "support/lstrings.h"
25 extern LyXRC * lyxrc;
27 /// Load font close to this size
28 string FontInfo::getFontname(int size)
30         if (!exist())
31                 return string();
33         int closestind = -1;
34         double error = 100000;
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         }
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         }
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         }
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];
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 #warning rewrite to use std::string constructs
74         int cut = 0, before = 0, after = 0;
75         for (string::size_type i = 0; i < font.length(); ++i) {
76                 if (font[i] == '-') {
77                         ++cut;
78                         if (cut == 7) {
79                                 before = i;
80                         } else if (cut == 8) {
81                                 after = i;
82                                 break;
83                         }
84                 }
85         }
87         string head = font;
88         head.erase(before + 1, string::npos);
89         string tail = font;
90         tail.erase(0, after);
91         return head + tostr(size) + tail;
94 /// Set new pattern
95 void FontInfo::setPattern(string const & pat)
97         release();
98         init();
99         pattern = pat;
102 /// Query font in X11
103 void FontInfo::query()
105         if (queried)
106                 return;
108         if (pattern.empty()) {
109                 lyxerr << "Can not use empty font name for font query." << endl;
110                 queried = true;
111                 return;
112         }
114         char ** list = XListFonts(fl_display, pattern.c_str(), 100, &matches);
116         if (list == 0) {
117                 // No fonts matched
118                 scalable = false;
119                 sizes = 0;
120         } else {
121                 release();
122                 sizes = new int[matches];
123                 strings = new string[matches];
125                 // We have matches. Run them through
126                 for(int i=0; i<matches; i++) {
127                         string name(list[i]);
128                         sizes[i] = atoi(token(name, '-',7).c_str());
129                         strings[i] = name;
130                         if (sizes[i] == 0) {
131                                 if (scaleindex == -1) {
132                                         scaleindex = i;
133                                 }
134                                 scalable = true;
135                         };
136                 };
137                 XFreeFontNames(list);
138         }
139         queried = true;
142 /// Release allocated stuff
143 void FontInfo::release()
145         if (sizes) {
146                 delete [] sizes;
147                 sizes = 0;
148         }
149         if (strings) {
150                 delete [] strings;
151                 strings = 0;
152         }