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
20ea969d53ddd53a8f125e6f2d10074c2f4a0b6554Steven Moreland#include <limits>
2120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#include <stdint.h>
2220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#include <sys/types.h>
2320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
2420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopiannamespace android {
2520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian// ----------------------------------------------------------------------------
2620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
2720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopiantemplate<typename RECT>
2820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopianclass region_operator
2920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian{
30068d47f29dfead847999a7b33b4217ee9514152bMathias Agopianpublic:
316027ba747a985fd14edf411395c79624f87f575bFabien Sanglard    typedef typename RECT::value_type TYPE;
326027ba747a985fd14edf411395c79624f87f575bFabien Sanglard    static const TYPE max_value = std::numeric_limits<TYPE>::max();
3320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
346027ba747a985fd14edf411395c79624f87f575bFabien Sanglard    /*
3520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian     * Common boolean operations:
3620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian     * value is computed as 0b101 op 0b110
3720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian     *    other boolean operation are possible, simply compute
3820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian     *    their corresponding value with the above formulae and use
3920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian     *    it when instantiating a region_operator.
4020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian     */
4120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    static const uint32_t LHS = 0x5;  // 0b101
4220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    static const uint32_t RHS = 0x6;  // 0b110
4320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    enum {
4420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        op_nand = LHS & ~RHS,
4520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        op_and  = LHS &  RHS,
4620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        op_or   = LHS |  RHS,
4720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        op_xor  = LHS ^  RHS
4820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    };
4920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
5020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    struct region {
5120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        RECT const* rects;
5220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        size_t count;
5320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        TYPE dx;
5420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        TYPE dy;
5520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        inline region(const region& rhs)
5620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            : rects(rhs.rects), count(rhs.count), dx(rhs.dx), dy(rhs.dy) { }
57382ecd3d6345aeeda158a8d94cc0aee1bd3a45dcColin Cross        inline region(RECT const* _r, size_t _c)
58382ecd3d6345aeeda158a8d94cc0aee1bd3a45dcColin Cross            : rects(_r), count(_c), dx(), dy() { }
59382ecd3d6345aeeda158a8d94cc0aee1bd3a45dcColin Cross        inline region(RECT const* _r, size_t _c, TYPE _dx, TYPE _dy)
60382ecd3d6345aeeda158a8d94cc0aee1bd3a45dcColin Cross            : rects(_r), count(_c), dx(_dx), dy(_dy) { }
6120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    };
6220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
6320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    class region_rasterizer {
6420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        friend class region_operator;
6520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        virtual void operator()(const RECT& rect) = 0;
66e7c4c28d0fe9b62eacaa04d901464e501e511265Mathias Agopian    public:
6717576de056a57753eb4af797545db88ef4f81ef0Colin Cross        virtual ~region_rasterizer() { }
6820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    };
6920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
708f279960c6ad8803e36503250b7ab89e34c9477bColin Cross    inline region_operator(uint32_t op, const region& lhs, const region& rhs)
7120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        : op_mask(op), spanner(lhs, rhs)
7220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    {
7320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    }
7420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
7520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    void operator()(region_rasterizer& rasterizer) {
7660d6922a011fe18c111b8d30fb6ef1f655b6b15ePablo Ceballos        RECT current(Rect::EMPTY_RECT);
7720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        do {
7820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            SpannerInner spannerInner(spanner.lhs, spanner.rhs);
7920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            int inside = spanner.next(current.top, current.bottom);
8020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            spannerInner.prepare(inside);
8120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            do {
8220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                TYPE left, right;
83382ecd3d6345aeeda158a8d94cc0aee1bd3a45dcColin Cross                int inner_inside = spannerInner.next(current.left, current.right);
84382ecd3d6345aeeda158a8d94cc0aee1bd3a45dcColin Cross                if ((op_mask >> inner_inside) & 1) {
8520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    if (current.left < current.right &&
8620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                            current.top < current.bottom) {
8720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                        rasterizer(current);
8820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    }
8920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                }
9038a7fa2ae37236952e5fb0186fddb4f6da5990d8Mathias Agopian            } while(!spannerInner.isDone());
9120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        } while(!spanner.isDone());
9220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    }
9320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
9420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopianprivate:
9520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    uint32_t op_mask;
9620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
9720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    class SpannerBase
9820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    {
9920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    public:
1003aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian        SpannerBase()
1013aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian            : lhs_head(max_value), lhs_tail(max_value),
1023aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian              rhs_head(max_value), rhs_tail(max_value) {
1033aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian        }
1043aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian
10520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        enum {
10620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            lhs_before_rhs   = 0,
10720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            lhs_after_rhs    = 1,
10820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            lhs_coincide_rhs = 2
10920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        };
11020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
11120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    protected:
11220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        TYPE lhs_head;
11320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        TYPE lhs_tail;
11420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        TYPE rhs_head;
11520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        TYPE rhs_tail;
11620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
11720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        inline int next(TYPE& head, TYPE& tail,
11820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                bool& more_lhs, bool& more_rhs)
11920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        {
12020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            int inside;
12120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            more_lhs = false;
12220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            more_rhs = false;
12320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            if (lhs_head < rhs_head) {
12420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                inside = lhs_before_rhs;
12520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                head = lhs_head;
12620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                if (lhs_tail <= rhs_head) {
12720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    tail = lhs_tail;
12820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    more_lhs = true;
12920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                } else {
13020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    lhs_head = rhs_head;
13120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    tail = rhs_head;
13220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                }
13320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            } else if (rhs_head < lhs_head) {
13420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                inside = lhs_after_rhs;
13520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                head = rhs_head;
13620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                if (rhs_tail <= lhs_head) {
13720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    tail = rhs_tail;
13820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    more_rhs = true;
13920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                } else {
14020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    rhs_head = lhs_head;
14120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    tail = lhs_head;
14220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                }
14320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            } else {
14420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                inside = lhs_coincide_rhs;
14520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                head = lhs_head;
14620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                if (lhs_tail <= rhs_tail) {
14720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    tail = rhs_head = lhs_tail;
14820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    more_lhs = true;
14920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                }
15020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                if (rhs_tail <= lhs_tail) {
15120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    tail = lhs_head = rhs_tail;
15220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    more_rhs = true;
15320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                }
15420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            }
15520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            return inside;
15620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        }
15720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    };
15820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
15920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    class Spanner : protected SpannerBase
16020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    {
16120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        friend class region_operator;
16220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        region lhs;
16320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        region rhs;
16420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
16520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    public:
166382ecd3d6345aeeda158a8d94cc0aee1bd3a45dcColin Cross        inline Spanner(const region& _lhs, const region& _rhs)
167382ecd3d6345aeeda158a8d94cc0aee1bd3a45dcColin Cross        : lhs(_lhs), rhs(_rhs)
16820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        {
1693aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian            if (lhs.count) {
1703aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian                SpannerBase::lhs_head = lhs.rects->top      + lhs.dy;
1713aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian                SpannerBase::lhs_tail = lhs.rects->bottom   + lhs.dy;
1723aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian            }
1733aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian            if (rhs.count) {
1743aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian                SpannerBase::rhs_head = rhs.rects->top      + rhs.dy;
1753aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian                SpannerBase::rhs_tail = rhs.rects->bottom   + rhs.dy;
1763aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian            }
17720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        }
17820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
17920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        inline bool isDone() const {
18020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            return !rhs.count && !lhs.count;
18120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        }
18220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
18320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        inline int next(TYPE& top, TYPE& bottom)
18420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        {
18520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            bool more_lhs = false;
18620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            bool more_rhs = false;
18720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            int inside = SpannerBase::next(top, bottom, more_lhs, more_rhs);
18820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            if (more_lhs) {
18920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                advance(lhs, SpannerBase::lhs_head, SpannerBase::lhs_tail);
19020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            }
19120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            if (more_rhs) {
19220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                advance(rhs, SpannerBase::rhs_head, SpannerBase::rhs_tail);
19320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            }
19420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            return inside;
19520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        }
19620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
19720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    private:
19820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        static inline
19920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        void advance(region& reg, TYPE& aTop, TYPE& aBottom) {
20020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            // got to next span
20120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            size_t count = reg.count;
20220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            RECT const * rects = reg.rects;
20320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            RECT const * const end = rects + count;
20420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            const int top = rects->top;
20520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            while (rects != end && rects->top == top) {
20620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                rects++;
20720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                count--;
20820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            }
20920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            if (rects != end) {
21020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                aTop    = rects->top    + reg.dy;
21120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                aBottom = rects->bottom + reg.dy;
21220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            } else {
21320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                aTop    = max_value;
21420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                aBottom = max_value;
21520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            }
21620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            reg.rects = rects;
21720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            reg.count = count;
21820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        }
21920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    };
22020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
22120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    class SpannerInner : protected SpannerBase
22220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    {
22320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        region lhs;
22420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        region rhs;
22520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
22620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    public:
227382ecd3d6345aeeda158a8d94cc0aee1bd3a45dcColin Cross        inline SpannerInner(const region& _lhs, const region& _rhs)
228382ecd3d6345aeeda158a8d94cc0aee1bd3a45dcColin Cross            : lhs(_lhs), rhs(_rhs)
22920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        {
23020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        }
23120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
23220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        inline void prepare(int inside) {
23320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            if (inside == SpannerBase::lhs_before_rhs) {
2343aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian                if (lhs.count) {
2353aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian                    SpannerBase::lhs_head = lhs.rects->left  + lhs.dx;
2363aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian                    SpannerBase::lhs_tail = lhs.rects->right + lhs.dx;
2373aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian                }
23820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                SpannerBase::rhs_head = max_value;
23920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                SpannerBase::rhs_tail = max_value;
24020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            } else if (inside == SpannerBase::lhs_after_rhs) {
24120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                SpannerBase::lhs_head = max_value;
24220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                SpannerBase::lhs_tail = max_value;
2433aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian                if (rhs.count) {
2443aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian                    SpannerBase::rhs_head = rhs.rects->left  + rhs.dx;
2453aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian                    SpannerBase::rhs_tail = rhs.rects->right + rhs.dx;
2463aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian                }
24720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            } else {
2483aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian                if (lhs.count) {
2493aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian                    SpannerBase::lhs_head = lhs.rects->left  + lhs.dx;
2503aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian                    SpannerBase::lhs_tail = lhs.rects->right + lhs.dx;
2513aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian                }
2523aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian                if (rhs.count) {
2533aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian                    SpannerBase::rhs_head = rhs.rects->left  + rhs.dx;
2543aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian                    SpannerBase::rhs_tail = rhs.rects->right + rhs.dx;
2553aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian                }
25620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            }
25720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        }
25820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
25920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        inline bool isDone() const {
26020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            return SpannerBase::lhs_head == max_value &&
26120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                   SpannerBase::rhs_head == max_value;
26220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        }
26320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
26420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        inline int next(TYPE& left, TYPE& right)
26520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        {
26620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            bool more_lhs = false;
26720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            bool more_rhs = false;
26820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            int inside = SpannerBase::next(left, right, more_lhs, more_rhs);
26920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            if (more_lhs) {
27020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                advance(lhs, SpannerBase::lhs_head, SpannerBase::lhs_tail);
27120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            }
27220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            if (more_rhs) {
27320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                advance(rhs, SpannerBase::rhs_head, SpannerBase::rhs_tail);
27420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            }
27520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            return inside;
27620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        }
27720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
27820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    private:
27920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        static inline
28020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        void advance(region& reg, TYPE& left, TYPE& right) {
28120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            if (reg.rects && reg.count) {
28220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                const int cur_span_top = reg.rects->top;
28320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                reg.rects++;
28420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                reg.count--;
28520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                if (!reg.count || reg.rects->top != cur_span_top) {
28620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    left  = max_value;
28720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    right = max_value;
28820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                } else {
28920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    left  = reg.rects->left  + reg.dx;
29020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    right = reg.rects->right + reg.dx;
29120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                }
29220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            }
29320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        }
29420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    };
29520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
29620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    Spanner spanner;
29720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian};
29820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
29920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian// ----------------------------------------------------------------------------
30020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian};
30120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
30220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#endif /* ANDROID_UI_PRIVATE_REGION_HELPER_H */
303