package Ġcom . cube . fusion . android . core . helper Ċ Ċ import Ġandroid . graphics . Color Ċ import Ġandroidx . annotation . Color Int Ċ import Ġandroidx . annotation . Px Ċ import Ġandroidx . core . graphics . blue Ċ import Ġandroidx . core . graphics . green Ċ import Ġandroidx . core . graphics . red Ċ import Ġcom . cube . fusion . android . core . utils . shadow . Shadow Basic Inset Ċ import Ġcom . cube . fusion . android . core . utils . shadow . Shadow Rect Spec Ċ import Ġkotlin . math . ceil Ċ import Ġkotlin . math . pow Ċ import Ġkotlin . math . round ToInt Ċ Ċ /** Ċ Ġ* ĠObject Ġcontaining Ġmethods Ġto Ġhelp Ġwith Ġthe Ġrendering Ġof Ġdrop Ġshadow s Ċ Ġ* Ċ Ġ* ĠCreated Ġby ĠJ R ĠMit che ll Ġon Ġ 1 0 / November / 2 0 2 1 . Ċ Ġ* ĠCopyright ĠÂ ® Ġ 3 Side d Cube . ĠAll Ġrights Ġreserved . Ċ Ġ*/ Ċ object ĠShadow Helper Ġ{ Ċ ĉ /** Ċĉ Ġ* ĠGenerates Ġa Ġlist Ġof Ġ[ Shadow Rect Spec ] Ġfor Ġa Ġview Ġbased Ġon Ġassumptions Ġ/ Ġapprox im ations Ċĉ Ġ* ĠDoes n 't Ġwork Ġas Ġwell Ġif Ġthe Ġshadow Ġis Ġlarger Ġthan Ġthe Ġavailable Ġspace Ġon Ġthe Ġscreen , Ġor Ġthe Ġblur Ġis Ġgreater Ġthan Ġthe Ġsize Ġof Ġthe Ġview Ċĉ Ġ* Ċĉ Ġ* Ġ@ param Ġcolour Ġthe Ġbase Ġcolour Ġof Ġthe Ġshadow Ġ- Ġnote Ġthat Ġthe Ġalpha Ġcomponent Ġis Ġignored Ċĉ Ġ* Ġ@ param Ġalpha Ġthe Ġalpha Ġof Ġthe Ġshadow Ċĉ Ġ* Ġ@ param Ġblur Ġthe Ġblur Ġradius Ġof Ġthe Ġshadow , Ġin ĠPx Ċĉ Ġ* Ġ@ param Ġcorner Radius Ġthe Ġcorner Ġradius Ġof Ġthe Ġshadow , Ġin ĠPx Ċĉ Ġ* Ġ@ param Ġinset Ġthe Ġbasic Ġinset Ġfor Ġthe Ġshadow Ċĉ Ġ*/ Ċ ĉ fun Ġgenerate Shadow V 3 (@ Color Int Ġcolour : ĠInt , Ġalpha : ĠDouble , Ġ@ Px Ġblur : ĠDouble , Ġ@ Px Ġcorner Radius : ĠFloat , Ġinset : ĠShadow Basic Inset ): ĠList < Shadow Rect Spec >? Ġ{ Ċĉ ĉ // Base ĠRGB Ġcomponents Ċĉ ĉ val Ġred Ġ= Ġcolour . red Ċĉ ĉ val Ġgreen Ġ= Ġcolour . green Ċĉ ĉ val Ġblue Ġ= Ġcolour . blue Ċĉ ĉ when Ġ{ Ċĉĉ ĉ alpha Ġ== Ġ 0 . 0 Ġ-> Ġ{ Ċĉĉĉ ĉ // No Ġshadow Ġneeded Ċĉĉĉ ĉ return Ġnull Ċĉĉ ĉ } Ċĉĉ ĉ blur Ġ== Ġ 0 . 0 Ġ-> Ġ{ Ċĉĉĉ ĉ // No Ġblur Ġneeded Ġ- Ġjust Ġa Ġsolid Ġrounded Ġrect Ġwith Ġgiven Ġinset Ċĉĉĉ ĉ return ĠlistOf ( Shadow Rect Spec ( Color . arg b (( alpha Ġ* Ġ 2 5 5 ). round ToInt (), Ġred , Ġgreen , Ġblue ), Ġcorner Radius , Ġinset . left , Ġinset . top , Ġinset . right , Ġinset . bottom )) Ċĉĉ ĉ } Ċĉĉ ĉ else Ġ-> Ġ{ Ċĉĉĉ ĉ val Ġer f 2 Ġ= Ġer f Approx ( 2 . 0 ) Ċĉĉĉ ĉ val Ġpixel Distance Ġ= Ġceil ( blur Ġ* Ġ 2 ). round ToInt () Ċĉĉĉ ĉ var Ġcurr Sum Alpha Ġ= Ġ 0 Ċĉĉĉ ĉ var Ġcurr Max Alpha Ġ= Ġ 0 Ċĉĉĉ ĉ val Ġpre multiplied Errors Ġ= Ġmutable ListOf ( 0 . 0 , Ġ 0 . 0 , Ġ 0 . 0 ) Ġ// Error Ġin Ġpre multiplied Ġvalues Ġfor ĠR , ĠG , ĠB Ċĉĉĉ ĉ return Ġ(- pixel Distance .. pixel Distance ). map Ġ{ Ċĉĉĉĉ ĉ if Ġ( curr Sum Alpha Ġ>= Ġ 2 5 5 ) Ġ{ Ċĉĉĉĉĉ ĉ return @ map Ġnull Ċĉĉĉĉ ĉ } Ċĉĉĉĉ ĉ /* Ċĉĉĉĉĉ Ġ* ĠBase Ġthe Ġblur Ġoff Ġan Ġapproximation Ġof Ġthe Ġerror Ġfunction Ċĉĉĉĉĉ Ġ* ĠThis Ġis Ġthe Ġintegral Ġof Ġthe ĠGaussian Ġblur Ġunder Ġthe Ġapproximation Ġthat Ġthe Ġshape Ġsides Ġare Ġinf initely Ġlong Ċĉĉĉĉĉ Ġ* ĠThis Ġapproximation Ġobviously Ġfalls Ġapart Ġnear / on Ġthe Ġrounded Ġcorners Ġof Ġthe Ġshape , Ġbut Ġit Ġworks Ġsufficient ly Ġwell Ġfor ĠV 1 Ċĉĉĉĉĉ Ġ*/ Ċĉĉĉĉ ĉ val Ġtarget Sum Alpha Ġ= Ġalpha Ġ* Ġ 0 . 5 Ġ* Ġ( 1 Ġ- Ġer f Approx (- it Ġ/ Ġblur ) Ġ/ Ġer f 2 ) Ċĉĉĉĉ ĉ /* Ċĉĉĉĉĉ Ġ* ĠBecause Ġthe Ġresulting Ġalpha Ġof Ġoverlay ing Ġalpha Ġa _ 2 Ġonto Ġalpha Ġa _ 1 Ġis Ġcalculated Ġas : Ċĉĉĉĉĉ Ġ* Ġ ĉ a _ o ( a _ 2 , Ġa _ 1 ) Ġ= Ġa _ 2 Ġ+ Ġa _ 1 ( 1 Ġ- Ġa _ 2 ) Ċĉĉĉĉĉ Ġ* Ġthis Ġcan Ġbe Ġre arrange d Ġto Ċĉĉĉĉĉ Ġ* Ġa _ 1 Ġ= Ġ( a _ o Ġ- Ġa _ 2 )/( 1 Ġ- Ġa _ 2 ) Ċĉĉĉĉĉ Ġ* ĠHere , Ġwe Ġaim Ġto Ġget Ġthe Ġtotal Ġcurrent Ġalpha Ġto Ġa _ o Ġby Ġoverlay ing Ġanother Ġlayer Ġof Ġalpha Ġa _ 1 Ċĉĉĉĉĉ Ġ*/ Ċĉĉĉĉ ĉ val Ġlayer Alpha Ġ= Ġ( target Sum Alpha Ġ- Ġ( curr Sum Alpha Ġ/ Ġ 2 5 5 . 0 )) Ġ/ Ġ( 1 Ġ- Ġ( curr Sum Alpha Ġ/ Ġ 2 5 5 . 0 )) Ċĉĉĉĉ ĉ val Ġlayer Alpha Co er ced Ġ= Ġlayer Alpha . coerce In ( 0 . 0 , Ġalpha ) ĊĊĉĉĉĉ ĉ // Since Ġthe Ġunderlying Ġgraphics Ġcalculations Ġwill Ġbe Ġdone Ġwith Ġints , Ġwe Ġround Ġto Ġints Ġand Ġdiscard Ġany Ġzero - alpha Ġlayers Ġfor Ġbetter Ġsmoothing Ċĉĉĉĉ ĉ val Ġlayer Alpha Int Ġ= Ġ( layer Alpha Co er ced Ġ* Ġ 2 5 5 ). round ToInt () Ċĉĉĉĉ ĉ curr Max Alpha Ġ= Ġmax Of ( curr Max Alpha , Ġlayer Alpha Int ) Ċĉĉĉĉ ĉ val Ġresult ant Alpha Ġ= Ġ( layer Alpha Int Ġ/ Ġ 2 5 5 . 0 ) Ġ+ Ġ( 1 . 0 Ġ- Ġ( layer Alpha Int Ġ/ Ġ 2 5 5 . 0 )) Ġ* Ġ( curr Sum Alpha Ġ/ Ġ 2 5 5 . 0 ) Ċĉĉĉĉ ĉ val Ġresult ant Alpha Int Ġ= Ġ( result ant Alpha Ġ* Ġ 2 5 5 ). round ToInt () ĊĊĉĉĉĉ ĉ if Ġ( layer Alpha Int Ġ!= Ġ 0 Ġ&& Ġresult ant Alpha Int Ġ!= Ġcurr Sum Alpha ) Ġ{ Ċĉĉĉĉĉ ĉ // Ensure Ġthe Ġcurrent Ġtotal Ġalpha Ġis Ġupdated Ċĉĉĉĉĉ ĉ curr Sum Alpha Ġ= Ġresult ant Alpha Int Ċĉĉĉĉĉ ĉ val Ġlayer Colo urs Ġ= Ġmutable ListOf ( red , Ġgreen , Ġblue ) Ċĉĉĉĉĉ ĉ if Ġ( curr Max Alpha Ġ<= Ġ 1 1 Ġ&& Ġcurr Sum Alpha Ġ<= Ġ 1 2 7 ) Ġ{ Ċĉĉĉĉĉĉ ĉ /* Ċĉĉĉĉĉĉĉ Ġ* ĠAdjust Ġthe Ġlower Ġopacity Ġlayers Ġto Ġensure Ġcorrect Ġpre multiplied Ġcolo urs Ċĉĉĉĉĉĉĉ Ġ* ĠSee Ġhttps :// en . wikipedia . org / wiki / Alpha _ comp osit ing # Str aight _ vers us _ pre multiplied Ċĉĉĉĉĉĉĉ Ġ* ĠNote Ġthat Ġthis Ġworks Ġon Ġthe Ġapproximation Ġthat Ġthe Ġalpha Ġoperation Ġa Ġover Ġb Ġis Ġequal Ġto Ġa Ġ+ Ġb Ċĉĉĉĉĉĉĉ Ġ* ĠThis Ġapproximation Ġis Ġvalid Ġfor Ġlow Ġlayer Alpha Int Ġand Ġlow Ġcurr Sum Alpha , Ġhence Ġthe Ġif Ġstatement Ċĉĉĉĉĉĉĉ Ġ* Ġ 1 1 Ġwas Ġselected Ġas Ġthe Ġcurr Max Alpha Ġcutoff Ġsince Ġit Ġis Ġthe Ġhighest Ġinteger Ġalpha Ġn Ġfor Ġwhich Ġround ( n Ġover Ġn ) Ġ= Ġ 2 n Ċĉĉĉĉĉĉĉ Ġ* Ġ 1 2 7 Ġwas Ġselected Ġas Ġthe Ġcurr Sum Alpha Ġcutoff Ġsince Ġit Ġis Ġthe Ġhighest Ġinteger Ġalpha Ġn Ġfor Ġwhich Ġround ( 1 Ġover Ġn ) Ġ= Ġn Ġ+ Ġ 1 Ċĉĉĉĉĉĉĉ Ġ*/ Ċĉĉĉĉĉĉ ĉ ( layer Colo urs Ġzip Ġpre multiplied Errors ). forEach Indexed Ġ{ Ġi , Ġ( initial Colour , Ġinitial Error ) Ġ-> Ċĉĉĉĉĉĉĉ ĉ val Ġpre multiplied Value Ġ= Ġinitial Colour . toDouble () Ġ* Ġlayer Alpha Int Ġ/ Ġ 2 5 5 Ċĉĉĉĉĉĉĉ ĉ val Ġpre multiplied ValueError Ġ= Ġpre multiplied Value . round ToInt () Ġ- Ġpre multiplied Value Ċĉĉĉĉĉĉĉ ĉ val Ġvalue Error Int Ġ= Ġ( initial Error Ġ+ Ġpre multiplied ValueError ). round ToInt () Ċĉĉĉĉĉĉĉ ĉ pre multiplied Errors [ i ] Ġ+= Ġpre multiplied ValueError Ġ- Ġvalue Error Int Ċĉĉĉĉĉĉĉ ĉ layer Colo urs [ i ] Ġ= Ġ( initial Colour Ġ- Ġ( value Error Int Ġ* Ġ 2 5 5 Ġ/ Ġlayer Alpha Int )). coerce In ( 0 , Ġ 2 5 5 ) Ċĉĉĉĉĉĉ ĉ } Ċĉĉĉĉĉ ĉ } Ċĉĉĉĉĉ ĉ val Ġlayer Colour Ġ= ĠColor . arg b ( layer Alpha Int , Ġlayer Colo urs [ 0 ], Ġlayer Colo urs [ 1 ], Ġlayer Colo urs [ 2 ]) Ċĉĉĉĉĉ ĉ Shadow Rect Spec ( layer Colour , Ġcorner Radius , Ġinset . left Ġ+ Ġit , Ġinset . top Ġ+ Ġit , Ġinset . right Ġ+ Ġit , Ġinset . bottom Ġ+ Ġit ) Ċĉĉĉĉ ĉ } Ċĉĉĉĉ ĉ else Ġ{ Ċĉĉĉĉĉ ĉ null Ċĉĉĉĉ ĉ } Ċĉĉĉ ĉ }. filter NotNull () Ċĉĉ ĉ } Ċĉ ĉ } Ċ ĉ } ĊĊ ĉ /** Ċĉ Ġ* ĠCalculate Ġthe Ġapproximate Ġvalue Ġof Ġthe Ġerror Ġfunction Ġer f ([ x ]) Ċĉ Ġ* ĠSee Ġhttps :// en . wikipedia . org / wiki / Error _ function # Num erical _ approx im ations Ċĉ Ġ* ĠUses Ġ[ er f Approx Positive ] Ġalong Ġwith Ġthe Ġodd Ġsym metry Ġof Ġthe Ġerror Ġfunction Ġto Ġcalculate Ġthe Ġerror Ġfunction Ġfor Ġany Ġvalue Ġon Ġthe Ġreal Ġnumber Ġline Ċĉ Ġ* Ċĉ Ġ* Ġ@ param Ġx Ġthe Ġvalue Ġto Ġcalculate Ġthe Ġerror Ġfunction Ġof Ċĉ Ġ*/ Ċ ĉ private Ġfun Ġer f Approx ( x : ĠDouble ): ĠDouble Ġ= Ġif Ġ( x Ġ< Ġ 0 ) Ġ{ Ċĉ ĉ - er f Approx Positive (- x ) Ċ ĉ } Ċ ĉ else Ġ{ Ċĉ ĉ er f Approx Positive ( x ) Ċ ĉ } ĊĊ ĉ /** Ċĉ Ġ* ĠCalculate Ġthe Ġapproximate Ġvalue Ġof Ġthe Ġerror Ġfunction Ġer f ([ x ]) ĠFOR ĠPOS ITIVE ĠX Ċĉ Ġ* ĠValues Ġwill Ġbe Ġincorrect Ġif Ġx Ġis Ġnegative Ċĉ Ġ* ĠSee Ġhttps :// en . wikipedia . org / wiki / Error _ function # Num erical _ approx im ations Ċĉ Ġ* Ċĉ Ġ* Ġ@ param Ġx Ġthe ĠPOS ITIVE Ġvalue Ġto Ġcalculate Ġthe Ġerror Ġfunction Ġof Ċĉ Ġ*/ Ċ ĉ private Ġfun Ġer f Approx Positive ( x : ĠDouble ): ĠDouble Ġ{ Ċĉ ĉ val Ġa 1 Ġ= Ġ 0 . 2 7 8 3 9 3 Ċĉ ĉ val Ġa 2 Ġ= Ġ 0 . 2 3 0 3 8 9 Ċĉ ĉ val Ġa 3 Ġ= Ġ 0 . 0 0 0 9 7 2 Ċĉ ĉ val Ġa 4 Ġ= Ġ 0 . 0 7 8 1 0 8 Ċĉ ĉ return Ġ( 1 f Ġ- Ġ 1 f Ġ/ Ġ(( 1 . 0 Ġ+ Ġa 1 Ġ* Ġx Ġ+ Ġa 2 Ġ* Ġ( x . pow ( 2 )) Ġ+ Ġa 3 Ġ* Ġ( x . pow ( 3 )) Ġ+ Ġa 4 Ġ* Ġ( x . pow ( 4 ))). pow ( 4 ))) Ċ ĉ } Ċ }