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. | 4 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. |
5 * All rights reserved. | 5 * All rights reserved. |
6 * | 6 * |
7 * This library is free software; you can redistribute it and/or | 7 * This library is free software; you can redistribute it and/or |
8 * modify it under the terms of the GNU Library General Public | 8 * modify it under the terms of the GNU Library General Public |
9 * License as published by the Free Software Foundation; either | 9 * License as published by the Free Software Foundation; either |
10 * version 2 of the License, or (at your option) any later version. | 10 * version 2 of the License, or (at your option) any later version. |
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
310 | 310 |
311 void InlineTextBox::clearTruncation() { | 311 void InlineTextBox::clearTruncation() { |
312 setTruncation(cNoTruncation); | 312 setTruncation(cNoTruncation); |
313 } | 313 } |
314 | 314 |
315 LayoutUnit InlineTextBox::placeEllipsisBox(bool flowIsLTR, | 315 LayoutUnit InlineTextBox::placeEllipsisBox(bool flowIsLTR, |
316 LayoutUnit visibleLeftEdge, | 316 LayoutUnit visibleLeftEdge, |
317 LayoutUnit visibleRightEdge, | 317 LayoutUnit visibleRightEdge, |
318 LayoutUnit ellipsisWidth, | 318 LayoutUnit ellipsisWidth, |
319 LayoutUnit& truncatedWidth, | 319 LayoutUnit& truncatedWidth, |
320 bool& foundBox) { | 320 bool& foundBox, |
| 321 LayoutUnit logicalLeftOffset) { |
321 if (foundBox) { | 322 if (foundBox) { |
322 setTruncation(cFullTruncation); | 323 setTruncation(cFullTruncation); |
323 return LayoutUnit(-1); | 324 return LayoutUnit(-1); |
324 } | 325 } |
325 | 326 |
| 327 // Criteria for full truncation: |
| 328 // LTR: the left edge of the ellipsis is to the left of our text run. |
| 329 // RTL: the right edge of the ellipsis is to the right of our text run. |
| 330 LayoutUnit adjustedLogicalLeft = logicalLeftOffset + logicalLeft(); |
| 331 |
326 // For LTR this is the left edge of the box, for RTL, the right edge in parent | 332 // For LTR this is the left edge of the box, for RTL, the right edge in parent |
327 // coordinates. | 333 // coordinates. |
328 LayoutUnit ellipsisX = flowIsLTR ? visibleRightEdge - ellipsisWidth | 334 LayoutUnit ellipsisX = flowIsLTR ? visibleRightEdge - ellipsisWidth |
329 : visibleLeftEdge + ellipsisWidth; | 335 : visibleLeftEdge + ellipsisWidth; |
330 | 336 |
331 // Criteria for full truncation: | 337 if (isLeftToRightDirection() == flowIsLTR && !flowIsLTR && |
332 // LTR: the left edge of the ellipsis is to the left of our text run. | 338 logicalLeftOffset < 0) |
333 // RTL: the right edge of the ellipsis is to the right of our text run. | 339 ellipsisX -= logicalLeftOffset; |
334 bool ltrFullTruncation = flowIsLTR && ellipsisX <= logicalLeft(); | 340 |
| 341 bool ltrFullTruncation = flowIsLTR && ellipsisX <= adjustedLogicalLeft; |
335 bool rtlFullTruncation = | 342 bool rtlFullTruncation = |
336 !flowIsLTR && ellipsisX >= logicalLeft() + logicalWidth(); | 343 !flowIsLTR && ellipsisX > adjustedLogicalLeft + logicalWidth(); |
337 if (ltrFullTruncation || rtlFullTruncation) { | 344 if (ltrFullTruncation || rtlFullTruncation) { |
338 // Too far. Just set full truncation, but return -1 and let the ellipsis | 345 // Too far. Just set full truncation, but return -1 and let the ellipsis |
339 // just be placed at the edge of the box. | 346 // just be placed at the edge of the box. |
340 setTruncation(cFullTruncation); | 347 setTruncation(cFullTruncation); |
341 foundBox = true; | 348 foundBox = true; |
342 return LayoutUnit(-1); | 349 return LayoutUnit(-1); |
343 } | 350 } |
344 | 351 |
345 bool ltrEllipsisWithinBox = flowIsLTR && (ellipsisX < logicalRight()); | 352 bool ltrEllipsisWithinBox = |
346 bool rtlEllipsisWithinBox = !flowIsLTR && (ellipsisX > logicalLeft()); | 353 flowIsLTR && ellipsisX < adjustedLogicalLeft + logicalWidth(); |
| 354 bool rtlEllipsisWithinBox = !flowIsLTR && ellipsisX > adjustedLogicalLeft; |
347 if (ltrEllipsisWithinBox || rtlEllipsisWithinBox) { | 355 if (ltrEllipsisWithinBox || rtlEllipsisWithinBox) { |
348 foundBox = true; | 356 foundBox = true; |
349 | 357 |
350 // The inline box may have different directionality than it's parent. Since | 358 // The inline box may have different directionality than it's parent. Since |
351 // truncation behavior depends both on both the parent and the inline | 359 // truncation behavior depends both on both the parent and the inline |
352 // block's directionality, we must keep track of these separately. | 360 // block's directionality, we must keep track of these separately. |
353 bool ltr = isLeftToRightDirection(); | 361 bool ltr = isLeftToRightDirection(); |
354 if (ltr != flowIsLTR) { | 362 if (ltr != flowIsLTR) { |
355 // Width in pixels of the visible portion of the box, excluding the | 363 // Width in pixels of the visible portion of the box, excluding the |
356 // ellipsis. | 364 // ellipsis. |
357 LayoutUnit visibleBoxWidth = | 365 LayoutUnit visibleBoxWidth = |
358 visibleRightEdge - visibleLeftEdge - ellipsisWidth; | 366 visibleRightEdge - visibleLeftEdge - ellipsisWidth; |
359 ellipsisX = flowIsLTR ? logicalLeft() + visibleBoxWidth | 367 ellipsisX = flowIsLTR ? adjustedLogicalLeft + visibleBoxWidth |
360 : logicalRight() - visibleBoxWidth; | 368 : logicalRight() - visibleBoxWidth; |
361 } | 369 } |
362 | 370 |
363 // The box's width includes partial glyphs, so respect that when placing | 371 // The box's width includes partial glyphs, so respect that when placing |
364 // the ellipsis. | 372 // the ellipsis. |
365 int offset = offsetForPosition(ellipsisX); | 373 int offset = offsetForPosition(ellipsisX); |
366 if (offset == 0 && ltr == flowIsLTR) { | 374 // Full truncation is only necessary when we're flowing left-to-right. |
| 375 if (flowIsLTR && offset == 0 && ltr == flowIsLTR) { |
367 // No characters should be laid out. Set ourselves to full truncation and | 376 // No characters should be laid out. Set ourselves to full truncation and |
368 // place the ellipsis at the min of our start and the ellipsis edge. | 377 // place the ellipsis at the min of our start and the ellipsis edge. |
369 setTruncation(cFullTruncation); | 378 setTruncation(cFullTruncation); |
370 truncatedWidth += ellipsisWidth; | 379 truncatedWidth += ellipsisWidth; |
371 return std::min(ellipsisX, logicalLeft()); | 380 return std::min(ellipsisX, logicalLeft()); |
372 } | 381 } |
373 | 382 |
374 // Set the truncation index on the text run. | 383 // Set the truncation index on the text run. |
375 setTruncation(offset); | 384 setTruncation(offset); |
376 | 385 |
377 // If we got here that means that we were only partially truncated and we | 386 // If we got here that means that we were only partially truncated and we |
378 // need to return the pixel offset at which to place the ellipsis. Where the | 387 // need to return the pixel offset at which to place the ellipsis. Where the |
379 // text and its flow have opposite directions then our offset into the text | 388 // text and its flow have opposite directions then our offset into the text |
380 // is at the start of the part that will be visible. | 389 // is at the start of the part that will be visible. |
381 LayoutUnit widthOfVisibleText(getLineLayoutItem().width( | 390 LayoutUnit widthOfVisibleText(getLineLayoutItem().width( |
382 ltr == flowIsLTR ? m_start : m_start + offset, | 391 ltr == flowIsLTR ? m_start : m_start + offset, |
383 ltr == flowIsLTR ? offset : m_len - offset, textPos(), | 392 ltr == flowIsLTR ? offset : m_len - offset, textPos(), |
384 flowIsLTR ? TextDirection::kLtr : TextDirection::kRtl, | 393 flowIsLTR ? TextDirection::kLtr : TextDirection::kRtl, |
385 isFirstLineStyle())); | 394 isFirstLineStyle())); |
386 | 395 |
387 // The ellipsis needs to be placed just after the last visible character. | 396 // The ellipsis needs to be placed just after the last visible character. |
388 // Where "after" is defined by the flow directionality, not the inline | 397 // Where "after" is defined by the flow directionality, not the inline |
389 // box directionality. | 398 // box directionality. |
390 // e.g. In the case of an LTR inline box truncated in an RTL flow then we | 399 // e.g. In the case of an LTR inline box truncated in an RTL flow then we |
391 // can have a situation such as |Hello| -> |...He| | 400 // can have a situation such as |Hello| -> |...He| |
392 truncatedWidth += widthOfVisibleText + ellipsisWidth; | 401 truncatedWidth += widthOfVisibleText + ellipsisWidth; |
393 if (flowIsLTR) | 402 if (flowIsLTR) |
394 return logicalLeft() + widthOfVisibleText; | 403 return logicalLeft() + widthOfVisibleText; |
395 return logicalRight() - widthOfVisibleText - ellipsisWidth; | 404 LayoutUnit result = logicalRight() - widthOfVisibleText - ellipsisWidth; |
| 405 return result; |
396 } | 406 } |
397 truncatedWidth += logicalWidth(); | 407 truncatedWidth += logicalWidth(); |
398 return LayoutUnit(-1); | 408 return LayoutUnit(-1); |
399 } | 409 } |
400 | 410 |
401 bool InlineTextBox::isLineBreak() const { | 411 bool InlineTextBox::isLineBreak() const { |
402 return getLineLayoutItem().isBR() || | 412 return getLineLayoutItem().isBR() || |
403 (getLineLayoutItem().style()->preserveNewline() && len() == 1 && | 413 (getLineLayoutItem().style()->preserveNewline() && len() == 1 && |
404 (*getLineLayoutItem().text().impl())[start()] == '\n'); | 414 (*getLineLayoutItem().text().impl())[start()] == '\n'); |
405 } | 415 } |
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
688 const int layoutObjectCharacterOffset = 75; | 698 const int layoutObjectCharacterOffset = 75; |
689 for (; printedCharacters < layoutObjectCharacterOffset; printedCharacters++) | 699 for (; printedCharacters < layoutObjectCharacterOffset; printedCharacters++) |
690 fputc(' ', stderr); | 700 fputc(' ', stderr); |
691 fprintf(stderr, "(%d,%d) \"%s\"\n", start(), start() + len(), | 701 fprintf(stderr, "(%d,%d) \"%s\"\n", start(), start() + len(), |
692 value.utf8().data()); | 702 value.utf8().data()); |
693 } | 703 } |
694 | 704 |
695 #endif | 705 #endif |
696 | 706 |
697 } // namespace blink | 707 } // namespace blink |
OLD | NEW |