<commit_before>//
//  VZFRasterizeNodeTool.m
//  VZFlexLayout
//
//  Created by heling on 2017/2/10.
//  Copyright © 2017年 Vizlab. All rights reserved.
//

#import "VZFRasterizeNodeTool.h"
#import "VZFAsyncConfig.h"
#import "VZFImageNode.h"
#import "VZFButtonNode.h"
#import "VZFTextNode.h"
#import "VZFImageNodeRenderer.h"
#import "VZFTextNodeRenderer.h"
#import "VZFTextNodeSpecs.h"
#import "VZFImageNodeSpecs.h"
#import "VZFNodeInternal.h"
#import "VZFlexNode.h"
#import "VZFStackNode.h"
#import "VZFBlankNodeRenderer.h"
#import "VZFButtonNodeSpecs.h"
#import "VZFImageNodeInternal.h"
#import "VZFTextNodeInternal.h"
#import <stack>



@interface VZFLayoutCheckResult : NSObject

@property (nonatomic, assign) BOOL hasOutOfBoundsChildren; //子孙中是否包含不能被光栅化的结点,并且这个结点与最近的clip为YES的祖先结点之间存在不能被光栅化的结点（不包括那个祖先结点，包括超出的子结点）
@property (nonatomic, assign) BOOL selfCanBeRasterized; //当前结点是否能被光栅化

@property (nonatomic, assign) BOOL childrenCannotBeRasterized; //父类如果有一个子节点不能被光栅化，那么从这个子节点往后都不能被光栅化


@end

@implementation VZFLayoutCheckResult


@end


@implementation VZFRasterizeNodeTool

+ (BOOL)canBeRasterized:(VZFNode *)node {
    //判断光栅化开关
    if (!VZFUseRasterize) {
        return NO;
    }
    
    NodeSpecs specs = node.specs;
    if (specs.gesture ||
        specs.display ||
        specs.highlightBackgroundColor ||
        //specs.borderWidth > 0 ||
        //(specs.clip && ([node isKindOfClass:[VZFStackNode class]] || [node  isMemberOfClass:[VZFNode class]]) ) ||
        specs.alpha < 1 ||
        specs.tag > 0 ||
        specs.applicator
        //        ||(specs.isAccessibilityElement != VZF_BOOL_UNDEFINED && specs.isAccessibilityElement) ||
        //        specs.accessibilityLabel
        ) {
        return NO;
    }
    
    if (!node.viewClass.hasView()) {
        return NO;
    }
    
    if ([node isKindOfClass:[VZFImageNode class]])
    {
        return YES;
    }
    else if ([node isKindOfClass:[VZFTextNode class]])
    {
        return YES;
    }
    else if([node  isKindOfClass:[VZFStackNode class]] || ([node  isMemberOfClass:[VZFNode class]] && ([@"VZFBlankNodeBackingView" isEqualToString:node.viewClass.identifier()] || [@"UIView" isEqualToString:node.viewClass.identifier()])) ){
        return YES;
    }
    //button需要独立处理事件 需要view不做光栅化处理
    
    return NO;
}



+(VZFRenderer *)getRenderer4RasterizedNode:(VZFNode *)node size:(CGSize)size {
    //判断光栅化开关
    if (![self canBeRasterized:node]) {
        return nil;
    }
    
    if ([node isKindOfClass:[VZFImageNode class]])
    {
        return [self getImageRenderer:((VZFImageNode* )node).imageSpecs node:(VZFImageNode *)node size:size];
    }
    else
        if ([node isKindOfClass:[VZFTextNode class]])
    {
        return [self getTextRenderer:((VZFTextNode* )node).textSpecs node:(VZFTextNode *)node size:size];
    }
    else if([node  isKindOfClass:[VZFStackNode class]] || ([node  isMemberOfClass:[VZFNode class]] && ([@"VZFBlankNodeBackingView" isEqualToString:node.viewClass.identifier()] || [@"UIView" isEqualToString:node.viewClass.identifier()]))){
        return [self getBlankRenderer:(VZFStackNode *)node];
    }
    //button需要独立处理事件 需要view不做光栅化处理
    
    return nil;
}

