| OLD | NEW |
| (Empty) |
| 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 #include "ui/base/resource/resource_bundle.h" | |
| 6 | |
| 7 #import <AppKit/AppKit.h> | |
| 8 | |
| 9 #include "base/basictypes.h" | |
| 10 #include "base/files/file_path.h" | |
| 11 #include "base/files/file_util.h" | |
| 12 #include "base/mac/bundle_locations.h" | |
| 13 #include "base/mac/mac_util.h" | |
| 14 #include "base/mac/scoped_nsobject.h" | |
| 15 #include "base/memory/ref_counted_memory.h" | |
| 16 #include "base/strings/sys_string_conversions.h" | |
| 17 #include "base/synchronization/lock.h" | |
| 18 #include "ui/base/resource/resource_handle.h" | |
| 19 #include "ui/gfx/image/image.h" | |
| 20 | |
| 21 namespace ui { | |
| 22 | |
| 23 namespace { | |
| 24 | |
| 25 base::FilePath GetResourcesPakFilePath(NSString* name, NSString* mac_locale) { | |
| 26 NSString *resource_path; | |
| 27 // Some of the helper processes need to be able to fetch resources | |
| 28 // (chrome_main.cc: SubprocessNeedsResourceBundle()). Fetch the same locale | |
| 29 // as the already-running browser instead of using what NSBundle might pick | |
| 30 // based on values at helper launch time. | |
| 31 if ([mac_locale length]) { | |
| 32 resource_path = [base::mac::FrameworkBundle() pathForResource:name | |
| 33 ofType:@"pak" | |
| 34 inDirectory:@"" | |
| 35 forLocalization:mac_locale]; | |
| 36 } else { | |
| 37 resource_path = [base::mac::FrameworkBundle() pathForResource:name | |
| 38 ofType:@"pak"]; | |
| 39 } | |
| 40 | |
| 41 if (!resource_path) { | |
| 42 // Return just the name of the pack file. | |
| 43 return base::FilePath(base::SysNSStringToUTF8(name) + ".pak"); | |
| 44 } | |
| 45 | |
| 46 return base::FilePath([resource_path fileSystemRepresentation]); | |
| 47 } | |
| 48 | |
| 49 } // namespace | |
| 50 | |
| 51 void ResourceBundle::LoadCommonResources() { | |
| 52 AddDataPackFromPath(GetResourcesPakFilePath(@"chrome_100_percent", | |
| 53 nil), SCALE_FACTOR_100P); | |
| 54 | |
| 55 // On Mac we load 1x and 2x resources and we let the UI framework decide | |
| 56 // which one to use. | |
| 57 if (IsScaleFactorSupported(SCALE_FACTOR_200P)) { | |
| 58 AddDataPackFromPath(GetResourcesPakFilePath(@"chrome_200_percent", nil), | |
| 59 SCALE_FACTOR_200P); | |
| 60 } | |
| 61 } | |
| 62 | |
| 63 base::FilePath ResourceBundle::GetLocaleFilePath(const std::string& app_locale, | |
| 64 bool test_file_exists) { | |
| 65 NSString* mac_locale = base::SysUTF8ToNSString(app_locale); | |
| 66 | |
| 67 // Mac OS X uses "_" instead of "-", so swap to get a Mac-style value. | |
| 68 mac_locale = [mac_locale stringByReplacingOccurrencesOfString:@"-" | |
| 69 withString:@"_"]; | |
| 70 | |
| 71 // On disk, the "en_US" resources are just "en" (http://crbug.com/25578). | |
| 72 if ([mac_locale isEqual:@"en_US"]) | |
| 73 mac_locale = @"en"; | |
| 74 | |
| 75 base::FilePath locale_file_path = | |
| 76 GetResourcesPakFilePath(@"locale", mac_locale); | |
| 77 | |
| 78 if (delegate_) { | |
| 79 locale_file_path = | |
| 80 delegate_->GetPathForLocalePack(locale_file_path, app_locale); | |
| 81 } | |
| 82 | |
| 83 // Don't try to load empty values or values that are not absolute paths. | |
| 84 if (locale_file_path.empty() || !locale_file_path.IsAbsolute()) | |
| 85 return base::FilePath(); | |
| 86 | |
| 87 if (test_file_exists && !base::PathExists(locale_file_path)) | |
| 88 return base::FilePath(); | |
| 89 | |
| 90 return locale_file_path; | |
| 91 } | |
| 92 | |
| 93 gfx::Image& ResourceBundle::GetNativeImageNamed(int resource_id, ImageRTL rtl) { | |
| 94 // Flipped images are not used on Mac. | |
| 95 DCHECK_EQ(rtl, RTL_DISABLED); | |
| 96 | |
| 97 // Check to see if the image is already in the cache. | |
| 98 { | |
| 99 base::AutoLock lock(*images_and_fonts_lock_); | |
| 100 if (images_.count(resource_id)) { | |
| 101 if (!images_[resource_id].HasRepresentation(gfx::Image::kImageRepCocoa)) { | |
| 102 DLOG(WARNING) << "ResourceBundle::GetNativeImageNamed() is returning a" | |
| 103 << " cached gfx::Image that isn't backed by an NSImage. The image" | |
| 104 << " will be converted, rather than going through the NSImage loader." | |
| 105 << " resource_id = " << resource_id; | |
| 106 } | |
| 107 return images_[resource_id]; | |
| 108 } | |
| 109 } | |
| 110 | |
| 111 gfx::Image image; | |
| 112 if (delegate_) | |
| 113 image = delegate_->GetNativeImageNamed(resource_id, rtl); | |
| 114 | |
| 115 if (image.IsEmpty()) { | |
| 116 base::scoped_nsobject<NSImage> ns_image; | |
| 117 for (size_t i = 0; i < data_packs_.size(); ++i) { | |
| 118 scoped_refptr<base::RefCountedStaticMemory> data( | |
| 119 data_packs_[i]->GetStaticMemory(resource_id)); | |
| 120 if (!data.get()) | |
| 121 continue; | |
| 122 | |
| 123 base::scoped_nsobject<NSData> ns_data( | |
| 124 [[NSData alloc] initWithBytes:data->front() length:data->size()]); | |
| 125 if (!ns_image.get()) { | |
| 126 ns_image.reset([[NSImage alloc] initWithData:ns_data]); | |
| 127 } else { | |
| 128 NSImageRep* image_rep = [NSBitmapImageRep imageRepWithData:ns_data]; | |
| 129 if (image_rep) | |
| 130 [ns_image addRepresentation:image_rep]; | |
| 131 } | |
| 132 } | |
| 133 | |
| 134 if (!ns_image.get()) { | |
| 135 LOG(WARNING) << "Unable to load image with id " << resource_id; | |
| 136 NOTREACHED(); // Want to assert in debug mode. | |
| 137 return GetEmptyImage(); | |
| 138 } | |
| 139 | |
| 140 image = gfx::Image(ns_image.release()); | |
| 141 } | |
| 142 | |
| 143 base::AutoLock lock(*images_and_fonts_lock_); | |
| 144 | |
| 145 // Another thread raced the load and has already cached the image. | |
| 146 if (images_.count(resource_id)) | |
| 147 return images_[resource_id]; | |
| 148 | |
| 149 images_[resource_id] = image; | |
| 150 return images_[resource_id]; | |
| 151 } | |
| 152 | |
| 153 } // namespace ui | |
| OLD | NEW |