| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "SkDistanceFieldGen.h" | 8 #include "SkDistanceFieldGen.h" |
| 9 #include "SkPoint.h" | 9 #include "SkPoint.h" |
| 10 | 10 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 kTop_NeighborFlag = 0x08, | 21 kTop_NeighborFlag = 0x08, |
| 22 kTopRight_NeighborFlag = 0x10, | 22 kTopRight_NeighborFlag = 0x10, |
| 23 kBottomLeft_NeighborFlag = 0x20, | 23 kBottomLeft_NeighborFlag = 0x20, |
| 24 kBottom_NeighborFlag = 0x40, | 24 kBottom_NeighborFlag = 0x40, |
| 25 kBottomRight_NeighborFlag = 0x80, | 25 kBottomRight_NeighborFlag = 0x80, |
| 26 kAll_NeighborFlags = 0xff, | 26 kAll_NeighborFlags = 0xff, |
| 27 | 27 |
| 28 kNeighborFlagCount = 8 | 28 kNeighborFlagCount = 8 |
| 29 }; | 29 }; |
| 30 | 30 |
| 31 // We treat an "edge" as a place where we cross from a texel >= 128 to a texel <
128, | 31 // We treat an "edge" as a place where we cross from black to non-black, or vice
versa. |
| 32 // or vice versa. This means we just need to check if the MSBs are different. | |
| 33 // 'neighborFlags' is used to limit the directions in which we test to avoid ind
exing | 32 // 'neighborFlags' is used to limit the directions in which we test to avoid ind
exing |
| 34 // outside of the image | 33 // outside of the image |
| 35 static bool found_edge(const unsigned char* imagePtr, int width, int neighborFla
gs) { | 34 static bool found_edge(const unsigned char* imagePtr, int width, int neighborFla
gs) { |
| 36 // the order of these should match the neighbor flags above | 35 // the order of these should match the neighbor flags above |
| 37 const int kNum8ConnectedNeighbors = 8; | 36 const int kNum8ConnectedNeighbors = 8; |
| 38 const int offsets[8] = {-1, 1, -width-1, -width, -width+1, width-1, width, w
idth+1 }; | 37 const int offsets[8] = {-1, 1, -width-1, -width, -width+1, width-1, width, w
idth+1 }; |
| 39 SkASSERT(kNum8ConnectedNeighbors == kNeighborFlagCount); | 38 SkASSERT(kNum8ConnectedNeighbors == kNeighborFlagCount); |
| 40 | 39 |
| 41 // search for an edge | 40 // search for an edge |
| 42 unsigned char currVal = *imagePtr >> 7; | 41 bool currVal = (*imagePtr != 0); |
| 43 for (int i = 0; i < kNum8ConnectedNeighbors; ++i) { | 42 for (int i = 0; i < kNum8ConnectedNeighbors; ++i) { |
| 44 unsigned char checkVal; | 43 bool checkVal; |
| 45 if ((1 << i) & neighborFlags) { | 44 if ((1 << i) & neighborFlags) { |
| 46 const unsigned char* checkPtr = imagePtr + offsets[i]; | 45 const unsigned char* checkPtr = imagePtr + offsets[i]; |
| 47 checkVal = *checkPtr >> 7; | 46 checkVal = (*checkPtr != 0); |
| 48 } else { | 47 } else { |
| 49 checkVal = 0; | 48 checkVal = false; |
| 50 } | 49 } |
| 51 SkASSERT(checkVal == 0 || checkVal == 1); | 50 SkASSERT(checkVal == 0 || checkVal == 1); |
| 52 SkASSERT(currVal == 0 || currVal == 1); | 51 SkASSERT(currVal == 0 || currVal == 1); |
| 53 if (checkVal != currVal) { | 52 if (checkVal != currVal) { |
| 54 return true; | 53 return true; |
| 55 } | 54 } |
| 56 } | 55 } |
| 57 | 56 |
| 58 return false; | 57 return false; |
| 59 } | 58 } |
| (...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 420 currEdge -= dataWidth-1; | 419 currEdge -= dataWidth-1; |
| 421 } | 420 } |
| 422 | 421 |
| 423 // copy results to final distance field data | 422 // copy results to final distance field data |
| 424 currData = dataPtr + dataWidth+1; | 423 currData = dataPtr + dataWidth+1; |
| 425 currEdge = edgePtr + dataWidth+1; | 424 currEdge = edgePtr + dataWidth+1; |
| 426 unsigned char *dfPtr = distanceField; | 425 unsigned char *dfPtr = distanceField; |
| 427 for (int j = 1; j < dataHeight-1; ++j) { | 426 for (int j = 1; j < dataHeight-1; ++j) { |
| 428 for (int i = 1; i < dataWidth-1; ++i) { | 427 for (int i = 1; i < dataWidth-1; ++i) { |
| 429 #if DUMP_EDGE | 428 #if DUMP_EDGE |
| 430 unsigned char val = (currData->fAlpha >= 0.5f) ? 255 : 0; | 429 unsigned char val = sk_float_round2int(255*currData->fAlpha); |
| 431 if (*currEdge) { | 430 if (*currEdge) { |
| 432 val = 128; | 431 val = 128; |
| 433 } | 432 } |
| 434 *dfPtr++ = val; | 433 *dfPtr++ = val; |
| 435 #else | 434 #else |
| 436 float dist; | 435 float dist; |
| 437 if (currData->fAlpha > 0.5f) { | 436 if (currData->fAlpha > 0.5f) { |
| 438 dist = -SkScalarSqrt(currData->fDistSq); | 437 dist = -SkScalarSqrt(currData->fDistSq); |
| 439 } else { | 438 } else { |
| 440 dist = SkScalarSqrt(currData->fDistSq); | 439 dist = SkScalarSqrt(currData->fDistSq); |
| 441 } | 440 } |
| 442 *dfPtr++ = pack_distance_field_val(dist, (float)distanceMagnitude); | 441 *dfPtr++ = pack_distance_field_val(dist, (float)distanceMagnitude); |
| 443 #endif | 442 #endif |
| 444 ++currData; | 443 ++currData; |
| 445 ++currEdge; | 444 ++currEdge; |
| 446 } | 445 } |
| 447 currData += 2; | 446 currData += 2; |
| 448 currEdge += 2; | 447 currEdge += 2; |
| 449 } | 448 } |
| 450 | 449 |
| 451 return true; | 450 return true; |
| 452 } | 451 } |
| OLD | NEW |