File: LayoutBlockBox.h

package info (click to toggle)
freespace2 24.2.0%2Brepack-3
  • links: PTS, VCS
  • area: non-free
  • in suites: forky, sid
  • size: 43,740 kB
  • sloc: cpp: 595,005; ansic: 21,741; python: 1,174; sh: 457; makefile: 243; xml: 181
file content (236 lines) | stat: -rw-r--r-- 10,431 bytes parent folder | download | duplicates (2)
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
/*
 * This source file is part of libRocket, the HTML/CSS Interface Middleware
 *
 * For the latest information, see http://www.librocket.com
 *
 * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 */

#ifndef ROCKETCORELAYOUTBLOCKBOX_H
#define ROCKETCORELAYOUTBLOCKBOX_H

#include "LayoutLineBox.h"
#include "../../Include/Rocket/Core/Box.h"
#include "../../Include/Rocket/Core/Types.h"

namespace Rocket {
namespace Core {

class LayoutBlockBoxSpace;
class LayoutEngine;

/**
	@author Peter Curry
 */

class LayoutBlockBox
{
public:
	enum FormattingContext
	{
		BLOCK,
		INLINE
	};

	enum CloseResult
	{
		OK,
		LAYOUT_SELF,
		LAYOUT_PARENT
	};

	/// Creates a new block box for rendering a block element.
	/// @param layout_engine[in] The layout engine that created this block box.
	/// @param parent[in] The parent of this block box. This will be NULL for the root element.
	/// @param element[in] The element this block box is laying out.
	LayoutBlockBox(LayoutEngine* layout_engine, LayoutBlockBox* parent, Element* element);
	/// Creates a new block box in an inline context.
	/// @param layout_engine[in] The layout engine that created this block box.
	/// @param parent[in] The parent of this block box.
	LayoutBlockBox(LayoutEngine* layout_engine, LayoutBlockBox* parent);
	/// Releases the block box.
	~LayoutBlockBox();

	/// Closes the box. This will determine the element's height (if it was unspecified).
	/// @return The result of the close; this may request a reformat of this element or our parent.
	CloseResult Close();

	/// Called by a closing block box child. Increments the cursor.
	/// @param child[in] The closing child block box.
	/// @return False if the block box caused an automatic vertical scrollbar to appear, forcing an entire reformat of the block box.
	bool CloseBlockBox(LayoutBlockBox* child);
	/// Called by a closing line box child. Increments the cursor, and creates a new line box to fit the overflow
	/// (if any).
	/// @param child[in] The closing child line box.
	/// @param overflow[in] The overflow from the closing line box. May be NULL if there was no overflow.
	/// @param overflow_chain[in] The end of the chained hierarchy to be spilled over to the new line, as the parent to the overflow box (if one exists).
	/// @return If the line box had overflow, this will be the last inline box created by the overflow.
	LayoutInlineBox* CloseLineBox(LayoutLineBox* child, LayoutInlineBox* overflow, LayoutInlineBox* overflow_chain);

	/// Adds a new block element to this block-context box.
	/// @param element[in] The new block element.
	/// @param placed[in] True if the element is to be placed, false otherwise.
	/// @return The block box representing the element. Once the element's children have been positioned, Close() must be called on it.
	LayoutBlockBox* AddBlockElement(Element* element);
	/// Adds a new inline element to this inline-context box.
	/// @param element[in] The new inline element.
	/// @param box[in] The box defining the element's bounds.
	/// @return The inline box representing the element. Once the element's children have been positioned, Close() must be called on it.
	LayoutInlineBox* AddInlineElement(Element* element, const Box& box);
	/// Adds a line-break to this block box.
	void AddBreak();

	/// Adds an element to this block box to be handled as a floating element.
	bool AddFloatElement(Element* element);

	/// Adds an element to this block box to be handled as an absolutely-positioned element. This element will be
	/// laid out, sized and positioned appropriately once this box is finished. This should only be called on boxes
	/// rendering in a block-context.
	/// @param element[in] The element to be positioned absolutely within this block box.
	void AddAbsoluteElement(Element* element);
	/// Formats, sizes, and positions all absolute elements in this block.
	void CloseAbsoluteElements();

