| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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.h" | 5 #include "ui/gfx/font_list.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" |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 63 int font_size) { | 63 int font_size) { |
| 64 std::string description = JoinString(font_names, ','); | 64 std::string description = JoinString(font_names, ','); |
| 65 description += "," + FontStyleAndSizeToString(font_style, font_size); | 65 description += "," + FontStyleAndSizeToString(font_style, font_size); |
| 66 return description; | 66 return description; |
| 67 } | 67 } |
| 68 | 68 |
| 69 } // namespace | 69 } // namespace |
| 70 | 70 |
| 71 namespace gfx { | 71 namespace gfx { |
| 72 | 72 |
| 73 FontList::FontList() : common_height_(-1), common_baseline_(-1) { | 73 FontList::FontList() |
| 74 : common_height_(-1), |
| 75 common_baseline_(-1), |
| 76 font_style_(-1), |
| 77 font_size_(-1) { |
| 74 fonts_.push_back(Font()); | 78 fonts_.push_back(Font()); |
| 75 } | 79 } |
| 76 | 80 |
| 77 FontList::FontList(const std::string& font_description_string) | 81 FontList::FontList(const std::string& font_description_string) |
| 78 : font_description_string_(font_description_string), | 82 : font_description_string_(font_description_string), |
| 79 common_height_(-1), | 83 common_height_(-1), |
| 80 common_baseline_(-1) { | 84 common_baseline_(-1), |
| 85 font_style_(-1), |
| 86 font_size_(-1) { |
| 81 DCHECK(!font_description_string.empty()); | 87 DCHECK(!font_description_string.empty()); |
| 82 // DCHECK description string ends with "px" for size in pixel. | 88 // DCHECK description string ends with "px" for size in pixel. |
| 83 DCHECK(EndsWith(font_description_string, "px", true)); | 89 DCHECK(EndsWith(font_description_string, "px", true)); |
| 84 } | 90 } |
| 85 | 91 |
| 92 FontList::FontList(const std::vector<std::string>& font_names, |
| 93 int font_style, |
| 94 int font_size) |
| 95 : font_description_string_(BuildFontDescription(font_names, font_style, |
| 96 font_size)), |
| 97 common_height_(-1), |
| 98 common_baseline_(-1), |
| 99 font_style_(font_style), |
| 100 font_size_(font_size) { |
| 101 DCHECK(!font_names.empty()); |
| 102 DCHECK(!font_names[0].empty()); |
| 103 } |
| 104 |
| 86 FontList::FontList(const std::vector<Font>& fonts) | 105 FontList::FontList(const std::vector<Font>& fonts) |
| 87 : fonts_(fonts), | 106 : fonts_(fonts), |
| 88 common_height_(-1), | 107 common_height_(-1), |
| 89 common_baseline_(-1) { | 108 common_baseline_(-1), |
| 109 font_style_(-1), |
| 110 font_size_(-1) { |
| 90 DCHECK(!fonts.empty()); | 111 DCHECK(!fonts.empty()); |
| 112 font_style_ = fonts[0].GetStyle(); |
| 113 font_size_ = fonts[0].GetFontSize(); |
| 91 if (DCHECK_IS_ON()) { | 114 if (DCHECK_IS_ON()) { |
| 92 int style = fonts[0].GetStyle(); | |
| 93 int size = fonts[0].GetFontSize(); | |
| 94 for (size_t i = 1; i < fonts.size(); ++i) { | 115 for (size_t i = 1; i < fonts.size(); ++i) { |
| 95 DCHECK_EQ(fonts[i].GetStyle(), style); | 116 DCHECK_EQ(fonts[i].GetStyle(), font_style_); |
| 96 DCHECK_EQ(fonts[i].GetFontSize(), size); | 117 DCHECK_EQ(fonts[i].GetFontSize(), font_size_); |
| 97 } | 118 } |
| 98 } | 119 } |
| 99 } | 120 } |
| 100 | 121 |
| 101 FontList::FontList(const Font& font) | 122 FontList::FontList(const Font& font) |
| 102 : common_height_(-1), | 123 : common_height_(-1), |
| 103 common_baseline_(-1) { | 124 common_baseline_(-1), |
| 125 font_style_(-1), |
| 126 font_size_(-1) { |
| 104 fonts_.push_back(font); | 127 fonts_.push_back(font); |
| 105 } | 128 } |
| 106 | 129 |
| 107 FontList::~FontList() { | 130 FontList::~FontList() { |
| 108 } | 131 } |
| 109 | 132 |
| 110 FontList FontList::DeriveFontList(int font_style) const { | 133 FontList FontList::DeriveFontList(int font_style) const { |
| 134 return DeriveFontListWithSizeDeltaAndStyle(0, font_style); |
| 135 } |
| 136 |
| 137 FontList FontList::DeriveFontListWithSize(int size) const { |
| 138 DCHECK_GT(size, 0); |
| 139 return DeriveFontListWithSizeDeltaAndStyle(size - GetFontSize(), |
| 140 GetFontStyle()); |
| 141 } |
| 142 |
| 143 FontList FontList::DeriveFontListWithSizeDelta(int size_delta) const { |
| 144 return DeriveFontListWithSizeDeltaAndStyle(size_delta, GetFontStyle()); |
| 145 } |
| 146 |
| 147 FontList FontList::DeriveFontListWithSizeDeltaAndStyle(int size_delta, |
| 148 int style) const { |
| 111 // If there is a font vector, derive from that. | 149 // If there is a font vector, derive from that. |
| 112 if (!fonts_.empty()) { | 150 if (!fonts_.empty()) { |
| 113 std::vector<Font> fonts = fonts_; | 151 std::vector<Font> fonts = fonts_; |
| 114 for (size_t i = 0; i < fonts.size(); ++i) | 152 for (size_t i = 0; i < fonts.size(); ++i) |
| 115 fonts[i] = fonts[i].DeriveFont(0, font_style); | 153 fonts[i] = fonts[i].DeriveFont(size_delta, style); |
| 116 return FontList(fonts); | 154 return FontList(fonts); |
| 117 } | 155 } |
| 118 | 156 |
| 119 // Otherwise, parse the font description string to derive from it. | 157 // Otherwise, parse the font description string to derive from it. |
| 120 std::vector<std::string> font_names; | 158 std::vector<std::string> font_names; |
| 159 int old_size; |
| 121 int old_style; | 160 int old_style; |
| 122 int font_size; | |
| 123 ParseFontDescriptionString(font_description_string_, &font_names, | 161 ParseFontDescriptionString(font_description_string_, &font_names, |
| 124 &old_style, &font_size); | 162 &old_style, &old_size); |
| 125 return FontList(BuildFontDescription(font_names, font_style, font_size)); | 163 int size = old_size + size_delta; |
| 126 } | |
| 127 | |
| 128 FontList FontList::DeriveFontListWithSize(int size) const { | |
| 129 DCHECK_GT(size, 0); | 164 DCHECK_GT(size, 0); |
| 130 | 165 return FontList(font_names, style, size); |
| 131 // If there is a font vector, derive from that. | |
| 132 int old_size = 0; | |
| 133 if (!fonts_.empty()) { | |
| 134 old_size = fonts_[0].GetFontSize(); | |
| 135 if (old_size == size) | |
| 136 return FontList(fonts_); | |
| 137 | |
| 138 std::vector<Font> fonts = fonts_; | |
| 139 for (size_t i = 0; i < fonts.size(); ++i) | |
| 140 fonts[i] = fonts[i].DeriveFont(size - old_size); | |
| 141 return FontList(fonts); | |
| 142 } | |
| 143 | |
| 144 // Otherwise, parse the font description string to derive from it. | |
| 145 std::vector<std::string> font_names; | |
| 146 int font_style = 0; | |
| 147 ParseFontDescriptionString(font_description_string_, &font_names, | |
| 148 &font_style, &old_size); | |
| 149 | |
| 150 if (old_size == size) | |
| 151 return FontList(font_description_string_); | |
| 152 | |
| 153 return FontList(BuildFontDescription(font_names, font_style, size)); | |
| 154 } | 166 } |
| 155 | 167 |
| 156 int FontList::GetHeight() const { | 168 int FontList::GetHeight() const { |
| 157 if (common_height_ < 0) { | 169 if (common_height_ == -1) |
| 158 int ascent = 0; | 170 CacheCommonFontHeightAndBaseline(); |
| 159 int descent = 0; | |
| 160 const std::vector<Font>& fonts = GetFonts(); | |
| 161 for (std::vector<Font>::const_iterator i = fonts.begin(); | |
| 162 i != fonts.end(); ++i) { | |
| 163 ascent = std::max(ascent, i->GetBaseline()); | |
| 164 descent = std::max(descent, i->GetHeight() - i->GetBaseline()); | |
| 165 } | |
| 166 common_height_ = ascent + descent; | |
| 167 } | |
| 168 return common_height_; | 171 return common_height_; |
| 169 } | 172 } |
| 170 | 173 |
| 171 int FontList::GetBaseline() const { | 174 int FontList::GetBaseline() const { |
| 172 if (common_baseline_ < 0) { | 175 if (common_baseline_ == -1) |
| 173 int baseline = 0; | 176 CacheCommonFontHeightAndBaseline(); |
| 174 const std::vector<Font>& fonts = GetFonts(); | |
| 175 for (std::vector<Font>::const_iterator i = fonts.begin(); | |
| 176 i != fonts.end(); ++i) { | |
| 177 baseline = std::max(baseline, i->GetBaseline()); | |
| 178 } | |
| 179 common_baseline_ = baseline; | |
| 180 } | |
| 181 return common_baseline_; | 177 return common_baseline_; |
| 182 } | 178 } |
| 183 | 179 |
| 180 int FontList::GetStringWidth(const base::string16& text) const { |
| 181 // Rely on the primary font metrics for the time being. |
| 182 // TODO(yukishiino): Not only the first font, all the fonts in the list should |
| 183 // be taken into account to compute the pixels needed to display |text|. |
| 184 // Also this method, including one in Font class, should be deprecated and |
| 185 // client code should call Canvas::GetStringWidth(text, font_list) directly. |
| 186 // Our plan is as follows: |
| 187 // 1. Introduce the FontList version of Canvas::GetStringWidth(). |
| 188 // 2. Make client code call Canvas::GetStringWidth(). |
| 189 // 3. Retire {Font,FontList}::GetStringWidth(). |
| 190 return GetPrimaryFont().GetStringWidth(text); |
| 191 } |
| 192 |
| 193 int FontList::GetExpectedTextWidth(int length) const { |
| 194 // Rely on the primary font metrics for the time being. |
| 195 return GetPrimaryFont().GetExpectedTextWidth(length); |
| 196 } |
| 197 |
| 184 int FontList::GetFontStyle() const { | 198 int FontList::GetFontStyle() const { |
| 185 if (!fonts_.empty()) | 199 if (font_style_ == -1) |
| 186 return fonts_[0].GetStyle(); | 200 CacheFontStyleAndSize(); |
| 187 | 201 return font_style_; |
| 188 std::vector<std::string> font_names; | |
| 189 int font_style; | |
| 190 int font_size; | |
| 191 ParseFontDescriptionString(font_description_string_, &font_names, | |
| 192 &font_style, &font_size); | |
| 193 return font_style; | |
| 194 } | 202 } |
| 195 | 203 |
| 196 const std::string& FontList::GetFontDescriptionString() const { | 204 const std::string& FontList::GetFontDescriptionString() const { |
| 197 if (font_description_string_.empty()) { | 205 if (font_description_string_.empty()) { |
| 198 DCHECK(!fonts_.empty()); | 206 DCHECK(!fonts_.empty()); |
| 199 for (size_t i = 0; i < fonts_.size(); ++i) { | 207 for (size_t i = 0; i < fonts_.size(); ++i) { |
| 200 std::string name = fonts_[i].GetFontName(); | 208 std::string name = fonts_[i].GetFontName(); |
| 201 font_description_string_ += name; | 209 font_description_string_ += name; |
| 202 font_description_string_ += ','; | 210 font_description_string_ += ','; |
| 203 } | 211 } |
| 204 // All fonts have the same style and size. | 212 // All fonts have the same style and size. |
| 205 font_description_string_ += | 213 font_description_string_ += |
| 206 FontStyleAndSizeToString(fonts_[0].GetStyle(), fonts_[0].GetFontSize()); | 214 FontStyleAndSizeToString(fonts_[0].GetStyle(), fonts_[0].GetFontSize()); |
| 207 } | 215 } |
| 208 return font_description_string_; | 216 return font_description_string_; |
| 209 } | 217 } |
| 210 | 218 |
| 211 int FontList::GetFontSize() const { | 219 int FontList::GetFontSize() const { |
| 212 if (!fonts_.empty()) | 220 if (font_size_ == -1) |
| 213 return fonts_[0].GetFontSize(); | 221 CacheFontStyleAndSize(); |
| 214 | 222 return font_size_; |
| 215 std::vector<std::string> font_names; | |
| 216 int font_style; | |
| 217 int font_size; | |
| 218 ParseFontDescriptionString(font_description_string_, &font_names, | |
| 219 &font_style, &font_size); | |
| 220 return font_size; | |
| 221 } | 223 } |
| 222 | 224 |
| 223 const std::vector<Font>& FontList::GetFonts() const { | 225 const std::vector<Font>& FontList::GetFonts() const { |
| 224 if (fonts_.empty()) { | 226 if (fonts_.empty()) { |
| 225 DCHECK(!font_description_string_.empty()); | 227 DCHECK(!font_description_string_.empty()); |
| 226 | 228 |
| 227 std::vector<std::string> font_names; | 229 std::vector<std::string> font_names; |
| 228 int font_style; | |
| 229 int font_size; | |
| 230 ParseFontDescriptionString(font_description_string_, &font_names, | 230 ParseFontDescriptionString(font_description_string_, &font_names, |
| 231 &font_style, &font_size); | 231 &font_style_, &font_size_); |
| 232 for (size_t i = 0; i < font_names.size(); ++i) { | 232 for (size_t i = 0; i < font_names.size(); ++i) { |
| 233 DCHECK(!font_names[i].empty()); | 233 DCHECK(!font_names[i].empty()); |
| 234 | 234 |
| 235 Font font(font_names[i], font_size); | 235 Font font(font_names[i], font_size_); |
| 236 if (font_style == Font::NORMAL) | 236 if (font_style_ == Font::NORMAL) |
| 237 fonts_.push_back(font); | 237 fonts_.push_back(font); |
| 238 else | 238 else |
| 239 fonts_.push_back(font.DeriveFont(0, font_style)); | 239 fonts_.push_back(font.DeriveFont(0, font_style_)); |
| 240 } | 240 } |
| 241 } | 241 } |
| 242 return fonts_; | 242 return fonts_; |
| 243 } | 243 } |
| 244 | 244 |
| 245 const Font& FontList::GetPrimaryFont() const { | 245 const Font& FontList::GetPrimaryFont() const { |
| 246 return GetFonts()[0]; | 246 return GetFonts()[0]; |
| 247 } | 247 } |
| 248 | 248 |
| 249 void FontList::CacheCommonFontHeightAndBaseline() const { |
| 250 int ascent = 0; |
| 251 int descent = 0; |
| 252 const std::vector<Font>& fonts = GetFonts(); |
| 253 for (std::vector<Font>::const_iterator i = fonts.begin(); |
| 254 i != fonts.end(); ++i) { |
| 255 ascent = std::max(ascent, i->GetBaseline()); |
| 256 descent = std::max(descent, i->GetHeight() - i->GetBaseline()); |
| 257 } |
| 258 common_height_ = ascent + descent; |
| 259 common_baseline_ = ascent; |
| 260 } |
| 261 |
| 262 void FontList::CacheFontStyleAndSize() const { |
| 263 if (!fonts_.empty()) { |
| 264 font_style_ = fonts_[0].GetStyle(); |
| 265 font_size_ = fonts_[0].GetFontSize(); |
| 266 } else { |
| 267 std::vector<std::string> font_names; |
| 268 ParseFontDescriptionString(font_description_string_, &font_names, |
| 269 &font_style_, &font_size_); |
| 270 } |
| 271 } |
| 272 |
| 249 } // namespace gfx | 273 } // namespace gfx |
| OLD | NEW |