diff options
Diffstat (limited to 'include/private/ui/RegionHelper.h')
-rw-r--r-- | include/private/ui/RegionHelper.h | 284 |
1 files changed, 0 insertions, 284 deletions
diff --git a/include/private/ui/RegionHelper.h b/include/private/ui/RegionHelper.h deleted file mode 100644 index 8d76533..0000000 --- a/include/private/ui/RegionHelper.h +++ /dev/null @@ -1,284 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_UI_PRIVATE_REGION_HELPER_H -#define ANDROID_UI_PRIVATE_REGION_HELPER_H - -#include <stdint.h> -#include <sys/types.h> - -namespace android { -// ---------------------------------------------------------------------------- - -template<typename RECT> -class region_operator -{ - typedef typename RECT::value_type TYPE; - static const TYPE max_value = 0x7FFFFFF; - -public: - /* - * Common boolean operations: - * value is computed as 0b101 op 0b110 - * other boolean operation are possible, simply compute - * their corresponding value with the above formulae and use - * it when instantiating a region_operator. - */ - static const uint32_t LHS = 0x5; // 0b101 - static const uint32_t RHS = 0x6; // 0b110 - enum { - op_nand = LHS & ~RHS, - op_and = LHS & RHS, - op_or = LHS | RHS, - op_xor = LHS ^ RHS - }; - - struct region { - RECT const* rects; - size_t count; - TYPE dx; - TYPE dy; - inline region(const region& rhs) - : rects(rhs.rects), count(rhs.count), dx(rhs.dx), dy(rhs.dy) { } - inline region(RECT const* r, size_t c) - : rects(r), count(c), dx(), dy() { } - inline region(RECT const* r, size_t c, TYPE dx, TYPE dy) - : rects(r), count(c), dx(dx), dy(dy) { } - }; - - class region_rasterizer { - friend class region_operator; - virtual void operator()(const RECT& rect) = 0; - public: - virtual ~region_rasterizer() { }; - }; - - inline region_operator(int op, const region& lhs, const region& rhs) - : op_mask(op), spanner(lhs, rhs) - { - } - - void operator()(region_rasterizer& rasterizer) { - RECT current; - do { - SpannerInner spannerInner(spanner.lhs, spanner.rhs); - int inside = spanner.next(current.top, current.bottom); - spannerInner.prepare(inside); - do { - TYPE left, right; - int inside = spannerInner.next(current.left, current.right); - if ((op_mask >> inside) & 1) { - if (current.left < current.right && - current.top < current.bottom) { - rasterizer(current); - } - } - } while(!spannerInner.isDone()); - } while(!spanner.isDone()); - } - -private: - uint32_t op_mask; - - class SpannerBase - { - public: - enum { - lhs_before_rhs = 0, - lhs_after_rhs = 1, - lhs_coincide_rhs = 2 - }; - - protected: - TYPE lhs_head; - TYPE lhs_tail; - TYPE rhs_head; - TYPE rhs_tail; - - inline int next(TYPE& head, TYPE& tail, - bool& more_lhs, bool& more_rhs) - { - int inside; - more_lhs = false; - more_rhs = false; - if (lhs_head < rhs_head) { - inside = lhs_before_rhs; - head = lhs_head; - if (lhs_tail <= rhs_head) { - tail = lhs_tail; - more_lhs = true; - } else { - lhs_head = rhs_head; - tail = rhs_head; - } - } else if (rhs_head < lhs_head) { - inside = lhs_after_rhs; - head = rhs_head; - if (rhs_tail <= lhs_head) { - tail = rhs_tail; - more_rhs = true; - } else { - rhs_head = lhs_head; - tail = lhs_head; - } - } else { - inside = lhs_coincide_rhs; - head = lhs_head; - if (lhs_tail <= rhs_tail) { - tail = rhs_head = lhs_tail; - more_lhs = true; - } - if (rhs_tail <= lhs_tail) { - tail = lhs_head = rhs_tail; - more_rhs = true; - } - } - return inside; - } - }; - - class Spanner : protected SpannerBase - { - friend class region_operator; - region lhs; - region rhs; - - public: - inline Spanner(const region& lhs, const region& rhs) - : lhs(lhs), rhs(rhs) - { - SpannerBase::lhs_head = lhs.rects->top + lhs.dy; - SpannerBase::lhs_tail = lhs.rects->bottom + lhs.dy; - SpannerBase::rhs_head = rhs.rects->top + rhs.dy; - SpannerBase::rhs_tail = rhs.rects->bottom + rhs.dy; - } - - inline bool isDone() const { - return !rhs.count && !lhs.count; - } - - inline int next(TYPE& top, TYPE& bottom) - { - bool more_lhs = false; - bool more_rhs = false; - int inside = SpannerBase::next(top, bottom, more_lhs, more_rhs); - if (more_lhs) { - advance(lhs, SpannerBase::lhs_head, SpannerBase::lhs_tail); - } - if (more_rhs) { - advance(rhs, SpannerBase::rhs_head, SpannerBase::rhs_tail); - } - return inside; - } - - private: - static inline - void advance(region& reg, TYPE& aTop, TYPE& aBottom) { - // got to next span - size_t count = reg.count; - RECT const * rects = reg.rects; - RECT const * const end = rects + count; - const int top = rects->top; - while (rects != end && rects->top == top) { - rects++; - count--; - } - if (rects != end) { - aTop = rects->top + reg.dy; - aBottom = rects->bottom + reg.dy; - } else { - aTop = max_value; - aBottom = max_value; - } - reg.rects = rects; - reg.count = count; - } - }; - - class SpannerInner : protected SpannerBase - { - region lhs; - region rhs; - - public: - inline SpannerInner(const region& lhs, const region& rhs) - : lhs(lhs), rhs(rhs) - { - } - - inline void prepare(int inside) { - if (inside == SpannerBase::lhs_before_rhs) { - SpannerBase::lhs_head = lhs.rects->left + lhs.dx; - SpannerBase::lhs_tail = lhs.rects->right + lhs.dx; - SpannerBase::rhs_head = max_value; - SpannerBase::rhs_tail = max_value; - } else if (inside == SpannerBase::lhs_after_rhs) { - SpannerBase::lhs_head = max_value; - SpannerBase::lhs_tail = max_value; - SpannerBase::rhs_head = rhs.rects->left + rhs.dx; - SpannerBase::rhs_tail = rhs.rects->right + rhs.dx; - } else { - SpannerBase::lhs_head = lhs.rects->left + lhs.dx; - SpannerBase::lhs_tail = lhs.rects->right + lhs.dx; - SpannerBase::rhs_head = rhs.rects->left + rhs.dx; - SpannerBase::rhs_tail = rhs.rects->right + rhs.dx; - } - } - - inline bool isDone() const { - return SpannerBase::lhs_head == max_value && - SpannerBase::rhs_head == max_value; - } - - inline int next(TYPE& left, TYPE& right) - { - bool more_lhs = false; - bool more_rhs = false; - int inside = SpannerBase::next(left, right, more_lhs, more_rhs); - if (more_lhs) { - advance(lhs, SpannerBase::lhs_head, SpannerBase::lhs_tail); - } - if (more_rhs) { - advance(rhs, SpannerBase::rhs_head, SpannerBase::rhs_tail); - } - return inside; - } - - private: - static inline - void advance(region& reg, TYPE& left, TYPE& right) { - if (reg.rects && reg.count) { - const int cur_span_top = reg.rects->top; - reg.rects++; - reg.count--; - if (!reg.count || reg.rects->top != cur_span_top) { - left = max_value; - right = max_value; - } else { - left = reg.rects->left + reg.dx; - right = reg.rects->right + reg.dx; - } - } - } - }; - - Spanner spanner; -}; - -// ---------------------------------------------------------------------------- -}; - -#endif /* ANDROID_UI_PRIVATE_REGION_HELPER_H */ |