/*
 * (C) 1999 Lars Knoll (knoll@kde.org)
 * (C) 2000 Dirk Mueller (mueller@kde.org)
 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc.
 *               All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 *
 */

#include "core/layout/line/InlineTextBox.h"

#include "core/layout/HitTestResult.h"
#include "core/layout/api/LineLayoutBR.h"
#include "core/layout/api/LineLayoutBox.h"
#include "core/layout/api/LineLayoutRubyRun.h"
#include "core/layout/api/LineLayoutRubyText.h"
#include "core/layout/line/AbstractInlineTextBox.h"
#include "core/layout/line/EllipsisBox.h"
#include "core/paint/InlineTextBoxPainter.h"
#include "platform/fonts/CharacterRange.h"
#include "platform/fonts/FontCache.h"
#include "wtf/Vector.h"
#include "wtf/text/StringBuilder.h"

#include <algorithm>

namespace blink {

struct SameSizeAsInlineTextBox : public InlineBox {
  unsigned variables[1];
  unsigned short variables2[2];
  void* pointers[2];
};

static_assert(sizeof(InlineTextBox) == sizeof(SameSizeAsInlineTextBox),
              "InlineTextBox should stay small");

typedef WTF::HashMap<const InlineTextBox*, LayoutRect> InlineTextBoxOverflowMap;
static InlineTextBoxOverflowMap* gTextBoxesWithOverflow;

void InlineTextBox::destroy() {
  AbstractInlineTextBox::willDestroy(this);

  if (!knownToHaveNoOverflow() && gTextBoxesWithOverflow)
    gTextBoxesWithOverflow->remove(this);
  InlineTextBoxPainter::removeFromTextBlobCache(*this);
  InlineBox::destroy();
}

void InlineTextBox::offsetRun(int delta) {
  ASSERT(!isDirty());
  InlineTextBoxPainter::removeFromTextBlobCache(*this);
  m_start += delta;
}

void InlineTextBox::markDirty() {
  // FIXME: Is it actually possible to try and paint a dirty InlineTextBox?
  InlineTextBoxPainter::removeFromTextBlobCache(*this);

  m_len = 0;
  m_start = 0;
  InlineBox::markDirty();
}

LayoutRect InlineTextBox::logicalOverflowRect() const {
  if (knownToHaveNoOverflow() || !gTextBoxesWithOverflow)
    return logicalFrameRect();

  const auto& it = gTextBoxesWithOverflow->find(this);
  if (it != gTextBoxesWithOverflow->end())
    return it->value;

  return logicalFrameRect();
}

void InlineTextBox::setLogicalOverflowRect(const LayoutRect& rect) {
  ASSERT(!knownToHaveNoOverflow());
  DCHECK(rect != logicalFrameRect());
  if (!gTextBoxesWithOverflow)
    gTextBoxesWithOverflow = new InlineTextBoxOverflowMap;
  gTextBoxesWithOverflow->set(this, rect);
}

void InlineTextBox::move(const LayoutSize& delta) {
  InlineBox::move(delta);

  if (!knownToHaveNoOverflow() && gTextBoxesWithOverflow) {
    const auto& it = gTextBoxesWithOverflow->find(this);
    if (it != gTextBoxesWithOverflow->end())
      it->value.move(isHorizontal() ? delta : delta.transposedSize());
  }
}

int InlineTextBox::baselinePosition(FontBaseline baselineType) const {
  if (!isText() || !parent())
    return 0;
  if (parent()->getLineLayoutItem() == getLineLayoutItem().parent())
    return parent()->baselinePosition(baselineType);
  return LineLayoutBoxModel(getLineLayoutItem().parent())
      .baselinePosition(baselineType, isFirstLineStyle(),
                        isHorizontal() ? HorizontalLine : VerticalLine,
                        PositionOnContainingLine);
}

LayoutUnit InlineTextBox::lineHeight() const {
  if (!isText() || !getLineLayoutItem().parent())
    return LayoutUnit();
  if (getLineLayoutItem().isBR())
    return LayoutUnit(
        LineLayoutBR(getLineLayoutItem()).lineHeight(isFirstLineStyle()));
  if (parent()->getLineLayoutItem() == getLineLayoutItem().parent())
    return parent()->lineHeight();
  return LineLayoutBoxModel(getLineLayoutItem().parent())
      .lineHeight(isFirstLineStyle(),
                  isHorizontal() ? HorizontalLine : VerticalLine,
                  PositionOnContainingLine);
}

bool InlineTextBox::isSelected(int startPos, int endPos) const {
  int sPos = std::max(startPos - m_start, 0);
  // The position after a hard line break is considered to be past its end.
  // See the corresponding code in InlineTextBox::getSelectionState.
  int ePos = std::min(endPos - m_start, int(m_len) + (isLineBreak() ? 0 : 1));
  return (sPos < ePos);
}

SelectionState InlineTextBox::getSelectionState() const {
  SelectionState state = getLineLayoutItem().getSelectionState();
  if (state == SelectionStart || state == SelectionEnd ||
      state == SelectionBoth) {
    int startPos, endPos;
    getLineLayoutItem().selectionStartEnd(startPos, endPos);
    // The position after a hard line break is considered to be past its end.
    // See the corresponding code in InlineTextBox::isSelected.
    int lastSelectable = start() + len() - (isLineBreak() ? 1 : 0);

    // FIXME: Remove -webkit-line-break: LineBreakAfterWhiteSpace.
    int endOfLineAdjustmentForCSSLineBreak =
        getLineLayoutItem().style()->getLineBreak() == LineBreakAfterWhiteSpace
            ? -1
            : 0;
    bool start =
        (state != SelectionEnd && startPos >= m_start &&
         startPos <= m_start + m_len + endOfLineAdjustmentForCSSLineBreak);
    bool end = (state != SelectionStart && endPos > m_start &&
                endPos <= lastSelectable);
    if (start && end)
      state = SelectionBoth;
    else if (start)
      state = SelectionStart;
    else if (end)
      state = SelectionEnd;
    else if ((state == SelectionEnd || startPos < m_start) &&
             (state == SelectionStart || endPos > lastSelectable))
      state = SelectionInside;
    else if (state == SelectionBoth)
      state = SelectionNone;
  }

  // If there are ellipsis following, make sure their selection is updated.
  if (m_truncation != cNoTruncation && root().ellipsisBox()) {
    EllipsisBox* ellipsis = root().ellipsisBox();
    if (state != SelectionNone) {
      int start, end;
      selectionStartEnd(start, end);
      // The ellipsis should be considered to be selected if the end of the
      // selection is past the beginning of the truncation and the beginning of
      // the selection is before or at the beginning of the truncation.
      ellipsis->setSelectionState(end >= m_truncation && start <= m_truncation
                                      ? SelectionInside
                                      : SelectionNone);
    } else {
      ellipsis->setSelectionState(SelectionNone);
    }
  }

  return state;
}

bool InlineTextBox::hasWrappedSelectionNewline() const {
  // TODO(wkorman): We shouldn't need layout at this point and it should be
  // enforced by DocumentLifecycle. http://crbug.com/537821
  // Bail out as currently looking up selection state can cause the editing code
  // can force a re-layout while scrutinizing the editing position, and
  // InlineTextBox instances are not guaranteed to survive a re-layout.
  if (getLineLayoutItem().needsLayout())
    return false;

  SelectionState state = getSelectionState();
  return (state == SelectionStart || state == SelectionInside)
         // Checking last leaf child can be slow, so we make sure to do this
         // only after the other simple conditionals.
         && (root().lastLeafChild() == this)
         // It's possible to have mixed LTR/RTL on a single line, and we only
         // want to paint a newline when we're the last leaf child and we make
         // sure there isn't a differently-directioned box following us.
         && ((!isLeftToRightDirection() && root().firstSelectedBox() == this) ||
             (isLeftToRightDirection() && root().lastSelectedBox() == this));
}

float InlineTextBox::newlineSpaceWidth() const {
  const ComputedStyle& styleToUse =
      getLineLayoutItem().styleRef(isFirstLineStyle());
  return styleToUse.font().spaceWidth();
}

LayoutRect InlineTextBox::localSelectionRect(int startPos, int endPos) const {
  int sPos = std::max(startPos - m_start, 0);
  int ePos = std::min(endPos - m_start, (int)m_len);

  if (sPos > ePos)
    return LayoutRect();

  FontCachePurgePreventer fontCachePurgePreventer;

  LayoutUnit selTop = root().selectionTop();
  LayoutUnit selHeight = root().selectionHeight();
  const ComputedStyle& styleToUse =
      getLineLayoutItem().styleRef(isFirstLineStyle());
  const Font& font = styleToUse.font();

  StringBuilder charactersWithHyphen;
  bool respectHyphen = ePos == m_len && hasHyphen();
  TextRun textRun =
      constructTextRun(styleToUse, respectHyphen ? &charactersWithHyphen : 0);

  LayoutPoint startingPoint = LayoutPoint(logicalLeft(), selTop);
  LayoutRect r;
  if (sPos || ePos != static_cast<int>(m_len)) {
    r = LayoutRect(enclosingIntRect(font.selectionRectForText(
        textRun, FloatPoint(startingPoint), selHeight.toInt(), sPos, ePos)));
  } else {
    // Avoid computing the font width when the entire line box is selected as an
    // optimization.
    r = LayoutRect(enclosingIntRect(
        LayoutRect(startingPoint, LayoutSize(m_logicalWidth, selHeight))));
  }

  LayoutUnit logicalWidth = r.width();
  if (r.x() > logicalRight())
    logicalWidth = LayoutUnit();
  else if (r.maxX() > logicalRight())
    logicalWidth = logicalRight() - r.x();

  LayoutPoint topPoint;
  LayoutUnit width;
  LayoutUnit height;
  if (isHorizontal()) {
    topPoint = LayoutPoint(r.x(), selTop);
    width = logicalWidth;
    height = selHeight;
    if (hasWrappedSelectionNewline()) {
      if (!isLeftToRightDirection())
        topPoint.setX(LayoutUnit(topPoint.x() - newlineSpaceWidth()));
      width += newlineSpaceWidth();
    }
  } else {
    topPoint = LayoutPoint(selTop, r.x());
    width = selHeight;
    height = logicalWidth;
    // TODO(wkorman): RTL text embedded in top-to-bottom text can create
    // bottom-to-top situations. Add tests and ensure we handle correctly.
    if (hasWrappedSelectionNewline())
      height += newlineSpaceWidth();
  }

  return LayoutRect(topPoint, LayoutSize(width, height));
}

void InlineTextBox::deleteLine() {
  getLineLayoutItem().removeTextBox(this);
  destroy();
}

void InlineTextBox::extractLine() {
  if (extracted())
    return;

  getLineLayoutItem().extractTextBox(this);
}

void InlineTextBox::attachLine() {
  if (!extracted())
    return;

  getLineLayoutItem().attachTextBox(this);
}

void InlineTextBox::setTruncation(unsigned truncation) {
  if (truncation == m_truncation)
    return;

  m_truncation = truncation;
  InlineTextBoxPainter::removeFromTextBlobCache(*this);
}

void InlineTextBox::clearTruncation() {
  setTruncation(cNoTruncation);
}

LayoutUnit InlineTextBox::placeEllipsisBox(bool flowIsLTR,
                                           LayoutUnit visibleLeftEdge,
                                           LayoutUnit visibleRightEdge,
                                           LayoutUnit ellipsisWidth,
                                           LayoutUnit& truncatedWidth,
                                           bool& foundBox) {
  if (foundBox) {
    setTruncation(cFullTruncation);
    return LayoutUnit(-1);
  }

  // For LTR this is the left edge of the box, for RTL, the right edge in parent
  // coordinates.
  LayoutUnit ellipsisX = flowIsLTR ? visibleRightEdge - ellipsisWidth
                                   : visibleLeftEdge + ellipsisWidth;

  // Criteria for full truncation:
  // LTR: the left edge of the ellipsis is to the left of our text run.
  // RTL: the right edge of the ellipsis is to the right of our text run.
  bool ltrFullTruncation = flowIsLTR && ellipsisX <= logicalLeft();
  bool rtlFullTruncation =
      !flowIsLTR && ellipsisX >= logicalLeft() + logicalWidth();
  if (ltrFullTruncation || rtlFullTruncation) {
    // Too far.  Just set full truncation, but return -1 and let the ellipsis
    // just be placed at the edge of the box.
    setTruncation(cFullTruncation);
    foundBox = true;
    return LayoutUnit(-1);
  }

  bool ltrEllipsisWithinBox = flowIsLTR && (ellipsisX < logicalRight());
  bool rtlEllipsisWithinBox = !flowIsLTR && (ellipsisX > logicalLeft());
  if (ltrEllipsisWithinBox || rtlEllipsisWithinBox) {
    foundBox = true;

    // The inline box may have different directionality than it's parent. Since
    // truncation behavior depends both on both the parent and the inline
    // block's directionality, we must keep track of these separately.
    bool ltr = isLeftToRightDirection();
    if (ltr != flowIsLTR) {
      // Width in pixels of the visible portion of the box, excluding the
      // ellipsis.
      int visibleBoxWidth =
          (visibleRightEdge - visibleLeftEdge - ellipsisWidth).toInt();
      ellipsisX = flowIsLTR ? logicalLeft() + visibleBoxWidth
                            : logicalRight() - visibleBoxWidth;
    }

    // The box's width includes partial glyphs, so respect that when placing
    // the ellipsis.
    int offset = offsetForPosition(ellipsisX);
    if (offset == 0 && ltr == flowIsLTR) {
      // No characters should be laid out.  Set ourselves to full truncation and
      // place the ellipsis at the min of our start and the ellipsis edge.
      setTruncation(cFullTruncation);
      truncatedWidth += ellipsisWidth;
      return std::min(ellipsisX, logicalLeft());
    }

    // Set the truncation index on the text run.
    setTruncation(offset);

    // If we got here that means that we were only partially truncated and we
    // need to return the pixel offset at which to place the ellipsis. Where the
    // text and its flow have opposite directions then our offset into the text
    // is at the start of the part that will be visible.
    LayoutUnit widthOfVisibleText(getLineLayoutItem().width(
        ltr == flowIsLTR ? m_start : m_start + offset,
        ltr == flowIsLTR ? offset : m_len - offset, textPos(),
        flowIsLTR ? LTR : RTL, isFirstLineStyle()));

    // The ellipsis needs to be placed just after the last visible character.
    // Where "after" is defined by the flow directionality, not the inline
    // box directionality.
    // e.g. In the case of an LTR inline box truncated in an RTL flow then we
    // can have a situation such as |Hello| -> |...He|
    truncatedWidth += widthOfVisibleText + ellipsisWidth;
    if (flowIsLTR)
      return logicalLeft() + widthOfVisibleText;
    return logicalRight() - widthOfVisibleText - ellipsisWidth;
  }
  truncatedWidth += logicalWidth();
  return LayoutUnit(-1);
}

bool InlineTextBox::isLineBreak() const {
  return getLineLayoutItem().isBR() ||
         (getLineLayoutItem().style()->preserveNewline() && len() == 1 &&
          (*getLineLayoutItem().text().impl())[start()] == '\n');
}

bool InlineTextBox::nodeAtPoint(HitTestResult& result,
                                const HitTestLocation& locationInContainer,
                                const LayoutPoint& accumulatedOffset,
                                LayoutUnit /* lineTop */,
                                LayoutUnit /*lineBottom*/) {
  if (isLineBreak() || m_truncation == cFullTruncation)
    return false;

  LayoutPoint boxOrigin = physicalLocation();
  boxOrigin.moveBy(accumulatedOffset);
  LayoutRect rect(boxOrigin, size());
  if (visibleToHitTestRequest(result.hitTestRequest()) &&
      locationInContainer.intersects(rect)) {
    getLineLayoutItem().updateHitTestResult(
        result, flipForWritingMode(locationInContainer.point() -
                                   toLayoutSize(accumulatedOffset)));
    if (result.addNodeToListBasedTestResult(getLineLayoutItem().node(),
                                            locationInContainer,
                                            rect) == StopHitTesting)
      return true;
  }
  return false;
}

bool InlineTextBox::getEmphasisMarkPosition(
    const ComputedStyle& style,
    TextEmphasisPosition& emphasisPosition) const {
  // This function returns true if there are text emphasis marks and they are
  // suppressed by ruby text.
  if (style.getTextEmphasisMark() == TextEmphasisMarkNone)
    return false;

  emphasisPosition = style.getTextEmphasisPosition();
  // Ruby text is always over, so it cannot suppress emphasis marks under.
  if (emphasisPosition == TextEmphasisPositionUnder)
    return true;

  LineLayoutBox containingBlock = getLineLayoutItem().containingBlock();
  // This text is not inside a ruby base, so it does not have ruby text over it.
  if (!containingBlock.isRubyBase())
    return true;

  // Cannot get the ruby text.
  if (!containingBlock.parent().isRubyRun())
    return true;

  LineLayoutRubyText rubyText =
      LineLayoutRubyRun(containingBlock.parent()).rubyText();

  // The emphasis marks over are suppressed only if there is a ruby text box and
  // it not empty.
  return !rubyText || !rubyText.firstLineBox();
}

void InlineTextBox::paint(const PaintInfo& paintInfo,
                          const LayoutPoint& paintOffset,
                          LayoutUnit /*lineTop*/,
                          LayoutUnit /*lineBottom*/) const {
  InlineTextBoxPainter(*this).paint(paintInfo, paintOffset);
}

void InlineTextBox::selectionStartEnd(int& sPos, int& ePos) const {
  int startPos, endPos;
  if (getLineLayoutItem().getSelectionState() == SelectionInside) {
    startPos = 0;
    endPos = getLineLayoutItem().textLength();
  } else {
    getLineLayoutItem().selectionStartEnd(startPos, endPos);
    if (getLineLayoutItem().getSelectionState() == SelectionStart)
      endPos = getLineLayoutItem().textLength();
    else if (getLineLayoutItem().getSelectionState() == SelectionEnd)
      startPos = 0;
  }

  sPos = std::max(startPos - m_start, 0);
  ePos = std::min(endPos - m_start, (int)m_len);
}

void InlineTextBox::paintDocumentMarker(GraphicsContext& pt,
                                        const LayoutPoint& boxOrigin,
                                        DocumentMarker* marker,
                                        const ComputedStyle& style,
                                        const Font& font,
                                        bool grammar) const {
  InlineTextBoxPainter(*this).paintDocumentMarker(pt, boxOrigin, marker, style,
                                                  font, grammar);
}

void InlineTextBox::paintTextMatchMarkerForeground(const PaintInfo& paintInfo,
                                                   const LayoutPoint& boxOrigin,
                                                   DocumentMarker* marker,
                                                   const ComputedStyle& style,
                                                   const Font& font) const {
  InlineTextBoxPainter(*this).paintTextMatchMarkerForeground(
      paintInfo, boxOrigin, marker, style, font);
}

void InlineTextBox::paintTextMatchMarkerBackground(const PaintInfo& paintInfo,
                                                   const LayoutPoint& boxOrigin,
                                                   DocumentMarker* marker,
                                                   const ComputedStyle& style,
                                                   const Font& font) const {
  InlineTextBoxPainter(*this).paintTextMatchMarkerBackground(
      paintInfo, boxOrigin, marker, style, font);
}

int InlineTextBox::caretMinOffset() const {
  return m_start;
}

int InlineTextBox::caretMaxOffset() const {
  return m_start + m_len;
}

LayoutUnit InlineTextBox::textPos() const {
  // When computing the width of a text run, LayoutBlock::
  // computeInlineDirectionPositionsForLine() doesn't include the actual offset
  // from the containing block edge in its measurement. textPos() should be
  // consistent so the text are laid out in the same width.
  if (logicalLeft() == 0)
    return LayoutUnit();
  return logicalLeft() - root().logicalLeft();
}

int InlineTextBox::offsetForPosition(LayoutUnit lineOffset,
                                     bool includePartialGlyphs) const {
  if (isLineBreak())
    return 0;

  if (lineOffset - logicalLeft() > logicalWidth())
    return isLeftToRightDirection() ? len() : 0;
  if (lineOffset - logicalLeft() < 0)
    return isLeftToRightDirection() ? 0 : len();

  LineLayoutText text = getLineLayoutItem();
  const ComputedStyle& style = text.styleRef(isFirstLineStyle());
  const Font& font = style.font();
  return font.offsetForPosition(constructTextRun(style),
                                (lineOffset - logicalLeft()).toFloat(),
                                includePartialGlyphs);
}

LayoutUnit InlineTextBox::positionForOffset(int offset) const {
  ASSERT(offset >= m_start);
  ASSERT(offset <= m_start + m_len);

  if (isLineBreak())
    return logicalLeft();

  LineLayoutText text = getLineLayoutItem();
  const ComputedStyle& styleToUse = text.styleRef(isFirstLineStyle());
  const Font& font = styleToUse.font();
  int from = !isLeftToRightDirection() ? offset - m_start : 0;
  int to = !isLeftToRightDirection() ? m_len : offset - m_start;
  // FIXME: Do we need to add rightBearing here?
  return LayoutUnit(
      font.selectionRectForText(constructTextRun(styleToUse),
                                IntPoint(logicalLeft().toInt(), 0), 0, from, to)
          .maxX());
}

bool InlineTextBox::containsCaretOffset(int offset) const {
  // Offsets before the box are never "in".
  if (offset < m_start)
    return false;

  int pastEnd = m_start + m_len;

  // Offsets inside the box (not at either edge) are always "in".
  if (offset < pastEnd)
    return true;

  // Offsets outside the box are always "out".
  if (offset > pastEnd)
    return false;

  // Offsets at the end are "out" for line breaks (they are on the next line).
  if (isLineBreak())
    return false;

  // Offsets at the end are "in" for normal boxes (but the caller has to check
  // affinity).
  return true;
}

void InlineTextBox::characterWidths(Vector<float>& widths) const {
  if (!m_len)
    return;

  FontCachePurgePreventer fontCachePurgePreventer;
  ASSERT(getLineLayoutItem().text());

  const ComputedStyle& styleToUse =
      getLineLayoutItem().styleRef(isFirstLineStyle());
  const Font& font = styleToUse.font();

  TextRun textRun = constructTextRun(styleToUse);
  Vector<CharacterRange> ranges = font.individualCharacterRanges(textRun);
  DCHECK_EQ(ranges.size(), m_len);

  widths.resize(ranges.size());
  for (unsigned i = 0; i < ranges.size(); i++)
    widths[i] = ranges[i].width();
}

TextRun InlineTextBox::constructTextRun(
    const ComputedStyle& style,
    StringBuilder* charactersWithHyphen) const {
  ASSERT(getLineLayoutItem().text());

  String string = getLineLayoutItem().text();
  unsigned startPos = start();
  unsigned length = len();
  return constructTextRun(style, StringView(string, startPos, length),
                          getLineLayoutItem().textLength() - startPos,
                          charactersWithHyphen);
}

TextRun InlineTextBox::constructTextRun(
    const ComputedStyle& style,
    StringView string,
    int maximumLength,
    StringBuilder* charactersWithHyphen) const {
  if (charactersWithHyphen) {
    const AtomicString& hyphenString = style.hyphenString();
    charactersWithHyphen->reserveCapacity(string.length() +
                                          hyphenString.length());
    charactersWithHyphen->append(string);
    charactersWithHyphen->append(hyphenString);
    string = charactersWithHyphen->toString();
    maximumLength = string.length();
  }

  ASSERT(maximumLength >= static_cast<int>(string.length()));

  TextRun run(string, textPos().toFloat(), expansion(), expansionBehavior(),
              direction(),
              dirOverride() || style.rtlOrdering() == EOrder::Visual);
  run.setTabSize(!style.collapseWhiteSpace(), style.getTabSize());
  run.setTextJustify(style.getTextJustify());

  // Propagate the maximum length of the characters buffer to the TextRun, even
  // when we're only processing a substring.
  run.setCharactersLength(maximumLength);
  ASSERT(run.charactersLength() >= run.length());
  return run;
}

TextRun InlineTextBox::constructTextRunForInspector(
    const ComputedStyle& style) const {
  return InlineTextBox::constructTextRun(style);
}

const char* InlineTextBox::boxName() const {
  return "InlineTextBox";
}

String InlineTextBox::debugName() const {
  return String(boxName()) + " '" + text() + "'";
}

String InlineTextBox::text() const {
  return getLineLayoutItem().text().substring(start(), len());
}

#ifndef NDEBUG

void InlineTextBox::showBox(int printedCharacters) const {
  String value = text();
  value.replace('\\', "\\\\");
  value.replace('\n', "\\n");
  printedCharacters += fprintf(stderr, "%s %p", boxName(), this);
  for (; printedCharacters < showTreeCharacterOffset; printedCharacters++)
    fputc(' ', stderr);
  const LineLayoutText obj = getLineLayoutItem();
  printedCharacters =
      fprintf(stderr, "\t%s %p", obj.name(), obj.debugPointer());
  const int layoutObjectCharacterOffset = 75;
  for (; printedCharacters < layoutObjectCharacterOffset; printedCharacters++)
    fputc(' ', stderr);
  fprintf(stderr, "(%d,%d) \"%s\"\n", start(), start() + len(),
          value.utf8().data());
}

#endif

}  // namespace blink
