<commit_before>/*
 *  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 "ASStackBaselinePositionedLayout.h"

#import "ASLayoutSpecUtilities.h"
#import "ASStackLayoutSpecUtilities.h"
#import "ASLayoutOptions.h"

static CGFloat baselineForItem(const ASStackLayoutSpecStyle &style,
                               const ASLayout *layout) {
  
  __weak id<ASLayoutable> child = layout.layoutableObject;
  switch (style.alignItems) {
    case ASStackLayoutAlignItemsBaselineFirst:
      return child.ascender;
    case ASStackLayoutAlignItemsBaselineLast:
      return layout.size.height + child.descender;
    default:
      return 0;
  }
  
}

static CGFloat baselineOffset(const ASStackLayoutSpecStyle &style,
                              const ASLayout *l,
                              const CGFloat maxAscender,
                              const CGFloat maxBaseline)
{
  if (style.direction == ASStackLayoutDirectionHorizontal) {
    __weak id<ASLayoutable> child = l.layoutableObject;
    switch (style.alignItems) {
      case ASStackLayoutAlignItemsBaselineFirst:
        return maxAscender - child.ascender;
      case ASStackLayoutAlignItemsBaselineLast:
        return maxBaseline - baselineForItem(style, l);
        
      default:
        return 0;
    }
  }
  return 0;
}

static CGFloat maxDimensionForLayout(const ASLayout *l,
                                     const ASStackLayoutSpecStyle &style)
{
  CGFloat maxDimension = crossDimension(style.direction, l.size);
  style.direction == ASStackLayoutDirectionVertical ? maxDimension += l.position.x : maxDimension += l.position.y;
  return maxDimension;
}

ASStackBaselinePositionedLayout ASStackBaselinePositionedLayout::compute(const ASStackPositionedLayout &positionedLayout,
                                                                         const ASStackLayoutSpecStyle &style,
                                                                         const ASSizeRange &constrainedSize)
{
  /* Step 1: Look at each child and determine the distance from the top of the child node it's baseline.
     For  example, let's say we have the following two text nodes and want to align them to the first baseline:
   
     Hello!    Why, hello there! How
               are you today?
   
     The first node has a font of size 14, the second a font of size 12. The first node will have a baseline offset of 
     the ascender of a font of size 14, the second will have a baseline of the ascender of a font of size 12. The first 
     baseline will be larger so we will keep that as the max baseline.
   
     However, if were to align from the last baseline we'd find the max baseline by taking the height of node and adding
     the font's descender (its negative). In the case of the first node, which is only 1 line, this should be the same value as the ascender.
     The second node, however, has a larger height and there will have a larger baseline offset.
   */
  const auto baselineIt = std::max_element(positionedLayout.sublayouts.begin(), positionedLayout.sublayouts.end(), [&](const ASLayout *a, const ASLayout *b){
    return baselineForItem(style, a) < baselineForItem(style, b);
  });
  const CGFloat maxBaseline = baselineIt == positionedLayout.sublayouts.end() ? 0 : baselineForItem(style, *baselineIt);
  
  /*
    Step 2: Find the max ascender for all of the children.
    Imagine 3 nodes aligned horizontally, all with the same text but with font sizes of 12, 14, 16. Because it is has the largest
    ascender node with font size of 16 will not need to move, the other two nodes will align to this node's baseline. The offset we will use
    for each node is our computed maxAscender - node.ascender. If the 16pt node had an ascender of 10 and the 14pt node
    had an ascender of 8, that means we will offset the 14pt node by 2 pts.
   
    Note: if we are alinging to the last baseline, then we don't need this value in our computation. However, we do want
    our layoutSpec to have it so that it can be baseline aligned with another text node or baseline layout spec.<commit_msg>fix typo and kick off build again.<commit_after>/*
 *  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 "ASStackBaselinePositionedLayout.h"

#import "ASLayoutSpecUtilities.h"
#import "ASStackLayoutSpecUtilities.h"
#import "ASLayoutOptions.h"

static CGFloat baselineForItem(const ASStackLayoutSpecStyle &style,
                               const ASLayout *layout) {
  
  __weak id<ASLayoutable> child = layout.layoutableObject;
  switch (style.alignItems) {
    case ASStackLayoutAlignItemsBaselineFirst:
      return child.ascender;
    case ASStackLayoutAlignItemsBaselineLast:
      return layout.size.height + child.descender;
    default:
      return 0;
  }
  
}

static CGFloat baselineOffset(const ASStackLayoutSpecStyle &style,
                              const ASLayout *l,
                              const CGFloat maxAscender,
                              const CGFloat maxBaseline)
{
  if (style.direction == ASStackLayoutDirectionHorizontal) {
    __weak id<ASLayoutable> child = l.layoutableObject;
    switch (style.alignItems) {
      case ASStackLayoutAlignItemsBaselineFirst:
        return maxAscender - child.ascender;
      case ASStackLayoutAlignItemsBaselineLast:
        return maxBaseline - baselineForItem(style, l);
        
      default:
        return 0;
    }
  }
  return 0;
}

static CGFloat maxDimensionForLayout(const ASLayout *l,
                                     const ASStackLayoutSpecStyle &style)
{
  CGFloat maxDimension = crossDimension(style.direction, l.size);
  style.direction == ASStackLayoutDirectionVertical ? maxDimension += l.position.x : maxDimension += l.position.y;
  return maxDimension;
}

ASStackBaselinePositionedLayout ASStackBaselinePositionedLayout::compute(const ASStackPositionedLayout &positionedLayout,
                                                                         const ASStackLayoutSpecStyle &style,
                                                                         const ASSizeRange &constrainedSize)
{
  /* Step 1: Look at each child and determine the distance from the top of the child node it's baseline.
     For  example, let's say we have the following two text nodes and want to align them to the first baseline:
   
     Hello!    Why, hello there! How
               are you today?
   
     The first node has a font of size 14, the second a font of size 12. The first node will have a baseline offset of 
     the ascender of a font of size 14, the second will have a baseline of the ascender of a font of size 12. The first 
     baseline will be larger so we will keep that as the max baseline.
   
     However, if were to align from the last baseline we'd find the max baseline by taking the height of node and adding
     the font's descender (it's negative). In the case of the first node, which is only 1 line, this should be the same value as the ascender.
     The second node, however, has a larger height and there will have a larger baseline offset.
   */
  const auto baselineIt = std::max_element(positionedLayout.sublayouts.begin(), positionedLayout.sublayouts.end(), [&](const ASLayout *a, const ASLayout *b){
    return baselineForItem(style, a) < baselineForItem(style, b);
  });
  const CGFloat maxBaseline = baselineIt == positionedLayout.sublayouts.end() ? 0 : baselineForItem(style, *baselineIt);
  
  /*
    Step 2: Find the max ascender for all of the children.
    Imagine 3 nodes aligned horizontally, all with the same text but with font sizes of 12, 14, 16. Because it is has the largest
    ascender node with font size of 16 will not need to move, the other two nodes will align to this node's baseline. The offset we will use
    for each node is our computed maxAscender - node.ascender. If the 16pt node had an ascender of 10 and the 14pt node
    had an ascender of 8, that means we will offset the 14pt node by 2 pts.
   
    Note: if we are alinging to the last baseline, then we don't need this value in our computation. However, we do want
    our layoutSpec to have it so that it can be baseline aligned with another text node or baseline layout spec.
{'fraction_non_alphanumeric': 0.05694603903559128, 'fraction_numerical': 0.008725602755453503, 'mean_word_length': 2.761226252158895, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 16, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1886983', 'n_tokens_mistral': 2335, 'n_tokens_neox': 2229, 'n_words': 985}