Logo ROOT   6.16/01
Reference Guide
XLFDParser.mm
Go to the documentation of this file.
1// @(#)root/graf2d:$Id$
2// Author: Timur Pocheptsov 2/03/2012
3
4/*************************************************************************
5 * Copyright (C) 1995-2012, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12//#define NDEBUG
13
14#include <stdexcept>
15#include <sstream>
16#include <cassert>
17#include <cctype>
18
19#include "XLFDParser.h"
20#include "TError.h"
21
22//
23// I did not find any formal description of what XLFD name can be.
24// The first version of this code was quite strict - it expected all
25// components to be in place, digits must be digits. But after using
26// ROOT's GUI for some time, I noticed that ROOT can use font name like
27// *, "fixed", "-*-" or something like this. In this case I have to set
28// some "default" or "wildcard" names.
29//
30
31namespace ROOT {
32namespace MacOSX {
33namespace X11 {
34
35namespace {
36
37typedef std::string::size_type size_type;
38
39//______________________________________________________________________________
40template<class T>
41void StringToInt(const std::string &str, const std::string &componentName, T &num)
42{
43 for (size_type i = 0, e = str.length(); i < e; ++i) {
44 const char symbol = str[i];
45 if (!std::isdigit(symbol))
46 throw std::runtime_error("bad symbol while converting component " + componentName + " into number");
47 }
48
49 std::istringstream in(str);
50 in>>num;
51}
52
53//______________________________________________________________________________
54size_type GetXLFDNameComponentAsString(const std::string &name, const std::string & componentName,
55 size_type pos, std::string &component)
56{
57 const size_type length = name.length();
58 if (pos + 1 >= length)
59 throw std::runtime_error("Unexpected end of name while parsing " + componentName);
60
61 //Starting symbol must be '-'.
62 if (name[pos] != '-')
63 throw std::runtime_error("Component " + componentName + " must start from '-'");
64
65 const size_type start = ++pos;
66 ++pos;
67 while (pos < length && name[pos] != '-')
68 ++pos;
69
70 if (pos - start)
71 component = name.substr(start, pos - start);
72 else
73 component = "";
74
75 return pos;
76}
77
78
79//______________________________________________________________________________
80template<class T>
81size_type GetXLFDNameComponentAsInteger(const std::string &name,
82 const std::string &componentName,
83 size_type pos, T &component)
84{
85 std::string num;
86 pos = GetXLFDNameComponentAsString(name, componentName, pos, num);
87 StringToInt(num, componentName, component);
88
89 return pos;
90}
91
92
93//______________________________________________________________________________
94size_type ParseFoundry(const std::string &name, size_type pos, XLFDName &/*dst*/)
95{
96 //Ignore foundry.
97 std::string dummy;
98 return GetXLFDNameComponentAsString(name, "foundry", pos, dummy);
99}
100
101
102//______________________________________________________________________________
103size_type ParseFamilyName(const std::string &name, size_type pos, XLFDName &dst)
104{
105 const size_type tokenEnd = GetXLFDNameComponentAsString(name, "family name", pos, dst.fFamilyName);
106
107 //This is a "special case": ROOT uses it's own symbol.ttf, but
108 //I can not use it to render text in a GUI, and also I can not use
109 //Apple's system symbol font - it can not encode all symbols ROOT wants.
110 if (dst.fFamilyName == "symbol")
111 dst.fFamilyName = "helvetica";
112
113 return tokenEnd;
114}
115
116
117//______________________________________________________________________________
118size_type ParseWeight(const std::string &name, size_type pos, XLFDName &dst)
119{
120 //Weight can be an integer, can be a word, can be a combination of a word
121 //and integer.
122 std::string weight;
123 pos = GetXLFDNameComponentAsString(name, "weight", pos, weight);
124
125 if (weight == "*")
126 dst.fWeight = kFWAny;
127 else if (weight == "bold")
128 dst.fWeight = kFWBold;
129 else
130 dst.fWeight = kFWMedium;
131
132 return pos;
133}
134
135
136//______________________________________________________________________________
137size_type ParseSlant(const std::string &name, size_type pos, XLFDName &dst)
138{
139 //Slant can be regular or italic now.
140 std::string slant;
141 pos = GetXLFDNameComponentAsString(name, "slant", pos, slant);
142
143 //Can be 'r', 'R', 'i', 'I', 'o', 'O', '*'.
144 if (slant == "*")
145 dst.fSlant = kFSAny;
146 else if (slant == "i" || slant == "I" || slant == "o" || slant == "O")
147 dst.fSlant = kFSItalic;
148 else
149 dst.fSlant = kFSRegular;
150
151 return pos;
152}
153
154//______________________________________________________________________________
155size_type ParseSetwidth(const std::string &name, size_type pos, XLFDName &/*dst*/)
156{
157 //Setwidth is ignored now.
158 std::string dummy;
159 return GetXLFDNameComponentAsString(name, "setwidth", pos, dummy);
160}
161
162//______________________________________________________________________________
163size_type ParseAddstyle(const std::string &name, size_type pos, XLFDName &/*dst*/)
164{
165 //Ignored at the moment.
166 std::string dummy;
167 return GetXLFDNameComponentAsString(name, "addstyle", pos, dummy);
168}
169
170//______________________________________________________________________________
171size_type ParsePixelSize(const std::string &name, size_type pos, XLFDName &dst)
172{
173 //First, try to parse as string. It can be '*' == 'any size'.
174 //In the first version it was more strict - throwing and exception.
175 std::string dummy;
176
177 size_type endOfSize = GetXLFDNameComponentAsString(name, "pixel size", pos, dummy);
178 if (dummy == "*") {
179 //Aha, ignore size.
180 dst.fPixelSize = 0;
181 return endOfSize;
182 }
183
184 const size_type pos1 = GetXLFDNameComponentAsInteger(name, "pixel size", pos, dst.fPixelSize);
185 if (dst.fPixelSize < 12)
186 dst.fPixelSize = 12;
187 //Real size in pixel?
188 return pos1;//GetXLFDNameComponentAsInteger(name, "pixel size", pos, dst.fPixelSize);
189}
190
191//______________________________________________________________________________
192size_type ParsePointSize(const std::string &name, size_type pos, XLFDName &/*dst*/)
193{
194 //Ignored at the moment.
195 std::string dummy;
196 return GetXLFDNameComponentAsString(name, "point size", pos, dummy);
197}
198
199
200//______________________________________________________________________________
201size_type ParseHoriz(const std::string &name, size_type pos, XLFDName &/*dst*/)
202{
203 //Ignored at the moment.
204 std::string dummy;
205 return GetXLFDNameComponentAsString(name, "horizontal", pos, dummy);
206}
207
208
209//______________________________________________________________________________
210size_type ParseVert(const std::string &name, size_type pos, XLFDName &/*dst*/)
211{
212 //Ignored at the moment.
213 std::string dummy;
214 return GetXLFDNameComponentAsString(name, "vertical", pos, dummy);
215}
216
217
218//______________________________________________________________________________
219size_type ParseSpacing(const std::string &name, size_type pos, XLFDName &/*dst*/)
220{
221 //Ignored at the moment.
222 std::string dummy;
223 return GetXLFDNameComponentAsString(name, "spacing", pos, dummy);
224}
225
226
227//______________________________________________________________________________
228size_type ParseAvgwidth(const std::string &name, size_type pos, XLFDName &/*dst*/)
229{
230 //Ignored at the moment.
231 std::string dummy;
232 return GetXLFDNameComponentAsString(name, "average width", pos, dummy);
233}
234
235
236//______________________________________________________________________________
237size_type ParseRgstry(const std::string &name, size_type pos, XLFDName &dst)
238{
239 return GetXLFDNameComponentAsString(name, "language", pos, dst.fRgstry);
240}
241
242
243//______________________________________________________________________________
244size_type ParseEncoding(const std::string &name, size_type pos, XLFDName &dst)
245{
246 return GetXLFDNameComponentAsString(name, "encoding", pos, dst.fRgstry);
247}
248
249}//Anonymous namespace.
250
251//______________________________________________________________________________
253 : fWeight(kFWAny),
254 fSlant(kFSAny),
255 fPixelSize(0)
256{
257}
258
259//______________________________________________________________________________
260bool ParseXLFDName(const std::string &xlfdName, XLFDName &dst)
261{
262 const size_type nameLength = xlfdName.length();
263
264 assert(nameLength && "XLFD name is a string with a zero length");
265
266 if (!nameLength) {
267 ::Warning("ROOT::MacOSX::X11::ParseXLFDName: ", "XLFD name is a string with a zero length");
268 return false;
269 }
270
271 try {
272 if (xlfdName == "fixed" || xlfdName == "*") {
273 //Is this correct XLFD name???? Who knows. Replace it.
274 dst.fFamilyName = "LucidaGrande";
275 dst.fPixelSize = 12;
276 } else {
277 size_type pos = ParseFoundry(xlfdName, 0, dst);
278 if (pos + 1 < nameLength)
279 pos = ParseFamilyName(xlfdName, pos, dst);
280
281 if (pos + 1 < nameLength)
282 pos = ParseWeight(xlfdName, pos, dst);
283 else
284 dst.fWeight = kFWMedium;
285
286 if (pos + 1 < nameLength)
287 pos = ParseSlant(xlfdName, pos, dst);
288 else
289 dst.fSlant = kFSRegular;
290
291 if (pos + 1 < nameLength)
292 pos = ParseSetwidth(xlfdName, pos, dst);
293 if (pos + 1 < nameLength)
294 pos = ParseAddstyle(xlfdName, pos, dst);
295 if (pos + 1 < nameLength)
296 pos = ParsePixelSize(xlfdName, pos, dst);
297 if (pos + 1 < nameLength)
298 pos = ParsePointSize(xlfdName, pos, dst);
299 if (pos + 1 < nameLength)
300 pos = ParseHoriz(xlfdName, pos, dst);
301 if (pos + 1 < nameLength)
302 pos = ParseVert(xlfdName, pos, dst);
303 if (pos + 1 < nameLength)
304 pos = ParseSpacing(xlfdName, pos, dst);
305 if (pos + 1 < nameLength)
306 pos = ParseAvgwidth(xlfdName, pos, dst);
307 if (pos + 1 < nameLength)
308 pos = ParseRgstry(xlfdName, pos, dst);
309 if (pos + 1 < nameLength)
310 pos = ParseEncoding(xlfdName, pos, dst);
311 }
312
313 return true;
314 } catch (const std::exception &e) {
315 ::Error("ROOT::MacOSX::Quartz::ParseXLFDName", "Failed to parse XLFD name - %s", e.what());
316 return false;
317 }
318}
319
320}//X11
321}//MacOSX
322}//ROOT
#define e(i)
Definition: RSha256.hxx:103
static RooMathCoreReg dummy
void Error(const char *location, const char *msgfmt,...)
void Warning(const char *location, const char *msgfmt,...)
bool ParseXLFDName(const std::string &xlfdName, XLFDName &dst)
Definition: XLFDParser.mm:260
double T(double x)
Definition: ChebyshevPol.h:34
Namespace for new ROOT classes and functions.
Definition: StringConv.hxx:21