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
20class SkAlphaRuns {
21public:
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
87private:
88    SkDEBUGCODE(int fWidth;)
89    SkDEBUGCODE(void validate() const;)
90};
91
92#endif
93
94