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,
86 data += pad*dataWidth;
88 edges += (pad*dataWidth + pad);
95 data->fAlpha = (*image)*0.00392156862f;
126 float dx = direction.
fX;
127 float dy = direction.
fY;
143 float a1num = 0.5f*dy;
149 if (alpha*
dx < a1num) {
153 }
else if (alpha*
dx < (
dx - a1num)) {
171 for (
int j = 0; j <
height; ++j) {
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;
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;
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;
sk_bzero(glyphs, sizeof(glyphs))
#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)
static void F1(DFData *curr, int width)
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)
void swap(sk_sp< T > &a, sk_sp< T > &b)
static bool SkScalarNearlyZero(SkScalar x, SkScalar tolerance=SK_ScalarNearlyZero)
#define SkScalarRoundToInt(x)
static bool SetLengthFast(SkPoint *pt, float length)
sk_sp< const SkImage > image
skia_private::AutoTArray< sk_sp< SkImageFilter > > filters TypedMatrix matrix TypedMatrix matrix SkScalar dx
std::unique_ptr< void, SkOverloadedFunctionObject< void(void *), sk_free > > UniqueVoidPtr
static const int imageHeight
static const int imageWidth
void scale(float scale, SkPoint *dst) const
std::shared_ptr< const fml::Mapping > data