xref: /aosp_15_r20/external/skia/src/text/gpu/SDFMaskFilter.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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