Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(203)

Side by Side Diff: third_party/WebKit/Source/core/layout/line/InlineTextBox.cpp

Issue 2699393002: Place ellipsis correctly inside inline-blocks (Closed)
Patch Set: bug 133700 Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/layout/line/InlineTextBox.h ('k') | third_party/WebKit/Source/core/layout/line/RootInlineBox.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698