OLD | NEW |
| (Empty) |
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 | |
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 | |
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), SkIntToScal
ar(lineIdx), | |
79 SkIntToScalar(i-start), SK_Scalar
1), | |
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(lineI
dx), | |
89 SkIntToScalar(width - 1 + end - start), S
K_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 | |
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 | |
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 } | |
OLD | NEW |