/* * Copyright 2013 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "include/core/SkCanvas.h" #include "include/core/SkMatrix.h" #include "include/core/SkPaint.h" #include "include/core/SkRect.h" #include "src/base/SkArenaAlloc.h" #ifdef SK_SUPPORT_LEGACY_DRAWLOOPER #include "include/core/SkDrawLooper.h" void SkDrawLooper::Context::Info::applyToCTM(SkMatrix* ctm) const { if (fApplyPostCTM) { ctm->postTranslate(fTranslate.fX, fTranslate.fY); } else { ctm->preTranslate(fTranslate.fX, fTranslate.fY); } } void SkDrawLooper::Context::Info::applyToCanvas(SkCanvas* canvas) const { if (fApplyPostCTM) { canvas->setMatrix(canvas->getLocalToDevice().postTranslate(fTranslate.fX, fTranslate.fY)); } else { canvas->translate(fTranslate.fX, fTranslate.fY); } } bool SkDrawLooper::canComputeFastBounds(const SkPaint& paint) const { SkSTArenaAlloc<48> alloc; SkDrawLooper::Context* context = this->makeContext(&alloc); for (;;) { SkPaint p(paint); SkDrawLooper::Context::Info info; if (context->next(&info, &p)) { if (!p.canComputeFastBounds()) { return false; } } else { break; } } return true; } void SkDrawLooper::computeFastBounds(const SkPaint& paint, const SkRect& s, SkRect* dst) const { // src and dst rects may alias and we need to keep the original src, so copy it. const SkRect src = s; SkSTArenaAlloc<48> alloc; *dst = src; // catch case where there are no loops SkDrawLooper::Context* context = this->makeContext(&alloc); for (bool firstTime = true;; firstTime = false) { SkPaint p(paint); SkDrawLooper::Context::Info info; if (context->next(&info, &p)) { SkRect r(src); p.computeFastBounds(r, &r); r.offset(info.fTranslate.fX, info.fTranslate.fY); if (firstTime) { *dst = r; } else { dst->join(r); } } else { break; } } } bool SkDrawLooper::asABlurShadow(BlurShadowRec*) const { return false; } void SkDrawLooper::apply(SkCanvas* canvas, const SkPaint& paint, std::function proc) { SkSTArenaAlloc<256> alloc; Context* ctx = this->makeContext(&alloc); if (ctx) { Context::Info info; for (;;) { SkPaint p = paint; if (!ctx->next(&info, &p)) { break; } canvas->save(); if (info.fApplyPostCTM) { canvas->setMatrix(canvas->getLocalToDevice().postTranslate(info.fTranslate.fX, info.fTranslate.fY)); } else { canvas->translate(info.fTranslate.fX, info.fTranslate.fY); } proc(canvas, p); canvas->restore(); } } } #endif