Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 | 8 |
| 9 #include "SkPDFShader.h" | 9 #include "SkPDFShader.h" |
| 10 | 10 |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 115 colorData[2][r,g,b]); | 115 colorData[2][r,g,b]); |
| 116 } else { | 116 } else { |
| 117 | 117 |
| 118 ... } else { | 118 ... } else { |
| 119 return colorData[info.fColorCount - 1][r,g,b]; | 119 return colorData[info.fColorCount - 1][r,g,b]; |
| 120 } | 120 } |
| 121 ... | 121 ... |
| 122 } | 122 } |
| 123 } | 123 } |
| 124 */ | 124 */ |
| 125 static const int kColorComponents = 3; | |
| 126 typedef SkScalar ColorTuple[kColorComponents]; | |
| 125 static void gradientFunctionCode(const SkShader::GradientInfo& info, | 127 static void gradientFunctionCode(const SkShader::GradientInfo& info, |
| 126 SkDynamicMemoryWStream* result) { | 128 SkDynamicMemoryWStream* result) { |
| 127 /* We want to linearly interpolate from the previous color to the next. | 129 /* We want to linearly interpolate from the previous color to the next. |
| 128 Scale the colors from 0..255 to 0..1 and determine the multipliers | 130 Scale the colors from 0..255 to 0..1 and determine the multipliers |
| 129 for interpolation. | 131 for interpolation. |
| 130 C{r,g,b}(t, section) = t - offset_(section-1) + t * Multiplier{r,g,b}. | 132 C{r,g,b}(t, section) = t - offset_(section-1) + t * Multiplier{r,g,b}. |
| 131 */ | 133 */ |
| 132 static const int kColorComponents = 3; | 134 |
| 133 typedef SkScalar ColorTuple[kColorComponents]; | |
| 134 SkAutoSTMalloc<4, ColorTuple> colorDataAlloc(info.fColorCount); | 135 SkAutoSTMalloc<4, ColorTuple> colorDataAlloc(info.fColorCount); |
| 135 ColorTuple *colorData = colorDataAlloc.get(); | 136 ColorTuple *colorData = colorDataAlloc.get(); |
| 136 const SkScalar scale = SkScalarInvert(SkIntToScalar(255)); | 137 const SkScalar scale = SkScalarInvert(SkIntToScalar(255)); |
| 137 for (int i = 0; i < info.fColorCount; i++) { | 138 for (int i = 0; i < info.fColorCount; i++) { |
| 138 colorData[i][0] = SkScalarMul(SkColorGetR(info.fColors[i]), scale); | 139 colorData[i][0] = SkScalarMul(SkColorGetR(info.fColors[i]), scale); |
| 139 colorData[i][1] = SkScalarMul(SkColorGetG(info.fColors[i]), scale); | 140 colorData[i][1] = SkScalarMul(SkColorGetG(info.fColors[i]), scale); |
| 140 colorData[i][2] = SkScalarMul(SkColorGetB(info.fColors[i]), scale); | 141 colorData[i][2] = SkScalarMul(SkColorGetB(info.fColors[i]), scale); |
| 141 } | 142 } |
| 142 | 143 |
| 143 // Clamp the initial color. | 144 // Clamp the initial color. |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 176 result->writeText(" "); | 177 result->writeText(" "); |
| 177 SkPDFUtils::AppendScalar(colorData[info.fColorCount - 1][1], result); | 178 SkPDFUtils::AppendScalar(colorData[info.fColorCount - 1][1], result); |
| 178 result->writeText(" "); | 179 result->writeText(" "); |
| 179 SkPDFUtils::AppendScalar(colorData[info.fColorCount - 1][2], result); | 180 SkPDFUtils::AppendScalar(colorData[info.fColorCount - 1][2], result); |
| 180 | 181 |
| 181 for (int i = 0 ; i < gradients + 1; i++) { | 182 for (int i = 0 ; i < gradients + 1; i++) { |
| 182 result->writeText("} ifelse\n"); | 183 result->writeText("} ifelse\n"); |
| 183 } | 184 } |
| 184 } | 185 } |
| 185 | 186 |
| 187 static sk_sp<SkPDFDict> createInterpolationFunction(const ColorTuple& color1, | |
| 188 const ColorTuple& color2 ) { | |
| 189 auto retval = sk_make_sp<SkPDFDict>(); | |
| 190 | |
| 191 auto c0 = sk_make_sp<SkPDFArray>(); | |
| 192 c0->appendScalar(color1[0]); | |
| 193 c0->appendScalar(color1[1]); | |
| 194 c0->appendScalar(color1[2]); | |
| 195 retval->insertObject("C0", sk_ref_sp(c0.get())); | |
|
hal.canary
2016/04/29 09:56:24
retval->insertObject("C0", c0);
should work. sk_
| |
| 196 | |
| 197 auto c1 = sk_make_sp<SkPDFArray>(); | |
| 198 c1->appendScalar(color2[0]); | |
| 199 c1->appendScalar(color2[1]); | |
| 200 c1->appendScalar(color2[2]); | |
| 201 retval->insertObject("C1", sk_ref_sp(c1.get())); | |
| 202 | |
| 203 auto domain = sk_make_sp<SkPDFArray>(); | |
| 204 domain->appendScalar(0); | |
| 205 domain->appendScalar(1.0f); | |
| 206 retval->insertObject("Domain", sk_ref_sp(domain.get())); | |
| 207 | |
| 208 retval->insertInt("FunctionType", 2); | |
| 209 retval->insertScalar("N", 1.0f); | |
| 210 | |
| 211 return retval; | |
| 212 } | |
| 213 | |
| 214 static sk_sp<SkPDFDict> gradientStitchCode(const SkShader::GradientInfo& info) { | |
| 215 auto retval = sk_make_sp<SkPDFDict>(); | |
| 216 | |
| 217 SkAutoSTMalloc<4, ColorTuple> colorDataAlloc(info.fColorCount); | |
| 218 ColorTuple *colorData = colorDataAlloc.get(); | |
| 219 const SkScalar scale = SkScalarInvert(SkIntToScalar(255)); | |
| 220 for (int i = 0; i < info.fColorCount; i++) { | |
| 221 colorData[i][0] = SkScalarMul(SkColorGetR(info.fColors[i]), scale); | |
| 222 colorData[i][1] = SkScalarMul(SkColorGetG(info.fColors[i]), scale); | |
| 223 colorData[i][2] = SkScalarMul(SkColorGetB(info.fColors[i]), scale); | |
| 224 } | |
| 225 | |
| 226 // no need for a stitch function if there are only 2 stops. | |
| 227 if (info.fColorCount == 2) | |
| 228 return createInterpolationFunction(colorData[0], colorData[1]); | |
| 229 | |
| 230 auto encode = sk_make_sp<SkPDFArray>(); | |
| 231 auto bounds = sk_make_sp<SkPDFArray>(); | |
| 232 auto functions = sk_make_sp<SkPDFArray>(); | |
| 233 | |
| 234 auto domain = sk_make_sp<SkPDFArray>(); | |
| 235 domain->appendScalar(0); | |
| 236 domain->appendScalar(1.0f); | |
| 237 retval->insertObject("Domain", sk_ref_sp(domain.get())); | |
| 238 retval->insertInt("FunctionType", 3); | |
| 239 | |
| 240 for (int i = 1; i < info.fColorCount; i++) { | |
| 241 SkScalar offset = 0; | |
| 242 if (functions->size() > 0) { | |
| 243 offset = info.fColorOffsets[i-1]; | |
| 244 if (offset >= 0.99998f) { | |
| 245 bounds->appendScalar(1.0f); | |
| 246 } else if (offset == 0) {// if a colorstop has offset 0, remove prev ious stops. | |
| 247 encode = sk_make_sp<SkPDFArray>(); | |
| 248 bounds = sk_make_sp<SkPDFArray>(); | |
| 249 functions = sk_make_sp<SkPDFArray>(); | |
| 250 } else { | |
| 251 bounds->appendScalar(offset); | |
| 252 } | |
| 253 } | |
| 254 | |
| 255 encode->appendScalar(0); | |
| 256 encode->appendScalar(1.0f); | |
| 257 | |
| 258 functions->appendObject(createInterpolationFunction(colorData[i-1], colo rData[i])); | |
| 259 | |
| 260 if (offset >= 0.99998f) { // stop at colorstop that has 100% offset. ign ore later ones. | |
| 261 break; | |
| 262 } | |
| 263 } | |
| 264 | |
| 265 retval->insertObject("Encode", sk_ref_sp(encode.get())); | |
| 266 retval->insertObject("Bounds", sk_ref_sp(bounds.get())); | |
| 267 retval->insertObject("Functions", sk_ref_sp(functions.get())); | |
| 268 | |
| 269 return retval; | |
| 270 } | |
| 271 | |
| 272 | |
| 186 /* Map a value of t on the stack into [0, 1) for Repeat or Mirror tile mode. */ | 273 /* Map a value of t on the stack into [0, 1) for Repeat or Mirror tile mode. */ |
| 187 static void tileModeCode(SkShader::TileMode mode, | 274 static void tileModeCode(SkShader::TileMode mode, |
| 188 SkDynamicMemoryWStream* result) { | 275 SkDynamicMemoryWStream* result) { |
| 189 if (mode == SkShader::kRepeat_TileMode) { | 276 if (mode == SkShader::kRepeat_TileMode) { |
| 190 result->writeText("dup truncate sub\n"); // Get the fractional part. | 277 result->writeText("dup truncate sub\n"); // Get the fractional part. |
| 191 result->writeText("dup 0 le {1 add} if\n"); // Map (-1,0) => (0,1) | 278 result->writeText("dup 0 le {1 add} if\n"); // Map (-1,0) => (0,1) |
| 192 return; | 279 return; |
| 193 } | 280 } |
| 194 | 281 |
| 195 if (mode == SkShader::kMirror_TileMode) { | 282 if (mode == SkShader::kMirror_TileMode) { |
| (...skipping 510 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 706 } | 793 } |
| 707 | 794 |
| 708 SkPDFFunctionShader* SkPDFFunctionShader::Create( | 795 SkPDFFunctionShader* SkPDFFunctionShader::Create( |
| 709 SkPDFCanon* canon, std::unique_ptr<SkPDFShader::State>* autoState) { | 796 SkPDFCanon* canon, std::unique_ptr<SkPDFShader::State>* autoState) { |
| 710 const SkPDFShader::State& state = **autoState; | 797 const SkPDFShader::State& state = **autoState; |
| 711 | 798 |
| 712 void (*codeFunction)(const SkShader::GradientInfo& info, | 799 void (*codeFunction)(const SkShader::GradientInfo& info, |
| 713 const SkMatrix& perspectiveRemover, | 800 const SkMatrix& perspectiveRemover, |
| 714 SkDynamicMemoryWStream* function) = nullptr; | 801 SkDynamicMemoryWStream* function) = nullptr; |
| 715 SkPoint transformPoints[2]; | 802 SkPoint transformPoints[2]; |
| 803 const SkShader::GradientInfo* info = &state.fInfo; | |
| 716 | 804 |
| 717 // Depending on the type of the gradient, we want to transform the | 805 bool doStitchFunctions = (state.fType == SkShader::kLinear_GradientType || |
| 718 // coordinate space in different ways. | 806 state.fType == SkShader::kRadial_GradientType || |
| 719 const SkShader::GradientInfo* info = &state.fInfo; | 807 state.fType == SkShader::kConical_GradientType) && |
| 720 transformPoints[0] = info->fPoint[0]; | 808 info->fTileMode == SkShader::kClamp_TileMode; |
|
caryclark
2016/05/04 17:38:26
It is unfortunate that this leaves the old way of
| |
| 721 transformPoints[1] = info->fPoint[1]; | |
| 722 switch (state.fType) { | |
| 723 case SkShader::kLinear_GradientType: | |
| 724 codeFunction = &linearCode; | |
| 725 break; | |
| 726 case SkShader::kRadial_GradientType: | |
| 727 transformPoints[1] = transformPoints[0]; | |
| 728 transformPoints[1].fX += info->fRadius[0]; | |
| 729 codeFunction = &radialCode; | |
| 730 break; | |
| 731 case SkShader::kConical_GradientType: { | |
| 732 transformPoints[1] = transformPoints[0]; | |
| 733 transformPoints[1].fX += SK_Scalar1; | |
| 734 codeFunction = &twoPointConicalCode; | |
| 735 break; | |
| 736 } | |
| 737 case SkShader::kSweep_GradientType: | |
| 738 transformPoints[1] = transformPoints[0]; | |
| 739 transformPoints[1].fX += SK_Scalar1; | |
| 740 codeFunction = &sweepCode; | |
| 741 break; | |
| 742 case SkShader::kColor_GradientType: | |
| 743 case SkShader::kNone_GradientType: | |
| 744 default: | |
| 745 return nullptr; | |
| 746 } | |
| 747 | |
| 748 // Move any scaling (assuming a unit gradient) or translation | |
| 749 // (and rotation for linear gradient), of the final gradient from | |
| 750 // info->fPoints to the matrix (updating bbox appropriately). Now | |
| 751 // the gradient can be drawn on on the unit segment. | |
| 752 SkMatrix mapperMatrix; | |
| 753 unitToPointsMatrix(transformPoints, &mapperMatrix); | |
| 754 | 809 |
| 755 SkMatrix finalMatrix = state.fCanvasTransform; | 810 SkMatrix finalMatrix = state.fCanvasTransform; |
| 756 finalMatrix.preConcat(state.fShaderTransform); | 811 finalMatrix.preConcat(state.fShaderTransform); |
| 757 finalMatrix.preConcat(mapperMatrix); | |
| 758 | |
| 759 // Preserves as much as posible in the final matrix, and only removes | |
| 760 // the perspective. The inverse of the perspective is stored in | |
| 761 // perspectiveInverseOnly matrix and has 3 useful numbers | |
| 762 // (p0, p1, p2), while everything else is either 0 or 1. | |
| 763 // In this way the shader will handle it eficiently, with minimal code. | |
| 764 SkMatrix perspectiveInverseOnly = SkMatrix::I(); | |
| 765 if (finalMatrix.hasPerspective()) { | |
| 766 if (!split_perspective(finalMatrix, | |
| 767 &finalMatrix, &perspectiveInverseOnly)) { | |
| 768 return nullptr; | |
| 769 } | |
| 770 } | |
| 771 | |
| 772 SkRect bbox; | |
| 773 bbox.set(state.fBBox); | |
| 774 if (!inverse_transform_bbox(finalMatrix, &bbox)) { | |
| 775 return nullptr; | |
| 776 } | |
| 777 | 812 |
| 778 auto domain = sk_make_sp<SkPDFArray>(); | 813 auto domain = sk_make_sp<SkPDFArray>(); |
| 779 domain->reserve(4); | |
| 780 domain->appendScalar(bbox.fLeft); | |
| 781 domain->appendScalar(bbox.fRight); | |
| 782 domain->appendScalar(bbox.fTop); | |
| 783 domain->appendScalar(bbox.fBottom); | |
| 784 | 814 |
| 785 SkDynamicMemoryWStream functionCode; | 815 int32_t shadingType = 1; |
| 816 auto pdfShader = sk_make_sp<SkPDFDict>(); | |
| 786 // The two point radial gradient further references | 817 // The two point radial gradient further references |
| 787 // state.fInfo | 818 // state.fInfo |
| 788 // in translating from x, y coordinates to the t parameter. So, we have | 819 // in translating from x, y coordinates to the t parameter. So, we have |
| 789 // to transform the points and radii according to the calculated matrix. | 820 // to transform the points and radii according to the calculated matrix. |
| 790 if (state.fType == SkShader::kConical_GradientType) { | 821 if (doStitchFunctions) { |
| 791 SkShader::GradientInfo twoPointRadialInfo = *info; | 822 pdfShader->insertObject("Function", sk_ref_sp(gradientStitchCode(*info). get())); |
| 792 SkMatrix inverseMapperMatrix; | 823 shadingType = (state.fType == SkShader::kLinear_GradientType) ? 2 : 3; |
| 793 if (!mapperMatrix.invert(&inverseMapperMatrix)) { | 824 |
| 825 auto extend = sk_make_sp<SkPDFArray>(); | |
| 826 extend->reserve(2); | |
| 827 extend->appendBool(true); | |
| 828 extend->appendBool(true); | |
| 829 pdfShader->insertObject("Extend", sk_ref_sp(extend.get())); | |
| 830 | |
| 831 auto coords = sk_make_sp<SkPDFArray>(); | |
| 832 if (state.fType == SkShader::kConical_GradientType) { | |
| 833 coords->reserve(6); | |
| 834 coords->appendScalar(info->fPoint[0].fX); | |
| 835 coords->appendScalar(info->fPoint[0].fY); | |
| 836 coords->appendScalar(info->fRadius[0]); | |
| 837 | |
| 838 coords->appendScalar(info->fPoint[1].fX); | |
| 839 coords->appendScalar(info->fPoint[1].fY); | |
| 840 coords->appendScalar(info->fRadius[1]); | |
| 841 } else if (state.fType == SkShader::kRadial_GradientType) { | |
| 842 coords->reserve(6); | |
| 843 coords->appendScalar(info->fPoint[0].fX); | |
| 844 coords->appendScalar(info->fPoint[0].fY); | |
| 845 coords->appendScalar(0); | |
| 846 | |
| 847 coords->appendScalar(info->fPoint[0].fX); | |
| 848 coords->appendScalar(info->fPoint[0].fY); | |
| 849 coords->appendScalar(info->fRadius[0]); | |
| 850 } else { | |
| 851 coords->reserve(4); | |
| 852 coords->appendScalar(info->fPoint[0].fX); | |
| 853 coords->appendScalar(info->fPoint[0].fY); | |
| 854 | |
| 855 coords->appendScalar(info->fPoint[1].fX); | |
| 856 coords->appendScalar(info->fPoint[1].fY); | |
| 857 } | |
| 858 | |
| 859 pdfShader->insertObject("Coords", sk_ref_sp(coords.get())); | |
| 860 } else { | |
| 861 // Depending on the type of the gradient, we want to transform the | |
| 862 // coordinate space in different ways. | |
| 863 transformPoints[0] = info->fPoint[0]; | |
| 864 transformPoints[1] = info->fPoint[1]; | |
| 865 switch (state.fType) { | |
| 866 case SkShader::kLinear_GradientType: | |
| 867 codeFunction = &linearCode; | |
| 868 break; | |
| 869 case SkShader::kRadial_GradientType: | |
| 870 transformPoints[1] = transformPoints[0]; | |
| 871 transformPoints[1].fX += info->fRadius[0]; | |
| 872 codeFunction = &radialCode; | |
| 873 break; | |
| 874 case SkShader::kConical_GradientType: { | |
| 875 transformPoints[1] = transformPoints[0]; | |
| 876 transformPoints[1].fX += SK_Scalar1; | |
| 877 codeFunction = &twoPointConicalCode; | |
| 878 break; | |
| 879 } | |
| 880 case SkShader::kSweep_GradientType: | |
| 881 transformPoints[1] = transformPoints[0]; | |
| 882 transformPoints[1].fX += SK_Scalar1; | |
| 883 codeFunction = &sweepCode; | |
| 884 break; | |
| 885 case SkShader::kColor_GradientType: | |
| 886 case SkShader::kNone_GradientType: | |
| 887 default: | |
| 888 return nullptr; | |
| 889 } | |
| 890 | |
| 891 // Move any scaling (assuming a unit gradient) or translation | |
| 892 // (and rotation for linear gradient), of the final gradient from | |
| 893 // info->fPoints to the matrix (updating bbox appropriately). Now | |
| 894 // the gradient can be drawn on on the unit segment. | |
| 895 SkMatrix mapperMatrix; | |
| 896 unitToPointsMatrix(transformPoints, &mapperMatrix); | |
| 897 | |
| 898 finalMatrix.preConcat(mapperMatrix); | |
| 899 | |
| 900 // Preserves as much as posible in the final matrix, and only removes | |
| 901 // the perspective. The inverse of the perspective is stored in | |
| 902 // perspectiveInverseOnly matrix and has 3 useful numbers | |
| 903 // (p0, p1, p2), while everything else is either 0 or 1. | |
| 904 // In this way the shader will handle it eficiently, with minimal code. | |
| 905 SkMatrix perspectiveInverseOnly = SkMatrix::I(); | |
| 906 if (finalMatrix.hasPerspective()) { | |
| 907 if (!split_perspective(finalMatrix, | |
| 908 &finalMatrix, &perspectiveInverseOnly)) { | |
| 909 return nullptr; | |
| 910 } | |
| 911 } | |
| 912 | |
| 913 SkRect bbox; | |
| 914 bbox.set(state.fBBox); | |
| 915 if (!inverse_transform_bbox(finalMatrix, &bbox)) { | |
| 794 return nullptr; | 916 return nullptr; |
| 795 } | 917 } |
| 796 inverseMapperMatrix.mapPoints(twoPointRadialInfo.fPoint, 2); | 918 domain->reserve(4); |
| 797 twoPointRadialInfo.fRadius[0] = | 919 domain->appendScalar(bbox.fLeft); |
| 798 inverseMapperMatrix.mapRadius(info->fRadius[0]); | 920 domain->appendScalar(bbox.fRight); |
| 799 twoPointRadialInfo.fRadius[1] = | 921 domain->appendScalar(bbox.fTop); |
| 800 inverseMapperMatrix.mapRadius(info->fRadius[1]); | 922 domain->appendScalar(bbox.fBottom); |
| 801 codeFunction(twoPointRadialInfo, perspectiveInverseOnly, &functionCode); | 923 |
| 802 } else { | 924 SkDynamicMemoryWStream functionCode; |
| 803 codeFunction(*info, perspectiveInverseOnly, &functionCode); | 925 |
| 926 if (state.fType == SkShader::kConical_GradientType) { | |
| 927 SkShader::GradientInfo twoPointRadialInfo = *info; | |
| 928 SkMatrix inverseMapperMatrix; | |
| 929 if (!mapperMatrix.invert(&inverseMapperMatrix)) { | |
| 930 return nullptr; | |
| 931 } | |
| 932 inverseMapperMatrix.mapPoints(twoPointRadialInfo.fPoint, 2); | |
| 933 twoPointRadialInfo.fRadius[0] = | |
| 934 inverseMapperMatrix.mapRadius(info->fRadius[0]); | |
| 935 twoPointRadialInfo.fRadius[1] = | |
| 936 inverseMapperMatrix.mapRadius(info->fRadius[1]); | |
| 937 codeFunction(twoPointRadialInfo, perspectiveInverseOnly, &functionCo de); | |
| 938 } else { | |
| 939 codeFunction(*info, perspectiveInverseOnly, &functionCode); | |
| 940 } | |
| 941 | |
| 942 pdfShader->insertObject("Domain", sk_ref_sp(domain.get())); | |
| 943 | |
| 944 // Call canon->makeRangeObject() instead of | |
| 945 // SkPDFShader::MakeRangeObject() so that the canon can | |
| 946 // deduplicate. | |
| 947 std::unique_ptr<SkStreamAsset> functionStream( | |
| 948 functionCode.detachAsStream()); | |
| 949 auto function = make_ps_function(std::move(functionStream), domain.get() , | |
| 950 canon->makeRangeObject()); | |
| 951 pdfShader->insertObjRef("Function", std::move(function)); | |
| 804 } | 952 } |
| 805 | 953 |
| 806 auto pdfShader = sk_make_sp<SkPDFDict>(); | 954 pdfShader->insertInt("ShadingType", shadingType); |
| 807 pdfShader->insertInt("ShadingType", 1); | |
| 808 pdfShader->insertName("ColorSpace", "DeviceRGB"); | 955 pdfShader->insertName("ColorSpace", "DeviceRGB"); |
| 809 pdfShader->insertObject("Domain", sk_ref_sp(domain.get())); | |
| 810 | |
| 811 // Call canon->makeRangeObject() instead of | |
| 812 // SkPDFShader::MakeRangeObject() so that the canon can | |
| 813 // deduplicate. | |
| 814 std::unique_ptr<SkStreamAsset> functionStream( | |
| 815 functionCode.detachAsStream()); | |
| 816 auto function = make_ps_function(std::move(functionStream), domain.get(), | |
| 817 canon->makeRangeObject()); | |
| 818 pdfShader->insertObjRef("Function", std::move(function)); | |
| 819 | 956 |
| 820 sk_sp<SkPDFFunctionShader> pdfFunctionShader( | 957 sk_sp<SkPDFFunctionShader> pdfFunctionShader( |
| 821 new SkPDFFunctionShader(autoState->release())); | 958 new SkPDFFunctionShader(autoState->release())); |
| 822 pdfFunctionShader->insertInt("PatternType", 2); | 959 pdfFunctionShader->insertInt("PatternType", 2); |
| 823 pdfFunctionShader->insertObject("Matrix", | 960 pdfFunctionShader->insertObject("Matrix", |
| 824 SkPDFUtils::MatrixToArray(finalMatrix)); | 961 SkPDFUtils::MatrixToArray(finalMatrix)); |
| 825 pdfFunctionShader->insertObject("Shading", std::move(pdfShader)); | 962 pdfFunctionShader->insertObject("Shading", std::move(pdfShader)); |
| 826 | 963 |
| 827 canon->addFunctionShader(pdfFunctionShader.get()); | 964 canon->addFunctionShader(pdfFunctionShader.get()); |
| 828 return pdfFunctionShader.release(); | 965 return pdfFunctionShader.release(); |
| (...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1231 return false; | 1368 return false; |
| 1232 } | 1369 } |
| 1233 | 1370 |
| 1234 void SkPDFShader::State::AllocateGradientInfoStorage() { | 1371 void SkPDFShader::State::AllocateGradientInfoStorage() { |
| 1235 fColorData.set(sk_malloc_throw( | 1372 fColorData.set(sk_malloc_throw( |
| 1236 fInfo.fColorCount * (sizeof(SkColor) + sizeof(SkScalar)))); | 1373 fInfo.fColorCount * (sizeof(SkColor) + sizeof(SkScalar)))); |
| 1237 fInfo.fColors = reinterpret_cast<SkColor*>(fColorData.get()); | 1374 fInfo.fColors = reinterpret_cast<SkColor*>(fColorData.get()); |
| 1238 fInfo.fColorOffsets = | 1375 fInfo.fColorOffsets = |
| 1239 reinterpret_cast<SkScalar*>(fInfo.fColors + fInfo.fColorCount); | 1376 reinterpret_cast<SkScalar*>(fInfo.fColors + fInfo.fColorCount); |
| 1240 } | 1377 } |
| OLD | NEW |