Bug 1905023 - viewBox values need to be adjusted in the presence of CSS zoom r=emilio

Differential Revision: https://phabricator.services.mozilla.com/D215300
This commit is contained in:
longsonr 2024-07-03 15:42:09 +00:00
Родитель d8d0cb658e
Коммит 03b674d7e6
7 изменённых файлов: 40 добавлений и 14 удалений

Просмотреть файл

@ -34,6 +34,9 @@ struct SVGViewBox {
SVGViewBox(float aX, float aY, float aWidth, float aHeight)
: x(aX), y(aY), width(aWidth), height(aHeight), none(false) {}
bool operator==(const SVGViewBox& aOther) const;
SVGViewBox operator*(const float m) const {
return SVGViewBox(x * m, y * m, width * m, height * m);
}
static nsresult FromString(const nsAString& aStr, SVGViewBox* aViewBox);
};

Просмотреть файл

@ -178,7 +178,8 @@ gfx::Matrix SVGMarkerElement::GetMarkerTransform(float aStrokeWidth,
SVGViewBox SVGMarkerElement::GetViewBox() {
if (mViewBox.HasRect()) {
return mViewBox.GetAnimValue();
float zoom = UserSpaceMetrics::GetZoom(this);
return mViewBox.GetAnimValue() * zoom;
}
return SVGViewBox(
0, 0, mLengthAttributes[MARKERWIDTH].GetAnimValueWithZoom(mCoordCtx),

Просмотреть файл

@ -183,19 +183,18 @@ gfx::Matrix SVGViewportElement::GetViewBoxTransform() const {
// SVGViewportElement
float SVGViewportElement::GetLength(uint8_t aCtxType) const {
const SVGViewBox* viewbox = GetViewBoxInternal().HasRect()
? &GetViewBoxInternal().GetAnimValue()
: nullptr;
const auto& animatedViewBox = GetViewBoxInternal();
float h = 0.0f, w = 0.0f;
bool shouldComputeWidth =
(aCtxType == SVGContentUtils::X || aCtxType == SVGContentUtils::XY),
shouldComputeHeight =
(aCtxType == SVGContentUtils::Y || aCtxType == SVGContentUtils::XY);
if (viewbox) {
w = viewbox->width;
h = viewbox->height;
if (animatedViewBox.HasRect()) {
float zoom = UserSpaceMetrics::GetZoom(this);
const auto& viewbox = animatedViewBox.GetAnimValue() * zoom;
w = viewbox.width;
h = viewbox.height;
} else if (IsInner()) {
// Resolving length for inner <svg> is exactly the same as other
// ordinary element. We shouldn't use the SVGViewportElement overload
@ -317,8 +316,10 @@ bool SVGViewportElement::ShouldSynthesizeViewBox() const {
SVGViewBox SVGViewportElement::GetViewBoxWithSynthesis(
float aViewportWidth, float aViewportHeight) const {
if (GetViewBoxInternal().HasRect()) {
return GetViewBoxInternal().GetAnimValue();
const auto& animatedViewBox = GetViewBoxInternal();
if (animatedViewBox.HasRect()) {
float zoom = UserSpaceMetrics::GetZoom(this);
return animatedViewBox.GetAnimValue() * zoom;
}
if (ShouldSynthesizeViewBox()) {

Просмотреть файл

@ -222,8 +222,10 @@ AspectRatio SVGOuterSVGFrame::GetIntrinsicRatio() const {
// 2. width and height are non-negative numbers.
// Otherwise, we use the viewbox rect.
// https://github.com/w3c/csswg-drafts/issues/6286
const float w = width.GetAnimValue(content);
const float h = height.GetAnimValue(content);
// Note width/height may have different units and therefore be
// affected by zoom in different ways.
const float w = width.GetAnimValueWithZoom(content);
const float h = height.GetAnimValueWithZoom(content);
if (w > 0.0f && h > 0.0f) {
return AspectRatio::FromSize(w, h);
}
@ -231,7 +233,8 @@ AspectRatio SVGOuterSVGFrame::GetIntrinsicRatio() const {
const auto& viewBox = content->GetViewBoxInternal();
if (viewBox.HasRect()) {
const auto& anim = viewBox.GetAnimValue();
float zoom = Style()->EffectiveZoom().ToFloat();
const auto& anim = viewBox.GetAnimValue() * zoom;
return AspectRatio::FromSize(anim.width, anim.height);
}

Просмотреть файл

@ -633,7 +633,8 @@ gfxMatrix SVGPatternFrame::ConstructCTM(const SVGAnimatedViewBox& aViewBox,
if (!aViewBox.IsExplicitlySet()) {
return gfxMatrix(scaleX, 0.0, 0.0, scaleY, 0.0, 0.0);
}
const SVGViewBox& viewBox = aViewBox.GetAnimValue();
const SVGViewBox& viewBox =
aViewBox.GetAnimValue() * Style()->EffectiveZoom().ToFloat();
if (viewBox.height <= 0.0f || viewBox.width <= 0.0f) {
return gfxMatrix(0.0, 0.0, 0.0, 0.0, 0.0, 0.0); // singular

Просмотреть файл

@ -0,0 +1,7 @@
<!doctype html>
<div class="container">
<svg width="46" height="46" viewBox="0 0 23 23" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="11.5" cy="11.5" r="11.5" fill="yellow"></circle>
<path d="M17.351 14.579c-.855-.064-1.645-.28-3.188-.99a.58.58 0 00-.741.23l-.683 1.148a.43.43 0 01-.607.14 16.749 16.749 0 01-2.316-1.923 16.748 16.748 0 01-1.923-2.316.43.43 0 01.14-.607l1.148-.683a.58.58 0 00.23-.741c-.71-1.544-.926-2.334-.99-3.188a.657.657 0 00-.71-.647h-.835c-.46 0-.895.215-1.174.583-.783 1.033-.803 2.196-.577 3.39A11.13 11.13 0 008.21 14.79a11.13 11.13 0 005.813 3.086c1.195.226 2.358.206 3.391-.577.368-.279.583-.713.583-1.174v-.835a.657.657 0 00-.647-.71z" fill="#2F9FBC"></path>
</svg>
</div>

Просмотреть файл

@ -0,0 +1,10 @@
<!doctype html>
<meta charset="utf-8">
<link rel="help" href="https://drafts.csswg.org/css-viewport/#zoom-property">
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1905023">
<link rel="match" href="svg-viewBox-ref.html">
<svg width="23" height="23" style="zoom: 2" viewBox="0 0 23 23" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="11.5" cy="11.5" r="11.5" fill="yellow"></circle>
<path d="M17.351 14.579c-.855-.064-1.645-.28-3.188-.99a.58.58 0 00-.741.23l-.683 1.148a.43.43 0 01-.607.14 16.749 16.749 0 01-2.316-1.923 16.748 16.748 0 01-1.923-2.316.43.43 0 01.14-.607l1.148-.683a.58.58 0 00.23-.741c-.71-1.544-.926-2.334-.99-3.188a.657.657 0 00-.71-.647h-.835c-.46 0-.895.215-1.174.583-.783 1.033-.803 2.196-.577 3.39A11.13 11.13 0 008.21 14.79a11.13 11.13 0 005.813 3.086c1.195.226 2.358.206 3.391-.577.368-.279.583-.713.583-1.174v-.835a.657.657 0 00-.647-.71z" fill="#2F9FBC">
</path>
</svg>