OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2010 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 #include "chrome/common/font_loader_mac.h" |
| 6 |
| 7 #import <Cocoa/Cocoa.h> |
| 8 |
| 9 #include "base/basictypes.h" |
| 10 #include "base/file_path.h" |
| 11 #include "base/file_util.h" |
| 12 #include "base/logging.h" |
| 13 #include "base/mac_util.h" |
| 14 #include "base/scoped_cftyperef.h" |
| 15 #include "base/sys_string_conversions.h" |
| 16 |
| 17 // static |
| 18 bool FontLoader::LoadFontIntoBuffer(const string16& font_name, |
| 19 float font_point_size, |
| 20 base::SharedMemory* font_data, |
| 21 uint32* font_data_size) { |
| 22 CHECK(font_data && font_data_size); |
| 23 *font_data_size = 0; |
| 24 |
| 25 // Load appropriate NSFont. |
| 26 NSString* font_name_ns = base::SysUTF16ToNSString(font_name); |
| 27 NSFont* font_to_encode = |
| 28 [NSFont fontWithName:font_name_ns size:font_point_size]; |
| 29 if (!font_to_encode) { |
| 30 LOG(ERROR) << "Failed to load font " << font_name; |
| 31 return false; |
| 32 } |
| 33 |
| 34 // NSFont -> ATSFontRef. |
| 35 ATSFontRef ats_font = |
| 36 CTFontGetPlatformFont(reinterpret_cast<CTFontRef>(font_to_encode), NULL); |
| 37 if (!ats_font) { |
| 38 LOG(ERROR) << "Conversion to ATSFontRef failed for " << font_name; |
| 39 return false; |
| 40 } |
| 41 |
| 42 // ATSFontRef -> File path. |
| 43 FSRef font_fsref; |
| 44 if (ATSFontGetFileReference(ats_font, &font_fsref) != noErr) { |
| 45 LOG(ERROR) << "Failed to find font file for " << font_name; |
| 46 return false; |
| 47 } |
| 48 FilePath font_path = FilePath(mac_util::PathFromFSRef(font_fsref)); |
| 49 |
| 50 // Load file into shared memory buffer. |
| 51 int64 font_file_size_64 = -1; |
| 52 if (!file_util::GetFileSize(font_path, &font_file_size_64)) { |
| 53 LOG(ERROR) << "Couldn't get font file size for " << font_path.value(); |
| 54 return false; |
| 55 } |
| 56 |
| 57 if (font_file_size_64 <= 0 || font_file_size_64 >= kint32max) { |
| 58 LOG(ERROR) << "Bad size for font file " << font_path.value(); |
| 59 return false; |
| 60 } |
| 61 |
| 62 int32 font_file_size_32 = static_cast<int32>(font_file_size_64); |
| 63 if (!font_data->Create(L"", false, false, font_file_size_32)) { |
| 64 LOG(ERROR) << "Failed to create shmem area for " << font_name; |
| 65 return false; |
| 66 } |
| 67 |
| 68 if (!font_data->Map(font_file_size_32)) { |
| 69 LOG(ERROR) << "Failed to map shmem area for " << font_name; |
| 70 return false; |
| 71 } |
| 72 |
| 73 int32 amt_read = file_util::ReadFile(font_path, |
| 74 reinterpret_cast<char*>(font_data->memory()), |
| 75 font_file_size_32); |
| 76 if (amt_read != font_file_size_32) { |
| 77 LOG(ERROR) << "Failed to read font data for " << font_path.value(); |
| 78 return false; |
| 79 } |
| 80 |
| 81 *font_data_size = font_file_size_32; |
| 82 return true; |
| 83 } |
| 84 |
| 85 // static |
| 86 bool FontLoader::CreateCGFontFromBuffer(base::SharedMemoryHandle font_data, |
| 87 uint32 font_data_size, |
| 88 CGFontRef *font) { |
| 89 using base::SharedMemory; |
| 90 DCHECK(SharedMemory::IsHandleValid(font_data)); |
| 91 DCHECK_GT(font_data_size, 0U); |
| 92 |
| 93 SharedMemory shm(font_data, true); |
| 94 if (!shm.Map(font_data_size)) |
| 95 return false; |
| 96 |
| 97 ATSFontContainerRef font_container = 0; |
| 98 OSStatus err = ATSFontActivateFromMemory(shm.memory(), font_data_size, |
| 99 kATSFontContextLocal, kATSFontFormatUnspecified, |
| 100 NULL, kATSOptionFlagsDefault, &font_container ); |
| 101 if (err != noErr || !font_container) |
| 102 return false; |
| 103 |
| 104 // Count the number of fonts that were loaded. |
| 105 ItemCount fontCount = 0; |
| 106 ATSFontFindFromContainer(font_container, kATSOptionFlagsDefault, 0, NULL, |
| 107 &fontCount); |
| 108 |
| 109 if (fontCount < 1) { |
| 110 ATSFontDeactivate(font_container, NULL, kATSOptionFlagsDefault); |
| 111 return false; |
| 112 } |
| 113 |
| 114 // Load font from container. |
| 115 ATSFontRef font_ref_ats = 0; |
| 116 ATSFontFindFromContainer(font_container, kATSOptionFlagsDefault, 1, |
| 117 &font_ref_ats, NULL); |
| 118 |
| 119 if (!font_ref_ats) { |
| 120 ATSFontDeactivate(font_container, NULL, kATSOptionFlagsDefault); |
| 121 return false; |
| 122 } |
| 123 |
| 124 // Convert to cgFont. |
| 125 CGFontRef font_ref_cg = CGFontCreateWithPlatformFont(&font_ref_ats); |
| 126 |
| 127 if (!font_ref_cg) { |
| 128 ATSFontDeactivate(font_container, NULL, kATSOptionFlagsDefault); |
| 129 return false; |
| 130 } |
| 131 |
| 132 *font = font_ref_cg; |
| 133 return true; |
| 134 } |
OLD | NEW |