Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(355)

Side by Side Diff: gfx/gtk_util.cc

Issue 6246027: Move src/gfx/ to src/ui/gfx... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « gfx/gtk_util.h ('k') | gfx/icon_util.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2009 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 "gfx/gtk_util.h"
6
7 #include <gdk/gdk.h>
8 #include <gtk/gtk.h>
9 #include <stdlib.h>
10
11 #include "base/basictypes.h"
12 #include "base/command_line.h"
13 #include "base/linux_util.h"
14 #include "gfx/rect.h"
15 #include "third_party/skia/include/core/SkBitmap.h"
16 #include "third_party/skia/include/core/SkUnPreMultiply.h"
17
18 namespace {
19
20 // A process wide singleton that manages our usage of gdk
21 // cursors. gdk_cursor_new() hits the disk in several places and GdkCursor
22 // instances can be reused throughout the process.
23 class GdkCursorCache {
24 public:
25 GdkCursorCache() {}
26 ~GdkCursorCache() {
27 for (std::map<GdkCursorType, GdkCursor*>::iterator it =
28 cursor_cache_.begin(); it != cursor_cache_.end(); ++it) {
29 gdk_cursor_unref(it->second);
30 }
31 cursor_cache_.clear();
32 }
33
34 GdkCursor* GetCursorImpl(GdkCursorType type) {
35 std::map<GdkCursorType, GdkCursor*>::iterator it = cursor_cache_.find(type);
36 GdkCursor* cursor = NULL;
37 if (it == cursor_cache_.end()) {
38 cursor = gdk_cursor_new(type);
39 cursor_cache_.insert(std::make_pair(type, cursor));
40 } else {
41 cursor = it->second;
42 }
43
44 // It is not necessary to add a reference here. The callers can ref the
45 // cursor if they need it for something.
46 return cursor;
47 }
48
49 std::map<GdkCursorType, GdkCursor*> cursor_cache_;
50
51 DISALLOW_COPY_AND_ASSIGN(GdkCursorCache);
52 };
53
54 void FreePixels(guchar* pixels, gpointer data) {
55 free(data);
56 }
57
58 // Common implementation of ConvertAcceleratorsFromWindowsStyle() and
59 // RemoveWindowsStyleAccelerators().
60 // Replaces all ampersands (as used in our grd files to indicate mnemonics)
61 // to |target|. Similarly any underscores get replaced with two underscores as
62 // is needed by pango.
63 std::string ConvertAmperstandsTo(const std::string& label,
64 const std::string& target) {
65 std::string ret;
66 ret.reserve(label.length() * 2);
67 for (size_t i = 0; i < label.length(); ++i) {
68 if ('_' == label[i]) {
69 ret.push_back('_');
70 ret.push_back('_');
71 } else if ('&' == label[i]) {
72 if (i + 1 < label.length() && '&' == label[i + 1]) {
73 ret.push_back('&');
74 ++i;
75 } else {
76 ret.append(target);
77 }
78 } else {
79 ret.push_back(label[i]);
80 }
81 }
82
83 return ret;
84 }
85
86 } // namespace
87
88 namespace gfx {
89
90 void GtkInitFromCommandLine(const CommandLine& command_line) {
91 const std::vector<std::string>& args = command_line.argv();
92 int argc = args.size();
93 scoped_array<char *> argv(new char *[argc + 1]);
94 for (size_t i = 0; i < args.size(); ++i) {
95 // TODO(piman@google.com): can gtk_init modify argv? Just being safe
96 // here.
97 argv[i] = strdup(args[i].c_str());
98 }
99 argv[argc] = NULL;
100 char **argv_pointer = argv.get();
101
102 gtk_init(&argc, &argv_pointer);
103 for (size_t i = 0; i < args.size(); ++i) {
104 free(argv[i]);
105 }
106 }
107
108 GdkPixbuf* GdkPixbufFromSkBitmap(const SkBitmap* bitmap) {
109 if (bitmap->isNull())
110 return NULL;
111
112 bitmap->lockPixels();
113
114 int width = bitmap->width();
115 int height = bitmap->height();
116 int stride = bitmap->rowBytes();
117
118 // SkBitmaps are premultiplied, we need to unpremultiply them.
119 const int kBytesPerPixel = 4;
120 uint8* divided = static_cast<uint8*>(malloc(height * stride));
121
122 for (int y = 0, i = 0; y < height; y++) {
123 for (int x = 0; x < width; x++) {
124 uint32 pixel = bitmap->getAddr32(0, y)[x];
125
126 int alpha = SkColorGetA(pixel);
127 if (alpha != 0 && alpha != 255) {
128 SkColor unmultiplied = SkUnPreMultiply::PMColorToColor(pixel);
129 divided[i + 0] = SkColorGetR(unmultiplied);
130 divided[i + 1] = SkColorGetG(unmultiplied);
131 divided[i + 2] = SkColorGetB(unmultiplied);
132 divided[i + 3] = alpha;
133 } else {
134 divided[i + 0] = SkColorGetR(pixel);
135 divided[i + 1] = SkColorGetG(pixel);
136 divided[i + 2] = SkColorGetB(pixel);
137 divided[i + 3] = alpha;
138 }
139 i += kBytesPerPixel;
140 }
141 }
142
143 // This pixbuf takes ownership of our malloc()ed data and will
144 // free it for us when it is destroyed.
145 GdkPixbuf* pixbuf = gdk_pixbuf_new_from_data(
146 divided,
147 GDK_COLORSPACE_RGB, // The only colorspace gtk supports.
148 true, // There is an alpha channel.
149 8,
150 width, height, stride, &FreePixels, divided);
151
152 bitmap->unlockPixels();
153 return pixbuf;
154 }
155
156 void SubtractRectanglesFromRegion(GdkRegion* region,
157 const std::vector<Rect>& cutouts) {
158 for (size_t i = 0; i < cutouts.size(); ++i) {
159 GdkRectangle rect = cutouts[i].ToGdkRectangle();
160 GdkRegion* rect_region = gdk_region_rectangle(&rect);
161 gdk_region_subtract(region, rect_region);
162 // TODO(deanm): It would be nice to be able to reuse the GdkRegion here.
163 gdk_region_destroy(rect_region);
164 }
165 }
166
167 double GetPangoResolution() {
168 static double resolution;
169 static bool determined_resolution = false;
170 if (!determined_resolution) {
171 determined_resolution = true;
172 PangoContext* default_context = gdk_pango_context_get();
173 resolution = pango_cairo_context_get_resolution(default_context);
174 g_object_unref(default_context);
175 }
176 return resolution;
177 }
178
179 GdkCursor* GetCursor(int type) {
180 static GdkCursorCache impl;
181 return impl.GetCursorImpl(static_cast<GdkCursorType>(type));
182 }
183
184 std::string ConvertAcceleratorsFromWindowsStyle(const std::string& label) {
185 return ConvertAmperstandsTo(label, "_");
186 }
187
188 std::string RemoveWindowsStyleAccelerators(const std::string& label) {
189 return ConvertAmperstandsTo(label, "");
190 }
191
192 uint8_t* BGRAToRGBA(const uint8_t* pixels, int width, int height, int stride) {
193 if (stride == 0)
194 stride = width * 4;
195
196 uint8_t* new_pixels = static_cast<uint8_t*>(malloc(height * stride));
197
198 // We have to copy the pixels and swap from BGRA to RGBA.
199 for (int i = 0; i < height; ++i) {
200 for (int j = 0; j < width; ++j) {
201 int idx = i * stride + j * 4;
202 new_pixels[idx] = pixels[idx + 2];
203 new_pixels[idx + 1] = pixels[idx + 1];
204 new_pixels[idx + 2] = pixels[idx];
205 new_pixels[idx + 3] = pixels[idx + 3];
206 }
207 }
208
209 return new_pixels;
210 }
211
212 } // namespace gfx
OLDNEW
« no previous file with comments | « gfx/gtk_util.h ('k') | gfx/icon_util.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698