зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1383650 - Resolve SVG geometry metrics from CSS r=longsonr,emilio
This patch makes SVG retrieve metrics from CSS style. It doesn't handle <svg> element because geometry properties for outer <svg> element has been partially implemented long ago, it needs special change. It doesn't deal with the impact on SMIL. Differential Revision: https://phabricator.services.mozilla.com/D29992 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
6002ad9aeb
Коммит
b1f320104b
|
@ -9,6 +9,7 @@
|
|||
#include "nsGkAtoms.h"
|
||||
#include "mozilla/dom/SVGCircleElementBinding.h"
|
||||
#include "mozilla/dom/SVGLengthBinding.h"
|
||||
#include "SVGGeometryProperty.h"
|
||||
|
||||
NS_IMPL_NS_NEW_SVG_ELEMENT(Circle)
|
||||
|
||||
|
@ -42,6 +43,8 @@ bool SVGCircleElement::IsAttributeMapped(const nsAtom* aAttribute) const {
|
|||
SVGCircleElementBase::IsAttributeMapped(aAttribute);
|
||||
}
|
||||
|
||||
namespace SVGT = SVGGeometryProperty::Tags;
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsINode methods
|
||||
|
||||
|
@ -66,8 +69,11 @@ already_AddRefed<DOMSVGAnimatedLength> SVGCircleElement::R() {
|
|||
|
||||
/* virtual */
|
||||
bool SVGCircleElement::HasValidDimensions() const {
|
||||
return mLengthAttributes[ATTR_R].IsExplicitlySet() &&
|
||||
mLengthAttributes[ATTR_R].GetAnimValInSpecifiedUnits() > 0;
|
||||
float r;
|
||||
|
||||
MOZ_ASSERT(GetPrimaryFrame());
|
||||
SVGGeometryProperty::ResolveAll<SVGT::R>(this, &r);
|
||||
return r > 0;
|
||||
}
|
||||
|
||||
SVGElement::LengthAttributesInfo SVGCircleElement::GetLengthInfo() {
|
||||
|
@ -82,7 +88,10 @@ bool SVGCircleElement::GetGeometryBounds(
|
|||
Rect* aBounds, const StrokeOptions& aStrokeOptions,
|
||||
const Matrix& aToBoundsSpace, const Matrix* aToNonScalingStrokeSpace) {
|
||||
float x, y, r;
|
||||
GetAnimatedLengthValues(&x, &y, &r, nullptr);
|
||||
|
||||
MOZ_ASSERT(GetPrimaryFrame());
|
||||
SVGGeometryProperty::ResolveAll<SVGT::Cx, SVGT::Cy, SVGT::R>(this, &x, &y,
|
||||
&r);
|
||||
|
||||
if (r <= 0.f) {
|
||||
// Rendering of the element is disabled
|
||||
|
@ -117,7 +126,9 @@ bool SVGCircleElement::GetGeometryBounds(
|
|||
|
||||
already_AddRefed<Path> SVGCircleElement::BuildPath(PathBuilder* aBuilder) {
|
||||
float x, y, r;
|
||||
GetAnimatedLengthValues(&x, &y, &r, nullptr);
|
||||
MOZ_ASSERT(GetPrimaryFrame());
|
||||
SVGGeometryProperty::ResolveAll<SVGT::Cx, SVGT::Cy, SVGT::R>(this, &x, &y,
|
||||
&r);
|
||||
|
||||
if (r <= 0.0f) {
|
||||
return nullptr;
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "mozilla/gfx/2D.h"
|
||||
#include "mozilla/gfx/PathHelpers.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "SVGGeometryProperty.h"
|
||||
|
||||
NS_IMPL_NS_NEW_SVG_ELEMENT(Ellipse)
|
||||
|
||||
|
@ -46,6 +47,8 @@ bool SVGEllipseElement::IsAttributeMapped(const nsAtom* aAttribute) const {
|
|||
SVGEllipseElementBase::IsAttributeMapped(aAttribute);
|
||||
}
|
||||
|
||||
namespace SVGT = SVGGeometryProperty::Tags;
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsINode methods
|
||||
|
||||
|
@ -75,10 +78,12 @@ already_AddRefed<DOMSVGAnimatedLength> SVGEllipseElement::Ry() {
|
|||
|
||||
/* virtual */
|
||||
bool SVGEllipseElement::HasValidDimensions() const {
|
||||
return mLengthAttributes[RX].IsExplicitlySet() &&
|
||||
mLengthAttributes[RX].GetAnimValInSpecifiedUnits() > 0 &&
|
||||
mLengthAttributes[RY].IsExplicitlySet() &&
|
||||
mLengthAttributes[RY].GetAnimValInSpecifiedUnits() > 0;
|
||||
float rx, ry;
|
||||
|
||||
MOZ_ASSERT(GetPrimaryFrame());
|
||||
SVGGeometryProperty::ResolveAll<SVGT::Rx, SVGT::Ry>(this, &rx, &ry);
|
||||
|
||||
return rx > 0 && ry > 0;
|
||||
}
|
||||
|
||||
SVGElement::LengthAttributesInfo SVGEllipseElement::GetLengthInfo() {
|
||||
|
@ -93,7 +98,10 @@ bool SVGEllipseElement::GetGeometryBounds(
|
|||
Rect* aBounds, const StrokeOptions& aStrokeOptions,
|
||||
const Matrix& aToBoundsSpace, const Matrix* aToNonScalingStrokeSpace) {
|
||||
float x, y, rx, ry;
|
||||
GetAnimatedLengthValues(&x, &y, &rx, &ry, nullptr);
|
||||
|
||||
MOZ_ASSERT(GetPrimaryFrame());
|
||||
SVGGeometryProperty::ResolveAll<SVGT::Cx, SVGT::Cy, SVGT::Rx, SVGT::Ry>(
|
||||
this, &x, &y, &rx, &ry);
|
||||
|
||||
if (rx <= 0.f || ry <= 0.f) {
|
||||
// Rendering of the element is disabled
|
||||
|
@ -129,7 +137,10 @@ bool SVGEllipseElement::GetGeometryBounds(
|
|||
|
||||
already_AddRefed<Path> SVGEllipseElement::BuildPath(PathBuilder* aBuilder) {
|
||||
float x, y, rx, ry;
|
||||
GetAnimatedLengthValues(&x, &y, &rx, &ry, nullptr);
|
||||
|
||||
MOZ_ASSERT(GetPrimaryFrame());
|
||||
SVGGeometryProperty::ResolveAll<SVGT::Cx, SVGT::Cy, SVGT::Rx, SVGT::Ry>(
|
||||
this, &x, &y, &rx, &ry);
|
||||
|
||||
if (rx <= 0.0f || ry <= 0.0f) {
|
||||
return nullptr;
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "mozilla/dom/SVGDocument.h"
|
||||
#include "mozilla/dom/SVGForeignObjectElementBinding.h"
|
||||
#include "mozilla/dom/SVGLengthBinding.h"
|
||||
#include "SVGGeometryProperty.h"
|
||||
|
||||
NS_IMPL_NS_NEW_SVG_ELEMENT(ForeignObject)
|
||||
|
||||
|
@ -40,6 +41,8 @@ SVGForeignObjectElement::SVGForeignObjectElement(
|
|||
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
|
||||
: SVGGraphicsElement(std::move(aNodeInfo)) {}
|
||||
|
||||
namespace SVGT = SVGGeometryProperty::Tags;
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsINode methods
|
||||
|
||||
|
@ -77,8 +80,16 @@ gfxMatrix SVGForeignObjectElement::PrependLocalTransformsTo(
|
|||
}
|
||||
// our 'x' and 'y' attributes:
|
||||
float x, y;
|
||||
const_cast<SVGForeignObjectElement*>(this)->GetAnimatedLengthValues(&x, &y,
|
||||
nullptr);
|
||||
|
||||
if (GetPrimaryFrame()) {
|
||||
SVGGeometryProperty::ResolveAll<SVGT::X, SVGT::Y>(this, &x, &y);
|
||||
} else {
|
||||
// This function might be called for element in display:none subtree
|
||||
// (e.g. getScreenCTM), we fall back to use SVG attributes.
|
||||
const_cast<SVGForeignObjectElement*>(this)->GetAnimatedLengthValues(
|
||||
&x, &y, nullptr);
|
||||
}
|
||||
|
||||
gfxMatrix toUserSpace = gfxMatrix::Translation(x, y);
|
||||
if (aWhich == eChildToUserSpace) {
|
||||
return toUserSpace * aMatrix;
|
||||
|
@ -89,10 +100,12 @@ gfxMatrix SVGForeignObjectElement::PrependLocalTransformsTo(
|
|||
|
||||
/* virtual */
|
||||
bool SVGForeignObjectElement::HasValidDimensions() const {
|
||||
return mLengthAttributes[ATTR_WIDTH].IsExplicitlySet() &&
|
||||
mLengthAttributes[ATTR_WIDTH].GetAnimValInSpecifiedUnits() > 0 &&
|
||||
mLengthAttributes[ATTR_HEIGHT].IsExplicitlySet() &&
|
||||
mLengthAttributes[ATTR_HEIGHT].GetAnimValInSpecifiedUnits() > 0;
|
||||
float width, height;
|
||||
|
||||
MOZ_ASSERT(GetPrimaryFrame());
|
||||
SVGGeometryProperty::ResolveAll<SVGT::Width, SVGT::Height>(
|
||||
const_cast<SVGForeignObjectElement*>(this), &width, &height);
|
||||
return width > 0 && height > 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
|
|
@ -0,0 +1,155 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_dom_SVGGeometryProperty_SVGGeometryProperty_h
|
||||
#define mozilla_dom_SVGGeometryProperty_SVGGeometryProperty_h
|
||||
|
||||
#include "mozilla/dom/SVGElement.h"
|
||||
#include "SVGAnimatedLength.h"
|
||||
#include "ComputedStyle.h"
|
||||
#include "nsIFrame.h"
|
||||
#include <type_traits>
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
namespace SVGGeometryProperty {
|
||||
namespace ResolverTypes {
|
||||
struct LengthPercentNoAuto {};
|
||||
struct LengthPercentRXY {};
|
||||
struct LengthPercentWidthHeight {};
|
||||
} // namespace ResolverTypes
|
||||
|
||||
namespace Tags {
|
||||
|
||||
#define SVGGEOMETRYPROPERTY_GENERATETAG(tagName, resolver, direction, \
|
||||
styleStruct) \
|
||||
struct tagName { \
|
||||
using ResolverType = ResolverTypes::resolver; \
|
||||
constexpr static auto CtxDirection = SVGContentUtils::direction; \
|
||||
constexpr static auto Getter = &styleStruct::m##tagName; \
|
||||
}
|
||||
|
||||
SVGGEOMETRYPROPERTY_GENERATETAG(X, LengthPercentNoAuto, X, nsStyleSVGReset);
|
||||
SVGGEOMETRYPROPERTY_GENERATETAG(Y, LengthPercentNoAuto, Y, nsStyleSVGReset);
|
||||
SVGGEOMETRYPROPERTY_GENERATETAG(Cx, LengthPercentNoAuto, X, nsStyleSVGReset);
|
||||
SVGGEOMETRYPROPERTY_GENERATETAG(Cy, LengthPercentNoAuto, Y, nsStyleSVGReset);
|
||||
SVGGEOMETRYPROPERTY_GENERATETAG(R, LengthPercentNoAuto, XY, nsStyleSVGReset);
|
||||
SVGGEOMETRYPROPERTY_GENERATETAG(Width, LengthPercentWidthHeight, X,
|
||||
nsStylePosition);
|
||||
SVGGEOMETRYPROPERTY_GENERATETAG(Height, LengthPercentWidthHeight, Y,
|
||||
nsStylePosition);
|
||||
|
||||
#undef SVGGEOMETRYPROPERTY_GENERATETAG
|
||||
|
||||
struct Ry;
|
||||
struct Rx {
|
||||
using ResolverType = ResolverTypes::LengthPercentRXY;
|
||||
constexpr static auto CtxDirection = SVGContentUtils::X;
|
||||
constexpr static auto Getter = &nsStyleSVGReset::mRx;
|
||||
using CounterPart = Ry;
|
||||
};
|
||||
struct Ry {
|
||||
using ResolverType = ResolverTypes::LengthPercentRXY;
|
||||
constexpr static auto CtxDirection = SVGContentUtils::Y;
|
||||
constexpr static auto Getter = &nsStyleSVGReset::mRy;
|
||||
using CounterPart = Rx;
|
||||
};
|
||||
|
||||
} // namespace Tags
|
||||
|
||||
namespace details {
|
||||
template <class T>
|
||||
using AlwaysFloat = float;
|
||||
|
||||
using CtxDirectionType = decltype(SVGContentUtils::X);
|
||||
|
||||
template <CtxDirectionType CTD>
|
||||
float ResolvePureLengthPercentage(SVGElement* aElement,
|
||||
const LengthPercentage& aLP) {
|
||||
return aLP.ResolveToCSSPixelsWith(
|
||||
[&] { return CSSCoord{SVGElementMetrics(aElement).GetAxisLength(CTD)}; });
|
||||
}
|
||||
|
||||
template <class Tag>
|
||||
float ResolveImpl(ComputedStyle const& aStyle, SVGElement* aElement,
|
||||
ResolverTypes::LengthPercentNoAuto) {
|
||||
auto const& value = aStyle.StyleSVGReset()->*Tag::Getter;
|
||||
return ResolvePureLengthPercentage<Tag::CtxDirection>(aElement, value);
|
||||
}
|
||||
|
||||
template <class Tag>
|
||||
float ResolveImpl(ComputedStyle const& aStyle, SVGElement* aElement,
|
||||
ResolverTypes::LengthPercentWidthHeight) {
|
||||
static_assert(
|
||||
std::is_same<Tag, Tags::Width>{} || std::is_same<Tag, Tags::Height>{},
|
||||
"Wrong tag");
|
||||
|
||||
auto const& value = aStyle.StylePosition()->*Tag::Getter;
|
||||
if (value.IsLengthPercentage()) {
|
||||
return ResolvePureLengthPercentage<Tag::CtxDirection>(
|
||||
aElement, value.AsLengthPercentage());
|
||||
}
|
||||
|
||||
// |auto| and |max-content| etc. are treated as 0.
|
||||
return 0.f;
|
||||
}
|
||||
|
||||
template <class Tag>
|
||||
float ResolveImpl(ComputedStyle const& aStyle, SVGElement* aElement,
|
||||
ResolverTypes::LengthPercentRXY) {
|
||||
static_assert(std::is_same<Tag, Tags::Rx>{} || std::is_same<Tag, Tags::Ry>{},
|
||||
"Wrong tag");
|
||||
|
||||
auto const& value = aStyle.StyleSVGReset()->*Tag::Getter;
|
||||
if (value.IsLengthPercentage()) {
|
||||
return ResolvePureLengthPercentage<Tag::CtxDirection>(
|
||||
aElement, value.AsLengthPercentage());
|
||||
}
|
||||
|
||||
MOZ_ASSERT(value.IsAuto());
|
||||
using Rother = typename Tag::CounterPart;
|
||||
auto const& valueOther = aStyle.StyleSVGReset()->*Rother::Getter;
|
||||
|
||||
if (valueOther.IsAuto()) {
|
||||
// Per SVG2, |Rx|, |Ry| resolve to 0 if both are |auto|
|
||||
return 0.f;
|
||||
}
|
||||
|
||||
// If |Rx| is auto while |Ry| not, |Rx| gets the value of |Ry|.
|
||||
return ResolvePureLengthPercentage<Rother::CtxDirection>(
|
||||
aElement, valueOther.AsLengthPercentage());
|
||||
}
|
||||
|
||||
} // namespace details
|
||||
|
||||
template <class Tag>
|
||||
float ResolveWith(const ComputedStyle& aStyle, const SVGElement* aElement) {
|
||||
// TODO: There are a lot of utilities lacking const-ness in dom/svg.
|
||||
// We should fix that problem and remove this `const_cast`.
|
||||
return details::ResolveImpl<Tag>(aStyle, const_cast<SVGElement*>(aElement),
|
||||
typename Tag::ResolverType{});
|
||||
}
|
||||
|
||||
// To add support for new properties, or to handle special cases for
|
||||
// existing properties, you can add a new tag in |Tags| and |ResolverTypes|
|
||||
// namespace, then implement the behavior in |details::ResolveImpl|.
|
||||
template <class... Tags>
|
||||
bool ResolveAll(const SVGElement* aElement,
|
||||
details::AlwaysFloat<Tags>*... aRes) {
|
||||
if (nsIFrame const* f = aElement->GetPrimaryFrame()) {
|
||||
using dummy = int[];
|
||||
(void)dummy{0, (*aRes = ResolveWith<Tags>(*f->Style(), aElement), 0)...};
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace SVGGeometryProperty
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
|
@ -5,13 +5,14 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/dom/SVGRectElement.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "mozilla/dom/SVGLengthBinding.h"
|
||||
#include "mozilla/dom/SVGRectElementBinding.h"
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "mozilla/gfx/Matrix.h"
|
||||
#include "mozilla/gfx/Rect.h"
|
||||
#include "mozilla/gfx/PathHelpers.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "SVGGeometryProperty.h"
|
||||
#include <algorithm>
|
||||
|
||||
NS_IMPL_NS_NEW_SVG_ELEMENT(Rect)
|
||||
|
@ -54,6 +55,8 @@ bool SVGRectElement::IsAttributeMapped(const nsAtom* aAttribute) const {
|
|||
SVGRectElementBase::IsAttributeMapped(aAttribute);
|
||||
}
|
||||
|
||||
namespace SVGT = SVGGeometryProperty::Tags;
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsINode methods
|
||||
|
||||
|
@ -90,10 +93,13 @@ already_AddRefed<DOMSVGAnimatedLength> SVGRectElement::Ry() {
|
|||
|
||||
/* virtual */
|
||||
bool SVGRectElement::HasValidDimensions() const {
|
||||
return mLengthAttributes[ATTR_WIDTH].IsExplicitlySet() &&
|
||||
mLengthAttributes[ATTR_WIDTH].GetAnimValInSpecifiedUnits() > 0 &&
|
||||
mLengthAttributes[ATTR_HEIGHT].IsExplicitlySet() &&
|
||||
mLengthAttributes[ATTR_HEIGHT].GetAnimValInSpecifiedUnits() > 0;
|
||||
float width, height;
|
||||
|
||||
MOZ_ASSERT(GetPrimaryFrame());
|
||||
SVGGeometryProperty::ResolveAll<SVGT::Width, SVGT::Height>(this, &width,
|
||||
&height);
|
||||
|
||||
return width > 0 && height > 0;
|
||||
}
|
||||
|
||||
SVGElement::LengthAttributesInfo SVGRectElement::GetLengthInfo() {
|
||||
|
@ -110,8 +116,11 @@ bool SVGRectElement::GetGeometryBounds(Rect* aBounds,
|
|||
const Matrix* aToNonScalingStrokeSpace) {
|
||||
Rect rect;
|
||||
Float rx, ry;
|
||||
GetAnimatedLengthValues(&rect.x, &rect.y, &rect.width, &rect.height, &rx, &ry,
|
||||
nullptr);
|
||||
|
||||
MOZ_ASSERT(GetPrimaryFrame());
|
||||
SVGGeometryProperty::ResolveAll<SVGT::X, SVGT::Y, SVGT::Width, SVGT::Height,
|
||||
SVGT::Rx, SVGT::Ry>(
|
||||
this, &rect.x, &rect.y, &rect.width, &rect.height, &rx, &ry);
|
||||
|
||||
if (rect.IsEmpty()) {
|
||||
// Rendering of the element disabled
|
||||
|
@ -160,7 +169,11 @@ bool SVGRectElement::GetGeometryBounds(Rect* aBounds,
|
|||
|
||||
void SVGRectElement::GetAsSimplePath(SimplePath* aSimplePath) {
|
||||
float x, y, width, height, rx, ry;
|
||||
GetAnimatedLengthValues(&x, &y, &width, &height, &rx, &ry, nullptr);
|
||||
|
||||
MOZ_ASSERT(GetPrimaryFrame());
|
||||
SVGGeometryProperty::ResolveAll<SVGT::X, SVGT::Y, SVGT::Width, SVGT::Height,
|
||||
SVGT::Rx, SVGT::Ry>(this, &x, &y, &width,
|
||||
&height, &rx, &ry);
|
||||
|
||||
if (width <= 0 || height <= 0) {
|
||||
aSimplePath->Reset();
|
||||
|
@ -180,7 +193,11 @@ void SVGRectElement::GetAsSimplePath(SimplePath* aSimplePath) {
|
|||
|
||||
already_AddRefed<Path> SVGRectElement::BuildPath(PathBuilder* aBuilder) {
|
||||
float x, y, width, height, rx, ry;
|
||||
GetAnimatedLengthValues(&x, &y, &width, &height, &rx, &ry, nullptr);
|
||||
|
||||
MOZ_ASSERT(GetPrimaryFrame());
|
||||
SVGGeometryProperty::ResolveAll<SVGT::X, SVGT::Y, SVGT::Width, SVGT::Height,
|
||||
SVGT::Rx, SVGT::Ry>(this, &x, &y, &width,
|
||||
&height, &rx, &ry);
|
||||
|
||||
if (width <= 0 || height <= 0) {
|
||||
return nullptr;
|
||||
|
@ -198,18 +215,6 @@ already_AddRefed<Path> SVGRectElement::BuildPath(PathBuilder* aBuilder) {
|
|||
aBuilder->LineTo(r.BottomLeft());
|
||||
aBuilder->Close();
|
||||
} else {
|
||||
// If either the 'rx' or the 'ry' attribute isn't set, then we have to
|
||||
// set it to the value of the other:
|
||||
bool hasRx = mLengthAttributes[ATTR_RX].IsExplicitlySet();
|
||||
bool hasRy = mLengthAttributes[ATTR_RY].IsExplicitlySet();
|
||||
MOZ_ASSERT(hasRx || hasRy);
|
||||
|
||||
if (hasRx && !hasRy) {
|
||||
ry = rx;
|
||||
} else if (hasRy && !hasRx) {
|
||||
rx = ry;
|
||||
}
|
||||
|
||||
// Clamp rx and ry to half the rect's width and height respectively:
|
||||
rx = std::min(rx, width / 2);
|
||||
ry = std::min(ry, height / 2);
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
[image-embedding-svg-with-viewport-units-inline-style.svg]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[image-embedding-svg-with-viewport-units.svg]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[percentage.svg]
|
||||
expected: FAIL
|
|
@ -1,4 +0,0 @@
|
|||
[ellipse-01.svg]
|
||||
expected:
|
||||
if (not (os == "win")): FAIL
|
||||
if (os == "win"): FAIL
|
|
@ -1,4 +0,0 @@
|
|||
[ellipse-02.svg]
|
||||
expected:
|
||||
if (not (os == "win")): FAIL
|
||||
if (os == "win"): FAIL
|
|
@ -1,4 +0,0 @@
|
|||
[ellipse-03.svg]
|
||||
expected:
|
||||
if (not (os == "win")): FAIL
|
||||
if (os == "win"): FAIL
|
|
@ -1,4 +0,0 @@
|
|||
[ellipse-05.svg]
|
||||
expected:
|
||||
if (not (os == "win")): FAIL
|
||||
if (os == "win"): FAIL
|
|
@ -1,4 +0,0 @@
|
|||
[ellipse-06.svg]
|
||||
expected:
|
||||
if (not (os == "win")): FAIL
|
||||
if (os == "win"): FAIL
|
|
@ -1,4 +0,0 @@
|
|||
[ellipse-07.svg]
|
||||
expected:
|
||||
if (not (os == "win")): FAIL
|
||||
if (os == "win"): FAIL
|
|
@ -1,4 +0,0 @@
|
|||
[ellipse-08.svg]
|
||||
expected:
|
||||
if (not (os == "win")): FAIL
|
||||
if (os == "win"): FAIL
|
|
@ -21,6 +21,7 @@
|
|||
<rect style="height: 0" width="10"/>
|
||||
<rect style="height: -10px"/>
|
||||
<rect style="height: -10px" width="10"/>
|
||||
<rect style="width: calc(-10px); height: calc(-10px)"/>
|
||||
</g>
|
||||
|
||||
<g transform="translate(150, 50)">
|
||||
|
@ -29,22 +30,22 @@
|
|||
<circle r="-10"/>
|
||||
<circle style="r: 0"/>
|
||||
<circle style="r: -10px"/>
|
||||
<circle style="r: calc(-10px)"/>
|
||||
</g>
|
||||
|
||||
<g transform="translate(250, 50)">
|
||||
<ellipse/>
|
||||
<ellipse rx="0"/>
|
||||
<ellipse rx="0" ry="10"/>
|
||||
<ellipse rx="-10" ry="10"/>
|
||||
<ellipse ry="0"/>
|
||||
<ellipse ry="0" rx="10"/>
|
||||
<ellipse ry="-10" rx="10"/>
|
||||
<ellipse style="rx: 0"/>
|
||||
<ellipse style="rx: -10px"/>
|
||||
<ellipse style="rx: 0" ry="10"/>
|
||||
<ellipse style="ry: 0"/>
|
||||
<ellipse style="ry: -10px"/>
|
||||
<ellipse style="ry: 0" rx="10"/>
|
||||
<ellipse style="rx: calc(-10px); ry: calc(-10px)"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
|
До Ширина: | Высота: | Размер: 1.6 KiB После Ширина: | Высота: | Размер: 1.7 KiB |
|
@ -22,6 +22,7 @@
|
|||
<rect style="height: 0" width="10"/>
|
||||
<rect style="height: -10px"/>
|
||||
<rect style="height: -10px" width="10"/>
|
||||
<rect style="width: calc(-10px); height: calc(-10px)"/>
|
||||
</g>
|
||||
|
||||
<g transform="translate(150, 50)">
|
||||
|
@ -30,22 +31,22 @@
|
|||
<circle r="-10"/>
|
||||
<circle style="r: 0"/>
|
||||
<circle style="r: -10px"/>
|
||||
<circle style="r: calc(-10px)"/>
|
||||
</g>
|
||||
|
||||
<g transform="translate(250, 50)">
|
||||
<ellipse/>
|
||||
<ellipse rx="0"/>
|
||||
<ellipse rx="0" ry="10"/>
|
||||
<ellipse rx="-10" ry="10"/>
|
||||
<ellipse ry="0"/>
|
||||
<ellipse ry="0" rx="10"/>
|
||||
<ellipse ry="-10" rx="10"/>
|
||||
<ellipse style="rx: 0"/>
|
||||
<ellipse style="rx: -10px"/>
|
||||
<ellipse style="rx: 0" ry="10"/>
|
||||
<ellipse style="ry: 0"/>
|
||||
<ellipse style="ry: -10px"/>
|
||||
<ellipse style="ry: 0" rx="10"/>
|
||||
<ellipse style="rx: calc(-10px); ry: calc(-10px)"/>
|
||||
</g>
|
||||
</g>
|
||||
<script><![CDATA[
|
||||
|
|
До Ширина: | Высота: | Размер: 2.3 KiB После Ширина: | Высота: | Размер: 2.4 KiB |
Загрузка…
Ссылка в новой задаче