1e60d85597f803c4dff6329840215af1d1d9a8fdcliyuqian/* 2e60d85597f803c4dff6329840215af1d1d9a8fdcliyuqian * Copyright 2014 Google Inc. 3e60d85597f803c4dff6329840215af1d1d9a8fdcliyuqian * 4e60d85597f803c4dff6329840215af1d1d9a8fdcliyuqian * Use of this source code is governed by a BSD-style license that can be 5e60d85597f803c4dff6329840215af1d1d9a8fdcliyuqian * found in the LICENSE file. 6e60d85597f803c4dff6329840215af1d1d9a8fdcliyuqian */ 7e60d85597f803c4dff6329840215af1d1d9a8fdcliyuqian 8e60d85597f803c4dff6329840215af1d1d9a8fdcliyuqian#include "gm.h" 9e60d85597f803c4dff6329840215af1d1d9a8fdcliyuqian#include "SkPath.h" 10e60d85597f803c4dff6329840215af1d1d9a8fdcliyuqian#include "SkScan.h" 11e60d85597f803c4dff6329840215af1d1d9a8fdcliyuqian 12e60d85597f803c4dff6329840215af1d1d9a8fdcliyuqian#define W 800 13e60d85597f803c4dff6329840215af1d1d9a8fdcliyuqian#define H 800 14e60d85597f803c4dff6329840215af1d1d9a8fdcliyuqian 15e60d85597f803c4dff6329840215af1d1d9a8fdcliyuqianclass AnalyticAntiAliasConvexGM : public skiagm::GM { 16e60d85597f803c4dff6329840215af1d1d9a8fdcliyuqianpublic: 17e60d85597f803c4dff6329840215af1d1d9a8fdcliyuqian AnalyticAntiAliasConvexGM() {} 18e60d85597f803c4dff6329840215af1d1d9a8fdcliyuqian 19e60d85597f803c4dff6329840215af1d1d9a8fdcliyuqianprotected: 20e60d85597f803c4dff6329840215af1d1d9a8fdcliyuqian 21e60d85597f803c4dff6329840215af1d1d9a8fdcliyuqian SkString onShortName() override { 22e60d85597f803c4dff6329840215af1d1d9a8fdcliyuqian return SkString("analytic_antialias_convex"); 23e60d85597f803c4dff6329840215af1d1d9a8fdcliyuqian } 24e60d85597f803c4dff6329840215af1d1d9a8fdcliyuqian 25e60d85597f803c4dff6329840215af1d1d9a8fdcliyuqian SkISize onISize() override { 26e60d85597f803c4dff6329840215af1d1d9a8fdcliyuqian return SkISize::Make(W, H); 27e60d85597f803c4dff6329840215af1d1d9a8fdcliyuqian } 28e60d85597f803c4dff6329840215af1d1d9a8fdcliyuqian 29e60d85597f803c4dff6329840215af1d1d9a8fdcliyuqian void onDraw(SkCanvas* canvas) override { 30e60d85597f803c4dff6329840215af1d1d9a8fdcliyuqian SkPaint p; 31e60d85597f803c4dff6329840215af1d1d9a8fdcliyuqian p.setColor(SK_ColorRED); 32e60d85597f803c4dff6329840215af1d1d9a8fdcliyuqian p.setAntiAlias(true); 33e60d85597f803c4dff6329840215af1d1d9a8fdcliyuqian 34e60d85597f803c4dff6329840215af1d1d9a8fdcliyuqian canvas->clear(0xFFFFFFFF); 35e60d85597f803c4dff6329840215af1d1d9a8fdcliyuqian 36e60d85597f803c4dff6329840215af1d1d9a8fdcliyuqian canvas->save(); 37e60d85597f803c4dff6329840215af1d1d9a8fdcliyuqian 38e60d85597f803c4dff6329840215af1d1d9a8fdcliyuqian SkScalar y = 0; 39e60d85597f803c4dff6329840215af1d1d9a8fdcliyuqian 40e60d85597f803c4dff6329840215af1d1d9a8fdcliyuqian canvas->translate(0, y); 41e60d85597f803c4dff6329840215af1d1d9a8fdcliyuqian canvas->rotate(1); 423661bc997620899695041010a750d11dbe8a972dMike Reed canvas->drawRect({ 20, 20, 200, 200 }, p); 43e60d85597f803c4dff6329840215af1d1d9a8fdcliyuqian canvas->restore(); 44e60d85597f803c4dff6329840215af1d1d9a8fdcliyuqian 45e60d85597f803c4dff6329840215af1d1d9a8fdcliyuqian y += 200; 46e60d85597f803c4dff6329840215af1d1d9a8fdcliyuqian 47e60d85597f803c4dff6329840215af1d1d9a8fdcliyuqian canvas->translate(0, y); 48e60d85597f803c4dff6329840215af1d1d9a8fdcliyuqian canvas->rotate(1); 493661bc997620899695041010a750d11dbe8a972dMike Reed canvas->drawRect({ 20, 20, 20.2f, 200 }, p); 503661bc997620899695041010a750d11dbe8a972dMike Reed canvas->drawRect({ 20, 200, 200, 200.1f }, p); 51e60d85597f803c4dff6329840215af1d1d9a8fdcliyuqian canvas->drawCircle(100, 100, 30, p); 52e60d85597f803c4dff6329840215af1d1d9a8fdcliyuqian canvas->restore(); 53451ceba3544fa1ff810378f1e9a47c7d20f48a9fliyuqian 54451ceba3544fa1ff810378f1e9a47c7d20f48a9fliyuqian // The following path is empty but it'll reveal bug chrome:662914 55451ceba3544fa1ff810378f1e9a47c7d20f48a9fliyuqian SkPath path; 56451ceba3544fa1ff810378f1e9a47c7d20f48a9fliyuqian path.moveTo(SkBits2Float(0x429b9d5c), SkBits2Float(0x4367a041)); // 77.8073f, 231.626f 57451ceba3544fa1ff810378f1e9a47c7d20f48a9fliyuqian // 77.8075f, 231.626f, 77.8074f, 231.625f, 77.8073f, 231.625f 58451ceba3544fa1ff810378f1e9a47c7d20f48a9fliyuqian path.cubicTo(SkBits2Float(0x429b9d71), SkBits2Float(0x4367a022), 59451ceba3544fa1ff810378f1e9a47c7d20f48a9fliyuqian SkBits2Float(0x429b9d64), SkBits2Float(0x4367a009), 60451ceba3544fa1ff810378f1e9a47c7d20f48a9fliyuqian SkBits2Float(0x429b9d50), SkBits2Float(0x43679ff2)); 61451ceba3544fa1ff810378f1e9a47c7d20f48a9fliyuqian path.lineTo(SkBits2Float(0x429b9d5c), SkBits2Float(0x4367a041)); // 77.8073f, 231.626f 62451ceba3544fa1ff810378f1e9a47c7d20f48a9fliyuqian path.close(); 63451ceba3544fa1ff810378f1e9a47c7d20f48a9fliyuqian canvas->drawPath(path, p); 640038b7feaaa3d2337b2e44938a11bd0f475cd525Yuqian Li 650038b7feaaa3d2337b2e44938a11bd0f475cd525Yuqian Li // The following path reveals a subtle SkAnalyticQuadraticEdge::updateQuadratic bug: 660038b7feaaa3d2337b2e44938a11bd0f475cd525Yuqian Li // we should not use any snapped y for the intermediate values whose error may accumulate; 670038b7feaaa3d2337b2e44938a11bd0f475cd525Yuqian Li // snapping should only be allowed once before updateLine. 680038b7feaaa3d2337b2e44938a11bd0f475cd525Yuqian Li path.reset(); 690038b7feaaa3d2337b2e44938a11bd0f475cd525Yuqian Li path.moveTo(SkBits2Float(0x434ba71e), SkBits2Float(0x438a06d0)); // 203.653f, 276.053f 700038b7feaaa3d2337b2e44938a11bd0f475cd525Yuqian Li path.lineTo(SkBits2Float(0x43492a74), SkBits2Float(0x4396d70d)); // 201.166f, 301.68f 710038b7feaaa3d2337b2e44938a11bd0f475cd525Yuqian Li // 200.921f, 304.207f, 196.939f, 303.82f, 0.707107f 720038b7feaaa3d2337b2e44938a11bd0f475cd525Yuqian Li path.conicTo(SkBits2Float(0x4348ebaf), SkBits2Float(0x43981a75), 730038b7feaaa3d2337b2e44938a11bd0f475cd525Yuqian Li SkBits2Float(0x4344f079), SkBits2Float(0x4397e900), SkBits2Float(0x3f3504f3)); 740038b7feaaa3d2337b2e44938a11bd0f475cd525Yuqian Li path.close(); 750038b7feaaa3d2337b2e44938a11bd0f475cd525Yuqian Li // Manually setting convexity is required. Otherwise, this path will be considered concave. 760038b7feaaa3d2337b2e44938a11bd0f475cd525Yuqian Li path.setConvexity(SkPath::kConvex_Convexity); 770038b7feaaa3d2337b2e44938a11bd0f475cd525Yuqian Li canvas->drawPath(path, p); 78e60d85597f803c4dff6329840215af1d1d9a8fdcliyuqian } 79e60d85597f803c4dff6329840215af1d1d9a8fdcliyuqian 80e60d85597f803c4dff6329840215af1d1d9a8fdcliyuqianprivate: 81e60d85597f803c4dff6329840215af1d1d9a8fdcliyuqian typedef skiagm::GM INHERITED; 82e60d85597f803c4dff6329840215af1d1d9a8fdcliyuqian}; 83e60d85597f803c4dff6329840215af1d1d9a8fdcliyuqian 84131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Liclass AnalyticAntiAliasGeneralGM : public skiagm::GM { 85131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Lipublic: 86131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li AnalyticAntiAliasGeneralGM() {} 87131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li 88131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Liprotected: 89131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li 90131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li SkString onShortName() override { 91131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li return SkString("analytic_antialias_general"); 92131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li } 93131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li 94131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li SkISize onISize() override { 95131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li return SkISize::Make(W, H); 96131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li } 97131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li 98131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li void onDraw(SkCanvas* canvas) override { 99131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li SkPaint p; 100131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li p.setColor(SK_ColorRED); 101131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li p.setAntiAlias(true); 102131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li 103131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li canvas->clear(0xFFFFFFFF); 104131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li 105131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li canvas->save(); 106131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li canvas->rotate(1); 107131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li const SkScalar R = 115.2f, C = 128.0f; 108131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li SkPath path; 109131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li path.moveTo(C + R, C); 110131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li for (int i = 1; i < 8; ++i) { 111131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li SkScalar a = 2.6927937f * i; 112131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li SkScalar cosine; 113131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li SkScalar sine = SkScalarSinCos(a, &cosine); 114131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li path.lineTo(C + R * cosine, C + R * sine); 115131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li } 116131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li canvas->drawPath(path, p); 117131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li canvas->restore(); 118131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li 119131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li canvas->save(); 120131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li canvas->translate(200, 0); 121131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li canvas->rotate(1); 122131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li p.setStyle(SkPaint::kStroke_Style); 123131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li p.setStrokeWidth(5); 124131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li canvas->drawPath(path, p); 125131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li canvas->restore(); 126131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li } 127131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li 128131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Liprivate: 129131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li typedef skiagm::GM INHERITED; 130131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li}; 131131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li 132131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Liclass AnalyticAntiAliasInverseGM : public skiagm::GM { 133131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Lipublic: 134131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li AnalyticAntiAliasInverseGM() {} 135131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li 136131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Liprotected: 137131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li 138131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li SkString onShortName() override { 139131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li return SkString("analytic_antialias_inverse"); 140131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li } 141131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li 142131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li SkISize onISize() override { 143131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li return SkISize::Make(W, H); 144131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li } 145131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li 146131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li void onDraw(SkCanvas* canvas) override { 147131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li SkPaint p; 148131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li p.setColor(SK_ColorRED); 149131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li p.setAntiAlias(true); 150131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li 151131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li canvas->save(); 152131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li 153131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li SkPath path; 154131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li path.addCircle(100, 100, 30); 155131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li path.setFillType(SkPath::kInverseWinding_FillType); 156131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li canvas->drawPath(path, p); 157131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li canvas->restore(); 158131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li } 159131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li 160131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Liprivate: 161131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li typedef skiagm::GM INHERITED; 162131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li}; 163131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian Li 164e60d85597f803c4dff6329840215af1d1d9a8fdcliyuqianDEF_GM( return new AnalyticAntiAliasConvexGM; ) 165131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian LiDEF_GM( return new AnalyticAntiAliasGeneralGM; ) 166131c1fb96328ee00cb18f629eddfb665b36e9463Yuqian LiDEF_GM( return new AnalyticAntiAliasInverseGM; ) 167