1 /* 2 * Copyright 2018 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 "GrSDFMaskFilter.h" 9 #include "SkDistanceFieldGen.h" 10 #include "SkMaskFilterBase.h" 11 #include "SkReadBuffer.h" 12 #include "SkSafeMath.h" 13 #include "SkWriteBuffer.h" 14 #include "SkString.h" 15 16 class SK_API GrSDFMaskFilterImpl : public SkMaskFilterBase { 17 public: 18 GrSDFMaskFilterImpl(); 19 20 // overrides from SkMaskFilterBase 21 // This method is not exported to java. 22 SkMask::Format getFormat() const override; 23 // This method is not exported to java. 24 bool filterMask(SkMask* dst, const SkMask& src, const SkMatrix&, 25 SkIPoint* margin) const override; 26 27 void computeFastBounds(const SkRect&, SkRect*) const override; 28 29 protected: 30 31 private: 32 SK_FLATTENABLE_HOOKS(GrSDFMaskFilterImpl) 33 34 typedef SkMaskFilter INHERITED; 35 friend void gr_register_sdf_maskfilter_createproc(); 36 }; 37 38 /////////////////////////////////////////////////////////////////////////////// 39 40 GrSDFMaskFilterImpl::GrSDFMaskFilterImpl() {} 41 42 SkMask::Format GrSDFMaskFilterImpl::getFormat() const { 43 return SkMask::kSDF_Format; 44 } 45 46 bool GrSDFMaskFilterImpl::filterMask(SkMask* dst, const SkMask& src, 47 const SkMatrix& matrix, SkIPoint* margin) const { 48 if (src.fFormat != SkMask::kA8_Format 49 && src.fFormat != SkMask::kBW_Format 50 && src.fFormat != SkMask::kLCD16_Format) { 51 return false; 52 } 53 54 *dst = SkMask::PrepareDestination(SK_DistanceFieldPad, SK_DistanceFieldPad, src); 55 dst->fFormat = SkMask::kSDF_Format; 56 57 if (margin) { 58 margin->set(SK_DistanceFieldPad, SK_DistanceFieldPad); 59 } 60 61 if (src.fImage == nullptr) { 62 return true; 63 } 64 if (dst->fImage == nullptr) { 65 dst->fBounds.setEmpty(); 66 return false; 67 } 68 69 if (src.fFormat == SkMask::kA8_Format) { 70 return SkGenerateDistanceFieldFromA8Image(dst->fImage, src.fImage, 71 src.fBounds.width(), src.fBounds.height(), 72 src.fRowBytes); 73 } else if (src.fFormat == SkMask::kLCD16_Format) { 74 return SkGenerateDistanceFieldFromLCD16Mask(dst->fImage, src.fImage, 75 src.fBounds.width(), src.fBounds.height(), 76 src.fRowBytes); 77 } else { 78 return SkGenerateDistanceFieldFromBWImage(dst->fImage, src.fImage, 79 src.fBounds.width(), src.fBounds.height(), 80 src.fRowBytes); 81 } 82 } 83 84 void GrSDFMaskFilterImpl::computeFastBounds(const SkRect& src, 85 SkRect* dst) const { 86 dst->set(src.fLeft - SK_DistanceFieldPad, src.fTop - SK_DistanceFieldPad, 87 src.fRight + SK_DistanceFieldPad, src.fBottom + SK_DistanceFieldPad); 88 } 89 90 sk_sp<SkFlattenable> GrSDFMaskFilterImpl::CreateProc(SkReadBuffer& buffer) { 91 return GrSDFMaskFilter::Make(); 92 } 93 94 void gr_register_sdf_maskfilter_createproc() { SK_REGISTER_FLATTENABLE(GrSDFMaskFilterImpl); } 95 96 /////////////////////////////////////////////////////////////////////////////// 97 98 sk_sp<SkMaskFilter> GrSDFMaskFilter::Make() { 99 return sk_sp<SkMaskFilter>(new GrSDFMaskFilterImpl()); 100 } 101