// Copyright 2019 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#include "core/fpdfapi/render/cpdf_rendershading.h"

#include <math.h>

#include <algorithm>
#include <array>
#include <memory>
#include <utility>
#include <vector>

#include "core/fpdfapi/page/cpdf_colorspace.h"
#include "core/fpdfapi/page/cpdf_dib.h"
#include "core/fpdfapi/page/cpdf_function.h"
#include "core/fpdfapi/page/cpdf_meshstream.h"
#include "core/fpdfapi/parser/cpdf_array.h"
#include "core/fpdfapi/parser/cpdf_dictionary.h"
#include "core/fpdfapi/parser/cpdf_stream.h"
#include "core/fpdfapi/parser/fpdf_parser_utility.h"
#include "core/fpdfapi/render/cpdf_devicebuffer.h"
#include "core/fpdfapi/render/cpdf_renderoptions.h"
#include "core/fxcrt/check.h"
#include "core/fxcrt/check_op.h"
#include "core/fxcrt/compiler_specific.h"
#include "core/fxcrt/fx_safe_types.h"
#include "core/fxcrt/fx_system.h"
#include "core/fxcrt/numerics/clamped_math.h"
#include "core/fxcrt/span.h"
#include "core/fxcrt/span_util.h"
#include "core/fxcrt/stl_util.h"
#include "core/fxcrt/unowned_ptr.h"
#include "core/fxge/cfx_fillrenderoptions.h"
#include "core/fxge/cfx_path.h"
#include "core/fxge/cfx_renderdevice.h"
#include "core/fxge/dib/cfx_dibitmap.h"
#include "core/fxge/dib/fx_dib.h"

