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