Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2251)

Unified Diff: third_party/WebKit/Source/core/layout/ng/ng_floats_utils.cc

Issue 2757603007: Move NG floats utility methods to the separate file (Closed)
Patch Set: Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/core/layout/ng/ng_floats_utils.cc
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_floats_utils.cc b/third_party/WebKit/Source/core/layout/ng/ng_floats_utils.cc
new file mode 100644
index 0000000000000000000000000000000000000000..61b987bb7d44fb52fa76f33f1a59422dd9ad1ce9
--- /dev/null
+++ b/third_party/WebKit/Source/core/layout/ng/ng_floats_utils.cc
@@ -0,0 +1,166 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "core/layout/ng/ng_floats_utils.h"
+
+#include "core/layout/ng/ng_box_fragment.h"
+
+namespace blink {
+namespace {
+
+// Adjusts the provided offset to the top edge alignment rule.
+// Top edge alignment rule: the outer top of a floating box may not be higher
+// than the outer top of any block or floated box generated by an element
+// earlier in the source document.
+NGLogicalOffset AdjustToTopEdgeAlignmentRule(const NGConstraintSpace& space,
+ const NGLogicalOffset& offset) {
+ NGLogicalOffset adjusted_offset = offset;
+ LayoutUnit& adjusted_block_offset = adjusted_offset.block_offset;
+ if (space.Exclusions()->last_left_float)
+ adjusted_block_offset =
+ std::max(adjusted_block_offset,
+ space.Exclusions()->last_left_float->rect.BlockStartOffset());
+ if (space.Exclusions()->last_right_float)
+ adjusted_block_offset =
+ std::max(adjusted_block_offset,
+ space.Exclusions()->last_right_float->rect.BlockStartOffset());
+ return adjusted_offset;
+}
+
+// Finds a layout opportunity for the fragment.
+// It iterates over all layout opportunities in the constraint space and returns
+// the first layout opportunity that is wider than the fragment or returns the
+// last one which is always the widest.
+//
+// @param space Constraint space that is used to find layout opportunity for
+// the fragment.
+// @param fragment Fragment that needs to be placed.
+// @param origin_point {@code space}'s offset relative to the space that
+// establishes a new formatting context that we're currently
+// in and where all our exclusions reside.
+// @param margins Margins of the fragment.
+// @return Layout opportunity for the fragment.
+const NGLayoutOpportunity FindLayoutOpportunityForFragment(
+ const NGConstraintSpace* space,
+ const NGFragment& fragment,
+ const NGLogicalOffset& origin_point,
+ const NGBoxStrut& margins) {
+ NGLogicalOffset adjusted_origin_point =
+ AdjustToTopEdgeAlignmentRule(*space, origin_point);
+
+ NGLayoutOpportunityIterator opportunity_iter(space, adjusted_origin_point);
+ NGLayoutOpportunity opportunity;
+ NGLayoutOpportunity opportunity_candidate = opportunity_iter.Next();
+
+ while (!opportunity_candidate.IsEmpty()) {
+ opportunity = opportunity_candidate;
+ // Checking opportunity's block size is not necessary as a float cannot be
+ // positioned on top of another float inside of the same constraint space.
+ auto fragment_inline_size = fragment.InlineSize() + margins.InlineSum();
+ if (opportunity.size.inline_size >= fragment_inline_size)
+ break;
+
+ opportunity_candidate = opportunity_iter.Next();
+ }
+ return opportunity;
+}
+
+// Calculates the logical offset for opportunity.
+NGLogicalOffset CalculateLogicalOffsetForOpportunity(
+ const NGLayoutOpportunity& opportunity,
+ const LayoutUnit float_offset,
+ const NGLogicalOffset& from_offset,
+ NGFloatingObject* floating_object) {
+ DCHECK(floating_object);
+ auto margins = floating_object->margins;
+ // Adjust to child's margin.
+ LayoutUnit inline_offset = margins.inline_start;
+ LayoutUnit block_offset = margins.block_start;
+
+ // Offset from the opportunity's block/inline start.
+ inline_offset += opportunity.offset.inline_offset;
+ block_offset += opportunity.offset.block_offset;
+
+ // Adjust to float: right offset if needed.
+ inline_offset += float_offset;
+
+ block_offset -= from_offset.block_offset;
+ inline_offset -= from_offset.inline_offset;
+
+ return NGLogicalOffset(inline_offset, block_offset);
+}
+
+// Creates an exclusion from the fragment that will be placed in the provided
+// layout opportunity.
+NGExclusion CreateExclusion(const NGFragment& fragment,
+ const NGLayoutOpportunity& opportunity,
+ const LayoutUnit float_offset,
+ const NGBoxStrut& margins,
+ NGExclusion::Type exclusion_type) {
+ NGExclusion exclusion;
+ exclusion.type = exclusion_type;
+ NGLogicalRect& rect = exclusion.rect;
+ rect.offset = opportunity.offset;
+ rect.offset.inline_offset += float_offset;
+
+ rect.size.inline_size = fragment.InlineSize() + margins.InlineSum();
+ rect.size.block_size = fragment.BlockSize() + margins.BlockSum();
+ return exclusion;
+}
+
+// Updates the Floating Object's left offset from the provided parent_space
+// and {@code floating_object}'s space and margins.
+void UpdateFloatingObjectLeftOffset(const NGConstraintSpace& new_parent_space,
+ const NGLogicalOffset& float_logical_offset,
+ NGFloatingObject* floating_object) {
+ DCHECK(floating_object);
+ // TODO(glebl): We should use physical offset here.
+ floating_object->left_offset =
+ floating_object->original_parent_space->BfcOffset().inline_offset -
+ new_parent_space.BfcOffset().inline_offset +
+ float_logical_offset.inline_offset;
+}
+} // namespace
+
+// Calculates the relative position from {@code from_offset} of the
+// floating object that is requested to be positioned from {@code origin_point}.
+NGLogicalOffset PositionFloat(const NGLogicalOffset& origin_point,
+ const NGLogicalOffset& from_offset,
+ NGFloatingObject* floating_object,
+ NGConstraintSpace* new_parent_space) {
+ DCHECK(floating_object);
+ const auto* float_space = floating_object->space.get();
+ DCHECK(floating_object->fragment) << "Fragment cannot be null here";
+
+ // TODO(ikilpatrick): The writing mode switching here looks wrong.
+ NGBoxFragment float_fragment(
+ float_space->WritingMode(),
+ toNGPhysicalBoxFragment(floating_object->fragment.get()));
+
+ // Find a layout opportunity that will fit our float.
+ const NGLayoutOpportunity opportunity = FindLayoutOpportunityForFragment(
+ float_space, float_fragment, origin_point, floating_object->margins);
+ DCHECK(!opportunity.IsEmpty()) << "Opportunity is empty but it shouldn't be";
+
+ // Calculate the float offset if needed.
+ LayoutUnit float_offset;
+ if (floating_object->exclusion_type == NGExclusion::kFloatRight) {
+ LayoutUnit float_margin_box_inline_size =
+ float_fragment.InlineSize() + floating_object->margins.InlineSum();
+ float_offset = opportunity.size.inline_size - float_margin_box_inline_size;
+ }
+
+ // Add the float as an exclusion.
+ const NGExclusion exclusion = CreateExclusion(
+ float_fragment, opportunity, float_offset, floating_object->margins,
+ floating_object->exclusion_type);
+ new_parent_space->AddExclusion(exclusion);
+
+ NGLogicalOffset logical_offset = CalculateLogicalOffsetForOpportunity(
+ opportunity, float_offset, from_offset, floating_object);
+ UpdateFloatingObjectLeftOffset(*new_parent_space, logical_offset,
+ floating_object);
+ return logical_offset;
+}
+} // namespace blink

Powered by Google App Engine
This is Rietveld 408576698