// Copyright 2014 PDFium Authors. All rights reserved.
// 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 "../../../include/fpdfapi/fpdf_render.h"
#include "../../../include/fpdfapi/fpdf_pageobj.h"
#include "../../../include/fxge/fx_ge.h"
#include "../fpdf_page/pageint.h"
#include "render_int.h"
#define SHADING_STEPS 256
static void _DrawAxialShading(CFX_DIBitmap* pBitmap,
                              CFX_AffineMatrix* pObject2Bitmap,
                              CPDF_Dictionary* pDict,
                              CPDF_Function** pFuncs,
                              int nFuncs,
                              CPDF_ColorSpace* pCS,
                              int alpha) {
  ASSERT(pBitmap->GetFormat() == FXDIB_Argb);
  CPDF_Array* pCoords = pDict->GetArray(FX_BSTRC("Coords"));
  if (pCoords == NULL) {
    return;
  }
  FX_FLOAT start_x = pCoords->GetNumber(0);
  FX_FLOAT start_y = pCoords->GetNumber(1);
  FX_FLOAT end_x = pCoords->GetNumber(2);
  FX_FLOAT end_y = pCoords->GetNumber(3);
  FX_FLOAT t_min = 0, t_max = 1.0f;
  CPDF_Array* pArray = pDict->GetArray(FX_BSTRC("Domain"));
  if (pArray) {
    t_min = pArray->GetNumber(0);
    t_max = pArray->GetNumber(1);
  }
  FX_BOOL bStartExtend = FALSE, bEndExtend = FALSE;
  pArray = pDict->GetArray(FX_BSTRC("Extend"));
  if (pArray) {
    bStartExtend = pArray->GetInteger(0);
    bEndExtend = pArray->GetInteger(1);
  }
  int width = pBitmap->GetWidth();
  int height = pBitmap->GetHeight();
  FX_FLOAT x_span = end_x - start_x;
  FX_FLOAT y_span = end_y - start_y;
  FX_FLOAT axis_len_square =
      FXSYS_Mul(x_span, x_span) + FXSYS_Mul(y_span, y_span);
  CFX_AffineMatrix matrix;
  matrix.SetReverse(*pObject2Bitmap);
  int total_results = 0;
  for (int j = 0; j < nFuncs; j++) {
    if (pFuncs[j]) {
      total_results += pFuncs[j]->CountOutputs();
    }
  }
  if (pCS->CountComponents() > total_results) {
    total_results = pCS->CountComponents();
  }
  CFX_FixedBufGrow<FX_FLOAT, 16> result_array(total_results);
  FX_FLOAT* pResults = result_array;
  FXSYS_memset(pResults, 0, total_results * sizeof(FX_FLOAT));
  FX_DWORD rgb_array[SHADING_STEPS];
  for (int i = 0; i < SHADING_STEPS; i++) {
    FX_FLOAT input = (t_max - t_min) * i / SHADING_STEPS + t_min;
    int offset = 0;
    for (int j = 0; j < nFuncs; j++) {
      if (pFuncs[j]) {
        int nresults = 0;
        if (pFuncs[j]->Call(&input, 1, pResults + offset, nresults)) {
          offset += nresults;
        }
      }
    }
    FX_FLOAT R = 0.0f, G = 0.0f, B = 0.0f;
    pCS->GetRGB(pResults, R, G, B);
    rgb_array[i] =
        FXARGB_TODIB(FXARGB_MAKE(alpha, FXSYS_round(R * 255),
                                 FXSYS_round(G * 255), FXSYS_round(B * 255)));
  }
  int pitch = pBitmap->GetPitch();
  for (int row = 0; row < height; row++) {
    FX_DWORD* dib_buf = (FX_DWORD*)(pBitmap->GetBuffer() + row * pitch);
    for (int column = 0; column < width; column++) {
      FX_FLOAT x = (FX_FLOAT)column, y = (FX_FLOAT)row;
      matrix.Transform(x, y);
      FX_FLOAT scale = FXSYS_Div(
          FXSYS_Mul(x - start_x, x_span) + FXSYS_Mul(y - start_y, y_span),
          axis_len_square);
      int index = (int32_t)(scale * (SHADING_STEPS - 1));
      if (index < 0) {
        if (!bStartExtend) {
          continue;
        }
        index = 0;
      } else if (index >= SHADING_STEPS) {
        if (!bEndExtend) {
          continue;
        }
        index = SHADING_STEPS - 1;
      }
      dib_buf[column] = rgb_array[index];
    }
  }
}
static void _DrawRadialShading(CFX_DIBitmap* pBitmap,
                               CFX_AffineMatrix* pObject2Bitmap,
                               CPDF_Dictionary* pDict,
                               CPDF_Function** pFuncs,
                               int nFuncs,
                               CPDF_ColorSpace* pCS,
                               int alpha) {
  ASSERT(pBitmap->GetFormat() == FXDIB_Argb);
  CPDF_Array* pCoords = pDict->GetArray(FX_BSTRC("Coords"));
  if (pCoords == NULL) {
    return;
  }
  FX_FLOAT start_x = pCoords->GetNumber(0);
  FX_FLOAT start_y = pCoords->GetNumber(1);
  FX_FLOAT start_r = pCoords->GetNumber(2);
  FX_FLOAT end_x = pCoords->GetNumber(3);
  FX_FLOAT end_y = pCoords->GetNumber(4);
  FX_FLOAT end_r = pCoords->GetNumber(5);
  CFX_AffineMatrix matrix;
  matrix.SetReverse(*pObject2Bitmap);
  FX_FLOAT t_min = 0, t_max = 1.0f;
  CPDF_Array* pArray = pDict->GetArray(FX_BSTRC("Domain"));
  if (pArray) {
    t_min = pArray->GetNumber(0);
    t_max = pArray->GetNumber(1);
  }
  FX_BOOL bStartExtend = FALSE, bEndExtend = FALSE;
  pArray = pDict->GetArray(FX_BSTRC("Extend"));
  if (pArray) {
    bStartExtend = pArray->GetInteger(0);
    bEndExtend = pArray->GetInteger(1);
  }
  int total_results = 0;
  for (int j = 0; j < nFuncs; j++) {
    if (pFuncs[j]) {
      total_results += pFuncs[j]->CountOutputs();
    }
  }
  if (pCS->CountComponents() > total_results) {
    total_results = pCS->CountComponents();
  }
  CFX_FixedBufGrow<FX_FLOAT, 16> result_array(total_results);
  FX_FLOAT* pResults = result_array;
  FXSYS_memset(pResults, 0, total_results * sizeof(FX_FLOAT));
  FX_DWORD rgb_array[SHADING_STEPS];
  for (int i = 0; i < SHADING_STEPS; i++) {
    FX_FLOAT input = (t_max - t_min) * i / SHADING_STEPS + t_min;
    int offset = 0;
    for (int j = 0; j < nFuncs; j++) {
      if (pFuncs[j]) {
        int nresults;
        if (pFuncs[j]->Call(&input, 1, pResults + offset, nresults)) {
          offset += nresults;
        }
      }
    }
    FX_FLOAT R = 0.0f, G = 0.0f, B = 0.0f;
    pCS->GetRGB(pResults, R, G, B);
    rgb_array[i] =
        FXARGB_TODIB(FXARGB_MAKE(alpha, FXSYS_round(R * 255),
                                 FXSYS_round(G * 255), FXSYS_round(B * 255)));
  }
  FX_FLOAT a = FXSYS_Mul(start_x - end_x, start_x - end_x) +
               FXSYS_Mul(start_y - end_y, start_y - end_y) -
               FXSYS_Mul(start_r - end_r, start_r - end_r);
  int width = pBitmap->GetWidth();
  int height = pBitmap->GetHeight();
  int pitch = pBitmap->GetPitch();
  FX_BOOL bDecreasing = FALSE;
  if (start_r > end_r) {
    int length = (int)FXSYS_sqrt((FXSYS_Mul(start_x - end_x, start_x - end_x) +
                                  FXSYS_Mul(start_y - end_y, start_y - end_y)));
    if (length < start_r - end_r) {
      bDecreasing = TRUE;
    }
  }
  for (int row = 0; row < height; row++) {
    FX_DWORD* dib_buf = (FX_DWORD*)(pBitmap->GetBuffer() + row * pitch);
    for (int column = 0; column < width; column++) {
      FX_FLOAT x = (FX_FLOAT)column, y = (FX_FLOAT)row;
      matrix.Transform(x, y);
      FX_FLOAT b = -2 * (FXSYS_Mul(x - start_x, end_x - start_x) +
                         FXSYS_Mul(y - start_y, end_y - start_y) +
                         FXSYS_Mul(start_r, end_r - start_r));
      FX_FLOAT c = FXSYS_Mul(x - start_x, x - start_x) +
                   FXSYS_Mul(y - start_y, y - start_y) -
                   FXSYS_Mul(start_r, start_r);
      FX_FLOAT s;
      if (a == 0) {
        s = FXSYS_Div(-c, b);
      } else {
        FX_FLOAT b2_4ac = FXSYS_Mul(b, b) - 4 * FXSYS_Mul(a, c);
        if (b2_4ac < 0) {
          continue;
        }
        FX_FLOAT root = FXSYS_sqrt(b2_4ac);
        FX_FLOAT s1, s2;
        if (a > 0) {
          s1 = FXSYS_Div(-b - root, 2 * a);
          s2 = FXSYS_Div(-b + root, 2 * a);
        } else {
          s2 = FXSYS_Div(-b - root, 2 * a);
          s1 = FXSYS_Div(-b + root, 2 * a);
        }
        if (bDecreasing) {
          if (s1 >= 0 || bStartExtend) {
            s = s1;
          } else {
            s = s2;
          }
        } else {
          if (s2 <= 1.0f || bEndExtend) {
            s = s2;
          } else {
            s = s1;
          }
        }
        if ((start_r + s * (end_r - start_r)) < 0) {
          continue;
        }
      }
      int index = (int32_t)(s * (SHADING_STEPS - 1));
      if (index < 0) {
        if (!bStartExtend) {
          continue;
        }
        index = 0;
      }
      if (index >= SHADING_STEPS) {
        if (!bEndExtend) {
          continue;
        }
        index = SHADING_STEPS - 1;
      }
      dib_buf[column] = rgb_array[index];
    }
  }
}
static void _DrawFuncShading(CFX_DIBitmap* pBitmap,
                             CFX_AffineMatrix* pObject2Bitmap,
                             CPDF_Dictionary* pDict,
                             CPDF_Function** pFuncs,
                             int nFuncs,
                             CPDF_ColorSpace* pCS,
                             int alpha) {
  ASSERT(pBitmap->GetFormat() == FXDIB_Argb);
  CPDF_Array* pDomain = pDict->GetArray(FX_BSTRC("Domain"));
  FX_FLOAT xmin = 0, ymin = 0, xmax = 1.0f, ymax = 1.0f;
  if (pDomain) {
    xmin = pDomain->GetNumber(0);
    xmax = pDomain->GetNumber(1);
    ymin = pDomain->GetNumber(2);
    ymax = pDomain->GetNumber(3);
  }
  CFX_AffineMatrix mtDomain2Target = pDict->GetMatrix(FX_BSTRC("Matrix"));
  CFX_AffineMatrix matrix, reverse_matrix;
  matrix.SetReverse(*pObject2Bitmap);
  reverse_matrix.SetReverse(mtDomain2Target);
  matrix.Concat(reverse_matrix);
  int width = pBitmap->GetWidth();
  int height = pBitmap->GetHeight();
  int pitch = pBitmap->GetPitch();
  int total_results = 0;
  for (int j = 0; j < nFuncs; j++) {
    if (pFuncs[j]) {
      total_results += pFuncs[j]->CountOutputs();
    }
  }
  if (pCS->CountComponents() > total_results) {
    total_results = pCS->CountComponents();
  }
  CFX_FixedBufGrow<FX_FLOAT, 16> result_array(total_results);
  FX_FLOAT* pResults = result_array;
  FXSYS_memset(pResults, 0, total_results * sizeof(FX_FLOAT));
  for (int row = 0; row < height; row++) {
    FX_DWORD* dib_buf = (FX_DWORD*)(pBitmap->GetBuffer() + row * pitch);
    for (int column = 0; column < width; column++) {
      FX_FLOAT x = (FX_FLOAT)column, y = (FX_FLOAT)row;
      matrix.Transform(x, y);
      if (x < xmin || x > xmax || y < ymin || y > ymax) {
        continue;
      }
      FX_FLOAT input[2];
      int offset = 0;
      input[0] = x;
      input[1] = y;
      for (int j = 0; j < nFuncs; j++) {
        if (pFuncs[j]) {
          int nresults;
          if (pFuncs[j]->Call(input, 2, pResults + offset, nresults)) {
            offset += nresults;
          }
        }
      }
      FX_FLOAT R = 0.0f, G = 0.0f, B = 0.0f;
      pCS->GetRGB(pResults, R, G, B);
      dib_buf[column] = FXARGB_TODIB(FXARGB_MAKE(
          alpha, (int32_t)(R * 255), (int32_t)(G * 255), (int32_t)(B * 255)));
    }
  }
}
FX_BOOL _GetScanlineIntersect(int y,
                              FX_FLOAT x1,
                              FX_FLOAT y1,
                              FX_FLOAT x2,
                              FX_FLOAT y2,
                              FX_FLOAT& x) {
  if (y1 == y2) {
    return FALSE;
  }
  if (y1 < y2) {
    if (y < y1 || y > y2) {
      return FALSE;
    }
  } else {
    if (y < y2 || y > y1) {
      return FALSE;
    }
  }
  x = x1 + FXSYS_MulDiv(x2 - x1, y - y1, y2 - y1);
  return TRUE;
}
static void _DrawGouraud(CFX_DIBitmap* pBitmap,
                         int alpha,
                         CPDF_MeshVertex triangle[3]) {
  FX_FLOAT min_y = triangle[0].y, max_y = triangle[0].y;
  for (int i = 1; i < 3; i++) {
    if (min_y > triangle[i].y) {
      min_y = triangle[i].y;
    }
    if (max_y < triangle[i].y) {
      max_y = triangle[i].y;
    }
  }
  if (min_y == max_y) {
    return;
  }
  int min_yi = (int)FXSYS_floor(min_y), max_yi = (int)FXSYS_ceil(max_y);
  if (min_yi < 0) {
    min_yi = 0;
  }
  if (max_yi >= pBitmap->GetHeight()) {
    max_yi = pBitmap->GetHeight() - 1;
  }
  for (int y = min_yi; y <= max_yi; y++) {
    int nIntersects = 0;
    FX_FLOAT inter_x[3], r[3], g[3], b[3];
    for (int i = 0; i < 3; i++) {
      CPDF_MeshVertex& vertex1 = triangle[i];
      CPDF_MeshVertex& vertex2 = triangle[(i + 1) % 3];
      FX_BOOL bIntersect = _GetScanlineIntersect(
          y, vertex1.x, vertex1.y, vertex2.x, vertex2.y, inter_x[nIntersects]);
      if (!bIntersect) {
        continue;
      }
      r[nIntersects] =
          vertex1.r + FXSYS_MulDiv(vertex2.r - vertex1.r, y - vertex1.y,
                                   vertex2.y - vertex1.y);
      g[nIntersects] =
          vertex1.g + FXSYS_MulDiv(vertex2.g - vertex1.g, y - vertex1.y,
                                   vertex2.y - vertex1.y);
      b[nIntersects] =
          vertex1.b + FXSYS_MulDiv(vertex2.b - vertex1.b, y - vertex1.y,
                                   vertex2.y - vertex1.y);
      nIntersects++;
    }
    if (nIntersects != 2) {
      continue;
    }
    int min_x, max_x, start_index, end_index;
    if (inter_x[0] < inter_x[1]) {
      min_x = (int)FXSYS_floor(inter_x[0]);
      max_x = (int)FXSYS_ceil(inter_x[1]);
      start_index = 0;
      end_index = 1;
    } else {
      min_x = (int)FXSYS_floor(inter_x[1]);
      max_x = (int)FXSYS_ceil(inter_x[0]);
      start_index = 1;
      end_index = 0;
    }
    int start_x = min_x, end_x = max_x;
    if (start_x < 0) {
      start_x = 0;
    }
    if (end_x > pBitmap->GetWidth()) {
      end_x = pBitmap->GetWidth();
    }
    uint8_t* dib_buf =
        pBitmap->GetBuffer() + y * pBitmap->GetPitch() + start_x * 4;
    FX_FLOAT r_unit = (r[end_index] - r[start_index]) / (max_x - min_x);
    FX_FLOAT g_unit = (g[end_index] - g[start_index]) / (max_x - min_x);
    FX_FLOAT b_unit = (b[end_index] - b[start_index]) / (max_x - min_x);
    FX_FLOAT R = r[start_index] + (start_x - min_x) * r_unit;
    FX_FLOAT G = g[start_index] + (start_x - min_x) * g_unit;
    FX_FLOAT B = b[start_index] + (start_x - min_x) * b_unit;
    for (int x = start_x; x < end_x; x++) {
      R += r_unit;
      G += g_unit;
      B += b_unit;
      FXARGB_SETDIB(dib_buf,
                    FXARGB_MAKE(alpha, (int32_t)(R * 255), (int32_t)(G * 255),
                                (int32_t)(B * 255)));
      dib_buf += 4;
    }
  }
}
static void _DrawFreeGouraudShading(CFX_DIBitmap* pBitmap,
                                    CFX_AffineMatrix* pObject2Bitmap,
                                    CPDF_Stream* pShadingStream,
                                    CPDF_Function** pFuncs,
                                    int nFuncs,
                                    CPDF_ColorSpace* pCS,
                                    int alpha) {
  ASSERT(pBitmap->GetFormat() == FXDIB_Argb);
  if (pShadingStream->GetType() != PDFOBJ_STREAM) {
    return;
  }
  CPDF_MeshStream stream;
  if (!stream.Load(pShadingStream, pFuncs, nFuncs, pCS)) {
    return;
  }
  CPDF_MeshVertex triangle[3];
  FXSYS_memset(triangle, 0, sizeof(triangle));

  while (!stream.m_BitStream.IsEOF()) {
    CPDF_MeshVertex vertex;
    FX_DWORD flag = stream.GetVertex(vertex, pObject2Bitmap);
    if (flag == 0) {
      triangle[0] = vertex;
      for (int j = 1; j < 3; j++) {
        stream.GetVertex(triangle[j], pObject2Bitmap);
      }
    } else {
      if (flag == 1) {
        triangle[0] = triangle[1];
      }
      triangle[1] = triangle[2];
      triangle[2] = vertex;
    }
    _DrawGouraud(pBitmap, alpha, triangle);
  }
}
static void _DrawLatticeGouraudShading(CFX_DIBitmap* pBitmap,
                                       CFX_AffineMatrix* pObject2Bitmap,
                                       CPDF_Stream* pShadingStream,
                                       CPDF_Function** pFuncs,
                                       int nFuncs,
                                       CPDF_ColorSpace* pCS,
                                       int alpha) {
  ASSERT(pBitmap->GetFormat() == FXDIB_Argb);
  if (pShadingStream->GetType() != PDFOBJ_STREAM) {
    return;
  }
  int row_verts = pShadingStream->GetDict()->GetInteger("VerticesPerRow");
  if (row_verts < 2) {
    return;
  }
  CPDF_MeshStream stream;
  if (!stream.Load(pShadingStream, pFuncs, nFuncs, pCS)) {
    return;
  }
  CPDF_MeshVertex* vertex = FX_Alloc2D(CPDF_MeshVertex, row_verts, 2);
  if (!stream.GetVertexRow(vertex, row_verts, pObject2Bitmap)) {
    FX_Free(vertex);
    return;
  }
  int last_index = 0;
  while (1) {
    CPDF_MeshVertex* last_row = vertex + last_index * row_verts;
    CPDF_MeshVertex* this_row = vertex + (1 - last_index) * row_verts;
    if (!stream.GetVertexRow(this_row, row_verts, pObject2Bitmap)) {
      FX_Free(vertex);
      return;
    }
    CPDF_MeshVertex triangle[3];
    for (int i = 1; i < row_verts; i++) {
      triangle[0] = last_row[i];
      triangle[1] = this_row[i - 1];
      triangle[2] = last_row[i - 1];
      _DrawGouraud(pBitmap, alpha, triangle);
      triangle[2] = this_row[i];
      _DrawGouraud(pBitmap, alpha, triangle);
    }
    last_index = 1 - last_index;
  }
  FX_Free(vertex);
}
struct Coon_BezierCoeff {
  float a, b, c, d;
  void FromPoints(float p0, float p1, float p2, float p3) {
    a = -p0 + 3 * p1 - 3 * p2 + p3;
    b = 3 * p0 - 6 * p1 + 3 * p2;
    c = -3 * p0 + 3 * p1;
    d = p0;
  }
  Coon_BezierCoeff first_half() {
    Coon_BezierCoeff result;
    result.a = a / 8;
    result.b = b / 4;
    result.c = c / 2;
    result.d = d;
    return result;
  }
  Coon_BezierCoeff second_half() {
    Coon_BezierCoeff result;
    result.a = a / 8;
    result.b = 3 * a / 8 + b / 4;
    result.c = 3 * a / 8 + b / 2 + c / 2;
    result.d = a / 8 + b / 4 + c / 2 + d;
    return result;
  }
  void GetPoints(float p[4]) {
    p[0] = d;
    p[1] = c / 3 + p[0];
    p[2] = b / 3 - p[0] + 2 * p[1];
    p[3] = a + p[0] - 3 * p[1] + 3 * p[2];
  }
  void GetPointsReverse(float p[4]) {
    p[3] = d;
    p[2] = c / 3 + p[3];
    p[1] = b / 3 - p[3] + 2 * p[2];
    p[0] = a + p[3] - 3 * p[2] + 3 * p[1];
  }
  void BezierInterpol(Coon_BezierCoeff& C1,
                      Coon_BezierCoeff& C2,
                      Coon_BezierCoeff& D1,
                      Coon_BezierCoeff& D2) {
    a = (D1.a + D2.a) / 2;
    b = (D1.b + D2.b) / 2;
    c = (D1.c + D2.c) / 2 - (C1.a / 8 + C1.b / 4 + C1.c / 2) +
        (C2.a / 8 + C2.b / 4) + (-C1.d + D2.d) / 2 - (C2.a + C2.b) / 2;
    d = C1.a / 8 + C1.b / 4 + C1.c / 2 + C1.d;
  }
  float Distance() {
    float dis = a + b + c;
    return dis < 0 ? -dis : dis;
  }
};
struct Coon_Bezier {
  Coon_BezierCoeff x, y;
  void FromPoints(float x0,
                  float y0,
                  float x1,
                  float y1,
                  float x2,
                  float y2,
                  float x3,
                  float y3) {
    x.FromPoints(x0, x1, x2, x3);
    y.FromPoints(y0, y1, y2, y3);
  }
  Coon_Bezier first_half() {
    Coon_Bezier result;
    result.x = x.first_half();
    result.y = y.first_half();
    return result;
  }
  Coon_Bezier second_half() {
    Coon_Bezier result;
    result.x = x.second_half();
    result.y = y.second_half();
    return result;
  }
  void BezierInterpol(Coon_Bezier& C1,
                      Coon_Bezier& C2,
                      Coon_Bezier& D1,
                      Coon_Bezier& D2) {
    x.BezierInterpol(C1.x, C2.x, D1.x, D2.x);
    y.BezierInterpol(C1.y, C2.y, D1.y, D2.y);
  }
  void GetPoints(FX_PATHPOINT* pPoints) {
    float p[4];
    int i;
    x.GetPoints(p);
    for (i = 0; i < 4; i++) {
      pPoints[i].m_PointX = p[i];
    }
    y.GetPoints(p);
    for (i = 0; i < 4; i++) {
      pPoints[i].m_PointY = p[i];
    }
  }
  void GetPointsReverse(FX_PATHPOINT* pPoints) {
    float p[4];
    int i;
    x.GetPointsReverse(p);
    for (i = 0; i < 4; i++) {
      pPoints[i].m_PointX = p[i];
    }
    y.GetPointsReverse(p);
    for (i = 0; i < 4; i++) {
      pPoints[i].m_PointY = p[i];
    }
  }
  float Distance() { return x.Distance() + y.Distance(); }
};
static int _BiInterpol(int c0,
                       int c1,
                       int c2,
                       int c3,
                       int x,
                       int y,
                       int x_scale,
                       int y_scale) {
  int x1 = c0 + (c3 - c0) * x / x_scale;
  int x2 = c1 + (c2 - c1) * x / x_scale;
  return x1 + (x2 - x1) * y / y_scale;
}
struct Coon_Color {
  Coon_Color() { FXSYS_memset(comp, 0, sizeof(int) * 3); }
  int comp[3];
  void BiInterpol(Coon_Color colors[4],
                  int x,
                  int y,
                  int x_scale,
                  int y_scale) {
    for (int i = 0; i < 3; i++)
      comp[i] =
          _BiInterpol(colors[0].comp[i], colors[1].comp[i], colors[2].comp[i],
                      colors[3].comp[i], x, y, x_scale, y_scale);
  }
  int Distance(Coon_Color& o) {
    int max, diff;
    max = FXSYS_abs(comp[0] - o.comp[0]);
    diff = FXSYS_abs(comp[1] - o.comp[1]);
    if (max < diff) {
      max = diff;
    }
    diff = FXSYS_abs(comp[2] - o.comp[2]);
    if (max < diff) {
      max = diff;
    }
    return max;
  }
};
struct CPDF_PatchDrawer {
  Coon_Color patch_colors[4];
  int max_delta;
  CFX_PathData path;
  CFX_RenderDevice* pDevice;
  int fill_mode;
  int alpha;
  void Draw(int x_scale,
            int y_scale,
            int left,
            int bottom,
            Coon_Bezier C1,
            Coon_Bezier C2,
            Coon_Bezier D1,
            Coon_Bezier D2) {
    FX_BOOL bSmall = C1.Distance() < 2 && C2.Distance() < 2 &&
                     D1.Distance() < 2 && D2.Distance() < 2;
    Coon_Color div_colors[4];
    int d_bottom, d_left, d_top, d_right;
    div_colors[0].BiInterpol(patch_colors, left, bottom, x_scale, y_scale);
    if (!bSmall) {
      div_colors[1].BiInterpol(patch_colors, left, bottom + 1, x_scale,
                               y_scale);
      div_colors[2].BiInterpol(patch_colors, left + 1, bottom + 1, x_scale,
                               y_scale);
      div_colors[3].BiInterpol(patch_colors, left + 1, bottom, x_scale,
                               y_scale);
      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]);
    }
