resource.cc 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. // Copyright 2018 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. #include "ui/lottie/resource.h"
  5. #include <memory>
  6. #include <utility>
  7. #include <vector>
  8. #include "base/bind.h"
  9. #include "base/memory/ref_counted_memory.h"
  10. #include "cc/paint/display_item_list.h"
  11. #include "cc/paint/record_paint_canvas.h"
  12. #include "cc/paint/skottie_color_map.h"
  13. #include "cc/paint/skottie_wrapper.h"
  14. #include "third_party/skia/include/core/SkColor.h"
  15. #include "ui/gfx/canvas.h"
  16. #include "ui/gfx/geometry/size.h"
  17. #include "ui/gfx/image/image_skia.h"
  18. #include "ui/gfx/image/image_skia_rep.h"
  19. #include "ui/gfx/image/image_skia_source.h"
  20. #include "ui/lottie/animation.h"
  21. #if BUILDFLAG(IS_CHROMEOS_ASH)
  22. #include "ui/base/models/image_model.h" // nogncheck
  23. #include "ui/color/color_id.h" // nogncheck
  24. #include "ui/color/color_provider.h" // nogncheck
  25. #endif
  26. namespace lottie {
  27. namespace {
  28. // A descendant of |gfx::ImageSkiaSource| that simply uses one
  29. // |gfx::ImageSkiaRep| for all scales.
  30. class LottieImageSource : public gfx::ImageSkiaSource {
  31. public:
  32. explicit LottieImageSource(const gfx::ImageSkiaRep& rep) : rep_(rep) {}
  33. LottieImageSource(const LottieImageSource&) = delete;
  34. LottieImageSource& operator=(const LottieImageSource&) = delete;
  35. ~LottieImageSource() override = default;
  36. // gfx::ImageSkiaSource overrides:
  37. gfx::ImageSkiaRep GetImageForScale(float scale) override { return rep_; }
  38. bool HasRepresentationAtAllScales() const override { return true; }
  39. private:
  40. gfx::ImageSkiaRep rep_;
  41. };
  42. // Uses |LottieImageSource| to create a |gfx::ImageSkia| from an |Animation|.
  43. gfx::ImageSkia CreateImageSkia(Animation* content) {
  44. const gfx::Size size = content->GetOriginalSize();
  45. scoped_refptr<cc::DisplayItemList> display_item_list =
  46. base::MakeRefCounted<cc::DisplayItemList>(
  47. cc::DisplayItemList::kToBeReleasedAsPaintOpBuffer);
  48. display_item_list->StartPaint();
  49. cc::RecordPaintCanvas record_canvas(
  50. display_item_list.get(), SkRect::MakeWH(SkFloatToScalar(size.width()),
  51. SkFloatToScalar(size.height())));
  52. gfx::Canvas canvas(&record_canvas, 1.0);
  53. #if DCHECK_IS_ON()
  54. gfx::Rect clip_rect;
  55. DCHECK(canvas.GetClipBounds(&clip_rect));
  56. DCHECK(clip_rect.Contains(gfx::Rect(size)));
  57. #endif
  58. content->PaintFrame(&canvas, 0.f, size);
  59. display_item_list->EndPaintOfPairedEnd();
  60. display_item_list->Finalize();
  61. const gfx::ImageSkiaRep rep(display_item_list->ReleaseAsRecord(), size, 0.f);
  62. return gfx::ImageSkia(std::make_unique<LottieImageSource>(rep),
  63. rep.pixel_size());
  64. }
  65. #if BUILDFLAG(IS_CHROMEOS_ASH)
  66. // Creates a |cc::SkottieColorMap| with theme colors from a |ui::ColorProvider|.
  67. cc::SkottieColorMap CreateColorMap(const ui::ColorProvider* color_provider) {
  68. return {
  69. cc::SkottieMapColor("_CrOS_Color1",
  70. color_provider->GetColor(ui::kColorNativeColor1)),
  71. cc::SkottieMapColor(
  72. "_CrOS_Color1Shade1",
  73. color_provider->GetColor(ui::kColorNativeColor1Shade1)),
  74. cc::SkottieMapColor(
  75. "_CrOS_Color1Shade2",
  76. color_provider->GetColor(ui::kColorNativeColor1Shade2)),
  77. cc::SkottieMapColor("_CrOS_Color2",
  78. color_provider->GetColor(ui::kColorNativeColor2)),
  79. cc::SkottieMapColor("_CrOS_Color3",
  80. color_provider->GetColor(ui::kColorNativeColor3)),
  81. cc::SkottieMapColor("_CrOS_Color4",
  82. color_provider->GetColor(ui::kColorNativeColor4)),
  83. cc::SkottieMapColor("_CrOS_Color5",
  84. color_provider->GetColor(ui::kColorNativeColor5)),
  85. cc::SkottieMapColor("_CrOS_Color6",
  86. color_provider->GetColor(ui::kColorNativeColor6)),
  87. cc::SkottieMapColor("_CrOS_BaseColor",
  88. color_provider->GetColor(ui::kColorNativeBaseColor)),
  89. cc::SkottieMapColor(
  90. "_CrOS_SecondaryColor",
  91. color_provider->GetColor(ui::kColorNativeSecondaryColor))};
  92. }
  93. // Used for a |ui::ImageModel::ImageGenerator|.
  94. gfx::ImageSkia CreateImageSkiaWithCurrentTheme(
  95. std::vector<uint8_t> bytes,
  96. const ui::ColorProvider* color_provider) {
  97. auto content = std::make_unique<Animation>(
  98. cc::SkottieWrapper::CreateSerializable(std::move(bytes)),
  99. CreateColorMap(color_provider));
  100. return CreateImageSkia(content.get());
  101. }
  102. #endif
  103. // Converts from |std::string| to |std::vector<uint8_t>|.
  104. std::vector<uint8_t> StringToBytes(const std::string& bytes_string) {
  105. const uint8_t* bytes_pointer =
  106. reinterpret_cast<const uint8_t*>(bytes_string.data());
  107. return std::vector<uint8_t>(bytes_pointer,
  108. bytes_pointer + bytes_string.size());
  109. }
  110. } // namespace
  111. gfx::ImageSkia ParseLottieAsStillImage(const std::string& bytes_string) {
  112. auto content = std::make_unique<Animation>(
  113. cc::SkottieWrapper::CreateSerializable(StringToBytes(bytes_string)));
  114. return CreateImageSkia(content.get());
  115. }
  116. #if BUILDFLAG(IS_CHROMEOS_ASH)
  117. ui::ImageModel ParseLottieAsThemedStillImage(const std::string& bytes_string) {
  118. std::vector<uint8_t> bytes = StringToBytes(bytes_string);
  119. const gfx::Size size =
  120. std::make_unique<Animation>(cc::SkottieWrapper::CreateSerializable(bytes))
  121. ->GetOriginalSize();
  122. return ui::ImageModel::FromImageGenerator(
  123. base::BindRepeating(&CreateImageSkiaWithCurrentTheme, std::move(bytes)),
  124. size);
  125. }
  126. #endif
  127. } // namespace lottie