15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2003, 2006, 2008 Apple Inc. All rights reserved.
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is free software; you can redistribute it and/or
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modify it under the terms of the GNU Library General Public
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * License as published by the Free Software Foundation; either
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * version 2 of the License, or (at your option) any later version.
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is distributed in the hope that it will be useful,
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * but WITHOUT ANY WARRANTY; without even the implied warranty of
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Library General Public License for more details.
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * You should have received a copy of the GNU Library General Public License
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * along with this library; see the file COPYING.LIB.  If not, write to
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Boston, MA 02110-1301, USA.
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h"
2153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RootInlineBox.h"
2253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
2353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/Document.h"
24197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "core/dom/StyleEngine.h"
2553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/EllipsisBox.h"
2653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/HitTestResult.h"
2753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/InlineTextBox.h"
2853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/PaintInfo.h"
2951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "core/rendering/RenderBlockFlow.h"
3053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderFlowThread.h"
3151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "core/rendering/RenderInline.h"
3253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderView.h"
3353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/VerticalPositionCache.h"
341e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/text/BidiResolver.h"
3502772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch#include "wtf/unicode/Unicode.h"
365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
37c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
3802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
3993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)struct SameSizeAsRootInlineBox : public InlineFlowBox {
40197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    unsigned unsignedVariable;
4193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    void* pointers[4];
42197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    LayoutUnit layoutVariables[5];
4393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)};
4493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
4593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)COMPILE_ASSERT(sizeof(RootInlineBox) == sizeof(SameSizeAsRootInlineBox), RootInlineBox_should_stay_small);
4693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)typedef WTF::HashMap<const RootInlineBox*, EllipsisBox*> EllipsisBoxMap;
485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static EllipsisBoxMap* gEllipsisBoxMap = 0;
495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
50d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)RootInlineBox::RootInlineBox(RenderBlockFlow& block)
515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    : InlineFlowBox(block)
525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_lineBreakPos(0)
535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_lineBreakObj(0)
545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_lineTop(0)
555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_lineBottom(0)
565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_lineTopWithLeading(0)
575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_lineBottomWithLeading(0)
58197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    , m_selectionBottom(0)
595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
60d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    setIsHorizontal(block.isHorizontalWritingMode());
615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
64f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)void RootInlineBox::destroy()
655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
66f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)    detachEllipsisBox();
67f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)    InlineFlowBox::destroy();
685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
70f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)void RootInlineBox::detachEllipsisBox()
715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (hasEllipsisBox()) {
735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        EllipsisBox* box = gEllipsisBoxMap->take(this);
745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        box->setParent(0);
75f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)        box->destroy();
765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        setHasEllipsisBox(false);
775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)RenderLineBoxList* RootInlineBox::rendererLineBoxes() const
815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
82d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return block().lineBoxes();
835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RootInlineBox::clearTruncation()
865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (hasEllipsisBox()) {
88f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)        detachEllipsisBox();
895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        InlineFlowBox::clearTruncation();
905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)int RootInlineBox::baselinePosition(FontBaseline baselineType) const
945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return boxModelObject()->baselinePosition(baselineType, isFirstLineStyle(), isHorizontal() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes);
965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)LayoutUnit RootInlineBox::lineHeight() const
995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return boxModelObject()->lineHeight(isFirstLineStyle(), isHorizontal() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes);
1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool RootInlineBox::lineCanAccommodateEllipsis(bool ltr, int blockEdge, int lineBoxEdge, int ellipsisWidth)
1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // First sanity-check the unoverflowed width of the whole line to see if there is sufficient room.
1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    int delta = ltr ? lineBoxEdge - blockEdge : blockEdge - lineBoxEdge;
1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (logicalWidth() - delta < ellipsisWidth)
1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Next iterate over all the line boxes on the line.  If we find a replaced element that intersects
1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // then we refuse to accommodate the ellipsis.  Otherwise we're ok.
1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return InlineFlowBox::canAccommodateEllipsis(ltr, blockEdge, ellipsisWidth);
1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)float RootInlineBox::placeEllipsis(const AtomicString& ellipsisStr,  bool ltr, float blockLeftEdge, float blockRightEdge, float ellipsisWidth,
1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                  InlineBox* markupBox)
1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Create an ellipsis box.
119f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)    EllipsisBox* ellipsisBox = new EllipsisBox(renderer(), ellipsisStr, this,
120f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)        ellipsisWidth - (markupBox ? markupBox->logicalWidth() : 0), logicalHeight(),
12109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        x(), y(), !prevRootBox(), isHorizontal(), markupBox);
12202772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!gEllipsisBoxMap)
1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        gEllipsisBoxMap = new EllipsisBoxMap();
1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    gEllipsisBoxMap->add(this, ellipsisBox);
1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    setHasEllipsisBox(true);
1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // FIXME: Do we need an RTL version of this?
12909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (ltr && (logicalLeft() + logicalWidth() + ellipsisWidth) <= blockRightEdge) {
13009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        ellipsisBox->setLogicalLeft(logicalLeft() + logicalWidth());
1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return logicalWidth() + ellipsisWidth;
1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Now attempt to find the nearest glyph horizontally and place just to the right (or left in RTL)
1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // of that glyph.  Mark all of the objects that intersect the ellipsis box as not painting (as being
1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // truncated).
1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool foundBox = false;
1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    float truncatedWidth = 0;
1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    float position = placeEllipsisBox(ltr, blockLeftEdge, blockRightEdge, ellipsisWidth, truncatedWidth, foundBox);
14009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    ellipsisBox->setLogicalLeft(position);
1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return truncatedWidth;
1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)float RootInlineBox::placeEllipsisBox(bool ltr, float blockLeftEdge, float blockRightEdge, float ellipsisWidth, float &truncatedWidth, bool& foundBox)
1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    float result = InlineFlowBox::placeEllipsisBox(ltr, blockLeftEdge, blockRightEdge, ellipsisWidth, truncatedWidth, foundBox);
1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (result == -1) {
1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        result = ltr ? blockRightEdge - ellipsisWidth : blockLeftEdge;
1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        truncatedWidth = blockRightEdge - blockLeftEdge;
1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return result;
1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RootInlineBox::paintEllipsisBox(PaintInfo& paintInfo, const LayoutPoint& paintOffset, LayoutUnit lineTop, LayoutUnit lineBottom) const
1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
156d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (hasEllipsisBox() && paintInfo.shouldPaintWithinRoot(&renderer()) && renderer().style()->visibility() == VISIBLE
1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            && paintInfo.phase == PaintPhaseForeground)
1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ellipsisBox()->paint(paintInfo, paintOffset, lineTop, lineBottom);
1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RootInlineBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset, LayoutUnit lineTop, LayoutUnit lineBottom)
1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    InlineFlowBox::paint(paintInfo, paintOffset, lineTop, lineBottom);
1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    paintEllipsisBox(paintInfo, paintOffset, lineTop, lineBottom);
1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool RootInlineBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, LayoutUnit lineTop, LayoutUnit lineBottom)
1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
16953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (hasEllipsisBox() && visibleToHitTestRequest(request)) {
1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (ellipsisBox()->nodeAtPoint(request, result, locationInContainer, accumulatedOffset, lineTop, lineBottom)) {
171d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            renderer().updateHitTestResult(result, locationInContainer.point() - toLayoutSize(accumulatedOffset));
1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return true;
1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return InlineFlowBox::nodeAtPoint(request, result, locationInContainer, accumulatedOffset, lineTop, lineBottom);
1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RootInlineBox::adjustPosition(float dx, float dy)
1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    InlineFlowBox::adjustPosition(dx, dy);
1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    LayoutUnit blockDirectionDelta = isHorizontal() ? dy : dx; // The block direction delta is a LayoutUnit.
1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_lineTop += blockDirectionDelta;
1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_lineBottom += blockDirectionDelta;
1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_lineTopWithLeading += blockDirectionDelta;
1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_lineBottomWithLeading += blockDirectionDelta;
186197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    m_selectionBottom += blockDirectionDelta;
1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (hasEllipsisBox())
1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ellipsisBox()->adjustPosition(dx, dy);
1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RootInlineBox::childRemoved(InlineBox* box)
1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
193d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (&box->renderer() == m_lineBreakObj)
1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        setLineBreakInfo(0, 0, BidiStatus());
1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
196d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    for (RootInlineBox* prev = prevRootBox(); prev && prev->lineBreakObj() == &box->renderer(); prev = prev->prevRootBox()) {
1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        prev->setLineBreakInfo(0, 0, BidiStatus());
1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        prev->markDirty();
1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)LayoutUnit RootInlineBox::alignBoxesInBlockDirection(LayoutUnit heightOfBlock, GlyphOverflowAndFallbackFontsMap& textBoxDataMap, VerticalPositionCache& verticalPositionCache)
2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // SVG will handle vertical alignment on its own.
2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (isSVGRootInlineBox())
2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
207926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    LayoutUnit maxPositionTop = 0;
2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    LayoutUnit maxPositionBottom = 0;
2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    int maxAscent = 0;
2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    int maxDescent = 0;
2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool setMaxAscent = false;
2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool setMaxDescent = false;
2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Figure out if we're in no-quirks mode.
216d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    bool noQuirksMode = renderer().document().inNoQuirksMode();
2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_baselineType = requiresIdeographicBaseline(textBoxDataMap) ? IdeographicBaseline : AlphabeticBaseline;
2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    computeLogicalBoxHeights(this, maxPositionTop, maxPositionBottom, maxAscent, maxDescent, setMaxAscent, setMaxDescent, noQuirksMode,
2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                             textBoxDataMap, baselineType(), verticalPositionCache);
2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
223197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if (maxAscent + maxDescent < std::max(maxPositionTop, maxPositionBottom))
2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        adjustMaxAscentAndDescent(maxAscent, maxDescent, maxPositionTop, maxPositionBottom);
2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    LayoutUnit maxHeight = maxAscent + maxDescent;
2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    LayoutUnit lineTop = heightOfBlock;
2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    LayoutUnit lineBottom = heightOfBlock;
2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    LayoutUnit lineTopIncludingMargins = heightOfBlock;
2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    LayoutUnit lineBottomIncludingMargins = heightOfBlock;
231197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    LayoutUnit selectionBottom = heightOfBlock;
2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool setLineTop = false;
2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool hasAnnotationsBefore = false;
2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool hasAnnotationsAfter = false;
235197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    placeBoxesInBlockDirection(heightOfBlock, maxHeight, maxAscent, noQuirksMode, lineTop, lineBottom, selectionBottom, setLineTop,
2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                               lineTopIncludingMargins, lineBottomIncludingMargins, hasAnnotationsBefore, hasAnnotationsAfter, baselineType());
2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_hasAnnotationsBefore = hasAnnotationsBefore;
2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_hasAnnotationsAfter = hasAnnotationsAfter;
23902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
240197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    maxHeight = std::max<LayoutUnit>(0, maxHeight); // FIXME: Is this really necessary?
2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
242197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    setLineTopBottomPositions(lineTop, lineBottom, heightOfBlock, heightOfBlock + maxHeight, selectionBottom);
243aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    if (block().view()->layoutState()->isPaginated())
244aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch        setPaginatedLineWidth(block().availableLogicalWidthForContent());
2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    LayoutUnit annotationsAdjustment = beforeAnnotationsAdjustment();
2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (annotationsAdjustment) {
2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // FIXME: Need to handle pagination here. We might have to move to the next page/column as a result of the
2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // ruby expansion.
250d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        adjustBlockDirectionPosition(annotationsAdjustment.toFloat());
2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        heightOfBlock += annotationsAdjustment;
2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return heightOfBlock + maxHeight;
2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
25793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)float RootInlineBox::maxLogicalTop() const
25893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
25993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    float maxLogicalTop = 0;
26093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    computeMaxLogicalTop(maxLogicalTop);
26193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    return maxLogicalTop;
26293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
26393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)LayoutUnit RootInlineBox::beforeAnnotationsAdjustment() const
2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    LayoutUnit result = 0;
2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
268d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (!renderer().style()->isFlippedLinesWritingMode()) {
2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Annotations under the previous line may push us down.
2705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (prevRootBox() && prevRootBox()->hasAnnotationsAfter())
2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            result = prevRootBox()->computeUnderAnnotationAdjustment(lineTop());
2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!hasAnnotationsBefore())
2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return result;
2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Annotations over this line may push us further down.
277197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        LayoutUnit highestAllowedPosition = prevRootBox() ? std::min(prevRootBox()->lineBottom(), lineTop()) + result : static_cast<LayoutUnit>(block().borderBefore());
2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        result = computeOverAnnotationAdjustment(highestAllowedPosition);
2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    } else {
2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Annotations under this line may push us up.
2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (hasAnnotationsBefore())
282d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            result = computeUnderAnnotationAdjustment(prevRootBox() ? prevRootBox()->lineBottom() : static_cast<LayoutUnit>(block().borderBefore()));
2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!prevRootBox() || !prevRootBox()->hasAnnotationsAfter())
2855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return result;
2865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // We have to compute the expansion for annotations over the previous line to see how much we should move.
288197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        LayoutUnit lowestAllowedPosition = std::max(prevRootBox()->lineBottom(), lineTop()) - result;
2895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        result = prevRootBox()->computeOverAnnotationAdjustment(lowestAllowedPosition);
2905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return result;
2935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2957242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciGapRects RootInlineBox::lineSelectionGap(const RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
2967242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci                                         LayoutUnit selTop, LayoutUnit selHeight, const PaintInfo* paintInfo) const
2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderObject::SelectionState lineState = selectionState();
2995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool leftGap, rightGap;
301d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    block().getSelectionGapInfo(lineState, leftGap, rightGap);
3025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    GapRects result;
3045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    InlineBox* firstBox = firstSelectedBox();
3065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    InlineBox* lastBox = lastSelectedBox();
307d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (leftGap) {
308d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        result.uniteLeft(block().logicalLeftSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock,
309d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            &firstBox->parent()->renderer(), firstBox->logicalLeft(), selTop, selHeight, paintInfo));
310d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
311d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (rightGap) {
312d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        result.uniteRight(block().logicalRightSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock,
313d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            &lastBox->parent()->renderer(), lastBox->logicalRight(), selTop, selHeight, paintInfo));
314d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
3155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // When dealing with bidi text, a non-contiguous selection region is possible.
3175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // e.g. The logical text aaaAAAbbb (capitals denote RTL text and non-capitals LTR) is layed out
3185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // visually as 3 text runs |aaa|bbb|AAA| if we select 4 characters from the start of the text the
3195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // selection will look like (underline denotes selection):
3205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // |aaa|bbb|AAA|
3215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    //  ___       _
3225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // We can see that the |bbb| run is not part of the selection while the runs around it are.
3235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (firstBox && firstBox != lastBox) {
3245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Now fill in any gaps on the line that occurred between two selected elements.
3255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        LayoutUnit lastLogicalLeft = firstBox->logicalRight();
3265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        bool isPreviousBoxSelected = firstBox->selectionState() != RenderObject::SelectionNone;
3275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        for (InlineBox* box = firstBox->nextLeafChild(); box; box = box->nextLeafChild()) {
3285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (box->selectionState() != RenderObject::SelectionNone) {
3295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                LayoutRect logicalRect(lastLogicalLeft, selTop, box->logicalLeft() - lastLogicalLeft, selHeight);
330d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                logicalRect.move(renderer().isHorizontalWritingMode() ? offsetFromRootBlock : LayoutSize(offsetFromRootBlock.height(), offsetFromRootBlock.width()));
3315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                LayoutRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, logicalRect);
3325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (isPreviousBoxSelected && gapRect.width() > 0 && gapRect.height() > 0) {
333d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    if (paintInfo && box->parent()->renderer().style()->visibility() == VISIBLE)
334d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                        paintInfo->context->fillRect(gapRect, box->parent()->renderer().selectionBackgroundColor());
3355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    // VisibleSelection may be non-contiguous, see comment above.
3365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    result.uniteCenter(gapRect);
3375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
3385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                lastLogicalLeft = box->logicalRight();
3395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
3405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (box == lastBox)
3415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                break;
3425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            isPreviousBoxSelected = box->selectionState() != RenderObject::SelectionNone;
3435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
3445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return result;
3475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3497242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciRenderObject::SelectionState RootInlineBox::selectionState() const
3505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Walk over all of the selected boxes.
3525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderObject::SelectionState state = RenderObject::SelectionNone;
3535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (InlineBox* box = firstLeafChild(); box; box = box->nextLeafChild()) {
3545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RenderObject::SelectionState boxState = box->selectionState();
3555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if ((boxState == RenderObject::SelectionStart && state == RenderObject::SelectionEnd) ||
3565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            (boxState == RenderObject::SelectionEnd && state == RenderObject::SelectionStart))
3575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            state = RenderObject::SelectionBoth;
3585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        else if (state == RenderObject::SelectionNone ||
3595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                 ((boxState == RenderObject::SelectionStart || boxState == RenderObject::SelectionEnd) &&
3605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                  (state == RenderObject::SelectionNone || state == RenderObject::SelectionInside)))
3615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            state = boxState;
3625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        else if (boxState == RenderObject::SelectionNone && state == RenderObject::SelectionStart) {
3635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // We are past the end of the selection.
3645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            state = RenderObject::SelectionBoth;
3655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
3665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (state == RenderObject::SelectionBoth)
3675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
3685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return state;
3715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3737242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciInlineBox* RootInlineBox::firstSelectedBox() const
3745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (InlineBox* box = firstLeafChild(); box; box = box->nextLeafChild()) {
3765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (box->selectionState() != RenderObject::SelectionNone)
3775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return box;
3785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return 0;
3815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3837242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciInlineBox* RootInlineBox::lastSelectedBox() const
3845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (InlineBox* box = lastLeafChild(); box; box = box->prevLeafChild()) {
3865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (box->selectionState() != RenderObject::SelectionNone)
3875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return box;
3885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return 0;
3915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)LayoutUnit RootInlineBox::selectionTop() const
3945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    LayoutUnit selectionTop = m_lineTop;
3965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_hasAnnotationsBefore)
398d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        selectionTop -= !renderer().style()->isFlippedLinesWritingMode() ? computeOverAnnotationAdjustment(m_lineTop) : computeUnderAnnotationAdjustment(m_lineTop);
3995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
400d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (renderer().style()->isFlippedLinesWritingMode() || !prevRootBox())
4015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return selectionTop;
4025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
403d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    LayoutUnit prevBottom = prevRootBox()->selectionBottom();
404d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (prevBottom < selectionTop && block().containsFloats()) {
4055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // This line has actually been moved further down, probably from a large line-height, but possibly because the
4065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // line was forced to clear floats.  If so, let's check the offsets, and only be willing to use the previous
4075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // line's bottom if the offsets are greater on both sides.
408d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        LayoutUnit prevLeft = block().logicalLeftOffsetForLine(prevBottom, false);
409d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        LayoutUnit prevRight = block().logicalRightOffsetForLine(prevBottom, false);
410d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        LayoutUnit newLeft = block().logicalLeftOffsetForLine(selectionTop, false);
411d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        LayoutUnit newRight = block().logicalRightOffsetForLine(selectionTop, false);
4125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (prevLeft > newLeft || prevRight < newRight)
4135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return selectionTop;
4145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
4155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return prevBottom;
4175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)LayoutUnit RootInlineBox::selectionTopAdjustedForPrecedingBlock() const
4205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    LayoutUnit top = selectionTop();
4225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
423d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    RenderObject::SelectionState blockSelectionState = root().block().selectionState();
4245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (blockSelectionState != RenderObject::SelectionInside && blockSelectionState != RenderObject::SelectionEnd)
4255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return top;
4265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    LayoutSize offsetToBlockBefore;
428d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (RenderBlock* block = root().block().blockBeforeWithinSelectionRoot(offsetToBlockBefore)) {
429197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        if (block->isRenderBlockFlow()) {
430197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            if (RootInlineBox* lastLine = toRenderBlockFlow(block)->lastRootBox()) {
431197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch                RenderObject::SelectionState lastLineSelectionState = lastLine->selectionState();
432197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch                if (lastLineSelectionState != RenderObject::SelectionInside && lastLineSelectionState != RenderObject::SelectionStart)
433197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch                    return top;
434197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
435197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch                LayoutUnit lastLineSelectionBottom = lastLine->selectionBottom() + offsetToBlockBefore.height();
436197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch                top = std::max(top, lastLineSelectionBottom);
437197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            }
4385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
4395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
4405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return top;
4425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)LayoutUnit RootInlineBox::selectionBottom() const
4455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
446197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    LayoutUnit selectionBottom = m_selectionBottom;
4475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_hasAnnotationsAfter)
449d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        selectionBottom += !renderer().style()->isFlippedLinesWritingMode() ? computeUnderAnnotationAdjustment(m_lineBottom) : computeOverAnnotationAdjustment(m_lineBottom);
4505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
451d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (!renderer().style()->isFlippedLinesWritingMode() || !nextRootBox())
4525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return selectionBottom;
4535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    LayoutUnit nextTop = nextRootBox()->selectionTop();
455d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (nextTop > selectionBottom && block().containsFloats()) {
4565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // The next line has actually been moved further over, probably from a large line-height, but possibly because the
4575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // line was forced to clear floats.  If so, let's check the offsets, and only be willing to use the next
4585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // line's top if the offsets are greater on both sides.
459d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        LayoutUnit nextLeft = block().logicalLeftOffsetForLine(nextTop, false);
460d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        LayoutUnit nextRight = block().logicalRightOffsetForLine(nextTop, false);
461d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        LayoutUnit newLeft = block().logicalLeftOffsetForLine(selectionBottom, false);
462d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        LayoutUnit newRight = block().logicalRightOffsetForLine(selectionBottom, false);
4635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (nextLeft > newLeft || nextRight < newRight)
4645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return selectionBottom;
4655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
4665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return nextTop;
4685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)int RootInlineBox::blockDirectionPointInLine() const
4715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
472197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return !block().style()->isFlippedBlocksWritingMode() ? std::max(lineTop(), selectionTop()) : std::min(lineBottom(), selectionBottom());
4735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
475d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)RenderBlockFlow& RootInlineBox::block() const
4765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
47751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    return toRenderBlockFlow(renderer());
4785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static bool isEditableLeaf(InlineBox* leaf)
4815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
482197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return leaf && leaf->renderer().node() && leaf->renderer().node()->hasEditableStyle();
4835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)InlineBox* RootInlineBox::closestLeafChildForPoint(const IntPoint& pointInContents, bool onlyEditableLeaves)
4865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
487d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return closestLeafChildForLogicalLeftPosition(block().isHorizontalWritingMode() ? pointInContents.x() : pointInContents.y(), onlyEditableLeaves);
4885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)InlineBox* RootInlineBox::closestLeafChildForLogicalLeftPosition(int leftPosition, bool onlyEditableLeaves)
4915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    InlineBox* firstLeaf = firstLeafChild();
4935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    InlineBox* lastLeaf = lastLeafChild();
4945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (firstLeaf != lastLeaf) {
4965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (firstLeaf->isLineBreak())
4975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            firstLeaf = firstLeaf->nextLeafChildIgnoringLineBreak();
4985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        else if (lastLeaf->isLineBreak())
4995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            lastLeaf = lastLeaf->prevLeafChildIgnoringLineBreak();
5005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
5015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (firstLeaf == lastLeaf && (!onlyEditableLeaves || isEditableLeaf(firstLeaf)))
5035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return firstLeaf;
5045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Avoid returning a list marker when possible.
506d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (leftPosition <= firstLeaf->logicalLeft() && !firstLeaf->renderer().isListMarker() && (!onlyEditableLeaves || isEditableLeaf(firstLeaf)))
5075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // The leftPosition coordinate is less or equal to left edge of the firstLeaf.
5085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Return it.
5095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return firstLeaf;
5105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
511d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (leftPosition >= lastLeaf->logicalRight() && !lastLeaf->renderer().isListMarker() && (!onlyEditableLeaves || isEditableLeaf(lastLeaf)))
5125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // The leftPosition coordinate is greater or equal to right edge of the lastLeaf.
5135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Return it.
5145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return lastLeaf;
5155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    InlineBox* closestLeaf = 0;
5175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (InlineBox* leaf = firstLeaf; leaf; leaf = leaf->nextLeafChildIgnoringLineBreak()) {
518d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if (!leaf->renderer().isListMarker() && (!onlyEditableLeaves || isEditableLeaf(leaf))) {
5195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            closestLeaf = leaf;
5205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (leftPosition < leaf->logicalRight())
5215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                // The x coordinate is less than the right edge of the box.
5225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                // Return it.
5235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                return leaf;
5245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
5255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
5265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return closestLeaf ? closestLeaf : lastLeaf;
5285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)BidiStatus RootInlineBox::lineBreakBidiStatus() const
53102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch{
5325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return BidiStatus(static_cast<WTF::Unicode::Direction>(m_lineBreakBidiStatusEor), static_cast<WTF::Unicode::Direction>(m_lineBreakBidiStatusLastStrong), static_cast<WTF::Unicode::Direction>(m_lineBreakBidiStatusLast), m_lineBreakContext);
5335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RootInlineBox::setLineBreakInfo(RenderObject* obj, unsigned breakPos, const BidiStatus& status)
5365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
53751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    // When setting lineBreakObj, the RenderObject must not be a RenderInline
53851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    // with no line boxes, otherwise all sorts of invariants are broken later.
53951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    // This has security implications because if the RenderObject does not
54051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    // point to at least one line box, then that RenderInline can be deleted
54151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    // later without resetting the lineBreakObj, leading to use-after-free.
54251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    ASSERT_WITH_SECURITY_IMPLICATION(!obj || obj->isText() || !(obj->isRenderInline() && obj->isBox() && !toRenderBox(obj)->inlineBoxWrapper()));
54351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
5445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_lineBreakObj = obj;
5455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_lineBreakPos = breakPos;
5465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_lineBreakBidiStatusEor = status.eor;
5475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_lineBreakBidiStatusLastStrong = status.lastStrong;
5485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_lineBreakBidiStatusLast = status.last;
5495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_lineBreakContext = status.context;
5505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)EllipsisBox* RootInlineBox::ellipsisBox() const
5535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!hasEllipsisBox())
5555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
5565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return gEllipsisBoxMap->get(this);
5575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RootInlineBox::removeLineBoxFromRenderObject()
5605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
561d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    block().lineBoxes()->removeLineBox(this);
5625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RootInlineBox::extractLineBoxFromRenderObject()
5655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
566d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    block().lineBoxes()->extractLineBox(this);
5675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RootInlineBox::attachLineBoxToRenderObject()
5705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
571d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    block().lineBoxes()->attachLineBox(this);
5725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)LayoutRect RootInlineBox::paddedLayoutOverflowRect(LayoutUnit endPadding) const
5755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    LayoutRect lineLayoutOverflow = layoutOverflowRect(lineTop(), lineBottom());
5775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!endPadding)
5785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return lineLayoutOverflow;
57902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
5805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (isHorizontal()) {
5815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (isLeftToRightDirection())
582197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            lineLayoutOverflow.shiftMaxXEdgeTo(std::max<LayoutUnit>(lineLayoutOverflow.maxX(), logicalRight() + endPadding));
5835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        else
584197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            lineLayoutOverflow.shiftXEdgeTo(std::min<LayoutUnit>(lineLayoutOverflow.x(), logicalLeft() - endPadding));
5855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    } else {
5865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (isLeftToRightDirection())
587197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            lineLayoutOverflow.shiftMaxYEdgeTo(std::max<LayoutUnit>(lineLayoutOverflow.maxY(), logicalRight() + endPadding));
5885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        else
589197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            lineLayoutOverflow.shiftYEdgeTo(std::min<LayoutUnit>(lineLayoutOverflow.y(), logicalLeft() - endPadding));
5905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
59102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
5925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return lineLayoutOverflow;
5935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static void setAscentAndDescent(int& ascent, int& descent, int newAscent, int newDescent, bool& ascentDescentSet)
5965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!ascentDescentSet) {
5985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ascentDescentSet = true;
5995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ascent = newAscent;
6005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        descent = newDescent;
6015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    } else {
602197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        ascent = std::max(ascent, newAscent);
603197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        descent = std::max(descent, newDescent);
6045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
6055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
6065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RootInlineBox::ascentAndDescentForBox(InlineBox* box, GlyphOverflowAndFallbackFontsMap& textBoxDataMap, int& ascent, int& descent,
6085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                           bool& affectsAscent, bool& affectsDescent) const
6095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
6105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool ascentDescentSet = false;
6115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Replaced boxes will return 0 for the line-height if line-box-contain says they are
6135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // not to be included.
614d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (box->renderer().isReplaced()) {
615d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if (renderer().style(isFirstLineStyle())->lineBoxContain() & LineBoxContainReplaced) {
6165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ascent = box->baselinePosition(baselineType());
6175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            descent = box->lineHeight() - ascent;
61802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
6195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // Replaced elements always affect both the ascent and descent.
6205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            affectsAscent = true;
6215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            affectsDescent = true;
6225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
6235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
6245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
6255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Vector<const SimpleFontData*>* usedFonts = 0;
6275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    GlyphOverflow* glyphOverflow = 0;
6285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (box->isText()) {
6295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        GlyphOverflowAndFallbackFontsMap::iterator it = textBoxDataMap.find(toInlineTextBox(box));
6305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        usedFonts = it == textBoxDataMap.end() ? 0 : &it->value.first;
6315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        glyphOverflow = it == textBoxDataMap.end() ? 0 : &it->value.second;
6325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
63302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
6345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool includeLeading = includeLeadingForBox(box);
6355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool includeFont = includeFontForBox(box);
63602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
6375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool setUsedFont = false;
6385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool setUsedFontWithLeading = false;
6395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
640d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (usedFonts && !usedFonts->isEmpty() && (includeFont || (box->renderer().style(isFirstLineStyle())->lineHeight().isNegative() && includeLeading))) {
641d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        usedFonts->append(box->renderer().style(isFirstLineStyle())->font().primaryFont());
6425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        for (size_t i = 0; i < usedFonts->size(); ++i) {
6435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            const FontMetrics& fontMetrics = usedFonts->at(i)->fontMetrics();
6445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            int usedFontAscent = fontMetrics.ascent(baselineType());
6455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            int usedFontDescent = fontMetrics.descent(baselineType());
6465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            int halfLeading = (fontMetrics.lineSpacing() - fontMetrics.height()) / 2;
6475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            int usedFontAscentAndLeading = usedFontAscent + halfLeading;
6485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            int usedFontDescentAndLeading = fontMetrics.lineSpacing() - usedFontAscentAndLeading;
6495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (includeFont) {
6505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                setAscentAndDescent(ascent, descent, usedFontAscent, usedFontDescent, ascentDescentSet);
6515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                setUsedFont = true;
6525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
6535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (includeLeading) {
6545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                setAscentAndDescent(ascent, descent, usedFontAscentAndLeading, usedFontDescentAndLeading, ascentDescentSet);
6555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                setUsedFontWithLeading = true;
6565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
6575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (!affectsAscent)
6585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                affectsAscent = usedFontAscent - box->logicalTop() > 0;
6595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (!affectsDescent)
6605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                affectsDescent = usedFontDescent + box->logicalTop() > 0;
6615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
6625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
6635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // If leading is included for the box, then we compute that box.
6655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (includeLeading && !setUsedFontWithLeading) {
6665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        int ascentWithLeading = box->baselinePosition(baselineType());
6675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        int descentWithLeading = box->lineHeight() - ascentWithLeading;
6685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        setAscentAndDescent(ascent, descent, ascentWithLeading, descentWithLeading, ascentDescentSet);
66902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
6705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Examine the font box for inline flows and text boxes to see if any part of it is above the baseline.
6715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // If the top of our font box relative to the root box baseline is above the root box baseline, then
6725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // we are contributing to the maxAscent value. Descent is similar. If any part of our font box is below
6735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // the root box's baseline, then we contribute to the maxDescent value.
6745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        affectsAscent = ascentWithLeading - box->logicalTop() > 0;
67502772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch        affectsDescent = descentWithLeading + box->logicalTop() > 0;
6765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
67702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
6785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (includeFontForBox(box) && !setUsedFont) {
679d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        int fontAscent = box->renderer().style(isFirstLineStyle())->fontMetrics().ascent(baselineType());
680d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        int fontDescent = box->renderer().style(isFirstLineStyle())->fontMetrics().descent(baselineType());
6815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        setAscentAndDescent(ascent, descent, fontAscent, fontDescent, ascentDescentSet);
6825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        affectsAscent = fontAscent - box->logicalTop() > 0;
68302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch        affectsDescent = fontDescent + box->logicalTop() > 0;
6845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
6855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (includeGlyphsForBox(box) && glyphOverflow && glyphOverflow->computeBounds) {
6875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        setAscentAndDescent(ascent, descent, glyphOverflow->top, glyphOverflow->bottom, ascentDescentSet);
6885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        affectsAscent = glyphOverflow->top - box->logicalTop() > 0;
68902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch        affectsDescent = glyphOverflow->bottom + box->logicalTop() > 0;
690197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        glyphOverflow->top = std::min(glyphOverflow->top, std::max(0, glyphOverflow->top - box->renderer().style(isFirstLineStyle())->fontMetrics().ascent(baselineType())));
691197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        glyphOverflow->bottom = std::min(glyphOverflow->bottom, std::max(0, glyphOverflow->bottom - box->renderer().style(isFirstLineStyle())->fontMetrics().descent(baselineType())));
6925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
6935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (includeMarginForBox(box)) {
695d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        LayoutUnit ascentWithMargin = box->renderer().style(isFirstLineStyle())->fontMetrics().ascent(baselineType());
696d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        LayoutUnit descentWithMargin = box->renderer().style(isFirstLineStyle())->fontMetrics().descent(baselineType());
697d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if (box->parent() && !box->renderer().isText()) {
6985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ascentWithMargin += box->boxModelObject()->borderBefore() + box->boxModelObject()->paddingBefore() + box->boxModelObject()->marginBefore();
6995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            descentWithMargin += box->boxModelObject()->borderAfter() + box->boxModelObject()->paddingAfter() + box->boxModelObject()->marginAfter();
7005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
7015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        setAscentAndDescent(ascent, descent, ascentWithMargin, descentWithMargin, ascentDescentSet);
70202772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
7035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Treat like a replaced element, since we're using the margin box.
7045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        affectsAscent = true;
7055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        affectsDescent = true;
7065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
7075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
7085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)LayoutUnit RootInlineBox::verticalPositionForBox(InlineBox* box, VerticalPositionCache& verticalPositionCache)
7105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
711d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (box->renderer().isText())
7125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return box->parent()->logicalTop();
71302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
7145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderBoxModelObject* renderer = box->boxModelObject();
7155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(renderer->isInline());
7165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!renderer->isInline())
7175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
7185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // This method determines the vertical position for inline elements.
7205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool firstLine = isFirstLineStyle();
7219bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    if (firstLine && !renderer->document().styleEngine()->usesFirstLineRules())
7225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        firstLine = false;
7235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Check the cache.
7255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool isRenderInline = renderer->isRenderInline();
7265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (isRenderInline && !firstLine) {
7275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        LayoutUnit verticalPosition = verticalPositionCache.get(renderer, baselineType());
7285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (verticalPosition != PositionUndefined)
7295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return verticalPosition;
7305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
7315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    LayoutUnit verticalPosition = 0;
7335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    EVerticalAlign verticalAlign = renderer->style()->verticalAlign();
7345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (verticalAlign == TOP || verticalAlign == BOTTOM)
7355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
73602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
7375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderObject* parent = renderer->parent();
7385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (parent->isRenderInline() && parent->style()->verticalAlign() != TOP && parent->style()->verticalAlign() != BOTTOM)
7395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        verticalPosition = box->parent()->logicalTop();
74002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
7415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (verticalAlign != BASELINE) {
7425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        const Font& font = parent->style(firstLine)->font();
7435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        const FontMetrics& fontMetrics = font.fontMetrics();
74409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        int fontSize = font.fontDescription().computedPixelSize();
7455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        LineDirectionMode lineDirection = parent->isHorizontalWritingMode() ? HorizontalLine : VerticalLine;
7475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (verticalAlign == SUB)
7495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            verticalPosition += fontSize / 5 + 1;
7505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        else if (verticalAlign == SUPER)
7515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            verticalPosition -= fontSize / 3 + 1;
7525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        else if (verticalAlign == TEXT_TOP)
7535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            verticalPosition += renderer->baselinePosition(baselineType(), firstLine, lineDirection) - fontMetrics.ascent(baselineType());
7545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        else if (verticalAlign == MIDDLE)
7555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            verticalPosition = (verticalPosition - static_cast<LayoutUnit>(fontMetrics.xHeight() / 2) - renderer->lineHeight(firstLine, lineDirection) / 2 + renderer->baselinePosition(baselineType(), firstLine, lineDirection)).round();
7565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        else if (verticalAlign == TEXT_BOTTOM) {
7575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            verticalPosition += fontMetrics.descent(baselineType());
7585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // lineHeight - baselinePosition is always 0 for replaced elements (except inline blocks), so don't bother wasting time in that case.
7595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (!renderer->isReplaced() || renderer->isInlineBlockOrInlineTable())
7605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                verticalPosition -= (renderer->lineHeight(firstLine, lineDirection) - renderer->baselinePosition(baselineType(), firstLine, lineDirection));
7615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        } else if (verticalAlign == BASELINE_MIDDLE)
7625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            verticalPosition += -renderer->lineHeight(firstLine, lineDirection) / 2 + renderer->baselinePosition(baselineType(), firstLine, lineDirection);
7635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        else if (verticalAlign == LENGTH) {
7645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            LayoutUnit lineHeight;
7655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            //Per http://www.w3.org/TR/CSS21/visudet.html#propdef-vertical-align: 'Percentages: refer to the 'line-height' of the element itself'.
7665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (renderer->style()->verticalAlignLength().isPercent())
7675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                lineHeight = renderer->style()->computedLineHeight();
7685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            else
7695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                lineHeight = renderer->lineHeight(firstLine, lineDirection);
77009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            verticalPosition -= valueForLength(renderer->style()->verticalAlignLength(), lineHeight);
7715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
7725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
7735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Store the cached value.
7755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (isRenderInline && !firstLine)
7765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        verticalPositionCache.set(renderer, baselineType(), verticalPosition);
7775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return verticalPosition;
7795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
7805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool RootInlineBox::includeLeadingForBox(InlineBox* box) const
7825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
783d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (box->renderer().isReplaced() || (box->renderer().isText() && !box->isText()))
7845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
7855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
786d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    LineBoxContain lineBoxContain = renderer().style()->lineBoxContain();
7875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return (lineBoxContain & LineBoxContainInline) || (box == this && (lineBoxContain & LineBoxContainBlock));
7885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
7895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool RootInlineBox::includeFontForBox(InlineBox* box) const
7915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
792d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (box->renderer().isReplaced() || (box->renderer().isText() && !box->isText()))
7935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
79402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
7955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!box->isText() && box->isInlineFlowBox() && !toInlineFlowBox(box)->hasTextChildren())
7965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
7975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // For now map "glyphs" to "font" in vertical text mode until the bounds returned by glyphs aren't garbage.
799d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    LineBoxContain lineBoxContain = renderer().style()->lineBoxContain();
8005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return (lineBoxContain & LineBoxContainFont) || (!isHorizontal() && (lineBoxContain & LineBoxContainGlyphs));
8015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
8025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool RootInlineBox::includeGlyphsForBox(InlineBox* box) const
8045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
805d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (box->renderer().isReplaced() || (box->renderer().isText() && !box->isText()))
8065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
80702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
8085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!box->isText() && box->isInlineFlowBox() && !toInlineFlowBox(box)->hasTextChildren())
8095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
8105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // FIXME: We can't fit to glyphs yet for vertical text, since the bounds returned are garbage.
812d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    LineBoxContain lineBoxContain = renderer().style()->lineBoxContain();
8135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return isHorizontal() && (lineBoxContain & LineBoxContainGlyphs);
8145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
8155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool RootInlineBox::includeMarginForBox(InlineBox* box) const
8175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
818d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (box->renderer().isReplaced() || (box->renderer().isText() && !box->isText()))
8195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
8205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
821d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    LineBoxContain lineBoxContain = renderer().style()->lineBoxContain();
8225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return lineBoxContain & LineBoxContainInlineBox;
8235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
8245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool RootInlineBox::fitsToGlyphs() const
8275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
8285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // FIXME: We can't fit to glyphs yet for vertical text, since the bounds returned are garbage.
829d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    LineBoxContain lineBoxContain = renderer().style()->lineBoxContain();
8305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return isHorizontal() && (lineBoxContain & LineBoxContainGlyphs);
8315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
8325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool RootInlineBox::includesRootLineBoxFontOrLeading() const
8345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
835d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    LineBoxContain lineBoxContain = renderer().style()->lineBoxContain();
8365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return (lineBoxContain & LineBoxContainBlock) || (lineBoxContain & LineBoxContainInline) || (lineBoxContain & LineBoxContainFont);
8375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
8385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Node* RootInlineBox::getLogicalStartBoxWithNode(InlineBox*& startBox) const
8405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
8415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Vector<InlineBox*> leafBoxesInLogicalOrder;
8425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    collectLeafBoxesInLogicalOrder(leafBoxesInLogicalOrder);
8435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (size_t i = 0; i < leafBoxesInLogicalOrder.size(); ++i) {
844d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if (leafBoxesInLogicalOrder[i]->renderer().node()) {
8455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            startBox = leafBoxesInLogicalOrder[i];
846d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            return startBox->renderer().node();
8475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
8485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
8495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    startBox = 0;
8505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return 0;
8515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
85202772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
8535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Node* RootInlineBox::getLogicalEndBoxWithNode(InlineBox*& endBox) const
8545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
8555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Vector<InlineBox*> leafBoxesInLogicalOrder;
8565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    collectLeafBoxesInLogicalOrder(leafBoxesInLogicalOrder);
85702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch    for (size_t i = leafBoxesInLogicalOrder.size(); i > 0; --i) {
858d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if (leafBoxesInLogicalOrder[i - 1]->renderer().node()) {
8595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            endBox = leafBoxesInLogicalOrder[i - 1];
860d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            return endBox->renderer().node();
8615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
8625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
8635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    endBox = 0;
8645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return 0;
8655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
8665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#ifndef NDEBUG
8685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)const char* RootInlineBox::boxName() const
8695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
8705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return "RootInlineBox";
8715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
8725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif
8735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
874c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink
875