1 // Copyright 2019 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 #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_DARK_MODE_FILTER_H_ 6 #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_DARK_MODE_FILTER_H_ 7 8 #include <memory> 9 10 #include "cc/paint/paint_flags.h" 11 #include "third_party/blink/renderer/platform/geometry/float_rect.h" 12 #include "third_party/blink/renderer/platform/graphics/color.h" 13 #include "third_party/blink/renderer/platform/graphics/dark_mode_settings.h" 14 #include "third_party/blink/renderer/platform/graphics/image.h" 15 #include "third_party/blink/renderer/platform/platform_export.h" 16 #include "third_party/skia/include/core/SkRefCnt.h" 17 18 class SkColorFilter; 19 20 namespace blink { 21 22 class DarkModeColorClassifier; 23 class DarkModeColorFilter; 24 class ScopedDarkModeElementRoleOverride; 25 26 class PLATFORM_EXPORT DarkModeFilter { 27 public: 28 // Dark mode is disabled by default. Enable it by calling UpdateSettings() 29 // with a mode other than DarkMode::kOff. 30 DarkModeFilter(); 31 ~DarkModeFilter(); 32 33 bool IsDarkModeActive() const; 34 settings()35 const DarkModeSettings& settings() const { return settings_; } 36 void UpdateSettings(const DarkModeSettings& new_settings); 37 38 // TODO(gilmanmh): Add a role for shadows. In general, we don't want to 39 // invert shadows, but we may need to do some other kind of processing for 40 // them. 41 enum class ElementRole { kText, kListSymbol, kBackground, kSVG }; 42 Color InvertColorIfNeeded(const Color& color, ElementRole element_role); 43 base::Optional<cc::PaintFlags> ApplyToFlagsIfNeeded( 44 const cc::PaintFlags& flags, 45 ElementRole element_role); 46 47 // |image| and |flags| must not be null. 48 void ApplyToImageFlagsIfNeeded(const FloatRect& src_rect, 49 const FloatRect& dest_rect, 50 Image* image, 51 cc::PaintFlags* flags); 52 GetImageFilterForTesting()53 SkColorFilter* GetImageFilterForTesting() { return image_filter_.get(); } 54 55 private: 56 friend class ScopedDarkModeElementRoleOverride; 57 58 DarkModeSettings settings_; 59 60 bool ShouldApplyToColor(const Color& color, ElementRole role); 61 62 std::unique_ptr<DarkModeColorClassifier> text_classifier_; 63 std::unique_ptr<DarkModeColorClassifier> background_classifier_; 64 std::unique_ptr<DarkModeColorFilter> color_filter_; 65 sk_sp<SkColorFilter> image_filter_; 66 base::Optional<ElementRole> role_override_; 67 }; 68 69 // Temporarily override the element role for the scope of this object's 70 // lifetime - for example when drawing symbols that play the role of text. 71 class PLATFORM_EXPORT ScopedDarkModeElementRoleOverride { 72 public: 73 ScopedDarkModeElementRoleOverride(GraphicsContext* graphics_context, 74 DarkModeFilter::ElementRole role); 75 ~ScopedDarkModeElementRoleOverride(); 76 77 private: 78 GraphicsContext* graphics_context_; 79 base::Optional<DarkModeFilter::ElementRole> previous_role_override_; 80 }; 81 82 } // namespace blink 83 84 #endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_DARK_MODE_FILTER_H_ 85