// 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_memset32(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();
    int Bpp = pBitmap->GetBPP() / 8;
    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 = (FX_INT32)(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_memset32(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, G, B;
        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();
    int Bpp = pBitmap->GetBPP() / 8;
    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 = (FX_INT32)(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 Bpp = pBitmap->GetBPP() / 8;
    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_memset32(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, G, B;
            pCS->GetRGB(pResults, R, G, B);
            dib_buf[column] = FXARGB_TODIB(FXARGB_MAKE(alpha, (FX_INT32)(R * 255), (FX_INT32)(G * 255), (FX_INT32)(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();
        }
        FX_LPBYTE 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, (FX_INT32)(R * 255), (FX_INT32)(G * 255), (FX_INT32)(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_memset32(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_Alloc(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_memset32(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());
            }
        }
    }
};
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;
    }
    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];
    int point_count = bTensor ? 16 : 12;
    while (!stream.m_BitStream.IsEOF()) {
        FX_DWORD flag = stream.GetFlag();
        int iStartPoint = 0, iStartColor = 0, i;
        if (flag) {
            iStartPoint = 4;
            iStartColor = 2;
            CFX_FloatPoint tempCoords[4];
            for (int i = 0; i < 4; i ++) {
                tempCoords[i] = coords[(flag * 3 + i) % 12];
            }
            FXSYS_memcpy32(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_memcpy32(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] = (FX_INT32)(r * 255);
            patch.patch_colors[i].comp[1] = (FX_INT32)(g * 255);
            patch.patch_colors[i].comp[2] = (FX_INT32)(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)
{
    int width = clip_rect.Width();
    int height = clip_rect.Height();
    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, (FX_INT32)(R * 255), (FX_INT32)(G * 255), (FX_INT32)(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);
#ifdef _FPDFAPI_MINI_
    if (m_DitherBits) {
        DitherObjectArea(pShadingObj, pObj2Device);
    }
#endif
    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 = FX_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 + (FX_INT32)FXSYS_ceil(clip_box.Width() * sa);
    clip_box.bottom = clip_box.top + (FX_INT32)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_Level + 1, 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();
        if (pStates) {
            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 = (*(FX_LPBYTE)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)
{
    FX_BOOL bPattern = FALSE;
    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;
            bPattern = TRUE;
        }
    }
    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;
            bPattern = TRUE;
        }
    }
#ifdef _FPDFAPI_MINI_
    if (bPattern && m_DitherBits) {
        DitherObjectArea(pPathObj, pObj2Device);
    }
#endif
}
