25#if !defined(SK_DISABLE_SDF_TEXT)
51static bool found_edge(
const unsigned char* imagePtr,
int width,
int neighborFlags) {
53 const int kNum8ConnectedNeighbors = 8;
58 unsigned char currVal = *imagePtr;
59 unsigned char currCheck = (currVal >> 7);
60 for (
int i = 0; i < kNum8ConnectedNeighbors; ++i) {
61 unsigned char neighborVal;
62 if ((1 << i) & neighborFlags) {
63 const unsigned char* checkPtr = imagePtr + offsets[i];
64 neighborVal = *checkPtr;
68 unsigned char neighborCheck = (neighborVal >> 7);
69 SkASSERT(currCheck == 0 || currCheck == 1);
70 SkASSERT(neighborCheck == 0 || neighborCheck == 1);
72 if (currCheck != neighborCheck ||
74 (!currCheck && !neighborCheck && currVal && neighborVal)) {
83 int dataWidth,
int dataHeight,
84 int imageWidth,
int imageHeight,
86 data += pad*dataWidth;
88 edges += (pad*dataWidth + pad);
90 for (
int j = 0; j < imageHeight; ++j) {
91 for (
int i = 0; i < imageWidth; ++i) {
95 data->fAlpha = (*image)*0.00392156862f;
101 if (i == imageWidth-1) {
107 if (j == imageHeight-1) {
126 float dx = direction.
fX;
127 float dy = direction.
fY;
130 distance = 0.5f - alpha;
143 float a1num = 0.5f*dy;
149 if (alpha*dx < a1num) {
151 distance = 0.5f*(dx + dy) -
SkScalarSqrt(2.0f*dx*dy*alpha);
153 }
else if (alpha*dx < (dx - a1num)) {
154 distance = (0.5f - alpha)*dx;
158 distance = -0.5f*(dx + dy) +
SkScalarSqrt(2.0f*dx*dy*(1.0f - alpha));
171 for (
int j = 0; j <
height; ++j) {
172 for (
int i = 0; i <
width; ++i) {
181 currGrad.
fX = (prevData+1)->fAlpha - (prevData-1)->fAlpha
184 + (nextData+1)->fAlpha - (nextData-1)->fAlpha;
185 currGrad.
fY = (nextData-1)->fAlpha - (prevData-1)->fAlpha
188 + (nextData+1)->fAlpha - (prevData+1)->fAlpha;
217 float distSq =
check->fDistSq - 2.0f*(distVec.
fX + distVec.
fY - 1.0f);
218 if (distSq < curr->fDistSq) {
227 distVec =
check->fDistVector;
228 distSq =
check->fDistSq - 2.0f*distVec.
fY + 1.0f;
229 if (distSq < curr->fDistSq) {
237 distVec =
check->fDistVector;
238 distSq =
check->fDistSq + 2.0f*(distVec.
fX - distVec.
fY + 1.0f);
239 if (distSq < curr->fDistSq) {
248 distVec =
check->fDistVector;
249 distSq =
check->fDistSq - 2.0f*distVec.
fX + 1.0f;
250 if (distSq < curr->fDistSq) {
263 float distSq =
check->fDistSq + 2.0f*distVec.
fX + 1.0f;
264 if (distSq < curr->fDistSq) {
277 float distSq =
check->fDistSq - 2.0f*distVec.
fX + 1.0f;
278 if (distSq < curr->fDistSq) {
291 float distSq =
check->fDistSq + 2.0f*distVec.
fX + 1.0f;
292 if (distSq < curr->fDistSq) {
300 distVec =
check->fDistVector;
301 distSq =
check->fDistSq - 2.0f*(distVec.
fX - distVec.
fY - 1.0f);
302 if (distSq < curr->fDistSq) {
311 distVec =
check->fDistVector;
312 distSq =
check->fDistSq + 2.0f*distVec.
fY + 1.0f;
313 if (distSq < curr->fDistSq) {
321 distVec =
check->fDistVector;
322 distSq =
check->fDistSq + 2.0f*(distVec.
fX + distVec.
fY + 1.0f);
323 if (distSq < curr->fDistSq) {
335template <
int distanceMagnitude>
340 dist = SkTPin<float>(-dist, -distanceMagnitude, distanceMagnitude * 127.0f / 128.0f);
343 dist += distanceMagnitude;
355 const unsigned char* copyPtr,
365 int dataWidth =
width + 2*pad;
366 int dataHeight =
height + 2*pad;
371 unsigned char* edgePtr = (
unsigned char*)storage.get() + dataWidth*dataHeight*
sizeof(
DFData);
375 dataWidth, dataHeight,
384 DFData* currData = dataPtr+dataWidth+1;
385 unsigned char* currEdge = edgePtr+dataWidth+1;
386 for (
int j = 1; j < dataHeight-1; ++j) {
388 for (
int i = 1; i < dataWidth-1; ++i) {
391 F1(currData, dataWidth);
400 for (
int i = 1; i < dataWidth-1; ++i) {
403 F2(currData, dataWidth);
409 currData += dataWidth+1;
410 currEdge += dataWidth+1;
414 currData = dataPtr+dataWidth*(dataHeight-2) - 1;
415 currEdge = edgePtr+dataWidth*(dataHeight-2) - 1;
416 for (
int j = 1; j < dataHeight-1; ++j) {
418 for (
int i = 1; i < dataWidth-1; ++i) {
421 B1(currData, dataWidth);
430 for (
int i = 1; i < dataWidth-1; ++i) {
433 B2(currData, dataWidth);
439 currData -= dataWidth-1;
440 currEdge -= dataWidth-1;
444 currData = dataPtr + dataWidth+1;
445 currEdge = edgePtr + dataWidth+1;
446 unsigned char *dfPtr = distanceField;
447 for (
int j = 1; j < dataHeight-1; ++j) {
448 for (
int i = 1; i < dataWidth-1; ++i) {
450 float alpha = currData->
fAlpha;
456 float result = alpha + (1.0f-alpha)*edge;
461 if (currData->
fAlpha > 0.5f) {
466 *dfPtr++ = pack_distance_field_val<SK_DistanceFieldMagnitude>(dist);
480 const unsigned char*
image,
487 unsigned char* copyPtr = (
unsigned char*) copyStorage.
get();
491 const unsigned char* currSrcScanLine =
image;
493 unsigned char* currDestPtr = copyPtr +
width + 2;
494 for (
int i = 0; i <
height; ++i) {
496 memcpy(currDestPtr, currSrcScanLine,
width);
497 currSrcScanLine += rowBytes;
498 currDestPtr +=
width;
508 const unsigned char*
image,
509 int w,
int h,
size_t rowBytes) {
515 unsigned char* copyPtr = (
unsigned char*) copyStorage.
get();
519 const uint16_t*
start =
reinterpret_cast<const uint16_t*
>(
image);
523 unsigned char* currDestPtr = copyPtr +
w + 2;
524 for (
int i = 0; i < h; ++i, currSrcScanline >>= rowBytes, endSrcScanline >>= rowBytes) {
526 for (
auto src = currSrcScanline; src < endSrcScanline; ++src) {
527 *currDestPtr++ = *src;
531 sk_bzero(currDestPtr, (
w+2)*
sizeof(
char));
538 const unsigned char*
image,
545 unsigned char* copyPtr = (
unsigned char*) copyStorage.
get();
549 const unsigned char* currSrcScanLine =
image;
551 unsigned char* currDestPtr = copyPtr +
width + 2;
552 for (
int i = 0; i <
height; ++i) {
555 int rowWritesLeft =
width;
556 const unsigned char *maskPtr = currSrcScanLine;
557 while (rowWritesLeft > 0) {
558 unsigned mask = *maskPtr++;
559 for (
int j = 7; j >= 0 && rowWritesLeft; --j, --rowWritesLeft) {
560 *currDestPtr++ = (mask & (1 << j)) ? 0xff : 0;
563 currSrcScanLine += rowBytes;
#define check(reporter, ref, unref, make, kill)
static void init_glyph_data(DFData *data, unsigned char *edges, const unsigned char *image, int dataWidth, int dataHeight, int imageWidth, int imageHeight, int pad)
static float edge_distance(const SkPoint &direction, float alpha)
bool SkGenerateDistanceFieldFromBWImage(unsigned char *distanceField, const unsigned char *image, int width, int height, size_t rowBytes)
static bool generate_distance_field_from_image(unsigned char *distanceField, const unsigned char *copyPtr, int width, int height)
static unsigned char pack_distance_field_val(float dist)
static void B2(DFData *curr, int width)
static void init_distances(DFData *data, unsigned char *edges, int width, int height)
bool SkGenerateDistanceFieldFromA8Image(unsigned char *distanceField, const unsigned char *image, int width, int height, size_t rowBytes)
static void B1(DFData *curr, int width)
static bool found_edge(const unsigned char *imagePtr, int width, int neighborFlags)
bool SkGenerateDistanceFieldFromLCD16Mask(unsigned char *distanceField, const unsigned char *image, int w, int h, size_t rowBytes)
static void F2(DFData *curr, int width)
@ kBottomLeft_NeighborFlag
@ kBottomRight_NeighborFlag
#define SK_DistanceFieldPad
#define sk_float_round2int(x)
static void * sk_calloc_throw(size_t size)
static void sk_bzero(void *buffer, size_t size)
static bool SkScalarNearlyZero(SkScalar x, SkScalar tolerance=SK_ScalarNearlyZero)
#define SkScalarRoundToInt(x)
static bool SetLengthFast(SkPoint *pt, float length)
std::unique_ptr< void, SkOverloadedFunctionObject< void(void *), sk_free > > UniqueVoidPtr
static void swap(TArray< T, M > &a, TArray< T, M > &b)
void scale(float scale, SkPoint *dst) const