1e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com
2e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com/*
3e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com * Copyright 2011 Google Inc.
4e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com *
5e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com * Use of this source code is governed by a BSD-style license that can be
6e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com * found in the LICENSE file.
7e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com */
8e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com
9e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com#ifndef SkAAClip_DEFINED
10e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com#define SkAAClip_DEFINED
11e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com
12e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com#include "SkBlitter.h"
13e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com#include "SkRegion.h"
14e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com
15e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.comclass SkAAClip {
16e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.compublic:
17e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com    SkAAClip();
18e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com    SkAAClip(const SkAAClip&);
19e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com    ~SkAAClip();
20e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com
21e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com    SkAAClip& operator=(const SkAAClip&);
22e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com    friend bool operator==(const SkAAClip&, const SkAAClip&);
23e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com    friend bool operator!=(const SkAAClip& a, const SkAAClip& b) {
24e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com        return !(a == b);
25e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com    }
26e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com
27e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com    void swap(SkAAClip&);
28e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com
2947ac84edafc6f26e2146ab10363e2043c5af0e62reed@google.com    bool isEmpty() const { return NULL == fRunHead; }
30e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com    const SkIRect& getBounds() const { return fBounds; }
31e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com
32e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com    bool setEmpty();
33e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com    bool setRect(const SkIRect&);
34f3c1da1e977a0e02535af71749fe9e92665ed51ereed@google.com    bool setRect(const SkRect&, bool doAA = true);
35f3c1da1e977a0e02535af71749fe9e92665ed51ereed@google.com    bool setPath(const SkPath&, const SkRegion* clip = NULL, bool doAA = true);
36f3c1da1e977a0e02535af71749fe9e92665ed51ereed@google.com    bool setRegion(const SkRegion&);
37322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com    bool set(const SkAAClip&);
38e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com
39e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com    bool op(const SkAAClip&, const SkAAClip&, SkRegion::Op);
40e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com
4147ac84edafc6f26e2146ab10363e2043c5af0e62reed@google.com    // Helpers for op()
4247ac84edafc6f26e2146ab10363e2043c5af0e62reed@google.com    bool op(const SkIRect&, SkRegion::Op);
430017708a5bcb6d0fbff0fac565085bef65de7433reed@google.com    bool op(const SkRect&, SkRegion::Op, bool doAA);
4447ac84edafc6f26e2146ab10363e2043c5af0e62reed@google.com    bool op(const SkAAClip&, SkRegion::Op);
4547ac84edafc6f26e2146ab10363e2043c5af0e62reed@google.com
4634f7e47a3593911d03307a08e5af625b218ceec3reed@google.com    bool translate(int dx, int dy, SkAAClip* dst) const;
4734f7e47a3593911d03307a08e5af625b218ceec3reed@google.com    bool translate(int dx, int dy) {
4834f7e47a3593911d03307a08e5af625b218ceec3reed@google.com        return this->translate(dx, dy, this);
4934f7e47a3593911d03307a08e5af625b218ceec3reed@google.com    }
501c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com
51322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com    /**
52322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com     *  Allocates a mask the size of the aaclip, and expands its data into
53322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com     *  the mask, using kA8_Format
54322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com     */
55322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com    void copyToMask(SkMask*) const;
56322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com
57e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com    // called internally
58fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
59e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com    bool quickContains(int left, int top, int right, int bottom) const;
60045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com    bool quickContains(const SkIRect& r) const {
61045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com        return this->quickContains(r.fLeft, r.fTop, r.fRight, r.fBottom);
62045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com    }
63045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com
64a4c6e4d6d3a4010df8dd2b04314675e4c201133breed@google.com    const uint8_t* findRow(int y, int* lastYForRow = NULL) const;
65a4c6e4d6d3a4010df8dd2b04314675e4c201133breed@google.com    const uint8_t* findX(const uint8_t data[], int x, int* initialCount = NULL) const;
66e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com
67322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com    class Iter;
68e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com    struct RunHead;
69e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com    struct YOffset;
70322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com    class Builder;
71e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com
72045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com#ifdef SK_DEBUG
73045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com    void validate() const;
74045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com#else
75045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com    void validate() const {}
76045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com#endif
77045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com
78322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.comprivate:
79e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com    SkIRect  fBounds;
80e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com    RunHead* fRunHead;
81e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com
82e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com    void freeRuns();
83045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com    bool trimBounds();
84c90419199525141a5b98091f856e359bf9daf5b1reed@google.com    bool trimTopBottom();
85c90419199525141a5b98091f856e359bf9daf5b1reed@google.com    bool trimLeftRight();
86e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com
87e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com    friend class Builder;
88e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com    class BuilderBlitter;
89e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com    friend class BuilderBlitter;
90e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com};
91e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com
92e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com///////////////////////////////////////////////////////////////////////////////
93e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com
94e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.comclass SkAAClipBlitter : public SkBlitter {
95e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.compublic:
96045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com    SkAAClipBlitter() : fScanlineScratch(NULL) {}
97e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com    virtual ~SkAAClipBlitter();
98e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com
99e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com    void init(SkBlitter* blitter, const SkAAClip* aaclip) {
100e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com        SkASSERT(aaclip && !aaclip->isEmpty());
101e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com        fBlitter = blitter;
102e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com        fAAClip = aaclip;
103e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com        fAAClipBounds = aaclip->getBounds();
104e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com    }
105fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
106e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com    virtual void blitH(int x, int y, int width) SK_OVERRIDE;
107e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com    virtual void blitAntiH(int x, int y, const SkAlpha[],
108e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com                           const int16_t runs[]) SK_OVERRIDE;
109e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com    virtual void blitV(int x, int y, int height, SkAlpha alpha) SK_OVERRIDE;
110e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com    virtual void blitRect(int x, int y, int width, int height) SK_OVERRIDE;
111e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com    virtual void blitMask(const SkMask&, const SkIRect& clip) SK_OVERRIDE;
112e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com    virtual const SkBitmap* justAnOpaqueColor(uint32_t* value) SK_OVERRIDE;
113fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
114e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.comprivate:
115e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com    SkBlitter*      fBlitter;
116e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com    const SkAAClip* fAAClip;
117e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com    SkIRect         fAAClipBounds;
118e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com
119045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com    // point into fScanlineScratch
120e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com    int16_t*        fRuns;
121045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com    SkAlpha*        fAA;
122045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com
123045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com    enum {
124045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com        kSize = 32 * 32
125045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com    };
126045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com    SkAutoSMalloc<kSize> fGrayMaskScratch;  // used for blitMask
127045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com    void* fScanlineScratch;  // enough for a mask at 32bit, or runs+aa
128e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com
129e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com    void ensureRunsAndAA();
130e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com};
131e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com
132e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com#endif
133