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