Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Static Public Member Functions | List of all members
SkBlurMask Class Reference

#include <SkBlurMask.h>

Static Public Member Functions

static bool BlurRect (SkScalar sigma, SkMaskBuilder *dst, const SkRect &src, SkBlurStyle, SkIPoint *margin=nullptr, SkMaskBuilder::CreateMode createMode=SkMaskBuilder::kComputeBoundsAndRenderImage_CreateMode)
 
static bool BlurRRect (SkScalar sigma, SkMaskBuilder *dst, const SkRRect &src, SkBlurStyle, SkIPoint *margin=nullptr, SkMaskBuilder::CreateMode createMode=SkMaskBuilder::kComputeBoundsAndRenderImage_CreateMode)
 
static bool BoxBlur (SkMaskBuilder *dst, const SkMask &src, SkScalar sigma, SkBlurStyle style, SkIPoint *margin=nullptr)
 
static bool BlurGroundTruth (SkScalar sigma, SkMaskBuilder *dst, const SkMask &src, SkBlurStyle, SkIPoint *margin=nullptr)
 
static SkScalar SK_SPI ConvertRadiusToSigma (SkScalar radius)
 
static SkScalar SK_SPI ConvertSigmaToRadius (SkScalar sigma)
 
static uint8_t ProfileLookup (const uint8_t *profile, int loc, int blurredWidth, int sharpWidth)
 
static void ComputeBlurProfile (uint8_t *profile, int size, SkScalar sigma)
 
static void ComputeBlurredScanline (uint8_t *pixels, const uint8_t *profile, unsigned int width, SkScalar sigma)
 

Detailed Description

Definition at line 22 of file SkBlurMask.h.

Member Function Documentation

◆ BlurGroundTruth()

bool SkBlurMask::BlurGroundTruth ( SkScalar  sigma,
SkMaskBuilder dst,
const SkMask src,
SkBlurStyle  style,
SkIPoint margin = nullptr 
)
static

Definition at line 517 of file SkBlurMask.cpp.

