From b45a7e3737907f9f57588a64b43496d345ea9055 Mon Sep 17 00:00:00 2001 From: Emil Sjolander Date: Fri, 14 Oct 2016 04:35:46 -0700 Subject: [PATCH] Don't assume a node with a measure function is a leaf node Summary: Don't assume a node with a measure function is a leaf node Reviewed By: gkassabli Differential Revision: D4021096 fbshipit-source-id: 7e039239b1697a0ac42dce9f4b7e252a931bad7e --- CSSLayout/CSSLayout.c | 11 ++++----- tests/CSSLayoutMeasureTest.cpp | 44 ++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 6 deletions(-) create mode 100644 tests/CSSLayoutMeasureTest.cpp diff --git a/CSSLayout/CSSLayout.c b/CSSLayout/CSSLayout.c index 183cbaef..e44429b7 100644 --- a/CSSLayout/CSSLayout.c +++ b/CSSLayout/CSSLayout.c @@ -242,10 +242,9 @@ uint32_t CSSNodeChildCount(const CSSNodeRef node) { } void CSSNodeMarkDirty(const CSSNodeRef node) { - CSS_ASSERT(node->measure != NULL, - "Nodes without custom measure functions " - "should not manually mark themselves as " - "dirty"); + CSS_ASSERT(node->measure != NULL || CSSNodeChildCount(node) > 0, + "Only leaf nodes with custom measure functions" + "should manually mark themselves as dirty"); _CSSNodeMarkDirty(node); } @@ -966,7 +965,7 @@ static void layoutNodeImpl(const CSSNodeRef node, // For content (text) nodes, determine the dimensions based on the text // contents. - if (node->measure) { + if (node->measure && CSSNodeChildCount(node) == 0) { const float innerWidth = availableWidth - marginAxisRow - paddingAndBorderAxisRow; const float innerHeight = availableHeight - marginAxisColumn - paddingAndBorderAxisColumn; @@ -2100,7 +2099,7 @@ bool layoutNodeInternal(const CSSNodeRef node, // most // expensive to measure, so it's worth avoiding redundant measurements if at // all possible. - if (node->measure) { + if (node->measure && CSSNodeChildCount(node) == 0) { const float marginAxisRow = getMarginAxis(node, CSSFlexDirectionRow); const float marginAxisColumn = getMarginAxis(node, CSSFlexDirectionColumn); diff --git a/tests/CSSLayoutMeasureTest.cpp b/tests/CSSLayoutMeasureTest.cpp new file mode 100644 index 00000000..b451dcfa --- /dev/null +++ b/tests/CSSLayoutMeasureTest.cpp @@ -0,0 +1,44 @@ +/** + * 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. + */ + +#include +#include + +static CSSSize _measure(void *context, + float width, + CSSMeasureMode widthMode, + float height, + CSSMeasureMode heightMode) { + int *measureCount = (int *)context; + *measureCount = *measureCount + 1; + return CSSSize { + .width = widthMode == CSSMeasureModeUndefined ? 10 : width, + .height = heightMode == CSSMeasureModeUndefined ? 10 : width, + }; +} + +TEST(CSSLayoutTest, ignore_measure_on_non_leaf_node) { + const CSSNodeRef root = CSSNodeNew(); + int measureCount = 0; + CSSNodeSetContext(root, &measureCount); + CSSNodeSetMeasureFunc(root, _measure); + + const CSSNodeRef root_child0 = CSSNodeNew(); + int childMeasureCount = 0; + CSSNodeSetContext(root_child0, &childMeasureCount); + CSSNodeSetMeasureFunc(root_child0, _measure); + CSSNodeInsertChild(root, root_child0, 0); + + CSSNodeCalculateLayout(root, CSSUndefined, CSSUndefined, CSSDirectionLTR); + + ASSERT_EQ(0, measureCount); + ASSERT_EQ(1, childMeasureCount); + + CSSNodeFreeRecursive(root); +}