namespace {

constexpr int kShadingSteps = 256;

uint32_t CountOutputsFromFunctions(
    const std::vector<std::unique_ptr<CPDF_Function>>& funcs) {
  FX_SAFE_UINT32 total = 0;
  for (const auto& func : funcs) {
    if (func) {
      total += func->OutputCount();
    }
  }
  return total.ValueOrDefault(0);
}

uint32_t GetValidatedOutputsCount(
    const std::vector<std::unique_ptr<CPDF_Function>>& funcs,
    const RetainPtr<CPDF_ColorSpace>& pCS) {
  uint32_t funcs_outputs = CountOutputsFromFunctions(funcs);
  return funcs_outputs ? std::max(funcs_outputs, pCS->ComponentCount()) : 0;
}

bool GetShadingSteps(float t_min,
                     float t_max,
                     const std::vector<std::unique_ptr<CPDF_Function>>& funcs,
                     const RetainPtr<CPDF_ColorSpace>& pCS,
                     int alpha,
                     std::array<FX_ARGB, kShadingSteps>* output) {
  const uint32_t results_count = GetValidatedOutputsCount(funcs, pCS);
  if (results_count == 0) {
    return false;
  }

  CHECK_GE(results_count, CountOutputsFromFunctions(funcs));
  CHECK_GE(results_count, pCS->ComponentCount());
  std::array<FX_ARGB, kShadingSteps>& shading_steps = *output;
  std::vector<float> result_array(results_count);
  float diff = t_max - t_min;
  for (int i = 0; i < kShadingSteps; ++i) {
    float input = diff * i / kShadingSteps + t_min;
    pdfium::span<float> result_span = pdfium::span(result_array);
    for (const auto& func : funcs) {
      if (!func) {
        continue;
      }
      std::optional<uint32_t> nresults =
          func->Call(pdfium::span_from_ref(input), result_span);
      if (nresults.has_value()) {
        result_span = result_span.subspan(nresults.value());
      }
    }
    auto rgb = pCS->GetRGBOrZerosOnError(result_array);
    shading_steps[i] =
        ArgbEncode(alpha, FXSYS_roundf(rgb.red * 255),
                   FXSYS_roundf(rgb.green * 255), FXSYS_roundf(rgb.blue * 255));
  }
  return true;
}

float ComponentToShadingIndex(float c, float c_min, float c_max) {
  if (c_min == c_max) {
    return 0;
  }
  return ((c - c_min) / (c_max - c_min)) * (kShadingSteps - 1);
}

void DrawAxialShading(const RetainPtr<CFX_DIBitmap>& pBitmap,
                      const CFX_Matrix& mtObject2Bitmap,
                      const CPDF_Dictionary* dict,
                      const std::vector<std::unique_ptr<CPDF_Function>>& funcs,
                      const RetainPtr<CPDF_ColorSpace>& pCS,
                      int alpha) {
  DCHECK_EQ(pBitmap->GetFormat(), FXDIB_Format::kBgra);

  RetainPtr<const CPDF_Array> pCoords = dict->GetArrayFor("Coords");
  if (!pCoords) {
    return;
  }

  float start_x = pCoords->GetFloatAt(0);
  float start_y = pCoords->GetFloatAt(1);
  float end_x = pCoords->GetFloatAt(2);
  float end_y = pCoords->GetFloatAt(3);
  float t_min = 0;
  float t_max = 1.0f;
  RetainPtr<const CPDF_Array> pArray = dict->GetArrayFor("Domain");
  if (pArray) {
    t_min = pArray->GetFloatAt(0);
    t_max = pArray->GetFloatAt(1);
  }
  pArray = dict->GetArrayFor("Extend");
  const bool bStartExtend = pArray && pArray->GetBooleanAt(0, false);
  const bool bEndExtend = pArray && pArray->GetBooleanAt(1, false);

  int width = pBitmap->GetWidth();
  int height = pBitmap->GetHeight();
  float x_span = end_x - start_x;
  float y_span = end_y - start_y;
  float axis_len_square = (x_span * x_span) + (y_span * y_span);

  std::array<FX_ARGB, kShadingSteps> shading_steps;
  if (!GetShadingSteps(t_min, t_max, funcs, pCS, alpha, &shading_steps)) {
    return;
  }

  CFX_Matrix matrix = mtObject2Bitmap.GetInverse();
  for (int row = 0; row < height; row++) {
    auto dest_buf = pBitmap->GetWritableScanlineAs<uint32_t>(row).first(
        static_cast<size_t>(width));
    size_t column_counter = 0;
    for (auto& pix : dest_buf) {
      const float column = static_cast<float>(column_counter++);
      const CFX_PointF pos =
          matrix.Transform(CFX_PointF(column, static_cast<float>(row)));
      float scale =
          (((pos.x - start_x) * x_span) + ((pos.y - start_y) * y_span)) /
          axis_len_square;
      int index = static_cast<int32_t>(scale * (kShadingSteps - 1));
      if (index < 0) {
        if (!bStartExtend) {
          continue;
        }
        index = 0;
      } else if (index >= kShadingSteps) {
        if (!bEndExtend) {
          continue;
        }
        index = kShadingSteps - 1;
      }
      pix = shading_steps[index];
    }
  }
}

void DrawRadialShading(const RetainPtr<CFX_DIBitmap>& pBitmap,
                       const CFX_Matrix& mtObject2Bitmap,
                       const CPDF_Dictionary* dict,
                       const std::vector<std::unique_ptr<CPDF_Function>>& funcs,
                       const RetainPtr<CPDF_ColorSpace>& pCS,
                       int alpha) {
  DCHECK_EQ(pBitmap->GetFormat(), FXDIB_Format::kBgra);

  RetainPtr<const CPDF_Array> pCoords = dict->GetArrayFor("Coords");
  if (!pCoords) {
    return;
  }

  float start_x = pCoords->GetFloatAt(0);
  float start_y = pCoords->GetFloatAt(1);
  float start_r = pCoords->GetFloatAt(2);
  float end_x = pCoords->GetFloatAt(3);
  float end_y = pCoords->GetFloatAt(4);
  float end_r = pCoords->GetFloatAt(5);
  float t_min = 0;
  float t_max = 1.0f;
  RetainPtr<const CPDF_Array> pArray = dict->GetArrayFor("Domain");
  if (pArray) {
    t_min = pArray->GetFloatAt(0);
    t_max = pArray->GetFloatAt(1);
  }
  pArray = dict->GetArrayFor("Extend");
  const bool bStartExtend = pArray && pArray->GetBooleanAt(0, false);
  const bool bEndExtend = pArray && pArray->GetBooleanAt(1, false);

  std::array<FX_ARGB, kShadingSteps> shading_steps;
  if (!GetShadingSteps(t_min, t_max, funcs, pCS, alpha, &shading_steps)) {
    return;
  }

  const float dx = end_x - start_x;
  const float dy = end_y - start_y;
  const float dr = end_r - start_r;
  const float a = dx * dx + dy * dy - dr * dr;
  const bool a_is_float_zero = FXSYS_IsFloatZero(a);

  int width = pBitmap->GetWidth();
  int height = pBitmap->GetHeight();
  bool bDecreasing = dr < 0 && static_cast<int>(hypotf(dx, dy)) < -dr;

  CFX_Matrix matrix = mtObject2Bitmap.GetInverse();
  for (int row = 0; row < height; row++) {
    auto dest_buf = pBitmap->GetWritableScanlineAs<uint32_t>(row).first(
        static_cast<size_t>(width));
    size_t column_counter = 0;
    for (auto& pix : dest_buf) {
      const float column = static_cast<float>(column_counter++);
      const CFX_PointF pos =
          matrix.Transform(CFX_PointF(column, static_cast<float>(row)));
      float pos_dx = pos.x - start_x;
      float pos_dy = pos.y - start_y;
      float b = -2 * (pos_dx * dx + pos_dy * dy + start_r * dr);
      float c = pos_dx * pos_dx + pos_dy * pos_dy - start_r * start_r;
      float s;
      if (FXSYS_IsFloatZero(b)) {
        s = sqrt(-c / a);
      } else if (a_is_float_zero) {
        s = -c / b;
      } else {
        float b2_4ac = (b * b) - 4 * (a * c);
        if (b2_4ac < 0) {
          continue;
        }
        float root = sqrt(b2_4ac);
        float s1 = (-b - root) / (2 * a);
        float s2 = (-b + root) / (2 * a);
        if (a <= 0) {
          std::swap(s1, s2);
        }
        if (bDecreasing) {
          s = (s1 >= 0 || bStartExtend) ? s1 : s2;
        } else {
          s = (s2 <= 1.0f || bEndExtend) ? s2 : s1;
        }
        if (start_r + s * dr < 0) {
          continue;
        }
      }
      int index = static_cast<int32_t>(s * (kShadingSteps - 1));
      if (index < 0) {
        if (!bStartExtend) {
          continue;
        }
        index = 0;
      } else if (index >= kShadingSteps) {
        if (!bEndExtend) {
          continue;
        }
        index = kShadingSteps - 1;
      }
      pix = shading_steps[index];
    }
  }
}

void DrawFuncShading(const RetainPtr<CFX_DIBitmap>& pBitmap,
                     const CFX_Matrix& mtObject2Bitmap,
                     const CPDF_Dictionary* dict,
                     const std::vector<std::unique_ptr<CPDF_Function>>& funcs,
                     const RetainPtr<CPDF_ColorSpace>& pCS,
                     int alpha) {
  DCHECK_EQ(pBitmap->GetFormat(), FXDIB_Format::kBgra);

  const uint32_t total_results = GetValidatedOutputsCount(funcs, pCS);
  if (total_results == 0) {
    return;
  }

  RetainPtr<const CPDF_Array> pDomain = dict->GetArrayFor("Domain");
  float xmin = 0.0f;
  float ymin = 0.0f;
  float xmax = 1.0f;
  float ymax = 1.0f;
  if (pDomain) {
    xmin = pDomain->GetFloatAt(0);
    xmax = pDomain->GetFloatAt(1);
    ymin = pDomain->GetFloatAt(2);
    ymax = pDomain->GetFloatAt(3);
  }
  CFX_Matrix mtDomain2Target = dict->GetMatrixFor("Matrix");
  CFX_Matrix matrix =
      mtObject2Bitmap.GetInverse() * mtDomain2Target.GetInverse();
  int width = pBitmap->GetWidth();
  int height = pBitmap->GetHeight();

  CHECK_GE(total_results, CountOutputsFromFunctions(funcs));
  CHECK_GE(total_results, pCS->ComponentCount());
  std::vector<float> result_array(total_results);
  for (int row = 0; row < height; ++row) {
    auto dib_buf = pBitmap->GetWritableScanlineAs<uint32_t>(row);
    for (int column = 0; column < width; column++) {
      CFX_PointF pos = matrix.Transform(
          CFX_PointF(static_cast<float>(column), static_cast<float>(row)));
      if (pos.x < xmin || pos.x > xmax || pos.y < ymin || pos.y > ymax) {
        continue;
      }

      float input[2] = {pos.x, pos.y};
      pdfium::span<float> result_span = pdfium::span(result_array);
      for (const auto& func : funcs) {
        if (!func) {
          continue;
        }
        std::optional<uint32_t> nresults = func->Call(input, result_span);
        if (nresults.has_value()) {
          result_span = result_span.subspan(nresults.value());
        }
      }
      auto rgb = pCS->GetRGBOrZerosOnError(result_array);
      dib_buf[column] = ArgbEncode(alpha, static_cast<int32_t>(rgb.red * 255),
                                   static_cast<int32_t>(rgb.green * 255),
                                   static_cast<int32_t>(rgb.blue * 255));
    }
  }
}

bool GetScanlineIntersect(int y,
                          const CFX_PointF& first,
                          const CFX_PointF& second,
                          float* x) {
  if (first.y == second.y) {
    return false;
  }

  if (first.y < second.y) {
    if (y < first.y || y > second.y) {
      return false;
    }
  } else if (y < second.y || y > first.y) {
    return false;
  }
  *x = first.x + ((second.x - first.x) * (y - first.y) / (second.y - first.y));
  return true;
}

void DrawGouraud(const RetainPtr<CFX_DIBitmap>& pBitmap,
                 int alpha,
                 pdfium::span<CPDF_MeshVertex, 3> triangle,
                 const std::array<FX_ARGB, kShadingSteps>* shading_steps) {
  float min_y = triangle[0].position.y;
  float max_y = triangle[0].position.y;
  for (int i = 1; i < 3; i++) {
    min_y = std::min(min_y, triangle[i].position.y);
    max_y = std::max(max_y, triangle[i].position.y);
  }
  if (min_y == max_y) {
    return;
  }

  int min_yi = std::max(static_cast<int>(floorf(min_y)), 0);
  int max_yi = static_cast<int>(ceilf(max_y));
  if (max_yi >= pBitmap->GetHeight()) {
    max_yi = pBitmap->GetHeight() - 1;
  }

  for (int y = min_yi; y <= max_yi; y++) {
    int nIntersects = 0;
    std::array<float, 3> inter_x;
    std::array<float, 3> r;
    std::array<float, 3> g;
    std::array<float, 3> b;
    for (int i = 0; i < 3; i++) {
      const CPDF_MeshVertex& vertex1 = triangle[i];
      const CPDF_MeshVertex& vertex2 = triangle[(i + 1) % 3];
      const CFX_PointF& position1 = vertex1.position;
      const CFX_PointF& position2 = vertex2.position;
      bool bIntersect =
          GetScanlineIntersect(y, position1, position2, &inter_x[nIntersects]);
      if (!bIntersect) {
        continue;
      }

      float y_dist = (y - position1.y) / (position2.y - position1.y);
      r[nIntersects] =
          vertex1.rgb.red + ((vertex2.rgb.red - vertex1.rgb.red) * y_dist);
      g[nIntersects] = vertex1.rgb.green +
                       ((vertex2.rgb.green - vertex1.rgb.green) * y_dist);
      b[nIntersects] =
          vertex1.rgb.blue + ((vertex2.rgb.blue - vertex1.rgb.blue) * y_dist);
      nIntersects++;
    }
    if (nIntersects != 2) {
      continue;
    }

    int min_x;
    int max_x;
    int start_index;
    int end_index;
    if (inter_x[0] < inter_x[1]) {
      min_x = static_cast<int>(floorf(inter_x[0]));
      max_x = static_cast<int>(ceilf(inter_x[1]));
      start_index = 0;
      end_index = 1;
    } else {
      min_x = static_cast<int>(floorf(inter_x[1]));
      max_x = static_cast<int>(ceilf(inter_x[0]));
      start_index = 1;
      end_index = 0;
    }

    int start_x = std::clamp(min_x, 0, pBitmap->GetWidth());
    int end_x = std::clamp(max_x, 0, pBitmap->GetWidth());
    const int range_x = pdfium::ClampSub(max_x, min_x);
    float r_unit = (r[end_index] - r[start_index]) / range_x;
    float g_unit = (g[end_index] - g[start_index]) / range_x;
    float b_unit = (b[end_index] - b[start_index]) / range_x;
    const int diff_x = pdfium::ClampSub(start_x, min_x);
    float r_result = r[start_index] + diff_x * r_unit;
    float g_result = g[start_index] + diff_x * g_unit;
    float b_result = b[start_index] + diff_x * b_unit;
    auto dib_span = pBitmap->GetWritableScanlineAs<FX_ARGB>(y).subspan(
        static_cast<size_t>(start_x));

    for (int x = start_x; x < end_x; x++) {
      r_result += r_unit;
      if (shading_steps) {
        int index = static_cast<int32_t>(r_result);
        if (index < 0) {
          index = 0;
        } else if (index >= kShadingSteps) {
          index = kShadingSteps - 1;
        }
        dib_span.front() = (*shading_steps)[index];
      } else {
        g_result += g_unit;
        b_result += b_unit;
        dib_span.front() = ArgbEncode(alpha, static_cast<int>(r_result * 255),
                                      static_cast<int>(g_result * 255),
                                      static_cast<int>(b_result * 255));
      }
      dib_span = dib_span.subspan<1u>();
    }
  }
}

void DrawFreeGouraudShading(
    const RetainPtr<CFX_DIBitmap>& pBitmap,
    const CFX_Matrix& mtObject2Bitmap,
    RetainPtr<const CPDF_Stream> pShadingStream,
    const std::vector<std::unique_ptr<CPDF_Function>>& funcs,
    RetainPtr<CPDF_ColorSpace> pCS,
    int alpha) {
  DCHECK_EQ(pBitmap->GetFormat(), FXDIB_Format::kBgra);

  CPDF_MeshStream stream(kFreeFormGouraudTriangleMeshShading, funcs,
                         std::move(pShadingStream), pCS);
  if (!stream.Load()) {
    return;
  }

  std::array<FX_ARGB, kShadingSteps> shading_steps;
  if (!funcs.empty()) {
    if (!GetShadingSteps(stream.component_min(0), stream.component_max(0),
                         funcs, pCS, alpha, &shading_steps)) {
      return;
    }
  }
  float c0_min = stream.component_min(0);
  float c0_max = stream.component_max(0);

  std::array<CPDF_MeshVertex, 3> triangle;
  while (!stream.IsEOF()) {
    CPDF_MeshVertex vertex;
    uint32_t flag;
    if (!stream.ReadVertex(mtObject2Bitmap, &vertex, &flag)) {
      return;
    }
    if (!funcs.empty()) {
      vertex.rgb.red = ComponentToShadingIndex(vertex.rgb.red, c0_min, c0_max);
    }

    if (flag == 0) {
      triangle[0] = vertex;
      for (int i = 1; i < 3; ++i) {
        uint32_t dummy_flag;
        if (!stream.ReadVertex(mtObject2Bitmap, &triangle[i], &dummy_flag)) {
          return;
        }
        if (!funcs.empty()) {
          triangle[i].rgb.red =
              ComponentToShadingIndex(triangle[i].rgb.red, c0_min, c0_max);
        }
      }
    } else {
      if (flag == 1) {
        triangle[0] = triangle[1];
      }

      triangle[1] = triangle[2];
      triangle[2] = vertex;
    }
    DrawGouraud(pBitmap, alpha, triangle,
                funcs.empty() ? nullptr : &shading_steps);
  }
}

void DrawLatticeGouraudShading(
    const RetainPtr<CFX_DIBitmap>& pBitmap,
    const CFX_Matrix& mtObject2Bitmap,
    RetainPtr<const CPDF_Stream> pShadingStream,
    const std::vector<std::unique_ptr<CPDF_Function>>& funcs,
    RetainPtr<CPDF_ColorSpace> pCS,
    int alpha) {
  DCHECK_EQ(pBitmap->GetFormat(), FXDIB_Format::kBgra);

  int row_verts = pShadingStream->GetDict()->GetIntegerFor("VerticesPerRow");
  if (row_verts < 2) {
    return;
  }

  CPDF_MeshStream stream(kLatticeFormGouraudTriangleMeshShading, funcs,
                         std::move(pShadingStream), pCS);
  if (!stream.Load()) {
    return;
  }

  std::array<FX_ARGB, kShadingSteps> shading_steps;
  if (!funcs.empty()) {
    if (!GetShadingSteps(stream.component_min(0), stream.component_max(0),
                         funcs, pCS, alpha, &shading_steps)) {
      return;
    }
  }
  float c0_min = stream.component_min(0);
  float c0_max = stream.component_max(0);

  std::array<std::vector<CPDF_MeshVertex>, 2> vertices;
  vertices[0] = stream.ReadVertexRow(mtObject2Bitmap, row_verts);
  if (vertices[0].empty()) {
    return;
  }
  for (auto& vertex : vertices[0]) {
    if (!funcs.empty()) {
      vertex.rgb.red = ComponentToShadingIndex(vertex.rgb.red, c0_min, c0_max);
    }
  }

  int last_index = 0;
  while (true) {
    vertices[1 - last_index] = stream.ReadVertexRow(mtObject2Bitmap, row_verts);
    if (vertices[1 - last_index].empty()) {
      return;
    }
    for (auto& vertex : vertices[1 - last_index]) {
      if (!funcs.empty()) {
        vertex.rgb.red =
            ComponentToShadingIndex(vertex.rgb.red, c0_min, c0_max);
      }
    }

    CPDF_MeshVertex triangle[3];
    for (int i = 1; i < row_verts; ++i) {
      triangle[0] = vertices[last_index][i];
      triangle[1] = vertices[1 - last_index][i - 1];
      triangle[2] = vertices[last_index][i - 1];
      DrawGouraud(pBitmap, alpha, triangle,
                  funcs.empty() ? nullptr : &shading_steps);
      triangle[2] = vertices[1 - last_index][i];
      DrawGouraud(pBitmap, alpha, triangle,
                  funcs.empty() ? nullptr : &shading_steps);
    }
    last_index = 1 - last_index;
  }
}

struct CubicBezierPatch {
  static constexpr size_t kBoundaryPathSize = 13u;