518 {
519
520 if (src.fFormat != SkMask::kA8_Format) {
521 return false;
522 }
523
524 float variance = sigma * sigma;
525
526 int windowSize = SkScalarCeilToInt(sigma*6);
527 // round window size up to nearest odd number
528 windowSize |= 1;
529
530 AutoTMalloc<float> gaussWindow(windowSize);
531
532 int halfWindow = windowSize >> 1;
533
534 gaussWindow[halfWindow] = 1;
535
536 float windowSum = 1;
537 for (int x = 1 ; x <= halfWindow ; ++x) {
538 float gaussian = expf(-x*x / (2*variance));
539 gaussWindow[halfWindow + x] = gaussWindow[halfWindow-x] = gaussian;
540 windowSum += 2*gaussian;
541 }
542
543 // leave the filter un-normalized for now; we will divide by the normalization
544 // sum later;
545
546 int pad = halfWindow;
547 if (margin) {
548 margin->set( pad, pad );
549 }
550
551 dst->bounds() = src.fBounds;
552 dst->bounds().outset(pad, pad);
553
554 dst->rowBytes() = dst->fBounds.width();
555 dst->format() = SkMask::kA8_Format;
556 dst->image() = nullptr;
557
558 if (src.fImage) {
559
560 size_t dstSize = dst->computeImageSize();
561 if (0 == dstSize) {
562 return false; // too big to allocate, abort
563 }
564
565 int srcWidth = src.fBounds.width();
566 int srcHeight = src.fBounds.height();
567 int dstWidth = dst->fBounds.width();
568
569 const uint8_t* srcPixels = src.fImage;
570 uint8_t* dstPixels = SkMaskBuilder::AllocImage(dstSize);
571 SkAutoMaskFreeImage autoFreeDstPixels(dstPixels);
572
573 // do the actual blur. First, make a padded copy of the source.
574 // use double pad so we never have to check if we're outside anything
575
576 int padWidth = srcWidth + 4*pad;
577 int padHeight = srcHeight;
578 int padSize = padWidth * padHeight;
579
580 AutoTMalloc<uint8_t> padPixels(padSize);
581 memset(padPixels, 0, padSize);
582
583 for (int y = 0 ; y < srcHeight; ++y) {
584 uint8_t* padptr = padPixels + y * padWidth + 2*pad;
585 const uint8_t* srcptr = srcPixels + y * srcWidth;
586 memcpy(padptr, srcptr, srcWidth);
587 }
588
589 // blur in X, transposing the result into a temporary floating point buffer.
590 // also double-pad the intermediate result so that the second blur doesn't
591 // have to do extra conditionals.
592
593 int tmpWidth = padHeight + 4*pad;
594 int tmpHeight = padWidth - 2*pad;
595 int tmpSize = tmpWidth * tmpHeight;
596
597 AutoTMalloc<float> tmpImage(tmpSize);
598 memset(tmpImage, 0, tmpSize*sizeof(tmpImage[0]));
599
600 for (int y = 0 ; y < padHeight ; ++y) {
601 uint8_t *srcScanline = padPixels + y*padWidth;
602 for (int x = pad ; x < padWidth - pad ; ++x) {
603 float *outPixel = tmpImage + (x-pad)*tmpWidth + y + 2*pad; // transposed output
604 uint8_t *windowCenter = srcScanline + x;
605 for (int i = -pad ; i <= pad ; ++i) {
606 *outPixel += gaussWindow[pad+i]*windowCenter[i];
607 }
608 *outPixel /= windowSum;
609 }
610 }
611
612 // blur in Y; now filling in the actual desired destination. We have to do
613 // the transpose again; these transposes guarantee that we read memory in
614 // linear order.
615
616 for (int y = 0 ; y < tmpHeight ; ++y) {
617 float *srcScanline = tmpImage + y*tmpWidth;
618 for (int x = pad ; x < tmpWidth - pad ; ++x) {
619 float *windowCenter = srcScanline + x;
620 float finalValue = 0;
621 for (int i = -pad ; i <= pad ; ++i) {
622 finalValue += gaussWindow[pad+i]*windowCenter[i];
623 }
624 finalValue /= windowSum;
625 uint8_t *outPixel = dstPixels + (x-pad)*dstWidth + y; // transposed output
626 int integerPixel = int(finalValue + 0.5f);
627 *outPixel = SkTPin(SkClampPos(integerPixel), 0, 255);
628 }
629 }
630
631 dst->image() = dstPixels;
632 switch (style) {
634 break;
635 case kSolid_SkBlurStyle: {
637 dstPixels + pad*dst->fRowBytes + pad, dst->fRowBytes,
638 SkMask::AlphaIter<SkMask::kA8_Format>(srcPixels), src.fRowBytes,
639 srcWidth, srcHeight);
640 } break;
641 case kOuter_SkBlurStyle: {
643 dstPixels + pad*dst->fRowBytes + pad, dst->fRowBytes,
644 SkMask::AlphaIter<SkMask::kA8_Format>(srcPixels), src.fRowBytes,
645 srcWidth, srcHeight);
646 } break;
647 case kInner_SkBlurStyle: {
648 // now we allocate the "real" dst, mirror the size of src
649 size_t srcSize = src.computeImageSize();
650 if (0 == srcSize) {
651 return false; // too big to allocate, abort
652 }
653 dst->image() = SkMaskBuilder::AllocImage(srcSize);
654 merge_src_with_blur(dst->image(), src.fRowBytes,
655 SkMask::AlphaIter<SkMask::kA8_Format>(srcPixels), src.fRowBytes,
656 dstPixels + pad*dst->fRowBytes + pad,
657 dst->fRowBytes, srcWidth, srcHeight);
658 SkMaskBuilder::FreeImage(dstPixels);
659 } break;
660 }
661 autoFreeDstPixels.release();
662 }
663
664 if (style == kInner_SkBlurStyle) {
665 dst->bounds() = src.fBounds; // restore trimmed bounds
666 dst->rowBytes() = src.fRowBytes;
667 }
668
669 return true;
670}
static float gaussian(int x, SkScalar sigma)
Definition BlurTest.cpp:223
static void merge_src_with_blur(uint8_t dst[], int dstRB, AlphaIter src, int srcRB, const uint8_t blur[], int blurRB, int sw, int sh)
static void clamp_solid_with_orig(uint8_t dst[], int dstRowBytes, AlphaIter src, int srcRowBytes, int sw, int sh)
static void clamp_outer_with_orig(uint8_t dst[], int dstRowBytes, AlphaIter src, int srcRowBytes, int sw, int sh)
@ kOuter_SkBlurStyle
nothing inside, fuzzy outside
Definition SkBlurTypes.h:14
@ kSolid_SkBlurStyle
solid inside, fuzzy outside
Definition SkBlurTypes.h:13
@ kInner_SkBlurStyle
fuzzy inside, nothing outside
Definition SkBlurTypes.h:15
@ kNormal_SkBlurStyle
fuzzy inside and outside
Definition SkBlurTypes.h:12
std::unique_ptr< uint8_t, SkFunctionObject< SkMaskBuilder::FreeImage > > SkAutoMaskFreeImage
Definition SkMask.h:316
static int SkClampPos(int value)
Definition SkMathPriv.h:30
#define SkScalarCeilToInt(x)
Definition SkScalar.h:36
static constexpr const T & SkTPin(const T &x, const T &lo, const T &hi)
Definition SkTPin.h:19
Type::kYUV Type::kRGBA() int(0.7 *637)
double y
double x
dst
Definition cp.py:12
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
@ kA8_Format
8bits per pixel mask (e.g. antialiasing)
Definition SkMask.h:28

