| Index: src/core/SkDistanceFieldGen.cpp
|
| diff --git a/src/core/SkDistanceFieldGen.cpp b/src/core/SkDistanceFieldGen.cpp
|
| index f453afe56f65f5ba0b3f4e63e3dbb0ed8247e868..43e92ba8fa10a6bebf31231f760d03471e7c3243 100755
|
| --- a/src/core/SkDistanceFieldGen.cpp
|
| +++ b/src/core/SkDistanceFieldGen.cpp
|
| @@ -28,7 +28,8 @@ enum NeighborFlags {
|
| kNeighborFlagCount = 8
|
| };
|
|
|
| -// We treat an "edge" as a place where we cross from black to non-black, or vice versa.
|
| +// We treat an "edge" as a place where we cross from >=128 to <128, or vice versa, or
|
| +// where we have two non-zero pixels that are <128.
|
| // 'neighborFlags' is used to limit the directions in which we test to avoid indexing
|
| // outside of the image
|
| static bool found_edge(const unsigned char* imagePtr, int width, int neighborFlags) {
|
| @@ -38,18 +39,23 @@ static bool found_edge(const unsigned char* imagePtr, int width, int neighborFla
|
| SkASSERT(kNum8ConnectedNeighbors == kNeighborFlagCount);
|
|
|
| // search for an edge
|
| - bool currVal = (*imagePtr != 0);
|
| + unsigned char currVal = *imagePtr;
|
| + unsigned char currCheck = (currVal >> 7);
|
| for (int i = 0; i < kNum8ConnectedNeighbors; ++i) {
|
| - bool checkVal;
|
| + unsigned char neighborVal;
|
| if ((1 << i) & neighborFlags) {
|
| const unsigned char* checkPtr = imagePtr + offsets[i];
|
| - checkVal = (*checkPtr != 0);
|
| + neighborVal = *checkPtr;
|
| } else {
|
| - checkVal = false;
|
| + neighborVal = 0;
|
| }
|
| - SkASSERT(checkVal == 0 || checkVal == 1);
|
| - SkASSERT(currVal == 0 || currVal == 1);
|
| - if (checkVal != currVal) {
|
| + unsigned char neighborCheck = (neighborVal >> 7);
|
| + SkASSERT(currCheck == 0 || currCheck == 1);
|
| + SkASSERT(neighborCheck == 0 || neighborCheck == 1);
|
| + // if sharp transition
|
| + if (currCheck != neighborCheck ||
|
| + // or both <128 and >0
|
| + (!currCheck && !neighborCheck && currVal && neighborVal)) {
|
| return true;
|
| }
|
| }
|
| @@ -349,10 +355,27 @@ bool SkGenerateDistanceFieldFromImage(unsigned char* distanceField,
|
| unsigned char* edgePtr = (unsigned char*) edgeStorage.get();
|
| sk_bzero(edgePtr, dataWidth*dataHeight*sizeof(char));
|
|
|
| + SkAutoSMalloc<1024> copyStorage((width+2)*(height+2)*sizeof(char));
|
| + unsigned char* copyPtr = (unsigned char*) copyStorage.get();
|
| +
|
| + // we copy our source image into a padded copy to ensure we catch edge transitions
|
| + // around the outside
|
| + const unsigned char* currImage = image;
|
| + sk_bzero(copyPtr, (width+2)*sizeof(char));
|
| + unsigned char* currCopy = copyPtr + width + 2;
|
| + for (int i = 0; i < height; ++i) {
|
| + *currCopy++ = 0;
|
| + memcpy(currCopy, currImage, width*sizeof(char));
|
| + currImage += width;
|
| + currCopy += width;
|
| + *currCopy++ = 0;
|
| + }
|
| + sk_bzero(currCopy, (width+2)*sizeof(char));
|
| +
|
| // copy glyph into distance field storage
|
| - init_glyph_data(dataPtr, edgePtr, image,
|
| + init_glyph_data(dataPtr, edgePtr, copyPtr,
|
| dataWidth, dataHeight,
|
| - width, height, pad);
|
| + width+2, height+2, pad-1);
|
|
|
| // create initial distance data, particularly at edges
|
| init_distances(dataPtr, edgePtr, dataWidth, dataHeight);
|
| @@ -426,10 +449,14 @@ bool SkGenerateDistanceFieldFromImage(unsigned char* distanceField,
|
| for (int j = 1; j < dataHeight-1; ++j) {
|
| for (int i = 1; i < dataWidth-1; ++i) {
|
| #if DUMP_EDGE
|
| - unsigned char val = sk_float_round2int(255*currData->fAlpha);
|
| + float alpha = currData->fAlpha;
|
| + float edge = 0.0f;
|
| if (*currEdge) {
|
| - val = 128;
|
| + edge = 0.25f;
|
| }
|
| + // blend with original image
|
| + float result = alpha + (1.0f-alpha)*edge;
|
| + unsigned char val = sk_float_round2int(255*result);
|
| *dfPtr++ = val;
|
| #else
|
| float dist;
|
|
|