  bool IsSmall() const {
    CFX_FloatRect bbox = CFX_FloatRect::GetBBox(
        fxcrt::reinterpret_span<const CFX_PointF>(pdfium::span(points)));
    return bbox.Width() < 2 && bbox.Height() < 2;
  }

  void GetBoundary(pdfium::span<CFX_Path::Point, kBoundaryPathSize> boundary) {
    // Returns a cubic bezier path consisting of the outer control points.
    // Note that patch boundary does not always contain all patch points,
    // but for "small" patches it's reasonably close.
    // TODO(thakis): The outer control points don't always contain all
    // points in the patch, e.g. for a single-color tensor product patch
    // where the "inner" control points (points[1][1], points[2][1],
    // points[1][2], points[2][2]) are far outside the "outer" ones.
    // Make a bezier patch stress test and fix this by continuing to
    // subdivide if the inner points are outside.
    boundary[0].point_ = points[0][0];
    boundary[1].point_ = points[0][1];
    boundary[2].point_ = points[0][2];
    boundary[3].point_ = points[0][3];
    boundary[4].point_ = points[1][3];
    boundary[5].point_ = points[2][3];
    boundary[6].point_ = points[3][3];
    boundary[7].point_ = points[3][2];
    boundary[8].point_ = points[3][1];
    boundary[9].point_ = points[3][0];
    boundary[10].point_ = points[2][0];
    boundary[11].point_ = points[1][0];
    boundary[12].point_ = points[0][0];
  }

