1064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org/* 2064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org * CAUTION: EXPERIMENTAL CODE 3064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org * 4064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org * This code is not to be used and will not be supported 5064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org * if it fails on you. DO NOT USE! 6064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org * 7064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org */ 8064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org 9064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org#include "SkPathUtils.h" 10064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org 11064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org#include "SkPath.h" 12064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org#include "SkPathOps.h" // this can't be found, how do I link it? 13064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org#include "SkRegion.h" 14064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org 15064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.orgtypedef void (*line2path)(SkPath*, const char*, int, int); 16064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org#define SQRT_2 1.41421356237f 17064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org#define ON 0xFF000000 // black pixel 18064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org#define OFF 0x00000000 // transparent pixel 19064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org 20064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org// assumes stride is in bytes 21064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org/* 22064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.orgstatic void FillRandomBits( int chars, char* bits ){ 23064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org SkTime time; 24e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.org SkRandom rand = SkRandom( time.GetMSecs() ); 25064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org 26064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org for (int i = 0; i < chars; ++i){ 27064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org bits[i] = rand.nextU(); 28064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org } 29064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org}OA 300d55dd7d2c07a77b22478bed9b30ff44ceecad68skia.committer@gmail.com*/ 31064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org 32064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.orgstatic int GetBit( const char* buffer, int x ) { 33064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org int byte = x >> 3; 34064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org int bit = x & 7; 35064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org 36064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org return buffer[byte] & (128 >> bit); 37064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org} 38064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org 39064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org/* 40064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.orgstatic void Line2path_pixel(SkPath* path, const char* line, 41064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org int lineIdx, int width) { 42064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org for (int i = 0; i < width; ++i) { 43064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org // simply makes every ON pixel into a rect path 44064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org if (GetBit(line,i)) { 45064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org path->addRect(SkRect::MakeXYWH(i, lineIdx, 1, 1), 46064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org SkPath::kCW_Direction); 47064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org } 48064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org } 49064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org} 50064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org 51064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.orgstatic void Line2path_pixelCircle(SkPath* path, const char* line, 52064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org int lineIdx, int width) { 53064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org for (int i = 0; i < width; ++i) { 54064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org // simply makes every ON pixel into a circle path 55064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org if (GetBit(line,i)) { 56064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org path->addCircle(i + SK_ScalarHalf, 57064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org lineIdx + SK_ScalarHalf, 584b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org SQRT_2 / 2.0f); 59064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org } 60064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org } 61064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org} 62064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org*/ 63064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org 64064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.orgstatic void Line2path_span(SkPath* path, const char* line, 65064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org int lineIdx, int width) { 66064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org bool inRun = 0; 67064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org int start = 1; 68064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org 69064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org for (int i = 0; i < width; ++i) { 70064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org int curPixel = GetBit(line,i); 71064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org 72064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org if ( (curPixel!=0) != inRun ) { // if transition 73064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org if (curPixel) { // if transition on 74064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org inRun = 1; 75064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org start = i; // mark beginning of span 76064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org }else { // if transition off add the span as a path 77064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org inRun = 0; 786b4231225f38f966b6c6ba07332877b8be469b17dierk@google.com path->addRect(SkRect::MakeXYWH(SkIntToScalar(start), SkIntToScalar(lineIdx), 7919b8438ffba0de8e280016705f2976bd0a21dff2dierk@google.com SkIntToScalar(i-start), SK_Scalar1), 80064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org SkPath::kCW_Direction); 81064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org } 82064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org } 83064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org } 84064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org 85064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org if (inRun==1) { // close any open spans 86064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org int end = 0; 87064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org if ( GetBit(line,width-1) ) ++end; 886b4231225f38f966b6c6ba07332877b8be469b17dierk@google.com path->addRect(SkRect::MakeXYWH(SkIntToScalar(start), SkIntToScalar(lineIdx), 896b4231225f38f966b6c6ba07332877b8be469b17dierk@google.com SkIntToScalar(width - 1 + end - start), SK_Scalar1), 90064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org SkPath::kCW_Direction); 916bee4ec36af9cd515e74bbc75f449815a8ffd842dierk@google.com } else if ( GetBit(line, width - 1) ) { // if last pixel on add 926b4231225f38f966b6c6ba07332877b8be469b17dierk@google.com path->addRect(SkRect::MakeXYWH(width - SK_Scalar1, SkIntToScalar(lineIdx), 9374887b6eddea9816c60313c6d5cfa744ccb90425dierk@google.com SK_Scalar1, SK_Scalar1), 94064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org SkPath::kCW_Direction); 95064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org } 96064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org} 97064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org 98064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.orgvoid SkPathUtils::BitsToPath_Path(SkPath* path, 99064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org const char* bitmap, 100d43f6449129f11c9823bdeb0fb8ac38ab6d76a28commit-bot@chromium.org int w, int h, int stride) { 101064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org // loop for every line in bitmap 102064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org for (int i = 0; i < h; ++i) { 103064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org // fn ptr handles each line separately 104064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org //l2p_fn(path, &bitmap[i*stride], i, w); 105064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org Line2path_span(path, &bitmap[i*stride], i, w); 106064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org } 107d43f6449129f11c9823bdeb0fb8ac38ab6d76a28commit-bot@chromium.org Simplify(*path, path); // simplify resulting path. 108064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org} 109064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org 110064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.orgvoid SkPathUtils::BitsToPath_Region(SkPath* path, 111064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org const char* bitmap, 112d43f6449129f11c9823bdeb0fb8ac38ab6d76a28commit-bot@chromium.org int w, int h, int stride) { 113064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org SkRegion region; 114064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org 115064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org // loop for each line 116064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org for (int y = 0; y < h; ++y){ 117064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org bool inRun = 0; 118064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org int start = 1; 119064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org const char* line = &bitmap[y * stride]; 1200d55dd7d2c07a77b22478bed9b30ff44ceecad68skia.committer@gmail.com 1210d55dd7d2c07a77b22478bed9b30ff44ceecad68skia.committer@gmail.com // loop for each pixel 122064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org for (int i = 0; i < w; ++i) { 123064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org int curPixel = GetBit(line,i); 1240d55dd7d2c07a77b22478bed9b30ff44ceecad68skia.committer@gmail.com 125064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org if ( (curPixel!=0) != inRun ) { // if transition 126064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org if (curPixel) { // if transition on 127064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org inRun = 1; 128064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org start = i; // mark beginning of span 129064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org }else { // if transition off add the span as a path 130064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org inRun = 0; 131064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org //add here 132064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org region.op(SkIRect::MakeXYWH(start, y, i-start, 1), 133064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org SkRegion::kUnion_Op ); 134064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org } 135064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org } 136064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org } 137064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org if (inRun==1) { // close any open spans 138064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org int end = 0; 139064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org if ( GetBit(line,w-1) ) ++end; 140064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org // add the thing here 141064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org region.op(SkIRect::MakeXYWH(start, y, w-1-start+end, 1), 142064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org SkRegion::kUnion_Op ); 1430d55dd7d2c07a77b22478bed9b30ff44ceecad68skia.committer@gmail.com 144064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org } else if ( GetBit(line,w-1) ) { // if last pixel on add rect 145064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org // add the thing here 146064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org region.op(SkIRect::MakeXYWH(w-1, y, 1, 1), 147064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org SkRegion::kUnion_Op ); 148064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org } 149064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org } 150064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org // convert region to path 151064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org region.getBoundaryPath(path); 152064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org} 153