예제 #1
0
RenderObject* RenderObjectChildList::beforePseudoElementRenderer(const RenderObject* owner) const
{
    // An anonymous (generated) inline run-in that has PseudoId BEFORE must come from a grandparent.
    // Therefore we should skip these generated run-ins when checking our immediate children.
    // If we don't find our :before child immediately, then we should check if we own a
    // generated inline run-in in the next level of children.
    RenderObject* first = const_cast<RenderObject*>(owner);
    do {
        first = first->firstChild();
        // Skip list markers and generated run-ins.
        while (first && (first->isListMarker() || (first->isRenderInline() && first->isRunIn())))
            first = first->nextInPreOrderAfterChildren(owner);
    } while (first && first->isAnonymous() && first->style()->styleType() == NOPSEUDO);

    if (!first)
        return 0;

    if (first->isBeforeContent())
        return first;

    // Check for a possible generated run-in, using run-in positioning rules.
    first = owner->firstChild();
    if (!first->isRenderBlock())
        return 0;
    
    first = first->firstChild();
    // We still need to skip any list markers that could exist before the run-in.
    while (first && first->isListMarker())
        first = first->nextSibling();
    if (first && first->isBeforeContent() && first->isRenderInline() && first->isRunIn())
        return first;
    
    return 0;
}
예제 #2
0
LayoutUnit RenderMathMLUnderOver::baselinePosition(FontBaseline, bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
{
    RenderObject* current = firstChild();
    if (!current || linePositionMode == PositionOfInteriorLineBoxes)
        return RenderBlock::baselinePosition(AlphabeticBaseline, firstLine, direction, linePositionMode);

    LayoutUnit baseline = 0;
    switch (m_kind) {
    case UnderOver:
    case Over:
        baseline += getOffsetHeight(current);
        current = current->nextSibling();
        if (current) {
            // actual base
            RenderObject* base = current->firstChild();
            if (!base || !base->isBoxModelObject())
                break;
            baseline += toRenderBoxModelObject(base)->baselinePosition(AlphabeticBaseline, firstLine, HorizontalLine, linePositionMode);
            // added the negative top margin
            baseline += current->style()->marginTop().value();
        }
        break;
    case Under:
        RenderObject* base = current->firstChild();
        if (base && base->isBoxModelObject())
            baseline += toRenderBoxModelObject(base)->baselinePosition(AlphabeticBaseline, true, HorizontalLine);
    }

    return baseline;
}
예제 #3
0
void RenderMathMLSubSup::layout()
{
    RenderBlock::layout();
    
    if (m_kind != SubSup || !m_scripts)
        return;
    RenderBoxModelObject* base = this->base();
    RenderObject* superscriptWrapper = m_scripts->firstChild();
    RenderObject* subscriptWrapper = m_scripts->lastChild();
    if (!base || !superscriptWrapper || !subscriptWrapper || superscriptWrapper == subscriptWrapper)
        return;
    ASSERT(superscriptWrapper->isRenderMathMLBlock());
    ASSERT(subscriptWrapper->isRenderMathMLBlock());
    RenderObject* superscript = superscriptWrapper->firstChild();
    RenderObject* subscript = subscriptWrapper->firstChild();
    if (!superscript || !subscript)
        return;
    
    LineDirectionMode lineDirection = style()->isHorizontalWritingMode() ? HorizontalLine : VerticalLine;
    LayoutUnit baseBaseline = base->baselinePosition(AlphabeticBaseline, true, lineDirection);
    LayoutUnit baseExtendUnderBaseline = getBoxModelObjectHeight(base) - baseBaseline;
    LayoutUnit axis = style()->fontMetrics().xHeight() / 2;
    LayoutUnit superscriptHeight = getBoxModelObjectHeight(superscript);
    LayoutUnit subscriptHeight = getBoxModelObjectHeight(subscript);
    
    // Our layout rules are: Don't let the superscript go below the "axis" (half x-height above the
    // baseline), or the subscript above the axis. Also, don't let the superscript's top edge be
    // below the base's top edge, or the subscript's bottom edge above the base's bottom edge.
    //
    // FIXME: Check any subscriptshift or superscriptshift attributes, and maybe use more sophisticated
    // heuristics from TeX or elsewhere. See https://bugs.webkit.org/show_bug.cgi?id=79274#c5.
    
    // Above we did scriptsStyle->setVerticalAlign(TOP) for mscripts' style, so the superscript's
    // top edge will equal the top edge of the base's padding.
    LayoutUnit basePaddingTop = superscriptHeight + axis - baseBaseline;
    // If basePaddingTop is positive, it's indeed the base's padding-top that we need. If it's negative,
    // then we should instead use its absolute value to pad the bottom of the superscript, to get the
    // superscript's bottom edge down to the axis. First we compute how much more we need to shift the
    // subscript down, once its top edge is at the axis.
    LayoutUnit superPaddingBottom = max<LayoutUnit>(baseExtendUnderBaseline + axis - subscriptHeight, 0);
    if (basePaddingTop < 0) {
        superPaddingBottom += -basePaddingTop;
        basePaddingTop = 0;
    }
    
    setChildNeedsLayout(true, false);
    
    RenderObject* baseWrapper = firstChild();
    baseWrapper->style()->setPaddingTop(Length(basePaddingTop, Fixed));
    baseWrapper->setNeedsLayout(true, false);
    
    superscriptWrapper->style()->setPaddingBottom(Length(superPaddingBottom, Fixed));
    superscriptWrapper->setNeedsLayout(true, false);
    m_scripts->setNeedsLayout(true, false);
    
    RenderBlock::layout();
}
예제 #4
0
static RenderObject* beforeAfterContainer(RenderObject* container, PseudoId type)
{
    if (type == BEFORE) {
        // An anonymous (generated) inline run-in that has PseudoId BEFORE must come from a grandparent.
        // Therefore we should skip these generated run-ins when checking our immediate children.
        // If we don't find our :before child immediately, then we should check if we own a
        // generated inline run-in in the next level of children.
        RenderObject* first = container;
        do {
            // Skip list markers and generated run-ins
            first = first->firstChild();
            while (first && (first->isListMarker() || (first->isRenderInline() && first->isRunIn() && first->isAnonymous())))
                first = first->nextSibling();
        } while (first && first->isAnonymous() && first->style()->styleType() == NOPSEUDO);

        if (!first)
            return 0;

        if (first->style()->styleType() == type)
            return first;

        // Check for a possible generated run-in, using run-in positioning rules.
        // Skip inlines and floating / positioned blocks, and place as the first child.
        first = container->firstChild();
        if (!first->isRenderBlock())
            return 0;
        while (first && first->isFloatingOrPositioned())
            first = first->nextSibling();
        if (first) {
            first = first->firstChild();
            // We still need to skip any list markers that could exist before the run-in.
            while (first && first->isListMarker())
                first = first->nextSibling();
            if (first && first->style()->styleType() == type && first->isRenderInline() && first->isRunIn() && first->isAnonymous())
                return first;
        }
        return 0;
    }

    if (type == AFTER) {
        RenderObject* last = container;
        do {
            last = last->lastChild();
        } while (last && last->isAnonymous() && last->style()->styleType() == NOPSEUDO && !last->isListMarker());
        if (last && last->style()->styleType() != type)
            return 0;
        return last;
    }

    ASSERT_NOT_REACHED();
    return 0;
}
int RenderMathMLUnderOver::nonOperatorHeight() const 
{
    int nonOperators = 0;
    for (RenderObject* current = firstChild(); current; current = current->nextSibling()) {
        if (current->firstChild() && current->firstChild()->isRenderMathMLBlock()) {
            RenderMathMLBlock* block = toRenderMathMLBlock(current->firstChild());
            if (!block->isRenderMathMLOperator()) 
                nonOperators += getOffsetHeight(current);
        } else
            nonOperators += getOffsetHeight(current);
    }
    return nonOperators;
}
static void write(QTextStream &ts, const RenderObject &o, int indent = 0)
{
    writeIndent(ts, indent);
    
    ts << o << "\n";
    
    if (o.isText() && !o.isBR()) {
        const RenderText &text = static_cast<const RenderText &>(o);
        for (InlineTextBox* box = text.firstTextBox(); box; box = box->nextTextBox()) {
            writeIndent(ts, indent+1);
            writeTextRun(ts, text, *box);
        }
    }

    for (RenderObject *child = o.firstChild(); child; child = child->nextSibling()) {
        if (child->layer()) {
            continue;
        }
        write(ts, *child, indent + 1);
    }
    
    if (o.isWidget()) {
        QWidget *widget = static_cast<const RenderWidget &>(o).widget();
        if (widget && widget->inherits("KHTMLView")) {
            KHTMLView *view = static_cast<KHTMLView *>(widget);
            RenderObject *root = KWQ(view->part())->renderer();
            if (root) {
                view->layout();
                RenderLayer* l = root->layer();
                if (l)
                    writeLayers(ts, l, l, QRect(l->xPos(), l->yPos(), l->width(), l->height()), indent+1);
            }
        }
    }
}
VisiblePosition RenderContainer::positionForCoordinates(int _x, int _y)
{
    // no children...return this render object's element, if there is one, and offset 0
    if (!firstChild())
        return VisiblePosition(element(), 0, DOWNSTREAM);

    // look for the geometrically-closest child and pass off to that child
    int min = INT_MAX;
    RenderObject *closestRenderer = 0;
    for (RenderObject *renderer = firstChild(); renderer; renderer = renderer->nextSibling()) {
        if (!renderer->firstChild() && !renderer->isInline() && !renderer->isBlockFlow())
            continue;

        int absx, absy;
        renderer->absolutePosition(absx, absy);
        
        int top = absy + borderTop() + paddingTop();
        int bottom = top + renderer->contentHeight();
        int left = absx + borderLeft() + paddingLeft();
        int right = left + renderer->contentWidth();
        
        int cmp;
        cmp = abs(_y - top);    if (cmp < min) { closestRenderer = renderer; min = cmp; }
        cmp = abs(_y - bottom); if (cmp < min) { closestRenderer = renderer; min = cmp; }
        cmp = abs(_x - left);   if (cmp < min) { closestRenderer = renderer; min = cmp; }
        cmp = abs(_x - right);  if (cmp < min) { closestRenderer = renderer; min = cmp; }
    }
    
    if (closestRenderer)
        return closestRenderer->positionForCoordinates(_x, _y);
    
    return VisiblePosition(element(), 0, DOWNSTREAM);
}
예제 #8
0
void write(TextStream& ts, const RenderObject& o, int indent)
{
#if ENABLE(SVG)
    if (o.isRenderPath()) {
        write(ts, *toRenderPath(&o), indent);
        return;
    }
    if (o.isSVGContainer()) {
        writeSVGContainer(ts, o, indent);
        return;
    }
    if (o.isSVGRoot()) {
        write(ts, *toRenderSVGRoot(&o), indent);
        return;
    }
    if (o.isSVGText()) {
        if (!o.isText())
            writeSVGText(ts, *toRenderBlock(&o), indent);
        else
            writeSVGInlineText(ts, *toRenderText(&o), indent);
        return;
    }
    if (o.isSVGImage()) {
        writeSVGImage(ts, *toRenderImage(&o), indent);
        return;
    }
#endif

    writeIndent(ts, indent);

    ts << o << "\n";

    if (o.isText() && !o.isBR()) {
        const RenderText& text = *toRenderText(&o);
        for (InlineTextBox* box = text.firstTextBox(); box; box = box->nextTextBox()) {
            writeIndent(ts, indent + 1);
            writeTextRun(ts, text, *box);
        }
    }

    for (RenderObject* child = o.firstChild(); child; child = child->nextSibling()) {
        if (child->hasLayer())
            continue;
        write(ts, *child, indent + 1);
    }

    if (o.isWidget()) {
        Widget* widget = toRenderWidget(&o)->widget();
        if (widget && widget->isFrameView()) {
            FrameView* view = static_cast<FrameView*>(widget);
            RenderView* root = view->frame()->contentRenderer();
            if (root) {
                view->layout();
                RenderLayer* l = root->layer();
                if (l)
                    writeLayers(ts, l, l, IntRect(l->x(), l->y(), l->width(), l->height()), indent + 1);
            }
        }
    }
}
bool isEmptyTableCell(const Node* node)
{
    // Returns true IFF the passed in node is one of:
    //   .) a table cell with no children,
    //   .) a table cell with a single BR child, and which has no other child renderers, including :before and :after renderers
    //   .) the BR child of such a table cell

    // Find rendered node
    while (node && !node->renderer())
        node = node->parentNode();
    if (!node)
        return false;

    // Make sure the rendered node is a table cell or <br>.
    // If it's a <br>, then the parent node has to be a table cell.
    RenderObject* renderer = node->renderer();
    if (renderer->isBR()) {
        renderer = renderer->parent();
        if (!renderer)
            return false;
    }
    if (!renderer->isTableCell())
        return false;

    // Check that the table cell contains no child renderers except for perhaps a single <br>.
    RenderObject* childRenderer = renderer->firstChild();
    if (!childRenderer)
        return true;
    if (!childRenderer->isBR())
        return false;
    return !childRenderer->nextSibling();
}
예제 #10
0
QRect RenderCanvas::selectionRect() const
{
    RenderObject *r = m_selectionStart;
    if (!r)
        return QRect();

    QRect selectionRect = enclosingPositionedRect(r);

    while (r && r != m_selectionEnd)
    {
        RenderObject* n;
        if ( !(n = r->firstChild()) ){
            if ( !(n = r->nextSibling()) )
            {
                n = r->parent();
                while (n && !n->nextSibling())
                    n = n->parent();
                if (n)
                    n = n->nextSibling();
            }
        }
        r = n;
        if (r) {
            selectionRect = selectionRect.unite(enclosingPositionedRect(r));
        }
    }

    return selectionRect;
}
예제 #11
0
void RenderListItem::updateMarkerLocation()
{
    // Sanity check the location of our marker.
    if (m_marker) {
        RenderObject* markerPar = m_marker->parent();
        RenderObject* lineBoxParent = getParentOfFirstLineBox(this, m_marker);
        if (!lineBoxParent) {
            // If the marker is currently contained inside an anonymous box,
            // then we are the only item in that anonymous box (since no line box
            // parent was found).  It's ok to just leave the marker where it is
            // in this case.
            if (markerPar && markerPar->isAnonymousBlock())
                lineBoxParent = markerPar;
            else
                lineBoxParent = this;
        }

        if (markerPar != lineBoxParent || m_marker->preferredLogicalWidthsDirty()) {
            // Removing and adding the marker can trigger repainting in
            // containers other than ourselves, so we need to disable LayoutState.
            LayoutStateDisabler layoutStateDisabler(view());
            updateFirstLetter();
            m_marker->remove();
            if (!lineBoxParent)
                lineBoxParent = this;
            lineBoxParent->addChild(m_marker, firstNonMarkerChild(lineBoxParent));
            m_marker->updateMarginsAndContent();
            // If markerPar is an anonymous block that has lost all its children, destroy it.
            if (markerPar && markerPar->isAnonymousBlock() && !markerPar->firstChild() && !toRenderBlock(markerPar)->continuation())
                markerPar->destroy();
        }
    }
}
void  RenderMathMLSubSup::stretchToHeight(int height)
{
    RenderObject* base = firstChild();
    if (!base)
        return;
    
    if (base->isRenderMathMLBlock()) {
        RenderMathMLBlock* block = toRenderMathMLBlock(base);
        block->stretchToHeight(static_cast<int>(gSubSupStretch * height));
    }
    if (height > 0 && m_kind == SubSup && m_scripts) {
        RenderObject* script = m_scripts->firstChild();
        if (script) {
            // Calculate the script height without the container margins.
            RenderObject* top = script;
            int topHeight = getBoxModelObjectHeight(top->firstChild());
            int topAdjust = topHeight / gTopAdjustDivisor;
            top->style()->setMarginTop(Length(-topAdjust, Fixed));
            top->style()->setMarginBottom(Length(height - topHeight + topAdjust, Fixed));
            if (top->isBoxModelObject()) {
                RenderBoxModelObject* topBox = toRenderBoxModelObject(top);
                topBox->updateBoxModelInfoFromStyle();
            }
            m_scripts->setNeedsLayoutAndPrefWidthsRecalc();
            m_scripts->markContainingBlocksForLayout();
        }
    }
    updateBoxModelInfoFromStyle();
    setNeedsLayoutAndPrefWidthsRecalc();
    markContainingBlocksForLayout();
}
예제 #13
0
static RenderObject* beforeAfterContainer(RenderObject* container, PseudoId type)
{
    if (type == BEFORE) {
        RenderObject* first = container;
        do {
            // Skip list markers.
            first = first->firstChild();
            while (first && first->isListMarker())
                first = first->nextSibling();
        } while (first && first->isAnonymous() && first->style()->styleType() == NOPSEUDO);
        if (first && first->style()->styleType() != type)
            return 0;
        return first;
    }
    if (type == AFTER) {
        RenderObject* last = container;
        do {
            last = last->lastChild();
        } while (last && last->isAnonymous() && last->style()->styleType() == NOPSEUDO && !last->isListMarker());
        if (last && last->style()->styleType() != type)
            return 0;
        return last;
    }

    ASSERT_NOT_REACHED();
    return 0;
}
void RenderLayerStackingNode::rebuildZOrderLists(OwnPtr<Vector<RenderLayerStackingNode*> >& posZOrderList,
    OwnPtr<Vector<RenderLayerStackingNode*> >& negZOrderList, const RenderLayerStackingNode* nodeToForceAsStackingContainer,
    CollectLayersBehavior collectLayersBehavior)
{
    for (RenderLayer* child = layer()->firstChild(); child; child = child->nextSibling()) {
        if (!layer()->reflectionInfo() || layer()->reflectionInfo()->reflectionLayer() != child)
            child->stackingNode()->collectLayers(posZOrderList, negZOrderList, nodeToForceAsStackingContainer, collectLayersBehavior);
    }

    // Sort the two lists.
    if (posZOrderList)
        std::stable_sort(posZOrderList->begin(), posZOrderList->end(), compareZIndex);

    if (negZOrderList)
        std::stable_sort(negZOrderList->begin(), negZOrderList->end(), compareZIndex);

    // Append layers for top layer elements after normal layer collection, to ensure they are on top regardless of z-indexes.
    // The renderers of top layer elements are children of the view, sorted in top layer stacking order.
    if (layer()->isRootLayer()) {
        RenderObject* view = renderer()->view();
        for (RenderObject* child = view->firstChild(); child; child = child->nextSibling()) {
            Element* childElement = (child->node() && child->node()->isElementNode()) ? toElement(child->node()) : 0;
            if (childElement && childElement->isInTopLayer()) {
                RenderLayer* layer = toRenderLayerModelObject(child)->layer();
                // Create the buffer if it doesn't exist yet.
                if (!posZOrderList)
                    posZOrderList = adoptPtr(new Vector<RenderLayerStackingNode*>);
                posZOrderList->append(layer->stackingNode());
            }
        }
    }
}
예제 #15
0
void RenderListItem::updateMarkerLocation()
{
    // Sanity check the location of our marker.
    if (m_marker) {
        RenderObject* markerPar = m_marker->parent();
        RenderObject* lineBoxParent = getParentOfFirstLineBox(this, m_marker);
        if (!lineBoxParent) {
            // If the marker is currently contained inside an anonymous box,
            // then we are the only item in that anonymous box (since no line box
            // parent was found).  It's ok to just leave the marker where it is
            // in this case.
            if (markerPar && markerPar->isAnonymousBlock())
                lineBoxParent = markerPar;
            else
                lineBoxParent = this;
        }
        
        if (markerPar != lineBoxParent || !m_marker->minMaxKnown()) {
            m_marker->remove();
            if (!lineBoxParent)
                lineBoxParent = this;
            lineBoxParent->addChild(m_marker, lineBoxParent->firstChild());
            if (!m_marker->minMaxKnown())
                m_marker->calcMinMaxWidth();
            recalcMinMaxWidths();
        }
    }
}
예제 #16
0
void  RenderMathMLUnderOver::stretchToHeight(int height)
{

    RenderObject* base = firstChild();
    if (!base)
        return;
        
    // For over or underover, the base is the sibling of the first child
    if (m_kind != Under) 
        base = base->nextSibling();
        
    if (!base)
        return;
        
    // use the child of the row which is the actual base
    base = base->firstChild();
    
    if (base && base->isRenderMathMLBlock()) {
        RenderMathMLBlock* block = toRenderMathMLBlock(base);
        block->stretchToHeight(height);
        updateBoxModelInfoFromStyle();
        setNeedsLayoutAndPrefWidthsRecalc();
        markContainingBlocksForLayout();
    }
}
예제 #17
0
static inline bool findPreviousAndNextAttributes(RenderObject* root, RenderSVGInlineText* locateElement, SVGTextLayoutAttributes*& previous, SVGTextLayoutAttributes*& next)
{
    ASSERT(root);
    ASSERT(locateElement);
    bool stopAfterNext = false;
    RenderObject* current = root->firstChild();
    while (current) {
        if (current->isSVGInlineText()) {
            RenderSVGInlineText* text = toRenderSVGInlineText(current);
            if (locateElement != text) {
                if (stopAfterNext) {
                    next = text->layoutAttributes();
                    return true;
                }

                previous = text->layoutAttributes();
            } else {
                stopAfterNext = true;
            }
        } else if (current->isSVGInline()) {
            // Descend into text content (if possible).
            if (RenderObject* child = current->firstChild()) {
                current = child;
                continue;
            }
        }

        current = current->nextInPreOrderAfterChildren(root);
    }
    return false;
}
예제 #18
0
void RenderTableRow::addChild(RenderObject* child, RenderObject* beforeChild)
{
    // Make sure we don't append things after :after-generated content if we have it.
    if (!beforeChild)
        beforeChild = findAfterContentRenderer();

    if (!child->isTableCell()) {
        RenderObject* last = beforeChild;
        if (!last)
            last = lastChild();
        if (last && last->isAnonymous() && last->isTableCell() && !last->isBeforeOrAfterContent()) {
            if (beforeChild == last)
                beforeChild = last->firstChild();
            last->addChild(child, beforeChild);
            return;
        }

        if (beforeChild && !beforeChild->isAnonymous() && beforeChild->parent() == this) {
            RenderObject* cell = beforeChild->previousSibling();
            if (cell && cell->isTableCell()) {
                ASSERT(cell->isAnonymous());
                cell->addChild(child);
                return;
            }
        }

        // If beforeChild is inside an anonymous cell, insert into the cell.
        if (last && !last->isTableCell() && last->parent() && last->parent()->isAnonymous() && !last->parent()->isBeforeOrAfterContent()) {
            last->parent()->addChild(child, beforeChild);
            return;
        }

        RenderTableCell* cell = new (renderArena()) RenderTableCell(document() /* anonymous object */);
        RefPtr<RenderStyle> newStyle = RenderStyle::create();
        newStyle->inheritFrom(style());
        newStyle->setDisplay(TABLE_CELL);
        cell->setStyle(newStyle.release());
        addChild(cell, beforeChild);
        cell->addChild(child);
        return;
    } 
    
    // If the next renderer is actually wrapped in an anonymous table cell, we need to go up and find that.
    while (beforeChild && beforeChild->parent() != this)
        beforeChild = beforeChild->parent();

    RenderTableCell* cell = toRenderTableCell(child);

    // Generated content can result in us having a null section so make sure to null check our parent.
    if (parent())
        section()->addCell(cell, this);

    ASSERT(!beforeChild || beforeChild->isTableCell());
    RenderBox::addChild(cell, beforeChild);

    if (beforeChild || nextSibling())
        section()->setNeedsCellRecalc();
}
예제 #19
0
void AutoTableLayout::fullRecalc()
{
    percentagesDirty = true;
    hasPercent = false;
    effWidthDirty = true;

    int nEffCols = table->numEffCols();
    layoutStruct.resize( nEffCols );
    layoutStruct.fill( Layout() );
    spanCells.fill( 0 );

    RenderObject *child = table->firstChild();
    Length grpWidth;
    int cCol = 0;
    while ( child ) {
	if ( child->isTableCol() ) {
	    RenderTableCol *col = static_cast<RenderTableCol *>(child);
	    int span = col->span();
	    if ( col->firstChild() ) {
		grpWidth = col->style()->width();
	    } else {
		Length w = col->style()->width();
		if ( w.isVariable() )
		    w = grpWidth;
		if ( (w.isFixed() && w.value() == 0) ||
		     (w.isPercent() && w.value() == 0) )
		    w = Length();
		int cEffCol = table->colToEffCol( cCol );
#ifdef DEBUG_LAYOUT
		qDebug("    col element %d (eff=%d): Length=%d(%d), span=%d, effColSpan=%d",  cCol, cEffCol, w.value(), w.type(), span, table->spanOfEffCol(cEffCol ) );
#endif
		if ( !w.isVariable() && span == 1 && cEffCol < nEffCols ) {
		    if ( table->spanOfEffCol( cEffCol ) == 1 ) {
			layoutStruct[cEffCol].width = w;
                        if (w.isFixed() && layoutStruct[cEffCol].maxWidth < w.value())
                            layoutStruct[cEffCol].maxWidth = w.value();
                    }
		}
		cCol += span;
	    }
	} else {
	    break;
	}

	RenderObject *next = child->firstChild();
	if ( !next )
	    next = child->nextSibling();
	if ( !next && child->parent()->isTableCol() ) {
	    next = child->parent()->nextSibling();
	    grpWidth = Length();
	}
	child = next;
    }


    for ( int i = 0; i < nEffCols; i++ )
	recalcColumn( i );
}
예제 #20
0
Position RenderInline::positionForCoordinates(int x, int y)
{
    for (RenderObject *c = continuation(); c; c = c->continuation()) {
        if (c->isInline() || c->firstChild())
            return c->positionForCoordinates(x, y);
    }

    return RenderFlow::positionForCoordinates(x, y);
}
RenderMathMLOperator* RenderMathMLFraction::unembellishedOperator()
{
    RenderObject* numeratorWrapper = firstChild();
    if (!numeratorWrapper)
        return 0;
    RenderObject* numerator = numeratorWrapper->firstChild();
    if (!numerator || !numerator->isRenderMathMLBlock())
        return 0;
    return toRenderMathMLBlock(numerator)->unembellishedOperator();
}
예제 #22
0
RenderBoxModelObject* RenderMathMLSubSup::base() const
{
    RenderObject* baseWrapper = firstChild();
    if (!baseWrapper)
        return 0;
    RenderObject* base = baseWrapper->firstChild();
    if (!base || !base->isBoxModelObject())
        return 0;
    return toRenderBoxModelObject(base);
}
예제 #23
0
void RenderMathMLUnderOver::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
    RenderMathMLBlock::styleDidChange(diff, oldStyle);
    
    RenderObject* base = this->base();
    for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
        ASSERT(child->isAnonymous() && child->style()->refCount() == 1);
        if (child->firstChild() != base)
            child->style()->setTextAlign(CENTER);
    }
}
예제 #24
0
static RenderObject* findBeforeAfterParent(RenderObject* object)
{
    // Only table parts need to search for the :before or :after parent
    if (!(object->isTable() || object->isTableSection() || object->isTableRow()))
        return object;

    RenderObject* beforeAfterParent = object;
    while (beforeAfterParent && !(beforeAfterParent->isText() || beforeAfterParent->isImage()))
        beforeAfterParent = beforeAfterParent->firstChild();
    return beforeAfterParent;
}
예제 #25
0
RenderBoxModelObject* RenderMathMLUnderOver::base() const
{
    RenderObject* baseWrapper = firstChild();
    if ((m_kind == Over || m_kind == UnderOver) && baseWrapper)
        baseWrapper = baseWrapper->nextSibling();
    if (!baseWrapper)
        return 0;
    RenderObject* base = baseWrapper->firstChild();
    if (!base || !base->isBoxModelObject())
        return 0;
    return toRenderBoxModelObject(base);
}
예제 #26
0
void RenderTableRow::addChild(RenderObject* child, RenderObject* beforeChild)
{
    // Make sure we don't append things after :after-generated content if we have it.
    if (!beforeChild)
        beforeChild = afterPseudoElementRenderer();

    if (!child->isTableCell()) {
        RenderObject* last = beforeChild;
        if (!last)
            last = lastChild();
        if (last && last->isAnonymous() && last->isTableCell() && !last->isBeforeOrAfterContent()) {
            if (beforeChild == last)
                beforeChild = last->firstChild();
            last->addChild(child, beforeChild);
            return;
        }

        if (beforeChild && !beforeChild->isAnonymous() && beforeChild->parent() == this) {
            RenderObject* cell = beforeChild->previousSibling();
            if (cell && cell->isTableCell() && cell->isAnonymous()) {
                cell->addChild(child);
                return;
            }
        }

        // If beforeChild is inside an anonymous cell, insert into the cell.
        if (last && !last->isTableCell() && last->parent() && last->parent()->isAnonymous() && !last->parent()->isBeforeOrAfterContent()) {
            last->parent()->addChild(child, beforeChild);
            return;
        }

        RenderTableCell* cell = RenderTableCell::createAnonymousWithParentRenderer(this);
        addChild(cell, beforeChild);
        cell->addChild(child);
        return;
    } 
    
    // If the next renderer is actually wrapped in an anonymous table cell, we need to go up and find that.
    while (beforeChild && beforeChild->parent() != this)
        beforeChild = beforeChild->parent();

    RenderTableCell* cell = toRenderTableCell(child);

    // Generated content can result in us having a null section so make sure to null check our parent.
    if (parent())
        section()->addCell(cell, this);

    ASSERT(!beforeChild || beforeChild->isTableCell());
    RenderBox::addChild(cell, beforeChild);

    if (beforeChild || nextSibling())
        section()->setNeedsCellRecalc();
}
void RenderContainer::removeLeftoverAnonymousBoxes()
{
    // we have to go over all child nodes and remove anonymous boxes, that do _not_
    // have inline children to keep the tree flat
    RenderObject *child = firstChild();
    while( child ) {
	RenderObject *next = child->nextSibling();
	
	if ( child->isRenderBlock() && child->isAnonymousBlock() && !child->continuation() && !child->childrenInline() && !child->isTableCell() ) {
	    RenderObject *firstAnChild = child->firstChild();
	    RenderObject *lastAnChild = child->lastChild();
	    if ( firstAnChild ) {
		RenderObject *o = firstAnChild;
		while( o ) {
		    o->setParent( this );
		    o = o->nextSibling();
		}
		firstAnChild->setPreviousSibling( child->previousSibling() );
		lastAnChild->setNextSibling( child->nextSibling() );
		if ( child->previousSibling() )
		    child->previousSibling()->setNextSibling( firstAnChild );
		if ( child->nextSibling() )
		    child->nextSibling()->setPreviousSibling( lastAnChild );
	    } else {
		if ( child->previousSibling() )
		    child->previousSibling()->setNextSibling( child->nextSibling() );
		if ( child->nextSibling() )
		    child->nextSibling()->setPreviousSibling( child->previousSibling() );
		
	    }
	    if ( child == firstChild() )
		m_first = firstAnChild;
	    if ( child == lastChild() )
		m_last = lastAnChild;
	    child->setParent( 0 );
	    child->setPreviousSibling( 0 );
	    child->setNextSibling( 0 );
	    if ( !child->isText() ) {
		RenderContainer *c = static_cast<RenderContainer *>(child);
		c->m_first = 0;
		c->m_next = 0;
	    }
	    child->detach();
	}
	child = next;
    }
    if ( parent() )
	parent()->removeLeftoverAnonymousBoxes();
}
예제 #28
0
static RenderObject* findBeforeAfterParent(RenderObject* object)
{
    // Only table parts need to search for the :before or :after parent
    if (!(object->isTable() || object->isTableSection() || object->isTableRow()))
        return object;

    // If there is a :first-letter style applied on the :before or :after content,
    // then we want the parent of the first-letter block
    RenderObject* beforeAfterParent = object;
    while (beforeAfterParent && !(beforeAfterParent->isText() || beforeAfterParent->isImage())
        && (beforeAfterParent->style()->styleType() != FIRST_LETTER))
        beforeAfterParent = beforeAfterParent->firstChild();

    return beforeAfterParent ? beforeAfterParent->parent() : 0;
}
예제 #29
0
void RenderTableRow::addChild(RenderObject* child, RenderObject* beforeChild)
{
    if (!child->isTableCell()) {
        RenderObject* last = beforeChild;
        if (!last)
            last = lastChild();
        if (last && last->isAnonymous() && last->isTableCell() && !last->isBeforeOrAfterContent()) {
            if (beforeChild == last)
                beforeChild = last->firstChild();
            last->addChild(child, beforeChild);
            return;
        }

        if (beforeChild && !beforeChild->isAnonymous() && beforeChild->parent() == this) {
            RenderObject* cell = beforeChild->previousSibling();
            if (cell && cell->isTableCell() && cell->isAnonymous()) {
                cell->addChild(child);
                return;
            }
        }

        // If beforeChild is inside an anonymous cell, insert into the cell.
        if (last && !last->isTableCell() && last->parent() && last->parent()->isAnonymous() && !last->parent()->isBeforeOrAfterContent()) {
            last->parent()->addChild(child, beforeChild);
            return;
        }

        RenderTableCell* cell = RenderTableCell::createAnonymousWithParentRenderer(this);
        addChild(cell, beforeChild);
        cell->addChild(child);
        return;
    } 

    if (beforeChild && beforeChild->parent() != this)
        beforeChild = splitAnonymousBoxesAroundChild(beforeChild);    

    RenderTableCell* cell = toRenderTableCell(child);

    // Generated content can result in us having a null section so make sure to null check our parent.
    if (parent())
        section()->addCell(cell, this);

    ASSERT(!beforeChild || beforeChild->isTableCell());
    RenderBox::addChild(cell, beforeChild);

    if (beforeChild || nextSibling())
        section()->setNeedsCellRecalc();
}
예제 #30
0
VisiblePosition RenderInline::positionForCoordinates(int x, int y)
{
    // Translate the coords from the pre-anonymous block to the post-anonymous block.
    RenderBlock* cb = containingBlock();
    int parentBlockX = cb->xPos() + x;
    int parentBlockY = cb->yPos() + y;
    for (RenderObject* c = continuation(); c; c = c->continuation()) {
        RenderObject* contBlock = c;
        if (c->isInline())
            contBlock = c->containingBlock();
        if (c->isInline() || c->firstChild())
            return c->positionForCoordinates(parentBlockX - contBlock->xPos(), parentBlockY - contBlock->yPos());
    }

    return RenderFlow::positionForCoordinates(x, y);
}