9#if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS)
11#ifdef SK_BUILD_FOR_MAC
12#import <ApplicationServices/ApplicationServices.h>
15#ifdef SK_BUILD_FOR_IOS
16#include <CoreText/CoreText.h>
17#include <CoreText/CTFontManager.h>
18#include <CoreGraphics/CoreGraphics.h>
19#include <CoreFoundation/CoreFoundation.h>
45#if (defined(SK_BUILD_FOR_IOS) && defined(__IPHONE_14_0) && \
46 __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_14_0) || \
47 (defined(SK_BUILD_FOR_MAC) && defined(__MAC_11_0) && \
48 __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_11_0)
50static uint32_t SkGetCoreTextVersion() {
53 static const uint32_t kCoreTextVersionNEWER = 0x000D0000;
54 return kCoreTextVersionNEWER;
59static uint32_t SkGetCoreTextVersion() {
61 static const bool kCoreTextIsAvailable = (&CTGetCoreTextVersion !=
nullptr);
62 if (kCoreTextIsAvailable) {
63 return CTGetCoreTextVersion();
67 static const uint32_t kCoreTextVersionUNKNOWN = 0;
68 return kCoreTextVersionUNKNOWN;
73static SkUniqueCFRef<CFStringRef> make_CFString(
const char s[]) {
74 return SkUniqueCFRef<CFStringRef>(CFStringCreateWithCString(
nullptr,
s, kCFStringEncodingUTF8));
79 SkUniqueCFRef<CTFontRef> ctFont(CTFontCreateWithFontDescriptor(
desc, 0,
nullptr));
87static SkUniqueCFRef<CTFontDescriptorRef> create_descriptor(
const char familyName[],
89 SkUniqueCFRef<CFMutableDictionaryRef> cfAttributes(
90 CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
91 &kCFTypeDictionaryKeyCallBacks,
92 &kCFTypeDictionaryValueCallBacks));
94 SkUniqueCFRef<CFMutableDictionaryRef> cfTraits(
95 CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
96 &kCFTypeDictionaryKeyCallBacks,
97 &kCFTypeDictionaryValueCallBacks));
99 if (!cfAttributes || !cfTraits) {
110 static const uint32_t kSkiaLocalCTVersionNumber10_14 = 0x000B0000;
111 static const uint32_t kSkiaLocalCTVersionNumber10_15 = 0x000C0000;
117 if (SkGetCoreTextVersion() < kSkiaLocalCTVersionNumber10_14) {
118 CTFontSymbolicTraits ctFontTraits = 0;
120 ctFontTraits |= kCTFontBoldTrait;
123 ctFontTraits |= kCTFontItalicTrait;
125 SkUniqueCFRef<CFNumberRef> cfFontTraits(
126 CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &ctFontTraits));
128 CFDictionaryAddValue(cfTraits.get(), kCTFontSymbolicTrait, cfFontTraits.get());
133 CGFloat ctWeight = SkCTFontCTWeightForCSSWeight(style.
weight());
134 SkUniqueCFRef<CFNumberRef> cfFontWeight(
135 CFNumberCreate(kCFAllocatorDefault, kCFNumberCGFloatType, &ctWeight));
137 CFDictionaryAddValue(cfTraits.get(), kCTFontWeightTrait, cfFontWeight.get());
140 CGFloat ctWidth = SkCTFontCTWidthForCSSWidth(style.
width());
141 SkUniqueCFRef<CFNumberRef> cfFontWidth(
142 CFNumberCreate(kCFAllocatorDefault, kCFNumberCGFloatType, &ctWidth));
144 CFDictionaryAddValue(cfTraits.get(), kCTFontWidthTrait, cfFontWidth.get());
148 if (SkGetCoreTextVersion() != kSkiaLocalCTVersionNumber10_15) {
150 SkUniqueCFRef<CFNumberRef> cfFontSlant(
151 CFNumberCreate(kCFAllocatorDefault, kCFNumberCGFloatType, &ctSlant));
153 CFDictionaryAddValue(cfTraits.get(), kCTFontSlantTrait, cfFontSlant.get());
157 CFDictionaryAddValue(cfAttributes.get(), kCTFontTraitsAttribute, cfTraits.get());
161 SkUniqueCFRef<CFStringRef> cfFontName = make_CFString(familyName);
163 CFDictionaryAddValue(cfAttributes.get(), kCTFontFamilyNameAttribute, cfFontName.get());
167 return SkUniqueCFRef<CTFontDescriptorRef>(
168 CTFontDescriptorCreateWithAttributes(cfAttributes.get()));
177 SkUniqueCFRef<CTFontRef> ctFont(CTFontCreateWithFontDescriptor(
desc, 0,
nullptr));
182 const CTFontSymbolicTraits traits = CTFontGetSymbolicTraits(ctFont.get());
183 CTFontSymbolicTraits expected_traits = traits;
185 expected_traits |= kCTFontItalicTrait;
188 expected_traits |= kCTFontBoldTrait;
191 if (expected_traits != traits) {
192 SkUniqueCFRef<CTFontRef> ctNewFont(CTFontCreateCopyWithSymbolicTraits(
193 ctFont.get(), 0,
nullptr, expected_traits, expected_traits));
195 ctFont = std::move(ctNewFont);
204 SkUniqueCFRef<CTFontDescriptorRef>
desc = create_descriptor(familyName, style);
208 return create_from_desc_and_style(
desc.get(), style);
211static const char* map_css_names(
const char*
name) {
212 static const struct {
216 {
"sans-serif",
"Helvetica" },
217 {
"serif",
"Times" },
218 {
"monospace",
"Courier" }
232 SkUniqueCFRef<CFStringRef> ref((CFStringRef)CTFontDescriptorCopyAttribute(
desc,
name));
236 SkStringFromCFString(ref.get(),
value);
240static inline int sqr(
int value) {
247 return sqr(
a.weight() -
b.weight()) +
248 sqr((
a.width() -
b.width()) * 100) +
249 sqr((
a.slant() !=
b.slant()) * 900);
252static SkUniqueCFRef<CFSetRef> name_required() {
253 CFStringRef set_values[] = {kCTFontFamilyNameAttribute};
254 return SkUniqueCFRef<CFSetRef>(CFSetCreate(kCFAllocatorDefault,
255 reinterpret_cast<const void**
>(set_values),
std::size(set_values),
256 &kCFTypeSetCallBacks));
261 SkFontStyleSet_Mac(CTFontDescriptorRef
desc)
262 : fArray(CTFontDescriptorCreateMatchingFontDescriptors(
desc, name_required().
get()))
266 fArray.reset(CFArrayCreate(
nullptr,
nullptr, 0,
nullptr));
271 int count()
override {
277 CTFontDescriptorRef
desc = (CTFontDescriptorRef)CFArrayGetValueAtIndex(fArray.get(), index);
279 *style = SkCTFontDescriptorGetSkFontStyle(
desc,
false);
282 if (!find_desc_str(
desc, kCTFontStyleNameAttribute,
name)) {
289 SkASSERT((
unsigned)index < (
unsigned)CFArrayGetCount(fArray.get()));
290 CTFontDescriptorRef
desc = (CTFontDescriptorRef)CFArrayGetValueAtIndex(fArray.get(), index);
292 return create_from_desc(
desc);
299 return create_from_desc(findMatchingDesc(pattern));
303 SkUniqueCFRef<CFArrayRef> fArray;
306 CTFontDescriptorRef findMatchingDesc(
const SkFontStyle& pattern)
const {
308 CTFontDescriptorRef bestDesc =
nullptr;
311 CTFontDescriptorRef
desc = (CTFontDescriptorRef)CFArrayGetValueAtIndex(fArray.get(),
i);
312 int metric = compute_metric(pattern, SkCTFontDescriptorGetSkFontStyle(
desc,
false));
316 if (metric < bestMetric) {
326SkUniqueCFRef<CFArrayRef> SkCopyAvailableFontFamilyNames(CTFontCollectionRef collection) {
328 SkUniqueCFRef<CFArrayRef> descriptors(
329 CTFontCollectionCreateMatchingFontDescriptors(collection));
332 auto addDescriptorFamilyNameToSet = [](
const void*
value,
void* context) ->
void {
333 CTFontDescriptorRef descriptor =
static_cast<CTFontDescriptorRef
>(
value);
334 CFMutableSetRef familyNameSet =
static_cast<CFMutableSetRef
>(context);
335 SkUniqueCFRef<CFTypeRef> familyName(
336 CTFontDescriptorCopyAttribute(descriptor, kCTFontFamilyNameAttribute));
338 CFSetAddValue(familyNameSet, familyName.get());
341 SkUniqueCFRef<CFMutableSetRef> familyNameSet(
342 CFSetCreateMutable(kCFAllocatorDefault, 0, &kCFTypeSetCallBacks));
343 CFArrayApplyFunction(descriptors.get(), CFRangeMake(0, CFArrayGetCount(descriptors.get())),
344 addDescriptorFamilyNameToSet, familyNameSet.get());
347 CFIndex
count = CFSetGetCount(familyNameSet.get());
348 std::unique_ptr<const void*[]> familyNames(
new const void*[
count]);
349 CFSetGetValues(familyNameSet.get(), familyNames.get());
352 std::sort(familyNames.get(), familyNames.get() +
count, [](
const void*
a,
const void*
b){
353 return CFStringCompare((CFStringRef)a, (CFStringRef)b, 0) == kCFCompareLessThan;
357 return SkUniqueCFRef<CFArrayRef>(
358 CFArrayCreate(kCFAllocatorDefault, familyNames.get(),
count, &kCFTypeArrayCallBacks));
362SkUniqueCFRef<CFArrayRef> SkCTFontManagerCopyAvailableFontFamilyNames() {
363#ifdef SK_BUILD_FOR_IOS
364 using CTFontManagerCopyAvailableFontFamilyNamesProc = CFArrayRef (*)(void);
365 CTFontManagerCopyAvailableFontFamilyNamesProc ctFontManagerCopyAvailableFontFamilyNames;
366 *(
void**)(&ctFontManagerCopyAvailableFontFamilyNames) =
367 dlsym(RTLD_DEFAULT,
"CTFontManagerCopyAvailableFontFamilyNames");
368 if (ctFontManagerCopyAvailableFontFamilyNames) {
369 return SkUniqueCFRef<CFArrayRef>(ctFontManagerCopyAvailableFontFamilyNames());
371 SkUniqueCFRef<CTFontCollectionRef> collection(
372 CTFontCollectionCreateFromAvailableFonts(
nullptr));
373 return SkUniqueCFRef<CFArrayRef>(SkCopyAvailableFontFamilyNames(collection.get()));
375 return SkUniqueCFRef<CFArrayRef>(CTFontManagerCopyAvailableFontFamilyNames());
382 SkUniqueCFRef<CFArrayRef> fNames;
385 CFStringRef getFamilyNameAt(
int index)
const {
387 return (CFStringRef)CFArrayGetValueAtIndex(fNames.get(), index);
391 SkUniqueCFRef<CFMutableDictionaryRef> cfAttr(
392 CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
393 &kCFTypeDictionaryKeyCallBacks,
394 &kCFTypeDictionaryValueCallBacks));
396 CFDictionaryAddValue(cfAttr.get(), kCTFontFamilyNameAttribute, cfFamilyName);
398 SkUniqueCFRef<CTFontDescriptorRef>
desc(
399 CTFontDescriptorCreateWithAttributes(cfAttr.get()));
404 SkUniqueCFRef<CTFontCollectionRef> fFontCollection;
405 SkFontMgr_Mac(CTFontCollectionRef fontCollection)
406 : fNames(fontCollection ? SkCopyAvailableFontFamilyNames(fontCollection)
407 : SkCTFontManagerCopyAvailableFontFamilyNames())
409 , fFontCollection(fontCollection ? (CTFontCollectionRef)CFRetain(fontCollection)
410 : CTFontCollectionCreateFromAvailableFonts(nullptr))
419 if ((
unsigned)index < (
unsigned)
fCount) {
420 SkStringFromCFString(this->getFamilyNameAt(index), familyName);
427 if ((
unsigned)index >= (
unsigned)
fCount) {
430 return CreateSet(this->getFamilyNameAt(index));
437 SkUniqueCFRef<CFStringRef> cfName = make_CFString(familyName);
438 return CreateSet(cfName.get());
443 SkUniqueCFRef<CTFontDescriptorRef> reqDesc = create_descriptor(familyName, style);
445 return create_from_desc(reqDesc.get());
447 SkUniqueCFRef<CTFontDescriptorRef> resolvedDesc(
448 CTFontDescriptorCreateMatchingFontDescriptor(reqDesc.get(), name_required().
get()));
452 return create_from_desc(resolvedDesc.get());
457 const char* bcp47[],
int bcp47Count,
459 SkUniqueCFRef<CTFontDescriptorRef>
desc = create_descriptor(familyName, style);
460 SkUniqueCFRef<CTFontRef> familyFont(CTFontCreateWithFontDescriptor(
desc.get(), 0,
nullptr));
465 constexpr CFStringEncoding encoding = kCFStringEncodingUTF32LE;
467 constexpr CFStringEncoding encoding = kCFStringEncodingUTF32BE;
469 SkUniqueCFRef<CFStringRef> string(CFStringCreateWithBytes(
477 CFRange range = CFRangeMake(0, CFStringGetLength(
string.
get()));
478 SkUniqueCFRef<CTFontRef> fallbackFont(
479 CTFontCreateForString(familyFont.get(),
string.get(), range));
489 int ttcIndex)
const override {
510 familyName = map_css_names(familyName);
519 static SkOnce lookupDefault;
520 static const char FONT_DEFAULT_NAME[] =
"Lucida Sans";
522 gDefaultFace = create_from_name(FONT_DEFAULT_NAME,
SkFontStyle()).release();
529 return sk_make_sp<SkFontMgr_Mac>(fontCollection);
static const Pair gPairs[]
SK_API sk_sp< SkFontMgr > SkFontMgr_New_CoreText(CTFontCollectionRef)
static constexpr int32_t SK_MaxS32
static std::vector< SkPDFIndirectReference > sort(const THashSet< SkPDFIndirectReference > &src)
sk_sp< T > sk_ref_sp(T *obj)
static int32_t SkAbs32(int32_t value)
constexpr int SkToInt(S x)
static sk_sp< SkData > MakeFromFileName(const char path[])
virtual void onGetFamilyName(int index, SkString *familyName) const =0
sk_sp< SkTypeface > makeFromStream(std::unique_ptr< SkStreamAsset >, int ttcIndex=0) const
virtual sk_sp< SkTypeface > onMakeFromData(sk_sp< SkData >, int ttcIndex) const =0
virtual sk_sp< SkFontStyleSet > onCreateStyleSet(int index) const =0
virtual sk_sp< SkTypeface > onMatchFamilyStyleCharacter(const char familyName[], const SkFontStyle &, const char *bcp47[], int bcp47Count, SkUnichar character) const =0
virtual sk_sp< SkFontStyleSet > onMatchFamily(const char familyName[]) const =0
virtual sk_sp< SkTypeface > onMakeFromStreamIndex(std::unique_ptr< SkStreamAsset >, int ttcIndex) const =0
virtual sk_sp< SkTypeface > onMakeFromStreamArgs(std::unique_ptr< SkStreamAsset >, const SkFontArguments &) const =0
virtual sk_sp< SkTypeface > onMatchFamilyStyle(const char familyName[], const SkFontStyle &) const =0
virtual sk_sp< SkTypeface > onLegacyMakeTypeface(const char familyName[], SkFontStyle) const =0
virtual sk_sp< SkTypeface > onMakeFromFile(const char path[], int ttcIndex) const =0
virtual int onCountFamilies() const =0
virtual sk_sp< SkTypeface > createTypeface(int index)=0
virtual sk_sp< SkTypeface > matchStyle(const SkFontStyle &pattern)=0
virtual void getStyle(int index, SkFontStyle *, SkString *style)=0
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
std::unique_ptr< SkCodec > MakeFromStream(std::unique_ptr< SkStream > stream, SkCodec::SelectionPolicy selectionPolicy, SkCodec::Result *result)
SK_API sk_sp< SkDocument > Make(SkWStream *dst, const SkSerialProcs *=nullptr, std::function< void(const SkPicture *)> onEndPage=nullptr)
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
DEF_SWITCHES_START aot vmservice shared library name
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
const myers::Point & get(const myers::Segment &)
std::shared_ptr< const fml::Mapping > data