blob: 9da0813bdd74617b34ba704111711f3ac9f09970 [file] [log] [blame]
// Copyright 2019-present the Material Components for iOS authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#import "MDCFontScaler.h"
#import <objc/runtime.h>
#import "UIFont+MaterialScalable.h"
#import "private/MDCTypographyUtilities.h"
MDCTextStyle const MDCTextStyleHeadline1 = @"MDC.TextStyle.Headline1";
MDCTextStyle const MDCTextStyleHeadline2 = @"MDC.TextStyle.Headline2";
MDCTextStyle const MDCTextStyleHeadline3 = @"MDC.TextStyle.Headline3";
MDCTextStyle const MDCTextStyleHeadline4 = @"MDC.TextStyle.Headline4";
MDCTextStyle const MDCTextStyleHeadline5 = @"MDC.TextStyle.Headline5";
MDCTextStyle const MDCTextStyleHeadline6 = @"MDC.TextStyle.Headline6";
MDCTextStyle const MDCTextStyleSubtitle1 = @"MDC.TextStyle.Subtitle1";
MDCTextStyle const MDCTextStyleSubtitle2 = @"MDC.TextStyle.Subtitle2";
MDCTextStyle const MDCTextStyleBody1 = @"MDC.TextStyle.Body1";
MDCTextStyle const MDCTextStyleBody2 = @"MDC.TextStyle.Body2";
MDCTextStyle const MDCTextStyleButton = @"MDC.TextStyle.Button";
MDCTextStyle const MDCTextStyleCaption = @"MDC.TextStyle.Caption";
MDCTextStyle const MDCTextStyleOverline = @"MDC.TextStyle.Overline";
@implementation MDCFontScaler {
NSDictionary<UIContentSizeCategory, NSNumber *> *_scalingCurve;
MDCTextStyle _textStyle;
}
+ (instancetype)scalerForMaterialTextStyle:(MDCTextStyle)textStyle {
return [[MDCFontScaler alloc] initForMaterialTextStyle:textStyle];
}
- (instancetype)initForMaterialTextStyle:(MDCTextStyle)textStyle {
self = [super init];
if (self) {
_textStyle = [textStyle copy];
// NOTE: All scaling curves MUST include a full set of values for ALL UIContentSizeCategory
// values. This values must not decrease as the category size increases. To put it another
// way, the value for UIContentSizeCategoryLarge must not be smaller than the value for
// UIContentSizeCategoryMedium.
if ([MDCTextStyleHeadline1 isEqualToString:textStyle]) {
NSDictionary<UIContentSizeCategory, NSNumber *> *scalingCurve = @{
UIContentSizeCategoryExtraSmall : @84,
UIContentSizeCategorySmall : @88,
UIContentSizeCategoryMedium : @92,
UIContentSizeCategoryLarge : @96,
UIContentSizeCategoryExtraLarge : @100,
UIContentSizeCategoryExtraExtraLarge : @104,
UIContentSizeCategoryExtraExtraExtraLarge : @108,
UIContentSizeCategoryAccessibilityMedium : @108,
UIContentSizeCategoryAccessibilityLarge : @108,
UIContentSizeCategoryAccessibilityExtraLarge : @108,
UIContentSizeCategoryAccessibilityExtraExtraLarge : @108,
UIContentSizeCategoryAccessibilityExtraExtraExtraLarge : @108
};
_scalingCurve = scalingCurve;
} else if ([MDCTextStyleHeadline2 isEqualToString:textStyle]) {
NSDictionary<UIContentSizeCategory, NSNumber *> *scalingCurve = @{
UIContentSizeCategoryExtraSmall : @54,
UIContentSizeCategorySmall : @56,
UIContentSizeCategoryMedium : @58,
UIContentSizeCategoryLarge : @60,
UIContentSizeCategoryExtraLarge : @62,
UIContentSizeCategoryExtraExtraLarge : @64,
UIContentSizeCategoryExtraExtraExtraLarge : @66,
UIContentSizeCategoryAccessibilityMedium : @66,
UIContentSizeCategoryAccessibilityLarge : @66,
UIContentSizeCategoryAccessibilityExtraLarge : @66,
UIContentSizeCategoryAccessibilityExtraExtraLarge : @66,
UIContentSizeCategoryAccessibilityExtraExtraExtraLarge : @66
};
_scalingCurve = scalingCurve;
} else if ([MDCTextStyleHeadline3 isEqualToString:textStyle]) {
NSDictionary<UIContentSizeCategory, NSNumber *> *scalingCurve = @{
UIContentSizeCategoryExtraSmall : @42,
UIContentSizeCategorySmall : @44,
UIContentSizeCategoryMedium : @46,
UIContentSizeCategoryLarge : @48,
UIContentSizeCategoryExtraLarge : @50,
UIContentSizeCategoryExtraExtraLarge : @52,
UIContentSizeCategoryExtraExtraExtraLarge : @54,
UIContentSizeCategoryAccessibilityMedium : @54,
UIContentSizeCategoryAccessibilityLarge : @54,
UIContentSizeCategoryAccessibilityExtraLarge : @54,
UIContentSizeCategoryAccessibilityExtraExtraLarge : @54,
UIContentSizeCategoryAccessibilityExtraExtraExtraLarge : @54
};
_scalingCurve = scalingCurve;
} else if ([MDCTextStyleHeadline4 isEqualToString:textStyle]) {
NSDictionary<UIContentSizeCategory, NSNumber *> *scalingCurve = @{
UIContentSizeCategoryExtraSmall : @28,
UIContentSizeCategorySmall : @30,
UIContentSizeCategoryMedium : @32,
UIContentSizeCategoryLarge : @34,
UIContentSizeCategoryExtraLarge : @36,
UIContentSizeCategoryExtraExtraLarge : @38,
UIContentSizeCategoryExtraExtraExtraLarge : @40,
UIContentSizeCategoryAccessibilityMedium : @42,
UIContentSizeCategoryAccessibilityLarge : @42,
UIContentSizeCategoryAccessibilityExtraLarge : @42,
UIContentSizeCategoryAccessibilityExtraExtraLarge : @42,
UIContentSizeCategoryAccessibilityExtraExtraExtraLarge : @42
};
_scalingCurve = scalingCurve;
} else if ([MDCTextStyleHeadline5 isEqualToString:textStyle]) {
NSDictionary<UIContentSizeCategory, NSNumber *> *scalingCurve = @{
UIContentSizeCategoryExtraSmall : @21,
UIContentSizeCategorySmall : @22,
UIContentSizeCategoryMedium : @23,
UIContentSizeCategoryLarge : @24,
UIContentSizeCategoryExtraLarge : @26,
UIContentSizeCategoryExtraExtraLarge : @28,
UIContentSizeCategoryExtraExtraExtraLarge : @30,
UIContentSizeCategoryAccessibilityMedium : @32,
UIContentSizeCategoryAccessibilityLarge : @32,
UIContentSizeCategoryAccessibilityExtraLarge : @32,
UIContentSizeCategoryAccessibilityExtraExtraLarge : @32,
UIContentSizeCategoryAccessibilityExtraExtraExtraLarge : @32
};
_scalingCurve = scalingCurve;
} else if ([MDCTextStyleHeadline6 isEqualToString:textStyle]) {
NSDictionary<UIContentSizeCategory, NSNumber *> *scalingCurve = @{
UIContentSizeCategoryExtraSmall : @17,
UIContentSizeCategorySmall : @18,
UIContentSizeCategoryMedium : @19,
UIContentSizeCategoryLarge : @20,
UIContentSizeCategoryExtraLarge : @22,
UIContentSizeCategoryExtraExtraLarge : @24,
UIContentSizeCategoryExtraExtraExtraLarge : @26,
UIContentSizeCategoryAccessibilityMedium : @28,
UIContentSizeCategoryAccessibilityLarge : @28,
UIContentSizeCategoryAccessibilityExtraLarge : @28,
UIContentSizeCategoryAccessibilityExtraExtraLarge : @28,
UIContentSizeCategoryAccessibilityExtraExtraExtraLarge : @28
};
_scalingCurve = scalingCurve;
} else if ([MDCTextStyleSubtitle1 isEqualToString:textStyle]) {
NSDictionary<UIContentSizeCategory, NSNumber *> *scalingCurve = @{
UIContentSizeCategoryExtraSmall : @13,
UIContentSizeCategorySmall : @14,
UIContentSizeCategoryMedium : @15,
UIContentSizeCategoryLarge : @16,
UIContentSizeCategoryExtraLarge : @18,
UIContentSizeCategoryExtraExtraLarge : @20,
UIContentSizeCategoryExtraExtraExtraLarge : @22,
UIContentSizeCategoryAccessibilityMedium : @25,
UIContentSizeCategoryAccessibilityLarge : @30,
UIContentSizeCategoryAccessibilityExtraLarge : @37,
UIContentSizeCategoryAccessibilityExtraExtraLarge : @44,
UIContentSizeCategoryAccessibilityExtraExtraExtraLarge : @52
};
_scalingCurve = scalingCurve;
} else if ([MDCTextStyleSubtitle2 isEqualToString:textStyle]) {
NSDictionary<UIContentSizeCategory, NSNumber *> *scalingCurve = @{
UIContentSizeCategoryExtraSmall : @11,
UIContentSizeCategorySmall : @12,
UIContentSizeCategoryMedium : @13,
UIContentSizeCategoryLarge : @14,
UIContentSizeCategoryExtraLarge : @16,
UIContentSizeCategoryExtraExtraLarge : @18,
UIContentSizeCategoryExtraExtraExtraLarge : @20,
UIContentSizeCategoryAccessibilityMedium : @22,
UIContentSizeCategoryAccessibilityLarge : @25,
UIContentSizeCategoryAccessibilityExtraLarge : @30,
UIContentSizeCategoryAccessibilityExtraExtraLarge : @36,
UIContentSizeCategoryAccessibilityExtraExtraExtraLarge : @42
};
_scalingCurve = scalingCurve;
} else if ([MDCTextStyleBody2 isEqualToString:textStyle]) {
NSDictionary<UIContentSizeCategory, NSNumber *> *scalingCurve = @{
UIContentSizeCategoryExtraSmall : @11,
UIContentSizeCategorySmall : @12,
UIContentSizeCategoryMedium : @13,
UIContentSizeCategoryLarge : @14,
UIContentSizeCategoryExtraLarge : @16,
UIContentSizeCategoryExtraExtraLarge : @18,
UIContentSizeCategoryExtraExtraExtraLarge : @20,
UIContentSizeCategoryAccessibilityMedium : @22,
UIContentSizeCategoryAccessibilityLarge : @25,
UIContentSizeCategoryAccessibilityExtraLarge : @30,
UIContentSizeCategoryAccessibilityExtraExtraLarge : @36,
UIContentSizeCategoryAccessibilityExtraExtraExtraLarge : @42
};
_scalingCurve = scalingCurve;
} else if ([MDCTextStyleButton isEqualToString:textStyle]) {
NSDictionary<UIContentSizeCategory, NSNumber *> *scalingCurve = @{
UIContentSizeCategoryExtraSmall : @11,
UIContentSizeCategorySmall : @12,
UIContentSizeCategoryMedium : @13,
UIContentSizeCategoryLarge : @14,
UIContentSizeCategoryExtraLarge : @16,
UIContentSizeCategoryExtraExtraLarge : @18,
UIContentSizeCategoryExtraExtraExtraLarge : @20,
UIContentSizeCategoryAccessibilityMedium : @22,
UIContentSizeCategoryAccessibilityLarge : @24,
UIContentSizeCategoryAccessibilityExtraLarge : @26,
UIContentSizeCategoryAccessibilityExtraExtraLarge : @28,
UIContentSizeCategoryAccessibilityExtraExtraExtraLarge : @30
};
_scalingCurve = scalingCurve;
} else if ([MDCTextStyleCaption isEqualToString:textStyle]) {
NSDictionary<UIContentSizeCategory, NSNumber *> *scalingCurve = @{
UIContentSizeCategoryExtraSmall : @11,
UIContentSizeCategorySmall : @11,
UIContentSizeCategoryMedium : @11,
UIContentSizeCategoryLarge : @12,
UIContentSizeCategoryExtraLarge : @14,
UIContentSizeCategoryExtraExtraLarge : @16,
UIContentSizeCategoryExtraExtraExtraLarge : @18,
UIContentSizeCategoryAccessibilityMedium : @20,
UIContentSizeCategoryAccessibilityLarge : @22,
UIContentSizeCategoryAccessibilityExtraLarge : @24,
UIContentSizeCategoryAccessibilityExtraExtraLarge : @26,
UIContentSizeCategoryAccessibilityExtraExtraExtraLarge : @28
};
_scalingCurve = scalingCurve;
} else if ([MDCTextStyleOverline isEqualToString:textStyle]) {
NSDictionary<UIContentSizeCategory, NSNumber *> *scalingCurve = @{
UIContentSizeCategoryExtraSmall : @8,
UIContentSizeCategorySmall : @8,
UIContentSizeCategoryMedium : @9,
UIContentSizeCategoryLarge : @10,
UIContentSizeCategoryExtraLarge : @12,
UIContentSizeCategoryExtraExtraLarge : @14,
UIContentSizeCategoryExtraExtraExtraLarge : @16,
UIContentSizeCategoryAccessibilityMedium : @18,
UIContentSizeCategoryAccessibilityLarge : @20,
UIContentSizeCategoryAccessibilityExtraLarge : @22,
UIContentSizeCategoryAccessibilityExtraExtraLarge : @24,
UIContentSizeCategoryAccessibilityExtraExtraExtraLarge : @26
};
_scalingCurve = scalingCurve;
} else {
// If nothing matches, return the metrics for MDCTextStyleBody1
_textStyle = [MDCTextStyleBody1 copy];
NSDictionary<UIContentSizeCategory, NSNumber *> *scalingCurve = @{
UIContentSizeCategoryExtraSmall : @13,
UIContentSizeCategorySmall : @14,
UIContentSizeCategoryMedium : @15,
UIContentSizeCategoryLarge : @16,
UIContentSizeCategoryExtraLarge : @18,
UIContentSizeCategoryExtraExtraLarge : @20,
UIContentSizeCategoryExtraExtraExtraLarge : @22,
UIContentSizeCategoryAccessibilityMedium : @26,
UIContentSizeCategoryAccessibilityLarge : @30,
UIContentSizeCategoryAccessibilityExtraLarge : @34,
UIContentSizeCategoryAccessibilityExtraExtraLarge : @38,
UIContentSizeCategoryAccessibilityExtraExtraExtraLarge : @42
};
_scalingCurve = scalingCurve;
}
}
return self;
}
- (UIFont *)scaledFontWithFont:(UIFont *)font {
// If it is available, query the preferredContentSizeCategory.
UIContentSizeCategory sizeCategory = GetCurrentSizeCategory();
// We create a new font to ensure we have a complete set of font traits.
// They we apply our new scaling curve before returning a scaled font.
UIFont *templateFont = [UIFont fontWithDescriptor:font.fontDescriptor size:0.0];
templateFont.mdc_scalingCurve = _scalingCurve;
UIFont *scaledFont = [templateFont mdc_scaledFontForSizeCategory:sizeCategory];
return scaledFont;
}
- (NSString *)description {
NSString *superDescription = [super description];
NSString *styleDescription = @"No Attached Style";
if (_textStyle) {
styleDescription = _textStyle;
}
return [NSString stringWithFormat:@"%@ %@", superDescription, styleDescription];
}
@end