15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/font.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string16.h"
8a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/strings/string_util.h"
9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if defined(OS_LINUX) && !defined(USE_OZONE)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <pango/pango.h>
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_WIN)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/platform_font_win.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gfx {
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class FontTest : public testing::Test {
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fulfills the memory management contract as outlined by the comment at
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // gfx::Font::GetNativeFont().
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void FreeIfNecessary(NativeFont font) {
26f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if defined(OS_LINUX) && !defined(USE_OZONE)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pango_font_description_free(font);
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ScopedMinimumFontSizeCallback {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit ScopedMinimumFontSizeCallback(int minimum_size) {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    minimum_size_ = minimum_size;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    old_callback_ = PlatformFontWin::get_minimum_font_size_callback;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PlatformFontWin::get_minimum_font_size_callback = &GetMinimumFontSize;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~ScopedMinimumFontSizeCallback() {
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PlatformFontWin::get_minimum_font_size_callback = old_callback_;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static int GetMinimumFontSize() {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return minimum_size_;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PlatformFontWin::GetMinimumFontSizeCallback old_callback_;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static int minimum_size_;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ScopedMinimumFontSizeCallback);
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ScopedMinimumFontSizeCallback::minimum_size_ = 0;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // defined(OS_WIN)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FontTest, LoadArial) {
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Font cf("Arial", 16);
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NativeFont native = cf.GetNativeFont();
634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(native);
644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(cf.GetStyle(), Font::NORMAL);
654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(cf.GetFontSize(), 16);
664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(cf.GetFontName(), "Arial");
67a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("arial", StringToLowerASCII(cf.GetActualFontNameForTesting()));
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FreeIfNecessary(native);
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FontTest, LoadArialBold) {
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Font cf("Arial", 16);
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Font bold(cf.DeriveFont(0, Font::BOLD));
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NativeFont native = bold.GetNativeFont();
754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(native);
764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(bold.GetStyle(), Font::BOLD);
77a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("arial", StringToLowerASCII(cf.GetActualFontNameForTesting()));
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FreeIfNecessary(native);
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FontTest, Ascent) {
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Font cf("Arial", 16);
834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_GT(cf.GetBaseline(), 2);
844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_LE(cf.GetBaseline(), 22);
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FontTest, Height) {
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Font cf("Arial", 16);
894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_GE(cf.GetHeight(), 16);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(akalin): Figure out why height is so large on Linux.
914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_LE(cf.GetHeight(), 26);
924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(FontTest, CapHeight) {
954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  Font cf("Arial", 16);
964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_GT(cf.GetCapHeight(), 0);
974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_GT(cf.GetCapHeight(), cf.GetHeight() / 2);
984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(OS_CHROMEOS) || defined(OS_LINUX)
990f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_EQ(cf.GetCapHeight(), cf.GetBaseline());
1004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#else
1010f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_LT(cf.GetCapHeight(), cf.GetBaseline());
1024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FontTest, AvgWidths) {
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Font cf("Arial", 16);
1074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(cf.GetExpectedTextWidth(0), 0);
1084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_GT(cf.GetExpectedTextWidth(1), cf.GetExpectedTextWidth(0));
1094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_GT(cf.GetExpectedTextWidth(2), cf.GetExpectedTextWidth(1));
1104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_GT(cf.GetExpectedTextWidth(3), cf.GetExpectedTextWidth(2));
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FontTest, AvgCharWidth) {
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Font cf("Arial", 16);
1154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_GT(cf.GetAverageCharacterWidth(), 0);
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FontTest, Widths) {
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Font cf("Arial", 16);
1204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(cf.GetStringWidth(base::string16()), 0);
1214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_GT(cf.GetStringWidth(ASCIIToUTF16("a")),
122868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            cf.GetStringWidth(base::string16()));
1234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_GT(cf.GetStringWidth(ASCIIToUTF16("ab")),
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            cf.GetStringWidth(ASCIIToUTF16("a")));
1254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_GT(cf.GetStringWidth(ASCIIToUTF16("abc")),
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            cf.GetStringWidth(ASCIIToUTF16("ab")));
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
129a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#if !defined(OS_WIN)
130a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// On Windows, Font::GetActualFontNameForTesting() doesn't work well for now.
131a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// http://crbug.com/327287
132a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(FontTest, GetActualFontNameForTesting) {
133a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  Font arial("Arial", 16);
134a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("arial", StringToLowerASCII(arial.GetActualFontNameForTesting()));
135a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  Font symbol("Symbol", 16);
136a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("symbol", StringToLowerASCII(symbol.GetActualFontNameForTesting()));
137a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
138a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const char* const invalid_font_name = "no_such_font_name";
139a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  Font fallback_font(invalid_font_name, 16);
140a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_NE(invalid_font_name,
141a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            StringToLowerASCII(fallback_font.GetActualFontNameForTesting()));
142a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
143a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#endif
144a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FontTest, DeriveFontResizesIfSizeTooSmall) {
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Font cf("Arial", 8);
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The minimum font size is set to 5 in browser_main.cc.
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScopedMinimumFontSizeCallback minimum_size(5);
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Font derived_font = cf.DeriveFont(-4);
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(5, derived_font.GetFontSize());
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FontTest, DeriveFontKeepsOriginalSizeIfHeightOk) {
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Font cf("Arial", 8);
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The minimum font size is set to 5 in browser_main.cc.
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScopedMinimumFontSizeCallback minimum_size(5);
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Font derived_font = cf.DeriveFont(-2);
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(6, derived_font.GetFontSize());
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // defined(OS_WIN)
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace gfx
167