| 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 #ifndef UI_BASE_RESOURCE_RESOURCE_BUNDLE_H_ | |
| 6 #define UI_BASE_RESOURCE_RESOURCE_BUNDLE_H_ | |
| 7 | |
| 8 #include <map> | |
| 9 #include <string> | |
| 10 | |
| 11 #include "base/basictypes.h" | |
| 12 #include "base/containers/hash_tables.h" | |
| 13 #include "base/files/file_path.h" | |
| 14 #include "base/files/memory_mapped_file.h" | |
| 15 #include "base/gtest_prod_util.h" | |
| 16 #include "base/memory/scoped_ptr.h" | |
| 17 #include "base/memory/scoped_vector.h" | |
| 18 #include "base/strings/string16.h" | |
| 19 #include "base/strings/string_piece.h" | |
| 20 #include "build/build_config.h" | |
| 21 #include "ui/base/layout.h" | |
| 22 #include "ui/base/ui_base_export.h" | |
| 23 #include "ui/gfx/font_list.h" | |
| 24 #include "ui/gfx/image/image.h" | |
| 25 #include "ui/gfx/native_widget_types.h" | |
| 26 | |
| 27 class SkBitmap; | |
| 28 | |
| 29 namespace base { | |
| 30 class File; | |
| 31 class Lock; | |
| 32 class RefCountedStaticMemory; | |
| 33 } | |
| 34 | |
| 35 namespace ui { | |
| 36 | |
| 37 class DataPack; | |
| 38 class ResourceHandle; | |
| 39 | |
| 40 // ResourceBundle is a central facility to load images and other resources, | |
| 41 // such as theme graphics. Every resource is loaded only once. | |
| 42 class UI_BASE_EXPORT ResourceBundle { | |
| 43 public: | |
| 44 // An enumeration of the various font styles used throughout Chrome. | |
| 45 // The following holds true for the font sizes: | |
| 46 // Small <= SmallBold <= Base <= Bold <= Medium <= MediumBold <= Large. | |
| 47 enum FontStyle { | |
| 48 // NOTE: depending upon the locale, using one of the *BoldFont below | |
| 49 // may *not* actually result in a bold font. | |
| 50 SmallFont, | |
| 51 SmallBoldFont, | |
| 52 BaseFont, | |
| 53 BoldFont, | |
| 54 MediumFont, | |
| 55 MediumBoldFont, | |
| 56 LargeFont, | |
| 57 LargeBoldFont, | |
| 58 }; | |
| 59 | |
| 60 enum ImageRTL { | |
| 61 // Images are flipped in RTL locales. | |
| 62 RTL_ENABLED, | |
| 63 // Images are never flipped. | |
| 64 RTL_DISABLED, | |
| 65 }; | |
| 66 | |
| 67 enum LoadResources { | |
| 68 LOAD_COMMON_RESOURCES, | |
| 69 DO_NOT_LOAD_COMMON_RESOURCES | |
| 70 }; | |
| 71 | |
| 72 // Delegate class that allows interception of pack file loading and resource | |
| 73 // requests. The methods of this class may be called on multiple threads. | |
| 74 class Delegate { | |
| 75 public: | |
| 76 // Called before a resource pack file is loaded. Return the full path for | |
| 77 // the pack file to continue loading or an empty value to cancel loading. | |
| 78 // |pack_path| will contain the complete default path for the pack file if | |
| 79 // known or just the pack file name otherwise. | |
| 80 virtual base::FilePath GetPathForResourcePack( | |
| 81 const base::FilePath& pack_path, | |
| 82 ScaleFactor scale_factor) = 0; | |
| 83 | |
| 84 // Called before a locale pack file is loaded. Return the full path for | |
| 85 // the pack file to continue loading or an empty value to cancel loading. | |
| 86 // |pack_path| will contain the complete default path for the pack file if | |
| 87 // known or just the pack file name otherwise. | |
| 88 virtual base::FilePath GetPathForLocalePack( | |
| 89 const base::FilePath& pack_path, | |
| 90 const std::string& locale) = 0; | |
| 91 | |
| 92 // Return an image resource or an empty value to attempt retrieval of the | |
| 93 // default resource. | |
| 94 virtual gfx::Image GetImageNamed(int resource_id) = 0; | |
| 95 | |
| 96 // Return an image resource or an empty value to attempt retrieval of the | |
| 97 // default resource. | |
| 98 virtual gfx::Image GetNativeImageNamed(int resource_id, ImageRTL rtl) = 0; | |
| 99 | |
| 100 // Return a static memory resource or NULL to attempt retrieval of the | |
| 101 // default resource. | |
| 102 virtual base::RefCountedStaticMemory* LoadDataResourceBytes( | |
| 103 int resource_id, | |
| 104 ScaleFactor scale_factor) = 0; | |
| 105 | |
| 106 // Retrieve a raw data resource. Return true if a resource was provided or | |
| 107 // false to attempt retrieval of the default resource. | |
| 108 virtual bool GetRawDataResource(int resource_id, | |
| 109 ScaleFactor scale_factor, | |
| 110 base::StringPiece* value) = 0; | |
| 111 | |
| 112 // Retrieve a localized string. Return true if a string was provided or | |
| 113 // false to attempt retrieval of the default string. | |
| 114 virtual bool GetLocalizedString(int message_id, base::string16* value) = 0; | |
| 115 | |
| 116 // Returns a font or NULL to attempt retrieval of the default resource. | |
| 117 virtual scoped_ptr<gfx::Font> GetFont(FontStyle style) = 0; | |
| 118 | |
| 119 protected: | |
| 120 virtual ~Delegate() {} | |
| 121 }; | |
| 122 | |
| 123 // Initialize the ResourceBundle for this process. Does not take ownership of | |
| 124 // the |delegate| value. Returns the language selected. | |
| 125 // NOTE: Mac ignores this and always loads up resources for the language | |
| 126 // defined by the Cocoa UI (i.e., NSBundle does the language work). | |
| 127 // | |
| 128 // TODO(sergeyu): This method also loads common resources (i.e. chrome.pak). | |
| 129 // There is no way to specify which resource files are loaded, i.e. names of | |
| 130 // the files are hardcoded in ResourceBundle. Fix it to allow to specify which | |
| 131 // files are loaded (e.g. add a new method in Delegate). | |
| 132 // |load_resources| controls whether or not LoadCommonResources is called. | |
| 133 static std::string InitSharedInstanceWithLocale( | |
| 134 const std::string& pref_locale, | |
| 135 Delegate* delegate, | |
| 136 LoadResources load_resources); | |
| 137 | |
| 138 // Initialize the ResourceBundle using the given file region. If |region| is | |
| 139 // MemoryMappedFile::Region::kWholeFile, the entire |pak_file| is used. | |
| 140 // This allows the use of this function in a sandbox without local file | |
| 141 // access (as on Android). | |
| 142 static void InitSharedInstanceWithPakFileRegion( | |
| 143 base::File pak_file, | |
| 144 const base::MemoryMappedFile::Region& region); | |
| 145 | |
| 146 // Initialize the ResourceBundle using given data pack path for testing. | |
| 147 static void InitSharedInstanceWithPakPath(const base::FilePath& path); | |
| 148 | |
| 149 // Delete the ResourceBundle for this process if it exists. | |
| 150 static void CleanupSharedInstance(); | |
| 151 | |
| 152 // Returns true after the global resource loader instance has been created. | |
| 153 static bool HasSharedInstance(); | |
| 154 | |
| 155 // Return the global resource loader instance. | |
| 156 static ResourceBundle& GetSharedInstance(); | |
| 157 | |
| 158 // Check if the .pak for the given locale exists. | |
| 159 bool LocaleDataPakExists(const std::string& locale); | |
| 160 | |
| 161 // Registers additional data pack files with this ResourceBundle. When | |
| 162 // looking for a DataResource, we will search these files after searching the | |
| 163 // main module. |path| should be the complete path to the pack file if known | |
| 164 // or just the pack file name otherwise (the delegate may optionally override | |
| 165 // this value). |scale_factor| is the scale of images in this resource pak | |
| 166 // relative to the images in the 1x resource pak. This method is not thread | |
| 167 // safe! You should call it immediately after calling InitSharedInstance. | |
| 168 void AddDataPackFromPath(const base::FilePath& path, | |
| 169 ScaleFactor scale_factor); | |
| 170 | |
| 171 // Same as above but using an already open file. | |
| 172 void AddDataPackFromFile(base::File file, ScaleFactor scale_factor); | |
| 173 | |
| 174 // Same as above but using only a region (offset + size) of the file. | |
| 175 void AddDataPackFromFileRegion(base::File file, | |
| 176 const base::MemoryMappedFile::Region& region, | |
| 177 ScaleFactor scale_factor); | |
| 178 | |
| 179 // Same as AddDataPackFromPath but does not log an error if the pack fails to | |
| 180 // load. | |
| 181 void AddOptionalDataPackFromPath(const base::FilePath& path, | |
| 182 ScaleFactor scale_factor); | |
| 183 | |
| 184 // Changes the locale for an already-initialized ResourceBundle, returning the | |
| 185 // name of the newly-loaded locale. Future calls to get strings will return | |
| 186 // the strings for this new locale. This has no effect on existing or future | |
| 187 // image resources. |locale_resources_data_| is protected by a lock for the | |
| 188 // duration of the swap, as GetLocalizedString() may be concurrently invoked | |
| 189 // on another thread. | |
| 190 std::string ReloadLocaleResources(const std::string& pref_locale); | |
| 191 | |
| 192 // Gets image with the specified resource_id from the current module data. | |
| 193 // Returns a pointer to a shared instance of gfx::ImageSkia. This shared | |
| 194 // instance is owned by the resource bundle and should not be freed. | |
| 195 // TODO(pkotwicz): Make method return const gfx::ImageSkia* | |
| 196 // | |
| 197 // NOTE: GetNativeImageNamed is preferred for cross-platform gfx::Image use. | |
| 198 gfx::ImageSkia* GetImageSkiaNamed(int resource_id); | |
| 199 | |
| 200 // Gets an image resource from the current module data. This will load the | |
| 201 // image in Skia format by default. The ResourceBundle owns this. | |
| 202 gfx::Image& GetImageNamed(int resource_id); | |
| 203 | |
| 204 // Similar to GetImageNamed, but rather than loading the image in Skia format, | |
| 205 // it will load in the native platform type. This can avoid conversion from | |
| 206 // one image type to another. ResourceBundle owns the result. | |
| 207 // | |
| 208 // Note that if the same resource has already been loaded in GetImageNamed(), | |
| 209 // gfx::Image will perform a conversion, rather than using the native image | |
| 210 // loading code of ResourceBundle. | |
| 211 // | |
| 212 // If |rtl| is RTL_ENABLED then the image is flipped in RTL locales. | |
| 213 gfx::Image& GetNativeImageNamed(int resource_id, ImageRTL rtl); | |
| 214 | |
| 215 // Same as GetNativeImageNamed() except that RTL is not enabled. | |
| 216 gfx::Image& GetNativeImageNamed(int resource_id); | |
| 217 | |
| 218 // Loads the raw bytes of a scale independent data resource. | |
| 219 base::RefCountedStaticMemory* LoadDataResourceBytes(int resource_id) const; | |
| 220 | |
| 221 // Loads the raw bytes of a data resource nearest the scale factor | |
| 222 // |scale_factor| into |bytes|, without doing any processing or | |
| 223 // interpretation of the resource. Use ResourceHandle::SCALE_FACTOR_NONE | |
| 224 // for scale independent image resources (such as wallpaper). | |
| 225 // Returns NULL if we fail to read the resource. | |
| 226 base::RefCountedStaticMemory* LoadDataResourceBytesForScale( | |
| 227 int resource_id, | |
| 228 ScaleFactor scale_factor) const; | |
| 229 | |
| 230 // Return the contents of a scale independent resource in a | |
| 231 // StringPiece given the resource id | |
| 232 base::StringPiece GetRawDataResource(int resource_id) const; | |
| 233 | |
| 234 // Return the contents of a resource in a StringPiece given the resource id | |
| 235 // nearest the scale factor |scale_factor|. | |
| 236 // Use ResourceHandle::SCALE_FACTOR_NONE for scale independent image resources | |
| 237 // (such as wallpaper). | |
| 238 base::StringPiece GetRawDataResourceForScale(int resource_id, | |
| 239 ScaleFactor scale_factor) const; | |
| 240 | |
| 241 // Get a localized string given a message id. Returns an empty | |
| 242 // string if the message_id is not found. | |
| 243 base::string16 GetLocalizedString(int message_id); | |
| 244 | |
| 245 // Returns the font list for the specified style. | |
| 246 const gfx::FontList& GetFontList(FontStyle style); | |
| 247 | |
| 248 // Returns the font for the specified style. | |
| 249 const gfx::Font& GetFont(FontStyle style); | |
| 250 | |
| 251 // Resets and reloads the cached fonts. This is useful when the fonts of the | |
| 252 // system have changed, for example, when the locale has changed. | |
| 253 void ReloadFonts(); | |
| 254 | |
| 255 // Overrides the path to the pak file from which the locale resources will be | |
| 256 // loaded. Pass an empty path to undo. | |
| 257 void OverrideLocalePakForTest(const base::FilePath& pak_path); | |
| 258 | |
| 259 // Overrides a localized string resource with the given string. If no delegate | |
| 260 // is present, the |string| will be returned when getting the localized string | |
| 261 // |message_id|. If |ReloadLocaleResources| is called, all overrides are | |
| 262 // cleared. This is intended to be used in conjunction with field trials and | |
| 263 // the variations service to experiment with different UI strings. This method | |
| 264 // is not thread safe! | |
| 265 void OverrideLocaleStringResource(int message_id, | |
| 266 const base::string16& string); | |
| 267 | |
| 268 // Returns the full pathname of the locale file to load. May return an empty | |
| 269 // string if no locale data files are found and |test_file_exists| is true. | |
| 270 // Used on Android to load the local file in the browser process and pass it | |
| 271 // to the sandboxed renderer process. | |
| 272 base::FilePath GetLocaleFilePath(const std::string& app_locale, | |
| 273 bool test_file_exists); | |
| 274 | |
| 275 // Returns the maximum scale factor currently loaded. | |
| 276 // Returns SCALE_FACTOR_100P if no resource is loaded. | |
| 277 ScaleFactor GetMaxScaleFactor() const; | |
| 278 | |
| 279 protected: | |
| 280 // Returns true if |scale_factor| is supported by this platform. | |
| 281 static bool IsScaleFactorSupported(ScaleFactor scale_factor); | |
| 282 | |
| 283 private: | |
| 284 FRIEND_TEST_ALL_PREFIXES(ResourceBundleTest, DelegateGetPathForLocalePack); | |
| 285 FRIEND_TEST_ALL_PREFIXES(ResourceBundleTest, DelegateGetImageNamed); | |
| 286 FRIEND_TEST_ALL_PREFIXES(ResourceBundleTest, DelegateGetNativeImageNamed); | |
| 287 | |
| 288 friend class ResourceBundleImageTest; | |
| 289 friend class ResourceBundleTest; | |
| 290 | |
| 291 class ResourceBundleImageSource; | |
| 292 friend class ResourceBundleImageSource; | |
| 293 | |
| 294 typedef base::hash_map<int, base::string16> IdToStringMap; | |
| 295 | |
| 296 // Ctor/dtor are private, since we're a singleton. | |
| 297 explicit ResourceBundle(Delegate* delegate); | |
| 298 ~ResourceBundle(); | |
| 299 | |
| 300 // Shared initialization. | |
| 301 static void InitSharedInstance(Delegate* delegate); | |
| 302 | |
| 303 // Free skia_images_. | |
| 304 void FreeImages(); | |
| 305 | |
| 306 // Load the main resources. | |
| 307 void LoadCommonResources(); | |
| 308 | |
| 309 // Implementation for AddDataPackFromPath and AddOptionalDataPackFromPath, if | |
| 310 // the pack is not |optional| logs an error on failure to load. | |
| 311 void AddDataPackFromPathInternal(const base::FilePath& path, | |
| 312 ScaleFactor scale_factor, | |
| 313 bool optional); | |
| 314 | |
| 315 // Inserts |data_pack| to |data_pack_| and updates |max_scale_factor_| | |
| 316 // accordingly. | |
| 317 void AddDataPack(DataPack* data_pack); | |
| 318 | |
| 319 // Try to load the locale specific strings from an external data module. | |
| 320 // Returns the locale that is loaded. | |
| 321 std::string LoadLocaleResources(const std::string& pref_locale); | |
| 322 | |
| 323 // Load test resources in given paths. If either path is empty an empty | |
| 324 // resource pack is loaded. | |
| 325 void LoadTestResources(const base::FilePath& path, | |
| 326 const base::FilePath& locale_path); | |
| 327 | |
| 328 // Unload the locale specific strings and prepares to load new ones. See | |
| 329 // comments for ReloadLocaleResources(). | |
| 330 void UnloadLocaleResources(); | |
| 331 | |
| 332 // Initializes all the gfx::FontList members if they haven't yet been | |
| 333 // initialized. | |
| 334 void LoadFontsIfNecessary(); | |
| 335 | |
| 336 // Returns a FontList or NULL by calling Delegate::GetFont and converting | |
| 337 // scoped_ptr<gfx::Font> to scoped_ptr<gfx::FontList>. | |
| 338 scoped_ptr<gfx::FontList> GetFontListFromDelegate(FontStyle style); | |
| 339 | |
| 340 // Fills the |bitmap| given the data file to look in and the |resource_id|. | |
| 341 // Returns false if the resource does not exist. | |
| 342 // | |
| 343 // If the call succeeds, |fell_back_to_1x| indicates whether Chrome's custom | |
| 344 // csCl PNG chunk is present (added by GRIT if it falls back to a 100% image). | |
| 345 bool LoadBitmap(const ResourceHandle& data_handle, | |
| 346 int resource_id, | |
| 347 SkBitmap* bitmap, | |
| 348 bool* fell_back_to_1x) const; | |
| 349 | |
| 350 // Fills the |bitmap| given the |resource_id| and |scale_factor|. | |
| 351 // Returns false if the resource does not exist. This may fall back to | |
| 352 // the data pack with SCALE_FACTOR_NONE, and when this happens, | |
| 353 // |scale_factor| will be set to SCALE_FACTOR_100P. | |
| 354 bool LoadBitmap(int resource_id, | |
| 355 ScaleFactor* scale_factor, | |
| 356 SkBitmap* bitmap, | |
| 357 bool* fell_back_to_1x) const; | |
| 358 | |
| 359 // Returns true if missing scaled resources should be visually indicated when | |
| 360 // drawing the fallback (e.g., by tinting the image). | |
| 361 static bool ShouldHighlightMissingScaledResources(); | |
| 362 | |
| 363 // Returns true if the data in |buf| is a PNG that has the special marker | |
| 364 // added by GRIT that indicates that the image is actually 1x data. | |
| 365 static bool PNGContainsFallbackMarker(const unsigned char* buf, size_t size); | |
| 366 | |
| 367 // A wrapper for PNGCodec::Decode that returns information about custom | |
| 368 // chunks. For security reasons we can't alter PNGCodec to return this | |
| 369 // information. Our PNG files are preprocessed by GRIT, and any special chunks | |
| 370 // should occur immediately after the IHDR chunk. | |
| 371 static bool DecodePNG(const unsigned char* buf, | |
| 372 size_t size, | |
| 373 SkBitmap* bitmap, | |
| 374 bool* fell_back_to_1x); | |
| 375 | |
| 376 // Returns an empty image for when a resource cannot be loaded. This is a | |
| 377 // bright red bitmap. | |
| 378 gfx::Image& GetEmptyImage(); | |
| 379 | |
| 380 const base::FilePath& GetOverriddenPakPath(); | |
| 381 | |
| 382 // This pointer is guaranteed to outlive the ResourceBundle instance and may | |
| 383 // be NULL. | |
| 384 Delegate* delegate_; | |
| 385 | |
| 386 // Protects |images_| and font-related members. | |
| 387 scoped_ptr<base::Lock> images_and_fonts_lock_; | |
| 388 | |
| 389 // Protects |locale_resources_data_|. | |
| 390 scoped_ptr<base::Lock> locale_resources_data_lock_; | |
| 391 | |
| 392 // Handles for data sources. | |
| 393 scoped_ptr<ResourceHandle> locale_resources_data_; | |
| 394 ScopedVector<ResourceHandle> data_packs_; | |
| 395 | |
| 396 // The maximum scale factor currently loaded. | |
| 397 ScaleFactor max_scale_factor_; | |
| 398 | |
| 399 // Cached images. The ResourceBundle caches all retrieved images and keeps | |
| 400 // ownership of the pointers. | |
| 401 typedef std::map<int, gfx::Image> ImageMap; | |
| 402 ImageMap images_; | |
| 403 | |
| 404 gfx::Image empty_image_; | |
| 405 | |
| 406 // The various font lists used. Cached to avoid repeated GDI | |
| 407 // creation/destruction. | |
| 408 scoped_ptr<gfx::FontList> base_font_list_; | |
| 409 scoped_ptr<gfx::FontList> bold_font_list_; | |
| 410 scoped_ptr<gfx::FontList> small_font_list_; | |
| 411 scoped_ptr<gfx::FontList> small_bold_font_list_; | |
| 412 scoped_ptr<gfx::FontList> medium_font_list_; | |
| 413 scoped_ptr<gfx::FontList> medium_bold_font_list_; | |
| 414 scoped_ptr<gfx::FontList> large_font_list_; | |
| 415 scoped_ptr<gfx::FontList> large_bold_font_list_; | |
| 416 scoped_ptr<gfx::FontList> web_font_list_; | |
| 417 | |
| 418 base::FilePath overridden_pak_path_; | |
| 419 | |
| 420 IdToStringMap overridden_locale_strings_; | |
| 421 | |
| 422 DISALLOW_COPY_AND_ASSIGN(ResourceBundle); | |
| 423 }; | |
| 424 | |
| 425 } // namespace ui | |
| 426 | |
| 427 // TODO(beng): Someday, maybe, get rid of this. | |
| 428 using ui::ResourceBundle; | |
| 429 | |
| 430 #endif // UI_BASE_RESOURCE_RESOURCE_BUNDLE_H_ | |
| OLD | NEW |