Alloc glyph image correctly for SkMask::k3D_Format.
This removes the no longer used outside Skia SK_SUPPORT_LEGACY_EMBOSSMASKFILTER define, and either deletes the code it guards or updates it to use the new emboss mask filter factory. This re-enables the code to test the emboss mask filter. Also added is a test to ensure that embossed text is drawn correctly, as before this glyphs did not allocate the proper amount of memory for the k3D_Format which this mask filter produces. This also fixes SkEmbossMask::Emboss to write the whole of the mul and add planes to avoid pixel differences and MemorySanitizer errors. Change-Id: Ib492c72a19d6a27d140e3cd48179a3ca9ce313f5 Reviewed-on: https://skia-review.googlesource.com/70260 Commit-Queue: Ben Wagner <bungeman@google.com> Reviewed-by: Herb Derby <herb@google.com>
This commit is contained in:
parent
0030c5ed3c
commit
6b26deb8d6
@ -6,11 +6,11 @@
|
||||
*/
|
||||
|
||||
#include "gm.h"
|
||||
#include "SkBlurMaskFilter.h"
|
||||
#include "SkBlurMask.h"
|
||||
#include "SkCanvas.h"
|
||||
#include "SkColorFilter.h"
|
||||
#include "SkEmbossMaskFilter.h"
|
||||
|
||||
#ifdef SK_SUPPORT_LEGACY_EMBOSSMASKFILTER
|
||||
static SkBitmap make_bm() {
|
||||
SkBitmap bm;
|
||||
bm.allocN32Pixels(100, 100);
|
||||
@ -41,17 +41,36 @@ protected:
|
||||
SkPaint paint;
|
||||
SkBitmap bm = make_bm();
|
||||
canvas->drawBitmap(bm, 10, 10, &paint);
|
||||
|
||||
const SkScalar dir[] = { 1, 1, 1 };
|
||||
paint.setMaskFilter(SkBlurMaskFilter::MakeEmboss(3, dir, 0.3f, 0.1f));
|
||||
canvas->translate(bm.width() + SkIntToScalar(10), 0);
|
||||
|
||||
paint.setMaskFilter(SkEmbossMaskFilter::Make(
|
||||
SkBlurMask::ConvertRadiusToSigma(3),
|
||||
{ { SK_Scalar1, SK_Scalar1, SK_Scalar1 }, 0, 128, 16*2 }));
|
||||
canvas->drawBitmap(bm, 10, 10, &paint);
|
||||
canvas->translate(bm.width() + SkIntToScalar(10), 0);
|
||||
|
||||
// this combination of emboss+colorfilter used to crash -- so we exercise it to
|
||||
// confirm that we have a fix.
|
||||
paint.setColorFilter(SkColorFilter::MakeModeFilter(0xFFFF0000, SkBlendMode::kSrcATop));
|
||||
canvas->translate(bm.width() + SkIntToScalar(10), 0);
|
||||
canvas->drawBitmap(bm, 10, 10, &paint);
|
||||
canvas->translate(bm.width() + SkIntToScalar(10), 0);
|
||||
|
||||
paint.setAntiAlias(true);
|
||||
paint.setStyle(SkPaint::kStroke_Style);
|
||||
paint.setStrokeWidth(SkIntToScalar(10));
|
||||
paint.setMaskFilter(SkEmbossMaskFilter::Make(
|
||||
SkBlurMask::ConvertRadiusToSigma(4),
|
||||
{ { SK_Scalar1, SK_Scalar1, SK_Scalar1 }, 0, 128, 16*2 }));
|
||||
paint.setColorFilter(nullptr);
|
||||
paint.setShader(SkShader::MakeColorShader(SK_ColorBLUE));
|
||||
paint.setDither(true);
|
||||
canvas->drawCircle(SkIntToScalar(50), SkIntToScalar(50),
|
||||
SkIntToScalar(30), paint);
|
||||
canvas->translate(SkIntToScalar(100), 0);
|
||||
|
||||
paint.setStyle(SkPaint::kFill_Style);
|
||||
paint.setTextSize(50);
|
||||
canvas->drawText("Hello", 5, 0, 50, paint);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -59,4 +78,3 @@ private:
|
||||
};
|
||||
|
||||
DEF_GM(return new EmbossGM;)
|
||||
#endif
|
||||
|
@ -48,19 +48,6 @@ public:
|
||||
return Make(style, sigma, SkRect::MakeEmpty(), flags);
|
||||
}
|
||||
|
||||
#ifdef SK_SUPPORT_LEGACY_EMBOSSMASKFILTER
|
||||
/** Create an emboss maskfilter
|
||||
@param blurSigma standard deviation of the Gaussian blur to apply
|
||||
before applying lighting (e.g. 3)
|
||||
@param direction array of 3 scalars [x, y, z] specifying the direction of the light source
|
||||
@param ambient 0...1 amount of ambient light
|
||||
@param specular coefficient for specular highlights (e.g. 8)
|
||||
@return the emboss maskfilter
|
||||
*/
|
||||
static sk_sp<SkMaskFilter> MakeEmboss(SkScalar blurSigma, const SkScalar direction[3],
|
||||
SkScalar ambient, SkScalar specular);
|
||||
#endif
|
||||
|
||||
static const int kMaxDivisions = 6;
|
||||
|
||||
// This method computes all the parameters for drawing a partially occluded nine-patched
|
||||
|
@ -208,13 +208,10 @@ static void apply_shader(SkPaint* paint, int index) {
|
||||
paint->setRasterizer(rastBuilder.detach());
|
||||
}
|
||||
|
||||
#ifdef SK_SUPPORT_LEGACY_EMBOSSMASKFILTER
|
||||
SkScalar dir[] = { SK_Scalar1, SK_Scalar1, SK_Scalar1 };
|
||||
paint->setMaskFilter(SkBlurMaskFilter::MakeEmboss(
|
||||
SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(3)), dir,
|
||||
SK_Scalar1/4, SkIntToScalar(4)));
|
||||
paint->setMaskFilter(SkEmbossMaskFilter::Make(
|
||||
SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(3)),
|
||||
{ { SK_Scalar1, SK_Scalar1, SK_Scalar1 }, 0, 128, 16*2 }));
|
||||
paint->setColor(SK_ColorBLUE);
|
||||
#endif
|
||||
}
|
||||
|
||||
class DemoView : public SampleView {
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "SkCanvas.h"
|
||||
#include "SkColorMatrixFilter.h"
|
||||
#include "SkDiscretePathEffect.h"
|
||||
#include "SkEmbossMaskFilter.h"
|
||||
#include "SkGradientShader.h"
|
||||
#include "SkPaint.h"
|
||||
#include "SkView.h"
|
||||
@ -28,11 +29,9 @@ static void paint_proc1(SkPaint* paint) {
|
||||
}
|
||||
|
||||
static void paint_proc2(SkPaint* paint) {
|
||||
#ifdef SK_SUPPORT_LEGACY_EMBOSSMASKFILTER
|
||||
SkScalar dir[3] = { 1, 1, 1};
|
||||
paint->setMaskFilter(
|
||||
SkBlurMaskFilter::MakeEmboss(SkBlurMask::ConvertRadiusToSigma(1), dir, 0.1f, 0.05f));
|
||||
#endif
|
||||
paint->setMaskFilter(SkEmbossMaskFilter::Make(
|
||||
SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(1)),
|
||||
{ { SK_Scalar1, SK_Scalar1, SK_Scalar1 }, 0, 64, 16 }));
|
||||
}
|
||||
|
||||
static void paint_proc3(SkPaint* paint) {
|
||||
|
@ -172,34 +172,57 @@ public:
|
||||
*/
|
||||
static unsigned ComputeRowBytes(unsigned width, SkMask::Format format) {
|
||||
unsigned rb = width;
|
||||
if (SkMask::kBW_Format == format) {
|
||||
switch (format) {
|
||||
case SkMask::kBW_Format:
|
||||
rb = BitsToBytes(rb);
|
||||
} else if (SkMask::kARGB32_Format == format) {
|
||||
rb <<= 2;
|
||||
} else if (SkMask::kLCD16_Format == format) {
|
||||
rb = SkAlign4(rb << 1);
|
||||
} else {
|
||||
break;
|
||||
case SkMask::kA8_Format:
|
||||
rb = SkAlign4(rb);
|
||||
break;
|
||||
case SkMask::k3D_Format:
|
||||
rb = SkAlign4(rb);
|
||||
break;
|
||||
case SkMask::kARGB32_Format:
|
||||
rb <<= 2;
|
||||
break;
|
||||
case SkMask::kLCD16_Format:
|
||||
rb = SkAlign4(rb << 1);
|
||||
break;
|
||||
default:
|
||||
SK_ABORT("Unknown mask format.");
|
||||
break;
|
||||
}
|
||||
return rb;
|
||||
}
|
||||
|
||||
size_t allocImage(SkArenaAlloc* alloc) {
|
||||
size_t allocSize;
|
||||
if (SkMask::kBW_Format == fMaskFormat) {
|
||||
switch (static_cast<SkMask::Format>(fMaskFormat)) {
|
||||
case SkMask::kBW_Format:
|
||||
allocSize = BitsToBytes(fWidth) * fHeight;
|
||||
fImage = alloc->makeArrayDefault<char>(allocSize);
|
||||
} else if (SkMask::kARGB32_Format == fMaskFormat) {
|
||||
break;
|
||||
case SkMask::kA8_Format:
|
||||
allocSize = SkAlign4(fWidth) * fHeight;
|
||||
fImage = alloc->makeArrayDefault<char>(allocSize);
|
||||
break;
|
||||
case SkMask::k3D_Format:
|
||||
allocSize = SkAlign4(fWidth) * fHeight * 3;
|
||||
fImage = alloc->makeArrayDefault<char>(allocSize);
|
||||
break;
|
||||
case SkMask::kARGB32_Format:
|
||||
allocSize = fWidth * fHeight;
|
||||
fImage = alloc->makeArrayDefault<uint32_t>(fWidth * fHeight);
|
||||
allocSize *= sizeof(uint32_t);
|
||||
} else if (SkMask::kLCD16_Format == fMaskFormat) {
|
||||
break;
|
||||
case SkMask::kLCD16_Format:
|
||||
allocSize = SkAlign2(fWidth) * fHeight;
|
||||
fImage = alloc->makeArrayDefault<uint16_t>(allocSize);
|
||||
allocSize *= sizeof(uint16_t);
|
||||
} else {
|
||||
allocSize = SkAlign4(fWidth) * fHeight;
|
||||
fImage = alloc->makeArrayDefault<char>(allocSize);
|
||||
break;
|
||||
default:
|
||||
SK_ABORT("Unknown mask format.");
|
||||
break;
|
||||
}
|
||||
return allocSize;
|
||||
}
|
||||
|
@ -26,8 +26,6 @@
|
||||
#include "SkStrokeRec.h"
|
||||
#include "SkWriteBuffer.h"
|
||||
|
||||
#define ComputeBWRowBytes(width) (((unsigned)(width) + 7) >> 3)
|
||||
|
||||
void SkGlyph::toMask(SkMask* mask) const {
|
||||
SkASSERT(mask);
|
||||
|
||||
|
@ -68,7 +68,6 @@ void SkEmbossMask::Emboss(SkMask* mask, const SkEmbossMaskFilter::Light& light)
|
||||
int next_row = neq_to_mask(y, maxy) & rowBytes;
|
||||
|
||||
for (int x = 0; x <= maxx; x++) {
|
||||
if (alpha[x]) {
|
||||
int nx = alpha[x + neq_to_one(x, maxx)] - alpha[x - nonzero_to_one(x)];
|
||||
int ny = alpha[x + next_row] - alpha[x - prev_row];
|
||||
|
||||
@ -104,11 +103,6 @@ void SkEmbossMask::Emboss(SkMask* mask, const SkEmbossMaskFilter::Light& light)
|
||||
}
|
||||
multiply[x] = SkToU8(mul);
|
||||
additive[x] = SkToU8(add);
|
||||
|
||||
// multiply[x] = 0xFF;
|
||||
// additive[x] = 0;
|
||||
// ((uint8_t*)alpha)[x] = alpha[x] * multiply[x] >> 8;
|
||||
}
|
||||
}
|
||||
alpha += rowBytes;
|
||||
multiply += rowBytes;
|
||||
|
@ -17,26 +17,6 @@ sk_sp<SkMaskFilter> SkEmbossMaskFilter::Make(SkScalar blurSigma, const Light& li
|
||||
return sk_sp<SkMaskFilter>(new SkEmbossMaskFilter(blurSigma, light));
|
||||
}
|
||||
|
||||
#ifdef SK_SUPPORT_LEGACY_EMBOSSMASKFILTER
|
||||
sk_sp<SkMaskFilter> SkBlurMaskFilter::MakeEmboss(SkScalar blurSigma, const SkScalar direction[3],
|
||||
SkScalar ambient, SkScalar specular) {
|
||||
if (direction == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
SkEmbossMaskFilter::Light light;
|
||||
|
||||
memcpy(light.fDirection, direction, sizeof(light.fDirection));
|
||||
// ambient should be 0...1 as a scalar
|
||||
light.fAmbient = SkUnitScalarClampToByte(ambient);
|
||||
// specular should be 0..15.99 as a scalar
|
||||
static const SkScalar kSpecularMultiplier = SkIntToScalar(255) / 16;
|
||||
light.fSpecular = static_cast<U8CPU>(SkScalarPin(specular, 0, 16) * kSpecularMultiplier + 0.5);
|
||||
|
||||
return SkEmbossMaskFilter::Make(blurSigma, light);
|
||||
}
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void normalize(SkScalar v[3]) {
|
||||
|
Loading…
Reference in New Issue
Block a user