41 const CFStringRef fixedFontNames[FontCache::nPadFonts] =
43 CFSTR(
"TimesNewRomanPS-ItalicMT"),
44 CFSTR(
"TimesNewRomanPS-BoldMT"),
45 CFSTR(
"TimesNewRomanPS-BoldItalicMT"),
47 CFSTR(
"Helvetica-Oblique"),
48 CFSTR(
"Helvetica-Bold"),
49 CFSTR(
"Helvetica-BoldOblique"),
51 CFSTR(
"Courier-Oblique"),
52 CFSTR(
"Courier-Bold"),
53 CFSTR(
"Courier-BoldOblique"),
55 CFSTR(
"TimesNewRomanPSMT"),
57 CFSTR(
"Symbol-Italic")
61 CTFontCollectionRef CreateFontCollection(
const X11::XLFDName &)
63 CTFontCollectionRef ctCollection = CTFontCollectionCreateFromAvailableFonts(0);
65 ::Error(
"CreateFontCollection",
"CTFontCollectionCreateFromAvailableFonts failed");
105 bool GetFamilyName(CTFontDescriptorRef fontDescriptor, std::vector<char> &name)
108 assert(fontDescriptor != 0 &&
"GetFamilyName, parameter 'fontDescriptor' is null");
112 Util::CFScopeGuard<CFStringRef> cfFamilyName((CFStringRef)CTFontDescriptorCopyAttribute(fontDescriptor, kCTFontFamilyNameAttribute));
113 if (
const CFIndex cfLen = CFStringGetLength(cfFamilyName.Get())) {
114 name.resize(cfLen + 1);
115 if (CFStringGetCString(cfFamilyName.Get(), &name[0], name.size(), kCFStringEncodingMacRoman))
122 #ifdef MAC_OS_X_VERSION_10_9
125 bool GetPostscriptName(CTFontDescriptorRef fontDescriptor, std::vector<char> &name)
128 assert(fontDescriptor != 0 &&
"GetPostscriptName, parameter 'fontDescriptor' is null");
132 Util::CFScopeGuard<CFStringRef> cfFamilyName((CFStringRef)CTFontDescriptorCopyAttribute(fontDescriptor, kCTFontNameAttribute));
134 if (
const CFIndex cfLen = CFStringGetLength(cfFamilyName.Get())) {
135 name.resize(cfLen + 1);
136 if (CFStringGetCString(cfFamilyName.Get(), &name[0], name.size(), kCFStringEncodingMacRoman))
146 void GetWeightAndSlant(CTFontDescriptorRef fontDescriptor,
X11::XLFDName &newXLFD)
149 const Util::CFScopeGuard<CFDictionaryRef> traits((CFDictionaryRef)CTFontDescriptorCopyAttribute(fontDescriptor, kCTFontTraitsAttribute));
151 if (CFNumberRef symbolTraits = (CFNumberRef)CFDictionaryGetValue(traits.Get(), kCTFontSymbolicTrait)) {
153 CFNumberGetValue(symbolTraits, kCFNumberIntType, &val);
154 if (val & kCTFontItalicTrait)
159 if (val & kCTFontBoldTrait)
184 void GetPixelSize(CTFontDescriptorRef fontDescriptor,
X11::XLFDName &newXLFD)
186 const Util::CFScopeGuard<CFNumberRef> size((CFNumberRef)CTFontDescriptorCopyAttribute(fontDescriptor, kCTFontSizeAttribute));
189 if(CFNumberIsFloatType(size.Get())) {
191 CFNumberGetValue(size.Get(), kCFNumberDoubleType, &val);
194 CFNumberGetValue(size.Get(), kCFNumberIntType, &pixelSize);
202 void CreateXLFDString(
const X11::XLFDName &xlfd, std::string &xlfdString)
204 xlfdString =
"-CoreText-";
205 xlfdString += xlfd.fFamilyName;
208 xlfdString += "-bold";
210 xlfdString += "-normal";
217 xlfdString += "-*-*";
220 std::ostringstream
out;
223 xlfdString += out.str();
227 xlfdString += "-*-*-*-*-*-*-*-";
234 : fSymbolFontRegistered(
false)
248 #ifdef MAC_OS_X_VERSION_10_9
251 const CFScopeGuard<CFStringRef> fontName(CFStringCreateWithCString(kCFAllocatorDefault, psName.c_str(), kCFStringEncodingMacRoman));
253 const CFScopeGuard<CFStringRef> fontName(CFStringCreateWithCString(kCFAllocatorDefault, xlfd.
fFamilyName.c_str(), kCFStringEncodingMacRoman));
256 const CFStrongReference<CTFontRef> baseFont(CTFontCreateWithName(fontName.Get(), xlfd.
fPixelSize, 0),
false);
258 if (!baseFont.Get()) {
259 ::Error(
"FontCache::LoadFont",
"CTFontCreateWithName failed for %s", xlfd.
fFamilyName.c_str());
263 CTFontSymbolicTraits symbolicTraits = CTFontSymbolicTraits();
266 symbolicTraits |= kCTFontBoldTrait;
268 symbolicTraits |= kCTFontItalicTrait;
270 if (symbolicTraits) {
271 const CFStrongReference<CTFontRef> font(CTFontCreateCopyWithSymbolicTraits(baseFont.Get(), xlfd.
fPixelSize, 0, symbolicTraits, symbolicTraits),
false);
289 CTFontRef fontRef = (CTFontRef)font;
292 assert(fontIter !=
fLoadedFonts.end() &&
"Attempt to unload font, not created by font manager");
300 typedef std::vector<char>::size_type size_type;
312 if (!collectionGuard.
Get())
317 ::Error(
"FontCache::ListFonts",
"CTFontCollectionCreateMatchingFontDescriptors failed %s", xlfd.
fFamilyName.c_str());
321 std::vector<char> xlfdData;
323 std::vector<char> familyName;
325 std::string xlfdString;
327 const CFIndex nFonts = CFArrayGetCount(fonts.
Get());
328 for (CFIndex i = 0; i < nFonts && count < maxNames; ++i) {
329 CTFontDescriptorRef font = (CTFontDescriptorRef)CFArrayGetValueAtIndex(fonts.
Get(), i);
331 if (!GetFamilyName(font, familyName))
342 if (newXLFD.
fFamilyName.find(
'-') != std::string::npos)
345 GetWeightAndSlant(font, newXLFD);
354 GetPixelSize(font, newXLFD);
360 #ifdef MAC_OS_X_VERSION_10_9
365 std::vector<char> postscriptName;
366 if (GetPostscriptName(font, postscriptName)) {
374 CreateXLFDString(newXLFD, xlfdString);
376 xlfdData.insert(xlfdData.end(), xlfdString.begin(), xlfdString.end());
377 xlfdData.push_back(0);
382 if (xlfdData.size()) {
386 std::vector<char> &data =
fFontLists.back().fStringData;
387 std::vector<char *> &list =
fFontLists.back().fList;
389 list.push_back(&data[0]);
390 for (size_type i = 1, e = data.size(); i < e; ++i) {
391 if (!data[i] && i + 1 < e)
392 list.push_back(&data[i + 1]);
406 for (std::list<FontList>::iterator it =
fFontLists.begin(), eIt =
fFontLists.end(); it != eIt; ++it) {
407 if (fontList == &it->fList[0]) {
413 assert(0 &&
"FreeFontNames, unknown fontList");
419 typedef std::vector<CGSize>::size_type size_type;
421 CTFontRef fontRef = (CTFontRef)font;
426 nChars = std::strlen(text);
428 std::vector<UniChar> unichars(text, text + nChars);
431 std::vector<CGGlyph> glyphs(unichars.size());
432 CTFontGetGlyphsForCharacters(fontRef, &unichars[0], &glyphs[0], unichars.size());
435 std::vector<CGSize> glyphAdvances(glyphs.size());
438 CGFloat textWidth = 0.;
439 for (size_type i = 0, e = glyphAdvances.size(); i < e; ++i)
440 textWidth +=
std::ceil(glyphAdvances[i].width);
449 CTFontRef fontRef = (CTFontRef)font;
454 maxAscent = int(CTFontGetAscent(fontRef) + 0.5) + 2;
455 maxDescent = int(CTFontGetDescent(fontRef) + 0.5);
456 }
catch (
const std::exception &) {
467 if (fontIndex >
nPadFonts || !fontIndex) {
468 ::Warning(
"FontCache::SelectFont",
"Font with index %d was requested", fontIndex);
473 if (fontIndex == 11 || fontIndex == 14)
479 if (it ==
fFonts[fontIndex].end()) {
482 const CTFontGuard_t font(CTFontCreateWithName(fixedFontNames[fontIndex], fixedSize, 0),
false);
484 ::Error(
"FontCache::SelectFont",
"CTFontCreateWithName failed for font %d", fontIndex);
488 fFonts[fontIndex][fixedSize] = font;
490 }
catch (
const std::exception &) {
501 assert(fontIndex == 11 || fontIndex == 14 &&
"SelectSymbolFont, parameter fontIndex has invalid value");
506 if (it ==
fFonts[fontIndex].end()) {
508 const char *
const fontDirectoryPath =
gEnv->
GetValue(
"Root.TTFontPath",
"$(ROOTSYS)/fonts");
513 if (!fontFileName || fontFileName[0] == 0) {
514 ::Error(
"FontCache::SelectSymbolFont",
"symbol.ttf file not found");
521 ::Error(
"FontCache::SelectSymbolFont",
"CFStringCreateWithCString failed");
526 if (!fontURL.
Get()) {
527 ::Error(
"FontCache::SelectSymbolFont",
"CFURLCreateWithFileSystemPath failed");
536 ::Error(
"FontCache::SelectSymbolFont",
"CTFontManagerRegisterFontsForURL failed");
545 ::Error(
"FontCache::SelectSymbolFont",
"CTFontManagerCreateFontDescriptorsFromURL failed");
549 CTFontDescriptorRef fontDesc = (CTFontDescriptorRef)CFArrayGetValueAtIndex(arr.
Get(), 0);
551 const CGAffineTransform shearMatrix = {1., 0., 0.26794, 1., 0., 0.};
552 const CTFontGuard_t font(CTFontCreateWithFontDescriptorAndOptions(fontDesc, fixedSize,
553 fontIndex == 11 ? &CGAffineTransformIdentity :
554 &shearMatrix, kCTFontOptionsDefault),
false);
556 ::Error(
"FontCache::SelectSymbolFont",
"CTFontCreateWithFontDescriptor failed");
560 fFonts[fontIndex][fixedSize] = font;
562 }
catch (
const std::exception &) {
580 }
catch (
const std::exception &) {
594 }
catch (
const std::exception &) {
609 assert(text != 0 &&
"GetAscent, parameter 'text' is null");
614 Int_t ascent = 0, descent = 0;
617 }
catch (
const std::exception &) {
629 Int_t ascent = 0, descent = 0;
632 }
catch (
const std::exception &) {
647 assert(text != 0 &&
"GetDescent, parameter 'text' is null");
652 Int_t ascent = 0, descent = 0;
655 }
catch (
const std::exception &) {
667 Int_t ascent = 0, descent = 0;
670 }
catch (
const std::exception &) {
char ** ListFonts(const X11::XLFDName &xlfd, int maxNames, int &count)
FontStruct_t LoadFont(const X11::XLFDName &xlfd)
FontMap_t fFonts[nPadFonts]
void GetBounds(UInt_t &w, UInt_t &h) const
std::map< CTFontRef, CTFontGuard_t > fLoadedFonts
virtual char * Which(const char *search, const char *file, EAccessMode mode=kFileExists)
Find location of file in a search path.
unsigned GetTextWidth(FontStruct_t font, const char *text, int nChars)
ClassImp(TIterator) Bool_t TIterator return false
Compare two iterator objects.
std::map< CTFontRef, CTFontGuard_t >::iterator font_iterator
PSNameMap_t fXLFDtoPostscriptNames
const CTFontOrientation horizontalFontOrientation
void GetTextBounds(UInt_t &w, UInt_t &h, const char *text) const
void FreeFontNames(char **fontList)
void GetAscentDescent(Int_t &asc, Int_t &desc) const
double GetLeading() const
R__EXTERN TSystem * gSystem
virtual Int_t GetValue(const char *name, Int_t dflt)
Returns the integer value for a resource.
void Warning(const char *location, const char *msgfmt,...)
std::list< FontList > fFontLists
FontMap_t::iterator font_map_iterator
void GetFontProperties(FontStruct_t font, int &maxAscent, int &maxDescent)
CTFontRef SelectFont(Font_t fontIndex, Float_t fontSize)
bool fSymbolFontRegistered
void UnloadFont(FontStruct_t font)
CTFontRef SelectSymbolFont(Float_t fontSize, unsigned fontIndex)
double GetDescent() const
void Error(ErrorHandler_t func, int code, const char *va_(fmt),...)
Write error message and call a handler, if required.