1cb93a386Sopenharmony_ci// Copyright 2020 Google LLC. 2cb93a386Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. 3cb93a386Sopenharmony_ci#include "tools/fiddle/examples.h" 4cb93a386Sopenharmony_ciREG_FIDDLE(ChromeMDRefreshTab, 256, 256, false, 0) { 5cb93a386Sopenharmony_ciSkPath GetBorderPath(float scale, 6cb93a386Sopenharmony_ci bool unscale_at_end, 7cb93a386Sopenharmony_ci bool extend_to_top, 8cb93a386Sopenharmony_ci float endcap_width, 9cb93a386Sopenharmony_ci const SkISize& size) { 10cb93a386Sopenharmony_ci // const float top = scale - 1; 11cb93a386Sopenharmony_ci const float right = size.fWidth * scale; 12cb93a386Sopenharmony_ci const float bottom = size.fHeight * scale; 13cb93a386Sopenharmony_ci const float scaled_endcap_radius = (endcap_width / 2) * scale; 14cb93a386Sopenharmony_ci 15cb93a386Sopenharmony_ci SkPath path; 16cb93a386Sopenharmony_ci path.moveTo(0, bottom - 1); 17cb93a386Sopenharmony_ci // bottom left 18cb93a386Sopenharmony_ci path.arcTo(scaled_endcap_radius - 1, scaled_endcap_radius - 1, 90, SkPath::kSmall_ArcSize, 19cb93a386Sopenharmony_ci SkPathDirection::kCCW, scaled_endcap_radius - 1, 20cb93a386Sopenharmony_ci bottom - 1 - scaled_endcap_radius); 21cb93a386Sopenharmony_ci // path.rLineTo(0, -1); 22cb93a386Sopenharmony_ci // path.rCubicTo(0.75 * scale, 0, 1.625 * scale, -0.5 * scale, 2 * scale, 23cb93a386Sopenharmony_ci // -1.5 * scale); 24cb93a386Sopenharmony_ci path.lineTo(scaled_endcap_radius - 1, scaled_endcap_radius + 1); 25cb93a386Sopenharmony_ci // path.lineTo((endcap_width - 2) * scale, top + 1.5 * scale); 26cb93a386Sopenharmony_ci // top left 27cb93a386Sopenharmony_ci path.arcTo(scaled_endcap_radius + 1, scaled_endcap_radius + 1, 90, SkPath::kSmall_ArcSize, 28cb93a386Sopenharmony_ci SkPathDirection::kCW, scaled_endcap_radius * 2, -1); 29cb93a386Sopenharmony_ci 30cb93a386Sopenharmony_ci // if (extend_to_top) { 31cb93a386Sopenharmony_ci // Create the vertical extension by extending the side diagonals until 32cb93a386Sopenharmony_ci // they reach the top of the bounds. 33cb93a386Sopenharmony_ci // const float dy = 2.5 * scale - 1; 34cb93a386Sopenharmony_ci // const float dx = Tab::GetInverseDiagonalSlope() * dy; 35cb93a386Sopenharmony_ci // path.rLineTo(dx, -dy); 36cb93a386Sopenharmony_ci // path.lineTo(right - (endcap_width - 2) * scale - dx, 0); 37cb93a386Sopenharmony_ci // path.rLineTo(dx, dy); 38cb93a386Sopenharmony_ci //} else { 39cb93a386Sopenharmony_ci // path.rCubicTo(0.375 * scale, -scale, 1.25 * scale, -1.5 * scale, 2 * scale, 40cb93a386Sopenharmony_ci // -1.5 * scale); 41cb93a386Sopenharmony_ci // path.lineTo(right - endcap_width * scale, top); 42cb93a386Sopenharmony_ci // path.rCubicTo(0.75 * scale, 0, 1.625 * scale, 0.5 * scale, 2 * scale, 43cb93a386Sopenharmony_ci // 1.5 * scale); 44cb93a386Sopenharmony_ci //} 45cb93a386Sopenharmony_ci path.lineTo(right - scaled_endcap_radius * 2, -1); 46cb93a386Sopenharmony_ci // path.lineTo(right - 2 * scale, bottom - 1 - 1.5 * scale); 47cb93a386Sopenharmony_ci 48cb93a386Sopenharmony_ci // top right 49cb93a386Sopenharmony_ci path.arcTo(scaled_endcap_radius + 1, scaled_endcap_radius + 1, 90, SkPath::kSmall_ArcSize, 50cb93a386Sopenharmony_ci SkPathDirection::kCW, right - scaled_endcap_radius + 1, 51cb93a386Sopenharmony_ci scaled_endcap_radius + 1); 52cb93a386Sopenharmony_ci // path.arcTo(SkRect::MakeLTRB(right - 2 * scale, bottom - 1 - 1.5 * scale, 53cb93a386Sopenharmony_ci // right - 2 * scale + 4, bottom - 1 - 1.5 * scale + 4), 90, 90, true); 54cb93a386Sopenharmony_ci // path.rCubicTo(0.375 * scale, scale, 1.25 * scale, 1.5 * scale, 2 * scale, 55cb93a386Sopenharmony_ci // 1.5 * scale); 56cb93a386Sopenharmony_ci 57cb93a386Sopenharmony_ci path.lineTo(right - scaled_endcap_radius + 1, bottom - 1 - scaled_endcap_radius); 58cb93a386Sopenharmony_ci // path.rLineTo(0, 1); 59cb93a386Sopenharmony_ci 60cb93a386Sopenharmony_ci // bottom right 61cb93a386Sopenharmony_ci path.arcTo(scaled_endcap_radius - 1, scaled_endcap_radius - 1, 90, SkPath::kSmall_ArcSize, 62cb93a386Sopenharmony_ci SkPathDirection::kCCW, right, bottom - 1); 63cb93a386Sopenharmony_ci path.close(); 64cb93a386Sopenharmony_ci 65cb93a386Sopenharmony_ci if (unscale_at_end && (scale != 1)) path.transform(SkMatrix::Scale(1.f / scale, 66cb93a386Sopenharmony_ci 1.f / scale)); 67cb93a386Sopenharmony_ci 68cb93a386Sopenharmony_ci return path; 69cb93a386Sopenharmony_ci} 70cb93a386Sopenharmony_ci 71cb93a386Sopenharmony_ciSkPath GetInteriorPath( 72cb93a386Sopenharmony_ci float scale, const SkISize& size, float endcap_width, float horizontal_inset = 0) { 73cb93a386Sopenharmony_ci const float right = size.fWidth * scale; 74cb93a386Sopenharmony_ci // The bottom of the tab needs to be pixel-aligned or else when we call 75cb93a386Sopenharmony_ci // ClipPath with anti-aliasing enabled it can cause artifacts. 76cb93a386Sopenharmony_ci const float bottom = std::ceil(size.fHeight * scale); 77cb93a386Sopenharmony_ci 78cb93a386Sopenharmony_ci // const float scaled_horizontal_inset = horizontal_inset * scale; 79cb93a386Sopenharmony_ci 80cb93a386Sopenharmony_ci const float scaled_endcap_radius = (endcap_width / 2) * scale; 81cb93a386Sopenharmony_ci 82cb93a386Sopenharmony_ci // Construct the interior path by intersecting paths representing the left 83cb93a386Sopenharmony_ci // and right halves of the tab. Compared to computing the full path at once, 84cb93a386Sopenharmony_ci // this makes it easier to avoid overdraw in the top center near minimum 85cb93a386Sopenharmony_ci // width, and to implement cases where |horizontal_inset| != 0. 86cb93a386Sopenharmony_ci SkPath right_path; 87cb93a386Sopenharmony_ci 88cb93a386Sopenharmony_ci right_path.moveTo(right, bottom); 89cb93a386Sopenharmony_ci // right_path.moveTo(right - 1 - scaled_horizontal_inset, bottom); 90cb93a386Sopenharmony_ci 91cb93a386Sopenharmony_ci right_path.arcTo(scaled_endcap_radius, scaled_endcap_radius, 90, SkPath::kSmall_ArcSize, 92cb93a386Sopenharmony_ci SkPathDirection::kCW, right - scaled_endcap_radius, 93cb93a386Sopenharmony_ci bottom - scaled_endcap_radius); 94cb93a386Sopenharmony_ci // right_path.rCubicTo(-0.75 * scale, 0, -1.625 * scale, -0.5 * scale, 95cb93a386Sopenharmony_ci // -2 * scale, -1.5 * scale); 96cb93a386Sopenharmony_ci 97cb93a386Sopenharmony_ci right_path.lineTo(right - scaled_endcap_radius, scaled_endcap_radius); 98cb93a386Sopenharmony_ci // right_path.lineTo( 99cb93a386Sopenharmony_ci // right - 1 - scaled_horizontal_inset - (endcap_width - 2) * scale, 100cb93a386Sopenharmony_ci // 2.5 * scale); 101cb93a386Sopenharmony_ci 102cb93a386Sopenharmony_ci right_path.arcTo(scaled_endcap_radius, scaled_endcap_radius, 90, SkPath::kSmall_ArcSize, 103cb93a386Sopenharmony_ci SkPathDirection::kCCW, right - scaled_endcap_radius * 2, 0); 104cb93a386Sopenharmony_ci // right_path.rCubicTo(-0.375 * scale, -1 * scale, -1.25 * scale, -1.5 * scale, 105cb93a386Sopenharmony_ci // -2 * scale, -1.5 * scale); 106cb93a386Sopenharmony_ci 107cb93a386Sopenharmony_ci right_path.lineTo(0, 0); 108cb93a386Sopenharmony_ci right_path.lineTo(0, bottom); 109cb93a386Sopenharmony_ci right_path.close(); 110cb93a386Sopenharmony_ci 111cb93a386Sopenharmony_ci SkPath left_path; 112cb93a386Sopenharmony_ci // const float scaled_endcap_width = 1 + endcap_width * scale; 113cb93a386Sopenharmony_ci left_path.moveTo(scaled_endcap_radius * 2, 0); 114cb93a386Sopenharmony_ci // left_path.moveTo(scaled_endcap_width + scaled_horizontal_inset, scale); 115cb93a386Sopenharmony_ci 116cb93a386Sopenharmony_ci left_path.arcTo(scaled_endcap_radius, scaled_endcap_radius, 90, SkPath::kSmall_ArcSize, 117cb93a386Sopenharmony_ci SkPathDirection::kCCW, scaled_endcap_radius, scaled_endcap_radius); 118cb93a386Sopenharmony_ci // left_path.rCubicTo(-0.75 * scale, 0, -1.625 * scale, 0.5 * scale, -2 * scale, 119cb93a386Sopenharmony_ci // 1.5 * scale); 120cb93a386Sopenharmony_ci 121cb93a386Sopenharmony_ci left_path.lineTo(scaled_endcap_radius, bottom - scaled_endcap_radius); 122cb93a386Sopenharmony_ci // left_path.lineTo(1 + scaled_horizontal_inset + 2 * scale, 123cb93a386Sopenharmony_ci // bottom - 1.5 * scale); 124cb93a386Sopenharmony_ci 125cb93a386Sopenharmony_ci left_path.arcTo(scaled_endcap_radius, scaled_endcap_radius, 90, SkPath::kSmall_ArcSize, 126cb93a386Sopenharmony_ci SkPathDirection::kCW, 0, bottom); 127cb93a386Sopenharmony_ci // left_path.rCubicTo(-0.375 * scale, scale, -1.25 * scale, 1.5 * scale, 128cb93a386Sopenharmony_ci // -2 * scale, 1.5 * scale); 129cb93a386Sopenharmony_ci 130cb93a386Sopenharmony_ci left_path.lineTo(right, bottom); 131cb93a386Sopenharmony_ci left_path.lineTo(right, 0); 132cb93a386Sopenharmony_ci left_path.close(); 133cb93a386Sopenharmony_ci 134cb93a386Sopenharmony_ci SkPath complete_path; 135cb93a386Sopenharmony_ci Op(left_path, right_path, SkPathOp::kIntersect_SkPathOp, &complete_path); 136cb93a386Sopenharmony_ci return complete_path; 137cb93a386Sopenharmony_ci} 138cb93a386Sopenharmony_ci 139cb93a386Sopenharmony_civoid draw(SkCanvas* canvas) { 140cb93a386Sopenharmony_ci SkPaint p; 141cb93a386Sopenharmony_ci p.setColor(SK_ColorRED); 142cb93a386Sopenharmony_ci p.setAntiAlias(true); 143cb93a386Sopenharmony_ci p.setStyle(SkPaint::kStroke_Style); 144cb93a386Sopenharmony_ci p.setStrokeWidth(1); 145cb93a386Sopenharmony_ci SkPath path = GetInteriorPath(1.f, SkISize::Make(250, 36), 16); 146cb93a386Sopenharmony_ci path.transform(SkMatrix::Translate(0, 30)); 147cb93a386Sopenharmony_ci canvas->drawPath(path, p); 148cb93a386Sopenharmony_ci 149cb93a386Sopenharmony_ci p.setColor(SK_ColorBLUE); 150cb93a386Sopenharmony_ci SkPath border_path = GetBorderPath(1.f, false, false, 16, SkISize::Make(250, 36)); 151cb93a386Sopenharmony_ci border_path.transform(SkMatrix::Translate(0, 30)); 152cb93a386Sopenharmony_ci canvas->drawPath(border_path, p); 153cb93a386Sopenharmony_ci 154cb93a386Sopenharmony_ci // canvas->drawLine(20, 20, 100, 100, p); 155cb93a386Sopenharmony_ci} 156cb93a386Sopenharmony_ci} // END FIDDLE 157