RenderCore/Geometry/RCDimension.mm (84 lines of code) (raw):

/* * 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 "RCDimension.h" #import <tgmath.h> #import <RenderCore/RCAssert.h> #import <RenderCore/RCEqualityHelpers.h> #import <RenderCore/CKMacros.h> #import <RenderCore/CKInternalHelpers.h> bool RCRelativeDimension::operator==(const RCRelativeDimension &other) const noexcept { // Implementation assumes that "auto" assigns '0' to value. if (_type != other._type) { return false; } switch (_type) { case Type::AUTO: return true; case Type::POINTS: case Type::PERCENT: return _value == other._value; } } NSString *RCRelativeDimension::description() const noexcept { switch (_type) { case Type::AUTO: return @"Auto"; case Type::POINTS: return [NSString stringWithFormat:@"%.0fpt", _value]; case Type::PERCENT: return [NSString stringWithFormat:@"%.0f%%", _value * 100.0]; } } CGFloat RCRelativeDimension::resolve(CGFloat autoSize, CGFloat parent) const noexcept { switch (_type) { case Type::AUTO: return autoSize; case Type::POINTS: return _value; case Type::PERCENT: return isnan(parent) || isinf(parent) ? autoSize : round(_value * parent); } } RCRelativeDimension::Type RCRelativeDimension::type(void) const noexcept { return _type; } CGFloat RCRelativeDimension::value(void) const noexcept { return _value; } size_t std::hash<RCRelativeDimension>::operator ()(const RCRelativeDimension &size) noexcept { NSUInteger subhashes[] = { (size_t)(size._type), std::hash<CGFloat>()(size._value), }; return RCIntegerArrayHash(subhashes, std::end(subhashes) - std::begin(subhashes)); }; RCRelativeSize::RCRelativeSize(const RCRelativeDimension &_width, const RCRelativeDimension &_height) noexcept : width(_width), height(_height) {} RCRelativeSize::RCRelativeSize(const CGSize &size) noexcept : RCRelativeSize(size.width, size.height) {} CGSize RCRelativeSize::resolveSize(const CGSize &parentSize, const CGSize &autoSize) const noexcept { return { width.resolve(autoSize.width, parentSize.width), height.resolve(autoSize.height, parentSize.height), }; } bool RCRelativeSize::operator==(const RCRelativeSize &other) const noexcept { return width == other.width && height == other.height; } NSString *RCRelativeSize::description() const noexcept { return [NSString stringWithFormat:@"{%@, %@}", width.description(), height.description()]; } RCRelativeSizeRange::RCRelativeSizeRange(const RCRelativeSize &_min, const RCRelativeSize &_max) : min(_min), max(_max) {} RCRelativeSizeRange::RCRelativeSizeRange(const RCRelativeSize &exact) noexcept : RCRelativeSizeRange(exact, exact) {} RCRelativeSizeRange::RCRelativeSizeRange(const CGSize &exact) noexcept : RCRelativeSizeRange(RCRelativeSize(exact)) {} RCRelativeSizeRange::RCRelativeSizeRange(const RCRelativeDimension &exactWidth, const RCRelativeDimension &exactHeight) noexcept : RCRelativeSizeRange(RCRelativeSize(exactWidth, exactHeight)) {} CKSizeRange RCRelativeSizeRange::resolveSizeRange(const CGSize &parentSize, const CKSizeRange &autoCKSizeRange) const noexcept { return { min.resolveSize(parentSize, autoCKSizeRange.min), max.resolveSize(parentSize, autoCKSizeRange.max) }; }