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
16class GrSDFMaskFilterImpl : public SkMaskFilterBase {
17public:
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
29protected:
30
31private:
32 SK_FLATTENABLE_HOOKS(GrSDFMaskFilterImpl)
33
34 typedef SkMaskFilter INHERITED;
35 friend void gr_register_sdf_maskfilter_createproc();
36};
37
38///////////////////////////////////////////////////////////////////////////////
39
40GrSDFMaskFilterImpl::GrSDFMaskFilterImpl() {}
41
42SkMask::Format GrSDFMaskFilterImpl::getFormat() const {
43 return SkMask::kSDF_Format;
44}
45
46bool 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
84void 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
90sk_sp<SkFlattenable> GrSDFMaskFilterImpl::CreateProc(SkReadBuffer& buffer) {
91 return GrSDFMaskFilter::Make();
92}
93
94void gr_register_sdf_maskfilter_createproc() { SK_REGISTER_FLATTENABLE(GrSDFMaskFilterImpl); }
95
96///////////////////////////////////////////////////////////////////////////////
97
98sk_sp<SkMaskFilter> GrSDFMaskFilter::Make() {
99 return sk_sp<SkMaskFilter>(new GrSDFMaskFilterImpl());
100}
101