| OLD | NEW |
| 1 | 1 |
| 2 /* | 2 /* |
| 3 * Copyright 2011 Google Inc. | 3 * Copyright 2011 Google Inc. |
| 4 * | 4 * |
| 5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
| 6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
| 7 */ | 7 */ |
| 8 | 8 |
| 9 | 9 |
| 10 #include "SkPDFShader.h" | 10 #include "SkPDFShader.h" |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 283 "mul " // y^2 x^2 | 283 "mul " // y^2 x^2 |
| 284 "add " // y^2+x^2 | 284 "add " // y^2+x^2 |
| 285 "sqrt\n"); // sqrt(y^2+x^2) | 285 "sqrt\n"); // sqrt(y^2+x^2) |
| 286 | 286 |
| 287 tileModeCode(info.fTileMode, &function); | 287 tileModeCode(info.fTileMode, &function); |
| 288 gradientFunctionCode(info, &function); | 288 gradientFunctionCode(info, &function); |
| 289 function.append("}"); | 289 function.append("}"); |
| 290 return function; | 290 return function; |
| 291 } | 291 } |
| 292 | 292 |
| 293 /* The math here is all based on the description in Two_Point_Radial_Gradient, | |
| 294 with one simplification, the coordinate space has been scaled so that | |
| 295 Dr = 1. This means we don't need to scale the entire equation by 1/Dr^2. | |
| 296 */ | |
| 297 static SkString twoPointRadialCode(const SkShader::GradientInfo& info, | |
| 298 const SkMatrix& perspectiveRemover) { | |
| 299 SkScalar dx = info.fPoint[0].fX - info.fPoint[1].fX; | |
| 300 SkScalar dy = info.fPoint[0].fY - info.fPoint[1].fY; | |
| 301 SkScalar sr = info.fRadius[0]; | |
| 302 SkScalar a = SkScalarMul(dx, dx) + SkScalarMul(dy, dy) - SK_Scalar1; | |
| 303 bool posRoot = info.fRadius[1] > info.fRadius[0]; | |
| 304 | |
| 305 // We start with a stack of (x y), copy it and then consume one copy in | |
| 306 // order to calculate b and the other to calculate c. | |
| 307 SkString function("{"); | |
| 308 | |
| 309 function.append(apply_perspective_to_coordinates(perspectiveRemover)); | |
| 310 | |
| 311 function.append("2 copy "); | |
| 312 | |
| 313 // Calculate -b and b^2. | |
| 314 function.appendScalar(dy); | |
| 315 function.append(" mul exch "); | |
| 316 function.appendScalar(dx); | |
| 317 function.append(" mul add "); | |
| 318 function.appendScalar(sr); | |
| 319 function.append(" sub 2 mul neg dup dup mul\n"); | |
| 320 | |
| 321 // Calculate c | |
| 322 function.append("4 2 roll dup mul exch dup mul add "); | |
| 323 function.appendScalar(SkScalarMul(sr, sr)); | |
| 324 function.append(" sub\n"); | |
| 325 | |
| 326 // Calculate the determinate | |
| 327 function.appendScalar(SkScalarMul(SkIntToScalar(4), a)); | |
| 328 function.append(" mul sub abs sqrt\n"); | |
| 329 | |
| 330 // And then the final value of t. | |
| 331 if (posRoot) { | |
| 332 function.append("sub "); | |
| 333 } else { | |
| 334 function.append("add "); | |
| 335 } | |
| 336 function.appendScalar(SkScalarMul(SkIntToScalar(2), a)); | |
| 337 function.append(" div\n"); | |
| 338 | |
| 339 tileModeCode(info.fTileMode, &function); | |
| 340 gradientFunctionCode(info, &function); | |
| 341 function.append("}"); | |
| 342 return function; | |
| 343 } | |
| 344 | |
| 345 /* Conical gradient shader, based on the Canvas spec for radial gradients | 293 /* Conical gradient shader, based on the Canvas spec for radial gradients |
| 346 See: http://www.w3.org/TR/2dcontext/#dom-context-2d-createradialgradient | 294 See: http://www.w3.org/TR/2dcontext/#dom-context-2d-createradialgradient |
| 347 */ | 295 */ |
| 348 static SkString twoPointConicalCode(const SkShader::GradientInfo& info, | 296 static SkString twoPointConicalCode(const SkShader::GradientInfo& info, |
| 349 const SkMatrix& perspectiveRemover) { | 297 const SkMatrix& perspectiveRemover) { |
| 350 SkScalar dx = info.fPoint[1].fX - info.fPoint[0].fX; | 298 SkScalar dx = info.fPoint[1].fX - info.fPoint[0].fX; |
| 351 SkScalar dy = info.fPoint[1].fY - info.fPoint[0].fY; | 299 SkScalar dy = info.fPoint[1].fY - info.fPoint[0].fY; |
| 352 SkScalar r0 = info.fRadius[0]; | 300 SkScalar r0 = info.fRadius[0]; |
| 353 SkScalar dr = info.fRadius[1] - info.fRadius[0]; | 301 SkScalar dr = info.fRadius[1] - info.fRadius[0]; |
| 354 SkScalar a = SkScalarMul(dx, dx) + SkScalarMul(dy, dy) - | 302 SkScalar a = SkScalarMul(dx, dx) + SkScalarMul(dy, dy) - |
| (...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 775 transformPoints[1] = info->fPoint[1]; | 723 transformPoints[1] = info->fPoint[1]; |
| 776 switch (state.fType) { | 724 switch (state.fType) { |
| 777 case SkShader::kLinear_GradientType: | 725 case SkShader::kLinear_GradientType: |
| 778 codeFunction = &linearCode; | 726 codeFunction = &linearCode; |
| 779 break; | 727 break; |
| 780 case SkShader::kRadial_GradientType: | 728 case SkShader::kRadial_GradientType: |
| 781 transformPoints[1] = transformPoints[0]; | 729 transformPoints[1] = transformPoints[0]; |
| 782 transformPoints[1].fX += info->fRadius[0]; | 730 transformPoints[1].fX += info->fRadius[0]; |
| 783 codeFunction = &radialCode; | 731 codeFunction = &radialCode; |
| 784 break; | 732 break; |
| 785 case SkShader::kRadial2_GradientType: { | |
| 786 // Bail out if the radii are the same. | |
| 787 if (info->fRadius[0] == info->fRadius[1]) { | |
| 788 return NULL; | |
| 789 } | |
| 790 transformPoints[1] = transformPoints[0]; | |
| 791 SkScalar dr = info->fRadius[1] - info->fRadius[0]; | |
| 792 transformPoints[1].fX += dr; | |
| 793 codeFunction = &twoPointRadialCode; | |
| 794 break; | |
| 795 } | |
| 796 case SkShader::kConical_GradientType: { | 733 case SkShader::kConical_GradientType: { |
| 797 transformPoints[1] = transformPoints[0]; | 734 transformPoints[1] = transformPoints[0]; |
| 798 transformPoints[1].fX += SK_Scalar1; | 735 transformPoints[1].fX += SK_Scalar1; |
| 799 codeFunction = &twoPointConicalCode; | 736 codeFunction = &twoPointConicalCode; |
| 800 break; | 737 break; |
| 801 } | 738 } |
| 802 case SkShader::kSweep_GradientType: | 739 case SkShader::kSweep_GradientType: |
| 803 transformPoints[1] = transformPoints[0]; | 740 transformPoints[1] = transformPoints[0]; |
| 804 transformPoints[1].fX += SK_Scalar1; | 741 transformPoints[1].fX += SK_Scalar1; |
| 805 codeFunction = &sweepCode; | 742 codeFunction = &sweepCode; |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 845 domain->appendScalar(bbox.fLeft); | 782 domain->appendScalar(bbox.fLeft); |
| 846 domain->appendScalar(bbox.fRight); | 783 domain->appendScalar(bbox.fRight); |
| 847 domain->appendScalar(bbox.fTop); | 784 domain->appendScalar(bbox.fTop); |
| 848 domain->appendScalar(bbox.fBottom); | 785 domain->appendScalar(bbox.fBottom); |
| 849 | 786 |
| 850 SkString functionCode; | 787 SkString functionCode; |
| 851 // The two point radial gradient further references | 788 // The two point radial gradient further references |
| 852 // state.fInfo | 789 // state.fInfo |
| 853 // in translating from x, y coordinates to the t parameter. So, we have | 790 // in translating from x, y coordinates to the t parameter. So, we have |
| 854 // to transform the points and radii according to the calculated matrix. | 791 // to transform the points and radii according to the calculated matrix. |
| 855 if (state.fType == SkShader::kRadial2_GradientType) { | 792 if (state.fType == SkShader::kConical_GradientType) { |
| 856 SkShader::GradientInfo twoPointRadialInfo = *info; | 793 SkShader::GradientInfo twoPointRadialInfo = *info; |
| 857 SkMatrix inverseMapperMatrix; | 794 SkMatrix inverseMapperMatrix; |
| 858 if (!mapperMatrix.invert(&inverseMapperMatrix)) { | 795 if (!mapperMatrix.invert(&inverseMapperMatrix)) { |
| 859 return NULL; | 796 return NULL; |
| 860 } | 797 } |
| 861 inverseMapperMatrix.mapPoints(twoPointRadialInfo.fPoint, 2); | 798 inverseMapperMatrix.mapPoints(twoPointRadialInfo.fPoint, 2); |
| 862 twoPointRadialInfo.fRadius[0] = | 799 twoPointRadialInfo.fRadius[0] = |
| 863 inverseMapperMatrix.mapRadius(info->fRadius[0]); | 800 inverseMapperMatrix.mapRadius(info->fRadius[0]); |
| 864 twoPointRadialInfo.fRadius[1] = | 801 twoPointRadialInfo.fRadius[1] = |
| 865 inverseMapperMatrix.mapRadius(info->fRadius[1]); | 802 inverseMapperMatrix.mapRadius(info->fRadius[1]); |
| (...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1136 case SkShader::kLinear_GradientType: | 1073 case SkShader::kLinear_GradientType: |
| 1137 if (fInfo.fPoint[1] != b.fInfo.fPoint[1]) { | 1074 if (fInfo.fPoint[1] != b.fInfo.fPoint[1]) { |
| 1138 return false; | 1075 return false; |
| 1139 } | 1076 } |
| 1140 break; | 1077 break; |
| 1141 case SkShader::kRadial_GradientType: | 1078 case SkShader::kRadial_GradientType: |
| 1142 if (fInfo.fRadius[0] != b.fInfo.fRadius[0]) { | 1079 if (fInfo.fRadius[0] != b.fInfo.fRadius[0]) { |
| 1143 return false; | 1080 return false; |
| 1144 } | 1081 } |
| 1145 break; | 1082 break; |
| 1146 case SkShader::kRadial2_GradientType: | |
| 1147 case SkShader::kConical_GradientType: | 1083 case SkShader::kConical_GradientType: |
| 1148 if (fInfo.fPoint[1] != b.fInfo.fPoint[1] || | 1084 if (fInfo.fPoint[1] != b.fInfo.fPoint[1] || |
| 1149 fInfo.fRadius[0] != b.fInfo.fRadius[0] || | 1085 fInfo.fRadius[0] != b.fInfo.fRadius[0] || |
| 1150 fInfo.fRadius[1] != b.fInfo.fRadius[1]) { | 1086 fInfo.fRadius[1] != b.fInfo.fRadius[1]) { |
| 1151 return false; | 1087 return false; |
| 1152 } | 1088 } |
| 1153 break; | 1089 break; |
| 1154 case SkShader::kSweep_GradientType: | 1090 case SkShader::kSweep_GradientType: |
| 1155 case SkShader::kNone_GradientType: | 1091 case SkShader::kNone_GradientType: |
| 1156 case SkShader::kColor_GradientType: | 1092 case SkShader::kColor_GradientType: |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1298 return false; | 1234 return false; |
| 1299 } | 1235 } |
| 1300 | 1236 |
| 1301 void SkPDFShader::State::AllocateGradientInfoStorage() { | 1237 void SkPDFShader::State::AllocateGradientInfoStorage() { |
| 1302 fColorData.set(sk_malloc_throw( | 1238 fColorData.set(sk_malloc_throw( |
| 1303 fInfo.fColorCount * (sizeof(SkColor) + sizeof(SkScalar)))); | 1239 fInfo.fColorCount * (sizeof(SkColor) + sizeof(SkScalar)))); |
| 1304 fInfo.fColors = reinterpret_cast<SkColor*>(fColorData.get()); | 1240 fInfo.fColors = reinterpret_cast<SkColor*>(fColorData.get()); |
| 1305 fInfo.fColorOffsets = | 1241 fInfo.fColorOffsets = |
| 1306 reinterpret_cast<SkScalar*>(fInfo.fColors + fInfo.fColorCount); | 1242 reinterpret_cast<SkScalar*>(fInfo.fColors + fInfo.fColorCount); |
| 1307 } | 1243 } |
| OLD | NEW |