Index: samplecode/SampleBitmap2Path.cpp |
diff --git a/samplecode/SampleBitmap2Path.cpp b/samplecode/SampleBitmap2Path.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..37b400a7220c5850a40bd99ea1cec6f054c72873 |
--- /dev/null |
+++ b/samplecode/SampleBitmap2Path.cpp |
@@ -0,0 +1,175 @@ |
+/* |
+ * Copyright 2011 Google Inc. |
+ * |
+ * Use of this source code is governed by a BSD-style license that can be |
+ * found in the LICENSE file. |
+ */ |
+ |
+#include "SampleCode.h" |
+#include "SkView.h" |
+#include "SkCanvas.h" |
+#include "SkPathOps.h" |
+ |
+#define CHAR_BIT 8 |
+#define SQRT_2 1.41421356237 |
+ |
+bool getBit( const char *buffer, |
reed1
2013/06/13 17:58:41
any function local to your file... static bool ...
|
+ const int x ) { |
reed1
2013/06/13 17:58:41
for parameters, const on a non-ptr is never meanin
|
+ |
+ int byte = x / CHAR_BIT; |
reed1
2013/06/13 17:58:41
nit: when you know your modulus is a power of two,
|
+ int bit = x % CHAR_BIT; |
+ |
+ return buffer[byte] & (1 << bit); |
reed1
2013/06/13 17:58:41
this is not a bool, but an int (which is fine), bu
|
+} |
+ |
+ |
+void line2path_pixel( SkPath* path, |
+ const char* line, |
+ const int lineIdx, |
+ const int width ) { |
+ for (int i=0; i<width; i++) { |
+ // simply makes every ON pixel into a rect path |
+ if (getBit(line,i)==1) { |
+ // add a rect for the pixel |
+ SkRect r = { i, lineIdx, i+1, lineIdx+1 }; |
reed1
2013/06/13 17:58:41
alternate:
SkRect::MakeXYWH(i, lineIdx, 1, 1)
co
|
+ path->addRect(r, SkPath::kCW_Direction); |
+ } |
+ } |
+} |
+ |
+void line2path_pixelCircle( SkPath* path, |
reed1
2013/06/13 17:58:41
all these guys can be marked 'static'
|
+ const char* line, |
+ const int lineIdx, |
+ const int width ) { |
+ for (int i=0; i<width; i++) { |
reed1
2013/06/13 17:58:41
very nitty: need more space, and pre-increment
fo
|
+ // simply makes every ON pixel into a circle path |
+ if (getBit(line,i)==1) { |
reed1
2013/06/13 17:58:41
if (getBit(...)) {
|
+ // add a circle for the pixel |
+ path->addCircle( i+.5, lineIdx+.5, SQRT_2 / 2.0 ); |
reed1
2013/06/13 17:58:41
all 3 params will generate doubles...
use 0.5f if
|
+ } |
+ } |
+} |
+ |
+void line2path_span( SkPath* path, |
+ const char* line, |
+ const int lineIdx, |
+ const int width ) { |
+ bool state = 0; |
+ int start = 1; |
+ |
+ for (int i=0; i<width; i++) { |
+ if (i==width-1) { // if the end of a scanline, close open paths |
+ if (state==1) { |
+ SkRect r = { start, lineIdx, |
+ i+getBit(line,i), lineIdx+1 }; |
+ path->addRect(r, SkPath::kCW_Direction); |
+ } else if (getBit(line,i)==1) { |
+ SkRect r = { i, lineIdx, |
+ i+1, lineIdx+1 }; |
+ path->addRect(r, SkPath::kCW_Direction); |
+ } |
+ start = 0; |
+ state = 0; |
+ // if a transition point: |
+ }else if (getBit(line,i)!=state) { |
+ if (getBit(line,i)==1) { // transition on |
+ state = 1; //mark beginning of span |
+ start = i; |
+ }else { // transition off |
+ state = 0; |
+ SkRect r = { start, lineIdx, |
+ i, lineIdx+1}; |
+ path->addRect(r, SkPath::kCW_Direction); |
+ } |
+ } |
+ } |
+} |
+ |
+void bitmap2path( SkPath* path, |
+ const char* bitmap, |
+ void (*line2path)( SkPath*, |
+ const char*, |
+ const int, |
+ const int ), |
+ const int h, const int w, |
+ const int stride ) { |
+// loop for every line in bitmap |
+ for (int i=0; i<h; i++) { |
+ line2path(path, &bitmap[i*stride], i, w); |
+ } |
+} |
+ |
+ |
+class Bitmap2Path : public SampleView { |
+public: |
+ Bitmap2Path() { |
+ } |
+ |
+protected: |
+ // overrides from SkEventSink |
+ virtual bool onQuery(SkEvent* evt) { |
+ if (SampleCode::TitleQ(*evt)) { |
+ SampleCode::TitleR(evt, "Bitmap2Path"); |
+ return true; |
+ } |
+ return this->INHERITED::onQuery(evt); |
+ } |
+ |
+ virtual void onDrawContent(SkCanvas* canvas) { |
+ const char raw_bits[] = { |
+ 0x99, 0x00, |
+ 0x5a, 0x00, |
+ 0x3c, 0x00, |
+ 0x18, 0x00, |
+ 0x99, 0x00, |
+ 0x5a, 0x00, |
+ 0x3c, 0x00, |
+ 0x18, 0x00, |
+ }; |
+ |
+ // pointer into memory for binary bitmap |
+ const char* bitmap = (char*) &raw_bits; |
+ int h=8, w=8, str=2; |
+ |
+ // array of funtion pointers for modes (allows looping) |
+ const int numModes = 3; |
+ void (*mode[numModes])( SkPath*, const char*, |
reed1
2013/06/13 17:58:41
const void (*....
maybe typdef this guy to a name
|
+ const int, const int ) |
+ = { line2path_pixel, line2path_pixelCircle, line2path_span }; |
+ |
+ // select paint for drawing binary pixels -- BLACK |
+ SkPaint paint; |
+ paint.setAntiAlias(true); |
+ paint.setStyle(SkPaint::kFill_Style); |
+ paint.setColor(SK_ColorBLACK); |
+ |
+ // for each mode |
+ for (int i=0; i<numModes; i++) |
+ { |
+ //convert bitmap to path |
+ SkPath path; |
+ bitmap2path(&path,bitmap,mode[i],h,w,str); |
+ |
+ //simplify path |
+ SkPath simple; |
+ Simplify(path, &simple); |
+ |
+ //draw to canvas |
+ canvas->save(); |
+ canvas->scale(10.0, 10.0); |
reed1
2013/06/13 17:58:41
more doubles
canvas->scale(10, 10);
|
+ canvas->translate(10.0*i, 0); |
+ canvas->drawPath(simple, paint); |
+ canvas->restore(); |
+ } |
+ |
+// this->inval(NULL); |
+ } |
+ |
+private: |
+ typedef SkView INHERITED; |
+}; |
+ |
+////////////////////////////////////////////////////////////////////////////// |
+ |
+static SkView* MyFactory() { return new Bitmap2Path; } |
+static SkViewRegister reg(MyFactory); |