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 |