1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2006 The Android Open Source Project 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */ 8ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkMaskFilter.h" 118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkBlitter.h" 128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkDraw.h" 13b0df8be137d8fb49436e46d1fd1a5aec8b7ab562reed#include "SkCachedData.h" 14045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com#include "SkRasterClip.h" 15a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com#include "SkRRect.h" 16491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com#include "SkTypes.h" 178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 180b82852b234753257835bf1f9ac0046848a283ecrobertphillips@google.com#if SK_SUPPORT_GPU 190b82852b234753257835bf1f9ac0046848a283ecrobertphillips@google.com#include "GrTexture.h" 200b82852b234753257835bf1f9ac0046848a283ecrobertphillips@google.com#include "SkGr.h" 210b82852b234753257835bf1f9ac0046848a283ecrobertphillips@google.com#include "SkGrPixelRef.h" 220b82852b234753257835bf1f9ac0046848a283ecrobertphillips@google.com#endif 23d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com 24b0df8be137d8fb49436e46d1fd1a5aec8b7ab562reedSkMaskFilter::NinePatch::~NinePatch() { 25b0df8be137d8fb49436e46d1fd1a5aec8b7ab562reed if (fCache) { 26b0df8be137d8fb49436e46d1fd1a5aec8b7ab562reed SkASSERT((const void*)fMask.fImage == fCache->data()); 27b0df8be137d8fb49436e46d1fd1a5aec8b7ab562reed fCache->unref(); 28b0df8be137d8fb49436e46d1fd1a5aec8b7ab562reed } else { 29b0df8be137d8fb49436e46d1fd1a5aec8b7ab562reed SkMask::FreeImage(fMask.fImage); 30b0df8be137d8fb49436e46d1fd1a5aec8b7ab562reed } 31b0df8be137d8fb49436e46d1fd1a5aec8b7ab562reed} 32b0df8be137d8fb49436e46d1fd1a5aec8b7ab562reed 33feb8cc870df055099c6fcdfebdd6c1486bd91b27reed@google.combool SkMaskFilter::filterMask(SkMask*, const SkMask&, const SkMatrix&, 3430711b764be6bbb58caa30a0ac5d1474c894efe7reed@google.com SkIPoint*) const { 358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 38daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.combool SkMaskFilter::asABlur(BlurRec*) const { 39daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com return false; 40daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com} 41daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com 42d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.comstatic void extractMaskSubset(const SkMask& src, SkMask* dst) { 43d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com SkASSERT(src.fBounds.contains(dst->fBounds)); 44d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com 45d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com const int dx = dst->fBounds.left() - src.fBounds.left(); 46d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com const int dy = dst->fBounds.top() - src.fBounds.top(); 47d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com dst->fImage = src.fImage + dy * src.fRowBytes + dx; 48d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com dst->fRowBytes = src.fRowBytes; 49d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com dst->fFormat = src.fFormat; 50d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com} 51d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com 52d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.comstatic void blitClippedMask(SkBlitter* blitter, const SkMask& mask, 53d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com const SkIRect& bounds, const SkIRect& clipR) { 54d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com SkIRect r; 55d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com if (r.intersect(bounds, clipR)) { 56d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com blitter->blitMask(mask, r); 57d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com } 58d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com} 59d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com 60d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.comstatic void blitClippedRect(SkBlitter* blitter, const SkIRect& rect, const SkIRect& clipR) { 61d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com SkIRect r; 62d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com if (r.intersect(rect, clipR)) { 63d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com blitter->blitRect(r.left(), r.top(), r.width(), r.height()); 64d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com } 65d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com} 66d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com 67d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com#if 0 68d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.comstatic void dump(const SkMask& mask) { 69d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com for (int y = mask.fBounds.top(); y < mask.fBounds.bottom(); ++y) { 70d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com for (int x = mask.fBounds.left(); x < mask.fBounds.right(); ++x) { 71d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com SkDebugf("%02X", *mask.getAddr8(x, y)); 72d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com } 73d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com SkDebugf("\n"); 74d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com } 75d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com SkDebugf("\n"); 76d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com} 77d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com#endif 78d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com 79d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.comstatic void draw_nine_clipped(const SkMask& mask, const SkIRect& outerR, 80dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com const SkIPoint& center, bool fillCenter, 81d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com const SkIRect& clipR, SkBlitter* blitter) { 82dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com int cx = center.x(); 83dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com int cy = center.y(); 84d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com SkMask m; 85453995e01d884d62ce2e808e0067e494c0c9c7faskia.committer@gmail.com 86d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com // top-left 87d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com m.fBounds = mask.fBounds; 88d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com m.fBounds.fRight = cx; 89d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com m.fBounds.fBottom = cy; 903c0ecc588b145497232b24eeaee409d7878ad4f2tomhudson@google.com if (m.fBounds.width() > 0 && m.fBounds.height() > 0) { 913c0ecc588b145497232b24eeaee409d7878ad4f2tomhudson@google.com extractMaskSubset(mask, &m); 923c0ecc588b145497232b24eeaee409d7878ad4f2tomhudson@google.com m.fBounds.offsetTo(outerR.left(), outerR.top()); 933c0ecc588b145497232b24eeaee409d7878ad4f2tomhudson@google.com blitClippedMask(blitter, m, m.fBounds, clipR); 943c0ecc588b145497232b24eeaee409d7878ad4f2tomhudson@google.com } 95453995e01d884d62ce2e808e0067e494c0c9c7faskia.committer@gmail.com 96d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com // top-right 97d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com m.fBounds = mask.fBounds; 98d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com m.fBounds.fLeft = cx + 1; 99d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com m.fBounds.fBottom = cy; 1003c0ecc588b145497232b24eeaee409d7878ad4f2tomhudson@google.com if (m.fBounds.width() > 0 && m.fBounds.height() > 0) { 1013c0ecc588b145497232b24eeaee409d7878ad4f2tomhudson@google.com extractMaskSubset(mask, &m); 1023c0ecc588b145497232b24eeaee409d7878ad4f2tomhudson@google.com m.fBounds.offsetTo(outerR.right() - m.fBounds.width(), outerR.top()); 1033c0ecc588b145497232b24eeaee409d7878ad4f2tomhudson@google.com blitClippedMask(blitter, m, m.fBounds, clipR); 1043c0ecc588b145497232b24eeaee409d7878ad4f2tomhudson@google.com } 105453995e01d884d62ce2e808e0067e494c0c9c7faskia.committer@gmail.com 106d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com // bottom-left 107d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com m.fBounds = mask.fBounds; 108d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com m.fBounds.fRight = cx; 109d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com m.fBounds.fTop = cy + 1; 1103c0ecc588b145497232b24eeaee409d7878ad4f2tomhudson@google.com if (m.fBounds.width() > 0 && m.fBounds.height() > 0) { 1113c0ecc588b145497232b24eeaee409d7878ad4f2tomhudson@google.com extractMaskSubset(mask, &m); 1123c0ecc588b145497232b24eeaee409d7878ad4f2tomhudson@google.com m.fBounds.offsetTo(outerR.left(), outerR.bottom() - m.fBounds.height()); 1133c0ecc588b145497232b24eeaee409d7878ad4f2tomhudson@google.com blitClippedMask(blitter, m, m.fBounds, clipR); 1143c0ecc588b145497232b24eeaee409d7878ad4f2tomhudson@google.com } 115453995e01d884d62ce2e808e0067e494c0c9c7faskia.committer@gmail.com 116d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com // bottom-right 117d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com m.fBounds = mask.fBounds; 118d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com m.fBounds.fLeft = cx + 1; 119d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com m.fBounds.fTop = cy + 1; 1203c0ecc588b145497232b24eeaee409d7878ad4f2tomhudson@google.com if (m.fBounds.width() > 0 && m.fBounds.height() > 0) { 1213c0ecc588b145497232b24eeaee409d7878ad4f2tomhudson@google.com extractMaskSubset(mask, &m); 1223c0ecc588b145497232b24eeaee409d7878ad4f2tomhudson@google.com m.fBounds.offsetTo(outerR.right() - m.fBounds.width(), 1233c0ecc588b145497232b24eeaee409d7878ad4f2tomhudson@google.com outerR.bottom() - m.fBounds.height()); 1243c0ecc588b145497232b24eeaee409d7878ad4f2tomhudson@google.com blitClippedMask(blitter, m, m.fBounds, clipR); 1253c0ecc588b145497232b24eeaee409d7878ad4f2tomhudson@google.com } 126d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com 127d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com SkIRect innerR; 128d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com innerR.set(outerR.left() + cx - mask.fBounds.left(), 129d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com outerR.top() + cy - mask.fBounds.top(), 130d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com outerR.right() + (cx + 1 - mask.fBounds.right()), 131d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com outerR.bottom() + (cy + 1 - mask.fBounds.bottom())); 132dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com if (fillCenter) { 133dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com blitClippedRect(blitter, innerR, clipR); 134dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com } 135d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com 136d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com const int innerW = innerR.width(); 137d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com size_t storageSize = (innerW + 1) * (sizeof(int16_t) + sizeof(uint8_t)); 138d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com SkAutoSMalloc<4*1024> storage(storageSize); 139d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com int16_t* runs = (int16_t*)storage.get(); 140d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com uint8_t* alpha = (uint8_t*)(runs + innerW + 1); 141d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com 142d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com SkIRect r; 143d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com // top 144d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com r.set(innerR.left(), outerR.top(), innerR.right(), innerR.top()); 145d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com if (r.intersect(clipR)) { 146d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com int startY = SkMax32(0, r.top() - outerR.top()); 147d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com int stopY = startY + r.height(); 148d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com int width = r.width(); 149d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com for (int y = startY; y < stopY; ++y) { 150d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com runs[0] = width; 151d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com runs[width] = 0; 152d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com alpha[0] = *mask.getAddr8(cx, mask.fBounds.top() + y); 153d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com blitter->blitAntiH(r.left(), outerR.top() + y, alpha, runs); 154d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com } 155d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com } 156d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com // bottom 157d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com r.set(innerR.left(), innerR.bottom(), innerR.right(), outerR.bottom()); 158d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com if (r.intersect(clipR)) { 159d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com int startY = outerR.bottom() - r.bottom(); 160d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com int stopY = startY + r.height(); 161d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com int width = r.width(); 162d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com for (int y = startY; y < stopY; ++y) { 163d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com runs[0] = width; 164d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com runs[width] = 0; 165d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com alpha[0] = *mask.getAddr8(cx, mask.fBounds.bottom() - y - 1); 166d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com blitter->blitAntiH(r.left(), outerR.bottom() - y - 1, alpha, runs); 167d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com } 168d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com } 169d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com // left 170d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com r.set(outerR.left(), innerR.top(), innerR.left(), innerR.bottom()); 171d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com if (r.intersect(clipR)) { 172d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com int startX = r.left() - outerR.left(); 173d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com int stopX = startX + r.width(); 174d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com int height = r.height(); 175d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com for (int x = startX; x < stopX; ++x) { 176d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com blitter->blitV(outerR.left() + x, r.top(), height, 177d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com *mask.getAddr8(mask.fBounds.left() + x, mask.fBounds.top() + cy)); 178d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com } 179d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com } 180d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com // right 181d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com r.set(innerR.right(), innerR.top(), outerR.right(), innerR.bottom()); 182d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com if (r.intersect(clipR)) { 183d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com int startX = outerR.right() - r.right(); 184d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com int stopX = startX + r.width(); 185d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com int height = r.height(); 186d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com for (int x = startX; x < stopX; ++x) { 187d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com blitter->blitV(outerR.right() - x - 1, r.top(), height, 188d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com *mask.getAddr8(mask.fBounds.right() - x - 1, mask.fBounds.top() + cy)); 189d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com } 190d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com } 191d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com} 192d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com 193868074b50b0fc3e460d2aa97c1096827fe0a1935reedstatic void draw_nine(const SkMask& mask, const SkIRect& outerR, const SkIPoint& center, 194868074b50b0fc3e460d2aa97c1096827fe0a1935reed bool fillCenter, const SkRasterClip& clip, SkBlitter* blitter) { 195d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com // if we get here, we need to (possibly) resolve the clip and blitter 196d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com SkAAClipBlitterWrapper wrapper(clip, blitter); 197d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com blitter = wrapper.getBlitter(); 198453995e01d884d62ce2e808e0067e494c0c9c7faskia.committer@gmail.com 199d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com SkRegion::Cliperator clipper(wrapper.getRgn(), outerR); 200453995e01d884d62ce2e808e0067e494c0c9c7faskia.committer@gmail.com 201868074b50b0fc3e460d2aa97c1096827fe0a1935reed if (!clipper.done()) { 202d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com const SkIRect& cr = clipper.rect(); 203d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com do { 204dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com draw_nine_clipped(mask, outerR, center, fillCenter, cr, blitter); 205d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com clipper.next(); 206d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com } while (!clipper.done()); 207d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com } 208d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com} 209d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com 210dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.comstatic int countNestedRects(const SkPath& path, SkRect rects[2]) { 21195bc5f349561fef2d6fbae71adb08cf5c2eec0c9caryclark if (path.isNestedFillRects(rects)) { 212dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com return 2; 213dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com } 214dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com return path.isRect(&rects[0]); 215dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com} 216dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com 217a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.combool SkMaskFilter::filterRRect(const SkRRect& devRRect, const SkMatrix& matrix, 218868074b50b0fc3e460d2aa97c1096827fe0a1935reed const SkRasterClip& clip, SkBlitter* blitter, 219868074b50b0fc3e460d2aa97c1096827fe0a1935reed SkPaint::Style style) const { 220a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com // Attempt to speed up drawing by creating a nine patch. If a nine patch 221a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com // cannot be used, return false to allow our caller to recover and perform 222a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com // the drawing another way. 223a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com NinePatch patch; 224a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com patch.fMask.fImage = NULL; 225a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com if (kTrue_FilterReturn != this->filterRRectToNine(devRRect, matrix, 226a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com clip.getBounds(), 227a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com &patch)) { 228a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com SkASSERT(NULL == patch.fMask.fImage); 229a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com return false; 230a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com } 231868074b50b0fc3e460d2aa97c1096827fe0a1935reed draw_nine(patch.fMask, patch.fOuterRect, patch.fCenter, true, clip, blitter); 232a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com return true; 233a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com} 234a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com 2358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkMaskFilter::filterPath(const SkPath& devPath, const SkMatrix& matrix, 236868074b50b0fc3e460d2aa97c1096827fe0a1935reed const SkRasterClip& clip, SkBlitter* blitter, 237868074b50b0fc3e460d2aa97c1096827fe0a1935reed SkPaint::Style style) const { 238dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com SkRect rects[2]; 239dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com int rectCount = 0; 2405f0add3ad6e1d6129307276c81ba6624f92ca112reed@google.com if (SkPaint::kFill_Style == style) { 241dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com rectCount = countNestedRects(devPath, rects); 242dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com } 243dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com if (rectCount > 0) { 244dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com NinePatch patch; 245dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com 246b0df8be137d8fb49436e46d1fd1a5aec8b7ab562reed switch (this->filterRectsToNine(rects, rectCount, matrix, clip.getBounds(), &patch)) { 247d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com case kFalse_FilterReturn: 248dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com SkASSERT(NULL == patch.fMask.fImage); 249d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com return false; 250dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com 251d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com case kTrue_FilterReturn: 252868074b50b0fc3e460d2aa97c1096827fe0a1935reed draw_nine(patch.fMask, patch.fOuterRect, patch.fCenter, 1 == rectCount, clip, 253868074b50b0fc3e460d2aa97c1096827fe0a1935reed blitter); 254d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com return true; 255dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com 256d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com case kUnimplemented_FilterReturn: 257dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com SkASSERT(NULL == patch.fMask.fImage); 258d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com // fall through 259d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com break; 260d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com } 261d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com } 262d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com 2638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMask srcM, dstM; 2648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!SkDraw::DrawToMask(devPath, &clip.getBounds(), this, &matrix, &srcM, 2662ac4ef5e6e0c9c95c9200408ba25a95ca758eac2junov@chromium.org SkMask::kComputeBoundsAndRenderImage_CreateMode, 2672ac4ef5e6e0c9c95c9200408ba25a95ca758eac2junov@chromium.org style)) { 2688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 2698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 27002f55841854ae32f21a13417e9ee711463e488cfbungeman@google.com SkAutoMaskFreeImage autoSrc(srcM.fImage); 2718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 272eabd0d73eebb940ec5ea06625f612a80156b61dbqiankun.miao if (!this->filterMask(&dstM, srcM, matrix, NULL)) { 273eabd0d73eebb940ec5ea06625f612a80156b61dbqiankun.miao return false; 274feb8cc870df055099c6fcdfebdd6c1486bd91b27reed@google.com } 27502f55841854ae32f21a13417e9ee711463e488cfbungeman@google.com SkAutoMaskFreeImage autoDst(dstM.fImage); 2768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 277045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com // if we get here, we need to (possibly) resolve the clip and blitter 278045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com SkAAClipBlitterWrapper wrapper(clip, blitter); 279045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com blitter = wrapper.getBlitter(); 280045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com 281045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com SkRegion::Cliperator clipper(wrapper.getRgn(), dstM.fBounds); 2828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 283868074b50b0fc3e460d2aa97c1096827fe0a1935reed if (!clipper.done()) { 2848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkIRect& cr = clipper.rect(); 2858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { 2868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com blitter->blitMask(dstM, cr); 2878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com clipper.next(); 2888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } while (!clipper.done()); 2898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 2928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 294d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.comSkMaskFilter::FilterReturn 295a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.comSkMaskFilter::filterRRectToNine(const SkRRect&, const SkMatrix&, 296a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com const SkIRect& clipBounds, NinePatch*) const { 297a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com return kUnimplemented_FilterReturn; 298a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com} 299a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com 300a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.comSkMaskFilter::FilterReturn 301dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.comSkMaskFilter::filterRectsToNine(const SkRect[], int count, const SkMatrix&, 30230711b764be6bbb58caa30a0ac5d1474c894efe7reed@google.com const SkIRect& clipBounds, NinePatch*) const { 303d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com return kUnimplemented_FilterReturn; 304d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com} 305d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com 3060b82852b234753257835bf1f9ac0046848a283ecrobertphillips@google.com#if SK_SUPPORT_GPU 307b0a8a377f832c59cee939ad721e1f87d378b7142joshualittbool SkMaskFilter::asFragmentProcessor(GrFragmentProcessor**, GrTexture*, const SkMatrix&) const { 308491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com return false; 309491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com} 310491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com 3111842adf01320f9197b449de7375d08ccac43f389skia.committer@gmail.combool SkMaskFilter::canFilterMaskGPU(const SkRect& devBounds, 312491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com const SkIRect& clipBounds, 313491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com const SkMatrix& ctm, 314491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com SkRect* maskRect) const { 315491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com return false; 316491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com} 317491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com 318cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org bool SkMaskFilter::directFilterMaskGPU(GrContext* context, 31925d9c154087d2132a51d1ca74a104726f60ef380joshualitt GrRenderTarget* rt, 320cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org GrPaint* grp, 321570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt const GrClip&, 3225531d51ce7426bdae7563547326fcf0bf926a083joshualitt const SkMatrix& viewMatrix, 323cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org const SkStrokeRec& strokeRec, 324cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org const SkPath& path) const { 325cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org return false; 326cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org} 327cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org 328491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com 329821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.orgbool SkMaskFilter::directFilterRRectMaskGPU(GrContext* context, 33025d9c154087d2132a51d1ca74a104726f60ef380joshualitt GrRenderTarget* rt, 331821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org GrPaint* grp, 332570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt const GrClip&, 3335531d51ce7426bdae7563547326fcf0bf926a083joshualitt const SkMatrix& viewMatrix, 334821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org const SkStrokeRec& strokeRec, 335821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org const SkRRect& rrect) const { 336821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org return false; 337821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org} 338821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org 3391842adf01320f9197b449de7375d08ccac43f389skia.committer@gmail.combool SkMaskFilter::filterMaskGPU(GrTexture* src, 34041bf930039314cc71039b12957195f1c65c30ce1commit-bot@chromium.org const SkMatrix& ctm, 3411842adf01320f9197b449de7375d08ccac43f389skia.committer@gmail.com const SkRect& maskRect, 342491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com GrTexture** result, 343491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com bool canOverwriteSrc) const { 344491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com return false; 3452b75f4279a237ceea929ff8ac019f7fbd3ad08b5reed@google.com} 3460b82852b234753257835bf1f9ac0046848a283ecrobertphillips@google.com#endif 3472b75f4279a237ceea929ff8ac019f7fbd3ad08b5reed@google.com 34830711b764be6bbb58caa30a0ac5d1474c894efe7reed@google.comvoid SkMaskFilter::computeFastBounds(const SkRect& src, SkRect* dst) const { 3499efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com SkMask srcM, dstM; 3509efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com 3519efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com srcM.fImage = NULL; 352b07a94f1cba3976596ae1a7f23d8c2043ba353f3reed srcM.fBounds = src.roundOut(); 3539efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com srcM.fRowBytes = 0; 3549efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com srcM.fFormat = SkMask::kA8_Format; 3559efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com 3569efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com SkIPoint margin; // ignored 3579efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com if (this->filterMask(&dstM, srcM, SkMatrix::I(), &margin)) { 3589efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com dst->set(dstM.fBounds); 3599efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com } else { 3609efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com dst->set(srcM.fBounds); 3619efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com } 3629efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com} 363