check-point for aaclip
git-svn-id: http://skia.googlecode.com/svn/trunk@2419 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
1deaab51e7
commit
47ac84edaf
175
samplecode/SampleAAClip2.cpp
Normal file
175
samplecode/SampleAAClip2.cpp
Normal file
@ -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 "SkAAClip.h"
|
||||
#include "SampleCode.h"
|
||||
#include "SkView.h"
|
||||
#include "SkCanvas.h"
|
||||
#include "SkGradientShader.h"
|
||||
#include "SkPath.h"
|
||||
#include "SkRegion.h"
|
||||
#include "SkShader.h"
|
||||
#include "SkUtils.h"
|
||||
#include "SkImageDecoder.h"
|
||||
|
||||
#ifdef SK_BUILD_FOR_WIN
|
||||
// windows doesn't have roundf
|
||||
inline float roundf(float x) { return (x-floor(x))>0.5 ? ceil(x) : floor(x); }
|
||||
#endif
|
||||
|
||||
static void drawClip(SkCanvas* canvas, const SkAAClip& clip) {
|
||||
SkMask mask;
|
||||
SkBitmap bm;
|
||||
|
||||
clip.copyToMask(&mask);
|
||||
bm.setConfig(SkBitmap::kA8_Config, mask.fBounds.width(),
|
||||
mask.fBounds.height(), mask.fRowBytes);
|
||||
bm.setPixels(mask.fImage);
|
||||
|
||||
SkPaint paint;
|
||||
canvas->drawBitmap(bm, mask.fBounds.fLeft, mask.fBounds.fTop, &paint);
|
||||
}
|
||||
|
||||
static void paint_rgn(SkCanvas* canvas, const SkAAClip& clip,
|
||||
const SkPaint& paint) {
|
||||
SkMask mask;
|
||||
SkBitmap bm;
|
||||
|
||||
clip.copyToMask(&mask);
|
||||
bm.setConfig(SkBitmap::kA8_Config, mask.fBounds.width(),
|
||||
mask.fBounds.height(), mask.fRowBytes);
|
||||
bm.setPixels(mask.fImage);
|
||||
|
||||
canvas->drawBitmap(bm, mask.fBounds.fLeft, mask.fBounds.fTop, &paint);
|
||||
}
|
||||
|
||||
class AAClipView2 : public SampleView {
|
||||
public:
|
||||
AAClipView2() {
|
||||
fBase.set(100, 100, 150, 150);
|
||||
fRect = fBase;
|
||||
fRect.inset(5, 5);
|
||||
fRect.offset(25, 25);
|
||||
this->setBGColor(0xFFDDDDDD);
|
||||
}
|
||||
|
||||
void build_rgn(SkAAClip* clip, SkRegion::Op op) {
|
||||
clip->setRect(fBase);
|
||||
#if 0
|
||||
SkIRect r = fBase;
|
||||
r.offset(75, 20);
|
||||
rgn->op(r, SkRegion::kUnion_Op);
|
||||
#endif
|
||||
|
||||
SkRect r;
|
||||
r.set(fRect);
|
||||
SkPath path;
|
||||
path.addOval(r);
|
||||
SkAAClip clip2;
|
||||
clip2.setPath(path);
|
||||
// hack
|
||||
op = SkRegion::kIntersect_Op;
|
||||
clip->op(clip2, op);
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
// overrides from SkEventSink
|
||||
virtual bool onQuery(SkEvent* evt) {
|
||||
if (SampleCode::TitleQ(*evt)) {
|
||||
SampleCode::TitleR(evt, "AAClips");
|
||||
return true;
|
||||
}
|
||||
return this->INHERITED::onQuery(evt);
|
||||
}
|
||||
|
||||
void drawOrig(SkCanvas* canvas, bool bg) {
|
||||
SkRect r;
|
||||
SkPaint paint;
|
||||
|
||||
paint.setStyle(SkPaint::kStroke_Style);
|
||||
if (bg)
|
||||
paint.setColor(0xFFBBBBBB);
|
||||
|
||||
r.set(fBase);
|
||||
canvas->drawRect(r, paint);
|
||||
r.set(fRect);
|
||||
canvas->drawRect(r, paint);
|
||||
}
|
||||
|
||||
void drawRgnOped(SkCanvas* canvas, SkRegion::Op op, SkColor color) {
|
||||
SkAAClip clip;
|
||||
|
||||
this->build_rgn(&clip, op);
|
||||
|
||||
this->drawOrig(canvas, true);
|
||||
|
||||
SkPaint paint;
|
||||
paint.setColor((color & ~(0xFF << 24)) | (0x44 << 24));
|
||||
paint_rgn(canvas, clip, paint);
|
||||
|
||||
paint.setStyle(SkPaint::kStroke_Style);
|
||||
paint.setColor(color);
|
||||
paint_rgn(canvas, clip, paint);
|
||||
}
|
||||
|
||||
virtual void onDrawContent(SkCanvas* canvas) {
|
||||
|
||||
static const struct {
|
||||
SkColor fColor;
|
||||
const char* fName;
|
||||
SkRegion::Op fOp;
|
||||
} gOps[] = {
|
||||
{ SK_ColorBLACK, "Difference", SkRegion::kDifference_Op },
|
||||
{ SK_ColorRED, "Intersect", SkRegion::kIntersect_Op },
|
||||
{ 0xFF008800, "Union", SkRegion::kUnion_Op },
|
||||
{ SK_ColorBLUE, "XOR", SkRegion::kXOR_Op }
|
||||
};
|
||||
|
||||
SkPaint textPaint;
|
||||
textPaint.setAntiAlias(true);
|
||||
textPaint.setTextSize(SK_Scalar1*24);
|
||||
|
||||
this->drawOrig(canvas, false);
|
||||
canvas->save();
|
||||
canvas->translate(SkIntToScalar(200), 0);
|
||||
this->drawRgnOped(canvas, SkRegion::kUnion_Op, SK_ColorBLACK);
|
||||
canvas->restore();
|
||||
|
||||
canvas->translate(0, SkIntToScalar(200));
|
||||
|
||||
for (size_t op = 0; op < SK_ARRAY_COUNT(gOps); op++) {
|
||||
canvas->drawText(gOps[op].fName, strlen(gOps[op].fName), SkIntToScalar(75), SkIntToScalar(50), textPaint);
|
||||
|
||||
this->drawRgnOped(canvas, gOps[op].fOp, gOps[op].fColor);
|
||||
|
||||
canvas->translate(SkIntToScalar(200), 0);
|
||||
}
|
||||
}
|
||||
|
||||
virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y) {
|
||||
return fRect.contains(SkScalarRound(x), SkScalarRound(y)) ? new Click(this) : NULL;
|
||||
}
|
||||
|
||||
virtual bool onClick(Click* click) {
|
||||
fRect.offset(click->fICurr.fX - click->fIPrev.fX,
|
||||
click->fICurr.fY - click->fIPrev.fY);
|
||||
this->inval(NULL);
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
SkIRect fBase, fRect;
|
||||
|
||||
typedef SampleView INHERITED;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static SkView* MyFactory() { return new AAClipView2; }
|
||||
static SkViewRegister reg(MyFactory);
|
||||
|
@ -112,7 +112,7 @@ void SkAAClip::Iter::next() {
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void SkAAClip::freeRuns() {
|
||||
if (this->isComplex()) {
|
||||
if (fRunHead) {
|
||||
SkASSERT(fRunHead->fRefCnt >= 1);
|
||||
if (1 == sk_atomic_dec(&fRunHead->fRefCnt)) {
|
||||
sk_free(fRunHead);
|
||||
@ -122,11 +122,11 @@ void SkAAClip::freeRuns() {
|
||||
|
||||
SkAAClip::SkAAClip() {
|
||||
fBounds.setEmpty();
|
||||
fRunHead = SkAAClip_gEmptyPtr;
|
||||
fRunHead = NULL;
|
||||
}
|
||||
|
||||
SkAAClip::SkAAClip(const SkAAClip& src) {
|
||||
fRunHead = SkAAClip_gEmptyPtr;
|
||||
fRunHead = NULL;
|
||||
*this = src;
|
||||
}
|
||||
|
||||
@ -139,7 +139,7 @@ SkAAClip& SkAAClip::operator=(const SkAAClip& src) {
|
||||
this->freeRuns();
|
||||
fBounds = src.fBounds;
|
||||
fRunHead = src.fRunHead;
|
||||
if (this->isComplex()) {
|
||||
if (fRunHead) {
|
||||
sk_atomic_inc(&fRunHead->fRefCnt);
|
||||
}
|
||||
}
|
||||
@ -163,7 +163,7 @@ bool operator==(const SkAAClip& a, const SkAAClip& b) {
|
||||
}
|
||||
|
||||
// now we insist that both are complex (but different ptrs)
|
||||
if (!a.isComplex() || !b.isComplex()) {
|
||||
if (!a.fRunHead || !b.fRunHead) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -185,7 +185,7 @@ bool SkAAClip::set(const SkAAClip& src) {
|
||||
bool SkAAClip::setEmpty() {
|
||||
this->freeRuns();
|
||||
fBounds.setEmpty();
|
||||
fRunHead = SkAAClip_gEmptyPtr;
|
||||
fRunHead = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -193,10 +193,14 @@ bool SkAAClip::setRect(const SkIRect& bounds) {
|
||||
if (bounds.isEmpty()) {
|
||||
return this->setEmpty();
|
||||
}
|
||||
this->freeRuns();
|
||||
fBounds = bounds;
|
||||
fRunHead = SkAAClip_gRectPtr;
|
||||
return true;
|
||||
|
||||
// TODO: special case this
|
||||
|
||||
SkRect r;
|
||||
r.set(bounds);
|
||||
SkPath path;
|
||||
path.addRect(r);
|
||||
return this->setPath(path);
|
||||
}
|
||||
|
||||
bool SkAAClip::setRect(const SkRect& r) {
|
||||
@ -212,7 +216,7 @@ bool SkAAClip::setRect(const SkRect& r) {
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const uint8_t* SkAAClip::findRow(int y, int* lastYForRow) const {
|
||||
SkASSERT(this->isComplex());
|
||||
SkASSERT(fRunHead);
|
||||
|
||||
if (!y_in_rect(y, fBounds)) {
|
||||
return NULL;
|
||||
@ -894,6 +898,22 @@ bool SkAAClip::op(const SkAAClip& clipAOrig, const SkAAClip& clipBOrig,
|
||||
return !this->isEmpty();
|
||||
}
|
||||
|
||||
bool SkAAClip::op(const SkIRect& r, SkRegion::Op op) {
|
||||
SkAAClip clip;
|
||||
clip.setRect(r);
|
||||
return this->op(*this, clip, op);
|
||||
}
|
||||
|
||||
bool SkAAClip::op(const SkRect& r, SkRegion::Op op) {
|
||||
SkAAClip clip;
|
||||
clip.setRect(r);
|
||||
return this->op(*this, clip, op);
|
||||
}
|
||||
|
||||
bool SkAAClip::op(const SkAAClip& clip, SkRegion::Op op) {
|
||||
return this->op(*this, clip, op);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -12,9 +12,6 @@
|
||||
#include "SkBlitter.h"
|
||||
#include "SkRegion.h"
|
||||
|
||||
#define SkAAClip_gEmptyPtr ((SkAAClip::RunHead*)-1)
|
||||
#define SkAAClip_gRectPtr NULL
|
||||
|
||||
class SkAAClip {
|
||||
public:
|
||||
SkAAClip();
|
||||
@ -29,9 +26,7 @@ public:
|
||||
|
||||
void swap(SkAAClip&);
|
||||
|
||||
bool isEmpty() const { return SkAAClip_gEmptyPtr == fRunHead; }
|
||||
// bool isRect() const { return SkAAClip_gRectPtr == fRunHead; }
|
||||
bool isComplex() const { return !this->isEmpty() /*&& !this->isRect()*/; }
|
||||
bool isEmpty() const { return NULL == fRunHead; }
|
||||
const SkIRect& getBounds() const { return fBounds; }
|
||||
|
||||
bool setEmpty();
|
||||
@ -42,6 +37,11 @@ public:
|
||||
|
||||
bool op(const SkAAClip&, const SkAAClip&, SkRegion::Op);
|
||||
|
||||
// Helpers for op()
|
||||
bool op(const SkIRect&, SkRegion::Op);
|
||||
bool op(const SkRect&, SkRegion::Op);
|
||||
bool op(const SkAAClip&, SkRegion::Op);
|
||||
|
||||
/**
|
||||
* Allocates a mask the size of the aaclip, and expands its data into
|
||||
* the mask, using kA8_Format
|
||||
|
Loading…
Reference in New Issue
Block a user