| OLD | NEW |
| 1 /* | 1 /* |
| 2 * (C) 1999 Lars Knoll (knoll@kde.org) | 2 * (C) 1999 Lars Knoll (knoll@kde.org) |
| 3 * (C) 2000 Dirk Mueller (mueller@kde.org) | 3 * (C) 2000 Dirk Mueller (mueller@kde.org) |
| 4 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All r
ights reserved. | 4 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All r
ights reserved. |
| 5 * | 5 * |
| 6 * This library is free software; you can redistribute it and/or | 6 * This library is free software; you can redistribute it and/or |
| 7 * modify it under the terms of the GNU Library General Public | 7 * modify it under the terms of the GNU Library General Public |
| 8 * License as published by the Free Software Foundation; either | 8 * License as published by the Free Software Foundation; either |
| 9 * version 2 of the License, or (at your option) any later version. | 9 * version 2 of the License, or (at your option) any later version. |
| 10 * | 10 * |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 96 ASSERT(!knownToHaveNoOverflow()); | 96 ASSERT(!knownToHaveNoOverflow()); |
| 97 if (!gTextBoxesWithOverflow) | 97 if (!gTextBoxesWithOverflow) |
| 98 gTextBoxesWithOverflow = new InlineTextBoxOverflowMap; | 98 gTextBoxesWithOverflow = new InlineTextBoxOverflowMap; |
| 99 gTextBoxesWithOverflow->add(this, rect); | 99 gTextBoxesWithOverflow->add(this, rect); |
| 100 } | 100 } |
| 101 | 101 |
| 102 int InlineTextBox::baselinePosition(FontBaseline baselineType) const | 102 int InlineTextBox::baselinePosition(FontBaseline baselineType) const |
| 103 { | 103 { |
| 104 if (!isText() || !parent()) | 104 if (!isText() || !parent()) |
| 105 return 0; | 105 return 0; |
| 106 if (parent()->renderer() == renderer().parent()) | 106 if (parent()->layoutObject() == layoutObject().parent()) |
| 107 return parent()->baselinePosition(baselineType); | 107 return parent()->baselinePosition(baselineType); |
| 108 return toLayoutBoxModelObject(renderer().parent())->baselinePosition(baselin
eType, isFirstLineStyle(), isHorizontal() ? HorizontalLine : VerticalLine, Posit
ionOnContainingLine); | 108 return toLayoutBoxModelObject(layoutObject().parent())->baselinePosition(bas
elineType, isFirstLineStyle(), isHorizontal() ? HorizontalLine : VerticalLine, P
ositionOnContainingLine); |
| 109 } | 109 } |
| 110 | 110 |
| 111 LayoutUnit InlineTextBox::lineHeight() const | 111 LayoutUnit InlineTextBox::lineHeight() const |
| 112 { | 112 { |
| 113 if (!isText() || !renderer().parent()) | 113 if (!isText() || !layoutObject().parent()) |
| 114 return 0; | 114 return 0; |
| 115 if (renderer().isBR()) | 115 if (layoutObject().isBR()) |
| 116 return toLayoutBR(renderer()).lineHeight(isFirstLineStyle()); | 116 return toLayoutBR(layoutObject()).lineHeight(isFirstLineStyle()); |
| 117 if (parent()->renderer() == renderer().parent()) | 117 if (parent()->layoutObject() == layoutObject().parent()) |
| 118 return parent()->lineHeight(); | 118 return parent()->lineHeight(); |
| 119 return toLayoutBoxModelObject(renderer().parent())->lineHeight(isFirstLineSt
yle(), isHorizontal() ? HorizontalLine : VerticalLine, PositionOnContainingLine)
; | 119 return toLayoutBoxModelObject(layoutObject().parent())->lineHeight(isFirstLi
neStyle(), isHorizontal() ? HorizontalLine : VerticalLine, PositionOnContainingL
ine); |
| 120 } | 120 } |
| 121 | 121 |
| 122 bool InlineTextBox::isSelected(int startPos, int endPos) const | 122 bool InlineTextBox::isSelected(int startPos, int endPos) const |
| 123 { | 123 { |
| 124 int sPos = std::max(startPos - m_start, 0); | 124 int sPos = std::max(startPos - m_start, 0); |
| 125 // The position after a hard line break is considered to be past its end. | 125 // The position after a hard line break is considered to be past its end. |
| 126 // See the corresponding code in InlineTextBox::selectionState. | 126 // See the corresponding code in InlineTextBox::selectionState. |
| 127 int ePos = std::min(endPos - m_start, int(m_len) + (isLineBreak() ? 0 : 1)); | 127 int ePos = std::min(endPos - m_start, int(m_len) + (isLineBreak() ? 0 : 1)); |
| 128 return (sPos < ePos); | 128 return (sPos < ePos); |
| 129 } | 129 } |
| 130 | 130 |
| 131 LayoutObject::SelectionState InlineTextBox::selectionState() const | 131 LayoutObject::SelectionState InlineTextBox::selectionState() const |
| 132 { | 132 { |
| 133 LayoutObject::SelectionState state = renderer().selectionState(); | 133 LayoutObject::SelectionState state = layoutObject().selectionState(); |
| 134 if (state == LayoutObject::SelectionStart || state == LayoutObject::Selectio
nEnd || state == LayoutObject::SelectionBoth) { | 134 if (state == LayoutObject::SelectionStart || state == LayoutObject::Selectio
nEnd || state == LayoutObject::SelectionBoth) { |
| 135 int startPos, endPos; | 135 int startPos, endPos; |
| 136 renderer().selectionStartEnd(startPos, endPos); | 136 layoutObject().selectionStartEnd(startPos, endPos); |
| 137 // The position after a hard line break is considered to be past its end
. | 137 // The position after a hard line break is considered to be past its end
. |
| 138 // See the corresponding code in InlineTextBox::isSelected. | 138 // See the corresponding code in InlineTextBox::isSelected. |
| 139 int lastSelectable = start() + len() - (isLineBreak() ? 1 : 0); | 139 int lastSelectable = start() + len() - (isLineBreak() ? 1 : 0); |
| 140 | 140 |
| 141 // FIXME: Remove -webkit-line-break: LineBreakAfterWhiteSpace. | 141 // FIXME: Remove -webkit-line-break: LineBreakAfterWhiteSpace. |
| 142 int endOfLineAdjustmentForCSSLineBreak = renderer().style()->lineBreak()
== LineBreakAfterWhiteSpace ? -1 : 0; | 142 int endOfLineAdjustmentForCSSLineBreak = layoutObject().style()->lineBre
ak() == LineBreakAfterWhiteSpace ? -1 : 0; |
| 143 bool start = (state != LayoutObject::SelectionEnd && startPos >= m_start
&& startPos <= m_start + m_len + endOfLineAdjustmentForCSSLineBreak); | 143 bool start = (state != LayoutObject::SelectionEnd && startPos >= m_start
&& startPos <= m_start + m_len + endOfLineAdjustmentForCSSLineBreak); |
| 144 bool end = (state != LayoutObject::SelectionStart && endPos > m_start &&
endPos <= lastSelectable); | 144 bool end = (state != LayoutObject::SelectionStart && endPos > m_start &&
endPos <= lastSelectable); |
| 145 if (start && end) | 145 if (start && end) |
| 146 state = LayoutObject::SelectionBoth; | 146 state = LayoutObject::SelectionBoth; |
| 147 else if (start) | 147 else if (start) |
| 148 state = LayoutObject::SelectionStart; | 148 state = LayoutObject::SelectionStart; |
| 149 else if (end) | 149 else if (end) |
| 150 state = LayoutObject::SelectionEnd; | 150 state = LayoutObject::SelectionEnd; |
| 151 else if ((state == LayoutObject::SelectionEnd || startPos < m_start) | 151 else if ((state == LayoutObject::SelectionEnd || startPos < m_start) |
| 152 && (state == LayoutObject::SelectionStart || endPos > lastSelectable
)) | 152 && (state == LayoutObject::SelectionStart || endPos > lastSelectable
)) |
| (...skipping 27 matching lines...) Expand all Loading... |
| 180 int sPos = std::max(startPos - m_start, 0); | 180 int sPos = std::max(startPos - m_start, 0); |
| 181 int ePos = std::min(endPos - m_start, (int)m_len); | 181 int ePos = std::min(endPos - m_start, (int)m_len); |
| 182 | 182 |
| 183 if (sPos > ePos) | 183 if (sPos > ePos) |
| 184 return LayoutRect(); | 184 return LayoutRect(); |
| 185 | 185 |
| 186 FontCachePurgePreventer fontCachePurgePreventer; | 186 FontCachePurgePreventer fontCachePurgePreventer; |
| 187 | 187 |
| 188 LayoutUnit selTop = root().selectionTop(); | 188 LayoutUnit selTop = root().selectionTop(); |
| 189 LayoutUnit selHeight = root().selectionHeight(); | 189 LayoutUnit selHeight = root().selectionHeight(); |
| 190 const LayoutStyle& styleToUse = renderer().styleRef(isFirstLineStyle()); | 190 const LayoutStyle& styleToUse = layoutObject().styleRef(isFirstLineStyle()); |
| 191 const Font& font = styleToUse.font(); | 191 const Font& font = styleToUse.font(); |
| 192 | 192 |
| 193 StringBuilder charactersWithHyphen; | 193 StringBuilder charactersWithHyphen; |
| 194 bool respectHyphen = ePos == m_len && hasHyphen(); | 194 bool respectHyphen = ePos == m_len && hasHyphen(); |
| 195 TextRun textRun = constructTextRun(styleToUse, font, respectHyphen ? &charac
tersWithHyphen : 0); | 195 TextRun textRun = constructTextRun(styleToUse, font, respectHyphen ? &charac
tersWithHyphen : 0); |
| 196 | 196 |
| 197 FloatPointWillBeLayoutPoint startingPoint = FloatPointWillBeLayoutPoint(logi
calLeft(), selTop.toFloat()); | 197 FloatPointWillBeLayoutPoint startingPoint = FloatPointWillBeLayoutPoint(logi
calLeft(), selTop.toFloat()); |
| 198 LayoutRect r; | 198 LayoutRect r; |
| 199 if (sPos || ePos != static_cast<int>(m_len)) { | 199 if (sPos || ePos != static_cast<int>(m_len)) { |
| 200 r = LayoutRect(enclosingIntRect(font.selectionRectForText(textRun, start
ingPoint.toFloatPoint(), selHeight, sPos, ePos))); | 200 r = LayoutRect(enclosingIntRect(font.selectionRectForText(textRun, start
ingPoint.toFloatPoint(), selHeight, sPos, ePos))); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 212 | 212 |
| 213 LayoutPoint topPoint = isHorizontal() ? LayoutPoint(r.x(), selTop) : LayoutP
oint(selTop, r.x()); | 213 LayoutPoint topPoint = isHorizontal() ? LayoutPoint(r.x(), selTop) : LayoutP
oint(selTop, r.x()); |
| 214 LayoutUnit width = isHorizontal() ? logicalWidth : selHeight; | 214 LayoutUnit width = isHorizontal() ? logicalWidth : selHeight; |
| 215 LayoutUnit height = isHorizontal() ? selHeight : logicalWidth; | 215 LayoutUnit height = isHorizontal() ? selHeight : logicalWidth; |
| 216 | 216 |
| 217 return LayoutRect(topPoint, LayoutSize(width, height)); | 217 return LayoutRect(topPoint, LayoutSize(width, height)); |
| 218 } | 218 } |
| 219 | 219 |
| 220 void InlineTextBox::deleteLine() | 220 void InlineTextBox::deleteLine() |
| 221 { | 221 { |
| 222 renderer().removeTextBox(this); | 222 layoutObject().removeTextBox(this); |
| 223 destroy(); | 223 destroy(); |
| 224 } | 224 } |
| 225 | 225 |
| 226 void InlineTextBox::extractLine() | 226 void InlineTextBox::extractLine() |
| 227 { | 227 { |
| 228 if (extracted()) | 228 if (extracted()) |
| 229 return; | 229 return; |
| 230 | 230 |
| 231 renderer().extractTextBox(this); | 231 layoutObject().extractTextBox(this); |
| 232 } | 232 } |
| 233 | 233 |
| 234 void InlineTextBox::attachLine() | 234 void InlineTextBox::attachLine() |
| 235 { | 235 { |
| 236 if (!extracted()) | 236 if (!extracted()) |
| 237 return; | 237 return; |
| 238 | 238 |
| 239 renderer().attachTextBox(this); | 239 layoutObject().attachTextBox(this); |
| 240 } | 240 } |
| 241 | 241 |
| 242 FloatWillBeLayoutUnit InlineTextBox::placeEllipsisBox(bool flowIsLTR, FloatWillB
eLayoutUnit visibleLeftEdge, FloatWillBeLayoutUnit visibleRightEdge, FloatWillBe
LayoutUnit ellipsisWidth, FloatWillBeLayoutUnit &truncatedWidth, bool& foundBox) | 242 FloatWillBeLayoutUnit InlineTextBox::placeEllipsisBox(bool flowIsLTR, FloatWillB
eLayoutUnit visibleLeftEdge, FloatWillBeLayoutUnit visibleRightEdge, FloatWillBe
LayoutUnit ellipsisWidth, FloatWillBeLayoutUnit &truncatedWidth, bool& foundBox) |
| 243 { | 243 { |
| 244 if (foundBox) { | 244 if (foundBox) { |
| 245 m_truncation = cFullTruncation; | 245 m_truncation = cFullTruncation; |
| 246 return -1; | 246 return -1; |
| 247 } | 247 } |
| 248 | 248 |
| 249 // For LTR this is the left edge of the box, for RTL, the right edge in pare
nt coordinates. | 249 // For LTR this is the left edge of the box, for RTL, the right edge in pare
nt coordinates. |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 283 m_truncation = cFullTruncation; | 283 m_truncation = cFullTruncation; |
| 284 truncatedWidth += ellipsisWidth; | 284 truncatedWidth += ellipsisWidth; |
| 285 return std::min(ellipsisX, logicalLeft()); | 285 return std::min(ellipsisX, logicalLeft()); |
| 286 } | 286 } |
| 287 | 287 |
| 288 // Set the truncation index on the text run. | 288 // Set the truncation index on the text run. |
| 289 m_truncation = offset; | 289 m_truncation = offset; |
| 290 | 290 |
| 291 // If we got here that means that we were only partially truncated and w
e need to return the pixel offset at which | 291 // If we got here that means that we were only partially truncated and w
e need to return the pixel offset at which |
| 292 // to place the ellipsis. | 292 // to place the ellipsis. |
| 293 FloatWillBeLayoutUnit widthOfVisibleText = renderer().width(m_start, off
set, textPos(), flowIsLTR ? LTR : RTL, isFirstLineStyle()); | 293 FloatWillBeLayoutUnit widthOfVisibleText = layoutObject().width(m_start,
offset, textPos(), flowIsLTR ? LTR : RTL, isFirstLineStyle()); |
| 294 | 294 |
| 295 // The ellipsis needs to be placed just after the last visible character
. | 295 // The ellipsis needs to be placed just after the last visible character
. |
| 296 // Where "after" is defined by the flow directionality, not the inline | 296 // Where "after" is defined by the flow directionality, not the inline |
| 297 // box directionality. | 297 // box directionality. |
| 298 // e.g. In the case of an LTR inline box truncated in an RTL flow then w
e can | 298 // e.g. In the case of an LTR inline box truncated in an RTL flow then w
e can |
| 299 // have a situation such as |Hello| -> |...He| | 299 // have a situation such as |Hello| -> |...He| |
| 300 truncatedWidth += widthOfVisibleText + ellipsisWidth; | 300 truncatedWidth += widthOfVisibleText + ellipsisWidth; |
| 301 if (flowIsLTR) | 301 if (flowIsLTR) |
| 302 return logicalLeft() + widthOfVisibleText; | 302 return logicalLeft() + widthOfVisibleText; |
| 303 return logicalRight() - widthOfVisibleText - ellipsisWidth; | 303 return logicalRight() - widthOfVisibleText - ellipsisWidth; |
| 304 } | 304 } |
| 305 truncatedWidth += logicalWidth(); | 305 truncatedWidth += logicalWidth(); |
| 306 return -1; | 306 return -1; |
| 307 } | 307 } |
| 308 | 308 |
| 309 bool InlineTextBox::isLineBreak() const | 309 bool InlineTextBox::isLineBreak() const |
| 310 { | 310 { |
| 311 return renderer().isBR() || (renderer().style()->preserveNewline() && len()
== 1 && (*renderer().text().impl())[start()] == '\n'); | 311 return layoutObject().isBR() || (layoutObject().style()->preserveNewline() &
& len() == 1 && (*layoutObject().text().impl())[start()] == '\n'); |
| 312 } | 312 } |
| 313 | 313 |
| 314 bool InlineTextBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& re
sult, const HitTestLocation& locationInContainer, const LayoutPoint& accumulated
Offset, LayoutUnit /* lineTop */, LayoutUnit /*lineBottom*/) | 314 bool InlineTextBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& re
sult, const HitTestLocation& locationInContainer, const LayoutPoint& accumulated
Offset, LayoutUnit /* lineTop */, LayoutUnit /*lineBottom*/) |
| 315 { | 315 { |
| 316 if (isLineBreak()) | 316 if (isLineBreak()) |
| 317 return false; | 317 return false; |
| 318 | 318 |
| 319 FloatPointWillBeLayoutPoint boxOrigin = locationIncludingFlipping(); | 319 FloatPointWillBeLayoutPoint boxOrigin = locationIncludingFlipping(); |
| 320 boxOrigin.moveBy(accumulatedOffset); | 320 boxOrigin.moveBy(accumulatedOffset); |
| 321 FloatRectWillBeLayoutRect rect(boxOrigin, size()); | 321 FloatRectWillBeLayoutRect rect(boxOrigin, size()); |
| 322 // FIXME: both calls to rawValue() below is temporary and should be removed
once the transition | 322 // FIXME: both calls to rawValue() below is temporary and should be removed
once the transition |
| 323 // to LayoutUnit-based types is complete (crbug.com/321237) | 323 // to LayoutUnit-based types is complete (crbug.com/321237) |
| 324 if (m_truncation != cFullTruncation && visibleToHitTestRequest(request) && l
ocationInContainer.intersects(rect.rawValue())) { | 324 if (m_truncation != cFullTruncation && visibleToHitTestRequest(request) && l
ocationInContainer.intersects(rect.rawValue())) { |
| 325 renderer().updateHitTestResult(result, flipForWritingMode(locationInCont
ainer.point() - toLayoutSize(accumulatedOffset))); | 325 layoutObject().updateHitTestResult(result, flipForWritingMode(locationIn
Container.point() - toLayoutSize(accumulatedOffset))); |
| 326 if (!result.addNodeToListBasedTestResult(renderer().node(), request, loc
ationInContainer, rect.rawValue())) | 326 if (!result.addNodeToListBasedTestResult(layoutObject().node(), request,
locationInContainer, rect.rawValue())) |
| 327 return true; | 327 return true; |
| 328 } | 328 } |
| 329 return false; | 329 return false; |
| 330 } | 330 } |
| 331 | 331 |
| 332 bool InlineTextBox::getEmphasisMarkPosition(const LayoutStyle& style, TextEmphas
isPosition& emphasisPosition) const | 332 bool InlineTextBox::getEmphasisMarkPosition(const LayoutStyle& style, TextEmphas
isPosition& emphasisPosition) const |
| 333 { | 333 { |
| 334 // This function returns true if there are text emphasis marks and they are
suppressed by ruby text. | 334 // This function returns true if there are text emphasis marks and they are
suppressed by ruby text. |
| 335 if (style.textEmphasisMark() == TextEmphasisMarkNone) | 335 if (style.textEmphasisMark() == TextEmphasisMarkNone) |
| 336 return false; | 336 return false; |
| 337 | 337 |
| 338 emphasisPosition = style.textEmphasisPosition(); | 338 emphasisPosition = style.textEmphasisPosition(); |
| 339 if (emphasisPosition == TextEmphasisPositionUnder) | 339 if (emphasisPosition == TextEmphasisPositionUnder) |
| 340 return true; // Ruby text is always over, so it cannot suppress emphasis
marks under. | 340 return true; // Ruby text is always over, so it cannot suppress emphasis
marks under. |
| 341 | 341 |
| 342 LayoutBlock* containingBlock = renderer().containingBlock(); | 342 LayoutBlock* containingBlock = layoutObject().containingBlock(); |
| 343 if (!containingBlock->isRubyBase()) | 343 if (!containingBlock->isRubyBase()) |
| 344 return true; // This text is not inside a ruby base, so it does not have
ruby text over it. | 344 return true; // This text is not inside a ruby base, so it does not have
ruby text over it. |
| 345 | 345 |
| 346 if (!containingBlock->parent()->isRubyRun()) | 346 if (!containingBlock->parent()->isRubyRun()) |
| 347 return true; // Cannot get the ruby text. | 347 return true; // Cannot get the ruby text. |
| 348 | 348 |
| 349 LayoutRubyText* rubyText = toLayoutRubyRun(containingBlock->parent())->rubyT
ext(); | 349 LayoutRubyText* rubyText = toLayoutRubyRun(containingBlock->parent())->rubyT
ext(); |
| 350 | 350 |
| 351 // The emphasis marks over are suppressed only if there is a ruby text box a
nd it not empty. | 351 // The emphasis marks over are suppressed only if there is a ruby text box a
nd it not empty. |
| 352 return !rubyText || !rubyText->firstLineBox(); | 352 return !rubyText || !rubyText->firstLineBox(); |
| 353 } | 353 } |
| 354 | 354 |
| 355 void InlineTextBox::paint(const PaintInfo& paintInfo, const LayoutPoint& paintOf
fset, LayoutUnit /*lineTop*/, LayoutUnit /*lineBottom*/) | 355 void InlineTextBox::paint(const PaintInfo& paintInfo, const LayoutPoint& paintOf
fset, LayoutUnit /*lineTop*/, LayoutUnit /*lineBottom*/) |
| 356 { | 356 { |
| 357 InlineTextBoxPainter(*this).paint(paintInfo, paintOffset); | 357 InlineTextBoxPainter(*this).paint(paintInfo, paintOffset); |
| 358 } | 358 } |
| 359 | 359 |
| 360 void InlineTextBox::selectionStartEnd(int& sPos, int& ePos) const | 360 void InlineTextBox::selectionStartEnd(int& sPos, int& ePos) const |
| 361 { | 361 { |
| 362 int startPos, endPos; | 362 int startPos, endPos; |
| 363 if (renderer().selectionState() == LayoutObject::SelectionInside) { | 363 if (layoutObject().selectionState() == LayoutObject::SelectionInside) { |
| 364 startPos = 0; | 364 startPos = 0; |
| 365 endPos = renderer().textLength(); | 365 endPos = layoutObject().textLength(); |
| 366 } else { | 366 } else { |
| 367 renderer().selectionStartEnd(startPos, endPos); | 367 layoutObject().selectionStartEnd(startPos, endPos); |
| 368 if (renderer().selectionState() == LayoutObject::SelectionStart) | 368 if (layoutObject().selectionState() == LayoutObject::SelectionStart) |
| 369 endPos = renderer().textLength(); | 369 endPos = layoutObject().textLength(); |
| 370 else if (renderer().selectionState() == LayoutObject::SelectionEnd) | 370 else if (layoutObject().selectionState() == LayoutObject::SelectionEnd) |
| 371 startPos = 0; | 371 startPos = 0; |
| 372 } | 372 } |
| 373 | 373 |
| 374 sPos = std::max(startPos - m_start, 0); | 374 sPos = std::max(startPos - m_start, 0); |
| 375 ePos = std::min(endPos - m_start, (int)m_len); | 375 ePos = std::min(endPos - m_start, (int)m_len); |
| 376 } | 376 } |
| 377 | 377 |
| 378 void InlineTextBox::paintDocumentMarker(GraphicsContext* pt, const FloatPointWil
lBeLayoutPoint& boxOrigin, DocumentMarker* marker, const LayoutStyle& style, con
st Font& font, bool grammar) | 378 void InlineTextBox::paintDocumentMarker(GraphicsContext* pt, const FloatPointWil
lBeLayoutPoint& boxOrigin, DocumentMarker* marker, const LayoutStyle& style, con
st Font& font, bool grammar) |
| 379 { | 379 { |
| 380 InlineTextBoxPainter(*this).paintDocumentMarker(pt, boxOrigin.toFloatPoint()
, marker, style, font, grammar); | 380 InlineTextBoxPainter(*this).paintDocumentMarker(pt, boxOrigin.toFloatPoint()
, marker, style, font, grammar); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 407 int InlineTextBox::offsetForPosition(FloatWillBeLayoutUnit lineOffset, bool incl
udePartialGlyphs) const | 407 int InlineTextBox::offsetForPosition(FloatWillBeLayoutUnit lineOffset, bool incl
udePartialGlyphs) const |
| 408 { | 408 { |
| 409 if (isLineBreak()) | 409 if (isLineBreak()) |
| 410 return 0; | 410 return 0; |
| 411 | 411 |
| 412 if (lineOffset - logicalLeft() > logicalWidth()) | 412 if (lineOffset - logicalLeft() > logicalWidth()) |
| 413 return isLeftToRightDirection() ? len() : 0; | 413 return isLeftToRightDirection() ? len() : 0; |
| 414 if (lineOffset - logicalLeft() < 0) | 414 if (lineOffset - logicalLeft() < 0) |
| 415 return isLeftToRightDirection() ? 0 : len(); | 415 return isLeftToRightDirection() ? 0 : len(); |
| 416 | 416 |
| 417 LayoutText& text = renderer(); | 417 LayoutText& text = layoutObject(); |
| 418 const LayoutStyle& style = text.styleRef(isFirstLineStyle()); | 418 const LayoutStyle& style = text.styleRef(isFirstLineStyle()); |
| 419 const Font& font = style.font(); | 419 const Font& font = style.font(); |
| 420 return font.offsetForPosition(constructTextRun(style, font), lineOffset - lo
gicalLeft(), includePartialGlyphs); | 420 return font.offsetForPosition(constructTextRun(style, font), lineOffset - lo
gicalLeft(), includePartialGlyphs); |
| 421 } | 421 } |
| 422 | 422 |
| 423 FloatWillBeLayoutUnit InlineTextBox::positionForOffset(int offset) const | 423 FloatWillBeLayoutUnit InlineTextBox::positionForOffset(int offset) const |
| 424 { | 424 { |
| 425 ASSERT(offset >= m_start); | 425 ASSERT(offset >= m_start); |
| 426 ASSERT(offset <= m_start + m_len); | 426 ASSERT(offset <= m_start + m_len); |
| 427 | 427 |
| 428 if (isLineBreak()) | 428 if (isLineBreak()) |
| 429 return logicalLeft(); | 429 return logicalLeft(); |
| 430 | 430 |
| 431 LayoutText& text = renderer(); | 431 LayoutText& text = layoutObject(); |
| 432 const LayoutStyle& styleToUse = text.styleRef(isFirstLineStyle()); | 432 const LayoutStyle& styleToUse = text.styleRef(isFirstLineStyle()); |
| 433 const Font& font = styleToUse.font(); | 433 const Font& font = styleToUse.font(); |
| 434 int from = !isLeftToRightDirection() ? offset - m_start : 0; | 434 int from = !isLeftToRightDirection() ? offset - m_start : 0; |
| 435 int to = !isLeftToRightDirection() ? m_len : offset - m_start; | 435 int to = !isLeftToRightDirection() ? m_len : offset - m_start; |
| 436 // FIXME: Do we need to add rightBearing here? | 436 // FIXME: Do we need to add rightBearing here? |
| 437 return font.selectionRectForText(constructTextRun(styleToUse, font), IntPoin
t(logicalLeft(), 0), 0, from, to).maxX(); | 437 return font.selectionRectForText(constructTextRun(styleToUse, font), IntPoin
t(logicalLeft(), 0), 0, from, to).maxX(); |
| 438 } | 438 } |
| 439 | 439 |
| 440 bool InlineTextBox::containsCaretOffset(int offset) const | 440 bool InlineTextBox::containsCaretOffset(int offset) const |
| 441 { | 441 { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 458 return false; | 458 return false; |
| 459 | 459 |
| 460 // Offsets at the end are "in" for normal boxes (but the caller has to check
affinity). | 460 // Offsets at the end are "in" for normal boxes (but the caller has to check
affinity). |
| 461 return true; | 461 return true; |
| 462 } | 462 } |
| 463 | 463 |
| 464 void InlineTextBox::characterWidths(Vector<FloatWillBeLayoutUnit>& widths) const | 464 void InlineTextBox::characterWidths(Vector<FloatWillBeLayoutUnit>& widths) const |
| 465 { | 465 { |
| 466 FontCachePurgePreventer fontCachePurgePreventer; | 466 FontCachePurgePreventer fontCachePurgePreventer; |
| 467 | 467 |
| 468 const LayoutStyle& styleToUse = renderer().styleRef(isFirstLineStyle()); | 468 const LayoutStyle& styleToUse = layoutObject().styleRef(isFirstLineStyle()); |
| 469 const Font& font = styleToUse.font(); | 469 const Font& font = styleToUse.font(); |
| 470 | 470 |
| 471 TextRun textRun = constructTextRun(styleToUse, font); | 471 TextRun textRun = constructTextRun(styleToUse, font); |
| 472 | 472 |
| 473 SimpleShaper shaper(&font, textRun); | 473 SimpleShaper shaper(&font, textRun); |
| 474 FloatWillBeLayoutUnit lastWidth; | 474 FloatWillBeLayoutUnit lastWidth; |
| 475 widths.resize(m_len); | 475 widths.resize(m_len); |
| 476 for (unsigned i = 0; i < m_len; i++) { | 476 for (unsigned i = 0; i < m_len; i++) { |
| 477 shaper.advance(i + 1); | 477 shaper.advance(i + 1); |
| 478 widths[i] = shaper.runWidthSoFar() - lastWidth; | 478 widths[i] = shaper.runWidthSoFar() - lastWidth; |
| 479 lastWidth = shaper.runWidthSoFar(); | 479 lastWidth = shaper.runWidthSoFar(); |
| 480 } | 480 } |
| 481 } | 481 } |
| 482 | 482 |
| 483 TextRun InlineTextBox::constructTextRun(const LayoutStyle& style, const Font& fo
nt, StringBuilder* charactersWithHyphen) const | 483 TextRun InlineTextBox::constructTextRun(const LayoutStyle& style, const Font& fo
nt, StringBuilder* charactersWithHyphen) const |
| 484 { | 484 { |
| 485 ASSERT(renderer().text()); | 485 ASSERT(layoutObject().text()); |
| 486 | 486 |
| 487 StringView string = renderer().text().createView(); | 487 StringView string = layoutObject().text().createView(); |
| 488 unsigned startPos = start(); | 488 unsigned startPos = start(); |
| 489 unsigned length = len(); | 489 unsigned length = len(); |
| 490 | 490 |
| 491 if (string.length() != length || startPos) | 491 if (string.length() != length || startPos) |
| 492 string.narrow(startPos, length); | 492 string.narrow(startPos, length); |
| 493 | 493 |
| 494 return constructTextRun(style, font, string, renderer().textLength() - start
Pos, charactersWithHyphen); | 494 return constructTextRun(style, font, string, layoutObject().textLength() - s
tartPos, charactersWithHyphen); |
| 495 } | 495 } |
| 496 | 496 |
| 497 TextRun InlineTextBox::constructTextRun(const LayoutStyle& style, const Font& fo
nt, StringView string, int maximumLength, StringBuilder* charactersWithHyphen) c
onst | 497 TextRun InlineTextBox::constructTextRun(const LayoutStyle& style, const Font& fo
nt, StringView string, int maximumLength, StringBuilder* charactersWithHyphen) c
onst |
| 498 { | 498 { |
| 499 if (charactersWithHyphen) { | 499 if (charactersWithHyphen) { |
| 500 const AtomicString& hyphenString = style.hyphenString(); | 500 const AtomicString& hyphenString = style.hyphenString(); |
| 501 charactersWithHyphen->reserveCapacity(string.length() + hyphenString.len
gth()); | 501 charactersWithHyphen->reserveCapacity(string.length() + hyphenString.len
gth()); |
| 502 charactersWithHyphen->append(string); | 502 charactersWithHyphen->append(string); |
| 503 charactersWithHyphen->append(hyphenString); | 503 charactersWithHyphen->append(hyphenString); |
| 504 string = charactersWithHyphen->toString().createView(); | 504 string = charactersWithHyphen->toString().createView(); |
| 505 maximumLength = string.length(); | 505 maximumLength = string.length(); |
| 506 } | 506 } |
| 507 | 507 |
| 508 ASSERT(maximumLength >= static_cast<int>(string.length())); | 508 ASSERT(maximumLength >= static_cast<int>(string.length())); |
| 509 | 509 |
| 510 TextRun run(string, textPos(), expansion(), expansionBehavior(), direction()
, dirOverride() || style.rtlOrdering() == VisualOrder, !renderer().canUseSimpleF
ontCodePath()); | 510 TextRun run(string, textPos(), expansion(), expansionBehavior(), direction()
, dirOverride() || style.rtlOrdering() == VisualOrder, !layoutObject().canUseSim
pleFontCodePath()); |
| 511 run.setTabSize(!style.collapseWhiteSpace(), style.tabSize()); | 511 run.setTabSize(!style.collapseWhiteSpace(), style.tabSize()); |
| 512 run.setCodePath(renderer().canUseSimpleFontCodePath() ? TextRun::ForceSimple
: TextRun::ForceComplex); | 512 run.setCodePath(layoutObject().canUseSimpleFontCodePath() ? TextRun::ForceSi
mple : TextRun::ForceComplex); |
| 513 run.setTextJustify(style.textJustify()); | 513 run.setTextJustify(style.textJustify()); |
| 514 | 514 |
| 515 // Propagate the maximum length of the characters buffer to the TextRun, eve
n when we're only processing a substring. | 515 // Propagate the maximum length of the characters buffer to the TextRun, eve
n when we're only processing a substring. |
| 516 run.setCharactersLength(maximumLength); | 516 run.setCharactersLength(maximumLength); |
| 517 ASSERT(run.charactersLength() >= run.length()); | 517 ASSERT(run.charactersLength() >= run.length()); |
| 518 return run; | 518 return run; |
| 519 } | 519 } |
| 520 | 520 |
| 521 TextRun InlineTextBox::constructTextRunForInspector(const LayoutStyle& style, co
nst Font& font) const | 521 TextRun InlineTextBox::constructTextRunForInspector(const LayoutStyle& style, co
nst Font& font) const |
| 522 { | 522 { |
| 523 return InlineTextBox::constructTextRun(style, font); | 523 return InlineTextBox::constructTextRun(style, font); |
| 524 } | 524 } |
| 525 | 525 |
| 526 #ifndef NDEBUG | 526 #ifndef NDEBUG |
| 527 | 527 |
| 528 const char* InlineTextBox::boxName() const | 528 const char* InlineTextBox::boxName() const |
| 529 { | 529 { |
| 530 return "InlineTextBox"; | 530 return "InlineTextBox"; |
| 531 } | 531 } |
| 532 | 532 |
| 533 void InlineTextBox::showBox(int printedCharacters) const | 533 void InlineTextBox::showBox(int printedCharacters) const |
| 534 { | 534 { |
| 535 const LayoutText& obj = renderer(); | 535 const LayoutText& obj = layoutObject(); |
| 536 String value = obj.text(); | 536 String value = obj.text(); |
| 537 value = value.substring(start(), len()); | 537 value = value.substring(start(), len()); |
| 538 value.replaceWithLiteral('\\', "\\\\"); | 538 value.replaceWithLiteral('\\', "\\\\"); |
| 539 value.replaceWithLiteral('\n', "\\n"); | 539 value.replaceWithLiteral('\n', "\\n"); |
| 540 printedCharacters += fprintf(stderr, "%s %p", boxName(), this); | 540 printedCharacters += fprintf(stderr, "%s %p", boxName(), this); |
| 541 for (; printedCharacters < showTreeCharacterOffset; printedCharacters++) | 541 for (; printedCharacters < showTreeCharacterOffset; printedCharacters++) |
| 542 fputc(' ', stderr); | 542 fputc(' ', stderr); |
| 543 printedCharacters = fprintf(stderr, "\t%s %p", obj.name(), &obj); | 543 printedCharacters = fprintf(stderr, "\t%s %p", obj.name(), &obj); |
| 544 const int rendererCharacterOffset = 75; | 544 const int rendererCharacterOffset = 75; |
| 545 for (; printedCharacters < rendererCharacterOffset; printedCharacters++) | 545 for (; printedCharacters < rendererCharacterOffset; printedCharacters++) |
| 546 fputc(' ', stderr); | 546 fputc(' ', stderr); |
| 547 fprintf(stderr, "(%d,%d) \"%s\"\n", start(), start() + len(), value.utf8().d
ata()); | 547 fprintf(stderr, "(%d,%d) \"%s\"\n", start(), start() + len(), value.utf8().d
ata()); |
| 548 } | 548 } |
| 549 | 549 |
| 550 #endif | 550 #endif |
| 551 | 551 |
| 552 } // namespace blink | 552 } // namespace blink |
| OLD | NEW |