	/// Returns the offset from the top-left corner of this box's offset element the next child box will be
	/// positioned at.
	/// @param[out] box_position The box cursor position.
	/// @param[in] top_margin The top margin of the box. This will be collapsed as appropriate against other block boxes.
	/// @param[in] clear_property The value of the underlying element's clear property.
	void PositionBox(Vector2f& box_position, float top_margin = 0, int clear_property = 0) const;
	/// Returns the offset from the top-left corner of this box's offset element the next child block box, of the
	/// given dimensions, will be positioned at. This will include the margins on the new block box.
	/// @param[out] box_position The block box cursor position.
	/// @param[in] box The dimensions of the new box.
	/// @param[in] clear_property The value of the underlying element's clear property.
	void PositionBlockBox(Vector2f& box_position, const Box& box, int clear_property) const;
	/// Returns the offset from the top-left corner of this box for the next line.
	/// @param box_position[out] The line box position.
	/// @param box_width[out] The available width for the line box.
	/// @param wrap_content[out] Set to true if the line box should grow to fit inline boxes, false if it should wrap them.
	/// @param dimensions[in] The minimum dimensions of the line.
	void PositionLineBox(Vector2f& box_position, float& box_width, bool& wrap_content, const Vector2f& dimensions) const;

	/// Returns the block box's element.
	/// @return The block box's element.
	Element* GetElement() const;

	/// Returns the block box's parent.
	/// @return The block box's parent.
	LayoutBlockBox* GetParent() const;

	/// Returns the position of the block box, relative to its parent's content area.
	/// @return The relative position of the block box.
	const Vector2f& GetPosition() const;

	/// Returns the block box against which all positions of boxes in the hierarchy are set relative to.
	/// @return This box's offset parent.
	LayoutBlockBox* GetOffsetParent() const;
	/// Returns the block box against which all positions of boxes in the hierarchy are calculated relative to.
	/// @return This box's offset root.
	LayoutBlockBox* GetOffsetRoot() const;

	/// Returns the block box's dimension box.
	/// @return The block box's dimension box.
	Box& GetBox();
	/// Returns the block box's dimension box.
	/// @return The block box's dimension box.
	const Box& GetBox() const;

	void* operator new(size_t size);
	void operator delete(void* chunk);

private:
	struct AbsoluteElement
	{
		Element* element;
		Vector2f position;
	};

	// Closes our last block box, if it is an open inline block box.
	CloseResult CloseInlineBlockBox();

	// Positions a floating element within this block box.
	void PositionFloat(Element* element, float offset = 0);

	// Checks if we have a new vertical overflow on an auto-scrolling element. If so, our vertical scrollbar will
	// be enabled and our block boxes will be destroyed. All content will need to re-formatted. Returns true if no
	// overflow occured, false if it did.
	bool CatchVerticalOverflow(float cursor = -1);

	typedef std::vector< AbsoluteElement > AbsoluteElementList;
	typedef std::vector< LayoutBlockBox* > BlockBoxList;
	typedef std::vector< LayoutLineBox* > LineBoxList;

	// The object managing our space, as occupied by floating elements of this box and our ancestors.
	LayoutBlockBoxSpace* space;

	// The box's layout engine.
	LayoutEngine* layout_engine;
	// The element this box represents. This will be NULL for boxes rendering in an inline context.
	Element* element;

	// The element we'll be computing our offset relative to during layout.
	LayoutBlockBox* offset_root;
	// The element this block box's children are to be offset from.
	LayoutBlockBox* offset_parent;

	// The box's block parent. This will be NULL for the root of the box tree.
	LayoutBlockBox* parent;

	// The context of the box's context; either block or inline.
	FormattingContext context;

	// The block box's position.
	Vector2f position;
	// The block box's size.
	Box box;
	float min_height;
	float max_height;
	// Used by inline contexts only; set to true if the block box's line boxes should stretch to fit their inline content instead of wrapping.
	bool wrap_content;

	// The vertical position of the next block box to be added to this box, relative to the top of this box.
	float box_cursor;

	// Used by block contexts only; stores the list of block boxes under this box.
	BlockBoxList block_boxes;
	// Used by block contexts only; stores any elements that are to be absolutely positioned within this block box.
	AbsoluteElementList absolute_elements;
	// Used by block contexts only; stores an inline element hierarchy that was interrupted by a child block box.
	// The hierarchy will be resumed in an inline-context box once the intervening block box is completed.
	LayoutInlineBox* interrupted_chain;
	// Used by block contexts only; stores the value of the overflow property for the element.
	int overflow_x_property;
	int overflow_y_property;
	// Used by block contexts only; if true, we've enabled our vertical scrollbar.
	bool vertical_overflow;

	// Used by inline contexts only; stores the list of line boxes flowing inline content.
	LineBoxList line_boxes;
	// Used by inline contexts only; stores any floating elements that are waiting for a line break to be positioned.
	ElementList float_elements;
};

}
}

#endif