◆ BlurRect()

bool SkBlurMask::BlurRect ( SkScalar  sigma,
SkMaskBuilder dst,
const SkRect src,
SkBlurStyle  style,
SkIPoint margin = nullptr,
SkMaskBuilder::CreateMode  createMode = SkMaskBuilder::kComputeBoundsAndRenderImage_CreateMode 
)
static

Definition at line 407 of file SkBlurMask.cpp.

409 {
410 int profileSize = SkScalarCeilToInt(6*sigma);
411 if (profileSize <= 0) {
412 return false; // no blur to compute
413 }
414
415 int pad = profileSize/2;
416 if (margin) {
417 margin->set( pad, pad );
418 }
419
420 dst->bounds().setLTRB(SkScalarRoundToInt(src.fLeft - pad),
421 SkScalarRoundToInt(src.fTop - pad),
422 SkScalarRoundToInt(src.fRight + pad),
423 SkScalarRoundToInt(src.fBottom + pad));
424
425 dst->rowBytes() = dst->fBounds.width();
426 dst->format() = SkMask::kA8_Format;
427 dst->image() = nullptr;
428
429 int sw = SkScalarFloorToInt(src.width());
430 int sh = SkScalarFloorToInt(src.height());
431
433 if (style == kInner_SkBlurStyle) {
434 dst->bounds() = src.round(); // restore trimmed bounds
435 dst->rowBytes() = sw;
436 }
437 return true;
438 }
439
440 AutoTMalloc<uint8_t> profile(profileSize);
441
442 ComputeBlurProfile(profile, profileSize, sigma);
443
444 size_t dstSize = dst->computeImageSize();
445 if (0 == dstSize) {
446 return false; // too big to allocate, abort
447 }
448
449 uint8_t* dp = SkMaskBuilder::AllocImage(dstSize);
450 dst->image() = dp;
451
452 int dstHeight = dst->fBounds.height();
453 int dstWidth = dst->fBounds.width();
454
455 uint8_t *outptr = dp;
456
457 AutoTMalloc<uint8_t> horizontalScanline(dstWidth);
458 AutoTMalloc<uint8_t> verticalScanline(dstHeight);
459
460 ComputeBlurredScanline(horizontalScanline, profile, dstWidth, sigma);
461 ComputeBlurredScanline(verticalScanline, profile, dstHeight, sigma);
462
463 for (int y = 0 ; y < dstHeight ; ++y) {
464 for (int x = 0 ; x < dstWidth ; x++) {
465 unsigned int maskval = SkMulDiv255Round(horizontalScanline[x], verticalScanline[y]);
466 *(outptr++) = maskval;
467 }
468 }
469
470 if (style == kInner_SkBlurStyle) {
471 // now we allocate the "real" dst, mirror the size of src
472 size_t srcSize = (size_t)(src.width() * src.height());
473 if (0 == srcSize) {
474 return false; // too big to allocate, abort
475 }
476 dst->image() = SkMaskBuilder::AllocImage(srcSize);
477 for (int y = 0 ; y < sh ; y++) {
478 uint8_t *blur_scanline = dp + (y+pad)*dstWidth + pad;
479 uint8_t *inner_scanline = dst->image() + y*sw;
480 memcpy(inner_scanline, blur_scanline, sw);
481 }
483
484 dst->bounds() = src.round(); // restore trimmed bounds
485 dst->rowBytes() = sw;
486
487 } else if (style == kOuter_SkBlurStyle) {
488 for (int y = pad ; y < dstHeight-pad ; y++) {
489 uint8_t *dst_scanline = dp + y*dstWidth + pad;
490 memset(dst_scanline, 0, sw);
491 }
492 } else if (style == kSolid_SkBlurStyle) {
493 for (int y = pad ; y < dstHeight-pad ; y++) {
494 uint8_t *dst_scanline = dp + y*dstWidth + pad;
495 memset(dst_scanline, 0xff, sw);
496 }
497 }
498 // normal and solid styles are the same for analytic rect blurs, so don't
499 // need to handle solid specially.
500
501 return true;
502}
static U8CPU SkMulDiv255Round(U16CPU a, U16CPU b)
Definition SkMath.h:73
#define SkScalarRoundToInt(x)
Definition SkScalar.h:37
#define SkScalarFloorToInt(x)
Definition SkScalar.h:35
static void inner_scanline(FDot8 L, int top, FDot8 R, U8CPU alpha, SkBlitter *blitter)
static void ComputeBlurProfile(uint8_t *profile, int size, SkScalar sigma)
static void ComputeBlurredScanline(uint8_t *pixels, const uint8_t *profile, unsigned int width, SkScalar sigma)
@ kJustComputeBounds_CreateMode
compute bounds and return
Definition SkMask.h:299

