aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/text/GrSDFMaskFilter.cpp
blob: ff79cdb3f0fe2bc4fcdc27048c279941a11ba4b7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
/*
 * Copyright 2018 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "GrSDFMaskFilter.h"
#include "SkDistanceFieldGen.h"
#include "SkMaskFilterBase.h"
#include "SkReadBuffer.h"
#include "SkSafeMath.h"
#include "SkWriteBuffer.h"
#include "SkString.h"

class SK_API GrSDFMaskFilterImpl : public SkMaskFilterBase {
public:
    GrSDFMaskFilterImpl();

    // overrides from SkMaskFilterBase
    //  This method is not exported to java.
    SkMask::Format getFormat() const override;
    //  This method is not exported to java.
    bool filterMask(SkMask* dst, const SkMask& src, const SkMatrix&,
                    SkIPoint* margin) const override;

    void computeFastBounds(const SkRect&, SkRect*) const override;

    void toString(SkString* str) const override;
    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(GrSDFMaskFilterImpl)

protected:

private:
    typedef SkMaskFilter INHERITED;
    friend void gr_register_sdf_maskfilter_createproc();
};

///////////////////////////////////////////////////////////////////////////////

GrSDFMaskFilterImpl::GrSDFMaskFilterImpl() {}

SkMask::Format GrSDFMaskFilterImpl::getFormat() const {
    return SkMask::kSDF_Format;
}

bool GrSDFMaskFilterImpl::filterMask(SkMask* dst, const SkMask& src,
                                 const SkMatrix& matrix, SkIPoint* margin) const {
    if (src.fFormat != SkMask::kA8_Format && src.fFormat != SkMask::kBW_Format) {
        return false;
    }

    *dst = SkMask::PrepareDestination(SK_DistanceFieldPad, SK_DistanceFieldPad, src);
    dst->fFormat = SkMask::kSDF_Format;

    if (margin) {
        margin->set(SK_DistanceFieldPad, SK_DistanceFieldPad);
    }

    if (src.fImage == nullptr) {
        return true;
    }
    if (dst->fImage == nullptr) {
        dst->fBounds.setEmpty();
        return false;
    }

    if (src.fFormat == SkMask::kA8_Format) {
        return SkGenerateDistanceFieldFromA8Image(dst->fImage, src.fImage,
                                                  src.fBounds.width(), src.fBounds.height(),
                                                  src.fRowBytes);

    } else {
        return SkGenerateDistanceFieldFromBWImage(dst->fImage, src.fImage,
                                                  src.fBounds.width(), src.fBounds.height(),
                                                  src.fRowBytes);
    }
}

void GrSDFMaskFilterImpl::computeFastBounds(const SkRect& src,
                                            SkRect* dst) const {
    dst->set(src.fLeft  - SK_DistanceFieldPad, src.fTop    - SK_DistanceFieldPad,
             src.fRight + SK_DistanceFieldPad, src.fBottom + SK_DistanceFieldPad);
}

sk_sp<SkFlattenable> GrSDFMaskFilterImpl::CreateProc(SkReadBuffer& buffer) {
    return GrSDFMaskFilter::Make();
}

void GrSDFMaskFilterImpl::toString(SkString* str) const {
    str->append("GrSDFMaskFilterImpl: ()");
}

void gr_register_sdf_maskfilter_createproc() {
    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(GrSDFMaskFilterImpl)
}

///////////////////////////////////////////////////////////////////////////////

sk_sp<SkMaskFilter> GrSDFMaskFilter::Make() {
    return sk_sp<SkMaskFilter>(new GrSDFMaskFilterImpl());
}