  void SubdivideVertical(CubicBezierPatch& top, CubicBezierPatch& bottom) {
    for (int x = 0; x < 4; ++x) {
      std::array<CFX_PointF, 3> level1 = {
          0.5f * (points[x][0] + points[x][1]),
          0.5f * (points[x][1] + points[x][2]),
          0.5f * (points[x][2] + points[x][3]),
      };
      std::array<CFX_PointF, 2> level2 = {
          0.5f * (level1[0] + level1[1]),
          0.5f * (level1[1] + level1[2]),
      };
      CFX_PointF level3 = 0.5f * (level2[0] + level2[1]);

      top.points[x][0] = points[x][0];
      top.points[x][1] = level1[0];
      top.points[x][2] = level2[0];
      top.points[x][3] = level3;

      bottom.points[x][0] = level3;
      bottom.points[x][1] = level2[1];
      bottom.points[x][2] = level1[2];
      bottom.points[x][3] = points[x][3];
    }
  }

  void SubdivideHorizontal(CubicBezierPatch& left, CubicBezierPatch& right) {
    for (int y = 0; y < 4; ++y) {
      std::array<CFX_PointF, 3> level1 = {
          0.5f * (points[0][y] + points[1][y]),
          0.5f * (points[1][y] + points[2][y]),
          0.5f * (points[2][y] + points[3][y]),
      };
      std::array<CFX_PointF, 2> level2 = {
          0.5f * (level1[0] + level1[1]),
          0.5f * (level1[1] + level1[2]),
      };
      CFX_PointF level3 = 0.5f * (level2[0] + level2[1]);

      left.points[0][y] = points[0][y];
      left.points[1][y] = level1[0];
      left.points[2][y] = level2[0];
      left.points[3][y] = level3;

      right.points[0][y] = level3;
      right.points[1][y] = level2[1];
      right.points[2][y] = level1[2];
      right.points[3][y] = points[3][y];
    }
  }

