/* * Copyright (c) 2014-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * */ #import "ASBaselineStackLayoutSpec.h" #import "ASStackLayoutable.h" #import #import #import "ASBaseDefines.h" #import "ASInternalHelpers.h" #import "ASLayoutSpecUtilities.h" #import "ASStackLayoutSpecUtilities.h" #import "ASStackPositionedLayout.h" #import "ASStackUnpositionedLayout.h" #import "ASBaselineStackPositionedLayout.h" #import "ASThread.h" @implementation ASBaselineStackLayoutSpec { ASBaselineStackLayoutSpecStyle _textStyle; std::vector> _stackChildren; ASDN::RecursiveMutex _propertyLock; } @synthesize ascender = _ascender; @synthesize descender = _descender; + (instancetype)newWithStyle:(ASBaselineStackLayoutSpecStyle)style children:(NSArray *)children { ASDisplayNodeAssert((style.stackLayoutStyle.direction == ASStackLayoutDirectionHorizontal && style.baselineAlignment != ASBaselineStackLayoutBaselineAlignmentNone) || style.stackLayoutStyle.direction == ASStackLayoutDirectionVertical, @"baselineAlignment is set to none. If you don't need baseline alignment please use ASStackLayoutSpec"); ASBaselineStackLayoutSpec *spec = [super new]; if (spec) { spec->_textStyle = style; spec->_stackChildren = std::vector>(); for (id child in children) { ASDisplayNodeAssert([child conformsToProtocol:@protocol(ASBaselineStackLayoutable)], @"child must conform to ASStackLayoutable"); spec->_stackChildren.push_back(child); } } return spec; } + (instancetype)new { ASDISPLAYNODE_NOT_DESIGNATED_INITIALIZER(); } - (ASLayout *)measureWithSizeRange:(ASSizeRange)constrainedSize { ASStackLayoutSpecStyle stackStyle = _textStyle.stackLayoutStyle; const auto unpositionedLayout = ASStackUnpositionedLayout::compute(_stackChildren, stackStyle, constrainedSize); const auto positionedLayout = ASStackPositionedLayout::compute(unpositionedLayout, stackStyle, constrainedSize); const auto baselinePositionedLayout = ASBaselineStackPositionedLayout::compute(positionedLayout, _textStyle, constrainedSize); const CGSize finalSize = directionSize(stackStyle.direction, unpositionedLayout.stackDimensionSum, baselinePositionedLayout.crossSize); NSArray *sublayouts = [NSArray arrayWithObjects:&baselinePositionedLayout.sublayouts[0] count:baselinePositionedLayout.sublayouts.size()]; ASDN::MutexLocker l(_propertyLock); _ascender = baselinePositionedLayout.ascender; _descender = baselinePositionedLayout.descender; return [ASLayout newWithLayoutableObject:self size:ASSizeRangeClamp(constrainedSize, finalSize) sublayouts:sublayouts]; } @end