| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ui/gfx/font_list_impl.h" | 5 #include "ui/gfx/font_list_impl.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/strings/string_number_conversions.h" | 10 #include "base/strings/string_number_conversions.h" |
| 11 #include "base/strings/string_split.h" | |
| 12 #include "base/strings/string_util.h" | 11 #include "base/strings/string_util.h" |
| 13 #include "ui/gfx/font.h" | 12 #include "ui/gfx/font.h" |
| 13 #include "ui/gfx/font_list.h" |
| 14 | 14 |
| 15 namespace { | 15 namespace { |
| 16 | 16 |
| 17 // Parses font description into |font_names|, |font_style| and |font_size|. | 17 // Returns a font description from |families|, |style|, and |size_pixels|. |
| 18 void ParseFontDescriptionString(const std::string& font_description_string, | 18 std::string BuildDescription(const std::vector<std::string>& families, |
| 19 std::vector<std::string>* font_names, | 19 int style, |
| 20 int* font_style, | 20 int size_pixels) { |
| 21 int* font_size) { | 21 std::string description = JoinString(families, ','); |
| 22 base::SplitString(font_description_string, ',', font_names); | 22 description += ","; |
| 23 DCHECK_GT(font_names->size(), 1U); | |
| 24 | 23 |
| 25 // The last item is [STYLE_OPTIONS] SIZE. | 24 if (style & gfx::Font::BOLD) |
| 26 std::vector<std::string> styles_size; | 25 description += "Bold "; |
| 27 base::SplitString(font_names->back(), ' ', &styles_size); | 26 if (style & gfx::Font::ITALIC) |
| 28 DCHECK(!styles_size.empty()); | 27 description += "Italic "; |
| 29 base::StringToInt(styles_size.back(), font_size); | |
| 30 DCHECK_GT(*font_size, 0); | |
| 31 font_names->pop_back(); | |
| 32 | 28 |
| 33 // Font supports BOLD and ITALIC; underline is supported via RenderText. | 29 description += base::IntToString(size_pixels); |
| 34 *font_style = 0; | 30 description += "px"; |
| 35 for (size_t i = 0; i < styles_size.size() - 1; ++i) { | |
| 36 // Styles are separated by white spaces. base::SplitString splits styles | |
| 37 // by space, and it inserts empty string for continuous spaces. | |
| 38 if (styles_size[i].empty()) | |
| 39 continue; | |
| 40 if (!styles_size[i].compare("Bold")) | |
| 41 *font_style |= gfx::Font::BOLD; | |
| 42 else if (!styles_size[i].compare("Italic")) | |
| 43 *font_style |= gfx::Font::ITALIC; | |
| 44 else | |
| 45 NOTREACHED(); | |
| 46 } | |
| 47 } | |
| 48 | 31 |
| 49 // Returns the font style and size as a string. | |
| 50 std::string FontStyleAndSizeToString(int font_style, int font_size) { | |
| 51 std::string result; | |
| 52 if (font_style & gfx::Font::BOLD) | |
| 53 result += "Bold "; | |
| 54 if (font_style & gfx::Font::ITALIC) | |
| 55 result += "Italic "; | |
| 56 result += base::IntToString(font_size); | |
| 57 result += "px"; | |
| 58 return result; | |
| 59 } | |
| 60 | |
| 61 // Returns font description from |font_names|, |font_style|, and |font_size|. | |
| 62 std::string BuildFontDescription(const std::vector<std::string>& font_names, | |
| 63 int font_style, | |
| 64 int font_size) { | |
| 65 std::string description = JoinString(font_names, ','); | |
| 66 description += "," + FontStyleAndSizeToString(font_style, font_size); | |
| 67 return description; | 32 return description; |
| 68 } | 33 } |
| 69 | 34 |
| 70 } // namespace | 35 } // namespace |
| 71 | 36 |
| 72 namespace gfx { | 37 namespace gfx { |
| 73 | 38 |
| 74 FontListImpl::FontListImpl(const std::string& font_description_string) | 39 FontListImpl::FontListImpl(const std::string& font_description_string) |
| 75 : font_description_string_(font_description_string), | 40 : font_description_string_(font_description_string), |
| 76 common_height_(-1), | 41 common_height_(-1), |
| 77 common_baseline_(-1), | 42 common_baseline_(-1), |
| 78 font_style_(-1), | 43 font_style_(-1), |
| 79 font_size_(-1) { | 44 font_size_(-1) { |
| 80 DCHECK(!font_description_string.empty()); | 45 DCHECK(!font_description_string.empty()); |
| 81 // DCHECK description string ends with "px" for size in pixel. | 46 // DCHECK description string ends with "px" for size in pixel. |
| 82 DCHECK(EndsWith(font_description_string, "px", true)); | 47 DCHECK(EndsWith(font_description_string, "px", true)); |
| 83 } | 48 } |
| 84 | 49 |
| 85 FontListImpl::FontListImpl(const std::vector<std::string>& font_names, | 50 FontListImpl::FontListImpl(const std::vector<std::string>& font_names, |
| 86 int font_style, | 51 int font_style, |
| 87 int font_size) | 52 int font_size) |
| 88 : font_description_string_(BuildFontDescription(font_names, font_style, | 53 : font_description_string_(BuildDescription(font_names, font_style, |
| 89 font_size)), | 54 font_size)), |
| 90 common_height_(-1), | 55 common_height_(-1), |
| 91 common_baseline_(-1), | 56 common_baseline_(-1), |
| 92 font_style_(font_style), | 57 font_style_(font_style), |
| 93 font_size_(font_size) { | 58 font_size_(font_size) { |
| 94 DCHECK(!font_names.empty()); | 59 DCHECK(!font_names.empty()); |
| 95 DCHECK(!font_names[0].empty()); | 60 DCHECK(!font_names[0].empty()); |
| 96 } | 61 } |
| 97 | 62 |
| 98 FontListImpl::FontListImpl(const std::vector<Font>& fonts) | 63 FontListImpl::FontListImpl(const std::vector<Font>& fonts) |
| 99 : fonts_(fonts), | 64 : fonts_(fonts), |
| (...skipping 26 matching lines...) Expand all Loading... |
| 126 std::vector<Font> fonts = fonts_; | 91 std::vector<Font> fonts = fonts_; |
| 127 for (size_t i = 0; i < fonts.size(); ++i) | 92 for (size_t i = 0; i < fonts.size(); ++i) |
| 128 fonts[i] = fonts[i].Derive(size_delta, font_style); | 93 fonts[i] = fonts[i].Derive(size_delta, font_style); |
| 129 return new FontListImpl(fonts); | 94 return new FontListImpl(fonts); |
| 130 } | 95 } |
| 131 | 96 |
| 132 // Otherwise, parse the font description string to derive from it. | 97 // Otherwise, parse the font description string to derive from it. |
| 133 std::vector<std::string> font_names; | 98 std::vector<std::string> font_names; |
| 134 int old_size; | 99 int old_size; |
| 135 int old_style; | 100 int old_style; |
| 136 ParseFontDescriptionString(font_description_string_, &font_names, | 101 CHECK(FontList::ParseDescription(font_description_string_, &font_names, |
| 137 &old_style, &old_size); | 102 &old_style, &old_size)); |
| 138 const int size = std::max(1, old_size + size_delta); | 103 const int size = std::max(1, old_size + size_delta); |
| 139 return new FontListImpl(font_names, font_style, size); | 104 return new FontListImpl(font_names, font_style, size); |
| 140 } | 105 } |
| 141 | 106 |
| 142 int FontListImpl::GetHeight() const { | 107 int FontListImpl::GetHeight() const { |
| 143 if (common_height_ == -1) | 108 if (common_height_ == -1) |
| 144 CacheCommonFontHeightAndBaseline(); | 109 CacheCommonFontHeightAndBaseline(); |
| 145 return common_height_; | 110 return common_height_; |
| 146 } | 111 } |
| 147 | 112 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 160 // Rely on the primary font metrics for the time being. | 125 // Rely on the primary font metrics for the time being. |
| 161 return GetPrimaryFont().GetExpectedTextWidth(length); | 126 return GetPrimaryFont().GetExpectedTextWidth(length); |
| 162 } | 127 } |
| 163 | 128 |
| 164 int FontListImpl::GetFontStyle() const { | 129 int FontListImpl::GetFontStyle() const { |
| 165 if (font_style_ == -1) | 130 if (font_style_ == -1) |
| 166 CacheFontStyleAndSize(); | 131 CacheFontStyleAndSize(); |
| 167 return font_style_; | 132 return font_style_; |
| 168 } | 133 } |
| 169 | 134 |
| 170 const std::string& FontListImpl::GetFontDescriptionString() const { | |
| 171 if (font_description_string_.empty()) { | |
| 172 DCHECK(!fonts_.empty()); | |
| 173 for (size_t i = 0; i < fonts_.size(); ++i) { | |
| 174 std::string name = fonts_[i].GetFontName(); | |
| 175 font_description_string_ += name; | |
| 176 font_description_string_ += ','; | |
| 177 } | |
| 178 // All fonts have the same style and size. | |
| 179 font_description_string_ += | |
| 180 FontStyleAndSizeToString(fonts_[0].GetStyle(), fonts_[0].GetFontSize()); | |
| 181 } | |
| 182 return font_description_string_; | |
| 183 } | |
| 184 | |
| 185 int FontListImpl::GetFontSize() const { | 135 int FontListImpl::GetFontSize() const { |
| 186 if (font_size_ == -1) | 136 if (font_size_ == -1) |
| 187 CacheFontStyleAndSize(); | 137 CacheFontStyleAndSize(); |
| 188 return font_size_; | 138 return font_size_; |
| 189 } | 139 } |
| 190 | 140 |
| 191 const std::vector<Font>& FontListImpl::GetFonts() const { | 141 const std::vector<Font>& FontListImpl::GetFonts() const { |
| 192 if (fonts_.empty()) { | 142 if (fonts_.empty()) { |
| 193 DCHECK(!font_description_string_.empty()); | 143 DCHECK(!font_description_string_.empty()); |
| 194 | 144 |
| 195 std::vector<std::string> font_names; | 145 std::vector<std::string> font_names; |
| 196 // It's possible that gfx::Font::UNDERLINE is specified and it's already | 146 // It's possible that gfx::Font::UNDERLINE is specified and it's already |
| 197 // stored in |font_style_| but |font_description_string_| doesn't have the | 147 // stored in |font_style_| but |font_description_string_| doesn't have the |
| 198 // underline info. So we should respect |font_style_| as long as it's | 148 // underline info. So we should respect |font_style_| as long as it's |
| 199 // valid. | 149 // valid. |
| 200 int style = 0; | 150 int style = 0; |
| 201 ParseFontDescriptionString(font_description_string_, &font_names, | 151 CHECK(FontList::ParseDescription(font_description_string_, &font_names, |
| 202 &style, &font_size_); | 152 &style, &font_size_)); |
| 203 if (font_style_ == -1) | 153 if (font_style_ == -1) |
| 204 font_style_ = style; | 154 font_style_ = style; |
| 205 for (size_t i = 0; i < font_names.size(); ++i) { | 155 for (size_t i = 0; i < font_names.size(); ++i) { |
| 206 DCHECK(!font_names[i].empty()); | 156 DCHECK(!font_names[i].empty()); |
| 207 | 157 |
| 208 Font font(font_names[i], font_size_); | 158 Font font(font_names[i], font_size_); |
| 209 if (font_style_ == Font::NORMAL) | 159 if (font_style_ == Font::NORMAL) |
| 210 fonts_.push_back(font); | 160 fonts_.push_back(font); |
| 211 else | 161 else |
| 212 fonts_.push_back(font.Derive(0, font_style_)); | 162 fonts_.push_back(font.Derive(0, font_style_)); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 233 common_height_ = ascent + descent; | 183 common_height_ = ascent + descent; |
| 234 common_baseline_ = ascent; | 184 common_baseline_ = ascent; |
| 235 } | 185 } |
| 236 | 186 |
| 237 void FontListImpl::CacheFontStyleAndSize() const { | 187 void FontListImpl::CacheFontStyleAndSize() const { |
| 238 if (!fonts_.empty()) { | 188 if (!fonts_.empty()) { |
| 239 font_style_ = fonts_[0].GetStyle(); | 189 font_style_ = fonts_[0].GetStyle(); |
| 240 font_size_ = fonts_[0].GetFontSize(); | 190 font_size_ = fonts_[0].GetFontSize(); |
| 241 } else { | 191 } else { |
| 242 std::vector<std::string> font_names; | 192 std::vector<std::string> font_names; |
| 243 ParseFontDescriptionString(font_description_string_, &font_names, | 193 CHECK(FontList::ParseDescription(font_description_string_, &font_names, |
| 244 &font_style_, &font_size_); | 194 &font_style_, &font_size_)); |
| 245 } | 195 } |
| 246 } | 196 } |
| 247 | 197 |
| 248 } // namespace gfx | 198 } // namespace gfx |
| OLD | NEW |