SkSVGPresentationAttributes SkSVGPresentationAttributes::MakeInitial() { SkSVGPresentationAttributes result; result.fFill.set(SkSVGPaint(SkSVGColorType(SK_ColorBLACK))); result.fFillOpacity.set(SkSVGNumberType(1)); result.fStroke.set(SkSVGPaint(SkSVGPaint::Type::kNone)); result.fStrokeLineCap.set(SkSVGLineCap(SkSVGLineCap::Type::kButt)); result.fStrokeLineJoin.set(SkSVGLineJoin(SkSVGLineJoin::Type::kMiter)); result.fStrokeOpacity.set(SkSVGNumberType(1)); result.fStrokeWidth.set(SkSVGLength(1)); return result; }
void initialize(const SkRRect& rrect, SkColor color, const SkPoint& p, const SkVector& s) { objectNode = make_svg_rrect(rrect); objectNode->setFill(SkSVGPaint(SkSVGColorType(color))); shadowNode = make_svg_rrect(rrect); shadowNode->setFillOpacity(SkSVGNumberType(kShadowOpacity)); pos = p; spd = s; size = SkSize::Make(rrect.width(), rrect.height()); }
// https://www.w3.org/TR/SVG/painting.html#SpecifyingPaint bool SkSVGAttributeParser::parsePaint(SkSVGPaint* paint) { SkSVGColorType c; SkSVGStringType iri; bool parsedValue = false; if (this->parseColor(&c)) { *paint = SkSVGPaint(c); parsedValue = true; } else if (this->parseExpectedStringToken("none")) { *paint = SkSVGPaint(SkSVGPaint::Type::kNone); parsedValue = true; } else if (this->parseExpectedStringToken("currentColor")) { *paint = SkSVGPaint(SkSVGPaint::Type::kCurrentColor); parsedValue = true; } else if (this->parseExpectedStringToken("inherit")) { *paint = SkSVGPaint(SkSVGPaint::Type::kInherit); parsedValue = true; } else if (this->parseFuncIRI(&iri)) { *paint = SkSVGPaint(iri.value()); parsedValue = true; } return parsedValue && this->parseEOSToken(); }
void onOnceBeforeDraw() override { const SkRect fieldBounds = kBounds.makeOutset(kBallSize / 2, kBallSize / 2); const SkRRect ball = SkRRect::MakeOval(SkRect::MakeWH(kBallSize, kBallSize)); const SkRRect paddle = SkRRect::MakeRectXY(SkRect::MakeWH(kPaddleSize.width(), kPaddleSize.height()), kPaddleSize.width() / 2, kPaddleSize.width() / 2); fBall.initialize(ball, SK_ColorGREEN, SkPoint::Make(kBounds.centerX(), kBounds.centerY()), SkVector::Make(fRand.nextRangeScalar(kBallSpeedMin, kBallSpeedMax), fRand.nextRangeScalar(kBallSpeedMin, kBallSpeedMax))); fPaddle0.initialize(paddle, SK_ColorBLUE, SkPoint::Make(fieldBounds.left() - kPaddleSize.width() / 2, fieldBounds.centerY()), SkVector::Make(0, 0)); fPaddle1.initialize(paddle, SK_ColorRED, SkPoint::Make(fieldBounds.right() + kPaddleSize.width() / 2, fieldBounds.centerY()), SkVector::Make(0, 0)); // Background decoration. SkPath bgPath; bgPath.moveTo(kBounds.left() , fieldBounds.top()); bgPath.lineTo(kBounds.right(), fieldBounds.top()); bgPath.moveTo(kBounds.left() , fieldBounds.bottom()); bgPath.lineTo(kBounds.right(), fieldBounds.bottom()); // TODO: stroke-dash support would come in handy right about now. for (uint32_t i = 0; i < kBackgroundDashCount; ++i) { bgPath.moveTo(kBounds.centerX(), kBounds.top() + (i + 0.25f) * kBounds.height() / kBackgroundDashCount); bgPath.lineTo(kBounds.centerX(), kBounds.top() + (i + 0.75f) * kBounds.height() / kBackgroundDashCount); } sk_sp<SkSVGPath> bg = SkSVGPath::Make(); bg->setPath(bgPath); bg->setFill(SkSVGPaint(SkSVGPaint::Type::kNone)); bg->setStroke(SkSVGPaint(SkSVGColorType(SK_ColorBLACK))); bg->setStrokeWidth(SkSVGLength(kBackgroundStroke)); // Build the SVG DOM tree. sk_sp<SkSVGSVG> root = SkSVGSVG::Make(); root->appendChild(std::move(bg)); root->appendChild(fPaddle0.shadowNode); root->appendChild(fPaddle1.shadowNode); root->appendChild(fBall.shadowNode); root->appendChild(fPaddle0.objectNode); root->appendChild(fPaddle1.objectNode); root->appendChild(fBall.objectNode); // Handle everything in a normalized 1x1 space. root->setViewBox(SkSVGViewBoxType(SkRect::MakeWH(1, 1))); fDom = sk_sp<SkSVGDOM>(new SkSVGDOM()); fDom->setContainerSize(SkSize::Make(this->width(), this->height())); fDom->setRoot(std::move(root)); // Off we go. this->updatePaddleStrategy(); }