  void Subdivide(CubicBezierPatch& top_left,
                 CubicBezierPatch& bottom_left,
                 CubicBezierPatch& top_right,
                 CubicBezierPatch& bottom_right) {
    CubicBezierPatch top;
    CubicBezierPatch bottom;
    SubdivideVertical(top, bottom);
    top.SubdivideHorizontal(top_left, top_right);
    bottom.SubdivideHorizontal(bottom_left, bottom_right);
  }

  std::array<std::array<CFX_PointF, 4>, 4> points;
};

int Interpolate(int p1, int p2, int delta1, int delta2, bool* overflow) {
  FX_SAFE_INT32 p = p2;
  p -= p1;
  p *= delta1;
  p /= delta2;
  p += p1;
  if (!p.IsValid()) {
    *overflow = true;
  }
  return p.ValueOrDefault(0);
}

int BiInterpolImpl(int c0,
                   int c1,
                   int c2,
                   int c3,
                   int x,
                   int y,
                   int x_scale,
                   int y_scale,
                   bool* overflow) {
  int x1 = Interpolate(c0, c3, x, x_scale, overflow);
  int x2 = Interpolate(c1, c2, x, x_scale, overflow);
  return Interpolate(x1, x2, y, y_scale, overflow);
}

struct CoonColor {
  CoonColor() = default;

