diff -r 000000000000 -r 6474c204b198 gfx/skia/trunk/src/utils/SkPathUtils.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gfx/skia/trunk/src/utils/SkPathUtils.cpp Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,152 @@ +/* + * 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; + SkRandom rand = SkRandom( 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, + 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(SkIntToScalar(start), SkIntToScalar(lineIdx), + SkIntToScalar(i-start), SK_Scalar1), + SkPath::kCW_Direction); + } + } + } + + if (inRun==1) { // close any open spans + int end = 0; + if ( GetBit(line,width-1) ) ++end; + path->addRect(SkRect::MakeXYWH(SkIntToScalar(start), SkIntToScalar(lineIdx), + SkIntToScalar(width - 1 + end - start), SK_Scalar1), + SkPath::kCW_Direction); + } else if ( GetBit(line, width - 1) ) { // if last pixel on add + path->addRect(SkRect::MakeXYWH(width - SK_Scalar1, SkIntToScalar(lineIdx), + SK_Scalar1, SK_Scalar1), + SkPath::kCW_Direction); + } +} + +void SkPathUtils::BitsToPath_Path(SkPath* path, + const char* bitmap, + int w, int h, 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 path. +} + +void SkPathUtils::BitsToPath_Region(SkPath* path, + const char* bitmap, + int w, int h, 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); +}