Chromium Code Reviews| 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); |