Home | History | Annotate | Download | only in common
      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.
      4 
      5 #import <Cocoa/Cocoa.h>
      6 
      7 #include "base/file_util.h"
      8 #include "base/logging.h"
      9 #include "base/mac/scoped_cftyperef.h"
     10 #include "base/memory/scoped_ptr.h"
     11 #include "base/memory/shared_memory.h"
     12 #include "content/common/mac/font_descriptor.h"
     13 #include "content/common/mac/font_loader.h"
     14 #include "content/common/sandbox_mac_unittest_helper.h"
     15 #include "testing/gtest/include/gtest/gtest.h"
     16 
     17 namespace content {
     18 
     19 class FontLoadingTestCase : public MacSandboxTestCase {
     20  public:
     21   FontLoadingTestCase() : font_data_length_(-1) {}
     22   virtual bool BeforeSandboxInit() OVERRIDE;
     23   virtual bool SandboxedTest() OVERRIDE;
     24  private:
     25   scoped_ptr<base::SharedMemory> font_shmem_;
     26   size_t font_data_length_;
     27 };
     28 REGISTER_SANDBOX_TEST_CASE(FontLoadingTestCase);
     29 
     30 
     31 // Load raw font data into shared memory object.
     32 bool FontLoadingTestCase::BeforeSandboxInit() {
     33   std::string font_data;
     34   if (!base::ReadFileToString(base::FilePath(test_data_.c_str()), &font_data)) {
     35     LOG(ERROR) << "Failed to read font data from file (" << test_data_ << ")";
     36     return false;
     37   }
     38 
     39   font_data_length_ = font_data.length();
     40   if (font_data_length_ <= 0) {
     41     LOG(ERROR) << "No font data: " << font_data_length_;
     42     return false;
     43   }
     44 
     45   font_shmem_.reset(new base::SharedMemory);
     46   if (!font_shmem_) {
     47     LOG(ERROR) << "Failed to create shared memory object.";
     48     return false;
     49   }
     50 
     51   if (!font_shmem_->CreateAndMapAnonymous(font_data_length_)) {
     52     LOG(ERROR) << "SharedMemory::Create failed";
     53     return false;
     54   }
     55 
     56   memcpy(font_shmem_->memory(), font_data.c_str(), font_data_length_);
     57   if (!font_shmem_->Unmap())  {
     58     LOG(ERROR) << "SharedMemory::Unmap failed";
     59     return false;
     60   }
     61   return true;
     62 }
     63 
     64 bool FontLoadingTestCase::SandboxedTest() {
     65   base::SharedMemoryHandle shmem_handle;
     66   if (!font_shmem_->ShareToProcess(base::kNullProcessHandle, &shmem_handle)) {
     67     LOG(ERROR) << "SharedMemory::ShareToProcess failed";
     68     return false;
     69   }
     70 
     71   CGFontRef cg_font_ref;
     72   if (!FontLoader::CGFontRefFromBuffer(shmem_handle, font_data_length_,
     73                                        &cg_font_ref)) {
     74     LOG(ERROR) << "Call to CreateCGFontFromBuffer() failed";
     75     return false;
     76   }
     77 
     78   if (!cg_font_ref) {
     79     LOG(ERROR) << "Got NULL CGFontRef";
     80     return false;
     81   }
     82   base::ScopedCFTypeRef<CGFontRef> cgfont(cg_font_ref);
     83 
     84   CTFontRef ct_font_ref =
     85       CTFontCreateWithGraphicsFont(cgfont.get(), 16.0, NULL, NULL);
     86   base::ScopedCFTypeRef<CTFontRef> ctfont(ct_font_ref);
     87 
     88   if (!ct_font_ref) {
     89     LOG(ERROR) << "CTFontCreateWithGraphicsFont() failed";
     90     return false;
     91   }
     92 
     93   // Do something with the font to make sure it's loaded.
     94   CGFloat cap_height = CTFontGetCapHeight(ct_font_ref);
     95 
     96   if (cap_height <= 0.0) {
     97     LOG(ERROR) << "Got bad value for CTFontGetCapHeight " << cap_height;
     98     return false;
     99   }
    100 
    101   return true;
    102 }
    103 
    104 TEST_F(MacSandboxTest, FontLoadingTest) {
    105   base::FilePath temp_file_path;
    106   FILE* temp_file = base::CreateAndOpenTemporaryFile(&temp_file_path);
    107   ASSERT_TRUE(temp_file);
    108   file_util::ScopedFILE temp_file_closer(temp_file);
    109 
    110   NSFont* srcFont = [NSFont fontWithName:@"Geeza Pro" size:16.0];
    111   FontDescriptor descriptor(srcFont);
    112   FontLoader::Result result;
    113   FontLoader::LoadFont(descriptor, &result);
    114   EXPECT_GT(result.font_data_size, 0U);
    115   EXPECT_GT(result.font_id, 0U);
    116 
    117   file_util::WriteFileDescriptor(fileno(temp_file),
    118       static_cast<const char *>(result.font_data.memory()),
    119       result.font_data_size);
    120 
    121   ASSERT_TRUE(RunTestInSandbox(SANDBOX_TYPE_RENDERER,
    122                   "FontLoadingTestCase", temp_file_path.value().c_str()));
    123   temp_file_closer.reset();
    124   ASSERT_TRUE(base::DeleteFile(temp_file_path, false));
    125 }
    126 
    127 }  // namespace content
    128