• 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/

     

  • 相关阅读:
    win7下php7.1运行getenv('REMOTE_ADDR')fastcgi停止运行
    Laravel 单设备登录
    CGI与FastCGI
    一起谈.NET技术,c#数据库存取图片的三种方式 狼人:
    一起谈.NET技术,ASP.NET的状态管理 狼人:
    一起谈.NET技术,Visual Studio 2010层架构验证的实现 狼人:
    一起谈.NET技术,4.0中的并行计算和多线程详解(二) 狼人:
    一起谈.NET技术,利用Visual Studio 2010流程模板实现Scrum敏捷开发 狼人:
    一起谈.NET技术,ASP.NET 安全漏洞临时解决方案 狼人:
    一起谈.NET技术,初识Silverlight 4及其架构 狼人:
  • 原文地址:https://www.cnblogs.com/ezhong/p/2264595.html
Copyright © 2020-2023  润新知