RegionHelper.h revision 20f68782a4ea71c6a977d7f87d8288d3daa265ec
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;
6520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    };
6620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
6720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    inline region_operator(int op, const region& lhs, const region& rhs)
6820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        : op_mask(op), spanner(lhs, rhs)
6920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    {
7020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    }
7120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
7220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    void operator()(region_rasterizer& rasterizer) {
7320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        RECT current;
7420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        do {
7520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            SpannerInner spannerInner(spanner.lhs, spanner.rhs);
7620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            int inside = spanner.next(current.top, current.bottom);
7720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            spannerInner.prepare(inside);
7820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            do {
7920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                TYPE left, right;
8020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                int inside = spannerInner.next(current.left, current.right);
8120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                if ((op_mask >> inside) & 1) {
8220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    if (current.left < current.right &&
8320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                            current.top < current.bottom) {
8420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                        rasterizer(current);
8520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    }
8620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                }
8720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            } while(!spannerInner.isDone());
8820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        } while(!spanner.isDone());
8920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    }
9020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
9120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopianprivate:
9220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    uint32_t op_mask;
9320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
9420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    class SpannerBase
9520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    {
9620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    public:
9720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        enum {
9820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            lhs_before_rhs   = 0,
9920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            lhs_after_rhs    = 1,
10020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            lhs_coincide_rhs = 2
10120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        };
10220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
10320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    protected:
10420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        TYPE lhs_head;
10520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        TYPE lhs_tail;
10620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        TYPE rhs_head;
10720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        TYPE rhs_tail;
10820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
10920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        inline int next(TYPE& head, TYPE& tail,
11020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                bool& more_lhs, bool& more_rhs)
11120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        {
11220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            int inside;
11320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            more_lhs = false;
11420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            more_rhs = false;
11520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            if (lhs_head < rhs_head) {
11620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                inside = lhs_before_rhs;
11720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                head = lhs_head;
11820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                if (lhs_tail <= rhs_head) {
11920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    tail = lhs_tail;
12020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    more_lhs = true;
12120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                } else {
12220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    lhs_head = rhs_head;
12320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    tail = rhs_head;
12420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                }
12520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            } else if (rhs_head < lhs_head) {
12620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                inside = lhs_after_rhs;
12720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                head = rhs_head;
12820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                if (rhs_tail <= lhs_head) {
12920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    tail = rhs_tail;
13020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    more_rhs = true;
13120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                } else {
13220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    rhs_head = lhs_head;
13320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    tail = lhs_head;
13420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                }
13520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            } else {
13620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                inside = lhs_coincide_rhs;
13720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                head = lhs_head;
13820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                if (lhs_tail <= rhs_tail) {
13920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    tail = rhs_head = lhs_tail;
14020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    more_lhs = true;
14120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                }
14220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                if (rhs_tail <= lhs_tail) {
14320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    tail = lhs_head = rhs_tail;
14420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    more_rhs = true;
14520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                }
14620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            }
14720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            return inside;
14820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        }
14920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    };
15020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
15120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    class Spanner : protected SpannerBase
15220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    {
15320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        friend class region_operator;
15420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        region lhs;
15520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        region rhs;
15620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
15720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    public:
15820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        inline Spanner(const region& lhs, const region& rhs)
15920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            : lhs(lhs), rhs(rhs)
16020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        {
16120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            SpannerBase::lhs_head = lhs.rects->top      + lhs.dy;
16220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            SpannerBase::lhs_tail = lhs.rects->bottom   + lhs.dy;
16320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            SpannerBase::rhs_head = rhs.rects->top      + rhs.dy;
16420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            SpannerBase::rhs_tail = rhs.rects->bottom   + rhs.dy;
16520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        }
16620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
16720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        inline bool isDone() const {
16820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            return !rhs.count && !lhs.count;
16920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        }
17020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
17120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        inline int next(TYPE& top, TYPE& bottom)
17220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        {
17320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            bool more_lhs = false;
17420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            bool more_rhs = false;
17520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            int inside = SpannerBase::next(top, bottom, more_lhs, more_rhs);
17620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            if (more_lhs) {
17720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                advance(lhs, SpannerBase::lhs_head, SpannerBase::lhs_tail);
17820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            }
17920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            if (more_rhs) {
18020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                advance(rhs, SpannerBase::rhs_head, SpannerBase::rhs_tail);
18120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            }
18220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            return inside;
18320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        }
18420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
18520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    private:
18620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        static inline
18720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        void advance(region& reg, TYPE& aTop, TYPE& aBottom) {
18820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            // got to next span
18920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            size_t count = reg.count;
19020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            RECT const * rects = reg.rects;
19120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            RECT const * const end = rects + count;
19220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            const int top = rects->top;
19320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            while (rects != end && rects->top == top) {
19420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                rects++;
19520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                count--;
19620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            }
19720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            if (rects != end) {
19820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                aTop    = rects->top    + reg.dy;
19920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                aBottom = rects->bottom + reg.dy;
20020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            } else {
20120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                aTop    = max_value;
20220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                aBottom = max_value;
20320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            }
20420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            reg.rects = rects;
20520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            reg.count = count;
20620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        }
20720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    };
20820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
20920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    class SpannerInner : protected SpannerBase
21020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    {
21120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        region lhs;
21220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        region rhs;
21320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
21420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    public:
21520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        inline SpannerInner(const region& lhs, const region& rhs)
21620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            : lhs(lhs), rhs(rhs)
21720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        {
21820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        }
21920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
22020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        inline void prepare(int inside) {
22120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            SpannerBase::lhs_head = lhs.rects->left  + lhs.dx;
22220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            SpannerBase::lhs_tail = lhs.rects->right + lhs.dx;
22320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            SpannerBase::rhs_head = rhs.rects->left  + rhs.dx;
22420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            SpannerBase::rhs_tail = rhs.rects->right + rhs.dx;
22520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            if (inside == SpannerBase::lhs_before_rhs) {
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;
23120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            } else {
23220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                // use both spans
23320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            }
23420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        }
23520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
23620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        inline bool isDone() const {
23720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            return SpannerBase::lhs_head == max_value &&
23820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                   SpannerBase::rhs_head == max_value;
23920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        }
24020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
24120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        inline int next(TYPE& left, TYPE& right)
24220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        {
24320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            bool more_lhs = false;
24420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            bool more_rhs = false;
24520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            int inside = SpannerBase::next(left, right, more_lhs, more_rhs);
24620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            if (more_lhs) {
24720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                advance(lhs, SpannerBase::lhs_head, SpannerBase::lhs_tail);
24820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            }
24920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            if (more_rhs) {
25020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                advance(rhs, SpannerBase::rhs_head, SpannerBase::rhs_tail);
25120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            }
25220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            return inside;
25320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        }
25420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
25520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    private:
25620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        static inline
25720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        void advance(region& reg, TYPE& left, TYPE& right) {
25820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            if (reg.rects && reg.count) {
25920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                const int cur_span_top = reg.rects->top;
26020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                reg.rects++;
26120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                reg.count--;
26220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                if (!reg.count || reg.rects->top != cur_span_top) {
26320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    left  = max_value;
26420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    right = max_value;
26520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                } else {
26620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    left  = reg.rects->left  + reg.dx;
26720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                    right = reg.rects->right + reg.dx;
26820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian                }
26920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            }
27020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        }
27120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    };
27220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
27320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    Spanner spanner;
27420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian};
27520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
27620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian// ----------------------------------------------------------------------------
27720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian};
27820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian
27920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#endif /* ANDROID_UI_PRIVATE_REGION_HELPER_H */
280