| 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 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 199 | 199 |
| 200 LayoutUnit selTop = root().selectionTop(); | 200 LayoutUnit selTop = root().selectionTop(); |
| 201 LayoutUnit selHeight = root().selectionHeight(); | 201 LayoutUnit selHeight = root().selectionHeight(); |
| 202 RenderStyle* styleToUse = renderer().style(isFirstLineStyle()); | 202 RenderStyle* styleToUse = renderer().style(isFirstLineStyle()); |
| 203 const Font& font = styleToUse->font(); | 203 const Font& font = styleToUse->font(); |
| 204 | 204 |
| 205 StringBuilder charactersWithHyphen; | 205 StringBuilder charactersWithHyphen; |
| 206 bool respectHyphen = ePos == m_len && hasHyphen(); | 206 bool respectHyphen = ePos == m_len && hasHyphen(); |
| 207 TextRun textRun = constructTextRun(styleToUse, font, respectHyphen ? &charac
tersWithHyphen : 0); | 207 TextRun textRun = constructTextRun(styleToUse, font, respectHyphen ? &charac
tersWithHyphen : 0); |
| 208 | 208 |
| 209 FloatPoint startingPoint = FloatPoint(logicalLeft(), selTop.toFloat()); | 209 FloatPointWillBeLayoutPoint startingPoint = FloatPointWillBeLayoutPoint(logi
calLeft(), selTop.toFloat()); |
| 210 LayoutRect r; | 210 LayoutRect r; |
| 211 if (sPos || ePos != static_cast<int>(m_len)) | 211 if (sPos || ePos != static_cast<int>(m_len)) |
| 212 r = enclosingIntRect(font.selectionRectForText(textRun, startingPoint, s
elHeight, sPos, ePos)); | 212 r = enclosingIntRect(font.selectionRectForText(textRun, startingPoint, s
elHeight, sPos, ePos)); |
| 213 else // Avoid computing the font width when the entire line box is selected
as an optimization. | 213 else // Avoid computing the font width when the entire line box is selected
as an optimization. |
| 214 r = enclosingIntRect(FloatRect(startingPoint, FloatSize(m_logicalWidth,
selHeight.toFloat()))); | 214 r = enclosingIntRect(FloatRectWillBeLayoutRect(startingPoint, FloatSizeW
illBeLayoutSize(m_logicalWidth, selHeight.toFloat()))); |
| 215 | 215 |
| 216 LayoutUnit logicalWidth = r.width(); | 216 LayoutUnit logicalWidth = r.width(); |
| 217 if (r.x() > logicalRight()) | 217 if (r.x() > logicalRight()) |
| 218 logicalWidth = 0; | 218 logicalWidth = 0; |
| 219 else if (r.maxX() > logicalRight()) | 219 else if (r.maxX() > logicalRight()) |
| 220 logicalWidth = logicalRight() - r.x(); | 220 logicalWidth = logicalRight() - r.x(); |
| 221 | 221 |
| 222 LayoutPoint topPoint = isHorizontal() ? LayoutPoint(r.x(), selTop) : LayoutP
oint(selTop, r.x()); | 222 LayoutPoint topPoint = isHorizontal() ? LayoutPoint(r.x(), selTop) : LayoutP
oint(selTop, r.x()); |
| 223 LayoutUnit width = isHorizontal() ? logicalWidth : selHeight; | 223 LayoutUnit width = isHorizontal() ? logicalWidth : selHeight; |
| 224 LayoutUnit height = isHorizontal() ? selHeight : logicalWidth; | 224 LayoutUnit height = isHorizontal() ? selHeight : logicalWidth; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 241 } | 241 } |
| 242 | 242 |
| 243 void InlineTextBox::attachLine() | 243 void InlineTextBox::attachLine() |
| 244 { | 244 { |
| 245 if (!extracted()) | 245 if (!extracted()) |
| 246 return; | 246 return; |
| 247 | 247 |
| 248 renderer().attachTextBox(this); | 248 renderer().attachTextBox(this); |
| 249 } | 249 } |
| 250 | 250 |
| 251 float InlineTextBox::placeEllipsisBox(bool flowIsLTR, float visibleLeftEdge, flo
at visibleRightEdge, float ellipsisWidth, float &truncatedWidth, bool& foundBox) | 251 FloatWillBeLayoutUnit InlineTextBox::placeEllipsisBox(bool flowIsLTR, FloatWillB
eLayoutUnit visibleLeftEdge, FloatWillBeLayoutUnit visibleRightEdge, FloatWillBe
LayoutUnit ellipsisWidth, FloatWillBeLayoutUnit &truncatedWidth, bool& foundBox) |
| 252 { | 252 { |
| 253 if (foundBox) { | 253 if (foundBox) { |
| 254 m_truncation = cFullTruncation; | 254 m_truncation = cFullTruncation; |
| 255 return -1; | 255 return -1; |
| 256 } | 256 } |
| 257 | 257 |
| 258 // For LTR this is the left edge of the box, for RTL, the right edge in pare
nt coordinates. | 258 // For LTR this is the left edge of the box, for RTL, the right edge in pare
nt coordinates. |
| 259 float ellipsisX = flowIsLTR ? visibleRightEdge - ellipsisWidth : visibleLeft
Edge + ellipsisWidth; | 259 FloatWillBeLayoutUnit ellipsisX = flowIsLTR ? visibleRightEdge - ellipsisWid
th : visibleLeftEdge + ellipsisWidth; |
| 260 | 260 |
| 261 // Criteria for full truncation: | 261 // Criteria for full truncation: |
| 262 // LTR: the left edge of the ellipsis is to the left of our text run. | 262 // LTR: the left edge of the ellipsis is to the left of our text run. |
| 263 // RTL: the right edge of the ellipsis is to the right of our text run. | 263 // RTL: the right edge of the ellipsis is to the right of our text run. |
| 264 bool ltrFullTruncation = flowIsLTR && ellipsisX <= logicalLeft(); | 264 bool ltrFullTruncation = flowIsLTR && ellipsisX <= logicalLeft(); |
| 265 bool rtlFullTruncation = !flowIsLTR && ellipsisX >= logicalLeft() + logicalW
idth(); | 265 bool rtlFullTruncation = !flowIsLTR && ellipsisX >= logicalLeft() + logicalW
idth(); |
| 266 if (ltrFullTruncation || rtlFullTruncation) { | 266 if (ltrFullTruncation || rtlFullTruncation) { |
| 267 // Too far. Just set full truncation, but return -1 and let the ellipsi
s just be placed at the edge of the box. | 267 // Too far. Just set full truncation, but return -1 and let the ellipsi
s just be placed at the edge of the box. |
| 268 m_truncation = cFullTruncation; | 268 m_truncation = cFullTruncation; |
| 269 foundBox = true; | 269 foundBox = true; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 292 m_truncation = cFullTruncation; | 292 m_truncation = cFullTruncation; |
| 293 truncatedWidth += ellipsisWidth; | 293 truncatedWidth += ellipsisWidth; |
| 294 return std::min(ellipsisX, logicalLeft()); | 294 return std::min(ellipsisX, logicalLeft()); |
| 295 } | 295 } |
| 296 | 296 |
| 297 // Set the truncation index on the text run. | 297 // Set the truncation index on the text run. |
| 298 m_truncation = offset; | 298 m_truncation = offset; |
| 299 | 299 |
| 300 // If we got here that means that we were only partially truncated and w
e need to return the pixel offset at which | 300 // If we got here that means that we were only partially truncated and w
e need to return the pixel offset at which |
| 301 // to place the ellipsis. | 301 // to place the ellipsis. |
| 302 float widthOfVisibleText = renderer().width(m_start, offset, textPos(),
flowIsLTR ? LTR : RTL, isFirstLineStyle()); | 302 FloatWillBeLayoutUnit widthOfVisibleText = renderer().width(m_start, off
set, textPos(), flowIsLTR ? LTR : RTL, isFirstLineStyle()); |
| 303 | 303 |
| 304 // The ellipsis needs to be placed just after the last visible character
. | 304 // The ellipsis needs to be placed just after the last visible character
. |
| 305 // Where "after" is defined by the flow directionality, not the inline | 305 // Where "after" is defined by the flow directionality, not the inline |
| 306 // box directionality. | 306 // box directionality. |
| 307 // e.g. In the case of an LTR inline box truncated in an RTL flow then w
e can | 307 // e.g. In the case of an LTR inline box truncated in an RTL flow then w
e can |
| 308 // have a situation such as |Hello| -> |...He| | 308 // have a situation such as |Hello| -> |...He| |
| 309 truncatedWidth += widthOfVisibleText + ellipsisWidth; | 309 truncatedWidth += widthOfVisibleText + ellipsisWidth; |
| 310 if (flowIsLTR) | 310 if (flowIsLTR) |
| 311 return logicalLeft() + widthOfVisibleText; | 311 return logicalLeft() + widthOfVisibleText; |
| 312 else | 312 else |
| 313 return logicalRight() - widthOfVisibleText - ellipsisWidth; | 313 return logicalRight() - widthOfVisibleText - ellipsisWidth; |
| 314 } | 314 } |
| 315 truncatedWidth += logicalWidth(); | 315 truncatedWidth += logicalWidth(); |
| 316 return -1; | 316 return -1; |
| 317 } | 317 } |
| 318 | 318 |
| 319 bool InlineTextBox::isLineBreak() const | 319 bool InlineTextBox::isLineBreak() const |
| 320 { | 320 { |
| 321 return renderer().isBR() || (renderer().style()->preserveNewline() && len()
== 1 && (*renderer().text().impl())[start()] == '\n'); | 321 return renderer().isBR() || (renderer().style()->preserveNewline() && len()
== 1 && (*renderer().text().impl())[start()] == '\n'); |
| 322 } | 322 } |
| 323 | 323 |
| 324 bool InlineTextBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& re
sult, const HitTestLocation& locationInContainer, const LayoutPoint& accumulated
Offset, LayoutUnit /* lineTop */, LayoutUnit /*lineBottom*/) | 324 bool InlineTextBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& re
sult, const HitTestLocation& locationInContainer, const LayoutPoint& accumulated
Offset, LayoutUnit /* lineTop */, LayoutUnit /*lineBottom*/) |
| 325 { | 325 { |
| 326 if (isLineBreak()) | 326 if (isLineBreak()) |
| 327 return false; | 327 return false; |
| 328 | 328 |
| 329 FloatPoint boxOrigin = locationIncludingFlipping(); | 329 FloatPointWillBeLayoutPoint boxOrigin = locationIncludingFlipping(); |
| 330 boxOrigin.moveBy(accumulatedOffset); | 330 boxOrigin.moveBy(accumulatedOffset); |
| 331 FloatRect rect(boxOrigin, size()); | 331 FloatRectWillBeLayoutRect rect(boxOrigin, size()); |
| 332 if (m_truncation != cFullTruncation && visibleToHitTestRequest(request) && l
ocationInContainer.intersects(rect)) { | 332 if (m_truncation != cFullTruncation && visibleToHitTestRequest(request) && l
ocationInContainer.intersects(rect)) { |
| 333 renderer().updateHitTestResult(result, flipForWritingMode(locationInCont
ainer.point() - toLayoutSize(accumulatedOffset))); | 333 renderer().updateHitTestResult(result, flipForWritingMode(locationInCont
ainer.point() - toLayoutSize(accumulatedOffset))); |
| 334 if (!result.addNodeToRectBasedTestResult(renderer().node(), request, loc
ationInContainer, rect)) | 334 if (!result.addNodeToRectBasedTestResult(renderer().node(), request, loc
ationInContainer, rect)) |
| 335 return true; | 335 return true; |
| 336 } | 336 } |
| 337 return false; | 337 return false; |
| 338 } | 338 } |
| 339 | 339 |
| 340 bool InlineTextBox::getEmphasisMarkPosition(RenderStyle* style, TextEmphasisPosi
tion& emphasisPosition) const | 340 bool InlineTextBox::getEmphasisMarkPosition(RenderStyle* style, TextEmphasisPosi
tion& emphasisPosition) const |
| 341 { | 341 { |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 376 if (renderer().selectionState() == RenderObject::SelectionStart) | 376 if (renderer().selectionState() == RenderObject::SelectionStart) |
| 377 endPos = renderer().textLength(); | 377 endPos = renderer().textLength(); |
| 378 else if (renderer().selectionState() == RenderObject::SelectionEnd) | 378 else if (renderer().selectionState() == RenderObject::SelectionEnd) |
| 379 startPos = 0; | 379 startPos = 0; |
| 380 } | 380 } |
| 381 | 381 |
| 382 sPos = std::max(startPos - m_start, 0); | 382 sPos = std::max(startPos - m_start, 0); |
| 383 ePos = std::min(endPos - m_start, (int)m_len); | 383 ePos = std::min(endPos - m_start, (int)m_len); |
| 384 } | 384 } |
| 385 | 385 |
| 386 void InlineTextBox::paintDocumentMarker(GraphicsContext* pt, const FloatPoint& b
oxOrigin, DocumentMarker* marker, RenderStyle* style, const Font& font, bool gra
mmar) | 386 void InlineTextBox::paintDocumentMarker(GraphicsContext* pt, const FloatPointWil
lBeLayoutPoint& boxOrigin, DocumentMarker* marker, RenderStyle* style, const Fon
t& font, bool grammar) |
| 387 { | 387 { |
| 388 InlineTextBoxPainter(*this).paintDocumentMarker(pt, boxOrigin, marker, style
, font, grammar); | 388 InlineTextBoxPainter(*this).paintDocumentMarker(pt, boxOrigin, marker, style
, font, grammar); |
| 389 } | 389 } |
| 390 | 390 |
| 391 void InlineTextBox::paintTextMatchMarker(GraphicsContext* pt, const FloatPoint&
boxOrigin, DocumentMarker* marker, RenderStyle* style, const Font& font) | 391 void InlineTextBox::paintTextMatchMarker(GraphicsContext* pt, const FloatPointWi
llBeLayoutPoint& boxOrigin, DocumentMarker* marker, RenderStyle* style, const Fo
nt& font) |
| 392 { | 392 { |
| 393 InlineTextBoxPainter(*this).paintTextMatchMarker(pt, boxOrigin, marker, styl
e, font); | 393 InlineTextBoxPainter(*this).paintTextMatchMarker(pt, boxOrigin, marker, styl
e, font); |
| 394 } | 394 } |
| 395 | 395 |
| 396 int InlineTextBox::caretMinOffset() const | 396 int InlineTextBox::caretMinOffset() const |
| 397 { | 397 { |
| 398 return m_start; | 398 return m_start; |
| 399 } | 399 } |
| 400 | 400 |
| 401 int InlineTextBox::caretMaxOffset() const | 401 int InlineTextBox::caretMaxOffset() const |
| 402 { | 402 { |
| 403 return m_start + m_len; | 403 return m_start + m_len; |
| 404 } | 404 } |
| 405 | 405 |
| 406 float InlineTextBox::textPos() const | 406 FloatWillBeLayoutUnit InlineTextBox::textPos() const |
| 407 { | 407 { |
| 408 // When computing the width of a text run, RenderBlock::computeInlineDirecti
onPositionsForLine() doesn't include the actual offset | 408 // When computing the width of a text run, RenderBlock::computeInlineDirecti
onPositionsForLine() doesn't include the actual offset |
| 409 // from the containing block edge in its measurement. textPos() should be co
nsistent so the text are rendered in the same width. | 409 // from the containing block edge in its measurement. textPos() should be co
nsistent so the text are rendered in the same width. |
| 410 if (logicalLeft() == 0) | 410 if (logicalLeft() == 0) |
| 411 return 0; | 411 return 0; |
| 412 return logicalLeft() - root().logicalLeft(); | 412 return logicalLeft() - root().logicalLeft(); |
| 413 } | 413 } |
| 414 | 414 |
| 415 int InlineTextBox::offsetForPosition(float lineOffset, bool includePartialGlyphs
) const | 415 int InlineTextBox::offsetForPosition(FloatWillBeLayoutUnit lineOffset, bool incl
udePartialGlyphs) const |
| 416 { | 416 { |
| 417 if (isLineBreak()) | 417 if (isLineBreak()) |
| 418 return 0; | 418 return 0; |
| 419 | 419 |
| 420 if (lineOffset - logicalLeft() > logicalWidth()) | 420 if (lineOffset - logicalLeft() > logicalWidth()) |
| 421 return isLeftToRightDirection() ? len() : 0; | 421 return isLeftToRightDirection() ? len() : 0; |
| 422 if (lineOffset - logicalLeft() < 0) | 422 if (lineOffset - logicalLeft() < 0) |
| 423 return isLeftToRightDirection() ? 0 : len(); | 423 return isLeftToRightDirection() ? 0 : len(); |
| 424 | 424 |
| 425 FontCachePurgePreventer fontCachePurgePreventer; | 425 FontCachePurgePreventer fontCachePurgePreventer; |
| 426 | 426 |
| 427 RenderText& text = renderer(); | 427 RenderText& text = renderer(); |
| 428 RenderStyle* style = text.style(isFirstLineStyle()); | 428 RenderStyle* style = text.style(isFirstLineStyle()); |
| 429 const Font& font = style->font(); | 429 const Font& font = style->font(); |
| 430 return font.offsetForPosition(constructTextRun(style, font), lineOffset - lo
gicalLeft(), includePartialGlyphs); | 430 return font.offsetForPosition(constructTextRun(style, font), lineOffset - lo
gicalLeft(), includePartialGlyphs); |
| 431 } | 431 } |
| 432 | 432 |
| 433 float InlineTextBox::positionForOffset(int offset) const | 433 FloatWillBeLayoutUnit InlineTextBox::positionForOffset(int offset) const |
| 434 { | 434 { |
| 435 ASSERT(offset >= m_start); | 435 ASSERT(offset >= m_start); |
| 436 ASSERT(offset <= m_start + m_len); | 436 ASSERT(offset <= m_start + m_len); |
| 437 | 437 |
| 438 if (isLineBreak()) | 438 if (isLineBreak()) |
| 439 return logicalLeft(); | 439 return logicalLeft(); |
| 440 | 440 |
| 441 FontCachePurgePreventer fontCachePurgePreventer; | 441 FontCachePurgePreventer fontCachePurgePreventer; |
| 442 | 442 |
| 443 RenderText& text = renderer(); | 443 RenderText& text = renderer(); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 467 return false; | 467 return false; |
| 468 | 468 |
| 469 // Offsets at the end are "out" for line breaks (they are on the next line). | 469 // Offsets at the end are "out" for line breaks (they are on the next line). |
| 470 if (isLineBreak()) | 470 if (isLineBreak()) |
| 471 return false; | 471 return false; |
| 472 | 472 |
| 473 // Offsets at the end are "in" for normal boxes (but the caller has to check
affinity). | 473 // Offsets at the end are "in" for normal boxes (but the caller has to check
affinity). |
| 474 return true; | 474 return true; |
| 475 } | 475 } |
| 476 | 476 |
| 477 void InlineTextBox::characterWidths(Vector<float>& widths) const | 477 void InlineTextBox::characterWidths(Vector<FloatWillBeLayoutUnit>& widths) const |
| 478 { | 478 { |
| 479 FontCachePurgePreventer fontCachePurgePreventer; | 479 FontCachePurgePreventer fontCachePurgePreventer; |
| 480 | 480 |
| 481 RenderStyle* styleToUse = renderer().style(isFirstLineStyle()); | 481 RenderStyle* styleToUse = renderer().style(isFirstLineStyle()); |
| 482 const Font& font = styleToUse->font(); | 482 const Font& font = styleToUse->font(); |
| 483 | 483 |
| 484 TextRun textRun = constructTextRun(styleToUse, font); | 484 TextRun textRun = constructTextRun(styleToUse, font); |
| 485 | 485 |
| 486 SimpleShaper shaper(&font, textRun); | 486 SimpleShaper shaper(&font, textRun); |
| 487 float lastWidth = 0; | 487 FloatWillBeLayoutUnit lastWidth = 0; |
| 488 widths.resize(m_len); | 488 widths.resize(m_len); |
| 489 for (unsigned i = 0; i < m_len; i++) { | 489 for (unsigned i = 0; i < m_len; i++) { |
| 490 shaper.advance(i + 1); | 490 shaper.advance(i + 1); |
| 491 widths[i] = shaper.runWidthSoFar() - lastWidth; | 491 widths[i] = shaper.runWidthSoFar() - lastWidth; |
| 492 lastWidth = shaper.runWidthSoFar(); | 492 lastWidth = shaper.runWidthSoFar(); |
| 493 } | 493 } |
| 494 } | 494 } |
| 495 | 495 |
| 496 TextRun InlineTextBox::constructTextRun(RenderStyle* style, const Font& font, St
ringBuilder* charactersWithHyphen) const | 496 TextRun InlineTextBox::constructTextRun(RenderStyle* style, const Font& font, St
ringBuilder* charactersWithHyphen) const |
| 497 { | 497 { |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 558 printedCharacters = fprintf(stderr, "\t%s %p", obj.renderName(), &obj); | 558 printedCharacters = fprintf(stderr, "\t%s %p", obj.renderName(), &obj); |
| 559 const int rendererCharacterOffset = 24; | 559 const int rendererCharacterOffset = 24; |
| 560 for (; printedCharacters < rendererCharacterOffset; printedCharacters++) | 560 for (; printedCharacters < rendererCharacterOffset; printedCharacters++) |
| 561 fputc(' ', stderr); | 561 fputc(' ', stderr); |
| 562 fprintf(stderr, "(%d,%d) \"%s\"\n", start(), start() + len(), value.utf8().d
ata()); | 562 fprintf(stderr, "(%d,%d) \"%s\"\n", start(), start() + len(), value.utf8().d
ata()); |
| 563 } | 563 } |
| 564 | 564 |
| 565 #endif | 565 #endif |
| 566 | 566 |
| 567 } // namespace blink | 567 } // namespace blink |
| OLD | NEW |