gtk_util.cc 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. // Copyright (c) 2019 GitHub, Inc.
  2. // Use of this source code is governed by the MIT license that can be
  3. // found in the LICENSE file.
  4. #include "shell/browser/ui/gtk_util.h"
  5. #include <gdk/gdk.h>
  6. #include <gtk/gtk.h>
  7. #include <stdint.h>
  8. #include <string>
  9. #include "base/no_destructor.h"
  10. #include "base/strings/string_number_conversions.h"
  11. #include "electron/electron_gtk_stubs.h"
  12. #include "third_party/skia/include/core/SkBitmap.h"
  13. #include "third_party/skia/include/core/SkColor.h"
  14. #include "third_party/skia/include/core/SkUnPreMultiply.h"
  15. #include "ui/gtk/gtk_compat.h" // nogncheck
  16. // The following utilities are pulled from
  17. // https://source.chromium.org/chromium/chromium/src/+/main:ui/gtk/select_file_dialog_linux_gtk.cc;l=44-75;drc=a03ba4ca94f75531207c3ea832d6a605cde77394
  18. namespace gtk_util {
  19. namespace {
  20. const char* GettextPackage() {
  21. static base::NoDestructor<std::string> gettext_package(
  22. "gtk" + base::NumberToString(gtk::GtkVersion().components()[0]) + "0");
  23. return gettext_package->c_str();
  24. }
  25. const char* GtkGettext(const char* str) {
  26. return g_dgettext(GettextPackage(), str);
  27. }
  28. } // namespace
  29. const char* GetCancelLabel() {
  30. static const char* cancel = GtkGettext("_Cancel");
  31. return cancel;
  32. }
  33. const char* GetOpenLabel() {
  34. static const char* open = GtkGettext("_Open");
  35. return open;
  36. }
  37. const char* GetSaveLabel() {
  38. static const char* save = GtkGettext("_Save");
  39. return save;
  40. }
  41. const char* GetOkLabel() {
  42. static const char* ok = GtkGettext("_Ok");
  43. return ok;
  44. }
  45. const char* GetNoLabel() {
  46. static const char* no = GtkGettext("_No");
  47. return no;
  48. }
  49. const char* GetYesLabel() {
  50. static const char* yes = GtkGettext("_Yes");
  51. return yes;
  52. }
  53. GdkPixbuf* GdkPixbufFromSkBitmap(const SkBitmap& bitmap) {
  54. if (bitmap.isNull())
  55. return nullptr;
  56. int width = bitmap.width();
  57. int height = bitmap.height();
  58. GdkPixbuf* pixbuf =
  59. gdk_pixbuf_new(GDK_COLORSPACE_RGB, // The only colorspace gtk supports.
  60. TRUE, // There is an alpha channel.
  61. 8, width, height);
  62. // SkBitmaps are premultiplied, we need to unpremultiply them.
  63. const int kBytesPerPixel = 4;
  64. uint8_t* divided = gdk_pixbuf_get_pixels(pixbuf);
  65. for (int y = 0, i = 0; y < height; y++) {
  66. for (int x = 0; x < width; x++) {
  67. uint32_t pixel = bitmap.getAddr32(0, y)[x];
  68. int alpha = SkColorGetA(pixel);
  69. if (alpha != 0 && alpha != 255) {
  70. SkColor unmultiplied = SkUnPreMultiply::PMColorToColor(pixel);
  71. divided[i + 0] = SkColorGetR(unmultiplied);
  72. divided[i + 1] = SkColorGetG(unmultiplied);
  73. divided[i + 2] = SkColorGetB(unmultiplied);
  74. divided[i + 3] = alpha;
  75. } else {
  76. divided[i + 0] = SkColorGetR(pixel);
  77. divided[i + 1] = SkColorGetG(pixel);
  78. divided[i + 2] = SkColorGetB(pixel);
  79. divided[i + 3] = alpha;
  80. }
  81. i += kBytesPerPixel;
  82. }
  83. }
  84. return pixbuf;
  85. }
  86. } // namespace gtk_util