• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  CAUTION: EXPERIMENTAL CODE
3  *
4  *  This code is not to be used and will not be supported
5  *  if it fails on you. DO NOT USE!
6  *
7  */
8 
9 #include "SkPathUtils.h"
10 
11 #include "SkPath.h"
12 #include "SkPathOps.h" // this can't be found, how do I link it?
13 #include "SkRegion.h"
14 
15 typedef void (*line2path)(SkPath*, const char*, int, int);
16 #define SQRT_2 1.41421356237f
17 #define ON  0xFF000000 // black pixel
18 #define OFF 0x00000000 // transparent pixel
19 
20 // assumes stride is in bytes
21 /*
22 static void FillRandomBits( int chars, char* bits ){
23     SkTime time;
24     SkRandom rand = SkRandom( time.GetMSecs() );
25 
26     for (int i = 0; i < chars; ++i){
27         bits[i] = rand.nextU();
28     }
29 }OA
30 */
31 
GetBit(const char * buffer,int x)32 static int GetBit( const char* buffer, int x ) {
33     int byte = x >> 3;
34     int bit = x & 7;
35 
36     return buffer[byte] & (128 >> bit);
37 }
38 
39 /*
40 static void Line2path_pixel(SkPath* path, const char* line,
41                             int lineIdx, int width) {
42     for (int i = 0; i < width; ++i) {
43         // simply makes every ON pixel into a rect path
44         if (GetBit(line,i)) {
45             path->addRect(SkRect::MakeXYWH(i, lineIdx, 1, 1),
46                           SkPath::kCW_Direction);
47         }
48     }
49 }
50 
51 static void Line2path_pixelCircle(SkPath* path, const char* line,
52                                   int lineIdx, int width) {
53     for (int i = 0; i < width; ++i) {
54         // simply makes every ON pixel into a circle path
55         if (GetBit(line,i)) {
56             path->addCircle(i + SK_ScalarHalf,
57                             lineIdx + SK_ScalarHalf,
58                             SQRT_2 / 2.0f);
59         }
60     }
61 }
62 */
63 
Line2path_span(SkPath * path,const char * line,int lineIdx,int width)64 static void Line2path_span(SkPath* path, const char* line,
65                            int lineIdx, int width) {
66     bool inRun = 0;
67     int start = 1;
68 
69     for (int i = 0; i < width; ++i) {
70         int curPixel = GetBit(line,i);
71 
72         if ( (curPixel!=0) != inRun ) { // if transition
73             if (curPixel) { // if transition on
74                 inRun = 1;
75                 start = i; // mark beginning of span
76             }else { // if transition off add the span as a path
77                 inRun = 0;
78                 path->addRect(SkRect::MakeXYWH(SkIntToScalar(start), SkIntToScalar(lineIdx),
79                                                SkIntToScalar(i-start), SK_Scalar1),
80                               SkPath::kCW_Direction);
81             }
82         }
83     }
84 
85     if (inRun==1) { // close any open spans
86         int end = 0;
87         if ( GetBit(line,width-1) ) ++end;
88         path->addRect(SkRect::MakeXYWH(SkIntToScalar(start), SkIntToScalar(lineIdx),
89                                        SkIntToScalar(width - 1 + end - start), SK_Scalar1),
90                       SkPath::kCW_Direction);
91     } else if ( GetBit(line, width - 1) ) { // if last pixel on add
92         path->addRect(SkRect::MakeXYWH(width - SK_Scalar1, SkIntToScalar(lineIdx),
93                                        SK_Scalar1, SK_Scalar1),
94                       SkPath::kCW_Direction);
95     }
96 }
97 
BitsToPath_Path(SkPath * path,const char * bitmap,int w,int h,int stride)98 void SkPathUtils::BitsToPath_Path(SkPath* path,
99                         const char* bitmap,
100                         int w, int h, int stride) {
101     // loop for every line in bitmap
102     for (int i = 0; i < h; ++i) {
103         // fn ptr handles each line separately
104         //l2p_fn(path, &bitmap[i*stride], i, w);
105         Line2path_span(path, &bitmap[i*stride], i, w);
106     }
107     Simplify(*path, path); // simplify resulting path.
108 }
109 
BitsToPath_Region(SkPath * path,const char * bitmap,int w,int h,int stride)110 void SkPathUtils::BitsToPath_Region(SkPath* path,
111                                const char* bitmap,
112                                int w, int h, int stride) {
113     SkRegion region;
114 
115     // loop for each line
116     for (int y = 0; y < h; ++y){
117         bool inRun = 0;
118         int start = 1;
119         const char* line = &bitmap[y * stride];
120 
121         // loop for each pixel
122         for (int i = 0; i < w; ++i) {
123             int curPixel = GetBit(line,i);
124 
125             if ( (curPixel!=0) != inRun ) { // if transition
126                 if (curPixel) { // if transition on
127                     inRun = 1;
128                     start = i; // mark beginning of span
129                 }else { // if transition off add the span as a path
130                     inRun = 0;
131                     //add here
132                     region.op(SkIRect::MakeXYWH(start, y, i-start, 1),
133                               SkRegion::kUnion_Op );
134                 }
135             }
136         }
137         if (inRun==1) { // close any open spans
138             int end = 0;
139             if ( GetBit(line,w-1) ) ++end;
140             // add the thing here
141             region.op(SkIRect::MakeXYWH(start, y, w-1-start+end, 1),
142                       SkRegion::kUnion_Op );
143 
144         } else if ( GetBit(line,w-1) ) { // if last pixel on add rect
145             // add the thing here
146             region.op(SkIRect::MakeXYWH(w-1, y, 1, 1),
147                       SkRegion::kUnion_Op );
148         }
149     }
150     // convert region to path
151     region.getBoundaryPath(path);
152 }
153