SkMaskFilter.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717
  1. /*
  2. * Copyright 2006 The Android Open Source Project
  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. #include "src/core/SkMaskFilterBase.h"
  8. #include "include/core/SkPath.h"
  9. #include "include/core/SkRRect.h"
  10. #include "src/core/SkAutoMalloc.h"
  11. #include "src/core/SkBlitter.h"
  12. #include "src/core/SkBlurPriv.h"
  13. #include "src/core/SkCachedData.h"
  14. #include "src/core/SkCoverageModePriv.h"
  15. #include "src/core/SkDraw.h"
  16. #include "src/core/SkRasterClip.h"
  17. #include "src/core/SkReadBuffer.h"
  18. #include "src/core/SkWriteBuffer.h"
  19. #if SK_SUPPORT_GPU
  20. #include "src/gpu/GrFragmentProcessor.h"
  21. #include "src/gpu/GrTextureProxy.h"
  22. #include "src/gpu/effects/GrXfermodeFragmentProcessor.h"
  23. #include "src/gpu/text/GrSDFMaskFilter.h"
  24. #endif
  25. SkMaskFilterBase::NinePatch::~NinePatch() {
  26. if (fCache) {
  27. SkASSERT((const void*)fMask.fImage == fCache->data());
  28. fCache->unref();
  29. } else {
  30. SkMask::FreeImage(fMask.fImage);
  31. }
  32. }
  33. bool SkMaskFilterBase::asABlur(BlurRec*) const {
  34. return false;
  35. }
  36. static void extractMaskSubset(const SkMask& src, SkMask* dst) {
  37. SkASSERT(src.fBounds.contains(dst->fBounds));
  38. const int dx = dst->fBounds.left() - src.fBounds.left();
  39. const int dy = dst->fBounds.top() - src.fBounds.top();
  40. dst->fImage = src.fImage + dy * src.fRowBytes + dx;
  41. dst->fRowBytes = src.fRowBytes;
  42. dst->fFormat = src.fFormat;
  43. }
  44. static void blitClippedMask(SkBlitter* blitter, const SkMask& mask,
  45. const SkIRect& bounds, const SkIRect& clipR) {
  46. SkIRect r;
  47. if (r.intersect(bounds, clipR)) {
  48. blitter->blitMask(mask, r);
  49. }
  50. }
  51. static void blitClippedRect(SkBlitter* blitter, const SkIRect& rect, const SkIRect& clipR) {
  52. SkIRect r;
  53. if (r.intersect(rect, clipR)) {
  54. blitter->blitRect(r.left(), r.top(), r.width(), r.height());
  55. }
  56. }
  57. #if 0
  58. static void dump(const SkMask& mask) {
  59. for (int y = mask.fBounds.top(); y < mask.fBounds.bottom(); ++y) {
  60. for (int x = mask.fBounds.left(); x < mask.fBounds.right(); ++x) {
  61. SkDebugf("%02X", *mask.getAddr8(x, y));
  62. }
  63. SkDebugf("\n");
  64. }
  65. SkDebugf("\n");
  66. }
  67. #endif
  68. static void draw_nine_clipped(const SkMask& mask, const SkIRect& outerR,
  69. const SkIPoint& center, bool fillCenter,
  70. const SkIRect& clipR, SkBlitter* blitter) {
  71. int cx = center.x();
  72. int cy = center.y();
  73. SkMask m;
  74. // top-left
  75. m.fBounds = mask.fBounds;
  76. m.fBounds.fRight = cx;
  77. m.fBounds.fBottom = cy;
  78. if (m.fBounds.width() > 0 && m.fBounds.height() > 0) {
  79. extractMaskSubset(mask, &m);
  80. m.fBounds.offsetTo(outerR.left(), outerR.top());
  81. blitClippedMask(blitter, m, m.fBounds, clipR);
  82. }
  83. // top-right
  84. m.fBounds = mask.fBounds;
  85. m.fBounds.fLeft = cx + 1;
  86. m.fBounds.fBottom = cy;
  87. if (m.fBounds.width() > 0 && m.fBounds.height() > 0) {
  88. extractMaskSubset(mask, &m);
  89. m.fBounds.offsetTo(outerR.right() - m.fBounds.width(), outerR.top());
  90. blitClippedMask(blitter, m, m.fBounds, clipR);
  91. }
  92. // bottom-left
  93. m.fBounds = mask.fBounds;
  94. m.fBounds.fRight = cx;
  95. m.fBounds.fTop = cy + 1;
  96. if (m.fBounds.width() > 0 && m.fBounds.height() > 0) {
  97. extractMaskSubset(mask, &m);
  98. m.fBounds.offsetTo(outerR.left(), outerR.bottom() - m.fBounds.height());
  99. blitClippedMask(blitter, m, m.fBounds, clipR);
  100. }
  101. // bottom-right
  102. m.fBounds = mask.fBounds;
  103. m.fBounds.fLeft = cx + 1;
  104. m.fBounds.fTop = cy + 1;
  105. if (m.fBounds.width() > 0 && m.fBounds.height() > 0) {
  106. extractMaskSubset(mask, &m);
  107. m.fBounds.offsetTo(outerR.right() - m.fBounds.width(),
  108. outerR.bottom() - m.fBounds.height());
  109. blitClippedMask(blitter, m, m.fBounds, clipR);
  110. }
  111. SkIRect innerR;
  112. innerR.set(outerR.left() + cx - mask.fBounds.left(),
  113. outerR.top() + cy - mask.fBounds.top(),
  114. outerR.right() + (cx + 1 - mask.fBounds.right()),
  115. outerR.bottom() + (cy + 1 - mask.fBounds.bottom()));
  116. if (fillCenter) {
  117. blitClippedRect(blitter, innerR, clipR);
  118. }
  119. const int innerW = innerR.width();
  120. size_t storageSize = (innerW + 1) * (sizeof(int16_t) + sizeof(uint8_t));
  121. SkAutoSMalloc<4*1024> storage(storageSize);
  122. int16_t* runs = (int16_t*)storage.get();
  123. uint8_t* alpha = (uint8_t*)(runs + innerW + 1);
  124. SkIRect r;
  125. // top
  126. r.set(innerR.left(), outerR.top(), innerR.right(), innerR.top());
  127. if (r.intersect(clipR)) {
  128. int startY = SkMax32(0, r.top() - outerR.top());
  129. int stopY = startY + r.height();
  130. int width = r.width();
  131. for (int y = startY; y < stopY; ++y) {
  132. runs[0] = width;
  133. runs[width] = 0;
  134. alpha[0] = *mask.getAddr8(cx, mask.fBounds.top() + y);
  135. blitter->blitAntiH(r.left(), outerR.top() + y, alpha, runs);
  136. }
  137. }
  138. // bottom
  139. r.set(innerR.left(), innerR.bottom(), innerR.right(), outerR.bottom());
  140. if (r.intersect(clipR)) {
  141. int startY = outerR.bottom() - r.bottom();
  142. int stopY = startY + r.height();
  143. int width = r.width();
  144. for (int y = startY; y < stopY; ++y) {
  145. runs[0] = width;
  146. runs[width] = 0;
  147. alpha[0] = *mask.getAddr8(cx, mask.fBounds.bottom() - y - 1);
  148. blitter->blitAntiH(r.left(), outerR.bottom() - y - 1, alpha, runs);
  149. }
  150. }
  151. // left
  152. r.set(outerR.left(), innerR.top(), innerR.left(), innerR.bottom());
  153. if (r.intersect(clipR)) {
  154. SkMask m;
  155. m.fImage = mask.getAddr8(mask.fBounds.left() + r.left() - outerR.left(),
  156. mask.fBounds.top() + cy);
  157. m.fBounds = r;
  158. m.fRowBytes = 0; // so we repeat the scanline for our height
  159. m.fFormat = SkMask::kA8_Format;
  160. blitter->blitMask(m, r);
  161. }
  162. // right
  163. r.set(innerR.right(), innerR.top(), outerR.right(), innerR.bottom());
  164. if (r.intersect(clipR)) {
  165. SkMask m;
  166. m.fImage = mask.getAddr8(mask.fBounds.right() - outerR.right() + r.left(),
  167. mask.fBounds.top() + cy);
  168. m.fBounds = r;
  169. m.fRowBytes = 0; // so we repeat the scanline for our height
  170. m.fFormat = SkMask::kA8_Format;
  171. blitter->blitMask(m, r);
  172. }
  173. }
  174. static void draw_nine(const SkMask& mask, const SkIRect& outerR, const SkIPoint& center,
  175. bool fillCenter, const SkRasterClip& clip, SkBlitter* blitter) {
  176. // if we get here, we need to (possibly) resolve the clip and blitter
  177. SkAAClipBlitterWrapper wrapper(clip, blitter);
  178. blitter = wrapper.getBlitter();
  179. SkRegion::Cliperator clipper(wrapper.getRgn(), outerR);
  180. if (!clipper.done()) {
  181. const SkIRect& cr = clipper.rect();
  182. do {
  183. draw_nine_clipped(mask, outerR, center, fillCenter, cr, blitter);
  184. clipper.next();
  185. } while (!clipper.done());
  186. }
  187. }
  188. static int countNestedRects(const SkPath& path, SkRect rects[2]) {
  189. if (path.isNestedFillRects(rects)) {
  190. return 2;
  191. }
  192. return path.isRect(&rects[0]);
  193. }
  194. bool SkMaskFilterBase::filterRRect(const SkRRect& devRRect, const SkMatrix& matrix,
  195. const SkRasterClip& clip, SkBlitter* blitter) const {
  196. // Attempt to speed up drawing by creating a nine patch. If a nine patch
  197. // cannot be used, return false to allow our caller to recover and perform
  198. // the drawing another way.
  199. NinePatch patch;
  200. patch.fMask.fImage = nullptr;
  201. if (kTrue_FilterReturn != this->filterRRectToNine(devRRect, matrix,
  202. clip.getBounds(),
  203. &patch)) {
  204. SkASSERT(nullptr == patch.fMask.fImage);
  205. return false;
  206. }
  207. draw_nine(patch.fMask, patch.fOuterRect, patch.fCenter, true, clip, blitter);
  208. return true;
  209. }
  210. bool SkMaskFilterBase::filterPath(const SkPath& devPath, const SkMatrix& matrix,
  211. const SkRasterClip& clip, SkBlitter* blitter,
  212. SkStrokeRec::InitStyle style) const {
  213. SkRect rects[2];
  214. int rectCount = 0;
  215. if (SkStrokeRec::kFill_InitStyle == style) {
  216. rectCount = countNestedRects(devPath, rects);
  217. }
  218. if (rectCount > 0) {
  219. NinePatch patch;
  220. switch (this->filterRectsToNine(rects, rectCount, matrix, clip.getBounds(), &patch)) {
  221. case kFalse_FilterReturn:
  222. SkASSERT(nullptr == patch.fMask.fImage);
  223. return false;
  224. case kTrue_FilterReturn:
  225. draw_nine(patch.fMask, patch.fOuterRect, patch.fCenter, 1 == rectCount, clip,
  226. blitter);
  227. return true;
  228. case kUnimplemented_FilterReturn:
  229. SkASSERT(nullptr == patch.fMask.fImage);
  230. // fall through
  231. break;
  232. }
  233. }
  234. SkMask srcM, dstM;
  235. if (!SkDraw::DrawToMask(devPath, &clip.getBounds(), this, &matrix, &srcM,
  236. SkMask::kComputeBoundsAndRenderImage_CreateMode,
  237. style)) {
  238. return false;
  239. }
  240. SkAutoMaskFreeImage autoSrc(srcM.fImage);
  241. if (!this->filterMask(&dstM, srcM, matrix, nullptr)) {
  242. return false;
  243. }
  244. SkAutoMaskFreeImage autoDst(dstM.fImage);
  245. // if we get here, we need to (possibly) resolve the clip and blitter
  246. SkAAClipBlitterWrapper wrapper(clip, blitter);
  247. blitter = wrapper.getBlitter();
  248. SkRegion::Cliperator clipper(wrapper.getRgn(), dstM.fBounds);
  249. if (!clipper.done()) {
  250. const SkIRect& cr = clipper.rect();
  251. do {
  252. blitter->blitMask(dstM, cr);
  253. clipper.next();
  254. } while (!clipper.done());
  255. }
  256. return true;
  257. }
  258. SkMaskFilterBase::FilterReturn
  259. SkMaskFilterBase::filterRRectToNine(const SkRRect&, const SkMatrix&,
  260. const SkIRect& clipBounds, NinePatch*) const {
  261. return kUnimplemented_FilterReturn;
  262. }
  263. SkMaskFilterBase::FilterReturn
  264. SkMaskFilterBase::filterRectsToNine(const SkRect[], int count, const SkMatrix&,
  265. const SkIRect& clipBounds, NinePatch*) const {
  266. return kUnimplemented_FilterReturn;
  267. }
  268. #if SK_SUPPORT_GPU
  269. std::unique_ptr<GrFragmentProcessor>
  270. SkMaskFilterBase::asFragmentProcessor(const GrFPArgs& args) const {
  271. auto fp = this->onAsFragmentProcessor(args);
  272. if (fp) {
  273. SkASSERT(this->hasFragmentProcessor());
  274. } else {
  275. SkASSERT(!this->hasFragmentProcessor());
  276. }
  277. return fp;
  278. }
  279. bool SkMaskFilterBase::hasFragmentProcessor() const {
  280. return this->onHasFragmentProcessor();
  281. }
  282. std::unique_ptr<GrFragmentProcessor>
  283. SkMaskFilterBase::onAsFragmentProcessor(const GrFPArgs&) const {
  284. return nullptr;
  285. }
  286. bool SkMaskFilterBase::onHasFragmentProcessor() const { return false; }
  287. bool SkMaskFilterBase::canFilterMaskGPU(const GrShape& shape,
  288. const SkIRect& devSpaceShapeBounds,
  289. const SkIRect& clipBounds,
  290. const SkMatrix& ctm,
  291. SkIRect* maskRect) const {
  292. return false;
  293. }
  294. bool SkMaskFilterBase::directFilterMaskGPU(GrRecordingContext*,
  295. GrRenderTargetContext*,
  296. GrPaint&&,
  297. const GrClip&,
  298. const SkMatrix& viewMatrix,
  299. const GrShape&) const {
  300. return false;
  301. }
  302. sk_sp<GrTextureProxy> SkMaskFilterBase::filterMaskGPU(GrRecordingContext*,
  303. sk_sp<GrTextureProxy> srcProxy,
  304. const SkMatrix& ctm,
  305. const SkIRect& maskRect) const {
  306. return nullptr;
  307. }
  308. #endif
  309. void SkMaskFilterBase::computeFastBounds(const SkRect& src, SkRect* dst) const {
  310. SkMask srcM, dstM;
  311. srcM.fBounds = src.roundOut();
  312. srcM.fRowBytes = 0;
  313. srcM.fFormat = SkMask::kA8_Format;
  314. SkIPoint margin; // ignored
  315. if (this->filterMask(&dstM, srcM, SkMatrix::I(), &margin)) {
  316. dst->set(dstM.fBounds);
  317. } else {
  318. dst->set(srcM.fBounds);
  319. }
  320. }
  321. ///////////////////////////////////////////////////////////////////////////////////////////////////
  322. template <typename T> static inline T join(const T& a, const T& b) {
  323. T r = a;
  324. r.join(b);
  325. return r;
  326. }
  327. template <typename T> static inline T sect(const T& a, const T& b) {
  328. T r = a;
  329. return r.intersect(b) ? r : T::MakeEmpty();
  330. }
  331. class SkComposeMF : public SkMaskFilterBase {
  332. public:
  333. SkComposeMF(sk_sp<SkMaskFilter> outer, sk_sp<SkMaskFilter> inner)
  334. : fOuter(std::move(outer))
  335. , fInner(std::move(inner))
  336. {
  337. SkASSERT(as_MFB(fOuter)->getFormat() == SkMask::kA8_Format);
  338. SkASSERT(as_MFB(fInner)->getFormat() == SkMask::kA8_Format);
  339. }
  340. bool filterMask(SkMask* dst, const SkMask& src, const SkMatrix&, SkIPoint*) const override;
  341. void computeFastBounds(const SkRect& src, SkRect* dst) const override {
  342. SkRect tmp;
  343. as_MFB(fInner)->computeFastBounds(src, &tmp);
  344. as_MFB(fOuter)->computeFastBounds(tmp, dst);
  345. }
  346. SkMask::Format getFormat() const override { return SkMask::kA8_Format; }
  347. protected:
  348. #if SK_SUPPORT_GPU
  349. std::unique_ptr<GrFragmentProcessor> onAsFragmentProcessor(const GrFPArgs& args) const override{
  350. std::unique_ptr<GrFragmentProcessor> array[2] = {
  351. as_MFB(fInner)->asFragmentProcessor(args),
  352. as_MFB(fOuter)->asFragmentProcessor(args),
  353. };
  354. if (!array[0] || !array[1]) {
  355. return nullptr;
  356. }
  357. return GrFragmentProcessor::RunInSeries(array, 2);
  358. }
  359. bool onHasFragmentProcessor() const override {
  360. return as_MFB(fInner)->hasFragmentProcessor() && as_MFB(fOuter)->hasFragmentProcessor();
  361. }
  362. #endif
  363. private:
  364. SK_FLATTENABLE_HOOKS(SkComposeMF)
  365. sk_sp<SkMaskFilter> fOuter;
  366. sk_sp<SkMaskFilter> fInner;
  367. void flatten(SkWriteBuffer&) const override;
  368. friend class SkMaskFilter;
  369. typedef SkMaskFilterBase INHERITED;
  370. };
  371. bool SkComposeMF::filterMask(SkMask* dst, const SkMask& src, const SkMatrix& ctm,
  372. SkIPoint* margin) const {
  373. SkIPoint innerMargin;
  374. SkMask innerMask;
  375. if (!as_MFB(fInner)->filterMask(&innerMask, src, ctm, &innerMargin)) {
  376. return false;
  377. }
  378. if (!as_MFB(fOuter)->filterMask(dst, innerMask, ctm, margin)) {
  379. return false;
  380. }
  381. if (margin) {
  382. margin->fX += innerMargin.fX;
  383. margin->fY += innerMargin.fY;
  384. }
  385. sk_free(innerMask.fImage);
  386. return true;
  387. }
  388. void SkComposeMF::flatten(SkWriteBuffer & buffer) const {
  389. buffer.writeFlattenable(fOuter.get());
  390. buffer.writeFlattenable(fInner.get());
  391. }
  392. sk_sp<SkFlattenable> SkComposeMF::CreateProc(SkReadBuffer& buffer) {
  393. auto outer = buffer.readMaskFilter();
  394. auto inner = buffer.readMaskFilter();
  395. if (!buffer.validate(outer && inner)) {
  396. return nullptr;
  397. }
  398. return SkMaskFilter::MakeCompose(std::move(outer), std::move(inner));
  399. }
  400. ///////////////////////////////////////////////////////////////////////////////////////////////////
  401. class SkCombineMF : public SkMaskFilterBase {
  402. public:
  403. SkCombineMF(sk_sp<SkMaskFilter> dst, sk_sp<SkMaskFilter> src, SkCoverageMode mode)
  404. : fDst(std::move(dst))
  405. , fSrc(std::move(src))
  406. , fMode(mode)
  407. {
  408. SkASSERT(as_MFB(fSrc)->getFormat() == SkMask::kA8_Format);
  409. SkASSERT(as_MFB(fDst)->getFormat() == SkMask::kA8_Format);
  410. }
  411. bool filterMask(SkMask* dst, const SkMask& src, const SkMatrix&, SkIPoint*) const override;
  412. void computeFastBounds(const SkRect& src, SkRect* dst) const override {
  413. SkRect srcR, dstR;
  414. as_MFB(fSrc)->computeFastBounds(src, &srcR);
  415. as_MFB(fDst)->computeFastBounds(src, &dstR);
  416. *dst = join(srcR, dstR);
  417. }
  418. SkMask::Format getFormat() const override { return SkMask::kA8_Format; }
  419. SK_FLATTENABLE_HOOKS(SkCombineMF)
  420. protected:
  421. #if SK_SUPPORT_GPU
  422. std::unique_ptr<GrFragmentProcessor> onAsFragmentProcessor(const GrFPArgs& args) const override{
  423. auto src = as_MFB(fSrc)->asFragmentProcessor(args);
  424. auto dst = as_MFB(fDst)->asFragmentProcessor(args);
  425. if (!src || !dst) {
  426. return nullptr;
  427. }
  428. return GrXfermodeFragmentProcessor::MakeFromTwoProcessors(std::move(src), std::move(dst),
  429. SkUncorrelatedCoverageModeToBlendMode(fMode));
  430. }
  431. bool onHasFragmentProcessor() const override {
  432. return as_MFB(fSrc)->hasFragmentProcessor() && as_MFB(fDst)->hasFragmentProcessor();
  433. }
  434. #endif
  435. private:
  436. sk_sp<SkMaskFilter> fDst;
  437. sk_sp<SkMaskFilter> fSrc;
  438. SkCoverageMode fMode;
  439. void flatten(SkWriteBuffer&) const override;
  440. friend class SkMaskFilter;
  441. typedef SkMaskFilterBase INHERITED;
  442. };
  443. #include "src/core/SkSafeMath.h"
  444. class DrawIntoMask : public SkDraw {
  445. public:
  446. // we ignore the offset of the mask->fBounds
  447. DrawIntoMask(SkMask* mask) {
  448. int w = mask->fBounds.width();
  449. int h = mask->fBounds.height();
  450. size_t size = SkSafeMath::Mul(w, h);
  451. mask->fFormat = SkMask::kA8_Format;
  452. mask->fImage = SkMask::AllocImage(size, SkMask::kZeroInit_Alloc);
  453. mask->fRowBytes = w;
  454. SkAssertResult(fDst.reset(*mask));
  455. fMatrixStorage.reset();
  456. fMatrix = &fMatrixStorage;
  457. fRCStorage.setRect({ 0, 0, w, h });
  458. fRC = &fRCStorage;
  459. }
  460. void drawAsBitmap(const SkMask& m, const SkPaint& p) {
  461. SkBitmap b;
  462. b.installMaskPixels(m);
  463. this->drawSprite(b, m.fBounds.fLeft, m.fBounds.fTop, p);
  464. }
  465. private:
  466. SkMatrix fMatrixStorage;
  467. SkRasterClip fRCStorage;
  468. };
  469. static SkIRect join(const SkIRect& src, const SkIRect& dst, SkCoverageMode mode) {
  470. switch (mode) {
  471. case SkCoverageMode::kUnion: return join(src, dst);
  472. case SkCoverageMode::kIntersect: return sect(src, dst);
  473. case SkCoverageMode::kDifference: return src;
  474. case SkCoverageMode::kReverseDifference: return dst;
  475. case SkCoverageMode::kXor: return join(src, dst);
  476. }
  477. // not reached
  478. return { 0, 0, 0, 0 };
  479. }
  480. bool SkCombineMF::filterMask(SkMask* dst, const SkMask& src, const SkMatrix& ctm,
  481. SkIPoint* margin) const {
  482. SkIPoint srcP, dstP;
  483. SkMask srcM, dstM;
  484. if (!as_MFB(fSrc)->filterMask(&srcM, src, ctm, &srcP)) {
  485. return false;
  486. }
  487. if (!as_MFB(fDst)->filterMask(&dstM, src, ctm, &dstP)) {
  488. return false;
  489. }
  490. dst->fBounds = join(srcM.fBounds, dstM.fBounds, fMode);
  491. dst->fFormat = SkMask::kA8_Format;
  492. if (src.fImage == nullptr) {
  493. dst->fImage = nullptr;
  494. return true;
  495. }
  496. DrawIntoMask md(dst);
  497. SkPaint p;
  498. p.setBlendMode(SkBlendMode::kSrc);
  499. dstM.fBounds.offset(-dst->fBounds.fLeft, -dst->fBounds.fTop);
  500. md.drawAsBitmap(dstM, p);
  501. p.setBlendMode(SkUncorrelatedCoverageModeToBlendMode(fMode));
  502. srcM.fBounds.offset(-dst->fBounds.fLeft, -dst->fBounds.fTop);
  503. md.drawAsBitmap(srcM, p);
  504. sk_free(srcM.fImage);
  505. sk_free(dstM.fImage);
  506. return true;
  507. }
  508. void SkCombineMF::flatten(SkWriteBuffer & buffer) const {
  509. buffer.writeFlattenable(fDst.get());
  510. buffer.writeFlattenable(fSrc.get());
  511. buffer.write32(static_cast<uint32_t>(fMode));
  512. }
  513. sk_sp<SkFlattenable> SkCombineMF::CreateProc(SkReadBuffer& buffer) {
  514. auto dst = buffer.readMaskFilter();
  515. auto src = buffer.readMaskFilter();
  516. SkCoverageMode mode = buffer.read32LE(SkCoverageMode::kLast);
  517. if (!buffer.validate(dst && src)) {
  518. return nullptr;
  519. }
  520. return SkMaskFilter::MakeCombine(std::move(dst), std::move(src), mode);
  521. }
  522. ///////////////////////////////////////////////////////////////////////////////////////////////////
  523. class SkMatrixMF : public SkMaskFilterBase {
  524. public:
  525. SkMatrixMF(sk_sp<SkMaskFilter> filter, const SkMatrix& lm)
  526. : fFilter(std::move(filter))
  527. , fLM(lm)
  528. {}
  529. bool filterMask(SkMask* dst, const SkMask& src, const SkMatrix& ctm,
  530. SkIPoint* margin) const override {
  531. return as_MFB(fFilter)->filterMask(dst, src, SkMatrix::Concat(ctm, fLM), margin);
  532. }
  533. void computeFastBounds(const SkRect& src, SkRect* dst) const override {
  534. *dst = src;
  535. SkRect tmp;
  536. fLM.mapRect(&tmp, src);
  537. as_MFB(fFilter)->computeFastBounds(tmp, dst);
  538. }
  539. SkMask::Format getFormat() const override { return as_MFB(fFilter)->getFormat(); }
  540. SK_FLATTENABLE_HOOKS(SkMatrixMF)
  541. protected:
  542. #if SK_SUPPORT_GPU
  543. std::unique_ptr<GrFragmentProcessor> onAsFragmentProcessor(const GrFPArgs& args) const override{
  544. return as_MFB(fFilter)->asFragmentProcessor(GrFPArgs::WithPostLocalMatrix(args, fLM));
  545. }
  546. bool onHasFragmentProcessor() const override {
  547. return as_MFB(fFilter)->hasFragmentProcessor();
  548. }
  549. #endif
  550. private:
  551. sk_sp<SkMaskFilter> fFilter;
  552. const SkMatrix fLM;
  553. void flatten(SkWriteBuffer& buffer) const override {
  554. buffer.writeMatrix(fLM);
  555. buffer.writeFlattenable(fFilter.get());
  556. }
  557. friend class SkMaskFilter;
  558. typedef SkMaskFilterBase INHERITED;
  559. };
  560. sk_sp<SkFlattenable> SkMatrixMF::CreateProc(SkReadBuffer& buffer) {
  561. SkMatrix m;
  562. buffer.readMatrix(&m);
  563. auto filter = buffer.readMaskFilter();
  564. return filter ? filter->makeWithMatrix(m) : nullptr;
  565. }
  566. ///////////////////////////////////////////////////////////////////////////////////////////////////
  567. sk_sp<SkMaskFilter> SkMaskFilter::MakeCompose(sk_sp<SkMaskFilter> outer,
  568. sk_sp<SkMaskFilter> inner) {
  569. if (!outer) {
  570. return inner;
  571. }
  572. if (!inner) {
  573. return outer;
  574. }
  575. if (as_MFB(inner)->getFormat() != SkMask::kA8_Format ||
  576. as_MFB(outer)->getFormat() != SkMask::kA8_Format) {
  577. return nullptr;
  578. }
  579. return sk_sp<SkMaskFilter>(new SkComposeMF(std::move(outer), std::move(inner)));
  580. }
  581. sk_sp<SkMaskFilter> SkMaskFilter::MakeCombine(sk_sp<SkMaskFilter> dst, sk_sp<SkMaskFilter> src,
  582. SkCoverageMode mode) {
  583. if (!dst) {
  584. return src;
  585. }
  586. if (!src) {
  587. return dst;
  588. }
  589. if (as_MFB(dst)->getFormat() != SkMask::kA8_Format ||
  590. as_MFB(src)->getFormat() != SkMask::kA8_Format) {
  591. return nullptr;
  592. }
  593. return sk_sp<SkMaskFilter>(new SkCombineMF(std::move(dst), std::move(src), mode));
  594. }
  595. sk_sp<SkMaskFilter> SkMaskFilter::makeWithMatrix(const SkMatrix& lm) const {
  596. sk_sp<SkMaskFilter> me = sk_ref_sp(const_cast<SkMaskFilter*>(this));
  597. if (lm.isIdentity()) {
  598. return me;
  599. }
  600. return sk_sp<SkMaskFilter>(new SkMatrixMF(std::move(me), lm));
  601. }
  602. void SkMaskFilter::RegisterFlattenables() {
  603. SK_REGISTER_FLATTENABLE(SkMatrixMF);
  604. SK_REGISTER_FLATTENABLE(SkComposeMF);
  605. SK_REGISTER_FLATTENABLE(SkCombineMF);
  606. sk_register_blur_maskfilter_createproc();
  607. #if SK_SUPPORT_GPU
  608. gr_register_sdf_maskfilter_createproc();
  609. #endif
  610. }