summaryrefslogtreecommitdiff
path: root/platform/darwin/src/MGLRendererConfiguration.mm
blob: 54bdcaa691a4e354f5aa9e1ccc572d3ae3189dad (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#import "MGLRendererConfiguration.h"
#import "MGLOfflineStorage_Private.h"
#import "MGLFoundation_Private.h"

#if TARGET_OS_IPHONE
#import <UIKit/UIKit.h>
#else
#import <AppKit/AppKit.h>
#endif

static NSString * const MGLCollisionBehaviorPre4_0Key = @"MGLCollisionBehaviorPre4_0";
static NSString * const MGLIdeographicFontFamilyNameKey = @"MGLIdeographicFontFamilyName";

@interface MGLRendererConfiguration ()
@property (nonatomic, readwrite) BOOL perSourceCollisions;
@end


@implementation MGLRendererConfiguration

+ (instancetype)currentConfiguration {
    return [[self alloc] init];
}

- (instancetype)init {
    return [self initWithPropertyDictionary:[[NSBundle mainBundle] infoDictionary]];
}

- (instancetype)initWithPropertyDictionary:(nonnull NSDictionary *)properties {
    self = [super init];
    
    if (self) {
        // Set the collision behaviour. A value set in `NSUserDefaults.standardUserDefaults`
        // should override anything in the application's info.plist
        NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

        if ([defaults objectForKey:MGLCollisionBehaviorPre4_0Key]) {
            _perSourceCollisions = [defaults boolForKey:MGLCollisionBehaviorPre4_0Key];
        }
        else {
            id collisionBehaviourValue = properties[MGLCollisionBehaviorPre4_0Key];
            
            NSNumber *collisionBehaviourNumber = MGL_OBJC_DYNAMIC_CAST(collisionBehaviourValue, NSNumber);
            
            if (collisionBehaviourNumber) {
                _perSourceCollisions = collisionBehaviourNumber.boolValue;
            } else {
                // Also support NSString to correspond with the behavior of `-[NSUserDefaults boolForKey:]`
                NSString *collisionBehaviourString = MGL_OBJC_DYNAMIC_CAST(collisionBehaviourValue, NSString);

                if (collisionBehaviourString) {
                    _perSourceCollisions = collisionBehaviourString.boolValue;
                }
            }
        }
    }
    
    return self;
}

- (const float)scaleFactor {
#if TARGET_OS_IPHONE
    return [UIScreen instancesRespondToSelector:@selector(nativeScale)] ? [[UIScreen mainScreen] nativeScale] : [[UIScreen mainScreen] scale];
#else
    return [NSScreen mainScreen].backingScaleFactor;
#endif
}

- (mbgl::optional<std::string>)cacheDir {
    return mbgl::optional<std::string>();
}

- (mbgl::optional<std::string>)localFontFamilyName {
    return [self _localFontFamilyNameWithPropertyDictionary:[[NSBundle mainBundle] infoDictionary]];
}

- (mbgl::optional<std::string>)_localFontFamilyNameWithPropertyDictionary:(nonnull NSDictionary *)properties {
    
    std::string systemFontFamilyName;
#if TARGET_OS_IPHONE
    systemFontFamilyName = std::string([[UIFont systemFontOfSize:0 weight:UIFontWeightRegular].familyName UTF8String]);
#else
    systemFontFamilyName = std::string([[NSFont systemFontOfSize:0 weight:NSFontWeightRegular].familyName UTF8String]);
#endif
    
    id fontFamilyName = properties[MGLIdeographicFontFamilyNameKey];
    
    if([fontFamilyName isKindOfClass:[NSNumber class]] && ![fontFamilyName boolValue])
    {
        return mbgl::optional<std::string>();
    }
    else if([fontFamilyName isKindOfClass:[NSString class]])
    {
        BOOL isValidFont = NO;
#if TARGET_OS_IPHONE
        if([[UIFont familyNames] containsObject:fontFamilyName]){
            isValidFont = YES;
        }
#else
        if([[[NSFontManager sharedFontManager] availableFontFamilies] containsObject:fontFamilyName]){
            isValidFont = YES;
        }
#endif
        return (fontFamilyName && isValidFont) ? std::string([fontFamilyName UTF8String]) : systemFontFamilyName;
    }
    // Ability to specify an array of fonts for fallbacks for `localIdeographicFontFamily`
    else if ([fontFamilyName isKindOfClass:[NSArray class]]){
        for(NSString *name in fontFamilyName){
#if TARGET_OS_IPHONE
            if([[UIFont familyNames] containsObject:name]){
                return std::string([name UTF8String]);
            }
#else
            if([[[NSFontManager sharedFontManager] availableFontFamilies] containsObject:name]){
                return std::string([name UTF8String]);
            }
#endif
        }
    }
    return systemFontFamilyName;
}

@end