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.
5 #include "chrome/browser/ui/libgtk2ui/gtk2_util.h"
9 #include "base/command_line.h"
10 #include "base/logging.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "skia/ext/platform_canvas.h"
13 #include "third_party/skia/include/core/SkBitmap.h"
14 #include "ui/gfx/canvas.h"
15 #include "ui/gfx/size.h"
19 void CommonInitFromCommandLine(const CommandLine
& command_line
,
20 void (*init_func
)(gint
*, gchar
***)) {
21 const std::vector
<std::string
>& args
= command_line
.argv();
22 int argc
= args
.size();
23 scoped_array
<char *> argv(new char *[argc
+ 1]);
24 for (size_t i
= 0; i
< args
.size(); ++i
) {
25 // TODO(piman@google.com): can gtk_init modify argv? Just being safe
27 argv
[i
] = strdup(args
[i
].c_str());
30 char **argv_pointer
= argv
.get();
32 init_func(&argc
, &argv_pointer
);
33 for (size_t i
= 0; i
< args
.size(); ++i
) {
42 void GtkInitFromCommandLine(const CommandLine
& command_line
) {
43 CommonInitFromCommandLine(command_line
, gtk_init
);
46 const SkBitmap
GdkPixbufToImageSkia(GdkPixbuf
* pixbuf
) {
47 // TODO(erg): What do we do in the case where the pixbuf fails these dchecks?
48 // I would prefer to use our gtk based canvas, but that would require
49 // recompiling half of our skia extensions with gtk support, which we can't
51 DCHECK_EQ(GDK_COLORSPACE_RGB
, gdk_pixbuf_get_colorspace(pixbuf
));
53 int n_channels
= gdk_pixbuf_get_n_channels(pixbuf
);
54 int w
= gdk_pixbuf_get_width(pixbuf
);
55 int h
= gdk_pixbuf_get_height(pixbuf
);
58 ret
.setConfig(SkBitmap::kARGB_8888_Config
, w
, h
);
62 uint32_t* skia_data
= static_cast<uint32_t*>(ret
.getAddr(0, 0));
64 if (n_channels
== 4) {
65 int total_length
= w
* h
;
66 guchar
* gdk_pixels
= gdk_pixbuf_get_pixels(pixbuf
);
68 // Now here's the trick: we need to convert the gdk data (which is RGBA and
69 // isn't premultiplied) to skia (which can be anything and premultiplied).
70 for (int i
= 0; i
< total_length
; ++i
, gdk_pixels
+= 4) {
71 const unsigned char& red
= gdk_pixels
[0];
72 const unsigned char& green
= gdk_pixels
[1];
73 const unsigned char& blue
= gdk_pixels
[2];
74 const unsigned char& alpha
= gdk_pixels
[3];
76 skia_data
[i
] = SkPreMultiplyARGB(alpha
, red
, green
, blue
);
78 } else if (n_channels
== 3) {
79 // Because GDK makes rowstrides word aligned, we need to do something a bit
80 // more complex when a pixel isn't perfectly a word of memory.
81 int rowstride
= gdk_pixbuf_get_rowstride(pixbuf
);
82 guchar
* gdk_pixels
= gdk_pixbuf_get_pixels(pixbuf
);
83 for (int y
= 0; y
< h
; ++y
) {
84 int row
= y
* rowstride
;
86 for (int x
= 0; x
< w
; ++x
) {
87 guchar
* pixel
= gdk_pixels
+ row
+ (x
* 3);
88 const unsigned char& red
= pixel
[0];
89 const unsigned char& green
= pixel
[1];
90 const unsigned char& blue
= pixel
[2];
92 skia_data
[y
* w
+ x
] = SkPreMultiplyARGB(255, red
, green
, blue
);
102 } // namespace libgtk2ui