Skip to content

Commit c4534c7

Browse files
Alberto MarinesAlberto Marines
authored andcommitted
Code cleanup + Remove FontSize constants
1 parent 101f5de commit c4534c7

File tree

4 files changed

+67
-83
lines changed

4 files changed

+67
-83
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
44

55
## [Unreleased]
6+
### Changed
7+
- Code cleanup, minor enhancements.
8+
9+
### Removed
10+
- iOS: Removed the `FontSize` constants.
611

712
## [2.0.0-beta.6] - 2018-08-21
813

index.d.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,6 @@ declare module "react-native-text-size" {
116116
}
117117

118118
interface TextSizeStatic {
119-
readonly FontSize: TSFontSize;
120-
121119
measure(params: TSMeasureParams): Promise<TSMeasureResult>;
122120
flatHeights(params: TSHeightsParams): Promise<number[]>;
123121
specsForTextStyles(): Promise<{ [key: string]: TSFontForStyle }>;

index.js.flow

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,6 @@ export interface TSMeasureResult {
115115
}
116116

117117
declare interface TextSizeStatic {
118-
+FontSize: TSFontSize;
119-
120118
measure(params: TSMeasureParams): Promise<TSMeasureResult>;
121119
flatHeights(params: TSHeightsParams): Promise<number[]>;
122120
specsForTextStyles(): Promise<{ [string]: TSFontForStyle }>;

ios/RNTextSize.m

Lines changed: 62 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#import "RNTextSize.h"
2+
13
#if __has_include(<React/RCTConvert.h>)
24
#import <React/RCTConvert.h>
35
#import <React/RCTFont.h>
@@ -11,9 +13,6 @@
1113
#endif
1214

1315
#import <CoreText/CoreText.h>
14-
#import "RNTextSize.h"
15-
16-
#define _DEBUG 1
1716

1817
static NSString *const E_MISSING_TEXT = @"E_MISSING_TEXT";
1918
static NSString *const E_INVALID_FONT_SPEC = @"E_INVALID_FONT_SPEC";
@@ -59,19 +58,6 @@ - (dispatch_queue_t)methodQueue {
5958
return dispatch_get_main_queue();
6059
}
6160

62-
/*
63-
Is RN exposing its default font size? Try to get a UIFont here warnings
64-
"Required dispatch_sync to load constants ...This may lead to deadlocks"
65-
as in https://github.com/facebook/react-native/issues/16376
66-
*/
67-
- (NSDictionary *)constantsToExport {
68-
// iOS standard sizes
69-
NSDictionary *fontSize = @{
70-
@"default": @(14),
71-
};
72-
return @{@"FontSize": fontSize};
73-
}
74-
7561
/**
7662
* Gets the width, height, line count and last line width for the provided text
7763
* font specifications.
@@ -93,7 +79,7 @@ - (NSDictionary *)constantsToExport {
9379
if (!text.length) {
9480
resolve(@{
9581
@"width": @0,
96-
@"height": @0,
82+
@"height": @14,
9783
@"lastLineWidth": @0,
9884
@"lineCount": @0,
9985
});
@@ -102,8 +88,7 @@ - (NSDictionary *)constantsToExport {
10288

10389
// We cann't use RCTConvert since it does not handle font scaling and RN
10490
// does not scale the font if a custom delegate has been defined to create.
105-
//UIFont * _Nullable font = [RCTConvert UIFont:options];
106-
UIFont *const _Nullable font = [RNTextSize UIFontFromUserSpecs:options withBridge:_bridge];
91+
UIFont *const _Nullable font = [self scaledUIFontFromUserSpecs:options];
10792
if (!font) {
10893
reject(E_INVALID_FONT_SPEC, @"Invalid font specification.", nil);
10994
return;
@@ -137,31 +122,28 @@ - (NSDictionary *)constantsToExport {
137122
size.width -= letterSpacing;
138123
}
139124

140-
const CGFloat epsilon = 1 / RCTScreenScale(); // Yoga seems do this
141-
const CGFloat width = MIN(RCTCeilPixelValue(size.width + 0.001), maxSize.width);
125+
const CGFloat epsilon = 0.001;
126+
const CGFloat width = MIN(RCTCeilPixelValue(size.width + epsilon), maxSize.width);
142127
const CGFloat height = MIN(RCTCeilPixelValue(size.height + epsilon), maxSize.height);
143128
const CGFloat lineCount = CGRound(size.height / (font.lineHeight + font.leading));
144129

145-
CGFloat lastLineWidth = 0.0;
146130
if ([options[@"usePreciseWidth"] boolValue]) {
147131
const CGFloat lastIndex = layoutManager.numberOfGlyphs - 1;
148132
const CGSize lastSize = [layoutManager lineFragmentUsedRectForGlyphAtIndex:lastIndex
149133
effectiveRange:nil].size;
150-
lastLineWidth = lastSize.width;
134+
resolve(@{
135+
@"width": @(width),
136+
@"height": @(height),
137+
@"lastLineWidth": @(lastSize.width),
138+
@"lineCount": @(lineCount),
139+
});
140+
} else {
141+
resolve(@{
142+
@"width": @(width),
143+
@"height": @(height),
144+
@"lineCount": @(lineCount),
145+
});
151146
}
152-
153-
const NSDictionary *result = @{
154-
@"width": @(width),
155-
@"height": @(height),
156-
@"lineCount": @(lineCount),
157-
#if _DEBUG
158-
@"_fontLineHeight": @(font.lineHeight),
159-
@"_rawWidth": @(size.width),
160-
@"_rawHeight": @(size.height),
161-
@"_leading": @(font.leading),
162-
#endif
163-
};
164-
resolve(result);
165147
}
166148

167149
/**
@@ -173,13 +155,14 @@ - (NSDictionary *)constantsToExport {
173155
resolver:(RCTPromiseResolveBlock)resolve
174156
rejecter:(RCTPromiseRejectBlock)reject)
175157
{
176-
NSArray<NSString *> *const _Nullable texts = [RCTConvert NSStringArray:options[@"text"]];
158+
// Don't use NSStringArray, we are handling nulls
159+
NSArray *const _Nullable texts = [RCTConvert NSArray:options[@"text"]];
177160
if (isNull(texts)) {
178161
reject(E_MISSING_TEXT, @"Missing required text, must be an array.", nil);
179162
return;
180163
}
181164

182-
UIFont *const _Nullable font = [RNTextSize UIFontFromUserSpecs:options withBridge:_bridge];
165+
UIFont *const _Nullable font = [self scaledUIFontFromUserSpecs:options];
183166
if (!font) {
184167
reject(E_INVALID_FONT_SPEC, @"Invalid font specification.", nil);
185168
return;
@@ -203,7 +186,7 @@ - (NSDictionary *)constantsToExport {
203186
[layoutManager addTextContainer:textContainer];
204187

205188
NSMutableArray<NSNumber *> *result = [[NSMutableArray alloc] initWithCapacity:texts.count];
206-
const CGFloat epsilon = 1 / RCTScreenScale(); // Yoga seems do this
189+
const CGFloat epsilon = 0.001;
207190

208191
for (int ix = 0; ix < texts.count; ix++) {
209192
NSString *text = texts[ix];
@@ -212,7 +195,7 @@ - (NSDictionary *)constantsToExport {
212195
continue;
213196
}
214197
if (text == (id) kCFNull) {
215-
result[ix] = @0;
198+
result[ix] = @14;
216199
continue;
217200
}
218201

@@ -235,48 +218,41 @@ - (NSDictionary *)constantsToExport {
235218
* the user. Rejects if the parameters are falsy or the font could not be created.
236219
*/
237220
RCT_EXPORT_METHOD(fontFromSpecs:(NSDictionary *)specs
238-
resolver:(RCTPromiseResolveBlock)resolve
239-
rejecter:(RCTPromiseRejectBlock)reject)
221+
resolver:(RCTPromiseResolveBlock)resolve
222+
rejecter:(RCTPromiseRejectBlock)reject)
240223
{
241224
if (isNull(specs)) {
242225
reject(E_INVALID_FONT_SPEC, @"Missing font specification.", nil);
243226
} else {
244-
UIFont * _Nullable font = [RNTextSize UIFontFromUserSpecs:specs withBridge:_bridge];
227+
UIFont * _Nullable font = [self UIFontFromUserSpecs:specs withScale:1.0];
245228
if (font) {
246-
resolve([RNTextSize fontInfoFromUIFont:font]);
229+
resolve([self fontInfoFromUIFont:font]);
247230
} else {
248231
reject(E_INVALID_FONT_SPEC, @"Invalid font specification.", nil);
249232
}
250233
}
251234
}
252235

253236
/**
254-
* Resolves with an array of font info from the predefined iOS Text Styles.
237+
* Resolves with an array of font info for the predefined iOS Text Styles.
238+
* The returned size is "Large", the default following the iOS HIG.
255239
*
256-
* NOTE: The info includes unscaled font size and letterSpacing because this is
257-
* managed by the RN `allowFontScaling` property.
258-
* The returned size is "Large" (body of 17pt) following the iOS HIG.
240+
* NOTE: The info includes unscaled fontSize and letterSpacing. fontSize is managed by
241+
* by RN `allowFontScaling`, but letterSpacing is not.
259242
*
260243
* Altough the technique used to get create the result is complicated to maintain,
261244
* it simplifies things a lot.
262-
*
263-
* @see https://devsign.co/notes/tracking-and-character-spacing
264-
* @see https://developer.apple.com/design/human-interface-guidelines/ios/visual-design/typography/
265-
* @see https://useyourloaf.com/blog/auto-adjusting-fonts-for-dynamic-type/
266245
*/
267246
RCT_EXPORT_METHOD(specsForTextStyles:(RCTPromiseResolveBlock)resolve
268-
rejecter:(RCTPromiseRejectBlock)reject)
247+
rejecter:(RCTPromiseRejectBlock)reject)
269248
{
249+
// From https://developer.apple.com/design/human-interface-guidelines/ios/visual-design/typography/
270250
// These are the predefined kerning (1/1000em) to convert into letterSpacing (points)
271251
static const int T_OFFSET = 10; // tracking start with fontSize 10
272252
static const char trackings[] = {
273253
12, 6, 0, -6, -11, -16, -20, -24, -25, -26,
274254
19, 17, 16, 16, 15, 14, 14, 13, 13, 13,
275-
12, 12, 12, 11, 11, 11, 11, 11, 11, 11,
276-
10, 10, 10, 10, 9, 9, 9, 9, 8, 8,
277-
7, 7, 7, 6, 6, 6, 5, 5, 5, 5,
278-
4, 4, 4, 4, 4, 3, 3, 3, 3, 2,
279-
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
255+
12, 12, 12, 11, 11,
280256
};
281257
// These are the names of the properties to return
282258
static char *keys[] = {
@@ -311,7 +287,7 @@ - (NSDictionary *)constantsToExport {
311287
UIFontTextStyleBody, UIFontTextStyleCallout, UIFontTextStyleSubheadline,
312288
UIFontTextStyleFootnote, UIFontTextStyleCaption1, UIFontTextStyleCaption2,
313289
textStyleLargeTitle,
314-
];
290+
];
315291

316292
// ...and with all in place, we are ready to create our result
317293
NSMutableDictionary *result = [NSMutableDictionary dictionaryWithCapacity:[textStyles count]];
@@ -324,9 +300,9 @@ - (NSDictionary *)constantsToExport {
324300
const NSDictionary *traits = [descriptor objectForKey:UIFontDescriptorTraitsAttribute];
325301

326302
const NSString *fontFamily = font.familyName ?: font.fontName ?: (id) [NSNull null];
327-
const NSArray *fontVariant = [RNTextSize fontVariantFromDescriptor:descriptor];
328-
const NSString *fontStyle = [RNTextSize fontStyleFromTraits:traits];
329-
const NSString *fontWeight = [RNTextSize fontWeightFromTraits:traits];
303+
const NSArray *fontVariant = [self fontVariantFromDescriptor:descriptor];
304+
const NSString *fontStyle = [self fontStyleFromTraits:traits];
305+
const NSString *fontWeight = [self fontWeightFromTraits:traits];
330306

331307
// The standard font size for this style is also used to calculate letterSpacing
332308
const int fontSize = sizes[ix];
@@ -359,7 +335,7 @@ - (NSDictionary *)constantsToExport {
359335
* Resolve with an array of font family names available on the system.
360336
*/
361337
RCT_EXPORT_METHOD(fontFamilyNames:(RCTPromiseResolveBlock)resolve
362-
rejecter:(RCTPromiseRejectBlock)reject)
338+
rejecter:(RCTPromiseRejectBlock)reject)
363339
{
364340
NSArray<NSString *> *fonts = [UIFont.familyNames
365341
sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
@@ -371,8 +347,8 @@ - (NSDictionary *)constantsToExport {
371347
* Reject if the name is falsy or the names could not be obtain.
372348
*/
373349
RCT_EXPORT_METHOD(fontNamesForFamilyName:(NSString * _Nullable)fontFamily
374-
resolver:(RCTPromiseResolveBlock)resolve
375-
rejecter:(RCTPromiseRejectBlock)reject)
350+
resolver:(RCTPromiseResolveBlock)resolve
351+
rejecter:(RCTPromiseRejectBlock)reject)
376352
{
377353
if (isNull(fontFamily)) {
378354
reject(E_INVALID_FONTFAMILY, @"Missing fontFamily name.", nil);
@@ -393,20 +369,28 @@ - (NSDictionary *)constantsToExport {
393369
//
394370

395371
/**
396-
* Create a font based on the given specs.
372+
* Create a scaled font based on the given specs.
397373
*
398-
* TODO: implement the following behavior:
374+
* TODO:
399375
* This method is used instead of [RCTConvert UIFont] to support the omission
400376
* of scaling when a custom delegate has been defined for font's creation.
401377
*/
402-
+ (UIFont * _Nullable)UIFontFromUserSpecs:(const NSDictionary *)specs
403-
withBridge:(const RCTBridge *)bridge
378+
- (UIFont * _Nullable)scaledUIFontFromUserSpecs:(const NSDictionary *)specs
404379
{
405380
const id allowFontScalingSrc = specs[@"allowFontScaling"];
406-
const BOOL allowFontScaling = allowFontScalingSrc == nil ? YES : [allowFontScalingSrc boolValue];
381+
const BOOL allowFontScaling = allowFontScalingSrc ? [allowFontScalingSrc boolValue] : YES;
407382
const CGFloat scaleMultiplier =
408-
allowFontScaling && bridge ? bridge.accessibilityManager.multiplier : 1.0;
383+
allowFontScaling && _bridge ? _bridge.accessibilityManager.multiplier : 1.0;
384+
385+
return [self UIFontFromUserSpecs:specs withScale:scaleMultiplier];
386+
}
409387

388+
/**
389+
* Create a font based on the given specs.
390+
*/
391+
- (UIFont * _Nullable)UIFontFromUserSpecs:(const NSDictionary *)specs
392+
withScale:(CGFloat)scaleMultiplier
393+
{
410394
return [RCTFont updateFont:nil
411395
withFamily:[RCTConvert NSString:specs[@"fontFamily"]]
412396
size:[RCTConvert NSNumber:specs[@"fontSize"]]
@@ -421,20 +405,19 @@ + (UIFont * _Nullable)UIFontFromUserSpecs:(const NSDictionary *)specs
421405
* The keys in the returned dictionary are a superset of the RN Text styles
422406
* so the format is not fully compatible.
423407
*/
424-
+ (NSDictionary *)fontInfoFromUIFont:(const UIFont *)font
408+
- (NSDictionary *)fontInfoFromUIFont:(const UIFont *)font
425409
{
426410
const UIFontDescriptor *descriptor = font.fontDescriptor;
427411
const NSDictionary *traits = [descriptor objectForKey:UIFontDescriptorTraitsAttribute];
428412
const NSArray *fontVariant = [self fontVariantFromDescriptor:descriptor];
429-
const id null = [NSNull null];
430413

431414
return @{
432-
@"fontFamily": font.familyName ?: null,
433-
@"fontName": font.fontName ?: null,
415+
@"fontFamily": RCTNullIfNil(font.familyName),
416+
@"fontName": RCTNullIfNil(font.fontName),
434417
@"fontSize": @(font.pointSize),
435418
@"fontStyle": [self fontStyleFromTraits:traits],
436419
@"fontWeight": [self fontWeightFromTraits:traits],
437-
@"fontVariant": fontVariant ?: null,
420+
@"fontVariant": RCTNullIfNil(fontVariant),
438421
@"ascender": @(font.ascender),
439422
@"descender": @(font.descender),
440423
@"capHeight": @(font.capHeight), // height of capital characters
@@ -453,7 +436,7 @@ + (NSDictionary *)fontInfoFromUIFont:(const UIFont *)font
453436
* @param trais NSDictionary with the traits of the font.
454437
* @return NSString with the weight of the font.
455438
*/
456-
+ (NSString *)fontWeightFromTraits:(const NSDictionary *)traits
439+
- (NSString *)fontWeightFromTraits:(const NSDictionary *)traits
457440
{
458441
// Use a small tolerance to avoid rounding problems
459442
const CGFloat weight = CGFloatValueFrom(traits[UIFontWeightTrait]) + 0.01;
@@ -474,7 +457,7 @@ + (NSString *)fontWeightFromTraits:(const NSDictionary *)traits
474457
* @param trais NSDictionary with the traits of the font.
475458
* @return NSString with the style.
476459
*/
477-
+ (NSString *)fontStyleFromTraits:(const NSDictionary *)traits
460+
- (NSString *)fontStyleFromTraits:(const NSDictionary *)traits
478461
{
479462
const UIFontDescriptorSymbolicTraits symbolicTrais = [traits[UIFontSymbolicTrait] unsignedIntValue];
480463
const BOOL isItalic = (symbolicTrais & UIFontDescriptorTraitItalic) != 0;
@@ -491,7 +474,7 @@ + (NSString *)fontStyleFromTraits:(const NSDictionary *)traits
491474
* FIXME:
492475
* kNumberCase variants are not being recognized... RN bug?
493476
*/
494-
+ (NSArray<NSString *> * _Nullable)fontVariantFromDescriptor:(const UIFontDescriptor *)descriptor
477+
- (NSArray<NSString *> * _Nullable)fontVariantFromDescriptor:(const UIFontDescriptor *)descriptor
495478
{
496479
const NSArray *features = descriptor.fontAttributes[UIFontDescriptorFeatureSettingsAttribute];
497480
if (isNull(features)) {

0 commit comments

Comments
 (0)