• SkRegion


    2011-11-26/20:01:51

    http://code.google.com/p/skia/wiki/SkRegion  code.google.skia.wiki

    Skia使用SkRegion表示canvas的裁剪范围。

    SkRegion对外部不透明,但可以通过迭代器(iterator)查询。

    SkRegion可以与其他的SkRegion或者矩形(可以当做简单的region)相组合。

    只要记得数学类中的操作(如交集、并集、不同等)就会使用SkRegion.

    bool SkRegion::isEmpty();
    bool SkRegion::isRect();
    bool SkRegion::isComplex();
    

     SkRegions分类为三种:empty、rectangle、complex.

    (空、矩形、复杂)?

    所有空的SkRegion是相等的(使用操作符==)。

    相比较而言,SkRect 和SKIRect中,任何fLeft>=fRight或者fTop>=fBottom的SkRect或者SkIRect都是认为是空的,但是他们是不同的矩形,不相等。

    SkRect a = { 0, 0, 0, 0 };
    SkRect b = { 1, 1, 1, 1 };
    

     矩形a和b都是空的,但是他们被定义为不相等。但是所有空的SkRegion是相等的。

    如果你查询空SkRegion对象的范围,你总是会得到{0,0,0,0},即使你移动这个SkRegion对象,仍然是{0,0,0,0}。

    SkRegion a, b;   // regions default to empty
    assert(a == b);
    a.offset(10, 20);
    assert(a == b);
    assert(a.getBounds() == { 0, 0, 0, 0 });   // not legal C++, but you get the point
    assert(b.getBounds() == { 0, 0, 0, 0 });
    

    要初始化SkRegion,可以使用多种set函数,例如:

    SkRegion a, b;
    a.setRect(10, 10, 50, 50);
    b.setRect(rect);    // see SkIRect
    c.setPath(path);   // see SkPath
    

    上面是SkCanvas执行任意一种clip()操作的第一步,裁剪数据先转换成设备坐标(见:SkMatrix),然后用这些rect或者path的数据初始化一个SkRegion对象,最后的步骤是将这个新的SkRegion对象用指定的操作与已经存在的clip范围相结合。结合方式有:

    enum Op {
        kUnion_Op,
        kIntersect_Op,
        kDifference_Op,
        kXor_Op,
        kReverseDifference_Op,
        kReplace_Op
    };
    

    调用clip操作的时候默认执行 kIntersect_Op 操作,其他方式也是同样有效的。

    // returns true if the resulting clip is non-empty (i.e. drawing can still occur) clip区域不为空返回true,
    bool SkCanvas::clipRect(const SkRect& rect, SkRegion::Op op) {
        SkRegion rgn;
    
        // peek at the CTM (current transformation matrix on the canvas)
        const SkMatrix& m = this->getTotalMatrix();
    
        if (m.rectStaysRect()) {    // check if a transformed rect can be represented as another rect 判断矩形是否能被另一个矩形代替?(矩阵是平行矩阵?)
            SkRect deviceRect;
            m.mapRect(&deviceRect, rect);   将形参rect(SkRect类型)转化成当前canvas矩阵上的 deviceRect(SkRect类型)
            SkIRect intRect;          
            deviceRect.round(&intRect);   用deviceRect设置intRect(SkIRect类型)
            rgn.setRect(intRect);       用intRect设置rgn(SkRegion)
        } else {  // matrix rotates or skew (or is perspective)   矩阵旋转 或者 倾斜 或者是 透视矩阵?
            SkPath path;
            path.addRect(rect);            用形参rect初始化path(SkPath)
            path.transform(m);        将path用当前canvas的矩阵转换
            rgn.setPath(path);             用path设置rgn
        }
    
        // now combine the new region with the current one, using the specified *op*
        return fCurrentClip.op(rgn, op);   //用指定的合并方式op合并   新的rgn   和   canvas的当前clip区域
    }
    

      

     ezhong的博客园:http://www.cnblogs.com/ezhong/

     

  • 相关阅读:
    myeclipse6.5设置智能提示
    web项目无法编译
    Duplicate property mapping of .....
    SSH常见面试题
    简易计算器JS方式实现
    js中两个感叹号的作用
    Pro Javascript Design Patterns勘误Errata汇总(持续更新中)
    Javascript简写条件语句
    js中值得推荐的Memoization
    使用au3脚本编写自动登录126邮箱
  • 原文地址:https://www.cnblogs.com/ezhong/p/2264595.html
Copyright © 2020-2023  润新知