1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2016 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#include "include/core/SkCanvas.h" 8cb93a386Sopenharmony_ci#include "include/core/SkPath.h" 9cb93a386Sopenharmony_ci#include "samplecode/Sample.h" 10cb93a386Sopenharmony_ci 11cb93a386Sopenharmony_ci#include <iostream> 12cb93a386Sopenharmony_ci#include <cmath> 13cb93a386Sopenharmony_ci 14cb93a386Sopenharmony_ci#define PI SK_ScalarPI 15cb93a386Sopenharmony_ci 16cb93a386Sopenharmony_ci#define LIN_SEGMENTS 10 17cb93a386Sopenharmony_ci 18cb93a386Sopenharmony_ciclass OverstrokeView : public Sample { 19cb93a386Sopenharmony_ci public: 20cb93a386Sopenharmony_ci SkScalar fStroke; 21cb93a386Sopenharmony_ci int fPathType; // super lazy enum 22cb93a386Sopenharmony_ci bool fClosePath; 23cb93a386Sopenharmony_ci bool fDrawFillPath; 24cb93a386Sopenharmony_ci bool fDumpHex; 25cb93a386Sopenharmony_ci OverstrokeView() { 26cb93a386Sopenharmony_ci fStroke = 5; 27cb93a386Sopenharmony_ci fPathType = 0; 28cb93a386Sopenharmony_ci fClosePath = false; 29cb93a386Sopenharmony_ci fDrawFillPath = false; 30cb93a386Sopenharmony_ci fDumpHex = false; 31cb93a386Sopenharmony_ci this->setBGColor(0xFFFFFFFF); 32cb93a386Sopenharmony_ci } 33cb93a386Sopenharmony_ci 34cb93a386Sopenharmony_ci protected: 35cb93a386Sopenharmony_ci SkString name() override { return SkString("PathOverstroke"); } 36cb93a386Sopenharmony_ci 37cb93a386Sopenharmony_ci bool onChar(SkUnichar uni) override { 38cb93a386Sopenharmony_ci switch (uni) { 39cb93a386Sopenharmony_ci case ',': 40cb93a386Sopenharmony_ci fStroke += 1.0; 41cb93a386Sopenharmony_ci return true; 42cb93a386Sopenharmony_ci case '.': 43cb93a386Sopenharmony_ci fStroke -= 1.0; 44cb93a386Sopenharmony_ci return true; 45cb93a386Sopenharmony_ci case 'x': 46cb93a386Sopenharmony_ci fPathType = (fPathType + 1) % 4; 47cb93a386Sopenharmony_ci return true; 48cb93a386Sopenharmony_ci case 'c': 49cb93a386Sopenharmony_ci fClosePath = !fClosePath; 50cb93a386Sopenharmony_ci return true; 51cb93a386Sopenharmony_ci case 'f': 52cb93a386Sopenharmony_ci fDrawFillPath = !fDrawFillPath; 53cb93a386Sopenharmony_ci return true; 54cb93a386Sopenharmony_ci case 'D': 55cb93a386Sopenharmony_ci fDumpHex = !fDumpHex; 56cb93a386Sopenharmony_ci return true; 57cb93a386Sopenharmony_ci default: 58cb93a386Sopenharmony_ci break; 59cb93a386Sopenharmony_ci } 60cb93a386Sopenharmony_ci return false; 61cb93a386Sopenharmony_ci } 62cb93a386Sopenharmony_ci 63cb93a386Sopenharmony_ci SkPath quadPath(SkPoint p1, SkPoint p2) { 64cb93a386Sopenharmony_ci SkASSERT(p1.y() == p2.y()); 65cb93a386Sopenharmony_ci 66cb93a386Sopenharmony_ci SkPath path; 67cb93a386Sopenharmony_ci path.moveTo(p1); 68cb93a386Sopenharmony_ci path.lineTo(p2); 69cb93a386Sopenharmony_ci 70cb93a386Sopenharmony_ci SkPoint p3 = SkPoint::Make((p1.x() + p2.x()) / 2.0f, p1.y() * 0.7f); 71cb93a386Sopenharmony_ci 72cb93a386Sopenharmony_ci path.quadTo(p3, p1); 73cb93a386Sopenharmony_ci 74cb93a386Sopenharmony_ci return path; 75cb93a386Sopenharmony_ci } 76cb93a386Sopenharmony_ci 77cb93a386Sopenharmony_ci SkPath cubicPath(SkPoint p1, SkPoint p2) { 78cb93a386Sopenharmony_ci SkASSERT(p1.y() == p2.y()); 79cb93a386Sopenharmony_ci 80cb93a386Sopenharmony_ci SkPath path; 81cb93a386Sopenharmony_ci path.moveTo(p1); 82cb93a386Sopenharmony_ci 83cb93a386Sopenharmony_ci SkPoint p3 = SkPoint::Make((p1.x() + p2.x()) / 3.0f, p1.y() * 0.7f); 84cb93a386Sopenharmony_ci SkPoint p4 = SkPoint::Make(2.0f*(p1.x() + p2.x()) / 3.0f, p1.y() * 1.5f); 85cb93a386Sopenharmony_ci 86cb93a386Sopenharmony_ci path.cubicTo(p3, p4, p2); 87cb93a386Sopenharmony_ci 88cb93a386Sopenharmony_ci return path; 89cb93a386Sopenharmony_ci } 90cb93a386Sopenharmony_ci 91cb93a386Sopenharmony_ci SkPath linSemicirclePath(SkPoint p1, SkPoint p2) { 92cb93a386Sopenharmony_ci SkASSERT(p1.y() == p2.y()); 93cb93a386Sopenharmony_ci 94cb93a386Sopenharmony_ci SkPath path; 95cb93a386Sopenharmony_ci path.moveTo(p1); 96cb93a386Sopenharmony_ci path.lineTo(p2); 97cb93a386Sopenharmony_ci 98cb93a386Sopenharmony_ci SkPoint pt; 99cb93a386Sopenharmony_ci 100cb93a386Sopenharmony_ci for (int i = 0; i < LIN_SEGMENTS; i++) { 101cb93a386Sopenharmony_ci float theta = i * PI / (LIN_SEGMENTS); 102cb93a386Sopenharmony_ci SkScalar x = 65 + 15 * cos(theta); 103cb93a386Sopenharmony_ci SkScalar y = 50 - 15 * sin(theta); 104cb93a386Sopenharmony_ci pt = SkPoint::Make(x, y); 105cb93a386Sopenharmony_ci path.lineTo(pt); 106cb93a386Sopenharmony_ci } 107cb93a386Sopenharmony_ci path.lineTo(p1); 108cb93a386Sopenharmony_ci 109cb93a386Sopenharmony_ci return path; 110cb93a386Sopenharmony_ci } 111cb93a386Sopenharmony_ci 112cb93a386Sopenharmony_ci SkPath rectPath(SkPoint p1) { 113cb93a386Sopenharmony_ci SkRect r = SkRect::MakeXYWH(p1.fX, p1.fY, 20, 20); 114cb93a386Sopenharmony_ci SkPath path; 115cb93a386Sopenharmony_ci path.addRect(r); 116cb93a386Sopenharmony_ci 117cb93a386Sopenharmony_ci return path; 118cb93a386Sopenharmony_ci } 119cb93a386Sopenharmony_ci 120cb93a386Sopenharmony_ci void onDrawContent(SkCanvas* canvas) override { 121cb93a386Sopenharmony_ci const float SCALE = 1; 122cb93a386Sopenharmony_ci 123cb93a386Sopenharmony_ci canvas->translate(30, 40); 124cb93a386Sopenharmony_ci canvas->scale(SCALE, SCALE); 125cb93a386Sopenharmony_ci 126cb93a386Sopenharmony_ci SkPoint p1 = SkPoint::Make(50, 50); 127cb93a386Sopenharmony_ci SkPoint p2 = SkPoint::Make(80, 50); 128cb93a386Sopenharmony_ci 129cb93a386Sopenharmony_ci SkPath path; 130cb93a386Sopenharmony_ci switch (fPathType) { 131cb93a386Sopenharmony_ci case 0: 132cb93a386Sopenharmony_ci path = quadPath(p1, p2); 133cb93a386Sopenharmony_ci break; 134cb93a386Sopenharmony_ci case 1: 135cb93a386Sopenharmony_ci path = cubicPath(p1, p2); 136cb93a386Sopenharmony_ci break; 137cb93a386Sopenharmony_ci case 2: 138cb93a386Sopenharmony_ci path = rectPath(p1); 139cb93a386Sopenharmony_ci break; 140cb93a386Sopenharmony_ci case 3: 141cb93a386Sopenharmony_ci path = linSemicirclePath(p1, p2); 142cb93a386Sopenharmony_ci break; 143cb93a386Sopenharmony_ci default: 144cb93a386Sopenharmony_ci path = quadPath(p1, p2); 145cb93a386Sopenharmony_ci break; 146cb93a386Sopenharmony_ci } 147cb93a386Sopenharmony_ci 148cb93a386Sopenharmony_ci if (fClosePath) { 149cb93a386Sopenharmony_ci path.close(); 150cb93a386Sopenharmony_ci } 151cb93a386Sopenharmony_ci 152cb93a386Sopenharmony_ci SkPaint p; 153cb93a386Sopenharmony_ci p.setColor(SK_ColorRED); 154cb93a386Sopenharmony_ci p.setAntiAlias(true); 155cb93a386Sopenharmony_ci p.setStyle(SkPaint::kStroke_Style); 156cb93a386Sopenharmony_ci p.setStrokeWidth(fStroke); 157cb93a386Sopenharmony_ci 158cb93a386Sopenharmony_ci canvas->drawPath(path, p); 159cb93a386Sopenharmony_ci 160cb93a386Sopenharmony_ci if (fDumpHex) { 161cb93a386Sopenharmony_ci std::cerr << "path dumpHex" << std::endl; 162cb93a386Sopenharmony_ci path.dumpHex(); 163cb93a386Sopenharmony_ci } 164cb93a386Sopenharmony_ci 165cb93a386Sopenharmony_ci SkPaint hairp; 166cb93a386Sopenharmony_ci hairp.setColor(SK_ColorBLACK); 167cb93a386Sopenharmony_ci hairp.setAntiAlias(true); 168cb93a386Sopenharmony_ci hairp.setStyle(SkPaint::kStroke_Style); 169cb93a386Sopenharmony_ci 170cb93a386Sopenharmony_ci if (fDrawFillPath) { 171cb93a386Sopenharmony_ci SkPath fillpath; 172cb93a386Sopenharmony_ci p.getFillPath(path, &fillpath); 173cb93a386Sopenharmony_ci 174cb93a386Sopenharmony_ci canvas->drawPath(fillpath, hairp); 175cb93a386Sopenharmony_ci 176cb93a386Sopenharmony_ci if (fDumpHex) { 177cb93a386Sopenharmony_ci std::cerr << "fillpath dumpHex" << std::endl; 178cb93a386Sopenharmony_ci fillpath.dumpHex(); 179cb93a386Sopenharmony_ci } 180cb93a386Sopenharmony_ci } 181cb93a386Sopenharmony_ci 182cb93a386Sopenharmony_ci if (fDumpHex) { 183cb93a386Sopenharmony_ci std::cerr << std::endl; 184cb93a386Sopenharmony_ci 185cb93a386Sopenharmony_ci fDumpHex = false; 186cb93a386Sopenharmony_ci } 187cb93a386Sopenharmony_ci 188cb93a386Sopenharmony_ci // draw original path with green hairline 189cb93a386Sopenharmony_ci hairp.setColor(SK_ColorGREEN); 190cb93a386Sopenharmony_ci canvas->drawPath(path, hairp); 191cb93a386Sopenharmony_ci } 192cb93a386Sopenharmony_ci 193cb93a386Sopenharmony_ci private: 194cb93a386Sopenharmony_ci using INHERITED = Sample; 195cb93a386Sopenharmony_ci}; 196cb93a386Sopenharmony_ci 197cb93a386Sopenharmony_ci/////////////////////////////////////////////////////////////////////////////// 198cb93a386Sopenharmony_ci 199cb93a386Sopenharmony_ciDEF_SAMPLE( return new OverstrokeView(); ) 200