3 Commits
Author SHA1 Message Date
ricky c239cada2e [ASTextNode2] Add support for pointSizeScaleFactors (#1966)
* [ASTextNode2] Add support for pointSizeScaleFactors

Implements `pointSizeScaleFactors` in ASTextNode2. If you provide and array of `pointSizeScaleFactors` and set a `maximumNumberOfLines` > 0, text layout will check if your text fit in the max number of lines. If not, it will scale your text by the scale factors in `pointSizeScaleFactors` until it either finds the first scale that allows the text to fit, or it runs out of scale factors.

* put this back where it was
2021-02-26 15:30:33 -08:00
ricky c3c4065227 [ASTextNode2] If a textnode's bounds match either the text container's size OR the layout's size, consider it a cache hit (#1965)
* [ASTextNode2] Don’t update the text container’s size before drawing

While working in `ASTextNode2` I noticed we don’t seem to use cached `ASTextLayout` when drawing the text. Here is what I’m seeing:

When `ASTextNode2` calculates its size it calls `layoutWithContainer:text:range:`. The container passed into `layoutWithContainer:text:range:` holds the input information for attributes like size, insets, exclusion paths, etc that will help create the layout. When the layout is computed it is passed back to `ASTextNode2` via an `ASTextLayout` object. This layout is placed into a cache using the container's size for the key.

When the text is actually drawn via `drawRect`, `drawParametersForAsyncLayer` provides us with a container that we use to look for the cached layout. However, after copying `ASTextNode2's`  `_textContainer` it changes its size to `self.bounds.size` :
```
    copiedContainer = [_textContainer copy];
    copiedContainer.size = self.bounds.size;
    [copiedContainer makeImmutable];
```

We then take this container and look in the cache for a related `ASTextLayout`. Of course, we don’t find the layout we just created since we are using a different `size` as a key into the cache. It seems like this behavior guarantees that we will always have a cache miss unless our original constrained size and the final size of the layout happen to be the same.

Am I missing something? Do we really want to change the container’s bounds here?

* Change logic around when to use a cached text layout

Previously we’d use a cached text layout if the container’s size is the same size as it was when the text layout was first computed. However, because we change the container’s size before the draw to be the text node’s bounds NOT its constrained size, this would often end in us having a cache miss.

This change checks to see if the container’s size is the same as the textLayout’s textBoundingSize. If so, we will use the cached layout even if the container’s size is not the same as when the text layout was computed.

The one trick in this is that if the text was truncated, we don’t use the layout’s textBoundingSize as the layout size. Instead, there is some logic in `ASTextNode2::calculateSizeThatFits` that will use the layout’s `truncatedLine` to determine the layout height. I moved this logic to `ASTextLayout` so it can be used in both `calculateSizeThatFits` and when checking the cache. I’m not sure if this is the best place for this method. Let me know if you have a different idea!

* remove unused parameter from method

includeTruncatedLine is always YES, so let’s take it out

* Update snapshot test
2021-02-26 12:58:37 -08:00
ricky 68a1bec062 [ASTextNode2] Make some ASTextNode2 layout files public (#1939)
* Trying to make ASTextLinePositionModifier public

* d’oh

* be a little more restrictive on the files we pull into the pod

* Never mind, I guess we need all of these

* update the project file as well

* try this again

* I think this will work this time.
2020-12-14 12:30:25 -08:00