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 |