◆ BlurRRect()

bool SkBlurMask::BlurRRect ( SkScalar  sigma,
SkMaskBuilder dst,
const SkRRect src,
SkBlurStyle  style,
SkIPoint margin = nullptr,
SkMaskBuilder::CreateMode  createMode = SkMaskBuilder::kComputeBoundsAndRenderImage_CreateMode 
)
static

Definition at line 504 of file SkBlurMask.cpp.

506 {
507 // Temporary for now -- always fail, should cause caller to fall back
508 // to old path. Plumbing just to land API and parallelize effort.
509
510 return false;
511}

◆ BoxBlur()

bool SkBlurMask::BoxBlur ( SkMaskBuilder dst,
const SkMask src,
SkScalar  sigma,
SkBlurStyle  style,
SkIPoint margin = nullptr 
)
static

Definition at line 116 of file SkBlurMask.cpp.

117 {
118 if (src.fFormat != SkMask::kBW_Format &&
119 src.fFormat != SkMask::kA8_Format &&
120 src.fFormat != SkMask::kARGB32_Format &&
121 src.fFormat != SkMask::kLCD16_Format)
122 {
123 return false;
124 }
125
126 SkMaskBlurFilter blurFilter{sigma, sigma};
127 if (blurFilter.hasNoBlur()) {
128 // If there is no effective blur most styles will just produce the original mask.
129 // However, kOuter_SkBlurStyle will produce an empty mask.
130 if (style == kOuter_SkBlurStyle) {
131 dst->image() = nullptr;
132 dst->bounds() = SkIRect::MakeEmpty();
133 dst->rowBytes() = dst->fBounds.width();
134 dst->format() = SkMask::kA8_Format;
135 if (margin != nullptr) {
136 // This filter will disregard the src.fImage completely.
137 // The margin is actually {-(src.fBounds.width() / 2), -(src.fBounds.height() / 2)}
138 // but it is not clear if callers will fall over with negative margins.
139 *margin = SkIPoint{0,0};
140 }
141 return true;
142 }
143 return false;
144 }
145 const SkIPoint border = blurFilter.blur(src, dst);
146 // If src.fImage is null, then this call is only to calculate the border.
147 if (src.fImage != nullptr && dst->fImage == nullptr) {
148 return false;
149 }
150
151 if (margin != nullptr) {
152 *margin = border;
153 }
154
155 if (src.fImage == nullptr) {
156 if (style == kInner_SkBlurStyle) {
157 dst->bounds() = src.fBounds; // restore trimmed bounds
158 dst->rowBytes() = dst->fBounds.width();
159 }
160 return true;
161 }
162
163 switch (style) {
165 break;
166 case kSolid_SkBlurStyle: {
167 auto dstStart = &dst->image()[border.x() + border.y() * dst->fRowBytes];
168 switch (src.fFormat) {
171 dstStart, dst->fRowBytes,
172 SkMask::AlphaIter<SkMask::kBW_Format>(src.fImage, 0), src.fRowBytes,
173 src.fBounds.width(), src.fBounds.height());
174 break;
177 dstStart, dst->fRowBytes,
179 src.fBounds.width(), src.fBounds.height());
180 break;
182 const uint32_t* srcARGB = reinterpret_cast<const uint32_t*>(src.fImage);
184 dstStart, dst->fRowBytes,
186 src.fBounds.width(), src.fBounds.height());
187 } break;
189 const uint16_t* srcLCD = reinterpret_cast<const uint16_t*>(src.fImage);
191 dstStart, dst->fRowBytes,
193 src.fBounds.width(), src.fBounds.height());
194 } break;
195 default:
196 SK_ABORT("Unhandled format.");
197 }
198 } break;
199 case kOuter_SkBlurStyle: {
200 auto dstStart = &dst->image()[border.x() + border.y() * dst->fRowBytes];
201 switch (src.fFormat) {
204 dstStart, dst->fRowBytes,
205 SkMask::AlphaIter<SkMask::kBW_Format>(src.fImage, 0), src.fRowBytes,
206 src.fBounds.width(), src.fBounds.height());
207 break;
210 dstStart, dst->fRowBytes,
212 src.fBounds.width(), src.fBounds.height());
213 break;
215 const uint32_t* srcARGB = reinterpret_cast<const uint32_t*>(src.fImage);
217 dstStart, dst->fRowBytes,
219 src.fBounds.width(), src.fBounds.height());
220 } break;
222 const uint16_t* srcLCD = reinterpret_cast<const uint16_t*>(src.fImage);
224 dstStart, dst->fRowBytes,
226 src.fBounds.width(), src.fBounds.height());
227 } break;
228 default:
229 SK_ABORT("Unhandled format.");
230 }
231 } break;
232 case kInner_SkBlurStyle: {
233 // now we allocate the "real" dst, mirror the size of src
234 SkMaskBuilder blur = std::move(*dst);
235 SkAutoMaskFreeImage autoFreeBlurMask(blur.image());
236
237 *dst = SkMaskBuilder(nullptr, src.fBounds, src.fBounds.width(), blur.format());
238 size_t dstSize = dst->computeImageSize();
239 if (0 == dstSize) {
240 return false; // too big to allocate, abort
241 }
242 dst->image() = SkMaskBuilder::AllocImage(dstSize);
243
244 auto blurStart = &blur.image()[border.x() + border.y() * blur.fRowBytes];
245 switch (src.fFormat) {
248 dst->image(), dst->fRowBytes,
249 SkMask::AlphaIter<SkMask::kBW_Format>(src.fImage, 0), src.fRowBytes,
250 blurStart, blur.fRowBytes,
251 src.fBounds.width(), src.fBounds.height());
252 break;
255 dst->image(), dst->fRowBytes,
257 blurStart, blur.fRowBytes,
258 src.fBounds.width(), src.fBounds.height());
259 break;
261 const uint32_t* srcARGB = reinterpret_cast<const uint32_t*>(src.fImage);
263 dst->image(), dst->fRowBytes,
265 blurStart, blur.fRowBytes,
266 src.fBounds.width(), src.fBounds.height());
267 } break;
269 const uint16_t* srcLCD = reinterpret_cast<const uint16_t*>(src.fImage);
271 dst->image(), dst->fRowBytes,
273 blurStart, blur.fRowBytes,
274 src.fBounds.width(), src.fBounds.height());
275 } break;
276 default:
277 SK_ABORT("Unhandled format.");
278 }
279 } break;
280 }
281
282 return true;
283}
#define SK_ABORT(message,...)
Definition SkAssert.h:70
constexpr int32_t y() const
constexpr int32_t x() const
static constexpr SkIRect MakeEmpty()
Definition SkRect.h:45
Format & format()
Definition SkMask.h:239
uint8_t *& image()
Definition SkMask.h:236
const uint32_t fRowBytes
Definition SkMask.h:43
@ kLCD16_Format
565 alpha for r/g/b
Definition SkMask.h:31
@ kARGB32_Format
SkPMColor.
Definition SkMask.h:30
@ kBW_Format
1bit per pixel mask (e.g. monochrome)
Definition SkMask.h:27

