diff options
author | yukishiino@chromium.org <yukishiino@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-22 07:20:05 +0000 |
---|---|---|
committer | yukishiino@chromium.org <yukishiino@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-22 07:20:05 +0000 |
commit | ad8d9d577af1a4cb79c7dbbf4b57b1156a6f0143 (patch) | |
tree | 4667e32b426f21c4c7d5c6364a94e2f0ce33da29 /ui | |
parent | 103ff3515ea4c37d7924fca6fee61d83da8d2744 (diff) | |
download | chromium_src-ad8d9d577af1a4cb79c7dbbf4b57b1156a6f0143.zip chromium_src-ad8d9d577af1a4cb79c7dbbf4b57b1156a6f0143.tar.gz chromium_src-ad8d9d577af1a4cb79c7dbbf4b57b1156a6f0143.tar.bz2 |
Supports gfx::FontList in gfx::Canvas and ui::ElideText family.
This is a part of the plan to support gfx::FontList in views::Label.
https://docs.google.com/a/chromium.org/document/d/1D_25fp9B8b9aZJORfAjDIFq61NWvUquZ5xmKH-VcC4k/edit
BUG=265485
Review URL: https://chromiumcodereview.appspot.com/22835002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@218926 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui')
-rw-r--r-- | ui/base/cocoa/menu_controller.mm | 1 | ||||
-rw-r--r-- | ui/base/text/text_elider.cc | 184 | ||||
-rw-r--r-- | ui/base/text/text_elider.h | 45 | ||||
-rw-r--r-- | ui/gfx/canvas.cc | 258 | ||||
-rw-r--r-- | ui/gfx/canvas.h | 227 | ||||
-rw-r--r-- | ui/gfx/canvas_android.cc | 26 | ||||
-rw-r--r-- | ui/gfx/canvas_mac.mm | 39 | ||||
-rw-r--r-- | ui/gfx/canvas_skia.cc | 120 | ||||
-rw-r--r-- | ui/gfx/text_utils.h | 7 | ||||
-rw-r--r-- | ui/gfx/text_utils_android.cc | 16 | ||||
-rw-r--r-- | ui/gfx/text_utils_ios.mm | 22 | ||||
-rw-r--r-- | ui/gfx/text_utils_skia.cc | 15 | ||||
-rw-r--r-- | ui/ui.gyp | 8 | ||||
-rw-r--r-- | ui/views/widget/tooltip_manager.cc | 1 |
14 files changed, 646 insertions, 323 deletions
diff --git a/ui/base/cocoa/menu_controller.mm b/ui/base/cocoa/menu_controller.mm index 11792849..ebec346 100644 --- a/ui/base/cocoa/menu_controller.mm +++ b/ui/base/cocoa/menu_controller.mm @@ -12,6 +12,7 @@ #include "ui/base/l10n/l10n_util_mac.h" #include "ui/base/models/simple_menu_model.h" #include "ui/base/text/text_elider.h" +#include "ui/gfx/font.h" #include "ui/gfx/image/image.h" @interface MenuController (Private) diff --git a/ui/base/text/text_elider.cc b/ui/base/text/text_elider.cc index 0590981..76dbb71 100644 --- a/ui/base/text/text_elider.cc +++ b/ui/base/text/text_elider.cc @@ -26,7 +26,8 @@ #include "net/base/registry_controlled_domains/registry_controlled_domain.h" #include "third_party/icu/source/common/unicode/rbbi.h" #include "third_party/icu/source/common/unicode/uloc.h" -#include "ui/gfx/font.h" +#include "ui/gfx/font_list.h" +#include "ui/gfx/text_utils.h" #include "url/gurl.h" namespace ui { @@ -115,7 +116,7 @@ string16 BuildPathFromComponents(const string16& path_prefix, // Add |filename|, ellipsis if necessary. if (num_components != (path_elements.size() - 1)) - path += UTF8ToUTF16(kEllipsis) + kForwardSlash; + path += string16(kEllipsisUTF16) + kForwardSlash; path += filename; return path; @@ -128,7 +129,7 @@ string16 ElideComponentizedPath(const string16& url_path_prefix, const std::vector<string16>& url_path_elements, const string16& url_filename, const string16& url_query, - const gfx::Font& font, + const gfx::FontList& font_list, int available_pixel_width) { const size_t url_path_number_of_elements = url_path_elements.size(); @@ -136,9 +137,9 @@ string16 ElideComponentizedPath(const string16& url_path_prefix, for (size_t i = url_path_number_of_elements - 1; i > 0; --i) { string16 elided_path = BuildPathFromComponents(url_path_prefix, url_path_elements, url_filename, i); - if (available_pixel_width >= font.GetStringWidth(elided_path)) - return ElideText(elided_path + url_query, - font, available_pixel_width, ELIDE_AT_END); + if (available_pixel_width >= gfx::GetStringWidth(elided_path, font_list)) + return ElideText(elided_path + url_query, font_list, + available_pixel_width, ELIDE_AT_END); } return string16(); @@ -147,9 +148,9 @@ string16 ElideComponentizedPath(const string16& url_path_prefix, } // namespace string16 ElideEmail(const string16& email, - const gfx::Font& font, + const gfx::FontList& font_list, int available_pixel_width) { - if (font.GetStringWidth(email) <= available_pixel_width) + if (gfx::GetStringWidth(email, font_list) <= available_pixel_width) return email; // Split the email into its local-part (username) and domain-part. The email @@ -166,16 +167,17 @@ string16 ElideEmail(const string16& email, // Subtract the @ symbol from the available width as it is mandatory. const string16 kAtSignUTF16 = ASCIIToUTF16("@"); - available_pixel_width -= font.GetStringWidth(kAtSignUTF16); + available_pixel_width -= gfx::GetStringWidth(kAtSignUTF16, font_list); // Check whether eliding the domain is necessary: if eliding the username // is sufficient, the domain will not be elided. - const int full_username_width = font.GetStringWidth(username); + const int full_username_width = gfx::GetStringWidth(username, font_list); const int available_domain_width = available_pixel_width - std::min(full_username_width, - font.GetStringWidth(username.substr(0, 1) + kEllipsisUTF16)); - if (font.GetStringWidth(domain) > available_domain_width) { + gfx::GetStringWidth(username.substr(0, 1) + kEllipsisUTF16, + font_list)); + if (gfx::GetStringWidth(domain, font_list) > available_domain_width) { // Elide the domain so that it only takes half of the available width. // Should the username not need all the width available in its half, the // domain will occupy the leftover width. @@ -186,7 +188,8 @@ string16 ElideEmail(const string16& email, std::min(available_domain_width, std::max(available_pixel_width - full_username_width, available_pixel_width / 2)); - domain = ElideText(domain, font, desired_domain_width, ELIDE_IN_MIDDLE); + domain = ElideText(domain, font_list, desired_domain_width, + ELIDE_IN_MIDDLE); // Failing to elide the domain such that at least one character remains // (other than the ellipsis itself) remains: return a single ellipsis. if (domain.length() <= 1U) @@ -196,20 +199,25 @@ string16 ElideEmail(const string16& email, // Fit the username in the remaining width (at this point the elided username // is guaranteed to fit with at least one character remaining given all the // precautions taken earlier). - username = ElideText(username, - font, - available_pixel_width - font.GetStringWidth(domain), + available_pixel_width -= gfx::GetStringWidth(domain, font_list); + username = ElideText(username, font_list, available_pixel_width, ELIDE_AT_END); return username + kAtSignUTF16 + domain; } +string16 ElideEmail(const string16& email, + const gfx::Font& font, + int available_pixel_width) { + return ElideEmail(email, gfx::FontList(font), available_pixel_width); +} + // TODO(pkasting): http://crbug.com/77883 This whole function gets // kerning/ligatures/etc. issues potentially wrong by assuming that the width of // a rendered string is always the sum of the widths of its substrings. Also I // suspect it could be made simpler. string16 ElideUrl(const GURL& url, - const gfx::Font& font, + const gfx::FontList& font_list, int available_pixel_width, const std::string& languages) { // Get a formatted string and corresponding parsing of the url. @@ -222,11 +230,12 @@ string16 ElideUrl(const GURL& url, // If non-standard, return plain eliding. if (!url.IsStandard()) - return ElideText(url_string, font, available_pixel_width, ELIDE_AT_END); + return ElideText(url_string, font_list, available_pixel_width, + ELIDE_AT_END); // Now start eliding url_string to fit within available pixel width. // Fist pass - check to see whether entire url_string fits. - const int pixel_width_url_string = font.GetStringWidth(url_string); + const int pixel_width_url_string = gfx::GetStringWidth(url_string, font_list); if (available_pixel_width >= pixel_width_url_string) return url_string; @@ -239,8 +248,9 @@ string16 ElideUrl(const GURL& url, // Return general elided text if url minus the query fits. const string16 url_minus_query = url_string.substr(0, path_start_index + path_len); - if (available_pixel_width >= font.GetStringWidth(url_minus_query)) - return ElideText(url_string, font, available_pixel_width, ELIDE_AT_END); + if (available_pixel_width >= gfx::GetStringWidth(url_minus_query, font_list)) + return ElideText(url_string, font_list, available_pixel_width, + ELIDE_AT_END); // Get Host. string16 url_host = UTF8ToUTF16(url.host()); @@ -288,15 +298,17 @@ string16 ElideUrl(const GURL& url, } // Second Pass - remove scheme - the rest fits. - const int pixel_width_url_host = font.GetStringWidth(url_host); - const int pixel_width_url_path = font.GetStringWidth(url_path_query_etc); + const int pixel_width_url_host = gfx::GetStringWidth(url_host, font_list); + const int pixel_width_url_path = gfx::GetStringWidth(url_path_query_etc, + font_list); if (available_pixel_width >= pixel_width_url_host + pixel_width_url_path) return url_host + url_path_query_etc; // Third Pass: Subdomain, domain and entire path fits. - const int pixel_width_url_domain = font.GetStringWidth(url_domain); - const int pixel_width_url_subdomain = font.GetStringWidth(url_subdomain); + const int pixel_width_url_domain = gfx::GetStringWidth(url_domain, font_list); + const int pixel_width_url_subdomain = gfx::GetStringWidth(url_subdomain, + font_list); if (available_pixel_width >= pixel_width_url_subdomain + pixel_width_url_domain + pixel_width_url_path) @@ -304,15 +316,15 @@ string16 ElideUrl(const GURL& url, // Query element. string16 url_query; - const int kPixelWidthDotsTrailer = - font.GetStringWidth(UTF8ToUTF16(kEllipsis)); + const int kPixelWidthDotsTrailer = gfx::GetStringWidth( + string16(kEllipsisUTF16), font_list); if (parsed.query.is_nonempty()) { url_query = UTF8ToUTF16("?") + url_string.substr(parsed.query.begin); - if (available_pixel_width >= (pixel_width_url_subdomain + - pixel_width_url_domain + pixel_width_url_path - - font.GetStringWidth(url_query))) { + if (available_pixel_width >= + (pixel_width_url_subdomain + pixel_width_url_domain + + pixel_width_url_path - gfx::GetStringWidth(url_query, font_list))) { return ElideText(url_subdomain + url_domain + url_path_query_etc, - font, available_pixel_width, ELIDE_AT_END); + font_list, available_pixel_width, ELIDE_AT_END); } } @@ -339,18 +351,19 @@ string16 ElideUrl(const GURL& url, url_path_number_of_elements > kMaxNumberOfUrlPathElementsAllowed) { // No path to elide, or too long of a path (could overflow in loop below) // Just elide this as a text string. - return ElideText(url_subdomain + url_domain + url_path_query_etc, font, + return ElideText(url_subdomain + url_domain + url_path_query_etc, font_list, available_pixel_width, ELIDE_AT_END); } // Start eliding the path and replacing elements by ".../". - const string16 kEllipsisAndSlash = UTF8ToUTF16(kEllipsis) + kForwardSlash; - const int pixel_width_ellipsis_slash = font.GetStringWidth(kEllipsisAndSlash); + const string16 kEllipsisAndSlash = string16(kEllipsisUTF16) + kForwardSlash; + const int pixel_width_ellipsis_slash = gfx::GetStringWidth(kEllipsisAndSlash, + font_list); // Check with both subdomain and domain. string16 elided_path = ElideComponentizedPath(url_subdomain + url_domain, url_path_elements, - url_filename, url_query, font, + url_filename, url_query, font_list, available_pixel_width); if (!elided_path.empty()) return elided_path; @@ -368,7 +381,7 @@ string16 ElideUrl(const GURL& url, url_elided_domain = url_domain; elided_path = ElideComponentizedPath(url_elided_domain, url_path_elements, - url_filename, url_query, font, + url_filename, url_query, font_list, available_pixel_width); if (!elided_path.empty()) @@ -377,24 +390,32 @@ string16 ElideUrl(const GURL& url, // Return elided domain/.../filename anyway. string16 final_elided_url_string(url_elided_domain); - const int url_elided_domain_width = font.GetStringWidth(url_elided_domain); + const int url_elided_domain_width = gfx::GetStringWidth(url_elided_domain, + font_list); // A hack to prevent trailing ".../...". if ((available_pixel_width - url_elided_domain_width) > pixel_width_ellipsis_slash + kPixelWidthDotsTrailer + - font.GetStringWidth(ASCIIToUTF16("UV"))) { + gfx::GetStringWidth(ASCIIToUTF16("UV"), font_list)) { final_elided_url_string += BuildPathFromComponents(string16(), url_path_elements, url_filename, 1); } else { final_elided_url_string += url_path; } - return ElideText(final_elided_url_string, font, available_pixel_width, + return ElideText(final_elided_url_string, font_list, available_pixel_width, ELIDE_AT_END); } +string16 ElideUrl(const GURL& url, + const gfx::Font& font, + int available_pixel_width, + const std::string& languages) { + return ElideUrl(url, gfx::FontList(font), available_pixel_width, languages); +} + string16 ElideFilename(const base::FilePath& filename, - const gfx::Font& font, + const gfx::FontList& font_list, int available_pixel_width) { #if defined(OS_WIN) string16 filename_utf16 = filename.value(); @@ -409,18 +430,18 @@ string16 ElideFilename(const base::FilePath& filename, filename.BaseName().RemoveExtension().value())); #endif - const int full_width = font.GetStringWidth(filename_utf16); + const int full_width = gfx::GetStringWidth(filename_utf16, font_list); if (full_width <= available_pixel_width) return base::i18n::GetDisplayStringInLTRDirectionality(filename_utf16); if (rootname.empty() || extension.empty()) { - const string16 elided_name = ElideText(filename_utf16, font, + const string16 elided_name = ElideText(filename_utf16, font_list, available_pixel_width, ELIDE_AT_END); return base::i18n::GetDisplayStringInLTRDirectionality(elided_name); } - const int ext_width = font.GetStringWidth(extension); - const int root_width = font.GetStringWidth(rootname); + const int ext_width = gfx::GetStringWidth(extension, font_list); + const int root_width = gfx::GetStringWidth(rootname, font_list); // We may have trimmed the path. if (root_width + ext_width <= available_pixel_width) { @@ -429,7 +450,7 @@ string16 ElideFilename(const base::FilePath& filename, } if (ext_width >= available_pixel_width) { - const string16 elided_name = ElideText(rootname + extension, font, + const string16 elided_name = ElideText(rootname + extension, font_list, available_pixel_width, ELIDE_IN_MIDDLE); return base::i18n::GetDisplayStringInLTRDirectionality(elided_name); @@ -437,19 +458,25 @@ string16 ElideFilename(const base::FilePath& filename, int available_root_width = available_pixel_width - ext_width; string16 elided_name = - ElideText(rootname, font, available_root_width, ELIDE_AT_END); + ElideText(rootname, font_list, available_root_width, ELIDE_AT_END); elided_name += extension; return base::i18n::GetDisplayStringInLTRDirectionality(elided_name); } +string16 ElideFilename(const base::FilePath& filename, + const gfx::Font& font, + int available_pixel_width) { + return ElideFilename(filename, gfx::FontList(font), available_pixel_width); +} + string16 ElideText(const string16& text, - const gfx::Font& font, + const gfx::FontList& font_list, int available_pixel_width, ElideBehavior elide_behavior) { if (text.empty()) return text; - const int current_text_pixel_width = font.GetStringWidth(text); + const int current_text_pixel_width = gfx::GetStringWidth(text, font_list); const bool elide_in_middle = (elide_behavior == ELIDE_IN_MIDDLE); const bool insert_ellipsis = (elide_behavior != TRUNCATE_AT_END); @@ -466,13 +493,14 @@ string16 ElideText(const string16& text, // ridiculous), but we should check other widths for bogus values as well. if (current_text_pixel_width <= 0 && !text.empty()) { const string16 cut = slicer.CutString(text.length() / 2, false); - return ElideText(cut, font, available_pixel_width, elide_behavior); + return ElideText(cut, font_list, available_pixel_width, elide_behavior); } if (current_text_pixel_width <= available_pixel_width) return text; - if (insert_ellipsis && font.GetStringWidth(ellipsis) > available_pixel_width) + if (insert_ellipsis && + gfx::GetStringWidth(ellipsis, font_list) > available_pixel_width) return string16(); // Use binary search to compute the elided text. @@ -483,12 +511,12 @@ string16 ElideText(const string16& text, // We check the length of the whole desired string at once to ensure we // handle kerning/ligatures/etc. correctly. const string16 cut = slicer.CutString(guess, insert_ellipsis); - const int guess_length = font.GetStringWidth(cut); + const int guess_length = gfx::GetStringWidth(cut, font_list); // Check again that we didn't hit a Pango width overflow. If so, cut the // current string in half and start over. if (guess_length <= 0) { return ElideText(slicer.CutString(guess / 2, false), - font, available_pixel_width, elide_behavior); + font_list, available_pixel_width, elide_behavior); } if (guess_length > available_pixel_width) hi = guess - 1; @@ -499,6 +527,14 @@ string16 ElideText(const string16& text, return slicer.CutString(guess, insert_ellipsis); } +string16 ElideText(const string16& text, + const gfx::Font& font, + int available_pixel_width, + ElideBehavior elide_behavior) { + return ElideText(text, gfx::FontList(font), available_pixel_width, + elide_behavior); +} + SortedDisplayURL::SortedDisplayURL(const GURL& url, const std::string& languages) { net::AppendFormattedHost(url, languages, &sort_host_); @@ -775,13 +811,13 @@ void RectangleString::NewLine(bool output) { // can be broken into smaller methods sharing this state. class RectangleText { public: - RectangleText(const gfx::Font& font, + RectangleText(const gfx::FontList& font_list, int available_pixel_width, int available_pixel_height, ui::WordWrapBehavior wrap_behavior, std::vector<string16>* lines) - : font_(font), - line_height_(font.GetHeight()), + : font_list_(font_list), + line_height_(font_list.GetHeight()), available_pixel_width_(available_pixel_width), available_pixel_height_(available_pixel_height), wrap_behavior_(wrap_behavior), @@ -833,8 +869,8 @@ class RectangleText { // Set the current position to the beginning of the next line. bool NewLine(); - // The font used for measuring text width. - const gfx::Font& font_; + // The font list used for measuring text width. + const gfx::FontList& font_list_; // The height of each line of text. const int line_height_; @@ -907,7 +943,7 @@ int RectangleText::Finalize() { } void RectangleText::AddLine(const string16& line) { - const int line_width = font_.GetStringWidth(line); + const int line_width = gfx::GetStringWidth(line, font_list_); if (line_width <= available_pixel_width_) { AddToCurrentLineWithWidth(line, line_width); } else { @@ -948,7 +984,8 @@ int RectangleText::WrapWord(const string16& word) { bool first_fragment = true; while (!insufficient_height_ && !text.empty()) { string16 fragment = - ui::ElideText(text, font_, available_pixel_width_, ui::TRUNCATE_AT_END); + ui::ElideText(text, font_list_, available_pixel_width_, + ui::TRUNCATE_AT_END); // At least one character has to be added at every line, even if the // available space is too small. if(fragment.empty()) @@ -982,7 +1019,7 @@ int RectangleText::AddWordOverflow(const string16& word) { (wrap_behavior_ == ui::ELIDE_LONG_WORDS ? ui::ELIDE_AT_END : ui::TRUNCATE_AT_END); const string16 elided_word = - ui::ElideText(word, font_, available_pixel_width_, elide_behavior); + ui::ElideText(word, font_list_, available_pixel_width_, elide_behavior); AddToCurrentLine(elided_word); insufficient_width_ = true; } @@ -994,7 +1031,7 @@ int RectangleText::AddWord(const string16& word) { int lines_added = 0; string16 trimmed; TrimWhitespace(word, TRIM_TRAILING, &trimmed); - const int trimmed_width = font_.GetStringWidth(trimmed); + const int trimmed_width = gfx::GetStringWidth(trimmed, font_list_); if (trimmed_width <= available_pixel_width_) { // Word can be made to fit, no need to fragment it. if ((current_width_ + trimmed_width > available_pixel_width_) && NewLine()) @@ -1009,7 +1046,7 @@ int RectangleText::AddWord(const string16& word) { } void RectangleText::AddToCurrentLine(const string16& text) { - AddToCurrentLineWithWidth(text, font_.GetStringWidth(text)); + AddToCurrentLineWithWidth(text, gfx::GetStringWidth(text, font_list_)); } void RectangleText::AddToCurrentLineWithWidth(const string16& text, @@ -1049,12 +1086,12 @@ bool ElideRectangleString(const string16& input, size_t max_rows, } int ElideRectangleText(const string16& input, - const gfx::Font& font, - int available_pixel_width, - int available_pixel_height, - WordWrapBehavior wrap_behavior, - std::vector<string16>* lines) { - RectangleText rect(font, + const gfx::FontList& font_list, + int available_pixel_width, + int available_pixel_height, + WordWrapBehavior wrap_behavior, + std::vector<string16>* lines) { + RectangleText rect(font_list, available_pixel_width, available_pixel_height, wrap_behavior, @@ -1064,6 +1101,17 @@ int ElideRectangleText(const string16& input, return rect.Finalize(); } +int ElideRectangleText(const string16& input, + const gfx::Font& font, + int available_pixel_width, + int available_pixel_height, + WordWrapBehavior wrap_behavior, + std::vector<string16>* lines) { + return ElideRectangleText(input, gfx::FontList(font), + available_pixel_width, available_pixel_height, + wrap_behavior, lines); +} + string16 TruncateString(const string16& string, size_t length) { if (string.size() <= length) // String fits, return it. diff --git a/ui/base/text/text_elider.h b/ui/base/text/text_elider.h index 1d31f8e..a4ea50da 100644 --- a/ui/base/text/text_elider.h +++ b/ui/base/text/text_elider.h @@ -15,7 +15,6 @@ #include "third_party/icu/source/common/unicode/uchar.h" #include "third_party/icu/source/i18n/unicode/coll.h" #include "ui/base/ui_export.h" -#include "ui/gfx/font.h" class GURL; @@ -23,13 +22,18 @@ namespace base { class FilePath; } +namespace gfx { +class Font; +class FontList; +} // namespace gfx + namespace ui { UI_EXPORT extern const char kEllipsis[]; UI_EXPORT extern const char16 kEllipsisUTF16[]; // Elides a well-formed email address (e.g. username@domain.com) to fit into -// |available_pixel_width| using the specified |font|. +// |available_pixel_width| using the specified |font_list|. // This function guarantees that the string returned will contain at least one // character, other than the ellipses, on either side of the '@'. If it is // impossible to achieve these requirements: only an ellipsis will be returned. @@ -39,6 +43,10 @@ UI_EXPORT extern const char16 kEllipsisUTF16[]; // doesn't need half the available width: the elided domain will occupy that // extra width). UI_EXPORT string16 ElideEmail(const string16& email, + const gfx::FontList& font_list, + int available_pixel_width); +// Obsolete version. Use the above version which takes gfx::FontList. +UI_EXPORT string16 ElideEmail(const string16& email, const gfx::Font& font, int available_pixel_width); @@ -57,6 +65,11 @@ UI_EXPORT string16 ElideEmail(const string16& email, // is displayed properly in an RTL context. Please refer to // http://crbug.com/6487 for more information. UI_EXPORT string16 ElideUrl(const GURL& url, + const gfx::FontList& font_list, + int available_pixel_width, + const std::string& languages); +// Obsolete version. Use the above version which takes gfx::FontList. +UI_EXPORT string16 ElideUrl(const GURL& url, const gfx::Font& font, int available_pixel_width, const std::string& languages); @@ -73,6 +86,11 @@ enum ElideBehavior { // Elides |text| to fit in |available_pixel_width| according to the specified // |elide_behavior|. UI_EXPORT string16 ElideText(const string16& text, + const gfx::FontList& font_list, + int available_pixel_width, + ElideBehavior elide_behavior); +// Obsolete version. Use the above version which takes gfx::FontList. +UI_EXPORT string16 ElideText(const string16& text, const gfx::Font& font, int available_pixel_width, ElideBehavior elide_behavior); @@ -84,6 +102,10 @@ UI_EXPORT string16 ElideText(const string16& text, // the elided filename is wrapped with LRE (Left-To-Right Embedding) mark and // PDF (Pop Directional Formatting) mark. UI_EXPORT string16 ElideFilename(const base::FilePath& filename, + const gfx::FontList& font_list, + int available_pixel_width); +// Obsolete version. Use the above version which takes gfx::FontList. +UI_EXPORT string16 ElideFilename(const base::FilePath& filename, const gfx::Font& font, int available_pixel_width); @@ -181,12 +203,19 @@ enum ReformattingResultFlags { // Reformats |text| into output vector |lines| so that the resulting text fits // into an |available_pixel_width| by |available_pixel_height| rectangle with -// the specified |font|. Input newlines are respected, but lines that are too -// long are broken into pieces. For words that are too wide to fit on a single -// line, the wrapping behavior can be specified with the |wrap_behavior| param. -// Returns a combination of |ReformattingResultFlags| that indicate whether the -// given rectangle had insufficient space to accommodate |texŧ|, leading to -// elision or truncation (and not just reformatting). +// the specified |font_list|. Input newlines are respected, but lines that are +// too long are broken into pieces. For words that are too wide to fit on a +// single line, the wrapping behavior can be specified with the |wrap_behavior| +// param. Returns a combination of |ReformattingResultFlags| that indicate +// whether the given rectangle had insufficient space to accommodate |texŧ|, +// leading to elision or truncation (and not just reformatting). +UI_EXPORT int ElideRectangleText(const string16& text, + const gfx::FontList& font_list, + int available_pixel_width, + int available_pixel_height, + WordWrapBehavior wrap_behavior, + std::vector<string16>* lines); +// Obsolete version. Use the above version which takes gfx::FontList. UI_EXPORT int ElideRectangleText(const string16& text, const gfx::Font& font, int available_pixel_width, diff --git a/ui/gfx/canvas.cc b/ui/gfx/canvas.cc index 2b0f504..b59d2a0 100644 --- a/ui/gfx/canvas.cc +++ b/ui/gfx/canvas.cc @@ -11,7 +11,7 @@ #include "third_party/skia/include/core/SkBitmap.h" #include "third_party/skia/include/effects/SkGradientShader.h" #include "ui/gfx/canvas.h" -#include "ui/gfx/font.h" +#include "ui/gfx/font_list.h" #include "ui/gfx/rect.h" #include "ui/gfx/size_conversions.h" #include "ui/gfx/skia_util.h" @@ -23,13 +23,11 @@ namespace gfx { -Canvas::Canvas(const gfx::Size& size, - ui::ScaleFactor scale_factor, - bool is_opaque) - : scale_factor_(scale_factor), - canvas_(NULL) { - gfx::Size pixel_size = gfx::ToCeiledSize( - gfx::ScaleSize(size, ui::GetScaleFactorScale(scale_factor))); +Canvas::Canvas(const Size& size, ui::ScaleFactor scale_factor, bool is_opaque) + : scale_factor_(scale_factor), + canvas_(NULL) { + Size pixel_size = ToCeiledSize( + ScaleSize(size, ui::GetScaleFactorScale(scale_factor))); owned_canvas_ = skia::AdoptRef(skia::CreatePlatformCanvas(pixel_size.width(), pixel_size.height(), is_opaque)); @@ -45,7 +43,7 @@ Canvas::Canvas(const gfx::Size& size, canvas_->scale(scale, scale); } -Canvas::Canvas(const gfx::ImageSkiaRep& image_rep, bool is_opaque) +Canvas::Canvas(const ImageSkiaRep& image_rep, bool is_opaque) : scale_factor_(image_rep.scale_factor()), owned_canvas_(skia::AdoptRef( skia::CreatePlatformCanvas(image_rep.pixel_width(), @@ -54,7 +52,7 @@ Canvas::Canvas(const gfx::ImageSkiaRep& image_rep, bool is_opaque) canvas_(owned_canvas_.get()) { SkScalar scale = SkFloatToScalar(ui::GetScaleFactorScale(scale_factor_)); canvas_->scale(scale, scale); - DrawImageInt(gfx::ImageSkia(image_rep), 0, 0); + DrawImageInt(ImageSkia(image_rep), 0, 0); } Canvas::Canvas() @@ -72,12 +70,12 @@ Canvas* Canvas::CreateCanvasWithoutScaling(SkCanvas* canvas, return new Canvas(canvas, scale_factor); } -void Canvas::RecreateBackingCanvas(const gfx::Size& size, +void Canvas::RecreateBackingCanvas(const Size& size, ui::ScaleFactor scale_factor, bool is_opaque) { scale_factor_ = scale_factor; - gfx::Size pixel_size = gfx::ToFlooredSize( - gfx::ScaleSize(size, ui::GetScaleFactorScale(scale_factor))); + Size pixel_size = ToFlooredSize( + ScaleSize(size, ui::GetScaleFactorScale(scale_factor))); owned_canvas_ = skia::AdoptRef(skia::CreatePlatformCanvas(pixel_size.width(), pixel_size.height(), is_opaque)); @@ -87,9 +85,27 @@ void Canvas::RecreateBackingCanvas(const gfx::Size& size, } // static -int Canvas::GetStringWidth(const base::string16& text, const gfx::Font& font) { +void Canvas::SizeStringInt(const base::string16& text, + const Font& font, + int* width, + int* height, + int line_height, + int flags) { + SizeStringInt(text, FontList(font), width, height, line_height, flags); +} + +// static +int Canvas::GetStringWidth(const base::string16& text, + const FontList& font_list) { + int width = 0, height = 0; + SizeStringInt(text, font_list, &width, &height, 0, NO_ELLIPSIS); + return width; +} + +// static +int Canvas::GetStringWidth(const base::string16& text, const Font& font) { int width = 0, height = 0; - Canvas::SizeStringInt(text, font, &width, &height, 0, NO_ELLIPSIS); + SizeStringInt(text, FontList(font), &width, &height, 0, NO_ELLIPSIS); return width; } @@ -98,7 +114,20 @@ int Canvas::DefaultCanvasTextAlignment() { return base::i18n::IsRTL() ? TEXT_ALIGN_RIGHT : TEXT_ALIGN_LEFT; } -gfx::ImageSkiaRep Canvas::ExtractImageRep() const { +void Canvas::DrawStringWithHalo(const base::string16& text, + const Font& font, + SkColor text_color, + SkColor halo_color_in, + int x, + int y, + int w, + int h, + int flags) { + DrawStringRectWithHalo(text, FontList(font), text_color, halo_color_in, + Rect(x, y, w, h), flags); +} + +ImageSkiaRep Canvas::ExtractImageRep() const { const SkBitmap& device_bitmap = canvas_->getDevice()->accessBitmap(false); // Make a bitmap to return, and a canvas to draw into it. We don't just want @@ -107,10 +136,10 @@ gfx::ImageSkiaRep Canvas::ExtractImageRep() const { SkBitmap result; device_bitmap.copyTo(&result, SkBitmap::kARGB_8888_Config); - return gfx::ImageSkiaRep(result, scale_factor_); + return ImageSkiaRep(result, scale_factor_); } -void Canvas::DrawDashedRect(const gfx::Rect& rect, SkColor color) { +void Canvas::DrawDashedRect(const Rect& rect, SkColor color) { // Create a 2D bitmap containing alternating on/off pixels - we do this // so that you never get two pixels of the same color around the edges // of the focus rect (this may mean that opposing edges of the rect may @@ -149,11 +178,11 @@ void Canvas::DrawDashedRect(const gfx::Rect& rect, SkColor color) { SkPaint paint; paint.setShader(shader.get()); - DrawRect(gfx::Rect(rect.x(), rect.y(), rect.width(), 1), paint); - DrawRect(gfx::Rect(rect.x(), rect.y() + rect.height() - 1, rect.width(), 1), + DrawRect(Rect(rect.x(), rect.y(), rect.width(), 1), paint); + DrawRect(Rect(rect.x(), rect.y() + rect.height() - 1, rect.width(), 1), paint); - DrawRect(gfx::Rect(rect.x(), rect.y(), 1, rect.height()), paint); - DrawRect(gfx::Rect(rect.x() + rect.width() - 1, rect.y(), 1, rect.height()), + DrawRect(Rect(rect.x(), rect.y(), 1, rect.height()), paint); + DrawRect(Rect(rect.x() + rect.width() - 1, rect.y(), 1, rect.height()), paint); } @@ -166,8 +195,8 @@ void Canvas::SaveLayerAlpha(uint8 alpha) { } -void Canvas::SaveLayerAlpha(uint8 alpha, const gfx::Rect& layer_bounds) { - SkRect bounds(gfx::RectToSkRect(layer_bounds)); +void Canvas::SaveLayerAlpha(uint8 alpha, const Rect& layer_bounds) { + SkRect bounds(RectToSkRect(layer_bounds)); canvas_->saveLayerAlpha(&bounds, alpha); } @@ -175,22 +204,22 @@ void Canvas::Restore() { canvas_->restore(); } -bool Canvas::ClipRect(const gfx::Rect& rect) { - return canvas_->clipRect(gfx::RectToSkRect(rect)); +bool Canvas::ClipRect(const Rect& rect) { + return canvas_->clipRect(RectToSkRect(rect)); } bool Canvas::ClipPath(const SkPath& path) { return canvas_->clipPath(path); } -bool Canvas::GetClipBounds(gfx::Rect* bounds) { +bool Canvas::GetClipBounds(Rect* bounds) { SkRect out; bool has_non_empty_clip = canvas_->getClipBounds(&out); bounds->SetRect(out.left(), out.top(), out.width(), out.height()); return has_non_empty_clip; } -void Canvas::Translate(const gfx::Vector2d& offset) { +void Canvas::Translate(const Vector2d& offset) { canvas_->translate(SkIntToScalar(offset.x()), SkIntToScalar(offset.y())); } @@ -206,11 +235,11 @@ void Canvas::DrawColor(SkColor color, SkXfermode::Mode mode) { canvas_->drawColor(color, mode); } -void Canvas::FillRect(const gfx::Rect& rect, SkColor color) { +void Canvas::FillRect(const Rect& rect, SkColor color) { FillRect(rect, color, SkXfermode::kSrcOver_Mode); } -void Canvas::FillRect(const gfx::Rect& rect, +void Canvas::FillRect(const Rect& rect, SkColor color, SkXfermode::Mode mode) { SkPaint paint; @@ -220,11 +249,11 @@ void Canvas::FillRect(const gfx::Rect& rect, DrawRect(rect, paint); } -void Canvas::DrawRect(const gfx::Rect& rect, SkColor color) { +void Canvas::DrawRect(const Rect& rect, SkColor color) { DrawRect(rect, color, SkXfermode::kSrcOver_Mode); } -void Canvas::DrawRect(const gfx::Rect& rect, +void Canvas::DrawRect(const Rect& rect, SkColor color, SkXfermode::Mode mode) { SkPaint paint; @@ -239,38 +268,34 @@ void Canvas::DrawRect(const gfx::Rect& rect, DrawRect(rect, paint); } -void Canvas::DrawRect(const gfx::Rect& rect, const SkPaint& paint) { +void Canvas::DrawRect(const Rect& rect, const SkPaint& paint) { canvas_->drawIRect(RectToSkIRect(rect), paint); } -void Canvas::DrawPoint(const gfx::Point& p1, const SkPaint& paint) { +void Canvas::DrawPoint(const Point& p1, const SkPaint& paint) { canvas_->drawPoint(SkIntToScalar(p1.x()), SkIntToScalar(p1.y()), paint); } -void Canvas::DrawLine(const gfx::Point& p1, - const gfx::Point& p2, - SkColor color) { +void Canvas::DrawLine(const Point& p1, const Point& p2, SkColor color) { SkPaint paint; paint.setColor(color); paint.setStrokeWidth(SkIntToScalar(1)); DrawLine(p1, p2, paint); } -void Canvas::DrawLine(const gfx::Point& p1, - const gfx::Point& p2, - const SkPaint& paint) { +void Canvas::DrawLine(const Point& p1, const Point& p2, const SkPaint& paint) { canvas_->drawLine(SkIntToScalar(p1.x()), SkIntToScalar(p1.y()), SkIntToScalar(p2.x()), SkIntToScalar(p2.y()), paint); } -void Canvas::DrawCircle(const gfx::Point& center_point, +void Canvas::DrawCircle(const Point& center_point, int radius, const SkPaint& paint) { canvas_->drawCircle(SkIntToScalar(center_point.x()), SkIntToScalar(center_point.y()), SkIntToScalar(radius), paint); } -void Canvas::DrawRoundRect(const gfx::Rect& rect, +void Canvas::DrawRoundRect(const Rect& rect, int radius, const SkPaint& paint) { canvas_->drawRoundRect(RectToSkRect(rect), SkIntToScalar(radius), @@ -281,25 +306,26 @@ void Canvas::DrawPath(const SkPath& path, const SkPaint& paint) { canvas_->drawPath(path, paint); } -void Canvas::DrawFocusRect(const gfx::Rect& rect) { +void Canvas::DrawFocusRect(const Rect& rect) { DrawDashedRect(rect, SK_ColorGRAY); } -void Canvas::DrawImageInt(const gfx::ImageSkia& image, int x, int y) { +void Canvas::DrawImageInt(const ImageSkia& image, int x, int y) { SkPaint paint; DrawImageInt(image, x, y, paint); } -void Canvas::DrawImageInt(const gfx::ImageSkia& image, int x, int y, uint8 a) { +void Canvas::DrawImageInt(const ImageSkia& image, int x, int y, uint8 a) { SkPaint paint; paint.setAlpha(a); DrawImageInt(image, x, y, paint); } -void Canvas::DrawImageInt(const gfx::ImageSkia& image, - int x, int y, +void Canvas::DrawImageInt(const ImageSkia& image, + int x, + int y, const SkPaint& paint) { - const gfx::ImageSkiaRep& image_rep = GetImageRepToPaint(image); + const ImageSkiaRep& image_rep = GetImageRepToPaint(image); if (image_rep.is_null()) return; const SkBitmap& bitmap = image_rep.sk_bitmap(); @@ -315,18 +341,30 @@ void Canvas::DrawImageInt(const gfx::ImageSkia& image, canvas_->restore(); } -void Canvas::DrawImageInt(const gfx::ImageSkia& image, - int src_x, int src_y, int src_w, int src_h, - int dest_x, int dest_y, int dest_w, int dest_h, +void Canvas::DrawImageInt(const ImageSkia& image, + int src_x, + int src_y, + int src_w, + int src_h, + int dest_x, + int dest_y, + int dest_w, + int dest_h, bool filter) { SkPaint p; DrawImageInt(image, src_x, src_y, src_w, src_h, dest_x, dest_y, dest_w, dest_h, filter, p); } -void Canvas::DrawImageInt(const gfx::ImageSkia& image, - int src_x, int src_y, int src_w, int src_h, - int dest_x, int dest_y, int dest_w, int dest_h, +void Canvas::DrawImageInt(const ImageSkia& image, + int src_x, + int src_y, + int src_w, + int src_h, + int dest_x, + int dest_y, + int dest_w, + int dest_h, bool filter, const SkPaint& paint) { DLOG_ASSERT(src_x + src_w < std::numeric_limits<int16_t>::max() && @@ -342,7 +380,7 @@ void Canvas::DrawImageInt(const gfx::ImageSkia& image, float user_scale_x = static_cast<float>(dest_w) / src_w; float user_scale_y = static_cast<float>(dest_h) / src_h; - const gfx::ImageSkiaRep& image_rep = GetImageRepToPaint(image, + const ImageSkiaRep& image_rep = GetImageRepToPaint(image, user_scale_x, user_scale_y); if (image_rep.is_null()) return; @@ -373,7 +411,7 @@ void Canvas::DrawImageInt(const gfx::ImageSkia& image, shader_scale.preTranslate(SkIntToScalar(-src_x), SkIntToScalar(-src_y)); shader_scale.postTranslate(SkIntToScalar(dest_x), SkIntToScalar(dest_y)); - skia::RefPtr<SkShader> shader = gfx::CreateImageRepShader( + skia::RefPtr<SkShader> shader = CreateImageRepShader( image_rep, SkShader::kRepeat_TileMode, shader_scale); @@ -388,18 +426,18 @@ void Canvas::DrawImageInt(const gfx::ImageSkia& image, canvas_->drawRect(dest_rect, p); } -void Canvas::DrawImageInPath(const gfx::ImageSkia& image, +void Canvas::DrawImageInPath(const ImageSkia& image, int x, int y, const SkPath& path, const SkPaint& paint) { - const gfx::ImageSkiaRep& image_rep = GetImageRepToPaint(image); + const ImageSkiaRep& image_rep = GetImageRepToPaint(image); if (image_rep.is_null()) return; SkMatrix matrix; matrix.setTranslate(SkIntToScalar(x), SkIntToScalar(y)); - skia::RefPtr<SkShader> shader = gfx::CreateImageRepShader( + skia::RefPtr<SkShader> shader = CreateImageRepShader( image_rep, SkShader::kRepeat_TileMode, matrix); @@ -409,55 +447,96 @@ void Canvas::DrawImageInPath(const gfx::ImageSkia& image, canvas_->drawPath(path, p); } +void Canvas::DrawStringRect(const base::string16& text, + const FontList& font_list, + SkColor color, + const Rect& display_rect) { + DrawStringRectWithFlags(text, font_list, color, display_rect, + DefaultCanvasTextAlignment()); +} + +void Canvas::DrawStringRectWithFlags(const base::string16& text, + const FontList& font_list, + SkColor color, + const Rect& display_rect, + int flags) { + DrawStringRectWithShadows(text, font_list, color, display_rect, 0, flags, + ShadowValues()); +} + void Canvas::DrawStringInt(const base::string16& text, - const gfx::Font& font, + const Font& font, SkColor color, - int x, int y, int w, int h) { + int x, + int y, + int w, + int h) { DrawStringInt(text, font, color, x, y, w, h, DefaultCanvasTextAlignment()); } void Canvas::DrawStringInt(const base::string16& text, - const gfx::Font& font, + const Font& font, SkColor color, - const gfx::Rect& display_rect) { + const Rect& display_rect) { DrawStringInt(text, font, color, display_rect.x(), display_rect.y(), display_rect.width(), display_rect.height()); } void Canvas::DrawStringInt(const base::string16& text, - const gfx::Font& font, + const Font& font, SkColor color, - int x, int y, int w, int h, + int x, + int y, + int w, + int h, int flags) { - DrawStringWithShadows(text, - font, - color, - gfx::Rect(x, y, w, h), - 0, - flags, + DrawStringWithShadows(text, font, color, Rect(x, y, w, h), 0, flags, ShadowValues()); } -void Canvas::TileImageInt(const gfx::ImageSkia& image, - int x, int y, int w, int h) { +void Canvas::DrawStringWithShadows(const base::string16& text, + const Font& font, + SkColor color, + const Rect& text_bounds, + int line_height, + int flags, + const ShadowValues& shadows) { + DrawStringRectWithShadows(text, FontList(font), color, text_bounds, + line_height, flags, shadows); +} + +void Canvas::TileImageInt(const ImageSkia& image, + int x, + int y, + int w, + int h) { TileImageInt(image, 0, 0, x, y, w, h); } -void Canvas::TileImageInt(const gfx::ImageSkia& image, - int src_x, int src_y, - int dest_x, int dest_y, int w, int h) { +void Canvas::TileImageInt(const ImageSkia& image, + int src_x, + int src_y, + int dest_x, + int dest_y, + int w, + int h) { TileImageInt(image, src_x, src_y, 1.0f, 1.0f, dest_x, dest_y, w, h); } -void Canvas::TileImageInt(const gfx::ImageSkia& image, - int src_x, int src_y, - float tile_scale_x, float tile_scale_y, - int dest_x, int dest_y, int w, int h) { +void Canvas::TileImageInt(const ImageSkia& image, + int src_x, + int src_y, + float tile_scale_x, + float tile_scale_y, + int dest_x, + int dest_y, + int w, + int h) { if (!IntersectsClipRectInt(dest_x, dest_y, w, h)) return; - const gfx::ImageSkiaRep& image_rep = GetImageRepToPaint(image, - tile_scale_x, tile_scale_y); + const ImageSkiaRep& image_rep = GetImageRepToPaint( + image, tile_scale_x, tile_scale_y); if (image_rep.is_null()) return; @@ -467,7 +546,7 @@ void Canvas::TileImageInt(const gfx::ImageSkia& image, shader_scale.preTranslate(SkIntToScalar(-src_x), SkIntToScalar(-src_y)); shader_scale.postTranslate(SkIntToScalar(dest_x), SkIntToScalar(dest_y)); - skia::RefPtr<SkShader> shader = gfx::CreateImageRepShader( + skia::RefPtr<SkShader> shader = CreateImageRepShader( image_rep, SkShader::kRepeat_TileMode, shader_scale); @@ -483,7 +562,7 @@ void Canvas::TileImageInt(const gfx::ImageSkia& image, canvas_->drawRect(dest_rect, paint); } -gfx::NativeDrawingContext Canvas::BeginPlatformPaint() { +NativeDrawingContext Canvas::BeginPlatformPaint() { return skia::BeginPlatformPaint(canvas_); } @@ -509,21 +588,20 @@ bool Canvas::IntersectsClipRectInt(int x, int y, int w, int h) { SkIntToScalar(y + h)); } -bool Canvas::IntersectsClipRect(const gfx::Rect& rect) { +bool Canvas::IntersectsClipRect(const Rect& rect) { return IntersectsClipRectInt(rect.x(), rect.y(), rect.width(), rect.height()); } -const gfx::ImageSkiaRep& Canvas::GetImageRepToPaint( - const gfx::ImageSkia& image) const { +const ImageSkiaRep& Canvas::GetImageRepToPaint(const ImageSkia& image) const { return GetImageRepToPaint(image, 1.0f, 1.0f); } -const gfx::ImageSkiaRep& Canvas::GetImageRepToPaint( - const gfx::ImageSkia& image, +const ImageSkiaRep& Canvas::GetImageRepToPaint( + const ImageSkia& image, float user_additional_scale_x, float user_additional_scale_y) const { - const gfx::ImageSkiaRep& image_rep = image.GetRepresentation(scale_factor_); + const ImageSkiaRep& image_rep = image.GetRepresentation(scale_factor_); if (!image_rep.is_null()) { SkMatrix m = canvas_->getTotalMatrix(); diff --git a/ui/gfx/canvas.h b/ui/gfx/canvas.h index 8baa45c..c8996a2 100644 --- a/ui/gfx/canvas.h +++ b/ui/gfx/canvas.h @@ -20,6 +20,7 @@ namespace gfx { class Rect; class Font; +class FontList; class Point; class Size; class Transform; @@ -95,17 +96,15 @@ class UI_EXPORT Canvas { // Creates canvas with provided DIP |size| and |scale_factor|. // If this canvas is not opaque, it's explicitly cleared to transparent before // being returned. - Canvas(const gfx::Size& size, - ui::ScaleFactor scale_factor, - bool is_opaque); + Canvas(const Size& size, ui::ScaleFactor scale_factor, bool is_opaque); // Constructs a canvas with the size and the scale factor of the // provided |image_rep|, and draws the |image_rep| into it. - Canvas(const gfx::ImageSkiaRep& image_rep, bool is_opaque); + Canvas(const ImageSkiaRep& image_rep, bool is_opaque); virtual ~Canvas(); - // Creates a gfx::Canvas backed by an |sk_canvas| with |scale_factor|. + // Creates a Canvas backed by an |sk_canvas| with |scale_factor|. // |sk_canvas| is assumed to be already scaled based on |scale_factor| // so no additional scaling is applied. static Canvas* CreateCanvasWithoutScaling(SkCanvas* sk_canvas, @@ -117,36 +116,47 @@ class UI_EXPORT Canvas { // canvas after having initialized the canvas. // TODO(pkotwicz): Push the scale factor into skia::PlatformCanvas such that // this method can be private. - void RecreateBackingCanvas(const gfx::Size& size, + void RecreateBackingCanvas(const Size& size, ui::ScaleFactor scale_factor, bool is_opaque); - // Compute the size required to draw some text with the provided font. + // Compute the size required to draw some text with the provided fonts. // Attempts to fit the text with the provided width and height. Increases // height and then width as needed to make the text fit. This method // supports multiple lines. On Skia only a line_height can be specified and // specifying a 0 value for it will cause the default height to be used. static void SizeStringInt(const base::string16& text, - const gfx::Font& font, - int* width, int* height, + const FontList& font_list, + int* width, + int* height, + int line_height, + int flags); + // Obsolete version. Use the above version which takes FontList. + static void SizeStringInt(const base::string16& text, + const Font& font, + int* width, + int* height, int line_height, int flags); // Returns the number of horizontal pixels needed to display the specified - // |text| with |font|. - static int GetStringWidth(const base::string16& text, const gfx::Font& font); + // |text| with |font_list|. + static int GetStringWidth(const base::string16& text, + const FontList& font_list); + // Obsolete version. Use the above version which takes FontList. + static int GetStringWidth(const base::string16& text, const Font& font); // Returns the default text alignment to be used when drawing text on a - // gfx::Canvas based on the directionality of the system locale language. - // This function is used by gfx::Canvas::DrawStringInt when the text alignment + // Canvas based on the directionality of the system locale language. + // This function is used by Canvas::DrawStringInt when the text alignment // is not specified. // - // This function returns either gfx::Canvas::TEXT_ALIGN_LEFT or - // gfx::Canvas::TEXT_ALIGN_RIGHT. + // This function returns either Canvas::TEXT_ALIGN_LEFT or + // Canvas::TEXT_ALIGN_RIGHT. static int DefaultCanvasTextAlignment(); // Draws text with a 1-pixel halo around it of the given color. - // On Windows, it allows ClearType to be drawn to an otherwise transparenct + // On Windows, it allows ClearType to be drawn to an otherwise transparent // bitmap for drag images. Drag images have only 1-bit of transparency, so // we don't do any fancy blurring. // On Linux, text with halo is created by stroking it with 2px |halo_color| @@ -154,18 +164,28 @@ class UI_EXPORT Canvas { // On Mac, NOTIMPLEMENTED. // TODO(dhollowa): Skia-native implementation is underway. Cut over to // that when ready. http::/crbug.com/109946 + void DrawStringRectWithHalo(const base::string16& text, + const FontList& font_list, + SkColor text_color, + SkColor halo_color, + const Rect& display_rect, + int flags); + // Obsolete version. Use the above version which takes FontList. void DrawStringWithHalo(const base::string16& text, - const gfx::Font& font, + const Font& font, SkColor text_color, SkColor halo_color, - int x, int y, int w, int h, + int x, + int y, + int w, + int h, int flags); // Extracts an ImageSkiaRep from the contents of this canvas. - gfx::ImageSkiaRep ExtractImageRep() const; + ImageSkiaRep ExtractImageRep() const; // Draws a dashed rectangle of the specified color. - void DrawDashedRect(const gfx::Rect& rect, SkColor color); + void DrawDashedRect(const Rect& rect, SkColor color); // Saves a copy of the drawing state onto a stack, operating on this copy // until a balanced call to Restore() is made. @@ -176,7 +196,7 @@ class UI_EXPORT Canvas { // |layer_bounds| are the bounds of the layer relative to the current // transform. void SaveLayerAlpha(uint8 alpha); - void SaveLayerAlpha(uint8 alpha, const gfx::Rect& layer_bounds); + void SaveLayerAlpha(uint8 alpha, const Rect& layer_bounds); // Restores the drawing state after a call to Save*(). It is an error to // call Restore() more times than Save*(). @@ -184,7 +204,7 @@ class UI_EXPORT Canvas { // Adds |rect| to the current clip. Returns true if the resulting clip is // non-empty. - bool ClipRect(const gfx::Rect& rect); + bool ClipRect(const Rect& rect); // Adds |path| to the current clip. Returns true if the resulting clip is // non-empty. @@ -192,9 +212,9 @@ class UI_EXPORT Canvas { // Returns the bounds of the current clip (in local coordinates) in the // |bounds| parameter, and returns true if it is non empty. - bool GetClipBounds(gfx::Rect* bounds); + bool GetClipBounds(Rect* bounds); - void Translate(const gfx::Vector2d& offset); + void Translate(const Vector2d& offset); void Scale(int x_scale, int y_scale); @@ -208,45 +228,43 @@ class UI_EXPORT Canvas { // Fills |rect| with |color| using a transfer mode of // SkXfermode::kSrcOver_Mode. - void FillRect(const gfx::Rect& rect, SkColor color); + void FillRect(const Rect& rect, SkColor color); // Fills |rect| with the specified |color| and |mode|. - void FillRect(const gfx::Rect& rect, SkColor color, SkXfermode::Mode mode); + void FillRect(const Rect& rect, SkColor color, SkXfermode::Mode mode); // Draws a single pixel rect in the specified region with the specified // color, using a transfer mode of SkXfermode::kSrcOver_Mode. // // NOTE: if you need a single pixel line, use DrawLine. - void DrawRect(const gfx::Rect& rect, SkColor color); + void DrawRect(const Rect& rect, SkColor color); // Draws a single pixel rect in the specified region with the specified // color and transfer mode. // // NOTE: if you need a single pixel line, use DrawLine. - void DrawRect(const gfx::Rect& rect, SkColor color, SkXfermode::Mode mode); + void DrawRect(const Rect& rect, SkColor color, SkXfermode::Mode mode); // Draws the given rectangle with the given |paint| parameters. - void DrawRect(const gfx::Rect& rect, const SkPaint& paint); + void DrawRect(const Rect& rect, const SkPaint& paint); // Draw the given point with the given |paint| parameters. - void DrawPoint(const gfx::Point& p, const SkPaint& paint); + void DrawPoint(const Point& p, const SkPaint& paint); // Draws a single pixel line with the specified color. - void DrawLine(const gfx::Point& p1, const gfx::Point& p2, SkColor color); + void DrawLine(const Point& p1, const Point& p2, SkColor color); // Draws a line with the given |paint| parameters. - void DrawLine(const gfx::Point& p1, - const gfx::Point& p2, - const SkPaint& paint); + void DrawLine(const Point& p1, const Point& p2, const SkPaint& paint); // Draws a circle with the given |paint| parameters. - void DrawCircle(const gfx::Point& center_point, + void DrawCircle(const Point& center_point, int radius, const SkPaint& paint); // Draws the given rectangle with rounded corners of |radius| using the // given |paint| parameters. - void DrawRoundRect(const gfx::Rect& rect, int radius, const SkPaint& paint); + void DrawRoundRect(const Rect& rect, int radius, const SkPaint& paint); // Draws the given path using the given |paint| parameters. void DrawPath(const SkPath& path, const SkPaint& paint); @@ -255,19 +273,20 @@ class UI_EXPORT Canvas { // corner of the bitmap is rendered at the specified location. // Parameters are specified relative to current canvas scale not in pixels. // Thus, x is 2 pixels if canvas scale = 2 & |x| = 1. - void DrawImageInt(const gfx::ImageSkia&, int x, int y); + void DrawImageInt(const ImageSkia&, int x, int y); // Helper for DrawImageInt(..., paint) that constructs a temporary paint and // calls paint.setAlpha(alpha). - void DrawImageInt(const gfx::ImageSkia&, int x, int y, uint8 alpha); + void DrawImageInt(const ImageSkia&, int x, int y, uint8 alpha); // Draws an image with the origin at the specified location, using the // specified paint. The upper left corner of the bitmap is rendered at the // specified location. // Parameters are specified relative to current canvas scale not in pixels. // Thus, |x| is 2 pixels if canvas scale = 2 & |x| = 1. - void DrawImageInt(const gfx::ImageSkia& image, - int x, int y, + void DrawImageInt(const ImageSkia& image, + int x, + int y, const SkPaint& paint); // Draws a portion of an image in the specified location. The src parameters @@ -282,13 +301,25 @@ class UI_EXPORT Canvas { // An optional custom SkPaint can be provided. // Parameters are specified relative to current canvas scale not in pixels. // Thus, |x| is 2 pixels if canvas scale = 2 & |x| = 1. - void DrawImageInt(const gfx::ImageSkia& image, - int src_x, int src_y, int src_w, int src_h, - int dest_x, int dest_y, int dest_w, int dest_h, + void DrawImageInt(const ImageSkia& image, + int src_x, + int src_y, + int src_w, + int src_h, + int dest_x, + int dest_y, + int dest_w, + int dest_h, bool filter); - void DrawImageInt(const gfx::ImageSkia& image, - int src_x, int src_y, int src_w, int src_h, - int dest_x, int dest_y, int dest_w, int dest_h, + void DrawImageInt(const ImageSkia& image, + int src_x, + int src_y, + int src_w, + int src_h, + int dest_x, + int dest_y, + int dest_w, + int dest_h, bool filter, const SkPaint& paint); @@ -296,59 +327,96 @@ class UI_EXPORT Canvas { // |path|. // Parameters are specified relative to current canvas scale not in pixels. // Thus, x is 2 pixels if canvas scale = 2 & |x| = 1. - void DrawImageInPath(const gfx::ImageSkia& image, + void DrawImageInPath(const ImageSkia& image, int x, int y, const SkPath& path, const SkPaint& paint); - // Draws text with the specified color, font and location. The text is + // Draws text with the specified color, fonts and location. The text is // aligned to the left, vertically centered, clipped to the region. If the // text is too big, it is truncated and '...' is added to the end. + void DrawStringRect(const base::string16& text, + const FontList& font_list, + SkColor color, + const Rect& display_rect); + // Obsolete versions. Use the above versions which take FontList. void DrawStringInt(const base::string16& text, - const gfx::Font& font, + const Font& font, SkColor color, - int x, int y, int w, int h); + int x, + int y, + int w, + int h); void DrawStringInt(const base::string16& text, - const gfx::Font& font, + const Font& font, SkColor color, - const gfx::Rect& display_rect); + const Rect& display_rect); - // Draws text with the specified color, font and location. The last argument + // Draws text with the specified color, fonts and location. The last argument // specifies flags for how the text should be rendered. It can be one of // TEXT_ALIGN_CENTER, TEXT_ALIGN_RIGHT or TEXT_ALIGN_LEFT. + void DrawStringRectWithFlags(const base::string16& text, + const FontList& font_list, + SkColor color, + const Rect& display_rect, + int flags); + // Obsolete version. Use the above version which takes FontList. void DrawStringInt(const base::string16& text, - const gfx::Font& font, + const Font& font, SkColor color, - int x, int y, int w, int h, + int x, + int y, + int w, + int h, int flags); // Similar to above DrawStringInt method but with text shadows support. // Currently it's only implemented for canvas skia. Specifying a 0 line_height // will cause the default height to be used. + void DrawStringRectWithShadows(const base::string16& text, + const FontList& font_list, + SkColor color, + const Rect& text_bounds, + int line_height, + int flags, + const ShadowValues& shadows); + // Obsolete version. Use the above version which takes FontList. void DrawStringWithShadows(const base::string16& text, - const gfx::Font& font, + const Font& font, SkColor color, - const gfx::Rect& text_bounds, + const Rect& text_bounds, int line_height, int flags, const ShadowValues& shadows); // Draws a dotted gray rectangle used for focus purposes. - void DrawFocusRect(const gfx::Rect& rect); + void DrawFocusRect(const Rect& rect); // Tiles the image in the specified region. // Parameters are specified relative to current canvas scale not in pixels. // Thus, |x| is 2 pixels if canvas scale = 2 & |x| = 1. - void TileImageInt(const gfx::ImageSkia& image, - int x, int y, int w, int h); - void TileImageInt(const gfx::ImageSkia& image, - int src_x, int src_y, - int dest_x, int dest_y, int w, int h); - void TileImageInt(const gfx::ImageSkia& image, - int src_x, int src_y, - float tile_scale_x, float tile_scale_y, - int dest_x, int dest_y, int w, int h); + void TileImageInt(const ImageSkia& image, + int x, + int y, + int w, + int h); + void TileImageInt(const ImageSkia& image, + int src_x, + int src_y, + int dest_x, + int dest_y, + int w, + int h); + void TileImageInt(const ImageSkia& image, + int src_x, + int src_y, + float tile_scale_x, + float tile_scale_y, + int dest_x, + int dest_y, + int w, + int h); // Returns a native drawing context for platform specific drawing routines to // use. Must be balanced by a call to EndPlatformPaint(). @@ -359,19 +427,27 @@ class UI_EXPORT Canvas { void EndPlatformPaint(); // Apply transformation on the canvas. - void Transform(const gfx::Transform& transform); + void Transform(const Transform& transform); // Draws the given string with the beginning and/or the end using a fade // gradient. When truncating the head // |desired_characters_to_truncate_from_head| specifies the maximum number of // characters that can be truncated. + void DrawFadeTruncatingStringRect( + const base::string16& text, + TruncateFadeMode truncate_mode, + size_t desired_characters_to_truncate_from_head, + const FontList& font_list, + SkColor color, + const Rect& display_rect); + // Obsolete version. Use the above version which takes FontList. void DrawFadeTruncatingString( const base::string16& text, TruncateFadeMode truncate_mode, size_t desired_characters_to_truncate_from_head, - const gfx::Font& font, + const Font& font, SkColor color, - const gfx::Rect& display_rect); + const Rect& display_rect); skia::PlatformCanvas* platform_canvas() const { return owned_canvas_.get(); } SkCanvas* sk_canvas() const { return canvas_; } @@ -382,19 +458,18 @@ class UI_EXPORT Canvas { // Test whether the provided rectangle intersects the current clip rect. bool IntersectsClipRectInt(int x, int y, int w, int h); - bool IntersectsClipRect(const gfx::Rect& rect); + bool IntersectsClipRect(const Rect& rect); // Returns the image rep which best matches the canvas |scale_factor_|. // Returns a null image rep if |image| contains no image reps. // Builds mip map for returned image rep if necessary. // // An optional additional user defined scale can be provided. - const gfx::ImageSkiaRep& GetImageRepToPaint( - const gfx::ImageSkia& image) const; - const gfx::ImageSkiaRep& GetImageRepToPaint( - const gfx::ImageSkia& image, + const ImageSkiaRep& GetImageRepToPaint(const ImageSkia& image) const; + const ImageSkiaRep& GetImageRepToPaint( + const ImageSkia& image, float user_defined_scale_factor_x, - float user_defined_scale_factor_y) const; + float user_defined_scale_factor_y) const; // The device scale factor at which drawing on this canvas occurs. // An additional scale can be applied via Canvas::Scale(). However, diff --git a/ui/gfx/canvas_android.cc b/ui/gfx/canvas_android.cc index c26a668..54e45f7 100644 --- a/ui/gfx/canvas_android.cc +++ b/ui/gfx/canvas_android.cc @@ -5,13 +5,12 @@ #include "ui/gfx/canvas.h" #include "base/logging.h" -#include "ui/gfx/font.h" namespace gfx { // static void Canvas::SizeStringInt(const base::string16& text, - const gfx::Font& font, + const FontList& font_list, int* width, int* height, int line_height, @@ -19,13 +18,22 @@ void Canvas::SizeStringInt(const base::string16& text, NOTIMPLEMENTED(); } -void Canvas::DrawStringWithShadows(const base::string16& text, - const gfx::Font& font, - SkColor color, - const gfx::Rect& text_bounds, - int line_height, - int flags, - const ShadowValues& shadows) { +void Canvas::DrawStringRectWithHalo(const base::string16& text, + const FontList& font_list, + SkColor text_color, + SkColor halo_color_in, + const Rect& display_rect, + int flags) { + NOTIMPLEMENTED(); +} + +void Canvas::DrawStringRectWithShadows(const base::string16& text, + const FontList& font_list, + SkColor color, + const Rect& text_bounds, + int line_height, + int flags, + const ShadowValues& shadows) { NOTIMPLEMENTED(); } diff --git a/ui/gfx/canvas_mac.mm b/ui/gfx/canvas_mac.mm index a906873..247c28b 100644 --- a/ui/gfx/canvas_mac.mm +++ b/ui/gfx/canvas_mac.mm @@ -2,14 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import <Cocoa/Cocoa.h> - #include "ui/gfx/canvas.h" +#import <Cocoa/Cocoa.h> + #include "base/logging.h" #include "base/strings/sys_string_conversions.h" #include "third_party/skia/include/core/SkTypeface.h" -#include "ui/gfx/font.h" +#include "ui/gfx/font_list.h" #include "ui/gfx/rect.h" // Note: This is a temporary Skia-based implementation of the ui/gfx text @@ -36,7 +36,7 @@ namespace gfx { // static void Canvas::SizeStringInt(const base::string16& text, - const gfx::Font& font, + const FontList& font_list, int* width, int* height, int line_height, @@ -44,27 +44,28 @@ void Canvas::SizeStringInt(const base::string16& text, DLOG_IF(WARNING, line_height != 0) << "Line heights not implemented."; DLOG_IF(WARNING, flags & Canvas::MULTI_LINE) << "Multi-line not implemented."; - NSFont* native_font = font.GetNativeFont(); + NSFont* native_font = font_list.GetPrimaryFont().GetNativeFont(); NSString* ns_string = base::SysUTF16ToNSString(text); NSDictionary* attributes = [NSDictionary dictionaryWithObject:native_font forKey:NSFontAttributeName]; NSSize string_size = [ns_string sizeWithAttributes:attributes]; *width = string_size.width; - *height = font.GetHeight(); + *height = font_list.GetHeight(); } -void Canvas::DrawStringWithShadows(const base::string16& text, - const gfx::Font& font, - SkColor color, - const gfx::Rect& text_bounds, - int line_height, - int flags, - const ShadowValues& shadows) { +void Canvas::DrawStringRectWithShadows(const base::string16& text, + const FontList& font_list, + SkColor color, + const Rect& text_bounds, + int line_height, + int flags, + const ShadowValues& shadows) { DLOG_IF(WARNING, line_height != 0) << "Line heights not implemented."; DLOG_IF(WARNING, flags & Canvas::MULTI_LINE) << "Multi-line not implemented."; DLOG_IF(WARNING, !shadows.empty()) << "Text shadows not implemented."; + const Font& font = font_list.GetPrimaryFont(); skia::RefPtr<SkTypeface> typeface = skia::AdoptRef( SkTypeface::CreateFromName( font.GetFontName().c_str(), FontTypefaceStyle(font))); @@ -78,12 +79,12 @@ void Canvas::DrawStringWithShadows(const base::string16& text, paint); } -void Canvas::DrawStringWithHalo(const base::string16& text, - const gfx::Font& font, - SkColor text_color, - SkColor halo_color, - int x, int y, int w, int h, - int flags) { +void Canvas::DrawStringRectWithHalo(const base::string16& text, + const FontList& font_list, + SkColor text_color, + SkColor halo_color, + const Rect& display_rect, + int flags) { } } // namespace gfx diff --git a/ui/gfx/canvas_skia.cc b/ui/gfx/canvas_skia.cc index bb8ce7d..11378d7 100644 --- a/ui/gfx/canvas_skia.cc +++ b/ui/gfx/canvas_skia.cc @@ -9,7 +9,6 @@ #include "base/memory/scoped_ptr.h" #include "ui/base/range/range.h" #include "ui/base/text/text_elider.h" -#include "ui/gfx/font.h" #include "ui/gfx/font_list.h" #include "ui/gfx/insets.h" #include "ui/gfx/rect.h" @@ -57,9 +56,9 @@ bool AdjustStringDirection(int flags, base::string16* text) { // Checks each pixel immediately adjacent to the given pixel in the bitmap. If // any of them are not the halo color, returns true. This defines the halo of // pixels that will appear around the text. Note that we have to check each -// pixel against both the halo color and transparent since |DrawStringWithHalo| -// will modify the bitmap as it goes, and cleared pixels shouldn't count as -// changed. +// pixel against both the halo color and transparent since +// |DrawStringRectWithHalo| will modify the bitmap as it goes, and cleared +// pixels shouldn't count as changed. bool PixelShouldGetHalo(const SkBitmap& bitmap, int x, int y, SkColor halo_color) { @@ -98,13 +97,13 @@ ui::Range StripAcceleratorChars(int flags, base::string16* text) { // Elides |text| and adjusts |range| appropriately. If eliding causes |range| // to no longer point to the same character in |text|, |range| is made invalid. -void ElideTextAndAdjustRange(const Font& font, +void ElideTextAndAdjustRange(const FontList& font_list, int width, base::string16* text, ui::Range* range) { const base::char16 start_char = (range->IsValid() ? text->at(range->start()) : 0); - *text = ui::ElideText(*text, font, width, ui::ELIDE_AT_END); + *text = ui::ElideText(*text, font_list, width, ui::ELIDE_AT_END); if (!range->IsValid()) return; if (range->start() >= text->length() || @@ -116,16 +115,16 @@ void ElideTextAndAdjustRange(const Font& font, // Updates |render_text| from the specified parameters. void UpdateRenderText(const Rect& rect, const base::string16& text, - const Font& font, + const FontList& font_list, int flags, SkColor color, RenderText* render_text) { - render_text->SetFont(font); + render_text->SetFontList(font_list); render_text->SetText(text); render_text->SetCursorEnabled(false); Rect display_rect = rect; - display_rect.set_height(font.GetHeight()); + display_rect.set_height(font_list.GetHeight()); render_text->SetDisplayRect(display_rect); // Set the text alignment explicitly based on the directionality of the UI, @@ -147,9 +146,10 @@ void UpdateRenderText(const Rect& rect, render_text->set_background_is_transparent(true); render_text->SetColor(color); - render_text->SetStyle(BOLD, (font.GetStyle() & Font::BOLD) != 0); - render_text->SetStyle(ITALIC, (font.GetStyle() & Font::ITALIC) != 0); - render_text->SetStyle(UNDERLINE, (font.GetStyle() & Font::UNDERLINE) != 0); + const int font_style = font_list.GetFontStyle(); + render_text->SetStyle(BOLD, (font_style & Font::BOLD) != 0); + render_text->SetStyle(ITALIC, (font_style & Font::ITALIC) != 0); + render_text->SetStyle(UNDERLINE, (font_style & Font::UNDERLINE) != 0); } // Returns updated |flags| to match platform-specific expected behavior. @@ -168,7 +168,7 @@ int AdjustPlatformSpecificFlags(const base::string16& text, int flags) { // static void Canvas::SizeStringInt(const base::string16& text, - const Font& font, + const FontList& font_list, int* width, int* height, int line_height, int flags) { @@ -191,17 +191,19 @@ void Canvas::SizeStringInt(const base::string16& text, Rect rect(*width, INT_MAX); std::vector<base::string16> strings; - ui::ElideRectangleText(adjusted_text, font, rect.width(), rect.height(), + ui::ElideRectangleText(adjusted_text, font_list, + rect.width(), rect.height(), wrap_behavior, &strings); scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); - UpdateRenderText(rect, base::string16(), font, flags, 0, render_text.get()); + UpdateRenderText(rect, base::string16(), font_list, flags, 0, + render_text.get()); int h = 0; int w = 0; for (size_t i = 0; i < strings.size(); ++i) { StripAcceleratorChars(flags, &strings[i]); render_text->SetText(strings[i]); - const Size string_size = render_text->GetStringSize(); + const Size& string_size = render_text->GetStringSize(); w = std::max(w, string_size.width()); h += (i > 0 && line_height > 0) ? line_height : string_size.height(); } @@ -212,27 +214,28 @@ void Canvas::SizeStringInt(const base::string16& text, // will inexplicably fail with result E_INVALIDARG. Guard against this. const size_t kMaxRenderTextLength = 5000; if (adjusted_text.length() >= kMaxRenderTextLength) { - *width = adjusted_text.length() * font.GetAverageCharacterWidth(); - *height = font.GetHeight(); + *width = font_list.GetExpectedTextWidth(adjusted_text.length()); + *height = font_list.GetHeight(); } else { scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); Rect rect(*width, *height); StripAcceleratorChars(flags, &adjusted_text); - UpdateRenderText(rect, adjusted_text, font, flags, 0, render_text.get()); - const Size string_size = render_text->GetStringSize(); + UpdateRenderText(rect, adjusted_text, font_list, flags, 0, + render_text.get()); + const Size& string_size = render_text->GetStringSize(); *width = string_size.width(); *height = string_size.height(); } } } -void Canvas::DrawStringWithShadows(const base::string16& text, - const Font& font, - SkColor color, - const Rect& text_bounds, - int line_height, - int flags, - const ShadowValues& shadows) { +void Canvas::DrawStringRectWithShadows(const base::string16& text, + const FontList& font_list, + SkColor color, + const Rect& text_bounds, + int line_height, + int flags, + const ShadowValues& shadows) { if (!IntersectsClipRect(text_bounds)) return; @@ -263,14 +266,15 @@ void Canvas::DrawStringWithShadows(const base::string16& text, std::vector<base::string16> strings; ui::ElideRectangleText(adjusted_text, - font, + font_list, text_bounds.width(), text_bounds.height(), wrap_behavior, &strings); for (size_t i = 0; i < strings.size(); i++) { ui::Range range = StripAcceleratorChars(flags, &strings[i]); - UpdateRenderText(rect, strings[i], font, flags, color, render_text.get()); + UpdateRenderText(rect, strings[i], font_list, flags, color, + render_text.get()); int line_padding = 0; if (line_height > 0) line_padding = line_height - render_text->GetStringSize().height(); @@ -311,13 +315,13 @@ void Canvas::DrawStringWithShadows(const base::string16& text, #endif if (elide_text) { - ElideTextAndAdjustRange(font, + ElideTextAndAdjustRange(font_list, text_bounds.width(), &adjusted_text, &range); } - UpdateRenderText(rect, adjusted_text, font, flags, color, + UpdateRenderText(rect, adjusted_text, font_list, flags, color, render_text.get()); const int text_height = render_text->GetStringSize().height(); @@ -333,19 +337,19 @@ void Canvas::DrawStringWithShadows(const base::string16& text, canvas_->restore(); } -void Canvas::DrawStringWithHalo(const base::string16& text, - const Font& font, - SkColor text_color, - SkColor halo_color_in, - int x, int y, int w, int h, - int flags) { +void Canvas::DrawStringRectWithHalo(const base::string16& text, + const FontList& font_list, + SkColor text_color, + SkColor halo_color_in, + const Rect& display_rect, + int flags) { // Some callers will have semitransparent halo colors, which we don't handle // (since the resulting image can have 1-bit transparency only). SkColor halo_color = SkColorSetA(halo_color_in, 0xFF); // Create a temporary buffer filled with the halo color. It must leave room // for the 1-pixel border around the text. - Size size(w + 2, h + 2); + Size size(display_rect.width() + 2, display_rect.height() + 2); Canvas text_canvas(size, scale_factor(), true); SkPaint bkgnd_paint; bkgnd_paint.setColor(halo_color); @@ -353,7 +357,9 @@ void Canvas::DrawStringWithHalo(const base::string16& text, // Draw the text into the temporary buffer. This will have correct // ClearType since the background color is the same as the halo color. - text_canvas.DrawStringInt(text, font, text_color, 1, 1, w, h, flags); + text_canvas.DrawStringRectWithFlags( + text, font_list, text_color, + Rect(1, 1, display_rect.width(), display_rect.height()), flags); uint32_t halo_premul = SkPreMultiplyColor(halo_color); SkBitmap& text_bitmap = const_cast<SkBitmap&>( @@ -376,22 +382,21 @@ void Canvas::DrawStringWithHalo(const base::string16& text, // Draw the halo bitmap with blur. ImageSkia text_image = ImageSkia(ImageSkiaRep(text_bitmap, text_canvas.scale_factor())); - DrawImageInt(text_image, x - 1, y - 1); + DrawImageInt(text_image, display_rect.x() - 1, display_rect.y() - 1); } -void Canvas::DrawFadeTruncatingString( - const base::string16& text, - TruncateFadeMode truncate_mode, - size_t desired_characters_to_truncate_from_head, - const Font& font, - SkColor color, - const Rect& display_rect) { +void Canvas::DrawFadeTruncatingStringRect( + const base::string16& text, + TruncateFadeMode truncate_mode, + size_t desired_characters_to_truncate_from_head, + const FontList& font_list, + SkColor color, + const Rect& display_rect) { int flags = NO_ELLIPSIS; // If the whole string fits in the destination then just draw it directly. - if (GetStringWidth(text, font) <= display_rect.width()) { - DrawStringInt(text, font, color, display_rect.x(), display_rect.y(), - display_rect.width(), display_rect.height(), flags); + if (GetStringWidth(text, font_list) <= display_rect.width()) { + DrawStringRectWithFlags(text, font_list, color, display_rect, flags); return; } @@ -437,7 +442,8 @@ void Canvas::DrawFadeTruncatingString( flags |= TEXT_ALIGN_LEFT; Rect rect = display_rect; - UpdateRenderText(rect, clipped_text, font, flags, color, render_text.get()); + UpdateRenderText(rect, clipped_text, font_list, flags, color, + render_text.get()); const int line_height = render_text->GetStringSize().height(); // Center the text vertically. @@ -451,4 +457,16 @@ void Canvas::DrawFadeTruncatingString( canvas_->restore(); } +void Canvas::DrawFadeTruncatingString( + const base::string16& text, + TruncateFadeMode truncate_mode, + size_t desired_characters_to_truncate_from_head, + const Font& font, + SkColor color, + const Rect& display_rect) { + DrawFadeTruncatingStringRect(text, truncate_mode, + desired_characters_to_truncate_from_head, + FontList(font), color, display_rect); +} + } // namespace gfx diff --git a/ui/gfx/text_utils.h b/ui/gfx/text_utils.h index 42bce43..15bf3ca 100644 --- a/ui/gfx/text_utils.h +++ b/ui/gfx/text_utils.h @@ -10,6 +10,8 @@ namespace gfx { +class FontList; + // Strip the accelerator char (typically '&') from a menu string. A double // accelerator char ('&&') will be converted to a single char. The out params // |accelerated_char_pos| and |accelerated_char_span| will be set to the index @@ -20,6 +22,11 @@ UI_EXPORT base::string16 RemoveAcceleratorChar(const base::string16& s, int* accelerated_char_pos, int* accelerated_char_span); +// Returns the number of horizontal pixels needed to display the specified +// |text| with |font_list|. +UI_EXPORT int GetStringWidth(const base::string16& text, + const FontList& font_list); + } // namespace gfx #endif // UI_GFX_TEXT_UTILS_H_ diff --git a/ui/gfx/text_utils_android.cc b/ui/gfx/text_utils_android.cc new file mode 100644 index 0000000..c564b9b --- /dev/null +++ b/ui/gfx/text_utils_android.cc @@ -0,0 +1,16 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/gfx/text_utils.h" + +#include "base/logging.h" + +namespace gfx { + +int GetStringWidth(const base::string16& text, const FontList& font_list) { + NOTIMPLEMENTED(); + return 0; +} + +} // namespace gfx diff --git a/ui/gfx/text_utils_ios.mm b/ui/gfx/text_utils_ios.mm new file mode 100644 index 0000000..1841864 --- /dev/null +++ b/ui/gfx/text_utils_ios.mm @@ -0,0 +1,22 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/gfx/text_utils.h" + +#import <UIKit/UIKit.h> + +#include <cmath> + +#include "base/strings/sys_string_conversions.h" +#include "ui/gfx/font_list.h" + +namespace gfx { + +int GetStringWidth(const base::string16& text, const FontList& font_list) { + NSString* ns_text = base::SysUTF16ToNSString(text); + NativeFont native_font = font_list.GetPrimaryFont().GetNativeFont(); + return std::ceil([ns_text sizeWithFont:native_font].width); +} + +} // namespace gfx diff --git a/ui/gfx/text_utils_skia.cc b/ui/gfx/text_utils_skia.cc new file mode 100644 index 0000000..0de1156 --- /dev/null +++ b/ui/gfx/text_utils_skia.cc @@ -0,0 +1,15 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/gfx/text_utils.h" + +#include "ui/gfx/canvas.h" + +namespace gfx { + +int GetStringWidth(const base::string16& text, const FontList& font_list) { + return Canvas::GetStringWidth(text, font_list); +} + +} // namespace gfx @@ -419,12 +419,12 @@ 'gfx/canvas.h', 'gfx/canvas_android.cc', 'gfx/canvas_mac.mm', + 'gfx/canvas_paint_gtk.cc', 'gfx/canvas_paint_gtk.h', 'gfx/canvas_paint_mac.h', - 'gfx/canvas_paint_win.h', - 'gfx/canvas_paint_gtk.cc', 'gfx/canvas_paint_mac.mm', 'gfx/canvas_paint_win.cc', + 'gfx/canvas_paint_win.h', 'gfx/canvas_skia.cc', 'gfx/canvas_skia_paint.h', 'gfx/codec/jpeg_codec.cc', @@ -583,6 +583,9 @@ 'gfx/text_constants.h', 'gfx/text_utils.cc', 'gfx/text_utils.h', + 'gfx/text_utils_android.cc', + 'gfx/text_utils_ios.mm', + 'gfx/text_utils_skia.cc', 'gfx/transform.cc', 'gfx/transform.h', 'gfx/transform_util.cc', @@ -908,6 +911,7 @@ 'sources!': [ 'gfx/render_text.cc', 'gfx/render_text.h', + 'gfx/text_utils_skia.cc', ], }], ['OS=="linux"', { diff --git a/ui/views/widget/tooltip_manager.cc b/ui/views/widget/tooltip_manager.cc index bfcbf02b..f600a12 100644 --- a/ui/views/widget/tooltip_manager.cc +++ b/ui/views/widget/tooltip_manager.cc @@ -9,6 +9,7 @@ #include "base/strings/string_split.h" #include "base/strings/utf_string_conversions.h" #include "ui/base/text/text_elider.h" +#include "ui/gfx/font.h" namespace { |