#define COONCOLOR_THRESHOLD 4
    if (bSmall ||
        (d_bottom < COONCOLOR_THRESHOLD && d_left < COONCOLOR_THRESHOLD &&
         d_top < COONCOLOR_THRESHOLD && d_right < COONCOLOR_THRESHOLD)) {
      FX_PATHPOINT* pPoints = path.GetPoints();
      C1.GetPoints(pPoints);
      D2.GetPoints(pPoints + 3);
      C2.GetPointsReverse(pPoints + 6);
      D1.GetPointsReverse(pPoints + 9);
      int fillFlags = FXFILL_WINDING | FXFILL_FULLCOVER;
      if (fill_mode & RENDER_NOPATHSMOOTH) {
        fillFlags |= FXFILL_NOPATHSMOOTH;
      }
      pDevice->DrawPath(
          &path, NULL, NULL,
          FXARGB_MAKE(alpha, div_colors[0].comp[0], div_colors[0].comp[1],
                      div_colors[0].comp[2]),
          0, fillFlags);
    } else {
      if (d_bottom < COONCOLOR_THRESHOLD && d_top < COONCOLOR_THRESHOLD) {
        Coon_Bezier m1;
        m1.BezierInterpol(D1, D2, C1, C2);
        y_scale *= 2;
        bottom *= 2;
        Draw(x_scale, y_scale, left, bottom, C1, m1, D1.first_half(),
             D2.first_half());
        Draw(x_scale, y_scale, left, bottom + 1, m1, C2, D1.second_half(),
             D2.second_half());
      } else if (d_left < COONCOLOR_THRESHOLD &&
                 d_right < COONCOLOR_THRESHOLD) {
        Coon_Bezier m2;
        m2.BezierInterpol(C1, C2, D1, D2);
        x_scale *= 2;
        left *= 2;
        Draw(x_scale, y_scale, left, bottom, C1.first_half(), C2.first_half(),
             D1, m2);
        Draw(x_scale, y_scale, left + 1, bottom, C1.second_half(),
             C2.second_half(), m2, D2);
      } else {
        Coon_Bezier m1, m2;
        m1.BezierInterpol(D1, D2, C1, C2);
        m2.BezierInterpol(C1, C2, D1, D2);
        Coon_Bezier m1f = m1.first_half();
        Coon_Bezier m1s = m1.second_half();
        Coon_Bezier m2f = m2.first_half();
        Coon_Bezier m2s = m2.second_half();
        x_scale *= 2;
        y_scale *= 2;
        left *= 2;
        bottom *= 2;
        Draw(x_scale, y_scale, left, bottom, C1.first_half(), m1f,
             D1.first_half(), m2f);
        Draw(x_scale, y_scale, left, bottom + 1, m1f, C2.first_half(),
             D1.second_half(), m2s);
        Draw(x_scale, y_scale, left + 1, bottom, C1.second_half(), m1s, m2f,
             D2.first_half());
        Draw(x_scale, y_scale, left + 1, bottom + 1, m1s, C2.second_half(), m2s,
             D2.second_half());
      }
    }
  }
};

