1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2014 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "gm/gm.h" 9cb93a386Sopenharmony_ci#include "include/core/SkCanvas.h" 10cb93a386Sopenharmony_ci#include "include/core/SkColor.h" 11cb93a386Sopenharmony_ci#include "include/core/SkPaint.h" 12cb93a386Sopenharmony_ci#include "include/core/SkPathBuilder.h" 13cb93a386Sopenharmony_ci#include "include/core/SkScalar.h" 14cb93a386Sopenharmony_ci#include "include/private/SkFloatBits.h" 15cb93a386Sopenharmony_ci#include "include/private/SkPathRef.h" 16cb93a386Sopenharmony_ci#include "src/core/SkPathPriv.h" 17cb93a386Sopenharmony_ci 18cb93a386Sopenharmony_ci#define W 800 19cb93a386Sopenharmony_ci#define H 800 20cb93a386Sopenharmony_ci 21cb93a386Sopenharmony_ciDEF_SIMPLE_GM(analytic_antialias_convex, canvas, W, H) { 22cb93a386Sopenharmony_ci SkPaint p; 23cb93a386Sopenharmony_ci p.setColor(SK_ColorRED); 24cb93a386Sopenharmony_ci p.setAntiAlias(true); 25cb93a386Sopenharmony_ci 26cb93a386Sopenharmony_ci canvas->clear(0xFFFFFFFF); 27cb93a386Sopenharmony_ci 28cb93a386Sopenharmony_ci canvas->save(); 29cb93a386Sopenharmony_ci 30cb93a386Sopenharmony_ci SkScalar y = 0; 31cb93a386Sopenharmony_ci 32cb93a386Sopenharmony_ci canvas->translate(0, y); 33cb93a386Sopenharmony_ci canvas->rotate(1); 34cb93a386Sopenharmony_ci canvas->drawRect({ 20, 20, 200, 200 }, p); 35cb93a386Sopenharmony_ci canvas->restore(); 36cb93a386Sopenharmony_ci 37cb93a386Sopenharmony_ci y += 200; 38cb93a386Sopenharmony_ci 39cb93a386Sopenharmony_ci canvas->save(); 40cb93a386Sopenharmony_ci canvas->translate(0, y); 41cb93a386Sopenharmony_ci canvas->rotate(1); 42cb93a386Sopenharmony_ci canvas->drawRect({ 20, 20, 20.2f, 200 }, p); 43cb93a386Sopenharmony_ci canvas->drawRect({ 20, 200, 200, 200.1f }, p); 44cb93a386Sopenharmony_ci canvas->drawCircle(100, 100, 30, p); 45cb93a386Sopenharmony_ci canvas->restore(); 46cb93a386Sopenharmony_ci 47cb93a386Sopenharmony_ci // The following path is empty but it'll reveal bug chrome:662914 48cb93a386Sopenharmony_ci SkPathBuilder path; 49cb93a386Sopenharmony_ci path.moveTo(SkBits2Float(0x429b9d5c), SkBits2Float(0x4367a041)); // 77.8073f, 231.626f 50cb93a386Sopenharmony_ci // 77.8075f, 231.626f, 77.8074f, 231.625f, 77.8073f, 231.625f 51cb93a386Sopenharmony_ci path.cubicTo(SkBits2Float(0x429b9d71), SkBits2Float(0x4367a022), 52cb93a386Sopenharmony_ci SkBits2Float(0x429b9d64), SkBits2Float(0x4367a009), 53cb93a386Sopenharmony_ci SkBits2Float(0x429b9d50), SkBits2Float(0x43679ff2)); 54cb93a386Sopenharmony_ci path.lineTo(SkBits2Float(0x429b9d5c), SkBits2Float(0x4367a041)); // 77.8073f, 231.626f 55cb93a386Sopenharmony_ci path.close(); 56cb93a386Sopenharmony_ci canvas->drawPath(path.detach(), p); 57cb93a386Sopenharmony_ci 58cb93a386Sopenharmony_ci // The following path reveals a subtle SkAnalyticQuadraticEdge::updateQuadratic bug: 59cb93a386Sopenharmony_ci // we should not use any snapped y for the intermediate values whose error may accumulate; 60cb93a386Sopenharmony_ci // snapping should only be allowed once before updateLine. 61cb93a386Sopenharmony_ci path.moveTo(SkBits2Float(0x434ba71e), SkBits2Float(0x438a06d0)); // 203.653f, 276.053f 62cb93a386Sopenharmony_ci path.lineTo(SkBits2Float(0x43492a74), SkBits2Float(0x4396d70d)); // 201.166f, 301.68f 63cb93a386Sopenharmony_ci // 200.921f, 304.207f, 196.939f, 303.82f, 0.707107f 64cb93a386Sopenharmony_ci path.conicTo(SkBits2Float(0x4348ebaf), SkBits2Float(0x43981a75), 65cb93a386Sopenharmony_ci SkBits2Float(0x4344f079), SkBits2Float(0x4397e900), SkBits2Float(0x3f3504f3)); 66cb93a386Sopenharmony_ci path.close(); 67cb93a386Sopenharmony_ci // Manually setting convexity is required. Otherwise, this path will be considered concave. 68cb93a386Sopenharmony_ci SkPathPriv::SetConvexity(&path, SkPathConvexity::kConvex); 69cb93a386Sopenharmony_ci canvas->drawPath(path.detach(), p); 70cb93a386Sopenharmony_ci 71cb93a386Sopenharmony_ci // skbug.com/7573 72cb93a386Sopenharmony_ci y += 200; 73cb93a386Sopenharmony_ci canvas->save(); 74cb93a386Sopenharmony_ci canvas->translate(0, y); 75cb93a386Sopenharmony_ci p.setAntiAlias(true); 76cb93a386Sopenharmony_ci path.moveTo(1.98009784f, 9.0162744f); 77cb93a386Sopenharmony_ci path.lineTo(47.843992f, 10.1922744f); 78cb93a386Sopenharmony_ci path.lineTo(47.804008f, 11.7597256f); 79cb93a386Sopenharmony_ci path.lineTo(1.93990216f, 10.5837256f); 80cb93a386Sopenharmony_ci canvas->drawPath(path.detach(), p); 81cb93a386Sopenharmony_ci canvas->restore(); 82cb93a386Sopenharmony_ci 83cb93a386Sopenharmony_ci // skbug.com/7813 84cb93a386Sopenharmony_ci // t8888 splits the 800-high canvas into 3 pieces; the boundary is close to 266 and 534 85cb93a386Sopenharmony_ci path.moveTo(700, 266); 86cb93a386Sopenharmony_ci path.lineTo(710, 266); 87cb93a386Sopenharmony_ci path.lineTo(710, 534); 88cb93a386Sopenharmony_ci path.lineTo(700, 534); 89cb93a386Sopenharmony_ci canvas->drawPath(path.detach(), p); 90cb93a386Sopenharmony_ci} 91cb93a386Sopenharmony_ci 92cb93a386Sopenharmony_ciDEF_SIMPLE_GM(analytic_antialias_general, canvas, W, H) { 93cb93a386Sopenharmony_ci SkPaint p; 94cb93a386Sopenharmony_ci p.setColor(SK_ColorRED); 95cb93a386Sopenharmony_ci p.setAntiAlias(true); 96cb93a386Sopenharmony_ci 97cb93a386Sopenharmony_ci canvas->clear(0xFFFFFFFF); 98cb93a386Sopenharmony_ci 99cb93a386Sopenharmony_ci canvas->save(); 100cb93a386Sopenharmony_ci canvas->rotate(1); 101cb93a386Sopenharmony_ci const SkScalar R = 115.2f, C = 128.0f; 102cb93a386Sopenharmony_ci SkPathBuilder builder; 103cb93a386Sopenharmony_ci builder.moveTo(C + R, C); 104cb93a386Sopenharmony_ci for (int i = 1; i < 8; ++i) { 105cb93a386Sopenharmony_ci SkScalar a = 2.6927937f * i; 106cb93a386Sopenharmony_ci builder.lineTo(C + R * SkScalarCos(a), C + R * SkScalarSin(a)); 107cb93a386Sopenharmony_ci } 108cb93a386Sopenharmony_ci SkPath path = builder.detach(); 109cb93a386Sopenharmony_ci canvas->drawPath(path, p); 110cb93a386Sopenharmony_ci canvas->restore(); 111cb93a386Sopenharmony_ci 112cb93a386Sopenharmony_ci canvas->save(); 113cb93a386Sopenharmony_ci canvas->translate(200, 0); 114cb93a386Sopenharmony_ci canvas->rotate(1); 115cb93a386Sopenharmony_ci p.setStyle(SkPaint::kStroke_Style); 116cb93a386Sopenharmony_ci p.setStrokeWidth(5); 117cb93a386Sopenharmony_ci canvas->drawPath(path, p); 118cb93a386Sopenharmony_ci canvas->restore(); 119cb93a386Sopenharmony_ci 120cb93a386Sopenharmony_ci 121cb93a386Sopenharmony_ci // The following two paths test if we correctly cumulates the alpha on the middle pixel 122cb93a386Sopenharmony_ci // column where the left rect and the right rect abut. 123cb93a386Sopenharmony_ci p.setStyle(SkPaint::kFill_Style); 124cb93a386Sopenharmony_ci canvas->translate(0, 300); 125cb93a386Sopenharmony_ci canvas->drawPath(SkPathBuilder().addRect({20, 20, 100.4999f, 100}) 126cb93a386Sopenharmony_ci .addRect({100.5001f, 20, 200, 100}) 127cb93a386Sopenharmony_ci .detach(), p); 128cb93a386Sopenharmony_ci 129cb93a386Sopenharmony_ci canvas->translate(300, 0); 130cb93a386Sopenharmony_ci canvas->drawPath(SkPathBuilder().addRect({20, 20, 100.1f, 100}) 131cb93a386Sopenharmony_ci .addRect({100.9f, 20, 200, 100}) 132cb93a386Sopenharmony_ci .detach(), p); 133cb93a386Sopenharmony_ci} 134cb93a386Sopenharmony_ci 135cb93a386Sopenharmony_ciDEF_SIMPLE_GM(analytic_antialias_inverse, canvas, W, H) { 136cb93a386Sopenharmony_ci SkPaint p; 137cb93a386Sopenharmony_ci p.setColor(SK_ColorRED); 138cb93a386Sopenharmony_ci p.setAntiAlias(true); 139cb93a386Sopenharmony_ci 140cb93a386Sopenharmony_ci canvas->save(); 141cb93a386Sopenharmony_ci 142cb93a386Sopenharmony_ci SkPath path = SkPath::Circle(100, 100, 30); 143cb93a386Sopenharmony_ci path.setFillType(SkPathFillType::kInverseWinding); 144cb93a386Sopenharmony_ci canvas->drawPath(path, p); 145cb93a386Sopenharmony_ci canvas->restore(); 146cb93a386Sopenharmony_ci} 147