| OLD | NEW |
| 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 } |
| OLD | NEW |