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; |
} |