  // Returns true if successful, false if overflow detected.
  bool BiInterpol(pdfium::span<CoonColor, 4> colors,
                  int x,
                  int y,
                  int x_scale,
                  int y_scale) {
    bool overflow = false;
    for (int i = 0; i < 3; i++) {
      comp[i] = BiInterpolImpl(colors[0].comp[i], colors[1].comp[i],
                               colors[2].comp[i], colors[3].comp[i], x, y,
                               x_scale, y_scale, &overflow);
    }
    return !overflow;
  }

  int Distance(const CoonColor& o) const {
    return std::max({abs(comp[0] - o.comp[0]), abs(comp[1] - o.comp[1]),
                     abs(comp[2] - o.comp[2])});
  }

  std::array<int, 3> comp = {};
};

struct PatchDrawer {
  static constexpr int kCoonColorThreshold = 4;

  void Draw(int x_scale,
            int y_scale,
            int left,
            int bottom,
            CubicBezierPatch patch,
            const std::array<FX_ARGB, kShadingSteps>* shading_steps) {
    bool bSmall = patch.IsSmall();

    CoonColor div_colors[4];
    int d_bottom = 0;
    int d_left = 0;
    int d_top = 0;
    int d_right = 0;
    if (!div_colors[0].BiInterpol(patch_colors, left, bottom, x_scale,
                                  y_scale)) {
      return;
    }
    if (!bSmall) {
      if (!div_colors[1].BiInterpol(patch_colors, left, bottom + 1, x_scale,
                                    y_scale)) {
        return;
      }
      if (!div_colors[2].BiInterpol(patch_colors, left + 1, bottom + 1, x_scale,
                                    y_scale)) {
        return;
      }
      if (!div_colors[3].BiInterpol(patch_colors, left + 1, bottom, x_scale,
                                    y_scale)) {
        return;
      }
      d_bottom = div_colors[3].Distance(div_colors[0]);
      d_left = div_colors[1].Distance(div_colors[0]);
      d_top = div_colors[1].Distance(div_colors[2]);
      d_right = div_colors[2].Distance(div_colors[3]);
    }

    if (bSmall ||
        (d_bottom < kCoonColorThreshold && d_left < kCoonColorThreshold &&
         d_top < kCoonColorThreshold && d_right < kCoonColorThreshold)) {
      pdfium::span<CFX_Path::Point> points = path.GetPoints();
      patch.GetBoundary(points.first<CubicBezierPatch::kBoundaryPathSize>());
      CFX_FillRenderOptions fill_options(
          CFX_FillRenderOptions::WindingOptions());
      fill_options.full_cover = true;
      if (bNoPathSmooth) {
        fill_options.aliased_path = true;
      }

      FX_ARGB color;
      if (shading_steps) {
        // Statically check that shading_steps->size() is > 0
        // (which it is because it has size kShadingSteps).
        // `shading_steps->size()` directly isn't constexpr.
        static_assert(decltype(*shading_steps){}.size() > 0);
        int index = std::clamp(div_colors[0].comp[0], 0,
                               static_cast<int>(shading_steps->size()) - 1);
        color = (*shading_steps)[index];
      } else {
        color = ArgbEncode(alpha, div_colors[0].comp[0], div_colors[0].comp[1],
                           div_colors[0].comp[2]);
      }
      pDevice->DrawPath(path, nullptr, nullptr, color, 0, fill_options);
    } else {
      if (d_bottom < kCoonColorThreshold && d_top < kCoonColorThreshold) {
        CubicBezierPatch top_patch;
        CubicBezierPatch bottom_patch;
        patch.SubdivideVertical(top_patch, bottom_patch);
        y_scale *= 2;
        bottom *= 2;
        Draw(x_scale, y_scale, left, bottom, top_patch, shading_steps);
        Draw(x_scale, y_scale, left, bottom + 1, bottom_patch, shading_steps);
      } else if (d_left < kCoonColorThreshold &&
                 d_right < kCoonColorThreshold) {
        CubicBezierPatch left_patch;
        CubicBezierPatch right_patch;
        patch.SubdivideHorizontal(left_patch, right_patch);
        x_scale *= 2;
        left *= 2;
        Draw(x_scale, y_scale, left, bottom, left_patch, shading_steps);
        Draw(x_scale, y_scale, left + 1, bottom, right_patch, shading_steps);
      } else {
        CubicBezierPatch top_left;
        CubicBezierPatch bottom_left;
        CubicBezierPatch top_right;
        CubicBezierPatch bottom_right;
        patch.Subdivide(top_left, bottom_left, top_right, bottom_right);
        x_scale *= 2;
        y_scale *= 2;
        left *= 2;
        bottom *= 2;
        Draw(x_scale, y_scale, left, bottom, top_left, shading_steps);
        Draw(x_scale, y_scale, left, bottom + 1, bottom_left, shading_steps);
        Draw(x_scale, y_scale, left + 1, bottom, top_right, shading_steps);
        Draw(x_scale, y_scale, left + 1, bottom + 1, bottom_right,
             shading_steps);
      }
    }
  }

