Chromium Code Reviews| Index: src/core/SkDistanceFieldGen.cpp |
| diff --git a/src/core/SkDistanceFieldGen.cpp b/src/core/SkDistanceFieldGen.cpp |
| index cd469a4d953077828fbaf394cd30d000c9557002..056472bd29d03ad1e62c7bb61a83e175a6df5ecd 100755 |
| --- a/src/core/SkDistanceFieldGen.cpp |
| +++ b/src/core/SkDistanceFieldGen.cpp |
| @@ -14,16 +14,37 @@ struct DFData { |
| SkPoint fDistVector; // distance vector to nearest (so far) edge texel |
| }; |
|
robertphillips
2014/03/12 16:40:07
Name this guy EdgeFlags? NeighborFlags might be cl
|
| +enum { |
| + kEdgeFlag_Left = 0x01, |
| + kEdgeFlag_Right = 0x02, |
| + kEdgeFlag_TopLeft = 0x04, |
| + kEdgeFlag_Top = 0x08, |
| + kEdgeFlag_TopRight = 0x10, |
| + kEdgeFlag_BottomLeft = 0x20, |
| + kEdgeFlag_Bottom = 0x40, |
| + kEdgeFlag_BottomRight = 0x80, |
| + kEdgeFlag_All = 0xff |
| +}; |
| + |
| // We treat an "edge" as a place where we cross from a texel >= 128 to a texel < 128, |
| // or vice versa. This means we just need to check if the MSBs are different. |
|
robertphillips
2014/03/12 16:40:07
// 'edgeFlags' is used to limit the directions in
|
| -static bool found_edge(const unsigned char* imagePtr, int width) { |
| +static bool found_edge(const unsigned char* imagePtr, int width, int edgeFlags) { |
| + // the order of these should match the edge flags above |
|
robertphillips
2014/03/12 16:40:07
swap 8 out for kEdgeFlagCount? Add kNum8ConnectedN
|
| const int offsets[8] = {-1, 1, -width-1, -width, -width+1, width-1, width, width+1 }; |
| // search for an edge |
| - int checkVal = *imagePtr >> 7; |
| + unsigned char currVal = *imagePtr >> 7; |
| for (int i = 0; i < 8; ++i) { |
| - const unsigned char* checkPtr = imagePtr + offsets[i]; |
| - if (checkVal ^ (*checkPtr >> 7)) { |
| + unsigned char checkVal; |
| + if ((1 << i) & edgeFlags) { |
| + const unsigned char* checkPtr = imagePtr + offsets[i]; |
| + checkVal = *checkPtr >> 7; |
| + } else { |
| + checkVal = 0; |
| + } |
| + SkASSERT(checkVal == 0 || checkVal == 1); |
| + SkASSERT(currVal == 0 || currVal == 1); |
| + if (checkVal != currVal) { |
| return true; |
| } |
| } |
| @@ -46,8 +67,20 @@ static void init_glyph_data(DFData* data, unsigned char* edges, const unsigned c |
| } else { |
| data->fAlpha = (*image)*0.00392156862f; // 1/255 |
| } |
| - if (i > 0 && i < imageWidth-1 && j > 0 && j < imageHeight-1 && |
| - found_edge(image, imageWidth)) { |
| + int checkMask = kEdgeFlag_All; |
|
robertphillips
2014/03/12 16:40:07
Would it be helpful to add helper values like "kAl
|
| + if (i == 0) { |
| + checkMask &= ~(kEdgeFlag_Left|kEdgeFlag_TopLeft|kEdgeFlag_BottomLeft); |
| + } |
| + if (i == imageWidth-1) { |
| + checkMask &= ~(kEdgeFlag_Right|kEdgeFlag_TopRight|kEdgeFlag_BottomRight); |
| + } |
| + if (j == 0) { |
| + checkMask &= ~(kEdgeFlag_TopLeft|kEdgeFlag_Top|kEdgeFlag_TopRight); |
| + } |
| + if (j == imageHeight-1) { |
| + checkMask &= ~(kEdgeFlag_BottomLeft|kEdgeFlag_Bottom|kEdgeFlag_BottomRight); |
| + } |
| + if (found_edge(image, imageWidth, checkMask)) { |
| *edges = 255; // using 255 makes for convenient debug rendering |
| } |
| ++data; |
| @@ -268,6 +301,9 @@ static void B2(DFData* curr, int width) { |
| } |
| } |
|
robertphillips
2014/03/12 16:40:07
// Enable this to ...?
|
| +#define DUMP_EDGE 0 |
| + |
| +#if !DUMP_EDGE |
| static unsigned char pack_distance_field_val(float dist, float distanceMagnitude) { |
| if (dist <= -distanceMagnitude) { |
| return 255; |
| @@ -277,6 +313,7 @@ static unsigned char pack_distance_field_val(float dist, float distanceMagnitude |
| return (unsigned char)((distanceMagnitude-dist)*128.0f/distanceMagnitude); |
| } |
| } |
| +#endif |
| // assumes an 8-bit image and distance field |
| bool SkGenerateDistanceFieldFromImage(unsigned char* distanceField, |
| @@ -382,14 +419,19 @@ bool SkGenerateDistanceFieldFromImage(unsigned char* distanceField, |
| unsigned char *dfPtr = distanceField; |
| for (int j = 1; j < dataHeight-1; ++j) { |
| for (int i = 1; i < dataWidth-1; ++i) { |
| +#if DUMP_EDGE |
| + unsigned char val = (currData->fAlpha >= 0.5f) ? 255 : 0; |
|
robertphillips
2014/03/12 16:40:07
newline after { and before } ?
|
| + if (*currEdge) { val = 128; } |
| + *dfPtr++ = val; |
| +#else |
| float dist; |
| if (currData->fAlpha > 0.5f) { |
| dist = -SkScalarSqrt(currData->fDistSq); |
| } else { |
| dist = SkScalarSqrt(currData->fDistSq); |
| } |
| - |
| *dfPtr++ = pack_distance_field_val(dist, (float)distanceMagnitude); |
| +#endif |
| ++currData; |
| ++currEdge; |
| } |