1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
|
// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_BREAK_TOKEN_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_BREAK_TOKEN_H_
#include "base/check_op.h"
#include "base/dcheck_is_on.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/layout/layout_input_node.h"
namespace blink {
// A break token is a continuation token for layout. A single layout input node
// can have multiple fragments asssociated with it.
//
// Each fragment whose node needs to resume layout in a future fragmentainer
// (column, line, etc.) will have a break token associated with it.
//
// See CSS Fragmentation (https://drafts.csswg.org/css-break/) for a detailed
// description of different types of breaks which can occur in CSS.
//
// Each layout algorithm which can fragment, e.g. block-flow can optionally
// accept a break token. For example:
//
// LayoutInputNode* node = ...;
// PhysicalFragment* fragment = node->Layout(space);
// PhysicalFragment* fragment2 =
// node->Layout(space, fragment->GetBreakToken());
//
// The break token should encapsulate enough information to "resume" the layout.
class CORE_EXPORT BreakToken : public GarbageCollected<BreakToken> {
public:
enum BreakTokenType {
kBlockBreakToken = LayoutInputNode::kBlock,
kInlineBreakToken = LayoutInputNode::kInline
};
BreakTokenType Type() const { return static_cast<BreakTokenType>(type_); }
bool IsBlockType() const { return Type() == kBlockBreakToken; }
bool IsInlineType() const { return Type() == kInlineBreakToken; }
// Returns the node associated with this break token. A break token cannot be
// used with any other node.
LayoutInputNode InputNode() const {
return LayoutInputNode::Create(
box_.Get(), static_cast<LayoutInputNode::LayoutInputNodeType>(type_));
}
// Return true if this break token is for a node that's being resumed in a
// parallel flow.
bool IsInParallelFlow() const;
#if DCHECK_IS_ON()
String ToString() const;
void ShowBreakTokenTree() const;
#endif
void Trace(Visitor*) const;
void TraceAfterDispatch(Visitor*) const;
protected:
BreakToken(BreakTokenType type, LayoutInputNode node, unsigned flags = 0)
: box_(node.GetLayoutBox()),
type_(type),
is_repeated_actual_break_(false),
flags_(flags),
is_break_before_(false),
is_forced_break_(false),
is_repeated_(false),
is_caused_by_column_spanner_(false),
is_at_block_end_(false),
has_seen_all_children_(false) {
DCHECK_EQ(type, static_cast<BreakTokenType>(node.Type()));
}
private:
// Because |LayoutInputNode| has a pointer and 1 bit flag, and it's fast to
// re-construct, keep |LayoutBox| to save the memory consumed by alignment.
Member<LayoutBox> box_;
unsigned type_ : 1;
protected:
// If true, this is a break token for an actual break in a cloned fragment. In
// such cases, only a few of the members here have been set up correctly, and
// the rest should therefore not be accessed. Such break tokens are never used
// in layout, only by pre-paint / paint.
unsigned is_repeated_actual_break_ : 1;
// The following bitfields are only to be used by InlineBreakToken (it's
// defined here to save memory, since that class has no bitfields).
const unsigned flags_ : 6; // InlineBreakTokenFlags
// The following bitfields are only to be used by BlockBreakToken (it's
// defined here to save memory, since that class has no bitfields).
unsigned is_break_before_ : 1;
unsigned is_forced_break_ : 1;
unsigned is_repeated_ : 1;
unsigned is_caused_by_column_spanner_ : 1;
// Set when layout is past the block-end border edge. If we break when we're
// in this state, it means that something is overflowing, and thus establishes
// a parallel flow.
unsigned is_at_block_end_ : 1;
// All children of this container have been "seen" at this point. This means
// that all children have been fully laid out, or have break tokens. No more
// children left to discover.
unsigned has_seen_all_children_ : 1;
// See |BlockBreakToken::HasUnpositionedListMarker|.
unsigned has_unpositioned_list_marker_ : 1;
};
typedef HeapVector<Member<const BreakToken>> BreakTokenVector;
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_BREAK_TOKEN_H_
|