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
|