| 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 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 105 LayoutRect logicalOverflowRect = this->logicalOverflowRect(); | 105 LayoutRect logicalOverflowRect = this->logicalOverflowRect(); |
| 106 logicalOverflowRect.move(isHorizontal() ? delta : delta.transposedSize()
); | 106 logicalOverflowRect.move(isHorizontal() ? delta : delta.transposedSize()
); |
| 107 setLogicalOverflowRect(logicalOverflowRect); | 107 setLogicalOverflowRect(logicalOverflowRect); |
| 108 } | 108 } |
| 109 } | 109 } |
| 110 | 110 |
| 111 int InlineTextBox::baselinePosition(FontBaseline baselineType) const | 111 int InlineTextBox::baselinePosition(FontBaseline baselineType) const |
| 112 { | 112 { |
| 113 if (!isText() || !parent()) | 113 if (!isText() || !parent()) |
| 114 return 0; | 114 return 0; |
| 115 if (parent()->lineLayoutItem() == lineLayoutItem().parent()) | 115 if (parent()->getLineLayoutItem() == getLineLayoutItem().parent()) |
| 116 return parent()->baselinePosition(baselineType); | 116 return parent()->baselinePosition(baselineType); |
| 117 return LineLayoutBoxModel(lineLayoutItem().parent()).baselinePosition(baseli
neType, isFirstLineStyle(), isHorizontal() ? HorizontalLine : VerticalLine, Posi
tionOnContainingLine); | 117 return LineLayoutBoxModel(getLineLayoutItem().parent()).baselinePosition(bas
elineType, isFirstLineStyle(), isHorizontal() ? HorizontalLine : VerticalLine, P
ositionOnContainingLine); |
| 118 } | 118 } |
| 119 | 119 |
| 120 LayoutUnit InlineTextBox::lineHeight() const | 120 LayoutUnit InlineTextBox::lineHeight() const |
| 121 { | 121 { |
| 122 if (!isText() || !lineLayoutItem().parent()) | 122 if (!isText() || !getLineLayoutItem().parent()) |
| 123 return LayoutUnit(); | 123 return LayoutUnit(); |
| 124 if (lineLayoutItem().isBR()) | 124 if (getLineLayoutItem().isBR()) |
| 125 return LayoutUnit(toLayoutBR(lineLayoutItem())->lineHeight(isFirstLineSt
yle())); | 125 return LayoutUnit(toLayoutBR(getLineLayoutItem())->lineHeight(isFirstLin
eStyle())); |
| 126 if (parent()->lineLayoutItem() == lineLayoutItem().parent()) | 126 if (parent()->getLineLayoutItem() == getLineLayoutItem().parent()) |
| 127 return parent()->lineHeight(); | 127 return parent()->lineHeight(); |
| 128 return LineLayoutBoxModel(lineLayoutItem().parent()).lineHeight(isFirstLineS
tyle(), isHorizontal() ? HorizontalLine : VerticalLine, PositionOnContainingLine
); | 128 return LineLayoutBoxModel(getLineLayoutItem().parent()).lineHeight(isFirstLi
neStyle(), isHorizontal() ? HorizontalLine : VerticalLine, PositionOnContainingL
ine); |
| 129 } | 129 } |
| 130 | 130 |
| 131 bool InlineTextBox::isSelected(int startPos, int endPos) const | 131 bool InlineTextBox::isSelected(int startPos, int endPos) const |
| 132 { | 132 { |
| 133 int sPos = std::max(startPos - m_start, 0); | 133 int sPos = std::max(startPos - m_start, 0); |
| 134 // The position after a hard line break is considered to be past its end. | 134 // The position after a hard line break is considered to be past its end. |
| 135 // See the corresponding code in InlineTextBox::selectionState. | 135 // See the corresponding code in InlineTextBox::getSelectionState. |
| 136 int ePos = std::min(endPos - m_start, int(m_len) + (isLineBreak() ? 0 : 1)); | 136 int ePos = std::min(endPos - m_start, int(m_len) + (isLineBreak() ? 0 : 1)); |
| 137 return (sPos < ePos); | 137 return (sPos < ePos); |
| 138 } | 138 } |
| 139 | 139 |
| 140 SelectionState InlineTextBox::selectionState() const | 140 SelectionState InlineTextBox::getSelectionState() const |
| 141 { | 141 { |
| 142 SelectionState state = lineLayoutItem().selectionState(); | 142 SelectionState state = getLineLayoutItem().getSelectionState(); |
| 143 if (state == SelectionStart || state == SelectionEnd || state == SelectionBo
th) { | 143 if (state == SelectionStart || state == SelectionEnd || state == SelectionBo
th) { |
| 144 int startPos, endPos; | 144 int startPos, endPos; |
| 145 lineLayoutItem().selectionStartEnd(startPos, endPos); | 145 getLineLayoutItem().selectionStartEnd(startPos, endPos); |
| 146 // The position after a hard line break is considered to be past its end
. | 146 // The position after a hard line break is considered to be past its end
. |
| 147 // See the corresponding code in InlineTextBox::isSelected. | 147 // See the corresponding code in InlineTextBox::isSelected. |
| 148 int lastSelectable = start() + len() - (isLineBreak() ? 1 : 0); | 148 int lastSelectable = start() + len() - (isLineBreak() ? 1 : 0); |
| 149 | 149 |
| 150 // FIXME: Remove -webkit-line-break: LineBreakAfterWhiteSpace. | 150 // FIXME: Remove -webkit-line-break: LineBreakAfterWhiteSpace. |
| 151 int endOfLineAdjustmentForCSSLineBreak = lineLayoutItem().style()->lineB
reak() == LineBreakAfterWhiteSpace ? -1 : 0; | 151 int endOfLineAdjustmentForCSSLineBreak = getLineLayoutItem().style()->li
neBreak() == LineBreakAfterWhiteSpace ? -1 : 0; |
| 152 bool start = (state != SelectionEnd && startPos >= m_start && startPos <
= m_start + m_len + endOfLineAdjustmentForCSSLineBreak); | 152 bool start = (state != SelectionEnd && startPos >= m_start && startPos <
= m_start + m_len + endOfLineAdjustmentForCSSLineBreak); |
| 153 bool end = (state != SelectionStart && endPos > m_start && endPos <= las
tSelectable); | 153 bool end = (state != SelectionStart && endPos > m_start && endPos <= las
tSelectable); |
| 154 if (start && end) | 154 if (start && end) |
| 155 state = SelectionBoth; | 155 state = SelectionBoth; |
| 156 else if (start) | 156 else if (start) |
| 157 state = SelectionStart; | 157 state = SelectionStart; |
| 158 else if (end) | 158 else if (end) |
| 159 state = SelectionEnd; | 159 state = SelectionEnd; |
| 160 else if ((state == SelectionEnd || startPos < m_start) | 160 else if ((state == SelectionEnd || startPos < m_start) |
| 161 && (state == SelectionStart || endPos > lastSelectable)) | 161 && (state == SelectionStart || endPos > lastSelectable)) |
| (...skipping 22 matching lines...) Expand all Loading... |
| 184 return state; | 184 return state; |
| 185 } | 185 } |
| 186 | 186 |
| 187 bool InlineTextBox::hasWrappedSelectionNewline() const | 187 bool InlineTextBox::hasWrappedSelectionNewline() const |
| 188 { | 188 { |
| 189 // TODO(wkorman): We shouldn't need layout at this point and it should | 189 // TODO(wkorman): We shouldn't need layout at this point and it should |
| 190 // be enforced by DocumentLifecycle. http://crbug.com/537821 | 190 // be enforced by DocumentLifecycle. http://crbug.com/537821 |
| 191 // Bail out as currently looking up selection state can cause the editing | 191 // Bail out as currently looking up selection state can cause the editing |
| 192 // code can force a re-layout while scrutinizing the editing position, and | 192 // code can force a re-layout while scrutinizing the editing position, and |
| 193 // InlineTextBox instances are not guaranteed to survive a re-layout. | 193 // InlineTextBox instances are not guaranteed to survive a re-layout. |
| 194 if (lineLayoutItem().needsLayout()) | 194 if (getLineLayoutItem().needsLayout()) |
| 195 return false; | 195 return false; |
| 196 | 196 |
| 197 SelectionState state = selectionState(); | 197 SelectionState state = getSelectionState(); |
| 198 return (state == SelectionStart || state == SelectionInside) | 198 return (state == SelectionStart || state == SelectionInside) |
| 199 // Checking last leaf child can be slow, so we make sure to do this only | 199 // Checking last leaf child can be slow, so we make sure to do this only |
| 200 // after the other simple conditionals. | 200 // after the other simple conditionals. |
| 201 && (root().lastLeafChild() == this) | 201 && (root().lastLeafChild() == this) |
| 202 // It's possible to have mixed LTR/RTL on a single line, and we only | 202 // It's possible to have mixed LTR/RTL on a single line, and we only |
| 203 // want to paint a newline when we're the last leaf child and we make | 203 // want to paint a newline when we're the last leaf child and we make |
| 204 // sure there isn't a differently-directioned box following us. | 204 // sure there isn't a differently-directioned box following us. |
| 205 && ((!isLeftToRightDirection() && root().firstSelectedBox() == this) | 205 && ((!isLeftToRightDirection() && root().firstSelectedBox() == this) |
| 206 || (isLeftToRightDirection() && root().lastSelectedBox() == this)); | 206 || (isLeftToRightDirection() && root().lastSelectedBox() == this)); |
| 207 } | 207 } |
| 208 | 208 |
| 209 float InlineTextBox::newlineSpaceWidth() const | 209 float InlineTextBox::newlineSpaceWidth() const |
| 210 { | 210 { |
| 211 const ComputedStyle& styleToUse = lineLayoutItem().styleRef(isFirstLineStyle
()); | 211 const ComputedStyle& styleToUse = getLineLayoutItem().styleRef(isFirstLineSt
yle()); |
| 212 return styleToUse.font().spaceWidth(); | 212 return styleToUse.font().spaceWidth(); |
| 213 } | 213 } |
| 214 | 214 |
| 215 LayoutRect InlineTextBox::localSelectionRect(int startPos, int endPos) const | 215 LayoutRect InlineTextBox::localSelectionRect(int startPos, int endPos) const |
| 216 { | 216 { |
| 217 int sPos = std::max(startPos - m_start, 0); | 217 int sPos = std::max(startPos - m_start, 0); |
| 218 int ePos = std::min(endPos - m_start, (int)m_len); | 218 int ePos = std::min(endPos - m_start, (int)m_len); |
| 219 | 219 |
| 220 if (sPos > ePos) | 220 if (sPos > ePos) |
| 221 return LayoutRect(); | 221 return LayoutRect(); |
| 222 | 222 |
| 223 FontCachePurgePreventer fontCachePurgePreventer; | 223 FontCachePurgePreventer fontCachePurgePreventer; |
| 224 | 224 |
| 225 LayoutUnit selTop = root().selectionTop(); | 225 LayoutUnit selTop = root().selectionTop(); |
| 226 LayoutUnit selHeight = root().selectionHeight(); | 226 LayoutUnit selHeight = root().selectionHeight(); |
| 227 const ComputedStyle& styleToUse = lineLayoutItem().styleRef(isFirstLineStyle
()); | 227 const ComputedStyle& styleToUse = getLineLayoutItem().styleRef(isFirstLineSt
yle()); |
| 228 const Font& font = styleToUse.font(); | 228 const Font& font = styleToUse.font(); |
| 229 | 229 |
| 230 StringBuilder charactersWithHyphen; | 230 StringBuilder charactersWithHyphen; |
| 231 bool respectHyphen = ePos == m_len && hasHyphen(); | 231 bool respectHyphen = ePos == m_len && hasHyphen(); |
| 232 TextRun textRun = constructTextRun(styleToUse, font, respectHyphen ? &charac
tersWithHyphen : 0); | 232 TextRun textRun = constructTextRun(styleToUse, font, respectHyphen ? &charac
tersWithHyphen : 0); |
| 233 | 233 |
| 234 LayoutPoint startingPoint = LayoutPoint(logicalLeft(), selTop); | 234 LayoutPoint startingPoint = LayoutPoint(logicalLeft(), selTop); |
| 235 LayoutRect r; | 235 LayoutRect r; |
| 236 if (sPos || ePos != static_cast<int>(m_len)) { | 236 if (sPos || ePos != static_cast<int>(m_len)) { |
| 237 r = LayoutRect(enclosingIntRect(font.selectionRectForText(textRun, Float
Point(startingPoint), selHeight, sPos, ePos))); | 237 r = LayoutRect(enclosingIntRect(font.selectionRectForText(textRun, Float
Point(startingPoint), selHeight, sPos, ePos))); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 267 // bottom-to-top situations. Add tests and ensure we handle correctly. | 267 // bottom-to-top situations. Add tests and ensure we handle correctly. |
| 268 if (hasWrappedSelectionNewline()) | 268 if (hasWrappedSelectionNewline()) |
| 269 height += newlineSpaceWidth(); | 269 height += newlineSpaceWidth(); |
| 270 } | 270 } |
| 271 | 271 |
| 272 return LayoutRect(topPoint, LayoutSize(width, height)); | 272 return LayoutRect(topPoint, LayoutSize(width, height)); |
| 273 } | 273 } |
| 274 | 274 |
| 275 void InlineTextBox::deleteLine() | 275 void InlineTextBox::deleteLine() |
| 276 { | 276 { |
| 277 lineLayoutItem().removeTextBox(this); | 277 getLineLayoutItem().removeTextBox(this); |
| 278 destroy(); | 278 destroy(); |
| 279 } | 279 } |
| 280 | 280 |
| 281 void InlineTextBox::extractLine() | 281 void InlineTextBox::extractLine() |
| 282 { | 282 { |
| 283 if (extracted()) | 283 if (extracted()) |
| 284 return; | 284 return; |
| 285 | 285 |
| 286 lineLayoutItem().extractTextBox(this); | 286 getLineLayoutItem().extractTextBox(this); |
| 287 } | 287 } |
| 288 | 288 |
| 289 void InlineTextBox::attachLine() | 289 void InlineTextBox::attachLine() |
| 290 { | 290 { |
| 291 if (!extracted()) | 291 if (!extracted()) |
| 292 return; | 292 return; |
| 293 | 293 |
| 294 lineLayoutItem().attachTextBox(this); | 294 getLineLayoutItem().attachTextBox(this); |
| 295 } | 295 } |
| 296 | 296 |
| 297 void InlineTextBox::setTruncation(unsigned truncation) | 297 void InlineTextBox::setTruncation(unsigned truncation) |
| 298 { | 298 { |
| 299 if (truncation == m_truncation) | 299 if (truncation == m_truncation) |
| 300 return; | 300 return; |
| 301 | 301 |
| 302 m_truncation = truncation; | 302 m_truncation = truncation; |
| 303 InlineTextBoxPainter::removeFromTextBlobCache(*this); | 303 InlineTextBoxPainter::removeFromTextBlobCache(*this); |
| 304 } | 304 } |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 352 setTruncation(cFullTruncation); | 352 setTruncation(cFullTruncation); |
| 353 truncatedWidth += ellipsisWidth; | 353 truncatedWidth += ellipsisWidth; |
| 354 return std::min(ellipsisX, logicalLeft()); | 354 return std::min(ellipsisX, logicalLeft()); |
| 355 } | 355 } |
| 356 | 356 |
| 357 // Set the truncation index on the text run. | 357 // Set the truncation index on the text run. |
| 358 setTruncation(offset); | 358 setTruncation(offset); |
| 359 | 359 |
| 360 // If we got here that means that we were only partially truncated and w
e need to return the pixel offset at which | 360 // If we got here that means that we were only partially truncated and w
e need to return the pixel offset at which |
| 361 // to place the ellipsis. | 361 // to place the ellipsis. |
| 362 LayoutUnit widthOfVisibleText(lineLayoutItem().width(m_start, offset, te
xtPos(), flowIsLTR ? LTR : RTL, isFirstLineStyle())); | 362 LayoutUnit widthOfVisibleText(getLineLayoutItem().width(m_start, offset,
textPos(), flowIsLTR ? LTR : RTL, isFirstLineStyle())); |
| 363 | 363 |
| 364 // The ellipsis needs to be placed just after the last visible character
. | 364 // The ellipsis needs to be placed just after the last visible character
. |
| 365 // Where "after" is defined by the flow directionality, not the inline | 365 // Where "after" is defined by the flow directionality, not the inline |
| 366 // box directionality. | 366 // box directionality. |
| 367 // e.g. In the case of an LTR inline box truncated in an RTL flow then w
e can | 367 // e.g. In the case of an LTR inline box truncated in an RTL flow then w
e can |
| 368 // have a situation such as |Hello| -> |...He| | 368 // have a situation such as |Hello| -> |...He| |
| 369 truncatedWidth += widthOfVisibleText + ellipsisWidth; | 369 truncatedWidth += widthOfVisibleText + ellipsisWidth; |
| 370 if (flowIsLTR) | 370 if (flowIsLTR) |
| 371 return logicalLeft() + widthOfVisibleText; | 371 return logicalLeft() + widthOfVisibleText; |
| 372 return logicalRight() - widthOfVisibleText - ellipsisWidth; | 372 return logicalRight() - widthOfVisibleText - ellipsisWidth; |
| 373 } | 373 } |
| 374 truncatedWidth += logicalWidth(); | 374 truncatedWidth += logicalWidth(); |
| 375 return LayoutUnit(-1); | 375 return LayoutUnit(-1); |
| 376 } | 376 } |
| 377 | 377 |
| 378 bool InlineTextBox::isLineBreak() const | 378 bool InlineTextBox::isLineBreak() const |
| 379 { | 379 { |
| 380 return lineLayoutItem().isBR() || (lineLayoutItem().style()->preserveNewline
() && len() == 1 && (*lineLayoutItem().text().impl())[start()] == '\n'); | 380 return getLineLayoutItem().isBR() || (getLineLayoutItem().style()->preserveN
ewline() && len() == 1 && (*getLineLayoutItem().text().impl())[start()] == '\n')
; |
| 381 } | 381 } |
| 382 | 382 |
| 383 bool InlineTextBox::nodeAtPoint(HitTestResult& result, const HitTestLocation& lo
cationInContainer, const LayoutPoint& accumulatedOffset, LayoutUnit /* lineTop *
/, LayoutUnit /*lineBottom*/) | 383 bool InlineTextBox::nodeAtPoint(HitTestResult& result, const HitTestLocation& lo
cationInContainer, const LayoutPoint& accumulatedOffset, LayoutUnit /* lineTop *
/, LayoutUnit /*lineBottom*/) |
| 384 { | 384 { |
| 385 if (isLineBreak() || m_truncation == cFullTruncation) | 385 if (isLineBreak() || m_truncation == cFullTruncation) |
| 386 return false; | 386 return false; |
| 387 | 387 |
| 388 LayoutPoint boxOrigin = locationIncludingFlipping(); | 388 LayoutPoint boxOrigin = locationIncludingFlipping(); |
| 389 boxOrigin.moveBy(accumulatedOffset); | 389 boxOrigin.moveBy(accumulatedOffset); |
| 390 LayoutRect rect(boxOrigin, size()); | 390 LayoutRect rect(boxOrigin, size()); |
| 391 if (visibleToHitTestRequest(result.hitTestRequest()) && locationInContainer.
intersects(rect)) { | 391 if (visibleToHitTestRequest(result.hitTestRequest()) && locationInContainer.
intersects(rect)) { |
| 392 lineLayoutItem().updateHitTestResult(result, flipForWritingMode(location
InContainer.point() - toLayoutSize(accumulatedOffset))); | 392 getLineLayoutItem().updateHitTestResult(result, flipForWritingMode(locat
ionInContainer.point() - toLayoutSize(accumulatedOffset))); |
| 393 if (result.addNodeToListBasedTestResult(lineLayoutItem().node(), locatio
nInContainer, rect) == StopHitTesting) | 393 if (result.addNodeToListBasedTestResult(getLineLayoutItem().node(), loca
tionInContainer, rect) == StopHitTesting) |
| 394 return true; | 394 return true; |
| 395 } | 395 } |
| 396 return false; | 396 return false; |
| 397 } | 397 } |
| 398 | 398 |
| 399 bool InlineTextBox::getEmphasisMarkPosition(const ComputedStyle& style, TextEmph
asisPosition& emphasisPosition) const | 399 bool InlineTextBox::getEmphasisMarkPosition(const ComputedStyle& style, TextEmph
asisPosition& emphasisPosition) const |
| 400 { | 400 { |
| 401 // This function returns true if there are text emphasis marks and they are
suppressed by ruby text. | 401 // This function returns true if there are text emphasis marks and they are
suppressed by ruby text. |
| 402 if (style.textEmphasisMark() == TextEmphasisMarkNone) | 402 if (style.textEmphasisMark() == TextEmphasisMarkNone) |
| 403 return false; | 403 return false; |
| 404 | 404 |
| 405 emphasisPosition = style.textEmphasisPosition(); | 405 emphasisPosition = style.textEmphasisPosition(); |
| 406 if (emphasisPosition == TextEmphasisPositionUnder) | 406 if (emphasisPosition == TextEmphasisPositionUnder) |
| 407 return true; // Ruby text is always over, so it cannot suppress emphasis
marks under. | 407 return true; // Ruby text is always over, so it cannot suppress emphasis
marks under. |
| 408 | 408 |
| 409 LineLayoutBox containingBlock = lineLayoutItem().containingBlock(); | 409 LineLayoutBox containingBlock = getLineLayoutItem().containingBlock(); |
| 410 if (!containingBlock.isRubyBase()) | 410 if (!containingBlock.isRubyBase()) |
| 411 return true; // This text is not inside a ruby base, so it does not have
ruby text over it. | 411 return true; // This text is not inside a ruby base, so it does not have
ruby text over it. |
| 412 | 412 |
| 413 if (!containingBlock.parent().isRubyRun()) | 413 if (!containingBlock.parent().isRubyRun()) |
| 414 return true; // Cannot get the ruby text. | 414 return true; // Cannot get the ruby text. |
| 415 | 415 |
| 416 LayoutRubyText* rubyText = LineLayoutRubyRun(containingBlock.parent()).rubyT
ext(); | 416 LayoutRubyText* rubyText = LineLayoutRubyRun(containingBlock.parent()).rubyT
ext(); |
| 417 | 417 |
| 418 // The emphasis marks over are suppressed only if there is a ruby text box a
nd it not empty. | 418 // The emphasis marks over are suppressed only if there is a ruby text box a
nd it not empty. |
| 419 return !rubyText || !rubyText->firstLineBox(); | 419 return !rubyText || !rubyText->firstLineBox(); |
| 420 } | 420 } |
| 421 | 421 |
| 422 void InlineTextBox::paint(const PaintInfo& paintInfo, const LayoutPoint& paintOf
fset, LayoutUnit /*lineTop*/, LayoutUnit /*lineBottom*/) const | 422 void InlineTextBox::paint(const PaintInfo& paintInfo, const LayoutPoint& paintOf
fset, LayoutUnit /*lineTop*/, LayoutUnit /*lineBottom*/) const |
| 423 { | 423 { |
| 424 InlineTextBoxPainter(*this).paint(paintInfo, paintOffset); | 424 InlineTextBoxPainter(*this).paint(paintInfo, paintOffset); |
| 425 } | 425 } |
| 426 | 426 |
| 427 void InlineTextBox::selectionStartEnd(int& sPos, int& ePos) const | 427 void InlineTextBox::selectionStartEnd(int& sPos, int& ePos) const |
| 428 { | 428 { |
| 429 int startPos, endPos; | 429 int startPos, endPos; |
| 430 if (lineLayoutItem().selectionState() == SelectionInside) { | 430 if (getLineLayoutItem().getSelectionState() == SelectionInside) { |
| 431 startPos = 0; | 431 startPos = 0; |
| 432 endPos = lineLayoutItem().textLength(); | 432 endPos = getLineLayoutItem().textLength(); |
| 433 } else { | 433 } else { |
| 434 lineLayoutItem().selectionStartEnd(startPos, endPos); | 434 getLineLayoutItem().selectionStartEnd(startPos, endPos); |
| 435 if (lineLayoutItem().selectionState() == SelectionStart) | 435 if (getLineLayoutItem().getSelectionState() == SelectionStart) |
| 436 endPos = lineLayoutItem().textLength(); | 436 endPos = getLineLayoutItem().textLength(); |
| 437 else if (lineLayoutItem().selectionState() == SelectionEnd) | 437 else if (getLineLayoutItem().getSelectionState() == SelectionEnd) |
| 438 startPos = 0; | 438 startPos = 0; |
| 439 } | 439 } |
| 440 | 440 |
| 441 sPos = std::max(startPos - m_start, 0); | 441 sPos = std::max(startPos - m_start, 0); |
| 442 ePos = std::min(endPos - m_start, (int)m_len); | 442 ePos = std::min(endPos - m_start, (int)m_len); |
| 443 } | 443 } |
| 444 | 444 |
| 445 void InlineTextBox::paintDocumentMarker(GraphicsContext& pt, const LayoutPoint&
boxOrigin, DocumentMarker* marker, const ComputedStyle& style, const Font& font,
bool grammar) const | 445 void InlineTextBox::paintDocumentMarker(GraphicsContext& pt, const LayoutPoint&
boxOrigin, DocumentMarker* marker, const ComputedStyle& style, const Font& font,
bool grammar) const |
| 446 { | 446 { |
| 447 InlineTextBoxPainter(*this).paintDocumentMarker(pt, boxOrigin, marker, style
, font, grammar); | 447 InlineTextBoxPainter(*this).paintDocumentMarker(pt, boxOrigin, marker, style
, font, grammar); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 479 int InlineTextBox::offsetForPosition(LayoutUnit lineOffset, bool includePartialG
lyphs) const | 479 int InlineTextBox::offsetForPosition(LayoutUnit lineOffset, bool includePartialG
lyphs) const |
| 480 { | 480 { |
| 481 if (isLineBreak()) | 481 if (isLineBreak()) |
| 482 return 0; | 482 return 0; |
| 483 | 483 |
| 484 if (lineOffset - logicalLeft() > logicalWidth()) | 484 if (lineOffset - logicalLeft() > logicalWidth()) |
| 485 return isLeftToRightDirection() ? len() : 0; | 485 return isLeftToRightDirection() ? len() : 0; |
| 486 if (lineOffset - logicalLeft() < 0) | 486 if (lineOffset - logicalLeft() < 0) |
| 487 return isLeftToRightDirection() ? 0 : len(); | 487 return isLeftToRightDirection() ? 0 : len(); |
| 488 | 488 |
| 489 LineLayoutText text = lineLayoutItem(); | 489 LineLayoutText text = getLineLayoutItem(); |
| 490 const ComputedStyle& style = text.styleRef(isFirstLineStyle()); | 490 const ComputedStyle& style = text.styleRef(isFirstLineStyle()); |
| 491 const Font& font = style.font(); | 491 const Font& font = style.font(); |
| 492 return font.offsetForPosition(constructTextRun(style, font), (lineOffset - l
ogicalLeft()).toFloat(), includePartialGlyphs); | 492 return font.offsetForPosition(constructTextRun(style, font), (lineOffset - l
ogicalLeft()).toFloat(), includePartialGlyphs); |
| 493 } | 493 } |
| 494 | 494 |
| 495 LayoutUnit InlineTextBox::positionForOffset(int offset) const | 495 LayoutUnit InlineTextBox::positionForOffset(int offset) const |
| 496 { | 496 { |
| 497 ASSERT(offset >= m_start); | 497 ASSERT(offset >= m_start); |
| 498 ASSERT(offset <= m_start + m_len); | 498 ASSERT(offset <= m_start + m_len); |
| 499 | 499 |
| 500 if (isLineBreak()) | 500 if (isLineBreak()) |
| 501 return logicalLeft(); | 501 return logicalLeft(); |
| 502 | 502 |
| 503 LineLayoutText text = lineLayoutItem(); | 503 LineLayoutText text = getLineLayoutItem(); |
| 504 const ComputedStyle& styleToUse = text.styleRef(isFirstLineStyle()); | 504 const ComputedStyle& styleToUse = text.styleRef(isFirstLineStyle()); |
| 505 const Font& font = styleToUse.font(); | 505 const Font& font = styleToUse.font(); |
| 506 int from = !isLeftToRightDirection() ? offset - m_start : 0; | 506 int from = !isLeftToRightDirection() ? offset - m_start : 0; |
| 507 int to = !isLeftToRightDirection() ? m_len : offset - m_start; | 507 int to = !isLeftToRightDirection() ? m_len : offset - m_start; |
| 508 // FIXME: Do we need to add rightBearing here? | 508 // FIXME: Do we need to add rightBearing here? |
| 509 return LayoutUnit(font.selectionRectForText(constructTextRun(styleToUse, fon
t), IntPoint(logicalLeft(), 0), 0, from, to).maxX()); | 509 return LayoutUnit(font.selectionRectForText(constructTextRun(styleToUse, fon
t), IntPoint(logicalLeft(), 0), 0, from, to).maxX()); |
| 510 } | 510 } |
| 511 | 511 |
| 512 bool InlineTextBox::containsCaretOffset(int offset) const | 512 bool InlineTextBox::containsCaretOffset(int offset) const |
| 513 { | 513 { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 532 // Offsets at the end are "in" for normal boxes (but the caller has to check
affinity). | 532 // Offsets at the end are "in" for normal boxes (but the caller has to check
affinity). |
| 533 return true; | 533 return true; |
| 534 } | 534 } |
| 535 | 535 |
| 536 void InlineTextBox::characterWidths(Vector<float>& widths) const | 536 void InlineTextBox::characterWidths(Vector<float>& widths) const |
| 537 { | 537 { |
| 538 if (!m_len) | 538 if (!m_len) |
| 539 return; | 539 return; |
| 540 | 540 |
| 541 FontCachePurgePreventer fontCachePurgePreventer; | 541 FontCachePurgePreventer fontCachePurgePreventer; |
| 542 ASSERT(lineLayoutItem().text()); | 542 ASSERT(getLineLayoutItem().text()); |
| 543 | 543 |
| 544 const ComputedStyle& styleToUse = lineLayoutItem().styleRef(isFirstLineStyle
()); | 544 const ComputedStyle& styleToUse = getLineLayoutItem().styleRef(isFirstLineSt
yle()); |
| 545 const Font& font = styleToUse.font(); | 545 const Font& font = styleToUse.font(); |
| 546 | 546 |
| 547 float lastWidth = 0; | 547 float lastWidth = 0; |
| 548 widths.resize(m_len); | 548 widths.resize(m_len); |
| 549 for (unsigned i = 0; i < m_len; i++) { | 549 for (unsigned i = 0; i < m_len; i++) { |
| 550 StringView substringView = lineLayoutItem().text().createView(); | 550 StringView substringView = getLineLayoutItem().text().createView(); |
| 551 substringView.narrow(start(), 1 + i); | 551 substringView.narrow(start(), 1 + i); |
| 552 TextRun textRun = constructTextRun(styleToUse, font, substringView, m_le
n); | 552 TextRun textRun = constructTextRun(styleToUse, font, substringView, m_le
n); |
| 553 widths[i] = font.width(textRun, nullptr, nullptr) - lastWidth; | 553 widths[i] = font.width(textRun, nullptr, nullptr) - lastWidth; |
| 554 lastWidth = font.width(textRun, nullptr, nullptr); | 554 lastWidth = font.width(textRun, nullptr, nullptr); |
| 555 } | 555 } |
| 556 } | 556 } |
| 557 | 557 |
| 558 TextRun InlineTextBox::constructTextRun(const ComputedStyle& style, const Font&
font, StringBuilder* charactersWithHyphen) const | 558 TextRun InlineTextBox::constructTextRun(const ComputedStyle& style, const Font&
font, StringBuilder* charactersWithHyphen) const |
| 559 { | 559 { |
| 560 ASSERT(lineLayoutItem().text()); | 560 ASSERT(getLineLayoutItem().text()); |
| 561 | 561 |
| 562 StringView string = lineLayoutItem().text().createView(); | 562 StringView string = getLineLayoutItem().text().createView(); |
| 563 unsigned startPos = start(); | 563 unsigned startPos = start(); |
| 564 unsigned length = len(); | 564 unsigned length = len(); |
| 565 | 565 |
| 566 if (string.length() != length || startPos) | 566 if (string.length() != length || startPos) |
| 567 string.narrow(startPos, length); | 567 string.narrow(startPos, length); |
| 568 | 568 |
| 569 return constructTextRun(style, font, string, lineLayoutItem().textLength() -
startPos, charactersWithHyphen); | 569 return constructTextRun(style, font, string, getLineLayoutItem().textLength(
) - startPos, charactersWithHyphen); |
| 570 } | 570 } |
| 571 | 571 |
| 572 TextRun InlineTextBox::constructTextRun(const ComputedStyle& style, const Font&
font, StringView string, int maximumLength, StringBuilder* charactersWithHyphen)
const | 572 TextRun InlineTextBox::constructTextRun(const ComputedStyle& style, const Font&
font, StringView string, int maximumLength, StringBuilder* charactersWithHyphen)
const |
| 573 { | 573 { |
| 574 if (charactersWithHyphen) { | 574 if (charactersWithHyphen) { |
| 575 const AtomicString& hyphenString = style.hyphenString(); | 575 const AtomicString& hyphenString = style.hyphenString(); |
| 576 charactersWithHyphen->reserveCapacity(string.length() + hyphenString.len
gth()); | 576 charactersWithHyphen->reserveCapacity(string.length() + hyphenString.len
gth()); |
| 577 charactersWithHyphen->append(string); | 577 charactersWithHyphen->append(string); |
| 578 charactersWithHyphen->append(hyphenString); | 578 charactersWithHyphen->append(hyphenString); |
| 579 string = charactersWithHyphen->toString().createView(); | 579 string = charactersWithHyphen->toString().createView(); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 602 return "InlineTextBox"; | 602 return "InlineTextBox"; |
| 603 } | 603 } |
| 604 | 604 |
| 605 String InlineTextBox::debugName() const | 605 String InlineTextBox::debugName() const |
| 606 { | 606 { |
| 607 return String(boxName()) + " '" + text() + "'"; | 607 return String(boxName()) + " '" + text() + "'"; |
| 608 } | 608 } |
| 609 | 609 |
| 610 String InlineTextBox::text() const | 610 String InlineTextBox::text() const |
| 611 { | 611 { |
| 612 return lineLayoutItem().text().substring(start(), len()); | 612 return getLineLayoutItem().text().substring(start(), len()); |
| 613 } | 613 } |
| 614 | 614 |
| 615 #ifndef NDEBUG | 615 #ifndef NDEBUG |
| 616 | 616 |
| 617 void InlineTextBox::showBox(int printedCharacters) const | 617 void InlineTextBox::showBox(int printedCharacters) const |
| 618 { | 618 { |
| 619 String value = text(); | 619 String value = text(); |
| 620 value.replaceWithLiteral('\\', "\\\\"); | 620 value.replaceWithLiteral('\\', "\\\\"); |
| 621 value.replaceWithLiteral('\n', "\\n"); | 621 value.replaceWithLiteral('\n', "\\n"); |
| 622 printedCharacters += fprintf(stderr, "%s %p", boxName(), this); | 622 printedCharacters += fprintf(stderr, "%s %p", boxName(), this); |
| 623 for (; printedCharacters < showTreeCharacterOffset; printedCharacters++) | 623 for (; printedCharacters < showTreeCharacterOffset; printedCharacters++) |
| 624 fputc(' ', stderr); | 624 fputc(' ', stderr); |
| 625 const LineLayoutText obj = lineLayoutItem(); | 625 const LineLayoutText obj = getLineLayoutItem(); |
| 626 printedCharacters = fprintf(stderr, "\t%s %p", obj.name(), obj.debugPointer(
)); | 626 printedCharacters = fprintf(stderr, "\t%s %p", obj.name(), obj.debugPointer(
)); |
| 627 const int layoutObjectCharacterOffset = 75; | 627 const int layoutObjectCharacterOffset = 75; |
| 628 for (; printedCharacters < layoutObjectCharacterOffset; printedCharacters++) | 628 for (; printedCharacters < layoutObjectCharacterOffset; printedCharacters++) |
| 629 fputc(' ', stderr); | 629 fputc(' ', stderr); |
| 630 fprintf(stderr, "(%d,%d) \"%s\"\n", start(), start() + len(), value.utf8().d
ata()); | 630 fprintf(stderr, "(%d,%d) \"%s\"\n", start(), start() + len(), value.utf8().d
ata()); |
| 631 } | 631 } |
| 632 | 632 |
| 633 #endif | 633 #endif |
| 634 | 634 |
| 635 } // namespace blink | 635 } // namespace blink |
| OLD | NEW |