Center distiller results on desktop
[chromium-blink-merge.git] / ui / gfx / font_list_impl.cc
blobbabadb118c15a32e00f5006dba277d090734edcd
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
3 // found in the LICENSE file.
5 #include "ui/gfx/font_list_impl.h"
7 #include <algorithm>
9 #include "base/logging.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "base/strings/string_util.h"
12 #include "ui/gfx/font.h"
13 #include "ui/gfx/font_list.h"
15 namespace {
17 // Returns a font description from |families|, |style|, and |size_pixels|.
18 std::string BuildDescription(const std::vector<std::string>& families,
19 int style,
20 int size_pixels) {
21 std::string description = JoinString(families, ',');
22 description += ",";
24 if (style & gfx::Font::BOLD)
25 description += "Bold ";
26 if (style & gfx::Font::ITALIC)
27 description += "Italic ";
29 description += base::IntToString(size_pixels);
30 description += "px";
32 return description;
35 } // namespace
37 namespace gfx {
39 FontListImpl::FontListImpl(const std::string& font_description_string)
40 : font_description_string_(font_description_string),
41 common_height_(-1),
42 common_baseline_(-1),
43 font_style_(-1),
44 font_size_(-1) {
45 DCHECK(!font_description_string.empty());
46 // DCHECK description string ends with "px" for size in pixel.
47 DCHECK(EndsWith(font_description_string, "px", true));
50 FontListImpl::FontListImpl(const std::vector<std::string>& font_names,
51 int font_style,
52 int font_size)
53 : font_description_string_(BuildDescription(font_names, font_style,
54 font_size)),
55 common_height_(-1),
56 common_baseline_(-1),
57 font_style_(font_style),
58 font_size_(font_size) {
59 DCHECK(!font_names.empty());
60 DCHECK(!font_names[0].empty());
63 FontListImpl::FontListImpl(const std::vector<Font>& fonts)
64 : fonts_(fonts),
65 common_height_(-1),
66 common_baseline_(-1),
67 font_style_(-1),
68 font_size_(-1) {
69 DCHECK(!fonts.empty());
70 font_style_ = fonts[0].GetStyle();
71 font_size_ = fonts[0].GetFontSize();
72 #if DCHECK_IS_ON()
73 for (size_t i = 1; i < fonts.size(); ++i) {
74 DCHECK_EQ(fonts[i].GetStyle(), font_style_);
75 DCHECK_EQ(fonts[i].GetFontSize(), font_size_);
77 #endif
80 FontListImpl::FontListImpl(const Font& font)
81 : common_height_(-1),
82 common_baseline_(-1),
83 font_style_(-1),
84 font_size_(-1) {
85 fonts_.push_back(font);
88 FontListImpl* FontListImpl::Derive(int size_delta, int font_style) const {
89 // If there is a font vector, derive from that.
90 if (!fonts_.empty()) {
91 std::vector<Font> fonts = fonts_;
92 for (size_t i = 0; i < fonts.size(); ++i)
93 fonts[i] = fonts[i].Derive(size_delta, font_style);
94 return new FontListImpl(fonts);
97 // Otherwise, parse the font description string to derive from it.
98 std::vector<std::string> font_names;
99 int old_size;
100 int old_style;
101 CHECK(FontList::ParseDescription(font_description_string_, &font_names,
102 &old_style, &old_size));
103 const int size = std::max(1, old_size + size_delta);
104 return new FontListImpl(font_names, font_style, size);
107 int FontListImpl::GetHeight() const {
108 if (common_height_ == -1)
109 CacheCommonFontHeightAndBaseline();
110 return common_height_;
113 int FontListImpl::GetBaseline() const {
114 if (common_baseline_ == -1)
115 CacheCommonFontHeightAndBaseline();
116 return common_baseline_;
119 int FontListImpl::GetCapHeight() const {
120 // Assume the primary font is used to render Latin characters.
121 return GetPrimaryFont().GetCapHeight();
124 int FontListImpl::GetExpectedTextWidth(int length) const {
125 // Rely on the primary font metrics for the time being.
126 return GetPrimaryFont().GetExpectedTextWidth(length);
129 int FontListImpl::GetFontStyle() const {
130 if (font_style_ == -1)
131 CacheFontStyleAndSize();
132 return font_style_;
135 int FontListImpl::GetFontSize() const {
136 if (font_size_ == -1)
137 CacheFontStyleAndSize();
138 return font_size_;
141 const std::vector<Font>& FontListImpl::GetFonts() const {
142 if (fonts_.empty()) {
143 DCHECK(!font_description_string_.empty());
145 std::vector<std::string> font_names;
146 // It's possible that gfx::Font::UNDERLINE is specified and it's already
147 // stored in |font_style_| but |font_description_string_| doesn't have the
148 // underline info. So we should respect |font_style_| as long as it's
149 // valid.
150 int style = 0;
151 CHECK(FontList::ParseDescription(font_description_string_, &font_names,
152 &style, &font_size_));
153 if (font_style_ == -1)
154 font_style_ = style;
155 for (size_t i = 0; i < font_names.size(); ++i) {
156 DCHECK(!font_names[i].empty());
158 Font font(font_names[i], font_size_);
159 if (font_style_ == Font::NORMAL)
160 fonts_.push_back(font);
161 else
162 fonts_.push_back(font.Derive(0, font_style_));
165 return fonts_;
168 const Font& FontListImpl::GetPrimaryFont() const {
169 return GetFonts()[0];
172 FontListImpl::~FontListImpl() {}
174 void FontListImpl::CacheCommonFontHeightAndBaseline() const {
175 int ascent = 0;
176 int descent = 0;
177 const std::vector<Font>& fonts = GetFonts();
178 for (std::vector<Font>::const_iterator i = fonts.begin();
179 i != fonts.end(); ++i) {
180 ascent = std::max(ascent, i->GetBaseline());
181 descent = std::max(descent, i->GetHeight() - i->GetBaseline());
183 common_height_ = ascent + descent;
184 common_baseline_ = ascent;
187 void FontListImpl::CacheFontStyleAndSize() const {
188 if (!fonts_.empty()) {
189 font_style_ = fonts_[0].GetStyle();
190 font_size_ = fonts_[0].GetFontSize();
191 } else {
192 std::vector<std::string> font_names;
193 CHECK(FontList::ParseDescription(font_description_string_, &font_names,
194 &font_style_, &font_size_));
198 } // namespace gfx