15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file.
45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/gfx/font_list_impl.h"
65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <algorithm>
85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/logging.h"
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/strings/string_number_conversions.h"
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/strings/string_split.h"
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/strings/string_util.h"
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/gfx/font.h"
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace {
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Parses font description into |font_names|, |font_style| and |font_size|.
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ParseFontDescriptionString(const std::string& font_description_string,
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                std::vector<std::string>* font_names,
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                int* font_style,
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                int* font_size) {
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::SplitString(font_description_string, ',', font_names);
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK_GT(font_names->size(), 1U);
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The last item is [STYLE_OPTIONS] SIZE.
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::vector<std::string> styles_size;
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::SplitString(font_names->back(), ' ', &styles_size);
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(!styles_size.empty());
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::StringToInt(styles_size.back(), font_size);
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK_GT(*font_size, 0);
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  font_names->pop_back();
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Font supports BOLD and ITALIC; underline is supported via RenderText.
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  *font_style = 0;
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (size_t i = 0; i < styles_size.size() - 1; ++i) {
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Styles are separated by white spaces. base::SplitString splits styles
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // by space, and it inserts empty string for continuous spaces.
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (styles_size[i].empty())
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      continue;
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (!styles_size[i].compare("Bold"))
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      *font_style |= gfx::Font::BOLD;
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    else if (!styles_size[i].compare("Italic"))
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      *font_style |= gfx::Font::ITALIC;
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    else
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      NOTREACHED();
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Returns the font style and size as a string.
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)std::string FontStyleAndSizeToString(int font_style, int font_size) {
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string result;
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (font_style & gfx::Font::BOLD)
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    result += "Bold ";
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (font_style & gfx::Font::ITALIC)
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    result += "Italic ";
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  result += base::IntToString(font_size);
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  result += "px";
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return result;
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Returns font description from |font_names|, |font_style|, and |font_size|.
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)std::string BuildFontDescription(const std::vector<std::string>& font_names,
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                 int font_style,
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                 int font_size) {
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string description = JoinString(font_names, ',');
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  description += "," + FontStyleAndSizeToString(font_style, font_size);
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return description;
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace gfx {
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)FontListImpl::FontListImpl(const std::string& font_description_string)
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : font_description_string_(font_description_string),
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      common_height_(-1),
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      common_baseline_(-1),
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      font_style_(-1),
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      font_size_(-1) {
805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(!font_description_string.empty());
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // DCHECK description string ends with "px" for size in pixel.
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(EndsWith(font_description_string, "px", true));
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)FontListImpl::FontListImpl(const std::vector<std::string>& font_names,
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                           int font_style,
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                           int font_size)
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : font_description_string_(BuildFontDescription(font_names, font_style,
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                    font_size)),
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      common_height_(-1),
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      common_baseline_(-1),
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      font_style_(font_style),
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      font_size_(font_size) {
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(!font_names.empty());
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(!font_names[0].empty());
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)FontListImpl::FontListImpl(const std::vector<Font>& fonts)
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : fonts_(fonts),
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      common_height_(-1),
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      common_baseline_(-1),
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      font_style_(-1),
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      font_size_(-1) {
1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(!fonts.empty());
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  font_style_ = fonts[0].GetStyle();
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  font_size_ = fonts[0].GetFontSize();
107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if DCHECK_IS_ON
108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (size_t i = 1; i < fonts.size(); ++i) {
109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DCHECK_EQ(fonts[i].GetStyle(), font_style_);
110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DCHECK_EQ(fonts[i].GetFontSize(), font_size_);
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif
1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)FontListImpl::FontListImpl(const Font& font)
1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : common_height_(-1),
1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      common_baseline_(-1),
1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      font_style_(-1),
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      font_size_(-1) {
1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  fonts_.push_back(font);
1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)FontListImpl* FontListImpl::Derive(int size_delta, int font_style) const {
1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // If there is a font vector, derive from that.
1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!fonts_.empty()) {
1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    std::vector<Font> fonts = fonts_;
1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    for (size_t i = 0; i < fonts.size(); ++i)
1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      fonts[i] = fonts[i].Derive(size_delta, font_style);
1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return new FontListImpl(fonts);
1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Otherwise, parse the font description string to derive from it.
1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::vector<std::string> font_names;
1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int old_size;
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int old_style;
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ParseFontDescriptionString(font_description_string_, &font_names,
1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                             &old_style, &old_size);
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const int size = std::max(1, old_size + size_delta);
1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return new FontListImpl(font_names, font_style, size);
1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int FontListImpl::GetHeight() const {
1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (common_height_ == -1)
1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    CacheCommonFontHeightAndBaseline();
1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return common_height_;
1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int FontListImpl::GetBaseline() const {
1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (common_baseline_ == -1)
1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    CacheCommonFontHeightAndBaseline();
1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return common_baseline_;
1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int FontListImpl::GetCapHeight() const {
1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Assume the primary font is used to render Latin characters.
1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return GetPrimaryFont().GetCapHeight();
1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int FontListImpl::GetExpectedTextWidth(int length) const {
1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Rely on the primary font metrics for the time being.
1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return GetPrimaryFont().GetExpectedTextWidth(length);
1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int FontListImpl::GetFontStyle() const {
1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (font_style_ == -1)
1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    CacheFontStyleAndSize();
1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return font_style_;
1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const std::string& FontListImpl::GetFontDescriptionString() const {
1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (font_description_string_.empty()) {
1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DCHECK(!fonts_.empty());
1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    for (size_t i = 0; i < fonts_.size(); ++i) {
1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      std::string name = fonts_[i].GetFontName();
1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      font_description_string_ += name;
1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      font_description_string_ += ',';
1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // All fonts have the same style and size.
1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    font_description_string_ +=
1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        FontStyleAndSizeToString(fonts_[0].GetStyle(), fonts_[0].GetFontSize());
1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return font_description_string_;
1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int FontListImpl::GetFontSize() const {
1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (font_size_ == -1)
1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    CacheFontStyleAndSize();
1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return font_size_;
1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const std::vector<Font>& FontListImpl::GetFonts() const {
1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (fonts_.empty()) {
1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DCHECK(!font_description_string_.empty());
1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    std::vector<std::string> font_names;
1965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // It's possible that gfx::Font::UNDERLINE is specified and it's already
1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // stored in |font_style_| but |font_description_string_| doesn't have the
1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // underline info.  So we should respect |font_style_| as long as it's
1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // valid.
2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int style = 0;
2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ParseFontDescriptionString(font_description_string_, &font_names,
2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                               &style, &font_size_);
2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (font_style_ == -1)
2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      font_style_ = style;
2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    for (size_t i = 0; i < font_names.size(); ++i) {
2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      DCHECK(!font_names[i].empty());
2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      Font font(font_names[i], font_size_);
2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if (font_style_ == Font::NORMAL)
2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        fonts_.push_back(font);
2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      else
2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        fonts_.push_back(font.Derive(0, font_style_));
2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return fonts_;
2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const Font& FontListImpl::GetPrimaryFont() const {
2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return GetFonts()[0];
2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)FontListImpl::~FontListImpl() {}
2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void FontListImpl::CacheCommonFontHeightAndBaseline() const {
2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int ascent = 0;
2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int descent = 0;
2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const std::vector<Font>& fonts = GetFonts();
2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (std::vector<Font>::const_iterator i = fonts.begin();
2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       i != fonts.end(); ++i) {
2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ascent = std::max(ascent, i->GetBaseline());
2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    descent = std::max(descent, i->GetHeight() - i->GetBaseline());
2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  common_height_ = ascent + descent;
2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  common_baseline_ = ascent;
2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void FontListImpl::CacheFontStyleAndSize() const {
2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!fonts_.empty()) {
2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    font_style_ = fonts_[0].GetStyle();
2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    font_size_ = fonts_[0].GetFontSize();
2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else {
2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    std::vector<std::string> font_names;
2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ParseFontDescriptionString(font_description_string_, &font_names,
2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                               &font_style_, &font_size_);
2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace gfx
249