diff options
author | 2013-07-01 17:50:29 +0000 | |
---|---|---|
committer | 2013-07-01 17:50:29 +0000 | |
commit | 064779aa18694b68536c113f7d5b74ccbe38d3ba (patch) | |
tree | dfd68ac72495ef4eb86957526a65e74ee7a92283 /src/utils | |
parent | c6081abd2f28d2179ad8e3bef557cb0d00fffe01 (diff) |
Adding my Bitmap2Path sample for 1on1 meeting.
BUG=
R=reed@google.com, borenet@google.com
Author: dierk@google.com
Review URL: https://chromiumcodereview.appspot.com/16829003
git-svn-id: http://skia.googlecode.com/svn/trunk@9843 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/utils')
-rw-r--r-- | src/utils/SkPathUtils.cpp | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/src/utils/SkPathUtils.cpp b/src/utils/SkPathUtils.cpp new file mode 100644 index 0000000000..3d9bc08a1f --- /dev/null +++ b/src/utils/SkPathUtils.cpp @@ -0,0 +1,150 @@ +/* + * CAUTION: EXPERIMENTAL CODE + * + * This code is not to be used and will not be supported + * if it fails on you. DO NOT USE! + * + */ + +#include "SkPathUtils.h" + +#include "SkPath.h" +#include "SkPathOps.h" // this can't be found, how do I link it? +#include "SkRegion.h" + +typedef void (*line2path)(SkPath*, const char*, int, int); +#define SQRT_2 1.41421356237f +#define ON 0xFF000000 // black pixel +#define OFF 0x00000000 // transparent pixel + +// assumes stride is in bytes +/* +static void FillRandomBits( int chars, char* bits ){ + SkTime time; + SkMWCRandom rand = SkMWCRandom( time.GetMSecs() ); + + for (int i = 0; i < chars; ++i){ + bits[i] = rand.nextU(); + } +}OA +*/ + +static int GetBit( const char* buffer, int x ) { + int byte = x >> 3; + int bit = x & 7; + + return buffer[byte] & (128 >> bit); +} + +/* +static void Line2path_pixel(SkPath* path, const char* line, + int lineIdx, int width) { + for (int i = 0; i < width; ++i) { + // simply makes every ON pixel into a rect path + if (GetBit(line,i)) { + path->addRect(SkRect::MakeXYWH(i, lineIdx, 1, 1), + SkPath::kCW_Direction); + } + } +} + +static void Line2path_pixelCircle(SkPath* path, const char* line, + int lineIdx, int width) { + for (int i = 0; i < width; ++i) { + // simply makes every ON pixel into a circle path + if (GetBit(line,i)) { + path->addCircle(i + SK_ScalarHalf, + lineIdx + SK_ScalarHalf, + SkFloatToScalar(SQRT_2 / 2.0f)); + } + } +} +*/ + +static void Line2path_span(SkPath* path, const char* line, + int lineIdx, int width) { + bool inRun = 0; + int start = 1; + + for (int i = 0; i < width; ++i) { + int curPixel = GetBit(line,i); + + if ( (curPixel!=0) != inRun ) { // if transition + if (curPixel) { // if transition on + inRun = 1; + start = i; // mark beginning of span + }else { // if transition off add the span as a path + inRun = 0; + path->addRect(SkRect::MakeXYWH(start, lineIdx, i-start, 1), + SkPath::kCW_Direction); + } + } + } + + if (inRun==1) { // close any open spans + int end = 0; + if ( GetBit(line,width-1) ) ++end; + path->addRect(SkRect::MakeXYWH(start, lineIdx, + width - 1 + end - start, 1), + SkPath::kCW_Direction); + } else if ( GetBit(line,width-1) ) { // if last pixel on add rect + path->addRect(SkRect::MakeXYWH(width-1, lineIdx, 1, 1), + SkPath::kCW_Direction); + } +} + +void SkPathUtils::BitsToPath_Path(SkPath* path, + const char* bitmap, + int h, int w, int stride) { + // loop for every line in bitmap + for (int i = 0; i < h; ++i) { + // fn ptr handles each line separately + //l2p_fn(path, &bitmap[i*stride], i, w); + Line2path_span(path, &bitmap[i*stride], i, w); + } + Simplify(*path, path); // simplify resulting bitmap +} + +void SkPathUtils::BitsToPath_Region(SkPath* path, + const char* bitmap, + int h, int w, int stride) { + SkRegion region; + + // loop for each line + for (int y = 0; y < h; ++y){ + bool inRun = 0; + int start = 1; + const char* line = &bitmap[y * stride]; + + // loop for each pixel + for (int i = 0; i < w; ++i) { + int curPixel = GetBit(line,i); + + if ( (curPixel!=0) != inRun ) { // if transition + if (curPixel) { // if transition on + inRun = 1; + start = i; // mark beginning of span + }else { // if transition off add the span as a path + inRun = 0; + //add here + region.op(SkIRect::MakeXYWH(start, y, i-start, 1), + SkRegion::kUnion_Op ); + } + } + } + if (inRun==1) { // close any open spans + int end = 0; + if ( GetBit(line,w-1) ) ++end; + // add the thing here + region.op(SkIRect::MakeXYWH(start, y, w-1-start+end, 1), + SkRegion::kUnion_Op ); + + } else if ( GetBit(line,w-1) ) { // if last pixel on add rect + // add the thing here + region.op(SkIRect::MakeXYWH(w-1, y, 1, 1), + SkRegion::kUnion_Op ); + } + } + // convert region to path + region.getBoundaryPath(path); +} |