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 |