Exemplo n.º 1
0
void LayoutAnalyzer::push(const LayoutObject& o)
{
    increment(TotalLayoutObjectsThatWereLaidOut);
    if (!o.everHadLayout())
        increment(LayoutObjectsThatHadNeverHadLayout);
    if (o.selfNeedsLayout())
        increment(LayoutObjectsThatNeedLayoutForThemselves);
    if (o.needsPositionedMovementLayout())
        increment(LayoutObjectsThatNeedPositionedMovementLayout);
    if (o.isOutOfFlowPositioned())
        increment(LayoutObjectsThatAreOutOfFlowPositioned);
    if (o.isTableCell())
        increment(LayoutObjectsThatAreTableCells);
    if (o.isFloating())
        increment(LayoutObjectsThatAreFloating);
    if (o.style()->specifiesColumns())
        increment(LayoutObjectsThatSpecifyColumns);
    if (o.hasLayer())
        increment(LayoutObjectsThatHaveALayer);
    if (o.isLayoutInline() && o.alwaysCreateLineBoxesForLayoutInline())
        increment(LayoutInlineObjectsThatAlwaysCreateLineBoxes);
    if (o.isText()) {
        const LayoutText& t = *toLayoutText(&o);
        if (t.canUseSimpleFontCodePath()) {
            increment(LayoutObjectsThatAreTextAndCanUseTheSimpleFontCodePath);
            increment(CharactersInLayoutObjectsThatAreTextAndCanUseTheSimpleFontCodePath, t.textLength());
        } else {
            increment(LayoutObjectsThatAreTextAndCanNotUseTheSimpleFontCodePath);
            increment(CharactersInLayoutObjectsThatAreTextAndCanNotUseTheSimpleFontCodePath, t.textLength());
        }
    }

    // This might be a root in a subtree layout, in which case the LayoutObject
    // has a parent but the stack is empty. If a LayoutObject subclass forgets
    // to call push() and is a root in a subtree layout, then this
    // assert would only fail if that LayoutObject instance has any children
    // that need layout and do call push().
    // LayoutBlock::layoutPositionedObjects() hoists positioned descendants.
    // LayoutBlockFlow::layoutInlineChildren() walks through inlines.
    // LayoutTableSection::layoutRows() walks through rows.
    if (!o.isPositioned()
        && !o.isTableCell()
        && !o.isSVGResourceContainer()
        && (m_stack.size() != 0)
        && !(o.parent()->childrenInline()
            && (o.isReplaced() || o.isFloating() || o.isOutOfFlowPositioned()))) {
        ASSERT(o.parent() == m_stack.peek());
    }
    m_stack.push(&o);

    // This refers to LayoutAnalyzer depth, not layout tree depth or DOM tree
    // depth. LayoutAnalyzer depth is generally closer to C++ stack recursion
    // depth. See above exceptions for when LayoutAnalyzer depth != layout tree
    // depth.
    if (m_stack.size() > m_counters[LayoutAnalyzerStackMaximumDepth])
        m_counters[LayoutAnalyzerStackMaximumDepth] = m_stack.size();

}
Exemplo n.º 2
0
static LayoutObject* getParentOfFirstLineBox(LayoutBlockFlow* curr, LayoutObject* marker)
{
    LayoutObject* firstChild = curr->firstChild();
    if (!firstChild)
        return nullptr;

    bool inQuirksMode = curr->document().inQuirksMode();
    for (LayoutObject* currChild = firstChild; currChild; currChild = currChild->nextSibling()) {
        if (currChild == marker)
            continue;

        if (currChild->isInline() && (!currChild->isLayoutInline() || curr->generatesLineBoxesForInlineChild(currChild)))
            return curr;

        if (currChild->isFloating() || currChild->isOutOfFlowPositioned())
            continue;

        if (!currChild->isLayoutBlockFlow() || (currChild->isBox() && toLayoutBox(currChild)->isWritingModeRoot()))
            break;

        if (curr->isListItem() && inQuirksMode && currChild->node()
            && (isHTMLUListElement(*currChild->node()) || isHTMLOListElement(*currChild->node())))
            break;

        LayoutObject* lineBox = getParentOfFirstLineBox(toLayoutBlockFlow(currChild), marker);
        if (lineBox)
            return lineBox;
    }

    return nullptr;
}
TracedLayoutObject::TracedLayoutObject(const LayoutObject& object)
    : m_address((unsigned long) &object)
    , m_isAnonymous(object.isAnonymous())
    , m_isPositioned(object.isOutOfFlowPositioned())
    , m_isRelPositioned(object.isRelPositioned())
    , m_isStickyPositioned(object.isStickyPositioned())
    , m_isFloating(object.isFloating())
    , m_selfNeeds(object.selfNeedsLayout())
    , m_positionedMovement(object.needsPositionedMovementLayout())
    , m_childNeeds(object.normalChildNeedsLayout())
    , m_posChildNeeds(object.posChildNeedsLayout())
    , m_isTableCell(object.isTableCell())
    , m_name(String(object.name()).isolatedCopy())
    , m_absRect(object.absoluteBoundingBoxRect())
{
    if (Node* node = object.node()) {
        m_tag = String(node->nodeName()).isolatedCopy();
        if (node->isElementNode()) {
            Element& element = toElement(*node);
            if (element.hasID())
                m_id = String(element.getIdAttribute()).isolatedCopy();
            if (element.hasClass()) {
                for (size_t i = 0; i < element.classNames().size(); ++i) {
                    m_classNames.append(
                        String(element.classNames()[i]).isolatedCopy());
                }
            }
        }
    }

    // FIXME: When the fixmes in LayoutTreeAsText::writeLayoutObject() are
    // fixed, deduplicate it with this.
    if (object.isText()) {
        m_rect = LayoutRect(toLayoutText(object).linesBoundingBox());
    } else if (object.isLayoutInline()) {
        m_rect = LayoutRect(toLayoutInline(object).linesBoundingBox());
    } else if (object.isBox()) {
        m_rect = toLayoutBox(&object)->frameRect();
    }

    if (m_isTableCell) {
        const LayoutTableCell& c = toLayoutTableCell(object);
        if (c.row() && c.row()->rowIndexWasSet() && c.hasCol()
            && (!c.row()->section() || !c.row()->section()->needsCellRecalc())) {
            m_row = c.rowIndex();
            m_col = c.col();
            m_rowSpan = c.rowSpan();
            m_colSpan = c.colSpan();
        }
    }

    for (LayoutObject* child = object.slowFirstChild(); child; child = child->nextSibling()) {
        m_children.append(adoptRef(new TracedLayoutObject(*child)));
    }
}
void LayoutAnalyzer::push(const LayoutObject& o)
{
    increment(TotalLayoutObjectsThatWereLaidOut);
    if (!o.everHadLayout())
        increment(LayoutObjectsThatHadNeverHadLayout);
    if (o.selfNeedsLayout())
        increment(LayoutObjectsThatNeedLayoutForThemselves);
    if (o.needsPositionedMovementLayout())
        increment(LayoutObjectsThatNeedPositionedMovementLayout);
    if (o.isOutOfFlowPositioned())
        increment(LayoutObjectsThatAreOutOfFlowPositioned);
    if (o.isTableCell())
        increment(LayoutObjectsThatAreTableCells);
    if (o.isFloating())
        increment(LayoutObjectsThatAreFloating);
    if (o.style()->specifiesColumns())
        increment(LayoutObjectsThatSpecifyColumns);
    if (o.hasLayer())
        increment(LayoutObjectsThatHaveALayer);
    if (o.isLayoutInline() && o.alwaysCreateLineBoxesForLayoutInline())
        increment(LayoutInlineObjectsThatAlwaysCreateLineBoxes);
    if (o.isText()) {
        const LayoutText& t = *toLayoutText(&o);
        if (t.canUseSimpleFontCodePath()) {
            increment(LayoutObjectsThatAreTextAndCanUseTheSimpleFontCodePath);
            increment(CharactersInLayoutObjectsThatAreTextAndCanUseTheSimpleFontCodePath, t.textLength());
        } else {
            increment(LayoutObjectsThatAreTextAndCanNotUseTheSimpleFontCodePath);
            increment(CharactersInLayoutObjectsThatAreTextAndCanNotUseTheSimpleFontCodePath, t.textLength());
        }
    }

    ++m_depth;

    // This refers to LayoutAnalyzer depth, which is generally closer to C++
    // stack recursion depth, not layout tree depth or DOM tree depth.
    m_counters[LayoutAnalyzerStackMaximumDepth] = max(m_counters[LayoutAnalyzerStackMaximumDepth], m_depth);
}