[svg] Add support for preserveAspectRatio
This fixes the aspect ratio for pretty much all tests. Since we're going to rebaseline everything, also have dm use a white background (to match other user agents). Bug: skia:10842 Change-Id: Iab2afd61560af540539c216d1c3673f19fe0fe51 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/328982 Commit-Queue: Florin Malita <fmalita@chromium.org> Commit-Queue: Florin Malita <fmalita@google.com> Reviewed-by: Tyler Denniston <tdenniston@google.com>
This commit is contained in:
parent
e51b6a3da6
commit
385e74470f
@ -1326,6 +1326,7 @@ Result SVGSrc::draw(GrDirectContext*, SkCanvas* canvas) const {
|
||||
|
||||
SkAutoCanvasRestore acr(canvas, true);
|
||||
canvas->scale(fScale, fScale);
|
||||
canvas->drawColor(SK_ColorWHITE);
|
||||
fDom->render(canvas);
|
||||
|
||||
return Result::Ok();
|
||||
|
@ -37,6 +37,7 @@ enum class SkSVGAttribute {
|
||||
kOpacity,
|
||||
kPatternTransform,
|
||||
kPoints,
|
||||
kPreserveAspectRatio,
|
||||
kR, // <circle>, <radialGradient>: radius
|
||||
kRx, // <ellipse>,<rect>: horizontal (corner) radius
|
||||
kRy, // <ellipse>,<rect>: vertical (corner) radius
|
||||
|
@ -32,6 +32,7 @@ public:
|
||||
bool parseGradientUnits(SkSVGGradientUnits*);
|
||||
bool parseVisibility(SkSVGVisibility*);
|
||||
bool parseDashArray(SkSVGDashArray*);
|
||||
bool parsePreserveAspectRatio(SkSVGPreserveAspectRatio*);
|
||||
|
||||
bool parseFontFamily(SkSVGFontFamily*);
|
||||
bool parseFontSize(SkSVGFontSize*);
|
||||
|
@ -128,4 +128,14 @@ private:
|
||||
using INHERITED = SkRefCnt;
|
||||
};
|
||||
|
||||
#undef SVG_PRES_ATTR // presentation attributes are only defined for the base class
|
||||
|
||||
#define SVG_ATTR(attr_name, attr_type, attr_default) \
|
||||
private: \
|
||||
attr_type f##attr_name = attr_default; \
|
||||
public: \
|
||||
const attr_type& get##attr_name() const { return f##attr_name; } \
|
||||
void set##attr_name(const attr_type& a) { f##attr_name = a; } \
|
||||
void set##attr_name(attr_type&& a) { f##attr_name = std::move(a); }
|
||||
|
||||
#endif // SkSVGNode_DEFINED
|
||||
|
@ -20,10 +20,13 @@ public:
|
||||
|
||||
static sk_sp<SkSVGSVG> Make() { return sk_sp<SkSVGSVG>(new SkSVGSVG()); }
|
||||
|
||||
void setX(const SkSVGLength&);
|
||||
void setY(const SkSVGLength&);
|
||||
void setWidth(const SkSVGLength&);
|
||||
void setHeight(const SkSVGLength&);
|
||||
SVG_ATTR(X , SkSVGLength, SkSVGLength(0))
|
||||
SVG_ATTR(Y , SkSVGLength, SkSVGLength(0))
|
||||
SVG_ATTR(Width , SkSVGLength, SkSVGLength(100, SkSVGLength::Unit::kPercentage))
|
||||
SVG_ATTR(Height , SkSVGLength, SkSVGLength(100, SkSVGLength::Unit::kPercentage))
|
||||
SVG_ATTR(PreserveAspectRatio, SkSVGPreserveAspectRatio, SkSVGPreserveAspectRatio())
|
||||
|
||||
// TODO: SVG_ATTR is not smart enough to handle SkTLazy<T>
|
||||
void setViewBox(const SkSVGViewBoxType&);
|
||||
|
||||
SkSize intrinsicSize(const SkSVGLengthContext&) const;
|
||||
@ -36,11 +39,6 @@ protected:
|
||||
private:
|
||||
SkSVGSVG();
|
||||
|
||||
SkSVGLength fX = SkSVGLength(0);
|
||||
SkSVGLength fY = SkSVGLength(0);
|
||||
SkSVGLength fWidth = SkSVGLength(100, SkSVGLength::Unit::kPercentage);
|
||||
SkSVGLength fHeight = SkSVGLength(100, SkSVGLength::Unit::kPercentage);
|
||||
|
||||
SkTLazy<SkSVGViewBoxType> fViewBox;
|
||||
|
||||
using INHERITED = SkSVGContainer;
|
||||
|
@ -437,4 +437,30 @@ private:
|
||||
Type fType;
|
||||
};
|
||||
|
||||
struct SkSVGPreserveAspectRatio {
|
||||
enum Align : uint8_t {
|
||||
// These values are chosen such that bits [0,1] encode X alignment, and
|
||||
// bits [2,3] encode Y alignment.
|
||||
kXMinYMin = 0x00,
|
||||
kXMidYMin = 0x01,
|
||||
kXMaxYMin = 0x02,
|
||||
kXMinYMid = 0x04,
|
||||
kXMidYMid = 0x05,
|
||||
kXMaxYMid = 0x06,
|
||||
kXMinYMax = 0x08,
|
||||
kXMidYMax = 0x09,
|
||||
kXMaxYMax = 0x0a,
|
||||
|
||||
kNone = 0x10,
|
||||
};
|
||||
|
||||
enum Scale {
|
||||
kMeet,
|
||||
kSlice,
|
||||
};
|
||||
|
||||
Align fAlign = kXMidYMid;
|
||||
Scale fScale = kMeet;
|
||||
};
|
||||
|
||||
#endif // SkSVGTypes_DEFINED
|
||||
|
@ -34,6 +34,7 @@ public:
|
||||
kPaint,
|
||||
kPath,
|
||||
kPoints,
|
||||
kPreserveAspectRatio,
|
||||
kSpreadMethod,
|
||||
kStopColor,
|
||||
kString,
|
||||
@ -106,4 +107,7 @@ using SkSVGFontSizeValue = SkSVGWrapperValue<SkSVGFontSize , SkSVGValue:
|
||||
using SkSVGFontStyleValue = SkSVGWrapperValue<SkSVGFontStyle , SkSVGValue::Type::kFontStyle >;
|
||||
using SkSVGFontWeightValue = SkSVGWrapperValue<SkSVGFontWeight , SkSVGValue::Type::kFontWeight>;
|
||||
|
||||
using SkSVGPreserveAspectRatioValue = SkSVGWrapperValue<SkSVGPreserveAspectRatio,
|
||||
SkSVGValue::Type::kPreserveAspectRatio>;
|
||||
|
||||
#endif // SkSVGValue_DEFINED
|
||||
|
@ -821,3 +821,41 @@ bool SkSVGAttributeParser::parseFontWeight(SkSVGFontWeight* weight) {
|
||||
|
||||
return parsedValue && this->parseEOSToken();
|
||||
}
|
||||
|
||||
// https://www.w3.org/TR/SVG11/coords.html#PreserveAspectRatioAttribute
|
||||
bool SkSVGAttributeParser::parsePreserveAspectRatio(SkSVGPreserveAspectRatio* par) {
|
||||
static constexpr std::tuple<const char*, SkSVGPreserveAspectRatio::Align> gAlignMap[] = {
|
||||
{ "none" , SkSVGPreserveAspectRatio::kNone },
|
||||
{ "xMinYMin", SkSVGPreserveAspectRatio::kXMinYMin },
|
||||
{ "xMidYMin", SkSVGPreserveAspectRatio::kXMidYMin },
|
||||
{ "xMaxYMin", SkSVGPreserveAspectRatio::kXMaxYMin },
|
||||
{ "xMinYMid", SkSVGPreserveAspectRatio::kXMinYMid },
|
||||
{ "xMidYMid", SkSVGPreserveAspectRatio::kXMidYMid },
|
||||
{ "xMaxYMid", SkSVGPreserveAspectRatio::kXMaxYMid },
|
||||
{ "xMinYMax", SkSVGPreserveAspectRatio::kXMinYMax },
|
||||
{ "xMidYMax", SkSVGPreserveAspectRatio::kXMidYMax },
|
||||
{ "xMaxYMax", SkSVGPreserveAspectRatio::kXMaxYMax },
|
||||
};
|
||||
|
||||
static constexpr std::tuple<const char*, SkSVGPreserveAspectRatio::Scale> gScaleMap[] = {
|
||||
{ "meet" , SkSVGPreserveAspectRatio::kMeet },
|
||||
{ "slice", SkSVGPreserveAspectRatio::kSlice },
|
||||
};
|
||||
|
||||
bool parsedValue = false;
|
||||
|
||||
// ignoring optional 'defer'
|
||||
this->parseExpectedStringToken("defer");
|
||||
this->parseWSToken();
|
||||
|
||||
if (this->parseEnumMap(gAlignMap, &par->fAlign)) {
|
||||
parsedValue = true;
|
||||
|
||||
// optional scaling selector
|
||||
this->parseWSToken();
|
||||
this->parseEnumMap(gScaleMap, &par->fScale);
|
||||
}
|
||||
|
||||
return parsedValue && this->parseEOSToken();
|
||||
}
|
||||
|
||||
|
@ -308,6 +308,18 @@ bool SetFontWeightAttribute(const sk_sp<SkSVGNode>& node, SkSVGAttribute attr,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SetPreserveAspectRatioAttribute(const sk_sp<SkSVGNode>& node, SkSVGAttribute attr,
|
||||
const char* stringValue) {
|
||||
SkSVGPreserveAspectRatio par;
|
||||
SkSVGAttributeParser parser(stringValue);
|
||||
if (!parser.parsePreserveAspectRatio(&par)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
node->setAttribute(attr, SkSVGPreserveAspectRatioValue(par));
|
||||
return true;
|
||||
}
|
||||
|
||||
SkString TrimmedString(const char* first, const char* last) {
|
||||
SkASSERT(first);
|
||||
SkASSERT(last);
|
||||
@ -386,57 +398,59 @@ struct AttrParseInfo {
|
||||
};
|
||||
|
||||
SortedDictionaryEntry<AttrParseInfo> gAttributeParseInfo[] = {
|
||||
{ "clip-path" , { SkSVGAttribute::kClipPath , SetClipPathAttribute }},
|
||||
{ "clip-rule" , { SkSVGAttribute::kClipRule , SetFillRuleAttribute }},
|
||||
{ "color" , { SkSVGAttribute::kColor , SetColorAttribute }},
|
||||
{ "cx" , { SkSVGAttribute::kCx , SetLengthAttribute }},
|
||||
{ "cy" , { SkSVGAttribute::kCy , SetLengthAttribute }},
|
||||
{ "d" , { SkSVGAttribute::kD , SetPathDataAttribute }},
|
||||
{ "fill" , { SkSVGAttribute::kFill , SetPaintAttribute }},
|
||||
{ "fill-opacity" , { SkSVGAttribute::kFillOpacity , SetNumberAttribute }},
|
||||
{ "fill-rule" , { SkSVGAttribute::kFillRule , SetFillRuleAttribute }},
|
||||
{ "font-family" , { SkSVGAttribute::kFontFamily , SetFontFamilyAttribute }},
|
||||
{ "font-size" , { SkSVGAttribute::kFontSize , SetFontSizeAttribute }},
|
||||
{ "font-style" , { SkSVGAttribute::kFontStyle , SetFontStyleAttribute }},
|
||||
{ "font-weight" , { SkSVGAttribute::kFontWeight , SetFontWeightAttribute }},
|
||||
{ "clip-path" , { SkSVGAttribute::kClipPath , SetClipPathAttribute }},
|
||||
{ "clip-rule" , { SkSVGAttribute::kClipRule , SetFillRuleAttribute }},
|
||||
{ "color" , { SkSVGAttribute::kColor , SetColorAttribute }},
|
||||
{ "cx" , { SkSVGAttribute::kCx , SetLengthAttribute }},
|
||||
{ "cy" , { SkSVGAttribute::kCy , SetLengthAttribute }},
|
||||
{ "d" , { SkSVGAttribute::kD , SetPathDataAttribute }},
|
||||
{ "fill" , { SkSVGAttribute::kFill , SetPaintAttribute }},
|
||||
{ "fill-opacity" , { SkSVGAttribute::kFillOpacity , SetNumberAttribute }},
|
||||
{ "fill-rule" , { SkSVGAttribute::kFillRule , SetFillRuleAttribute }},
|
||||
{ "font-family" , { SkSVGAttribute::kFontFamily , SetFontFamilyAttribute }},
|
||||
{ "font-size" , { SkSVGAttribute::kFontSize , SetFontSizeAttribute }},
|
||||
{ "font-style" , { SkSVGAttribute::kFontStyle , SetFontStyleAttribute }},
|
||||
{ "font-weight" , { SkSVGAttribute::kFontWeight , SetFontWeightAttribute }},
|
||||
// focal point x & y
|
||||
{ "fx" , { SkSVGAttribute::kFx , SetLengthAttribute }},
|
||||
{ "fy" , { SkSVGAttribute::kFy , SetLengthAttribute }},
|
||||
{ "gradientTransform", { SkSVGAttribute::kGradientTransform, SetTransformAttribute }},
|
||||
{ "gradientUnits" , { SkSVGAttribute::kGradientUnits , SetGradientUnitsAttribute}},
|
||||
{ "height" , { SkSVGAttribute::kHeight , SetLengthAttribute }},
|
||||
{ "offset" , { SkSVGAttribute::kOffset , SetLengthAttribute }},
|
||||
{ "opacity" , { SkSVGAttribute::kOpacity , SetNumberAttribute }},
|
||||
{ "patternTransform" , { SkSVGAttribute::kPatternTransform , SetTransformAttribute }},
|
||||
{ "points" , { SkSVGAttribute::kPoints , SetPointsAttribute }},
|
||||
{ "r" , { SkSVGAttribute::kR , SetLengthAttribute }},
|
||||
{ "rx" , { SkSVGAttribute::kRx , SetLengthAttribute }},
|
||||
{ "ry" , { SkSVGAttribute::kRy , SetLengthAttribute }},
|
||||
{ "spreadMethod" , { SkSVGAttribute::kSpreadMethod , SetSpreadMethodAttribute }},
|
||||
{ "stop-color" , { SkSVGAttribute::kStopColor , SetStopColorAttribute }},
|
||||
{ "stop-opacity" , { SkSVGAttribute::kStopOpacity , SetNumberAttribute }},
|
||||
{ "stroke" , { SkSVGAttribute::kStroke , SetPaintAttribute }},
|
||||
{ "stroke-dasharray" , { SkSVGAttribute::kStrokeDashArray , SetDashArrayAttribute }},
|
||||
{ "stroke-dashoffset", { SkSVGAttribute::kStrokeDashOffset , SetLengthAttribute }},
|
||||
{ "stroke-linecap" , { SkSVGAttribute::kStrokeLineCap , SetLineCapAttribute }},
|
||||
{ "stroke-linejoin" , { SkSVGAttribute::kStrokeLineJoin , SetLineJoinAttribute }},
|
||||
{ "stroke-miterlimit", { SkSVGAttribute::kStrokeMiterLimit , SetNumberAttribute }},
|
||||
{ "stroke-opacity" , { SkSVGAttribute::kStrokeOpacity , SetNumberAttribute }},
|
||||
{ "stroke-width" , { SkSVGAttribute::kStrokeWidth , SetLengthAttribute }},
|
||||
{ "style" , { SkSVGAttribute::kUnknown , SetStyleAttributes }},
|
||||
{ "text" , { SkSVGAttribute::kText , SetStringAttribute }},
|
||||
{ "text-anchor" , { SkSVGAttribute::kTextAnchor , SetStringAttribute }},
|
||||
{ "transform" , { SkSVGAttribute::kTransform , SetTransformAttribute }},
|
||||
{ "viewBox" , { SkSVGAttribute::kViewBox , SetViewBoxAttribute }},
|
||||
{ "visibility" , { SkSVGAttribute::kVisibility , SetVisibilityAttribute }},
|
||||
{ "width" , { SkSVGAttribute::kWidth , SetLengthAttribute }},
|
||||
{ "x" , { SkSVGAttribute::kX , SetLengthAttribute }},
|
||||
{ "x1" , { SkSVGAttribute::kX1 , SetLengthAttribute }},
|
||||
{ "x2" , { SkSVGAttribute::kX2 , SetLengthAttribute }},
|
||||
{ "xlink:href" , { SkSVGAttribute::kHref , SetIRIAttribute }},
|
||||
{ "y" , { SkSVGAttribute::kY , SetLengthAttribute }},
|
||||
{ "y1" , { SkSVGAttribute::kY1 , SetLengthAttribute }},
|
||||
{ "y2" , { SkSVGAttribute::kY2 , SetLengthAttribute }},
|
||||
{ "fx" , { SkSVGAttribute::kFx , SetLengthAttribute }},
|
||||
{ "fy" , { SkSVGAttribute::kFy , SetLengthAttribute }},
|
||||
{ "gradientTransform" , { SkSVGAttribute::kGradientTransform, SetTransformAttribute }},
|
||||
{ "gradientUnits" , { SkSVGAttribute::kGradientUnits , SetGradientUnitsAttribute}},
|
||||
{ "height" , { SkSVGAttribute::kHeight , SetLengthAttribute }},
|
||||
{ "offset" , { SkSVGAttribute::kOffset , SetLengthAttribute }},
|
||||
{ "opacity" , { SkSVGAttribute::kOpacity , SetNumberAttribute }},
|
||||
{ "patternTransform" , { SkSVGAttribute::kPatternTransform , SetTransformAttribute }},
|
||||
{ "points" , { SkSVGAttribute::kPoints , SetPointsAttribute }},
|
||||
{ "preserveAspectRatio", { SkSVGAttribute::kPreserveAspectRatio,
|
||||
SetPreserveAspectRatioAttribute }},
|
||||
{ "r" , { SkSVGAttribute::kR , SetLengthAttribute }},
|
||||
{ "rx" , { SkSVGAttribute::kRx , SetLengthAttribute }},
|
||||
{ "ry" , { SkSVGAttribute::kRy , SetLengthAttribute }},
|
||||
{ "spreadMethod" , { SkSVGAttribute::kSpreadMethod , SetSpreadMethodAttribute }},
|
||||
{ "stop-color" , { SkSVGAttribute::kStopColor , SetStopColorAttribute }},
|
||||
{ "stop-opacity" , { SkSVGAttribute::kStopOpacity , SetNumberAttribute }},
|
||||
{ "stroke" , { SkSVGAttribute::kStroke , SetPaintAttribute }},
|
||||
{ "stroke-dasharray" , { SkSVGAttribute::kStrokeDashArray , SetDashArrayAttribute }},
|
||||
{ "stroke-dashoffset" , { SkSVGAttribute::kStrokeDashOffset , SetLengthAttribute }},
|
||||
{ "stroke-linecap" , { SkSVGAttribute::kStrokeLineCap , SetLineCapAttribute }},
|
||||
{ "stroke-linejoin" , { SkSVGAttribute::kStrokeLineJoin , SetLineJoinAttribute }},
|
||||
{ "stroke-miterlimit" , { SkSVGAttribute::kStrokeMiterLimit , SetNumberAttribute }},
|
||||
{ "stroke-opacity" , { SkSVGAttribute::kStrokeOpacity , SetNumberAttribute }},
|
||||
{ "stroke-width" , { SkSVGAttribute::kStrokeWidth , SetLengthAttribute }},
|
||||
{ "style" , { SkSVGAttribute::kUnknown , SetStyleAttributes }},
|
||||
{ "text" , { SkSVGAttribute::kText , SetStringAttribute }},
|
||||
{ "text-anchor" , { SkSVGAttribute::kTextAnchor , SetStringAttribute }},
|
||||
{ "transform" , { SkSVGAttribute::kTransform , SetTransformAttribute }},
|
||||
{ "viewBox" , { SkSVGAttribute::kViewBox , SetViewBoxAttribute }},
|
||||
{ "visibility" , { SkSVGAttribute::kVisibility , SetVisibilityAttribute }},
|
||||
{ "width" , { SkSVGAttribute::kWidth , SetLengthAttribute }},
|
||||
{ "x" , { SkSVGAttribute::kX , SetLengthAttribute }},
|
||||
{ "x1" , { SkSVGAttribute::kX1 , SetLengthAttribute }},
|
||||
{ "x2" , { SkSVGAttribute::kX2 , SetLengthAttribute }},
|
||||
{ "xlink:href" , { SkSVGAttribute::kHref , SetIRIAttribute }},
|
||||
{ "y" , { SkSVGAttribute::kY , SetLengthAttribute }},
|
||||
{ "y1" , { SkSVGAttribute::kY1 , SetLengthAttribute }},
|
||||
{ "y2" , { SkSVGAttribute::kY2 , SetLengthAttribute }},
|
||||
};
|
||||
|
||||
SortedDictionaryEntry<sk_sp<SkSVGNode>(*)()> gTagFactories[] = {
|
||||
|
@ -12,6 +12,58 @@
|
||||
|
||||
SkSVGSVG::SkSVGSVG() : INHERITED(SkSVGTag::kSvg) { }
|
||||
|
||||
static SkMatrix ViewboxMatrix(const SkRect& view_box, const SkRect& view_port,
|
||||
const SkSVGPreserveAspectRatio& par) {
|
||||
SkASSERT(!view_box.isEmpty());
|
||||
SkASSERT(!view_port.isEmpty());
|
||||
|
||||
auto compute_scale = [&]() -> SkV2 {
|
||||
const auto sx = view_port.width() / view_box.width(),
|
||||
sy = view_port.height() / view_box.height();
|
||||
|
||||
if (par.fAlign == SkSVGPreserveAspectRatio::kNone) {
|
||||
// none -> anisotropic scaling, regardless of fScale
|
||||
return {sx,sy};
|
||||
}
|
||||
|
||||
// isotropic scaling
|
||||
const auto s = par.fScale == SkSVGPreserveAspectRatio::kMeet
|
||||
? std::min(sx, sy)
|
||||
: std::max(sx, sy);
|
||||
return {s,s};
|
||||
};
|
||||
|
||||
auto compute_trans = [&](const SkV2& scale) -> SkV2 {
|
||||
static constexpr float gAlignCoeffs[] = {
|
||||
0.0f, // Min
|
||||
0.5f, // Mid
|
||||
1.0f // Max
|
||||
};
|
||||
|
||||
const size_t x_coeff = par.fAlign>>0 & 0x03,
|
||||
y_coeff = par.fAlign>>2 & 0x03;
|
||||
|
||||
SkASSERT(x_coeff < SK_ARRAY_COUNT(gAlignCoeffs) &&
|
||||
y_coeff < SK_ARRAY_COUNT(gAlignCoeffs));
|
||||
|
||||
const auto tx = -view_box.x() * scale.x,
|
||||
ty = -view_box.y() * scale.y,
|
||||
dx = view_port.width() - view_box.width() * scale.x,
|
||||
dy = view_port.height() - view_box.height()* scale.y;
|
||||
|
||||
return {
|
||||
tx + dx * gAlignCoeffs[x_coeff],
|
||||
ty + dy * gAlignCoeffs[y_coeff]
|
||||
};
|
||||
};
|
||||
|
||||
const auto s = compute_scale(),
|
||||
t = compute_trans(s);
|
||||
|
||||
return SkMatrix::Translate(t.x, t.y) *
|
||||
SkMatrix::Scale(s.x, s.y);
|
||||
}
|
||||
|
||||
bool SkSVGSVG::onPrepareToRender(SkSVGRenderContext* ctx) const {
|
||||
auto viewPortRect = ctx->lengthContext().resolveRect(fX, fY, fWidth, fHeight);
|
||||
auto contentMatrix = SkMatrix::Translate(viewPortRect.x(), viewPortRect.y());
|
||||
@ -28,8 +80,7 @@ bool SkSVGSVG::onPrepareToRender(SkSVGRenderContext* ctx) const {
|
||||
// A viewBox overrides the intrinsic viewport.
|
||||
viewPort = SkSize::Make(viewBox.width(), viewBox.height());
|
||||
|
||||
contentMatrix.preConcat(
|
||||
SkMatrix::MakeRectToRect(viewBox, viewPortRect, SkMatrix::kFill_ScaleToFit));
|
||||
contentMatrix.preConcat(ViewboxMatrix(viewBox, viewPortRect, fPreserveAspectRatio));
|
||||
}
|
||||
|
||||
if (!contentMatrix.isIdentity()) {
|
||||
@ -44,22 +95,6 @@ bool SkSVGSVG::onPrepareToRender(SkSVGRenderContext* ctx) const {
|
||||
return this->INHERITED::onPrepareToRender(ctx);
|
||||
}
|
||||
|
||||
void SkSVGSVG::setX(const SkSVGLength& x) {
|
||||
fX = x;
|
||||
}
|
||||
|
||||
void SkSVGSVG::setY(const SkSVGLength& y) {
|
||||
fY = y;
|
||||
}
|
||||
|
||||
void SkSVGSVG::setWidth(const SkSVGLength& w) {
|
||||
fWidth = w;
|
||||
}
|
||||
|
||||
void SkSVGSVG::setHeight(const SkSVGLength& h) {
|
||||
fHeight = h;
|
||||
}
|
||||
|
||||
void SkSVGSVG::setViewBox(const SkSVGViewBoxType& vb) {
|
||||
fViewBox.set(vb);
|
||||
}
|
||||
@ -91,6 +126,11 @@ void SkSVGSVG::onSetAttribute(SkSVGAttribute attr, const SkSVGValue& v) {
|
||||
this->setViewBox(*vb);
|
||||
}
|
||||
break;
|
||||
case SkSVGAttribute::kPreserveAspectRatio:
|
||||
if (const auto* par = v.as<SkSVGPreserveAspectRatioValue>()) {
|
||||
this->setPreserveAspectRatio(*par);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
this->INHERITED::onSetAttribute(attr, v);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user