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