+(VZFTextNodeRenderer *)getTextRenderer:(const TextNodeSpecs& )textNodeSpecs node:(VZFTextNode* )node size:(CGSize)size{
    VZFTextNodeRenderer *renderer = node.renderer;
    UIEdgeInsets edgeInsets = node.flexNode.resultPadding;
    renderer.edgeInsets = edgeInsets;
    renderer.maxSize = CGSizeMake(size.width - edgeInsets.left - edgeInsets.right,size.height - edgeInsets.top - edgeInsets.bottom);
    [self setRenderer:renderer specs:node.specs];
    return renderer;
}

+(VZFBlankNodeRenderer *)getBlankRenderer:(VZFStackNode *)node{
    VZFBlankNodeRenderer *renderer = [VZFBlankNodeRenderer new];
    [self setRenderer:renderer specs:node.specs];
    return renderer;
}

+(VZFImageNodeRenderer *)getImageRenderer:(const ImageNodeSpecs& )imageSpec node:(VZFImageNode* )node size:(CGSize)size{

    NSDictionary *ctx = [imageSpec.context isKindOfClass:[NSDictionary class]] ? (NSDictionary *)imageSpec.context : @{} ;
    int animateCount = [ctx[@"animate-count"] intValue]?:0;
    
    if (animateCount > 1) {
        return nil;
    }
    //这个情况需要一个view
    if(imageSpec.imageUrl.length && !node.imageDownloader){
        return nil;
    }
    
    //图片已经下载成功
    UIImage *downLoadImage = nil;
    if(node.downloadImage && [node.downloadImageUrl isEqualToString:imageSpec.imageUrl]){
        downLoadImage = node.downloadImage;
    }
    
    NSArray *images = downLoadImage.images;
    NSTimeInterval duration = downLoadImage.duration;
    
    if (images.count && duration) {
        //gif 图片 需要用view来处理
        return nil;
    }
    
    
    VZFImageNodeRenderer *renderer = node.renderer;
    if (!renderer) {
        renderer = [VZFImageNodeRenderer new];
    }
    renderer.animateCount = animateCount;
    renderer.scale = VZ::Helper::screenScale();
    renderer.contentMode = imageSpec.contentMode;
    renderer.image = imageSpec.image;
    
    [self setRenderer:renderer specs:node.specs];

    if (imageSpec.imageUrl.length) {
        //已经下载成功 并缓存 直接赋值
        if (downLoadImage) {
            renderer.image = downLoadImage;
        }else{
            [node.imageDownloader vz_setImageWithURL:[NSURL URLWithString:imageSpec.imageUrl] size:size contentMode:renderer.contentMode  placeholderImage:imageSpec.image errorImage:imageSpec.errorImage context:imageSpec.context completionBlock:renderer];
            if([renderer.downloadImageUrl isEqualToString:imageSpec.imageUrl]){
                //同步回调 在node缓存image
                node.downloadImageUrl = renderer.downloadImageUrl;
                node.downloadImage = renderer.image;
                if (node.downloadImage.images.count) {
                    return nil;
                }
            }
        }
    }
    
    return renderer;
}



