LCOV - code coverage report
Current view: directory - gfx/skia/src/core - SkBlitter.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 545 0 0.0 %
Date: 2012-06-02 Functions: 68 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 "SkBlitter.h"
      11                 : #include "SkAntiRun.h"
      12                 : #include "SkColor.h"
      13                 : #include "SkColorFilter.h"
      14                 : #include "SkMask.h"
      15                 : #include "SkMaskFilter.h"
      16                 : #include "SkTemplatesPriv.h"
      17                 : #include "SkUtils.h"
      18                 : #include "SkXfermode.h"
      19                 : 
      20               0 : SkBlitter::~SkBlitter() {}
      21                 : 
      22               0 : const SkBitmap* SkBlitter::justAnOpaqueColor(uint32_t* value) {
      23               0 :     return NULL;
      24                 : }
      25                 : 
      26               0 : void SkBlitter::blitH(int x, int y, int width) {
      27               0 :     SkDEBUGFAIL("unimplemented");
      28               0 : }
      29                 : 
      30               0 : void SkBlitter::blitAntiH(int x, int y, const SkAlpha antialias[],
      31                 :                           const int16_t runs[]) {
      32               0 :     SkDEBUGFAIL("unimplemented");
      33               0 : }
      34                 : 
      35               0 : void SkBlitter::blitV(int x, int y, int height, SkAlpha alpha) {
      36               0 :     if (alpha == 255) {
      37               0 :         this->blitRect(x, y, 1, height);
      38                 :     } else {
      39                 :         int16_t runs[2];
      40               0 :         runs[0] = 1;
      41               0 :         runs[1] = 0;
      42                 : 
      43               0 :         while (--height >= 0) {
      44               0 :             this->blitAntiH(x, y++, &alpha, runs);
      45                 :         }
      46                 :     }
      47               0 : }
      48                 : 
      49               0 : void SkBlitter::blitRect(int x, int y, int width, int height) {
      50               0 :     SkASSERT(width > 0);
      51               0 :     while (--height >= 0) {
      52               0 :         this->blitH(x, y++, width);
      53                 :     }
      54               0 : }
      55                 : 
      56                 : /// Default implementation doesn't check for any easy optimizations
      57                 : /// such as alpha == 0 or 255; also uses blitV(), which some subclasses
      58                 : /// may not support.
      59               0 : void SkBlitter::blitAntiRect(int x, int y, int width, int height,
      60                 :                              SkAlpha leftAlpha, SkAlpha rightAlpha) {
      61               0 :     this->blitV(x++, y, height, leftAlpha);
      62               0 :     if (width > 0) {
      63               0 :         this->blitRect(x, y, width, height);
      64               0 :         x += width;
      65                 :     }
      66               0 :     this->blitV(x, y, height, rightAlpha);
      67               0 : }
      68                 : 
      69                 : //////////////////////////////////////////////////////////////////////////////
      70                 : 
      71               0 : static inline void bits_to_runs(SkBlitter* blitter, int x, int y,
      72                 :                                 const uint8_t bits[],
      73                 :                                 U8CPU left_mask, int rowBytes,
      74                 :                                 U8CPU right_mask) {
      75               0 :     int inFill = 0;
      76               0 :     int pos = 0;
      77                 : 
      78               0 :     while (--rowBytes >= 0) {
      79               0 :         unsigned b = *bits++ & left_mask;
      80               0 :         if (rowBytes == 0) {
      81               0 :             b &= right_mask;
      82                 :         }
      83                 : 
      84               0 :         for (unsigned test = 0x80; test != 0; test >>= 1) {
      85               0 :             if (b & test) {
      86               0 :                 if (!inFill) {
      87               0 :                     pos = x;
      88               0 :                     inFill = true;
      89                 :                 }
      90                 :             } else {
      91               0 :                 if (inFill) {
      92               0 :                     blitter->blitH(pos, y, x - pos);
      93               0 :                     inFill = false;
      94                 :                 }
      95                 :             }
      96               0 :             x += 1;
      97                 :         }
      98               0 :         left_mask = 0xFF;
      99                 :     }
     100                 : 
     101                 :     // final cleanup
     102               0 :     if (inFill) {
     103               0 :         blitter->blitH(pos, y, x - pos);
     104                 :     }
     105               0 : }
     106                 : 
     107               0 : void SkBlitter::blitMask(const SkMask& mask, const SkIRect& clip) {
     108               0 :     SkASSERT(mask.fBounds.contains(clip));
     109                 : 
     110               0 :     if (mask.fFormat == SkMask::kBW_Format) {
     111               0 :         int cx = clip.fLeft;
     112               0 :         int cy = clip.fTop;
     113               0 :         int maskLeft = mask.fBounds.fLeft;
     114               0 :         int mask_rowBytes = mask.fRowBytes;
     115               0 :         int height = clip.height();
     116                 : 
     117               0 :         const uint8_t* bits = mask.getAddr1(cx, cy);
     118                 : 
     119               0 :         if (cx == maskLeft && clip.fRight == mask.fBounds.fRight) {
     120               0 :             while (--height >= 0) {
     121               0 :                 bits_to_runs(this, cx, cy, bits, 0xFF, mask_rowBytes, 0xFF);
     122               0 :                 bits += mask_rowBytes;
     123               0 :                 cy += 1;
     124                 :             }
     125                 :         } else {
     126               0 :             int left_edge = cx - maskLeft;
     127               0 :             SkASSERT(left_edge >= 0);
     128               0 :             int rite_edge = clip.fRight - maskLeft;
     129               0 :             SkASSERT(rite_edge > left_edge);
     130                 : 
     131               0 :             int left_mask = 0xFF >> (left_edge & 7);
     132               0 :             int rite_mask = 0xFF << (8 - (rite_edge & 7));
     133               0 :             int full_runs = (rite_edge >> 3) - ((left_edge + 7) >> 3);
     134                 : 
     135                 :             // check for empty right mask, so we don't read off the end (or go slower than we need to)
     136               0 :             if (rite_mask == 0) {
     137               0 :                 SkASSERT(full_runs >= 0);
     138               0 :                 full_runs -= 1;
     139               0 :                 rite_mask = 0xFF;
     140                 :             }
     141               0 :             if (left_mask == 0xFF) {
     142               0 :                 full_runs -= 1;
     143                 :             }
     144                 : 
     145                 :             // back up manually so we can keep in sync with our byte-aligned src
     146                 :             // have cx reflect our actual starting x-coord
     147               0 :             cx -= left_edge & 7;
     148                 : 
     149               0 :             if (full_runs < 0) {
     150               0 :                 SkASSERT((left_mask & rite_mask) != 0);
     151               0 :                 while (--height >= 0) {
     152               0 :                     bits_to_runs(this, cx, cy, bits, left_mask, 1, rite_mask);
     153               0 :                     bits += mask_rowBytes;
     154               0 :                     cy += 1;
     155                 :                 }
     156                 :             } else {
     157               0 :                 while (--height >= 0) {
     158               0 :                     bits_to_runs(this, cx, cy, bits, left_mask, full_runs + 2, rite_mask);
     159               0 :                     bits += mask_rowBytes;
     160               0 :                     cy += 1;
     161                 :                 }
     162                 :             }
     163                 :         }
     164                 :     } else {
     165               0 :         int                         width = clip.width();
     166               0 :         SkAutoSTMalloc<64, int16_t> runStorage(width + 1);
     167               0 :         int16_t*                    runs = runStorage.get();
     168               0 :         const uint8_t*              aa = mask.getAddr8(clip.fLeft, clip.fTop);
     169                 : 
     170               0 :         sk_memset16((uint16_t*)runs, 1, width);
     171               0 :         runs[width] = 0;
     172                 : 
     173               0 :         int height = clip.height();
     174               0 :         int y = clip.fTop;
     175               0 :         while (--height >= 0) {
     176               0 :             this->blitAntiH(clip.fLeft, y, aa, runs);
     177               0 :             aa += mask.fRowBytes;
     178               0 :             y += 1;
     179                 :         }
     180                 :     }
     181               0 : }
     182                 : 
     183                 : /////////////////////// these guys are not virtual, just a helpers
     184                 : 
     185               0 : void SkBlitter::blitMaskRegion(const SkMask& mask, const SkRegion& clip) {
     186               0 :     if (clip.quickReject(mask.fBounds)) {
     187               0 :         return;
     188                 :     }
     189                 : 
     190               0 :     SkRegion::Cliperator clipper(clip, mask.fBounds);
     191                 : 
     192               0 :     while (!clipper.done()) {
     193               0 :         const SkIRect& cr = clipper.rect();
     194               0 :         this->blitMask(mask, cr);
     195               0 :         clipper.next();
     196                 :     }
     197                 : }
     198                 : 
     199               0 : void SkBlitter::blitRectRegion(const SkIRect& rect, const SkRegion& clip) {
     200               0 :     SkRegion::Cliperator clipper(clip, rect);
     201                 : 
     202               0 :     while (!clipper.done()) {
     203               0 :         const SkIRect& cr = clipper.rect();
     204               0 :         this->blitRect(cr.fLeft, cr.fTop, cr.width(), cr.height());
     205               0 :         clipper.next();
     206                 :     }
     207               0 : }
     208                 : 
     209               0 : void SkBlitter::blitRegion(const SkRegion& clip) {
     210               0 :     SkRegion::Iterator iter(clip);
     211                 : 
     212               0 :     while (!iter.done()) {
     213               0 :         const SkIRect& cr = iter.rect();
     214               0 :         this->blitRect(cr.fLeft, cr.fTop, cr.width(), cr.height());
     215               0 :         iter.next();
     216                 :     }
     217               0 : }
     218                 : 
     219                 : ///////////////////////////////////////////////////////////////////////////////
     220                 : 
     221               0 : void SkNullBlitter::blitH(int x, int y, int width) {}
     222                 : 
     223               0 : void SkNullBlitter::blitAntiH(int x, int y, const SkAlpha antialias[],
     224               0 :                               const int16_t runs[]) {}
     225                 : 
     226               0 : void SkNullBlitter::blitV(int x, int y, int height, SkAlpha alpha) {}
     227                 : 
     228               0 : void SkNullBlitter::blitRect(int x, int y, int width, int height) {}
     229                 : 
     230               0 : void SkNullBlitter::blitMask(const SkMask& mask, const SkIRect& clip) {}
     231                 : 
     232               0 : const SkBitmap* SkNullBlitter::justAnOpaqueColor(uint32_t* value) {
     233               0 :     return NULL;
     234                 : }
     235                 : 
     236                 : ///////////////////////////////////////////////////////////////////////////////
     237                 : 
     238               0 : static int compute_anti_width(const int16_t runs[]) {
     239               0 :     int width = 0;
     240                 : 
     241               0 :     for (;;) {
     242               0 :         int count = runs[0];
     243                 : 
     244               0 :         SkASSERT(count >= 0);
     245               0 :         if (count == 0) {
     246                 :             break;
     247                 :         }
     248               0 :         width += count;
     249               0 :         runs += count;
     250                 : 
     251               0 :         SkASSERT(width < 20000);
     252                 :     }
     253               0 :     return width;
     254                 : }
     255                 : 
     256               0 : static inline bool y_in_rect(int y, const SkIRect& rect) {
     257               0 :     return (unsigned)(y - rect.fTop) < (unsigned)rect.height();
     258                 : }
     259                 : 
     260               0 : static inline bool x_in_rect(int x, const SkIRect& rect) {
     261               0 :     return (unsigned)(x - rect.fLeft) < (unsigned)rect.width();
     262                 : }
     263                 : 
     264               0 : void SkRectClipBlitter::blitH(int left, int y, int width) {
     265               0 :     SkASSERT(width > 0);
     266                 : 
     267               0 :     if (!y_in_rect(y, fClipRect)) {
     268               0 :         return;
     269                 :     }
     270                 : 
     271               0 :     int right = left + width;
     272                 : 
     273               0 :     if (left < fClipRect.fLeft) {
     274               0 :         left = fClipRect.fLeft;
     275                 :     }
     276               0 :     if (right > fClipRect.fRight) {
     277               0 :         right = fClipRect.fRight;
     278                 :     }
     279                 : 
     280               0 :     width = right - left;
     281               0 :     if (width > 0) {
     282               0 :         fBlitter->blitH(left, y, width);
     283                 :     }
     284                 : }
     285                 : 
     286               0 : void SkRectClipBlitter::blitAntiH(int left, int y, const SkAlpha aa[],
     287                 :                                   const int16_t runs[]) {
     288               0 :     if (!y_in_rect(y, fClipRect) || left >= fClipRect.fRight) {
     289               0 :         return;
     290                 :     }
     291                 : 
     292               0 :     int x0 = left;
     293               0 :     int x1 = left + compute_anti_width(runs);
     294                 : 
     295               0 :     if (x1 <= fClipRect.fLeft) {
     296               0 :         return;
     297                 :     }
     298                 : 
     299               0 :     SkASSERT(x0 < x1);
     300               0 :     if (x0 < fClipRect.fLeft) {
     301               0 :         int dx = fClipRect.fLeft - x0;
     302               0 :         SkAlphaRuns::BreakAt((int16_t*)runs, (uint8_t*)aa, dx);
     303               0 :         runs += dx;
     304               0 :         aa += dx;
     305               0 :         x0 = fClipRect.fLeft;
     306                 :     }
     307                 : 
     308               0 :     SkASSERT(x0 < x1 && runs[x1 - x0] == 0);
     309               0 :     if (x1 > fClipRect.fRight) {
     310               0 :         x1 = fClipRect.fRight;
     311               0 :         SkAlphaRuns::BreakAt((int16_t*)runs, (uint8_t*)aa, x1 - x0);
     312               0 :         ((int16_t*)runs)[x1 - x0] = 0;
     313                 :     }
     314                 : 
     315               0 :     SkASSERT(x0 < x1 && runs[x1 - x0] == 0);
     316               0 :     SkASSERT(compute_anti_width(runs) == x1 - x0);
     317                 : 
     318               0 :     fBlitter->blitAntiH(x0, y, aa, runs);
     319                 : }
     320                 : 
     321               0 : void SkRectClipBlitter::blitV(int x, int y, int height, SkAlpha alpha) {
     322               0 :     SkASSERT(height > 0);
     323                 : 
     324               0 :     if (!x_in_rect(x, fClipRect)) {
     325               0 :         return;
     326                 :     }
     327                 : 
     328               0 :     int y0 = y;
     329               0 :     int y1 = y + height;
     330                 : 
     331               0 :     if (y0 < fClipRect.fTop) {
     332               0 :         y0 = fClipRect.fTop;
     333                 :     }
     334               0 :     if (y1 > fClipRect.fBottom) {
     335               0 :         y1 = fClipRect.fBottom;
     336                 :     }
     337                 : 
     338               0 :     if (y0 < y1) {
     339               0 :         fBlitter->blitV(x, y0, y1 - y0, alpha);
     340                 :     }
     341                 : }
     342                 : 
     343               0 : void SkRectClipBlitter::blitRect(int left, int y, int width, int height) {
     344                 :     SkIRect    r;
     345                 : 
     346               0 :     r.set(left, y, left + width, y + height);
     347               0 :     if (r.intersect(fClipRect)) {
     348               0 :         fBlitter->blitRect(r.fLeft, r.fTop, r.width(), r.height());
     349                 :     }
     350               0 : }
     351                 : 
     352               0 : void SkRectClipBlitter::blitAntiRect(int left, int y, int width, int height,
     353                 :                                      SkAlpha leftAlpha, SkAlpha rightAlpha) {
     354                 :     SkIRect    r;
     355                 : 
     356                 :     // The *true* width of the rectangle blitted is width+2:
     357               0 :     r.set(left, y, left + width + 2, y + height);
     358               0 :     if (r.intersect(fClipRect)) {
     359               0 :         if (r.fLeft != left) {
     360               0 :             SkASSERT(r.fLeft > left);
     361               0 :             leftAlpha = 255;
     362                 :         }
     363               0 :         if (r.fRight != left + width + 2) {
     364               0 :             SkASSERT(r.fRight < left + width + 2);
     365               0 :             rightAlpha = 255;
     366                 :         }
     367               0 :         if (255 == leftAlpha && 255 == rightAlpha) {
     368               0 :             fBlitter->blitRect(r.fLeft, r.fTop, r.width(), r.height());
     369               0 :         } else if (1 == r.width()) {
     370               0 :             if (r.fLeft == left) {
     371               0 :                 fBlitter->blitV(r.fLeft, r.fTop, r.height(), leftAlpha);
     372                 :             } else {
     373               0 :                 SkASSERT(r.fLeft == left + width + 1);
     374               0 :                 fBlitter->blitV(r.fLeft, r.fTop, r.height(), rightAlpha);
     375                 :             }
     376                 :         } else {
     377               0 :             fBlitter->blitAntiRect(r.fLeft, r.fTop, r.width() - 2, r.height(),
     378               0 :                                    leftAlpha, rightAlpha);
     379                 :         }
     380                 :     }
     381               0 : }
     382                 : 
     383               0 : void SkRectClipBlitter::blitMask(const SkMask& mask, const SkIRect& clip) {
     384               0 :     SkASSERT(mask.fBounds.contains(clip));
     385                 : 
     386               0 :     SkIRect    r = clip;
     387                 : 
     388               0 :     if (r.intersect(fClipRect)) {
     389               0 :         fBlitter->blitMask(mask, r);
     390                 :     }
     391               0 : }
     392                 : 
     393               0 : const SkBitmap* SkRectClipBlitter::justAnOpaqueColor(uint32_t* value) {
     394               0 :     return fBlitter->justAnOpaqueColor(value);
     395                 : }
     396                 : 
     397                 : ///////////////////////////////////////////////////////////////////////////////
     398                 : 
     399               0 : void SkRgnClipBlitter::blitH(int x, int y, int width) {
     400               0 :     SkRegion::Spanerator span(*fRgn, y, x, x + width);
     401                 :     int left, right;
     402                 : 
     403               0 :     while (span.next(&left, &right)) {
     404               0 :         SkASSERT(left < right);
     405               0 :         fBlitter->blitH(left, y, right - left);
     406                 :     }
     407               0 : }
     408                 : 
     409               0 : void SkRgnClipBlitter::blitAntiH(int x, int y, const SkAlpha aa[],
     410                 :                                  const int16_t runs[]) {
     411               0 :     int width = compute_anti_width(runs);
     412               0 :     SkRegion::Spanerator span(*fRgn, y, x, x + width);
     413                 :     int left, right;
     414               0 :     SkDEBUGCODE(const SkIRect& bounds = fRgn->getBounds();)
     415                 : 
     416               0 :     int prevRite = x;
     417               0 :     while (span.next(&left, &right)) {
     418               0 :         SkASSERT(x <= left);
     419               0 :         SkASSERT(left < right);
     420               0 :         SkASSERT(left >= bounds.fLeft && right <= bounds.fRight);
     421                 : 
     422               0 :         SkAlphaRuns::Break((int16_t*)runs, (uint8_t*)aa, left - x, right - left);
     423                 : 
     424                 :         // now zero before left
     425               0 :         if (left > prevRite) {
     426               0 :             int index = prevRite - x;
     427               0 :             ((uint8_t*)aa)[index] = 0;   // skip runs after right
     428               0 :             ((int16_t*)runs)[index] = SkToS16(left - prevRite);
     429                 :         }
     430                 : 
     431               0 :         prevRite = right;
     432                 :     }
     433                 : 
     434               0 :     if (prevRite > x) {
     435               0 :         ((int16_t*)runs)[prevRite - x] = 0;
     436                 : 
     437               0 :         if (x < 0) {
     438               0 :             int skip = runs[0];
     439               0 :             SkASSERT(skip >= -x);
     440               0 :             aa += skip;
     441               0 :             runs += skip;
     442               0 :             x += skip;
     443                 :         }
     444               0 :         fBlitter->blitAntiH(x, y, aa, runs);
     445                 :     }
     446               0 : }
     447                 : 
     448               0 : void SkRgnClipBlitter::blitV(int x, int y, int height, SkAlpha alpha) {
     449                 :     SkIRect    bounds;
     450               0 :     bounds.set(x, y, x + 1, y + height);
     451                 : 
     452               0 :     SkRegion::Cliperator    iter(*fRgn, bounds);
     453                 : 
     454               0 :     while (!iter.done()) {
     455               0 :         const SkIRect& r = iter.rect();
     456               0 :         SkASSERT(bounds.contains(r));
     457                 : 
     458               0 :         fBlitter->blitV(x, r.fTop, r.height(), alpha);
     459               0 :         iter.next();
     460                 :     }
     461               0 : }
     462                 : 
     463               0 : void SkRgnClipBlitter::blitRect(int x, int y, int width, int height) {
     464                 :     SkIRect    bounds;
     465               0 :     bounds.set(x, y, x + width, y + height);
     466                 : 
     467               0 :     SkRegion::Cliperator    iter(*fRgn, bounds);
     468                 : 
     469               0 :     while (!iter.done()) {
     470               0 :         const SkIRect& r = iter.rect();
     471               0 :         SkASSERT(bounds.contains(r));
     472                 : 
     473               0 :         fBlitter->blitRect(r.fLeft, r.fTop, r.width(), r.height());
     474               0 :         iter.next();
     475                 :     }
     476               0 : }
     477                 : 
     478               0 : void SkRgnClipBlitter::blitAntiRect(int x, int y, int width, int height,
     479                 :                                     SkAlpha leftAlpha, SkAlpha rightAlpha) {
     480                 :     // The *true* width of the rectangle to blit is width + 2
     481                 :     SkIRect    bounds;
     482               0 :     bounds.set(x, y, x + width + 2, y + height);
     483                 : 
     484               0 :     SkRegion::Cliperator    iter(*fRgn, bounds);
     485                 : 
     486               0 :     while (!iter.done()) {
     487               0 :         const SkIRect& r = iter.rect();
     488               0 :         SkASSERT(bounds.contains(r));
     489               0 :         SkASSERT(r.fLeft >= x);
     490               0 :         SkASSERT(r.fRight <= x + width + 2);
     491                 : 
     492               0 :         SkAlpha effectiveLeftAlpha = (r.fLeft == x) ? leftAlpha : 255;
     493                 :         SkAlpha effectiveRightAlpha = (r.fRight == x + width + 2) ?
     494               0 :                                       rightAlpha : 255;
     495                 : 
     496               0 :         if (255 == effectiveLeftAlpha && 255 == effectiveRightAlpha) {
     497               0 :             fBlitter->blitRect(r.fLeft, r.fTop, r.width(), r.height());
     498               0 :         } else if (1 == r.width()) {
     499               0 :             if (r.fLeft == x) {
     500                 :                 fBlitter->blitV(r.fLeft, r.fTop, r.height(), 
     501               0 :                                 effectiveLeftAlpha);
     502                 :             } else {
     503               0 :                 SkASSERT(r.fLeft == x + width + 1);
     504                 :                 fBlitter->blitV(r.fLeft, r.fTop, r.height(),
     505               0 :                                 effectiveRightAlpha);
     506                 :             }
     507                 :         } else {
     508               0 :             fBlitter->blitAntiRect(r.fLeft, r.fTop, r.width() - 2, r.height(),
     509               0 :                                    effectiveLeftAlpha, effectiveRightAlpha);
     510                 :         }
     511               0 :         iter.next();
     512                 :     }
     513               0 : }
     514                 : 
     515                 : 
     516               0 : void SkRgnClipBlitter::blitMask(const SkMask& mask, const SkIRect& clip) {
     517               0 :     SkASSERT(mask.fBounds.contains(clip));
     518                 : 
     519               0 :     SkRegion::Cliperator iter(*fRgn, clip);
     520               0 :     const SkIRect&       r = iter.rect();
     521               0 :     SkBlitter*           blitter = fBlitter;
     522                 : 
     523               0 :     while (!iter.done()) {
     524               0 :         blitter->blitMask(mask, r);
     525               0 :         iter.next();
     526                 :     }
     527               0 : }
     528                 : 
     529               0 : const SkBitmap* SkRgnClipBlitter::justAnOpaqueColor(uint32_t* value) {
     530               0 :     return fBlitter->justAnOpaqueColor(value);
     531                 : }
     532                 : 
     533                 : ///////////////////////////////////////////////////////////////////////////////
     534                 : 
     535               0 : SkBlitter* SkBlitterClipper::apply(SkBlitter* blitter, const SkRegion* clip,
     536                 :                                    const SkIRect* ir) {
     537               0 :     if (clip) {
     538               0 :         const SkIRect& clipR = clip->getBounds();
     539                 : 
     540               0 :         if (clip->isEmpty() || (ir && !SkIRect::Intersects(clipR, *ir))) {
     541               0 :             blitter = &fNullBlitter;
     542               0 :         } else if (clip->isRect()) {
     543               0 :             if (ir == NULL || !clipR.contains(*ir)) {
     544               0 :                 fRectBlitter.init(blitter, clipR);
     545               0 :                 blitter = &fRectBlitter;
     546                 :             }
     547                 :         } else {
     548               0 :             fRgnBlitter.init(blitter, clip);
     549               0 :             blitter = &fRgnBlitter;
     550                 :         }
     551                 :     }
     552               0 :     return blitter;
     553                 : }
     554                 : 
     555                 : ///////////////////////////////////////////////////////////////////////////////
     556                 : 
     557                 : #include "SkColorShader.h"
     558                 : #include "SkColorPriv.h"
     559                 : 
     560                 : class Sk3DShader : public SkShader {
     561                 : public:
     562               0 :     Sk3DShader(SkShader* proxy) : fProxy(proxy) {
     563               0 :         SkSafeRef(proxy);
     564               0 :         fMask = NULL;
     565               0 :     }
     566                 : 
     567               0 :     virtual ~Sk3DShader() {
     568               0 :         SkSafeUnref(fProxy);
     569               0 :     }
     570                 : 
     571               0 :     void setMask(const SkMask* mask) { fMask = mask; }
     572                 : 
     573               0 :     virtual bool setContext(const SkBitmap& device, const SkPaint& paint,
     574                 :                             const SkMatrix& matrix) {
     575               0 :         if (fProxy) {
     576               0 :             return fProxy->setContext(device, paint, matrix);
     577                 :         } else {
     578               0 :             fPMColor = SkPreMultiplyColor(paint.getColor());
     579               0 :             return this->INHERITED::setContext(device, paint, matrix);
     580                 :         }
     581                 :     }
     582                 : 
     583               0 :     virtual void shadeSpan(int x, int y, SkPMColor span[], int count) {
     584               0 :         if (fProxy) {
     585               0 :             fProxy->shadeSpan(x, y, span, count);
     586                 :         }
     587                 : 
     588               0 :         if (fMask == NULL) {
     589               0 :             if (fProxy == NULL) {
     590               0 :                 sk_memset32(span, fPMColor, count);
     591                 :             }
     592               0 :             return;
     593                 :         }
     594                 : 
     595               0 :         SkASSERT(fMask->fBounds.contains(x, y));
     596               0 :         SkASSERT(fMask->fBounds.contains(x + count - 1, y));
     597                 : 
     598               0 :         size_t          size = fMask->computeImageSize();
     599               0 :         const uint8_t*  alpha = fMask->getAddr8(x, y);
     600               0 :         const uint8_t*  mulp = alpha + size;
     601               0 :         const uint8_t*  addp = mulp + size;
     602                 : 
     603               0 :         if (fProxy) {
     604               0 :             for (int i = 0; i < count; i++) {
     605               0 :                 if (alpha[i]) {
     606               0 :                     SkPMColor c = span[i];
     607               0 :                     if (c) {
     608               0 :                         unsigned a = SkGetPackedA32(c);
     609               0 :                         unsigned r = SkGetPackedR32(c);
     610               0 :                         unsigned g = SkGetPackedG32(c);
     611               0 :                         unsigned b = SkGetPackedB32(c);
     612                 : 
     613               0 :                         unsigned mul = SkAlpha255To256(mulp[i]);
     614               0 :                         unsigned add = addp[i];
     615                 : 
     616               0 :                         r = SkFastMin32(SkAlphaMul(r, mul) + add, a);
     617               0 :                         g = SkFastMin32(SkAlphaMul(g, mul) + add, a);
     618               0 :                         b = SkFastMin32(SkAlphaMul(b, mul) + add, a);
     619                 : 
     620               0 :                         span[i] = SkPackARGB32(a, r, g, b);
     621                 :                     }
     622                 :                 } else {
     623               0 :                     span[i] = 0;
     624                 :                 }
     625                 :             }
     626                 :         } else {    // color
     627               0 :             unsigned a = SkGetPackedA32(fPMColor);
     628               0 :             unsigned r = SkGetPackedR32(fPMColor);
     629               0 :             unsigned g = SkGetPackedG32(fPMColor);
     630               0 :             unsigned b = SkGetPackedB32(fPMColor);
     631               0 :             for (int i = 0; i < count; i++) {
     632               0 :                 if (alpha[i]) {
     633               0 :                     unsigned mul = SkAlpha255To256(mulp[i]);
     634               0 :                     unsigned add = addp[i];
     635                 : 
     636               0 :                     span[i] = SkPackARGB32( a,
     637               0 :                                     SkFastMin32(SkAlphaMul(r, mul) + add, a),
     638               0 :                                     SkFastMin32(SkAlphaMul(g, mul) + add, a),
     639               0 :                                     SkFastMin32(SkAlphaMul(b, mul) + add, a));
     640                 :                 } else {
     641               0 :                     span[i] = 0;
     642                 :                 }
     643                 :             }
     644                 :         }
     645                 :     }
     646                 : 
     647               0 :     virtual void beginSession() {
     648               0 :         this->INHERITED::beginSession();
     649               0 :         if (fProxy) {
     650               0 :             fProxy->beginSession();
     651                 :         }
     652               0 :     }
     653                 : 
     654               0 :     virtual void endSession() {
     655               0 :         if (fProxy) {
     656               0 :             fProxy->endSession();
     657                 :         }
     658               0 :         this->INHERITED::endSession();
     659               0 :     }
     660                 : 
     661                 : protected:
     662               0 :     Sk3DShader(SkFlattenableReadBuffer& buffer) :
     663               0 :             INHERITED(buffer) {
     664               0 :         fProxy = static_cast<SkShader*>(buffer.readFlattenable());
     665               0 :         fPMColor = buffer.readU32();
     666               0 :         fMask = NULL;
     667               0 :     }
     668                 : 
     669               0 :     virtual void flatten(SkFlattenableWriteBuffer& buffer) {
     670               0 :         this->INHERITED::flatten(buffer);
     671               0 :         buffer.writeFlattenable(fProxy);
     672               0 :         buffer.write32(fPMColor);
     673               0 :     }
     674                 : 
     675               0 :     virtual Factory getFactory() {
     676               0 :         return CreateProc;
     677                 :     }
     678                 : 
     679                 : private:
     680               0 :     static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
     681               0 :         return SkNEW_ARGS(Sk3DShader, (buffer));
     682                 :     }
     683                 : 
     684                 :     SkShader*       fProxy;
     685                 :     SkPMColor       fPMColor;
     686                 :     const SkMask*   fMask;
     687                 : 
     688                 :     typedef SkShader INHERITED;
     689                 : };
     690                 : 
     691                 : class Sk3DBlitter : public SkBlitter {
     692                 : public:
     693               0 :     Sk3DBlitter(SkBlitter* proxy, Sk3DShader* shader, void (*killProc)(void*))
     694               0 :             : fProxy(proxy), f3DShader(shader), fKillProc(killProc) {
     695               0 :         shader->ref();
     696               0 :     }
     697                 : 
     698               0 :     virtual ~Sk3DBlitter() {
     699               0 :         f3DShader->unref();
     700               0 :         fKillProc(fProxy);
     701               0 :     }
     702                 : 
     703               0 :     virtual void blitH(int x, int y, int width) {
     704               0 :         fProxy->blitH(x, y, width);
     705               0 :     }
     706                 : 
     707               0 :     virtual void blitAntiH(int x, int y, const SkAlpha antialias[],
     708                 :                            const int16_t runs[]) {
     709               0 :         fProxy->blitAntiH(x, y, antialias, runs);
     710               0 :     }
     711                 : 
     712               0 :     virtual void blitV(int x, int y, int height, SkAlpha alpha) {
     713               0 :         fProxy->blitV(x, y, height, alpha);
     714               0 :     }
     715                 : 
     716               0 :     virtual void blitRect(int x, int y, int width, int height) {
     717               0 :         fProxy->blitRect(x, y, width, height);
     718               0 :     }
     719                 : 
     720               0 :     virtual void blitMask(const SkMask& mask, const SkIRect& clip) {
     721               0 :         if (mask.fFormat == SkMask::k3D_Format) {
     722               0 :             f3DShader->setMask(&mask);
     723                 : 
     724               0 :             ((SkMask*)&mask)->fFormat = SkMask::kA8_Format;
     725               0 :             fProxy->blitMask(mask, clip);
     726               0 :             ((SkMask*)&mask)->fFormat = SkMask::k3D_Format;
     727                 : 
     728               0 :             f3DShader->setMask(NULL);
     729                 :         } else {
     730               0 :             fProxy->blitMask(mask, clip);
     731                 :         }
     732               0 :     }
     733                 : 
     734                 : private:
     735                 :     SkBlitter*  fProxy;
     736                 :     Sk3DShader* f3DShader;
     737                 :     void        (*fKillProc)(void*);
     738                 : };
     739                 : 
     740                 : ///////////////////////////////////////////////////////////////////////////////
     741                 : 
     742                 : #include "SkCoreBlitters.h"
     743                 : 
     744                 : class SkAutoCallProc {
     745                 : public:
     746                 :     typedef void (*Proc)(void*);
     747                 : 
     748               0 :     SkAutoCallProc(void* obj, Proc proc)
     749               0 :     : fObj(obj), fProc(proc) {}
     750                 : 
     751               0 :     ~SkAutoCallProc() {
     752               0 :         if (fObj && fProc) {
     753               0 :             fProc(fObj);
     754                 :         }
     755               0 :     }
     756                 : 
     757                 :     void* get() const { return fObj; }
     758                 : 
     759               0 :     void* detach() {
     760               0 :         void* obj = fObj;
     761               0 :         fObj = NULL;
     762               0 :         return obj;
     763                 :     }
     764                 : 
     765                 : private:
     766                 :     void*   fObj;
     767                 :     Proc    fProc;
     768                 : };
     769                 : 
     770               0 : static void destroy_blitter(void* blitter) {
     771               0 :     ((SkBlitter*)blitter)->~SkBlitter();
     772               0 : }
     773                 : 
     774               0 : static void delete_blitter(void* blitter) {
     775               0 :     SkDELETE((SkBlitter*)blitter);
     776               0 : }
     777                 : 
     778               0 : static bool just_solid_color(const SkPaint& paint) {
     779               0 :     if (paint.getAlpha() == 0xFF && paint.getColorFilter() == NULL) {
     780               0 :         SkShader* shader = paint.getShader();
     781               0 :         if (NULL == shader ||
     782               0 :             (shader->getFlags() & SkShader::kOpaqueAlpha_Flag)) {
     783               0 :             return true;
     784                 :         }
     785                 :     }
     786               0 :     return false;
     787                 : }
     788                 : 
     789                 : /** By analyzing the paint (with an xfermode), we may decide we can take
     790                 :     special action. This enum lists our possible actions
     791                 :  */
     792                 : enum XferInterp {
     793                 :     kNormal_XferInterp,         // no special interpretation, draw normally
     794                 :     kSrcOver_XferInterp,        // draw as if in srcover mode
     795                 :     kSkipDrawing_XferInterp     // draw nothing
     796                 : };
     797                 : 
     798               0 : static XferInterp interpret_xfermode(const SkPaint& paint, SkXfermode* xfer,
     799                 :                                      SkBitmap::Config deviceConfig) {
     800                 :     SkXfermode::Mode  mode;
     801                 : 
     802               0 :     if (SkXfermode::AsMode(xfer, &mode)) {
     803               0 :         switch (mode) {
     804                 :             case SkXfermode::kSrc_Mode:
     805               0 :                 if (just_solid_color(paint)) {
     806               0 :                     return kSrcOver_XferInterp;
     807                 :                 }
     808               0 :                 break;
     809                 :             case SkXfermode::kDst_Mode:
     810               0 :                 return kSkipDrawing_XferInterp;
     811                 :             case SkXfermode::kSrcOver_Mode:
     812               0 :                 return kSrcOver_XferInterp;
     813                 :             case SkXfermode::kDstOver_Mode:
     814               0 :                 if (SkBitmap::kRGB_565_Config == deviceConfig) {
     815               0 :                     return kSkipDrawing_XferInterp;
     816                 :                 }
     817               0 :                 break;
     818                 :             case SkXfermode::kSrcIn_Mode:
     819               0 :                 if (SkBitmap::kRGB_565_Config == deviceConfig &&
     820               0 :                     just_solid_color(paint)) {
     821               0 :                     return kSrcOver_XferInterp;
     822                 :                 }
     823               0 :                 break;
     824                 :             case SkXfermode::kDstIn_Mode:
     825               0 :                 if (just_solid_color(paint)) {
     826               0 :                     return kSkipDrawing_XferInterp;
     827                 :                 }
     828               0 :                 break;
     829                 :             default:
     830               0 :                 break;
     831                 :         }
     832                 :     }
     833               0 :     return kNormal_XferInterp;
     834                 : }
     835                 : 
     836               0 : SkBlitter* SkBlitter::Choose(const SkBitmap& device,
     837                 :                              const SkMatrix& matrix,
     838                 :                              const SkPaint& origPaint,
     839                 :                              void* storage, size_t storageSize) {
     840               0 :     SkASSERT(storageSize == 0 || storage != NULL);
     841                 : 
     842               0 :     SkBlitter*  blitter = NULL;
     843                 : 
     844                 :     // which check, in case we're being called by a client with a dummy device
     845                 :     // (e.g. they have a bounder that always aborts the draw)
     846               0 :     if (SkBitmap::kNo_Config == device.getConfig()) {
     847               0 :         SK_PLACEMENT_NEW(blitter, SkNullBlitter, storage, storageSize);
     848               0 :         return blitter;
     849                 :     }
     850                 : 
     851               0 :     SkPaint paint(origPaint);
     852               0 :     SkShader* shader = paint.getShader();
     853               0 :     SkColorFilter* cf = paint.getColorFilter();
     854               0 :     SkXfermode* mode = paint.getXfermode();
     855                 : 
     856               0 :     Sk3DShader* shader3D = NULL;
     857               0 :     if (paint.getMaskFilter() != NULL &&
     858               0 :             paint.getMaskFilter()->getFormat() == SkMask::k3D_Format) {
     859               0 :         shader3D = SkNEW_ARGS(Sk3DShader, (shader));
     860               0 :         paint.setShader(shader3D)->unref();
     861               0 :         shader = shader3D;
     862                 :     }
     863                 : 
     864               0 :     if (NULL != mode) {
     865               0 :         switch (interpret_xfermode(paint, mode, device.config())) {
     866                 :             case kSrcOver_XferInterp:
     867               0 :                 mode = NULL;
     868               0 :                 paint.setXfermode(NULL);
     869               0 :                 break;
     870                 :             case kSkipDrawing_XferInterp:
     871               0 :                 SK_PLACEMENT_NEW(blitter, SkNullBlitter, storage, storageSize);
     872               0 :                 return blitter;
     873                 :             default:
     874               0 :                 break;
     875                 :         }
     876                 :     }
     877                 : 
     878               0 :     if (NULL == shader) {
     879                 : #ifdef SK_IGNORE_CF_OPTIMIZATION
     880                 :         if (mode || cf) {
     881                 : #else
     882               0 :         if (mode) {
     883                 : #endif
     884                 :             // xfermodes (and filters) require shaders for our current blitters
     885               0 :             shader = SkNEW(SkColorShader);
     886               0 :             paint.setShader(shader)->unref();
     887               0 :         } else if (cf) {
     888                 :             // if no shader && no xfermode, we just apply the colorfilter to
     889                 :             // our color and move on.
     890               0 :             paint.setColor(cf->filterColor(paint.getColor()));
     891               0 :             paint.setColorFilter(NULL);
     892               0 :             cf = NULL;
     893                 :         }
     894                 :     }
     895                 : 
     896               0 :     if (cf) {
     897               0 :         SkASSERT(shader);
     898               0 :         shader = SkNEW_ARGS(SkFilterShader, (shader, cf));
     899               0 :         paint.setShader(shader)->unref();
     900                 :         // blitters should ignore the presence/absence of a filter, since
     901                 :         // if there is one, the shader will take care of it.
     902                 :     }
     903                 : 
     904               0 :     if (shader && !shader->setContext(device, paint, matrix)) {
     905               0 :         return SkNEW(SkNullBlitter);
     906                 :     }
     907                 : 
     908               0 :     switch (device.getConfig()) {
     909                 :         case SkBitmap::kA1_Config:
     910               0 :             SK_PLACEMENT_NEW_ARGS(blitter, SkA1_Blitter,
     911                 :                                   storage, storageSize, (device, paint));
     912               0 :             break;
     913                 : 
     914                 :         case SkBitmap::kA8_Config:
     915               0 :             if (shader) {
     916               0 :                 SK_PLACEMENT_NEW_ARGS(blitter, SkA8_Shader_Blitter,
     917                 :                                       storage, storageSize, (device, paint));
     918                 :             } else {
     919               0 :                 SK_PLACEMENT_NEW_ARGS(blitter, SkA8_Blitter,
     920                 :                                       storage, storageSize, (device, paint));
     921                 :             }
     922               0 :             break;
     923                 : 
     924                 :         case SkBitmap::kARGB_4444_Config:
     925               0 :             blitter = SkBlitter_ChooseD4444(device, paint, storage, storageSize);
     926               0 :             break;
     927                 : 
     928                 :         case SkBitmap::kRGB_565_Config:
     929               0 :             blitter = SkBlitter_ChooseD565(device, paint, storage, storageSize);
     930               0 :             break;
     931                 : 
     932                 :         case SkBitmap::kARGB_8888_Config:
     933               0 :             if (shader) {
     934               0 :                 SK_PLACEMENT_NEW_ARGS(blitter, SkARGB32_Shader_Blitter,
     935                 :                                       storage, storageSize, (device, paint));
     936               0 :             } else if (paint.getColor() == SK_ColorBLACK) {
     937               0 :                 SK_PLACEMENT_NEW_ARGS(blitter, SkARGB32_Black_Blitter,
     938                 :                                       storage, storageSize, (device, paint));
     939               0 :             } else if (paint.getAlpha() == 0xFF) {
     940               0 :                 SK_PLACEMENT_NEW_ARGS(blitter, SkARGB32_Opaque_Blitter,
     941                 :                                       storage, storageSize, (device, paint));
     942                 :             } else {
     943               0 :                 SK_PLACEMENT_NEW_ARGS(blitter, SkARGB32_Blitter,
     944                 :                                       storage, storageSize, (device, paint));
     945                 :             }
     946               0 :             break;
     947                 : 
     948                 :         default:
     949               0 :             SkDEBUGFAIL("unsupported device config");
     950               0 :             SK_PLACEMENT_NEW(blitter, SkNullBlitter, storage, storageSize);
     951               0 :             break;
     952                 :     }
     953                 : 
     954               0 :     if (shader3D) {
     955               0 :         void (*proc)(void*) = ((void*)storage == (void*)blitter) ? destroy_blitter : delete_blitter;
     956               0 :         SkAutoCallProc  tmp(blitter, proc);
     957                 : 
     958               0 :         blitter = SkNEW_ARGS(Sk3DBlitter, (blitter, shader3D, proc));
     959               0 :         (void)tmp.detach();
     960                 :     }
     961               0 :     return blitter;
     962                 : }
     963                 : 
     964                 : ///////////////////////////////////////////////////////////////////////////////
     965                 : 
     966                 : const uint16_t gMask_0F0F = 0xF0F;
     967                 : const uint32_t gMask_00FF00FF = 0xFF00FF;
     968                 : 
     969                 : ///////////////////////////////////////////////////////////////////////////////
     970                 : 
     971               0 : SkShaderBlitter::SkShaderBlitter(const SkBitmap& device, const SkPaint& paint)
     972               0 :         : INHERITED(device) {
     973               0 :     fShader = paint.getShader();
     974               0 :     SkASSERT(fShader);
     975                 : 
     976               0 :     fShader->ref();
     977               0 :     fShader->beginSession();
     978               0 :     fShaderFlags = fShader->getFlags();
     979               0 : }
     980                 : 
     981               0 : SkShaderBlitter::~SkShaderBlitter() {
     982               0 :     fShader->endSession();
     983               0 :     fShader->unref();
     984               0 : }
     985                 : 

Generated by: LCOV version 1.7