[line-clamp] Place the line-clamp ellipsis during line breaking

The current behavior of both `text-overflow: ellipsis` and
`(-webkit-)line-clamp` with respect to positioning the ellipsis is
that after the inline items are positioned, glyphs and other inline
items will be truncated from the visual end of the line until there is
enough space for the ellipsis to fit in the line box, and then the
ellipsis is placed at that position.

For `(-webkit-)line-clamp`, this disagrees with the upcoming
specification, which says that rather than truncating glyphs one by
one, instead all inline content should be truncated until the last
break opportunity where the ellipsis would fit. Furthermore, inline
content should be truncated logically, rather than visually.
And there is an open discussion in
https://github.com/w3c/csswg-drafts/issues/10844 about where the
ellipsis should be positioned in bidi content, which might not be at
the visual end of the line.

This means that the ellipsis should be taken into account at the line
breaking phase. We tried laying out the ellipsis as part of
`LineBreaker` and somehow including it in the `InlineItemResult`s it
produces, but we found it was not always feasible. Instead, we shape
the ellipsis in the `InlineLayoutAlgorithm`, pass its width to
`LineBreaker`, and then in `LogicalLineBuilder` we add a
`LogicalLineItem` for the ellipsis just before bidi reordering.

This also fixes a long-standing bug where lines with the `line-clamp`
ellipsis were not properly aligned or justified (bug 40265829). This
happened because the line content was only trimmed, and the ellipsis
was only shaped, after every `LogicalLineItem` was positioned
according to the alignment and justification. With this patch, since
the trimming and ellipsis shaping happens during line breaking, and
the ellipsis `LogicalLineItem` is created at the same time as other
`LogicalLineItem`s, the ellipsis behaves the same as any other inline
content for alignment and justification.

Some WPT and internal tests break with this change. Some of them are
tests that were written expecting the previous behavior, and probably
need to be updated. But others show that this implementation is
incomplete. Therefore, we are putting this behind the runtime feature
`CSSLineClampLineBreakingEllipsis`.

Bug: 40336192, 40265829
Change-Id: I2d5a645899734b8dea5b0929906b7835b45bd50e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6106171
Reviewed-by: Andreu Botella <abotella@igalia.com>
Reviewed-by: Koji Ishii <kojii@chromium.org>
Commit-Queue: Andreu Botella <abotella@igalia.com>
Cr-Commit-Position: refs/heads/main@{#1405438}
33 files changed
tree: 92629ce937a987ce2629a17db5aca1a71faaec18
  1. android_webview/
  2. apps/
  3. ash/
  4. base/
  5. build/
  6. build_overrides/
  7. buildtools/
  8. cc/
  9. chrome/
  10. chromecast/
  11. chromeos/
  12. codelabs/
  13. components/
  14. content/
  15. crypto/
  16. dbus/
  17. device/
  18. docs/
  19. extensions/
  20. fuchsia_web/
  21. gin/
  22. google_apis/
  23. gpu/
  24. headless/
  25. infra/
  26. ios/
  27. ipc/
  28. media/
  29. mojo/
  30. native_client_sdk/
  31. net/
  32. pdf/
  33. ppapi/
  34. printing/
  35. remoting/
  36. rlz/
  37. sandbox/
  38. services/
  39. skia/
  40. sql/
  41. storage/
  42. styleguide/
  43. testing/
  44. third_party/
  45. tools/
  46. ui/
  47. url/
  48. webkit/
  49. .clang-format
  50. .clang-tidy
  51. .clangd
  52. .git-blame-ignore-revs
  53. .gitallowed
  54. .gitattributes
  55. .gitignore
  56. .gitmodules
  57. .gn
  58. .mailmap
  59. .rustfmt.toml
  60. .vpython3
  61. .yapfignore
  62. ATL_OWNERS
  63. AUTHORS
  64. BUILD.gn
  65. CODE_OF_CONDUCT.md
  66. codereview.settings
  67. CPPLINT.cfg
  68. CRYPTO_OWNERS
  69. DEPS
  70. DIR_METADATA
  71. LICENSE
  72. LICENSE.chromium_os
  73. OWNERS
  74. PRESUBMIT.py
  75. PRESUBMIT_test.py
  76. PRESUBMIT_test_mocks.py
  77. README.md
  78. WATCHLISTS
README.md

Logo Chromium

Chromium is an open-source browser project that aims to build a safer, faster, and more stable way for all users to experience the web.

The project's web site is https://www.chromium.org.

To check out the source code locally, don't use git clone! Instead, follow the instructions on how to get the code.

Documentation in the source is rooted in docs/README.md.

Learn how to Get Around the Chromium Source Code Directory Structure.

For historical reasons, there are some small top level directories. Now the guidance is that new top level directories are for product (e.g. Chrome, Android WebView, Ash). Even if these products have multiple executables, the code should be in subdirectories of the product.

If you found a bug, please file it at https://crbug.com/new.