120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian/*
220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian * Copyright (C) 2009 The Android Open Source Project
320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian *
420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian * Licensed under the Apache License, Version 2.0 (the "License");
520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian * you may not use this file except in compliance with the License.
620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian * You may obtain a copy of the License at
720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian *
820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian *      http://www.apache.org/licenses/LICENSE-2.0
920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian *
1020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian * Unless required by applicable law or agreed to in writing, software
1120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian * distributed under the License is distributed on an "AS IS" BASIS,
1220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian * See the License for the specific language governing permissions and
1420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian * limitations under the License.
1520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian */
1620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
1720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#ifndef ANDROID_UI_PRIVATE_REGION_HELPER_H
1820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#define ANDROID_UI_PRIVATE_REGION_HELPER_H
1920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
2020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#include <stdint.h>
2120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#include <sys/types.h>
2220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
2320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopiannamespace android {
2420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian// ----------------------------------------------------------------------------
2520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
2620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopiantemplate<typename RECT>
2720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopianclass region_operator
2820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian{
29068d47f29dfead847999a7b33b4217ee9514152bMathias Agopianpublic:
3020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    typedef typename RECT::value_type TYPE;
3120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    static const TYPE max_value = 0x7FFFFFF;
3220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
3320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    /*
3420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian     * Common boolean operations:
3520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian     * value is computed as 0b101 op 0b110
3620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian     *    other boolean operation are possible, simply compute
3720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian     *    their corresponding value with the above formulae and use
3820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian     *    it when instantiating a region_operator.
3920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian     */
4020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    static const uint32_t LHS = 0x5;  // 0b101
4120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    static const uint32_t RHS = 0x6;  // 0b110
4220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    enum {
4320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        op_nand = LHS & ~RHS,
4420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        op_and  = LHS &  RHS,
4520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        op_or   = LHS |  RHS,
4620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        op_xor  = LHS ^  RHS
4720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    };
4820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
4920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    struct region {
5020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        RECT const* rects;
5120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        size_t count;
5220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        TYPE dx;
5320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        TYPE dy;
5420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        inline region(const region& rhs)
5520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            : rects(rhs.rects), count(rhs.count), dx(rhs.dx), dy(rhs.dy) { }
5620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        inline region(RECT const* r, size_t c)
5720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            : rects(r), count(c), dx(), dy() { }
5820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        inline region(RECT const* r, size_t c, TYPE dx, TYPE dy)
5920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            : rects(r), count(c), dx(dx), dy(dy) { }
6020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    };
6120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
6220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    class region_rasterizer {
6320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        friend class region_operator;
6420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        virtual void operator()(const RECT& rect) = 0;
65e7c4c28d0fe9b62eacaa04d901464e501e511265Mathias Agopian    public:
66e7c4c28d0fe9b62eacaa04d901464e501e511265Mathias Agopian        virtual ~region_rasterizer() { };
6720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    };
6820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
6920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    inline region_operator(int op, const region& lhs, const region& rhs)
7020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        : op_mask(op), spanner(lhs, rhs)
7120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    {
7220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    }
7320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
7420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    void operator()(region_rasterizer& rasterizer) {
7520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        RECT current;
7620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        do {
7720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            SpannerInner spannerInner(spanner.lhs, spanner.rhs);
7820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            int inside = spanner.next(current.top, current.bottom);
7920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            spannerInner.prepare(inside);
8020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            do {
8120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                TYPE left, right;
8220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                int inside = spannerInner.next(current.left, current.right);
8320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                if ((op_mask >> inside) & 1) {
8420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    if (current.left < current.right &&
8520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                            current.top < current.bottom) {
8620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                        rasterizer(current);
8720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    }
8820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                }
8938a7fa2ae37236952e5fb0186fddb4f6da5990d8Mathias Agopian            } while(!spannerInner.isDone());
9020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        } while(!spanner.isDone());
9120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    }
9220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
9320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopianprivate:
9420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    uint32_t op_mask;
9520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
9620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    class SpannerBase
9720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    {
9820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    public:
993aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian        SpannerBase()
1003aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian            : lhs_head(max_value), lhs_tail(max_value),
1013aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian              rhs_head(max_value), rhs_tail(max_value) {
1023aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian        }
1033aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian
10420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        enum {
10520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            lhs_before_rhs   = 0,
10620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            lhs_after_rhs    = 1,
10720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            lhs_coincide_rhs = 2
10820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        };
10920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
11020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    protected:
11120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        TYPE lhs_head;
11220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        TYPE lhs_tail;
11320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        TYPE rhs_head;
11420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        TYPE rhs_tail;
11520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
11620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        inline int next(TYPE& head, TYPE& tail,
11720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                bool& more_lhs, bool& more_rhs)
11820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        {
11920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            int inside;
12020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            more_lhs = false;
12120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            more_rhs = false;
12220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            if (lhs_head < rhs_head) {
12320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                inside = lhs_before_rhs;
12420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                head = lhs_head;
12520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                if (lhs_tail <= rhs_head) {
12620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    tail = lhs_tail;
12720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    more_lhs = true;
12820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                } else {
12920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    lhs_head = rhs_head;
13020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    tail = rhs_head;
13120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                }
13220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            } else if (rhs_head < lhs_head) {
13320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                inside = lhs_after_rhs;
13420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                head = rhs_head;
13520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                if (rhs_tail <= lhs_head) {
13620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    tail = rhs_tail;
13720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    more_rhs = true;
13820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                } else {
13920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    rhs_head = lhs_head;
14020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    tail = lhs_head;
14120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                }
14220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            } else {
14320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                inside = lhs_coincide_rhs;
14420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                head = lhs_head;
14520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                if (lhs_tail <= rhs_tail) {
14620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    tail = rhs_head = lhs_tail;
14720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    more_lhs = true;
14820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                }
14920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                if (rhs_tail <= lhs_tail) {
15020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    tail = lhs_head = rhs_tail;
15120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    more_rhs = true;
15220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                }
15320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            }
15420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            return inside;
15520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        }
15620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    };
15720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
15820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    class Spanner : protected SpannerBase
15920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    {
16020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        friend class region_operator;
16120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        region lhs;
16220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        region rhs;
16320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
16420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    public:
16520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        inline Spanner(const region& lhs, const region& rhs)
1663aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian        : lhs(lhs), rhs(rhs)
16720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        {
1683aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian            if (lhs.count) {
1693aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian                SpannerBase::lhs_head = lhs.rects->top      + lhs.dy;
1703aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian                SpannerBase::lhs_tail = lhs.rects->bottom   + lhs.dy;
1713aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian            }
1723aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian            if (rhs.count) {
1733aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian                SpannerBase::rhs_head = rhs.rects->top      + rhs.dy;
1743aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian                SpannerBase::rhs_tail = rhs.rects->bottom   + rhs.dy;
1753aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian            }
17620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        }
17720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
17820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        inline bool isDone() const {
17920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            return !rhs.count && !lhs.count;
18020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        }
18120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
18220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        inline int next(TYPE& top, TYPE& bottom)
18320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        {
18420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            bool more_lhs = false;
18520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            bool more_rhs = false;
18620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            int inside = SpannerBase::next(top, bottom, more_lhs, more_rhs);
18720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            if (more_lhs) {
18820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                advance(lhs, SpannerBase::lhs_head, SpannerBase::lhs_tail);
18920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            }
19020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            if (more_rhs) {
19120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                advance(rhs, SpannerBase::rhs_head, SpannerBase::rhs_tail);
19220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            }
19320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            return inside;
19420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        }
19520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
19620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    private:
19720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        static inline
19820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        void advance(region& reg, TYPE& aTop, TYPE& aBottom) {
19920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            // got to next span
20020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            size_t count = reg.count;
20120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            RECT const * rects = reg.rects;
20220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            RECT const * const end = rects + count;
20320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            const int top = rects->top;
20420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            while (rects != end && rects->top == top) {
20520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                rects++;
20620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                count--;
20720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            }
20820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            if (rects != end) {
20920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                aTop    = rects->top    + reg.dy;
21020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                aBottom = rects->bottom + reg.dy;
21120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            } else {
21220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                aTop    = max_value;
21320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                aBottom = max_value;
21420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            }
21520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            reg.rects = rects;
21620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            reg.count = count;
21720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        }
21820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    };
21920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
22020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    class SpannerInner : protected SpannerBase
22120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    {
22220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        region lhs;
22320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        region rhs;
22420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
22520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    public:
22620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        inline SpannerInner(const region& lhs, const region& rhs)
22720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            : lhs(lhs), rhs(rhs)
22820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        {
22920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        }
23020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
23120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        inline void prepare(int inside) {
23220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            if (inside == SpannerBase::lhs_before_rhs) {
2333aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian                if (lhs.count) {
2343aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian                    SpannerBase::lhs_head = lhs.rects->left  + lhs.dx;
2353aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian                    SpannerBase::lhs_tail = lhs.rects->right + lhs.dx;
2363aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian                }
23720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                SpannerBase::rhs_head = max_value;
23820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                SpannerBase::rhs_tail = max_value;
23920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            } else if (inside == SpannerBase::lhs_after_rhs) {
24020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                SpannerBase::lhs_head = max_value;
24120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                SpannerBase::lhs_tail = max_value;
2423aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian                if (rhs.count) {
2433aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian                    SpannerBase::rhs_head = rhs.rects->left  + rhs.dx;
2443aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian                    SpannerBase::rhs_tail = rhs.rects->right + rhs.dx;
2453aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian                }
24620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            } else {
2473aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian                if (lhs.count) {
2483aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian                    SpannerBase::lhs_head = lhs.rects->left  + lhs.dx;
2493aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian                    SpannerBase::lhs_tail = lhs.rects->right + lhs.dx;
2503aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian                }
2513aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian                if (rhs.count) {
2523aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian                    SpannerBase::rhs_head = rhs.rects->left  + rhs.dx;
2533aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian                    SpannerBase::rhs_tail = rhs.rects->right + rhs.dx;
2543aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian                }
25520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            }
25620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        }
25720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
25820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        inline bool isDone() const {
25920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            return SpannerBase::lhs_head == max_value &&
26020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                   SpannerBase::rhs_head == max_value;
26120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        }
26220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
26320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        inline int next(TYPE& left, TYPE& right)
26420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        {
26520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            bool more_lhs = false;
26620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            bool more_rhs = false;
26720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            int inside = SpannerBase::next(left, right, more_lhs, more_rhs);
26820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            if (more_lhs) {
26920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                advance(lhs, SpannerBase::lhs_head, SpannerBase::lhs_tail);
27020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            }
27120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            if (more_rhs) {
27220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                advance(rhs, SpannerBase::rhs_head, SpannerBase::rhs_tail);
27320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            }
27420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            return inside;
27520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        }
27620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
27720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    private:
27820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        static inline
27920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        void advance(region& reg, TYPE& left, TYPE& right) {
28020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            if (reg.rects && reg.count) {
28120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                const int cur_span_top = reg.rects->top;
28220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                reg.rects++;
28320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                reg.count--;
28420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                if (!reg.count || reg.rects->top != cur_span_top) {
28520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    left  = max_value;
28620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    right = max_value;
28720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                } else {
28820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    left  = reg.rects->left  + reg.dx;
28920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    right = reg.rects->right + reg.dx;
29020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                }
29120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            }
29220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        }
29320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    };
29420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
29520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    Spanner spanner;
29620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian};
29720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
29820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian// ----------------------------------------------------------------------------
29920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian};
30020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
30120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#endif /* ANDROID_UI_PRIVATE_REGION_HELPER_H */
302