◆ ComputeBlurProfile()

void SkBlurMask::ComputeBlurProfile ( uint8_t *  profile,
int  size,
SkScalar  sigma 
)
static

Populate the profile of a 1D blurred halfplane.

Parameters
profileThe 1D table to fill in
sizeShould be 6*sigma bytes
sigmaThe standard deviation of the gaussian blur kernel

Definition at line 349 of file SkBlurMask.cpp.

349 {
350 SkASSERT(SkScalarCeilToInt(6*sigma) == size);
351
352 int center = size >> 1;
353
354 float invr = 1.f/(2*sigma);
355
356 profile[0] = 255;
357 for (int x = 1 ; x < size ; ++x) {
358 float scaled_x = (center - x - .5f) * invr;
359 float gi = gaussianIntegral(scaled_x);
360 profile[x] = 255 - (uint8_t) (255.f * gi);
361 }
362}
#define SkASSERT(cond)
Definition SkAssert.h:116
static float gaussianIntegral(float x)
static SkScalar center(float pos0, float pos1)
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition switches.h:259

◆ ComputeBlurredScanline()

void SkBlurMask::ComputeBlurredScanline ( uint8_t *  pixels,
const uint8_t *  profile,
unsigned int  width,
SkScalar  sigma 
)
static

Compute an entire scanline of a blurred step function. This is a 1D helper that will produce both the horizontal and vertical profiles of the blurry rectangle.

