skia2/samplecode/SampleRegion.cpp
caryclark@google.com 02939ce4bd fix warnings on Mac in ssamplecode
Fix these class of warnings:
- unused functions
- unused locals
- sign mismatch
- missing function prototypes
- missing newline at end of file
- 64 to 32 bit truncation

The changes prefer to link in dead code in the debug build
with 'if (false)' than to comment it out, but trivial cases
are commented out or sometimes deleted if it appears to be
a copy/paste error.
Review URL: https://codereview.appspot.com/6301044

git-svn-id: http://skia.googlecode.com/svn/trunk@4183 2bbb7eff-a529-9590-31e7-b0007b416f81
2012-06-06 12:09:51 +00:00

419 lines
12 KiB
C++

/*
* 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 "SkGradientShader.h"
#include "SkPath.h"
#include "SkRegion.h"
#include "SkShader.h"
#include "SkUtils.h"
#include "SkImageDecoder.h"
static void test_strokerect(SkCanvas* canvas) {
int width = 100;
int height = 100;
SkBitmap bitmap;
bitmap.setConfig(SkBitmap::kA8_Config, width*2, height*2);
bitmap.allocPixels();
bitmap.eraseColor(0);
SkScalar dx = 20;
SkScalar dy = 20;
SkPath path;
path.addRect(0.0f, 0.0f,
SkIntToScalar(width), SkIntToScalar(height),
SkPath::kCW_Direction);
SkRect r = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height));
SkCanvas c(bitmap);
c.translate(dx, dy);
SkPaint paint;
paint.setStyle(SkPaint::kStroke_Style);
paint.setStrokeWidth(1);
// use the rect
c.clear(0);
c.drawRect(r, paint);
canvas->drawBitmap(bitmap, 0, 0, NULL);
// use the path
c.clear(0);
c.drawPath(path, paint);
canvas->drawBitmap(bitmap, SkIntToScalar(2*width), 0, NULL);
}
static void drawFadingText(SkCanvas* canvas,
const char* text, size_t len, SkScalar x, SkScalar y,
const SkPaint& paint) {
// Need a bounds for the text
SkRect bounds;
SkPaint::FontMetrics fm;
paint.getFontMetrics(&fm);
bounds.set(x, y + fm.fTop, x + paint.measureText(text, len), y + fm.fBottom);
// may need to outset bounds a little, to account for hinting and/or
// antialiasing
bounds.inset(-SkIntToScalar(2), -SkIntToScalar(2));
canvas->saveLayer(&bounds, NULL);
canvas->drawText(text, len, x, y, paint);
const SkPoint pts[] = {
{ bounds.fLeft, y },
{ bounds.fRight, y }
};
const SkColor colors[] = { SK_ColorBLACK, SK_ColorBLACK, 0 };
// pos[1] value is where we start to fade, relative to the width
// of our pts[] array.
const SkScalar pos[] = { 0, SkFloatToScalar(0.9f), SK_Scalar1 };
SkShader* s = SkGradientShader::CreateLinear(pts, colors, pos, 3,
SkShader::kClamp_TileMode);
SkPaint p;
p.setShader(s)->unref();
p.setXfermodeMode(SkXfermode::kDstIn_Mode);
canvas->drawRect(bounds, p);
canvas->restore();
}
static void test_text(SkCanvas* canvas) {
SkPaint paint;
paint.setAntiAlias(true);
paint.setTextSize(20);
const char* str = "Hamburgefons";
size_t len = strlen(str);
SkScalar x = 20;
SkScalar y = 20;
canvas->drawText(str, len, x, y, paint);
y += 20;
const SkPoint pts[] = { { x, y }, { x + paint.measureText(str, len), y } };
const SkColor colors[] = { SK_ColorBLACK, SK_ColorBLACK, 0 };
const SkScalar pos[] = { 0, 0.9f, 1 };
SkShader* s = SkGradientShader::CreateLinear(pts, colors, pos,
SK_ARRAY_COUNT(colors),
SkShader::kClamp_TileMode);
paint.setShader(s)->unref();
canvas->drawText(str, len, x, y, paint);
y += 20;
paint.setShader(NULL);
drawFadingText(canvas, str, len, x, y, paint);
}
#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
#ifdef SK_DEBUG
static void make_rgn(SkRegion* rgn, int left, int top, int right, int bottom,
size_t count, int32_t runs[]) {
SkIRect r;
r.set(left, top, right, bottom);
rgn->debugSetRuns(runs, count);
SkASSERT(rgn->getBounds() == r);
}
static void test_union_bug_1505668(SkRegion* ra, SkRegion* rb, SkRegion* rc) {
static int32_t dataA[] = {
0x00000001,
0x000001dd, 2, 0x00000001, 0x0000000c, 0x0000000d, 0x00000025, 0x7fffffff,
0x000001de, 1, 0x00000001, 0x00000025, 0x7fffffff,
0x000004b3, 1, 0x00000001, 0x00000026, 0x7fffffff,
0x000004b4, 1, 0x0000000c, 0x00000026, 0x7fffffff,
0x00000579, 1, 0x00000000, 0x0000013a, 0x7fffffff,
0x000005d8, 1, 0x00000000, 0x0000013b, 0x7fffffff,
0x7fffffff
};
make_rgn(ra, 0, 1, 315, 1496, SK_ARRAY_COUNT(dataA), dataA);
static int32_t dataB[] = {
0x000000b6,
0x000000c4, 1, 0x000000a1, 0x000000f0, 0x7fffffff,
0x000000d6, 0, 0x7fffffff,
0x000000e4, 2, 0x00000070, 0x00000079, 0x000000a1, 0x000000b0, 0x7fffffff,
0x000000e6, 0, 0x7fffffff,
0x000000f4, 2, 0x00000070, 0x00000079, 0x000000a1, 0x000000b0, 0x7fffffff,
0x000000f6, 0, 0x7fffffff,
0x00000104, 1, 0x000000a1, 0x000000b0, 0x7fffffff,
0x7fffffff
};
make_rgn(rb, 112, 182, 240, 260, SK_ARRAY_COUNT(dataB), dataB);
rc->op(*ra, *rb, SkRegion::kUnion_Op);
}
#endif
static void scale_rect(SkIRect* dst, const SkIRect& src, float scale) {
dst->fLeft = (int)::roundf(src.fLeft * scale);
dst->fTop = (int)::roundf(src.fTop * scale);
dst->fRight = (int)::roundf(src.fRight * scale);
dst->fBottom = (int)::roundf(src.fBottom * scale);
}
static void scale_rgn(SkRegion* dst, const SkRegion& src, float scale) {
SkRegion tmp;
SkRegion::Iterator iter(src);
for (; !iter.done(); iter.next()) {
SkIRect r;
scale_rect(&r, iter.rect(), scale);
tmp.op(r, SkRegion::kUnion_Op);
}
dst->swap(tmp);
}
static void paint_rgn(SkCanvas* canvas, const SkRegion& rgn,
const SkPaint& paint) {
SkRegion scaled;
scale_rgn(&scaled, rgn, 0.5f);
SkRegion::Iterator iter(rgn);
for (; !iter.done(); iter.next())
{
SkRect r;
r.set(iter.rect());
canvas->drawRect(r, paint);
}
}
class RegionView : public SampleView {
public:
RegionView() {
fBase.set(100, 100, 150, 150);
fRect = fBase;
fRect.inset(5, 5);
fRect.offset(25, 25);
this->setBGColor(0xFFDDDDDD);
}
void build_base_rgn(SkRegion* rgn) {
rgn->setRect(fBase);
SkIRect r = fBase;
r.offset(75, 20);
rgn->op(r, SkRegion::kUnion_Op);
}
void build_rgn(SkRegion* rgn, SkRegion::Op op) {
build_base_rgn(rgn);
rgn->op(fRect, op);
}
protected:
// overrides from SkEventSink
virtual bool onQuery(SkEvent* evt) {
if (SampleCode::TitleQ(*evt)) {
SampleCode::TitleR(evt, "Regions");
return true;
}
return this->INHERITED::onQuery(evt);
}
static void drawstr(SkCanvas* canvas, const char text[], const SkPoint& loc,
bool hilite) {
SkPaint paint;
paint.setAntiAlias(true);
paint.setTextSize(SkIntToScalar(20));
paint.setColor(hilite ? SK_ColorRED : 0x40FF0000);
canvas->drawText(text, strlen(text), loc.fX, loc.fY, paint);
}
void drawPredicates(SkCanvas* canvas, const SkPoint pts[]) {
SkRegion rgn;
build_base_rgn(&rgn);
drawstr(canvas, "Intersects", pts[0], rgn.intersects(fRect));
drawstr(canvas, "Contains", pts[1], rgn.contains(fRect));
}
void drawOrig(SkCanvas* canvas, bool bg) {
SkRect r;
SkPaint paint;
paint.setStyle(SkPaint::kStroke_Style);
if (bg)
paint.setColor(0xFFBBBBBB);
SkRegion rgn;
build_base_rgn(&rgn);
paint_rgn(canvas, rgn, paint);
r.set(fRect);
canvas->drawRect(r, paint);
}
void drawRgnOped(SkCanvas* canvas, SkRegion::Op op, SkColor color) {
SkRegion rgn;
this->build_rgn(&rgn, op);
{
SkRegion tmp, tmp2(rgn);
tmp = tmp2;
tmp.translate(5, -3);
{
char buffer[1000];
size_t size = tmp.flatten(NULL);
SkASSERT(size <= sizeof(buffer));
size_t size2 = tmp.flatten(buffer);
SkASSERT(size == size2);
SkRegion tmp3;
size2 = tmp3.unflatten(buffer);
SkASSERT(size == size2);
SkASSERT(tmp3 == tmp);
}
rgn.translate(20, 30, &tmp);
SkASSERT(rgn.isEmpty() || tmp != rgn);
tmp.translate(-20, -30);
SkASSERT(tmp == rgn);
}
this->drawOrig(canvas, true);
SkPaint paint;
paint.setColor((color & ~(0xFF << 24)) | (0x44 << 24));
paint_rgn(canvas, rgn, paint);
paint.setStyle(SkPaint::kStroke_Style);
paint.setColor(color);
paint_rgn(canvas, rgn, paint);
}
void drawPathOped(SkCanvas* canvas, SkRegion::Op op, SkColor color) {
SkRegion rgn;
SkPath path;
this->build_rgn(&rgn, op);
rgn.getBoundaryPath(&path);
this->drawOrig(canvas, true);
SkPaint paint;
paint.setStyle(SkPaint::kFill_Style);
paint.setColor((color & ~(0xFF << 24)) | (0x44 << 24));
canvas->drawPath(path, paint);
paint.setColor(color);
paint.setStyle(SkPaint::kStroke_Style);
canvas->drawPath(path, paint);
}
virtual void onDrawContent(SkCanvas* canvas) {
if (false) { // avoid bit rot, suppress warning
test_strokerect(canvas);
return;
}
if (false) { // avoid bit rot, suppress warning
test_text(canvas);
return;
}
#ifdef SK_DEBUG
if (true) {
SkRegion a, b, c;
test_union_bug_1505668(&a, &b, &c);
if (false) { // draw the result of the test
SkPaint paint;
canvas->translate(SkIntToScalar(10), SkIntToScalar(10));
paint.setColor(SK_ColorRED);
paint_rgn(canvas, a, paint);
paint.setColor(0x800000FF);
paint_rgn(canvas, b, paint);
paint.setColor(SK_ColorBLACK);
paint.setStyle(SkPaint::kStroke_Style);
// paint_rgn(canvas, c, paint);
return;
}
}
#endif
const SkPoint origins[] = {
{ 30*SK_Scalar1, 50*SK_Scalar1 },
{ 150*SK_Scalar1, 50*SK_Scalar1 },
};
this->drawPredicates(canvas, origins);
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->save();
canvas->translate(0, SkIntToScalar(200));
this->drawPathOped(canvas, gOps[op].fOp, gOps[op].fColor);
canvas->restore();
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 RegionView; }
static SkViewRegister reg(MyFactory);