blob: 5a10fc1d1ffca6344e0400e59d6a5007a15bb84e [file] [log] [blame]
/*
* Copyright (C) 2018 Apple Inc. 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 APPLE INC. AND ITS 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 APPLE INC. OR ITS 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
#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
#include "LayoutBox.h"
#include "LayoutInlineBox.h"
#include "LayoutLineBreakBox.h"
namespace WebCore {
namespace Layout {
class InlineItem {
public:
InlineItem(const Box& layoutBox);
enum class Type { Text, HardLineBreak, InlineBox, Float };
Type type() const;
const Box& layoutBox() const { return m_layoutBox; }
const RenderStyle& style() const { return m_layoutBox.style(); }
String textContent() const;
// DetachingRule indicates whether the inline element needs to be wrapped in a dediceted run or break from previous/next runs.
// <span>start</span><span style="position: relative;"> middle </span><span>end</span>
// input to line breaking -> <start middle end>
// output of line breaking (considering infinite constraint) -> <start middle end>
// due to the in-flow positioning, the final runs are: <start>< middle ><end>
// "start" -> n/a
// " middle " -> BreakAtStart and BreakAtEnd
// "end" -> n/a
//
// <span>parent </span><span style="padding: 10px;">start<span> middle </span>end</span><span> parent</span>
// input to line breaking -> <parent start middle end parent>
// output of line breaking (considering infinite constraint) -> <parent start middle end parent>
// due to padding, final runs -> <parent><start middle end><parent>
// "parent" -> n/a
// "start" -> BreakAtStart
// " middle " -> n/a
// "end" -> BreakAtEnd
// "parent" -> n/a
enum class DetachingRule {
BreakAtStart = 1 << 0,
BreakAtEnd = 1 << 1
};
void addDetachingRule(OptionSet<DetachingRule> detachingRule) { m_detachingRules.add(detachingRule); }
OptionSet<DetachingRule> detachingRules() const { return m_detachingRules; }
// Non-breakable start/end marks margin/padding/border space (even when it does not directly come from the associated layout box)
// <span style="padding: 5px"><span>nested content with padding parent</span</span>
// <nested content with padding parent> inline run has 5px non-breakable start/end.
LayoutUnit nonBreakableStart() const { return m_nonBreakableStart; }
LayoutUnit nonBreakableEnd() const { return m_nonBreakableEnd; }
void addNonBreakableStart(LayoutUnit value) { m_nonBreakableStart += value; }
void addNonBreakableEnd(LayoutUnit value) { m_nonBreakableEnd += value; }
private:
const Box& m_layoutBox;
OptionSet<DetachingRule> m_detachingRules;
LayoutUnit m_nonBreakableStart;
LayoutUnit m_nonBreakableEnd;
};
using InlineContent = ListHashSet<std::unique_ptr<InlineItem>>;
inline InlineItem::InlineItem(const Box& layoutBox)
: m_layoutBox(layoutBox)
{
}
inline InlineItem::Type InlineItem::type() const
{
if (is<InlineBox>(m_layoutBox) && downcast<InlineBox>(m_layoutBox).hasTextContent())
return Type::Text;
if (is<LineBreakBox>(m_layoutBox))
return Type::HardLineBreak;
if (m_layoutBox.isFloatingPositioned())
return Type::Float;
ASSERT(m_layoutBox.isInlineLevelBox());
return Type::InlineBox;
}
inline String InlineItem::textContent() const
{
if (type() != Type::Text)
return { };
return downcast<InlineBox>(m_layoutBox).textContent();
}
}
}
#endif