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 "include/core/SkString.h"
9 #include "src/core/SkDistanceFieldGen.h"
10 #include "src/core/SkMaskFilterBase.h"
11 #include "src/core/SkReadBuffer.h"
12 #include "src/core/SkSafeMath.h"
13 #include "src/core/SkWriteBuffer.h"
14 #include "src/gpu/text/GrSDFMaskFilter.h"
15 
16 class 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 
GrSDFMaskFilterImpl()40 GrSDFMaskFilterImpl::GrSDFMaskFilterImpl() {}
41 
getFormat() const42 SkMask::Format GrSDFMaskFilterImpl::getFormat() const {
43     return SkMask::kSDF_Format;
44 }
45 
filterMask(SkMask * dst,const SkMask & src,const SkMatrix & matrix,SkIPoint * margin) const46 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 
computeFastBounds(const SkRect & src,SkRect * dst) const84 void GrSDFMaskFilterImpl::computeFastBounds(const SkRect& src,
85                                             SkRect* dst) const {
86     dst->setLTRB(src.fLeft  - SK_DistanceFieldPad, src.fTop    - SK_DistanceFieldPad,
87                  src.fRight + SK_DistanceFieldPad, src.fBottom + SK_DistanceFieldPad);
88 }
89 
CreateProc(SkReadBuffer & buffer)90 sk_sp<SkFlattenable> GrSDFMaskFilterImpl::CreateProc(SkReadBuffer& buffer) {
91     return GrSDFMaskFilter::Make();
92 }
93 
gr_register_sdf_maskfilter_createproc()94 void gr_register_sdf_maskfilter_createproc() { SK_REGISTER_FLATTENABLE(GrSDFMaskFilterImpl); }
95 
96 ///////////////////////////////////////////////////////////////////////////////
97 
Make()98 sk_sp<SkMaskFilter> GrSDFMaskFilter::Make() {
99     return sk_sp<SkMaskFilter>(new GrSDFMaskFilterImpl());
100 }
101