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