blob: 31b52e3b1a5799a0d70a27345dc2c99e9053439f [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
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
reed@android.com8a1c16f2008-12-17 15:59:43 +00009
10#ifndef SkAntiRun_DEFINED
11#define SkAntiRun_DEFINED
12
13#include "SkBlitter.h"
14
tomhudson@google.com05fffdc2011-12-01 20:41:24 +000015/** 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
reed@android.com8a1c16f2008-12-17 15:59:43 +000020class SkAlphaRuns {
21public:
22 int16_t* fRuns;
23 uint8_t* fAlpha;
24
tomhudson@google.com05fffdc2011-12-01 20:41:24 +000025 /// Returns true if the scanline contains only a single run,
26 /// of alpha value 0.
mike@reedtribe.orgd11f0e02011-04-09 19:39:25 +000027 bool empty() const {
reed@android.com8a1c16f2008-12-17 15:59:43 +000028 SkASSERT(fRuns[0] > 0);
29 return fAlpha[0] == 0 && fRuns[fRuns[0]] == 0;
30 }
mike@reedtribe.orgd11f0e02011-04-09 19:39:25 +000031
tomhudson@google.com05fffdc2011-12-01 20:41:24 +000032 /// Reinitialize for a new scanline.
reed@android.com8a1c16f2008-12-17 15:59:43 +000033 void reset(int width);
rmistry@google.comfbfcd562012-08-23 18:09:54 +000034
reed@google.comfa57ae72011-05-31 19:18:02 +000035 /**
tomhudson@google.com05fffdc2011-12-01 20:41:24 +000036 * 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
reed@google.comfa57ae72011-05-31 19:18:02 +000044 * 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
reed@android.com8a1c16f2008-12-17 15:59:43 +000051 SkDEBUGCODE(void assertValid(int y, int maxStep) const;)
52 SkDEBUGCODE(void dump() const;)
53
tomhudson@google.com05fffdc2011-12-01 20:41:24 +000054 /**
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 */
reed@android.com8a1c16f2008-12-17 15:59:43 +000062 static void Break(int16_t runs[], uint8_t alpha[], int x, int count);
mike@reedtribe.orgd11f0e02011-04-09 19:39:25 +000063
tomhudson@google.com05fffdc2011-12-01 20:41:24 +000064 /**
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 */
mike@reedtribe.orgd11f0e02011-04-09 19:39:25 +000070 static void BreakAt(int16_t runs[], uint8_t alpha[], int x) {
71 while (x > 0) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000072 int n = runs[0];
73 SkASSERT(n > 0);
74
mike@reedtribe.orgd11f0e02011-04-09 19:39:25 +000075 if (x < n) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000076 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