Utils.h 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. /**
  2. * Copyright (c) 2014-present, Facebook, Inc.
  3. *
  4. * This source code is licensed under the MIT license found in the
  5. * LICENSE file in the root directory of this source tree.
  6. */
  7. #pragma once
  8. #include "YGNode.h"
  9. #include "Yoga-internal.h"
  10. // This struct is an helper model to hold the data for step 4 of flexbox
  11. // algo, which is collecting the flex items in a line.
  12. //
  13. // - itemsOnLine: Number of items which can fit in a line considering the
  14. // available Inner dimension, the flex items computed flexbasis and their
  15. // margin. It may be different than the difference between start and end
  16. // indicates because we skip over absolute-positioned items.
  17. //
  18. // - sizeConsumedOnCurrentLine: It is accumulation of the dimensions and margin
  19. // of all the children on the current line. This will be used in order to either
  20. // set the dimensions of the node if none already exist or to compute the
  21. // remaining space left for the flexible children.
  22. //
  23. // - totalFlexGrowFactors: total flex grow factors of flex items which are to be
  24. // layed in the current line
  25. //
  26. // - totalFlexShrinkFactors: total flex shrink factors of flex items which are
  27. // to be layed in the current line
  28. //
  29. // - endOfLineIndex: Its the end index of the last flex item which was examined
  30. // and it may or may not be part of the current line(as it may be absolutely
  31. // positioned or inculding it may have caused to overshoot availableInnerDim)
  32. //
  33. // - relativeChildren: Maintain a vector of the child nodes that can shrink
  34. // and/or grow.
  35. struct YGCollectFlexItemsRowValues {
  36. uint32_t itemsOnLine;
  37. float sizeConsumedOnCurrentLine;
  38. float totalFlexGrowFactors;
  39. float totalFlexShrinkScaledFactors;
  40. uint32_t endOfLineIndex;
  41. std::vector<YGNodeRef> relativeChildren;
  42. float remainingFreeSpace;
  43. // The size of the mainDim for the row after considering size, padding, margin
  44. // and border of flex items. This is used to calculate maxLineDim after going
  45. // through all the rows to decide on the main axis size of owner.
  46. float mainDim;
  47. // The size of the crossDim for the row after considering size, padding,
  48. // margin and border of flex items. Used for calculating containers crossSize.
  49. float crossDim;
  50. };
  51. bool YGValueEqual(const YGValue a, const YGValue b);
  52. // This custom float equality function returns true if either absolute
  53. // difference between two floats is less than 0.0001f or both are undefined.
  54. bool YGFloatsEqual(const float a, const float b);
  55. // We need custom max function, since we want that, if one argument is
  56. // YGUndefined then the max funtion should return the other argument as the max
  57. // value. We wouldn't have needed a custom max function if YGUndefined was NAN
  58. // as fmax has the same behaviour, but with NAN we cannot use `-ffast-math`
  59. // compiler flag.
  60. float YGFloatMax(const float a, const float b);
  61. YGFloatOptional YGFloatOptionalMax(
  62. const YGFloatOptional& op1,
  63. const YGFloatOptional& op2);
  64. // We need custom min function, since we want that, if one argument is
  65. // YGUndefined then the min funtion should return the other argument as the min
  66. // value. We wouldn't have needed a custom min function if YGUndefined was NAN
  67. // as fmin has the same behaviour, but with NAN we cannot use `-ffast-math`
  68. // compiler flag.
  69. float YGFloatMin(const float a, const float b);
  70. // This custom float comparision function compares the array of float with
  71. // YGFloatsEqual, as the default float comparision operator will not work(Look
  72. // at the comments of YGFloatsEqual function).
  73. template <std::size_t size>
  74. bool YGFloatArrayEqual(
  75. const std::array<float, size>& val1,
  76. const std::array<float, size>& val2) {
  77. bool areEqual = true;
  78. for (std::size_t i = 0; i < size && areEqual; ++i) {
  79. areEqual = YGFloatsEqual(val1[i], val2[i]);
  80. }
  81. return areEqual;
  82. }
  83. // This function returns 0 if YGFloatIsUndefined(val) is true and val otherwise
  84. float YGFloatSanitize(const float& val);
  85. // This function unwraps optional and returns YGUndefined if not defined or
  86. // op.value otherwise
  87. // TODO: Get rid off this function
  88. float YGUnwrapFloatOptional(const YGFloatOptional& op);
  89. YGFlexDirection YGFlexDirectionCross(
  90. const YGFlexDirection flexDirection,
  91. const YGDirection direction);
  92. inline bool YGFlexDirectionIsRow(const YGFlexDirection flexDirection) {
  93. return flexDirection == YGFlexDirectionRow ||
  94. flexDirection == YGFlexDirectionRowReverse;
  95. }
  96. inline YGFloatOptional YGResolveValue(const YGValue value, const float ownerSize) {
  97. switch (value.unit) {
  98. case YGUnitUndefined:
  99. case YGUnitAuto:
  100. return YGFloatOptional();
  101. case YGUnitPoint:
  102. return YGFloatOptional(value.value);
  103. case YGUnitPercent:
  104. return YGFloatOptional(
  105. static_cast<float>(value.value * ownerSize * 0.01));
  106. }
  107. return YGFloatOptional();
  108. }
  109. inline bool YGFlexDirectionIsColumn(const YGFlexDirection flexDirection) {
  110. return flexDirection == YGFlexDirectionColumn ||
  111. flexDirection == YGFlexDirectionColumnReverse;
  112. }
  113. inline YGFlexDirection YGResolveFlexDirection(
  114. const YGFlexDirection flexDirection,
  115. const YGDirection direction) {
  116. if (direction == YGDirectionRTL) {
  117. if (flexDirection == YGFlexDirectionRow) {
  118. return YGFlexDirectionRowReverse;
  119. } else if (flexDirection == YGFlexDirectionRowReverse) {
  120. return YGFlexDirectionRow;
  121. }
  122. }
  123. return flexDirection;
  124. }
  125. static inline YGFloatOptional YGResolveValueMargin(
  126. const YGValue value,
  127. const float ownerSize) {
  128. return value.unit == YGUnitAuto ? YGFloatOptional(0)
  129. : YGResolveValue(value, ownerSize);
  130. }