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

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

Issue 2699393002: Place ellipsis correctly inside inline-blocks (Closed)
Patch Set: Created 3 years, 10 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 299 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698