-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathStrongRenderer.m
More file actions
98 lines (81 loc) · 4.21 KB
/
StrongRenderer.m
File metadata and controls
98 lines (81 loc) · 4.21 KB
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
#import "StrongRenderer.h"
#import "FontUtils.h"
#import "MarkdownASTNode.h"
#import "RenderContext.h"
#import "RendererFactory.h"
#import "StyleConfig.h"
#import <React/RCTFont.h>
@implementation StrongRenderer {
__weak RendererFactory *_rendererFactory;
StyleConfig *_config;
}
- (instancetype)initWithRendererFactory:(id)rendererFactory config:(id)config
{
if (self = [super init]) {
_rendererFactory = rendererFactory;
_config = (StyleConfig *)config;
}
return self;
}
#pragma mark - Rendering
- (void)renderNode:(MarkdownASTNode *)node into:(NSMutableAttributedString *)output context:(RenderContext *)context
{
NSUInteger start = output.length;
[_rendererFactory renderChildrenOfNode:node into:output context:context];
NSRange range = NSMakeRange(start, output.length - start);
if (range.length == 0)
return;
BlockStyle *blockStyle = [context getBlockStyle];
RCTUIColor *configStrongColor = [_config strongColor];
RCTUIColor *calculatedColor =
configStrongColor ? [RenderContext calculateStrongColor:configStrongColor blockColor:blockStyle.color] : nil;
NSString *strongFontFamily = [_config strongFontFamily];
NSString *strongFontWeight = [_config strongFontWeight];
BOOL useNormalWeight = [strongFontWeight isEqualToString:@"normal"];
[output enumerateAttributesInRange:range
options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired
usingBlock:^(NSDictionary<NSAttributedStringKey, id> *attrs, NSRange subrange, BOOL *stop) {
// 1. Resolve Font
UIFont *currentFont =
attrs[NSFontAttributeName] ?: cachedFontFromBlockStyle(blockStyle, context);
UIFont *resolvedFont = currentFont;
if (strongFontFamily.length > 0) {
NSString *weight = useNormalWeight ? nil : @"bold";
resolvedFont = [RCTFont updateFont:currentFont
withFamily:strongFontFamily
size:nil
weight:weight
style:nil
variant:nil
scaleMultiplier:1.0];
} else if (!([currentFont.fontDescriptor symbolicTraits] & UIFontDescriptorTraitBold)) {
resolvedFont = [self ensureFontIsBold:currentFont];
}
if (resolvedFont && ![resolvedFont isEqual:currentFont]) {
[output addAttribute:NSFontAttributeName value:resolvedFont range:subrange];
}
// 2. Resolve Color
// Only apply if we have a color and the current segment doesn't explicitly forbid overrides
if (calculatedColor && ![RenderContext shouldPreserveColors:attrs]) {
// Optimization: Check if this color is already set to avoid redundant attribute changes
if (![attrs[NSForegroundColorAttributeName] isEqual:calculatedColor]) {
[output addAttribute:NSForegroundColorAttributeName
value:calculatedColor
range:subrange];
}
}
}];
}
#pragma mark - Helper Methods
- (UIFont *)ensureFontIsBold:(UIFont *)font
{
if (!font)
return nil;
UIFontDescriptor *descriptor = font.fontDescriptor;
UIFontDescriptorSymbolicTraits traits = descriptor.symbolicTraits;
// Create new descriptor combining current traits with Bold
UIFontDescriptor *boldDescriptor = [descriptor fontDescriptorWithSymbolicTraits:(traits | UIFontDescriptorTraitBold)];
// Fallback to original font if bold version is unavailable
return boldDescriptor ? [UIFont fontWithDescriptor:boldDescriptor size:0] : font;
}
@end