gtk_util.cc 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  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 "third_party/skia/include/core/SkBitmap.h"
  9. #include "third_party/skia/include/core/SkColor.h"
  10. #include "third_party/skia/include/core/SkUnPreMultiply.h"
  11. namespace gtk_util {
  12. // Copied from L40-L55 in
  13. // https://cs.chromium.org/chromium/src/chrome/browser/ui/libgtkui/select_file_dialog_impl_gtk.cc
  14. #if GTK_CHECK_VERSION(3, 90, 0)
  15. // GTK stock items have been deprecated. The docs say to switch to using the
  16. // strings "_Open", etc. However this breaks i18n. We could supply our own
  17. // internationalized strings, but the "_" in these strings is significant: it's
  18. // the keyboard shortcut to select these actions. TODO: Provide
  19. // internationalized strings when GTK provides support for it.
  20. const char* const kCancelLabel = "_Cancel";
  21. const char* const kNoLabel = "_No";
  22. const char* const kOkLabel = "_OK";
  23. const char* const kOpenLabel = "_Open";
  24. const char* const kSaveLabel = "_Save";
  25. const char* const kYesLabel = "_Yes";
  26. #else
  27. G_GNUC_BEGIN_IGNORE_DEPRECATIONS
  28. const char* const kCancelLabel = GTK_STOCK_CANCEL;
  29. const char* const kNoLabel = GTK_STOCK_NO;
  30. const char* const kOkLabel = GTK_STOCK_OK;
  31. const char* const kOpenLabel = GTK_STOCK_OPEN;
  32. const char* const kSaveLabel = GTK_STOCK_SAVE;
  33. const char* const kYesLabel = GTK_STOCK_YES;
  34. G_GNUC_END_IGNORE_DEPRECATIONS
  35. #endif
  36. GdkPixbuf* GdkPixbufFromSkBitmap(const SkBitmap& bitmap) {
  37. if (bitmap.isNull())
  38. return nullptr;
  39. int width = bitmap.width();
  40. int height = bitmap.height();
  41. GdkPixbuf* pixbuf =
  42. gdk_pixbuf_new(GDK_COLORSPACE_RGB, // The only colorspace gtk supports.
  43. TRUE, // There is an alpha channel.
  44. 8, width, height);
  45. // SkBitmaps are premultiplied, we need to unpremultiply them.
  46. const int kBytesPerPixel = 4;
  47. uint8_t* divided = gdk_pixbuf_get_pixels(pixbuf);
  48. for (int y = 0, i = 0; y < height; y++) {
  49. for (int x = 0; x < width; x++) {
  50. uint32_t pixel = bitmap.getAddr32(0, y)[x];
  51. int alpha = SkColorGetA(pixel);
  52. if (alpha != 0 && alpha != 255) {
  53. SkColor unmultiplied = SkUnPreMultiply::PMColorToColor(pixel);
  54. divided[i + 0] = SkColorGetR(unmultiplied);
  55. divided[i + 1] = SkColorGetG(unmultiplied);
  56. divided[i + 2] = SkColorGetB(unmultiplied);
  57. divided[i + 3] = alpha;
  58. } else {
  59. divided[i + 0] = SkColorGetR(pixel);
  60. divided[i + 1] = SkColorGetG(pixel);
  61. divided[i + 2] = SkColorGetB(pixel);
  62. divided[i + 3] = alpha;
  63. }
  64. i += kBytesPerPixel;
  65. }
  66. }
  67. return pixbuf;
  68. }
  69. } // namespace gtk_util