1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2016 Google Inc.
3*c8dee2aaSAndroid Build Coastguard Worker *
4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker */
7*c8dee2aaSAndroid Build Coastguard Worker
8*c8dee2aaSAndroid Build Coastguard Worker #include "modules/svg/include/SkSVGCircle.h"
9*c8dee2aaSAndroid Build Coastguard Worker
10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkCanvas.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPoint.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "modules/svg/include/SkSVGAttributeParser.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "modules/svg/include/SkSVGRenderContext.h"
14*c8dee2aaSAndroid Build Coastguard Worker
15*c8dee2aaSAndroid Build Coastguard Worker class SkPaint;
16*c8dee2aaSAndroid Build Coastguard Worker enum class SkPathFillType;
17*c8dee2aaSAndroid Build Coastguard Worker
SkSVGCircle()18*c8dee2aaSAndroid Build Coastguard Worker SkSVGCircle::SkSVGCircle() : INHERITED(SkSVGTag::kCircle) {}
19*c8dee2aaSAndroid Build Coastguard Worker
parseAndSetAttribute(const char * n,const char * v)20*c8dee2aaSAndroid Build Coastguard Worker bool SkSVGCircle::parseAndSetAttribute(const char* n, const char* v) {
21*c8dee2aaSAndroid Build Coastguard Worker return INHERITED::parseAndSetAttribute(n, v) ||
22*c8dee2aaSAndroid Build Coastguard Worker this->setCx(SkSVGAttributeParser::parse<SkSVGLength>("cx", n, v)) ||
23*c8dee2aaSAndroid Build Coastguard Worker this->setCy(SkSVGAttributeParser::parse<SkSVGLength>("cy", n, v)) ||
24*c8dee2aaSAndroid Build Coastguard Worker this->setR(SkSVGAttributeParser::parse<SkSVGLength>("r", n, v));
25*c8dee2aaSAndroid Build Coastguard Worker }
26*c8dee2aaSAndroid Build Coastguard Worker
resolve(const SkSVGLengthContext & lctx) const27*c8dee2aaSAndroid Build Coastguard Worker std::tuple<SkPoint, SkScalar> SkSVGCircle::resolve(const SkSVGLengthContext& lctx) const {
28*c8dee2aaSAndroid Build Coastguard Worker const auto cx = lctx.resolve(fCx, SkSVGLengthContext::LengthType::kHorizontal);
29*c8dee2aaSAndroid Build Coastguard Worker const auto cy = lctx.resolve(fCy, SkSVGLengthContext::LengthType::kVertical);
30*c8dee2aaSAndroid Build Coastguard Worker const auto r = lctx.resolve(fR , SkSVGLengthContext::LengthType::kOther);
31*c8dee2aaSAndroid Build Coastguard Worker
32*c8dee2aaSAndroid Build Coastguard Worker return std::make_tuple(SkPoint::Make(cx, cy), r);
33*c8dee2aaSAndroid Build Coastguard Worker }
onDraw(SkCanvas * canvas,const SkSVGLengthContext & lctx,const SkPaint & paint,SkPathFillType) const34*c8dee2aaSAndroid Build Coastguard Worker void SkSVGCircle::onDraw(SkCanvas* canvas, const SkSVGLengthContext& lctx,
35*c8dee2aaSAndroid Build Coastguard Worker const SkPaint& paint, SkPathFillType) const {
36*c8dee2aaSAndroid Build Coastguard Worker SkPoint pos;
37*c8dee2aaSAndroid Build Coastguard Worker SkScalar r;
38*c8dee2aaSAndroid Build Coastguard Worker std::tie(pos, r) = this->resolve(lctx);
39*c8dee2aaSAndroid Build Coastguard Worker
40*c8dee2aaSAndroid Build Coastguard Worker if (r > 0) {
41*c8dee2aaSAndroid Build Coastguard Worker canvas->drawCircle(pos.x(), pos.y(), r, paint);
42*c8dee2aaSAndroid Build Coastguard Worker }
43*c8dee2aaSAndroid Build Coastguard Worker }
44*c8dee2aaSAndroid Build Coastguard Worker
onAsPath(const SkSVGRenderContext & ctx) const45*c8dee2aaSAndroid Build Coastguard Worker SkPath SkSVGCircle::onAsPath(const SkSVGRenderContext& ctx) const {
46*c8dee2aaSAndroid Build Coastguard Worker SkPoint pos;
47*c8dee2aaSAndroid Build Coastguard Worker SkScalar r;
48*c8dee2aaSAndroid Build Coastguard Worker std::tie(pos, r) = this->resolve(ctx.lengthContext());
49*c8dee2aaSAndroid Build Coastguard Worker
50*c8dee2aaSAndroid Build Coastguard Worker SkPath path = SkPath::Circle(pos.x(), pos.y(), r);
51*c8dee2aaSAndroid Build Coastguard Worker this->mapToParent(&path);
52*c8dee2aaSAndroid Build Coastguard Worker
53*c8dee2aaSAndroid Build Coastguard Worker return path;
54*c8dee2aaSAndroid Build Coastguard Worker }
55*c8dee2aaSAndroid Build Coastguard Worker
onObjectBoundingBox(const SkSVGRenderContext & ctx) const56*c8dee2aaSAndroid Build Coastguard Worker SkRect SkSVGCircle::onObjectBoundingBox(const SkSVGRenderContext& ctx) const {
57*c8dee2aaSAndroid Build Coastguard Worker const auto [pos, r] = this->resolve(ctx.lengthContext());
58*c8dee2aaSAndroid Build Coastguard Worker return SkRect::MakeXYWH(pos.fX - r, pos.fY - r, 2 * r, 2 * r);
59*c8dee2aaSAndroid Build Coastguard Worker }
60