  int max_delta;
  CFX_Path path;
  UnownedPtr<CFX_RenderDevice> pDevice;
  bool bNoPathSmooth;
  int alpha;
  std::array<CoonColor, 4> patch_colors;
};

void DrawCoonPatchMeshes(
    ShadingType type,
    const RetainPtr<CFX_DIBitmap>& pBitmap,
    const CFX_Matrix& mtObject2Bitmap,
    RetainPtr<const CPDF_Stream> pShadingStream,
    const std::vector<std::unique_ptr<CPDF_Function>>& funcs,
    RetainPtr<CPDF_ColorSpace> pCS,
    bool bNoPathSmooth,
    int alpha) {
  DCHECK_EQ(pBitmap->GetFormat(), FXDIB_Format::kBgra);
  DCHECK(type == kCoonsPatchMeshShading ||
         type == kTensorProductPatchMeshShading);

  std::unique_ptr<CFX_RenderDevice> device =
      CFX_RenderDevice::CreateForBitmap(pBitmap);
  if (!device) {
    return;
  }

  CPDF_MeshStream stream(type, funcs, std::move(pShadingStream), pCS);
  if (!stream.Load()) {
    return;
  }

  std::array<FX_ARGB, kShadingSteps> shading_steps;
  if (!funcs.empty()) {
    if (!GetShadingSteps(stream.component_min(0), stream.component_max(0),
                         funcs, pCS, alpha, &shading_steps)) {
      return;
    }
  }
  float c0_min = stream.component_min(0);
  float c0_max = stream.component_max(0);

  PatchDrawer patch_drawer;
  patch_drawer.alpha = alpha;
  patch_drawer.pDevice = device.get();
  patch_drawer.bNoPathSmooth = bNoPathSmooth;

  for (size_t i = 0; i < CubicBezierPatch::kBoundaryPathSize; i++) {
    patch_drawer.path.AppendPoint(
        CFX_PointF(),
        i == 0 ? CFX_Path::Point::Type::kMove : CFX_Path::Point::Type::kBezier);
  }

  std::array<CFX_PointF, 16> coords;
  int point_count = type == kTensorProductPatchMeshShading ? 16 : 12;
  while (!stream.IsEOF()) {
    if (!stream.CanReadFlag()) {
      break;
    }
    uint32_t flag = stream.ReadFlag();
    int iStartPoint = 0;
    int iStartColor = 0;
    int i = 0;
    if (flag) {
      iStartPoint = 4;
      iStartColor = 2;
      std::array<CFX_PointF, 4> tempCoords;
      for (i = 0; i < 4; i++) {
        tempCoords[i] = coords[(flag * 3 + i) % 12];
      }
      fxcrt::Copy(tempCoords, coords);
      std::array<CoonColor, 2> tempColors = {{
          patch_drawer.patch_colors[flag],
          patch_drawer.patch_colors[(flag + 1) % 4],
      }};
      fxcrt::Copy(tempColors, patch_drawer.patch_colors);
    }
    for (i = iStartPoint; i < point_count; i++) {
      if (!stream.CanReadCoords()) {
        break;
      }
      coords[i] = mtObject2Bitmap.Transform(stream.ReadCoords());
    }

    for (i = iStartColor; i < 4; i++) {
      if (!stream.CanReadColor()) {
        break;
      }

      FX_RGB_STRUCT<float> rgb = stream.ReadColor();
      if (funcs.empty()) {
        patch_drawer.patch_colors[i].comp[0] =
            static_cast<int32_t>(rgb.red * 255);
        patch_drawer.patch_colors[i].comp[1] =
            static_cast<int32_t>(rgb.green * 255);
        patch_drawer.patch_colors[i].comp[2] =
            static_cast<int32_t>(rgb.blue * 255);
      } else {
        patch_drawer.patch_colors[i].comp[0] = static_cast<int32_t>(
            ComponentToShadingIndex(rgb.red, c0_min, c0_max));
        patch_drawer.patch_colors[i].comp[1] = 0;
        patch_drawer.patch_colors[i].comp[2] = 0;
      }
    }

    CFX_FloatRect bbox = CFX_FloatRect::GetBBox(
        pdfium::span(coords).first(static_cast<size_t>(point_count)));
    if (bbox.right <= 0 || bbox.left >= (float)pBitmap->GetWidth() ||
        bbox.top <= 0 || bbox.bottom >= (float)pBitmap->GetHeight()) {
      continue;
    }

    CubicBezierPatch patch;
    patch.points[0][0] = coords[0];
    patch.points[0][1] = coords[1];
    patch.points[0][2] = coords[2];
    patch.points[0][3] = coords[3];
    patch.points[1][3] = coords[4];
    patch.points[2][3] = coords[5];
    patch.points[3][3] = coords[6];
    patch.points[3][2] = coords[7];
    patch.points[3][1] = coords[8];
    patch.points[3][0] = coords[9];
    patch.points[2][0] = coords[10];
    patch.points[1][0] = coords[11];
    if (type == kTensorProductPatchMeshShading) {
      patch.points[1][1] = coords[12];
      patch.points[1][2] = coords[13];
      patch.points[2][2] = coords[14];
      patch.points[2][1] = coords[15];
    } else {
      CHECK_EQ(type, kCoonsPatchMeshShading);
      // These equations are from ISO 32000-2:2020, page 267, in
      // 8.7.4.5.8 Type 7 (tensor-product patch mesh) shadings:
      patch.points[1][1] =
          (1.0f / 9.0f) * (-4.0f * patch.points[0][0] +
                           6.0f * (patch.points[0][1] + patch.points[1][0]) -
                           2.0f * (patch.points[0][3] + patch.points[3][0]) +
                           3.0f * (patch.points[3][1] + patch.points[1][3]) -
                           1.0f * patch.points[3][3]);
      patch.points[1][2] =
          (1.0f / 9.0f) * (-4.0f * patch.points[0][3] +
                           6.0f * (patch.points[0][2] + patch.points[1][3]) -
                           2.0f * (patch.points[0][0] + patch.points[3][3]) +
                           3.0f * (patch.points[3][2] + patch.points[1][0]) -
                           1.0f * patch.points[3][0]);
      patch.points[2][1] =
          (1.0f / 9.0f) * (-4.0f * patch.points[3][0] +
                           6.0f * (patch.points[3][1] + patch.points[2][0]) -
                           2.0f * (patch.points[3][3] + patch.points[0][0]) +
                           3.0f * (patch.points[0][1] + patch.points[2][3]) -
                           1.0f * patch.points[0][3]);
      patch.points[2][2] =
          (1.0f / 9.0f) * (-4.0f * patch.points[3][3] +
                           6.0f * (patch.points[3][2] + patch.points[2][3]) -
                           2.0f * (patch.points[3][0] + patch.points[0][3]) +
                           3.0f * (patch.points[0][2] + patch.points[2][0]) -
                           1.0f * patch.points[0][0]);
    }

    patch_drawer.Draw(1, 1, 0, 0, patch,
                      funcs.empty() ? nullptr : &shading_steps);
  }
}

}  // namespace

