From 93f9ed72d2ba6c36b52322b85b90e892b58221f9 Mon Sep 17 00:00:00 2001 From: Gingeh <39150378+Gingeh@users.noreply.github.com> Date: Wed, 8 Jan 2025 14:44:00 +1100 Subject: [PATCH] LibWeb/SVG: Skip unwanted transformations on clip-path --- Libraries/LibWeb/Painting/SVGMaskable.cpp | 10 ++++++++- Libraries/LibWeb/SVG/SVGGraphicsElement.h | 10 ++++----- .../expected/svg-clip-path-transform-ref.html | 10 +++++++++ .../images/svg-clip-path-transform-ref.png | Bin 0 -> 5155 bytes .../input/svg-clip-path-transform.html | 20 ++++++++++++++++++ 5 files changed, 44 insertions(+), 6 deletions(-) create mode 100644 Tests/LibWeb/Screenshot/expected/svg-clip-path-transform-ref.html create mode 100644 Tests/LibWeb/Screenshot/images/svg-clip-path-transform-ref.png create mode 100644 Tests/LibWeb/Screenshot/input/svg-clip-path-transform.html diff --git a/Libraries/LibWeb/Painting/SVGMaskable.cpp b/Libraries/LibWeb/Painting/SVGMaskable.cpp index e841d31c938..5cb1a2f5aa2 100644 --- a/Libraries/LibWeb/Painting/SVGMaskable.cpp +++ b/Libraries/LibWeb/Painting/SVGMaskable.cpp @@ -87,7 +87,15 @@ RefPtr SVGMaskable::calculate_mask_of_svg(PaintContext& co DisplayListRecorder display_list_recorder(*display_list); display_list_recorder.translate(-mask_rect.location().to_type()); auto paint_context = context.clone(display_list_recorder); - paint_context.set_svg_transform(graphics_element.get_transform()); + auto const& mask_element = as(*paintable.dom_node()); + // FIXME: Nested transformations are incorrect when clipPathUnits="objectBoundingBox". + paint_context.set_svg_transform( + // Transform the mask's content into the target's space. + graphics_element.get_transform() + // Undo any transformations already applied to the mask's parents. + .multiply(mask_element.get_transform().inverse().value()) + // Re-apply the mask's own transformation since that is still needed. + .multiply(mask_element.element_transform())); paint_context.set_draw_svg_geometry_for_clip_path(is(paintable)); StackingContext::paint_svg(paint_context, paintable, PaintPhase::Foreground); auto painting_surface = Gfx::PaintingSurface::wrap_bitmap(*mask_bitmap); diff --git a/Libraries/LibWeb/SVG/SVGGraphicsElement.h b/Libraries/LibWeb/SVG/SVGGraphicsElement.h index f54084335a9..d4fb41cc8d7 100644 --- a/Libraries/LibWeb/SVG/SVGGraphicsElement.h +++ b/Libraries/LibWeb/SVG/SVGGraphicsElement.h @@ -67,16 +67,16 @@ public: GC::Ptr get_screen_ctm(); -protected: - SVGGraphicsElement(DOM::Document&, DOM::QualifiedName); - - virtual void initialize(JS::Realm&) override; - virtual Gfx::AffineTransform element_transform() const { return m_transform; } +protected: + SVGGraphicsElement(DOM::Document&, DOM::QualifiedName); + + virtual void initialize(JS::Realm&) override; + Optional svg_paint_computed_value_to_gfx_paint_style(SVGPaintContext const& paint_context, Optional const& paint_value) const; Gfx::AffineTransform m_transform = {}; diff --git a/Tests/LibWeb/Screenshot/expected/svg-clip-path-transform-ref.html b/Tests/LibWeb/Screenshot/expected/svg-clip-path-transform-ref.html new file mode 100644 index 00000000000..7e1088f46ae --- /dev/null +++ b/Tests/LibWeb/Screenshot/expected/svg-clip-path-transform-ref.html @@ -0,0 +1,10 @@ + + diff --git a/Tests/LibWeb/Screenshot/images/svg-clip-path-transform-ref.png b/Tests/LibWeb/Screenshot/images/svg-clip-path-transform-ref.png new file mode 100644 index 0000000000000000000000000000000000000000..408c5b758100274751fb54182a4d041485fcbbde GIT binary patch literal 5155 zcmeAS@N?(olHy`uVBq!ia0y~yU{+vYV2a>iV_;yIRn}C%z##m})5S5QV$R#UXY=Mf zuRZqA{;Ok$*MfoJ z!6V7nPuyBouMX|*uK!h4w(Zs3^7}P+_Wiy4URN(HcCXb3dwvFnKdCz|o%D~4t^NFZ z?b^x5)926qcWbu!etW-rebbK~UG?#!-!mo#hFl(XhjYp4&!2p3x1aOxjPftA6?Ux1b z-mTvM`@4UA-uiMO<^8`xujbbo|H)-wFj%zfr^uS#UcWjY+V!>GBCts z+-322r5ka$?04B~RtAQGg`5-eg%ubW3__Tm+)hi2(q~|3;9fhK;ph9q?q83({@A}; zSb%{+VwImA>ud4L&HKT3x~KhHgA%Sul#m=wOmiQ?F`$$JA>Po z&tFyZcdvB(@l!`ytQRpe9GJi>qhPH)pMT$?iL(mrwopYx_fg zW`>4|W(5sz^46DbTs%`eeAT`gE339W|H90`(3bn4|6y$O|3%%hXLV!k4u^hbU^w8w z#y8=(b$r>z#XEOjk7?jzU^r}6(6B~6r*z}uovka&qx?a^l>dOCvf#(`THX`a^UmvT zoyWkyAb#%v<0t#++jrl%cxP?v?zQR+32FTM$n->$8)y7+WTnc90Da3Co!e9vGRQ+MTQ-?DW&`|d-WwU7D9%}+;na6V+; zJ$;p$dh~e)hK7k3${TEAf9}~W%KP{2y{*@T85j~$zQ`(6Tl??2bMegF@L;e@PQ0*o zxOPqdSoDT}zb@6h=441h%`*+>Dc;>40`|S{Q>lrFH{@L(a*7uIZ3aQyMb8VR!7~I_I z88?+0zH8dIrG6$H{DroPzo8Gfctv5zqo;er^%s)N=qyY}ko*Qr%?wL9ne>0iJ0#_R2! z8}Gh|OB^|$wGVE|wVWx&)U5y&{%l()!o}7 zg@e@(2JPKy^{O^hfBpI^|GqxGwR2<8?9ctLejahO7e4=Fy;>gs+jM3IhWl5;8*HlX ze1GfwDz*3etBXl%<#fZ|&j0u4-i^AuyLQE07LL9;`_`Jydug%nY*#+M7bW{O?6qtD z&a&mA4BDyu=@D@tB*!W9-BAAdU_ZA>KRD}FUCjT`|3A)NpKThR zy)__vYk>c&x%vP8eS7S=H+Z&b_;J%~FZD01-@m(T|0*#^9w_?P|1dVT_VMYRx7O^u zwWj~|=HU2WtMukuhF!}_TycHYpR;FfU8pl-VEFKtjc>x|9Wm>(Hin)1^KEVOtQG5D z-IeE=vVDJffN=V~Pm^2s*46VeFf8zY&OhO8@Vj@{7j{~$SXvd~{q=*-`THwpr*}== z8nvQz=VHb6>^J* z90LP`vOA&_f(fk8^*EW^wh1x!o~47@#Q z4HkbH7#h^Tm2L4p2F`n|wJY}g!dGgwD28IJCq}B=xESG0sxNs$d zwS)TtBg2A~7r7uBr+}LpZm%Ks_{LgZ-dy+d^s1LHS8d&DE?-^kJn#C(pFgj0GcY79 z>6Mk2m;e6v)pULTd-J}Q&9JHb^!I*tt?}Xe|F*rlzCUj_BLjomjhlWBbtisQT)lMZ z1K&>#T{NsRa$RXQ31qaiRF0;3@?8UmvsFd71*Au#+y;2(ebmj$y8 U&(uC;U|?YIboFyt=akR{0Pxb`?f?J) literal 0 HcmV?d00001 diff --git a/Tests/LibWeb/Screenshot/input/svg-clip-path-transform.html b/Tests/LibWeb/Screenshot/input/svg-clip-path-transform.html new file mode 100644 index 00000000000..20837356ffb --- /dev/null +++ b/Tests/LibWeb/Screenshot/input/svg-clip-path-transform.html @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + +