Example #1
0
void InlineFlowBox::adjustMaxAscentAndDescent(int& maxAscent, int& maxDescent,
                                              int maxPositionTop, int maxPositionBottom)
{
    for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) {
        // The computed lineheight needs to be extended for the
        // positioned elements
        // see khtmltests/rendering/html_align.html

        if (curr->object()->isPositioned())
            continue; // Positioned placeholders don't affect calculations.
        if (curr->yPos() == PositionTop || curr->yPos() == PositionBottom) {
            if (curr->yPos() == PositionTop) {
                if (maxAscent + maxDescent < curr->height())
                    maxDescent = curr->height() - maxAscent;
            }
            else {
                if (maxAscent + maxDescent < curr->height())
                    maxAscent = curr->height() - maxDescent;
            }

            if ( maxAscent + maxDescent >= kMax( maxPositionTop, maxPositionBottom ) )
                break;
        }

        if (curr->isInlineFlowBox())
            static_cast<InlineFlowBox*>(curr)->adjustMaxAscentAndDescent(maxAscent, maxDescent, maxPositionTop, maxPositionBottom);
    }
}
Example #2
0
void InlineFlowBox::computeLogicalBoxHeights(int& maxPositionTop, int& maxPositionBottom,
                                             int& maxAscent, int& maxDescent, bool strictMode)
{
    if (isRootInlineBox()) {
        // Examine our root box.
        setHeight(object()->lineHeight(m_firstLine));
        bool isTableCell = object()->isTableCell();
        if (isTableCell) {
            RenderTableCell* tableCell = static_cast<RenderTableCell*>(object());
            setBaseline(tableCell->RenderBlock::baselinePosition(m_firstLine));
        }
        else
            setBaseline(object()->baselinePosition(m_firstLine));
        if (hasTextChildren() || strictMode) {
            int ascent = baseline();
            int descent = height() - ascent;
            if (maxAscent < ascent)
                maxAscent = ascent;
            if (maxDescent < descent)
                maxDescent = descent;
        }
    }

    for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) {
        if (curr->object()->isPositioned())
            continue; // Positioned placeholders don't affect calculations.

        curr->setHeight(curr->object()->lineHeight(m_firstLine));
        curr->setBaseline(curr->object()->baselinePosition(m_firstLine));
        curr->setYPos(curr->object()->verticalPositionHint(m_firstLine));
        if (curr->yPos() == PositionTop) {
            if (maxPositionTop < curr->height())
                maxPositionTop = curr->height();
        }
        else if (curr->yPos() == PositionBottom) {
            if (maxPositionBottom < curr->height())
                maxPositionBottom = curr->height();
        }
        else if (curr->hasTextChildren() || strictMode) {
            int ascent = curr->baseline() - curr->yPos();
            int descent = curr->height() - ascent;
            if (maxAscent < ascent)
                maxAscent = ascent;
            if (maxDescent < descent)
                maxDescent = descent;
        }

        if (curr->isInlineFlowBox())
            static_cast<InlineFlowBox*>(curr)->computeLogicalBoxHeights(maxPositionTop, maxPositionBottom, maxAscent, maxDescent, strictMode);
    }
}
Example #3
0
FloatRect RenderSVGText::relativeBBox(bool includeStroke) const
{
    FloatRect repaintRect;

    for (InlineRunBox* runBox = firstLineBox(); runBox; runBox = runBox->nextLineBox()) {
        ASSERT(runBox->isInlineFlowBox());

        InlineFlowBox* flowBox = static_cast<InlineFlowBox*>(runBox);
        for (InlineBox* box = flowBox->firstChild(); box; box = box->nextOnLine())
            repaintRect.unite(FloatRect(box->xPos(), box->yPos(), box->width(), box->height()));
    }

    // SVG needs to include the strokeWidth(), not the textStrokeWidth().
    if (includeStroke && style()->svgStyle()->hasStroke()) {
        float strokeWidth = SVGRenderStyle::cssPrimitiveToLength(this, style()->svgStyle()->strokeWidth(), 0.0f);

#if ENABLE(SVG_FONTS)
        const Font& font = style()->font();
        if (font.primaryFont()->isSVGFont()) {
            float scale = font.unitsPerEm() > 0 ? font.size() / font.unitsPerEm() : 0.0f;

            if (scale != 0.0f)
                strokeWidth /= scale;
        }
#endif

        repaintRect.inflate(strokeWidth);
    }

    repaintRect.move(xPos(), yPos());
    return repaintRect;
}
Example #4
0
FloatRect RenderSVGText::objectBoundingBox() const
{
    FloatRect boundingBox;

    for (InlineFlowBox* flow = firstLineBox(); flow; flow = flow->nextLineBox()) {
        for (InlineBox* box = flow->firstChild(); box; box = box->nextOnLine())
            boundingBox.unite(FloatRect(box->x(), box->y(), box->width(), box->height()));
    }

    boundingBox.move(x(), y());
    return boundingBox;
}
FloatRect RenderSVGText::objectBoundingBox() const
{
    FloatRect boundingBox;

    for (InlineRunBox* runBox = firstLineBox(); runBox; runBox = runBox->nextLineBox()) {
        ASSERT(runBox->isInlineFlowBox());

        InlineFlowBox* flowBox = static_cast<InlineFlowBox*>(runBox);
        for (InlineBox* box = flowBox->firstChild(); box; box = box->nextOnLine())
            boundingBox.unite(FloatRect(box->x(), box->y(), box->width(), box->height()));
    }

    boundingBox.move(x(), y());
    return boundingBox;
}
Example #6
0
void RenderSVGText::absoluteQuads(Vector<FloatQuad>& quads)
{
    RenderSVGRoot* root = findSVGRootObject(parent());
    if (!root)
        return;
 
    // Don't use objectBoundingBox here, as it's unites the selection rects. Makes it hard
    // to spot errors, if there are any using WebInspector. Individually feed them into 'rects'.
    for (InlineFlowBox* flow = firstLineBox(); flow; flow = flow->nextLineBox()) {
        for (InlineBox* box = flow->firstChild(); box; box = box->nextOnLine()) {
            FloatRect boxRect(box->x(), box->y(), box->width(), box->height());
            // FIXME: crawling up the parent chain to map each quad is very inefficient
            // we should compute the absoluteTransform outside this loop first.
            quads.append(localToAbsoluteQuad(boxRect));
        }
    }
}
Example #7
0
FloatRect RenderSVGText::relativeBBox(bool includeStroke) const
{
    FloatRect repaintRect;

    for (InlineRunBox* runBox = firstLineBox(); runBox; runBox = runBox->nextLineBox()) {
        ASSERT(runBox->isInlineFlowBox());

        InlineFlowBox* flowBox = static_cast<InlineFlowBox*>(runBox);
        for (InlineBox* box = flowBox->firstChild(); box; box = box->nextOnLine())
            repaintRect.unite(FloatRect(box->xPos(), box->yPos(), box->width(), box->height()));
    }

    // SVG needs to include the strokeWidth(), not the textStrokeWidth().
    if (includeStroke && style()->svgStyle()->hasStroke())
        repaintRect.inflate(narrowPrecisionToFloat(KSVGPainterFactory::cssPrimitiveToLength(this, style()->svgStyle()->strokeWidth(), 0.0)));

    repaintRect.move(xPos(), yPos());
    return repaintRect;
}
void RenderSVGText::absoluteRects(Vector<IntRect>& rects, int, int)
{
    RenderSVGRoot* root = findSVGRootObject(parent());
    if (!root)
        return;
 
    // Don't use objectBoundingBox here, as it's unites the selection rects. Makes it hard
    // to spot errors, if there are any using WebInspector. Individually feed them into 'rects'.
    for (InlineRunBox* runBox = firstLineBox(); runBox; runBox = runBox->nextLineBox()) {
        ASSERT(runBox->isInlineFlowBox());

        InlineFlowBox* flowBox = static_cast<InlineFlowBox*>(runBox);
        for (InlineBox* box = flowBox->firstChild(); box; box = box->nextOnLine()) {
            FloatRect boxRect(box->x(), box->y(), box->width(), box->height());
            // FIXME: crawling up the parent chain to map each rect is very inefficient
            // we should compute the absoluteTransform outside this loop first.
            rects.append(enclosingIntRect(localToAbsoluteQuad(boxRect).boundingBox()));
        }
    }
}
Example #9
0
void RenderSVGText::absoluteRects(Vector<IntRect>& rects, int, int, bool)
{
    RenderSVGRoot* root = findSVGRootObject(parent());
    if (!root)
        return;

    int x, y;
    absolutePosition(x, y);

    AffineTransform htmlParentCtm = root->RenderContainer::absoluteTransform();
 
    // Don't use relativeBBox here, as it's unites the selection rects. Makes it hard
    // to spot errors, if there are any using WebInspector. Individually feed them into 'rects'.
    for (InlineRunBox* runBox = firstLineBox(); runBox; runBox = runBox->nextLineBox()) {
        ASSERT(runBox->isInlineFlowBox());

        InlineFlowBox* flowBox = static_cast<InlineFlowBox*>(runBox);
        for (InlineBox* box = flowBox->firstChild(); box; box = box->nextOnLine()) {
            FloatRect boxRect(box->xPos(), box->yPos(), box->width(), box->height());
            boxRect.move(narrowPrecisionToFloat(x - htmlParentCtm.e()), narrowPrecisionToFloat(y - htmlParentCtm.f()));
            rects.append(enclosingIntRect(absoluteTransform().mapRect(boxRect)));
        }
    }
}
Example #10
0
void InlineFlowBox::placeBoxesVertically(int y, int maxHeight, int maxAscent, bool strictMode,
                                         int& topPosition, int& bottomPosition)
{
    if (isRootInlineBox()) {
        setYPos(y + maxAscent - baseline());// Place our root box.
        // CSS2: 10.8.1 - line-height on the block level element specifies the *minimum*
        // height of the generated line box
        if (hasTextChildren() && maxHeight < object()->lineHeight(m_firstLine))
            maxHeight = object()->lineHeight(m_firstLine);
    }

    for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) {
        if (curr->object()->isPositioned())
            continue; // Positioned placeholders don't affect calculations.

        // Adjust boxes to use their real box y/height and not the logical height (as dictated by
        // line-height).
        if (curr->isInlineFlowBox())
            static_cast<InlineFlowBox*>(curr)->placeBoxesVertically(y, maxHeight, maxAscent, strictMode,
                                                                    topPosition, bottomPosition);

        bool childAffectsTopBottomPos = true;

        if (curr->yPos() == PositionTop)
            curr->setYPos(y);
        else if (curr->yPos() == PositionBottom)
            curr->setYPos(y + maxHeight - curr->height());
        else {
            if (!strictMode && !curr->hasTextDescendant())
                childAffectsTopBottomPos = false;
            curr->setYPos(curr->yPos() + y + maxAscent - curr->baseline());
        }
        int newY = curr->yPos();
        int newHeight = curr->height();
        int newBaseline = curr->baseline();
        int overflowTop = 0;
        int overflowBottom = 0;
        if (curr->isInlineTextBox() || curr->isInlineFlowBox()) {
            const QFontMetrics &fm = curr->object()->fontMetrics( m_firstLine );
#ifdef APPLE_CHANGES
            newBaseline = fm.ascent();
            newY += curr->baseline() - newBaseline;
            newHeight = newBaseline+fm.descent();
#else
            // only adjust if the leading delta is superior to the font's natural leading
            if ( kAbs(fm.ascent() - curr->baseline()) > fm.leading()/2 ) {
                int ascent = fm.ascent()+fm.leading()/2;
                newBaseline = ascent;
                newY += curr->baseline() - newBaseline;
                newHeight = fm.lineSpacing();
            }
#endif
            for (ShadowData* shadow = curr->object()->style()->textShadow(); shadow; shadow = shadow->next) {
                overflowTop = kMin(overflowTop, shadow->y - shadow->blur);
                overflowBottom = kMax(overflowBottom, shadow->y + shadow->blur);
            }
            if (curr->isInlineFlowBox()) {
                newHeight += curr->object()->borderTop() + curr->object()->paddingTop() +
                            curr->object()->borderBottom() + curr->object()->paddingBottom();
                newY -= curr->object()->borderTop() + curr->object()->paddingTop();
                newBaseline += curr->object()->borderTop() + curr->object()->paddingTop();
            }
        } else {
            newY += curr->object()->marginTop();
            newHeight = curr->height() - (curr->object()->marginTop() + curr->object()->marginBottom());
            overflowTop = curr->object()->overflowTop();
            overflowBottom = curr->object()->overflowHeight() - newHeight;
       }
        curr->setYPos(newY);
        curr->setHeight(newHeight);
        curr->setBaseline(newBaseline);

        if (childAffectsTopBottomPos) {
            topPosition = kMin(topPosition, newY + overflowTop);
            bottomPosition = kMax(bottomPosition, newY + newHeight + overflowBottom);
        }
    }

    if (isRootInlineBox()) {
        const QFontMetrics &fm = object()->fontMetrics( m_firstLine );
#ifdef APPLE_CHANGES
        setHeight(fm.ascent()+fm.descent());
        setYPos(yPos() + baseline() - fm.ascent());
        setBaseline(fm.ascent());
#else
        if ( kAbs(fm.ascent() - baseline()) > fm.leading()/2 ) {
            int ascent = fm.ascent()+fm.leading()/2;
            setHeight(fm.lineSpacing());
            setYPos(yPos() + baseline() - ascent);
            setBaseline(ascent);
        }
#endif
        if (hasTextDescendant() || strictMode) {
            if (yPos() < topPosition)
                topPosition = yPos();
            if (yPos() + height() > bottomPosition)
                bottomPosition = yPos() + height();
        }
    }
}