+(void)setRenderer:(VZFRenderer *)renderer specs:(const NodeSpecs&)vs{
    renderer.backgroundColor = vs.backgroundColor;
    renderer.borderWidth = vs.borderWidth;
    renderer.borderColor = vs.borderColor;
    renderer.customCorner = vzfRoundedCorner(vs.cornerRadius);
    renderer.clip = vs.clip;
  
    BOOL isTextRenderer = [renderer isKindOfClass:[VZFTextNodeRenderer class]];<commit_msg>支持自定义圆角<commit_after>//
//  VZFRasterizeNodeTool.m
//  VZFlexLayout
//
//  Created by heling on 2017/2/10.
//  Copyright © 2017年 Vizlab. All rights reserved.
//

#import "VZFRasterizeNodeTool.h"
#import "VZFAsyncConfig.h"
#import "VZFImageNode.h"
#import "VZFButtonNode.h"
#import "VZFTextNode.h"
#import "VZFImageNodeRenderer.h"
#import "VZFTextNodeRenderer.h"
#import "VZFTextNodeSpecs.h"
#import "VZFImageNodeSpecs.h"
#import "VZFNodeInternal.h"
#import "VZFlexNode.h"
#import "VZFStackNode.h"
#import "VZFBlankNodeRenderer.h"
#import "VZFButtonNodeSpecs.h"
#import "VZFImageNodeInternal.h"
#import "VZFTextNodeInternal.h"
#import <stack>



@interface VZFLayoutCheckResult : NSObject

@property (nonatomic, assign) BOOL hasOutOfBoundsChildren; //子孙中是否包含不能被光栅化的结点,并且这个结点与最近的clip为YES的祖先结点之间存在不能被光栅化的结点（不包括那个祖先结点，包括超出的子结点）
@property (nonatomic, assign) BOOL selfCanBeRasterized; //当前结点是否能被光栅化

@property (nonatomic, assign) BOOL childrenCannotBeRasterized; //父类如果有一个子节点不能被光栅化，那么从这个子节点往后都不能被光栅化


@end

@implementation VZFLayoutCheckResult


@end


@implementation VZFRasterizeNodeTool

+ (BOOL)canBeRasterized:(VZFNode *)node {
    //判断光栅化开关
    if (!VZFUseRasterize) {
        return NO;
    }
    
    NodeSpecs specs = node.specs;
    if (specs.gesture ||
        specs.display ||
        specs.highlightBackgroundColor ||
        //specs.borderWidth > 0 ||
        //(specs.clip && ([node isKindOfClass:[VZFStackNode class]] || [node  isMemberOfClass:[VZFNode class]]) ) ||
        specs.alpha < 1 ||
        specs.tag > 0 ||
        specs.applicator
        //        ||(specs.isAccessibilityElement != VZF_BOOL_UNDEFINED && specs.isAccessibilityElement) ||
        //        specs.accessibilityLabel
        ) {
        return NO;
    }
    
    if (!node.viewClass.hasView()) {
        return NO;
    }
    
    if ([node isKindOfClass:[VZFImageNode class]])
    {
        return YES;
    }
    else if ([node isKindOfClass:[VZFTextNode class]])
    {
        return YES;
    }
    else if([node  isKindOfClass:[VZFStackNode class]] || ([node  isMemberOfClass:[VZFNode class]] && ([@"VZFBlankNodeBackingView" isEqualToString:node.viewClass.identifier()] || [@"UIView" isEqualToString:node.viewClass.identifier()])) ){
        return YES;
    }
    //button需要独立处理事件 需要view不做光栅化处理
    
    return NO;
}



+(VZFRenderer *)getRenderer4RasterizedNode:(VZFNode *)node size:(CGSize)size {
    //判断光栅化开关
    if (![self canBeRasterized:node]) {
        return nil;
    }
    
    if ([node isKindOfClass:[VZFImageNode class]])
    {
        return [self getImageRenderer:((VZFImageNode* )node).imageSpecs node:(VZFImageNode *)node size:size];
    }
    else
        if ([node isKindOfClass:[VZFTextNode class]])
    {
        return [self getTextRenderer:((VZFTextNode* )node).textSpecs node:(VZFTextNode *)node size:size];
    }
    else if([node  isKindOfClass:[VZFStackNode class]] || ([node  isMemberOfClass:[VZFNode class]] && ([@"VZFBlankNodeBackingView" isEqualToString:node.viewClass.identifier()] || [@"UIView" isEqualToString:node.viewClass.identifier()]))){
        return [self getBlankRenderer:(VZFStackNode *)node];
    }
    //button需要独立处理事件 需要view不做光栅化处理
    
    return nil;
}

+(VZFTextNodeRenderer *)getTextRenderer:(const TextNodeSpecs& )textNodeSpecs node:(VZFTextNode* )node size:(CGSize)size{
    VZFTextNodeRenderer *renderer = node.renderer;
    UIEdgeInsets edgeInsets = node.flexNode.resultPadding;
    renderer.edgeInsets = edgeInsets;
    renderer.maxSize = CGSizeMake(size.width - edgeInsets.left - edgeInsets.right,size.height - edgeInsets.top - edgeInsets.bottom);
    [self setRenderer:renderer specs:node.specs];
    return renderer;
}

+(VZFBlankNodeRenderer *)getBlankRenderer:(VZFStackNode *)node{
    VZFBlankNodeRenderer *renderer = [VZFBlankNodeRenderer new];
    [self setRenderer:renderer specs:node.specs];
    return renderer;
}

+(VZFImageNodeRenderer *)getImageRenderer:(const ImageNodeSpecs& )imageSpec node:(VZFImageNode* )node size:(CGSize)size{

    NSDictionary *ctx = [imageSpec.context isKindOfClass:[NSDictionary class]] ? (NSDictionary *)imageSpec.context : @{} ;
    int animateCount = [ctx[@"animate-count"] intValue]?:0;
    
    if (animateCount > 1) {
        return nil;
    }
    //这个情况需要一个view
    if(imageSpec.imageUrl.length && !node.imageDownloader){
        return nil;
    }
    
    //图片已经下载成功
    UIImage *downLoadImage = nil;
    if(node.downloadImage && [node.downloadImageUrl isEqualToString:imageSpec.imageUrl]){
        downLoadImage = node.downloadImage;
    }
    
    NSArray *images = downLoadImage.images;
    NSTimeInterval duration = downLoadImage.duration;
    
    if (images.count && duration) {
        //gif 图片 需要用view来处理
        return nil;
    }
    
    
    VZFImageNodeRenderer *renderer = node.renderer;
    if (!renderer) {
        renderer = [VZFImageNodeRenderer new];
    }
    renderer.animateCount = animateCount;
    renderer.scale = VZ::Helper::screenScale();
    renderer.contentMode = imageSpec.contentMode;
    renderer.image = imageSpec.image;
    
    [self setRenderer:renderer specs:node.specs];

    if (imageSpec.imageUrl.length) {
        //已经下载成功 并缓存 直接赋值
        if (downLoadImage) {
            renderer.image = downLoadImage;
        }else{
            [node.imageDownloader vz_setImageWithURL:[NSURL URLWithString:imageSpec.imageUrl] size:size contentMode:renderer.contentMode  placeholderImage:imageSpec.image errorImage:imageSpec.errorImage context:imageSpec.context completionBlock:renderer];
            if([renderer.downloadImageUrl isEqualToString:imageSpec.imageUrl]){
                //同步回调 在node缓存image
                node.downloadImageUrl = renderer.downloadImageUrl;
                node.downloadImage = renderer.image;
                if (node.downloadImage.images.count) {
                    return nil;
                }
            }
        }
    }
    
    return renderer;
}



+(void)setRenderer:(VZFRenderer *)renderer specs:(const NodeSpecs&)vs{
    renderer.backgroundColor = vs.backgroundColor;
    renderer.borderWidth = vs.borderWidth;
    renderer.borderColor = vs.borderColor;
    
    CGFloat cornerRadiusTopLeft = vs.cornerRadiusTopLeft != VZ::FlexValue::Undefined() ? vs.cornerRadiusTopLeft.value : vs.cornerRadius;
    CGFloat cornerRadiusTopRight = vs.cornerRadiusTopRight != VZ::FlexValue::Undefined() ? vs.cornerRadiusTopRight.value : vs.cornerRadius;
    CGFloat cornerRadiusBottomLeft = vs.cornerRadiusBottomLeft != VZ::FlexValue::Undefined() ? vs.cornerRadiusBottomLeft.value : vs.cornerRadius;
    CGFloat cornerRadiusBottomRight = vs.cornerRadiusBottomRight != VZ::FlexValue::Undefined() ? vs.cornerRadiusBottomRight.value : vs.cornerRadius;
    renderer.customCorner = {cornerRadiusTopLeft, cornerRadiusTopRight, cornerRadiusBottomLeft, cornerRadiusBottomRight};
    renderer.clip = vs.clip;
  
    BOOL isTextRenderer = [renderer isKindOfClass:[VZFTextNodeRenderer class]];
{'fraction_non_alphanumeric': 0.11621580776787063, 'fraction_numerical': 0.0025691400936980503, 'mean_word_length': 3.4955842391304346, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 20, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6975970', 'n_tokens_mistral': 4779, 'n_tokens_neox': 4682, 'n_words': 738}