Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
2 /*
3 * Copyright 2006 The Android Open Source Project
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
10 #include "SkComposeShader.h"
11 #include "SkColorFilter.h"
12 #include "SkColorPriv.h"
13 #include "SkColorShader.h"
14 #include "SkReadBuffer.h"
15 #include "SkWriteBuffer.h"
16 #include "SkXfermode.h"
17 #include "SkString.h"
19 ///////////////////////////////////////////////////////////////////////////////
21 SkComposeShader::SkComposeShader(SkShader* sA, SkShader* sB, SkXfermode* mode) {
22 fShaderA = sA; sA->ref();
23 fShaderB = sB; sB->ref();
24 // mode may be null
25 fMode = mode;
26 SkSafeRef(mode);
27 }
29 SkComposeShader::SkComposeShader(SkReadBuffer& buffer) :
30 INHERITED(buffer) {
31 fShaderA = buffer.readShader();
32 if (NULL == fShaderA) {
33 fShaderA = SkNEW_ARGS(SkColorShader, (0));
34 }
35 fShaderB = buffer.readShader();
36 if (NULL == fShaderB) {
37 fShaderB = SkNEW_ARGS(SkColorShader, (0));
38 }
39 fMode = buffer.readXfermode();
40 }
42 SkComposeShader::~SkComposeShader() {
43 SkSafeUnref(fMode);
44 fShaderB->unref();
45 fShaderA->unref();
46 }
48 class SkAutoAlphaRestore {
49 public:
50 SkAutoAlphaRestore(SkPaint* paint, uint8_t newAlpha) {
51 fAlpha = paint->getAlpha();
52 fPaint = paint;
53 paint->setAlpha(newAlpha);
54 }
56 ~SkAutoAlphaRestore() {
57 fPaint->setAlpha(fAlpha);
58 }
59 private:
60 SkPaint* fPaint;
61 uint8_t fAlpha;
62 };
63 #define SkAutoAlphaRestore(...) SK_REQUIRE_LOCAL_VAR(SkAutoAlphaRestore)
65 void SkComposeShader::flatten(SkWriteBuffer& buffer) const {
66 this->INHERITED::flatten(buffer);
67 buffer.writeFlattenable(fShaderA);
68 buffer.writeFlattenable(fShaderB);
69 buffer.writeFlattenable(fMode);
70 }
72 /* We call setContext on our two worker shaders. However, we
73 always let them see opaque alpha, and if the paint really
74 is translucent, then we apply that after the fact.
76 We need to keep the calls to setContext/endContext balanced, since if we
77 return false, our endContext() will not be called.
78 */
79 bool SkComposeShader::setContext(const SkBitmap& device,
80 const SkPaint& paint,
81 const SkMatrix& matrix) {
82 if (!this->INHERITED::setContext(device, paint, matrix)) {
83 return false;
84 }
86 // we preconcat our localMatrix (if any) with the device matrix
87 // before calling our sub-shaders
89 SkMatrix tmpM;
91 tmpM.setConcat(matrix, this->getLocalMatrix());
93 SkAutoAlphaRestore restore(const_cast<SkPaint*>(&paint), 0xFF);
95 bool setContextA = fShaderA->setContext(device, paint, tmpM);
96 bool setContextB = fShaderB->setContext(device, paint, tmpM);
97 if (!setContextA || !setContextB) {
98 if (setContextB) {
99 fShaderB->endContext();
100 }
101 else if (setContextA) {
102 fShaderA->endContext();
103 }
104 this->INHERITED::endContext();
105 return false;
106 }
107 return true;
108 }
110 void SkComposeShader::endContext() {
111 fShaderB->endContext();
112 fShaderA->endContext();
113 this->INHERITED::endContext();
114 }
116 // larger is better (fewer times we have to loop), but we shouldn't
117 // take up too much stack-space (each element is 4 bytes)
118 #define TMP_COLOR_COUNT 64
120 void SkComposeShader::shadeSpan(int x, int y, SkPMColor result[], int count) {
121 SkShader* shaderA = fShaderA;
122 SkShader* shaderB = fShaderB;
123 SkXfermode* mode = fMode;
124 unsigned scale = SkAlpha255To256(this->getPaintAlpha());
126 SkPMColor tmp[TMP_COLOR_COUNT];
128 if (NULL == mode) { // implied SRC_OVER
129 // TODO: when we have a good test-case, should use SkBlitRow::Proc32
130 // for these loops
131 do {
132 int n = count;
133 if (n > TMP_COLOR_COUNT) {
134 n = TMP_COLOR_COUNT;
135 }
137 shaderA->shadeSpan(x, y, result, n);
138 shaderB->shadeSpan(x, y, tmp, n);
140 if (256 == scale) {
141 for (int i = 0; i < n; i++) {
142 result[i] = SkPMSrcOver(tmp[i], result[i]);
143 }
144 } else {
145 for (int i = 0; i < n; i++) {
146 result[i] = SkAlphaMulQ(SkPMSrcOver(tmp[i], result[i]),
147 scale);
148 }
149 }
151 result += n;
152 x += n;
153 count -= n;
154 } while (count > 0);
155 } else { // use mode for the composition
156 do {
157 int n = count;
158 if (n > TMP_COLOR_COUNT) {
159 n = TMP_COLOR_COUNT;
160 }
162 shaderA->shadeSpan(x, y, result, n);
163 shaderB->shadeSpan(x, y, tmp, n);
164 mode->xfer32(result, tmp, n, NULL);
166 if (256 == scale) {
167 for (int i = 0; i < n; i++) {
168 result[i] = SkAlphaMulQ(result[i], scale);
169 }
170 }
172 result += n;
173 x += n;
174 count -= n;
175 } while (count > 0);
176 }
177 }
179 #ifndef SK_IGNORE_TO_STRING
180 void SkComposeShader::toString(SkString* str) const {
181 str->append("SkComposeShader: (");
183 str->append("ShaderA: ");
184 fShaderA->toString(str);
185 str->append(" ShaderB: ");
186 fShaderB->toString(str);
187 str->append(" Xfermode: ");
188 fMode->toString(str);
190 this->INHERITED::toString(str);
192 str->append(")");
193 }
194 #endif