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
3 // found in the LICENSE file.
5 #import <Cocoa/Cocoa.h>
7 #include "base/files/file_util.h"
8 #include "base/files/scoped_file.h"
9 #include "base/logging.h"
10 #include "base/mac/scoped_cftyperef.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/memory/shared_memory.h"
13 #include "content/common/mac/font_descriptor.h"
14 #include "content/common/mac/font_loader.h"
15 #include "content/common/sandbox_mac_unittest_helper.h"
16 #include "testing/gtest/include/gtest/gtest.h"
20 class FontLoadingTestCase : public MacSandboxTestCase {
22 FontLoadingTestCase() : font_data_length_(-1) {}
23 virtual bool BeforeSandboxInit() OVERRIDE;
24 virtual bool SandboxedTest() OVERRIDE;
26 scoped_ptr<base::SharedMemory> font_shmem_;
27 size_t font_data_length_;
29 REGISTER_SANDBOX_TEST_CASE(FontLoadingTestCase);
32 // Load raw font data into shared memory object.
33 bool FontLoadingTestCase::BeforeSandboxInit() {
34 std::string font_data;
35 if (!base::ReadFileToString(base::FilePath(test_data_.c_str()), &font_data)) {
36 LOG(ERROR) << "Failed to read font data from file (" << test_data_ << ")";
40 font_data_length_ = font_data.length();
41 if (font_data_length_ <= 0) {
42 LOG(ERROR) << "No font data: " << font_data_length_;
46 font_shmem_.reset(new base::SharedMemory);
48 LOG(ERROR) << "Failed to create shared memory object.";
52 if (!font_shmem_->CreateAndMapAnonymous(font_data_length_)) {
53 LOG(ERROR) << "SharedMemory::Create failed";
57 memcpy(font_shmem_->memory(), font_data.c_str(), font_data_length_);
58 if (!font_shmem_->Unmap()) {
59 LOG(ERROR) << "SharedMemory::Unmap failed";
65 bool FontLoadingTestCase::SandboxedTest() {
66 base::SharedMemoryHandle shmem_handle;
67 if (!font_shmem_->ShareToProcess(base::kNullProcessHandle, &shmem_handle)) {
68 LOG(ERROR) << "SharedMemory::ShareToProcess failed";
72 CGFontRef cg_font_ref;
73 if (!FontLoader::CGFontRefFromBuffer(shmem_handle, font_data_length_,
75 LOG(ERROR) << "Call to CreateCGFontFromBuffer() failed";
80 LOG(ERROR) << "Got NULL CGFontRef";
83 base::ScopedCFTypeRef<CGFontRef> cgfont(cg_font_ref);
85 CTFontRef ct_font_ref =
86 CTFontCreateWithGraphicsFont(cgfont.get(), 16.0, NULL, NULL);
87 base::ScopedCFTypeRef<CTFontRef> ctfont(ct_font_ref);
90 LOG(ERROR) << "CTFontCreateWithGraphicsFont() failed";
94 // Do something with the font to make sure it's loaded.
95 CGFloat cap_height = CTFontGetCapHeight(ct_font_ref);
97 if (cap_height <= 0.0) {
98 LOG(ERROR) << "Got bad value for CTFontGetCapHeight " << cap_height;
105 TEST_F(MacSandboxTest, FontLoadingTest) {
106 base::FilePath temp_file_path;
107 FILE* temp_file = base::CreateAndOpenTemporaryFile(&temp_file_path);
108 ASSERT_TRUE(temp_file);
109 base::ScopedFILE temp_file_closer(temp_file);
111 NSFont* srcFont = [NSFont fontWithName:@"Geeza Pro" size:16.0];
112 FontDescriptor descriptor(srcFont);
113 FontLoader::Result result;
114 FontLoader::LoadFont(descriptor, &result);
115 EXPECT_GT(result.font_data_size, 0U);
116 EXPECT_GT(result.font_id, 0U);
118 base::WriteFileDescriptor(fileno(temp_file),
119 static_cast<const char *>(result.font_data.memory()),
120 result.font_data_size);
122 ASSERT_TRUE(RunTestInSandbox(SANDBOX_TYPE_RENDERER,
123 "FontLoadingTestCase", temp_file_path.value().c_str()));
124 temp_file_closer.reset();
125 ASSERT_TRUE(base::DeleteFile(temp_file_path, false));
128 } // namespace content