Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(142)

Unified Diff: src/core/SkDistanceFieldGen.cpp

Issue 208893003: More distance field improvements (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Slightly faster clearing of temp glyph buffer Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | src/gpu/GrDistanceFieldTextContext.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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;
« no previous file with comments | « no previous file | src/gpu/GrDistanceFieldTextContext.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698