gfx/skia/trunk/src/effects/SkLayerDrawLooper.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

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.

michael@0 1
michael@0 2 /*
michael@0 3 * Copyright 2011 Google Inc.
michael@0 4 *
michael@0 5 * Use of this source code is governed by a BSD-style license that can be
michael@0 6 * found in the LICENSE file.
michael@0 7 */
michael@0 8 #include "SkCanvas.h"
michael@0 9 #include "SkColor.h"
michael@0 10 #include "SkReadBuffer.h"
michael@0 11 #include "SkWriteBuffer.h"
michael@0 12 #include "SkLayerDrawLooper.h"
michael@0 13 #include "SkString.h"
michael@0 14 #include "SkStringUtils.h"
michael@0 15 #include "SkUnPreMultiply.h"
michael@0 16
michael@0 17 SkLayerDrawLooper::LayerInfo::LayerInfo() {
michael@0 18 fPaintBits = 0; // ignore our paint fields
michael@0 19 fColorMode = SkXfermode::kDst_Mode; // ignore our color
michael@0 20 fOffset.set(0, 0);
michael@0 21 fPostTranslate = false;
michael@0 22 }
michael@0 23
michael@0 24 SkLayerDrawLooper::SkLayerDrawLooper()
michael@0 25 : fRecs(NULL),
michael@0 26 fTopRec(NULL),
michael@0 27 fCount(0) {
michael@0 28 }
michael@0 29
michael@0 30 SkLayerDrawLooper::~SkLayerDrawLooper() {
michael@0 31 Rec* rec = fRecs;
michael@0 32 while (rec) {
michael@0 33 Rec* next = rec->fNext;
michael@0 34 SkDELETE(rec);
michael@0 35 rec = next;
michael@0 36 }
michael@0 37 }
michael@0 38
michael@0 39 SkPaint* SkLayerDrawLooper::addLayer(const LayerInfo& info) {
michael@0 40 fCount += 1;
michael@0 41
michael@0 42 Rec* rec = SkNEW(Rec);
michael@0 43 rec->fNext = fRecs;
michael@0 44 rec->fInfo = info;
michael@0 45 fRecs = rec;
michael@0 46 if (NULL == fTopRec) {
michael@0 47 fTopRec = rec;
michael@0 48 }
michael@0 49
michael@0 50 return &rec->fPaint;
michael@0 51 }
michael@0 52
michael@0 53 void SkLayerDrawLooper::addLayer(SkScalar dx, SkScalar dy) {
michael@0 54 LayerInfo info;
michael@0 55
michael@0 56 info.fOffset.set(dx, dy);
michael@0 57 (void)this->addLayer(info);
michael@0 58 }
michael@0 59
michael@0 60 SkPaint* SkLayerDrawLooper::addLayerOnTop(const LayerInfo& info) {
michael@0 61 fCount += 1;
michael@0 62
michael@0 63 Rec* rec = SkNEW(Rec);
michael@0 64 rec->fNext = NULL;
michael@0 65 rec->fInfo = info;
michael@0 66 if (NULL == fRecs) {
michael@0 67 fRecs = rec;
michael@0 68 } else {
michael@0 69 SkASSERT(NULL != fTopRec);
michael@0 70 fTopRec->fNext = rec;
michael@0 71 }
michael@0 72 fTopRec = rec;
michael@0 73
michael@0 74 return &rec->fPaint;
michael@0 75 }
michael@0 76
michael@0 77 SkLayerDrawLooper::Context* SkLayerDrawLooper::createContext(SkCanvas* canvas, void* storage) const {
michael@0 78 canvas->save(SkCanvas::kMatrix_SaveFlag);
michael@0 79 return SkNEW_PLACEMENT_ARGS(storage, LayerDrawLooperContext, (this));
michael@0 80 }
michael@0 81
michael@0 82 static SkColor xferColor(SkColor src, SkColor dst, SkXfermode::Mode mode) {
michael@0 83 switch (mode) {
michael@0 84 case SkXfermode::kSrc_Mode:
michael@0 85 return src;
michael@0 86 case SkXfermode::kDst_Mode:
michael@0 87 return dst;
michael@0 88 default: {
michael@0 89 SkPMColor pmS = SkPreMultiplyColor(src);
michael@0 90 SkPMColor pmD = SkPreMultiplyColor(dst);
michael@0 91 SkPMColor result = SkXfermode::GetProc(mode)(pmS, pmD);
michael@0 92 return SkUnPreMultiply::PMColorToColor(result);
michael@0 93 }
michael@0 94 }
michael@0 95 }
michael@0 96
michael@0 97 // Even with kEntirePaint_Bits, we always ensure that the master paint's
michael@0 98 // text-encoding is respected, since that controls how we interpret the
michael@0 99 // text/length parameters of a draw[Pos]Text call.
michael@0 100 void SkLayerDrawLooper::LayerDrawLooperContext::ApplyInfo(
michael@0 101 SkPaint* dst, const SkPaint& src, const LayerInfo& info) {
michael@0 102
michael@0 103 dst->setColor(xferColor(src.getColor(), dst->getColor(), info.fColorMode));
michael@0 104
michael@0 105 BitFlags bits = info.fPaintBits;
michael@0 106 SkPaint::TextEncoding encoding = dst->getTextEncoding();
michael@0 107
michael@0 108 if (0 == bits) {
michael@0 109 return;
michael@0 110 }
michael@0 111 if (kEntirePaint_Bits == bits) {
michael@0 112 // we've already computed these, so save it from the assignment
michael@0 113 uint32_t f = dst->getFlags();
michael@0 114 SkColor c = dst->getColor();
michael@0 115 *dst = src;
michael@0 116 dst->setFlags(f);
michael@0 117 dst->setColor(c);
michael@0 118 dst->setTextEncoding(encoding);
michael@0 119 return;
michael@0 120 }
michael@0 121
michael@0 122 if (bits & kStyle_Bit) {
michael@0 123 dst->setStyle(src.getStyle());
michael@0 124 dst->setStrokeWidth(src.getStrokeWidth());
michael@0 125 dst->setStrokeMiter(src.getStrokeMiter());
michael@0 126 dst->setStrokeCap(src.getStrokeCap());
michael@0 127 dst->setStrokeJoin(src.getStrokeJoin());
michael@0 128 }
michael@0 129
michael@0 130 if (bits & kTextSkewX_Bit) {
michael@0 131 dst->setTextSkewX(src.getTextSkewX());
michael@0 132 }
michael@0 133
michael@0 134 if (bits & kPathEffect_Bit) {
michael@0 135 dst->setPathEffect(src.getPathEffect());
michael@0 136 }
michael@0 137 if (bits & kMaskFilter_Bit) {
michael@0 138 dst->setMaskFilter(src.getMaskFilter());
michael@0 139 }
michael@0 140 if (bits & kShader_Bit) {
michael@0 141 dst->setShader(src.getShader());
michael@0 142 }
michael@0 143 if (bits & kColorFilter_Bit) {
michael@0 144 dst->setColorFilter(src.getColorFilter());
michael@0 145 }
michael@0 146 if (bits & kXfermode_Bit) {
michael@0 147 dst->setXfermode(src.getXfermode());
michael@0 148 }
michael@0 149
michael@0 150 // we don't override these
michael@0 151 #if 0
michael@0 152 dst->setTypeface(src.getTypeface());
michael@0 153 dst->setTextSize(src.getTextSize());
michael@0 154 dst->setTextScaleX(src.getTextScaleX());
michael@0 155 dst->setRasterizer(src.getRasterizer());
michael@0 156 dst->setLooper(src.getLooper());
michael@0 157 dst->setTextEncoding(src.getTextEncoding());
michael@0 158 dst->setHinting(src.getHinting());
michael@0 159 #endif
michael@0 160 }
michael@0 161
michael@0 162 // Should we add this to canvas?
michael@0 163 static void postTranslate(SkCanvas* canvas, SkScalar dx, SkScalar dy) {
michael@0 164 SkMatrix m = canvas->getTotalMatrix();
michael@0 165 m.postTranslate(dx, dy);
michael@0 166 canvas->setMatrix(m);
michael@0 167 }
michael@0 168
michael@0 169 SkLayerDrawLooper::LayerDrawLooperContext::LayerDrawLooperContext(
michael@0 170 const SkLayerDrawLooper* looper) : fCurrRec(looper->fRecs) {}
michael@0 171
michael@0 172 bool SkLayerDrawLooper::LayerDrawLooperContext::next(SkCanvas* canvas,
michael@0 173 SkPaint* paint) {
michael@0 174 canvas->restore();
michael@0 175 if (NULL == fCurrRec) {
michael@0 176 return false;
michael@0 177 }
michael@0 178
michael@0 179 ApplyInfo(paint, fCurrRec->fPaint, fCurrRec->fInfo);
michael@0 180
michael@0 181 canvas->save(SkCanvas::kMatrix_SaveFlag);
michael@0 182 if (fCurrRec->fInfo.fPostTranslate) {
michael@0 183 postTranslate(canvas, fCurrRec->fInfo.fOffset.fX,
michael@0 184 fCurrRec->fInfo.fOffset.fY);
michael@0 185 } else {
michael@0 186 canvas->translate(fCurrRec->fInfo.fOffset.fX,
michael@0 187 fCurrRec->fInfo.fOffset.fY);
michael@0 188 }
michael@0 189 fCurrRec = fCurrRec->fNext;
michael@0 190
michael@0 191 return true;
michael@0 192 }
michael@0 193
michael@0 194 ///////////////////////////////////////////////////////////////////////////////
michael@0 195
michael@0 196 void SkLayerDrawLooper::flatten(SkWriteBuffer& buffer) const {
michael@0 197 this->INHERITED::flatten(buffer);
michael@0 198
michael@0 199 #ifdef SK_DEBUG
michael@0 200 {
michael@0 201 Rec* rec = fRecs;
michael@0 202 int count = 0;
michael@0 203 while (rec) {
michael@0 204 rec = rec->fNext;
michael@0 205 count += 1;
michael@0 206 }
michael@0 207 SkASSERT(count == fCount);
michael@0 208 }
michael@0 209 #endif
michael@0 210
michael@0 211 buffer.writeInt(fCount);
michael@0 212
michael@0 213 Rec* rec = fRecs;
michael@0 214 for (int i = 0; i < fCount; i++) {
michael@0 215 // Legacy "flagsmask" field -- now ignored, remove when we bump version
michael@0 216 buffer.writeInt(0);
michael@0 217
michael@0 218 buffer.writeInt(rec->fInfo.fPaintBits);
michael@0 219 buffer.writeInt(rec->fInfo.fColorMode);
michael@0 220 buffer.writePoint(rec->fInfo.fOffset);
michael@0 221 buffer.writeBool(rec->fInfo.fPostTranslate);
michael@0 222 buffer.writePaint(rec->fPaint);
michael@0 223 rec = rec->fNext;
michael@0 224 }
michael@0 225 }
michael@0 226
michael@0 227 SkFlattenable* SkLayerDrawLooper::CreateProc(SkReadBuffer& buffer) {
michael@0 228 int count = buffer.readInt();
michael@0 229
michael@0 230 Builder builder;
michael@0 231 for (int i = 0; i < count; i++) {
michael@0 232 LayerInfo info;
michael@0 233 // Legacy "flagsmask" field -- now ignored, remove when we bump version
michael@0 234 (void)buffer.readInt();
michael@0 235
michael@0 236 info.fPaintBits = buffer.readInt();
michael@0 237 info.fColorMode = (SkXfermode::Mode)buffer.readInt();
michael@0 238 buffer.readPoint(&info.fOffset);
michael@0 239 info.fPostTranslate = buffer.readBool();
michael@0 240 buffer.readPaint(builder.addLayerOnTop(info));
michael@0 241 }
michael@0 242 SkLayerDrawLooper* looper = builder.detachLooper();
michael@0 243 SkASSERT(count == looper->fCount);
michael@0 244
michael@0 245 #ifdef SK_DEBUG
michael@0 246 {
michael@0 247 Rec* rec = looper->fRecs;
michael@0 248 int n = 0;
michael@0 249 while (rec) {
michael@0 250 rec = rec->fNext;
michael@0 251 n += 1;
michael@0 252 }
michael@0 253 SkASSERT(count == n);
michael@0 254 }
michael@0 255 #endif
michael@0 256
michael@0 257 return looper;
michael@0 258 }
michael@0 259
michael@0 260 #ifndef SK_IGNORE_TO_STRING
michael@0 261 void SkLayerDrawLooper::toString(SkString* str) const {
michael@0 262 str->appendf("SkLayerDrawLooper (%d): ", fCount);
michael@0 263
michael@0 264 Rec* rec = fRecs;
michael@0 265 for (int i = 0; i < fCount; i++) {
michael@0 266 str->appendf("%d: paintBits: (", i);
michael@0 267 if (0 == rec->fInfo.fPaintBits) {
michael@0 268 str->append("None");
michael@0 269 } else if (kEntirePaint_Bits == rec->fInfo.fPaintBits) {
michael@0 270 str->append("EntirePaint");
michael@0 271 } else {
michael@0 272 bool needSeparator = false;
michael@0 273 SkAddFlagToString(str, SkToBool(kStyle_Bit & rec->fInfo.fPaintBits), "Style",
michael@0 274 &needSeparator);
michael@0 275 SkAddFlagToString(str, SkToBool(kTextSkewX_Bit & rec->fInfo.fPaintBits), "TextSkewX",
michael@0 276 &needSeparator);
michael@0 277 SkAddFlagToString(str, SkToBool(kPathEffect_Bit & rec->fInfo.fPaintBits), "PathEffect",
michael@0 278 &needSeparator);
michael@0 279 SkAddFlagToString(str, SkToBool(kMaskFilter_Bit & rec->fInfo.fPaintBits), "MaskFilter",
michael@0 280 &needSeparator);
michael@0 281 SkAddFlagToString(str, SkToBool(kShader_Bit & rec->fInfo.fPaintBits), "Shader",
michael@0 282 &needSeparator);
michael@0 283 SkAddFlagToString(str, SkToBool(kColorFilter_Bit & rec->fInfo.fPaintBits), "ColorFilter",
michael@0 284 &needSeparator);
michael@0 285 SkAddFlagToString(str, SkToBool(kXfermode_Bit & rec->fInfo.fPaintBits), "Xfermode",
michael@0 286 &needSeparator);
michael@0 287 }
michael@0 288 str->append(") ");
michael@0 289
michael@0 290 static const char* gModeStrings[SkXfermode::kLastMode+1] = {
michael@0 291 "kClear", "kSrc", "kDst", "kSrcOver", "kDstOver", "kSrcIn", "kDstIn",
michael@0 292 "kSrcOut", "kDstOut", "kSrcATop", "kDstATop", "kXor", "kPlus",
michael@0 293 "kMultiply", "kScreen", "kOverlay", "kDarken", "kLighten", "kColorDodge",
michael@0 294 "kColorBurn", "kHardLight", "kSoftLight", "kDifference", "kExclusion"
michael@0 295 };
michael@0 296
michael@0 297 str->appendf("mode: %s ", gModeStrings[rec->fInfo.fColorMode]);
michael@0 298
michael@0 299 str->append("offset: (");
michael@0 300 str->appendScalar(rec->fInfo.fOffset.fX);
michael@0 301 str->append(", ");
michael@0 302 str->appendScalar(rec->fInfo.fOffset.fY);
michael@0 303 str->append(") ");
michael@0 304
michael@0 305 str->append("postTranslate: ");
michael@0 306 if (rec->fInfo.fPostTranslate) {
michael@0 307 str->append("true ");
michael@0 308 } else {
michael@0 309 str->append("false ");
michael@0 310 }
michael@0 311
michael@0 312 rec->fPaint.toString(str);
michael@0 313 rec = rec->fNext;
michael@0 314 }
michael@0 315 }
michael@0 316 #endif
michael@0 317
michael@0 318 SkLayerDrawLooper::Builder::Builder()
michael@0 319 : fRecs(NULL),
michael@0 320 fTopRec(NULL),
michael@0 321 fCount(0) {
michael@0 322 }
michael@0 323
michael@0 324 SkLayerDrawLooper::Builder::~Builder() {
michael@0 325 Rec* rec = fRecs;
michael@0 326 while (rec) {
michael@0 327 Rec* next = rec->fNext;
michael@0 328 SkDELETE(rec);
michael@0 329 rec = next;
michael@0 330 }
michael@0 331 }
michael@0 332
michael@0 333 SkPaint* SkLayerDrawLooper::Builder::addLayer(const LayerInfo& info) {
michael@0 334 fCount += 1;
michael@0 335
michael@0 336 Rec* rec = SkNEW(Rec);
michael@0 337 rec->fNext = fRecs;
michael@0 338 rec->fInfo = info;
michael@0 339 fRecs = rec;
michael@0 340 if (NULL == fTopRec) {
michael@0 341 fTopRec = rec;
michael@0 342 }
michael@0 343
michael@0 344 return &rec->fPaint;
michael@0 345 }
michael@0 346
michael@0 347 void SkLayerDrawLooper::Builder::addLayer(SkScalar dx, SkScalar dy) {
michael@0 348 LayerInfo info;
michael@0 349
michael@0 350 info.fOffset.set(dx, dy);
michael@0 351 (void)this->addLayer(info);
michael@0 352 }
michael@0 353
michael@0 354 SkPaint* SkLayerDrawLooper::Builder::addLayerOnTop(const LayerInfo& info) {
michael@0 355 fCount += 1;
michael@0 356
michael@0 357 Rec* rec = SkNEW(Rec);
michael@0 358 rec->fNext = NULL;
michael@0 359 rec->fInfo = info;
michael@0 360 if (NULL == fRecs) {
michael@0 361 fRecs = rec;
michael@0 362 } else {
michael@0 363 SkASSERT(NULL != fTopRec);
michael@0 364 fTopRec->fNext = rec;
michael@0 365 }
michael@0 366 fTopRec = rec;
michael@0 367
michael@0 368 return &rec->fPaint;
michael@0 369 }
michael@0 370
michael@0 371 SkLayerDrawLooper* SkLayerDrawLooper::Builder::detachLooper() {
michael@0 372 SkLayerDrawLooper* looper = SkNEW(SkLayerDrawLooper);
michael@0 373 looper->fCount = fCount;
michael@0 374 looper->fRecs = fRecs;
michael@0 375
michael@0 376 fCount = 0;
michael@0 377 fRecs = NULL;
michael@0 378 fTopRec = NULL;
michael@0 379
michael@0 380 return looper;
michael@0 381 }

mercurial