gfx/skia/trunk/src/core/SkComposeShader.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.

     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

mercurial