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

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

Issue 1265503005: clang-format all pdfium code. (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: sigh Created 5 years, 4 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
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 "../../../include/fpdfapi/fpdf_render.h" 7 #include "../../../include/fpdfapi/fpdf_render.h"
8 #include "../../../include/fpdfapi/fpdf_pageobj.h" 8 #include "../../../include/fpdfapi/fpdf_pageobj.h"
9 #include "../../../include/fxge/fx_ge.h" 9 #include "../../../include/fxge/fx_ge.h"
10 #include "../fpdf_page/pageint.h" 10 #include "../fpdf_page/pageint.h"
11 #include "render_int.h" 11 #include "render_int.h"
12 #define SHADING_STEPS 256 12 #define SHADING_STEPS 256
13 static void _DrawAxialShading(CFX_DIBitmap* pBitmap, CFX_AffineMatrix* pObject2B itmap, 13 static void _DrawAxialShading(CFX_DIBitmap* pBitmap,
14 CPDF_Dictionary* pDict, CPDF_Function** pFuncs, in t nFuncs, 14 CFX_AffineMatrix* pObject2Bitmap,
15 CPDF_ColorSpace* pCS, int alpha) 15 CPDF_Dictionary* pDict,
16 { 16 CPDF_Function** pFuncs,
17 ASSERT(pBitmap->GetFormat() == FXDIB_Argb); 17 int nFuncs,
18 CPDF_Array* pCoords = pDict->GetArray(FX_BSTRC("Coords")); 18 CPDF_ColorSpace* pCS,
19 if (pCoords == NULL) { 19 int alpha) {
20 return; 20 ASSERT(pBitmap->GetFormat() == FXDIB_Argb);
21 } 21 CPDF_Array* pCoords = pDict->GetArray(FX_BSTRC("Coords"));
22 FX_FLOAT start_x = pCoords->GetNumber(0); 22 if (pCoords == NULL) {
23 FX_FLOAT start_y = pCoords->GetNumber(1); 23 return;
24 FX_FLOAT end_x = pCoords->GetNumber(2); 24 }
25 FX_FLOAT end_y = pCoords->GetNumber(3); 25 FX_FLOAT start_x = pCoords->GetNumber(0);
26 FX_FLOAT t_min = 0, t_max = 1.0f; 26 FX_FLOAT start_y = pCoords->GetNumber(1);
27 CPDF_Array* pArray = pDict->GetArray(FX_BSTRC("Domain")); 27 FX_FLOAT end_x = pCoords->GetNumber(2);
28 if (pArray) { 28 FX_FLOAT end_y = pCoords->GetNumber(3);
29 t_min = pArray->GetNumber(0); 29 FX_FLOAT t_min = 0, t_max = 1.0f;
30 t_max = pArray->GetNumber(1); 30 CPDF_Array* pArray = pDict->GetArray(FX_BSTRC("Domain"));
31 } 31 if (pArray) {
32 FX_BOOL bStartExtend = FALSE, bEndExtend = FALSE; 32 t_min = pArray->GetNumber(0);
33 pArray = pDict->GetArray(FX_BSTRC("Extend")); 33 t_max = pArray->GetNumber(1);
34 if (pArray) { 34 }
35 bStartExtend = pArray->GetInteger(0); 35 FX_BOOL bStartExtend = FALSE, bEndExtend = FALSE;
36 bEndExtend = pArray->GetInteger(1); 36 pArray = pDict->GetArray(FX_BSTRC("Extend"));
37 } 37 if (pArray) {
38 int width = pBitmap->GetWidth(); 38 bStartExtend = pArray->GetInteger(0);
39 int height = pBitmap->GetHeight(); 39 bEndExtend = pArray->GetInteger(1);
40 FX_FLOAT x_span = end_x - start_x; 40 }
41 FX_FLOAT y_span = end_y - start_y; 41 int width = pBitmap->GetWidth();
42 FX_FLOAT axis_len_square = FXSYS_Mul(x_span, x_span) + FXSYS_Mul(y_span, y_s pan); 42 int height = pBitmap->GetHeight();
43 CFX_AffineMatrix matrix; 43 FX_FLOAT x_span = end_x - start_x;
44 matrix.SetReverse(*pObject2Bitmap); 44 FX_FLOAT y_span = end_y - start_y;
45 int total_results = 0; 45 FX_FLOAT axis_len_square =
46 for (int j = 0; j < nFuncs; j ++) { 46 FXSYS_Mul(x_span, x_span) + FXSYS_Mul(y_span, y_span);
47 CFX_AffineMatrix matrix;
48 matrix.SetReverse(*pObject2Bitmap);
49 int total_results = 0;
50 for (int j = 0; j < nFuncs; j++) {
51 if (pFuncs[j]) {
52 total_results += pFuncs[j]->CountOutputs();
53 }
54 }
55 if (pCS->CountComponents() > total_results) {
56 total_results = pCS->CountComponents();
57 }
58 CFX_FixedBufGrow<FX_FLOAT, 16> result_array(total_results);
59 FX_FLOAT* pResults = result_array;
60 FXSYS_memset(pResults, 0, total_results * sizeof(FX_FLOAT));
61 FX_DWORD rgb_array[SHADING_STEPS];
62 for (int i = 0; i < SHADING_STEPS; i++) {
63 FX_FLOAT input = (t_max - t_min) * i / SHADING_STEPS + t_min;
64 int offset = 0;
65 for (int j = 0; j < nFuncs; j++) {
66 if (pFuncs[j]) {
67 int nresults = 0;
68 if (pFuncs[j]->Call(&input, 1, pResults + offset, nresults)) {
69 offset += nresults;
70 }
71 }
72 }
73 FX_FLOAT R = 0.0f, G = 0.0f, B = 0.0f;
74 pCS->GetRGB(pResults, R, G, B);
75 rgb_array[i] =
76 FXARGB_TODIB(FXARGB_MAKE(alpha, FXSYS_round(R * 255),
77 FXSYS_round(G * 255), FXSYS_round(B * 255)));
78 }
79 int pitch = pBitmap->GetPitch();
80 for (int row = 0; row < height; row++) {
81 FX_DWORD* dib_buf = (FX_DWORD*)(pBitmap->GetBuffer() + row * pitch);
82 for (int column = 0; column < width; column++) {
83 FX_FLOAT x = (FX_FLOAT)column, y = (FX_FLOAT)row;
84 matrix.Transform(x, y);
85 FX_FLOAT scale = FXSYS_Div(
86 FXSYS_Mul(x - start_x, x_span) + FXSYS_Mul(y - start_y, y_span),
87 axis_len_square);
88 int index = (int32_t)(scale * (SHADING_STEPS - 1));
89 if (index < 0) {
90 if (!bStartExtend) {
91 continue;
92 }
93 index = 0;
94 } else if (index >= SHADING_STEPS) {
95 if (!bEndExtend) {
96 continue;
97 }
98 index = SHADING_STEPS - 1;
99 }
100 dib_buf[column] = rgb_array[index];
101 }
102 }
103 }
104 static void _DrawRadialShading(CFX_DIBitmap* pBitmap,
105 CFX_AffineMatrix* pObject2Bitmap,
106 CPDF_Dictionary* pDict,
107 CPDF_Function** pFuncs,
108 int nFuncs,
109 CPDF_ColorSpace* pCS,
110 int alpha) {
111 ASSERT(pBitmap->GetFormat() == FXDIB_Argb);
112 CPDF_Array* pCoords = pDict->GetArray(FX_BSTRC("Coords"));
113 if (pCoords == NULL) {
114 return;
115 }
116 FX_FLOAT start_x = pCoords->GetNumber(0);
117 FX_FLOAT start_y = pCoords->GetNumber(1);
118 FX_FLOAT start_r = pCoords->GetNumber(2);
119 FX_FLOAT end_x = pCoords->GetNumber(3);
120 FX_FLOAT end_y = pCoords->GetNumber(4);
121 FX_FLOAT end_r = pCoords->GetNumber(5);
122 CFX_AffineMatrix matrix;
123 matrix.SetReverse(*pObject2Bitmap);
124 FX_FLOAT t_min = 0, t_max = 1.0f;
125 CPDF_Array* pArray = pDict->GetArray(FX_BSTRC("Domain"));
126 if (pArray) {
127 t_min = pArray->GetNumber(0);
128 t_max = pArray->GetNumber(1);
129 }
130 FX_BOOL bStartExtend = FALSE, bEndExtend = FALSE;
131 pArray = pDict->GetArray(FX_BSTRC("Extend"));
132 if (pArray) {
133 bStartExtend = pArray->GetInteger(0);
134 bEndExtend = pArray->GetInteger(1);
135 }
136 int total_results = 0;
137 for (int j = 0; j < nFuncs; j++) {
138 if (pFuncs[j]) {
139 total_results += pFuncs[j]->CountOutputs();
140 }
141 }
142 if (pCS->CountComponents() > total_results) {
143 total_results = pCS->CountComponents();
144 }
145 CFX_FixedBufGrow<FX_FLOAT, 16> result_array(total_results);
146 FX_FLOAT* pResults = result_array;
147 FXSYS_memset(pResults, 0, total_results * sizeof(FX_FLOAT));
148 FX_DWORD rgb_array[SHADING_STEPS];
149 for (int i = 0; i < SHADING_STEPS; i++) {
150 FX_FLOAT input = (t_max - t_min) * i / SHADING_STEPS + t_min;
151 int offset = 0;
152 for (int j = 0; j < nFuncs; j++) {
153 if (pFuncs[j]) {
154 int nresults;
155 if (pFuncs[j]->Call(&input, 1, pResults + offset, nresults)) {
156 offset += nresults;
157 }
158 }
159 }
160 FX_FLOAT R = 0.0f, G = 0.0f, B = 0.0f;
161 pCS->GetRGB(pResults, R, G, B);
162 rgb_array[i] =
163 FXARGB_TODIB(FXARGB_MAKE(alpha, FXSYS_round(R * 255),
164 FXSYS_round(G * 255), FXSYS_round(B * 255)));
165 }
166 FX_FLOAT a = FXSYS_Mul(start_x - end_x, start_x - end_x) +
167 FXSYS_Mul(start_y - end_y, start_y - end_y) -
168 FXSYS_Mul(start_r - end_r, start_r - end_r);
169 int width = pBitmap->GetWidth();
170 int height = pBitmap->GetHeight();
171 int pitch = pBitmap->GetPitch();
172 FX_BOOL bDecreasing = FALSE;
173 if (start_r > end_r) {
174 int length = (int)FXSYS_sqrt((FXSYS_Mul(start_x - end_x, start_x - end_x) +
175 FXSYS_Mul(start_y - end_y, start_y - end_y)));
176 if (length < start_r - end_r) {
177 bDecreasing = TRUE;
178 }
179 }
180 for (int row = 0; row < height; row++) {
181 FX_DWORD* dib_buf = (FX_DWORD*)(pBitmap->GetBuffer() + row * pitch);
182 for (int column = 0; column < width; column++) {
183 FX_FLOAT x = (FX_FLOAT)column, y = (FX_FLOAT)row;
184 matrix.Transform(x, y);
185 FX_FLOAT b = -2 * (FXSYS_Mul(x - start_x, end_x - start_x) +
186 FXSYS_Mul(y - start_y, end_y - start_y) +
187 FXSYS_Mul(start_r, end_r - start_r));
188 FX_FLOAT c = FXSYS_Mul(x - start_x, x - start_x) +
189 FXSYS_Mul(y - start_y, y - start_y) -
190 FXSYS_Mul(start_r, start_r);
191 FX_FLOAT s;
192 if (a == 0) {
193 s = FXSYS_Div(-c, b);
194 } else {
195 FX_FLOAT b2_4ac = FXSYS_Mul(b, b) - 4 * FXSYS_Mul(a, c);
196 if (b2_4ac < 0) {
197 continue;
198 }
199 FX_FLOAT root = FXSYS_sqrt(b2_4ac);
200 FX_FLOAT s1, s2;
201 if (a > 0) {
202 s1 = FXSYS_Div(-b - root, 2 * a);
203 s2 = FXSYS_Div(-b + root, 2 * a);
204 } else {
205 s2 = FXSYS_Div(-b - root, 2 * a);
206 s1 = FXSYS_Div(-b + root, 2 * a);
207 }
208 if (bDecreasing) {
209 if (s1 >= 0 || bStartExtend) {
210 s = s1;
211 } else {
212 s = s2;
213 }
214 } else {
215 if (s2 <= 1.0f || bEndExtend) {
216 s = s2;
217 } else {
218 s = s1;
219 }
220 }
221 if ((start_r + s * (end_r - start_r)) < 0) {
222 continue;
223 }
224 }
225 int index = (int32_t)(s * (SHADING_STEPS - 1));
226 if (index < 0) {
227 if (!bStartExtend) {
228 continue;
229 }
230 index = 0;
231 }
232 if (index >= SHADING_STEPS) {
233 if (!bEndExtend) {
234 continue;
235 }
236 index = SHADING_STEPS - 1;
237 }
238 dib_buf[column] = rgb_array[index];
239 }
240 }
241 }
242 static void _DrawFuncShading(CFX_DIBitmap* pBitmap,
243 CFX_AffineMatrix* pObject2Bitmap,
244 CPDF_Dictionary* pDict,
245 CPDF_Function** pFuncs,
246 int nFuncs,
247 CPDF_ColorSpace* pCS,
248 int alpha) {
249 ASSERT(pBitmap->GetFormat() == FXDIB_Argb);
250 CPDF_Array* pDomain = pDict->GetArray(FX_BSTRC("Domain"));
251 FX_FLOAT xmin = 0, ymin = 0, xmax = 1.0f, ymax = 1.0f;
252 if (pDomain) {
253 xmin = pDomain->GetNumber(0);
254 xmax = pDomain->GetNumber(1);
255 ymin = pDomain->GetNumber(2);
256 ymax = pDomain->GetNumber(3);
257 }
258 CFX_AffineMatrix mtDomain2Target = pDict->GetMatrix(FX_BSTRC("Matrix"));
259 CFX_AffineMatrix matrix, reverse_matrix;
260 matrix.SetReverse(*pObject2Bitmap);
261 reverse_matrix.SetReverse(mtDomain2Target);
262 matrix.Concat(reverse_matrix);
263 int width = pBitmap->GetWidth();
264 int height = pBitmap->GetHeight();
265 int pitch = pBitmap->GetPitch();
266 int total_results = 0;
267 for (int j = 0; j < nFuncs; j++) {
268 if (pFuncs[j]) {
269 total_results += pFuncs[j]->CountOutputs();
270 }
271 }
272 if (pCS->CountComponents() > total_results) {
273 total_results = pCS->CountComponents();
274 }
275 CFX_FixedBufGrow<FX_FLOAT, 16> result_array(total_results);
276 FX_FLOAT* pResults = result_array;
277 FXSYS_memset(pResults, 0, total_results * sizeof(FX_FLOAT));
278 for (int row = 0; row < height; row++) {
279 FX_DWORD* dib_buf = (FX_DWORD*)(pBitmap->GetBuffer() + row * pitch);
280 for (int column = 0; column < width; column++) {
281 FX_FLOAT x = (FX_FLOAT)column, y = (FX_FLOAT)row;
282 matrix.Transform(x, y);
283 if (x < xmin || x > xmax || y < ymin || y > ymax) {
284 continue;
285 }
286 FX_FLOAT input[2];
287 int offset = 0;
288 input[0] = x;
289 input[1] = y;
290 for (int j = 0; j < nFuncs; j++) {
47 if (pFuncs[j]) { 291 if (pFuncs[j]) {
48 total_results += pFuncs[j]->CountOutputs(); 292 int nresults;
49 } 293 if (pFuncs[j]->Call(input, 2, pResults + offset, nresults)) {
50 } 294 offset += nresults;
51 if (pCS->CountComponents() > total_results) { 295 }
52 total_results = pCS->CountComponents(); 296 }
53 } 297 }
54 CFX_FixedBufGrow<FX_FLOAT, 16> result_array(total_results); 298 FX_FLOAT R = 0.0f, G = 0.0f, B = 0.0f;
55 FX_FLOAT* pResults = result_array; 299 pCS->GetRGB(pResults, R, G, B);
56 FXSYS_memset(pResults, 0, total_results * sizeof(FX_FLOAT)); 300 dib_buf[column] = FXARGB_TODIB(FXARGB_MAKE(
57 FX_DWORD rgb_array[SHADING_STEPS]; 301 alpha, (int32_t)(R * 255), (int32_t)(G * 255), (int32_t)(B * 255)));
58 for (int i = 0; i < SHADING_STEPS; i ++) { 302 }
59 FX_FLOAT input = (t_max - t_min) * i / SHADING_STEPS + t_min; 303 }
60 int offset = 0; 304 }
61 for (int j = 0; j < nFuncs; j ++) { 305 FX_BOOL _GetScanlineIntersect(int y,
62 if (pFuncs[j]) { 306 FX_FLOAT x1,
63 int nresults = 0; 307 FX_FLOAT y1,
64 if (pFuncs[j]->Call(&input, 1, pResults + offset, nresults)) { 308 FX_FLOAT x2,
65 offset += nresults; 309 FX_FLOAT y2,
66 } 310 FX_FLOAT& x) {
67 } 311 if (y1 == y2) {
68 } 312 return FALSE;
69 FX_FLOAT R = 0.0f, G = 0.0f, B = 0.0f; 313 }
70 pCS->GetRGB(pResults, R, G, B); 314 if (y1 < y2) {
71 rgb_array[i] = FXARGB_TODIB(FXARGB_MAKE(alpha, FXSYS_round(R * 255), FXS YS_round(G * 255), FXSYS_round(B * 255))); 315 if (y < y1 || y > y2) {
72 } 316 return FALSE;
73 int pitch = pBitmap->GetPitch(); 317 }
74 for (int row = 0; row < height; row ++) { 318 } else {
75 FX_DWORD* dib_buf = (FX_DWORD*)(pBitmap->GetBuffer() + row * pitch); 319 if (y < y2 || y > y1) {
76 for (int column = 0; column < width; column ++) { 320 return FALSE;
77 FX_FLOAT x = (FX_FLOAT)column, y = (FX_FLOAT)row; 321 }
78 matrix.Transform(x, y); 322 }
79 FX_FLOAT scale = FXSYS_Div(FXSYS_Mul(x - start_x, x_span) + FXSYS_Mu l(y - start_y, y_span), axis_len_square); 323 x = x1 + FXSYS_MulDiv(x2 - x1, y - y1, y2 - y1);
80 int index = (int32_t)(scale * (SHADING_STEPS - 1)); 324 return TRUE;
81 if (index < 0) { 325 }
82 if (!bStartExtend) { 326 static void _DrawGouraud(CFX_DIBitmap* pBitmap,
83 continue; 327 int alpha,
84 } 328 CPDF_MeshVertex triangle[3]) {
85 index = 0; 329 FX_FLOAT min_y = triangle[0].y, max_y = triangle[0].y;
86 } else if (index >= SHADING_STEPS) { 330 for (int i = 1; i < 3; i++) {
87 if (!bEndExtend) { 331 if (min_y > triangle[i].y) {
88 continue; 332 min_y = triangle[i].y;
89 } 333 }
90 index = SHADING_STEPS - 1; 334 if (max_y < triangle[i].y) {
91 } 335 max_y = triangle[i].y;
92 dib_buf[column] = rgb_array[index]; 336 }
93 } 337 }
94 } 338 if (min_y == max_y) {
95 } 339 return;
96 static void _DrawRadialShading(CFX_DIBitmap* pBitmap, CFX_AffineMatrix* pObject2 Bitmap, 340 }
97 CPDF_Dictionary* pDict, CPDF_Function** pFuncs, i nt nFuncs, 341 int min_yi = (int)FXSYS_floor(min_y), max_yi = (int)FXSYS_ceil(max_y);
98 CPDF_ColorSpace* pCS, int alpha) 342 if (min_yi < 0) {
99 { 343 min_yi = 0;
100 ASSERT(pBitmap->GetFormat() == FXDIB_Argb); 344 }
101 CPDF_Array* pCoords = pDict->GetArray(FX_BSTRC("Coords")); 345 if (max_yi >= pBitmap->GetHeight()) {
102 if (pCoords == NULL) { 346 max_yi = pBitmap->GetHeight() - 1;
103 return; 347 }
104 } 348 for (int y = min_yi; y <= max_yi; y++) {
105 FX_FLOAT start_x = pCoords->GetNumber(0); 349 int nIntersects = 0;
106 FX_FLOAT start_y = pCoords->GetNumber(1); 350 FX_FLOAT inter_x[3], r[3], g[3], b[3];
107 FX_FLOAT start_r = pCoords->GetNumber(2); 351 for (int i = 0; i < 3; i++) {
108 FX_FLOAT end_x = pCoords->GetNumber(3); 352 CPDF_MeshVertex& vertex1 = triangle[i];
109 FX_FLOAT end_y = pCoords->GetNumber(4); 353 CPDF_MeshVertex& vertex2 = triangle[(i + 1) % 3];
110 FX_FLOAT end_r = pCoords->GetNumber(5); 354 FX_BOOL bIntersect = _GetScanlineIntersect(
111 CFX_AffineMatrix matrix; 355 y, vertex1.x, vertex1.y, vertex2.x, vertex2.y, inter_x[nIntersects]);
112 matrix.SetReverse(*pObject2Bitmap); 356 if (!bIntersect) {
113 FX_FLOAT t_min = 0, t_max = 1.0f; 357 continue;
114 CPDF_Array* pArray = pDict->GetArray(FX_BSTRC("Domain")); 358 }
115 if (pArray) { 359 r[nIntersects] =
116 t_min = pArray->GetNumber(0); 360 vertex1.r + FXSYS_MulDiv(vertex2.r - vertex1.r, y - vertex1.y,
117 t_max = pArray->GetNumber(1); 361 vertex2.y - vertex1.y);
118 } 362 g[nIntersects] =
119 FX_BOOL bStartExtend = FALSE, bEndExtend = FALSE; 363 vertex1.g + FXSYS_MulDiv(vertex2.g - vertex1.g, y - vertex1.y,
120 pArray = pDict->GetArray(FX_BSTRC("Extend")); 364 vertex2.y - vertex1.y);
121 if (pArray) { 365 b[nIntersects] =
122 bStartExtend = pArray->GetInteger(0); 366 vertex1.b + FXSYS_MulDiv(vertex2.b - vertex1.b, y - vertex1.y,
123 bEndExtend = pArray->GetInteger(1); 367 vertex2.y - vertex1.y);
124 } 368 nIntersects++;
125 int total_results = 0; 369 }
126 for (int j = 0; j < nFuncs; j ++) { 370 if (nIntersects != 2) {
127 if (pFuncs[j]) { 371 continue;
128 total_results += pFuncs[j]->CountOutputs(); 372 }
129 } 373 int min_x, max_x, start_index, end_index;
130 } 374 if (inter_x[0] < inter_x[1]) {
131 if (pCS->CountComponents() > total_results) { 375 min_x = (int)FXSYS_floor(inter_x[0]);
132 total_results = pCS->CountComponents(); 376 max_x = (int)FXSYS_ceil(inter_x[1]);
133 } 377 start_index = 0;
134 CFX_FixedBufGrow<FX_FLOAT, 16> result_array(total_results); 378 end_index = 1;
135 FX_FLOAT* pResults = result_array;
136 FXSYS_memset(pResults, 0, total_results * sizeof(FX_FLOAT));
137 FX_DWORD rgb_array[SHADING_STEPS];
138 for (int i = 0; i < SHADING_STEPS; i ++) {
139 FX_FLOAT input = (t_max - t_min) * i / SHADING_STEPS + t_min;
140 int offset = 0;
141 for (int j = 0; j < nFuncs; j ++) {
142 if (pFuncs[j]) {
143 int nresults;
144 if (pFuncs[j]->Call(&input, 1, pResults + offset, nresults)) {
145 offset += nresults;
146 }
147 }
148 }
149 FX_FLOAT R = 0.0f, G = 0.0f, B = 0.0f;
150 pCS->GetRGB(pResults, R, G, B);
151 rgb_array[i] = FXARGB_TODIB(FXARGB_MAKE(alpha, FXSYS_round(R * 255), FXS YS_round(G * 255), FXSYS_round(B * 255)));
152 }
153 FX_FLOAT a = FXSYS_Mul(start_x - end_x, start_x - end_x) +
154 FXSYS_Mul(start_y - end_y, start_y - end_y) - FXSYS_Mul(start_r - end_r, start_r - end_r);
155 int width = pBitmap->GetWidth();
156 int height = pBitmap->GetHeight();
157 int pitch = pBitmap->GetPitch();
158 FX_BOOL bDecreasing = FALSE;
159 if (start_r > end_r) {
160 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)));
161 if (length < start_r - end_r) {
162 bDecreasing = TRUE;
163 }
164 }
165 for (int row = 0; row < height; row ++) {
166 FX_DWORD* dib_buf = (FX_DWORD*)(pBitmap->GetBuffer() + row * pitch);
167 for (int column = 0; column < width; column ++) {
168 FX_FLOAT x = (FX_FLOAT)column, y = (FX_FLOAT)row;
169 matrix.Transform(x, y);
170 FX_FLOAT b = -2 * (FXSYS_Mul(x - start_x, end_x - start_x) + FXSYS_M ul(y - start_y, end_y - start_y) +
171 FXSYS_Mul(start_r, end_r - start_r));
172 FX_FLOAT c = FXSYS_Mul(x - start_x, x - start_x) + FXSYS_Mul(y - sta rt_y, y - start_y) -
173 FXSYS_Mul(start_r, start_r);
174 FX_FLOAT s;
175 if (a == 0) {
176 s = FXSYS_Div(-c, b);
177 } else {
178 FX_FLOAT b2_4ac = FXSYS_Mul(b, b) - 4 * FXSYS_Mul(a, c);
179 if (b2_4ac < 0) {
180 continue;
181 }
182 FX_FLOAT root = FXSYS_sqrt(b2_4ac);
183 FX_FLOAT s1, s2;
184 if (a > 0) {
185 s1 = FXSYS_Div(-b - root, 2 * a);
186 s2 = FXSYS_Div(-b + root, 2 * a);
187 } else {
188 s2 = FXSYS_Div(-b - root, 2 * a);
189 s1 = FXSYS_Div(-b + root, 2 * a);
190 }
191 if (bDecreasing) {
192 if (s1 >= 0 || bStartExtend) {
193 s = s1;
194 } else {
195 s = s2;
196 }
197 } else {
198 if (s2 <= 1.0f || bEndExtend) {
199 s = s2;
200 } else {
201 s = s1;
202 }
203 }
204 if ((start_r + s * (end_r - start_r)) < 0) {
205 continue;
206 }
207 }
208 int index = (int32_t)(s * (SHADING_STEPS - 1));
209 if (index < 0) {
210 if (!bStartExtend) {
211 continue;
212 }
213 index = 0;
214 }
215 if (index >= SHADING_STEPS) {
216 if (!bEndExtend) {
217 continue;
218 }
219 index = SHADING_STEPS - 1;
220 }
221 dib_buf[column] = rgb_array[index];
222 }
223 }
224 }
225 static void _DrawFuncShading(CFX_DIBitmap* pBitmap, CFX_AffineMatrix* pObject2Bi tmap,
226 CPDF_Dictionary* pDict, CPDF_Function** pFuncs, int nFuncs,
227 CPDF_ColorSpace* pCS, int alpha)
228 {
229 ASSERT(pBitmap->GetFormat() == FXDIB_Argb);
230 CPDF_Array* pDomain = pDict->GetArray(FX_BSTRC("Domain"));
231 FX_FLOAT xmin = 0, ymin = 0, xmax = 1.0f, ymax = 1.0f;
232 if (pDomain) {
233 xmin = pDomain->GetNumber(0);
234 xmax = pDomain->GetNumber(1);
235 ymin = pDomain->GetNumber(2);
236 ymax = pDomain->GetNumber(3);
237 }
238 CFX_AffineMatrix mtDomain2Target = pDict->GetMatrix(FX_BSTRC("Matrix"));
239 CFX_AffineMatrix matrix, reverse_matrix;
240 matrix.SetReverse(*pObject2Bitmap);
241 reverse_matrix.SetReverse(mtDomain2Target);
242 matrix.Concat(reverse_matrix);
243 int width = pBitmap->GetWidth();
244 int height = pBitmap->GetHeight();
245 int pitch = pBitmap->GetPitch();
246 int total_results = 0;
247 for (int j = 0; j < nFuncs; j ++) {
248 if (pFuncs[j]) {
249 total_results += pFuncs[j]->CountOutputs();
250 }
251 }
252 if (pCS->CountComponents() > total_results) {
253 total_results = pCS->CountComponents();
254 }
255 CFX_FixedBufGrow<FX_FLOAT, 16> result_array(total_results);
256 FX_FLOAT* pResults = result_array;
257 FXSYS_memset(pResults, 0, total_results * sizeof(FX_FLOAT));
258 for (int row = 0; row < height; row ++) {
259 FX_DWORD* dib_buf = (FX_DWORD*)(pBitmap->GetBuffer() + row * pitch);
260 for (int column = 0; column < width; column ++) {
261 FX_FLOAT x = (FX_FLOAT)column, y = (FX_FLOAT)row;
262 matrix.Transform(x, y);
263 if (x < xmin || x > xmax || y < ymin || y > ymax) {
264 continue;
265 }
266 FX_FLOAT input[2];
267 int offset = 0;
268 input[0] = x;
269 input[1] = y;
270 for (int j = 0; j < nFuncs; j ++) {
271 if (pFuncs[j]) {
272 int nresults;
273 if (pFuncs[j]->Call(input, 2, pResults + offset, nresults)) {
274 offset += nresults;
275 }
276 }
277 }
278 FX_FLOAT R = 0.0f, G = 0.0f, B = 0.0f;
279 pCS->GetRGB(pResults, R, G, B);
280 dib_buf[column] = FXARGB_TODIB(FXARGB_MAKE(alpha, (int32_t)(R * 255) , (int32_t)(G * 255), (int32_t)(B * 255)));
281 }
282 }
283 }
284 FX_BOOL _GetScanlineIntersect(int y, FX_FLOAT x1, FX_FLOAT y1, FX_FLOAT x2, FX_F LOAT y2, FX_FLOAT& x)
285 {
286 if (y1 == y2) {
287 return FALSE;
288 }
289 if (y1 < y2) {
290 if (y < y1 || y > y2) {
291 return FALSE;
292 }
293 } else { 379 } else {
294 if (y < y2 || y > y1) { 380 min_x = (int)FXSYS_floor(inter_x[1]);
295 return FALSE; 381 max_x = (int)FXSYS_ceil(inter_x[0]);
296 } 382 start_index = 1;
297 } 383 end_index = 0;
298 x = x1 + FXSYS_MulDiv(x2 - x1, y - y1, y2 - y1); 384 }
299 return TRUE; 385 int start_x = min_x, end_x = max_x;
300 } 386 if (start_x < 0) {
301 static void _DrawGouraud(CFX_DIBitmap* pBitmap, int alpha, CPDF_MeshVertex trian gle[3]) 387 start_x = 0;
302 { 388 }
303 FX_FLOAT min_y = triangle[0].y, max_y = triangle[0].y; 389 if (end_x > pBitmap->GetWidth()) {
304 for (int i = 1; i < 3; i ++) { 390 end_x = pBitmap->GetWidth();
305 if (min_y > triangle[i].y) { 391 }
306 min_y = triangle[i].y; 392 uint8_t* dib_buf =
307 } 393 pBitmap->GetBuffer() + y * pBitmap->GetPitch() + start_x * 4;
308 if (max_y < triangle[i].y) { 394 FX_FLOAT r_unit = (r[end_index] - r[start_index]) / (max_x - min_x);
309 max_y = triangle[i].y; 395 FX_FLOAT g_unit = (g[end_index] - g[start_index]) / (max_x - min_x);
310 } 396 FX_FLOAT b_unit = (b[end_index] - b[start_index]) / (max_x - min_x);
311 } 397 FX_FLOAT R = r[start_index] + (start_x - min_x) * r_unit;
312 if (min_y == max_y) { 398 FX_FLOAT G = g[start_index] + (start_x - min_x) * g_unit;
313 return; 399 FX_FLOAT B = b[start_index] + (start_x - min_x) * b_unit;
314 } 400 for (int x = start_x; x < end_x; x++) {
315 int min_yi = (int)FXSYS_floor(min_y), max_yi = (int)FXSYS_ceil(max_y); 401 R += r_unit;
316 if (min_yi < 0) { 402 G += g_unit;
317 min_yi = 0; 403 B += b_unit;
318 } 404 FXARGB_SETDIB(dib_buf,
319 if (max_yi >= pBitmap->GetHeight()) { 405 FXARGB_MAKE(alpha, (int32_t)(R * 255), (int32_t)(G * 255),
320 max_yi = pBitmap->GetHeight() - 1; 406 (int32_t)(B * 255)));
321 } 407 dib_buf += 4;
322 for (int y = min_yi; y <= max_yi; y ++) { 408 }
323 int nIntersects = 0; 409 }
324 FX_FLOAT inter_x[3], r[3], g[3], b[3]; 410 }
325 for (int i = 0; i < 3; i ++) { 411 static void _DrawFreeGouraudShading(CFX_DIBitmap* pBitmap,
326 CPDF_MeshVertex& vertex1 = triangle[i]; 412 CFX_AffineMatrix* pObject2Bitmap,
327 CPDF_MeshVertex& vertex2 = triangle[(i + 1) % 3]; 413 CPDF_Stream* pShadingStream,
328 FX_BOOL bIntersect = _GetScanlineIntersect(y, vertex1.x, vertex1.y, 414 CPDF_Function** pFuncs,
329 vertex2.x, vertex2.y, inter_x[nIntersects]); 415 int nFuncs,
330 if (!bIntersect) { 416 CPDF_ColorSpace* pCS,
331 continue; 417 int alpha) {
332 } 418 ASSERT(pBitmap->GetFormat() == FXDIB_Argb);
333 r[nIntersects] = vertex1.r + FXSYS_MulDiv(vertex2.r - vertex1.r, y - vertex1.y, vertex2.y - vertex1.y); 419 if (pShadingStream->GetType() != PDFOBJ_STREAM) {
334 g[nIntersects] = vertex1.g + FXSYS_MulDiv(vertex2.g - vertex1.g, y - vertex1.y, vertex2.y - vertex1.y); 420 return;
335 b[nIntersects] = vertex1.b + FXSYS_MulDiv(vertex2.b - vertex1.b, y - vertex1.y, vertex2.y - vertex1.y); 421 }
336 nIntersects ++; 422 CPDF_MeshStream stream;
337 } 423 if (!stream.Load(pShadingStream, pFuncs, nFuncs, pCS)) {
338 if (nIntersects != 2) { 424 return;
339 continue; 425 }
340 } 426 CPDF_MeshVertex triangle[3];
341 int min_x, max_x, start_index, end_index; 427 FXSYS_memset(triangle, 0, sizeof(triangle));
342 if (inter_x[0] < inter_x[1]) { 428
343 min_x = (int)FXSYS_floor(inter_x[0]); 429 while (!stream.m_BitStream.IsEOF()) {
344 max_x = (int)FXSYS_ceil(inter_x[1]); 430 CPDF_MeshVertex vertex;
345 start_index = 0; 431 FX_DWORD flag = stream.GetVertex(vertex, pObject2Bitmap);
346 end_index = 1; 432 if (flag == 0) {
347 } else { 433 triangle[0] = vertex;
348 min_x = (int)FXSYS_floor(inter_x[1]); 434 for (int j = 1; j < 3; j++) {
349 max_x = (int)FXSYS_ceil(inter_x[0]); 435 stream.GetVertex(triangle[j], pObject2Bitmap);
350 start_index = 1; 436 }
351 end_index = 0; 437 } else {
352 } 438 if (flag == 1) {
353 int start_x = min_x, end_x = max_x; 439 triangle[0] = triangle[1];
354 if (start_x < 0) { 440 }
355 start_x = 0; 441 triangle[1] = triangle[2];
356 } 442 triangle[2] = vertex;
357 if (end_x > pBitmap->GetWidth()) { 443 }
358 end_x = pBitmap->GetWidth(); 444 _DrawGouraud(pBitmap, alpha, triangle);
359 } 445 }
360 uint8_t* dib_buf = pBitmap->GetBuffer() + y * pBitmap->GetPitch() + star t_x * 4; 446 }
361 FX_FLOAT r_unit = (r[end_index] - r[start_index]) / (max_x - min_x); 447 static void _DrawLatticeGouraudShading(CFX_DIBitmap* pBitmap,
362 FX_FLOAT g_unit = (g[end_index] - g[start_index]) / (max_x - min_x); 448 CFX_AffineMatrix* pObject2Bitmap,
363 FX_FLOAT b_unit = (b[end_index] - b[start_index]) / (max_x - min_x); 449 CPDF_Stream* pShadingStream,
364 FX_FLOAT R = r[start_index] + (start_x - min_x) * r_unit; 450 CPDF_Function** pFuncs,
365 FX_FLOAT G = g[start_index] + (start_x - min_x) * g_unit; 451 int nFuncs,
366 FX_FLOAT B = b[start_index] + (start_x - min_x) * b_unit; 452 CPDF_ColorSpace* pCS,
367 for (int x = start_x; x < end_x; x ++) { 453 int alpha) {
368 R += r_unit; 454 ASSERT(pBitmap->GetFormat() == FXDIB_Argb);
369 G += g_unit; 455 if (pShadingStream->GetType() != PDFOBJ_STREAM) {
370 B += b_unit; 456 return;
371 FXARGB_SETDIB(dib_buf, FXARGB_MAKE(alpha, (int32_t)(R * 255), (int32 _t)(G * 255), (int32_t)(B * 255))); 457 }
372 dib_buf += 4; 458 int row_verts = pShadingStream->GetDict()->GetInteger("VerticesPerRow");
373 } 459 if (row_verts < 2) {
374 } 460 return;
375 } 461 }
376 static void _DrawFreeGouraudShading(CFX_DIBitmap* pBitmap, CFX_AffineMatrix* pOb ject2Bitmap, 462 CPDF_MeshStream stream;
377 CPDF_Stream* pShadingStream, CPDF_Function** pFuncs, int nFuncs, 463 if (!stream.Load(pShadingStream, pFuncs, nFuncs, pCS)) {
378 CPDF_ColorSpace* pCS, int alpha) 464 return;
379 { 465 }
380 ASSERT(pBitmap->GetFormat() == FXDIB_Argb); 466 CPDF_MeshVertex* vertex = FX_Alloc2D(CPDF_MeshVertex, row_verts, 2);
381 if (pShadingStream->GetType() != PDFOBJ_STREAM) { 467 if (!stream.GetVertexRow(vertex, row_verts, pObject2Bitmap)) {
382 return; 468 FX_Free(vertex);
383 } 469 return;
384 CPDF_MeshStream stream; 470 }
385 if (!stream.Load(pShadingStream, pFuncs, nFuncs, pCS)) { 471 int last_index = 0;
386 return; 472 while (1) {
473 CPDF_MeshVertex* last_row = vertex + last_index * row_verts;
474 CPDF_MeshVertex* this_row = vertex + (1 - last_index) * row_verts;
475 if (!stream.GetVertexRow(this_row, row_verts, pObject2Bitmap)) {
476 FX_Free(vertex);
477 return;
387 } 478 }
388 CPDF_MeshVertex triangle[3]; 479 CPDF_MeshVertex triangle[3];
389 FXSYS_memset(triangle, 0, sizeof(triangle)); 480 for (int i = 1; i < row_verts; i++) {
390 481 triangle[0] = last_row[i];
391 while (!stream.m_BitStream.IsEOF()) { 482 triangle[1] = this_row[i - 1];
392 CPDF_MeshVertex vertex; 483 triangle[2] = last_row[i - 1];
393 FX_DWORD flag = stream.GetVertex(vertex, pObject2Bitmap); 484 _DrawGouraud(pBitmap, alpha, triangle);
394 if (flag == 0) { 485 triangle[2] = this_row[i];
395 triangle[0] = vertex; 486 _DrawGouraud(pBitmap, alpha, triangle);
396 for (int j = 1; j < 3; j ++) { 487 }
397 stream.GetVertex(triangle[j], pObject2Bitmap); 488 last_index = 1 - last_index;
398 } 489 }
399 } else { 490 FX_Free(vertex);
400 if (flag == 1) {
401 triangle[0] = triangle[1];
402 }
403 triangle[1] = triangle[2];
404 triangle[2] = vertex;
405 }
406 _DrawGouraud(pBitmap, alpha, triangle);
407 }
408 }
409 static void _DrawLatticeGouraudShading(CFX_DIBitmap* pBitmap, CFX_AffineMatrix* pObject2Bitmap,
410 CPDF_Stream* pShadingStream, CPDF_Functio n** pFuncs, int nFuncs,
411 CPDF_ColorSpace* pCS, int alpha)
412 {
413 ASSERT(pBitmap->GetFormat() == FXDIB_Argb);
414 if (pShadingStream->GetType() != PDFOBJ_STREAM) {
415 return;
416 }
417 int row_verts = pShadingStream->GetDict()->GetInteger("VerticesPerRow");
418 if (row_verts < 2) {
419 return;
420 }
421 CPDF_MeshStream stream;
422 if (!stream.Load(pShadingStream, pFuncs, nFuncs, pCS)) {
423 return;
424 }
425 CPDF_MeshVertex* vertex = FX_Alloc2D(CPDF_MeshVertex, row_verts, 2);
426 if (!stream.GetVertexRow(vertex, row_verts, pObject2Bitmap)) {
427 FX_Free(vertex);
428 return;
429 }
430 int last_index = 0;
431 while (1) {
432 CPDF_MeshVertex* last_row = vertex + last_index * row_verts;
433 CPDF_MeshVertex* this_row = vertex + (1 - last_index) * row_verts;
434 if (!stream.GetVertexRow(this_row, row_verts, pObject2Bitmap)) {
435 FX_Free(vertex);
436 return;
437 }
438 CPDF_MeshVertex triangle[3];
439 for (int i = 1; i < row_verts; i ++) {
440 triangle[0] = last_row[i];
441 triangle[1] = this_row[i - 1];
442 triangle[2] = last_row[i - 1];
443 _DrawGouraud(pBitmap, alpha, triangle);
444 triangle[2] = this_row[i];
445 _DrawGouraud(pBitmap, alpha, triangle);
446 }
447 last_index = 1 - last_index;
448 }
449 FX_Free(vertex);
450 } 491 }
451 struct Coon_BezierCoeff { 492 struct Coon_BezierCoeff {
452 float a, b, c, d; 493 float a, b, c, d;
453 void FromPoints(float p0, float p1, float p2, float p3) 494 void FromPoints(float p0, float p1, float p2, float p3) {
454 { 495 a = -p0 + 3 * p1 - 3 * p2 + p3;
455 a = -p0 + 3 * p1 - 3 * p2 + p3; 496 b = 3 * p0 - 6 * p1 + 3 * p2;
456 b = 3 * p0 - 6 * p1 + 3 * p2; 497 c = -3 * p0 + 3 * p1;
457 c = -3 * p0 + 3 * p1; 498 d = p0;
458 d = p0; 499 }
459 } 500 Coon_BezierCoeff first_half() {
460 Coon_BezierCoeff first_half() 501 Coon_BezierCoeff result;
461 { 502 result.a = a / 8;
462 Coon_BezierCoeff result; 503 result.b = b / 4;
463 result.a = a / 8; 504 result.c = c / 2;
464 result.b = b / 4; 505 result.d = d;
465 result.c = c / 2; 506 return result;
466 result.d = d; 507 }
467 return result; 508 Coon_BezierCoeff second_half() {
468 } 509 Coon_BezierCoeff result;
469 Coon_BezierCoeff second_half() 510 result.a = a / 8;
470 { 511 result.b = 3 * a / 8 + b / 4;
471 Coon_BezierCoeff result; 512 result.c = 3 * a / 8 + b / 2 + c / 2;
472 result.a = a / 8; 513 result.d = a / 8 + b / 4 + c / 2 + d;
473 result.b = 3 * a / 8 + b / 4; 514 return result;
474 result.c = 3 * a / 8 + b / 2 + c / 2; 515 }
475 result.d = a / 8 + b / 4 + c / 2 + d; 516 void GetPoints(float p[4]) {
476 return result; 517 p[0] = d;
477 } 518 p[1] = c / 3 + p[0];
478 void GetPoints(float p[4]) 519 p[2] = b / 3 - p[0] + 2 * p[1];
479 { 520 p[3] = a + p[0] - 3 * p[1] + 3 * p[2];
480 p[0] = d; 521 }
481 p[1] = c / 3 + p[0]; 522 void GetPointsReverse(float p[4]) {
482 p[2] = b / 3 - p[0] + 2 * p[1]; 523 p[3] = d;
483 p[3] = a + p[0] - 3 * p[1] + 3 * p[2]; 524 p[2] = c / 3 + p[3];
484 } 525 p[1] = b / 3 - p[3] + 2 * p[2];
485 void GetPointsReverse(float p[4]) 526 p[0] = a + p[3] - 3 * p[2] + 3 * p[1];
486 { 527 }
487 p[3] = d; 528 void BezierInterpol(Coon_BezierCoeff& C1,
488 p[2] = c / 3 + p[3]; 529 Coon_BezierCoeff& C2,
489 p[1] = b / 3 - p[3] + 2 * p[2]; 530 Coon_BezierCoeff& D1,
490 p[0] = a + p[3] - 3 * p[2] + 3 * p[1]; 531 Coon_BezierCoeff& D2) {
491 } 532 a = (D1.a + D2.a) / 2;
492 void BezierInterpol(Coon_BezierCoeff& C1, Coon_BezierCoeff& C2, Coon_BezierC oeff& D1, Coon_BezierCoeff& D2) 533 b = (D1.b + D2.b) / 2;
493 { 534 c = (D1.c + D2.c) / 2 - (C1.a / 8 + C1.b / 4 + C1.c / 2) +
494 a = (D1.a + D2.a) / 2; 535 (C2.a / 8 + C2.b / 4) + (-C1.d + D2.d) / 2 - (C2.a + C2.b) / 2;
495 b = (D1.b + D2.b) / 2; 536 d = C1.a / 8 + C1.b / 4 + C1.c / 2 + C1.d;
496 c = (D1.c + D2.c) / 2 - (C1.a / 8 + C1.b / 4 + C1.c / 2) + (C2.a / 8 + C 2.b / 4) + (-C1.d + D2.d) / 2 - (C2.a + C2.b) / 2; 537 }
497 d = C1.a / 8 + C1.b / 4 + C1.c / 2 + C1.d; 538 float Distance() {
498 } 539 float dis = a + b + c;
499 float Distance() 540 return dis < 0 ? -dis : dis;
500 { 541 }
501 float dis = a + b + c;
502 return dis < 0 ? -dis : dis;
503 }
504 }; 542 };
505 struct Coon_Bezier { 543 struct Coon_Bezier {
506 Coon_BezierCoeff x, y; 544 Coon_BezierCoeff x, y;
507 void FromPoints(float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3) 545 void FromPoints(float x0,
508 { 546 float y0,
509 x.FromPoints(x0, x1, x2, x3); 547 float x1,
510 y.FromPoints(y0, y1, y2, y3); 548 float y1,
511 } 549 float x2,
512 Coon_Bezier first_half() 550 float y2,
513 { 551 float x3,
514 Coon_Bezier result; 552 float y3) {
515 result.x = x.first_half(); 553 x.FromPoints(x0, x1, x2, x3);
516 result.y = y.first_half(); 554 y.FromPoints(y0, y1, y2, y3);
517 return result; 555 }
518 } 556 Coon_Bezier first_half() {
519 Coon_Bezier second_half() 557 Coon_Bezier result;
520 { 558 result.x = x.first_half();
521 Coon_Bezier result; 559 result.y = y.first_half();
522 result.x = x.second_half(); 560 return result;
523 result.y = y.second_half(); 561 }
524 return result; 562 Coon_Bezier second_half() {
525 } 563 Coon_Bezier result;
526 void BezierInterpol(Coon_Bezier& C1, Coon_Bezier& C2, Coon_Bezier& D1, Coon_ Bezier& D2) 564 result.x = x.second_half();
527 { 565 result.y = y.second_half();
528 x.BezierInterpol(C1.x, C2.x, D1.x, D2.x); 566 return result;
529 y.BezierInterpol(C1.y, C2.y, D1.y, D2.y); 567 }
530 } 568 void BezierInterpol(Coon_Bezier& C1,
531 void GetPoints(FX_PATHPOINT* pPoints) 569 Coon_Bezier& C2,
532 { 570 Coon_Bezier& D1,
533 float p[4]; 571 Coon_Bezier& D2) {
534 int i; 572 x.BezierInterpol(C1.x, C2.x, D1.x, D2.x);
535 x.GetPoints(p); 573 y.BezierInterpol(C1.y, C2.y, D1.y, D2.y);
536 for (i = 0; i < 4; i ++) { 574 }
537 pPoints[i].m_PointX = p[i]; 575 void GetPoints(FX_PATHPOINT* pPoints) {
538 } 576 float p[4];
539 y.GetPoints(p); 577 int i;
540 for (i = 0; i < 4; i ++) { 578 x.GetPoints(p);
541 pPoints[i].m_PointY = p[i]; 579 for (i = 0; i < 4; i++) {
542 } 580 pPoints[i].m_PointX = p[i];
543 } 581 }
544 void GetPointsReverse(FX_PATHPOINT* pPoints) 582 y.GetPoints(p);
545 { 583 for (i = 0; i < 4; i++) {
546 float p[4]; 584 pPoints[i].m_PointY = p[i];
547 int i; 585 }
548 x.GetPointsReverse(p); 586 }
549 for (i = 0; i < 4; i ++) { 587 void GetPointsReverse(FX_PATHPOINT* pPoints) {
550 pPoints[i].m_PointX = p[i]; 588 float p[4];
551 } 589 int i;
552 y.GetPointsReverse(p); 590 x.GetPointsReverse(p);
553 for (i = 0; i < 4; i ++) { 591 for (i = 0; i < 4; i++) {
554 pPoints[i].m_PointY = p[i]; 592 pPoints[i].m_PointX = p[i];
555 } 593 }
556 } 594 y.GetPointsReverse(p);
557 float Distance() 595 for (i = 0; i < 4; i++) {
558 { 596 pPoints[i].m_PointY = p[i];
559 return x.Distance() + y.Distance(); 597 }
560 } 598 }
599 float Distance() { return x.Distance() + y.Distance(); }
561 }; 600 };
562 static int _BiInterpol(int c0, int c1, int c2, int c3, int x, int y, int x_scale , int y_scale) 601 static int _BiInterpol(int c0,
563 { 602 int c1,
564 int x1 = c0 + (c3 - c0) * x / x_scale; 603 int c2,
565 int x2 = c1 + (c2 - c1) * x / x_scale; 604 int c3,
566 return x1 + (x2 - x1) * y / y_scale; 605 int x,
606 int y,
607 int x_scale,
608 int y_scale) {
609 int x1 = c0 + (c3 - c0) * x / x_scale;
610 int x2 = c1 + (c2 - c1) * x / x_scale;
611 return x1 + (x2 - x1) * y / y_scale;
567 } 612 }
568 struct Coon_Color { 613 struct Coon_Color {
569 Coon_Color() 614 Coon_Color() { FXSYS_memset(comp, 0, sizeof(int) * 3); }
570 { 615 int comp[3];
571 FXSYS_memset(comp, 0, sizeof(int) * 3); 616 void BiInterpol(Coon_Color colors[4],
572 } 617 int x,
573 int»» comp[3]; 618 int y,
574 void» BiInterpol(Coon_Color colors[4], int x, int y, int x_scale, int y_scale) 619 int x_scale,
575 { 620 int y_scale) {
576 for (int i = 0; i < 3; i ++) 621 for (int i = 0; i < 3; i++)
577 comp[i] = _BiInterpol(colors[0].comp[i], colors[1].comp[i], colors[2 ].comp[i], colors[3].comp[i], 622 comp[i] =
578 x, y, x_scale, y_scale); 623 _BiInterpol(colors[0].comp[i], colors[1].comp[i], colors[2].comp[i],
579 } 624 colors[3].comp[i], x, y, x_scale, y_scale);
580 int»» Distance(Coon_Color& o) 625 }
581 { 626 int Distance(Coon_Color& o) {
582 int max, diff; 627 int max, diff;
583 max = FXSYS_abs(comp[0] - o.comp[0]); 628 max = FXSYS_abs(comp[0] - o.comp[0]);
584 diff = FXSYS_abs(comp[1] - o.comp[1]); 629 diff = FXSYS_abs(comp[1] - o.comp[1]);
585 if (max < diff) { 630 if (max < diff) {
586 max = diff; 631 max = diff;
587 } 632 }
588 diff = FXSYS_abs(comp[2] - o.comp[2]); 633 diff = FXSYS_abs(comp[2] - o.comp[2]);
589 if (max < diff) { 634 if (max < diff) {
590 max = diff; 635 max = diff;
591 } 636 }
592 return max; 637 return max;
593 } 638 }
594 }; 639 };
595 struct CPDF_PatchDrawer { 640 struct CPDF_PatchDrawer {
596 Coon_Color» » » patch_colors[4]; 641 Coon_Color patch_colors[4];
597 int»» » » » max_delta; 642 int max_delta;
598 CFX_PathData» » path; 643 CFX_PathData path;
599 CFX_RenderDevice*» pDevice; 644 CFX_RenderDevice* pDevice;
600 int»» » » » fill_mode; 645 int fill_mode;
601 int»» » » » alpha; 646 int alpha;
602 void Draw(int x_scale, int y_scale, int left, int bottom, Coon_Bezier C1, Co on_Bezier C2, Coon_Bezier D1, Coon_Bezier D2) 647 void Draw(int x_scale,
603 { 648 int y_scale,
604 FX_BOOL bSmall = C1.Distance() < 2 && C2.Distance() < 2 && D1.Distance() < 2 && D2.Distance() < 2; 649 int left,
605 Coon_Color div_colors[4]; 650 int bottom,
606 int d_bottom, d_left, d_top, d_right; 651 Coon_Bezier C1,
607 div_colors[0].BiInterpol(patch_colors, left, bottom, x_scale, y_scale); 652 Coon_Bezier C2,
608 if (!bSmall) { 653 Coon_Bezier D1,
609 div_colors[1].BiInterpol(patch_colors, left, bottom + 1, x_scale, y_ scale); 654 Coon_Bezier D2) {
610 div_colors[2].BiInterpol(patch_colors, left + 1, bottom + 1, x_scale , y_scale); 655 FX_BOOL bSmall = C1.Distance() < 2 && C2.Distance() < 2 &&
611 div_colors[3].BiInterpol(patch_colors, left + 1, bottom, x_scale, y_ scale); 656 D1.Distance() < 2 && D2.Distance() < 2;
612 d_bottom = div_colors[3].Distance(div_colors[0]); 657 Coon_Color div_colors[4];
613 d_left = div_colors[1].Distance(div_colors[0]); 658 int d_bottom, d_left, d_top, d_right;
614 d_top = div_colors[1].Distance(div_colors[2]); 659 div_colors[0].BiInterpol(patch_colors, left, bottom, x_scale, y_scale);
615 d_right = div_colors[2].Distance(div_colors[3]); 660 if (!bSmall) {
616 } 661 div_colors[1].BiInterpol(patch_colors, left, bottom + 1, x_scale,
662 y_scale);
663 div_colors[2].BiInterpol(patch_colors, left + 1, bottom + 1, x_scale,
664 y_scale);
665 div_colors[3].BiInterpol(patch_colors, left + 1, bottom, x_scale,
666 y_scale);
667 d_bottom = div_colors[3].Distance(div_colors[0]);
668 d_left = div_colors[1].Distance(div_colors[0]);
669 d_top = div_colors[1].Distance(div_colors[2]);
670 d_right = div_colors[2].Distance(div_colors[3]);
671 }
617 #define COONCOLOR_THRESHOLD 4 672 #define COONCOLOR_THRESHOLD 4
618 if (bSmall || (d_bottom < COONCOLOR_THRESHOLD && d_left < COONCOLOR_THRE SHOLD && 673 if (bSmall ||
619 d_top < COONCOLOR_THRESHOLD && d_right < COONCOLOR_THRESH OLD)) { 674 (d_bottom < COONCOLOR_THRESHOLD && d_left < COONCOLOR_THRESHOLD &&
620 FX_PATHPOINT* pPoints = path.GetPoints(); 675 d_top < COONCOLOR_THRESHOLD && d_right < COONCOLOR_THRESHOLD)) {
621 C1.GetPoints(pPoints); 676 FX_PATHPOINT* pPoints = path.GetPoints();
622 D2.GetPoints(pPoints + 3); 677 C1.GetPoints(pPoints);
623 C2.GetPointsReverse(pPoints + 6); 678 D2.GetPoints(pPoints + 3);
624 D1.GetPointsReverse(pPoints + 9); 679 C2.GetPointsReverse(pPoints + 6);
625 int fillFlags = FXFILL_WINDING | FXFILL_FULLCOVER; 680 D1.GetPointsReverse(pPoints + 9);
626 if (fill_mode & RENDER_NOPATHSMOOTH) { 681 int fillFlags = FXFILL_WINDING | FXFILL_FULLCOVER;
627 fillFlags |= FXFILL_NOPATHSMOOTH; 682 if (fill_mode & RENDER_NOPATHSMOOTH) {
628 } 683 fillFlags |= FXFILL_NOPATHSMOOTH;
629 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); 684 }
630 } else { 685 pDevice->DrawPath(
631 if (d_bottom < COONCOLOR_THRESHOLD && d_top < COONCOLOR_THRESHOLD) { 686 &path, NULL, NULL,
632 Coon_Bezier m1; 687 FXARGB_MAKE(alpha, div_colors[0].comp[0], div_colors[0].comp[1],
633 m1.BezierInterpol(D1, D2, C1, C2); 688 div_colors[0].comp[2]),
634 y_scale *= 2; 689 0, fillFlags);
635 bottom *= 2; 690 } else {
636 Draw(x_scale, y_scale, left, bottom, C1, m1, D1.first_half(), D2 .first_half()); 691 if (d_bottom < COONCOLOR_THRESHOLD && d_top < COONCOLOR_THRESHOLD) {
637 Draw(x_scale, y_scale, left, bottom + 1, m1, C2, D1.second_half( ), D2.second_half()); 692 Coon_Bezier m1;
638 } else if (d_left < COONCOLOR_THRESHOLD && d_right < COONCOLOR_THRES HOLD) { 693 m1.BezierInterpol(D1, D2, C1, C2);
639 Coon_Bezier m2; 694 y_scale *= 2;
640 m2.BezierInterpol(C1, C2, D1, D2); 695 bottom *= 2;
641 x_scale *= 2; 696 Draw(x_scale, y_scale, left, bottom, C1, m1, D1.first_half(),
642 left *= 2; 697 D2.first_half());
643 Draw(x_scale, y_scale, left, bottom, C1.first_half(), C2.first_h alf(), D1, m2); 698 Draw(x_scale, y_scale, left, bottom + 1, m1, C2, D1.second_half(),
644 Draw(x_scale, y_scale, left + 1, bottom, C1.second_half(), C2.se cond_half(), m2, D2); 699 D2.second_half());
645 } else { 700 } else if (d_left < COONCOLOR_THRESHOLD &&
646 Coon_Bezier m1, m2; 701 d_right < COONCOLOR_THRESHOLD) {
647 m1.BezierInterpol(D1, D2, C1, C2); 702 Coon_Bezier m2;
648 m2.BezierInterpol(C1, C2, D1, D2); 703 m2.BezierInterpol(C1, C2, D1, D2);
649 Coon_Bezier m1f = m1.first_half(); 704 x_scale *= 2;
650 Coon_Bezier m1s = m1.second_half(); 705 left *= 2;
651 Coon_Bezier m2f = m2.first_half(); 706 Draw(x_scale, y_scale, left, bottom, C1.first_half(), C2.first_half(),
652 Coon_Bezier m2s = m2.second_half(); 707 D1, m2);
653 x_scale *= 2; 708 Draw(x_scale, y_scale, left + 1, bottom, C1.second_half(),
654 y_scale *= 2; 709 C2.second_half(), m2, D2);
655 left *= 2; 710 } else {
656 bottom *= 2; 711 Coon_Bezier m1, m2;
657 Draw(x_scale, y_scale, left, bottom, C1.first_half(), m1f, D1.fi rst_half(), m2f); 712 m1.BezierInterpol(D1, D2, C1, C2);
658 Draw(x_scale, y_scale, left, bottom + 1, m1f, C2.first_half(), D 1.second_half(), m2s); 713 m2.BezierInterpol(C1, C2, D1, D2);
659 Draw(x_scale, y_scale, left + 1, bottom, C1.second_half(), m1s, m2f, D2.first_half()); 714 Coon_Bezier m1f = m1.first_half();
660 Draw(x_scale, y_scale, left + 1, bottom + 1, m1s, C2.second_half (), m2s, D2.second_half()); 715 Coon_Bezier m1s = m1.second_half();
661 } 716 Coon_Bezier m2f = m2.first_half();
662 } 717 Coon_Bezier m2s = m2.second_half();
663 } 718 x_scale *= 2;
719 y_scale *= 2;
720 left *= 2;
721 bottom *= 2;
722 Draw(x_scale, y_scale, left, bottom, C1.first_half(), m1f,
723 D1.first_half(), m2f);
724 Draw(x_scale, y_scale, left, bottom + 1, m1f, C2.first_half(),
725 D1.second_half(), m2s);
726 Draw(x_scale, y_scale, left + 1, bottom, C1.second_half(), m1s, m2f,
727 D2.first_half());
728 Draw(x_scale, y_scale, left + 1, bottom + 1, m1s, C2.second_half(), m2s,
729 D2.second_half());
730 }
731 }
732 }
664 }; 733 };
665 734
666 FX_BOOL _CheckCoonTensorPara(const CPDF_MeshStream &stream) 735 FX_BOOL _CheckCoonTensorPara(const CPDF_MeshStream& stream) {
667 { 736 FX_BOOL bCoorBits = (stream.m_nCoordBits == 1 || stream.m_nCoordBits == 2 ||
668 FX_BOOL bCoorBits = ( stream.m_nCoordBits== 1 || 737 stream.m_nCoordBits == 4 || stream.m_nCoordBits == 8 ||
669 stream.m_nCoordBits == 2 || 738 stream.m_nCoordBits == 12 || stream.m_nCoordBits == 16 ||
670 stream.m_nCoordBits == 4 || 739 stream.m_nCoordBits == 24 || stream.m_nCoordBits == 32);
671 stream.m_nCoordBits == 8 ||
672 stream.m_nCoordBits == 12 ||
673 stream.m_nCoordBits == 16 ||
674 stream.m_nCoordBits == 24 ||
675 stream.m_nCoordBits == 32 );
676 740
677 FX_BOOL bCompBits = ( stream.m_nCompBits == 1 || 741 FX_BOOL bCompBits = (stream.m_nCompBits == 1 || stream.m_nCompBits == 2 ||
678 stream.m_nCompBits == 2 || 742 stream.m_nCompBits == 4 || stream.m_nCompBits == 8 ||
679 stream.m_nCompBits == 4 || 743 stream.m_nCompBits == 12 || stream.m_nCompBits == 16);
680 stream.m_nCompBits == 8 ||
681 stream.m_nCompBits == 12 ||
682 stream.m_nCompBits == 16 );
683 744
684 FX_BOOL bFlagBits = ( stream.m_nFlagBits == 2 || 745 FX_BOOL bFlagBits = (stream.m_nFlagBits == 2 || stream.m_nFlagBits == 4 ||
685 stream.m_nFlagBits == 4 || 746 stream.m_nFlagBits == 8);
686 stream.m_nFlagBits == 8 );
687 747
688 return bCoorBits && bCompBits && bFlagBits; 748 return bCoorBits && bCompBits && bFlagBits;
689 } 749 }
690 750
691 static void _DrawCoonPatchMeshes(FX_BOOL bTensor, CFX_DIBitmap* pBitmap, CFX_Aff ineMatrix* pObject2Bitmap, 751 static void _DrawCoonPatchMeshes(FX_BOOL bTensor,
692 CPDF_Stream* pShadingStream, CPDF_Function** pF uncs, int nFuncs, 752 CFX_DIBitmap* pBitmap,
693 CPDF_ColorSpace* pCS, int fill_mode, int alpha) 753 CFX_AffineMatrix* pObject2Bitmap,
694 { 754 CPDF_Stream* pShadingStream,
695 ASSERT(pBitmap->GetFormat() == FXDIB_Argb); 755 CPDF_Function** pFuncs,
696 if (pShadingStream->GetType() != PDFOBJ_STREAM) { 756 int nFuncs,
697 return; 757 CPDF_ColorSpace* pCS,
698 } 758 int fill_mode,
699 CFX_FxgeDevice device; 759 int alpha) {
700 device.Attach(pBitmap); 760 ASSERT(pBitmap->GetFormat() == FXDIB_Argb);
701 CPDF_MeshStream stream; 761 if (pShadingStream->GetType() != PDFOBJ_STREAM) {
702 if (!stream.Load(pShadingStream, pFuncs, nFuncs, pCS)) { 762 return;
703 return; 763 }
704 } 764 CFX_FxgeDevice device;
765 device.Attach(pBitmap);
766 CPDF_MeshStream stream;
767 if (!stream.Load(pShadingStream, pFuncs, nFuncs, pCS)) {
768 return;
769 }
705 770
706 if (!_CheckCoonTensorPara(stream)) { 771 if (!_CheckCoonTensorPara(stream)) {
707 return; 772 return;
708 } 773 }
709 774
710 CPDF_PatchDrawer patch; 775 CPDF_PatchDrawer patch;
711 patch.alpha = alpha; 776 patch.alpha = alpha;
712 patch.pDevice = &device; 777 patch.pDevice = &device;
713 patch.fill_mode = fill_mode; 778 patch.fill_mode = fill_mode;
714 patch.path.SetPointCount(13); 779 patch.path.SetPointCount(13);
715 FX_PATHPOINT* pPoints = patch.path.GetPoints(); 780 FX_PATHPOINT* pPoints = patch.path.GetPoints();
716 pPoints[0].m_Flag = FXPT_MOVETO; 781 pPoints[0].m_Flag = FXPT_MOVETO;
717 for (int i = 1; i < 13; i ++) { 782 for (int i = 1; i < 13; i++) {
718 pPoints[i].m_Flag = FXPT_BEZIERTO; 783 pPoints[i].m_Flag = FXPT_BEZIERTO;
719 } 784 }
720 CFX_FloatPoint coords[16]; 785 CFX_FloatPoint coords[16];
721 for (int i = 0; i < 16; i ++) { 786 for (int i = 0; i < 16; i++) {
722 coords[i].Set(0.0f, 0.0f); 787 coords[i].Set(0.0f, 0.0f);
723 } 788 }
724 789
725 int point_count = bTensor ? 16 : 12; 790 int point_count = bTensor ? 16 : 12;
726 while (!stream.m_BitStream.IsEOF()) { 791 while (!stream.m_BitStream.IsEOF()) {
727 FX_DWORD flag = stream.GetFlag(); 792 FX_DWORD flag = stream.GetFlag();
728 int iStartPoint = 0, iStartColor = 0, i = 0; 793 int iStartPoint = 0, iStartColor = 0, i = 0;
729 if (flag) { 794 if (flag) {
730 iStartPoint = 4; 795 iStartPoint = 4;
731 iStartColor = 2; 796 iStartColor = 2;
732 CFX_FloatPoint tempCoords[4]; 797 CFX_FloatPoint tempCoords[4];
733 for (i = 0; i < 4; i ++) { 798 for (i = 0; i < 4; i++) {
734 tempCoords[i] = coords[(flag * 3 + i) % 12]; 799 tempCoords[i] = coords[(flag * 3 + i) % 12];
735 } 800 }
736 FXSYS_memcpy(coords, tempCoords, sizeof(CFX_FloatPoint) * 4); 801 FXSYS_memcpy(coords, tempCoords, sizeof(CFX_FloatPoint) * 4);
737 Coon_Color tempColors[2]; 802 Coon_Color tempColors[2];
738 tempColors[0] = patch.patch_colors[flag]; 803 tempColors[0] = patch.patch_colors[flag];
739 tempColors[1] = patch.patch_colors[(flag + 1) % 4]; 804 tempColors[1] = patch.patch_colors[(flag + 1) % 4];
740 FXSYS_memcpy(patch.patch_colors, tempColors, sizeof(Coon_Color) * 2) ; 805 FXSYS_memcpy(patch.patch_colors, tempColors, sizeof(Coon_Color) * 2);
741 } 806 }
742 for (i = iStartPoint; i < point_count; i ++) { 807 for (i = iStartPoint; i < point_count; i++) {
743 stream.GetCoords(coords[i].x, coords[i].y); 808 stream.GetCoords(coords[i].x, coords[i].y);
744 pObject2Bitmap->Transform(coords[i].x, coords[i].y); 809 pObject2Bitmap->Transform(coords[i].x, coords[i].y);
745 } 810 }
746 for (i = iStartColor; i < 4; i ++) { 811 for (i = iStartColor; i < 4; i++) {
747 FX_FLOAT r=0.0f, g=0.0f, b=0.0f; 812 FX_FLOAT r = 0.0f, g = 0.0f, b = 0.0f;
748 stream.GetColor(r, g, b); 813 stream.GetColor(r, g, b);
749 patch.patch_colors[i].comp[0] = (int32_t)(r * 255); 814 patch.patch_colors[i].comp[0] = (int32_t)(r * 255);
750 patch.patch_colors[i].comp[1] = (int32_t)(g * 255); 815 patch.patch_colors[i].comp[1] = (int32_t)(g * 255);
751 patch.patch_colors[i].comp[2] = (int32_t)(b * 255); 816 patch.patch_colors[i].comp[2] = (int32_t)(b * 255);
752 } 817 }
753 CFX_FloatRect bbox = CFX_FloatRect::GetBBox(coords, point_count); 818 CFX_FloatRect bbox = CFX_FloatRect::GetBBox(coords, point_count);
754 if (bbox.right <= 0 || bbox.left >= (FX_FLOAT)pBitmap->GetWidth() || bbo x.top <= 0 || 819 if (bbox.right <= 0 || bbox.left >= (FX_FLOAT)pBitmap->GetWidth() ||
755 bbox.bottom >= (FX_FLOAT)pBitmap->GetHeight()) { 820 bbox.top <= 0 || bbox.bottom >= (FX_FLOAT)pBitmap->GetHeight()) {
756 continue; 821 continue;
757 } 822 }
758 Coon_Bezier C1, C2, D1, D2; 823 Coon_Bezier C1, C2, D1, D2;
759 C1.FromPoints(coords[0].x, coords[0].y, coords[11].x, coords[11].y, coor ds[10].x, coords[10].y, 824 C1.FromPoints(coords[0].x, coords[0].y, coords[11].x, coords[11].y,
760 coords[9].x, coords[9].y); 825 coords[10].x, coords[10].y, coords[9].x, coords[9].y);
761 C2.FromPoints(coords[3].x, coords[3].y, coords[4].x, coords[4].y, coords [5].x, coords[5].y, 826 C2.FromPoints(coords[3].x, coords[3].y, coords[4].x, coords[4].y,
762 coords[6].x, coords[6].y); 827 coords[5].x, coords[5].y, coords[6].x, coords[6].y);
763 D1.FromPoints(coords[0].x, coords[0].y, coords[1].x, coords[1].y, coords [2].x, coords[2].y, 828 D1.FromPoints(coords[0].x, coords[0].y, coords[1].x, coords[1].y,
764 coords[3].x, coords[3].y); 829 coords[2].x, coords[2].y, coords[3].x, coords[3].y);
765 D2.FromPoints(coords[9].x, coords[9].y, coords[8].x, coords[8].y, coords [7].x, coords[7].y, 830 D2.FromPoints(coords[9].x, coords[9].y, coords[8].x, coords[8].y,
766 coords[6].x, coords[6].y); 831 coords[7].x, coords[7].y, coords[6].x, coords[6].y);
767 patch.Draw(1, 1, 0, 0, C1, C2, D1, D2); 832 patch.Draw(1, 1, 0, 0, C1, C2, D1, D2);
768 } 833 }
769 } 834 }
770 void CPDF_RenderStatus::DrawShading(CPDF_ShadingPattern* pPattern, CFX_AffineMat rix* pMatrix, 835 void CPDF_RenderStatus::DrawShading(CPDF_ShadingPattern* pPattern,
771 FX_RECT& clip_rect, int alpha, FX_BOOL bAlph aMode) 836 CFX_AffineMatrix* pMatrix,
772 { 837 FX_RECT& clip_rect,
773 CPDF_Function** pFuncs = pPattern->m_pFunctions; 838 int alpha,
774 int nFuncs = pPattern->m_nFuncs; 839 FX_BOOL bAlphaMode) {
775 CPDF_Dictionary* pDict = pPattern->m_pShadingObj->GetDict(); 840 CPDF_Function** pFuncs = pPattern->m_pFunctions;
776 CPDF_ColorSpace* pColorSpace = pPattern->m_pCS; 841 int nFuncs = pPattern->m_nFuncs;
777 if (pColorSpace == NULL) { 842 CPDF_Dictionary* pDict = pPattern->m_pShadingObj->GetDict();
778 return; 843 CPDF_ColorSpace* pColorSpace = pPattern->m_pCS;
779 } 844 if (pColorSpace == NULL) {
780 FX_ARGB background = 0; 845 return;
781 if (!pPattern->m_bShadingObj && pPattern->m_pShadingObj->GetDict()->KeyExist (FX_BSTRC("Background"))) { 846 }
782 CPDF_Array* pBackColor = pPattern->m_pShadingObj->GetDict()->GetArray(FX _BSTRC("Background")); 847 FX_ARGB background = 0;
783 if (pBackColor && pBackColor->GetCount() >= (FX_DWORD)pColorSpace->Count Components()) { 848 if (!pPattern->m_bShadingObj &&
784 CFX_FixedBufGrow<FX_FLOAT, 16> comps(pColorSpace->CountComponents()) ; 849 pPattern->m_pShadingObj->GetDict()->KeyExist(FX_BSTRC("Background"))) {
785 for (int i = 0; i < pColorSpace->CountComponents(); i ++) { 850 CPDF_Array* pBackColor =
786 comps[i] = pBackColor->GetNumber(i); 851 pPattern->m_pShadingObj->GetDict()->GetArray(FX_BSTRC("Background"));
787 } 852 if (pBackColor &&
788 FX_FLOAT R = 0.0f, G = 0.0f, B = 0.0f; 853 pBackColor->GetCount() >= (FX_DWORD)pColorSpace->CountComponents()) {
789 pColorSpace->GetRGB(comps, R, G, B); 854 CFX_FixedBufGrow<FX_FLOAT, 16> comps(pColorSpace->CountComponents());
790 background = ArgbEncode(255, (int32_t)(R * 255), (int32_t)(G * 255), (int32_t)(B * 255)); 855 for (int i = 0; i < pColorSpace->CountComponents(); i++) {
791 } 856 comps[i] = pBackColor->GetNumber(i);
792 } 857 }
793 if (pDict->KeyExist(FX_BSTRC("BBox"))) { 858 FX_FLOAT R = 0.0f, G = 0.0f, B = 0.0f;
794 CFX_FloatRect rect = pDict->GetRect(FX_BSTRC("BBox")); 859 pColorSpace->GetRGB(comps, R, G, B);
795 rect.Transform(pMatrix); 860 background = ArgbEncode(255, (int32_t)(R * 255), (int32_t)(G * 255),
796 clip_rect.Intersect(rect.GetOutterRect()); 861 (int32_t)(B * 255));
797 } 862 }
798 CPDF_DeviceBuffer buffer; 863 }
799 buffer.Initialize(m_pContext, m_pDevice, &clip_rect, m_pCurObj, 150); 864 if (pDict->KeyExist(FX_BSTRC("BBox"))) {
800 CFX_AffineMatrix FinalMatrix = *pMatrix; 865 CFX_FloatRect rect = pDict->GetRect(FX_BSTRC("BBox"));
801 FinalMatrix.Concat(*buffer.GetMatrix()); 866 rect.Transform(pMatrix);
802 CFX_DIBitmap* pBitmap = buffer.GetBitmap(); 867 clip_rect.Intersect(rect.GetOutterRect());
803 if (pBitmap->GetBuffer() == NULL) { 868 }
804 return; 869 CPDF_DeviceBuffer buffer;
805 } 870 buffer.Initialize(m_pContext, m_pDevice, &clip_rect, m_pCurObj, 150);
806 pBitmap->Clear(background); 871 CFX_AffineMatrix FinalMatrix = *pMatrix;
807 int fill_mode = m_Options.m_Flags; 872 FinalMatrix.Concat(*buffer.GetMatrix());
808 switch (pPattern->m_ShadingType) { 873 CFX_DIBitmap* pBitmap = buffer.GetBitmap();
809 case 1: 874 if (pBitmap->GetBuffer() == NULL) {
810 _DrawFuncShading(pBitmap, &FinalMatrix, pDict, pFuncs, nFuncs, pColo rSpace, alpha); 875 return;
811 break; 876 }
812 case 2: 877 pBitmap->Clear(background);
813 _DrawAxialShading(pBitmap, &FinalMatrix, pDict, pFuncs, nFuncs, pCol orSpace, alpha); 878 int fill_mode = m_Options.m_Flags;
814 break; 879 switch (pPattern->m_ShadingType) {
815 case 3: 880 case 1:
816 _DrawRadialShading(pBitmap, &FinalMatrix, pDict, pFuncs, nFuncs, pCo lorSpace, alpha); 881 _DrawFuncShading(pBitmap, &FinalMatrix, pDict, pFuncs, nFuncs,
817 break; 882 pColorSpace, alpha);
818 case 4: { 883 break;
819 _DrawFreeGouraudShading(pBitmap, &FinalMatrix, (CPDF_Stream*)pPa ttern->m_pShadingObj, 884 case 2:
820 pFuncs, nFuncs, pColorSpace, alpha); 885 _DrawAxialShading(pBitmap, &FinalMatrix, pDict, pFuncs, nFuncs,
821 } 886 pColorSpace, alpha);
822 break; 887 break;
823 case 5: { 888 case 3:
824 _DrawLatticeGouraudShading(pBitmap, &FinalMatrix, (CPDF_Stream*) pPattern->m_pShadingObj, 889 _DrawRadialShading(pBitmap, &FinalMatrix, pDict, pFuncs, nFuncs,
825 pFuncs, nFuncs, pColorSpace, alpha); 890 pColorSpace, alpha);
826 } 891 break;
827 break; 892 case 4: {
828 case 6: 893 _DrawFreeGouraudShading(pBitmap, &FinalMatrix,
829 case 7: { 894 (CPDF_Stream*)pPattern->m_pShadingObj, pFuncs,
830 _DrawCoonPatchMeshes(pPattern->m_ShadingType - 6, pBitmap, &Fina lMatrix, (CPDF_Stream*)pPattern->m_pShadingObj, 895 nFuncs, pColorSpace, alpha);
831 pFuncs, nFuncs, pColorSpace, fill_mode, alp ha); 896 } break;
832 } 897 case 5: {
833 break; 898 _DrawLatticeGouraudShading(pBitmap, &FinalMatrix,
834 } 899 (CPDF_Stream*)pPattern->m_pShadingObj, pFuncs,
835 if (bAlphaMode) { 900 nFuncs, pColorSpace, alpha);
836 pBitmap->LoadChannel(FXDIB_Red, pBitmap, FXDIB_Alpha); 901 } break;
837 } 902 case 6:
838 if (m_Options.m_ColorMode == RENDER_COLOR_GRAY) { 903 case 7: {
839 pBitmap->ConvertColorScale(m_Options.m_ForeColor, m_Options.m_BackColor) ; 904 _DrawCoonPatchMeshes(pPattern->m_ShadingType - 6, pBitmap, &FinalMatrix,
840 } 905 (CPDF_Stream*)pPattern->m_pShadingObj, pFuncs,
841 buffer.OutputToDevice(); 906 nFuncs, pColorSpace, fill_mode, alpha);
842 } 907 } break;
843 void CPDF_RenderStatus::DrawShadingPattern(CPDF_ShadingPattern* pattern, CPDF_Pa geObject* pPageObj, const CFX_AffineMatrix* pObj2Device, FX_BOOL bStroke) 908 }
844 { 909 if (bAlphaMode) {
845 if (!pattern->Load()) { 910 pBitmap->LoadChannel(FXDIB_Red, pBitmap, FXDIB_Alpha);
846 return; 911 }
847 } 912 if (m_Options.m_ColorMode == RENDER_COLOR_GRAY) {
848 m_pDevice->SaveState(); 913 pBitmap->ConvertColorScale(m_Options.m_ForeColor, m_Options.m_BackColor);
849 if (pPageObj->m_Type == PDFPAGE_PATH) { 914 }
850 if (!SelectClipPath((CPDF_PathObject*)pPageObj, pObj2Device, bStroke)) { 915 buffer.OutputToDevice();
851 m_pDevice->RestoreState(); 916 }
852 return; 917 void CPDF_RenderStatus::DrawShadingPattern(CPDF_ShadingPattern* pattern,
853 } 918 CPDF_PageObject* pPageObj,
854 } else if (pPageObj->m_Type == PDFPAGE_IMAGE) { 919 const CFX_AffineMatrix* pObj2Device,
855 FX_RECT rect = pPageObj->GetBBox(pObj2Device); 920 FX_BOOL bStroke) {
856 m_pDevice->SetClip_Rect(&rect); 921 if (!pattern->Load()) {
857 } else { 922 return;
858 return; 923 }
859 } 924 m_pDevice->SaveState();
860 FX_RECT rect; 925 if (pPageObj->m_Type == PDFPAGE_PATH) {
861 if (GetObjectClippedRect(pPageObj, pObj2Device, FALSE, rect)) { 926 if (!SelectClipPath((CPDF_PathObject*)pPageObj, pObj2Device, bStroke)) {
927 m_pDevice->RestoreState();
928 return;
929 }
930 } else if (pPageObj->m_Type == PDFPAGE_IMAGE) {
931 FX_RECT rect = pPageObj->GetBBox(pObj2Device);
932 m_pDevice->SetClip_Rect(&rect);
933 } else {
934 return;
935 }
936 FX_RECT rect;
937 if (GetObjectClippedRect(pPageObj, pObj2Device, FALSE, rect)) {
938 m_pDevice->RestoreState();
939 return;
940 }
941 CFX_AffineMatrix matrix = pattern->m_Pattern2Form;
942 matrix.Concat(*pObj2Device);
943 GetScaledMatrix(matrix);
944 int alpha = pPageObj->m_GeneralState.GetAlpha(bStroke);
945 DrawShading(pattern, &matrix, rect, alpha,
946 m_Options.m_ColorMode == RENDER_COLOR_ALPHA);
947 m_pDevice->RestoreState();
948 }
949 FX_BOOL CPDF_RenderStatus::ProcessShading(CPDF_ShadingObject* pShadingObj,
950 const CFX_AffineMatrix* pObj2Device) {
951 FX_RECT rect = pShadingObj->GetBBox(pObj2Device);
952 FX_RECT clip_box = m_pDevice->GetClipBox();
953 rect.Intersect(clip_box);
954 if (rect.IsEmpty()) {
955 return TRUE;
956 }
957 CFX_AffineMatrix matrix = pShadingObj->m_Matrix;
958 matrix.Concat(*pObj2Device);
959 DrawShading(pShadingObj->m_pShading, &matrix, rect,
960 pShadingObj->m_GeneralState.GetAlpha(FALSE),
961 m_Options.m_ColorMode == RENDER_COLOR_ALPHA);
962 return TRUE;
963 }
964 static CFX_DIBitmap* DrawPatternBitmap(CPDF_Document* pDoc,
965 CPDF_PageRenderCache* pCache,
966 CPDF_TilingPattern* pPattern,
967 const CFX_AffineMatrix* pObject2Device,
968 int width,
969 int height,
970 int flags) {
971 CFX_DIBitmap* pBitmap = new CFX_DIBitmap;
972 if (!pBitmap->Create(width, height,
973 pPattern->m_bColored ? FXDIB_Argb : FXDIB_8bppMask)) {
974 delete pBitmap;
975 return NULL;
976 }
977 CFX_FxgeDevice bitmap_device;
978 bitmap_device.Attach(pBitmap);
979 pBitmap->Clear(0);
980 CFX_FloatRect cell_bbox = pPattern->m_BBox;
981 pPattern->m_Pattern2Form.TransformRect(cell_bbox);
982 pObject2Device->TransformRect(cell_bbox);
983 CFX_FloatRect bitmap_rect(0.0f, 0.0f, (FX_FLOAT)width, (FX_FLOAT)height);
984 CFX_AffineMatrix mtAdjust;
985 mtAdjust.MatchRect(bitmap_rect, cell_bbox);
986 CFX_AffineMatrix mtPattern2Bitmap = *pObject2Device;
987 mtPattern2Bitmap.Concat(mtAdjust);
988 CPDF_RenderOptions options;
989 if (!pPattern->m_bColored) {
990 options.m_ColorMode = RENDER_COLOR_ALPHA;
991 }
992 flags |= RENDER_FORCE_HALFTONE;
993 options.m_Flags = flags;
994 CPDF_RenderContext context;
995 context.Create(pDoc, pCache, NULL);
996 context.DrawObjectList(&bitmap_device, pPattern->m_pForm, &mtPattern2Bitmap,
997 &options);
998 return pBitmap;
999 }
1000 void CPDF_RenderStatus::DrawTilingPattern(CPDF_TilingPattern* pPattern,
1001 CPDF_PageObject* pPageObj,
1002 const CFX_AffineMatrix* pObj2Device,
1003 FX_BOOL bStroke) {
1004 if (!pPattern->Load()) {
1005 return;
1006 }
1007 m_pDevice->SaveState();
1008 if (pPageObj->m_Type == PDFPAGE_PATH) {
1009 if (!SelectClipPath((CPDF_PathObject*)pPageObj, pObj2Device, bStroke)) {
1010 m_pDevice->RestoreState();
1011 return;
1012 }
1013 } else if (pPageObj->m_Type == PDFPAGE_IMAGE) {
1014 FX_RECT rect = pPageObj->GetBBox(pObj2Device);
1015 m_pDevice->SetClip_Rect(&rect);
1016 } else {
1017 return;
1018 }
1019 FX_RECT clip_box = m_pDevice->GetClipBox();
1020 if (clip_box.IsEmpty()) {
1021 m_pDevice->RestoreState();
1022 return;
1023 }
1024 CFX_Matrix dCTM = m_pDevice->GetCTM();
1025 FX_FLOAT sa = FXSYS_fabs(dCTM.a);
1026 FX_FLOAT sd = FXSYS_fabs(dCTM.d);
1027 clip_box.right = clip_box.left + (int32_t)FXSYS_ceil(clip_box.Width() * sa);
1028 clip_box.bottom = clip_box.top + (int32_t)FXSYS_ceil(clip_box.Height() * sd);
1029 CFX_AffineMatrix mtPattern2Device = pPattern->m_Pattern2Form;
1030 mtPattern2Device.Concat(*pObj2Device);
1031 GetScaledMatrix(mtPattern2Device);
1032 FX_BOOL bAligned = FALSE;
1033 if (pPattern->m_BBox.left == 0 && pPattern->m_BBox.bottom == 0 &&
1034 pPattern->m_BBox.right == pPattern->m_XStep &&
1035 pPattern->m_BBox.top == pPattern->m_YStep &&
1036 (mtPattern2Device.IsScaled() || mtPattern2Device.Is90Rotated())) {
1037 bAligned = TRUE;
1038 }
1039 CFX_FloatRect cell_bbox = pPattern->m_BBox;
1040 mtPattern2Device.TransformRect(cell_bbox);
1041 int width = (int)FXSYS_ceil(cell_bbox.Width());
1042 int height = (int)FXSYS_ceil(cell_bbox.Height());
1043 if (width == 0) {
1044 width = 1;
1045 }
1046 if (height == 0) {
1047 height = 1;
1048 }
1049 int min_col, max_col, min_row, max_row;
1050 CFX_AffineMatrix mtDevice2Pattern;
1051 mtDevice2Pattern.SetReverse(mtPattern2Device);
1052 CFX_FloatRect clip_box_p(clip_box);
1053 clip_box_p.Transform(&mtDevice2Pattern);
1054 min_col = (int)FXSYS_ceil(
1055 FXSYS_Div(clip_box_p.left - pPattern->m_BBox.right, pPattern->m_XStep));
1056 max_col = (int)FXSYS_floor(
1057 FXSYS_Div(clip_box_p.right - pPattern->m_BBox.left, pPattern->m_XStep));
1058 min_row = (int)FXSYS_ceil(
1059 FXSYS_Div(clip_box_p.bottom - pPattern->m_BBox.top, pPattern->m_YStep));
1060 max_row = (int)FXSYS_floor(
1061 FXSYS_Div(clip_box_p.top - pPattern->m_BBox.bottom, pPattern->m_YStep));
1062 if (width > clip_box.Width() || height > clip_box.Height() ||
1063 width * height > clip_box.Width() * clip_box.Height()) {
1064 CPDF_GraphicStates* pStates = NULL;
1065 if (!pPattern->m_bColored) {
1066 pStates = CloneObjStates(pPageObj, bStroke);
1067 }
1068 CPDF_Dictionary* pFormResource = NULL;
1069 if (pPattern->m_pForm->m_pFormDict) {
1070 pFormResource =
1071 pPattern->m_pForm->m_pFormDict->GetDict(FX_BSTRC("Resources"));
1072 }
1073 for (int col = min_col; col <= max_col; col++)
1074 for (int row = min_row; row <= max_row; row++) {
1075 FX_FLOAT orig_x, orig_y;
1076 orig_x = col * pPattern->m_XStep;
1077 orig_y = row * pPattern->m_YStep;
1078 mtPattern2Device.Transform(orig_x, orig_y);
1079 CFX_AffineMatrix matrix = *pObj2Device;
1080 matrix.Translate(orig_x - mtPattern2Device.e,
1081 orig_y - mtPattern2Device.f);
1082 m_pDevice->SaveState();
1083 CPDF_RenderStatus status;
1084 status.Initialize(m_pContext, m_pDevice, NULL, NULL, this, pStates,
1085 &m_Options, pPattern->m_pForm->m_Transparency,
1086 m_bDropObjects, pFormResource);
1087 status.RenderObjectList(pPattern->m_pForm, &matrix);
862 m_pDevice->RestoreState(); 1088 m_pDevice->RestoreState();
863 return; 1089 }
864 }
865 CFX_AffineMatrix matrix = pattern->m_Pattern2Form;
866 matrix.Concat(*pObj2Device);
867 GetScaledMatrix(matrix);
868 int alpha = pPageObj->m_GeneralState.GetAlpha(bStroke);
869 DrawShading(pattern, &matrix, rect, alpha, m_Options.m_ColorMode == RENDER_C OLOR_ALPHA);
870 m_pDevice->RestoreState(); 1090 m_pDevice->RestoreState();
871 } 1091 delete pStates;
872 FX_BOOL CPDF_RenderStatus::ProcessShading(CPDF_ShadingObject* pShadingObj, const CFX_AffineMatrix* pObj2Device) 1092 return;
873 { 1093 }
874 FX_RECT rect = pShadingObj->GetBBox(pObj2Device); 1094 if (bAligned) {
875 FX_RECT clip_box = m_pDevice->GetClipBox(); 1095 int orig_x = FXSYS_round(mtPattern2Device.e);
876 rect.Intersect(clip_box); 1096 int orig_y = FXSYS_round(mtPattern2Device.f);
877 if (rect.IsEmpty()) { 1097 min_col = (clip_box.left - orig_x) / width;
878 return TRUE; 1098 if (clip_box.left < orig_x) {
879 } 1099 min_col--;
880 CFX_AffineMatrix matrix = pShadingObj->m_Matrix; 1100 }
881 matrix.Concat(*pObj2Device); 1101 max_col = (clip_box.right - orig_x) / width;
882 DrawShading(pShadingObj->m_pShading, &matrix, rect, pShadingObj->m_GeneralSt ate.GetAlpha(FALSE), 1102 if (clip_box.right <= orig_x) {
883 m_Options.m_ColorMode == RENDER_COLOR_ALPHA); 1103 max_col--;
884 return TRUE; 1104 }
885 } 1105 min_row = (clip_box.top - orig_y) / height;
886 static CFX_DIBitmap* DrawPatternBitmap(CPDF_Document* pDoc, CPDF_PageRenderCache * pCache, 1106 if (clip_box.top < orig_y) {
887 CPDF_TilingPattern* pPattern, const CFX_A ffineMatrix* pObject2Device, 1107 min_row--;
888 int width, int height, int flags) 1108 }
889 { 1109 max_row = (clip_box.bottom - orig_y) / height;
890 CFX_DIBitmap* pBitmap = new CFX_DIBitmap; 1110 if (clip_box.bottom <= orig_y) {
891 if (!pBitmap->Create(width, height, pPattern->m_bColored ? FXDIB_Argb : FXDI B_8bppMask)) { 1111 max_row--;
892 delete pBitmap; 1112 }
893 return NULL; 1113 }
894 } 1114 FX_FLOAT left_offset = cell_bbox.left - mtPattern2Device.e;
895 CFX_FxgeDevice bitmap_device; 1115 FX_FLOAT top_offset = cell_bbox.bottom - mtPattern2Device.f;
896 bitmap_device.Attach(pBitmap); 1116 CFX_DIBitmap* pPatternBitmap = NULL;
897 pBitmap->Clear(0); 1117 if (width * height < 16) {
898 CFX_FloatRect cell_bbox = pPattern->m_BBox; 1118 CFX_DIBitmap* pEnlargedBitmap =
899 pPattern->m_Pattern2Form.TransformRect(cell_bbox); 1119 DrawPatternBitmap(m_pContext->m_pDocument, m_pContext->m_pPageCache,
900 pObject2Device->TransformRect(cell_bbox); 1120 pPattern, pObj2Device, 8, 8, m_Options.m_Flags);
901 CFX_FloatRect bitmap_rect(0.0f, 0.0f, (FX_FLOAT)width, (FX_FLOAT)height); 1121 pPatternBitmap = pEnlargedBitmap->StretchTo(width, height);
902 CFX_AffineMatrix mtAdjust; 1122 delete pEnlargedBitmap;
903 mtAdjust.MatchRect(bitmap_rect, cell_bbox); 1123 } else {
904 CFX_AffineMatrix mtPattern2Bitmap = *pObject2Device; 1124 pPatternBitmap = DrawPatternBitmap(
905 mtPattern2Bitmap.Concat(mtAdjust); 1125 m_pContext->m_pDocument, m_pContext->m_pPageCache, pPattern,
906 CPDF_RenderOptions options; 1126 pObj2Device, width, height, m_Options.m_Flags);
907 if (!pPattern->m_bColored) { 1127 }
908 options.m_ColorMode = RENDER_COLOR_ALPHA; 1128 if (pPatternBitmap == NULL) {
909 }
910 flags |= RENDER_FORCE_HALFTONE;
911 options.m_Flags = flags;
912 CPDF_RenderContext context;
913 context.Create(pDoc, pCache, NULL);
914 context.DrawObjectList(&bitmap_device, pPattern->m_pForm, &mtPattern2Bitmap, &options);
915 return pBitmap;
916 }
917 void CPDF_RenderStatus::DrawTilingPattern(CPDF_TilingPattern* pPattern, CPDF_Pag eObject* pPageObj, const CFX_AffineMatrix* pObj2Device, FX_BOOL bStroke)
918 {
919 if (!pPattern->Load()) {
920 return;
921 }
922 m_pDevice->SaveState();
923 if (pPageObj->m_Type == PDFPAGE_PATH) {
924 if (!SelectClipPath((CPDF_PathObject*)pPageObj, pObj2Device, bStroke)) {
925 m_pDevice->RestoreState();
926 return;
927 }
928 } else if (pPageObj->m_Type == PDFPAGE_IMAGE) {
929 FX_RECT rect = pPageObj->GetBBox(pObj2Device);
930 m_pDevice->SetClip_Rect(&rect);
931 } else {
932 return;
933 }
934 FX_RECT clip_box = m_pDevice->GetClipBox();
935 if (clip_box.IsEmpty()) {
936 m_pDevice->RestoreState();
937 return;
938 }
939 CFX_Matrix dCTM = m_pDevice->GetCTM();
940 FX_FLOAT sa = FXSYS_fabs(dCTM.a);
941 FX_FLOAT sd = FXSYS_fabs(dCTM.d);
942 clip_box.right = clip_box.left + (int32_t)FXSYS_ceil(clip_box.Width() * sa);
943 clip_box.bottom = clip_box.top + (int32_t)FXSYS_ceil(clip_box.Height() * sd) ;
944 CFX_AffineMatrix mtPattern2Device = pPattern->m_Pattern2Form;
945 mtPattern2Device.Concat(*pObj2Device);
946 GetScaledMatrix(mtPattern2Device);
947 FX_BOOL bAligned = FALSE;
948 if (pPattern->m_BBox.left == 0 && pPattern->m_BBox.bottom == 0 &&
949 pPattern->m_BBox.right == pPattern->m_XStep && pPattern->m_BBox.top == pPattern->m_YStep &&
950 (mtPattern2Device.IsScaled() || mtPattern2Device.Is90Rotated())) {
951 bAligned = TRUE;
952 }
953 CFX_FloatRect cell_bbox = pPattern->m_BBox;
954 mtPattern2Device.TransformRect(cell_bbox);
955 int width = (int)FXSYS_ceil(cell_bbox.Width());
956 int height = (int)FXSYS_ceil(cell_bbox.Height());
957 if (width == 0) {
958 width = 1;
959 }
960 if (height == 0) {
961 height = 1;
962 }
963 int min_col, max_col, min_row, max_row;
964 CFX_AffineMatrix mtDevice2Pattern;
965 mtDevice2Pattern.SetReverse(mtPattern2Device);
966 CFX_FloatRect clip_box_p(clip_box);
967 clip_box_p.Transform(&mtDevice2Pattern);
968 min_col = (int)FXSYS_ceil(FXSYS_Div(clip_box_p.left - pPattern->m_BBox.right , pPattern->m_XStep));
969 max_col = (int)FXSYS_floor(FXSYS_Div(clip_box_p.right - pPattern->m_BBox.lef t, pPattern->m_XStep));
970 min_row = (int)FXSYS_ceil(FXSYS_Div(clip_box_p.bottom - pPattern->m_BBox.top , pPattern->m_YStep));
971 max_row = (int)FXSYS_floor(FXSYS_Div(clip_box_p.top - pPattern->m_BBox.botto m, pPattern->m_YStep));
972 if (width > clip_box.Width() || height > clip_box.Height() || width * height > clip_box.Width() * clip_box.Height()) {
973 CPDF_GraphicStates* pStates = NULL;
974 if (!pPattern->m_bColored) {
975 pStates = CloneObjStates(pPageObj, bStroke);
976 }
977 CPDF_Dictionary* pFormResource = NULL;
978 if (pPattern->m_pForm->m_pFormDict) {
979 pFormResource = pPattern->m_pForm->m_pFormDict->GetDict(FX_BSTRC("Re sources"));
980 }
981 for (int col = min_col; col <= max_col; col ++)
982 for (int row = min_row; row <= max_row; row ++) {
983 FX_FLOAT orig_x, orig_y;
984 orig_x = col * pPattern->m_XStep;
985 orig_y = row * pPattern->m_YStep;
986 mtPattern2Device.Transform(orig_x, orig_y);
987 CFX_AffineMatrix matrix = *pObj2Device;
988 matrix.Translate(orig_x - mtPattern2Device.e, orig_y - mtPattern 2Device.f);
989 m_pDevice->SaveState();
990 CPDF_RenderStatus status;
991 status.Initialize(m_pContext, m_pDevice, NULL, NULL, this, pStat es, &m_Options,
992 pPattern->m_pForm->m_Transparency, m_bDropObje cts, pFormResource);
993 status.RenderObjectList(pPattern->m_pForm, &matrix);
994 m_pDevice->RestoreState();
995 }
996 m_pDevice->RestoreState();
997 delete pStates;
998 return;
999 }
1000 if (bAligned) {
1001 int orig_x = FXSYS_round(mtPattern2Device.e);
1002 int orig_y = FXSYS_round(mtPattern2Device.f);
1003 min_col = (clip_box.left - orig_x) / width;
1004 if (clip_box.left < orig_x) {
1005 min_col --;
1006 }
1007 max_col = (clip_box.right - orig_x) / width;
1008 if (clip_box.right <= orig_x) {
1009 max_col --;
1010 }
1011 min_row = (clip_box.top - orig_y) / height;
1012 if (clip_box.top < orig_y) {
1013 min_row --;
1014 }
1015 max_row = (clip_box.bottom - orig_y) / height;
1016 if (clip_box.bottom <= orig_y) {
1017 max_row --;
1018 }
1019 }
1020 FX_FLOAT left_offset = cell_bbox.left - mtPattern2Device.e;
1021 FX_FLOAT top_offset = cell_bbox.bottom - mtPattern2Device.f;
1022 CFX_DIBitmap* pPatternBitmap = NULL;
1023 if (width * height < 16) {
1024 CFX_DIBitmap* pEnlargedBitmap = DrawPatternBitmap(m_pContext->m_pDocumen t, m_pContext->m_pPageCache, pPattern, pObj2Device, 8, 8, m_Options.m_Flags);
1025 pPatternBitmap = pEnlargedBitmap->StretchTo(width, height);
1026 delete pEnlargedBitmap;
1027 } else {
1028 pPatternBitmap = DrawPatternBitmap(m_pContext->m_pDocument, m_pContext-> m_pPageCache, pPattern, pObj2Device, width, height, m_Options.m_Flags);
1029 }
1030 if (pPatternBitmap == NULL) {
1031 m_pDevice->RestoreState();
1032 return;
1033 }
1034 if (m_Options.m_ColorMode == RENDER_COLOR_GRAY) {
1035 pPatternBitmap->ConvertColorScale(m_Options.m_ForeColor, m_Options.m_Bac kColor);
1036 }
1037 FX_ARGB fill_argb = GetFillArgb(pPageObj);
1038 int clip_width = clip_box.right - clip_box.left;
1039 int clip_height = clip_box.bottom - clip_box.top;
1040 CFX_DIBitmap screen;
1041 if (!screen.Create(clip_width, clip_height, FXDIB_Argb)) {
1042 return;
1043 }
1044 screen.Clear(0);
1045 FX_DWORD* src_buf = (FX_DWORD*)pPatternBitmap->GetBuffer();
1046 for (int col = min_col; col <= max_col; col ++) {
1047 for (int row = min_row; row <= max_row; row ++) {
1048 int start_x, start_y;
1049 if (bAligned) {
1050 start_x = FXSYS_round(mtPattern2Device.e) + col * width - clip_b ox.left;
1051 start_y = FXSYS_round(mtPattern2Device.f) + row * height - clip_ box.top;
1052 } else {
1053 FX_FLOAT orig_x = col * pPattern->m_XStep;
1054 FX_FLOAT orig_y = row * pPattern->m_YStep;
1055 mtPattern2Device.Transform(orig_x, orig_y);
1056 start_x = FXSYS_round(orig_x + left_offset) - clip_box.left;
1057 start_y = FXSYS_round(orig_y + top_offset) - clip_box.top;
1058 }
1059 if (width == 1 && height == 1) {
1060 if (start_x < 0 || start_x >= clip_box.Width() || start_y < 0 || start_y >= clip_box.Height()) {
1061 continue;
1062 }
1063 FX_DWORD* dest_buf = (FX_DWORD*)(screen.GetBuffer() + screen.Get Pitch() * start_y + start_x * 4);
1064 if (pPattern->m_bColored) {
1065 *dest_buf = *src_buf;
1066 } else {
1067 *dest_buf = (*(uint8_t*)src_buf << 24) | (fill_argb & 0xffff ff);
1068 }
1069 } else {
1070 if (pPattern->m_bColored) {
1071 screen.CompositeBitmap(start_x, start_y, width, height, pPat ternBitmap, 0, 0);
1072 } else {
1073 screen.CompositeMask(start_x, start_y, width, height, pPatte rnBitmap, fill_argb, 0, 0);
1074 }
1075 }
1076 }
1077 }
1078 CompositeDIBitmap(&screen, clip_box.left, clip_box.top, 0, 255, FXDIB_BLEND_ NORMAL, FALSE);
1079 m_pDevice->RestoreState(); 1129 m_pDevice->RestoreState();
1080 delete pPatternBitmap; 1130 return;
1081 } 1131 }
1082 void CPDF_RenderStatus::DrawPathWithPattern(CPDF_PathObject* pPathObj, const CFX _AffineMatrix* pObj2Device, CPDF_Color* pColor, FX_BOOL bStroke) 1132 if (m_Options.m_ColorMode == RENDER_COLOR_GRAY) {
1083 { 1133 pPatternBitmap->ConvertColorScale(m_Options.m_ForeColor,
1084 CPDF_Pattern* pattern = pColor->GetPattern(); 1134 m_Options.m_BackColor);
1085 if (pattern == NULL) { 1135 }
1086 return; 1136 FX_ARGB fill_argb = GetFillArgb(pPageObj);
1087 } 1137 int clip_width = clip_box.right - clip_box.left;
1088 if(pattern->m_PatternType == PATTERN_TILING) { 1138 int clip_height = clip_box.bottom - clip_box.top;
1089 DrawTilingPattern((CPDF_TilingPattern*)pattern, pPathObj, pObj2Device, b Stroke); 1139 CFX_DIBitmap screen;
1090 } else { 1140 if (!screen.Create(clip_width, clip_height, FXDIB_Argb)) {
1091 DrawShadingPattern((CPDF_ShadingPattern*)pattern, pPathObj, pObj2Device, bStroke); 1141 return;
1092 } 1142 }
1093 } 1143 screen.Clear(0);
1094 void CPDF_RenderStatus::ProcessPathPattern(CPDF_PathObject* pPathObj, const CFX_ AffineMatrix* pObj2Device, int& filltype, FX_BOOL& bStroke) 1144 FX_DWORD* src_buf = (FX_DWORD*)pPatternBitmap->GetBuffer();
1095 { 1145 for (int col = min_col; col <= max_col; col++) {
1096 if(filltype) { 1146 for (int row = min_row; row <= max_row; row++) {
1097 CPDF_Color& FillColor = *pPathObj->m_ColorState.GetFillColor(); 1147 int start_x, start_y;
1098 if(FillColor.m_pCS && FillColor.m_pCS->GetFamily() == PDFCS_PATTERN) { 1148 if (bAligned) {
1099 DrawPathWithPattern(pPathObj, pObj2Device, &FillColor, FALSE); 1149 start_x = FXSYS_round(mtPattern2Device.e) + col * width - clip_box.left;
1100 filltype = 0; 1150 start_y = FXSYS_round(mtPattern2Device.f) + row * height - clip_box.top;
1101 } 1151 } else {
1102 } 1152 FX_FLOAT orig_x = col * pPattern->m_XStep;
1103 if(bStroke) { 1153 FX_FLOAT orig_y = row * pPattern->m_YStep;
1104 CPDF_Color& StrokeColor = *pPathObj->m_ColorState.GetStrokeColor(); 1154 mtPattern2Device.Transform(orig_x, orig_y);
1105 if(StrokeColor.m_pCS && StrokeColor.m_pCS->GetFamily() == PDFCS_PATTERN) { 1155 start_x = FXSYS_round(orig_x + left_offset) - clip_box.left;
1106 DrawPathWithPattern(pPathObj, pObj2Device, &StrokeColor, TRUE); 1156 start_y = FXSYS_round(orig_y + top_offset) - clip_box.top;
1107 bStroke = FALSE; 1157 }
1108 } 1158 if (width == 1 && height == 1) {
1109 } 1159 if (start_x < 0 || start_x >= clip_box.Width() || start_y < 0 ||
1110 } 1160 start_y >= clip_box.Height()) {
1161 continue;
1162 }
1163 FX_DWORD* dest_buf =
1164 (FX_DWORD*)(screen.GetBuffer() + screen.GetPitch() * start_y +
1165 start_x * 4);
1166 if (pPattern->m_bColored) {
1167 *dest_buf = *src_buf;
1168 } else {
1169 *dest_buf = (*(uint8_t*)src_buf << 24) | (fill_argb & 0xffffff);
1170 }
1171 } else {
1172 if (pPattern->m_bColored) {
1173 screen.CompositeBitmap(start_x, start_y, width, height,
1174 pPatternBitmap, 0, 0);
1175 } else {
1176 screen.CompositeMask(start_x, start_y, width, height, pPatternBitmap,
1177 fill_argb, 0, 0);
1178 }
1179 }
1180 }
1181 }
1182 CompositeDIBitmap(&screen, clip_box.left, clip_box.top, 0, 255,
1183 FXDIB_BLEND_NORMAL, FALSE);
1184 m_pDevice->RestoreState();
1185 delete pPatternBitmap;
1186 }
1187 void CPDF_RenderStatus::DrawPathWithPattern(CPDF_PathObject* pPathObj,
1188 const CFX_AffineMatrix* pObj2Device,
1189 CPDF_Color* pColor,
1190 FX_BOOL bStroke) {
1191 CPDF_Pattern* pattern = pColor->GetPattern();
1192 if (pattern == NULL) {
1193 return;
1194 }
1195 if (pattern->m_PatternType == PATTERN_TILING) {
1196 DrawTilingPattern((CPDF_TilingPattern*)pattern, pPathObj, pObj2Device,
1197 bStroke);
1198 } else {
1199 DrawShadingPattern((CPDF_ShadingPattern*)pattern, pPathObj, pObj2Device,
1200 bStroke);
1201 }
1202 }
1203 void CPDF_RenderStatus::ProcessPathPattern(CPDF_PathObject* pPathObj,
1204 const CFX_AffineMatrix* pObj2Device,
1205 int& filltype,
1206 FX_BOOL& bStroke) {
1207 if (filltype) {
1208 CPDF_Color& FillColor = *pPathObj->m_ColorState.GetFillColor();
1209 if (FillColor.m_pCS && FillColor.m_pCS->GetFamily() == PDFCS_PATTERN) {
1210 DrawPathWithPattern(pPathObj, pObj2Device, &FillColor, FALSE);
1211 filltype = 0;
1212 }
1213 }
1214 if (bStroke) {
1215 CPDF_Color& StrokeColor = *pPathObj->m_ColorState.GetStrokeColor();
1216 if (StrokeColor.m_pCS && StrokeColor.m_pCS->GetFamily() == PDFCS_PATTERN) {
1217 DrawPathWithPattern(pPathObj, pObj2Device, &StrokeColor, TRUE);
1218 bStroke = FALSE;
1219 }
1220 }
1221 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698