LCOV - code coverage report
Current view: directory - gfx/skia/src/core - SkComposeShader.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 88 0 0.0 %
Date: 2012-06-02 Functions: 11 0 0.0 %

       1                 : 
       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                 :  */
       8                 : 
       9                 : 
      10                 : #include "SkComposeShader.h"
      11                 : #include "SkColorFilter.h"
      12                 : #include "SkColorPriv.h"
      13                 : #include "SkColorShader.h"
      14                 : #include "SkXfermode.h"
      15                 : 
      16                 : ///////////////////////////////////////////////////////////////////////////////
      17                 : 
      18               0 : SkComposeShader::SkComposeShader(SkShader* sA, SkShader* sB, SkXfermode* mode) {
      19               0 :     fShaderA = sA;  sA->ref();
      20               0 :     fShaderB = sB;  sB->ref();
      21                 :     // mode may be null
      22               0 :     fMode = mode;
      23               0 :     SkSafeRef(mode);
      24               0 : }
      25                 : 
      26               0 : SkComposeShader::SkComposeShader(SkFlattenableReadBuffer& buffer) :
      27               0 :     INHERITED(buffer) {
      28               0 :     fShaderA = static_cast<SkShader*>(buffer.readFlattenable());
      29               0 :     if (NULL == fShaderA) {
      30               0 :         fShaderA = SkNEW_ARGS(SkColorShader, (0));
      31                 :     }
      32               0 :     fShaderB = static_cast<SkShader*>(buffer.readFlattenable());
      33               0 :     if (NULL == fShaderB) {
      34               0 :         fShaderB = SkNEW_ARGS(SkColorShader, (0));
      35                 :     }
      36               0 :     fMode = static_cast<SkXfermode*>(buffer.readFlattenable());
      37               0 : }
      38                 : 
      39               0 : SkComposeShader::~SkComposeShader() {
      40               0 :     SkSafeUnref(fMode);
      41               0 :     fShaderB->unref();
      42               0 :     fShaderA->unref();
      43               0 : }
      44                 : 
      45               0 : void SkComposeShader::beginSession() {
      46               0 :     this->INHERITED::beginSession();
      47               0 :     fShaderA->beginSession();
      48               0 :     fShaderB->beginSession();
      49               0 : }
      50                 : 
      51               0 : void SkComposeShader::endSession() {
      52               0 :     fShaderA->endSession();
      53               0 :     fShaderB->endSession();
      54               0 :     this->INHERITED::endSession();
      55               0 : }
      56                 : 
      57                 : class SkAutoAlphaRestore {
      58                 : public:
      59               0 :     SkAutoAlphaRestore(SkPaint* paint, uint8_t newAlpha) {
      60               0 :         fAlpha = paint->getAlpha();
      61               0 :         fPaint = paint;
      62               0 :         paint->setAlpha(newAlpha);
      63               0 :     }
      64                 : 
      65               0 :     ~SkAutoAlphaRestore() {
      66               0 :         fPaint->setAlpha(fAlpha);
      67               0 :     }
      68                 : private:
      69                 :     SkPaint*    fPaint;
      70                 :     uint8_t     fAlpha;
      71                 : };
      72                 : 
      73               0 : void SkComposeShader::flatten(SkFlattenableWriteBuffer& buffer) {
      74               0 :     this->INHERITED::flatten(buffer);
      75               0 :     buffer.writeFlattenable(fShaderA);
      76               0 :     buffer.writeFlattenable(fShaderB);
      77               0 :     buffer.writeFlattenable(fMode);
      78               0 : }
      79                 : 
      80                 : /*  We call setContext on our two worker shaders. However, we
      81                 :     always let them see opaque alpha, and if the paint really
      82                 :     is translucent, then we apply that after the fact.
      83                 : */
      84               0 : bool SkComposeShader::setContext(const SkBitmap& device,
      85                 :                                  const SkPaint& paint,
      86                 :                                  const SkMatrix& matrix) {
      87               0 :     if (!this->INHERITED::setContext(device, paint, matrix)) {
      88               0 :         return false;
      89                 :     }
      90                 : 
      91                 :     // we preconcat our localMatrix (if any) with the device matrix
      92                 :     // before calling our sub-shaders
      93                 : 
      94                 :     SkMatrix tmpM;
      95                 : 
      96               0 :     (void)this->getLocalMatrix(&tmpM);
      97               0 :     tmpM.setConcat(matrix, tmpM);
      98                 : 
      99               0 :     SkAutoAlphaRestore  restore(const_cast<SkPaint*>(&paint), 0xFF);
     100                 : 
     101               0 :     return  fShaderA->setContext(device, paint, tmpM) &&
     102               0 :             fShaderB->setContext(device, paint, tmpM);
     103                 : }
     104                 : 
     105                 : // larger is better (fewer times we have to loop), but we shouldn't
     106                 : // take up too much stack-space (each element is 4 bytes)
     107                 : #define TMP_COLOR_COUNT     64
     108                 : 
     109               0 : void SkComposeShader::shadeSpan(int x, int y, SkPMColor result[], int count) {
     110               0 :     SkShader*   shaderA = fShaderA;
     111               0 :     SkShader*   shaderB = fShaderB;
     112               0 :     SkXfermode* mode = fMode;
     113               0 :     unsigned    scale = SkAlpha255To256(this->getPaintAlpha());
     114                 : 
     115                 :     SkPMColor   tmp[TMP_COLOR_COUNT];
     116                 : 
     117               0 :     if (NULL == mode) {   // implied SRC_OVER
     118                 :         // TODO: when we have a good test-case, should use SkBlitRow::Proc32
     119                 :         // for these loops
     120               0 :         do {
     121               0 :             int n = count;
     122               0 :             if (n > TMP_COLOR_COUNT) {
     123               0 :                 n = TMP_COLOR_COUNT;
     124                 :             }
     125                 : 
     126               0 :             shaderA->shadeSpan(x, y, result, n);
     127               0 :             shaderB->shadeSpan(x, y, tmp, n);
     128                 : 
     129               0 :             if (256 == scale) {
     130               0 :                 for (int i = 0; i < n; i++) {
     131               0 :                     result[i] = SkPMSrcOver(tmp[i], result[i]);
     132                 :                 }
     133                 :             } else {
     134               0 :                 for (int i = 0; i < n; i++) {
     135               0 :                     result[i] = SkAlphaMulQ(SkPMSrcOver(tmp[i], result[i]),
     136               0 :                                             scale);
     137                 :                 }
     138                 :             }
     139                 : 
     140               0 :             result += n;
     141               0 :             x += n;
     142               0 :             count -= n;
     143                 :         } while (count > 0);
     144                 :     } else {    // use mode for the composition
     145               0 :         do {
     146               0 :             int n = count;
     147               0 :             if (n > TMP_COLOR_COUNT) {
     148               0 :                 n = TMP_COLOR_COUNT;
     149                 :             }
     150                 : 
     151               0 :             shaderA->shadeSpan(x, y, result, n);
     152               0 :             shaderB->shadeSpan(x, y, tmp, n);
     153               0 :             mode->xfer32(result, tmp, n, NULL);
     154                 : 
     155               0 :             if (256 == scale) {
     156               0 :                 for (int i = 0; i < n; i++) {
     157               0 :                     result[i] = SkAlphaMulQ(result[i], scale);
     158                 :                 }
     159                 :             }
     160                 : 
     161               0 :             result += n;
     162               0 :             x += n;
     163               0 :             count -= n;
     164                 :         } while (count > 0);
     165                 :     }
     166               0 : }
     167                 : 

Generated by: LCOV version 1.7