Parameters
pixelsLocation to store the resulting pixel data; allocated and managed by caller
profilePrecomputed blur profile computed by ComputeBlurProfile above.
widthSize of the pixels array.
sigmaStandard deviation of the gaussian blur kernel used to compute the profile; this implicitly gives the size of the pixels array.

Definition at line 383 of file SkBlurMask.cpp.

384 {
385
386 unsigned int profile_size = SkScalarCeilToInt(6*sigma);
387 skia_private::AutoTMalloc<uint8_t> horizontalScanline(width);
388
389 unsigned int sw = width - profile_size;
390 // nearest odd number less than the profile size represents the center
391 // of the (2x scaled) profile
392 int center = ( profile_size & ~1 ) - 1;
393
394 int w = sw - center;
395
396 for (unsigned int x = 0 ; x < width ; ++x) {
397 if (profile_size <= sw) {
398 pixels[x] = ProfileLookup(profile, x, width, w);
399 } else {
400 float span = float(sw)/(2*sigma);
401 float giX = 1.5f - (x+.5f)/(2*sigma);
402 pixels[x] = (uint8_t) (255 * (gaussianIntegral(giX) - gaussianIntegral(giX + span)));
403 }
404 }
405}
static uint8_t ProfileLookup(const uint8_t *profile, int loc, int blurredWidth, int sharpWidth)
SkScalar w
int32_t width

◆ ConvertRadiusToSigma()

SkScalar SkBlurMask::ConvertRadiusToSigma ( SkScalar  radius)
static

Definition at line 39 of file SkBlurMask.cpp.

39 {
40 return radius > 0 ? kBLUR_SIGMA_SCALE * radius + 0.5f : 0.0f;
41}
static const SkScalar kBLUR_SIGMA_SCALE

◆ ConvertSigmaToRadius()

SkScalar SkBlurMask::ConvertSigmaToRadius ( SkScalar  sigma)
static

Definition at line 43 of file SkBlurMask.cpp.

43 {
44 return sigma > 0.5f ? (sigma - 0.5f) / kBLUR_SIGMA_SCALE : 0.0f;
45}

◆ ProfileLookup()

uint8_t SkBlurMask::ProfileLookup ( const uint8_t *  profile,
int  loc,
int  blurredWidth,
int  sharpWidth 
)
static

Look up the intensity of the (one dimnensional) blurred half-plane.

Parameters
profileThe precomputed 1D blur profile; initialized by ComputeBlurProfile below.
locthe location to look up; The lookup will clamp invalid inputs, but meaningful data are available between 0 and blurred_width
blurred_widthThe width of the final, blurred rectangle
sharp_widthThe width of the original, unblurred rectangle.

Definition at line 371 of file SkBlurMask.cpp.

372 {
373 // how far are we from the original edge?
374 int dx = SkAbs32(((loc << 1) + 1) - blurredWidth) - sharpWidth;
375 int ox = dx >> 1;
376 if (ox < 0) {
377 ox = 0;
378 }
379
380 return profile[ox];
381}
static int32_t SkAbs32(int32_t value)
Definition SkSafe32.h:41
skia_private::AutoTArray< sk_sp< SkImageFilter > > filters TypedMatrix matrix TypedMatrix matrix SkScalar dx
Definition SkRecords.h:208

The documentation for this class was generated from the following files: