1// Copyright 2018-present 650 Industries. All rights reserved.
2
3#import <EXFont/EXFontScalersManager.h>
4
5#import <ExpoModulesCore/EXDefines.h>
6#import <EXFont/EXFont.h>
7
8#import <objc/runtime.h>
9
10static NSPointerArray *currentFontScalers;
11
12@implementation UIFont (EXFontLoader)
13
14- (UIFont *)EXFontWithSize:(CGFloat)fontSize
15{
16  for (id<EXFontScalerInterface> fontScaler in currentFontScalers) {
17    UIFont *scaledFont = [fontScaler scaledFont:self toSize:fontSize];
18    if (scaledFont) {
19      return scaledFont;
20    }
21  }
22
23  return [self EXFontWithSize:fontSize];
24}
25
26@end
27
28/**
29 * A singleton module responsible for overriding UIFont's
30 * fontWithSize: method which is used for scaling fonts.
31 * We need this one, central place to store the scalers
32 * as for now to get rid of timing problems when backgrounding/
33 * foregrounding apps.
34 */
35
36@implementation EXFontScalersManager
37
38EX_REGISTER_SINGLETON_MODULE(FontScalersManager);
39
40+ (void)initialize
41{
42  static dispatch_once_t initializeCurrentFontScalersOnce;
43  dispatch_once(&initializeCurrentFontScalersOnce, ^{
44    currentFontScalers = [NSPointerArray weakObjectsPointerArray];
45
46    Class uiFont = [UIFont class];
47    SEL uiUpdate = @selector(fontWithSize:);
48    SEL exUpdate = @selector(EXFontWithSize:);
49
50    method_exchangeImplementations(class_getInstanceMethod(uiFont, uiUpdate),
51                                   class_getInstanceMethod(uiFont, exUpdate));
52  });
53}
54
55- (void)registerFontScaler:(id<EXFontScalerInterface>)fontScaler
56{
57  [currentFontScalers compact];
58  [currentFontScalers addPointer:(__bridge void * _Nullable)(fontScaler)];
59}
60
61@end
62