Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
SkEmbossMaskFilter.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2006 The Android Open Source Project
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
9
16#include "src/core/SkBlurMask.h"
20
21#if defined(SK_SUPPORT_LEGACY_EMBOSSMASKFILTER)
23#endif
24
25#include <cstring>
26
28 if (!SkIsFinite(blurSigma) || blurSigma <= 0) {
29 return nullptr;
30 }
31
32 SkPoint3 lightDir{light.fDirection[0], light.fDirection[1], light.fDirection[2]};
33 if (!lightDir.normalize()) {
34 return nullptr;
35 }
36 Light newLight = light;
37 newLight.fDirection[0] = lightDir.x();
38 newLight.fDirection[1] = lightDir.y();
39 newLight.fDirection[2] = lightDir.z();
40
41 return sk_sp<SkMaskFilter>(new SkEmbossMaskFilter(blurSigma, newLight));
42}
43
44#ifdef SK_SUPPORT_LEGACY_EMBOSSMASKFILTER
45sk_sp<SkMaskFilter> SkBlurMaskFilter::MakeEmboss(SkScalar blurSigma, const SkScalar direction[3],
46 SkScalar ambient, SkScalar specular) {
47 if (direction == nullptr) {
48 return nullptr;
49 }
50
52
53 memcpy(light.fDirection, direction, sizeof(light.fDirection));
54 // ambient should be 0...1 as a scalar
55 light.fAmbient = SkUnitScalarClampToByte(ambient);
56 // specular should be 0..15.99 as a scalar
57 static const SkScalar kSpecularMultiplier = SkIntToScalar(255) / 16;
58 light.fSpecular = static_cast<U8CPU>(SkTPin(specular, 0.0f, 16.0f) * kSpecularMultiplier + 0.5);
59
60 return SkEmbossMaskFilter::Make(blurSigma, light);
61}
62#endif
63
64///////////////////////////////////////////////////////////////////////////////
65
67 : fLight(light), fBlurSigma(blurSigma)
68{
69 SkASSERT(fBlurSigma > 0);
70 SkASSERT(SkIsFinite(fLight.fDirection, 3));
71}
72
76
78 const SkMatrix& matrix, SkIPoint* margin) const {
79 if (src.fFormat != SkMask::kA8_Format) {
80 return false;
81 }
82
83 SkScalar sigma = matrix.mapRadius(fBlurSigma);
84
85 if (!SkBlurMask::BoxBlur(dst, src, sigma, kInner_SkBlurStyle)) {
86 return false;
87 }
88
89 dst->format() = SkMask::k3D_Format;
90 if (margin) {
91 margin->set(SkScalarCeilToInt(3*sigma), SkScalarCeilToInt(3*sigma));
92 }
93
94 if (src.fImage == nullptr) {
95 return true;
96 }
97
98 // create a larger buffer for the other two channels (should force fBlur to do this for us)
99
100 {
101 uint8_t* alphaPlane = dst->image();
102 size_t planeSize = dst->computeImageSize();
103 if (0 == planeSize) {
104 return false; // too big to allocate, abort
105 }
106 dst->image() = SkMaskBuilder::AllocImage(planeSize * 3);
107 memcpy(dst->image(), alphaPlane, planeSize);
108 SkMaskBuilder::FreeImage(alphaPlane);
109 }
110
111 // run the light direction through the matrix...
112 Light light = fLight;
113 matrix.mapVectors((SkVector*)(void*)light.fDirection,
114 (SkVector*)(void*)fLight.fDirection, 1);
115
116 // now restore the length of the XY component
117 // cast to SkVector so we can call setLength (this double cast silences alias warnings)
118 SkVector* vec = (SkVector*)(void*)light.fDirection;
119 vec->setLength(light.fDirection[0],
120 light.fDirection[1],
121 SkPoint::Length(fLight.fDirection[0], fLight.fDirection[1]));
122
123 SkEmbossMask::Emboss(dst, light);
124
125 // restore original alpha
126 memcpy(dst->image(), src.fImage, src.computeImageSize());
127
128 return true;
129}
130
131sk_sp<SkFlattenable> SkEmbossMaskFilter::CreateProc(SkReadBuffer& buffer) {
132 Light light;
133 if (buffer.readByteArray(&light, sizeof(Light))) {
134 light.fPad = 0; // for the font-cache lookup to be clean
135 const SkScalar sigma = buffer.readScalar();
136 return Make(sigma, light);
137 }
138 return nullptr;
139}
140
142 Light tmpLight = fLight;
143 tmpLight.fPad = 0; // for the font-cache lookup to be clean
144 buffer.writeByteArray(&tmpLight, sizeof(tmpLight));
145 buffer.writeScalar(fBlurSigma);
146}
#define SkASSERT(cond)
Definition SkAssert.h:116
@ kInner_SkBlurStyle
fuzzy inside, nothing outside
Definition SkBlurTypes.h:15
unsigned U8CPU
Definition SkCPUTypes.h:18
static U8CPU SkUnitScalarClampToByte(SkScalar x)
Definition SkColorPriv.h:36
static bool SkIsFinite(T x, Pack... values)
#define SkScalarCeilToInt(x)
Definition SkScalar.h:36
#define SkIntToScalar(x)
Definition SkScalar.h:57
static constexpr const T & SkTPin(const T &x, const T &lo, const T &hi)
Definition SkTPin.h:19
static bool BoxBlur(SkMaskBuilder *dst, const SkMask &src, SkScalar sigma, SkBlurStyle style, SkIPoint *margin=nullptr)
SkMask::Format getFormat() const override
static sk_sp< SkMaskFilter > Make(SkScalar blurSigma, const Light &light)
bool filterMask(SkMaskBuilder *dst, const SkMask &src, const SkMatrix &, SkIPoint *margin) const override
SkEmbossMaskFilter(SkScalar blurSigma, const Light &light)
void flatten(SkWriteBuffer &) const override
static void Emboss(SkMaskBuilder *mask, const SkEmbossMaskFilter::Light &)
float SkScalar
Definition extension.cpp:12
static const uint8_t buffer[]
void set(int32_t x, int32_t y)
static void FreeImage(void *image)
Definition SkMask.cpp:57
static uint8_t * AllocImage(size_t bytes, AllocType=kUninit_Alloc)
Definition SkMask.cpp:45
Format
Definition SkMask.h:26
@ k3D_Format
3 8bit per pixl planes: alpha, mul, add
Definition SkMask.h:29
@ kA8_Format
8bits per pixel mask (e.g. antialiasing)
Definition SkMask.h:28
bool setLength(float length)
Definition SkPoint.cpp:30
static float Length(float x, float y)
Definition SkPoint.cpp:79