LCOV - code coverage report
Current view: top level - gfx/skia/skia/src/core - SkBitmapDevice.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 158 277 57.0 %
Date: 2017-07-14 16:53:18 Functions: 28 45 62.2 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright 2013 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 "SkBitmapDevice.h"
       9             : #include "SkDraw.h"
      10             : #include "SkImageFilter.h"
      11             : #include "SkImageFilterCache.h"
      12             : #include "SkMallocPixelRef.h"
      13             : #include "SkMatrix.h"
      14             : #include "SkPaint.h"
      15             : #include "SkPath.h"
      16             : #include "SkPixelRef.h"
      17             : #include "SkPixmap.h"
      18             : #include "SkRasterClip.h"
      19             : #include "SkRasterHandleAllocator.h"
      20             : #include "SkShader.h"
      21             : #include "SkSpecialImage.h"
      22             : #include "SkSurface.h"
      23             : #include "SkVertices.h"
      24             : 
      25             : class SkColorTable;
      26             : 
      27         107 : static bool valid_for_bitmap_device(const SkImageInfo& info,
      28             :                                     SkAlphaType* newAlphaType) {
      29         107 :     if (info.width() < 0 || info.height() < 0) {
      30           0 :         return false;
      31             :     }
      32             : 
      33             :     // TODO: can we stop supporting kUnknown in SkBitmkapDevice?
      34         107 :     if (kUnknown_SkColorType == info.colorType()) {
      35           0 :         if (newAlphaType) {
      36           0 :             *newAlphaType = kUnknown_SkAlphaType;
      37             :         }
      38           0 :         return true;
      39             :     }
      40             : 
      41         107 :     switch (info.alphaType()) {
      42             :         case kPremul_SkAlphaType:
      43             :         case kOpaque_SkAlphaType:
      44         107 :             break;
      45             :         default:
      46           0 :             return false;
      47             :     }
      48             : 
      49         107 :     SkAlphaType canonicalAlphaType = info.alphaType();
      50             : 
      51         107 :     switch (info.colorType()) {
      52             :         case kAlpha_8_SkColorType:
      53           4 :             break;
      54             :         case kRGB_565_SkColorType:
      55           0 :             canonicalAlphaType = kOpaque_SkAlphaType;
      56           0 :             break;
      57             :         case kN32_SkColorType:
      58         103 :             break;
      59             :         case kRGBA_F16_SkColorType:
      60           0 :             break;
      61             :         default:
      62           0 :             return false;
      63             :     }
      64             : 
      65         107 :     if (newAlphaType) {
      66          22 :         *newAlphaType = canonicalAlphaType;
      67             :     }
      68         107 :     return true;
      69             : }
      70             : 
      71           0 : SkBitmapDevice::SkBitmapDevice(const SkBitmap& bitmap)
      72           0 :     : INHERITED(bitmap.info(), SkSurfaceProps(SkSurfaceProps::kLegacyFontHost_InitType))
      73             :     , fBitmap(bitmap)
      74           0 :     , fRCStack(bitmap.width(), bitmap.height())
      75             : {
      76           0 :     SkASSERT(valid_for_bitmap_device(bitmap.info(), nullptr));
      77           0 :     fBitmap.lockPixels();
      78           0 : }
      79             : 
      80           0 : SkBitmapDevice* SkBitmapDevice::Create(const SkImageInfo& info) {
      81           0 :     return Create(info, SkSurfaceProps(SkSurfaceProps::kLegacyFontHost_InitType));
      82             : }
      83             : 
      84          85 : SkBitmapDevice::SkBitmapDevice(const SkBitmap& bitmap, const SkSurfaceProps& surfaceProps,
      85          85 :                                SkRasterHandleAllocator::Handle hndl)
      86             :     : INHERITED(bitmap.info(), surfaceProps)
      87             :     , fBitmap(bitmap)
      88             :     , fRasterHandle(hndl)
      89          85 :     , fRCStack(bitmap.width(), bitmap.height())
      90             : {
      91          85 :     SkASSERT(valid_for_bitmap_device(bitmap.info(), nullptr));
      92          85 :     fBitmap.lockPixels();
      93          85 : }
      94             : 
      95          22 : SkBitmapDevice* SkBitmapDevice::Create(const SkImageInfo& origInfo,
      96             :                                        const SkSurfaceProps& surfaceProps,
      97             :                                        SkRasterHandleAllocator* allocator) {
      98          22 :     SkAlphaType newAT = origInfo.alphaType();
      99          22 :     if (!valid_for_bitmap_device(origInfo, &newAT)) {
     100           0 :         return nullptr;
     101             :     }
     102             : 
     103          22 :     SkRasterHandleAllocator::Handle hndl = nullptr;
     104          44 :     const SkImageInfo info = origInfo.makeAlphaType(newAT);
     105          44 :     SkBitmap bitmap;
     106             : 
     107          22 :     if (kUnknown_SkColorType == info.colorType()) {
     108           0 :         if (!bitmap.setInfo(info)) {
     109           0 :             return nullptr;
     110             :         }
     111          22 :     } else if (allocator) {
     112           0 :         hndl = allocator->allocBitmap(info, &bitmap);
     113           0 :         if (!hndl) {
     114           0 :             return nullptr;
     115             :         }
     116          22 :     } else if (info.isOpaque()) {
     117             :         // If this bitmap is opaque, we don't have any sensible default color,
     118             :         // so we just return uninitialized pixels.
     119           3 :         if (!bitmap.tryAllocPixels(info)) {
     120           0 :             return nullptr;
     121             :         }
     122             :     } else {
     123             :         // This bitmap has transparency, so we'll zero the pixels (to transparent).
     124             :         // We use the flag as a faster alloc-then-eraseColor(SK_ColorTRANSPARENT).
     125          19 :         if (!bitmap.tryAllocPixels(info, nullptr/*colortable*/, SkBitmap::kZeroPixels_AllocFlag)) {
     126           0 :             return nullptr;
     127             :         }
     128             :     }
     129             : 
     130          22 :     return new SkBitmapDevice(bitmap, surfaceProps, hndl);
     131             : }
     132             : 
     133           0 : void SkBitmapDevice::replaceBitmapBackendForRasterSurface(const SkBitmap& bm) {
     134           0 :     SkASSERT(bm.width() == fBitmap.width());
     135           0 :     SkASSERT(bm.height() == fBitmap.height());
     136           0 :     fBitmap = bm;   // intent is to use bm's pixelRef (and rowbytes/config)
     137           0 :     fBitmap.lockPixels();
     138           0 :     this->privateResize(fBitmap.info().width(), fBitmap.info().height());
     139           0 : }
     140             : 
     141          22 : SkBaseDevice* SkBitmapDevice::onCreateDevice(const CreateInfo& cinfo, const SkPaint*) {
     142          22 :     const SkSurfaceProps surfaceProps(this->surfaceProps().flags(), cinfo.fPixelGeometry);
     143          22 :     return SkBitmapDevice::Create(cinfo.fInfo, surfaceProps, cinfo.fAllocator);
     144             : }
     145             : 
     146         473 : bool SkBitmapDevice::onAccessPixels(SkPixmap* pmap) {
     147         473 :     if (this->onPeekPixels(pmap)) {
     148         473 :         fBitmap.notifyPixelsChanged();
     149         473 :         return true;
     150             :     }
     151           0 :     return false;
     152             : }
     153             : 
     154         513 : bool SkBitmapDevice::onPeekPixels(SkPixmap* pmap) {
     155        1026 :     const SkImageInfo info = fBitmap.info();
     156         513 :     if (fBitmap.getPixels() && (kUnknown_SkColorType != info.colorType())) {
     157         513 :         SkColorTable* ctable = nullptr;
     158         513 :         pmap->reset(fBitmap.info(), fBitmap.getPixels(), fBitmap.rowBytes(), ctable);
     159         513 :         return true;
     160             :     }
     161           0 :     return false;
     162             : }
     163             : 
     164           0 : bool SkBitmapDevice::onWritePixels(const SkImageInfo& srcInfo, const void* srcPixels,
     165             :                                    size_t srcRowBytes, int x, int y) {
     166             :     // since we don't stop creating un-pixeled devices yet, check for no pixels here
     167           0 :     if (nullptr == fBitmap.getPixels()) {
     168           0 :         return false;
     169             :     }
     170             : 
     171           0 :     if (fBitmap.writePixels(SkPixmap(srcInfo, srcPixels, srcRowBytes), x, y)) {
     172           0 :         fBitmap.notifyPixelsChanged();
     173           0 :         return true;
     174             :     }
     175           0 :     return false;
     176             : }
     177             : 
     178           0 : bool SkBitmapDevice::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
     179             :                                   int x, int y) {
     180           0 :     return fBitmap.readPixels(dstInfo, dstPixels, dstRowBytes, x, y);
     181             : }
     182             : 
     183             : ///////////////////////////////////////////////////////////////////////////////
     184             : 
     185         452 : class SkBitmapDevice::BDDraw : public SkDraw {
     186             : public:
     187         452 :     BDDraw(SkBitmapDevice* dev) {
     188             :         // we need fDst to be set, and if we're actually drawing, to dirty the genID
     189         452 :         if (!dev->accessPixels(&fDst)) {
     190             :             // NoDrawDevice uses us (why?) so we have to catch this case w/ no pixels
     191           0 :             fDst.reset(dev->imageInfo(), nullptr, 0);
     192             :         }
     193         452 :         fMatrix = &dev->ctm();
     194         452 :         fRC = &dev->fRCStack.rc();
     195         452 :     }
     196             : };
     197             : 
     198          17 : void SkBitmapDevice::drawPaint(const SkPaint& paint) {
     199          17 :     BDDraw(this).drawPaint(paint);
     200          17 : }
     201             : 
     202          13 : void SkBitmapDevice::drawPoints(SkCanvas::PointMode mode, size_t count,
     203             :                                 const SkPoint pts[], const SkPaint& paint) {
     204          13 :     BDDraw(this).drawPoints(mode, count, pts, paint, nullptr);
     205          13 : }
     206             : 
     207         188 : void SkBitmapDevice::drawRect(const SkRect& r, const SkPaint& paint) {
     208         188 :     BDDraw(this).drawRect(r, paint);
     209         188 : }
     210             : 
     211           0 : void SkBitmapDevice::drawOval(const SkRect& oval, const SkPaint& paint) {
     212           0 :     SkPath path;
     213           0 :     path.addOval(oval);
     214             :     // call the VIRTUAL version, so any subclasses who do handle drawPath aren't
     215             :     // required to override drawOval.
     216           0 :     this->drawPath(path, paint, nullptr, true);
     217           0 : }
     218             : 
     219           0 : void SkBitmapDevice::drawRRect(const SkRRect& rrect, const SkPaint& paint) {
     220             : #ifdef SK_IGNORE_BLURRED_RRECT_OPT
     221             :     SkPath  path;
     222             : 
     223             :     path.addRRect(rrect);
     224             :     // call the VIRTUAL version, so any subclasses who do handle drawPath aren't
     225             :     // required to override drawRRect.
     226             :     this->drawPath(path, paint, nullptr, true);
     227             : #else
     228           0 :     BDDraw(this).drawRRect(rrect, paint);
     229             : #endif
     230           0 : }
     231             : 
     232          61 : void SkBitmapDevice::drawPath(const SkPath& path,
     233             :                               const SkPaint& paint, const SkMatrix* prePathMatrix,
     234             :                               bool pathIsMutable) {
     235          61 :     BDDraw(this).drawPath(path, paint, prePathMatrix, pathIsMutable);
     236          61 : }
     237             : 
     238           4 : void SkBitmapDevice::drawBitmap(const SkBitmap& bitmap,
     239             :                                 const SkMatrix& matrix, const SkPaint& paint) {
     240           4 :     LogDrawScaleFactor(SkMatrix::Concat(this->ctm(), matrix), paint.getFilterQuality());
     241           4 :     BDDraw(this).drawBitmap(bitmap, matrix, nullptr, paint);
     242           4 : }
     243             : 
     244         126 : static inline bool CanApplyDstMatrixAsCTM(const SkMatrix& m, const SkPaint& paint) {
     245         126 :     if (!paint.getMaskFilter()) {
     246         126 :         return true;
     247             :     }
     248             : 
     249             :     // Some mask filters parameters (sigma) depend on the CTM/scale.
     250           0 :     return m.getType() <= SkMatrix::kTranslate_Mask;
     251             : }
     252             : 
     253         140 : void SkBitmapDevice::drawBitmapRect(const SkBitmap& bitmap,
     254             :                                     const SkRect* src, const SkRect& dst,
     255             :                                     const SkPaint& paint, SkCanvas::SrcRectConstraint constraint) {
     256             :     SkMatrix    matrix;
     257             :     SkRect      bitmapBounds, tmpSrc, tmpDst;
     258         154 :     SkBitmap    tmpBitmap;
     259             : 
     260         140 :     bitmapBounds.isetWH(bitmap.width(), bitmap.height());
     261             : 
     262             :     // Compute matrix from the two rectangles
     263         140 :     if (src) {
     264         140 :         tmpSrc = *src;
     265             :     } else {
     266           0 :         tmpSrc = bitmapBounds;
     267             :     }
     268         140 :     matrix.setRectToRect(tmpSrc, dst, SkMatrix::kFill_ScaleToFit);
     269             : 
     270         140 :     LogDrawScaleFactor(SkMatrix::Concat(this->ctm(), matrix), paint.getFilterQuality());
     271             : 
     272         140 :     const SkRect* dstPtr = &dst;
     273         140 :     const SkBitmap* bitmapPtr = &bitmap;
     274             : 
     275             :     // clip the tmpSrc to the bounds of the bitmap, and recompute dstRect if
     276             :     // needed (if the src was clipped). No check needed if src==null.
     277         140 :     if (src) {
     278         140 :         if (!bitmapBounds.contains(*src)) {
     279           0 :             if (!tmpSrc.intersect(bitmapBounds)) {
     280           0 :                 return; // nothing to draw
     281             :             }
     282             :             // recompute dst, based on the smaller tmpSrc
     283           0 :             matrix.mapRect(&tmpDst, tmpSrc);
     284           0 :             dstPtr = &tmpDst;
     285             :         }
     286             :     }
     287             : 
     288         280 :     if (src && !src->contains(bitmapBounds) &&
     289         140 :         SkCanvas::kFast_SrcRectConstraint == constraint &&
     290           0 :         paint.getFilterQuality() != kNone_SkFilterQuality) {
     291             :         // src is smaller than the bounds of the bitmap, and we are filtering, so we don't know
     292             :         // how much more of the bitmap we need, so we can't use extractSubset or drawBitmap,
     293             :         // but we must use a shader w/ dst bounds (which can access all of the bitmap needed).
     294           0 :         goto USE_SHADER;
     295             :     }
     296             : 
     297         140 :     if (src) {
     298             :         // since we may need to clamp to the borders of the src rect within
     299             :         // the bitmap, we extract a subset.
     300         140 :         const SkIRect srcIR = tmpSrc.roundOut();
     301         140 :         if (!bitmap.extractSubset(&tmpBitmap, srcIR)) {
     302           0 :             return;
     303             :         }
     304         140 :         bitmapPtr = &tmpBitmap;
     305             : 
     306             :         // Since we did an extract, we need to adjust the matrix accordingly
     307         140 :         SkScalar dx = 0, dy = 0;
     308         140 :         if (srcIR.fLeft > 0) {
     309          12 :             dx = SkIntToScalar(srcIR.fLeft);
     310             :         }
     311         140 :         if (srcIR.fTop > 0) {
     312          12 :             dy = SkIntToScalar(srcIR.fTop);
     313             :         }
     314         140 :         if (dx || dy) {
     315          14 :             matrix.preTranslate(dx, dy);
     316             :         }
     317             : 
     318             : #ifdef SK_DRAWBITMAPRECT_FAST_OFFSET
     319             :         SkRect extractedBitmapBounds = SkRect::MakeXYWH(dx, dy,
     320             :                                                         SkIntToScalar(bitmapPtr->width()),
     321             :                                                         SkIntToScalar(bitmapPtr->height()));
     322             : #else
     323             :         SkRect extractedBitmapBounds;
     324         140 :         extractedBitmapBounds.isetWH(bitmapPtr->width(), bitmapPtr->height());
     325             : #endif
     326         140 :         if (extractedBitmapBounds == tmpSrc) {
     327             :             // no fractional part in src, we can just call drawBitmap
     328         126 :             goto USE_DRAWBITMAP;
     329             :         }
     330             :     } else {
     331             :         USE_DRAWBITMAP:
     332             :         // We can go faster by just calling drawBitmap, which will concat the
     333             :         // matrix with the CTM, and try to call drawSprite if it can. If not,
     334             :         // it will make a shader and call drawRect, as we do below.
     335         126 :         if (CanApplyDstMatrixAsCTM(matrix, paint)) {
     336         126 :             BDDraw(this).drawBitmap(*bitmapPtr, matrix, dstPtr, paint);
     337         126 :             return;
     338             :         }
     339             :     }
     340             : 
     341             :     USE_SHADER:
     342             : 
     343             :     // TODO(herb): Move this over to SkArenaAlloc when arena alloc has a facility to return sk_sps.
     344             :     // Since the shader need only live for our stack-frame, pass in a custom allocator. This
     345             :     // can save malloc calls, and signals to SkMakeBitmapShader to not try to copy the bitmap
     346             :     // if its mutable, since that precaution is not needed (give the short lifetime of the shader).
     347             : 
     348             :     // construct a shader, so we can call drawRect with the dst
     349             :     auto s = SkMakeBitmapShader(*bitmapPtr, SkShader::kClamp_TileMode, SkShader::kClamp_TileMode,
     350          28 :                                 &matrix, kNever_SkCopyPixelsMode);
     351          14 :     if (!s) {
     352           0 :         return;
     353             :     }
     354             : 
     355          28 :     SkPaint paintWithShader(paint);
     356          14 :     paintWithShader.setStyle(SkPaint::kFill_Style);
     357          14 :     paintWithShader.setShader(s);
     358             : 
     359             :     // Call ourself, in case the subclass wanted to share this setup code
     360             :     // but handle the drawRect code themselves.
     361          14 :     this->drawRect(*dstPtr, paintWithShader);
     362             : }
     363             : 
     364           3 : void SkBitmapDevice::drawSprite(const SkBitmap& bitmap, int x, int y, const SkPaint& paint) {
     365           3 :     BDDraw(this).drawSprite(bitmap, x, y, paint);
     366           3 : }
     367             : 
     368           0 : void SkBitmapDevice::drawText(const void* text, size_t len,
     369             :                               SkScalar x, SkScalar y, const SkPaint& paint) {
     370           0 :     BDDraw(this).drawText((const char*)text, len, x, y, paint, &fSurfaceProps);
     371           0 : }
     372             : 
     373          21 : void SkBitmapDevice::drawPosText(const void* text, size_t len, const SkScalar xpos[],
     374             :                                  int scalarsPerPos, const SkPoint& offset, const SkPaint& paint) {
     375          42 :     BDDraw(this).drawPosText((const char*)text, len, xpos, scalarsPerPos, offset, paint,
     376          21 :                              &fSurfaceProps);
     377          21 : }
     378             : 
     379           0 : void SkBitmapDevice::drawVertices(const SkVertices* vertices, SkBlendMode bmode,
     380             :                                   const SkPaint& paint) {
     381           0 :     BDDraw(this).drawVertices(vertices->mode(), vertices->vertexCount(), vertices->positions(),
     382             :                               vertices->texCoords(), vertices->colors(), bmode,
     383           0 :                               vertices->indices(), vertices->indexCount(), paint);
     384           0 : }
     385             : 
     386          19 : void SkBitmapDevice::drawDevice(SkBaseDevice* device, int x, int y, const SkPaint& paint) {
     387          19 :     SkASSERT(!paint.getImageFilter());
     388          19 :     BDDraw(this).drawSprite(static_cast<SkBitmapDevice*>(device)->fBitmap, x, y, paint);
     389          19 : }
     390             : 
     391             : ///////////////////////////////////////////////////////////////////////////////
     392             : 
     393           3 : void SkBitmapDevice::drawSpecial(SkSpecialImage* srcImg, int x, int y,
     394             :                                  const SkPaint& paint) {
     395           3 :     SkASSERT(!srcImg->isTextureBacked());
     396             : 
     397           6 :     SkBitmap resultBM;
     398             : 
     399           3 :     SkImageFilter* filter = paint.getImageFilter();
     400           3 :     if (filter) {
     401           0 :         SkIPoint offset = SkIPoint::Make(0, 0);
     402           0 :         SkMatrix matrix = this->ctm();
     403           0 :         matrix.postTranslate(SkIntToScalar(-x), SkIntToScalar(-y));
     404           0 :         const SkIRect clipBounds = fRCStack.rc().getBounds().makeOffset(-x, -y);
     405           0 :         sk_sp<SkImageFilterCache> cache(this->getImageFilterCache());
     406           0 :         SkImageFilter::OutputProperties outputProperties(fBitmap.colorSpace());
     407           0 :         SkImageFilter::Context ctx(matrix, clipBounds, cache.get(), outputProperties);
     408             : 
     409           0 :         sk_sp<SkSpecialImage> resultImg(filter->filterImage(srcImg, ctx, &offset));
     410           0 :         if (resultImg) {
     411           0 :             SkPaint tmpUnfiltered(paint);
     412           0 :             tmpUnfiltered.setImageFilter(nullptr);
     413           0 :             if (resultImg->getROPixels(&resultBM)) {
     414           0 :                 this->drawSprite(resultBM, x + offset.x(), y + offset.y(), tmpUnfiltered);
     415             :             }
     416             :         }
     417             :     } else {
     418           3 :         if (srcImg->getROPixels(&resultBM)) {
     419           3 :             this->drawSprite(resultBM, x, y, paint);
     420             :         }
     421             :     }
     422           3 : }
     423             : 
     424           3 : sk_sp<SkSpecialImage> SkBitmapDevice::makeSpecial(const SkBitmap& bitmap) {
     425           3 :     return SkSpecialImage::MakeFromRaster(bitmap.bounds(), bitmap);
     426             : }
     427             : 
     428           0 : sk_sp<SkSpecialImage> SkBitmapDevice::makeSpecial(const SkImage* image) {
     429           0 :     return SkSpecialImage::MakeFromImage(SkIRect::MakeWH(image->width(), image->height()),
     430           0 :                                          image->makeNonTextureImage(), fBitmap.colorSpace());
     431             : }
     432             : 
     433           3 : sk_sp<SkSpecialImage> SkBitmapDevice::snapSpecial() {
     434           3 :     return this->makeSpecial(fBitmap);
     435             : }
     436             : 
     437             : ///////////////////////////////////////////////////////////////////////////////
     438             : 
     439           0 : sk_sp<SkSurface> SkBitmapDevice::makeSurface(const SkImageInfo& info, const SkSurfaceProps& props) {
     440           0 :     return SkSurface::MakeRaster(info, &props);
     441             : }
     442             : 
     443           0 : SkImageFilterCache* SkBitmapDevice::getImageFilterCache() {
     444           0 :     SkImageFilterCache* cache = SkImageFilterCache::Get();
     445           0 :     cache->ref();
     446           0 :     return cache;
     447             : }
     448             : 
     449             : ///////////////////////////////////////////////////////////////////////////////////////////////////
     450             : 
     451          21 : bool SkBitmapDevice::onShouldDisableLCD(const SkPaint& paint) const {
     452          63 :     if (kN32_SkColorType != fBitmap.colorType() ||
     453          42 :         paint.getRasterizer() ||
     454          42 :         paint.getPathEffect() ||
     455          42 :         paint.isFakeBoldText() ||
     456          63 :         paint.getStyle() != SkPaint::kFill_Style ||
     457          21 :         !paint.isSrcOver())
     458             :     {
     459           0 :         return true;
     460             :     }
     461          21 :     return false;
     462             : }
     463             : 
     464             : ///////////////////////////////////////////////////////////////////////////////////////////////////
     465             : 
     466         617 : void SkBitmapDevice::onSave() {
     467         617 :     fRCStack.save();
     468         617 : }
     469             : 
     470         617 : void SkBitmapDevice::onRestore() {
     471         617 :     fRCStack.restore();
     472         617 : }
     473             : 
     474         532 : void SkBitmapDevice::onClipRect(const SkRect& rect, SkClipOp op, bool aa) {
     475         532 :     fRCStack.clipRect(this->ctm(), rect, op, aa);
     476         532 : }
     477             : 
     478           0 : void SkBitmapDevice::onClipRRect(const SkRRect& rrect, SkClipOp op, bool aa) {
     479           0 :     fRCStack.clipRRect(this->ctm(), rrect, op, aa);
     480           0 : }
     481             : 
     482          39 : void SkBitmapDevice::onClipPath(const SkPath& path, SkClipOp op, bool aa) {
     483          39 :     fRCStack.clipPath(this->ctm(), path, op, aa);
     484          39 : }
     485             : 
     486          24 : void SkBitmapDevice::onClipRegion(const SkRegion& rgn, SkClipOp op) {
     487          24 :     SkIPoint origin = this->getOrigin();
     488          48 :     SkRegion tmp;
     489          24 :     const SkRegion* ptr = &rgn;
     490          24 :     if (origin.fX | origin.fY) {
     491             :         // translate from "global/canvas" coordinates to relative to this device
     492           0 :         rgn.translate(-origin.fX, -origin.fY, &tmp);
     493           0 :         ptr = &tmp;
     494             :     }
     495          24 :     fRCStack.clipRegion(*ptr, op);
     496          24 : }
     497             : 
     498          85 : void SkBitmapDevice::onSetDeviceClipRestriction(SkIRect* mutableClipRestriction) {
     499          85 :     fRCStack.setDeviceClipRestriction(mutableClipRestriction);
     500          85 :     if (!mutableClipRestriction->isEmpty()) {
     501           0 :         SkRegion rgn(*mutableClipRestriction);
     502           0 :         fRCStack.clipRegion(rgn, SkClipOp::kIntersect);
     503             :     }
     504          85 : }
     505             : 
     506           0 : bool SkBitmapDevice::onClipIsAA() const {
     507           0 :     const SkRasterClip& rc = fRCStack.rc();
     508           0 :     return !rc.isEmpty() && rc.isAA();
     509             : }
     510             : 
     511           0 : void SkBitmapDevice::onAsRgnClip(SkRegion* rgn) const {
     512           0 :     const SkRasterClip& rc = fRCStack.rc();
     513           0 :     if (rc.isAA()) {
     514           0 :         rgn->setRect(rc.getBounds());
     515             :     } else {
     516           0 :         *rgn = rc.bwRgn();
     517             :     }
     518           0 : }
     519             : 
     520           0 : void SkBitmapDevice::validateDevBounds(const SkIRect& drawClipBounds) {
     521             : #ifdef SK_DEBUG
     522           0 :     const SkIRect& stackBounds = fRCStack.rc().getBounds();
     523           0 :     SkASSERT(drawClipBounds == stackBounds);
     524             : #endif
     525           0 : }
     526             : 
     527           0 : SkBaseDevice::ClipType SkBitmapDevice::onGetClipType() const {
     528           0 :     const SkRasterClip& rc = fRCStack.rc();
     529           0 :     if (rc.isEmpty()) {
     530           0 :         return kEmpty_ClipType;
     531           0 :     } else if (rc.isRect()) {
     532           0 :         return kRect_ClipType;
     533             :     } else {
     534           0 :         return kComplex_ClipType;
     535             :     }
     536             : }

Generated by: LCOV version 1.13