blob: d0689b481f5782397971adefc9bd1f636b07d144 [file] [log] [blame]
/*
* Copyright (C) 2000 Lars Knoll (knoll@kde.org)
* Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All right reserved.
* Copyright (C) 2010 Google Inc. All rights reserved.
* Copyright (C) 2013 ChangSeok Oh <shivamidow@gmail.com>
* Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include "LayoutRect.h"
#include "RenderBlockFlow.h"
#include <wtf/RefCounted.h>
namespace WebCore {
class FloatWithRect : public RefCounted<FloatWithRect> {
WTF_MAKE_FAST_ALLOCATED;
public:
static Ref<FloatWithRect> create(RenderBox& renderer)
{
return adoptRef(*new FloatWithRect(renderer));
}
RenderBox& renderer() const { return m_renderer; }
LayoutRect rect() const { return m_rect; }
bool everHadLayout() const { return m_everHadLayout; }
void adjustRect(const LayoutRect& rect) { m_rect = rect; }
private:
FloatWithRect(RenderBox& renderer)
: m_renderer(renderer)
, m_rect(LayoutRect(renderer.x() - renderer.marginLeft(), renderer.y() - renderer.marginTop(), renderer.width() + renderer.horizontalMarginExtent(), renderer.height() + renderer.verticalMarginExtent()))
, m_everHadLayout(renderer.everHadLayout())
{
}
RenderBox& m_renderer;
LayoutRect m_rect;
bool m_everHadLayout { false };
};
// Like LayoutState for layout(), LineLayoutState keeps track of global information
// during an entire linebox tree layout pass (aka layoutInlineChildren).
class LineLayoutState {
public:
class FloatList {
public:
void append(Ref<FloatWithRect>&& floatWithRect)
{
m_floats.add(floatWithRect.copyRef());
m_floatWithRectMap.add(&floatWithRect->renderer(), WTFMove(floatWithRect));
}
void setLastFloat(FloatingObject* lastFloat) { m_lastFloat = lastFloat; }
FloatingObject* lastFloat() const { return m_lastFloat; }
void setLastCleanFloat(RenderBox& floatBox) { m_lastCleanFloat = &floatBox; }
RenderBox* lastCleanFloat() const { return m_lastCleanFloat; }
FloatWithRect* floatWithRect(RenderBox& floatBox) const { return m_floatWithRectMap.get(&floatBox); }
using Iterator = ListHashSet<Ref<FloatWithRect>>::iterator;
Iterator begin() { return m_floats.begin(); }
Iterator end() { return m_floats.end(); }
Iterator find(FloatWithRect& floatBoxWithRect) { return m_floats.find(floatBoxWithRect); }
bool isEmpty() const { return m_floats.isEmpty(); }
private:
ListHashSet<Ref<FloatWithRect>> m_floats;
HashMap<RenderBox*, Ref<FloatWithRect>> m_floatWithRectMap;
FloatingObject* m_lastFloat { nullptr };
RenderBox* m_lastCleanFloat { nullptr };
};
LineLayoutState(const RenderBlockFlow& blockFlow, bool fullLayout, LayoutUnit& repaintLogicalTop, LayoutUnit& repaintLogicalBottom, RenderFragmentedFlow* fragmentedFlow)
: m_fragmentedFlow(fragmentedFlow)
, m_repaintLogicalTop(repaintLogicalTop)
, m_repaintLogicalBottom(repaintLogicalBottom)
, m_marginInfo(blockFlow, blockFlow.borderAndPaddingBefore(), blockFlow.borderAndPaddingAfter() + blockFlow.scrollbarLogicalHeight())
, m_endLineMatched(false)
, m_checkForFloatsFromLastLine(false)
, m_isFullLayout(fullLayout)
, m_usesRepaintBounds(false)
{
}
LineInfo& lineInfo() { return m_lineInfo; }
const LineInfo& lineInfo() const { return m_lineInfo; }
LayoutUnit endLineLogicalTop() const { return m_endLineLogicalTop; }
void setEndLineLogicalTop(LayoutUnit logicalTop) { m_endLineLogicalTop = logicalTop; }
RootInlineBox* endLine() const { return m_endLine; }
void setEndLine(RootInlineBox* line) { m_endLine = line; }
LayoutUnit adjustedLogicalLineTop() const { return m_adjustedLogicalLineTop; }
void setAdjustedLogicalLineTop(LayoutUnit value) { m_adjustedLogicalLineTop = value; }
RenderFragmentedFlow* fragmentedFlow() const { return m_fragmentedFlow; }
void setFragmentedFlow(RenderFragmentedFlow* thread) { m_fragmentedFlow = thread; }
bool endLineMatched() const { return m_endLineMatched; }
void setEndLineMatched(bool endLineMatched) { m_endLineMatched = endLineMatched; }
bool checkForFloatsFromLastLine() const { return m_checkForFloatsFromLastLine; }
void setCheckForFloatsFromLastLine(bool check) { m_checkForFloatsFromLastLine = check; }
void markForFullLayout() { m_isFullLayout = true; }
bool isFullLayout() const { return m_isFullLayout; }
bool usesRepaintBounds() const { return m_usesRepaintBounds; }
void setRepaintRange(LayoutUnit logicalHeight)
{
m_usesRepaintBounds = true;
m_repaintLogicalTop = m_repaintLogicalBottom = logicalHeight;
}
void updateRepaintRangeFromBox(RootInlineBox* box, LayoutUnit paginationDelta = 0_lu)
{
m_usesRepaintBounds = true;
m_repaintLogicalTop = std::min(m_repaintLogicalTop, box->logicalTopVisualOverflow() + std::min<LayoutUnit>(paginationDelta, 0));
m_repaintLogicalBottom = std::max(m_repaintLogicalBottom, box->logicalBottomVisualOverflow() + std::max<LayoutUnit>(paginationDelta, 0));
}
RenderBlockFlow::MarginInfo& marginInfo() { return m_marginInfo; }
FloatList& floatList() { return m_floatList; }
private:
LineInfo m_lineInfo;
LayoutUnit m_endLineLogicalTop;
RootInlineBox* m_endLine { nullptr };
LayoutUnit m_adjustedLogicalLineTop;
RenderFragmentedFlow* m_fragmentedFlow { nullptr };
FloatList m_floatList;
// FIXME: Should this be a range object instead of two ints?
LayoutUnit& m_repaintLogicalTop;
LayoutUnit& m_repaintLogicalBottom;
RenderBlockFlow::MarginInfo m_marginInfo;
bool m_endLineMatched : 1;
bool m_checkForFloatsFromLastLine : 1;
bool m_isFullLayout : 1;
bool m_usesRepaintBounds : 1;
};
} // namespace WebCore