FX_BOOL _CheckCoonTensorPara(const CPDF_MeshStream& stream) {
  FX_BOOL bCoorBits = (stream.m_nCoordBits == 1 || stream.m_nCoordBits == 2 ||
                       stream.m_nCoordBits == 4 || stream.m_nCoordBits == 8 ||
                       stream.m_nCoordBits == 12 || stream.m_nCoordBits == 16 ||
                       stream.m_nCoordBits == 24 || stream.m_nCoordBits == 32);

  FX_BOOL bCompBits = (stream.m_nCompBits == 1 || stream.m_nCompBits == 2 ||
                       stream.m_nCompBits == 4 || stream.m_nCompBits == 8 ||
                       stream.m_nCompBits == 12 || stream.m_nCompBits == 16);

  FX_BOOL bFlagBits = (stream.m_nFlagBits == 2 || stream.m_nFlagBits == 4 ||
                       stream.m_nFlagBits == 8);

  return bCoorBits && bCompBits && bFlagBits;
}

static void _DrawCoonPatchMeshes(FX_BOOL bTensor,
                                 CFX_DIBitmap* pBitmap,
                                 CFX_AffineMatrix* pObject2Bitmap,
                                 CPDF_Stream* pShadingStream,
                                 CPDF_Function** pFuncs,
                                 int nFuncs,
                                 CPDF_ColorSpace* pCS,
                                 int fill_mode,
                                 int alpha) {
  ASSERT(pBitmap->GetFormat() == FXDIB_Argb);
  if (pShadingStream->GetType() != PDFOBJ_STREAM) {
    return;
  }
  CFX_FxgeDevice device;
  device.Attach(pBitmap);
  CPDF_MeshStream stream;
  if (!stream.Load(pShadingStream, pFuncs, nFuncs, pCS)) {
    return;
  }

  if (!_CheckCoonTensorPara(stream)) {
    return;
  }

  CPDF_PatchDrawer patch;
  patch.alpha = alpha;
  patch.pDevice = &device;
  patch.fill_mode = fill_mode;
  patch.path.SetPointCount(13);
  FX_PATHPOINT* pPoints = patch.path.GetPoints();
  pPoints[0].m_Flag = FXPT_MOVETO;
  for (int i = 1; i < 13; i++) {
    pPoints[i].m_Flag = FXPT_BEZIERTO;
  }
  CFX_FloatPoint coords[16];
  for (int i = 0; i < 16; i++) {
    coords[i].Set(0.0f, 0.0f);
  }

  int point_count = bTensor ? 16 : 12;
  while (!stream.m_BitStream.IsEOF()) {
    FX_DWORD flag = stream.GetFlag();
    int iStartPoint = 0, iStartColor = 0, i = 0;
    if (flag) {
      iStartPoint = 4;
      iStartColor = 2;
      CFX_FloatPoint tempCoords[4];
      for (i = 0; i < 4; i++) {
        tempCoords[i] = coords[(flag * 3 + i) % 12];
      }
      FXSYS_memcpy(coords, tempCoords, sizeof(CFX_FloatPoint) * 4);
      Coon_Color tempColors[2];
      tempColors[0] = patch.patch_colors[flag];
      tempColors[1] = patch.patch_colors[(flag + 1) % 4];
      FXSYS_memcpy(patch.patch_colors, tempColors, sizeof(Coon_Color) * 2);
    }
    for (i = iStartPoint; i < point_count; i++) {
      stream.GetCoords(coords[i].x, coords[i].y);
      pObject2Bitmap->Transform(coords[i].x, coords[i].y);
    }
    for (i = iStartColor; i < 4; i++) {
      FX_FLOAT r = 0.0f, g = 0.0f, b = 0.0f;
      stream.GetColor(r, g, b);
      patch.patch_colors[i].comp[0] = (int32_t)(r * 255);
      patch.patch_colors[i].comp[1] = (int32_t)(g * 255);
      patch.patch_colors[i].comp[2] = (int32_t)(b * 255);
    }
    CFX_FloatRect bbox = CFX_FloatRect::GetBBox(coords, point_count);
    if (bbox.right <= 0 || bbox.left >= (FX_FLOAT)pBitmap->GetWidth() ||
        bbox.top <= 0 || bbox.bottom >= (FX_FLOAT)pBitmap->GetHeight()) {
      continue;
    }
    Coon_Bezier C1, C2, D1, D2;
    C1.FromPoints(coords[0].x, coords[0].y, coords[11].x, coords[11].y,
                  coords[10].x, coords[10].y, coords[9].x, coords[9].y);
    C2.FromPoints(coords[3].x, coords[3].y, coords[4].x, coords[4].y,
                  coords[5].x, coords[5].y, coords[6].x, coords[6].y);
    D1.FromPoints(coords[0].x, coords[0].y, coords[1].x, coords[1].y,
                  coords[2].x, coords[2].y, coords[3].x, coords[3].y);
    D2.FromPoints(coords[9].x, coords[9].y, coords[8].x, coords[8].y,
                  coords[7].x, coords[7].y, coords[6].x, coords[6].y);
    patch.Draw(1, 1, 0, 0, C1, C2, D1, D2);
  }
}
void CPDF_RenderStatus::DrawShading(CPDF_ShadingPattern* pPattern,
                                    CFX_AffineMatrix* pMatrix,
                                    FX_RECT& clip_rect,
                                    int alpha,
                                    FX_BOOL bAlphaMode) {
  CPDF_Function** pFuncs = pPattern->m_pFunctions;
  int nFuncs = pPattern->m_nFuncs;
  CPDF_Dictionary* pDict = pPattern->m_pShadingObj->GetDict();
  CPDF_ColorSpace* pColorSpace = pPattern->m_pCS;
  if (pColorSpace == NULL) {
    return;
  }
  FX_ARGB background = 0;
  if (!pPattern->m_bShadingObj &&
      pPattern->m_pShadingObj->GetDict()->KeyExist(FX_BSTRC("Background"))) {
    CPDF_Array* pBackColor =
        pPattern->m_pShadingObj->GetDict()->GetArray(FX_BSTRC("Background"));
    if (pBackColor &&
        pBackColor->GetCount() >= (FX_DWORD)pColorSpace->CountComponents()) {
      CFX_FixedBufGrow<FX_FLOAT, 16> comps(pColorSpace->CountComponents());
      for (int i = 0; i < pColorSpace->CountComponents(); i++) {
        comps[i] = pBackColor->GetNumber(i);
      }
      FX_FLOAT R = 0.0f, G = 0.0f, B = 0.0f;
      pColorSpace->GetRGB(comps, R, G, B);
      background = ArgbEncode(255, (int32_t)(R * 255), (int32_t)(G * 255),
                              (int32_t)(B * 255));
    }
  }
  if (pDict->KeyExist(FX_BSTRC("BBox"))) {
    CFX_FloatRect rect = pDict->GetRect(FX_BSTRC("BBox"));
    rect.Transform(pMatrix);
    clip_rect.Intersect(rect.GetOutterRect());
  }
  CPDF_DeviceBuffer buffer;
  buffer.Initialize(m_pContext, m_pDevice, &clip_rect, m_pCurObj, 150);
  CFX_AffineMatrix FinalMatrix = *pMatrix;
  FinalMatrix.Concat(*buffer.GetMatrix());
  CFX_DIBitmap* pBitmap = buffer.GetBitmap();
  if (pBitmap->GetBuffer() == NULL) {
    return;
  }
  pBitmap->Clear(background);
  int fill_mode = m_Options.m_Flags;
  switch (pPattern->m_ShadingType) {
    case 1:
      _DrawFuncShading(pBitmap, &FinalMatrix, pDict, pFuncs, nFuncs,
                       pColorSpace, alpha);
      break;
    case 2:
      _DrawAxialShading(pBitmap, &FinalMatrix, pDict, pFuncs, nFuncs,
                        pColorSpace, alpha);
      break;
    case 3:
      _DrawRadialShading(pBitmap, &FinalMatrix, pDict, pFuncs, nFuncs,
                         pColorSpace, alpha);
      break;
    case 4: {
      _DrawFreeGouraudShading(pBitmap, &FinalMatrix,
                              (CPDF_Stream*)pPattern->m_pShadingObj, pFuncs,
                              nFuncs, pColorSpace, alpha);
    } break;
    case 5: {
      _DrawLatticeGouraudShading(pBitmap, &FinalMatrix,
                                 (CPDF_Stream*)pPattern->m_pShadingObj, pFuncs,
                                 nFuncs, pColorSpace, alpha);
    } break;
    case 6:
    case 7: {
      _DrawCoonPatchMeshes(pPattern->m_ShadingType - 6, pBitmap, &FinalMatrix,
                           (CPDF_Stream*)pPattern->m_pShadingObj, pFuncs,
                           nFuncs, pColorSpace, fill_mode, alpha);
    } break;
  }
  if (bAlphaMode) {
    pBitmap->LoadChannel(FXDIB_Red, pBitmap, FXDIB_Alpha);
  }
  if (m_Options.m_ColorMode == RENDER_COLOR_GRAY) {
    pBitmap->ConvertColorScale(m_Options.m_ForeColor, m_Options.m_BackColor);
  }
  buffer.OutputToDevice();
}
void CPDF_RenderStatus::DrawShadingPattern(CPDF_ShadingPattern* pattern,
                                           CPDF_PageObject* pPageObj,
                                           const CFX_AffineMatrix* pObj2Device,
                                           FX_BOOL bStroke) {
  if (!pattern->Load()) {
    return;
  }
  m_pDevice->SaveState();
  if (pPageObj->m_Type == PDFPAGE_PATH) {
    if (!SelectClipPath((CPDF_PathObject*)pPageObj, pObj2Device, bStroke)) {
      m_pDevice->RestoreState();
      return;
    }
  } else if (pPageObj->m_Type == PDFPAGE_IMAGE) {
    FX_RECT rect = pPageObj->GetBBox(pObj2Device);
    m_pDevice->SetClip_Rect(&rect);
  } else {
    return;
  }
  FX_RECT rect;
  if (GetObjectClippedRect(pPageObj, pObj2Device, FALSE, rect)) {
    m_pDevice->RestoreState();
    return;
  }
  CFX_AffineMatrix matrix = pattern->m_Pattern2Form;
  matrix.Concat(*pObj2Device);
  GetScaledMatrix(matrix);
  int alpha = pPageObj->m_GeneralState.GetAlpha(bStroke);
  DrawShading(pattern, &matrix, rect, alpha,
              m_Options.m_ColorMode == RENDER_COLOR_ALPHA);
  m_pDevice->RestoreState();
}
FX_BOOL CPDF_RenderStatus::ProcessShading(CPDF_ShadingObject* pShadingObj,
                                          const CFX_AffineMatrix* pObj2Device) {
  FX_RECT rect = pShadingObj->GetBBox(pObj2Device);
  FX_RECT clip_box = m_pDevice->GetClipBox();
  rect.Intersect(clip_box);
  if (rect.IsEmpty()) {
    return TRUE;
  }
  CFX_AffineMatrix matrix = pShadingObj->m_Matrix;
  matrix.Concat(*pObj2Device);
  DrawShading(pShadingObj->m_pShading, &matrix, rect,
              pShadingObj->m_GeneralState.GetAlpha(FALSE),
              m_Options.m_ColorMode == RENDER_COLOR_ALPHA);
  return TRUE;
}
static CFX_DIBitmap* DrawPatternBitmap(CPDF_Document* pDoc,
                                       CPDF_PageRenderCache* pCache,
                                       CPDF_TilingPattern* pPattern,
                                       const CFX_AffineMatrix* pObject2Device,
                                       int width,
                                       int height,
                                       int flags) {
  CFX_DIBitmap* pBitmap = new CFX_DIBitmap;
  if (!pBitmap->Create(width, height,
                       pPattern->m_bColored ? FXDIB_Argb : FXDIB_8bppMask)) {
    delete pBitmap;
    return NULL;
  }
  CFX_FxgeDevice bitmap_device;
  bitmap_device.Attach(pBitmap);
  pBitmap->Clear(0);
  CFX_FloatRect cell_bbox = pPattern->m_BBox;
  pPattern->m_Pattern2Form.TransformRect(cell_bbox);
  pObject2Device->TransformRect(cell_bbox);
  CFX_FloatRect bitmap_rect(0.0f, 0.0f, (FX_FLOAT)width, (FX_FLOAT)height);
  CFX_AffineMatrix mtAdjust;
  mtAdjust.MatchRect(bitmap_rect, cell_bbox);
  CFX_AffineMatrix mtPattern2Bitmap = *pObject2Device;
  mtPattern2Bitmap.Concat(mtAdjust);
  CPDF_RenderOptions options;
  if (!pPattern->m_bColored) {
    options.m_ColorMode = RENDER_COLOR_ALPHA;
  }
  flags |= RENDER_FORCE_HALFTONE;
  options.m_Flags = flags;
  CPDF_RenderContext context;
  context.Create(pDoc, pCache, NULL);
  context.DrawObjectList(&bitmap_device, pPattern->m_pForm, &mtPattern2Bitmap,
                         &options);
  return pBitmap;
}
void CPDF_RenderStatus::DrawTilingPattern(CPDF_TilingPattern* pPattern,
                                          CPDF_PageObject* pPageObj,
                                          const CFX_AffineMatrix* pObj2Device,
                                          FX_BOOL bStroke) {
  if (!pPattern->Load()) {
    return;
  }
  m_pDevice->SaveState();
  if (pPageObj->m_Type == PDFPAGE_PATH) {
    if (!SelectClipPath((CPDF_PathObject*)pPageObj, pObj2Device, bStroke)) {
      m_pDevice->RestoreState();
      return;
    }
  } else if (pPageObj->m_Type == PDFPAGE_IMAGE) {
    FX_RECT rect = pPageObj->GetBBox(pObj2Device);
    m_pDevice->SetClip_Rect(&rect);
  } else {
    return;
  }
  FX_RECT clip_box = m_pDevice->GetClipBox();
  if (clip_box.IsEmpty()) {
    m_pDevice->RestoreState();
    return;
  }
  CFX_Matrix dCTM = m_pDevice->GetCTM();
  FX_FLOAT sa = FXSYS_fabs(dCTM.a);
  FX_FLOAT sd = FXSYS_fabs(dCTM.d);
  clip_box.right = clip_box.left + (int32_t)FXSYS_ceil(clip_box.Width() * sa);
  clip_box.bottom = clip_box.top + (int32_t)FXSYS_ceil(clip_box.Height() * sd);
  CFX_AffineMatrix mtPattern2Device = pPattern->m_Pattern2Form;
  mtPattern2Device.Concat(*pObj2Device);
  GetScaledMatrix(mtPattern2Device);
  FX_BOOL bAligned = FALSE;
  if (pPattern->m_BBox.left == 0 && pPattern->m_BBox.bottom == 0 &&
      pPattern->m_BBox.right == pPattern->m_XStep &&
      pPattern->m_BBox.top == pPattern->m_YStep &&
      (mtPattern2Device.IsScaled() || mtPattern2Device.Is90Rotated())) {
    bAligned = TRUE;
  }
  CFX_FloatRect cell_bbox = pPattern->m_BBox;
  mtPattern2Device.TransformRect(cell_bbox);
  int width = (int)FXSYS_ceil(cell_bbox.Width());
  int height = (int)FXSYS_ceil(cell_bbox.Height());
  if (width == 0) {
    width = 1;
  }
  if (height == 0) {
    height = 1;
  }
  int min_col, max_col, min_row, max_row;
  CFX_AffineMatrix mtDevice2Pattern;
  mtDevice2Pattern.SetReverse(mtPattern2Device);
  CFX_FloatRect clip_box_p(clip_box);
  clip_box_p.Transform(&mtDevice2Pattern);
  min_col = (int)FXSYS_ceil(
      FXSYS_Div(clip_box_p.left - pPattern->m_BBox.right, pPattern->m_XStep));
  max_col = (int)FXSYS_floor(
      FXSYS_Div(clip_box_p.right - pPattern->m_BBox.left, pPattern->m_XStep));
  min_row = (int)FXSYS_ceil(
      FXSYS_Div(clip_box_p.bottom - pPattern->m_BBox.top, pPattern->m_YStep));
  max_row = (int)FXSYS_floor(
      FXSYS_Div(clip_box_p.top - pPattern->m_BBox.bottom, pPattern->m_YStep));
  if (width > clip_box.Width() || height > clip_box.Height() ||
      width * height > clip_box.Width() * clip_box.Height()) {
    CPDF_GraphicStates* pStates = NULL;
    if (!pPattern->m_bColored) {
      pStates = CloneObjStates(pPageObj, bStroke);
    }
    CPDF_Dictionary* pFormResource = NULL;
    if (pPattern->m_pForm->m_pFormDict) {
      pFormResource =
          pPattern->m_pForm->m_pFormDict->GetDict(FX_BSTRC("Resources"));
    }
    for (int col = min_col; col <= max_col; col++)
      for (int row = min_row; row <= max_row; row++) {
        FX_FLOAT orig_x, orig_y;
        orig_x = col * pPattern->m_XStep;
        orig_y = row * pPattern->m_YStep;
        mtPattern2Device.Transform(orig_x, orig_y);
        CFX_AffineMatrix matrix = *pObj2Device;
        matrix.Translate(orig_x - mtPattern2Device.e,
                         orig_y - mtPattern2Device.f);
        m_pDevice->SaveState();
        CPDF_RenderStatus status;
        status.Initialize(m_pContext, m_pDevice, NULL, NULL, this, pStates,
                          &m_Options, pPattern->m_pForm->m_Transparency,
                          m_bDropObjects, pFormResource);
        status.RenderObjectList(pPattern->m_pForm, &matrix);
        m_pDevice->RestoreState();
      }
    m_pDevice->RestoreState();
    delete pStates;
    return;
  }
  if (bAligned) {
    int orig_x = FXSYS_round(mtPattern2Device.e);
    int orig_y = FXSYS_round(mtPattern2Device.f);
    min_col = (clip_box.left - orig_x) / width;
    if (clip_box.left < orig_x) {
      min_col--;
    }
    max_col = (clip_box.right - orig_x) / width;
    if (clip_box.right <= orig_x) {
      max_col--;
    }
    min_row = (clip_box.top - orig_y) / height;
    if (clip_box.top < orig_y) {
      min_row--;
    }
    max_row = (clip_box.bottom - orig_y) / height;
    if (clip_box.bottom <= orig_y) {
      max_row--;
    }
  }
  FX_FLOAT left_offset = cell_bbox.left - mtPattern2Device.e;
  FX_FLOAT top_offset = cell_bbox.bottom - mtPattern2Device.f;
  CFX_DIBitmap* pPatternBitmap = NULL;
  if (width * height < 16) {
    CFX_DIBitmap* pEnlargedBitmap =
        DrawPatternBitmap(m_pContext->m_pDocument, m_pContext->m_pPageCache,
                          pPattern, pObj2Device, 8, 8, m_Options.m_Flags);
    pPatternBitmap = pEnlargedBitmap->StretchTo(width, height);
    delete pEnlargedBitmap;
  } else {
    pPatternBitmap = DrawPatternBitmap(
        m_pContext->m_pDocument, m_pContext->m_pPageCache, pPattern,
        pObj2Device, width, height, m_Options.m_Flags);
  }
  if (pPatternBitmap == NULL) {
    m_pDevice->RestoreState();
    return;
  }
  if (m_Options.m_ColorMode == RENDER_COLOR_GRAY) {
    pPatternBitmap->ConvertColorScale(m_Options.m_ForeColor,
                                      m_Options.m_BackColor);
  }
  FX_ARGB fill_argb = GetFillArgb(pPageObj);
  int clip_width = clip_box.right - clip_box.left;
  int clip_height = clip_box.bottom - clip_box.top;
  CFX_DIBitmap screen;
  if (!screen.Create(clip_width, clip_height, FXDIB_Argb)) {
    return;
  }
  screen.Clear(0);
  FX_DWORD* src_buf = (FX_DWORD*)pPatternBitmap->GetBuffer();
  for (int col = min_col; col <= max_col; col++) {
    for (int row = min_row; row <= max_row; row++) {
      int start_x, start_y;
      if (bAligned) {
        start_x = FXSYS_round(mtPattern2Device.e) + col * width - clip_box.left;
        start_y = FXSYS_round(mtPattern2Device.f) + row * height - clip_box.top;
      } else {
        FX_FLOAT orig_x = col * pPattern->m_XStep;
        FX_FLOAT orig_y = row * pPattern->m_YStep;
        mtPattern2Device.Transform(orig_x, orig_y);
        start_x = FXSYS_round(orig_x + left_offset) - clip_box.left;
        start_y = FXSYS_round(orig_y + top_offset) - clip_box.top;
      }
      if (width == 1 && height == 1) {
        if (start_x < 0 || start_x >= clip_box.Width() || start_y < 0 ||
            start_y >= clip_box.Height()) {
          continue;
        }
        FX_DWORD* dest_buf =
            (FX_DWORD*)(screen.GetBuffer() + screen.GetPitch() * start_y +
                        start_x * 4);
        if (pPattern->m_bColored) {
          *dest_buf = *src_buf;
        } else {
          *dest_buf = (*(uint8_t*)src_buf << 24) | (fill_argb & 0xffffff);
        }
      } else {
        if (pPattern->m_bColored) {
          screen.CompositeBitmap(start_x, start_y, width, height,
                                 pPatternBitmap, 0, 0);
        } else {
          screen.CompositeMask(start_x, start_y, width, height, pPatternBitmap,
                               fill_argb, 0, 0);
        }
      }
    }
  }
  CompositeDIBitmap(&screen, clip_box.left, clip_box.top, 0, 255,
                    FXDIB_BLEND_NORMAL, FALSE);
  m_pDevice->RestoreState();
  delete pPatternBitmap;
}
void CPDF_RenderStatus::DrawPathWithPattern(CPDF_PathObject* pPathObj,
                                            const CFX_AffineMatrix* pObj2Device,
                                            CPDF_Color* pColor,
                                            FX_BOOL bStroke) {
  CPDF_Pattern* pattern = pColor->GetPattern();
  if (pattern == NULL) {
    return;
  }
  if (pattern->m_PatternType == PATTERN_TILING) {
    DrawTilingPattern((CPDF_TilingPattern*)pattern, pPathObj, pObj2Device,
                      bStroke);
  } else {
    DrawShadingPattern((CPDF_ShadingPattern*)pattern, pPathObj, pObj2Device,
                       bStroke);
  }
}
void CPDF_RenderStatus::ProcessPathPattern(CPDF_PathObject* pPathObj,
                                           const CFX_AffineMatrix* pObj2Device,
                                           int& filltype,
                                           FX_BOOL& bStroke) {
  if (filltype) {
    CPDF_Color& FillColor = *pPathObj->m_ColorState.GetFillColor();
    if (FillColor.m_pCS && FillColor.m_pCS->GetFamily() == PDFCS_PATTERN) {
      DrawPathWithPattern(pPathObj, pObj2Device, &FillColor, FALSE);
      filltype = 0;
    }
  }
  if (bStroke) {
    CPDF_Color& StrokeColor = *pPathObj->m_ColorState.GetStrokeColor();
    if (StrokeColor.m_pCS && StrokeColor.m_pCS->GetFamily() == PDFCS_PATTERN) {
      DrawPathWithPattern(pPathObj, pObj2Device, &StrokeColor, TRUE);
      bStroke = FALSE;
    }
  }
}
