Chromium Code Reviews| Index: core/fpdfapi/fpdf_render/fpdf_render_pattern.cpp |
| diff --git a/core/fpdfapi/fpdf_render/fpdf_render_pattern.cpp b/core/fpdfapi/fpdf_render/fpdf_render_pattern.cpp |
| index ef604ec70f55a42969e834e062ad0d069bd356d7..c28d977905abeaeba5f7e358bb6aa08a08b309d6 100644 |
| --- a/core/fpdfapi/fpdf_render/fpdf_render_pattern.cpp |
| +++ b/core/fpdfapi/fpdf_render/fpdf_render_pattern.cpp |
| @@ -6,6 +6,8 @@ |
| #include "core/fpdfapi/fpdf_render/render_int.h" |
| +#include <algorithm> |
| + |
| #include "core/fpdfapi/fpdf_page/cpdf_graphicstates.h" |
| #include "core/fpdfapi/fpdf_page/cpdf_meshstream.h" |
| #include "core/fpdfapi/fpdf_page/cpdf_shadingpattern.h" |
| @@ -21,14 +23,25 @@ |
| #include "core/fpdfapi/fpdf_render/include/cpdf_renderoptions.h" |
| #include "core/fxge/include/fx_ge.h" |
| +namespace { |
| + |
| +uint32_t CountOutputs( |
| + const std::vector<std::unique_ptr<CPDF_Function>>& funcs) { |
| + uint32_t total = 0; |
| + for (const auto& func : funcs) { |
| + if (func) |
| + total += func->CountOutputs(); |
| + } |
| + return total; |
| +} |
| + |
| #define SHADING_STEPS 256 |
| -static void DrawAxialShading(CFX_DIBitmap* pBitmap, |
| - CFX_Matrix* pObject2Bitmap, |
| - CPDF_Dictionary* pDict, |
| - CPDF_Function** pFuncs, |
| - int nFuncs, |
| - CPDF_ColorSpace* pCS, |
| - int alpha) { |
| +void DrawAxialShading(CFX_DIBitmap* pBitmap, |
| + CFX_Matrix* pObject2Bitmap, |
| + CPDF_Dictionary* pDict, |
| + const std::vector<std::unique_ptr<CPDF_Function>>& funcs, |
| + CPDF_ColorSpace* pCS, |
| + int alpha) { |
| ASSERT(pBitmap->GetFormat() == FXDIB_Argb); |
| CPDF_Array* pCoords = pDict->GetArrayBy("Coords"); |
| if (!pCoords) { |
| @@ -57,13 +70,8 @@ static void DrawAxialShading(CFX_DIBitmap* pBitmap, |
| FX_FLOAT axis_len_square = (x_span * x_span) + (y_span * y_span); |
| CFX_Matrix matrix; |
| matrix.SetReverse(*pObject2Bitmap); |
| - uint32_t 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(); |
| + uint32_t total_results = |
| + std::max(CountOutputs(funcs), 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)); |
| @@ -71,12 +79,11 @@ static void DrawAxialShading(CFX_DIBitmap* pBitmap, |
| 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]) { |
| + for (const auto& func : funcs) { |
| + if (func) { |
| int nresults = 0; |
| - if (pFuncs[j]->Call(&input, 1, pResults + offset, nresults)) { |
| + if (func->Call(&input, 1, pResults + offset, nresults)) |
| offset += nresults; |
| - } |
| } |
| } |
| FX_FLOAT R = 0.0f, G = 0.0f, B = 0.0f; |
| @@ -109,13 +116,13 @@ static void DrawAxialShading(CFX_DIBitmap* pBitmap, |
| } |
| } |
| } |
| -static void DrawRadialShading(CFX_DIBitmap* pBitmap, |
| - CFX_Matrix* pObject2Bitmap, |
| - CPDF_Dictionary* pDict, |
| - CPDF_Function** pFuncs, |
| - int nFuncs, |
| - CPDF_ColorSpace* pCS, |
| - int alpha) { |
| + |
| +void DrawRadialShading(CFX_DIBitmap* pBitmap, |
| + CFX_Matrix* pObject2Bitmap, |
| + CPDF_Dictionary* pDict, |
| + const std::vector<std::unique_ptr<CPDF_Function>>& funcs, |
| + CPDF_ColorSpace* pCS, |
| + int alpha) { |
| ASSERT(pBitmap->GetFormat() == FXDIB_Argb); |
| CPDF_Array* pCoords = pDict->GetArrayBy("Coords"); |
| if (!pCoords) { |
| @@ -141,15 +148,8 @@ static void DrawRadialShading(CFX_DIBitmap* pBitmap, |
| bStartExtend = pArray->GetIntegerAt(0); |
| bEndExtend = pArray->GetIntegerAt(1); |
| } |
| - uint32_t 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(); |
| - } |
| + uint32_t total_results = |
| + std::max(CountOutputs(funcs), 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)); |
| @@ -157,12 +157,11 @@ static void DrawRadialShading(CFX_DIBitmap* pBitmap, |
| 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]) { |
| + for (const auto& func : funcs) { |
| + if (func) { |
| int nresults; |
| - if (pFuncs[j]->Call(&input, 1, pResults + offset, nresults)) { |
| + if (func->Call(&input, 1, pResults + offset, nresults)) |
| offset += nresults; |
| - } |
| } |
| } |
| FX_FLOAT R = 0.0f, G = 0.0f, B = 0.0f; |
| @@ -246,13 +245,13 @@ static void DrawRadialShading(CFX_DIBitmap* pBitmap, |
| } |
| } |
| } |
| -static void DrawFuncShading(CFX_DIBitmap* pBitmap, |
| - CFX_Matrix* pObject2Bitmap, |
| - CPDF_Dictionary* pDict, |
| - CPDF_Function** pFuncs, |
| - int nFuncs, |
| - CPDF_ColorSpace* pCS, |
| - int alpha) { |
| + |
| +void DrawFuncShading(CFX_DIBitmap* pBitmap, |
| + CFX_Matrix* pObject2Bitmap, |
| + CPDF_Dictionary* pDict, |
| + const std::vector<std::unique_ptr<CPDF_Function>>& funcs, |
| + CPDF_ColorSpace* pCS, |
| + int alpha) { |
| ASSERT(pBitmap->GetFormat() == FXDIB_Argb); |
| CPDF_Array* pDomain = pDict->GetArrayBy("Domain"); |
| FX_FLOAT xmin = 0, ymin = 0, xmax = 1.0f, ymax = 1.0f; |
| @@ -270,13 +269,8 @@ static void DrawFuncShading(CFX_DIBitmap* pBitmap, |
| int width = pBitmap->GetWidth(); |
| int height = pBitmap->GetHeight(); |
| int pitch = pBitmap->GetPitch(); |
| - uint32_t 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(); |
| + uint32_t total_results = |
| + std::max(CountOutputs(funcs), 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)); |
| @@ -292,12 +286,11 @@ static void DrawFuncShading(CFX_DIBitmap* pBitmap, |
| int offset = 0; |
| input[0] = x; |
| input[1] = y; |
| - for (int j = 0; j < nFuncs; j++) { |
| - if (pFuncs[j]) { |
| + for (const auto& func : funcs) { |
| + if (func) { |
| int nresults; |
| - if (pFuncs[j]->Call(input, 2, pResults + offset, nresults)) { |
| + if (func->Call(input, 2, pResults + offset, nresults)) |
| offset += nresults; |
| - } |
| } |
| } |
| FX_FLOAT R = 0.0f, G = 0.0f, B = 0.0f; |
| @@ -307,30 +300,30 @@ static void DrawFuncShading(CFX_DIBitmap* pBitmap, |
| } |
| } |
| } |
| -FX_BOOL _GetScanlineIntersect(int y, |
| - FX_FLOAT x1, |
| - FX_FLOAT y1, |
| - FX_FLOAT x2, |
| - FX_FLOAT y2, |
| - FX_FLOAT& x) { |
| - if (y1 == y2) { |
| + |
| +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) { |
| + if (y < y1 || y > y2) |
| return FALSE; |
| - } |
| } else { |
| - if (y < y2 || y > y1) { |
| + if (y < y2 || y > y1) |
| return FALSE; |
| - } |
| } |
| - x = x1 + ((x2 - x1) * (y - y1) / (y2 - y1)); |
| + *x = x1 + ((x2 - x1) * (y - y1) / (y2 - y1)); |
| return TRUE; |
| } |
| -static void DrawGouraud(CFX_DIBitmap* pBitmap, |
| - int alpha, |
| - CPDF_MeshVertex triangle[3]) { |
| + |
| +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) { |
| @@ -356,11 +349,10 @@ static void DrawGouraud(CFX_DIBitmap* pBitmap, |
| 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) { |
| + bool bIntersect = GetScanlineIntersect(y, vertex1.x, vertex1.y, vertex2.x, |
| + vertex2.y, &inter_x[nIntersects]); |
| + if (!bIntersect) |
| continue; |
| - } |
| FX_FLOAT y_dist = (y - vertex1.y) / (vertex2.y - vertex1.y); |
| r[nIntersects] = vertex1.r + ((vertex2.r - vertex1.r) * y_dist); |
| @@ -409,23 +401,24 @@ static void DrawGouraud(CFX_DIBitmap* pBitmap, |
| } |
| } |
| } |
| -static void DrawFreeGouraudShading(CFX_DIBitmap* pBitmap, |
| - CFX_Matrix* pObject2Bitmap, |
| - CPDF_Stream* pShadingStream, |
| - CPDF_Function** pFuncs, |
| - int nFuncs, |
| - CPDF_ColorSpace* pCS, |
| - int alpha) { |
| + |
| +void DrawFreeGouraudShading( |
| + CFX_DIBitmap* pBitmap, |
| + CFX_Matrix* pObject2Bitmap, |
| + CPDF_Stream* pShadingStream, |
| + const std::vector<std::unique_ptr<CPDF_Function>>& funcs, |
| + CPDF_ColorSpace* pCS, |
| + int alpha) { |
| ASSERT(pBitmap->GetFormat() == FXDIB_Argb); |
| - CPDF_MeshStream stream; |
| - if (!stream.Load(pShadingStream, pFuncs, nFuncs, pCS)) |
| + CPDF_MeshStream stream(funcs, pCS); |
| + if (!stream.Load(pShadingStream)) |
| return; |
| CPDF_MeshVertex triangle[3]; |
| FXSYS_memset(triangle, 0, sizeof(triangle)); |
| - while (!stream.m_BitStream.IsEOF()) { |
| + while (!stream.BitStream()->IsEOF()) { |
| CPDF_MeshVertex vertex; |
| uint32_t flag = stream.GetVertex(vertex, pObject2Bitmap); |
| if (flag == 0) { |
| @@ -443,36 +436,36 @@ static void DrawFreeGouraudShading(CFX_DIBitmap* pBitmap, |
| DrawGouraud(pBitmap, alpha, triangle); |
| } |
| } |
| -static void DrawLatticeGouraudShading(CFX_DIBitmap* pBitmap, |
| - CFX_Matrix* pObject2Bitmap, |
| - CPDF_Stream* pShadingStream, |
| - CPDF_Function** pFuncs, |
| - int nFuncs, |
| - CPDF_ColorSpace* pCS, |
| - int alpha) { |
| + |
| +void DrawLatticeGouraudShading( |
| + CFX_DIBitmap* pBitmap, |
| + CFX_Matrix* pObject2Bitmap, |
| + CPDF_Stream* pShadingStream, |
| + const std::vector<std::unique_ptr<CPDF_Function>>& funcs, |
| + CPDF_ColorSpace* pCS, |
| + int alpha) { |
| ASSERT(pBitmap->GetFormat() == FXDIB_Argb); |
| int row_verts = pShadingStream->GetDict()->GetIntegerBy("VerticesPerRow"); |
| if (row_verts < 2) |
| return; |
| - CPDF_MeshStream stream; |
| - if (!stream.Load(pShadingStream, pFuncs, nFuncs, pCS)) |
| + CPDF_MeshStream stream(funcs, pCS); |
| + if (!stream.Load(pShadingStream)) |
| return; |
| - CPDF_MeshVertex* vertex = FX_Alloc2D(CPDF_MeshVertex, row_verts, 2); |
| - if (!stream.GetVertexRow(vertex, row_verts, pObject2Bitmap)) { |
| - FX_Free(vertex); |
| + std::unique_ptr<CPDF_MeshVertex, FxFreeDeleter> vertex( |
| + FX_Alloc2D(CPDF_MeshVertex, row_verts, 2)); |
| + if (!stream.GetVertexRow(vertex.get(), row_verts, pObject2Bitmap)) |
| 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); |
| + CPDF_MeshVertex* last_row = vertex.get() + last_index * row_verts; |
| + CPDF_MeshVertex* this_row = vertex.get() + (1 - last_index) * row_verts; |
| + if (!stream.GetVertexRow(this_row, row_verts, pObject2Bitmap)) |
| return; |
| - } |
| + |
| CPDF_MeshVertex triangle[3]; |
| for (int i = 1; i < row_verts; i++) { |
| triangle[0] = last_row[i]; |
| @@ -484,8 +477,8 @@ static void DrawLatticeGouraudShading(CFX_DIBitmap* pBitmap, |
| } |
| 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) { |
| @@ -537,6 +530,7 @@ struct Coon_BezierCoeff { |
| return dis < 0 ? -dis : dis; |
| } |
| }; |
| + |
| struct Coon_Bezier { |
| Coon_BezierCoeff x, y; |
| void FromPoints(float x0, |
| @@ -595,45 +589,43 @@ struct Coon_Bezier { |
| } |
| 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 BiInterpolImpl(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); |
| + 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); |
| + } |
| } |
| + |
| 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; |
| + return std::max({FXSYS_abs(comp[0] - o.comp[0]), |
| + FXSYS_abs(comp[1] - o.comp[1]), |
| + FXSYS_abs(comp[2] - o.comp[2])}); |
| } |
| }; |
| + |
| struct CPDF_PatchDrawer { |
| Coon_Color patch_colors[4]; |
| int max_delta; |
| @@ -732,39 +724,38 @@ struct CPDF_PatchDrawer { |
| } |
| }; |
| -bool _CheckCoonTensorPara(const CPDF_MeshStream& stream) { |
| - 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); |
| +bool CheckCoonTensorPara(const CPDF_MeshStream& stream) { |
| + uint32_t coord = stream.CoordBits(); |
| + bool bCoorBits = (coord == 1 || coord == 2 || coord == 4 || coord == 8 || |
|
Tom Sepez
2016/05/23 19:09:33
nit: bCoordBitsValid
Lei Zhang
2016/05/23 19:26:20
Done.
|
| + coord == 12 || coord == 16 || coord == 24 || coord == 32); |
| - 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); |
| + uint32_t comp = stream.CompBits(); |
| + bool bCompBits = (comp == 1 || comp == 2 || comp == 4 || comp == 8 || |
|
Tom Sepez
2016/05/23 19:09:33
nit: bCompBitsValid
Lei Zhang
2016/05/23 19:26:20
Done.
|
| + comp == 12 || comp == 16); |
| - bool bFlagBits = (stream.m_nFlagBits == 2 || stream.m_nFlagBits == 4 || |
| - stream.m_nFlagBits == 8); |
| + uint32_t flag = stream.FlagBits(); |
| + bool bFlagBits = (flag == 2 || flag == 4 || flag == 8); |
|
Tom Sepez
2016/05/23 19:09:33
nit: bFlagBitsValid
Lei Zhang
2016/05/23 19:26:20
Done.
|
| return bCoorBits && bCompBits && bFlagBits; |
| } |
| -static void DrawCoonPatchMeshes(FX_BOOL bTensor, |
| - CFX_DIBitmap* pBitmap, |
| - CFX_Matrix* pObject2Bitmap, |
| - CPDF_Stream* pShadingStream, |
| - CPDF_Function** pFuncs, |
| - int nFuncs, |
| - CPDF_ColorSpace* pCS, |
| - int fill_mode, |
| - int alpha) { |
| +void DrawCoonPatchMeshes( |
| + FX_BOOL bTensor, |
| + CFX_DIBitmap* pBitmap, |
| + CFX_Matrix* pObject2Bitmap, |
| + CPDF_Stream* pShadingStream, |
| + const std::vector<std::unique_ptr<CPDF_Function>>& funcs, |
| + CPDF_ColorSpace* pCS, |
| + int fill_mode, |
| + int alpha) { |
| ASSERT(pBitmap->GetFormat() == FXDIB_Argb); |
| CFX_FxgeDevice device; |
| device.Attach(pBitmap); |
| - CPDF_MeshStream stream; |
| - if (!stream.Load(pShadingStream, pFuncs, nFuncs, pCS)) |
| + CPDF_MeshStream stream(funcs, pCS); |
| + if (!stream.Load(pShadingStream)) |
| return; |
| - if (!_CheckCoonTensorPara(stream)) |
| + if (!CheckCoonTensorPara(stream)) |
| return; |
| CPDF_PatchDrawer patch; |
| @@ -779,7 +770,7 @@ static void DrawCoonPatchMeshes(FX_BOOL bTensor, |
| } |
| CFX_PointF coords[16]; |
| int point_count = bTensor ? 16 : 12; |
| - while (!stream.m_BitStream.IsEOF()) { |
| + while (!stream.BitStream()->IsEOF()) { |
| uint32_t flag = stream.GetFlag(); |
| int iStartPoint = 0, iStartColor = 0, i = 0; |
| if (flag) { |
| @@ -823,23 +814,60 @@ static void DrawCoonPatchMeshes(FX_BOOL bTensor, |
| patch.Draw(1, 1, 0, 0, C1, C2, D1, D2); |
| } |
| } |
| + |
| +std::unique_ptr<CFX_DIBitmap> DrawPatternBitmap( |
| + CPDF_Document* pDoc, |
| + CPDF_PageRenderCache* pCache, |
| + CPDF_TilingPattern* pPattern, |
| + const CFX_Matrix* pObject2Device, |
| + int width, |
| + int height, |
| + int flags) { |
| + std::unique_ptr<CFX_DIBitmap> pBitmap(new CFX_DIBitmap); |
| + if (!pBitmap->Create(width, height, |
| + pPattern->colored() ? FXDIB_Argb : FXDIB_8bppMask)) { |
| + pBitmap.reset(); |
|
Tom Sepez
2016/05/23 19:09:33
or just return std::unique_ptr<CFX_DIBitmap>() and
Lei Zhang
2016/05/23 19:26:20
Done.
|
| + return pBitmap; |
| + } |
| + CFX_FxgeDevice bitmap_device; |
| + bitmap_device.Attach(pBitmap.get()); |
| + pBitmap->Clear(0); |
| + CFX_FloatRect cell_bbox = pPattern->bbox(); |
| + pPattern->pattern_to_form()->TransformRect(cell_bbox); |
| + pObject2Device->TransformRect(cell_bbox); |
| + CFX_FloatRect bitmap_rect(0.0f, 0.0f, (FX_FLOAT)width, (FX_FLOAT)height); |
| + CFX_Matrix mtAdjust; |
| + mtAdjust.MatchRect(bitmap_rect, cell_bbox); |
| + CFX_Matrix mtPattern2Bitmap = *pObject2Device; |
| + mtPattern2Bitmap.Concat(mtAdjust); |
| + CPDF_RenderOptions options; |
| + if (!pPattern->colored()) |
| + options.m_ColorMode = RENDER_COLOR_ALPHA; |
| + |
| + flags |= RENDER_FORCE_HALFTONE; |
| + options.m_Flags = flags; |
| + CPDF_RenderContext context(pDoc, pCache); |
| + context.AppendLayer(pPattern->form(), &mtPattern2Bitmap); |
| + context.Render(&bitmap_device, &options, nullptr); |
| + return pBitmap; |
| +} |
| + |
| +} // namespace |
| + |
| void CPDF_RenderStatus::DrawShading(CPDF_ShadingPattern* pPattern, |
| CFX_Matrix* 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) { |
| + const auto& funcs = pPattern->GetFuncs(); |
| + CPDF_Dictionary* pDict = pPattern->GetShadingObject()->GetDict(); |
| + CPDF_ColorSpace* pColorSpace = pPattern->GetCS(); |
| + if (!pColorSpace) |
| return; |
| - } |
| + |
| FX_ARGB background = 0; |
| - if (!pPattern->m_bShadingObj && |
| - pPattern->m_pShadingObj->GetDict()->KeyExist("Background")) { |
| - CPDF_Array* pBackColor = |
| - pPattern->m_pShadingObj->GetDict()->GetArrayBy("Background"); |
| + if (!pPattern->IsShadingObject() && pDict->KeyExist("Background")) { |
| + CPDF_Array* pBackColor = pDict->GetArrayBy("Background"); |
| if (pBackColor && |
| pBackColor->GetCount() >= pColorSpace->CountComponents()) { |
| CFX_FixedBufGrow<FX_FLOAT, 16> comps(pColorSpace->CountComponents()); |
| @@ -866,70 +894,68 @@ void CPDF_RenderStatus::DrawShading(CPDF_ShadingPattern* pPattern, |
| CFX_Matrix FinalMatrix = *pMatrix; |
| FinalMatrix.Concat(*buffer.GetMatrix()); |
| CFX_DIBitmap* pBitmap = buffer.GetBitmap(); |
| - if (!pBitmap->GetBuffer()) { |
| + if (!pBitmap->GetBuffer()) |
| return; |
| - } |
| + |
| pBitmap->Clear(background); |
| int fill_mode = m_Options.m_Flags; |
| - switch (pPattern->m_ShadingType) { |
| + switch (pPattern->GetShadingType()) { |
| case kInvalidShading: |
| case kMaxShading: |
| return; |
| case kFunctionBasedShading: |
| - DrawFuncShading(pBitmap, &FinalMatrix, pDict, pFuncs, nFuncs, pColorSpace, |
| - alpha); |
| + DrawFuncShading(pBitmap, &FinalMatrix, pDict, funcs, pColorSpace, alpha); |
| break; |
| case kAxialShading: |
| - DrawAxialShading(pBitmap, &FinalMatrix, pDict, pFuncs, nFuncs, |
| - pColorSpace, alpha); |
| + DrawAxialShading(pBitmap, &FinalMatrix, pDict, funcs, pColorSpace, alpha); |
| break; |
| case kRadialShading: |
| - DrawRadialShading(pBitmap, &FinalMatrix, pDict, pFuncs, nFuncs, |
| - pColorSpace, alpha); |
| + DrawRadialShading(pBitmap, &FinalMatrix, pDict, 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. |
| - if (CPDF_Stream* pStream = ToStream(pPattern->m_pShadingObj)) { |
| - DrawFreeGouraudShading(pBitmap, &FinalMatrix, pStream, pFuncs, nFuncs, |
| + if (CPDF_Stream* pStream = ToStream(pPattern->GetShadingObject())) { |
| + DrawFreeGouraudShading(pBitmap, &FinalMatrix, 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. |
| - if (CPDF_Stream* pStream = ToStream(pPattern->m_pShadingObj)) { |
| - DrawLatticeGouraudShading(pBitmap, &FinalMatrix, pStream, pFuncs, |
| - nFuncs, pColorSpace, alpha); |
| + if (CPDF_Stream* pStream = ToStream(pPattern->GetShadingObject())) { |
| + DrawLatticeGouraudShading(pBitmap, &FinalMatrix, 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. |
| - if (CPDF_Stream* pStream = ToStream(pPattern->m_pShadingObj)) { |
| + if (CPDF_Stream* pStream = ToStream(pPattern->GetShadingObject())) { |
| DrawCoonPatchMeshes( |
| - pPattern->m_ShadingType == kTensorProductPatchMeshShading, pBitmap, |
| - &FinalMatrix, pStream, pFuncs, nFuncs, pColorSpace, fill_mode, |
| + pPattern->GetShadingType() == kTensorProductPatchMeshShading, |
| + pBitmap, &FinalMatrix, pStream, funcs, pColorSpace, fill_mode, |
| alpha); |
| } |
| } break; |
| } |
| - if (bAlphaMode) { |
| + if (bAlphaMode) |
| pBitmap->LoadChannel(FXDIB_Red, pBitmap, FXDIB_Alpha); |
| - } |
| - if (m_Options.m_ColorMode == RENDER_COLOR_GRAY) { |
| + |
| + 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, |
| const CPDF_PageObject* pPageObj, |
| const CFX_Matrix* pObj2Device, |
| FX_BOOL bStroke) { |
| - if (!pattern->Load()) { |
| + if (!pattern->Load()) |
| return; |
| - } |
| + |
| m_pDevice->SaveState(); |
| if (pPageObj->IsPath()) { |
| if (!SelectClipPath(pPageObj->AsPath(), pObj2Device, bStroke)) { |
| @@ -954,56 +980,22 @@ void CPDF_RenderStatus::DrawShadingPattern(CPDF_ShadingPattern* pattern, |
| m_Options.m_ColorMode == RENDER_COLOR_ALPHA); |
| m_pDevice->RestoreState(); |
| } |
| -FX_BOOL CPDF_RenderStatus::ProcessShading(const CPDF_ShadingObject* pShadingObj, |
| - const CFX_Matrix* pObj2Device) { |
| + |
| +void CPDF_RenderStatus::ProcessShading(const CPDF_ShadingObject* pShadingObj, |
| + const CFX_Matrix* pObj2Device) { |
| FX_RECT rect = pShadingObj->GetBBox(pObj2Device); |
| FX_RECT clip_box = m_pDevice->GetClipBox(); |
| rect.Intersect(clip_box); |
| - if (rect.IsEmpty()) { |
| - return TRUE; |
| - } |
| + if (rect.IsEmpty()) |
| + return; |
| + |
| CFX_Matrix 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_Matrix* pObject2Device, |
| - int width, |
| - int height, |
| - int flags) { |
| - CFX_DIBitmap* pBitmap = new CFX_DIBitmap; |
| - if (!pBitmap->Create(width, height, |
| - pPattern->colored() ? FXDIB_Argb : FXDIB_8bppMask)) { |
| - delete pBitmap; |
| - return NULL; |
| - } |
| - CFX_FxgeDevice bitmap_device; |
| - bitmap_device.Attach(pBitmap); |
| - pBitmap->Clear(0); |
| - CFX_FloatRect cell_bbox = pPattern->bbox(); |
| - pPattern->pattern_to_form()->TransformRect(cell_bbox); |
| - pObject2Device->TransformRect(cell_bbox); |
| - CFX_FloatRect bitmap_rect(0.0f, 0.0f, (FX_FLOAT)width, (FX_FLOAT)height); |
| - CFX_Matrix mtAdjust; |
| - mtAdjust.MatchRect(bitmap_rect, cell_bbox); |
| - CFX_Matrix mtPattern2Bitmap = *pObject2Device; |
| - mtPattern2Bitmap.Concat(mtAdjust); |
| - CPDF_RenderOptions options; |
| - if (!pPattern->colored()) |
| - options.m_ColorMode = RENDER_COLOR_ALPHA; |
| - flags |= RENDER_FORCE_HALFTONE; |
| - options.m_Flags = flags; |
| - CPDF_RenderContext context(pDoc, pCache); |
| - context.AppendLayer(pPattern->form(), &mtPattern2Bitmap); |
| - context.Render(&bitmap_device, &options, nullptr); |
| - return pBitmap; |
| -} |
| void CPDF_RenderStatus::DrawTilingPattern(CPDF_TilingPattern* pPattern, |
| const CPDF_PageObject* pPageObj, |
| const CFX_Matrix* pObj2Device, |
| @@ -1120,13 +1112,12 @@ void CPDF_RenderStatus::DrawTilingPattern(CPDF_TilingPattern* pPattern, |
| } |
| FX_FLOAT left_offset = cell_bbox.left - mtPattern2Device.e; |
| FX_FLOAT top_offset = cell_bbox.bottom - mtPattern2Device.f; |
| - CFX_DIBitmap* pPatternBitmap = NULL; |
| + std::unique_ptr<CFX_DIBitmap> pPatternBitmap; |
| if (width * height < 16) { |
| - CFX_DIBitmap* pEnlargedBitmap = |
| + std::unique_ptr<CFX_DIBitmap> pEnlargedBitmap = |
| DrawPatternBitmap(m_pContext->GetDocument(), m_pContext->GetPageCache(), |
| pPattern, pObj2Device, 8, 8, m_Options.m_Flags); |
| - pPatternBitmap = pEnlargedBitmap->StretchTo(width, height); |
| - delete pEnlargedBitmap; |
| + pPatternBitmap.reset(pEnlargedBitmap->StretchTo(width, height)); |
| } else { |
| pPatternBitmap = DrawPatternBitmap( |
| m_pContext->GetDocument(), m_pContext->GetPageCache(), pPattern, |
| @@ -1177,10 +1168,10 @@ void CPDF_RenderStatus::DrawTilingPattern(CPDF_TilingPattern* pPattern, |
| } else { |
| if (pPattern->colored()) { |
| screen.CompositeBitmap(start_x, start_y, width, height, |
| - pPatternBitmap, 0, 0); |
| + pPatternBitmap.get(), 0, 0); |
| } else { |
| - screen.CompositeMask(start_x, start_y, width, height, pPatternBitmap, |
| - fill_argb, 0, 0); |
| + screen.CompositeMask(start_x, start_y, width, height, |
| + pPatternBitmap.get(), fill_argb, 0, 0); |
| } |
| } |
| } |
| @@ -1188,7 +1179,6 @@ void CPDF_RenderStatus::DrawTilingPattern(CPDF_TilingPattern* pPattern, |
| CompositeDIBitmap(&screen, clip_box.left, clip_box.top, 0, 255, |
| FXDIB_BLEND_NORMAL, FALSE); |
| m_pDevice->RestoreState(); |
| - delete pPatternBitmap; |
| } |
| void CPDF_RenderStatus::DrawPathWithPattern(const CPDF_PathObject* pPathObj, |