LCOV - code coverage report
Current view: directory - gfx/skia/src/core - SkBlitter_A8.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 185 0 0.0 %
Date: 2012-06-02 Functions: 15 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 "SkCoreBlitters.h"
      11                 : #include "SkColorPriv.h"
      12                 : #include "SkShader.h"
      13                 : #include "SkXfermode.h"
      14                 : 
      15               0 : SkA8_Blitter::SkA8_Blitter(const SkBitmap& device, const SkPaint& paint)
      16               0 :         : INHERITED(device) {
      17               0 :     fSrcA = paint.getAlpha();
      18               0 : }
      19                 : 
      20               0 : const SkBitmap* SkA8_Blitter::justAnOpaqueColor(uint32_t* value) {
      21               0 :     if (255 == fSrcA) {
      22               0 :         *value = 255;
      23               0 :         return &fDevice;
      24                 :     }
      25               0 :     return NULL;
      26                 : }
      27                 : 
      28               0 : void SkA8_Blitter::blitH(int x, int y, int width) {
      29               0 :     SkASSERT(x >= 0 && y >= 0 &&
      30                 :              (unsigned)(x + width) <= (unsigned)fDevice.width());
      31                 : 
      32               0 :     if (fSrcA == 0) {
      33               0 :         return;
      34                 :     }
      35                 : 
      36               0 :     uint8_t* device = fDevice.getAddr8(x, y);
      37                 : 
      38               0 :     if (fSrcA == 255) {
      39               0 :         memset(device, 0xFF, width);
      40                 :     } else {
      41               0 :         unsigned scale = 256 - SkAlpha255To256(fSrcA);
      42               0 :         unsigned srcA = fSrcA;
      43                 : 
      44               0 :         for (int i = 0; i < width; i++) {
      45               0 :             device[i] = SkToU8(srcA + SkAlphaMul(device[i], scale));
      46                 :         }
      47                 :     }
      48                 : }
      49                 : 
      50               0 : void SkA8_Blitter::blitAntiH(int x, int y, const SkAlpha antialias[],
      51                 :                              const int16_t runs[]) {
      52               0 :     if (fSrcA == 0) {
      53               0 :         return;
      54                 :     }
      55                 : 
      56               0 :     uint8_t*    device = fDevice.getAddr8(x, y);
      57               0 :     unsigned    srcA = fSrcA;
      58                 : 
      59               0 :     for (;;) {
      60               0 :         int count = runs[0];
      61               0 :         SkASSERT(count >= 0);
      62               0 :         if (count == 0) {
      63               0 :             return;
      64                 :         }
      65               0 :         unsigned aa = antialias[0];
      66                 : 
      67               0 :         if (aa == 255 && srcA == 255) {
      68               0 :             memset(device, 0xFF, count);
      69                 :         } else {
      70               0 :             unsigned sa = SkAlphaMul(srcA, SkAlpha255To256(aa));
      71               0 :             unsigned scale = 256 - sa;
      72                 : 
      73               0 :             for (int i = 0; i < count; i++) {
      74               0 :                 device[i] = SkToU8(sa + SkAlphaMul(device[i], scale));
      75                 :             }
      76                 :         }
      77               0 :         runs += count;
      78               0 :         antialias += count;
      79               0 :         device += count;
      80                 :     }
      81                 : }
      82                 : 
      83                 : /////////////////////////////////////////////////////////////////////////////////////
      84                 : 
      85                 : #define solid_8_pixels(mask, dst)           \
      86                 :     do {                                    \
      87                 :         if (mask & 0x80) dst[0] = 0xFF;     \
      88                 :         if (mask & 0x40) dst[1] = 0xFF;     \
      89                 :         if (mask & 0x20) dst[2] = 0xFF;     \
      90                 :         if (mask & 0x10) dst[3] = 0xFF;     \
      91                 :         if (mask & 0x08) dst[4] = 0xFF;     \
      92                 :         if (mask & 0x04) dst[5] = 0xFF;     \
      93                 :         if (mask & 0x02) dst[6] = 0xFF;     \
      94                 :         if (mask & 0x01) dst[7] = 0xFF;     \
      95                 :     } while (0)
      96                 : 
      97                 : #define SK_BLITBWMASK_NAME                  SkA8_BlitBW
      98                 : #define SK_BLITBWMASK_ARGS
      99                 : #define SK_BLITBWMASK_BLIT8(mask, dst)      solid_8_pixels(mask, dst)
     100                 : #define SK_BLITBWMASK_GETADDR               getAddr8
     101                 : #define SK_BLITBWMASK_DEVTYPE               uint8_t
     102                 : #include "SkBlitBWMaskTemplate.h"
     103                 : 
     104               0 : static inline void blend_8_pixels(U8CPU bw, uint8_t dst[], U8CPU sa,
     105                 :                                   unsigned dst_scale) {
     106               0 :     if (bw & 0x80) dst[0] = SkToU8(sa + SkAlphaMul(dst[0], dst_scale));
     107               0 :     if (bw & 0x40) dst[1] = SkToU8(sa + SkAlphaMul(dst[1], dst_scale));
     108               0 :     if (bw & 0x20) dst[2] = SkToU8(sa + SkAlphaMul(dst[2], dst_scale));
     109               0 :     if (bw & 0x10) dst[3] = SkToU8(sa + SkAlphaMul(dst[3], dst_scale));
     110               0 :     if (bw & 0x08) dst[4] = SkToU8(sa + SkAlphaMul(dst[4], dst_scale));
     111               0 :     if (bw & 0x04) dst[5] = SkToU8(sa + SkAlphaMul(dst[5], dst_scale));
     112               0 :     if (bw & 0x02) dst[6] = SkToU8(sa + SkAlphaMul(dst[6], dst_scale));
     113               0 :     if (bw & 0x01) dst[7] = SkToU8(sa + SkAlphaMul(dst[7], dst_scale));
     114               0 : }
     115                 : 
     116                 : #define SK_BLITBWMASK_NAME                  SkA8_BlendBW
     117                 : #define SK_BLITBWMASK_ARGS                  , U8CPU sa, unsigned dst_scale
     118                 : #define SK_BLITBWMASK_BLIT8(mask, dst)      blend_8_pixels(mask, dst, sa, dst_scale)
     119                 : #define SK_BLITBWMASK_GETADDR               getAddr8
     120                 : #define SK_BLITBWMASK_DEVTYPE               uint8_t
     121                 : #include "SkBlitBWMaskTemplate.h"
     122                 : 
     123               0 : void SkA8_Blitter::blitMask(const SkMask& mask, const SkIRect& clip) {
     124               0 :     if (fSrcA == 0) {
     125               0 :         return;
     126                 :     }
     127                 : 
     128               0 :     if (mask.fFormat == SkMask::kBW_Format) {
     129               0 :         if (fSrcA == 0xFF) {
     130               0 :             SkA8_BlitBW(fDevice, mask, clip);
     131                 :         } else {
     132                 :             SkA8_BlendBW(fDevice, mask, clip, fSrcA,
     133               0 :                          SkAlpha255To256(255 - fSrcA));
     134                 :         }
     135               0 :         return;
     136                 :     }
     137                 : 
     138               0 :     int x = clip.fLeft;
     139               0 :     int y = clip.fTop;
     140               0 :     int width = clip.width();
     141               0 :     int height = clip.height();
     142               0 :     uint8_t* device = fDevice.getAddr8(x, y);
     143               0 :     const uint8_t* alpha = mask.getAddr8(x, y);
     144               0 :     unsigned    srcA = fSrcA;
     145                 : 
     146               0 :     while (--height >= 0) {
     147               0 :         for (int i = width - 1; i >= 0; --i) {
     148                 :             unsigned sa;
     149                 :             // scale our src by the alpha value
     150                 :             {
     151               0 :                 int aa = alpha[i];
     152               0 :                 if (aa == 0) {
     153               0 :                     continue;
     154                 :                 }
     155               0 :                 if (aa == 255) {
     156               0 :                     if (srcA == 255) {
     157               0 :                         device[i] = 0xFF;
     158               0 :                         continue;
     159                 :                     }
     160               0 :                     sa = srcA;
     161                 :                 } else {
     162               0 :                     sa = SkAlphaMul(srcA, SkAlpha255To256(aa));
     163                 :                 }
     164                 :             }
     165                 : 
     166               0 :             int scale = 256 - SkAlpha255To256(sa);
     167               0 :             device[i] = SkToU8(sa + SkAlphaMul(device[i], scale));
     168                 :         }
     169               0 :         device += fDevice.rowBytes();
     170               0 :         alpha += mask.fRowBytes;
     171                 :     }
     172                 : }
     173                 : 
     174                 : ///////////////////////////////////////////////////////////////////////////////
     175                 : 
     176               0 : void SkA8_Blitter::blitV(int x, int y, int height, SkAlpha alpha) {
     177               0 :     if (fSrcA == 0) {
     178               0 :         return;
     179                 :     }
     180                 : 
     181               0 :     unsigned sa = SkAlphaMul(fSrcA, SkAlpha255To256(alpha));
     182               0 :     uint8_t* device = fDevice.getAddr8(x, y);
     183               0 :     int      rowBytes = fDevice.rowBytes();
     184                 : 
     185               0 :     if (sa == 0xFF) {
     186               0 :         for (int i = 0; i < height; i++) {
     187               0 :             *device = SkToU8(sa);
     188               0 :             device += rowBytes;
     189                 :         }
     190                 :     } else {
     191               0 :         unsigned scale = 256 - SkAlpha255To256(sa);
     192                 : 
     193               0 :         for (int i = 0; i < height; i++) {
     194               0 :             *device = SkToU8(sa + SkAlphaMul(*device, scale));
     195               0 :             device += rowBytes;
     196                 :         }
     197                 :     }
     198                 : }
     199                 : 
     200               0 : void SkA8_Blitter::blitRect(int x, int y, int width, int height) {
     201               0 :     SkASSERT(x >= 0 && y >= 0 &&
     202                 :              (unsigned)(x + width) <= (unsigned)fDevice.width() &&
     203                 :              (unsigned)(y + height) <= (unsigned)fDevice.height());
     204                 : 
     205               0 :     if (fSrcA == 0) {
     206               0 :         return;
     207                 :     }
     208                 : 
     209               0 :     uint8_t*    device = fDevice.getAddr8(x, y);
     210               0 :     unsigned    srcA = fSrcA;
     211                 : 
     212               0 :     if (srcA == 255) {
     213               0 :         while (--height >= 0) {
     214               0 :             memset(device, 0xFF, width);
     215               0 :             device += fDevice.rowBytes();
     216                 :         }
     217                 :     } else {
     218               0 :         unsigned scale = 256 - SkAlpha255To256(srcA);
     219                 : 
     220               0 :         while (--height >= 0) {
     221               0 :             for (int i = 0; i < width; i++) {
     222               0 :                 device[i] = SkToU8(srcA + SkAlphaMul(device[i], scale));
     223                 :             }
     224               0 :             device += fDevice.rowBytes();
     225                 :         }
     226                 :     }
     227                 : }
     228                 : 
     229                 : ///////////////////////////////////////////////////////////////////////
     230                 : 
     231               0 : SkA8_Shader_Blitter::SkA8_Shader_Blitter(const SkBitmap& device, const SkPaint& paint)
     232               0 :     : INHERITED(device, paint) {
     233               0 :     if ((fXfermode = paint.getXfermode()) != NULL) {
     234               0 :         fXfermode->ref();
     235               0 :         SkASSERT(fShader);
     236                 :     }
     237                 : 
     238               0 :     int width = device.width();
     239               0 :     fBuffer = (SkPMColor*)sk_malloc_throw(sizeof(SkPMColor) * (width + (SkAlign4(width) >> 2)));
     240               0 :     fAAExpand = (uint8_t*)(fBuffer + width);
     241               0 : }
     242                 : 
     243               0 : SkA8_Shader_Blitter::~SkA8_Shader_Blitter() {
     244               0 :     if (fXfermode) SkSafeUnref(fXfermode);
     245               0 :     sk_free(fBuffer);
     246               0 : }
     247                 : 
     248               0 : void SkA8_Shader_Blitter::blitH(int x, int y, int width) {
     249               0 :     SkASSERT(x >= 0 && y >= 0 &&
     250                 :              (unsigned)(x + width) <= (unsigned)fDevice.width());
     251                 : 
     252               0 :     uint8_t* device = fDevice.getAddr8(x, y);
     253                 : 
     254               0 :     if ((fShader->getFlags() & SkShader::kOpaqueAlpha_Flag) && !fXfermode) {
     255               0 :         memset(device, 0xFF, width);
     256                 :     } else {
     257               0 :         SkPMColor*  span = fBuffer;
     258                 : 
     259               0 :         fShader->shadeSpan(x, y, span, width);
     260               0 :         if (fXfermode) {
     261               0 :             fXfermode->xferA8(device, span, width, NULL);
     262                 :         } else {
     263               0 :             for (int i = width - 1; i >= 0; --i) {
     264               0 :                 unsigned    srcA = SkGetPackedA32(span[i]);
     265               0 :                 unsigned    scale = 256 - SkAlpha255To256(srcA);
     266                 : 
     267               0 :                 device[i] = SkToU8(srcA + SkAlphaMul(device[i], scale));
     268                 :             }
     269                 :         }
     270                 :     }
     271               0 : }
     272                 : 
     273               0 : static inline uint8_t aa_blend8(SkPMColor src, U8CPU da, int aa) {
     274               0 :     SkASSERT((unsigned)aa <= 255);
     275                 : 
     276               0 :     int src_scale = SkAlpha255To256(aa);
     277               0 :     int sa = SkGetPackedA32(src);
     278               0 :     int dst_scale = 256 - SkAlphaMul(sa, src_scale);
     279                 : 
     280               0 :     return SkToU8((sa * src_scale + da * dst_scale) >> 8);
     281                 : }
     282                 : 
     283               0 : void SkA8_Shader_Blitter::blitAntiH(int x, int y, const SkAlpha antialias[],
     284                 :                                     const int16_t runs[]) {
     285               0 :     SkShader*   shader = fShader;
     286               0 :     SkXfermode* mode = fXfermode;
     287               0 :     uint8_t*    aaExpand = fAAExpand;
     288               0 :     SkPMColor*  span = fBuffer;
     289               0 :     uint8_t*    device = fDevice.getAddr8(x, y);
     290               0 :     int         opaque = fShader->getFlags() & SkShader::kOpaqueAlpha_Flag;
     291                 : 
     292               0 :     for (;;) {
     293               0 :         int count = *runs;
     294               0 :         if (count == 0) {
     295                 :             break;
     296                 :         }
     297               0 :         int aa = *antialias;
     298               0 :         if (aa) {
     299               0 :             if (opaque && aa == 255 && mode == NULL) {
     300               0 :                 memset(device, 0xFF, count);
     301                 :             } else {
     302               0 :                 shader->shadeSpan(x, y, span, count);
     303               0 :                 if (mode) {
     304               0 :                     memset(aaExpand, aa, count);
     305               0 :                     mode->xferA8(device, span, count, aaExpand);
     306                 :                 } else {
     307               0 :                     for (int i = count - 1; i >= 0; --i) {
     308               0 :                         device[i] = aa_blend8(span[i], device[i], aa);
     309                 :                     }
     310                 :                 }
     311                 :             }
     312                 :         }
     313               0 :         device += count;
     314               0 :         runs += count;
     315               0 :         antialias += count;
     316               0 :         x += count;
     317                 :     }
     318               0 : }
     319                 : 
     320               0 : void SkA8_Shader_Blitter::blitMask(const SkMask& mask, const SkIRect& clip) {
     321               0 :     if (mask.fFormat == SkMask::kBW_Format) {
     322               0 :         this->INHERITED::blitMask(mask, clip);
     323               0 :         return;
     324                 :     }
     325                 : 
     326               0 :     int x = clip.fLeft;
     327               0 :     int y = clip.fTop;
     328               0 :     int width = clip.width();
     329               0 :     int height = clip.height();
     330               0 :     uint8_t* device = fDevice.getAddr8(x, y);
     331               0 :     const uint8_t* alpha = mask.getAddr8(x, y);
     332                 : 
     333               0 :     SkPMColor*  span = fBuffer;
     334                 : 
     335               0 :     while (--height >= 0) {
     336               0 :         fShader->shadeSpan(x, y, span, width);
     337               0 :         if (fXfermode) {
     338               0 :             fXfermode->xferA8(device, span, width, alpha);
     339                 :         }
     340                 : 
     341               0 :         y += 1;
     342               0 :         device += fDevice.rowBytes();
     343               0 :         alpha += mask.fRowBytes;
     344                 :     }
     345                 : }
     346                 : 

Generated by: LCOV version 1.7