// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "pdf/draw_utils.h"

#include <math.h>
#include <stddef.h>
#include <stdint.h>
#include <algorithm>
#include <vector>

#include "base/logging.h"
#include "base/numerics/safe_math.h"

namespace chrome_pdf {

inline uint8_t GetBlue(const uint32_t& pixel) {
  return static_cast<uint8_t>(pixel & 0xFF);
}

inline uint8_t GetGreen(const uint32_t& pixel) {
  return static_cast<uint8_t>((pixel >> 8) & 0xFF);
}

inline uint8_t GetRed(const uint32_t& pixel) {
  return static_cast<uint8_t>((pixel >> 16) & 0xFF);
}

inline uint8_t GetAlpha(const uint32_t& pixel) {
  return static_cast<uint8_t>((pixel >> 24) & 0xFF);
}

inline uint32_t MakePixel(uint8_t red,
                          uint8_t green,
                          uint8_t blue,
                          uint8_t alpha) {
  return (static_cast<uint32_t>(alpha) << 24) |
         (static_cast<uint32_t>(red) << 16) |
         (static_cast<uint32_t>(green) << 8) | static_cast<uint32_t>(blue);
}

inline uint8_t ProcessColor(uint8_t src_color,
                            uint8_t dest_color,
                            uint8_t alpha) {
  uint32_t processed = static_cast<uint32_t>(src_color) * alpha +
                       static_cast<uint32_t>(dest_color) * (0xFF - alpha);
  return static_cast<uint8_t>((processed / 0xFF) & 0xFF);
}

ShadowMatrix::ShadowMatrix(uint32_t depth, double factor, uint32_t background)
    : depth_(depth), factor_(factor), background_(background) {
  DCHECK(depth_ > 0);
  matrix_.resize(depth_ * depth_);

  // pv - is a rounding power factor for smoothing corners.
  // pv = 2.0 will make corners completely round.
  const double pv = 4.0;
  // pow_pv - cache to avoid recalculating pow(x, pv) every time.
  std::vector<double> pow_pv(depth_, 0.0);

  double r = static_cast<double>(depth_);
  double coef = 256.0 / pow(r, factor);

  for (uint32_t y = 0; y < depth_; y++) {
    // Since matrix is symmetrical, we can reduce the number of calculations
    // by mirroring results.
    for (uint32_t x = 0; x <= y; x++) {
      // Fill cache if needed.
      if (pow_pv[x] == 0.0)
        pow_pv[x] = pow(x, pv);
      if (pow_pv[y] == 0.0)
        pow_pv[y] = pow(y, pv);

      // v - is a value for the smoothing function.
      // If x == 0 simplify calculations.
      double v = (x == 0) ? y : pow(pow_pv[x] + pow_pv[y], 1 / pv);

      // Smoothing function.
      // If factor == 1, smoothing will be linear from 0 to the end,
      // if 0 < factor < 1, smoothing will drop faster near 0.
      // if factor > 1, smoothing will drop faster near the end (depth).
      double f = 256.0 - coef * pow(v, factor);

      uint8_t alpha = 0;
      if (f > kOpaqueAlpha)
        alpha = kOpaqueAlpha;
      else if (f < kTransparentAlpha)
        alpha = kTransparentAlpha;
      else
        alpha = static_cast<uint8_t>(f);

      uint8_t red = ProcessColor(0, GetRed(background), alpha);
      uint8_t green = ProcessColor(0, GetGreen(background), alpha);
      uint8_t blue = ProcessColor(0, GetBlue(background), alpha);
      uint32_t pixel = MakePixel(red, green, blue, GetAlpha(background));

      // Mirror matrix.
      matrix_[y * depth_ + x] = pixel;
      matrix_[x * depth_ + y] = pixel;
    }
  }
}

ShadowMatrix::~ShadowMatrix() {}

void PaintShadow(pp::ImageData* image,
                 const pp::Rect& clip_rc,
                 const pp::Rect& shadow_rc,
                 const ShadowMatrix& matrix) {
  pp::Rect draw_rc = shadow_rc.Intersect(clip_rc);
  if (draw_rc.IsEmpty())
    return;

  int32_t depth = static_cast<int32_t>(matrix.depth());
  for (int32_t y = draw_rc.y(); y < draw_rc.bottom(); y++) {
    for (int32_t x = draw_rc.x(); x < draw_rc.right(); x++) {
      int32_t matrix_x = std::max(depth + shadow_rc.x() - x - 1,
                                  depth - shadow_rc.right() + x);
      int32_t matrix_y = std::max(depth + shadow_rc.y() - y - 1,
                                  depth - shadow_rc.bottom() + y);
      uint32_t* pixel = image->GetAddr32(pp::Point(x, y));

      if (matrix_x < 0)
        matrix_x = 0;
      else if (matrix_x >= static_cast<int32_t>(depth))
        matrix_x = depth - 1;

      if (matrix_y < 0)
        matrix_y = 0;
      else if (matrix_y >= static_cast<int32_t>(depth))
        matrix_y = depth - 1;

      *pixel = matrix.GetValue(matrix_x, matrix_y);
    }
  }
}

void DrawShadow(pp::ImageData* image,
                const pp::Rect& shadow_rc,
                const pp::Rect& object_rc,
                const pp::Rect& clip_rc,
                const ShadowMatrix& matrix) {
  if (shadow_rc == object_rc)
    return;  // Nothing to paint.

  // Fill top part.
  pp::Rect rc(shadow_rc.point(),
              pp::Size(shadow_rc.width(), object_rc.y() - shadow_rc.y()));
  PaintShadow(image, rc.Intersect(clip_rc), shadow_rc, matrix);

  // Fill bottom part.
  rc = pp::Rect(shadow_rc.x(), object_rc.bottom(), shadow_rc.width(),
                shadow_rc.bottom() - object_rc.bottom());
  PaintShadow(image, rc.Intersect(clip_rc), shadow_rc, matrix);

  // Fill left part.
  rc = pp::Rect(shadow_rc.x(), object_rc.y(), object_rc.x() - shadow_rc.x(),
                object_rc.height());
  PaintShadow(image, rc.Intersect(clip_rc), shadow_rc, matrix);

  // Fill right part.
  rc = pp::Rect(object_rc.right(), object_rc.y(),
                shadow_rc.right() - object_rc.right(), object_rc.height());
  PaintShadow(image, rc.Intersect(clip_rc), shadow_rc, matrix);
}

}  // namespace chrome_pdf
