linear_gradient.cc 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. // Copyright 2022 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/gfx/geometry/linear_gradient.h"
  5. #include <sstream>
  6. #include "base/check_op.h"
  7. #include "base/containers/adapters.h"
  8. #include "base/strings/string_number_conversions.h"
  9. #include "base/strings/stringprintf.h"
  10. #include "ui/gfx/geometry/angle_conversions.h"
  11. #include "ui/gfx/geometry/point_f.h"
  12. #include "ui/gfx/geometry/transform.h"
  13. namespace gfx {
  14. // static
  15. LinearGradient& LinearGradient::GetEmpty() {
  16. static LinearGradient kEmpty;
  17. return kEmpty;
  18. }
  19. LinearGradient::LinearGradient() = default;
  20. LinearGradient::LinearGradient(int16_t angle) : angle_(angle) {}
  21. LinearGradient::LinearGradient(const LinearGradient& copy) = default;
  22. void LinearGradient::AddStep(float fraction, uint8_t alpha) {
  23. DCHECK_LT(step_count_, kMaxStepSize);
  24. DCHECK_GE(fraction, 0);
  25. DCHECK_LE(fraction, 1);
  26. // make sure the step's fraction is monotonically increasing.
  27. DCHECK(step_count_ ? steps_[step_count_ - 1].fraction < fraction : true)
  28. << base::StringPrintf("prev[%zu]=%f, next[%zu]=%f", step_count_ - 1,
  29. steps_[step_count_ - 1].fraction, step_count_,
  30. fraction);
  31. steps_[step_count_].fraction = fraction;
  32. steps_[step_count_++].alpha = alpha;
  33. }
  34. void LinearGradient::ReverseSteps() {
  35. std::reverse(steps_.begin(), steps_.end());
  36. std::rotate(steps_.begin(), steps_.end() - step_count_, steps_.end());
  37. for (size_t i = 0; i < step_count_; i++)
  38. steps_[i].fraction = 1.f - steps_[i].fraction;
  39. }
  40. void LinearGradient::Transform(const gfx::Transform& transform) {
  41. if (transform.IsIdentity())
  42. return;
  43. gfx::PointF origin, end;
  44. float radian = gfx::DegToRad(static_cast<float>(angle_));
  45. float y = -sin(radian);
  46. float x = cos(radian);
  47. end.Offset(x, y);
  48. transform.TransformPoint(&origin);
  49. transform.TransformPoint(&end);
  50. gfx::Vector2dF diff = end - origin;
  51. float new_angle = gfx::RadToDeg(atan2(diff.y(), diff.x()));
  52. angle_ = -static_cast<int16_t>(std::round(new_angle));
  53. }
  54. std::string LinearGradient::ToString() const {
  55. std::string result = base::StringPrintf(
  56. "LinearGradient{angle=%d, step_count=%zu [", angle_, step_count_);
  57. for (size_t i = 0; i < step_count_; ++i) {
  58. if (i)
  59. result += " - ";
  60. result += base::StringPrintf("%f:%u", steps_[i].fraction, steps_[i].alpha);
  61. }
  62. return result + "]}";
  63. }
  64. } // namespace gfx