Example #1
0
void RenderMathMLSquareRoot::layout()
{
    int maxHeight = 0;
    
    RenderObject* current = firstChild();
    while (current) {
        if (current->isBoxModelObject()) {
            RenderBoxModelObject* box = toRenderBoxModelObject(current);
            
            if (box->offsetHeight() > maxHeight)
                maxHeight = box->offsetHeight();
            
            box->style()->setVerticalAlign(BASELINE);
        }
        current = current->nextSibling();
    }
    
    if (!maxHeight)
        maxHeight = style()->fontSize();

    
    if (maxHeight > static_cast<int>(gThresholdBaseHeight * style()->fontSize()))
        style()->setPaddingBottom(Length(static_cast<int>(gRootBottomPadding * style()->fontSize()), Fixed));

    
    RenderBlock::layout();
}
Example #2
0
void RenderMathMLRow::layout() 
{
    RenderBlock::layout();
    
    LayoutUnit maxHeight = 0;
    int childCount = 0;
    int operatorCount = 0;

    // Calculate the non-operator max height of the row.
    LayoutUnit operatorHeight = 0;
    for (RenderObject* current = firstChild(); current; current = current->nextSibling()) {
        childCount++;
        if (current->isRenderMathMLBlock()) {
            RenderMathMLBlock* block = toRenderMathMLBlock(current);
            // Check to see if the non-operator block has a greater height.
            if (!block->hasBase() && !block->isRenderMathMLOperator() && block->offsetHeight() > maxHeight)
                maxHeight = block->offsetHeight();
            if (block->hasBase() && block->nonOperatorHeight() > maxHeight) 
                maxHeight = block->nonOperatorHeight();
            // If the block is an operator, capture the maximum height and increment the count.
            if (block->isRenderMathMLOperator()) {
                if (block->offsetHeight() > operatorHeight)
                    operatorHeight = block->offsetHeight();
                operatorCount++;
            }
        } else if (current->isBoxModelObject()) {
            RenderBoxModelObject* box = toRenderBoxModelObject(current);
            // Check to see if this box has a larger height.
            if (box->offsetHeight() > maxHeight)
                maxHeight = box->offsetHeight();
        }
    }
    
    if (childCount > 0 && childCount == operatorCount) {
        // We have only operators and so set the max height to the operator height.
        maxHeight = operatorHeight;
    }
    
    // Stretch everything to the same height (blocks can ignore the request).
    if (maxHeight > 0) {
        bool didStretch = false;
        for (RenderObject* current = firstChild(); current; current = current->nextSibling()) {
            if (current->isRenderMathMLBlock()) {
                RenderMathMLBlock* block = toRenderMathMLBlock(current);
                block->stretchToHeight(maxHeight);
                didStretch = true;
            }
        }
        if (didStretch) {
            setNeedsLayout(true);
            setPreferredLogicalWidthsDirty(true, false);
            RenderBlock::layout();
        }
    }
    
}    
int RenderMathMLSubSup::baselinePosition(bool firstLine, bool isRootLineBox) const
{
    RenderObject* base = firstChild();
    if (!base) 
        return offsetHeight();
    base = base->firstChild();
    if (!base) 
        return offsetHeight();
    
    int baseline = offsetHeight();
    
    switch (m_kind) {
    case SubSup:
        if (m_scripts) {
            int topAdjust = 0;
            if (base->isBoxModelObject()) {
                RenderBoxModelObject* box = toRenderBoxModelObject(base);
                topAdjust = (m_scripts->offsetHeight() - box->offsetHeight()) / 2;
            }
            return topAdjust + (base ? base->baselinePosition(firstLine, isRootLineBox) : 0) + 4;
        }
        break;
    case Sup:
        if (base) {
            baseline = base->baselinePosition(firstLine, isRootLineBox) + 4;
            // FIXME: The extra amount of the superscript ascending above the base's box
            // isn't taken into account.  This should be calculated in a more reliable
            // way.
            RenderObject* sup = base->nextSibling();
            if (sup && sup->isBoxModelObject()) {
                RenderBoxModelObject* box = toRenderBoxModelObject(sup);
                // we'll take half of the sup's box height into account in the baseline
                baseline += static_cast<int>(box->offsetHeight() * 0.5);
            }
            baseline++;
        }
        break;
    case Sub:
        if (base) 
            baseline = base->baselinePosition(true) + 4;
    }
    
    return baseline;
    
}
Example #4
0
inline int getOffsetHeight(RenderObject* obj) 
{
    if (obj->isBoxModelObject()) {
        RenderBoxModelObject* box = toRenderBoxModelObject(obj);
        return box->offsetHeight();
    }
   
    return 0;
}
void RenderMathMLRoot::layout()
{
    RenderBlock::layout();

    if (!firstChild() || !lastChild())
        return;

    int maxHeight = toRenderBoxModelObject(lastChild())->offsetHeight();
    
    RenderObject* current = lastChild()->firstChild();
    if (current)
        current->style()->setVerticalAlign(BASELINE);
    
    if (!maxHeight)
        maxHeight = style()->fontSize();
    
    // Base height above which the shape of the root changes
    int thresholdHeight = static_cast<int>(gThresholdBaseHeight * style()->fontSize());
    int topStartShift = 0;
    
    if (maxHeight > thresholdHeight && thresholdHeight) {
        float shift = (maxHeight - thresholdHeight) / static_cast<float>(thresholdHeight);
        if (shift > 1.)
            shift = 1.0f;
        int frontWidth = static_cast<int>(style()->fontSize() * gRadicalWidth);
        topStartShift = static_cast<int>(gRadicalBottomPointXPos * frontWidth * shift);
        
        style()->setPaddingBottom(Length(static_cast<int>(gRootBottomPadding * style()->fontSize()), Fixed));
    }
    
    // Positioning of the index
    RenderObject* possibleIndex = firstChild()->firstChild();
    while (possibleIndex && !possibleIndex->isBoxModelObject())
        possibleIndex = possibleIndex->nextSibling();
    RenderBoxModelObject* indexBox = toRenderBoxModelObject(possibleIndex);
    if (!indexBox)
        return;
    
    int indexShift = indexBox->offsetWidth() + topStartShift;
    int radicalHeight = static_cast<int>((1 - gRadicalTopLeftPointYPos) * maxHeight);
    int rootMarginTop = radicalHeight + style()->paddingBottom().value() + indexBox->offsetHeight() - (maxHeight + static_cast<int>(gRootPadding * style()->fontSize()));
    
    style()->setPaddingLeft(Length(indexShift, Fixed));
    if (rootMarginTop > 0)
        style()->setPaddingTop(Length(rootMarginTop + static_cast<int>(gRootPadding * style()->fontSize()), Fixed));
    
    setNeedsLayout(true);
    setPreferredLogicalWidthsDirty(true, false);
    RenderBlock::layout();

    indexBox->style()->setBottom(Length(radicalHeight + style()->paddingBottom().value(), Fixed));

    // Now that we've potentially changed its position, we need layout the index again.
    indexBox->setNeedsLayout(true);
    indexBox->layout();
}
Example #6
0
int RenderMathMLRow::nonOperatorHeight() const
{
    int maxHeight = 0;
    for (RenderObject* current = firstChild(); current; current = current->nextSibling()) {
        if (current->isRenderMathMLBlock()) {
            RenderMathMLBlock* block = toRenderMathMLBlock(current);
            int blockHeight = block->nonOperatorHeight();
            // Check to see if this box has a larger height
            if (blockHeight > maxHeight)
                maxHeight = blockHeight;
        } else if (current->isBoxModelObject()) {
            RenderBoxModelObject* box = toRenderBoxModelObject(current);
            // Check to see if this box has a larger height
            if (box->offsetHeight() > maxHeight)
                maxHeight = box->offsetHeight();
        }
        
    }
    return maxHeight;
}
void RenderMathMLRoot::paint(PaintInfo& info, int tx, int ty)
{
    RenderMathMLBlock::paint(info , tx , ty);
    
    if (info.context->paintingDisabled())
        return;

    if (!firstChild() || !lastChild())
        return;

    tx += x();
    ty += y();
    
    RenderBoxModelObject* indexBox = toRenderBoxModelObject(lastChild());
    
    int maxHeight = indexBox->offsetHeight();
    // default to the font size in pixels if we're empty
    if (!maxHeight)
        maxHeight = style()->fontSize();
    int width = indexBox->offsetWidth();
    
    int indexWidth = 0;
    RenderObject* current = firstChild();
    while (current != lastChild()) {
        if (current->isBoxModelObject()) {
            RenderBoxModelObject* box = toRenderBoxModelObject(current);
            indexWidth += box->offsetWidth();
        }
        current = current->nextSibling();
    }
    
    int frontWidth = static_cast<int>(style()->fontSize() * gRadicalWidth);
    int topStartShift = 0;
    // Base height above which the shape of the root changes
    int thresholdHeight = static_cast<int>(gThresholdBaseHeight * style()->fontSize());
    
    if (maxHeight > thresholdHeight && thresholdHeight) {
        float shift = (maxHeight - thresholdHeight) / static_cast<float>(thresholdHeight);
        if (shift > 1.)
            shift = 1.0f;
        topStartShift = static_cast<int>(gRadicalBottomPointXPos * frontWidth * shift);
    }
    
    width += topStartShift;
    
    int rootPad = static_cast<int>(gRootPadding * style()->fontSize());
    int start = tx + indexWidth + gRadicalLeftMargin + style()->paddingLeft().value() - rootPad;
    ty += style()->paddingTop().value() - rootPad;
    
    FloatPoint topStart(start - topStartShift, ty);
    FloatPoint bottomLeft(start - gRadicalBottomPointXPos * frontWidth , ty + maxHeight + gRadicalBasePad);
    FloatPoint topLeft(start - gRadicalTopLeftPointXPos * frontWidth , ty + gRadicalTopLeftPointYPos * maxHeight);
    FloatPoint leftEnd(start - frontWidth , topLeft.y() + gRadicalLeftEndYShift * style()->fontSize());
    
    info.context->save();
    
    info.context->setStrokeThickness(gRadicalLineThickness * style()->fontSize());
    info.context->setStrokeStyle(SolidStroke);
    info.context->setStrokeColor(style()->visitedDependentColor(CSSPropertyColor), ColorSpaceDeviceRGB);
    info.context->setLineJoin(MiterJoin);
    info.context->setMiterLimit(style()->fontSize());
    
    Path root;
    
    root.moveTo(FloatPoint(topStart.x() + width, ty));
    // draw top
    root.addLineTo(topStart);
    // draw from top left corner to bottom point of radical
    root.addLineTo(bottomLeft);
    // draw from bottom point to top of left part of radical base "pocket"
    root.addLineTo(topLeft);
    // draw to end
    root.addLineTo(leftEnd);
    
    info.context->strokePath(root);
    
    info.context->save();
    
    // Build a mask to draw the thick part of the root.
    Path mask;
    
    mask.moveTo(topStart);
    mask.addLineTo(bottomLeft);
    mask.addLineTo(topLeft);
    mask.addLineTo(FloatPoint(2 * topLeft.x() - leftEnd.x(), 2 * topLeft.y() - leftEnd.y()));
    
    info.context->clip(mask);
    
    // Draw the thick part of the root.
    info.context->setStrokeThickness(gRadicalThickLineThickness * style()->fontSize());
    info.context->setLineCap(SquareCap);
    
    Path line;
    line.moveTo(bottomLeft);
    line.addLineTo(topLeft);

    info.context->strokePath(line);
    
    info.context->restore();
    
    info.context->restore();

}
void RenderMathMLRow::layout() 
{
    RenderBlock::layout();
    
    // Calculate the maximum height of the row without the operators.
    int maxHeight = nonOperatorHeight();
    
    // Set the maximum height of the row for intermediate layouts.
    style()->setHeight(Length(maxHeight, Fixed));

    // Notify contained operators they may need to re-layout their stretched operators.
    // We need to keep track of the number of children and operators because a row of
    // operators needs some special handling.
    int childCount = 0;
    int operatorCount = 0;
    for (RenderObject* current = firstChild(); current; current = current->nextSibling()) {
        childCount++;
        if (current->isRenderMathMLBlock()) {
            RenderMathMLBlock* block = toRenderMathMLBlock(current);
            block->stretchToHeight(maxHeight);
            if (block->isRenderMathMLOperator()) 
                operatorCount++;
        }
    }
    
    // Layout the non-operators which have just been stretched.
    setNeedsLayoutAndPrefWidthsRecalc();
    markContainingBlocksForLayout();
    RenderBlock::layout();

    // Make a second pass with the real height of the operators.
    int operatorHeight = 0;
    for (RenderObject* current = firstChild(); current; current = current->nextSibling()) {
        if (current->isRenderMathMLBlock()) {
            RenderMathMLBlock* block = toRenderMathMLBlock(current);
            if (!block->hasBase() && !block->isRenderMathMLOperator()) {
                // Check to see if this box has a larger height.
                if (block->offsetHeight() > maxHeight)
                    maxHeight = block->offsetHeight();
            }
            if (block->isRenderMathMLOperator())
                if (block->offsetHeight() > operatorHeight)
                    operatorHeight = block->offsetHeight();
        } else if (current->isBoxModelObject()) {
            RenderBoxModelObject* box = toRenderBoxModelObject(current);
            // Check to see if this box has a larger height.
            if (box->offsetHeight() > maxHeight)
                maxHeight = box->offsetHeight();
        }
    }
    
    if (childCount > 0 && childCount == operatorCount) {
        // We have only operators and so set the max height to the operator height.
        maxHeight = operatorHeight;
    }
    
    int stretchHeight = maxHeight;
    
    // Stretch the operators again and re-calculate the row height.
    for (RenderObject* current = firstChild(); current; current = current->nextSibling()) {
        if (current->isRenderMathMLBlock()) {
            RenderMathMLBlock* block = toRenderMathMLBlock(current);
            if (block->isRenderMathMLOperator()) {
                RenderMathMLOperator* mathop = toRenderMathMLOperator(block);
                mathop->stretchToHeight(stretchHeight);
            } else {
                block->stretchToHeight(stretchHeight);
                RenderBoxModelObject* box = toRenderBoxModelObject(current);
                // Check to see if this box has a larger height
                if (box->offsetHeight() > maxHeight)
                    maxHeight = box->offsetHeight();
            }
        } else if (current->isBoxModelObject()) {
            RenderBoxModelObject* box = toRenderBoxModelObject(current);
            // Check to see if this box has a larger height
            if (box->offsetHeight() > maxHeight)
                maxHeight = box->offsetHeight();
        }
    }

    // Set the maximum height of the row based on the calculations.
    style()->setHeight(Length(maxHeight, Fixed));
    
    // Do the final layout by calling our parent's layout again.
    setNeedsLayoutAndPrefWidthsRecalc();
    markContainingBlocksForLayout();
    RenderBlock::layout();
}