Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
FontCache.mm
Go to the documentation of this file.
1// @(#)root/graf2d:$Id$
2// Author: Timur Pocheptsov 19/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 <string>
18#include <cmath>
19
20#include "CocoaUtils.h"
21#include "QuartzText.h"
22#include "FontCache.h"
23#include "TSystem.h"
24#include "TError.h"
25#include "TEnv.h"
26#include "TROOT.h"
27
28namespace ROOT {
29namespace MacOSX {
30namespace Details {
31
32namespace {
33
34//ROOT uses indices for fonts. Indices are in the range [1 .. 15],
35//12 is a symbol font (quite special thing, see the code below,
36//15 is a "symbol italic" font - shear transformation is applied.
37
38//TODO: actually, it's not good to assume I have these fonts for sure,
39//find a better way to check the available fonts and search for the best
40//match.
41
42const CFStringRef fixedFontNames[FontCache::nPadFonts] =
43 {
44 CFSTR("TimesNewRomanPS-ItalicMT"),
45 CFSTR("TimesNewRomanPS-BoldMT"),
46 CFSTR("TimesNewRomanPS-BoldItalicMT"),
47 CFSTR("Helvetica"),
48 CFSTR("Helvetica-Oblique"),
49 CFSTR("Helvetica-Bold"),
50 CFSTR("Helvetica-BoldOblique"),
51 CFSTR("Courier"),
52 CFSTR("Courier-Oblique"),
53 CFSTR("Courier-Bold"),
54 CFSTR("Courier-BoldOblique"),
55 CFSTR("Symbol"),
56 CFSTR("TimesNewRomanPSMT"),
57 CFSTR("Wingdings"),
58 CFSTR("Symbol-Italic")
59 };
60
61//______________________________________________________________________________
62CTFontCollectionRef CreateFontCollection(const X11::XLFDName &/*xlfd*/)
63{
64 CTFontCollectionRef ctCollection = CTFontCollectionCreateFromAvailableFonts(0);
65 if (!ctCollection)
66 ::Error("CreateFontCollection", "CTFontCollectionCreateFromAvailableFonts failed");
67
68 return ctCollection;
69/* CTFontCollectionRef ctCollection = 0;
70 if (xlfd.fFamilyName == "*")
71 ctCollection = CTFontCollectionCreateFromAvailableFonts(0);//Select all available fonts.
72 else {
73 //Create collection, using font descriptor?
74 const Util::CFScopeGuard<CFStringRef> fontName(CFStringCreateWithCString(kCFAllocatorDefault, xlfd.fFamilyName.c_str(), kCFStringEncodingMacRoman));
75 if (!fontName.Get()) {
76 ::Error("CreateFontCollection", "CFStringCreateWithCString failed");
77 return 0;
78 }
79
80 const Util::CFScopeGuard<CTFontDescriptorRef> fontDescriptor(CTFontDescriptorCreateWithNameAndSize(fontName.Get(), 0.));
81 if (!fontDescriptor.Get()) {
82 ::Error("CreateFontCollection", "CTFontDescriptorCreateWithNameAndSize failed");
83 return 0;
84 }
85
86 Util::CFScopeGuard<CFMutableArrayRef> descriptors(CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks));
87 if (!descriptors.Get()) {
88 ::Error("CreateFontCollection", "CFArrayCreateMutable failed");
89 return 0;
90 }
91
92 CFArrayAppendValue(descriptors.Get(), fontDescriptor.Get());
93 ctCollection = CTFontCollectionCreateWithFontDescriptors(descriptors.Get(), 0);//Oh mama, so many code just to do this :(((
94 }
95
96 if (!ctCollection) {
97 ::Error("CreateFontCollection", "No fonts are available for family %s", xlfd.fFamilyName.c_str());//WTF???
98 return 0;
99 }
100
101
102 return ctCollection;*/
103}
104
105//______________________________________________________________________________
106bool GetFamilyName(CTFontDescriptorRef fontDescriptor, std::vector<char> &name)
107{
108 //If success, this function returns a null-terminated string in a vector.
109 assert(fontDescriptor != 0 && "GetFamilyName, parameter 'fontDescriptor' is null");
110
111 name.clear();
112
113 Util::CFScopeGuard<CFStringRef> cfFamilyName((CFStringRef)CTFontDescriptorCopyAttribute(fontDescriptor, kCTFontFamilyNameAttribute));
114 if (const CFIndex cfLen = CFStringGetLength(cfFamilyName.Get())) {
115 name.resize(cfLen + 1);//+ 1 for '\0'.
116 if (CFStringGetCString(cfFamilyName.Get(), &name[0], name.size(), kCFStringEncodingMacRoman))
117 return true;
118 }
119
120 return false;
121}
122
123#ifdef MAC_OS_X_VERSION_10_9
124
125//______________________________________________________________________________
126bool GetPostscriptName(CTFontDescriptorRef fontDescriptor, std::vector<char> &name)
127{
128 //If success, this function returns a null-terminated string in a vector.
129 assert(fontDescriptor != 0 && "GetPostscriptName, parameter 'fontDescriptor' is null");
130
131 name.clear();
132
133 Util::CFScopeGuard<CFStringRef> cfFamilyName((CFStringRef)CTFontDescriptorCopyAttribute(fontDescriptor, kCTFontNameAttribute));
134
135 if (const CFIndex cfLen = CFStringGetLength(cfFamilyName.Get())) {
136 name.resize(cfLen + 1);//+ 1 for '\0'.
137 if (CFStringGetCString(cfFamilyName.Get(), &name[0], name.size(), kCFStringEncodingMacRoman))
138 return true;
139 }
140
141 return false;
142}
143
144#endif
145
146//______________________________________________________________________________
147void GetWeightAndSlant(CTFontDescriptorRef fontDescriptor, X11::XLFDName &newXLFD)
148{
149 //Let's ask for a weight and pixel size.
150 const Util::CFScopeGuard<CFDictionaryRef> traits((CFDictionaryRef)CTFontDescriptorCopyAttribute(fontDescriptor, kCTFontTraitsAttribute));
151 if (traits.Get()) {
152 if (CFNumberRef symbolTraits = (CFNumberRef)CFDictionaryGetValue(traits.Get(), kCTFontSymbolicTrait)) {
153 uint32_t val = 0;
154 CFNumberGetValue(symbolTraits, kCFNumberIntType, &val);
155 if (val & kCTFontItalicTrait)
156 newXLFD.fSlant = X11::kFSItalic;
157 else
158 newXLFD.fSlant = X11::kFSRegular;
159
160 if (val & kCTFontBoldTrait)
161 newXLFD.fWeight = X11::kFWBold;
162 else
163 newXLFD.fWeight = X11::kFWMedium;
164 }
165
166 /*
167 //The code below is wrong - using it, I can not identify bold or italic and always have
168 //only medium/regular.
169 if(CFNumberRef weight = (CFNumberRef)CFDictionaryGetValue(traits.Get(), kCTFontWeightTrait)) {
170 double val = 0.;
171 if (CFNumberGetValue(weight, kCFNumberDoubleType, &val))
172 newXLFD.fWeight = val > 0. ? X11::kFWBold : X11::kFWMedium;
173 }
174
175 if(CFNumberRef slant = (CFNumberRef)CFDictionaryGetValue(traits.Get(), kCTFontSlantTrait)) {
176 double val = 0.;
177 if (CFNumberGetValue(slant, kCFNumberDoubleType, &val))
178 newXLFD.fSlant = val > 0. ? X11::kFSItalic : X11::kFSRegular;
179 }
180 */
181 }
182}
183
184//______________________________________________________________________________
185void GetPixelSize(CTFontDescriptorRef fontDescriptor, X11::XLFDName &newXLFD)
186{
187 const Util::CFScopeGuard<CFNumberRef> size((CFNumberRef)CTFontDescriptorCopyAttribute(fontDescriptor, kCTFontSizeAttribute));
188 if (size.Get()) {
189 int pixelSize = 0;
190 if(CFNumberIsFloatType(size.Get())) {
191 double val = 0;
192 CFNumberGetValue(size.Get(), kCFNumberDoubleType, &val);
193 pixelSize = val;
194 } else
195 CFNumberGetValue(size.Get(), kCFNumberIntType, &pixelSize);
196
197 if(pixelSize)
198 newXLFD.fPixelSize = pixelSize;
199 }
200}
201
202//_________________________________________________________________
203void CreateXLFDString(const X11::XLFDName &xlfd, std::string &xlfdString)
204{
205 xlfdString = "-CoreText-"; //Fake foundry.
206 xlfdString += xlfd.fFamilyName;
207
208 if (xlfd.fWeight == X11::kFWBold)
209 xlfdString += "-bold";
210 else
211 xlfdString += "-normal";
212
213 if (xlfd.fSlant == X11::kFSItalic)
214 xlfdString += "-i";
215 else
216 xlfdString += "-r";
217
218 xlfdString += "-*-*"; //width, addstyle
219
220 if (xlfd.fPixelSize) {
221 std::ostringstream out;
222 out<<xlfd.fPixelSize;
223 xlfdString += "-";
224 xlfdString += out.str();
225 } else
226 xlfdString += "-*";
227
228 xlfdString += "-*-*-*-*-*-*-*-";
229}
230
231}
232
233//_________________________________________________________________
235 : fSymbolFontRegistered(false)
236{
237 //XLFD name is not exactly PS name thus generating a warning with a new Core Text.
238 fXLFDtoPostscriptNames["helvetica"] = "Helvetica";
239 fXLFDtoPostscriptNames["courier"] = "Courier";
240 fXLFDtoPostscriptNames["times"] = "Times-Roman";
241}
242
243//______________________________________________________________________________
245{
246 using Util::CFScopeGuard;
248
249#ifdef MAC_OS_X_VERSION_10_9
250 PSNameMap_t::const_iterator nameIt = fXLFDtoPostscriptNames.find(xlfd.fFamilyName);
251 const std::string &psName = nameIt == fXLFDtoPostscriptNames.end() ? xlfd.fFamilyName : nameIt->second;
252 const CFScopeGuard<CFStringRef> fontName(CFStringCreateWithCString(kCFAllocatorDefault, psName.c_str(), kCFStringEncodingMacRoman));
253#else
254 const CFScopeGuard<CFStringRef> fontName(CFStringCreateWithCString(kCFAllocatorDefault, xlfd.fFamilyName.c_str(), kCFStringEncodingMacRoman));
255#endif
256
257 const CFStrongReference<CTFontRef> baseFont(CTFontCreateWithName(fontName.Get(), xlfd.fPixelSize, 0), false);//false == do not retain
258
259 if (!baseFont.Get()) {
260 ::Error("FontCache::LoadFont", "CTFontCreateWithName failed for %s", xlfd.fFamilyName.c_str());
261 return FontStruct_t();//Haha! Die ROOT, die!
262 }
263
264 CTFontSymbolicTraits symbolicTraits = CTFontSymbolicTraits();
265
266 if (xlfd.fWeight == X11::kFWBold)
267 symbolicTraits |= kCTFontBoldTrait;
268 if (xlfd.fSlant == X11::kFSItalic)
269 symbolicTraits |= kCTFontItalicTrait;
270
271 if (symbolicTraits) {
272 const CFStrongReference<CTFontRef> font(CTFontCreateCopyWithSymbolicTraits(baseFont.Get(), xlfd.fPixelSize, 0, symbolicTraits, symbolicTraits), false);//false == do not retain.
273 if (font.Get()) {
274 if (fLoadedFonts.find(font.Get()) == fLoadedFonts.end())
275 fLoadedFonts[font.Get()] = font;
276
277 return reinterpret_cast<FontStruct_t>(font.Get());
278 }
279 }
280
281 if (fLoadedFonts.find(baseFont.Get()) == fLoadedFonts.end())
282 fLoadedFonts[baseFont.Get()] = baseFont;
283
284 return reinterpret_cast<FontStruct_t>(baseFont.Get());
285}
286
287//______________________________________________________________________________
289{
290 CTFontRef fontRef = (CTFontRef)font;
291 font_iterator fontIter = fLoadedFonts.find(fontRef);
292
293 assert(fontIter != fLoadedFonts.end() && "Attempt to unload font, not created by font manager");
294
295 fLoadedFonts.erase(fontIter);
296}
297
298//______________________________________________________________________________
299char **FontCache::ListFonts(const X11::XLFDName &xlfd, int maxNames, int &count)
300{
301 typedef std::vector<char>::size_type size_type;
302
303 count = 0;
304
305 //Ugly, ugly code. I should "think different"!!!
306 //To extract font names, I have to: create CFString, create font descriptor, create
307 //CFArray, create CTFontCollection, that's a mess!!!
308 //It's good I have my small and ugly RAII classes, otherwise the code will be
309 //total trash and sodomy because of all possible cleanup actions.
310
311 //First, create a font collection.
312 const Util::CFScopeGuard<CTFontCollectionRef> collectionGuard(CreateFontCollection(xlfd));
313 if (!collectionGuard.Get())
314 return 0;
315
316 Util::CFScopeGuard<CFArrayRef> fonts(CTFontCollectionCreateMatchingFontDescriptors(collectionGuard.Get()));
317 if (!fonts.Get()) {
318 ::Error("FontCache::ListFonts", "CTFontCollectionCreateMatchingFontDescriptors failed %s", xlfd.fFamilyName.c_str());
319 return 0;
320 }
321
322 std::vector<char> xlfdData;
323 //familyName is actually a null-terminated string.
324 std::vector<char> familyName;
325 X11::XLFDName newXLFD;
326 std::string xlfdString;
327
328 const CFIndex nFonts = CFArrayGetCount(fonts.Get());
329 for (CFIndex i = 0; i < nFonts && count < maxNames; ++i) {
330 CTFontDescriptorRef font = (CTFontDescriptorRef)CFArrayGetValueAtIndex(fonts.Get(), i);
331
332 if (!GetFamilyName(font, familyName))
333 continue;
334
335 if (xlfd.fFamilyName != "*" && xlfd.fFamilyName != &familyName[0])
336 continue;
337
338 newXLFD.fFamilyName = &familyName[0];
339
340 //If family name has '-', ROOT's GUI can not parse it correctly -
341 //'-' is a separator in XLFD. Just skip this font (anyway, it wan not requested by GUI, only
342 //listed by FontCache.
343 if (newXLFD.fFamilyName.find('-') != std::string::npos)
344 continue;
345
346 GetWeightAndSlant(font, newXLFD);
347
348 //Check weight and slant.
349 if (xlfd.fWeight != X11::kFWAny && newXLFD.fWeight != xlfd.fWeight)
350 continue;
351 if (xlfd.fSlant != X11::kFSAny && newXLFD.fSlant != xlfd.fSlant)
352 continue;
353
354 if (xlfd.fPixelSize) {//Size was requested.
355 GetPixelSize(font, newXLFD);
356 //Core Text supports different font sizes.
357 if (!newXLFD.fPixelSize)
358 newXLFD.fPixelSize = xlfd.fPixelSize;
359 }
360
361#ifdef MAC_OS_X_VERSION_10_9
362 //To avoid a warning from Core Text, save a mapping from a name seen by ROOT (family)
363 //to a right postscript name (required by Core Text).
364
365 //It's a null-terminated string:
366 std::vector<char> postscriptName;
367 if (GetPostscriptName(font, postscriptName)) {
368 if (fXLFDtoPostscriptNames.find(&familyName[0]) == fXLFDtoPostscriptNames.end())
369 fXLFDtoPostscriptNames[&familyName[0]] = &postscriptName[0];
370 }
371#endif
372
373
374 //Ok, now lets create XLFD name, and place into list.
375 CreateXLFDString(newXLFD, xlfdString);
376 //
377 xlfdData.insert(xlfdData.end(), xlfdString.begin(), xlfdString.end());
378 xlfdData.push_back(0);//terminal 0.
379 ++count;
380 }
381
382 //Setup array with string addresses.
383 if (xlfdData.size()) {
384 fFontLists.push_back(fDummyList);
385 fFontLists.back().fStringData.swap(xlfdData);
386
387 std::vector<char> &data = fFontLists.back().fStringData;
388 std::vector<char *> &list = fFontLists.back().fList;
389
390 list.push_back(&data[0]);
391 for (size_type i = 1, e = data.size(); i < e; ++i) {
392 if (!data[i] && i + 1 < e)
393 list.push_back(&data[i + 1]);
394 }
395
396 return &list[0];
397 } else
398 return 0;
399}
400
401//______________________________________________________________________________
402void FontCache::FreeFontNames(char **fontList)
403{
404 if (!fontList)
405 return;
406
407 for (std::list<FontList>::iterator it = fFontLists.begin(), eIt = fFontLists.end(); it != eIt; ++it) {
408 if (fontList == &it->fList[0]) {
409 fFontLists.erase(it);
410 return;
411 }
412 }
413
414 assert(0 && "FreeFontNames, unknown fontList");
415}
416
417//______________________________________________________________________________
418unsigned FontCache::GetTextWidth(FontStruct_t font, const char *text, int nChars)
419{
420 if (nChars == 0)
421 return 0;
422
423 typedef std::vector<CGSize>::size_type size_type;
424 //
425 CTFontRef fontRef = (CTFontRef)font;
426 assert(fLoadedFonts.find(fontRef) != fLoadedFonts.end() && "Font was not created by font manager");
427
428 //nChars is either positive, or negative (take all string).
429 if (nChars < 0)
430 nChars = std::strlen(text);
431
432 std::vector<UniChar> unichars(text, text + nChars);
433
434 //Extract glyphs for a text.
435 std::vector<CGGlyph> glyphs(unichars.size());
436 CTFontGetGlyphsForCharacters(fontRef, &unichars[0], &glyphs[0], unichars.size());
437
438 //Glyps' advances for a text.
439 std::vector<CGSize> glyphAdvances(glyphs.size());
440 CTFontGetAdvancesForGlyphs(fontRef, Quartz::horizontalFontOrientation, &glyphs[0], &glyphAdvances[0], glyphs.size());
441
442 CGFloat textWidth = 0.;
443 for (size_type i = 0, e = glyphAdvances.size(); i < e; ++i)
444 textWidth += std::ceil(glyphAdvances[i].width);
445
446 return textWidth;
447}
448
449
450//_________________________________________________________________
451void FontCache::GetFontProperties(FontStruct_t font, int &maxAscent, int &maxDescent)
452{
453 CTFontRef fontRef = (CTFontRef)font;
454
455 assert(fLoadedFonts.find(fontRef) != fLoadedFonts.end() && "Font was not created by font manager");
456
457 try {
458 maxAscent = int(CTFontGetAscent(fontRef) + 0.5) + 2;
459 maxDescent = int(CTFontGetDescent(fontRef) + 0.5);
460 } catch (const std::exception &) {
461 throw;
462 }
463}
464
465
466//_________________________________________________________________
467CTFontRef FontCache::SelectFont(Font_t fontIndex, Float_t fontSize)
468{
469 fontIndex /= 10;
470
471 if (fontIndex > nPadFonts || !fontIndex) {
472 ::Warning("FontCache::SelectFont", "Font with index %d was requested", fontIndex);
473 fontIndex = 3;//Select the Helvetica as default.
474 } else
475 fontIndex -= 1;
476
477 if (fontIndex == 11 || fontIndex == 14)//Special case, our own symbol.ttf file.
478 return SelectSymbolFont(fontSize, fontIndex);
479
480 const UInt_t fixedSize = UInt_t(fontSize);
481 font_map_iterator it = fFonts[fontIndex].find(fixedSize);
482
483 if (it == fFonts[fontIndex].end()) {
484 //Insert the new font.
485 try {
486 const CTFontGuard_t font(CTFontCreateWithName(fixedFontNames[fontIndex], fixedSize, 0), false);
487 if (!font.Get()) {//With Apple's lame documentation it's not clear, if function can return 0.
488 ::Error("FontCache::SelectFont", "CTFontCreateWithName failed for font %d", fontIndex);
489 return 0;
490 }
491
492 fFonts[fontIndex][fixedSize] = font;//Insetion can throw.
493 return fSelectedFont = font.Get();
494 } catch (const std::exception &) {//Bad alloc.
495 return 0;
496 }
497 }
498
499 return fSelectedFont = it->second.Get();
500}
501
502//_________________________________________________________________
503CTFontRef FontCache::SelectSymbolFont(Float_t fontSize, unsigned fontIndex)
504{
505 assert(fontIndex == 11 || fontIndex == 14 && "SelectSymbolFont, parameter fontIndex has invalid value");
506
507 const UInt_t fixedSize = UInt_t(fontSize);
508 font_map_iterator it = fFonts[fontIndex].find(fixedSize);//In ROOT, 11 is a font from symbol.ttf.
509
510 if (it == fFonts[fontIndex].end()) {
511 //This GetValue
512 const char * const fontDirectoryPath = gEnv->GetValue("Root.TTFontPath",TROOT::GetTTFFontDir());
513 char * const fontFileName = gSystem->Which(fontDirectoryPath, "symbol.ttf", kReadPermission);//This must be deleted.
514
515 const Util::ScopedArray<char> arrayGuard(fontFileName);
516
517 if (!fontFileName || fontFileName[0] == 0) {
518 ::Error("FontCache::SelectSymbolFont", "symbol.ttf file not found");
519 return 0;
520 }
521
522 try {
523 const Util::CFScopeGuard<CFStringRef> path(CFStringCreateWithCString(kCFAllocatorDefault, fontFileName, kCFURLPOSIXPathStyle));
524 if (!path.Get()) {
525 ::Error("FontCache::SelectSymbolFont", "CFStringCreateWithCString failed");
526 return 0;
527 }
528
529 const Util::CFScopeGuard<CFURLRef> fontURL(CFURLCreateWithFileSystemPath(kCFAllocatorDefault, path.Get(), kCFURLPOSIXPathStyle, false));
530 if (!fontURL.Get()) {
531 ::Error("FontCache::SelectSymbolFont", "CFURLCreateWithFileSystemPath failed");
532 return 0;
533 }
534
535 //Try to register this font.
537 CFErrorRef err = 0;
538 fSymbolFontRegistered = CTFontManagerRegisterFontsForURL(fontURL.Get(), kCTFontManagerScopeProcess, &err);
540 ::Error("FontCache::SelectSymbolFont", "CTFontManagerRegisterFontsForURL failed");
541 if (err)
542 CFRelease(err);
543 return 0;
544 }
545 }
546
547 const Util::CFScopeGuard<CFArrayRef> arr(CTFontManagerCreateFontDescriptorsFromURL(fontURL.Get()));
548 if (!arr.Get()) {
549 ::Error("FontCache::SelectSymbolFont", "CTFontManagerCreateFontDescriptorsFromURL failed");
550 return 0;
551 }
552
553 CTFontDescriptorRef fontDesc = (CTFontDescriptorRef)CFArrayGetValueAtIndex(arr.Get(), 0);
554
555 const CGAffineTransform shearMatrix = {1., 0., 0.26794, 1., 0., 0.};//Yes, these are hardcoded values, taken from TPDF class.
556 const CTFontGuard_t font(CTFontCreateWithFontDescriptorAndOptions(fontDesc, fixedSize,
557 fontIndex == 11 ? &CGAffineTransformIdentity :
558 &shearMatrix, kCTFontOptionsDefault), false);
559 if (!font.Get()) {
560 ::Error("FontCache::SelectSymbolFont", "CTFontCreateWithFontDescriptor failed");
561 return 0;
562 }
563
564 fFonts[fontIndex][fixedSize] = font;//This can throw.
565 return fSelectedFont = font.Get();
566 } catch (const std::exception &) {//Bad alloc.
567 //RAII destructors should do their work.
568 return 0;
569 }
570 }
571
572 return fSelectedFont = it->second.Get();
573}
574
575//_________________________________________________________________
576void FontCache::GetTextBounds(UInt_t &w, UInt_t &h, const char *text)const
577{
578 assert(fSelectedFont != 0 && "GetTextBounds: no font was selected");
579
580 try {
581 const Quartz::TextLine ctLine(text, fSelectedFont);
582 ctLine.GetBounds(w, h);
583 h += 2;
584 } catch (const std::exception &) {
585 throw;
586 }
587}
588
589//_________________________________________________________________
590void FontCache::GetTextBounds(UInt_t &w, UInt_t &h, const std::vector<UniChar> &unichars)const
591{
592 assert(fSelectedFont != 0 && "GetTextBounds: no font was selected");
593
594 try {
595 const Quartz::TextLine ctLine(unichars, fSelectedFont);
596 ctLine.GetBounds(w, h);
597 h += 2;
598 } catch (const std::exception &) {
599 throw;
600 }
601}
602
603//_________________________________________________________________
605{
606 assert(fSelectedFont != 0 && "GetAscent, no font was selected");
607 return CTFontGetAscent(fSelectedFont) + 1;
608}
609
610//_________________________________________________________________
611double FontCache::GetAscent(const char *text)const
612{
613 assert(text != 0 && "GetAscent, parameter 'text' is null");
614 assert(fSelectedFont != 0 && "GetAscent, no font was selected");
615
616 try {
617 const Quartz::TextLine ctLine(text, fSelectedFont);
618 Int_t ascent = 0, descent = 0;
619 ctLine.GetAscentDescent(ascent, descent);
620 return ascent;
621 } catch (const std::exception &) {
622 throw;
623 }
624}
625
626//_________________________________________________________________
627double FontCache::GetAscent(const std::vector<UniChar> &unichars)const
628{
629 assert(fSelectedFont != 0 && "GetAscent, no font was selected");
630
631 try {
632 const Quartz::TextLine ctLine(unichars, fSelectedFont);
633 Int_t ascent = 0, descent = 0;
634 ctLine.GetAscentDescent(ascent, descent);
635 return ascent;
636 } catch (const std::exception &) {
637 throw;
638 }
639}
640
641//_________________________________________________________________
643{
644 assert(fSelectedFont != 0 && "GetDescent, no font was selected");
645 return CTFontGetDescent(fSelectedFont) + 1;
646}
647
648//_________________________________________________________________
649double FontCache::GetDescent(const char *text)const
650{
651 assert(text != 0 && "GetDescent, parameter 'text' is null");
652 assert(fSelectedFont != 0 && "GetDescent, no font was selected");
653
654 try {
655 const Quartz::TextLine ctLine(text, fSelectedFont);
656 Int_t ascent = 0, descent = 0;
657 ctLine.GetAscentDescent(ascent, descent);
658 return descent;
659 } catch (const std::exception &) {
660 throw;
661 }
662}
663
664//_________________________________________________________________
665double FontCache::GetDescent(const std::vector<UniChar> &unichars)const
666{
667 assert(fSelectedFont != 0 && "GetDescent, no font was selected");
668
669 try {
670 const Quartz::TextLine ctLine(unichars, fSelectedFont);
671 Int_t ascent = 0, descent = 0;
672 ctLine.GetAscentDescent(ascent, descent);
673 return descent;
674 } catch (const std::exception &) {
675 throw;
676 }
677}
678
679//_________________________________________________________________
681{
682 assert(fSelectedFont != 0 && "GetLeading, no font was selected");
683 return CTFontGetLeading(fSelectedFont);
684}
685
686
687}//Details
688}//MacOSX
689}//ROOT
Handle_t FontStruct_t
Pointer to font structure.
Definition GuiTypes.h:39
#define h(i)
Definition RSha256.hxx:106
#define e(i)
Definition RSha256.hxx:103
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
unsigned int UInt_t
Definition RtypesCore.h:46
float Float_t
Definition RtypesCore.h:57
short Font_t
Definition RtypesCore.h:88
R__EXTERN TEnv * gEnv
Definition TEnv.h:170
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition TError.cxx:185
void Warning(const char *location, const char *msgfmt,...)
Use this function in warning situations.
Definition TError.cxx:229
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
Option_t Option_t width
Option_t Option_t TPoint TPoint const char text
char name[80]
Definition TGX11.cxx:110
@ kReadPermission
Definition TSystem.h:45
R__EXTERN TSystem * gSystem
Definition TSystem.h:555
void FreeFontNames(char **fontList)
Definition FontCache.mm:402
void GetFontProperties(FontStruct_t font, int &maxAscent, int &maxDescent)
Definition FontCache.mm:451
std::map< CTFontRef, CTFontGuard_t >::iterator font_iterator
Definition FontCache.h:82
char ** ListFonts(const X11::XLFDName &xlfd, int maxNames, int &count)
Definition FontCache.mm:299
unsigned GetTextWidth(FontStruct_t font, const char *text, int nChars)
Definition FontCache.mm:418
CTFontRef SelectSymbolFont(Float_t fontSize, unsigned fontIndex)
Definition FontCache.mm:503
std::list< FontList > fFontLists
Definition FontCache.h:107
void GetTextBounds(UInt_t &w, UInt_t &h, const char *text) const
Definition FontCache.mm:576
std::map< CTFontRef, CTFontGuard_t > fLoadedFonts
Definition FontCache.h:81
FontStruct_t LoadFont(const X11::XLFDName &xlfd)
Definition FontCache.mm:244
void UnloadFont(FontStruct_t font)
Definition FontCache.mm:288
CTFontRef SelectFont(Font_t fontIndex, Float_t fontSize)
Definition FontCache.mm:467
FontMap_t::iterator font_map_iterator
Definition FontCache.h:87
FontMap_t fFonts[nPadFonts]
Definition FontCache.h:90
void GetBounds(UInt_t &w, UInt_t &h) const
void GetAscentDescent(Int_t &asc, Int_t &desc) const
virtual Int_t GetValue(const char *name, Int_t dflt) const
Returns the integer value for a resource.
Definition TEnv.cxx:491
static const TString & GetTTFFontDir()
Get the fonts directory in the installation. Static utility function.
Definition TROOT.cxx:3142
virtual char * Which(const char *search, const char *file, EAccessMode mode=kFileExists)
Find location of file in a search path.
Definition TSystem.cxx:1548
TCanvas * fonts()
Definition fonts.C:10
const CTFontOrientation horizontalFontOrientation
Definition QuartzText.mm:39
This file contains a specialised ROOT message handler to test for diagnostic in unit tests.