diff options
Diffstat (limited to 'libs/hwui/FontRenderer.cpp')
-rw-r--r-- | libs/hwui/FontRenderer.cpp | 140 |
1 files changed, 8 insertions, 132 deletions
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp index 77b8df1..f0dcb30 100644 --- a/libs/hwui/FontRenderer.cpp +++ b/libs/hwui/FontRenderer.cpp @@ -23,9 +23,11 @@ #include <utils/Log.h> -#include "RenderScript.h" +#include <RenderScript.h> +#include "utils/Blur.h" #include "utils/Timing.h" + #include "Caches.h" #include "Debug.h" #include "FontRenderer.h" @@ -569,7 +571,7 @@ FontRenderer::DropShadow FontRenderer::renderDropShadow(SkPaint* paint, const ch } int size = paddedWidth * paddedHeight; - uint8_t* dataBuffer = (uint8_t*)memalign(RS_CPU_ALLOCATION_ALIGNMENT, size); + uint8_t* dataBuffer = (uint8_t*) memalign(RS_CPU_ALLOCATION_ALIGNMENT, size); memset(dataBuffer, 0, size); int penX = radius - bounds.left; @@ -655,147 +657,21 @@ void FontRenderer::removeFont(const Font* font) { } } -void FontRenderer::computeGaussianWeights(float* weights, int32_t radius) { - // Compute gaussian weights for the blur - // e is the euler's number - float e = 2.718281828459045f; - float pi = 3.1415926535897932f; - // g(x) = ( 1 / sqrt( 2 * pi ) * sigma) * e ^ ( -x^2 / 2 * sigma^2 ) - // x is of the form [-radius .. 0 .. radius] - // and sigma varies with radius. - // Based on some experimental radius values and sigma's - // we approximately fit sigma = f(radius) as - // sigma = radius * 0.3 + 0.6 - // The larger the radius gets, the more our gaussian blur - // will resemble a box blur since with large sigma - // the gaussian curve begins to lose its shape - float sigma = 0.3f * (float) radius + 0.6f; - - // Now compute the coefficints - // We will store some redundant values to save some math during - // the blur calculations - // precompute some values - float coeff1 = 1.0f / (sqrt( 2.0f * pi ) * sigma); - float coeff2 = - 1.0f / (2.0f * sigma * sigma); - - float normalizeFactor = 0.0f; - for (int32_t r = -radius; r <= radius; r ++) { - float floatR = (float) r; - weights[r + radius] = coeff1 * pow(e, floatR * floatR * coeff2); - normalizeFactor += weights[r + radius]; - } - - //Now we need to normalize the weights because all our coefficients need to add up to one - normalizeFactor = 1.0f / normalizeFactor; - for (int32_t r = -radius; r <= radius; r ++) { - weights[r + radius] *= normalizeFactor; - } -} - -void FontRenderer::horizontalBlur(float* weights, int32_t radius, - const uint8_t* source, uint8_t* dest, int32_t width, int32_t height) { - float blurredPixel = 0.0f; - float currentPixel = 0.0f; - - for (int32_t y = 0; y < height; y ++) { - - const uint8_t* input = source + y * width; - uint8_t* output = dest + y * width; - - for (int32_t x = 0; x < width; x ++) { - blurredPixel = 0.0f; - const float* gPtr = weights; - // Optimization for non-border pixels - if (x > radius && x < (width - radius)) { - const uint8_t *i = input + (x - radius); - for (int r = -radius; r <= radius; r ++) { - currentPixel = (float) (*i); - blurredPixel += currentPixel * gPtr[0]; - gPtr++; - i++; - } - } else { - for (int32_t r = -radius; r <= radius; r ++) { - // Stepping left and right away from the pixel - int validW = x + r; - if (validW < 0) { - validW = 0; - } - if (validW > width - 1) { - validW = width - 1; - } - - currentPixel = (float) input[validW]; - blurredPixel += currentPixel * gPtr[0]; - gPtr++; - } - } - *output = (uint8_t)blurredPixel; - output ++; - } - } -} - -void FontRenderer::verticalBlur(float* weights, int32_t radius, - const uint8_t* source, uint8_t* dest, int32_t width, int32_t height) { - float blurredPixel = 0.0f; - float currentPixel = 0.0f; - - for (int32_t y = 0; y < height; y ++) { - uint8_t* output = dest + y * width; - - for (int32_t x = 0; x < width; x ++) { - blurredPixel = 0.0f; - const float* gPtr = weights; - const uint8_t* input = source + x; - // Optimization for non-border pixels - if (y > radius && y < (height - radius)) { - const uint8_t *i = input + ((y - radius) * width); - for (int32_t r = -radius; r <= radius; r ++) { - currentPixel = (float)(*i); - blurredPixel += currentPixel * gPtr[0]; - gPtr++; - i += width; - } - } else { - for (int32_t r = -radius; r <= radius; r ++) { - int validH = y + r; - // Clamp to zero and width - if (validH < 0) { - validH = 0; - } - if (validH > height - 1) { - validH = height - 1; - } - - const uint8_t *i = input + validH * width; - currentPixel = (float) (*i); - blurredPixel += currentPixel * gPtr[0]; - gPtr++; - } - } - *output = (uint8_t) blurredPixel; - output++; - } - } -} - void FontRenderer::blurImage(uint8_t** image, int32_t width, int32_t height, int32_t radius) { if (width * height * radius < RS_MIN_INPUT_CUTOFF) { float *gaussian = new float[2 * radius + 1]; - computeGaussianWeights(gaussian, radius); + Blur::generateGaussianWeights(gaussian, radius); uint8_t* scratch = new uint8_t[width * height]; - - horizontalBlur(gaussian, radius, *image, scratch, width, height); - verticalBlur(gaussian, radius, scratch, *image, width, height); + Blur::horizontal(gaussian, radius, *image, scratch, width, height); + Blur::vertical(gaussian, radius, scratch, *image, width, height); delete[] gaussian; delete[] scratch; return; } - uint8_t* outImage = (uint8_t*)memalign(RS_CPU_ALLOCATION_ALIGNMENT, width * height); + uint8_t* outImage = (uint8_t*) memalign(RS_CPU_ALLOCATION_ALIGNMENT, width * height); if (mRs.get() == 0) { mRs = new RSC::RS(); |