⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 renderflexiblebox.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/* * This file is part of the render object implementation for KHTML. * * Copyright (C) 1999 Lars Knoll (knoll@kde.org) *           (C) 1999 Antti Koivisto (koivisto@kde.org) * Copyright (C) 2003 Apple Computer, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB.  If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */#include "config.h"#include "RenderFlexibleBox.h"#include "CharacterNames.h"#include "RenderLayer.h"#include "RenderView.h"#include <wtf/StdLibExtras.h>using namespace std;namespace WebCore {class FlexBoxIterator {public:    FlexBoxIterator(RenderFlexibleBox* parent) {        box = parent;        if (box->style()->boxOrient() == HORIZONTAL && box->style()->direction() == RTL)            forward = box->style()->boxDirection() != BNORMAL;        else            forward = box->style()->boxDirection() == BNORMAL;        lastOrdinal = 1;         if (!forward) {            // No choice, since we're going backwards, we have to find out the highest ordinal up front.            RenderBox* child = box->firstChildBox();            while (child) {                if (child->style()->boxOrdinalGroup() > lastOrdinal)                    lastOrdinal = child->style()->boxOrdinalGroup();                child = child->nextSiblingBox();            }        }                reset();    }    void reset() {        current = 0;        currentOrdinal = forward ? 0 : lastOrdinal+1;    }    RenderBox* first() {        reset();        return next();    }        RenderBox* next() {        do {             if (!current) {                if (forward) {                    currentOrdinal++;                     if (currentOrdinal > lastOrdinal)                        return 0;                    current = box->firstChildBox();                } else {                    currentOrdinal--;                    if (currentOrdinal == 0)                        return 0;                    current = box->lastChildBox();                }            }            else                current = forward ? current->nextSiblingBox() : current->previousSiblingBox();            if (current && current->style()->boxOrdinalGroup() > lastOrdinal)                lastOrdinal = current->style()->boxOrdinalGroup();        } while (!current || current->style()->boxOrdinalGroup() != currentOrdinal ||                 current->style()->visibility() == COLLAPSE);        return current;    }private:    RenderFlexibleBox* box;    RenderBox* current;    bool forward;    unsigned int currentOrdinal;    unsigned int lastOrdinal;};    RenderFlexibleBox::RenderFlexibleBox(Node* node):RenderBlock(node){    setChildrenInline(false); // All of our children must be block-level    m_flexingChildren = m_stretchingChildren = false;}RenderFlexibleBox::~RenderFlexibleBox(){}void RenderFlexibleBox::calcHorizontalPrefWidths(){    for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {        // positioned children don't affect the minmaxwidth        if (child->isPositioned() || child->style()->visibility() == COLLAPSE)            continue;        // A margin basically has three types: fixed, percentage, and auto (variable).        // Auto and percentage margins simply become 0 when computing min/max width.        // Fixed margins can be added in as is.        Length ml = child->style()->marginLeft();        Length mr = child->style()->marginRight();        int margin = 0, marginLeft = 0, marginRight = 0;        if (ml.isFixed())            marginLeft += ml.value();        if (mr.isFixed())            marginRight += mr.value();        margin = marginLeft + marginRight;        m_minPrefWidth += child->minPrefWidth() + margin;        m_maxPrefWidth += child->maxPrefWidth() + margin;    }    }void RenderFlexibleBox::calcVerticalPrefWidths(){    for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {        // Positioned children and collapsed children don't affect the min/max width        if (child->isPositioned() || child->style()->visibility() == COLLAPSE)            continue;        // A margin basically has three types: fixed, percentage, and auto (variable).        // Auto/percentage margins simply become 0 when computing min/max width.        // Fixed margins can be added in as is.        Length ml = child->style()->marginLeft();        Length mr = child->style()->marginRight();        int margin = 0;        if (ml.isFixed())            margin += ml.value();        if (mr.isFixed())            margin += mr.value();                int w = child->minPrefWidth() + margin;        m_minPrefWidth = max(w, m_minPrefWidth);                w = child->maxPrefWidth() + margin;        m_maxPrefWidth = max(w, m_maxPrefWidth);    }    }void RenderFlexibleBox::calcPrefWidths(){    ASSERT(prefWidthsDirty());    if (style()->width().isFixed() && style()->width().value() > 0)        m_minPrefWidth = m_maxPrefWidth = calcContentBoxWidth(style()->width().value());    else {        m_minPrefWidth = m_maxPrefWidth = 0;        if (hasMultipleLines() || isVertical())            calcVerticalPrefWidths();        else            calcHorizontalPrefWidths();        m_maxPrefWidth = max(m_minPrefWidth, m_maxPrefWidth);    }    if (style()->minWidth().isFixed() && style()->minWidth().value() > 0) {        m_maxPrefWidth = max(m_maxPrefWidth, calcContentBoxWidth(style()->minWidth().value()));        m_minPrefWidth = max(m_minPrefWidth, calcContentBoxWidth(style()->minWidth().value()));    }        if (style()->maxWidth().isFixed() && style()->maxWidth().value() != undefinedLength) {        m_maxPrefWidth = min(m_maxPrefWidth, calcContentBoxWidth(style()->maxWidth().value()));        m_minPrefWidth = min(m_minPrefWidth, calcContentBoxWidth(style()->maxWidth().value()));    }    int toAdd = borderLeft() + borderRight() + paddingLeft() + paddingRight();    m_minPrefWidth += toAdd;    m_maxPrefWidth += toAdd;    setPrefWidthsDirty(false);}void RenderFlexibleBox::layoutBlock(bool relayoutChildren){    ASSERT(needsLayout());    if (!relayoutChildren && layoutOnlyPositionedObjects())        return;    LayoutRepainter repainter(*this, checkForRepaintDuringLayout());    LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()), hasTransform() || hasReflection());    int previousWidth = width();    int previousHeight = height();        calcWidth();    calcHeight();    m_overflowWidth = width();    if (previousWidth != width() || previousHeight != height() ||        (parent()->isFlexibleBox() && parent()->style()->boxOrient() == HORIZONTAL &&         parent()->style()->boxAlign() == BSTRETCH))        relayoutChildren = true;    setHeight(0);    m_overflowHeight = 0;    m_flexingChildren = m_stretchingChildren = false;    initMaxMarginValues();    // For overflow:scroll blocks, ensure we have both scrollbars in place always.    if (scrollsOverflow()) {        if (style()->overflowX() == OSCROLL)            layer()->setHasHorizontalScrollbar(true);        if (style()->overflowY() == OSCROLL)            layer()->setHasVerticalScrollbar(true);    }    if (isHorizontal())        layoutHorizontalBox(relayoutChildren);    else        layoutVerticalBox(relayoutChildren);    int oldHeight = height();    calcHeight();    if (oldHeight != height()) {        // If the block got expanded in size, then increase our overflowheight to match.        if (m_overflowHeight > height())            m_overflowHeight -= (borderBottom() + paddingBottom() + horizontalScrollbarHeight());        if (m_overflowHeight < height())            m_overflowHeight = height();    }    if (previousHeight != height())        relayoutChildren = true;    layoutPositionedObjects(relayoutChildren || isRoot());    if (!isFloatingOrPositioned() && height() == 0) {        // We are a block with no border and padding and a computed height        // of 0.  The CSS spec states that zero-height blocks collapse their margins        // together.        // When blocks are self-collapsing, we just use the top margin values and set the        // bottom margin max values to 0.  This way we don't factor in the values        // twice when we collapse with our previous vertically adjacent and        // following vertically adjacent blocks.        int pos = maxTopPosMargin();        int neg = maxTopNegMargin();        if (maxBottomPosMargin() > pos)            pos = maxBottomPosMargin();        if (maxBottomNegMargin() > neg)            neg = maxBottomNegMargin();        setMaxTopMargins(pos, neg);        setMaxBottomMargins(0, 0);    }    // Always ensure our overflow width is at least as large as our width.    if (m_overflowWidth < width())        m_overflowWidth = width();    if (!hasOverflowClip()) {        for (ShadowData* boxShadow = style()->boxShadow(); boxShadow; boxShadow = boxShadow->next) {            m_overflowLeft = min(m_overflowLeft, boxShadow->x - boxShadow->blur);            m_overflowWidth = max(m_overflowWidth, width() + boxShadow->x + boxShadow->blur);            m_overflowTop = min(m_overflowTop, boxShadow->y - boxShadow->blur);            m_overflowHeight = max(m_overflowHeight, height() + boxShadow->y + boxShadow->blur);        }                if (hasReflection()) {            IntRect reflection(reflectionBox());            m_overflowTop = min(m_overflowTop, reflection.y());            m_overflowHeight = max(m_overflowHeight, reflection.bottom());            m_overflowLeft = min(m_overflowLeft, reflection.x());

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -