Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(161)

Side by Side Diff: core/fpdfapi/fpdf_render/fpdf_render_pattern.cpp

Issue 2000973002: Make CPDF_Function::Load() return an unique_ptr. (Closed) Base URL: https://pdfium.googlesource.com/pdfium@master
Patch Set: fix build, nits Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « core/fpdfapi/fpdf_render/fpdf_render_image.cpp ('k') | core/fpdfapi/fpdf_render/render_int.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 PDFium Authors. All rights reserved. 1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6 6
7 #include "core/fpdfapi/fpdf_render/render_int.h" 7 #include "core/fpdfapi/fpdf_render/render_int.h"
8 8
9 #include <algorithm>
10
9 #include "core/fpdfapi/fpdf_page/cpdf_graphicstates.h" 11 #include "core/fpdfapi/fpdf_page/cpdf_graphicstates.h"
10 #include "core/fpdfapi/fpdf_page/cpdf_meshstream.h" 12 #include "core/fpdfapi/fpdf_page/cpdf_meshstream.h"
11 #include "core/fpdfapi/fpdf_page/cpdf_shadingpattern.h" 13 #include "core/fpdfapi/fpdf_page/cpdf_shadingpattern.h"
12 #include "core/fpdfapi/fpdf_page/cpdf_tilingpattern.h" 14 #include "core/fpdfapi/fpdf_page/cpdf_tilingpattern.h"
13 #include "core/fpdfapi/fpdf_page/include/cpdf_form.h" 15 #include "core/fpdfapi/fpdf_page/include/cpdf_form.h"
14 #include "core/fpdfapi/fpdf_page/include/cpdf_pageobject.h" 16 #include "core/fpdfapi/fpdf_page/include/cpdf_pageobject.h"
15 #include "core/fpdfapi/fpdf_page/include/cpdf_pathobject.h" 17 #include "core/fpdfapi/fpdf_page/include/cpdf_pathobject.h"
16 #include "core/fpdfapi/fpdf_page/include/cpdf_shadingobject.h" 18 #include "core/fpdfapi/fpdf_page/include/cpdf_shadingobject.h"
17 #include "core/fpdfapi/fpdf_page/pageint.h" 19 #include "core/fpdfapi/fpdf_page/pageint.h"
18 #include "core/fpdfapi/fpdf_parser/include/cpdf_array.h" 20 #include "core/fpdfapi/fpdf_parser/include/cpdf_array.h"
19 #include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h" 21 #include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h"
20 #include "core/fpdfapi/fpdf_render/include/cpdf_rendercontext.h" 22 #include "core/fpdfapi/fpdf_render/include/cpdf_rendercontext.h"
21 #include "core/fpdfapi/fpdf_render/include/cpdf_renderoptions.h" 23 #include "core/fpdfapi/fpdf_render/include/cpdf_renderoptions.h"
22 #include "core/fxge/include/fx_ge.h" 24 #include "core/fxge/include/fx_ge.h"
23 25
26 namespace {
27
28 uint32_t CountOutputs(
29 const std::vector<std::unique_ptr<CPDF_Function>>& funcs) {
30 uint32_t total = 0;
31 for (const auto& func : funcs) {
32 if (func)
33 total += func->CountOutputs();
34 }
35 return total;
36 }
37
24 #define SHADING_STEPS 256 38 #define SHADING_STEPS 256
25 static void DrawAxialShading(CFX_DIBitmap* pBitmap, 39 void DrawAxialShading(CFX_DIBitmap* pBitmap,
26 CFX_Matrix* pObject2Bitmap, 40 CFX_Matrix* pObject2Bitmap,
27 CPDF_Dictionary* pDict, 41 CPDF_Dictionary* pDict,
28 CPDF_Function** pFuncs, 42 const std::vector<std::unique_ptr<CPDF_Function>>& funcs,
29 int nFuncs, 43 CPDF_ColorSpace* pCS,
30 CPDF_ColorSpace* pCS, 44 int alpha) {
31 int alpha) {
32 ASSERT(pBitmap->GetFormat() == FXDIB_Argb); 45 ASSERT(pBitmap->GetFormat() == FXDIB_Argb);
33 CPDF_Array* pCoords = pDict->GetArrayBy("Coords"); 46 CPDF_Array* pCoords = pDict->GetArrayBy("Coords");
34 if (!pCoords) { 47 if (!pCoords) {
35 return; 48 return;
36 } 49 }
37 FX_FLOAT start_x = pCoords->GetNumberAt(0); 50 FX_FLOAT start_x = pCoords->GetNumberAt(0);
38 FX_FLOAT start_y = pCoords->GetNumberAt(1); 51 FX_FLOAT start_y = pCoords->GetNumberAt(1);
39 FX_FLOAT end_x = pCoords->GetNumberAt(2); 52 FX_FLOAT end_x = pCoords->GetNumberAt(2);
40 FX_FLOAT end_y = pCoords->GetNumberAt(3); 53 FX_FLOAT end_y = pCoords->GetNumberAt(3);
41 FX_FLOAT t_min = 0, t_max = 1.0f; 54 FX_FLOAT t_min = 0, t_max = 1.0f;
42 CPDF_Array* pArray = pDict->GetArrayBy("Domain"); 55 CPDF_Array* pArray = pDict->GetArrayBy("Domain");
43 if (pArray) { 56 if (pArray) {
44 t_min = pArray->GetNumberAt(0); 57 t_min = pArray->GetNumberAt(0);
45 t_max = pArray->GetNumberAt(1); 58 t_max = pArray->GetNumberAt(1);
46 } 59 }
47 FX_BOOL bStartExtend = FALSE, bEndExtend = FALSE; 60 FX_BOOL bStartExtend = FALSE, bEndExtend = FALSE;
48 pArray = pDict->GetArrayBy("Extend"); 61 pArray = pDict->GetArrayBy("Extend");
49 if (pArray) { 62 if (pArray) {
50 bStartExtend = pArray->GetIntegerAt(0); 63 bStartExtend = pArray->GetIntegerAt(0);
51 bEndExtend = pArray->GetIntegerAt(1); 64 bEndExtend = pArray->GetIntegerAt(1);
52 } 65 }
53 int width = pBitmap->GetWidth(); 66 int width = pBitmap->GetWidth();
54 int height = pBitmap->GetHeight(); 67 int height = pBitmap->GetHeight();
55 FX_FLOAT x_span = end_x - start_x; 68 FX_FLOAT x_span = end_x - start_x;
56 FX_FLOAT y_span = end_y - start_y; 69 FX_FLOAT y_span = end_y - start_y;
57 FX_FLOAT axis_len_square = (x_span * x_span) + (y_span * y_span); 70 FX_FLOAT axis_len_square = (x_span * x_span) + (y_span * y_span);
58 CFX_Matrix matrix; 71 CFX_Matrix matrix;
59 matrix.SetReverse(*pObject2Bitmap); 72 matrix.SetReverse(*pObject2Bitmap);
60 uint32_t total_results = 0; 73 uint32_t total_results =
61 for (int j = 0; j < nFuncs; j++) { 74 std::max(CountOutputs(funcs), pCS->CountComponents());
62 if (pFuncs[j])
63 total_results += pFuncs[j]->CountOutputs();
64 }
65 if (pCS->CountComponents() > total_results)
66 total_results = pCS->CountComponents();
67 CFX_FixedBufGrow<FX_FLOAT, 16> result_array(total_results); 75 CFX_FixedBufGrow<FX_FLOAT, 16> result_array(total_results);
68 FX_FLOAT* pResults = result_array; 76 FX_FLOAT* pResults = result_array;
69 FXSYS_memset(pResults, 0, total_results * sizeof(FX_FLOAT)); 77 FXSYS_memset(pResults, 0, total_results * sizeof(FX_FLOAT));
70 uint32_t rgb_array[SHADING_STEPS]; 78 uint32_t rgb_array[SHADING_STEPS];
71 for (int i = 0; i < SHADING_STEPS; i++) { 79 for (int i = 0; i < SHADING_STEPS; i++) {
72 FX_FLOAT input = (t_max - t_min) * i / SHADING_STEPS + t_min; 80 FX_FLOAT input = (t_max - t_min) * i / SHADING_STEPS + t_min;
73 int offset = 0; 81 int offset = 0;
74 for (int j = 0; j < nFuncs; j++) { 82 for (const auto& func : funcs) {
75 if (pFuncs[j]) { 83 if (func) {
76 int nresults = 0; 84 int nresults = 0;
77 if (pFuncs[j]->Call(&input, 1, pResults + offset, nresults)) { 85 if (func->Call(&input, 1, pResults + offset, nresults))
78 offset += nresults; 86 offset += nresults;
79 }
80 } 87 }
81 } 88 }
82 FX_FLOAT R = 0.0f, G = 0.0f, B = 0.0f; 89 FX_FLOAT R = 0.0f, G = 0.0f, B = 0.0f;
83 pCS->GetRGB(pResults, R, G, B); 90 pCS->GetRGB(pResults, R, G, B);
84 rgb_array[i] = 91 rgb_array[i] =
85 FXARGB_TODIB(FXARGB_MAKE(alpha, FXSYS_round(R * 255), 92 FXARGB_TODIB(FXARGB_MAKE(alpha, FXSYS_round(R * 255),
86 FXSYS_round(G * 255), FXSYS_round(B * 255))); 93 FXSYS_round(G * 255), FXSYS_round(B * 255)));
87 } 94 }
88 int pitch = pBitmap->GetPitch(); 95 int pitch = pBitmap->GetPitch();
89 for (int row = 0; row < height; row++) { 96 for (int row = 0; row < height; row++) {
(...skipping 12 matching lines...) Expand all
102 } else if (index >= SHADING_STEPS) { 109 } else if (index >= SHADING_STEPS) {
103 if (!bEndExtend) { 110 if (!bEndExtend) {
104 continue; 111 continue;
105 } 112 }
106 index = SHADING_STEPS - 1; 113 index = SHADING_STEPS - 1;
107 } 114 }
108 dib_buf[column] = rgb_array[index]; 115 dib_buf[column] = rgb_array[index];
109 } 116 }
110 } 117 }
111 } 118 }
112 static void DrawRadialShading(CFX_DIBitmap* pBitmap, 119
113 CFX_Matrix* pObject2Bitmap, 120 void DrawRadialShading(CFX_DIBitmap* pBitmap,
114 CPDF_Dictionary* pDict, 121 CFX_Matrix* pObject2Bitmap,
115 CPDF_Function** pFuncs, 122 CPDF_Dictionary* pDict,
116 int nFuncs, 123 const std::vector<std::unique_ptr<CPDF_Function>>& funcs,
117 CPDF_ColorSpace* pCS, 124 CPDF_ColorSpace* pCS,
118 int alpha) { 125 int alpha) {
119 ASSERT(pBitmap->GetFormat() == FXDIB_Argb); 126 ASSERT(pBitmap->GetFormat() == FXDIB_Argb);
120 CPDF_Array* pCoords = pDict->GetArrayBy("Coords"); 127 CPDF_Array* pCoords = pDict->GetArrayBy("Coords");
121 if (!pCoords) { 128 if (!pCoords) {
122 return; 129 return;
123 } 130 }
124 FX_FLOAT start_x = pCoords->GetNumberAt(0); 131 FX_FLOAT start_x = pCoords->GetNumberAt(0);
125 FX_FLOAT start_y = pCoords->GetNumberAt(1); 132 FX_FLOAT start_y = pCoords->GetNumberAt(1);
126 FX_FLOAT start_r = pCoords->GetNumberAt(2); 133 FX_FLOAT start_r = pCoords->GetNumberAt(2);
127 FX_FLOAT end_x = pCoords->GetNumberAt(3); 134 FX_FLOAT end_x = pCoords->GetNumberAt(3);
128 FX_FLOAT end_y = pCoords->GetNumberAt(4); 135 FX_FLOAT end_y = pCoords->GetNumberAt(4);
129 FX_FLOAT end_r = pCoords->GetNumberAt(5); 136 FX_FLOAT end_r = pCoords->GetNumberAt(5);
130 CFX_Matrix matrix; 137 CFX_Matrix matrix;
131 matrix.SetReverse(*pObject2Bitmap); 138 matrix.SetReverse(*pObject2Bitmap);
132 FX_FLOAT t_min = 0, t_max = 1.0f; 139 FX_FLOAT t_min = 0, t_max = 1.0f;
133 CPDF_Array* pArray = pDict->GetArrayBy("Domain"); 140 CPDF_Array* pArray = pDict->GetArrayBy("Domain");
134 if (pArray) { 141 if (pArray) {
135 t_min = pArray->GetNumberAt(0); 142 t_min = pArray->GetNumberAt(0);
136 t_max = pArray->GetNumberAt(1); 143 t_max = pArray->GetNumberAt(1);
137 } 144 }
138 FX_BOOL bStartExtend = FALSE, bEndExtend = FALSE; 145 FX_BOOL bStartExtend = FALSE, bEndExtend = FALSE;
139 pArray = pDict->GetArrayBy("Extend"); 146 pArray = pDict->GetArrayBy("Extend");
140 if (pArray) { 147 if (pArray) {
141 bStartExtend = pArray->GetIntegerAt(0); 148 bStartExtend = pArray->GetIntegerAt(0);
142 bEndExtend = pArray->GetIntegerAt(1); 149 bEndExtend = pArray->GetIntegerAt(1);
143 } 150 }
144 uint32_t total_results = 0; 151 uint32_t total_results =
145 for (int j = 0; j < nFuncs; j++) { 152 std::max(CountOutputs(funcs), pCS->CountComponents());
146 if (pFuncs[j]) {
147 total_results += pFuncs[j]->CountOutputs();
148 }
149 }
150 if (pCS->CountComponents() > total_results) {
151 total_results = pCS->CountComponents();
152 }
153 CFX_FixedBufGrow<FX_FLOAT, 16> result_array(total_results); 153 CFX_FixedBufGrow<FX_FLOAT, 16> result_array(total_results);
154 FX_FLOAT* pResults = result_array; 154 FX_FLOAT* pResults = result_array;
155 FXSYS_memset(pResults, 0, total_results * sizeof(FX_FLOAT)); 155 FXSYS_memset(pResults, 0, total_results * sizeof(FX_FLOAT));
156 uint32_t rgb_array[SHADING_STEPS]; 156 uint32_t rgb_array[SHADING_STEPS];
157 for (int i = 0; i < SHADING_STEPS; i++) { 157 for (int i = 0; i < SHADING_STEPS; i++) {
158 FX_FLOAT input = (t_max - t_min) * i / SHADING_STEPS + t_min; 158 FX_FLOAT input = (t_max - t_min) * i / SHADING_STEPS + t_min;
159 int offset = 0; 159 int offset = 0;
160 for (int j = 0; j < nFuncs; j++) { 160 for (const auto& func : funcs) {
161 if (pFuncs[j]) { 161 if (func) {
162 int nresults; 162 int nresults;
163 if (pFuncs[j]->Call(&input, 1, pResults + offset, nresults)) { 163 if (func->Call(&input, 1, pResults + offset, nresults))
164 offset += nresults; 164 offset += nresults;
165 }
166 } 165 }
167 } 166 }
168 FX_FLOAT R = 0.0f, G = 0.0f, B = 0.0f; 167 FX_FLOAT R = 0.0f, G = 0.0f, B = 0.0f;
169 pCS->GetRGB(pResults, R, G, B); 168 pCS->GetRGB(pResults, R, G, B);
170 rgb_array[i] = 169 rgb_array[i] =
171 FXARGB_TODIB(FXARGB_MAKE(alpha, FXSYS_round(R * 255), 170 FXARGB_TODIB(FXARGB_MAKE(alpha, FXSYS_round(R * 255),
172 FXSYS_round(G * 255), FXSYS_round(B * 255))); 171 FXSYS_round(G * 255), FXSYS_round(B * 255)));
173 } 172 }
174 FX_FLOAT a = ((start_x - end_x) * (start_x - end_x)) + 173 FX_FLOAT a = ((start_x - end_x) * (start_x - end_x)) +
175 ((start_y - end_y) * (start_y - end_y)) - 174 ((start_y - end_y) * (start_y - end_y)) -
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 if (index >= SHADING_STEPS) { 238 if (index >= SHADING_STEPS) {
240 if (!bEndExtend) { 239 if (!bEndExtend) {
241 continue; 240 continue;
242 } 241 }
243 index = SHADING_STEPS - 1; 242 index = SHADING_STEPS - 1;
244 } 243 }
245 dib_buf[column] = rgb_array[index]; 244 dib_buf[column] = rgb_array[index];
246 } 245 }
247 } 246 }
248 } 247 }
249 static void DrawFuncShading(CFX_DIBitmap* pBitmap, 248
250 CFX_Matrix* pObject2Bitmap, 249 void DrawFuncShading(CFX_DIBitmap* pBitmap,
251 CPDF_Dictionary* pDict, 250 CFX_Matrix* pObject2Bitmap,
252 CPDF_Function** pFuncs, 251 CPDF_Dictionary* pDict,
253 int nFuncs, 252 const std::vector<std::unique_ptr<CPDF_Function>>& funcs,
254 CPDF_ColorSpace* pCS, 253 CPDF_ColorSpace* pCS,
255 int alpha) { 254 int alpha) {
256 ASSERT(pBitmap->GetFormat() == FXDIB_Argb); 255 ASSERT(pBitmap->GetFormat() == FXDIB_Argb);
257 CPDF_Array* pDomain = pDict->GetArrayBy("Domain"); 256 CPDF_Array* pDomain = pDict->GetArrayBy("Domain");
258 FX_FLOAT xmin = 0, ymin = 0, xmax = 1.0f, ymax = 1.0f; 257 FX_FLOAT xmin = 0, ymin = 0, xmax = 1.0f, ymax = 1.0f;
259 if (pDomain) { 258 if (pDomain) {
260 xmin = pDomain->GetNumberAt(0); 259 xmin = pDomain->GetNumberAt(0);
261 xmax = pDomain->GetNumberAt(1); 260 xmax = pDomain->GetNumberAt(1);
262 ymin = pDomain->GetNumberAt(2); 261 ymin = pDomain->GetNumberAt(2);
263 ymax = pDomain->GetNumberAt(3); 262 ymax = pDomain->GetNumberAt(3);
264 } 263 }
265 CFX_Matrix mtDomain2Target = pDict->GetMatrixBy("Matrix"); 264 CFX_Matrix mtDomain2Target = pDict->GetMatrixBy("Matrix");
266 CFX_Matrix matrix, reverse_matrix; 265 CFX_Matrix matrix, reverse_matrix;
267 matrix.SetReverse(*pObject2Bitmap); 266 matrix.SetReverse(*pObject2Bitmap);
268 reverse_matrix.SetReverse(mtDomain2Target); 267 reverse_matrix.SetReverse(mtDomain2Target);
269 matrix.Concat(reverse_matrix); 268 matrix.Concat(reverse_matrix);
270 int width = pBitmap->GetWidth(); 269 int width = pBitmap->GetWidth();
271 int height = pBitmap->GetHeight(); 270 int height = pBitmap->GetHeight();
272 int pitch = pBitmap->GetPitch(); 271 int pitch = pBitmap->GetPitch();
273 uint32_t total_results = 0; 272 uint32_t total_results =
274 for (int j = 0; j < nFuncs; j++) { 273 std::max(CountOutputs(funcs), pCS->CountComponents());
275 if (pFuncs[j])
276 total_results += pFuncs[j]->CountOutputs();
277 }
278 if (pCS->CountComponents() > total_results)
279 total_results = pCS->CountComponents();
280 CFX_FixedBufGrow<FX_FLOAT, 16> result_array(total_results); 274 CFX_FixedBufGrow<FX_FLOAT, 16> result_array(total_results);
281 FX_FLOAT* pResults = result_array; 275 FX_FLOAT* pResults = result_array;
282 FXSYS_memset(pResults, 0, total_results * sizeof(FX_FLOAT)); 276 FXSYS_memset(pResults, 0, total_results * sizeof(FX_FLOAT));
283 for (int row = 0; row < height; row++) { 277 for (int row = 0; row < height; row++) {
284 uint32_t* dib_buf = (uint32_t*)(pBitmap->GetBuffer() + row * pitch); 278 uint32_t* dib_buf = (uint32_t*)(pBitmap->GetBuffer() + row * pitch);
285 for (int column = 0; column < width; column++) { 279 for (int column = 0; column < width; column++) {
286 FX_FLOAT x = (FX_FLOAT)column, y = (FX_FLOAT)row; 280 FX_FLOAT x = (FX_FLOAT)column, y = (FX_FLOAT)row;
287 matrix.Transform(x, y); 281 matrix.Transform(x, y);
288 if (x < xmin || x > xmax || y < ymin || y > ymax) { 282 if (x < xmin || x > xmax || y < ymin || y > ymax) {
289 continue; 283 continue;
290 } 284 }
291 FX_FLOAT input[2]; 285 FX_FLOAT input[2];
292 int offset = 0; 286 int offset = 0;
293 input[0] = x; 287 input[0] = x;
294 input[1] = y; 288 input[1] = y;
295 for (int j = 0; j < nFuncs; j++) { 289 for (const auto& func : funcs) {
296 if (pFuncs[j]) { 290 if (func) {
297 int nresults; 291 int nresults;
298 if (pFuncs[j]->Call(input, 2, pResults + offset, nresults)) { 292 if (func->Call(input, 2, pResults + offset, nresults))
299 offset += nresults; 293 offset += nresults;
300 }
301 } 294 }
302 } 295 }
303 FX_FLOAT R = 0.0f, G = 0.0f, B = 0.0f; 296 FX_FLOAT R = 0.0f, G = 0.0f, B = 0.0f;
304 pCS->GetRGB(pResults, R, G, B); 297 pCS->GetRGB(pResults, R, G, B);
305 dib_buf[column] = FXARGB_TODIB(FXARGB_MAKE( 298 dib_buf[column] = FXARGB_TODIB(FXARGB_MAKE(
306 alpha, (int32_t)(R * 255), (int32_t)(G * 255), (int32_t)(B * 255))); 299 alpha, (int32_t)(R * 255), (int32_t)(G * 255), (int32_t)(B * 255)));
307 } 300 }
308 } 301 }
309 } 302 }
310 FX_BOOL _GetScanlineIntersect(int y, 303
311 FX_FLOAT x1, 304 bool GetScanlineIntersect(int y,
312 FX_FLOAT y1, 305 FX_FLOAT x1,
313 FX_FLOAT x2, 306 FX_FLOAT y1,
314 FX_FLOAT y2, 307 FX_FLOAT x2,
315 FX_FLOAT& x) { 308 FX_FLOAT y2,
316 if (y1 == y2) { 309 FX_FLOAT* x) {
310 if (y1 == y2)
317 return FALSE; 311 return FALSE;
312
313 if (y1 < y2) {
314 if (y < y1 || y > y2)
315 return FALSE;
316 } else {
317 if (y < y2 || y > y1)
318 return FALSE;
318 } 319 }
319 if (y1 < y2) { 320 *x = x1 + ((x2 - x1) * (y - y1) / (y2 - y1));
320 if (y < y1 || y > y2) {
321 return FALSE;
322 }
323 } else {
324 if (y < y2 || y > y1) {
325 return FALSE;
326 }
327 }
328 x = x1 + ((x2 - x1) * (y - y1) / (y2 - y1));
329 return TRUE; 321 return TRUE;
330 } 322 }
331 static void DrawGouraud(CFX_DIBitmap* pBitmap, 323
332 int alpha, 324 void DrawGouraud(CFX_DIBitmap* pBitmap,
333 CPDF_MeshVertex triangle[3]) { 325 int alpha,
326 CPDF_MeshVertex triangle[3]) {
334 FX_FLOAT min_y = triangle[0].y, max_y = triangle[0].y; 327 FX_FLOAT min_y = triangle[0].y, max_y = triangle[0].y;
335 for (int i = 1; i < 3; i++) { 328 for (int i = 1; i < 3; i++) {
336 if (min_y > triangle[i].y) { 329 if (min_y > triangle[i].y) {
337 min_y = triangle[i].y; 330 min_y = triangle[i].y;
338 } 331 }
339 if (max_y < triangle[i].y) { 332 if (max_y < triangle[i].y) {
340 max_y = triangle[i].y; 333 max_y = triangle[i].y;
341 } 334 }
342 } 335 }
343 if (min_y == max_y) { 336 if (min_y == max_y) {
344 return; 337 return;
345 } 338 }
346 int min_yi = (int)FXSYS_floor(min_y), max_yi = (int)FXSYS_ceil(max_y); 339 int min_yi = (int)FXSYS_floor(min_y), max_yi = (int)FXSYS_ceil(max_y);
347 if (min_yi < 0) { 340 if (min_yi < 0) {
348 min_yi = 0; 341 min_yi = 0;
349 } 342 }
350 if (max_yi >= pBitmap->GetHeight()) { 343 if (max_yi >= pBitmap->GetHeight()) {
351 max_yi = pBitmap->GetHeight() - 1; 344 max_yi = pBitmap->GetHeight() - 1;
352 } 345 }
353 for (int y = min_yi; y <= max_yi; y++) { 346 for (int y = min_yi; y <= max_yi; y++) {
354 int nIntersects = 0; 347 int nIntersects = 0;
355 FX_FLOAT inter_x[3], r[3], g[3], b[3]; 348 FX_FLOAT inter_x[3], r[3], g[3], b[3];
356 for (int i = 0; i < 3; i++) { 349 for (int i = 0; i < 3; i++) {
357 CPDF_MeshVertex& vertex1 = triangle[i]; 350 CPDF_MeshVertex& vertex1 = triangle[i];
358 CPDF_MeshVertex& vertex2 = triangle[(i + 1) % 3]; 351 CPDF_MeshVertex& vertex2 = triangle[(i + 1) % 3];
359 FX_BOOL bIntersect = _GetScanlineIntersect( 352 bool bIntersect = GetScanlineIntersect(y, vertex1.x, vertex1.y, vertex2.x,
360 y, vertex1.x, vertex1.y, vertex2.x, vertex2.y, inter_x[nIntersects]); 353 vertex2.y, &inter_x[nIntersects]);
361 if (!bIntersect) { 354 if (!bIntersect)
362 continue; 355 continue;
363 }
364 356
365 FX_FLOAT y_dist = (y - vertex1.y) / (vertex2.y - vertex1.y); 357 FX_FLOAT y_dist = (y - vertex1.y) / (vertex2.y - vertex1.y);
366 r[nIntersects] = vertex1.r + ((vertex2.r - vertex1.r) * y_dist); 358 r[nIntersects] = vertex1.r + ((vertex2.r - vertex1.r) * y_dist);
367 g[nIntersects] = vertex1.g + ((vertex2.g - vertex1.g) * y_dist); 359 g[nIntersects] = vertex1.g + ((vertex2.g - vertex1.g) * y_dist);
368 b[nIntersects] = vertex1.b + ((vertex2.b - vertex1.b) * y_dist); 360 b[nIntersects] = vertex1.b + ((vertex2.b - vertex1.b) * y_dist);
369 nIntersects++; 361 nIntersects++;
370 } 362 }
371 if (nIntersects != 2) { 363 if (nIntersects != 2) {
372 continue; 364 continue;
373 } 365 }
(...skipping 28 matching lines...) Expand all
402 R += r_unit; 394 R += r_unit;
403 G += g_unit; 395 G += g_unit;
404 B += b_unit; 396 B += b_unit;
405 FXARGB_SETDIB(dib_buf, 397 FXARGB_SETDIB(dib_buf,
406 FXARGB_MAKE(alpha, (int32_t)(R * 255), (int32_t)(G * 255), 398 FXARGB_MAKE(alpha, (int32_t)(R * 255), (int32_t)(G * 255),
407 (int32_t)(B * 255))); 399 (int32_t)(B * 255)));
408 dib_buf += 4; 400 dib_buf += 4;
409 } 401 }
410 } 402 }
411 } 403 }
412 static void DrawFreeGouraudShading(CFX_DIBitmap* pBitmap, 404
413 CFX_Matrix* pObject2Bitmap, 405 void DrawFreeGouraudShading(
414 CPDF_Stream* pShadingStream, 406 CFX_DIBitmap* pBitmap,
415 CPDF_Function** pFuncs, 407 CFX_Matrix* pObject2Bitmap,
416 int nFuncs, 408 CPDF_Stream* pShadingStream,
417 CPDF_ColorSpace* pCS, 409 const std::vector<std::unique_ptr<CPDF_Function>>& funcs,
418 int alpha) { 410 CPDF_ColorSpace* pCS,
411 int alpha) {
419 ASSERT(pBitmap->GetFormat() == FXDIB_Argb); 412 ASSERT(pBitmap->GetFormat() == FXDIB_Argb);
420 413
421 CPDF_MeshStream stream; 414 CPDF_MeshStream stream(funcs, pCS);
422 if (!stream.Load(pShadingStream, pFuncs, nFuncs, pCS)) 415 if (!stream.Load(pShadingStream))
423 return; 416 return;
424 417
425 CPDF_MeshVertex triangle[3]; 418 CPDF_MeshVertex triangle[3];
426 FXSYS_memset(triangle, 0, sizeof(triangle)); 419 FXSYS_memset(triangle, 0, sizeof(triangle));
427 420
428 while (!stream.m_BitStream.IsEOF()) { 421 while (!stream.BitStream()->IsEOF()) {
429 CPDF_MeshVertex vertex; 422 CPDF_MeshVertex vertex;
430 uint32_t flag = stream.GetVertex(vertex, pObject2Bitmap); 423 uint32_t flag = stream.GetVertex(vertex, pObject2Bitmap);
431 if (flag == 0) { 424 if (flag == 0) {
432 triangle[0] = vertex; 425 triangle[0] = vertex;
433 for (int j = 1; j < 3; j++) { 426 for (int j = 1; j < 3; j++) {
434 stream.GetVertex(triangle[j], pObject2Bitmap); 427 stream.GetVertex(triangle[j], pObject2Bitmap);
435 } 428 }
436 } else { 429 } else {
437 if (flag == 1) { 430 if (flag == 1) {
438 triangle[0] = triangle[1]; 431 triangle[0] = triangle[1];
439 } 432 }
440 triangle[1] = triangle[2]; 433 triangle[1] = triangle[2];
441 triangle[2] = vertex; 434 triangle[2] = vertex;
442 } 435 }
443 DrawGouraud(pBitmap, alpha, triangle); 436 DrawGouraud(pBitmap, alpha, triangle);
444 } 437 }
445 } 438 }
446 static void DrawLatticeGouraudShading(CFX_DIBitmap* pBitmap, 439
447 CFX_Matrix* pObject2Bitmap, 440 void DrawLatticeGouraudShading(
448 CPDF_Stream* pShadingStream, 441 CFX_DIBitmap* pBitmap,
449 CPDF_Function** pFuncs, 442 CFX_Matrix* pObject2Bitmap,
450 int nFuncs, 443 CPDF_Stream* pShadingStream,
451 CPDF_ColorSpace* pCS, 444 const std::vector<std::unique_ptr<CPDF_Function>>& funcs,
452 int alpha) { 445 CPDF_ColorSpace* pCS,
446 int alpha) {
453 ASSERT(pBitmap->GetFormat() == FXDIB_Argb); 447 ASSERT(pBitmap->GetFormat() == FXDIB_Argb);
454 448
455 int row_verts = pShadingStream->GetDict()->GetIntegerBy("VerticesPerRow"); 449 int row_verts = pShadingStream->GetDict()->GetIntegerBy("VerticesPerRow");
456 if (row_verts < 2) 450 if (row_verts < 2)
457 return; 451 return;
458 452
459 CPDF_MeshStream stream; 453 CPDF_MeshStream stream(funcs, pCS);
460 if (!stream.Load(pShadingStream, pFuncs, nFuncs, pCS)) 454 if (!stream.Load(pShadingStream))
461 return; 455 return;
462 456
463 CPDF_MeshVertex* vertex = FX_Alloc2D(CPDF_MeshVertex, row_verts, 2); 457 std::unique_ptr<CPDF_MeshVertex, FxFreeDeleter> vertex(
464 if (!stream.GetVertexRow(vertex, row_verts, pObject2Bitmap)) { 458 FX_Alloc2D(CPDF_MeshVertex, row_verts, 2));
465 FX_Free(vertex); 459 if (!stream.GetVertexRow(vertex.get(), row_verts, pObject2Bitmap))
466 return; 460 return;
467 } 461
468 int last_index = 0; 462 int last_index = 0;
469 while (1) { 463 while (1) {
470 CPDF_MeshVertex* last_row = vertex + last_index * row_verts; 464 CPDF_MeshVertex* last_row = vertex.get() + last_index * row_verts;
471 CPDF_MeshVertex* this_row = vertex + (1 - last_index) * row_verts; 465 CPDF_MeshVertex* this_row = vertex.get() + (1 - last_index) * row_verts;
472 if (!stream.GetVertexRow(this_row, row_verts, pObject2Bitmap)) { 466 if (!stream.GetVertexRow(this_row, row_verts, pObject2Bitmap))
473 FX_Free(vertex);
474 return; 467 return;
475 } 468
476 CPDF_MeshVertex triangle[3]; 469 CPDF_MeshVertex triangle[3];
477 for (int i = 1; i < row_verts; i++) { 470 for (int i = 1; i < row_verts; i++) {
478 triangle[0] = last_row[i]; 471 triangle[0] = last_row[i];
479 triangle[1] = this_row[i - 1]; 472 triangle[1] = this_row[i - 1];
480 triangle[2] = last_row[i - 1]; 473 triangle[2] = last_row[i - 1];
481 DrawGouraud(pBitmap, alpha, triangle); 474 DrawGouraud(pBitmap, alpha, triangle);
482 triangle[2] = this_row[i]; 475 triangle[2] = this_row[i];
483 DrawGouraud(pBitmap, alpha, triangle); 476 DrawGouraud(pBitmap, alpha, triangle);
484 } 477 }
485 last_index = 1 - last_index; 478 last_index = 1 - last_index;
486 } 479 }
487 FX_Free(vertex);
488 } 480 }
481
489 struct Coon_BezierCoeff { 482 struct Coon_BezierCoeff {
490 float a, b, c, d; 483 float a, b, c, d;
491 void FromPoints(float p0, float p1, float p2, float p3) { 484 void FromPoints(float p0, float p1, float p2, float p3) {
492 a = -p0 + 3 * p1 - 3 * p2 + p3; 485 a = -p0 + 3 * p1 - 3 * p2 + p3;
493 b = 3 * p0 - 6 * p1 + 3 * p2; 486 b = 3 * p0 - 6 * p1 + 3 * p2;
494 c = -3 * p0 + 3 * p1; 487 c = -3 * p0 + 3 * p1;
495 d = p0; 488 d = p0;
496 } 489 }
497 Coon_BezierCoeff first_half() { 490 Coon_BezierCoeff first_half() {
498 Coon_BezierCoeff result; 491 Coon_BezierCoeff result;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
530 b = (D1.b + D2.b) / 2; 523 b = (D1.b + D2.b) / 2;
531 c = (D1.c + D2.c) / 2 - (C1.a / 8 + C1.b / 4 + C1.c / 2) + 524 c = (D1.c + D2.c) / 2 - (C1.a / 8 + C1.b / 4 + C1.c / 2) +
532 (C2.a / 8 + C2.b / 4) + (-C1.d + D2.d) / 2 - (C2.a + C2.b) / 2; 525 (C2.a / 8 + C2.b / 4) + (-C1.d + D2.d) / 2 - (C2.a + C2.b) / 2;
533 d = C1.a / 8 + C1.b / 4 + C1.c / 2 + C1.d; 526 d = C1.a / 8 + C1.b / 4 + C1.c / 2 + C1.d;
534 } 527 }
535 float Distance() { 528 float Distance() {
536 float dis = a + b + c; 529 float dis = a + b + c;
537 return dis < 0 ? -dis : dis; 530 return dis < 0 ? -dis : dis;
538 } 531 }
539 }; 532 };
533
540 struct Coon_Bezier { 534 struct Coon_Bezier {
541 Coon_BezierCoeff x, y; 535 Coon_BezierCoeff x, y;
542 void FromPoints(float x0, 536 void FromPoints(float x0,
543 float y0, 537 float y0,
544 float x1, 538 float x1,
545 float y1, 539 float y1,
546 float x2, 540 float x2,
547 float y2, 541 float y2,
548 float x3, 542 float x3,
549 float y3) { 543 float y3) {
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
588 for (i = 0; i < 4; i++) { 582 for (i = 0; i < 4; i++) {
589 pPoints[i].m_PointX = p[i]; 583 pPoints[i].m_PointX = p[i];
590 } 584 }
591 y.GetPointsReverse(p); 585 y.GetPointsReverse(p);
592 for (i = 0; i < 4; i++) { 586 for (i = 0; i < 4; i++) {
593 pPoints[i].m_PointY = p[i]; 587 pPoints[i].m_PointY = p[i];
594 } 588 }
595 } 589 }
596 float Distance() { return x.Distance() + y.Distance(); } 590 float Distance() { return x.Distance() + y.Distance(); }
597 }; 591 };
598 static int _BiInterpol(int c0, 592
599 int c1, 593 int BiInterpolImpl(int c0,
600 int c2, 594 int c1,
601 int c3, 595 int c2,
602 int x, 596 int c3,
603 int y, 597 int x,
604 int x_scale, 598 int y,
605 int y_scale) { 599 int x_scale,
600 int y_scale) {
606 int x1 = c0 + (c3 - c0) * x / x_scale; 601 int x1 = c0 + (c3 - c0) * x / x_scale;
607 int x2 = c1 + (c2 - c1) * x / x_scale; 602 int x2 = c1 + (c2 - c1) * x / x_scale;
608 return x1 + (x2 - x1) * y / y_scale; 603 return x1 + (x2 - x1) * y / y_scale;
609 } 604 }
605
610 struct Coon_Color { 606 struct Coon_Color {
611 Coon_Color() { FXSYS_memset(comp, 0, sizeof(int) * 3); } 607 Coon_Color() { FXSYS_memset(comp, 0, sizeof(int) * 3); }
612 int comp[3]; 608 int comp[3];
609
613 void BiInterpol(Coon_Color colors[4], 610 void BiInterpol(Coon_Color colors[4],
614 int x, 611 int x,
615 int y, 612 int y,
616 int x_scale, 613 int x_scale,
617 int y_scale) { 614 int y_scale) {
618 for (int i = 0; i < 3; i++) 615 for (int i = 0; i < 3; i++) {
619 comp[i] = 616 comp[i] = BiInterpolImpl(colors[0].comp[i], colors[1].comp[i],
620 _BiInterpol(colors[0].comp[i], colors[1].comp[i], colors[2].comp[i], 617 colors[2].comp[i], colors[3].comp[i], x, y,
621 colors[3].comp[i], x, y, x_scale, y_scale); 618 x_scale, y_scale);
619 }
622 } 620 }
621
623 int Distance(Coon_Color& o) { 622 int Distance(Coon_Color& o) {
624 int max, diff; 623 return std::max({FXSYS_abs(comp[0] - o.comp[0]),
625 max = FXSYS_abs(comp[0] - o.comp[0]); 624 FXSYS_abs(comp[1] - o.comp[1]),
626 diff = FXSYS_abs(comp[1] - o.comp[1]); 625 FXSYS_abs(comp[2] - o.comp[2])});
627 if (max < diff) {
628 max = diff;
629 }
630 diff = FXSYS_abs(comp[2] - o.comp[2]);
631 if (max < diff) {
632 max = diff;
633 }
634 return max;
635 } 626 }
636 }; 627 };
628
637 struct CPDF_PatchDrawer { 629 struct CPDF_PatchDrawer {
638 Coon_Color patch_colors[4]; 630 Coon_Color patch_colors[4];
639 int max_delta; 631 int max_delta;
640 CFX_PathData path; 632 CFX_PathData path;
641 CFX_RenderDevice* pDevice; 633 CFX_RenderDevice* pDevice;
642 int fill_mode; 634 int fill_mode;
643 int alpha; 635 int alpha;
644 void Draw(int x_scale, 636 void Draw(int x_scale,
645 int y_scale, 637 int y_scale,
646 int left, 638 int left,
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
725 D1.second_half(), m2s); 717 D1.second_half(), m2s);
726 Draw(x_scale, y_scale, left + 1, bottom, C1.second_half(), m1s, m2f, 718 Draw(x_scale, y_scale, left + 1, bottom, C1.second_half(), m1s, m2f,
727 D2.first_half()); 719 D2.first_half());
728 Draw(x_scale, y_scale, left + 1, bottom + 1, m1s, C2.second_half(), m2s, 720 Draw(x_scale, y_scale, left + 1, bottom + 1, m1s, C2.second_half(), m2s,
729 D2.second_half()); 721 D2.second_half());
730 } 722 }
731 } 723 }
732 } 724 }
733 }; 725 };
734 726
735 bool _CheckCoonTensorPara(const CPDF_MeshStream& stream) { 727 bool CheckCoonTensorPara(const CPDF_MeshStream& stream) {
736 bool bCoorBits = (stream.m_nCoordBits == 1 || stream.m_nCoordBits == 2 || 728 uint32_t coord = stream.CoordBits();
737 stream.m_nCoordBits == 4 || stream.m_nCoordBits == 8 || 729 bool bCoordBitsValid =
738 stream.m_nCoordBits == 12 || stream.m_nCoordBits == 16 || 730 (coord == 1 || coord == 2 || coord == 4 || coord == 8 || coord == 12 ||
739 stream.m_nCoordBits == 24 || stream.m_nCoordBits == 32); 731 coord == 16 || coord == 24 || coord == 32);
740 732
741 bool bCompBits = (stream.m_nCompBits == 1 || stream.m_nCompBits == 2 || 733 uint32_t comp = stream.CompBits();
742 stream.m_nCompBits == 4 || stream.m_nCompBits == 8 || 734 bool bCompBitsValid = (comp == 1 || comp == 2 || comp == 4 || comp == 8 ||
743 stream.m_nCompBits == 12 || stream.m_nCompBits == 16); 735 comp == 12 || comp == 16);
744 736
745 bool bFlagBits = (stream.m_nFlagBits == 2 || stream.m_nFlagBits == 4 || 737 uint32_t flag = stream.FlagBits();
746 stream.m_nFlagBits == 8); 738 bool bFlagBitsValid = (flag == 2 || flag == 4 || flag == 8);
747 739
748 return bCoorBits && bCompBits && bFlagBits; 740 return bCoordBitsValid && bCompBitsValid && bFlagBitsValid;
749 } 741 }
750 742
751 static void DrawCoonPatchMeshes(FX_BOOL bTensor, 743 void DrawCoonPatchMeshes(
752 CFX_DIBitmap* pBitmap, 744 FX_BOOL bTensor,
753 CFX_Matrix* pObject2Bitmap, 745 CFX_DIBitmap* pBitmap,
754 CPDF_Stream* pShadingStream, 746 CFX_Matrix* pObject2Bitmap,
755 CPDF_Function** pFuncs, 747 CPDF_Stream* pShadingStream,
756 int nFuncs, 748 const std::vector<std::unique_ptr<CPDF_Function>>& funcs,
757 CPDF_ColorSpace* pCS, 749 CPDF_ColorSpace* pCS,
758 int fill_mode, 750 int fill_mode,
759 int alpha) { 751 int alpha) {
760 ASSERT(pBitmap->GetFormat() == FXDIB_Argb); 752 ASSERT(pBitmap->GetFormat() == FXDIB_Argb);
761 753
762 CFX_FxgeDevice device; 754 CFX_FxgeDevice device;
763 device.Attach(pBitmap); 755 device.Attach(pBitmap);
764 CPDF_MeshStream stream; 756 CPDF_MeshStream stream(funcs, pCS);
765 if (!stream.Load(pShadingStream, pFuncs, nFuncs, pCS)) 757 if (!stream.Load(pShadingStream))
766 return; 758 return;
767 if (!_CheckCoonTensorPara(stream)) 759 if (!CheckCoonTensorPara(stream))
768 return; 760 return;
769 761
770 CPDF_PatchDrawer patch; 762 CPDF_PatchDrawer patch;
771 patch.alpha = alpha; 763 patch.alpha = alpha;
772 patch.pDevice = &device; 764 patch.pDevice = &device;
773 patch.fill_mode = fill_mode; 765 patch.fill_mode = fill_mode;
774 patch.path.SetPointCount(13); 766 patch.path.SetPointCount(13);
775 FX_PATHPOINT* pPoints = patch.path.GetPoints(); 767 FX_PATHPOINT* pPoints = patch.path.GetPoints();
776 pPoints[0].m_Flag = FXPT_MOVETO; 768 pPoints[0].m_Flag = FXPT_MOVETO;
777 for (int i = 1; i < 13; i++) { 769 for (int i = 1; i < 13; i++) {
778 pPoints[i].m_Flag = FXPT_BEZIERTO; 770 pPoints[i].m_Flag = FXPT_BEZIERTO;
779 } 771 }
780 CFX_PointF coords[16]; 772 CFX_PointF coords[16];
781 int point_count = bTensor ? 16 : 12; 773 int point_count = bTensor ? 16 : 12;
782 while (!stream.m_BitStream.IsEOF()) { 774 while (!stream.BitStream()->IsEOF()) {
783 uint32_t flag = stream.GetFlag(); 775 uint32_t flag = stream.GetFlag();
784 int iStartPoint = 0, iStartColor = 0, i = 0; 776 int iStartPoint = 0, iStartColor = 0, i = 0;
785 if (flag) { 777 if (flag) {
786 iStartPoint = 4; 778 iStartPoint = 4;
787 iStartColor = 2; 779 iStartColor = 2;
788 CFX_PointF tempCoords[4]; 780 CFX_PointF tempCoords[4];
789 for (i = 0; i < 4; i++) { 781 for (i = 0; i < 4; i++) {
790 tempCoords[i] = coords[(flag * 3 + i) % 12]; 782 tempCoords[i] = coords[(flag * 3 + i) % 12];
791 } 783 }
792 FXSYS_memcpy(coords, tempCoords, sizeof(tempCoords)); 784 FXSYS_memcpy(coords, tempCoords, sizeof(tempCoords));
(...skipping 23 matching lines...) Expand all
816 coords[10].x, coords[10].y, coords[9].x, coords[9].y); 808 coords[10].x, coords[10].y, coords[9].x, coords[9].y);
817 C2.FromPoints(coords[3].x, coords[3].y, coords[4].x, coords[4].y, 809 C2.FromPoints(coords[3].x, coords[3].y, coords[4].x, coords[4].y,
818 coords[5].x, coords[5].y, coords[6].x, coords[6].y); 810 coords[5].x, coords[5].y, coords[6].x, coords[6].y);
819 D1.FromPoints(coords[0].x, coords[0].y, coords[1].x, coords[1].y, 811 D1.FromPoints(coords[0].x, coords[0].y, coords[1].x, coords[1].y,
820 coords[2].x, coords[2].y, coords[3].x, coords[3].y); 812 coords[2].x, coords[2].y, coords[3].x, coords[3].y);
821 D2.FromPoints(coords[9].x, coords[9].y, coords[8].x, coords[8].y, 813 D2.FromPoints(coords[9].x, coords[9].y, coords[8].x, coords[8].y,
822 coords[7].x, coords[7].y, coords[6].x, coords[6].y); 814 coords[7].x, coords[7].y, coords[6].x, coords[6].y);
823 patch.Draw(1, 1, 0, 0, C1, C2, D1, D2); 815 patch.Draw(1, 1, 0, 0, C1, C2, D1, D2);
824 } 816 }
825 } 817 }
818
819 std::unique_ptr<CFX_DIBitmap> DrawPatternBitmap(
820 CPDF_Document* pDoc,
821 CPDF_PageRenderCache* pCache,
822 CPDF_TilingPattern* pPattern,
823 const CFX_Matrix* pObject2Device,
824 int width,
825 int height,
826 int flags) {
827 std::unique_ptr<CFX_DIBitmap> pBitmap(new CFX_DIBitmap);
828 if (!pBitmap->Create(width, height,
829 pPattern->colored() ? FXDIB_Argb : FXDIB_8bppMask)) {
830 return std::unique_ptr<CFX_DIBitmap>();
831 }
832 CFX_FxgeDevice bitmap_device;
833 bitmap_device.Attach(pBitmap.get());
834 pBitmap->Clear(0);
835 CFX_FloatRect cell_bbox = pPattern->bbox();
836 pPattern->pattern_to_form()->TransformRect(cell_bbox);
837 pObject2Device->TransformRect(cell_bbox);
838 CFX_FloatRect bitmap_rect(0.0f, 0.0f, (FX_FLOAT)width, (FX_FLOAT)height);
839 CFX_Matrix mtAdjust;
840 mtAdjust.MatchRect(bitmap_rect, cell_bbox);
841 CFX_Matrix mtPattern2Bitmap = *pObject2Device;
842 mtPattern2Bitmap.Concat(mtAdjust);
843 CPDF_RenderOptions options;
844 if (!pPattern->colored())
845 options.m_ColorMode = RENDER_COLOR_ALPHA;
846
847 flags |= RENDER_FORCE_HALFTONE;
848 options.m_Flags = flags;
849 CPDF_RenderContext context(pDoc, pCache);
850 context.AppendLayer(pPattern->form(), &mtPattern2Bitmap);
851 context.Render(&bitmap_device, &options, nullptr);
852 return pBitmap;
853 }
854
855 } // namespace
856
826 void CPDF_RenderStatus::DrawShading(CPDF_ShadingPattern* pPattern, 857 void CPDF_RenderStatus::DrawShading(CPDF_ShadingPattern* pPattern,
827 CFX_Matrix* pMatrix, 858 CFX_Matrix* pMatrix,
828 FX_RECT& clip_rect, 859 FX_RECT& clip_rect,
829 int alpha, 860 int alpha,
830 FX_BOOL bAlphaMode) { 861 FX_BOOL bAlphaMode) {
831 CPDF_Function** pFuncs = pPattern->m_pFunctions; 862 const auto& funcs = pPattern->GetFuncs();
832 int nFuncs = pPattern->m_nFuncs; 863 CPDF_Dictionary* pDict = pPattern->GetShadingObject()->GetDict();
833 CPDF_Dictionary* pDict = pPattern->m_pShadingObj->GetDict(); 864 CPDF_ColorSpace* pColorSpace = pPattern->GetCS();
834 CPDF_ColorSpace* pColorSpace = pPattern->m_pCS; 865 if (!pColorSpace)
835 if (!pColorSpace) {
836 return; 866 return;
837 } 867
838 FX_ARGB background = 0; 868 FX_ARGB background = 0;
839 if (!pPattern->m_bShadingObj && 869 if (!pPattern->IsShadingObject() && pDict->KeyExist("Background")) {
840 pPattern->m_pShadingObj->GetDict()->KeyExist("Background")) { 870 CPDF_Array* pBackColor = pDict->GetArrayBy("Background");
841 CPDF_Array* pBackColor =
842 pPattern->m_pShadingObj->GetDict()->GetArrayBy("Background");
843 if (pBackColor && 871 if (pBackColor &&
844 pBackColor->GetCount() >= pColorSpace->CountComponents()) { 872 pBackColor->GetCount() >= pColorSpace->CountComponents()) {
845 CFX_FixedBufGrow<FX_FLOAT, 16> comps(pColorSpace->CountComponents()); 873 CFX_FixedBufGrow<FX_FLOAT, 16> comps(pColorSpace->CountComponents());
846 for (uint32_t i = 0; i < pColorSpace->CountComponents(); i++) 874 for (uint32_t i = 0; i < pColorSpace->CountComponents(); i++)
847 comps[i] = pBackColor->GetNumberAt(i); 875 comps[i] = pBackColor->GetNumberAt(i);
848 FX_FLOAT R = 0.0f, G = 0.0f, B = 0.0f; 876 FX_FLOAT R = 0.0f, G = 0.0f, B = 0.0f;
849 pColorSpace->GetRGB(comps, R, G, B); 877 pColorSpace->GetRGB(comps, R, G, B);
850 background = ArgbEncode(255, (int32_t)(R * 255), (int32_t)(G * 255), 878 background = ArgbEncode(255, (int32_t)(R * 255), (int32_t)(G * 255),
851 (int32_t)(B * 255)); 879 (int32_t)(B * 255));
852 } 880 }
853 } 881 }
854 if (pDict->KeyExist("BBox")) { 882 if (pDict->KeyExist("BBox")) {
855 CFX_FloatRect rect = pDict->GetRectBy("BBox"); 883 CFX_FloatRect rect = pDict->GetRectBy("BBox");
856 rect.Transform(pMatrix); 884 rect.Transform(pMatrix);
857 clip_rect.Intersect(rect.GetOutterRect()); 885 clip_rect.Intersect(rect.GetOutterRect());
858 } 886 }
859 if (m_pDevice->GetDeviceCaps(FXDC_RENDER_CAPS) & FXRC_SHADING && 887 if (m_pDevice->GetDeviceCaps(FXDC_RENDER_CAPS) & FXRC_SHADING &&
860 m_pDevice->GetDeviceDriver()->DrawShading(pPattern, pMatrix, clip_rect, 888 m_pDevice->GetDeviceDriver()->DrawShading(pPattern, pMatrix, clip_rect,
861 alpha, bAlphaMode)) { 889 alpha, bAlphaMode)) {
862 return; 890 return;
863 } 891 }
864 CPDF_DeviceBuffer buffer; 892 CPDF_DeviceBuffer buffer;
865 buffer.Initialize(m_pContext, m_pDevice, &clip_rect, m_pCurObj, 150); 893 buffer.Initialize(m_pContext, m_pDevice, &clip_rect, m_pCurObj, 150);
866 CFX_Matrix FinalMatrix = *pMatrix; 894 CFX_Matrix FinalMatrix = *pMatrix;
867 FinalMatrix.Concat(*buffer.GetMatrix()); 895 FinalMatrix.Concat(*buffer.GetMatrix());
868 CFX_DIBitmap* pBitmap = buffer.GetBitmap(); 896 CFX_DIBitmap* pBitmap = buffer.GetBitmap();
869 if (!pBitmap->GetBuffer()) { 897 if (!pBitmap->GetBuffer())
870 return; 898 return;
871 } 899
872 pBitmap->Clear(background); 900 pBitmap->Clear(background);
873 int fill_mode = m_Options.m_Flags; 901 int fill_mode = m_Options.m_Flags;
874 switch (pPattern->m_ShadingType) { 902 switch (pPattern->GetShadingType()) {
875 case kInvalidShading: 903 case kInvalidShading:
876 case kMaxShading: 904 case kMaxShading:
877 return; 905 return;
878 case kFunctionBasedShading: 906 case kFunctionBasedShading:
879 DrawFuncShading(pBitmap, &FinalMatrix, pDict, pFuncs, nFuncs, pColorSpace, 907 DrawFuncShading(pBitmap, &FinalMatrix, pDict, funcs, pColorSpace, alpha);
880 alpha);
881 break; 908 break;
882 case kAxialShading: 909 case kAxialShading:
883 DrawAxialShading(pBitmap, &FinalMatrix, pDict, pFuncs, nFuncs, 910 DrawAxialShading(pBitmap, &FinalMatrix, pDict, funcs, pColorSpace, alpha);
884 pColorSpace, alpha);
885 break; 911 break;
886 case kRadialShading: 912 case kRadialShading:
887 DrawRadialShading(pBitmap, &FinalMatrix, pDict, pFuncs, nFuncs, 913 DrawRadialShading(pBitmap, &FinalMatrix, pDict, funcs, pColorSpace,
888 pColorSpace, alpha); 914 alpha);
889 break; 915 break;
890 case kFreeFormGouraudTriangleMeshShading: { 916 case kFreeFormGouraudTriangleMeshShading: {
891 // The shading object can be a stream or a dictionary. We do not handle 917 // The shading object can be a stream or a dictionary. We do not handle
892 // the case of dictionary at the moment. 918 // the case of dictionary at the moment.
893 if (CPDF_Stream* pStream = ToStream(pPattern->m_pShadingObj)) { 919 if (CPDF_Stream* pStream = ToStream(pPattern->GetShadingObject())) {
894 DrawFreeGouraudShading(pBitmap, &FinalMatrix, pStream, pFuncs, nFuncs, 920 DrawFreeGouraudShading(pBitmap, &FinalMatrix, pStream, funcs,
895 pColorSpace, alpha); 921 pColorSpace, alpha);
896 } 922 }
897 } break; 923 } break;
898 case kLatticeFormGouraudTriangleMeshShading: { 924 case kLatticeFormGouraudTriangleMeshShading: {
899 // The shading object can be a stream or a dictionary. We do not handle 925 // The shading object can be a stream or a dictionary. We do not handle
900 // the case of dictionary at the moment. 926 // the case of dictionary at the moment.
901 if (CPDF_Stream* pStream = ToStream(pPattern->m_pShadingObj)) { 927 if (CPDF_Stream* pStream = ToStream(pPattern->GetShadingObject())) {
902 DrawLatticeGouraudShading(pBitmap, &FinalMatrix, pStream, pFuncs, 928 DrawLatticeGouraudShading(pBitmap, &FinalMatrix, pStream, funcs,
903 nFuncs, pColorSpace, alpha); 929 pColorSpace, alpha);
904 } 930 }
905 } break; 931 } break;
906 case kCoonsPatchMeshShading: 932 case kCoonsPatchMeshShading:
907 case kTensorProductPatchMeshShading: { 933 case kTensorProductPatchMeshShading: {
908 // The shading object can be a stream or a dictionary. We do not handle 934 // The shading object can be a stream or a dictionary. We do not handle
909 // the case of dictionary at the moment. 935 // the case of dictionary at the moment.
910 if (CPDF_Stream* pStream = ToStream(pPattern->m_pShadingObj)) { 936 if (CPDF_Stream* pStream = ToStream(pPattern->GetShadingObject())) {
911 DrawCoonPatchMeshes( 937 DrawCoonPatchMeshes(
912 pPattern->m_ShadingType == kTensorProductPatchMeshShading, pBitmap, 938 pPattern->GetShadingType() == kTensorProductPatchMeshShading,
913 &FinalMatrix, pStream, pFuncs, nFuncs, pColorSpace, fill_mode, 939 pBitmap, &FinalMatrix, pStream, funcs, pColorSpace, fill_mode,
914 alpha); 940 alpha);
915 } 941 }
916 } break; 942 } break;
917 } 943 }
918 if (bAlphaMode) { 944 if (bAlphaMode)
919 pBitmap->LoadChannel(FXDIB_Red, pBitmap, FXDIB_Alpha); 945 pBitmap->LoadChannel(FXDIB_Red, pBitmap, FXDIB_Alpha);
920 } 946
921 if (m_Options.m_ColorMode == RENDER_COLOR_GRAY) { 947 if (m_Options.m_ColorMode == RENDER_COLOR_GRAY)
922 pBitmap->ConvertColorScale(m_Options.m_ForeColor, m_Options.m_BackColor); 948 pBitmap->ConvertColorScale(m_Options.m_ForeColor, m_Options.m_BackColor);
923 }
924 buffer.OutputToDevice(); 949 buffer.OutputToDevice();
925 } 950 }
951
926 void CPDF_RenderStatus::DrawShadingPattern(CPDF_ShadingPattern* pattern, 952 void CPDF_RenderStatus::DrawShadingPattern(CPDF_ShadingPattern* pattern,
927 const CPDF_PageObject* pPageObj, 953 const CPDF_PageObject* pPageObj,
928 const CFX_Matrix* pObj2Device, 954 const CFX_Matrix* pObj2Device,
929 FX_BOOL bStroke) { 955 FX_BOOL bStroke) {
930 if (!pattern->Load()) { 956 if (!pattern->Load())
931 return; 957 return;
932 } 958
933 m_pDevice->SaveState(); 959 m_pDevice->SaveState();
934 if (pPageObj->IsPath()) { 960 if (pPageObj->IsPath()) {
935 if (!SelectClipPath(pPageObj->AsPath(), pObj2Device, bStroke)) { 961 if (!SelectClipPath(pPageObj->AsPath(), pObj2Device, bStroke)) {
936 m_pDevice->RestoreState(); 962 m_pDevice->RestoreState();
937 return; 963 return;
938 } 964 }
939 } else if (pPageObj->IsImage()) { 965 } else if (pPageObj->IsImage()) {
940 m_pDevice->SetClip_Rect(pPageObj->GetBBox(pObj2Device)); 966 m_pDevice->SetClip_Rect(pPageObj->GetBBox(pObj2Device));
941 } else { 967 } else {
942 return; 968 return;
943 } 969 }
944 FX_RECT rect; 970 FX_RECT rect;
945 if (GetObjectClippedRect(pPageObj, pObj2Device, FALSE, rect)) { 971 if (GetObjectClippedRect(pPageObj, pObj2Device, FALSE, rect)) {
946 m_pDevice->RestoreState(); 972 m_pDevice->RestoreState();
947 return; 973 return;
948 } 974 }
949 CFX_Matrix matrix = *pattern->pattern_to_form(); 975 CFX_Matrix matrix = *pattern->pattern_to_form();
950 matrix.Concat(*pObj2Device); 976 matrix.Concat(*pObj2Device);
951 GetScaledMatrix(matrix); 977 GetScaledMatrix(matrix);
952 int alpha = pPageObj->m_GeneralState.GetAlpha(bStroke); 978 int alpha = pPageObj->m_GeneralState.GetAlpha(bStroke);
953 DrawShading(pattern, &matrix, rect, alpha, 979 DrawShading(pattern, &matrix, rect, alpha,
954 m_Options.m_ColorMode == RENDER_COLOR_ALPHA); 980 m_Options.m_ColorMode == RENDER_COLOR_ALPHA);
955 m_pDevice->RestoreState(); 981 m_pDevice->RestoreState();
956 } 982 }
957 FX_BOOL CPDF_RenderStatus::ProcessShading(const CPDF_ShadingObject* pShadingObj, 983
958 const CFX_Matrix* pObj2Device) { 984 void CPDF_RenderStatus::ProcessShading(const CPDF_ShadingObject* pShadingObj,
985 const CFX_Matrix* pObj2Device) {
959 FX_RECT rect = pShadingObj->GetBBox(pObj2Device); 986 FX_RECT rect = pShadingObj->GetBBox(pObj2Device);
960 FX_RECT clip_box = m_pDevice->GetClipBox(); 987 FX_RECT clip_box = m_pDevice->GetClipBox();
961 rect.Intersect(clip_box); 988 rect.Intersect(clip_box);
962 if (rect.IsEmpty()) { 989 if (rect.IsEmpty())
963 return TRUE; 990 return;
964 } 991
965 CFX_Matrix matrix = pShadingObj->m_Matrix; 992 CFX_Matrix matrix = pShadingObj->m_Matrix;
966 matrix.Concat(*pObj2Device); 993 matrix.Concat(*pObj2Device);
967 DrawShading(pShadingObj->m_pShading, &matrix, rect, 994 DrawShading(pShadingObj->m_pShading, &matrix, rect,
968 pShadingObj->m_GeneralState.GetAlpha(FALSE), 995 pShadingObj->m_GeneralState.GetAlpha(FALSE),
969 m_Options.m_ColorMode == RENDER_COLOR_ALPHA); 996 m_Options.m_ColorMode == RENDER_COLOR_ALPHA);
970 return TRUE;
971 } 997 }
972 static CFX_DIBitmap* DrawPatternBitmap(CPDF_Document* pDoc,
973 CPDF_PageRenderCache* pCache,
974 CPDF_TilingPattern* pPattern,
975 const CFX_Matrix* pObject2Device,
976 int width,
977 int height,
978 int flags) {
979 CFX_DIBitmap* pBitmap = new CFX_DIBitmap;
980 if (!pBitmap->Create(width, height,
981 pPattern->colored() ? FXDIB_Argb : FXDIB_8bppMask)) {
982 delete pBitmap;
983 return NULL;
984 }
985 CFX_FxgeDevice bitmap_device;
986 bitmap_device.Attach(pBitmap);
987 pBitmap->Clear(0);
988 CFX_FloatRect cell_bbox = pPattern->bbox();
989 pPattern->pattern_to_form()->TransformRect(cell_bbox);
990 pObject2Device->TransformRect(cell_bbox);
991 CFX_FloatRect bitmap_rect(0.0f, 0.0f, (FX_FLOAT)width, (FX_FLOAT)height);
992 CFX_Matrix mtAdjust;
993 mtAdjust.MatchRect(bitmap_rect, cell_bbox);
994 CFX_Matrix mtPattern2Bitmap = *pObject2Device;
995 mtPattern2Bitmap.Concat(mtAdjust);
996 CPDF_RenderOptions options;
997 if (!pPattern->colored())
998 options.m_ColorMode = RENDER_COLOR_ALPHA;
999 998
1000 flags |= RENDER_FORCE_HALFTONE;
1001 options.m_Flags = flags;
1002 CPDF_RenderContext context(pDoc, pCache);
1003 context.AppendLayer(pPattern->form(), &mtPattern2Bitmap);
1004 context.Render(&bitmap_device, &options, nullptr);
1005 return pBitmap;
1006 }
1007 void CPDF_RenderStatus::DrawTilingPattern(CPDF_TilingPattern* pPattern, 999 void CPDF_RenderStatus::DrawTilingPattern(CPDF_TilingPattern* pPattern,
1008 const CPDF_PageObject* pPageObj, 1000 const CPDF_PageObject* pPageObj,
1009 const CFX_Matrix* pObj2Device, 1001 const CFX_Matrix* pObj2Device,
1010 FX_BOOL bStroke) { 1002 FX_BOOL bStroke) {
1011 if (!pPattern->Load()) { 1003 if (!pPattern->Load()) {
1012 return; 1004 return;
1013 } 1005 }
1014 m_pDevice->SaveState(); 1006 m_pDevice->SaveState();
1015 if (pPageObj->IsPath()) { 1007 if (pPageObj->IsPath()) {
1016 if (!SelectClipPath(pPageObj->AsPath(), pObj2Device, bStroke)) { 1008 if (!SelectClipPath(pPageObj->AsPath(), pObj2Device, bStroke)) {
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
1113 if (clip_box.top < orig_y) { 1105 if (clip_box.top < orig_y) {
1114 min_row--; 1106 min_row--;
1115 } 1107 }
1116 max_row = (clip_box.bottom - orig_y) / height; 1108 max_row = (clip_box.bottom - orig_y) / height;
1117 if (clip_box.bottom <= orig_y) { 1109 if (clip_box.bottom <= orig_y) {
1118 max_row--; 1110 max_row--;
1119 } 1111 }
1120 } 1112 }
1121 FX_FLOAT left_offset = cell_bbox.left - mtPattern2Device.e; 1113 FX_FLOAT left_offset = cell_bbox.left - mtPattern2Device.e;
1122 FX_FLOAT top_offset = cell_bbox.bottom - mtPattern2Device.f; 1114 FX_FLOAT top_offset = cell_bbox.bottom - mtPattern2Device.f;
1123 CFX_DIBitmap* pPatternBitmap = NULL; 1115 std::unique_ptr<CFX_DIBitmap> pPatternBitmap;
1124 if (width * height < 16) { 1116 if (width * height < 16) {
1125 CFX_DIBitmap* pEnlargedBitmap = 1117 std::unique_ptr<CFX_DIBitmap> pEnlargedBitmap =
1126 DrawPatternBitmap(m_pContext->GetDocument(), m_pContext->GetPageCache(), 1118 DrawPatternBitmap(m_pContext->GetDocument(), m_pContext->GetPageCache(),
1127 pPattern, pObj2Device, 8, 8, m_Options.m_Flags); 1119 pPattern, pObj2Device, 8, 8, m_Options.m_Flags);
1128 pPatternBitmap = pEnlargedBitmap->StretchTo(width, height); 1120 pPatternBitmap.reset(pEnlargedBitmap->StretchTo(width, height));
1129 delete pEnlargedBitmap;
1130 } else { 1121 } else {
1131 pPatternBitmap = DrawPatternBitmap( 1122 pPatternBitmap = DrawPatternBitmap(
1132 m_pContext->GetDocument(), m_pContext->GetPageCache(), pPattern, 1123 m_pContext->GetDocument(), m_pContext->GetPageCache(), pPattern,
1133 pObj2Device, width, height, m_Options.m_Flags); 1124 pObj2Device, width, height, m_Options.m_Flags);
1134 } 1125 }
1135 if (!pPatternBitmap) { 1126 if (!pPatternBitmap) {
1136 m_pDevice->RestoreState(); 1127 m_pDevice->RestoreState();
1137 return; 1128 return;
1138 } 1129 }
1139 if (m_Options.m_ColorMode == RENDER_COLOR_GRAY) { 1130 if (m_Options.m_ColorMode == RENDER_COLOR_GRAY) {
(...skipping 30 matching lines...) Expand all
1170 uint32_t* dest_buf = 1161 uint32_t* dest_buf =
1171 (uint32_t*)(screen.GetBuffer() + screen.GetPitch() * start_y + 1162 (uint32_t*)(screen.GetBuffer() + screen.GetPitch() * start_y +
1172 start_x * 4); 1163 start_x * 4);
1173 if (pPattern->colored()) 1164 if (pPattern->colored())
1174 *dest_buf = *src_buf; 1165 *dest_buf = *src_buf;
1175 else 1166 else
1176 *dest_buf = (*(uint8_t*)src_buf << 24) | (fill_argb & 0xffffff); 1167 *dest_buf = (*(uint8_t*)src_buf << 24) | (fill_argb & 0xffffff);
1177 } else { 1168 } else {
1178 if (pPattern->colored()) { 1169 if (pPattern->colored()) {
1179 screen.CompositeBitmap(start_x, start_y, width, height, 1170 screen.CompositeBitmap(start_x, start_y, width, height,
1180 pPatternBitmap, 0, 0); 1171 pPatternBitmap.get(), 0, 0);
1181 } else { 1172 } else {
1182 screen.CompositeMask(start_x, start_y, width, height, pPatternBitmap, 1173 screen.CompositeMask(start_x, start_y, width, height,
1183 fill_argb, 0, 0); 1174 pPatternBitmap.get(), fill_argb, 0, 0);
1184 } 1175 }
1185 } 1176 }
1186 } 1177 }
1187 } 1178 }
1188 CompositeDIBitmap(&screen, clip_box.left, clip_box.top, 0, 255, 1179 CompositeDIBitmap(&screen, clip_box.left, clip_box.top, 0, 255,
1189 FXDIB_BLEND_NORMAL, FALSE); 1180 FXDIB_BLEND_NORMAL, FALSE);
1190 m_pDevice->RestoreState(); 1181 m_pDevice->RestoreState();
1191 delete pPatternBitmap;
1192 } 1182 }
1193 1183
1194 void CPDF_RenderStatus::DrawPathWithPattern(const CPDF_PathObject* pPathObj, 1184 void CPDF_RenderStatus::DrawPathWithPattern(const CPDF_PathObject* pPathObj,
1195 const CFX_Matrix* pObj2Device, 1185 const CFX_Matrix* pObj2Device,
1196 CPDF_Color* pColor, 1186 CPDF_Color* pColor,
1197 FX_BOOL bStroke) { 1187 FX_BOOL bStroke) {
1198 CPDF_Pattern* pattern = pColor->GetPattern(); 1188 CPDF_Pattern* pattern = pColor->GetPattern();
1199 if (!pattern) 1189 if (!pattern)
1200 return; 1190 return;
1201 1191
(...skipping 15 matching lines...) Expand all
1217 } 1207 }
1218 } 1208 }
1219 if (bStroke) { 1209 if (bStroke) {
1220 CPDF_Color& StrokeColor = *pPathObj->m_ColorState.GetStrokeColor(); 1210 CPDF_Color& StrokeColor = *pPathObj->m_ColorState.GetStrokeColor();
1221 if (StrokeColor.IsPattern()) { 1211 if (StrokeColor.IsPattern()) {
1222 DrawPathWithPattern(pPathObj, pObj2Device, &StrokeColor, TRUE); 1212 DrawPathWithPattern(pPathObj, pObj2Device, &StrokeColor, TRUE);
1223 bStroke = FALSE; 1213 bStroke = FALSE;
1224 } 1214 }
1225 } 1215 }
1226 } 1216 }
OLDNEW
« no previous file with comments | « core/fpdfapi/fpdf_render/fpdf_render_image.cpp ('k') | core/fpdfapi/fpdf_render/render_int.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698