Home | History | Annotate | Download | only in core
      1 /*
      2  * Copyright 2017 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #include "SkClipStackDevice.h"
      9 #include "SkDraw.h"
     10 #include "SkRasterClip.h"
     11 
     12 SkIRect SkClipStackDevice::devClipBounds() const {
     13     SkIRect r = fClipStack.bounds(this->imageInfo().bounds()).roundOut();
     14     if (!r.isEmpty()) {
     15         SkASSERT(this->imageInfo().bounds().contains(r));
     16     }
     17     return r;
     18 }
     19 
     20 ///////////////////////////////////////////////////////////////////////////////////////////////////
     21 
     22 void SkClipStackDevice::onSave() {
     23     fClipStack.save();
     24 }
     25 
     26 void SkClipStackDevice::onRestore() {
     27     fClipStack.restore();
     28 }
     29 
     30 void SkClipStackDevice::onClipRect(const SkRect& rect, SkClipOp op, bool aa) {
     31     fClipStack.clipRect(rect, this->ctm(), op, aa);
     32 }
     33 
     34 void SkClipStackDevice::onClipRRect(const SkRRect& rrect, SkClipOp op, bool aa) {
     35     fClipStack.clipRRect(rrect, this->ctm(), op, aa);
     36 }
     37 
     38 void SkClipStackDevice::onClipPath(const SkPath& path, SkClipOp op, bool aa) {
     39     fClipStack.clipPath(path, this->ctm(), op, aa);
     40 }
     41 
     42 void SkClipStackDevice::onClipRegion(const SkRegion& rgn, SkClipOp op) {
     43     SkIPoint origin = this->getOrigin();
     44     SkRegion tmp;
     45     const SkRegion* ptr = &rgn;
     46     if (origin.fX | origin.fY) {
     47         // translate from "global/canvas" coordinates to relative to this device
     48         rgn.translate(-origin.fX, -origin.fY, &tmp);
     49         ptr = &tmp;
     50     }
     51     fClipStack.clipDevRect(ptr->getBounds(), op);
     52 }
     53 
     54 void SkClipStackDevice::onSetDeviceClipRestriction(SkIRect* clipRestriction) {
     55     if (clipRestriction->isEmpty()) {
     56         fClipStack.setDeviceClipRestriction(*clipRestriction);
     57     } else {
     58         SkIPoint origin = this->getOrigin();
     59         SkIRect rect = clipRestriction->makeOffset(-origin.x(), -origin.y());
     60         fClipStack.setDeviceClipRestriction(rect);
     61         fClipStack.clipDevRect(rect, SkClipOp::kIntersect);
     62     }
     63 }
     64 
     65 bool SkClipStackDevice::onClipIsAA() const {
     66     SkClipStack::B2TIter        iter(fClipStack);
     67     const SkClipStack::Element* element;
     68 
     69     while ((element = iter.next()) != nullptr) {
     70         if (element->isAA()) {
     71             return true;
     72         }
     73     }
     74     return false;
     75 }
     76 
     77 void SkClipStackDevice::onAsRgnClip(SkRegion* rgn) const {
     78     SkClipStack::BoundsType boundType;
     79     bool isIntersectionOfRects;
     80     SkRect bounds;
     81     fClipStack.getBounds(&bounds, &boundType, &isIntersectionOfRects);
     82     if (isIntersectionOfRects && SkClipStack::kNormal_BoundsType == boundType) {
     83         rgn->setRect(bounds.round());
     84     } else {
     85         SkPath path;
     86         fClipStack.asPath(&path);
     87         rgn->setPath(path, SkRegion(SkIRect::MakeWH(this->width(), this->height())));
     88     }
     89 }
     90 
     91 SkBaseDevice::ClipType SkClipStackDevice::onGetClipType() const {
     92     if (fClipStack.isWideOpen()) {
     93         return kRect_ClipType;
     94     }
     95     if (fClipStack.isEmpty(SkIRect::MakeWH(this->width(), this->height()))) {
     96         return kEmpty_ClipType;
     97     } else {
     98         SkClipStack::BoundsType boundType;
     99         bool isIntersectionOfRects;
    100         SkRect bounds;
    101         fClipStack.getBounds(&bounds, &boundType, &isIntersectionOfRects);
    102         if (isIntersectionOfRects && SkClipStack::kNormal_BoundsType == boundType) {
    103             return kRect_ClipType;
    104         } else {
    105             return kComplex_ClipType;
    106         }
    107     }
    108 }
    109