Home | History | Annotate | Download | only in core
      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 #ifndef SkAntiRun_DEFINED
     11 #define SkAntiRun_DEFINED
     12 
     13 #include "SkBlitter.h"
     14 
     15 /** Sparse array of run-length-encoded alpha (supersampling coverage) values.
     16     Sparseness allows us to independently compose several paths into the
     17     same SkAlphaRuns buffer.
     18 */
     19 
     20 class SkAlphaRuns {
     21 public:
     22     int16_t*    fRuns;
     23     uint8_t*     fAlpha;
     24 
     25     /// Returns true if the scanline contains only a single run,
     26     /// of alpha value 0.
     27     bool empty() const {
     28         SkASSERT(fRuns[0] > 0);
     29         return fAlpha[0] == 0 && fRuns[fRuns[0]] == 0;
     30     }
     31 
     32     /// Reinitialize for a new scanline.
     33     void    reset(int width);
     34 
     35     /**
     36      *  Insert into the buffer a run starting at (x-offsetX):
     37      *      if startAlpha > 0
     38      *          one pixel with value += startAlpha,
     39      *              max 255
     40      *      if middleCount > 0
     41      *          middleCount pixels with value += maxValue
     42      *      if stopAlpha > 0
     43      *          one pixel with value += stopAlpha
     44      *  Returns the offsetX value that should be passed on the next call,
     45      *  assuming we're on the same scanline. If the caller is switching
     46      *  scanlines, then offsetX should be 0 when this is called.
     47      */
     48     int add(int x, U8CPU startAlpha, int middleCount, U8CPU stopAlpha,
     49             U8CPU maxValue, int offsetX);
     50 
     51     SkDEBUGCODE(void assertValid(int y, int maxStep) const;)
     52     SkDEBUGCODE(void dump() const;)
     53 
     54     /**
     55      * Break the runs in the buffer at offsets x and x+count, properly
     56      * updating the runs to the right and left.
     57      *   i.e. from the state AAAABBBB, run-length encoded as A4B4,
     58      *   Break(..., 2, 5) would produce AAAABBBB rle as A2A2B3B1.
     59      * Allows add() to sum another run to some of the new sub-runs.
     60      *   i.e. adding ..CCCCC. would produce AADDEEEB, rle as A2D2E3B1.
     61      */
     62     static void Break(int16_t runs[], uint8_t alpha[], int x, int count);
     63 
     64     /**
     65      * Cut (at offset x in the buffer) a run into two shorter runs with
     66      * matching alpha values.
     67      * Used by the RectClipBlitter to trim a RLE encoding to match the
     68      * clipping rectangle.
     69      */
     70     static void BreakAt(int16_t runs[], uint8_t alpha[], int x) {
     71         while (x > 0) {
     72             int n = runs[0];
     73             SkASSERT(n > 0);
     74 
     75             if (x < n) {
     76                 alpha[x] = alpha[0];
     77                 runs[0] = SkToS16(x);
     78                 runs[x] = SkToS16(n - x);
     79                 break;
     80             }
     81             runs += n;
     82             alpha += n;
     83             x -= n;
     84         }
     85     }
     86 
     87 private:
     88     SkDEBUGCODE(int fWidth;)
     89     SkDEBUGCODE(void validate() const;)
     90 };
     91 
     92 #endif
     93