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