Flutter Engine
The Flutter Engine
SkSVGRect.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2016 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include <tuple>
9
12#include "include/core/SkRect.h"
16
17std::tuple<float, float> ResolveOptionalRadii(const SkTLazy<SkSVGLength>& opt_rx,
18 const SkTLazy<SkSVGLength>& opt_ry,
19 const SkSVGLengthContext& lctx) {
20 // https://www.w3.org/TR/SVG2/shapes.html#RectElement
21 //
22 // The used values for rx and ry are determined from the computed values by following these
23 // steps in order:
24 //
25 // 1. If both rx and ry have a computed value of auto (since auto is the initial value for both
26 // properties, this will also occur if neither are specified by the author or if all
27 // author-supplied values are invalid), then the used value of both rx and ry is 0.
28 // (This will result in square corners.)
29 // 2. Otherwise, convert specified values to absolute values as follows:
30 // 1. If rx is set to a length value or a percentage, but ry is auto, calculate an absolute
31 // length equivalent for rx, resolving percentages against the used width of the
32 // rectangle; the absolute value for ry is the same.
33 // 2. If ry is set to a length value or a percentage, but rx is auto, calculate the absolute
34 // length equivalent for ry, resolving percentages against the used height of the
35 // rectangle; the absolute value for rx is the same.
36 // 3. If both rx and ry were set to lengths or percentages, absolute values are generated
37 // individually, resolving rx percentages against the used width, and resolving ry
38 // percentages against the used height.
39 const float rx = opt_rx.isValid()
41 : 0;
42 const float ry = opt_ry.isValid()
44 : 0;
45
46 return std::make_tuple(opt_rx.isValid() ? rx : ry,
47 opt_ry.isValid() ? ry : rx);
48}
49
50SkSVGRect::SkSVGRect() : INHERITED(SkSVGTag::kRect) {}
51
52bool SkSVGRect::parseAndSetAttribute(const char* n, const char* v) {
54 this->setX(SkSVGAttributeParser::parse<SkSVGLength>("x", n, v)) ||
55 this->setY(SkSVGAttributeParser::parse<SkSVGLength>("y", n, v)) ||
56 this->setWidth(SkSVGAttributeParser::parse<SkSVGLength>("width", n, v)) ||
57 this->setHeight(SkSVGAttributeParser::parse<SkSVGLength>("height", n, v)) ||
58 this->setRx(SkSVGAttributeParser::parse<SkSVGLength>("rx", n, v)) ||
59 this->setRy(SkSVGAttributeParser::parse<SkSVGLength>("ry", n, v));
60}
61
62SkRRect SkSVGRect::resolve(const SkSVGLengthContext& lctx) const {
63 const auto rect = lctx.resolveRect(fX, fY, fWidth, fHeight);
64 const auto [ rx, ry ] = ResolveOptionalRadii(fRx, fRy, lctx);
65
66 // https://www.w3.org/TR/SVG2/shapes.html#RectElement
67 // ...
68 // 3. Finally, apply clamping to generate the used values:
69 // 1. If the absolute rx (after the above steps) is greater than half of the used width,
70 // then the used value of rx is half of the used width.
71 // 2. If the absolute ry (after the above steps) is greater than half of the used height,
72 // then the used value of ry is half of the used height.
73 // 3. Otherwise, the used values of rx and ry are the absolute values computed previously.
74
76 std::min(rx, rect.width() / 2),
77 std::min(ry, rect.height() / 2));
78}
79
81 const SkPaint& paint, SkPathFillType) const {
82 canvas->drawRRect(this->resolve(lctx), paint);
83}
84
86 SkPath path = SkPath::RRect(this->resolve(ctx.lengthContext()));
87
88 this->mapToParent(&path);
89
90 return path;
91}
92
94 return ctx.lengthContext().resolveRect(fX, fY, fWidth, fHeight);
95}
SkPathFillType
Definition: SkPathTypes.h:11
#define INHERITED(method,...)
Definition: SkRecorder.cpp:128
SkSVGTag
Definition: SkSVGNode.h:23
std::tuple< float, float > ResolveOptionalRadii(const SkTLazy< SkSVGLength > &opt_rx, const SkTLazy< SkSVGLength > &opt_ry, const SkSVGLengthContext &lctx)
Definition: SkSVGRect.cpp:17
void drawRRect(const SkRRect &rrect, const SkPaint &paint)
Definition: SkCanvas.cpp:1705
Definition: SkPath.h:59
static SkPath RRect(const SkRRect &, SkPathDirection dir=SkPathDirection::kCW)
Definition: SkPath.cpp:3602
static SkRRect MakeRectXY(const SkRect &rect, SkScalar xRad, SkScalar yRad)
Definition: SkRRect.h:180
SkRect resolveRect(const SkSVGLength &x, const SkSVGLength &y, const SkSVGLength &w, const SkSVGLength &h) const
SkScalar resolve(const SkSVGLength &, LengthType) const
virtual bool parseAndSetAttribute(const char *name, const char *value)
Definition: SkSVGNode.cpp:90
SkRect onObjectBoundingBox(const SkSVGRenderContext &) const override
Definition: SkSVGRect.cpp:93
bool parseAndSetAttribute(const char *, const char *) override
Definition: SkSVGRect.cpp:52
SkPath onAsPath(const SkSVGRenderContext &) const override
Definition: SkSVGRect.cpp:85
void onDraw(SkCanvas *, const SkSVGLengthContext &, const SkPaint &, SkPathFillType) const override
Definition: SkSVGRect.cpp:80
const SkSVGLengthContext & lengthContext() const
void mapToParent(SkPath *) const
bool isValid() const
Definition: SkTLazy.h:77
const Paint & paint
Definition: color_source.cc:38
static float min(float r, float g, float b)
Definition: hsl.cpp:48
sk_sp< SkBlender > blender SkRect rect
Definition: SkRecords.h:350
constexpr std::array< std::array< float, 2 >, 2 > kRect
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition: switches.h:57