Scott Goodson 589efefcf2 [ASDimension] Disable assertions for Percent values being between 0.0 and 1.0.
This triggers on existing code that needs to be updated, but also there is some investigation
needed as to whether it is a valid use case to have a >1.0 value in order to position greater-than-bounds elements.
2016-07-30 23:44:46 -07:00

140 lines
5.0 KiB
Plaintext

//
// ASDimension.mm
// AsyncDisplayKit
//
// 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 "ASDimension.h"
#import "ASAssert.h"
ASRelativeDimension const ASRelativeDimensionUnconstrained = {};
#pragma mark - ASRelativeDimension
ASRelativeDimension ASRelativeDimensionMake(ASRelativeDimensionType type, CGFloat value)
{
if (type == ASRelativeDimensionTypePoints) {
ASDisplayNodeCAssertPositiveReal(@"Points", value);
} else if (type == ASRelativeDimensionTypePercent) {
// TODO: Enable this assertion for 2.0. Check that there is no use case for using a larger value, e.g. to layout for a clipsToBounds = NO element.
// ASDisplayNodeCAssert( 0 <= value && value <= 1.0, @"ASRelativeDimension percent value (%f) must be between 0 and 1.", value);
}
ASRelativeDimension dimension; dimension.type = type; dimension.value = value; return dimension;
}
ASRelativeDimension ASRelativeDimensionMakeWithPoints(CGFloat points)
{
ASDisplayNodeCAssertPositiveReal(@"Points", points);
return ASRelativeDimensionMake(ASRelativeDimensionTypePoints, points);
}
ASRelativeDimension ASRelativeDimensionMakeWithPercent(CGFloat percent)
{
// ASDisplayNodeCAssert( 0 <= percent && percent <= 1.0, @"ASRelativeDimension percent value (%f) must be between 0 and 1.", percent);
return ASRelativeDimensionMake(ASRelativeDimensionTypePercent, percent);
}
ASRelativeDimension ASRelativeDimensionCopy(ASRelativeDimension aDimension)
{
return ASRelativeDimensionMake(aDimension.type, aDimension.value);
}
BOOL ASRelativeDimensionEqualToRelativeDimension(ASRelativeDimension lhs, ASRelativeDimension rhs)
{
return lhs.type == rhs.type && lhs.value == rhs.value;
}
NSString *NSStringFromASRelativeDimension(ASRelativeDimension dimension)
{
switch (dimension.type) {
case ASRelativeDimensionTypePoints:
return [NSString stringWithFormat:@"%.0fpt", dimension.value];
case ASRelativeDimensionTypePercent:
return [NSString stringWithFormat:@"%.0f%%", dimension.value * 100.0];
}
}
CGFloat ASRelativeDimensionResolve(ASRelativeDimension dimension, CGFloat parent)
{
switch (dimension.type) {
case ASRelativeDimensionTypePoints:
return dimension.value;
case ASRelativeDimensionTypePercent:
return dimension.value * parent;
}
}
#pragma mark - ASSizeRange
ASSizeRange ASSizeRangeMake(CGSize min, CGSize max)
{
ASDisplayNodeCAssertPositiveReal(@"Range min width", min.width);
ASDisplayNodeCAssertPositiveReal(@"Range min height", min.height);
ASDisplayNodeCAssertInfOrPositiveReal(@"Range max width", max.width);
ASDisplayNodeCAssertInfOrPositiveReal(@"Range max height", max.height);
ASDisplayNodeCAssert(min.width <= max.width,
@"Range min width (%f) must not be larger than max width (%f).", min.width, max.width);
ASDisplayNodeCAssert(min.height <= max.height,
@"Range min height (%f) must not be larger than max height (%f).", min.height, max.height);
ASSizeRange sizeRange; sizeRange.min = min; sizeRange.max = max; return sizeRange;
}
ASSizeRange ASSizeRangeMakeExactSize(CGSize size)
{
return ASSizeRangeMake(size, size);
}
CGSize ASSizeRangeClamp(ASSizeRange sizeRange, CGSize size)
{
return CGSizeMake(MAX(sizeRange.min.width, MIN(sizeRange.max.width, size.width)),
MAX(sizeRange.min.height, MIN(sizeRange.max.height, size.height)));
}
struct _Range {
CGFloat min;
CGFloat max;
/**
Intersects another dimension range. If the other range does not overlap, this size range "wins" by returning a
single point within its own range that is closest to the non-overlapping range.
*/
_Range intersect(const _Range &other) const
{
CGFloat newMin = MAX(min, other.min);
CGFloat newMax = MIN(max, other.max);
if (newMin <= newMax) {
return {newMin, newMax};
} else {
// No intersection. If we're before the other range, return our max; otherwise our min.
if (min < other.min) {
return {max, max};
} else {
return {min, min};
}
}
}
};
ASSizeRange ASSizeRangeIntersect(ASSizeRange sizeRange, ASSizeRange otherSizeRange)
{
auto w = _Range({sizeRange.min.width, sizeRange.max.width}).intersect({otherSizeRange.min.width, otherSizeRange.max.width});
auto h = _Range({sizeRange.min.height, sizeRange.max.height}).intersect({otherSizeRange.min.height, otherSizeRange.max.height});
return {{w.min, h.min}, {w.max, h.max}};
}
BOOL ASSizeRangeEqualToSizeRange(ASSizeRange lhs, ASSizeRange rhs)
{
return CGSizeEqualToSize(lhs.min, rhs.min) && CGSizeEqualToSize(lhs.max, rhs.max);
}
NSString * NSStringFromASSizeRange(ASSizeRange sizeRange)
{
return [NSString stringWithFormat:@"<ASSizeRange: min=%@, max=%@>",
NSStringFromCGSize(sizeRange.min),
NSStringFromCGSize(sizeRange.max)];
}