This source file includes following definitions.
- m_cue
- layout
- findFirstLineBox
- initializeLayoutParameters
- placeBoxInDefaultPosition
- isOutside
- isOverlapping
- shouldSwitchDirection
- moveBoxesByStep
- switchDirection
- repositionCueSnapToLinesSet
- repositionCueSnapToLinesNotSet
#include "config.h"
#include "core/rendering/RenderVTTCue.h"
#include "core/html/track/vtt/VTTCue.h"
#include "core/rendering/LayoutRectRecorder.h"
#include "core/rendering/RenderView.h"
namespace WebCore {
RenderVTTCue::RenderVTTCue(VTTCueBox* element)
: RenderBlockFlow(element)
, m_cue(element->getCue())
{
}
void RenderVTTCue::layout()
{
LayoutRectRecorder recorder(*this);
RenderBlockFlow::layout();
if (!m_cue->regionId().isEmpty())
return;
LayoutStateMaintainer statePusher(*this, locationOffset());
if (m_cue->snapToLines())
repositionCueSnapToLinesSet();
else
repositionCueSnapToLinesNotSet();
}
bool RenderVTTCue::findFirstLineBox(InlineFlowBox*& firstLineBox)
{
if (firstChild()->isRenderInline())
firstLineBox = toRenderInline(firstChild())->firstLineBox();
else
return false;
return true;
}
bool RenderVTTCue::initializeLayoutParameters(InlineFlowBox* firstLineBox, LayoutUnit& step, LayoutUnit& position)
{
ASSERT(firstChild());
RenderBlock* parentBlock = containingBlock();
step = m_cue->getWritingDirection() == VTTCue::Horizontal ? firstLineBox->height() : firstLineBox->width();
if (!step)
return false;
int linePosition = m_cue->calculateComputedLinePosition();
if (m_cue->getWritingDirection() == VTTCue::VerticalGrowingLeft)
linePosition = -(linePosition + 1);
position = step * linePosition;
if (m_cue->getWritingDirection() == VTTCue::VerticalGrowingLeft) {
position -= width();
position += step;
}
if (linePosition < 0) {
position += m_cue->getWritingDirection() == VTTCue::Horizontal ? parentBlock->height() : parentBlock->width();
step = -step;
}
return true;
}
void RenderVTTCue::placeBoxInDefaultPosition(LayoutUnit position, bool& switched)
{
if (m_cue->getWritingDirection() == VTTCue::Horizontal) {
setY(y() + position);
} else {
setX(x() + position);
}
m_fallbackPosition = FloatPoint(location());
switched = false;
}
bool RenderVTTCue::isOutside() const
{
return !containingBlock()->absoluteBoundingBoxRect().contains(absoluteContentBox());
}
bool RenderVTTCue::isOverlapping() const
{
for (RenderObject* box = previousSibling(); box; box = box->previousSibling()) {
IntRect boxRect = box->absoluteBoundingBoxRect();
if (absoluteBoundingBoxRect().intersects(boxRect))
return true;
}
return false;
}
bool RenderVTTCue::shouldSwitchDirection(InlineFlowBox* firstLineBox, LayoutUnit step) const
{
LayoutUnit top = y();
LayoutUnit left = x();
LayoutUnit bottom = top + firstLineBox->height();
LayoutUnit right = left + firstLineBox->width();
LayoutUnit parentHeight = containingBlock()->height();
if (m_cue->getWritingDirection() == VTTCue::Horizontal && ((step < 0 && top < 0) || (step > 0 && bottom > parentHeight)))
return true;
LayoutUnit parentWidth = containingBlock()->width();
if (m_cue->getWritingDirection() != VTTCue::Horizontal && ((step < 0 && left < 0) || (step > 0 && right > parentWidth)))
return true;
return false;
}
void RenderVTTCue::moveBoxesByStep(LayoutUnit step)
{
if (m_cue->getWritingDirection() == VTTCue::Horizontal)
setY(y() + step);
else
setX(x() + step);
}
bool RenderVTTCue::switchDirection(bool& switched, LayoutUnit& step)
{
setX(m_fallbackPosition.x());
setY(m_fallbackPosition.y());
if (switched)
return false;
step = -step;
switched = true;
return true;
}
void RenderVTTCue::repositionCueSnapToLinesSet()
{
InlineFlowBox* firstLineBox;
LayoutUnit step;
LayoutUnit position;
if (!findFirstLineBox(firstLineBox))
return;
if (!initializeLayoutParameters(firstLineBox, step, position))
return;
bool switched;
placeBoxInDefaultPosition(position, switched);
while (isOutside() || isOverlapping()) {
if (!shouldSwitchDirection(firstLineBox, step)) {
moveBoxesByStep(step);
} else if (!switchDirection(switched, step)) {
break;
}
}
if (hasInlineDirectionBordersPaddingOrMargin()) {
IntRect containerRect = containingBlock()->absoluteBoundingBoxRect();
IntRect cueRect = absoluteBoundingBoxRect();
int topOverflow = cueRect.y() - containerRect.y();
int bottomOverflow = containerRect.y() + containerRect.height() - cueRect.y() - cueRect.height();
int adjustment = 0;
if (topOverflow < 0)
adjustment = -topOverflow;
else if (bottomOverflow < 0)
adjustment = bottomOverflow;
if (adjustment)
setY(y() + adjustment);
}
}
void RenderVTTCue::repositionCueSnapToLinesNotSet()
{
}
}