Skip to content

Commit

Permalink
mac: Use CTFont instead of ATS in font_loader.mm.
Browse files Browse the repository at this point in the history
ATS is deprecated in the 10.8 sdk.

No intended functionality change.

BUG=139138
TEST=Remove renderer.sb line that allows reading of ~/Library/Fonts.
`cp /Library/Fonts/Arial.ttf ~/Library/Fonts`.
Add logging to the font loader that shows it's being called (see patch swt "with logging").
Create a jsfiddle with a CSS of `* { font-family: Arial; }`.
Verify that that shows up correctly on 10.6, 10.7, 10.8.
TBR=avi

Review URL: https://chromiumcodereview.appspot.com/17102004

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@207176 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
thakis@chromium.org committed Jun 19, 2013
1 parent 868c619 commit 0e4e07b
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 27 deletions.
66 changes: 41 additions & 25 deletions content/common/mac/font_loader.mm
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,13 @@
#include "base/mac/foundation_util.h"
#include "base/mac/mac_util.h"
#include "base/mac/scoped_cftyperef.h"
#include "base/memory/scoped_nsobject.h"
#include "base/strings/sys_string_conversions.h"
#include "base/threading/thread_restrictions.h"
#include "content/common/mac/font_descriptor.h"

#include <map>

extern "C" {

// Work around http://crbug.com/93191, a really nasty memory smasher bug.
Expand Down Expand Up @@ -53,10 +56,39 @@ void _CTFontManagerUnregisterFontForData(NSUInteger, int) {

} // extern "C"

namespace {

uint32 GetFontIDForFont(const base::FilePath& font_path) {
// content/common can't depend on content/browser, so this cannot call
// BrowserThread::CurrentlyOn(). Check this is always called on the same
// thread.
static pthread_t thread_id = pthread_self();
DCHECK_EQ(pthread_self(), thread_id);

// Font loading used to call ATSFontGetContainer()
// and used that as font id.
// ATS is deprecated and CTFont doesn't seem to have a obvious fixed id for a
// font. Since this function is only called from a single thread, use a static
// map to store ids.
typedef std::map<base::FilePath, uint32> FontIdMap;
CR_DEFINE_STATIC_LOCAL(FontIdMap, font_ids, ());

auto it = font_ids.find(font_path);
if (it != font_ids.end())
return it->second;

uint32 font_id = font_ids.size() + 1;
font_ids[font_path] = font_id;
return font_id;
}

} // namespace

// static
void FontLoader::LoadFont(const FontDescriptor& font,
FontLoader::Result* result) {
base::ThreadRestrictions::AssertIOAllowed();

DCHECK(result);
result->font_data_size = 0;
result->font_id = 0;
Expand All @@ -71,40 +103,24 @@ void _CTFontManagerUnregisterFontForData(NSUInteger, int) {
return;
}

// NSFont -> ATSFontRef.
ATSFontRef ats_font =
CTFontGetPlatformFont(reinterpret_cast<CTFontRef>(font_to_encode), NULL);
if (!ats_font) {
DLOG(ERROR) << "Conversion to ATSFontRef failed for " << font_name;
return;
}

// Retrieve the ATSFontContainerRef corresponding to the font file we want to
// load. This is a unique identifier that allows the caller determine if the
// font file in question is already loaded.
COMPILE_ASSERT(sizeof(ATSFontContainerRef) == sizeof(result->font_id),
uint32_cant_hold_fontcontainer_ref);
ATSFontContainerRef fontContainer = kATSFontContainerRefUnspecified;
if (ATSFontGetContainer(ats_font, 0, &fontContainer) != noErr) {
DLOG(ERROR) << "Failed to get font container ref for " << font_name;
return;
}

// ATSFontRef -> File path.
// NSFont -> File path.
// Warning: Calling this function on a font activated from memory will result
// in failure with a -50 - paramErr. This may occur if
// CreateCGFontFromBuffer() is called in the same process as this function
// e.g. when writing a unit test that exercises these two functions together.
// If said unit test were to load a system font and activate it from memory
// it becomes impossible for the system to the find the original file ref
// since the font now lives in memory as far as it's concerned.
FSRef font_fsref;
if (ATSFontGetFileReference(ats_font, &font_fsref) != noErr) {
CTFontRef ct_font_to_encode = (CTFontRef)font_to_encode;
scoped_nsobject<NSURL> font_url(
base::mac::CFToNSCast(base::mac::CFCastStrict<CFURLRef>(
CTFontCopyAttribute(ct_font_to_encode, kCTFontURLAttribute))));
if (![font_url isFileURL]) {
DLOG(ERROR) << "Failed to find font file for " << font_name;
return;
}
base::FilePath font_path =
base::FilePath(base::mac::PathFromFSRef(font_fsref));

base::FilePath font_path = base::mac::NSStringToFilePath([font_url path]);

// Load file into shared memory buffer.
int64 font_file_size_64 = -1;
Expand Down Expand Up @@ -133,7 +149,7 @@ void _CTFontManagerUnregisterFontForData(NSUInteger, int) {
}

result->font_data_size = font_file_size_32;
result->font_id = fontContainer;
result->font_id = GetFontIDForFont(font_path);
}

// static
Expand Down
3 changes: 1 addition & 2 deletions ui/shell_dialogs/select_file_dialog_mac.mm
Original file line number Diff line number Diff line change
Expand Up @@ -378,8 +378,7 @@ - (void)endedPanel:(NSSavePanel*)panel
if (!did_cancel) {
if (type == ui::SelectFileDialog::SELECT_SAVEAS_FILE) {
if ([[panel URL] isFileURL]) {
paths.push_back(base::FilePath(
base::SysNSStringToUTF8([[panel URL] path])));
paths.push_back(base::mac::NSStringToFilePath([[panel URL] path]));
}

NSView* accessoryView = [panel accessoryView];
Expand Down

0 comments on commit 0e4e07b

Please sign in to comment.