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 |