iPlug2 - C++ Audio Plug-in Framework
Loading...
Searching...
No Matches
IGraphicsCoreText.mm
1/*
2 ==============================================================================
3
4 This file is part of the iPlug 2 library. Copyright (C) the iPlug 2 developers.
5
6 See LICENSE.txt for more info.
7
8 ==============================================================================
9*/
10
11#include "IGraphicsCoreText.h"
12#include "IPlugPaths.h"
13
14using namespace iplug;
15using namespace igraphics;
16
17IFontDataPtr CoreTextFont::GetFontData()
18{
19 CFLocal<CFDataRef> rawData(CGDataProviderCopyData(mProvider));
20 const UInt8* bytes = CFDataGetBytePtr(rawData.Get());
21 int faceIdx = 0;
22
23 if (mStyleString.GetLength())
24 faceIdx = GetFaceIdx(bytes, static_cast<int>(CFDataGetLength(rawData.Get())), mStyleString.Get());
25
26 IFontDataPtr fontData(new IFontData(bytes, static_cast<int>(CFDataGetLength(rawData.Get())), faceIdx));
27
28 return fontData;
29}
30
31CoreTextFont::~CoreTextFont()
32{
33 CGDataProviderRelease(mProvider);
34 if (mDescriptor)
35 CFRelease(mDescriptor);
36};
37
38PlatformFontPtr CoreTextHelpers::LoadPlatformFont(const char* fontID, const char* fileNameOrResID, const char* bundleID, const char* sharedResourceSubPath)
39{
40 WDL_String fullPath;
41 const EResourceLocation fontLocation = LocateResource(fileNameOrResID, "ttf", fullPath, bundleID, nullptr, sharedResourceSubPath);
42
43 if (fontLocation == kNotFound)
44 return nullptr;
45
46 CFLocal<CFStringRef> path(CFStringCreateWithCString(NULL, fullPath.Get(), kCFStringEncodingUTF8));
47 CFLocal<CFURLRef> url(CFURLCreateWithFileSystemPath(NULL, path.Get(), kCFURLPOSIXPathStyle, false));
48 CFLocal<CGDataProviderRef> provider(url.Get() ? CGDataProviderCreateWithURL(url.Get()) : nullptr); // CGDataProviderCreateWithURL will fail in macOS sandbox!
49
50 if (!provider.Get())
51 return nullptr;
52
53 CFLocal<CGFontRef> cgFont(CGFontCreateWithDataProvider(provider.Get()));
54 CFLocal<CTFontRef> ctFont(CTFontCreateWithGraphicsFont(cgFont.Get(), 0.f, NULL, NULL));
55 CFLocal<CTFontDescriptorRef> descriptor(CTFontCopyFontDescriptor(ctFont.Get()));
56
57 if (!descriptor.Get())
58 return nullptr;
59
60 return PlatformFontPtr(new CoreTextFont(descriptor.Release(), provider.Release(), "", false));
61}
62
63PlatformFontPtr CoreTextHelpers::LoadPlatformFont(const char* fontID, const char* fontName, ETextStyle style)
64{
65 CFLocal<CFStringRef> fontStr(CFStringCreateWithCString(NULL, fontName, kCFStringEncodingUTF8));
66 CFLocal<CFStringRef> styleStr(CFStringCreateWithCString(NULL, TextStyleString(style), kCFStringEncodingUTF8));
67
68 CFStringRef keys[] = { kCTFontFamilyNameAttribute, kCTFontStyleNameAttribute };
69 CFTypeRef values[] = { fontStr.Get(), styleStr.Get() };
70
71 CFLocal<CFDictionaryRef> dictionary(CFDictionaryCreate(NULL, (const void**)&keys, (const void**)&values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
72 CFLocal<CTFontDescriptorRef> descriptor(CTFontDescriptorCreateWithAttributes(dictionary.Get()));
73 CFLocal<CFSetRef> keysAsSet(CFSetCreate(NULL, (const void**)&keys, 2, &kCFTypeSetCallBacks));
74 CFLocal<CFArrayRef> matched(CTFontDescriptorCreateMatchingFontDescriptors(descriptor.Get(), keysAsSet.Get()));
75
76 for (int i = 0; i < CFArrayGetCount(matched.Get()); i++)
77 {
78 // Loop until we get a font which provides data
79
80 CTFontDescriptorRef testDescriptor = (CTFontDescriptorRef) CFArrayGetValueAtIndex(matched.Get(), i);
81 CFLocal<CFURLRef> url((CFURLRef) CTFontDescriptorCopyAttribute(testDescriptor, kCTFontURLAttribute));
82 CFLocal<CGDataProviderRef> provider(url.Get() ? CGDataProviderCreateWithURL(url.Get()) : nullptr);
83
84 if (provider.Get())
85 {
86 CFRetain(testDescriptor);
87 return PlatformFontPtr(new CoreTextFont(testDescriptor, provider.Release(), TextStyleString(style), true));
88 }
89 }
90
91 return nullptr;
92}
93
94void releaseFontData(void* info, const void* data, size_t size)
95{
96 uint8_t* pData = (uint8_t*)data;
97 delete[] pData;
98}
99
100PlatformFontPtr CoreTextHelpers::LoadPlatformFont(const char* fontID, void* pData, int dataSize)
101{
102 uint8_t* dataCopy = new uint8_t[dataSize];
103 memcpy((void*)dataCopy, pData, dataSize);
104
105 CFLocal<CGDataProviderRef> provider(CGDataProviderCreateWithData(nullptr, dataCopy, (size_t)dataSize, &releaseFontData));
106
107 if (!provider.Get())
108 return nullptr;
109
110 CFLocal<CGFontRef> cgFont(CGFontCreateWithDataProvider(provider.Get()));
111 CFLocal<CTFontRef> ctFont(CTFontCreateWithGraphicsFont(cgFont.Get(), 0.f, NULL, NULL));
112 CFLocal<CTFontDescriptorRef> descriptor(CTFontCopyFontDescriptor(ctFont.Get()));
113
114 if (!descriptor.Get())
115 return nullptr;
116
117 return PlatformFontPtr(new CoreTextFont(descriptor.Release(), provider.Release(), "", false));
118}
119
120void CoreTextHelpers::CachePlatformFont(const char* fontID, const PlatformFontPtr& font, StaticStorage<CoreTextFontDescriptor>& cache)
121{
122 StaticStorage<CoreTextFontDescriptor>::Accessor storage(cache);
123
124 CTFontDescriptorRef descriptor = font->GetDescriptor();
125 IFontDataPtr data = font->GetFontData();
126
127 if (!storage.Find(fontID))
128 storage.Add(new CoreTextFontDescriptor(descriptor, data->GetHeightEMRatio()), fontID);
129}
130
131CoreTextFontDescriptor* CoreTextHelpers::GetCTFontDescriptor(const IText& text, StaticStorage<CoreTextFontDescriptor>& cache)
132{
133 StaticStorage<CoreTextFontDescriptor>::Accessor storage(cache);
134
135 CoreTextFontDescriptor* cachedFont = storage.Find(text.mFont);
136
137 assert(cachedFont && "font not found - did you forget to load it?");
138
139 return cachedFont;
140}
141
Common paths useful for plug-ins.
EResourceLocation LocateResource(const char *fileNameOrResID, const char *type, WDL_String &result, const char *bundleID, void *pHInstance, const char *sharedResourcesSubPath)
Find the absolute path of a resource based on it's file name (e.g.
static const char * TextStyleString(ETextStyle style)
Helper to get a CString based on ETextStyle.
IText is used to manage font and text/text entry style for a piece of text on the UI,...