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//______________________________________________________________________________
124void GetWeightAndSlant(CTFontDescriptorRef fontDescriptor, X11::XLFDName &newXLFD)
125{
126 //Let's ask for a weight and pixel size.
127 const Util::CFScopeGuard<CFDictionaryRef> traits((CFDictionaryRef)CTFontDescriptorCopyAttribute(fontDescriptor, kCTFontTraitsAttribute));
128 if (traits.Get()) {
129 if (CFNumberRef symbolTraits = (CFNumberRef)CFDictionaryGetValue(traits.Get(), kCTFontSymbolicTrait)) {
130 uint32_t val = 0;
131 CFNumberGetValue(symbolTraits, kCFNumberIntType, &val);
132 if (val & kCTFontItalicTrait)
133 newXLFD.fSlant = X11::kFSItalic;
134 else
135 newXLFD.fSlant = X11::kFSRegular;
136
137 if (val & kCTFontBoldTrait)
138 newXLFD.fWeight = X11::kFWBold;
139 else
140 newXLFD.fWeight = X11::kFWMedium;
141 }
142
143 /*
144 //The code below is wrong - using it, I can not identify bold or italic and always have
145 //only medium/regular.
146 if(CFNumberRef weight = (CFNumberRef)CFDictionaryGetValue(traits.Get(), kCTFontWeightTrait)) {
147 double val = 0.;
148 if (CFNumberGetValue(weight, kCFNumberDoubleType, &val))
149 newXLFD.fWeight = val > 0. ? X11::kFWBold : X11::kFWMedium;
150 }
151
152 if(CFNumberRef slant = (CFNumberRef)CFDictionaryGetValue(traits.Get(), kCTFontSlantTrait)) {
153 double val = 0.;
154 if (CFNumberGetValue(slant, kCFNumberDoubleType, &val))
155 newXLFD.fSlant = val > 0. ? X11::kFSItalic : X11::kFSRegular;
156 }
157 */
158 }
159}
160
161//______________________________________________________________________________
162void GetPixelSize(CTFontDescriptorRef fontDescriptor, X11::XLFDName &newXLFD)
163{
164 const Util::CFScopeGuard<CFNumberRef> size((CFNumberRef)CTFontDescriptorCopyAttribute(fontDescriptor, kCTFontSizeAttribute));
165 if (size.Get()) {
166 int pixelSize = 0;
167 if(CFNumberIsFloatType(size.Get())) {
168 double val = 0;
169 CFNumberGetValue(size.Get(), kCFNumberDoubleType, &val);
170 pixelSize = val;
171 } else
172 CFNumberGetValue(size.Get(), kCFNumberIntType, &pixelSize);
173
174 if(pixelSize)
175 newXLFD.fPixelSize = pixelSize;
176 }
177}
178
179//_________________________________________________________________
180void CreateXLFDString(const X11::XLFDName &xlfd, std::string &xlfdString)
181{
182 xlfdString = "-CoreText-"; //Fake foundry.
183 xlfdString += xlfd.fFamilyName;
184
185 if (xlfd.fWeight == X11::kFWBold)
186 xlfdString += "-bold";
187 else
188 xlfdString += "-normal";
189
190 if (xlfd.fSlant == X11::kFSItalic)
191 xlfdString += "-i";
192 else
193 xlfdString += "-r";
194
195 xlfdString += "-*-*"; //width, addstyle
196
197 if (xlfd.fPixelSize) {
198 std::ostringstream out;
199 out<<xlfd.fPixelSize;
200 xlfdString += "-";
201 xlfdString += out.str();
202 } else
203 xlfdString += "-*";
204
205 xlfdString += "-*-*-*-*-*-*-*-";
206}
207
208}
209
210//_________________________________________________________________
212 : fSymbolFontRegistered(false)
213{
214 //XLFD name is not exactly PS name thus generating a warning with a new Core Text.
215 fXLFDtoPostscriptNames["helvetica"] = "Helvetica";
216 fXLFDtoPostscriptNames["courier"] = "Courier";
217 fXLFDtoPostscriptNames["times"] = "Times-Roman";
218}
219
220//______________________________________________________________________________
222{
223 using Util::CFScopeGuard;
225
226#ifdef MAC_OS_X_VERSION_10_9
227 PSNameMap_t::const_iterator nameIt = fXLFDtoPostscriptNames.find(xlfd.fFamilyName);
228 const std::string &psName = nameIt == fXLFDtoPostscriptNames.end() ? xlfd.fFamilyName : nameIt->second;
229 const CFScopeGuard<CFStringRef> fontName(CFStringCreateWithCString(kCFAllocatorDefault, psName.c_str(), kCFStringEncodingMacRoman));
230#else
231 const CFScopeGuard<CFStringRef> fontName(CFStringCreateWithCString(kCFAllocatorDefault, xlfd.fFamilyName.c_str(), kCFStringEncodingMacRoman));
232#endif
233
234 const CFStrongReference<CTFontRef> baseFont(CTFontCreateWithName(fontName.Get(), xlfd.fPixelSize, 0), false);//false == do not retain
235
236 if (!baseFont.Get()) {
237 ::Error("FontCache::LoadFont", "CTFontCreateWithName failed for %s", xlfd.fFamilyName.c_str());
238 return FontStruct_t();//Haha! Die ROOT, die!
239 }
240
241 CTFontSymbolicTraits symbolicTraits = CTFontSymbolicTraits();
242
243 if (xlfd.fWeight == X11::kFWBold)
244 symbolicTraits |= kCTFontBoldTrait;
245 if (xlfd.fSlant == X11::kFSItalic)
246 symbolicTraits |= kCTFontItalicTrait;
247
248 if (symbolicTraits) {
249 const CFStrongReference<CTFontRef> font(CTFontCreateCopyWithSymbolicTraits(baseFont.Get(), xlfd.fPixelSize, 0, symbolicTraits, symbolicTraits), false);//false == do not retain.
250 if (font.Get()) {
251 if (fLoadedFonts.find(font.Get()) == fLoadedFonts.end())
252 fLoadedFonts[font.Get()] = font;
253
254 return reinterpret_cast<FontStruct_t>(font.Get());
255 }
256 }
257
258 if (fLoadedFonts.find(baseFont.Get()) == fLoadedFonts.end())
259 fLoadedFonts[baseFont.Get()] = baseFont;
260
261 return reinterpret_cast<FontStruct_t>(baseFont.Get());
262}
263
264//______________________________________________________________________________
266{
267 CTFontRef fontRef = (CTFontRef)font;
268 font_iterator fontIter = fLoadedFonts.find(fontRef);
269
270 assert(fontIter != fLoadedFonts.end() && "Attempt to unload font, not created by font manager");
271
272 fLoadedFonts.erase(fontIter);
273}
274
275//______________________________________________________________________________
276char **FontCache::ListFonts(const X11::XLFDName &xlfd, int maxNames, int &count)
277{
278 typedef std::vector<char>::size_type size_type;
279
280 count = 0;
281
282 //Ugly, ugly code. I should "think different"!!!
283 //To extract font names, I have to: create CFString, create font descriptor, create
284 //CFArray, create CTFontCollection, that's a mess!!!
285 //It's good I have my small and ugly RAII classes, otherwise the code will be
286 //messy because of all possible cleanup actions.
287
288 //First, create a font collection.
289 const Util::CFScopeGuard<CTFontCollectionRef> collectionGuard(CreateFontCollection(xlfd));
290 if (!collectionGuard.Get())
291 return 0;
292
293 Util::CFScopeGuard<CFArrayRef> fonts(CTFontCollectionCreateMatchingFontDescriptors(collectionGuard.Get()));
294 if (!fonts.Get()) {
295 ::Error("FontCache::ListFonts", "CTFontCollectionCreateMatchingFontDescriptors failed %s", xlfd.fFamilyName.c_str());
296 return 0;
297 }
298
299 std::vector<char> xlfdData;
300 //familyName is actually a null-terminated string.
301 std::vector<char> familyName;
302 X11::XLFDName newXLFD;
303 std::string xlfdString;
304
305 const CFIndex nFonts = CFArrayGetCount(fonts.Get());
306 for (CFIndex i = 0; i < nFonts && count < maxNames; ++i) {
307 CTFontDescriptorRef font = (CTFontDescriptorRef)CFArrayGetValueAtIndex(fonts.Get(), i);
308
309 if (!GetFamilyName(font, familyName))
310 continue;
311
312 if (xlfd.fFamilyName != "*" && xlfd.fFamilyName != &familyName[0])
313 continue;
314
315 newXLFD.fFamilyName = &familyName[0];
316
317 //If family name has '-', ROOT's GUI can not parse it correctly -
318 //'-' is a separator in XLFD. Just skip this font (anyway, it wan not requested by GUI, only
319 //listed by FontCache.
320 if (newXLFD.fFamilyName.find('-') != std::string::npos)
321 continue;
322
323 GetWeightAndSlant(font, newXLFD);
324
325 //Check weight and slant.
326 if (xlfd.fWeight != X11::kFWAny && newXLFD.fWeight != xlfd.fWeight)
327 continue;
328 if (xlfd.fSlant != X11::kFSAny && newXLFD.fSlant != xlfd.fSlant)
329 continue;
330
331 if (xlfd.fPixelSize) {//Size was requested.
332 GetPixelSize(font, newXLFD);
333 //Core Text supports different font sizes.
334 if (!newXLFD.fPixelSize)
335 newXLFD.fPixelSize = xlfd.fPixelSize;
336 }
337
338 //Ok, now lets create XLFD name, and place into list.
339 CreateXLFDString(newXLFD, xlfdString);
340 //
341 xlfdData.insert(xlfdData.end(), xlfdString.begin(), xlfdString.end());
342 xlfdData.push_back(0);//terminal 0.
343 ++count;
344 }
345
346 //Setup array with string addresses.
347 if (xlfdData.size()) {
348 fFontLists.push_back(fDummyList);
349 fFontLists.back().fStringData.swap(xlfdData);
350
351 std::vector<char> &data = fFontLists.back().fStringData;
352 std::vector<char *> &list = fFontLists.back().fList;
353
354 list.push_back(&data[0]);
355 for (size_type i = 1, e = data.size(); i < e; ++i) {
356 if (!data[i] && i + 1 < e)
357 list.push_back(&data[i + 1]);
358 }
359
360 return &list[0];
361 } else
362 return 0;
363}
364
365//______________________________________________________________________________
366void FontCache::FreeFontNames(char **fontList)
367{
368 if (!fontList)
369 return;
370
371 for (std::list<FontList>::iterator it = fFontLists.begin(), eIt = fFontLists.end(); it != eIt; ++it) {
372 if (fontList == &it->fList[0]) {
373 fFontLists.erase(it);
374 return;
375 }
376 }
377
378 assert(0 && "FreeFontNames, unknown fontList");
379}
380
381//______________________________________________________________________________
382unsigned FontCache::GetTextWidth(FontStruct_t font, const char *text, int nChars)
383{
384 if (nChars == 0)
385 return 0;
386
387 typedef std::vector<CGSize>::size_type size_type;
388 //
389 CTFontRef fontRef = (CTFontRef)font;
390 assert(fLoadedFonts.find(fontRef) != fLoadedFonts.end() && "Font was not created by font manager");
391
392 //nChars is either positive, or negative (take all string).
393 if (nChars < 0)
394 nChars = std::strlen(text);
395
396 std::vector<UniChar> unichars(text, text + nChars);
397
398 //Extract glyphs for a text.
399 std::vector<CGGlyph> glyphs(unichars.size());
400 CTFontGetGlyphsForCharacters(fontRef, &unichars[0], &glyphs[0], unichars.size());
401
402 //Glyps' advances for a text.
403 std::vector<CGSize> glyphAdvances(glyphs.size());
404 CTFontGetAdvancesForGlyphs(fontRef, Quartz::horizontalFontOrientation, &glyphs[0], &glyphAdvances[0], glyphs.size());
405
406 CGFloat textWidth = 0.;
407 for (size_type i = 0, e = glyphAdvances.size(); i < e; ++i)
408 textWidth += std::ceil(glyphAdvances[i].width);
409
410 return textWidth;
411}
412
413
414//_________________________________________________________________
415void FontCache::GetFontProperties(FontStruct_t font, int &maxAscent, int &maxDescent)
416{
417 CTFontRef fontRef = (CTFontRef)font;
418
419 assert(fLoadedFonts.find(fontRef) != fLoadedFonts.end() && "Font was not created by font manager");
420
421 try {
422 maxAscent = int(CTFontGetAscent(fontRef) + 0.5) + 2;
423 maxDescent = int(CTFontGetDescent(fontRef) + 0.5);
424 } catch (const std::exception &) {
425 throw;
426 }
427}
428
429
430//_________________________________________________________________
431CTFontRef FontCache::SelectFont(Font_t fontIndex, Float_t fontSize)
432{
433 fontIndex /= 10;
434
435 if (fontIndex > nPadFonts || !fontIndex) {
436 ::Warning("FontCache::SelectFont", "Font with index %d was requested", fontIndex);
437 fontIndex = 3;//Select the Helvetica as default.
438 } else
439 fontIndex -= 1;
440
441 if (fontIndex == 11 || fontIndex == 14)//Special case, our own symbol.ttf file.
442 return SelectSymbolFont(fontSize, fontIndex);
443
444 const UInt_t fixedSize = UInt_t(fontSize);
445 font_map_iterator it = fFonts[fontIndex].find(fixedSize);
446
447 if (it == fFonts[fontIndex].end()) {
448 //Insert the new font.
449 try {
450 const CTFontGuard_t font(CTFontCreateWithName(fixedFontNames[fontIndex], fixedSize, 0), false);
451 if (!font.Get()) {//With Apple's lame documentation it's not clear, if function can return 0.
452 ::Error("FontCache::SelectFont", "CTFontCreateWithName failed for font %d", fontIndex);
453 return 0;
454 }
455
456 fFonts[fontIndex][fixedSize] = font;//Insetion can throw.
457 return fSelectedFont = font.Get();
458 } catch (const std::exception &) {//Bad alloc.
459 return 0;
460 }
461 }
462
463 return fSelectedFont = it->second.Get();
464}
465
466//_________________________________________________________________
467CTFontRef FontCache::SelectSymbolFont(Float_t fontSize, unsigned fontIndex)
468{
469 assert(fontIndex == 11 || fontIndex == 14 && "SelectSymbolFont, parameter fontIndex has invalid value");
470
471 const UInt_t fixedSize = UInt_t(fontSize);
472 font_map_iterator it = fFonts[fontIndex].find(fixedSize);//In ROOT, 11 is a font from symbol.ttf.
473
474 if (it == fFonts[fontIndex].end()) {
475 //This GetValue
476 const char * const fontDirectoryPath = gEnv->GetValue("Root.TTFontPath",TROOT::GetTTFFontDir());
477 char * const fontFileName = gSystem->Which(fontDirectoryPath, "symbol.ttf", kReadPermission);//This must be deleted.
478
479 const Util::ScopedArray<char> arrayGuard(fontFileName);
480
481 if (!fontFileName || fontFileName[0] == 0) {
482 ::Error("FontCache::SelectSymbolFont", "symbol.ttf file not found");
483 return 0;
484 }
485
486 try {
487 const Util::CFScopeGuard<CFStringRef> path(CFStringCreateWithCString(kCFAllocatorDefault, fontFileName, kCFURLPOSIXPathStyle));
488 if (!path.Get()) {
489 ::Error("FontCache::SelectSymbolFont", "CFStringCreateWithCString failed");
490 return 0;
491 }
492
493 const Util::CFScopeGuard<CFURLRef> fontURL(CFURLCreateWithFileSystemPath(kCFAllocatorDefault, path.Get(), kCFURLPOSIXPathStyle, false));
494 if (!fontURL.Get()) {
495 ::Error("FontCache::SelectSymbolFont", "CFURLCreateWithFileSystemPath failed");
496 return 0;
497 }
498
499 //Try to register this font.
501 CFErrorRef err = 0;
502 fSymbolFontRegistered = CTFontManagerRegisterFontsForURL(fontURL.Get(), kCTFontManagerScopeProcess, &err);
504 ::Error("FontCache::SelectSymbolFont", "CTFontManagerRegisterFontsForURL failed");
505 if (err)
506 CFRelease(err);
507 return 0;
508 }
509 }
510
511 const Util::CFScopeGuard<CFArrayRef> arr(CTFontManagerCreateFontDescriptorsFromURL(fontURL.Get()));
512 if (!arr.Get()) {
513 ::Error("FontCache::SelectSymbolFont", "CTFontManagerCreateFontDescriptorsFromURL failed");
514 return 0;
515 }
516
517 CTFontDescriptorRef fontDesc = (CTFontDescriptorRef)CFArrayGetValueAtIndex(arr.Get(), 0);
518
519 const CGAffineTransform shearMatrix = {1., 0., 0.26794, 1., 0., 0.};//Yes, these are hardcoded values, taken from TPDF class.
520 const CTFontGuard_t font(CTFontCreateWithFontDescriptorAndOptions(fontDesc, fixedSize,
521 fontIndex == 11 ? &CGAffineTransformIdentity :
522 &shearMatrix, kCTFontOptionsDefault), false);
523 if (!font.Get()) {
524 ::Error("FontCache::SelectSymbolFont", "CTFontCreateWithFontDescriptor failed");
525 return 0;
526 }
527
528 fFonts[fontIndex][fixedSize] = font;//This can throw.
529 return fSelectedFont = font.Get();
530 } catch (const std::exception &) {//Bad alloc.
531 //RAII destructors should do their work.
532 return 0;
533 }
534 }
535
536 return fSelectedFont = it->second.Get();
537}
538
539//_________________________________________________________________
540void FontCache::GetTextBounds(UInt_t &w, UInt_t &h, const char *text)const
541{
542 assert(fSelectedFont != 0 && "GetTextBounds: no font was selected");
543
544 try {
545 const Quartz::TextLine ctLine(text, fSelectedFont);
546 ctLine.GetBounds(w, h);
547 h += 2;
548 } catch (const std::exception &) {
549 throw;
550 }
551}
552
553//_________________________________________________________________
554void FontCache::GetTextBounds(UInt_t &w, UInt_t &h, const std::vector<UniChar> &unichars)const
555{
556 assert(fSelectedFont != 0 && "GetTextBounds: no font was selected");
557
558 try {
559 const Quartz::TextLine ctLine(unichars, fSelectedFont);
560 ctLine.GetBounds(w, h);
561 h += 2;
562 } catch (const std::exception &) {
563 throw;
564 }
565}
566
567//_________________________________________________________________
569{
570 assert(fSelectedFont != 0 && "GetAscent, no font was selected");
571 return CTFontGetAscent(fSelectedFont) + 1;
572}
573
574//_________________________________________________________________
575double FontCache::GetAscent(const char *text)const
576{
577 assert(text != 0 && "GetAscent, parameter 'text' is null");
578 assert(fSelectedFont != 0 && "GetAscent, no font was selected");
579
580 try {
581 const Quartz::TextLine ctLine(text, fSelectedFont);
582 Int_t ascent = 0, descent = 0;
583 ctLine.GetAscentDescent(ascent, descent);
584 return ascent;
585 } catch (const std::exception &) {
586 throw;
587 }
588}
589
590//_________________________________________________________________
591double FontCache::GetAscent(const std::vector<UniChar> &unichars)const
592{
593 assert(fSelectedFont != 0 && "GetAscent, no font was selected");
594
595 try {
596 const Quartz::TextLine ctLine(unichars, fSelectedFont);
597 Int_t ascent = 0, descent = 0;
598 ctLine.GetAscentDescent(ascent, descent);
599 return ascent;
600 } catch (const std::exception &) {
601 throw;
602 }
603}
604
605//_________________________________________________________________
607{
608 assert(fSelectedFont != 0 && "GetDescent, no font was selected");
609 return CTFontGetDescent(fSelectedFont) + 1;
610}
611
612//_________________________________________________________________
613double FontCache::GetDescent(const char *text)const
614{
615 assert(text != 0 && "GetDescent, parameter 'text' is null");
616 assert(fSelectedFont != 0 && "GetDescent, no font was selected");
617
618 try {
619 const Quartz::TextLine ctLine(text, fSelectedFont);
620 Int_t ascent = 0, descent = 0;
621 ctLine.GetAscentDescent(ascent, descent);
622 return descent;
623 } catch (const std::exception &) {
624 throw;
625 }
626}
627
628//_________________________________________________________________
629double FontCache::GetDescent(const std::vector<UniChar> &unichars)const
630{
631 assert(fSelectedFont != 0 && "GetDescent, no font was selected");
632
633 try {
634 const Quartz::TextLine ctLine(unichars, fSelectedFont);
635 Int_t ascent = 0, descent = 0;
636 ctLine.GetAscentDescent(ascent, descent);
637 return descent;
638 } catch (const std::exception &) {
639 throw;
640 }
641}
642
643//_________________________________________________________________
645{
646 assert(fSelectedFont != 0 && "GetLeading, no font was selected");
647 return CTFontGetLeading(fSelectedFont);
648}
649
650
651}//Details
652}//MacOSX
653}//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:81
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:561
void FreeFontNames(char **fontList)
Definition FontCache.mm:366
void GetFontProperties(FontStruct_t font, int &maxAscent, int &maxDescent)
Definition FontCache.mm:415
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:276
unsigned GetTextWidth(FontStruct_t font, const char *text, int nChars)
Definition FontCache.mm:382
CTFontRef SelectSymbolFont(Float_t fontSize, unsigned fontIndex)
Definition FontCache.mm:467
std::list< FontList > fFontLists
Definition FontCache.h:107
void GetTextBounds(UInt_t &w, UInt_t &h, const char *text) const
Definition FontCache.mm:540
std::map< CTFontRef, CTFontGuard_t > fLoadedFonts
Definition FontCache.h:81
FontStruct_t LoadFont(const X11::XLFDName &xlfd)
Definition FontCache.mm:221
void UnloadFont(FontStruct_t font)
Definition FontCache.mm:265
CTFontRef SelectFont(Font_t fontIndex, Float_t fontSize)
Definition FontCache.mm:431
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:3193
virtual char * Which(const char *search, const char *file, EAccessMode mode=kFileExists)
Find location of file in a search path.
Definition TSystem.cxx:1548
const CTFontOrientation horizontalFontOrientation
Definition QuartzText.mm:39
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
const char * fonts[]
Definition texts.C:25