RegionHelper.h revision 38a7fa2ae37236952e5fb0186fddb4f6da5990d8
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{
2920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    typedef typename RECT::value_type TYPE;
3020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    static const TYPE max_value = 0x7FFFFFF;
3120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
3220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopianpublic:
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:
9920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        enum {
10020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            lhs_before_rhs   = 0,
10120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            lhs_after_rhs    = 1,
10220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            lhs_coincide_rhs = 2
10320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        };
10420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
10520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    protected:
10620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        TYPE lhs_head;
10720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        TYPE lhs_tail;
10820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        TYPE rhs_head;
10920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        TYPE rhs_tail;
11020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
11120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        inline int next(TYPE& head, TYPE& tail,
11220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                bool& more_lhs, bool& more_rhs)
11320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        {
11420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            int inside;
11520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            more_lhs = false;
11620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            more_rhs = false;
11720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            if (lhs_head < rhs_head) {
11820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                inside = lhs_before_rhs;
11920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                head = lhs_head;
12020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                if (lhs_tail <= rhs_head) {
12120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    tail = lhs_tail;
12220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    more_lhs = true;
12320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                } else {
12420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    lhs_head = rhs_head;
12520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    tail = rhs_head;
12620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                }
12720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            } else if (rhs_head < lhs_head) {
12820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                inside = lhs_after_rhs;
12920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                head = rhs_head;
13020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                if (rhs_tail <= lhs_head) {
13120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    tail = rhs_tail;
13220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    more_rhs = true;
13320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                } else {
13420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    rhs_head = lhs_head;
13520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    tail = lhs_head;
13620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                }
13720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            } else {
13820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                inside = lhs_coincide_rhs;
13920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                head = lhs_head;
14020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                if (lhs_tail <= rhs_tail) {
14120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    tail = rhs_head = lhs_tail;
14220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    more_lhs = true;
14320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                }
14420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                if (rhs_tail <= lhs_tail) {
14520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    tail = lhs_head = rhs_tail;
14620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    more_rhs = true;
14720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                }
14820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            }
14920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            return inside;
15020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        }
15120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    };
15220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
15320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    class Spanner : protected SpannerBase
15420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    {
15520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        friend class region_operator;
15620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        region lhs;
15720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        region rhs;
15820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
15920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    public:
16020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        inline Spanner(const region& lhs, const region& rhs)
16120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            : lhs(lhs), rhs(rhs)
16220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        {
16320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            SpannerBase::lhs_head = lhs.rects->top      + lhs.dy;
16420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            SpannerBase::lhs_tail = lhs.rects->bottom   + lhs.dy;
16520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            SpannerBase::rhs_head = rhs.rects->top      + rhs.dy;
16620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            SpannerBase::rhs_tail = rhs.rects->bottom   + rhs.dy;
16720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        }
16820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
16920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        inline bool isDone() const {
17020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            return !rhs.count && !lhs.count;
17120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        }
17220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
17320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        inline int next(TYPE& top, TYPE& bottom)
17420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        {
17520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            bool more_lhs = false;
17620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            bool more_rhs = false;
17720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            int inside = SpannerBase::next(top, bottom, more_lhs, more_rhs);
17820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            if (more_lhs) {
17920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                advance(lhs, SpannerBase::lhs_head, SpannerBase::lhs_tail);
18020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            }
18120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            if (more_rhs) {
18220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                advance(rhs, SpannerBase::rhs_head, SpannerBase::rhs_tail);
18320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            }
18420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            return inside;
18520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        }
18620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
18720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    private:
18820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        static inline
18920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        void advance(region& reg, TYPE& aTop, TYPE& aBottom) {
19020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            // got to next span
19120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            size_t count = reg.count;
19220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            RECT const * rects = reg.rects;
19320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            RECT const * const end = rects + count;
19420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            const int top = rects->top;
19520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            while (rects != end && rects->top == top) {
19620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                rects++;
19720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                count--;
19820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            }
19920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            if (rects != end) {
20020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                aTop    = rects->top    + reg.dy;
20120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                aBottom = rects->bottom + reg.dy;
20220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            } else {
20320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                aTop    = max_value;
20420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                aBottom = max_value;
20520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            }
20620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            reg.rects = rects;
20720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            reg.count = count;
20820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        }
20920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    };
21020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
21120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    class SpannerInner : protected SpannerBase
21220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    {
21320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        region lhs;
21420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        region rhs;
21520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
21620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    public:
21720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        inline SpannerInner(const region& lhs, const region& rhs)
21820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            : lhs(lhs), rhs(rhs)
21920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        {
22020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        }
22120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
22220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        inline void prepare(int inside) {
22320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            if (inside == SpannerBase::lhs_before_rhs) {
22438a7fa2ae37236952e5fb0186fddb4f6da5990d8Mathias Agopian                SpannerBase::lhs_head = lhs.rects->left  + lhs.dx;
22538a7fa2ae37236952e5fb0186fddb4f6da5990d8Mathias Agopian                SpannerBase::lhs_tail = lhs.rects->right + lhs.dx;
22620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                SpannerBase::rhs_head = max_value;
22720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                SpannerBase::rhs_tail = max_value;
22820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            } else if (inside == SpannerBase::lhs_after_rhs) {
22920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                SpannerBase::lhs_head = max_value;
23020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                SpannerBase::lhs_tail = max_value;
23138a7fa2ae37236952e5fb0186fddb4f6da5990d8Mathias Agopian                SpannerBase::rhs_head = rhs.rects->left  + rhs.dx;
23238a7fa2ae37236952e5fb0186fddb4f6da5990d8Mathias Agopian                SpannerBase::rhs_tail = rhs.rects->right + rhs.dx;
23320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            } else {
23438a7fa2ae37236952e5fb0186fddb4f6da5990d8Mathias Agopian                SpannerBase::lhs_head = lhs.rects->left  + lhs.dx;
23538a7fa2ae37236952e5fb0186fddb4f6da5990d8Mathias Agopian                SpannerBase::lhs_tail = lhs.rects->right + lhs.dx;
23638a7fa2ae37236952e5fb0186fddb4f6da5990d8Mathias Agopian                SpannerBase::rhs_head = rhs.rects->left  + rhs.dx;
23738a7fa2ae37236952e5fb0186fddb4f6da5990d8Mathias Agopian                SpannerBase::rhs_tail = rhs.rects->right + rhs.dx;
23820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            }
23920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        }
24020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
24120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        inline bool isDone() const {
24220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            return SpannerBase::lhs_head == max_value &&
24320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                   SpannerBase::rhs_head == max_value;
24420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        }
24520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
24620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        inline int next(TYPE& left, TYPE& right)
24720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        {
24820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            bool more_lhs = false;
24920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            bool more_rhs = false;
25020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            int inside = SpannerBase::next(left, right, more_lhs, more_rhs);
25120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            if (more_lhs) {
25220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                advance(lhs, SpannerBase::lhs_head, SpannerBase::lhs_tail);
25320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            }
25420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            if (more_rhs) {
25520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                advance(rhs, SpannerBase::rhs_head, SpannerBase::rhs_tail);
25620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            }
25720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            return inside;
25820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        }
25920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
26020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    private:
26120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        static inline
26220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        void advance(region& reg, TYPE& left, TYPE& right) {
26320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            if (reg.rects && reg.count) {
26420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                const int cur_span_top = reg.rects->top;
26520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                reg.rects++;
26620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                reg.count--;
26720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                if (!reg.count || reg.rects->top != cur_span_top) {
26820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    left  = max_value;
26920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    right = max_value;
27020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                } else {
27120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    left  = reg.rects->left  + reg.dx;
27220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    right = reg.rects->right + reg.dx;
27320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                }
27420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            }
27520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        }
27620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    };
27720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
27820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    Spanner spanner;
27920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian};
28020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
28120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian// ----------------------------------------------------------------------------
28220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian};
28320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
28420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#endif /* ANDROID_UI_PRIVATE_REGION_HELPER_H */
285