zegJ{F&LUqJ144*oC0y5uXWW@!=;n`v&3z?d0C=fC-cN^d^UIS-m
zVSam2kZ3zgE^xDm3?zT2L#8evx68pF&&SNn*A0RaIqpY;td`l)sm
zwO`KxE<=4_F98&6=_d?I0|cdWRVa2{Imuw>
zs)XS4x#<%_7E#dgVuyZVZaLo{9mT%Lz~$-;)h*vM3=#+6u);%R;o+7t;bzs9&u}w}tVK0^eP?BdaqY-xl7*nsz;ByK)-jy>+Kdon**j
zN}LNA$X=w7=)*@HKFEs{)rpRdmVUH~$TUi?i5GKlU!7808ZHSdR|1@F&o|9eb>g^`
zQWK$qvq;U|zbqott45guVGpz{ZhJZwc&lb`^ip_4L`o(eck3!#_2&a%q79(xIc}GO
zvnNSg_o11hh$Zr{6?2&(!ceI}ru*+E{+H%9P3V}bl8L5_(RF1|(D16NFp
zB)6Hex;2Y;*UN4USV}*bc;@`$a|)SwkQt5Wxd%;+joNBzA%KSFz2uY-;e#NR&<*Cn
zN}uxh`1qdQ-umR0_Z^Yv!y3|vM3|VqND7W^pVfKrpztr$<~^#)c>bILZ$hcM2$lnc
zdoG}Arb0qO_AV~{Q&WicKG_&Sqf}6=0BYZ#Zi)se1$E!_4g$0kfVY~zzdzG+_T|L!
z&0U=j{ro(g=!;L}<)6r#j}`#MxP~|(KT+g5eQR&0zp4)wZI?|0_z!Zo)7&Pe{J4zg
zau3jO!7
zD5Q-WI$0o
zHM+sh+ADK&+CY7O`v!kQ?75eL(#cV;1)-E}Y%;`MMsr)=N-P*u?L;sCC>3Q>2JIcE
zPyt(z!I!UG(Xq3;neM>Fe*e9rD0~G5{2NYtNzd>~sxN)6t$q)t;%TbkK_8J#qmsjY}1ufHnt~H*6Iq3mbTJ^!3?$=^^=eCGVhr
ziPRZh-jeBl4klWm!cN)S-4X;ke}zLeH_zDGhR4;&jcjdw1_W%v7a2;M==JmdGiu1M
zv~`gis{-0h*#!k9q=m>iT2f!1{_`O#k#p`lR1nbc+2QT1QSV&DU~}%lkUyA$ijDX*
zI-&ns7vsGKW@1xo+L)dbBr8l}Vxn;c&coP#n1G{%PKR-XQ-1_v9l+-kh(z5oK3d@o
zSXb&N3ea!ir}kF>tp!@jo)gGWRYdCMs5b`mTFA=p*BFIACB)~4xD4O{pr@juA_E+7
zgNdFXU>+C~!|nr+JTg5c<*bLNr|3lpqEt=IxGG?7M?nx6n+5SpV>~6?Vl)dutnw4c
zHDQnSWifd)MHf)K?%-RM7!xo~XP7+hoXy?L_8}i_OmB$>(Hn5L(V?5S&0;9YIkf
z#D8c~erF=|Y7gAib=;tW3ZmzWQ<3Dt6Z=`48z_iJv`~PVlb0T$idc@P12ZCnwwFgA
z*s}DTNXP{T6LjwG>W&Da3fz7%?0cVPb@v;VZl8G8>T+6tSj^GTLzYU
z&krrh>aSB%K$P_R4Z+qFhwIHz|2QmFd=%`gu7BN9XL
z{-Yl*6>rX_?D_9L3ai4BtBOVEa!w_j8B&lcxAfvoQ
zpz0Y78LAIHyAON&`bO$XEVx&?UFoP!9%Mi7ElC%Sv4iF
z8zdw7yY66Ny5G18S%-s363!^Y<|}Tf&{CzVK#n6!0WF2eE=z0xED)q1Dmo#73urt-
zb~b!VIJUVE6W=_2M^7&roZ{C}QHpGD33yP1K|eHU-J!j`om^8%&z`+2`!@xtS#^M_
z%FfAgn@ThW*jH924cL8l|1;9-?4uLPXm-++N!BvRiWm#~{Os^k`tD3&-Ox^Vv!p{$sd~@#KjE*`jlGo)A#NZc|NCpR(k67jbWFCD9rWoBQ+zDeRf5dH(&aV)+g+b|>p}!qdrt6JL_5#^$)yGnSbFn-8|CnJNe?qQIVtVEkqf#&
znZJKOsO5Eg{Mcl+EfMY>EV8u)S$+bMm703Pw7>vJ(@#6TX@?a_@cbcCG`jbTUAva9
zeeve`px0}4IML*eIjcU#&
zczgHhfDR03n}I~~J9f_f-Qt5s?08%nz`u%p8LPB8cG*XsiludXVeN
zV$Cs8K7GSe0D-*wb2a|zdoj^?ZZg`eBkK9pItWDhw(Z&QTDJutp?!BI|aW?45lAB_HZ1wCZ
z0yunseHd={Gn{wk@Z3mP<7)k+FfwNo*mGjS;$2h`_@2)%Zs@T}%!Ta#gkRjQ6azKo
zVIc8nhekW2o)hfN3<9=fXv=NwQ-6OWB|I=F=;&Soh@?swPc$M?4j%2u?+1?zKz|8@
zCQXFf5EBU=o&>(Zv_0Q|sZ%~tRL47_sjySmD*k^JO8c)yHFd~56BJ6ugFzuim^Q#O
zs>>W@sIXQmEMX0zwk&i>?U@r36Q8}sS_1weg6MO6f*$C0fW~?8$B%R1*_K^755NsS
zkHLqub%dgcJ>M$OIhu9igAM-nxVHCvb?(WK@j*EhpWrc3cO+5v(Vf5Pc&Uo{FXp(j
z%b=4QL#qu;^^josuZOo8KMybm!f1fM|4l-pBlzrO2u=hYQ}vYM0ETjMqS|Lg7o|b3iby0LFI#IJvLS}xp6b0@of14;8)7LnbHA>ZP`m-8nqpx@
zrtlN;q|BXBMOul{?<^Z$WqtlU@T(zs13_N<}fZ{LT*y?=z_k6UpuO@c**O=du
z(as!Nf7M@OuFb|~%%&?ux{0RPnV-rftLUYrC3`!&PSERaxGn$=Afg}iGJymZDi)VB
z?L1l!l$)*~d4T9mOdEL0ZD3#!yTAMMK;$B1j^zMs^($x;K#*#HMqpH-3pbTKL=n~L
l!WG48bDHPxlTpZR7v}rpN=kyB1(R=8Q_{Mbf5ZIg{{d!~wb=jw
delta 8257
zcmYjW1zZ%}*PcZhiB}X91Xe|mUbF=(-zTf}%TV{vZnS0MY_c`Z0&za3xM8Xe5^!ICmNNxcU6rTtm3PM1LH|M|+`uzvK
zphW{&&6pD;+)wph^XlsTformEAHzb0hFCAA%Vb^BcSBX~kR+EfvT#QF+c!2wwd4eZ
zl@yQ__#=NIrdNMtEMC8P%EeL|y!qo3!^XP!`UFBIx1EnS8sZ!0;mOWO>?jQNEhIF<
zmByubnWUE%m%%62iV^qmsSVp^-*AB=5oM-44a^sqVcqefV8LK(fqan#-)Ta&4%SWK
z&1cfoj8A5(rnhJpVw-S!!Y_|>iamO!%f4IG*OcdA)7;<8t<}$B^0hM0d15+Gi#E?i
z_4M;YX%oG9kuJ52qTri~6zOlC66X|Ae9&TUx&3@Ej{elFl`H1nH66V0t0Y;{0js|n
z&whARSUrO6`jm;8pZ*AQgu@ZO)l${AW0S4r;}VGDo`#nbyBPh3RpzCx0xD4){EDYx
zD+QUWhy+oooor6pk2el%iCeD!d?G*jg5bH+({IUR2G$H8$fe?|?oL7kK@E>XK4Qct
z#wW+d>a9giP9UWP=L7@O#T^JDb+^^jb=6f?5-~4H#*x5bV`k(L77()HM+tF&fvq_BxGgO?gv^C`I4p&EEm0OIAwg~-?zm7qV-gfU
zpAd?dSBQt3KW-b(fml%UFJ|Iw@frX3-vsID1P%eIRcgcd9Eatz=;s|rde1}961G&kQNX3R-UJ(Wr-jKjT8<;QHjR=
z9Rxh%M;N(arqC*T@iIB3t&9N%&dMyk;L$sIKgX~0XKK>M)PZ6!6^D;!4?z;f
zM{=Xbz}eNRu%
z$if)9*EQQ4xPH`aJv};>mhV~F*mf6tZ|v^vEw2>T4|Syo@}p3uVTF%IK3c|!YuaN9
zEUzLE&BHBa);;uVBP9w^^y2D#G=t;S9?Wnpd{$@ar7&G6l@K4_KC}6CW;3g_^u+`C
zG6hfHRjE9mix1r01xQ~&7d}3ml5w1<(Mu705YH&?wWDYPpX^#74^EFZh^`|2I`>FR
z&6@BXhl|X%e9g_xL*?Ir56$Jv-%gJ9-Of%=!uMm?jjA-msJVuwTf)j5Mn1MRG^&L>
z)_(M;n2KE&wKDcOkVH#e{q5(^GQElgw<+xMj_EYC@pu(|Z?_0S%`hZtLkI-9U$JzBNzBR9Xk1zP1H8(et
zlRQao{WVgNG$A=o12!m4tO8y>IMJAF9S`l)t#;41JV!|S5(?K=SLc}_QoC{Eh9uEV
zSy|b*61&V(!`FvL+1vK7Pph1
zLlet*>C&a_H*chX=bhn7!~Rp6GhZ{a^mtCAoat%w*ueT)#iYROjD@A;W-4I|ntO;+
zsp9qO&Nf*H?bWNAE-obnCiUH3JW_l#FBv_>=oK)HSqrL>BuMR@oh1$5qqT}EkB!%F
zdlzR5o0^*Lz@6#o>1`+;9TF<`Xn_0Hncnu7Y;&8BOMMQUEn#aHUSbF;5wo^=@Bq^i
zM!oxM)0`L`eg78YozZ$&vIXfk+_Sit1%^}gmxtkcCMG7HCyrp?sz)==oxXqCoC%0d
z$(`#+kfc^3CMMQRhoB5K6O**$FApYp)<Pf5M$uxce#S#K
zG&J-U8KSwS?qtuv&DAw4H}_sZKtLq?OU5mM80mZ|0S3dY9ImY
z$So_=T3cK5I^1EwyHoslqqSrsHz((<5D2KHrKR5Y_Yz!JhB)Z6ubd|%Ti%-MsPZ}Z
z2tw=~NG|qG&q*)hLw>fd9v-=sl}Xfm{Wi;cx!D^x{3xW9Zcv3~0}~RsOonQ`_a8sI
z@NH}?cVfcWv(~tFtDOx7S!?*3qe;ylIWB8$H$|x;V&^YxY6O2Ak|46%u*Uv
zyGJNAOZD1l!Y3;xWw!lHYm@aRH*em&hzI?++`03$X6aB8&OE&W{2%KMQrRKMHu-Ei
z1&L_IH%7h(a|z2}{B`dGQ4u`SA%u_lXLImR+K(Oo7XS~R|j_9XP
zVMMBgufC}J>V4E@O(!Q#IRvCj52l$L8DZcxW5VA5X~m38HBDj=VEj_ZZP%SeHI+9I
zq)P?vvMry8S~}%a*b=$tUL~PsZT;bNE1{l3Ldn9^R0=-bP8;m)mF9+^`2O+n{QU`U
zRYyn1XXJ579ecSJr<|+T<~(32baA4@$&Lo7J0W%{-{P26UDv-0lb%0svoTTINs53H
zvF12tjxcZ?9<6>w`dvo*_!yoYFGwzw5>O<$E%n_5H)mB!bBEE-w=kPdw$dyQ1@nAGcq@W~j
zpI74E+T!BknwYmB5MB3H^<)Skq&aqJXU8tJVC9F$+dWrq+5EF@d+WoMapChDh=bWU
z)qz2HP|lL0005MPn$tp(2|}(VE}1EB*M>DJQ7oW#$P_(1DkP3pd2{S2(|q@mK;~1q
z20^ym5)uXR@l>^Er$^7oNqF8y1sGG{D9YgD<6|dhwc}mrPVEmMAisqRA>V@$edQg}
z(X>beTH2kb6jH`n@81VDx{;v-1mH}t3}OVN2(Z1%
z@)vX#+9xL`htpwPS#M>1He0BV8z6`=Jc)iUK9oblq3OC`=OW1A$2X>n7?3;u5Okq;
zaVNh-}n4=})G9SMFy;4?szF}oICo@ytsUiiPDDLO#
z=B6ed6ngtQD5VW9_yh!l-@kXl#Z_14-K({9bUq9XX_u9kt4HhM21w%tNE4d{LOdcO
zIo|v0;IS&-qjHcy!G22hk@Jd=j*Yo(PRm6O@{h!=M9>N@cP8-yih{uNWXc#E82Gxf
ztA0KgHyUuLKA&|{KslDz*4~2(zPr1dot+(`aY4Bq*p{9y4P${)W{#W>K~}VES}4x0OY0R
zpHofxMWzV6Viq>>qzY%7>wb(jfcySysFI$ZUQS+~rn&h$P*YyMd?}~qaBJet`u>r!
zcf^x=6H-#rSI%=UppWir`v3Z<9FGL1S_H$2cy48YSyZI4PZ%2+aU^tDCa*YG8s-!f
zXgfM`d@vMd@%!Z?VZ8aUC@+saU$5l33iem2F0tU9cHuhghNS$m)bYir9(JAfh`W-o1Z
zE|?KZEyRPSiwPhlYd}A}W+DW4zR*6f0p}N+ncnsSB6JHA&`A*8-hS88+FC>U14rVj
zgO;|oIw8~$4j9M4@NibDsK=IJBfd;J1qRmzH(D-?>QTzzQvt`(=3ITqj~eYB?E9?A
ztbk~q5DCYY`X0HnE~3QdA-~%w(dN%TOoys@6=fm4
za)%`MwNbg7j!u{YBPB@!=(7I^d~L`yP=dru8jLcns$#2D&LzVHHT+~oc9L<6vpGCM
z)5Zs!Q*?4Fh-8o~@b||7xfOuyuMk((RUVIhKoXLS4B1Ei!SJfE^Rv)V
zB{w&IgF*;mX5jz^sLOu$;rx5UL7q98=Hn;zfv>zU{6;nUFf*EV~M(qLVqI_BQNjXKp7L-Gj+Dsl!O!{(@jKs8FFixrl4vi%QL`CHrDFJX}4
zMo0BQ{^^)=PTEQ~YlL|CpE(Q{Jtd};05p%LM7FQv>j;B!p$^C$Ak2GC^pF(yLDbY3
z7hX#XOG4sCw^2B+4s$zB)}^uc+#MKzi>_H)zI
zuVp)G0kc8eZQI?q22^HNcm-34F?dkhQtZX_5d=@|?htICU;jkB1@IZN64~&Vt8~w-
zX}jVqZwH8YNE0G^^lBa#tGp6Q*D>*ZnJ;nWMO@rFz#^BMLn!rY9&_UXvP1NLvK&6UNuA*bmDE1A!kW*yau8&2;$!ZvxD_ib
z*A8b*L@Y6my>XglF)mVrLfAMs22&o?W#{CucJHYKfMBmZ-s
zwG0iFu+LMc(QWnJ;{s*i4k)tlMN6uX@BBZHPDGq%74@TJA_cS3L_JhMgm_O)Moo6H
zu(D1!^0R2HHnMPX4ox)$X_=UCrS-JFLr3qfU~=o~jDyG-n0x>a4jQ@U!kbV>^p2)0
z?xjtDNG)(q0pu%ZM^6VfAE8gg0a6xL$&dXDR0rmWr%x`}Sq>tX|
z64`Qxk+-0n0)?dU!n($$BNnrwrL3%c*Gv4uB|_ZU?E}~O&MV`UF4jYZz(=732@sEm
zM4Br2Ou}ciqobn(pu_`RMW3%XJ2#j8@uRwymX`iU3nH*rrlG%9qu1A+_yq;+A3ltJ
zyVz2~3;Q>k>Vv`m*^st%bkwr9U&%8`Xq}moX7XdSYKy&jI9T}PJ=lFMIyySyK$-K2
zN%LAEj$`FmPJm?*0HmF7!8%rk@-^)3b3t9+1tL@dW1d;f0HDs#&wqz5FomT3RnbQn(l)59o4wcX#)*sIZc-w{Nclkp!a3
z=w1S+<)w2_v>z}ZOpV<+z+WTtTU=`|B-!w(4mpr6Pd!Y8WFYS6e*|uw@6iB|IUr3a
zGNO+RvOzOMTTU*Jm6a7+Gprs%5K47(9OjB9SrA9B&Fj4E-!8o2Nrb#|DC6S7oc2={+X(3>fOrEy|D+hTaRAVz3$8atRJALK_)#Kl+8fD
zd@-M2_q)2f@*KgS5O>N$p}dDeO4m$ji*=Q-g753sV9?2XE#@hs2Bt+cpZ`-f`S|!U
z6d7ftO-W!NwGNka3mNZ#Itqkj`Ymij2aT^$@u5fy&;8-Xgt*bChh|^g$gmT%MO$xp
zHE%qJw0CFQC{x9~_bNGbfS~y^eOu|$p~NEI)0f~0>HYQb6oJH|a$qrnu_<#b{u?3%r3FeeuqoCe}*!d66|(ET*jM-|1rx90bjBiFr6;
zY#09ZXwkt$izyQ!4@)F^ZQSLJ9gZbCQ{`u|0
z^7DX~kq(uWl>s`|M60BGK78X4sS;xo6fP!dXaef%%18p;ujoD_svb#)Ulg~#5t
z#(-e6Q4kh+(J_I0C>sUXA;@$Ex-ML@|J3;MLVGhX0)_SLu!Nt`(jDQ5`R@2O+Xa_P
za2gh7rbp2Ak!tBwc^3<;yN93SfkH_s#dyRI)C(EQ_Fs(t$bv3d2Vv#WwIpkB<0lgE
z@KtIlM*DrGZ#HCYhX3986+*W#Z}TOavz91}rUA48j4BXNw9#PojX5i?il{2?SP=xl
z4Gzw!KjpsA4v79I*E9?hI_CPGo+DV?ZD1?`ci#44QdCp>haBXF$13GW3K%ha9d}ct{K@{kvei-iN1eVLx|*=e1$X5gzP5%4>?HQI##%YttC2-ckNXf
zDK^@OP&0L|d+oBZpwP|k9|3t}nY$tQ+xk}gXi%sCU+Xu*eESxCJ%*62cS<{7|2^2A
zlXZ{!{&L4LK)lQk3PZ49ZRkZbcaBL9=lFjDZ!8vfF(w#>)1L%bMZ=j8wgK{w6jV%8
z0#90^R>rSbsDMT&;G`cUPdB5y*2*wgg56elLjt>J4QhyHVqdBqe^U|8gnL*fvH_oY
z(}}n$f|6S{u=_h?gn0aP&1eY?v`{IpUR|x->APp=;4n~Z-U`UbuTv0^@h|N6xxTS(
z6Ha56HXrN0OjOg>j&Fzmv~tHP9^~fdE5|4{4{Xcog5+V!IyQ+Y?#nH#Q4hbZyEMx_
zBmhAVm7t~7RlZ~M_!loSGFXHzVTg}PKDX)p#&0AcGDh(>p!Uz7C;^TB<%>MOfI$1k
zKJ8&~P*6}3k$*0R>*SV~YabjOfY`)}b`VOWzAZ`ltSEGT
z^5&muqaD6KbDCWxFT~^~C)0rU7z?ND6og+FwwFLVp~_{UyGByy4?=P&w=YNv=K?x4
zK0c1^_<+|VJnrI~Nl0uyd(~C$Ar+o1PH`R|2nj*QU%@Wb@Hm)J19h2iu6i@2{Q`beZrrTsQoC}k~jO4-6YXlzXz&{B1eTNf^!$1i&{BcCelB2P{)
zmbi^kS5s?bm4ioHRJ&QZxG+Gg3=R!t0*LFfTMh5C*waFg^~XWF=-cZwogaF|^g;x(
zm|X-3Q2MMY-Jw0dD+$HDlzWrU)PSV8TPmGuOpzEE!)(osg)B}mM~%&q7AxS`{1|*U
zmGk~1m))GHu!G_Rzpu5alVSzrh(7@zcAIBv$eZ{6@3*cU(AxTN|9yYh=YI+>Hg(Rs
z{Qb#Nxgt%B602YGrBiFSiu}RKnN?p8WNUo*6RNwPHw>`&0)h3)S~aZQ6|gv~-DGoX>Gm3`bfZDZ0*}4O_8{mS20Y8!TL;u%wv@F$i2cDH
zpZ1KNET~_kS8O~} 'calc(2px)'
border-top-width: 'calc(2px * var(--n))' -> 'calc(2px * 2)'
bottom: 'calc(2px)' -> 'calc(2px)'
bottom: 'calc(2px * var(--n))' -> 'calc(2px * 2)'
-clip-path: 'polygon(calc(0px) calc(2px), calc(2px) calc(0px), calc(2px) calc(2px))' -> 'polygon(calc(0px) calc(2px),calc(2px) calc(0px),calc(2px) calc(2px))'
-clip-path: 'polygon(calc(0px * var(--n)) calc(2px * var(--n)), calc(2px * var(--n)) calc(0px * var(--n)), calc(2px * var(--n)) calc(2px * var(--n)))' -> 'polygon(calc(0px * 2) calc(2px * 2),calc(2px * 2) calc(0px * 2),calc(2px * 2) calc(2px * 2))'
-clip-path: 'polygon(calc(0%) calc(2%), calc(2%) calc(0%), calc(2%) calc(2%))' -> 'polygon(calc(0%) calc(2%),calc(2%) calc(0%),calc(2%) calc(2%))'
-clip-path: 'polygon(calc(0% * var(--n)) calc(2% * var(--n)), calc(2% * var(--n)) calc(0% * var(--n)), calc(2% * var(--n)) calc(2% * var(--n)))' -> 'polygon(calc(0% * 2) calc(2% * 2),calc(2% * 2) calc(0% * 2),calc(2% * 2) calc(2% * 2))'
+clip-path: 'polygon(calc(0px) calc(2px), calc(2px) calc(0px), calc(2px) calc(2px))' -> 'polygon(nonzero, calc(0px) calc(2px), calc(2px) calc(0px), calc(2px) calc(2px))'
+clip-path: 'polygon(calc(0px * var(--n)) calc(2px * var(--n)), calc(2px * var(--n)) calc(0px * var(--n)), calc(2px * var(--n)) calc(2px * var(--n)))' -> 'polygon(nonzero, calc(0px * 2) calc(2px * 2), calc(2px * 2) calc(0px * 2), calc(2px * 2) calc(2px * 2))'
+clip-path: 'polygon(calc(0%) calc(2%), calc(2%) calc(0%), calc(2%) calc(2%))' -> 'polygon(nonzero, calc(0%) calc(2%), calc(2%) calc(0%), calc(2%) calc(2%))'
+clip-path: 'polygon(calc(0% * var(--n)) calc(2% * var(--n)), calc(2% * var(--n)) calc(0% * var(--n)), calc(2% * var(--n)) calc(2% * var(--n)))' -> 'polygon(nonzero, calc(0% * 2) calc(2% * 2), calc(2% * 2) calc(0% * 2), calc(2% * 2) calc(2% * 2))'
column-count: 'calc(2)' -> 'calc(2)'
column-count: 'calc(2 * var(--n))' -> '4'
column-gap: 'calc(2px)' -> 'calc(2px)'
diff --git a/Userland/Libraries/LibGfx/Path.h b/Userland/Libraries/LibGfx/Path.h
index c9fe6ee027b..4a1f21e5b66 100644
--- a/Userland/Libraries/LibGfx/Path.h
+++ b/Userland/Libraries/LibGfx/Path.h
@@ -39,6 +39,7 @@ public:
[[nodiscard]] virtual bool is_empty() const = 0;
virtual Gfx::FloatPoint last_point() const = 0;
virtual Gfx::FloatRect bounding_box() const = 0;
+ virtual void set_fill_type(Gfx::WindingRule winding_rule) = 0;
virtual bool contains(FloatPoint point, Gfx::WindingRule) const = 0;
virtual NonnullOwnPtr clone() const = 0;
@@ -86,6 +87,7 @@ public:
Gfx::FloatPoint last_point() const { return impl().last_point(); }
Gfx::FloatRect bounding_box() const { return impl().bounding_box(); }
bool contains(FloatPoint point, Gfx::WindingRule winding_rule) const { return impl().contains(point, winding_rule); }
+ void set_fill_type(Gfx::WindingRule winding_rule) { impl().set_fill_type(winding_rule); }
Gfx::Path clone() const { return Gfx::Path { impl().clone() }; }
Gfx::Path copy_transformed(Gfx::AffineTransform const& transform) const { return Gfx::Path { impl().copy_transformed(transform) }; }
diff --git a/Userland/Libraries/LibGfx/PathSkia.cpp b/Userland/Libraries/LibGfx/PathSkia.cpp
index 94db9cdce1b..9d17952202c 100644
--- a/Userland/Libraries/LibGfx/PathSkia.cpp
+++ b/Userland/Libraries/LibGfx/PathSkia.cpp
@@ -29,6 +29,12 @@ PathImplSkia::PathImplSkia()
{
}
+PathImplSkia::PathImplSkia(PathImplSkia const& other)
+ : m_last_move_to(other.m_last_move_to)
+ , m_path(adopt_own(*new SkPath(other.sk_path())))
+{
+}
+
PathImplSkia::~PathImplSkia() = default;
void PathImplSkia::clear()
@@ -217,21 +223,24 @@ bool PathImplSkia::contains(FloatPoint point, Gfx::WindingRule winding_rule) con
return temp_path.contains(point.x(), point.y());
}
+void PathImplSkia::set_fill_type(Gfx::WindingRule winding_rule)
+{
+ m_path->setFillType(to_skia_path_fill_type(winding_rule));
+}
+
NonnullOwnPtr PathImplSkia::clone() const
{
- auto new_path = PathImplSkia::create();
- new_path->sk_path().addPath(*m_path);
- return new_path;
+ return adopt_own(*new PathImplSkia(*this));
}
NonnullOwnPtr PathImplSkia::copy_transformed(Gfx::AffineTransform const& transform) const
{
- auto new_path = PathImplSkia::create();
+ auto new_path = adopt_own(*new PathImplSkia(*this));
auto matrix = SkMatrix::MakeAll(
transform.a(), transform.c(), transform.e(),
transform.b(), transform.d(), transform.f(),
0, 0, 1);
- new_path->sk_path().addPath(*m_path, matrix);
+ new_path->sk_path().transform(matrix);
return new_path;
}
diff --git a/Userland/Libraries/LibGfx/PathSkia.h b/Userland/Libraries/LibGfx/PathSkia.h
index 6039281eab2..e968948e474 100644
--- a/Userland/Libraries/LibGfx/PathSkia.h
+++ b/Userland/Libraries/LibGfx/PathSkia.h
@@ -36,6 +36,7 @@ public:
virtual Gfx::FloatPoint last_point() const override;
virtual Gfx::FloatRect bounding_box() const override;
virtual bool contains(FloatPoint point, Gfx::WindingRule) const override;
+ virtual void set_fill_type(Gfx::WindingRule winding_rule) override;
virtual NonnullOwnPtr clone() const override;
virtual NonnullOwnPtr copy_transformed(Gfx::AffineTransform const&) const override;
@@ -46,6 +47,7 @@ public:
private:
PathImplSkia();
+ PathImplSkia(PathImplSkia const& other);
Gfx::FloatPoint m_last_move_to;
NonnullOwnPtr m_path;
diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp
index 072497de9b0..b389d07e384 100644
--- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp
+++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp
@@ -1457,15 +1457,15 @@ RefPtr Parser::parse_basic_shape_value(TokenStream fill_rule;
+ Optional fill_rule;
auto first_argument = arguments[0];
TokenStream first_argument_tokens { first_argument };
first_argument_tokens.discard_whitespace();
if (first_argument_tokens.next_token().is_ident("nonzero"sv)) {
- fill_rule = FillRule::Nonzero;
+ fill_rule = Gfx::WindingRule::Nonzero;
} else if (first_argument_tokens.next_token().is_ident("evenodd"sv)) {
- fill_rule = FillRule::Evenodd;
+ fill_rule = Gfx::WindingRule::EvenOdd;
}
if (fill_rule.has_value()) {
@@ -1475,7 +1475,7 @@ RefPtr Parser::parse_basic_shape_value(TokenStream
+#include
#include
#include
#include
@@ -84,8 +85,7 @@ struct Polygon {
bool operator==(Polygon const&) const = default;
- // FIXME: Actually use the fill rule
- FillRule fill_rule;
+ Gfx::WindingRule fill_rule;
Vector points;
};