diff options
-rw-r--r-- | gm/emboss.cpp | 32 | ||||
-rw-r--r-- | include/effects/SkBlurMaskFilter.h | 13 | ||||
-rw-r--r-- | samplecode/SampleAll.cpp | 9 | ||||
-rw-r--r-- | samplecode/SampleEffects.cpp | 9 | ||||
-rw-r--r-- | src/core/SkGlyph.h | 45 | ||||
-rw-r--r-- | src/core/SkScalerContext.cpp | 2 | ||||
-rw-r--r-- | src/effects/SkEmbossMask.cpp | 70 | ||||
-rw-r--r-- | src/effects/SkEmbossMaskFilter.cpp | 20 | ||||
-rw-r--r-- | src/gpu/text/GrAtlasGlyphCache.cpp | 2 |
9 files changed, 102 insertions, 100 deletions
diff --git a/gm/emboss.cpp b/gm/emboss.cpp index a8483d0882..c14c9d9278 100644 --- a/gm/emboss.cpp +++ b/gm/emboss.cpp @@ -6,11 +6,11 @@ */ #include "gm.h" -#include "SkBlurMask.h" +#include "SkBlurMaskFilter.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,36 +41,17 @@ protected: SkPaint paint; SkBitmap bm = make_bm(); canvas->drawBitmap(bm, 10, 10, &paint); - 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); + const SkScalar dir[] = { 1, 1, 1 }; + paint.setMaskFilter(SkBlurMaskFilter::MakeEmboss(3, dir, 0.3f, 0.1f)); canvas->translate(bm.width() + SkIntToScalar(10), 0); + canvas->drawBitmap(bm, 10, 10, &paint); // 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->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); + canvas->drawBitmap(bm, 10, 10, &paint); } private: @@ -78,3 +59,4 @@ private: }; DEF_GM(return new EmbossGM;) +#endif diff --git a/include/effects/SkBlurMaskFilter.h b/include/effects/SkBlurMaskFilter.h index e000732a85..8b032e50ee 100644 --- a/include/effects/SkBlurMaskFilter.h +++ b/include/effects/SkBlurMaskFilter.h @@ -48,6 +48,19 @@ 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 diff --git a/samplecode/SampleAll.cpp b/samplecode/SampleAll.cpp index ea7d508979..e1b85934b1 100644 --- a/samplecode/SampleAll.cpp +++ b/samplecode/SampleAll.cpp @@ -208,10 +208,13 @@ static void apply_shader(SkPaint* paint, int index) { paint->setRasterizer(rastBuilder.detach()); } - paint->setMaskFilter(SkEmbossMaskFilter::Make( - SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(3)), - { { SK_Scalar1, SK_Scalar1, SK_Scalar1 }, 0, 128, 16*2 })); +#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->setColor(SK_ColorBLUE); +#endif } class DemoView : public SampleView { diff --git a/samplecode/SampleEffects.cpp b/samplecode/SampleEffects.cpp index 49654983da..8c6793eb67 100644 --- a/samplecode/SampleEffects.cpp +++ b/samplecode/SampleEffects.cpp @@ -10,7 +10,6 @@ #include "SkCanvas.h" #include "SkColorMatrixFilter.h" #include "SkDiscretePathEffect.h" -#include "SkEmbossMaskFilter.h" #include "SkGradientShader.h" #include "SkPaint.h" #include "SkView.h" @@ -29,9 +28,11 @@ static void paint_proc1(SkPaint* paint) { } static void paint_proc2(SkPaint* paint) { - paint->setMaskFilter(SkEmbossMaskFilter::Make( - SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(1)), - { { SK_Scalar1, SK_Scalar1, SK_Scalar1 }, 0, 64, 16 })); +#ifdef SK_SUPPORT_LEGACY_EMBOSSMASKFILTER + SkScalar dir[3] = { 1, 1, 1}; + paint->setMaskFilter( + SkBlurMaskFilter::MakeEmboss(SkBlurMask::ConvertRadiusToSigma(1), dir, 0.1f, 0.05f)); +#endif } static void paint_proc3(SkPaint* paint) { diff --git a/src/core/SkGlyph.h b/src/core/SkGlyph.h index b54635277b..06c1d76fb3 100644 --- a/src/core/SkGlyph.h +++ b/src/core/SkGlyph.h @@ -172,57 +172,34 @@ public: */ static unsigned ComputeRowBytes(unsigned width, SkMask::Format format) { unsigned rb = width; - switch (format) { - case SkMask::kBW_Format: + if (SkMask::kBW_Format == format) { rb = BitsToBytes(rb); - break; - case SkMask::kA8_Format: - rb = SkAlign4(rb); - break; - case SkMask::k3D_Format: - rb = SkAlign4(rb); - break; - case SkMask::kARGB32_Format: + } else if (SkMask::kARGB32_Format == format) { rb <<= 2; - break; - case SkMask::kLCD16_Format: + } else if (SkMask::kLCD16_Format == format) { rb = SkAlign4(rb << 1); - break; - default: - SK_ABORT("Unknown mask format."); - break; + } else { + rb = SkAlign4(rb); } return rb; } size_t allocImage(SkArenaAlloc* alloc) { size_t allocSize; - switch (static_cast<SkMask::Format>(fMaskFormat)) { - case SkMask::kBW_Format: + if (SkMask::kBW_Format == fMaskFormat) { allocSize = BitsToBytes(fWidth) * fHeight; fImage = alloc->makeArrayDefault<char>(allocSize); - 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: + } else if (SkMask::kARGB32_Format == fMaskFormat) { allocSize = fWidth * fHeight; fImage = alloc->makeArrayDefault<uint32_t>(fWidth * fHeight); allocSize *= sizeof(uint32_t); - break; - case SkMask::kLCD16_Format: + } else if (SkMask::kLCD16_Format == fMaskFormat) { allocSize = SkAlign2(fWidth) * fHeight; fImage = alloc->makeArrayDefault<uint16_t>(allocSize); allocSize *= sizeof(uint16_t); - break; - default: - SK_ABORT("Unknown mask format."); - break; + } else { + allocSize = SkAlign4(fWidth) * fHeight; + fImage = alloc->makeArrayDefault<char>(allocSize); } return allocSize; } diff --git a/src/core/SkScalerContext.cpp b/src/core/SkScalerContext.cpp index 828f978287..8a1ab60ae8 100644 --- a/src/core/SkScalerContext.cpp +++ b/src/core/SkScalerContext.cpp @@ -26,6 +26,8 @@ #include "SkStrokeRec.h" #include "SkWriteBuffer.h" +#define ComputeBWRowBytes(width) (((unsigned)(width) + 7) >> 3) + void SkGlyph::toMask(SkMask* mask) const { SkASSERT(mask); diff --git a/src/effects/SkEmbossMask.cpp b/src/effects/SkEmbossMask.cpp index e081186564..c73d0c8406 100644 --- a/src/effects/SkEmbossMask.cpp +++ b/src/effects/SkEmbossMask.cpp @@ -68,41 +68,47 @@ 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++) { - 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]; - - SkFixed numer = lx * nx + ly * ny + lz_dot_nz; - int mul = ambient; - int add = 0; - - if (numer > 0) { // preflight when numer/denom will be <= 0 - int denom = SkSqrt32(nx * nx + ny * ny + kDelta*kDelta); - SkFixed dot = numer / denom; - dot >>= 8; // now dot is 2^8 instead of 2^16 - mul = SkFastMin32(mul + dot, 255); - - // now for the reflection - - // R = 2 (Light * Normal) Normal - Light - // hilite = R * Eye(0, 0, 1) - - int hilite = (2 * dot - lz_dot8) * lz_dot8 >> 8; - if (hilite > 0) { - // pin hilite to 255, since our fast math is also a little sloppy - hilite = SkClampMax(hilite, 255); - - // specular is 4.4 - // would really like to compute the fractional part of this - // and then possibly cache a 256 table for a given specular - // value in the light, and just pass that in to this function. - add = hilite; - for (int i = specular >> 4; i > 0; --i) { - add = div255(add * hilite); + 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]; + + SkFixed numer = lx * nx + ly * ny + lz_dot_nz; + int mul = ambient; + int add = 0; + + if (numer > 0) { // preflight when numer/denom will be <= 0 + int denom = SkSqrt32(nx * nx + ny * ny + kDelta*kDelta); + SkFixed dot = numer / denom; + dot >>= 8; // now dot is 2^8 instead of 2^16 + mul = SkFastMin32(mul + dot, 255); + + // now for the reflection + + // R = 2 (Light * Normal) Normal - Light + // hilite = R * Eye(0, 0, 1) + + int hilite = (2 * dot - lz_dot8) * lz_dot8 >> 8; + if (hilite > 0) { + // pin hilite to 255, since our fast math is also a little sloppy + hilite = SkClampMax(hilite, 255); + + // specular is 4.4 + // would really like to compute the fractional part of this + // and then possibly cache a 256 table for a given specular + // value in the light, and just pass that in to this function. + add = hilite; + for (int i = specular >> 4; i > 0; --i) { + add = div255(add * hilite); + } } } + multiply[x] = SkToU8(mul); + additive[x] = SkToU8(add); + + // multiply[x] = 0xFF; + // additive[x] = 0; + // ((uint8_t*)alpha)[x] = alpha[x] * multiply[x] >> 8; } - multiply[x] = SkToU8(mul); - additive[x] = SkToU8(add); } alpha += rowBytes; multiply += rowBytes; diff --git a/src/effects/SkEmbossMaskFilter.cpp b/src/effects/SkEmbossMaskFilter.cpp index b51e2545b6..4caef9ef0b 100644 --- a/src/effects/SkEmbossMaskFilter.cpp +++ b/src/effects/SkEmbossMaskFilter.cpp @@ -17,6 +17,26 @@ 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]) { diff --git a/src/gpu/text/GrAtlasGlyphCache.cpp b/src/gpu/text/GrAtlasGlyphCache.cpp index 421160f28f..80f4314b91 100644 --- a/src/gpu/text/GrAtlasGlyphCache.cpp +++ b/src/gpu/text/GrAtlasGlyphCache.cpp @@ -213,8 +213,6 @@ static inline GrMaskFormat get_packed_glyph_mask_format(const SkGlyph& glyph) { // fall through to kA8 -- we store BW glyphs in our 8-bit cache case SkMask::kA8_Format: return kA8_GrMaskFormat; - case SkMask::k3D_Format: - return kA8_GrMaskFormat; // ignore the mul and add planes, just use the mask case SkMask::kLCD16_Format: return kA565_GrMaskFormat; case SkMask::kARGB32_Format: |