1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
|
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_VIEWS_TABS_FILENAME_ELIDER_H_
#define CHROME_BROWSER_UI_VIEWS_TABS_FILENAME_ELIDER_H_
#include <stddef.h>
#include <string>
#include <string_view>
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/render_text.h"
// Helper class used to elide local filenames with a RenderText object that
// is provided with the correct setup and formatting.
class FilenameElider {
public:
using LineLengths = std::pair<size_t, size_t>;
explicit FilenameElider(std::unique_ptr<gfx::RenderText> render_text);
~FilenameElider();
// Returns the elided text. Equivalent to:
// Elide(GetLineLengths(display_rect))
// See those methods for a detailed description.
std::u16string Elide(std::u16string_view text,
const gfx::Rect& display_rect) const;
// Returns the start of the image dimensions as typically formatted by
// Chrome in page titles, as a hint at how to potentially elide or split
// the title. Expects something in the format "title (width×height)".
// Returns std::u16string::npos if this pattern isn't found, otherwise
// returns the index of the opening parenthesis in the string.
//
// If the result isn't npos, then the character previous to the open paren
// character is guaranteed to be whitespace.
static size_t FindImageDimensions(std::u16string_view text);
private:
friend class TabHoverCardBubbleViewFilenameEliderTest;
// Given the current text and a rectangle to display text in, returns the
// maximum length in characters of the first and second lines.
//
// The first value is the number of characters from the beginning of the
// text that will fit on the line. The second value is the number of
// characters from the end of the text that will fit on a line, minus
// enough space to insert an ellipsis.
//
// Note that the sum of the two values may be greater than the length of
// the text. Both segments are guaranteed to end at grapheme boundaries.
LineLengths GetLineLengths(const gfx::Rect& display_rect) const;
// Returns a string formatted for two-line elision given the last string
// passed to SetText() and the maximum extent of the first and second
// lines. The resulting string will either be the original text (if it fits
// on one line) or the first line, followed by a newline, an ellipsis, and
// the second line. The cut points passed in must be at grapheme
// boundaries.
//
// If the two lines overlap (that is, if the line lengths sum to more than
// the length of the original text), an optimum breakpoint will be chosen
// to insert the newline:
// * If possible, the extension (and if it's an image, the image
// dimensions) will be placed alone on the second line.
// * Otherwise, as many characters as possible will be placed on the first
// line.
// TODO(dfried): consider optimizing to break at natural breaks: spaces,
// punctuation, etc.
//
// Note that if the extension is isolated on the second line or an ellipsis
// is inserted, the second line will be marked as a bidirectional isolate,
// so that its direction is determined by the leading text on the line
// rather than whatever is "left over" from the first line. We find this
// produces a much more visually appealing and less confusing result than
// inheriting the preceding directionality.
std::u16string ElideImpl(LineLengths line_lengths) const;
std::unique_ptr<gfx::RenderText> render_text_;
};
#endif // CHROME_BROWSER_UI_VIEWS_TABS_FILENAME_ELIDER_H_
|