Index: chrome/common/font_loader_mac.mm |
diff --git a/chrome/common/font_loader_mac.mm b/chrome/common/font_loader_mac.mm |
new file mode 100644 |
index 0000000000000000000000000000000000000000..ef9b96a0b1eefa0243821580296cca5241462eff |
--- /dev/null |
+++ b/chrome/common/font_loader_mac.mm |
@@ -0,0 +1,134 @@ |
+// Copyright (c) 2010 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "chrome/common/font_loader_mac.h" |
+ |
+#import <Cocoa/Cocoa.h> |
+ |
+#include "base/basictypes.h" |
+#include "base/file_path.h" |
+#include "base/file_util.h" |
+#include "base/logging.h" |
+#include "base/mac_util.h" |
+#include "base/scoped_cftyperef.h" |
+#include "base/sys_string_conversions.h" |
+ |
+// static |
+bool FontLoader::LoadFontIntoBuffer(const string16& font_name, |
+ float font_point_size, |
+ base::SharedMemory* font_data, |
+ uint32* font_data_size) { |
+ CHECK(font_data && font_data_size); |
+ *font_data_size = 0; |
+ |
+ // Load appropriate NSFont. |
+ NSString* font_name_ns = base::SysUTF16ToNSString(font_name); |
+ NSFont* font_to_encode = |
+ [NSFont fontWithName:font_name_ns size:font_point_size]; |
+ if (!font_to_encode) { |
+ LOG(ERROR) << "Failed to load font " << font_name; |
+ return false; |
+ } |
+ |
+ // NSFont -> ATSFontRef. |
+ ATSFontRef ats_font = |
+ CTFontGetPlatformFont(reinterpret_cast<CTFontRef>(font_to_encode), NULL); |
+ if (!ats_font) { |
+ LOG(ERROR) << "Conversion to ATSFontRef failed for " << font_name; |
+ return false; |
+ } |
+ |
+ // ATSFontRef -> File path. |
+ FSRef font_fsref; |
+ if (ATSFontGetFileReference(ats_font, &font_fsref) != noErr) { |
+ LOG(ERROR) << "Failed to find font file for " << font_name; |
+ return false; |
+ } |
+ FilePath font_path = FilePath(mac_util::PathFromFSRef(font_fsref)); |
+ |
+ // Load file into shared memory buffer. |
+ int64 font_file_size_64 = -1; |
+ if (!file_util::GetFileSize(font_path, &font_file_size_64)) { |
+ LOG(ERROR) << "Couldn't get font file size for " << font_path.value(); |
+ return false; |
+ } |
+ |
+ if (font_file_size_64 <= 0 || font_file_size_64 >= kint32max) { |
+ LOG(ERROR) << "Bad size for font file " << font_path.value(); |
+ return false; |
+ } |
+ |
+ int32 font_file_size_32 = static_cast<int32>(font_file_size_64); |
+ if (!font_data->Create(L"", false, false, font_file_size_32)) { |
+ LOG(ERROR) << "Failed to create shmem area for " << font_name; |
+ return false; |
+ } |
+ |
+ if (!font_data->Map(font_file_size_32)) { |
+ LOG(ERROR) << "Failed to map shmem area for " << font_name; |
+ return false; |
+ } |
+ |
+ int32 amt_read = file_util::ReadFile(font_path, |
+ reinterpret_cast<char*>(font_data->memory()), |
+ font_file_size_32); |
+ if (amt_read != font_file_size_32) { |
+ LOG(ERROR) << "Failed to read font data for " << font_path.value(); |
+ return false; |
+ } |
+ |
+ *font_data_size = font_file_size_32; |
+ return true; |
+} |
+ |
+// static |
+bool FontLoader::CreateCGFontFromBuffer(base::SharedMemoryHandle font_data, |
+ uint32 font_data_size, |
+ CGFontRef *font) { |
+ using base::SharedMemory; |
+ DCHECK(SharedMemory::IsHandleValid(font_data)); |
+ DCHECK_GT(font_data_size, 0U); |
+ |
+ SharedMemory shm(font_data, true); |
+ if (!shm.Map(font_data_size)) |
+ return false; |
+ |
+ ATSFontContainerRef font_container = 0; |
+ OSStatus err = ATSFontActivateFromMemory(shm.memory(), font_data_size, |
+ kATSFontContextLocal, kATSFontFormatUnspecified, |
+ NULL, kATSOptionFlagsDefault, &font_container ); |
+ if (err != noErr || !font_container) |
+ return false; |
+ |
+ // Count the number of fonts that were loaded. |
+ ItemCount fontCount = 0; |
+ ATSFontFindFromContainer(font_container, kATSOptionFlagsDefault, 0, NULL, |
+ &fontCount); |
+ |
+ if (fontCount < 1) { |
+ ATSFontDeactivate(font_container, NULL, kATSOptionFlagsDefault); |
+ return false; |
+ } |
+ |
+ // Load font from container. |
+ ATSFontRef font_ref_ats = 0; |
+ ATSFontFindFromContainer(font_container, kATSOptionFlagsDefault, 1, |
+ &font_ref_ats, NULL); |
+ |
+ if (!font_ref_ats) { |
+ ATSFontDeactivate(font_container, NULL, kATSOptionFlagsDefault); |
+ return false; |
+ } |
+ |
+ // Convert to cgFont. |
+ CGFontRef font_ref_cg = CGFontCreateWithPlatformFont(&font_ref_ats); |
+ |
+ if (!font_ref_cg) { |
+ ATSFontDeactivate(font_container, NULL, kATSOptionFlagsDefault); |
+ return false; |
+ } |
+ |
+ *font = font_ref_cg; |
+ return true; |
+} |