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 #include "base/i18n/rtl.h" | |
8 #include "base/logging.h" | |
9 #include "base/memory/ref_counted_memory.h" | |
10 #include "base/path_service.h" | |
11 #include "base/synchronization/lock.h" | |
12 #include "third_party/skia/include/core/SkBitmap.h" | |
13 #include "ui/base/layout.h" | |
14 #include "ui/base/resource/resource_handle.h" | |
15 #include "ui/base/ui_base_paths.h" | |
16 #include "ui/gfx/image/image.h" | |
17 #include "ui/gfx/scoped_gobject.h" | |
18 | |
19 #include <gtk/gtk.h> | |
20 | |
21 namespace ui { | |
22 | |
23 namespace { | |
24 | |
25 // Convert the raw image data into a GdkPixbuf. The GdkPixbuf that is returned | |
26 // has a ref count of 1 so the caller must call g_object_unref to free the | |
27 // memory. | |
28 GdkPixbuf* LoadPixbuf(base::RefCountedStaticMemory* data, bool rtl_enabled) { | |
29 ScopedGObject<GdkPixbufLoader>::Type loader(gdk_pixbuf_loader_new()); | |
30 bool ok = data && gdk_pixbuf_loader_write(loader.get(), | |
31 data->front_as<guint8>(), data->size(), NULL); | |
32 if (!ok) | |
33 return NULL; | |
34 // Calling gdk_pixbuf_loader_close forces the data to be parsed by the | |
35 // loader. We must do this before calling gdk_pixbuf_loader_get_pixbuf. | |
36 ok = gdk_pixbuf_loader_close(loader.get(), NULL); | |
37 if (!ok) | |
38 return NULL; | |
39 GdkPixbuf* pixbuf = gdk_pixbuf_loader_get_pixbuf(loader.get()); | |
40 if (!pixbuf) | |
41 return NULL; | |
42 | |
43 if (base::i18n::IsRTL() && rtl_enabled) { | |
44 // |pixbuf| will get unreffed and destroyed (see below). The returned value | |
45 // has ref count 1. | |
46 return gdk_pixbuf_flip(pixbuf, TRUE); | |
47 } else { | |
48 // The pixbuf is owned by the loader, so add a ref so when we delete the | |
49 // loader (when the ScopedGObject goes out of scope), the pixbuf still | |
50 // exists. | |
51 g_object_ref(pixbuf); | |
52 return pixbuf; | |
53 } | |
54 } | |
55 | |
56 base::FilePath GetResourcesPakFilePath(const std::string& pak_name) { | |
57 base::FilePath path; | |
58 if (PathService::Get(base::DIR_MODULE, &path)) | |
59 return path.AppendASCII(pak_name.c_str()); | |
60 | |
61 // Return just the name of the pack file. | |
62 return base::FilePath(pak_name.c_str()); | |
63 } | |
64 | |
65 } // namespace | |
66 | |
67 void ResourceBundle::LoadCommonResources() { | |
68 AddDataPackFromPath(GetResourcesPakFilePath( | |
69 "chrome_100_percent.pak"), | |
70 SCALE_FACTOR_100P); | |
71 } | |
72 | |
73 gfx::Image& ResourceBundle::GetNativeImageNamed(int resource_id, ImageRTL rtl) { | |
74 // Use the negative |resource_id| for the key for BIDI-aware images. | |
75 int key = rtl == RTL_ENABLED ? -resource_id : resource_id; | |
76 | |
77 // Check to see if the image is already in the cache. | |
78 { | |
79 base::AutoLock lock_scope(*images_and_fonts_lock_); | |
80 if (images_.count(key)) | |
81 return images_[key]; | |
82 } | |
83 | |
84 gfx::Image image; | |
85 if (delegate_) | |
86 image = delegate_->GetNativeImageNamed(resource_id, rtl); | |
87 | |
88 if (image.IsEmpty()) { | |
89 scoped_refptr<base::RefCountedStaticMemory> data( | |
90 LoadDataResourceBytesForScale(resource_id, SCALE_FACTOR_100P)); | |
91 GdkPixbuf* pixbuf = LoadPixbuf(data.get(), rtl == RTL_ENABLED); | |
92 | |
93 if (!pixbuf) { | |
94 LOG(WARNING) << "Unable to load pixbuf with id " << resource_id; | |
95 NOTREACHED(); // Want to assert in debug mode. | |
96 return GetEmptyImage(); | |
97 } | |
98 | |
99 image = gfx::Image(pixbuf); // Takes ownership. | |
100 } | |
101 | |
102 base::AutoLock lock_scope(*images_and_fonts_lock_); | |
103 | |
104 // Another thread raced the load and has already cached the image. | |
105 if (images_.count(key)) | |
106 return images_[key]; | |
107 | |
108 images_[key] = image; | |
109 return images_[key]; | |
110 } | |
111 | |
112 } // namespace ui | |
OLD | NEW |