Android Region代码分析

本文深入探讨了Android中的Region概念,它由一个或多个Rect组成,Region的合法性涉及Rect的排序和边界检查。文章详细分析了Region的合法性验证,包括Rect的合法性、排序和Span的检查。此外,还介绍了Region的布尔操作,如op_or,并通过源码解析了操作过程。最后,讨论了T-Junction问题及其消除策略,以避免渲染中的图形异常。通过测试验证了理论分析的准确性。
摘要由CSDN通过智能技术生成

一、Region的定义和合法性检查

Android系统中,定义了Region的概念,它代表屏幕上的一个区域,它是由一个或多个Rect组成的,代码位于frameworks/native/libs/ui/Region.cpp。而Rect则代表屏幕上的一个方形区域,这个区域可能是不可见的,部分可见或者完全不可见的。从代码实现的角度来看Region的实现,它拥有一个私有的数据成员变量:mStorage,它的类型为Vector<Rect>

1. mStorage是一个有序数组,数组元素类型为Rect,除了包含构成Region区域的Rect外,还额外地包含一个元素,它就是这块区域的边界。

2. 如果Region只是一个简单的方形区域,则mStorage只包含这个Rect类型的元素。

从上述两点可知,mStorge的大小永远不可能为2,要想知道某个区域的边界大小,只需返回mStorage的最后一个元素。

3. RectRegion的关系是is-a关系,反之则不成立。

 inline  bool        isEmpty() const     { return getBounds().isEmpty(); }
    inline  bool        isRect() const      { return mStorage.size() == 1; }

    inline  Rect        getBounds() const   { return mStorage[mStorage.size() - 1]; }
    inline  Rect        bounds() const      { return getBounds(); }

接下来研究的话题是Region的合法性。由于Region本身是由一系列Rect组成的,所以,首先,构成的Rect本身必须是合法的。其次,构成的Rect必须以Y方向和X方向排序,Y方向优先排序。这里引入另一个概念Span,它也是一个区域的概念,也是由一个或多个Rect组成,可以认为它是一种特殊的Region, 其本身也是构成Region的一部分,事实上,一个Region可以看成是由许多Span构成的。不过这些构成SpanRect必须在Y方向上,topbottom值与其他的Rect相同,即Y方向上不能重叠,在X上方向,leftright之间的覆盖的区域不能与其他的Rect之间有重叠。基于上述的描述,要检查一个Region是否合法,就要对上述的一些要求做检查,我们可以看Regionvalidate()函数,它实际上就是这样做的:

1. 首先检查构成RegionRect本身的合法性。

...
        if (cur->isValid() == false) {
            ALOGE_IF(!silent, "%s: region contains an invalid Rect", name);
            result = false;
        }
        if (cur->right > region_operator<Rect>::max_value) {
            ALOGE_IF(!silent, "%s: rect->right > max_value", name);
            result = false;
        }
        if (cur->bottom > region_operator<Rect>::max_value) {
            ALOGE_IF(!silent, "%s: rect->right > max_value", name);
            result = false;
        }
...

2. 接下来,检查这些Rect是否是有序的。

            if ((*prev < *cur) == false) {
                ALOGE_IF(!silent, "%s: region's Rects not sorted", name);
                result = false;
            }

3. 然后就是检查Span的合法性

          if (cur->top == prev->top) {
                if (cur->bottom != prev->bottom) {
                    ALOGE_IF(!silent, "%s: invalid span %p", name, cur);
                    result = false;
                } else if (cur->left < prev->right) {
                    ALOGE_IF(!silent,
                            "%s: spans overlap horizontally prev=%p, cur=%p",
                            name, prev, cur);
                    result = false;
                }
            } else if (cur->top < prev->bottom) {
                ALOGE_IF(!silent,
                        "%s: spans overlap vertically prev&
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值