// static
void CPDF_RenderShading::Draw(CFX_RenderDevice* pDevice,
                              CPDF_RenderContext* context,
                              const CPDF_PageObject* pCurObj,
                              const CPDF_ShadingPattern* pPattern,
                              const CFX_Matrix& mtMatrix,
                              const FX_RECT& clip_rect,
                              int alpha,
                              const CPDF_RenderOptions& options) {
  RetainPtr<CPDF_ColorSpace> pColorSpace = pPattern->GetCS();
  if (!pColorSpace) {
    return;
  }

  FX_ARGB background = 0;
  RetainPtr<const CPDF_Dictionary> dict =
      pPattern->GetShadingObject()->GetDict();
  if (!pPattern->IsShadingObject() && dict->KeyExist("Background")) {
    RetainPtr<const CPDF_Array> pBackColor = dict->GetArrayFor("Background");
    if (pBackColor && pBackColor->size() >= pColorSpace->ComponentCount()) {
      std::vector<float> comps = ReadArrayElementsToVector(
          pBackColor.Get(), pColorSpace->ComponentCount());

      auto rgb = pColorSpace->GetRGBOrZerosOnError(comps);
      background = ArgbEncode(255, static_cast<int32_t>(rgb.red * 255),
                              static_cast<int32_t>(rgb.green * 255),
                              static_cast<int32_t>(rgb.blue * 255));
    }
  }
  FX_RECT clip_rect_bbox = clip_rect;
  if (dict->KeyExist("BBox")) {
    clip_rect_bbox.Intersect(
        mtMatrix.TransformRect(dict->GetRectFor("BBox")).GetOuterRect());
  }
#if defined(PDF_USE_SKIA)
  if (pDevice->RenderCapShading() &&
      pDevice->DrawShading(*pPattern, mtMatrix, clip_rect_bbox, alpha)) {
    return;
  }
#endif  // defined(PDF_USE_SKIA)
  CPDF_DeviceBuffer buffer(context, pDevice, clip_rect_bbox, pCurObj, 150);
  RetainPtr<CFX_DIBitmap> pBitmap = buffer.Initialize();
  if (!pBitmap) {
    return;
  }

  if (background != 0) {
    pBitmap->Clear(background);
  }
  const CFX_Matrix final_matrix = mtMatrix * buffer.GetMatrix();
  const auto& funcs = pPattern->GetFuncs();
  switch (pPattern->GetShadingType()) {
    case kInvalidShading:
    case kMaxShading:
      return;
    case kFunctionBasedShading:
      DrawFuncShading(pBitmap, final_matrix, dict.Get(), funcs, pColorSpace,
                      alpha);
      break;
    case kAxialShading:
      DrawAxialShading(pBitmap, final_matrix, dict.Get(), funcs, pColorSpace,
                       alpha);
      break;
    case kRadialShading:
      DrawRadialShading(pBitmap, final_matrix, dict.Get(), funcs, pColorSpace,
                        alpha);
      break;
    case kFreeFormGouraudTriangleMeshShading: {
      // The shading object can be a stream or a dictionary. We do not handle
      // the case of dictionary at the moment.
      RetainPtr<const CPDF_Stream> pStream =
          ToStream(pPattern->GetShadingObject());
      if (pStream) {
        DrawFreeGouraudShading(pBitmap, final_matrix, std::move(pStream), funcs,
                               pColorSpace, alpha);
      }
      break;
    }
    case kLatticeFormGouraudTriangleMeshShading: {
      // The shading object can be a stream or a dictionary. We do not handle
      // the case of dictionary at the moment.
      RetainPtr<const CPDF_Stream> pStream =
          ToStream(pPattern->GetShadingObject());
      if (pStream) {
        DrawLatticeGouraudShading(pBitmap, final_matrix, std::move(pStream),
                                  funcs, pColorSpace, alpha);
      }
      break;
    }
    case kCoonsPatchMeshShading:
    case kTensorProductPatchMeshShading: {
      // The shading object can be a stream or a dictionary. We do not handle
      // the case of dictionary at the moment.
      RetainPtr<const CPDF_Stream> pStream =
          ToStream(pPattern->GetShadingObject());
      if (pStream) {
        DrawCoonPatchMeshes(pPattern->GetShadingType(), pBitmap, final_matrix,
                            std::move(pStream), funcs, pColorSpace,
                            options.GetOptions().bNoPathSmooth, alpha);
      }
      break;
    }
  }

  if (options.ColorModeIs(CPDF_RenderOptions::kAlpha)) {
    pBitmap->SetRedFromAlpha();
  } else if (options.ColorModeIs(CPDF_RenderOptions::kGray)) {
    pBitmap->ConvertColorScale(/*is_white_on_black=*/false);
  }

  buffer.OutputToDevice();
}
