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");
676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ("arial",
686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            base::StringToLowerASCII(cf.GetActualFontNameForTesting()));
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FreeIfNecessary(native);
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FontTest, LoadArialBold) {
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Font cf("Arial", 16);
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Font bold(cf.Derive(0, Font::BOLD));
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NativeFont native = bold.GetNativeFont();
764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(native);
774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(bold.GetStyle(), Font::BOLD);
786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ("arial",
796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            base::StringToLowerASCII(cf.GetActualFontNameForTesting()));
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FreeIfNecessary(native);
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FontTest, Ascent) {
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Font cf("Arial", 16);
854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_GT(cf.GetBaseline(), 2);
864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_LE(cf.GetBaseline(), 22);
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FontTest, Height) {
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Font cf("Arial", 16);
914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_GE(cf.GetHeight(), 16);
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(akalin): Figure out why height is so large on Linux.
934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_LE(cf.GetHeight(), 26);
944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(FontTest, CapHeight) {
974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  Font cf("Arial", 16);
984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_GT(cf.GetCapHeight(), 0);
994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_GT(cf.GetCapHeight(), cf.GetHeight() / 2);
1000f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_LT(cf.GetCapHeight(), cf.GetBaseline());
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FontTest, AvgWidths) {
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Font cf("Arial", 16);
1054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(cf.GetExpectedTextWidth(0), 0);
1064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_GT(cf.GetExpectedTextWidth(1), cf.GetExpectedTextWidth(0));
1074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_GT(cf.GetExpectedTextWidth(2), cf.GetExpectedTextWidth(1));
1084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_GT(cf.GetExpectedTextWidth(3), cf.GetExpectedTextWidth(2));
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#if !defined(OS_WIN)
112a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// On Windows, Font::GetActualFontNameForTesting() doesn't work well for now.
113a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// http://crbug.com/327287
114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)//
115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Check that fonts used for testing are installed and enabled. On Mac
116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// fonts may be installed but still need enabling in Font Book.app.
117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// http://crbug.com/347429
118a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(FontTest, GetActualFontNameForTesting) {
119a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  Font arial("Arial", 16);
1206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ("arial",
1216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            base::StringToLowerASCII(arial.GetActualFontNameForTesting()))
122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      << "********\n"
123a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      << "Your test environment seems to be missing Arial font, which is "
124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      << "needed for unittests.  Check if Arial font is installed.\n"
125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      << "********";
126a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  Font symbol("Symbol", 16);
1276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ("symbol",
1286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            base::StringToLowerASCII(symbol.GetActualFontNameForTesting()))
129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      << "********\n"
130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      << "Your test environment seems to be missing Symbol font, which is "
131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      << "needed for unittests.  Check if Symbol font is installed.\n"
132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      << "********";
133a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
134a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const char* const invalid_font_name = "no_such_font_name";
135a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  Font fallback_font(invalid_font_name, 16);
136a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_NE(invalid_font_name,
1376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            base::StringToLowerASCII(
1386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                fallback_font.GetActualFontNameForTesting()));
139a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
140a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#endif
141a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(FontTest, DeriveResizesIfSizeTooSmall) {
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Font cf("Arial", 8);
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The minimum font size is set to 5 in browser_main.cc.
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScopedMinimumFontSizeCallback minimum_size(5);
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Font derived_font = cf.Derive(-4, cf.GetStyle());
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(5, derived_font.GetFontSize());
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(FontTest, DeriveKeepsOriginalSizeIfHeightOk) {
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Font cf("Arial", 8);
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The minimum font size is set to 5 in browser_main.cc.
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScopedMinimumFontSizeCallback minimum_size(5);
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Font derived_font = cf.Derive(-2, cf.GetStyle());
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(6, derived_font.GetFontSize());
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // defined(OS_WIN)
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace gfx
164