123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231 |
- /*
- * 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 "include/core/SkBitmap.h"
- #include "include/core/SkCanvas.h"
- #include "include/core/SkColorFilter.h"
- #include "include/core/SkColorPriv.h"
- #include "include/core/SkGraphics.h"
- #include "include/core/SkPath.h"
- #include "include/core/SkRegion.h"
- #include "include/core/SkShader.h"
- #include "include/core/SkStream.h"
- #include "include/core/SkTime.h"
- #include "include/core/SkTypeface.h"
- #include "include/effects/SkCornerPathEffect.h"
- #include "include/effects/SkGradientShader.h"
- #include "include/private/SkTo.h"
- #include "include/utils/SkRandom.h"
- #include "samplecode/Sample.h"
- #include "src/utils/SkUTF.h"
- static SkRandom gRand;
- static void generate_pts(SkPoint pts[], int count, int w, int h) {
- for (int i = 0; i < count; i++) {
- pts[i].set(gRand.nextUScalar1() * 3 * w - SkIntToScalar(w),
- gRand.nextUScalar1() * 3 * h - SkIntToScalar(h));
- }
- }
- static bool check_zeros(const SkPMColor pixels[], int count, int skip) {
- for (int i = 0; i < count; i++) {
- if (*pixels) {
- return false;
- }
- pixels += skip;
- }
- return true;
- }
- static bool check_bitmap_margin(const SkBitmap& bm, int margin) {
- size_t rb = bm.rowBytes();
- for (int i = 0; i < margin; i++) {
- if (!check_zeros(bm.getAddr32(0, i), bm.width(), 1)) {
- return false;
- }
- int bottom = bm.height() - i - 1;
- if (!check_zeros(bm.getAddr32(0, bottom), bm.width(), 1)) {
- return false;
- }
- // left column
- if (!check_zeros(bm.getAddr32(i, 0), bm.height(), SkToInt(rb >> 2))) {
- return false;
- }
- int right = bm.width() - margin + i;
- if (!check_zeros(bm.getAddr32(right, 0), bm.height(),
- SkToInt(rb >> 2))) {
- return false;
- }
- }
- return true;
- }
- #define WIDTH 620
- #define HEIGHT 460
- #define MARGIN 10
- static void line_proc(SkCanvas* canvas, const SkPaint& paint,
- const SkBitmap& bm) {
- const int N = 2;
- SkPoint pts[N];
- for (int i = 0; i < 400; i++) {
- generate_pts(pts, N, WIDTH, HEIGHT);
- canvas->drawLine(pts[0], pts[1], paint);
- if (!check_bitmap_margin(bm, MARGIN)) {
- SkDebugf("---- hairline failure (%g %g) (%g %g)\n",
- pts[0].fX, pts[0].fY, pts[1].fX, pts[1].fY);
- break;
- }
- }
- }
- static void poly_proc(SkCanvas* canvas, const SkPaint& paint,
- const SkBitmap& bm) {
- const int N = 8;
- SkPoint pts[N];
- for (int i = 0; i < 50; i++) {
- generate_pts(pts, N, WIDTH, HEIGHT);
- SkPath path;
- path.moveTo(pts[0]);
- for (int j = 1; j < N; j++) {
- path.lineTo(pts[j]);
- }
- canvas->drawPath(path, paint);
- }
- }
- static SkPoint ave(const SkPoint& a, const SkPoint& b) {
- SkPoint c = a + b;
- c.fX = SkScalarHalf(c.fX);
- c.fY = SkScalarHalf(c.fY);
- return c;
- }
- static void quad_proc(SkCanvas* canvas, const SkPaint& paint,
- const SkBitmap& bm) {
- const int N = 30;
- SkPoint pts[N];
- for (int i = 0; i < 10; i++) {
- generate_pts(pts, N, WIDTH, HEIGHT);
- SkPath path;
- path.moveTo(pts[0]);
- for (int j = 1; j < N - 2; j++) {
- path.quadTo(pts[j], ave(pts[j], pts[j+1]));
- }
- path.quadTo(pts[N - 2], pts[N - 1]);
- canvas->drawPath(path, paint);
- }
- }
- static void add_cubic(SkPath* path, const SkPoint& mid, const SkPoint& end) {
- SkPoint start;
- path->getLastPt(&start);
- path->cubicTo(ave(start, mid), ave(mid, end), end);
- }
- static void cube_proc(SkCanvas* canvas, const SkPaint& paint,
- const SkBitmap& bm) {
- const int N = 30;
- SkPoint pts[N];
- for (int i = 0; i < 10; i++) {
- generate_pts(pts, N, WIDTH, HEIGHT);
- SkPath path;
- path.moveTo(pts[0]);
- for (int j = 1; j < N - 2; j++) {
- add_cubic(&path, pts[j], ave(pts[j], pts[j+1]));
- }
- add_cubic(&path, pts[N - 2], pts[N - 1]);
- canvas->drawPath(path, paint);
- }
- }
- typedef void (*HairProc)(SkCanvas*, const SkPaint&, const SkBitmap&);
- static const struct {
- const char* fName;
- HairProc fProc;
- } gProcs[] = {
- { "line", line_proc },
- { "poly", poly_proc },
- { "quad", quad_proc },
- { "cube", cube_proc },
- };
- static int cycle_hairproc_index(int index) {
- return (index + 1) % SK_ARRAY_COUNT(gProcs);
- }
- class HairlineView : public Sample {
- SkMSec fNow;
- int fProcIndex;
- bool fDoAA;
- public:
- HairlineView() {
- fProcIndex = 0;
- fDoAA = true;
- fNow = 0;
- }
- protected:
- SkString name() override { return SkStringPrintf("Hair-%s", gProcs[fProcIndex].fName); }
- void show_bitmaps(SkCanvas* canvas, const SkBitmap& b0, const SkBitmap& b1,
- const SkIRect& inset) {
- canvas->drawBitmap(b0, 0, 0, nullptr);
- canvas->drawBitmap(b1, SkIntToScalar(b0.width()), 0, nullptr);
- }
- void onDrawContent(SkCanvas* canvas) override {
- gRand.setSeed(fNow);
- SkBitmap bm, bm2;
- bm.allocN32Pixels(WIDTH + MARGIN*2, HEIGHT + MARGIN*2);
- // this will erase our margin, which we want to always stay 0
- bm.eraseColor(SK_ColorTRANSPARENT);
- bm2.installPixels(SkImageInfo::MakeN32Premul(WIDTH, HEIGHT),
- bm.getAddr32(MARGIN, MARGIN), bm.rowBytes());
- SkCanvas c2(bm2);
- SkPaint paint;
- paint.setAntiAlias(fDoAA);
- paint.setStyle(SkPaint::kStroke_Style);
- bm2.eraseColor(SK_ColorTRANSPARENT);
- gProcs[fProcIndex].fProc(&c2, paint, bm);
- canvas->drawBitmap(bm2, SkIntToScalar(10), SkIntToScalar(10), nullptr);
- }
- bool onAnimate(double /*nanos*/) override {
- if (fDoAA) {
- fProcIndex = cycle_hairproc_index(fProcIndex);
- // todo: signal that we want to rebuild our TITLE
- }
- fDoAA = !fDoAA;
- return true;
- }
- Sample::Click* onFindClickHandler(SkScalar x, SkScalar y, ModifierKey modi) override {
- fDoAA = !fDoAA;
- return this->INHERITED::onFindClickHandler(x, y, modi);
- }
- private:
- typedef Sample INHERITED;
- };
- //////////////////////////////////////////////////////////////////////////////
- DEF_SAMPLE( return new HairlineView(); )
|