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

Side by Side Diff: src/pdf/SkPDFShader.cpp

Issue 2151863003: SkPdf: smaller color serialization (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: SkFixed - 2016-07-15 (Friday) 15:45:32 EDT Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/pdf/SkPDFDevice.cpp ('k') | src/pdf/SkPDFTypes.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 22 matching lines...) Expand all
33 SkVector vec = pts[1] - pts[0]; 33 SkVector vec = pts[1] - pts[0];
34 SkScalar mag = vec.length(); 34 SkScalar mag = vec.length();
35 SkScalar inv = mag ? SkScalarInvert(mag) : 0; 35 SkScalar inv = mag ? SkScalarInvert(mag) : 0;
36 36
37 vec.scale(inv); 37 vec.scale(inv);
38 matrix->setSinCos(vec.fY, vec.fX); 38 matrix->setSinCos(vec.fY, vec.fX);
39 matrix->preScale(mag, mag); 39 matrix->preScale(mag, mag);
40 matrix->postTranslate(pts[0].fX, pts[0].fY); 40 matrix->postTranslate(pts[0].fX, pts[0].fY);
41 } 41 }
42 42
43 static const int kColorComponents = 3;
44 typedef uint8_t ColorTuple[kColorComponents];
45
43 /* Assumes t + startOffset is on the stack and does a linear interpolation on t 46 /* Assumes t + startOffset is on the stack and does a linear interpolation on t
44 between startOffset and endOffset from prevColor to curColor (for each color 47 between startOffset and endOffset from prevColor to curColor (for each color
45 component), leaving the result in component order on the stack. It assumes 48 component), leaving the result in component order on the stack. It assumes
46 there are always 3 components per color. 49 there are always 3 components per color.
47 @param range endOffset - startOffset 50 @param range endOffset - startOffset
48 @param curColor[components] The current color components. 51 @param curColor[components] The current color components.
49 @param prevColor[components] The previous color components. 52 @param prevColor[components] The previous color components.
50 @param result The result ps function. 53 @param result The result ps function.
51 */ 54 */
52 static void interpolateColorCode(SkScalar range, SkScalar* curColor, 55 static void interpolateColorCode(SkScalar range, const ColorTuple& curColor,
53 SkScalar* prevColor, 56 const ColorTuple& prevColor,
54 SkDynamicMemoryWStream* result) { 57 SkDynamicMemoryWStream* result) {
55 SkASSERT(range != SkIntToScalar(0)); 58 SkASSERT(range != SkIntToScalar(0));
56 static const int kColorComponents = 3;
57 59
58 // Figure out how to scale each color component. 60 // Figure out how to scale each color component.
59 SkScalar multiplier[kColorComponents]; 61 SkScalar multiplier[kColorComponents];
60 for (int i = 0; i < kColorComponents; i++) { 62 for (int i = 0; i < kColorComponents; i++) {
61 multiplier[i] = (curColor[i] - prevColor[i]) / range; 63 static const SkScalar kColorScale = SkScalarInvert(255);
64 multiplier[i] = kColorScale * (curColor[i] - prevColor[i]) / range;
62 } 65 }
63 66
64 // Calculate when we no longer need to keep a copy of the input parameter t. 67 // Calculate when we no longer need to keep a copy of the input parameter t.
65 // If the last component to use t is i, then dupInput[0..i - 1] = true 68 // If the last component to use t is i, then dupInput[0..i - 1] = true
66 // and dupInput[i .. components] = false. 69 // and dupInput[i .. components] = false.
67 bool dupInput[kColorComponents]; 70 bool dupInput[kColorComponents];
68 dupInput[kColorComponents - 1] = false; 71 dupInput[kColorComponents - 1] = false;
69 for (int i = kColorComponents - 2; i >= 0; i--) { 72 for (int i = kColorComponents - 2; i >= 0; i--) {
70 dupInput[i] = dupInput[i + 1] || multiplier[i + 1] != 0; 73 dupInput[i] = dupInput[i + 1] || multiplier[i + 1] != 0;
71 } 74 }
72 75
73 if (!dupInput[0] && multiplier[0] == 0) { 76 if (!dupInput[0] && multiplier[0] == 0) {
74 result->writeText("pop "); 77 result->writeText("pop ");
75 } 78 }
76 79
77 for (int i = 0; i < kColorComponents; i++) { 80 for (int i = 0; i < kColorComponents; i++) {
78 // If the next components needs t and this component will consume a 81 // If the next components needs t and this component will consume a
79 // copy, make another copy. 82 // copy, make another copy.
80 if (dupInput[i] && multiplier[i] != 0) { 83 if (dupInput[i] && multiplier[i] != 0) {
81 result->writeText("dup "); 84 result->writeText("dup ");
82 } 85 }
83 86
84 if (multiplier[i] == 0) { 87 if (multiplier[i] == 0) {
85 SkPDFUtils::AppendScalar(prevColor[i], result); 88 SkPDFUtils::AppendColorComponent(prevColor[i], result);
86 result->writeText(" "); 89 result->writeText(" ");
87 } else { 90 } else {
88 if (multiplier[i] != 1) { 91 if (multiplier[i] != 1) {
89 SkPDFUtils::AppendScalar(multiplier[i], result); 92 SkPDFUtils::AppendScalar(multiplier[i], result);
90 result->writeText(" mul "); 93 result->writeText(" mul ");
91 } 94 }
92 if (prevColor[i] != 0) { 95 if (prevColor[i] != 0) {
93 SkPDFUtils::AppendScalar(prevColor[i], result); 96 SkPDFUtils::AppendColorComponent(prevColor[i], result);
94 result->writeText(" add "); 97 result->writeText(" add ");
95 } 98 }
96 } 99 }
97 100
98 if (dupInput[i]) { 101 if (dupInput[i]) {
99 result->writeText("exch\n"); 102 result->writeText("exch\n");
100 } 103 }
101 } 104 }
102 } 105 }
103 106
(...skipping 11 matching lines...) Expand all
115 colorData[2][r,g,b]); 118 colorData[2][r,g,b]);
116 } else { 119 } else {
117 120
118 ... } else { 121 ... } else {
119 return colorData[info.fColorCount - 1][r,g,b]; 122 return colorData[info.fColorCount - 1][r,g,b];
120 } 123 }
121 ... 124 ...
122 } 125 }
123 } 126 }
124 */ 127 */
125 static const int kColorComponents = 3;
126 typedef SkScalar ColorTuple[kColorComponents];
127 static void gradientFunctionCode(const SkShader::GradientInfo& info, 128 static void gradientFunctionCode(const SkShader::GradientInfo& info,
128 SkDynamicMemoryWStream* result) { 129 SkDynamicMemoryWStream* result) {
129 /* We want to linearly interpolate from the previous color to the next. 130 /* We want to linearly interpolate from the previous color to the next.
130 Scale the colors from 0..255 to 0..1 and determine the multipliers 131 Scale the colors from 0..255 to 0..1 and determine the multipliers
131 for interpolation. 132 for interpolation.
132 C{r,g,b}(t, section) = t - offset_(section-1) + t * Multiplier{r,g,b}. 133 C{r,g,b}(t, section) = t - offset_(section-1) + t * Multiplier{r,g,b}.
133 */ 134 */
134 135
135 SkAutoSTMalloc<4, ColorTuple> colorDataAlloc(info.fColorCount); 136 SkAutoSTMalloc<4, ColorTuple> colorDataAlloc(info.fColorCount);
136 ColorTuple *colorData = colorDataAlloc.get(); 137 ColorTuple *colorData = colorDataAlloc.get();
137 const SkScalar scale = SkScalarInvert(SkIntToScalar(255));
138 for (int i = 0; i < info.fColorCount; i++) { 138 for (int i = 0; i < info.fColorCount; i++) {
139 colorData[i][0] = SkScalarMul(SkColorGetR(info.fColors[i]), scale); 139 colorData[i][0] = SkColorGetR(info.fColors[i]);
140 colorData[i][1] = SkScalarMul(SkColorGetG(info.fColors[i]), scale); 140 colorData[i][1] = SkColorGetG(info.fColors[i]);
141 colorData[i][2] = SkScalarMul(SkColorGetB(info.fColors[i]), scale); 141 colorData[i][2] = SkColorGetB(info.fColors[i]);
142 } 142 }
143 143
144 // Clamp the initial color. 144 // Clamp the initial color.
145 result->writeText("dup 0 le {pop "); 145 result->writeText("dup 0 le {pop ");
146 SkPDFUtils::AppendScalar(colorData[0][0], result); 146 SkPDFUtils::AppendColorComponent(colorData[0][0], result);
147 result->writeText(" "); 147 result->writeText(" ");
148 SkPDFUtils::AppendScalar(colorData[0][1], result); 148 SkPDFUtils::AppendColorComponent(colorData[0][1], result);
149 result->writeText(" "); 149 result->writeText(" ");
150 SkPDFUtils::AppendScalar(colorData[0][2], result); 150 SkPDFUtils::AppendColorComponent(colorData[0][2], result);
151 result->writeText(" }\n"); 151 result->writeText(" }\n");
152 152
153 // The gradient colors. 153 // The gradient colors.
154 int gradients = 0; 154 int gradients = 0;
155 for (int i = 1 ; i < info.fColorCount; i++) { 155 for (int i = 1 ; i < info.fColorCount; i++) {
156 if (info.fColorOffsets[i] == info.fColorOffsets[i - 1]) { 156 if (info.fColorOffsets[i] == info.fColorOffsets[i - 1]) {
157 continue; 157 continue;
158 } 158 }
159 gradients++; 159 gradients++;
160 160
161 result->writeText("{dup "); 161 result->writeText("{dup ");
162 SkPDFUtils::AppendScalar(info.fColorOffsets[i], result); 162 SkPDFUtils::AppendScalar(info.fColorOffsets[i], result);
163 result->writeText(" le {"); 163 result->writeText(" le {");
164 if (info.fColorOffsets[i - 1] != 0) { 164 if (info.fColorOffsets[i - 1] != 0) {
165 SkPDFUtils::AppendScalar(info.fColorOffsets[i - 1], result); 165 SkPDFUtils::AppendScalar(info.fColorOffsets[i - 1], result);
166 result->writeText(" sub\n"); 166 result->writeText(" sub\n");
167 } 167 }
168 168
169 interpolateColorCode(info.fColorOffsets[i] - info.fColorOffsets[i - 1], 169 interpolateColorCode(info.fColorOffsets[i] - info.fColorOffsets[i - 1],
170 colorData[i], colorData[i - 1], result); 170 colorData[i], colorData[i - 1], result);
171 result->writeText("}\n"); 171 result->writeText("}\n");
172 } 172 }
173 173
174 // Clamp the final color. 174 // Clamp the final color.
175 result->writeText("{pop "); 175 result->writeText("{pop ");
176 SkPDFUtils::AppendScalar(colorData[info.fColorCount - 1][0], result); 176 SkPDFUtils::AppendColorComponent(colorData[info.fColorCount - 1][0], result) ;
177 result->writeText(" "); 177 result->writeText(" ");
178 SkPDFUtils::AppendScalar(colorData[info.fColorCount - 1][1], result); 178 SkPDFUtils::AppendColorComponent(colorData[info.fColorCount - 1][1], result) ;
179 result->writeText(" "); 179 result->writeText(" ");
180 SkPDFUtils::AppendScalar(colorData[info.fColorCount - 1][2], result); 180 SkPDFUtils::AppendColorComponent(colorData[info.fColorCount - 1][2], result) ;
181 181
182 for (int i = 0 ; i < gradients + 1; i++) { 182 for (int i = 0 ; i < gradients + 1; i++) {
183 result->writeText("} ifelse\n"); 183 result->writeText("} ifelse\n");
184 } 184 }
185 } 185 }
186 186
187 static sk_sp<SkPDFDict> createInterpolationFunction(const ColorTuple& color1, 187 static sk_sp<SkPDFDict> createInterpolationFunction(const ColorTuple& color1,
188 const ColorTuple& color2) { 188 const ColorTuple& color2) {
189 auto retval = sk_make_sp<SkPDFDict>(); 189 auto retval = sk_make_sp<SkPDFDict>();
190 190
191 auto c0 = sk_make_sp<SkPDFArray>(); 191 auto c0 = sk_make_sp<SkPDFArray>();
192 c0->appendScalar(color1[0]); 192 c0->appendColorComponent(color1[0]);
193 c0->appendScalar(color1[1]); 193 c0->appendColorComponent(color1[1]);
194 c0->appendScalar(color1[2]); 194 c0->appendColorComponent(color1[2]);
195 retval->insertObject("C0", std::move(c0)); 195 retval->insertObject("C0", std::move(c0));
196 196
197 auto c1 = sk_make_sp<SkPDFArray>(); 197 auto c1 = sk_make_sp<SkPDFArray>();
198 c1->appendScalar(color2[0]); 198 c1->appendColorComponent(color2[0]);
199 c1->appendScalar(color2[1]); 199 c1->appendColorComponent(color2[1]);
200 c1->appendScalar(color2[2]); 200 c1->appendColorComponent(color2[2]);
201 retval->insertObject("C1", std::move(c1)); 201 retval->insertObject("C1", std::move(c1));
202 202
203 auto domain = sk_make_sp<SkPDFArray>(); 203 auto domain = sk_make_sp<SkPDFArray>();
204 domain->appendScalar(0); 204 domain->appendScalar(0);
205 domain->appendScalar(1.0f); 205 domain->appendScalar(1.0f);
206 retval->insertObject("Domain", std::move(domain)); 206 retval->insertObject("Domain", std::move(domain));
207 207
208 retval->insertInt("FunctionType", 2); 208 retval->insertInt("FunctionType", 2);
209 retval->insertScalar("N", 1.0f); 209 retval->insertScalar("N", 1.0f);
210 210
(...skipping 30 matching lines...) Expand all
241 colorOffsets[i] += 0.00001f; 241 colorOffsets[i] += 0.00001f;
242 } 242 }
243 } 243 }
244 // check if last 2 stops coincide 244 // check if last 2 stops coincide
245 if (colorOffsets[i - 1] == colorOffsets[i]) { 245 if (colorOffsets[i - 1] == colorOffsets[i]) {
246 colorOffsets[i - 1] -= 0.00001f; 246 colorOffsets[i - 1] -= 0.00001f;
247 } 247 }
248 248
249 SkAutoSTMalloc<4, ColorTuple> colorDataAlloc(colorCount); 249 SkAutoSTMalloc<4, ColorTuple> colorDataAlloc(colorCount);
250 ColorTuple *colorData = colorDataAlloc.get(); 250 ColorTuple *colorData = colorDataAlloc.get();
251 const SkScalar scale = SkScalarInvert(SkIntToScalar(255));
252 for (int i = 0; i < colorCount; i++) { 251 for (int i = 0; i < colorCount; i++) {
253 colorData[i][0] = SkScalarMul(SkColorGetR(colors[i]), scale); 252 colorData[i][0] = SkColorGetR(colors[i]);
254 colorData[i][1] = SkScalarMul(SkColorGetG(colors[i]), scale); 253 colorData[i][1] = SkColorGetG(colors[i]);
255 colorData[i][2] = SkScalarMul(SkColorGetB(colors[i]), scale); 254 colorData[i][2] = SkColorGetB(colors[i]);
256 } 255 }
257 256
258 // no need for a stitch function if there are only 2 stops. 257 // no need for a stitch function if there are only 2 stops.
259 if (colorCount == 2) 258 if (colorCount == 2)
260 return createInterpolationFunction(colorData[0], colorData[1]); 259 return createInterpolationFunction(colorData[0], colorData[1]);
261 260
262 auto encode = sk_make_sp<SkPDFArray>(); 261 auto encode = sk_make_sp<SkPDFArray>();
263 auto bounds = sk_make_sp<SkPDFArray>(); 262 auto bounds = sk_make_sp<SkPDFArray>();
264 auto functions = sk_make_sp<SkPDFArray>(); 263 auto functions = sk_make_sp<SkPDFArray>();
265 264
(...skipping 1145 matching lines...) Expand 10 before | Expand all | Expand 10 after
1411 return false; 1410 return false;
1412 } 1411 }
1413 1412
1414 void SkPDFShader::State::AllocateGradientInfoStorage() { 1413 void SkPDFShader::State::AllocateGradientInfoStorage() {
1415 fColorData.set(sk_malloc_throw( 1414 fColorData.set(sk_malloc_throw(
1416 fInfo.fColorCount * (sizeof(SkColor) + sizeof(SkScalar)))); 1415 fInfo.fColorCount * (sizeof(SkColor) + sizeof(SkScalar))));
1417 fInfo.fColors = reinterpret_cast<SkColor*>(fColorData.get()); 1416 fInfo.fColors = reinterpret_cast<SkColor*>(fColorData.get());
1418 fInfo.fColorOffsets = 1417 fInfo.fColorOffsets =
1419 reinterpret_cast<SkScalar*>(fInfo.fColors + fInfo.fColorCount); 1418 reinterpret_cast<SkScalar*>(fInfo.fColors + fInfo.fColorCount);
1420 } 1419 }
OLDNEW
« no previous file with comments | « src/pdf/SkPDFDevice.cpp ('k') | src/pdf/SkPDFTypes.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698