nsStyleStruct.h 140 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016
  1. /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* This Source Code Form is subject to the terms of the Mozilla Public
  3. * License, v. 2.0. If a copy of the MPL was not distributed with this
  4. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. /*
  6. * structs that contain the data provided by nsStyleContext, the
  7. * internal API for computed style data for an element
  8. */
  9. #ifndef nsStyleStruct_h___
  10. #define nsStyleStruct_h___
  11. #include "mozilla/ArenaObjectID.h"
  12. #include "mozilla/Attributes.h"
  13. #include "mozilla/CSSVariableValues.h"
  14. #include "mozilla/Maybe.h"
  15. #include "mozilla/SheetType.h"
  16. #include "mozilla/StaticPtr.h"
  17. #include "mozilla/StyleComplexColor.h"
  18. #include "mozilla/StyleStructContext.h"
  19. #include "mozilla/UniquePtr.h"
  20. #include "nsColor.h"
  21. #include "nsCoord.h"
  22. #include "nsMargin.h"
  23. #include "nsFont.h"
  24. #include "nsStyleCoord.h"
  25. #include "nsStyleConsts.h"
  26. #include "nsChangeHint.h"
  27. #include "nsPresContext.h"
  28. #include "nsCOMPtr.h"
  29. #include "nsCOMArray.h"
  30. #include "nsTArray.h"
  31. #include "nsCSSValue.h"
  32. #include "imgRequestProxy.h"
  33. #include "Orientation.h"
  34. #include "CounterStyleManager.h"
  35. #include <cstddef> // offsetof()
  36. #include <utility>
  37. #include "X11UndefineNone.h"
  38. class nsIFrame;
  39. class nsIURI;
  40. class nsStyleContext;
  41. class nsTextFrame;
  42. class imgIContainer;
  43. struct nsStyleVisibility;
  44. namespace mozilla {
  45. namespace dom {
  46. class ImageTracker;
  47. } // namespace dom
  48. } // namespace mozilla
  49. // Includes nsStyleStructID.
  50. #include "nsStyleStructFwd.h"
  51. // Bits for each struct.
  52. // NS_STYLE_INHERIT_BIT defined in nsStyleStructFwd.h
  53. #define NS_STYLE_INHERIT_MASK 0x000ffffff
  54. // Bits for inherited structs.
  55. #define NS_STYLE_INHERITED_STRUCT_MASK \
  56. ((nsStyleStructID_size_t(1) << nsStyleStructID_Inherited_Count) - 1)
  57. // Bits for reset structs.
  58. #define NS_STYLE_RESET_STRUCT_MASK \
  59. (((nsStyleStructID_size_t(1) << nsStyleStructID_Reset_Count) - 1) \
  60. << nsStyleStructID_Inherited_Count)
  61. // Additional bits for nsStyleContext's mBits:
  62. // See nsStyleContext::HasTextDecorationLines
  63. #define NS_STYLE_HAS_TEXT_DECORATION_LINES 0x001000000
  64. // See nsStyleContext::HasPseudoElementData.
  65. #define NS_STYLE_HAS_PSEUDO_ELEMENT_DATA 0x002000000
  66. // See nsStyleContext::RelevantLinkIsVisited
  67. #define NS_STYLE_RELEVANT_LINK_VISITED 0x004000000
  68. // See nsStyleContext::IsStyleIfVisited
  69. #define NS_STYLE_IS_STYLE_IF_VISITED 0x008000000
  70. // See nsStyleContext::HasChildThatUsesGrandancestorStyle
  71. #define NS_STYLE_CHILD_USES_GRANDANCESTOR_STYLE 0x010000000
  72. // See nsStyleContext::IsShared
  73. #define NS_STYLE_IS_SHARED 0x020000000
  74. // See nsStyleContext::AssertStructsNotUsedElsewhere
  75. // (This bit is currently only used in #ifdef DEBUG code.)
  76. #define NS_STYLE_IS_GOING_AWAY 0x040000000
  77. // See nsStyleContext::ShouldSuppressLineBreak
  78. #define NS_STYLE_SUPPRESS_LINEBREAK 0x080000000
  79. // See nsStyleContext::IsInDisplayNoneSubtree
  80. #define NS_STYLE_IN_DISPLAY_NONE_SUBTREE 0x100000000
  81. // See nsStyleContext::FindChildWithRules
  82. #define NS_STYLE_INELIGIBLE_FOR_SHARING 0x200000000
  83. // See nsStyleContext::HasChildThatUsesResetStyle
  84. #define NS_STYLE_HAS_CHILD_THAT_USES_RESET_STYLE 0x400000000
  85. // See nsStyleContext::IsTextCombined
  86. #define NS_STYLE_IS_TEXT_COMBINED 0x800000000
  87. // See nsStyleContext::GetPseudoEnum
  88. #define NS_STYLE_CONTEXT_TYPE_SHIFT 36
  89. // Additional bits for nsRuleNode's mDependentBits:
  90. #define NS_RULE_NODE_IS_ANIMATION_RULE 0x01000000
  91. // Free bit 0x02000000
  92. #define NS_RULE_NODE_USED_DIRECTLY 0x04000000
  93. #define NS_RULE_NODE_IS_IMPORTANT 0x08000000
  94. #define NS_RULE_NODE_LEVEL_MASK 0xf0000000
  95. #define NS_RULE_NODE_LEVEL_SHIFT 28
  96. // Additional bits for nsRuleNode's mNoneBits:
  97. #define NS_RULE_NODE_HAS_ANIMATION_DATA 0x80000000
  98. static_assert(int(mozilla::SheetType::Count) - 1 <=
  99. (NS_RULE_NODE_LEVEL_MASK >> NS_RULE_NODE_LEVEL_SHIFT),
  100. "NS_RULE_NODE_LEVEL_MASK cannot fit SheetType");
  101. static_assert(NS_STYLE_INHERIT_MASK == (1 << nsStyleStructID_Length) - 1,
  102. "NS_STYLE_INHERIT_MASK is not correct");
  103. static_assert((NS_RULE_NODE_IS_ANIMATION_RULE & NS_STYLE_INHERIT_MASK) == 0,
  104. "NS_RULE_NODE_IS_ANIMATION_RULE must not overlap the style struct bits.");
  105. namespace mozilla {
  106. struct Position {
  107. using Coord = nsStyleCoord::CalcValue;
  108. Coord mXPosition, mYPosition;
  109. // Initialize nothing
  110. Position() {}
  111. // Sets both mXPosition and mYPosition to the given percent value for the
  112. // initial property-value (e.g. 0.0f for "0% 0%", or 0.5f for "50% 50%")
  113. void SetInitialPercentValues(float aPercentVal);
  114. // Sets both mXPosition and mYPosition to 0 (app units) for the
  115. // initial property-value as a length with no percentage component.
  116. void SetInitialZeroValues();
  117. // True if the effective background image position described by this depends
  118. // on the size of the corresponding frame.
  119. bool DependsOnPositioningAreaSize() const {
  120. return mXPosition.mPercent != 0.0f || mYPosition.mPercent != 0.0f;
  121. }
  122. bool operator==(const Position& aOther) const {
  123. return mXPosition == aOther.mXPosition &&
  124. mYPosition == aOther.mYPosition;
  125. }
  126. bool operator!=(const Position& aOther) const {
  127. return !(*this == aOther);
  128. }
  129. };
  130. } // namespace mozilla
  131. // The lifetime of these objects is managed by the presshell's arena.
  132. struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleFont
  133. {
  134. nsStyleFont(const nsFont& aFont, StyleStructContext aContext);
  135. nsStyleFont(const nsStyleFont& aStyleFont);
  136. explicit nsStyleFont(StyleStructContext aContext);
  137. ~nsStyleFont() {
  138. MOZ_COUNT_DTOR(nsStyleFont);
  139. }
  140. void FinishStyle(nsPresContext* aPresContext) {}
  141. nsChangeHint CalcDifference(const nsStyleFont& aNewData) const;
  142. static nsChangeHint MaxDifference() {
  143. return NS_STYLE_HINT_REFLOW |
  144. nsChangeHint_NeutralChange;
  145. }
  146. static nsChangeHint DifferenceAlwaysHandledForDescendants() {
  147. // CalcDifference never returns the reflow hints that are sometimes
  148. // handled for descendants as hints not handled for descendants.
  149. return nsChangeHint_NeedReflow |
  150. nsChangeHint_ReflowChangesSizeOrPosition |
  151. nsChangeHint_ClearAncestorIntrinsics;
  152. }
  153. /**
  154. * Return aSize multiplied by the current text zoom factor (in aPresContext).
  155. * aSize is allowed to be negative, but the caller is expected to deal with
  156. * negative results. The result is clamped to nscoord_MIN .. nscoord_MAX.
  157. */
  158. static nscoord ZoomText(StyleStructContext aContext, nscoord aSize);
  159. /**
  160. * Return aSize divided by the current text zoom factor (in aPresContext).
  161. * aSize is allowed to be negative, but the caller is expected to deal with
  162. * negative results. The result is clamped to nscoord_MIN .. nscoord_MAX.
  163. */
  164. static nscoord UnZoomText(nsPresContext* aPresContext, nscoord aSize);
  165. static already_AddRefed<nsIAtom> GetLanguage(StyleStructContext aPresContext);
  166. void* operator new(size_t sz, nsStyleFont* aSelf) { return aSelf; }
  167. void* operator new(size_t sz, nsPresContext* aContext) {
  168. return aContext->PresShell()->
  169. AllocateByObjectID(mozilla::eArenaObjectID_nsStyleFont, sz);
  170. }
  171. void Destroy(nsPresContext* aContext);
  172. void EnableZoom(nsPresContext* aContext, bool aEnable);
  173. nsFont mFont; // [inherited]
  174. nscoord mSize; // [inherited] Our "computed size". Can be different
  175. // from mFont.size which is our "actual size" and is
  176. // enforced to be >= the user's preferred min-size.
  177. // mFont.size should be used for display purposes
  178. // while mSize is the value to return in
  179. // getComputedStyle() for example.
  180. uint8_t mGenericID; // [inherited] generic CSS font family, if any;
  181. // value is a kGenericFont_* constant, see nsFont.h.
  182. // MathML scriptlevel support
  183. int8_t mScriptLevel; // [inherited]
  184. // MathML mathvariant support
  185. uint8_t mMathVariant; // [inherited]
  186. // MathML displaystyle support
  187. uint8_t mMathDisplay; // [inherited]
  188. // allow different min font-size for certain cases
  189. uint8_t mMinFontSizeRatio; // [inherited] percent * 100
  190. // was mLanguage set based on a lang attribute in the document?
  191. bool mExplicitLanguage; // [inherited]
  192. // should calls to ZoomText() and UnZoomText() be made to the font
  193. // size on this nsStyleFont?
  194. bool mAllowZoom; // [inherited]
  195. // The value mSize would have had if scriptminsize had never been applied
  196. nscoord mScriptUnconstrainedSize;
  197. nscoord mScriptMinSize; // [inherited] length
  198. float mScriptSizeMultiplier; // [inherited]
  199. nsCOMPtr<nsIAtom> mLanguage; // [inherited]
  200. };
  201. struct nsStyleGradientStop
  202. {
  203. nsStyleCoord mLocation; // percent, coord, calc, none
  204. nscolor mColor;
  205. bool mIsInterpolationHint;
  206. // Use ==/!= on nsStyleGradient instead of on the gradient stop.
  207. bool operator==(const nsStyleGradientStop&) const = delete;
  208. bool operator!=(const nsStyleGradientStop&) const = delete;
  209. };
  210. class nsStyleGradient final
  211. {
  212. public:
  213. nsStyleGradient();
  214. uint8_t mShape; // NS_STYLE_GRADIENT_SHAPE_*
  215. uint8_t mSize; // NS_STYLE_GRADIENT_SIZE_*;
  216. // not used (must be FARTHEST_CORNER) for linear shape
  217. bool mRepeating;
  218. bool mLegacySyntax;
  219. nsStyleCoord mBgPosX; // percent, coord, calc, none
  220. nsStyleCoord mBgPosY; // percent, coord, calc, none
  221. nsStyleCoord mAngle; // none, angle
  222. nsStyleCoord mRadiusX; // percent, coord, calc, none
  223. nsStyleCoord mRadiusY; // percent, coord, calc, none
  224. // stops are in the order specified in the stylesheet
  225. nsTArray<nsStyleGradientStop> mStops;
  226. bool operator==(const nsStyleGradient& aOther) const;
  227. bool operator!=(const nsStyleGradient& aOther) const {
  228. return !(*this == aOther);
  229. }
  230. bool IsOpaque();
  231. bool HasCalc();
  232. uint32_t Hash(PLDHashNumber aHash);
  233. NS_INLINE_DECL_THREADSAFE_REFCOUNTING(nsStyleGradient)
  234. private:
  235. // Private destructor, to discourage deletion outside of Release():
  236. ~nsStyleGradient() {}
  237. nsStyleGradient(const nsStyleGradient& aOther) = delete;
  238. nsStyleGradient& operator=(const nsStyleGradient& aOther) = delete;
  239. };
  240. /**
  241. * A wrapper for an imgRequestProxy that supports off-main-thread creation
  242. * and equality comparison.
  243. *
  244. * An nsStyleImageRequest can be created in two ways:
  245. *
  246. * 1. Using the constructor that takes an imgRequestProxy. This must
  247. * be called from the main thread. The nsStyleImageRequest is
  248. * immediately considered "resolved", and the get() method that
  249. * returns the imgRequestProxy can be called.
  250. *
  251. * 2. Using the constructor that takes the URL, base URI, referrer
  252. * and principal that can be used to inititiate an image load and
  253. * produce an imgRequestProxy later. This can be called from
  254. * any thread. The nsStyleImageRequest is not considered "resolved"
  255. * at this point, and the Resolve() method must be called later
  256. * to initiate the image load and make calls to get() valid.
  257. *
  258. * Calls to TrackImage(), UntrackImage(), LockImage(), UnlockImage() and
  259. * RequestDiscard() are made to the imgRequestProxy and ImageTracker as
  260. * appropriate, according to the mode flags passed in to the constructor.
  261. *
  262. * The main thread constructor takes a pointer to the css::ImageValue that
  263. * is the specified url() value, while the off-main-thread constructor
  264. * creates a new css::ImageValue to represent the url() information passed
  265. * to the constructor. This ImageValue is held on to for the comparisons done
  266. * in DefinitelyEquals(), so that we don't need to call into the non-OMT-safe
  267. * Equals() on the nsIURI objects returned from imgRequestProxy::GetURI().
  268. */
  269. class nsStyleImageRequest
  270. {
  271. public:
  272. // Flags describing whether the imgRequestProxy must be tracked in the
  273. // ImageTracker, whether LockImage/UnlockImage calls will be made
  274. // when obtaining and releasing the imgRequestProxy, and whether
  275. // RequestDiscard will be called on release.
  276. enum class Mode : uint8_t {
  277. // The imgRequestProxy will be added to the ImageTracker when resolved
  278. // Without this flag, the nsStyleImageRequest itself will call LockImage/
  279. // UnlockImage on the imgRequestProxy, rather than leaving locking to the
  280. // ImageTracker to manage.
  281. //
  282. // This flag is currently used by all nsStyleImageRequests except
  283. // those for list-style-image and cursor.
  284. Track = 0x1,
  285. // The imgRequestProxy will have its RequestDiscard method called when
  286. // the nsStyleImageRequest is going away.
  287. //
  288. // This is currently used only for cursor images.
  289. Discard = 0x2,
  290. };
  291. // Must be called from the main thread.
  292. //
  293. // aImageTracker must be non-null iff aModeFlags contains Track.
  294. nsStyleImageRequest(Mode aModeFlags,
  295. imgRequestProxy* aRequestProxy,
  296. mozilla::css::ImageValue* aImageValue,
  297. mozilla::dom::ImageTracker* aImageTracker);
  298. // Can be called from any thread, but Resolve() must be called later
  299. // on the main thread before get() can be used.
  300. nsStyleImageRequest(
  301. Mode aModeFlags,
  302. nsStringBuffer* aURLBuffer,
  303. already_AddRefed<mozilla::PtrHolder<nsIURI>> aBaseURI,
  304. already_AddRefed<mozilla::PtrHolder<nsIURI>> aReferrer,
  305. already_AddRefed<mozilla::PtrHolder<nsIPrincipal>> aPrincipal);
  306. bool Resolve(nsPresContext* aPresContext);
  307. bool IsResolved() const { return mResolved; }
  308. imgRequestProxy* get() {
  309. MOZ_ASSERT(IsResolved(), "Resolve() must be called first");
  310. MOZ_ASSERT(NS_IsMainThread());
  311. return mRequestProxy.get();
  312. }
  313. const imgRequestProxy* get() const {
  314. return const_cast<nsStyleImageRequest*>(this)->get();
  315. }
  316. // Returns whether the ImageValue objects in the two nsStyleImageRequests
  317. // return true from URLValueData::DefinitelyEqualURIs.
  318. bool DefinitelyEquals(const nsStyleImageRequest& aOther) const;
  319. NS_INLINE_DECL_THREADSAFE_REFCOUNTING(nsStyleImageRequest);
  320. private:
  321. ~nsStyleImageRequest();
  322. nsStyleImageRequest& operator=(const nsStyleImageRequest& aOther) = delete;
  323. void MaybeTrackAndLock();
  324. RefPtr<imgRequestProxy> mRequestProxy;
  325. RefPtr<mozilla::css::ImageValue> mImageValue;
  326. RefPtr<mozilla::dom::ImageTracker> mImageTracker;
  327. Mode mModeFlags;
  328. bool mResolved;
  329. };
  330. MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(nsStyleImageRequest::Mode)
  331. enum nsStyleImageType {
  332. eStyleImageType_Null,
  333. eStyleImageType_Image,
  334. eStyleImageType_Gradient,
  335. eStyleImageType_Element
  336. };
  337. struct CachedBorderImageData
  338. {
  339. // Caller are expected to ensure that the value of aSVGViewportSize is
  340. // different from the cached one since the method won't do the check.
  341. void SetCachedSVGViewportSize(const mozilla::Maybe<nsSize>& aSVGViewportSize);
  342. const mozilla::Maybe<nsSize>& GetCachedSVGViewportSize();
  343. void PurgeCachedImages();
  344. void SetSubImage(uint8_t aIndex, imgIContainer* aSubImage);
  345. imgIContainer* GetSubImage(uint8_t aIndex);
  346. private:
  347. // If this is a SVG border-image, we save the size of the SVG viewport that
  348. // we used when rasterizing any cached border-image subimages. (The viewport
  349. // size matters for percent-valued sizes & positions in inner SVG doc).
  350. mozilla::Maybe<nsSize> mCachedSVGViewportSize;
  351. nsCOMArray<imgIContainer> mSubImages;
  352. };
  353. /**
  354. * Represents a paintable image of one of the following types.
  355. * (1) A real image loaded from an external source.
  356. * (2) A CSS linear or radial gradient.
  357. * (3) An element within a document, or an <img>, <video>, or <canvas> element
  358. * not in a document.
  359. * (*) Optionally a crop rect can be set to paint a partial (rectangular)
  360. * region of an image. (Currently, this feature is only supported with an
  361. * image of type (1)).
  362. */
  363. struct nsStyleImage
  364. {
  365. nsStyleImage();
  366. ~nsStyleImage();
  367. nsStyleImage(const nsStyleImage& aOther);
  368. nsStyleImage& operator=(const nsStyleImage& aOther);
  369. void SetNull();
  370. void SetImageRequest(already_AddRefed<nsStyleImageRequest> aImage);
  371. void SetGradientData(nsStyleGradient* aGradient);
  372. void SetElementId(const char16_t* aElementId);
  373. void SetCropRect(mozilla::UniquePtr<nsStyleSides> aCropRect);
  374. void ResolveImage(nsPresContext* aContext) {
  375. MOZ_ASSERT(mType != eStyleImageType_Image || mImage);
  376. if (mType == eStyleImageType_Image && !mImage->IsResolved()) {
  377. mImage->Resolve(aContext);
  378. }
  379. }
  380. nsStyleImageType GetType() const {
  381. return mType;
  382. }
  383. nsStyleImageRequest* GetImageRequest() const {
  384. MOZ_ASSERT(mType == eStyleImageType_Image, "Data is not an image!");
  385. MOZ_ASSERT(mImage);
  386. return mImage;
  387. }
  388. imgRequestProxy* GetImageData() const {
  389. return GetImageRequest()->get();
  390. }
  391. nsStyleGradient* GetGradientData() const {
  392. NS_ASSERTION(mType == eStyleImageType_Gradient, "Data is not a gradient!");
  393. return mGradient;
  394. }
  395. const char16_t* GetElementId() const {
  396. NS_ASSERTION(mType == eStyleImageType_Element, "Data is not an element!");
  397. return mElementId;
  398. }
  399. const mozilla::UniquePtr<nsStyleSides>& GetCropRect() const {
  400. NS_ASSERTION(mType == eStyleImageType_Image,
  401. "Only image data can have a crop rect");
  402. return mCropRect;
  403. }
  404. /**
  405. * Compute the actual crop rect in pixels, using the source image bounds.
  406. * The computation involves converting percentage unit to pixel unit and
  407. * clamping each side value to fit in the source image bounds.
  408. * @param aActualCropRect the computed actual crop rect.
  409. * @param aIsEntireImage true iff |aActualCropRect| is identical to the
  410. * source image bounds.
  411. * @return true iff |aActualCropRect| holds a meaningful value.
  412. */
  413. bool ComputeActualCropRect(nsIntRect& aActualCropRect,
  414. bool* aIsEntireImage = nullptr) const;
  415. /**
  416. * Starts the decoding of a image.
  417. */
  418. nsresult StartDecoding() const;
  419. /**
  420. * @return true if the item is definitely opaque --- i.e., paints every
  421. * pixel within its bounds opaquely, and the bounds contains at least a pixel.
  422. */
  423. bool IsOpaque() const;
  424. /**
  425. * @return true if this image is fully loaded, and its size is calculated;
  426. * always returns true if |mType| is |eStyleImageType_Gradient| or
  427. * |eStyleImageType_Element|.
  428. */
  429. bool IsComplete() const;
  430. /**
  431. * @return true if this image is loaded without error;
  432. * always returns true if |mType| is |eStyleImageType_Gradient| or
  433. * |eStyleImageType_Element|.
  434. */
  435. bool IsLoaded() const;
  436. /**
  437. * @return true if it is 100% confident that this image contains no pixel
  438. * to draw.
  439. */
  440. bool IsEmpty() const {
  441. // There are some other cases when the image will be empty, for example
  442. // when the crop rect is empty. However, checking the emptiness of crop
  443. // rect is non-trivial since each side value can be specified with
  444. // percentage unit, which can not be evaluated until the source image size
  445. // is available. Therefore, we currently postpone the evaluation of crop
  446. // rect until the actual rendering time --- alternatively until GetOpaqueRegion()
  447. // is called.
  448. return mType == eStyleImageType_Null;
  449. }
  450. bool operator==(const nsStyleImage& aOther) const;
  451. bool operator!=(const nsStyleImage& aOther) const {
  452. return !(*this == aOther);
  453. }
  454. bool ImageDataEquals(const nsStyleImage& aOther) const
  455. {
  456. return GetType() == eStyleImageType_Image &&
  457. aOther.GetType() == eStyleImageType_Image &&
  458. GetImageData() == aOther.GetImageData();
  459. }
  460. // These methods are used for the caller to caches the sub images created
  461. // during a border-image paint operation
  462. inline void SetSubImage(uint8_t aIndex, imgIContainer* aSubImage) const;
  463. inline imgIContainer* GetSubImage(uint8_t aIndex) const;
  464. void PurgeCacheForViewportChange(
  465. const mozilla::Maybe<nsSize>& aSVGViewportSize,
  466. const bool aHasIntrinsicRatio) const;
  467. private:
  468. void DoCopy(const nsStyleImage& aOther);
  469. void EnsureCachedBIData() const;
  470. // This variable keeps some cache data for border image and is lazily
  471. // allocated since it is only used in border image case.
  472. mozilla::UniquePtr<CachedBorderImageData> mCachedBIData;
  473. nsStyleImageType mType;
  474. union {
  475. nsStyleImageRequest* mImage;
  476. nsStyleGradient* mGradient;
  477. char16_t* mElementId;
  478. };
  479. // This is _currently_ used only in conjunction with eStyleImageType_Image.
  480. mozilla::UniquePtr<nsStyleSides> mCropRect;
  481. };
  482. struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleColor
  483. {
  484. explicit nsStyleColor(StyleStructContext aContext);
  485. nsStyleColor(const nsStyleColor& aOther);
  486. ~nsStyleColor() {
  487. MOZ_COUNT_DTOR(nsStyleColor);
  488. }
  489. void FinishStyle(nsPresContext* aPresContext) {}
  490. nscolor CalcComplexColor(const mozilla::StyleComplexColor& aColor) const {
  491. return mozilla::LinearBlendColors(aColor.mColor, mColor,
  492. aColor.mForegroundRatio);
  493. }
  494. nsChangeHint CalcDifference(const nsStyleColor& aNewData) const;
  495. static nsChangeHint MaxDifference() {
  496. return nsChangeHint_RepaintFrame;
  497. }
  498. static nsChangeHint DifferenceAlwaysHandledForDescendants() {
  499. // CalcDifference never returns the reflow hints that are sometimes
  500. // handled for descendants at all.
  501. return nsChangeHint(0);
  502. }
  503. void* operator new(size_t sz, nsStyleColor* aSelf) { return aSelf; }
  504. void* operator new(size_t sz, nsPresContext* aContext) {
  505. return aContext->PresShell()->
  506. AllocateByObjectID(mozilla::eArenaObjectID_nsStyleColor, sz);
  507. }
  508. void Destroy(nsPresContext* aContext) {
  509. this->~nsStyleColor();
  510. aContext->PresShell()->
  511. FreeByObjectID(mozilla::eArenaObjectID_nsStyleColor, this);
  512. }
  513. // Don't add ANY members to this struct! We can achieve caching in the rule
  514. // tree (rather than the style tree) by letting color stay by itself! -dwh
  515. nscolor mColor; // [inherited]
  516. };
  517. /**
  518. * An array of objects, similar to AutoTArray<T,1> but which is memmovable. It
  519. * always has length >= 1.
  520. */
  521. template<typename T>
  522. class nsStyleAutoArray
  523. {
  524. public:
  525. // This constructor places a single element in mFirstElement.
  526. enum WithSingleInitialElement { WITH_SINGLE_INITIAL_ELEMENT };
  527. explicit nsStyleAutoArray(WithSingleInitialElement) {}
  528. nsStyleAutoArray(const nsStyleAutoArray& aOther) { *this = aOther; }
  529. nsStyleAutoArray& operator=(const nsStyleAutoArray& aOther) {
  530. mFirstElement = aOther.mFirstElement;
  531. mOtherElements = aOther.mOtherElements;
  532. return *this;
  533. }
  534. bool operator==(const nsStyleAutoArray& aOther) const {
  535. return Length() == aOther.Length() &&
  536. mFirstElement == aOther.mFirstElement &&
  537. mOtherElements == aOther.mOtherElements;
  538. }
  539. bool operator!=(const nsStyleAutoArray& aOther) const {
  540. return !(*this == aOther);
  541. }
  542. size_t Length() const {
  543. return mOtherElements.Length() + 1;
  544. }
  545. const T& operator[](size_t aIndex) const {
  546. return aIndex == 0 ? mFirstElement : mOtherElements[aIndex - 1];
  547. }
  548. T& operator[](size_t aIndex) {
  549. return aIndex == 0 ? mFirstElement : mOtherElements[aIndex - 1];
  550. }
  551. void EnsureLengthAtLeast(size_t aMinLen) {
  552. if (aMinLen > 0) {
  553. mOtherElements.EnsureLengthAtLeast(aMinLen - 1);
  554. }
  555. }
  556. void SetLengthNonZero(size_t aNewLen) {
  557. MOZ_ASSERT(aNewLen > 0);
  558. mOtherElements.SetLength(aNewLen - 1);
  559. }
  560. void TruncateLengthNonZero(size_t aNewLen) {
  561. MOZ_ASSERT(aNewLen > 0);
  562. MOZ_ASSERT(aNewLen <= Length());
  563. mOtherElements.TruncateLength(aNewLen - 1);
  564. }
  565. private:
  566. T mFirstElement;
  567. nsTArray<T> mOtherElements;
  568. };
  569. struct nsStyleImageLayers {
  570. // Indices into kBackgroundLayerTable and kMaskLayerTable
  571. enum {
  572. shorthand = 0,
  573. color,
  574. image,
  575. repeat,
  576. positionX,
  577. positionY,
  578. clip,
  579. origin,
  580. size,
  581. attachment,
  582. maskMode,
  583. composite
  584. };
  585. enum class LayerType : uint8_t {
  586. Background = 0,
  587. Mask
  588. };
  589. explicit nsStyleImageLayers(LayerType aType);
  590. nsStyleImageLayers(const nsStyleImageLayers &aSource);
  591. ~nsStyleImageLayers() {
  592. MOZ_COUNT_DTOR(nsStyleImageLayers);
  593. }
  594. static bool IsInitialPositionForLayerType(mozilla::Position aPosition, LayerType aType);
  595. struct Size;
  596. friend struct Size;
  597. struct Size {
  598. struct Dimension : public nsStyleCoord::CalcValue {
  599. nscoord ResolveLengthPercentage(nscoord aAvailable) const {
  600. double d = double(mPercent) * double(aAvailable) + double(mLength);
  601. if (d < 0.0) {
  602. return 0;
  603. }
  604. return NSToCoordRoundWithClamp(float(d));
  605. }
  606. };
  607. Dimension mWidth, mHeight;
  608. bool IsInitialValue() const {
  609. return mWidthType == eAuto && mHeightType == eAuto;
  610. }
  611. nscoord ResolveWidthLengthPercentage(const nsSize& aBgPositioningArea) const {
  612. MOZ_ASSERT(mWidthType == eLengthPercentage,
  613. "resolving non-length/percent dimension!");
  614. return mWidth.ResolveLengthPercentage(aBgPositioningArea.width);
  615. }
  616. nscoord ResolveHeightLengthPercentage(const nsSize& aBgPositioningArea) const {
  617. MOZ_ASSERT(mHeightType == eLengthPercentage,
  618. "resolving non-length/percent dimension!");
  619. return mHeight.ResolveLengthPercentage(aBgPositioningArea.height);
  620. }
  621. // Except for eLengthPercentage, Dimension types which might change
  622. // how a layer is painted when the corresponding frame's dimensions
  623. // change *must* precede all dimension types which are agnostic to
  624. // frame size; see DependsOnDependsOnPositioningAreaSizeSize.
  625. enum DimensionType {
  626. // If one of mWidth and mHeight is eContain or eCover, then both are.
  627. // NOTE: eContain and eCover *must* be equal to NS_STYLE_BG_SIZE_CONTAIN
  628. // and NS_STYLE_BG_SIZE_COVER (in kBackgroundSizeKTable).
  629. eContain, eCover,
  630. eAuto,
  631. eLengthPercentage,
  632. eDimensionType_COUNT
  633. };
  634. uint8_t mWidthType, mHeightType;
  635. // True if the effective image size described by this depends on the size of
  636. // the corresponding frame, when aImage (which must not have null type) is
  637. // the background image.
  638. bool DependsOnPositioningAreaSize(const nsStyleImage& aImage) const;
  639. // Initialize nothing
  640. Size() {}
  641. // Initialize to initial values
  642. void SetInitialValues();
  643. bool operator==(const Size& aOther) const;
  644. bool operator!=(const Size& aOther) const {
  645. return !(*this == aOther);
  646. }
  647. };
  648. struct Repeat;
  649. friend struct Repeat;
  650. struct Repeat {
  651. uint8_t mXRepeat, mYRepeat;
  652. // Initialize nothing
  653. Repeat() {}
  654. bool IsInitialValue() const {
  655. return mXRepeat == NS_STYLE_IMAGELAYER_REPEAT_REPEAT &&
  656. mYRepeat == NS_STYLE_IMAGELAYER_REPEAT_REPEAT;
  657. }
  658. bool DependsOnPositioningAreaSize() const {
  659. return mXRepeat == NS_STYLE_IMAGELAYER_REPEAT_SPACE ||
  660. mYRepeat == NS_STYLE_IMAGELAYER_REPEAT_SPACE;
  661. }
  662. // Initialize to initial values
  663. void SetInitialValues() {
  664. mXRepeat = NS_STYLE_IMAGELAYER_REPEAT_REPEAT;
  665. mYRepeat = NS_STYLE_IMAGELAYER_REPEAT_REPEAT;
  666. }
  667. bool operator==(const Repeat& aOther) const {
  668. return mXRepeat == aOther.mXRepeat &&
  669. mYRepeat == aOther.mYRepeat;
  670. }
  671. bool operator!=(const Repeat& aOther) const {
  672. return !(*this == aOther);
  673. }
  674. };
  675. struct Layer;
  676. friend struct Layer;
  677. struct Layer {
  678. typedef mozilla::StyleGeometryBox StyleGeometryBox;
  679. nsStyleImage mImage; // [reset]
  680. RefPtr<mozilla::css::URLValueData> mSourceURI; // [reset]
  681. // mask-only property
  682. // This property is used for mask layer only.
  683. // For a background layer, it should always
  684. // be the initial value, which is nullptr.
  685. // Store mask-image URI so that we can resolve
  686. // SVG mask path later. (Might be a URLValue
  687. // or an ImageValue.)
  688. mozilla::Position mPosition; // [reset]
  689. Size mSize; // [reset]
  690. StyleGeometryBox mClip; // [reset] See nsStyleConsts.h
  691. MOZ_INIT_OUTSIDE_CTOR
  692. StyleGeometryBox mOrigin; // [reset] See nsStyleConsts.h
  693. uint8_t mAttachment; // [reset] See nsStyleConsts.h
  694. // background-only property
  695. // This property is used for background layer
  696. // only. For a mask layer, it should always
  697. // be the initial value, which is
  698. // NS_STYLE_IMAGELAYER_ATTACHMENT_SCROLL.
  699. uint8_t mBlendMode; // [reset] See nsStyleConsts.h
  700. // background-only property
  701. // This property is used for background layer
  702. // only. For a mask layer, it should always
  703. // be the initial value, which is
  704. // NS_STYLE_BLEND_NORMAL.
  705. uint8_t mComposite; // [reset] See nsStyleConsts.h
  706. // mask-only property
  707. // This property is used for mask layer only.
  708. // For a background layer, it should always
  709. // be the initial value, which is
  710. // NS_STYLE_COMPOSITE_MODE_ADD.
  711. uint8_t mMaskMode; // [reset] See nsStyleConsts.h
  712. // mask-only property
  713. // This property is used for mask layer only.
  714. // For a background layer, it should always
  715. // be the initial value, which is
  716. // NS_STYLE_MASK_MODE_MATCH_SOURCE.
  717. Repeat mRepeat; // [reset] See nsStyleConsts.h
  718. // This constructor does not initialize mRepeat or mOrigin and Initialize()
  719. // must be called to do that.
  720. Layer();
  721. ~Layer();
  722. // Initialize mRepeat and mOrigin by specified layer type
  723. void Initialize(LayerType aType);
  724. void ResolveImage(nsPresContext* aContext) {
  725. if (mImage.GetType() == eStyleImageType_Image) {
  726. mImage.ResolveImage(aContext);
  727. }
  728. }
  729. // True if the rendering of this layer might change when the size
  730. // of the background positioning area changes. This is true for any
  731. // non-solid-color background whose position or size depends on
  732. // the size of the positioning area. It's also true for SVG images
  733. // whose root <svg> node has a viewBox.
  734. bool RenderingMightDependOnPositioningAreaSizeChange() const;
  735. // Compute the change hint required by changes in just this layer.
  736. nsChangeHint CalcDifference(const Layer& aNewLayer) const;
  737. // An equality operator that compares the images using URL-equality
  738. // rather than pointer-equality.
  739. bool operator==(const Layer& aOther) const;
  740. bool operator!=(const Layer& aOther) const {
  741. return !(*this == aOther);
  742. }
  743. };
  744. // The (positive) number of computed values of each property, since
  745. // the lengths of the lists are independent.
  746. uint32_t mAttachmentCount,
  747. mClipCount,
  748. mOriginCount,
  749. mRepeatCount,
  750. mPositionXCount,
  751. mPositionYCount,
  752. mImageCount,
  753. mSizeCount,
  754. mMaskModeCount,
  755. mBlendModeCount,
  756. mCompositeCount;
  757. // Layers are stored in an array, matching the top-to-bottom order in
  758. // which they are specified in CSS. The number of layers to be used
  759. // should come from the background-image property. We create
  760. // additional |Layer| objects for *any* property, not just
  761. // background-image. This means that the bottommost layer that
  762. // callers in layout care about (which is also the one whose
  763. // background-clip applies to the background-color) may not be last
  764. // layer. In layers below the bottom layer, properties will be
  765. // uninitialized unless their count, above, indicates that they are
  766. // present.
  767. nsStyleAutoArray<Layer> mLayers;
  768. const Layer& BottomLayer() const { return mLayers[mImageCount - 1]; }
  769. void ResolveImages(nsPresContext* aContext) {
  770. for (uint32_t i = 0; i < mImageCount; ++i) {
  771. mLayers[i].ResolveImage(aContext);
  772. }
  773. }
  774. nsChangeHint CalcDifference(const nsStyleImageLayers& aNewLayers,
  775. nsStyleImageLayers::LayerType aType) const;
  776. bool HasLayerWithImage() const;
  777. nsStyleImageLayers& operator=(const nsStyleImageLayers& aOther);
  778. static const nsCSSPropertyID kBackgroundLayerTable[];
  779. static const nsCSSPropertyID kMaskLayerTable[];
  780. #define NS_FOR_VISIBLE_IMAGE_LAYERS_BACK_TO_FRONT(var_, layers_) \
  781. for (uint32_t var_ = (layers_).mImageCount; var_-- != 0; )
  782. #define NS_FOR_VISIBLE_IMAGE_LAYERS_BACK_TO_FRONT_WITH_RANGE(var_, layers_, start_, count_) \
  783. NS_ASSERTION((int32_t)(start_) >= 0 && (uint32_t)(start_) < (layers_).mImageCount, "Invalid layer start!"); \
  784. NS_ASSERTION((count_) > 0 && (count_) <= (start_) + 1, "Invalid layer range!"); \
  785. for (uint32_t var_ = (start_) + 1; var_-- != (uint32_t)((start_) + 1 - (count_)); )
  786. };
  787. struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleBackground {
  788. explicit nsStyleBackground(StyleStructContext aContext);
  789. nsStyleBackground(const nsStyleBackground& aOther);
  790. ~nsStyleBackground();
  791. // Resolves and tracks the images in mImage. Only called with a Servo-backed
  792. // style system, where those images must be resolved later than the OMT
  793. // nsStyleBackground constructor call.
  794. void FinishStyle(nsPresContext* aPresContext);
  795. void* operator new(size_t sz, nsStyleBackground* aSelf) { return aSelf; }
  796. void* operator new(size_t sz, nsPresContext* aContext) {
  797. return aContext->PresShell()->
  798. AllocateByObjectID(mozilla::eArenaObjectID_nsStyleBackground, sz);
  799. }
  800. void Destroy(nsPresContext* aContext);
  801. nsChangeHint CalcDifference(const nsStyleBackground& aNewData) const;
  802. static nsChangeHint MaxDifference() {
  803. return nsChangeHint_UpdateEffects |
  804. nsChangeHint_RepaintFrame |
  805. nsChangeHint_UpdateBackgroundPosition |
  806. nsChangeHint_NeutralChange;
  807. }
  808. static nsChangeHint DifferenceAlwaysHandledForDescendants() {
  809. // CalcDifference never returns the reflow hints that are sometimes
  810. // handled for descendants at all.
  811. return nsChangeHint(0);
  812. }
  813. // True if this background is completely transparent.
  814. bool IsTransparent() const;
  815. // We have to take slower codepaths for fixed background attachment,
  816. // but we don't want to do that when there's no image.
  817. // Not inline because it uses an nsCOMPtr<imgIRequest>
  818. // FIXME: Should be in nsStyleStructInlines.h.
  819. bool HasFixedBackground(nsIFrame* aFrame) const;
  820. // Checks to see if this has a non-empty image with "local" attachment.
  821. // This is defined in nsStyleStructInlines.h.
  822. inline bool HasLocalBackground() const;
  823. const nsStyleImageLayers::Layer& BottomLayer() const { return mImage.BottomLayer(); }
  824. nsStyleImageLayers mImage;
  825. nscolor mBackgroundColor; // [reset]
  826. };
  827. #define NS_SPACING_MARGIN 0
  828. #define NS_SPACING_PADDING 1
  829. #define NS_SPACING_BORDER 2
  830. struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleMargin
  831. {
  832. explicit nsStyleMargin(StyleStructContext aContext);
  833. nsStyleMargin(const nsStyleMargin& aMargin);
  834. ~nsStyleMargin() {
  835. MOZ_COUNT_DTOR(nsStyleMargin);
  836. }
  837. void FinishStyle(nsPresContext* aPresContext) {}
  838. void* operator new(size_t sz, nsStyleMargin* aSelf) { return aSelf; }
  839. void* operator new(size_t sz, nsPresContext* aContext) {
  840. return aContext->PresShell()->
  841. AllocateByObjectID(mozilla::eArenaObjectID_nsStyleMargin, sz);
  842. }
  843. void Destroy(nsPresContext* aContext);
  844. nsChangeHint CalcDifference(const nsStyleMargin& aNewData) const;
  845. static nsChangeHint MaxDifference() {
  846. return nsChangeHint_NeedReflow |
  847. nsChangeHint_ReflowChangesSizeOrPosition |
  848. nsChangeHint_ClearAncestorIntrinsics;
  849. }
  850. static nsChangeHint DifferenceAlwaysHandledForDescendants() {
  851. // CalcDifference can return all of the reflow hints sometimes not
  852. // handled for descendants as hints not handled for descendants.
  853. return nsChangeHint(0);
  854. }
  855. bool GetMargin(nsMargin& aMargin) const
  856. {
  857. if (!mMargin.ConvertsToLength()) {
  858. return false;
  859. }
  860. NS_FOR_CSS_SIDES(side) {
  861. aMargin.Side(side) = mMargin.ToLength(side);
  862. }
  863. return true;
  864. }
  865. // Return true if either the start or end side in the axis is 'auto'.
  866. // (defined in WritingModes.h since we need the full WritingMode type)
  867. inline bool HasBlockAxisAuto(mozilla::WritingMode aWM) const;
  868. inline bool HasInlineAxisAuto(mozilla::WritingMode aWM) const;
  869. nsStyleSides mMargin; // [reset] coord, percent, calc, auto
  870. };
  871. struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStylePadding
  872. {
  873. explicit nsStylePadding(StyleStructContext aContext);
  874. nsStylePadding(const nsStylePadding& aPadding);
  875. ~nsStylePadding() {
  876. MOZ_COUNT_DTOR(nsStylePadding);
  877. }
  878. void FinishStyle(nsPresContext* aPresContext) {}
  879. void* operator new(size_t sz, nsStylePadding* aSelf) { return aSelf; }
  880. void* operator new(size_t sz, nsPresContext* aContext) {
  881. return aContext->PresShell()->
  882. AllocateByObjectID(mozilla::eArenaObjectID_nsStylePadding, sz);
  883. }
  884. void Destroy(nsPresContext* aContext);
  885. nsChangeHint CalcDifference(const nsStylePadding& aNewData) const;
  886. static nsChangeHint MaxDifference() {
  887. return NS_STYLE_HINT_REFLOW & ~nsChangeHint_ClearDescendantIntrinsics;
  888. }
  889. static nsChangeHint DifferenceAlwaysHandledForDescendants() {
  890. // CalcDifference can return nsChangeHint_ClearAncestorIntrinsics as
  891. // a hint not handled for descendants. We could (and perhaps
  892. // should) return nsChangeHint_NeedReflow and
  893. // nsChangeHint_ReflowChangesSizeOrPosition as always handled for
  894. // descendants, but since they're always returned in conjunction
  895. // with nsChangeHint_ClearAncestorIntrinsics (which is not), it
  896. // won't ever lead to any optimization in
  897. // nsStyleContext::CalcStyleDifference.
  898. return nsChangeHint(0);
  899. }
  900. nsStyleSides mPadding; // [reset] coord, percent, calc
  901. bool IsWidthDependent() const {
  902. return !mPadding.ConvertsToLength();
  903. }
  904. bool GetPadding(nsMargin& aPadding) const
  905. {
  906. if (!mPadding.ConvertsToLength()) {
  907. return false;
  908. }
  909. NS_FOR_CSS_SIDES(side) {
  910. // Clamp negative calc() to 0.
  911. aPadding.Side(side) = std::max(mPadding.ToLength(side), 0);
  912. }
  913. return true;
  914. }
  915. };
  916. struct nsBorderColors
  917. {
  918. nsBorderColors* mNext;
  919. nscolor mColor;
  920. nsBorderColors() : mNext(nullptr), mColor(NS_RGB(0,0,0)) {}
  921. explicit nsBorderColors(const nscolor& aColor) : mNext(nullptr), mColor(aColor) {}
  922. ~nsBorderColors();
  923. nsBorderColors* Clone() const { return Clone(true); }
  924. static bool Equal(const nsBorderColors* c1,
  925. const nsBorderColors* c2) {
  926. if (c1 == c2) {
  927. return true;
  928. }
  929. while (c1 && c2) {
  930. if (c1->mColor != c2->mColor) {
  931. return false;
  932. }
  933. c1 = c1->mNext;
  934. c2 = c2->mNext;
  935. }
  936. // both should be nullptr if these are equal, otherwise one
  937. // has more colors than another
  938. return !c1 && !c2;
  939. }
  940. private:
  941. nsBorderColors* Clone(bool aDeep) const;
  942. };
  943. struct nsCSSShadowItem
  944. {
  945. nscoord mXOffset;
  946. nscoord mYOffset;
  947. nscoord mRadius;
  948. nscoord mSpread;
  949. nscolor mColor;
  950. bool mHasColor; // Whether mColor should be used
  951. bool mInset;
  952. nsCSSShadowItem() : mHasColor(false) {
  953. MOZ_COUNT_CTOR(nsCSSShadowItem);
  954. }
  955. ~nsCSSShadowItem() {
  956. MOZ_COUNT_DTOR(nsCSSShadowItem);
  957. }
  958. bool operator==(const nsCSSShadowItem& aOther) const {
  959. return (mXOffset == aOther.mXOffset &&
  960. mYOffset == aOther.mYOffset &&
  961. mRadius == aOther.mRadius &&
  962. mHasColor == aOther.mHasColor &&
  963. mSpread == aOther.mSpread &&
  964. mInset == aOther.mInset &&
  965. (!mHasColor || mColor == aOther.mColor));
  966. }
  967. bool operator!=(const nsCSSShadowItem& aOther) const {
  968. return !(*this == aOther);
  969. }
  970. };
  971. class nsCSSShadowArray final
  972. {
  973. public:
  974. void* operator new(size_t aBaseSize, uint32_t aArrayLen) {
  975. // We can allocate both this nsCSSShadowArray and the
  976. // actual array in one allocation. The amount of memory to
  977. // allocate is equal to the class's size + the number of bytes for all
  978. // but the first array item (because aBaseSize includes one
  979. // item, see the private declarations)
  980. return ::operator new(aBaseSize +
  981. (aArrayLen - 1) * sizeof(nsCSSShadowItem));
  982. }
  983. explicit nsCSSShadowArray(uint32_t aArrayLen) :
  984. mLength(aArrayLen)
  985. {
  986. MOZ_COUNT_CTOR(nsCSSShadowArray);
  987. for (uint32_t i = 1; i < mLength; ++i) {
  988. // Make sure we call the constructors of each nsCSSShadowItem
  989. // (the first one is called for us because we declared it under private)
  990. new (&mArray[i]) nsCSSShadowItem();
  991. }
  992. }
  993. private:
  994. // Private destructor, to discourage deletion outside of Release():
  995. ~nsCSSShadowArray() {
  996. MOZ_COUNT_DTOR(nsCSSShadowArray);
  997. for (uint32_t i = 1; i < mLength; ++i) {
  998. mArray[i].~nsCSSShadowItem();
  999. }
  1000. }
  1001. public:
  1002. uint32_t Length() const { return mLength; }
  1003. nsCSSShadowItem* ShadowAt(uint32_t i) {
  1004. MOZ_ASSERT(i < mLength, "Accessing too high an index in the text shadow array!");
  1005. return &mArray[i];
  1006. }
  1007. const nsCSSShadowItem* ShadowAt(uint32_t i) const {
  1008. MOZ_ASSERT(i < mLength, "Accessing too high an index in the text shadow array!");
  1009. return &mArray[i];
  1010. }
  1011. bool HasShadowWithInset(bool aInset) {
  1012. for (uint32_t i = 0; i < mLength; ++i) {
  1013. if (mArray[i].mInset == aInset) {
  1014. return true;
  1015. }
  1016. }
  1017. return false;
  1018. }
  1019. bool operator==(const nsCSSShadowArray& aOther) const {
  1020. if (mLength != aOther.Length()) {
  1021. return false;
  1022. }
  1023. for (uint32_t i = 0; i < mLength; ++i) {
  1024. if (ShadowAt(i) != aOther.ShadowAt(i)) {
  1025. return false;
  1026. }
  1027. }
  1028. return true;
  1029. }
  1030. NS_INLINE_DECL_THREADSAFE_REFCOUNTING(nsCSSShadowArray)
  1031. private:
  1032. uint32_t mLength;
  1033. nsCSSShadowItem mArray[1]; // This MUST be the last item
  1034. };
  1035. // Border widths are rounded to the nearest integer number of pixels, but values
  1036. // between zero and one device pixels are always rounded up to one device pixel.
  1037. #define NS_ROUND_BORDER_TO_PIXELS(l,tpp) \
  1038. ((l) == 0) ? 0 : std::max((tpp), ((l) + ((tpp) / 2)) / (tpp) * (tpp))
  1039. // Caret widths are rounded to the nearest-below integer number of pixels, but values
  1040. // between zero and one device pixels are always rounded up to one device pixel.
  1041. #define NS_ROUND_CARET_TO_PIXELS(l,tpp) \
  1042. ((l) == 0) ? 0 : std::max((tpp), (l) / (tpp) * (tpp))
  1043. // Outline offset is rounded to the nearest integer number of pixels, but values
  1044. // between zero and one device pixels are always rounded up to one device pixel.
  1045. // Note that the offset can be negative.
  1046. #define NS_ROUND_OFFSET_TO_PIXELS(l,tpp) \
  1047. (((l) == 0) ? 0 : \
  1048. ((l) > 0) ? std::max( (tpp), ((l) + ((tpp) / 2)) / (tpp) * (tpp)) : \
  1049. std::min(-(tpp), ((l) - ((tpp) / 2)) / (tpp) * (tpp)))
  1050. // Returns if the given border style type is visible or not
  1051. static bool IsVisibleBorderStyle(uint8_t aStyle)
  1052. {
  1053. return (aStyle != NS_STYLE_BORDER_STYLE_NONE &&
  1054. aStyle != NS_STYLE_BORDER_STYLE_HIDDEN);
  1055. }
  1056. struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleBorder
  1057. {
  1058. explicit nsStyleBorder(StyleStructContext aContext);
  1059. nsStyleBorder(const nsStyleBorder& aBorder);
  1060. ~nsStyleBorder();
  1061. // Resolves and tracks mBorderImageSource. Only called with a Servo-backed
  1062. // style system, where those images must be resolved later than the OMT
  1063. // nsStyleBorder constructor call.
  1064. void FinishStyle(nsPresContext* aPresContext);
  1065. void* operator new(size_t sz, nsStyleBorder* aSelf) { return aSelf; }
  1066. void* operator new(size_t sz, nsPresContext* aContext) {
  1067. return aContext->PresShell()->
  1068. AllocateByObjectID(mozilla::eArenaObjectID_nsStyleBorder, sz);
  1069. }
  1070. void Destroy(nsPresContext* aContext);
  1071. nsChangeHint CalcDifference(const nsStyleBorder& aNewData) const;
  1072. static nsChangeHint MaxDifference() {
  1073. return NS_STYLE_HINT_REFLOW |
  1074. nsChangeHint_UpdateOverflow |
  1075. nsChangeHint_BorderStyleNoneChange |
  1076. nsChangeHint_NeutralChange;
  1077. }
  1078. static nsChangeHint DifferenceAlwaysHandledForDescendants() {
  1079. // CalcDifference never returns the reflow hints that are sometimes
  1080. // handled for descendants as hints not handled for descendants.
  1081. return nsChangeHint_NeedReflow |
  1082. nsChangeHint_ReflowChangesSizeOrPosition |
  1083. nsChangeHint_ClearAncestorIntrinsics;
  1084. }
  1085. void EnsureBorderColors() {
  1086. if (!mBorderColors) {
  1087. mBorderColors = new nsBorderColors*[4];
  1088. if (mBorderColors) {
  1089. for (int32_t i = 0; i < 4; i++) {
  1090. mBorderColors[i] = nullptr;
  1091. }
  1092. }
  1093. }
  1094. }
  1095. void ClearBorderColors(mozilla::css::Side aSide) {
  1096. if (mBorderColors && mBorderColors[aSide]) {
  1097. delete mBorderColors[aSide];
  1098. mBorderColors[aSide] = nullptr;
  1099. }
  1100. }
  1101. // Return whether aStyle is a visible style. Invisible styles cause
  1102. // the relevant computed border width to be 0.
  1103. // Note that this does *not* consider the effects of 'border-image':
  1104. // if border-style is none, but there is a loaded border image,
  1105. // HasVisibleStyle will be false even though there *is* a border.
  1106. bool HasVisibleStyle(mozilla::css::Side aSide) const
  1107. {
  1108. return IsVisibleBorderStyle(mBorderStyle[aSide]);
  1109. }
  1110. // aBorderWidth is in twips
  1111. void SetBorderWidth(mozilla::css::Side aSide, nscoord aBorderWidth)
  1112. {
  1113. nscoord roundedWidth =
  1114. NS_ROUND_BORDER_TO_PIXELS(aBorderWidth, mTwipsPerPixel);
  1115. mBorder.Side(aSide) = roundedWidth;
  1116. if (HasVisibleStyle(aSide)) {
  1117. mComputedBorder.Side(aSide) = roundedWidth;
  1118. }
  1119. }
  1120. // Get the computed border (plus rounding). This does consider the
  1121. // effects of 'border-style: none', but does not consider
  1122. // 'border-image'.
  1123. const nsMargin& GetComputedBorder() const
  1124. {
  1125. return mComputedBorder;
  1126. }
  1127. bool HasBorder() const
  1128. {
  1129. return mComputedBorder != nsMargin(0,0,0,0) || !mBorderImageSource.IsEmpty();
  1130. }
  1131. // Get the actual border width for a particular side, in appunits. Note that
  1132. // this is zero if and only if there is no border to be painted for this
  1133. // side. That is, this value takes into account the border style and the
  1134. // value is rounded to the nearest device pixel by NS_ROUND_BORDER_TO_PIXELS.
  1135. nscoord GetComputedBorderWidth(mozilla::css::Side aSide) const
  1136. {
  1137. return GetComputedBorder().Side(aSide);
  1138. }
  1139. uint8_t GetBorderStyle(mozilla::css::Side aSide) const
  1140. {
  1141. NS_ASSERTION(aSide <= NS_SIDE_LEFT, "bad side");
  1142. return mBorderStyle[aSide];
  1143. }
  1144. void SetBorderStyle(mozilla::css::Side aSide, uint8_t aStyle)
  1145. {
  1146. NS_ASSERTION(aSide <= NS_SIDE_LEFT, "bad side");
  1147. mBorderStyle[aSide] = aStyle;
  1148. mComputedBorder.Side(aSide) =
  1149. (HasVisibleStyle(aSide) ? mBorder.Side(aSide) : 0);
  1150. }
  1151. inline bool IsBorderImageLoaded() const
  1152. {
  1153. return mBorderImageSource.IsLoaded();
  1154. }
  1155. void ResolveImage(nsPresContext* aContext)
  1156. {
  1157. if (mBorderImageSource.GetType() == eStyleImageType_Image) {
  1158. mBorderImageSource.ResolveImage(aContext);
  1159. }
  1160. }
  1161. nsMargin GetImageOutset() const;
  1162. void GetCompositeColors(int32_t aIndex, nsBorderColors** aColors) const
  1163. {
  1164. if (!mBorderColors) {
  1165. *aColors = nullptr;
  1166. } else {
  1167. *aColors = mBorderColors[aIndex];
  1168. }
  1169. }
  1170. void AppendBorderColor(int32_t aIndex, nscolor aColor)
  1171. {
  1172. NS_ASSERTION(aIndex >= 0 && aIndex <= 3, "bad side for composite border color");
  1173. nsBorderColors* colorEntry = new nsBorderColors(aColor);
  1174. if (!mBorderColors[aIndex]) {
  1175. mBorderColors[aIndex] = colorEntry;
  1176. } else {
  1177. nsBorderColors* last = mBorderColors[aIndex];
  1178. while (last->mNext) {
  1179. last = last->mNext;
  1180. }
  1181. last->mNext = colorEntry;
  1182. }
  1183. }
  1184. imgIRequest* GetBorderImageRequest() const
  1185. {
  1186. if (mBorderImageSource.GetType() == eStyleImageType_Image) {
  1187. return mBorderImageSource.GetImageData();
  1188. }
  1189. return nullptr;
  1190. }
  1191. public:
  1192. nsBorderColors** mBorderColors; // [reset] composite (stripe) colors
  1193. nsStyleCorners mBorderRadius; // [reset] coord, percent
  1194. nsStyleImage mBorderImageSource; // [reset]
  1195. nsStyleSides mBorderImageSlice; // [reset] factor, percent
  1196. nsStyleSides mBorderImageWidth; // [reset] length, factor, percent, auto
  1197. nsStyleSides mBorderImageOutset; // [reset] length, factor
  1198. uint8_t mBorderImageFill; // [reset]
  1199. uint8_t mBorderImageRepeatH; // [reset] see nsStyleConsts.h
  1200. uint8_t mBorderImageRepeatV; // [reset]
  1201. mozilla::StyleFloatEdge mFloatEdge; // [reset]
  1202. mozilla::StyleBoxDecorationBreak mBoxDecorationBreak; // [reset]
  1203. protected:
  1204. uint8_t mBorderStyle[4]; // [reset] See nsStyleConsts.h
  1205. public:
  1206. // [reset] the colors to use for a simple border.
  1207. // not used for -moz-border-colors
  1208. union {
  1209. struct {
  1210. mozilla::StyleComplexColor mBorderTopColor;
  1211. mozilla::StyleComplexColor mBorderRightColor;
  1212. mozilla::StyleComplexColor mBorderBottomColor;
  1213. mozilla::StyleComplexColor mBorderLeftColor;
  1214. };
  1215. mozilla::StyleComplexColor mBorderColor[4];
  1216. };
  1217. protected:
  1218. // mComputedBorder holds the CSS2.1 computed border-width values.
  1219. // In particular, these widths take into account the border-style
  1220. // for the relevant side, and the values are rounded to the nearest
  1221. // device pixel (which is not part of the definition of computed
  1222. // values). The presence or absence of a border-image does not
  1223. // affect border-width values.
  1224. nsMargin mComputedBorder;
  1225. // mBorder holds the nscoord values for the border widths as they
  1226. // would be if all the border-style values were visible (not hidden
  1227. // or none). This member exists so that when we create structs
  1228. // using the copy constructor during style resolution the new
  1229. // structs will know what the specified values of the border were in
  1230. // case they have more specific rules setting the border style.
  1231. //
  1232. // Note that this isn't quite the CSS specified value, since this
  1233. // has had the enumerated border widths converted to lengths, and
  1234. // all lengths converted to twips. But it's not quite the computed
  1235. // value either. The values are rounded to the nearest device pixel.
  1236. nsMargin mBorder;
  1237. private:
  1238. nscoord mTwipsPerPixel;
  1239. nsStyleBorder& operator=(const nsStyleBorder& aOther) = delete;
  1240. };
  1241. #define ASSERT_BORDER_COLOR_FIELD(side_) \
  1242. static_assert(offsetof(nsStyleBorder, mBorder##side_##Color) == \
  1243. offsetof(nsStyleBorder, mBorderColor) + \
  1244. size_t(mozilla::eSide##side_) * \
  1245. sizeof(mozilla::StyleComplexColor), \
  1246. "mBorder" #side_ "Color must be at same offset " \
  1247. "as mBorderColor[mozilla::eSide" #side_ "]")
  1248. ASSERT_BORDER_COLOR_FIELD(Top);
  1249. ASSERT_BORDER_COLOR_FIELD(Right);
  1250. ASSERT_BORDER_COLOR_FIELD(Bottom);
  1251. ASSERT_BORDER_COLOR_FIELD(Left);
  1252. #undef ASSERT_BORDER_COLOR_FIELD
  1253. struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleOutline
  1254. {
  1255. explicit nsStyleOutline(StyleStructContext aContext);
  1256. nsStyleOutline(const nsStyleOutline& aOutline);
  1257. ~nsStyleOutline() {
  1258. MOZ_COUNT_DTOR(nsStyleOutline);
  1259. }
  1260. void FinishStyle(nsPresContext* aPresContext) {}
  1261. void* operator new(size_t sz, nsStyleOutline* aSelf) { return aSelf; }
  1262. void* operator new(size_t sz, nsPresContext* aContext) {
  1263. return aContext->PresShell()->
  1264. AllocateByObjectID(mozilla::eArenaObjectID_nsStyleOutline, sz);
  1265. }
  1266. void Destroy(nsPresContext* aContext) {
  1267. this->~nsStyleOutline();
  1268. aContext->PresShell()->
  1269. FreeByObjectID(mozilla::eArenaObjectID_nsStyleOutline, this);
  1270. }
  1271. void RecalcData();
  1272. nsChangeHint CalcDifference(const nsStyleOutline& aNewData) const;
  1273. static nsChangeHint MaxDifference() {
  1274. return nsChangeHint_UpdateOverflow |
  1275. nsChangeHint_SchedulePaint |
  1276. nsChangeHint_RepaintFrame |
  1277. nsChangeHint_NeutralChange;
  1278. }
  1279. static nsChangeHint DifferenceAlwaysHandledForDescendants() {
  1280. // CalcDifference never returns the reflow hints that are sometimes
  1281. // handled for descendants at all.
  1282. return nsChangeHint(0);
  1283. }
  1284. nsStyleCorners mOutlineRadius; // [reset] coord, percent, calc
  1285. // This is the specified value of outline-width, but with length values
  1286. // computed to absolute. mActualOutlineWidth stores the outline-width
  1287. // value used by layout. (We must store mOutlineWidth for the same
  1288. // style struct resolution reasons that we do nsStyleBorder::mBorder;
  1289. // see that field's comment.)
  1290. nsStyleCoord mOutlineWidth; // [reset] coord, enum (see nsStyleConsts.h)
  1291. nscoord mOutlineOffset; // [reset]
  1292. mozilla::StyleComplexColor mOutlineColor; // [reset]
  1293. uint8_t mOutlineStyle; // [reset] See nsStyleConsts.h
  1294. nscoord GetOutlineWidth() const
  1295. {
  1296. return mActualOutlineWidth;
  1297. }
  1298. protected:
  1299. // The actual value of outline-width is the computed value (an absolute
  1300. // length, forced to zero when outline-style is none) rounded to device
  1301. // pixels. This is the value used by layout.
  1302. nscoord mActualOutlineWidth;
  1303. nscoord mTwipsPerPixel;
  1304. };
  1305. /**
  1306. * An object that allows sharing of arrays that store 'quotes' property
  1307. * values. This is particularly important for inheritance, where we want
  1308. * to share the same 'quotes' value with a parent style context.
  1309. */
  1310. class nsStyleQuoteValues
  1311. {
  1312. public:
  1313. typedef nsTArray<std::pair<nsString, nsString>> QuotePairArray;
  1314. NS_INLINE_DECL_THREADSAFE_REFCOUNTING(nsStyleQuoteValues);
  1315. QuotePairArray mQuotePairs;
  1316. private:
  1317. ~nsStyleQuoteValues() {}
  1318. };
  1319. struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleList
  1320. {
  1321. explicit nsStyleList(StyleStructContext aContext);
  1322. nsStyleList(const nsStyleList& aStyleList);
  1323. ~nsStyleList();
  1324. void FinishStyle(nsPresContext* aPresContext);
  1325. void* operator new(size_t sz, nsStyleList* aSelf) { return aSelf; }
  1326. void* operator new(size_t sz, nsPresContext* aContext) {
  1327. return aContext->PresShell()->
  1328. AllocateByObjectID(mozilla::eArenaObjectID_nsStyleList, sz);
  1329. }
  1330. void Destroy(nsPresContext* aContext) {
  1331. this->~nsStyleList();
  1332. aContext->PresShell()->
  1333. FreeByObjectID(mozilla::eArenaObjectID_nsStyleList, this);
  1334. }
  1335. nsChangeHint CalcDifference(const nsStyleList& aNewData) const;
  1336. static nsChangeHint MaxDifference() {
  1337. return nsChangeHint_ReconstructFrame |
  1338. NS_STYLE_HINT_REFLOW;
  1339. }
  1340. static nsChangeHint DifferenceAlwaysHandledForDescendants() {
  1341. // CalcDifference never returns the reflow hints that are sometimes
  1342. // handled for descendants as hints not handled for descendants.
  1343. return nsChangeHint_NeedReflow |
  1344. nsChangeHint_ReflowChangesSizeOrPosition |
  1345. nsChangeHint_ClearAncestorIntrinsics;
  1346. }
  1347. static void Shutdown() {
  1348. sInitialQuotes = nullptr;
  1349. sNoneQuotes = nullptr;
  1350. }
  1351. imgRequestProxy* GetListStyleImage() const
  1352. {
  1353. return mListStyleImage ? mListStyleImage->get() : nullptr;
  1354. }
  1355. void GetListStyleType(nsSubstring& aType) const { mCounterStyle->GetStyleName(aType); }
  1356. mozilla::CounterStyle* GetCounterStyle() const
  1357. {
  1358. return mCounterStyle.get();
  1359. }
  1360. void SetCounterStyle(mozilla::CounterStyle* aStyle)
  1361. {
  1362. // NB: This function is called off-main-thread during parallel restyle, but
  1363. // only with builtin styles that use dummy refcounting.
  1364. MOZ_ASSERT(NS_IsMainThread() || !aStyle->IsDependentStyle());
  1365. mCounterStyle = aStyle;
  1366. }
  1367. void SetListStyleType(const nsSubstring& aType,
  1368. nsPresContext* aPresContext)
  1369. {
  1370. SetCounterStyle(aPresContext->CounterStyleManager()->BuildCounterStyle(aType));
  1371. }
  1372. const nsStyleQuoteValues::QuotePairArray& GetQuotePairs() const;
  1373. void SetQuotesInherit(const nsStyleList* aOther);
  1374. void SetQuotesInitial();
  1375. void SetQuotesNone();
  1376. void SetQuotes(nsStyleQuoteValues::QuotePairArray&& aValues);
  1377. uint8_t mListStylePosition; // [inherited]
  1378. RefPtr<nsStyleImageRequest> mListStyleImage; // [inherited]
  1379. private:
  1380. RefPtr<mozilla::CounterStyle> mCounterStyle; // [inherited]
  1381. RefPtr<nsStyleQuoteValues> mQuotes; // [inherited]
  1382. nsStyleList& operator=(const nsStyleList& aOther) = delete;
  1383. public:
  1384. nsRect mImageRegion; // [inherited] the rect to use within an image
  1385. private:
  1386. // nsStyleQuoteValues objects representing two common values, for sharing.
  1387. static mozilla::StaticRefPtr<nsStyleQuoteValues> sInitialQuotes;
  1388. static mozilla::StaticRefPtr<nsStyleQuoteValues> sNoneQuotes;
  1389. };
  1390. struct nsStyleGridLine
  1391. {
  1392. // http://dev.w3.org/csswg/css-grid/#typedef-grid-line
  1393. // XXXmats we could optimize memory size here
  1394. bool mHasSpan;
  1395. int32_t mInteger; // 0 means not provided
  1396. nsString mLineName; // Empty string means not provided.
  1397. // These are the limits that we choose to clamp grid line numbers to.
  1398. // http://dev.w3.org/csswg/css-grid/#overlarge-grids
  1399. // mInteger is clamped to this range:
  1400. static const int32_t kMinLine = -10000;
  1401. static const int32_t kMaxLine = 10000;
  1402. nsStyleGridLine()
  1403. : mHasSpan(false)
  1404. , mInteger(0)
  1405. // mLineName get its default constructor, the empty string
  1406. {
  1407. }
  1408. nsStyleGridLine(const nsStyleGridLine& aOther)
  1409. {
  1410. (*this) = aOther;
  1411. }
  1412. void operator=(const nsStyleGridLine& aOther)
  1413. {
  1414. mHasSpan = aOther.mHasSpan;
  1415. mInteger = aOther.mInteger;
  1416. mLineName = aOther.mLineName;
  1417. }
  1418. bool operator!=(const nsStyleGridLine& aOther) const
  1419. {
  1420. return mHasSpan != aOther.mHasSpan ||
  1421. mInteger != aOther.mInteger ||
  1422. mLineName != aOther.mLineName;
  1423. }
  1424. void SetToInteger(uint32_t value)
  1425. {
  1426. mHasSpan = false;
  1427. mInteger = value;
  1428. mLineName.Truncate();
  1429. }
  1430. void SetAuto()
  1431. {
  1432. mHasSpan = false;
  1433. mInteger = 0;
  1434. mLineName.Truncate();
  1435. }
  1436. bool IsAuto() const
  1437. {
  1438. bool haveInitialValues = mInteger == 0 && mLineName.IsEmpty();
  1439. MOZ_ASSERT(!(haveInitialValues && mHasSpan),
  1440. "should not have 'span' when other components are "
  1441. "at their initial values");
  1442. return haveInitialValues;
  1443. }
  1444. };
  1445. // Computed value of the grid-template-columns or grid-template-rows property
  1446. // (but *not* grid-template-areas.)
  1447. // http://dev.w3.org/csswg/css-grid/#track-sizing
  1448. //
  1449. // This represents either:
  1450. // * none:
  1451. // mIsSubgrid is false, all three arrays are empty
  1452. // * <track-list>:
  1453. // mIsSubgrid is false,
  1454. // mMinTrackSizingFunctions and mMaxTrackSizingFunctions
  1455. // are of identical non-zero size,
  1456. // and mLineNameLists is one element longer than that.
  1457. // (Delimiting N columns requires N+1 lines:
  1458. // one before each track, plus one at the very end.)
  1459. //
  1460. // An omitted <line-names> is still represented in mLineNameLists,
  1461. // as an empty sub-array.
  1462. //
  1463. // A <track-size> specified as a single <track-breadth> is represented
  1464. // as identical min and max sizing functions.
  1465. // A 'fit-content(size)' <track-size> is represented as eStyleUnit_None
  1466. // in the min sizing function and 'size' in the max sizing function.
  1467. //
  1468. // The units for nsStyleCoord are:
  1469. // * eStyleUnit_Percent represents a <percentage>
  1470. // * eStyleUnit_FlexFraction represents a <flex> flexible fraction
  1471. // * eStyleUnit_Coord represents a <length>
  1472. // * eStyleUnit_Enumerated represents min-content or max-content
  1473. // * subgrid <line-name-list>?:
  1474. // mIsSubgrid is true,
  1475. // mLineNameLists may or may not be empty,
  1476. // mMinTrackSizingFunctions and mMaxTrackSizingFunctions are empty.
  1477. //
  1478. // If mRepeatAutoIndex != -1 then that index is an <auto-repeat> and
  1479. // mIsAutoFill == true means it's an 'auto-fill', otherwise 'auto-fit'.
  1480. // mRepeatAutoLineNameListBefore is the list of line names before the track
  1481. // size, mRepeatAutoLineNameListAfter the names after. (They are empty
  1482. // when there is no <auto-repeat> track, i.e. when mRepeatAutoIndex == -1).
  1483. // When mIsSubgrid is true, mRepeatAutoLineNameListBefore contains the line
  1484. // names and mRepeatAutoLineNameListAfter is empty.
  1485. struct nsStyleGridTemplate
  1486. {
  1487. nsTArray<nsTArray<nsString>> mLineNameLists;
  1488. nsTArray<nsStyleCoord> mMinTrackSizingFunctions;
  1489. nsTArray<nsStyleCoord> mMaxTrackSizingFunctions;
  1490. nsTArray<nsString> mRepeatAutoLineNameListBefore;
  1491. nsTArray<nsString> mRepeatAutoLineNameListAfter;
  1492. int16_t mRepeatAutoIndex; // -1 or the track index for an auto-fill/fit track
  1493. bool mIsAutoFill : 1;
  1494. bool mIsSubgrid : 1;
  1495. nsStyleGridTemplate()
  1496. : mRepeatAutoIndex(-1)
  1497. , mIsAutoFill(false)
  1498. , mIsSubgrid(false)
  1499. {
  1500. }
  1501. inline bool operator!=(const nsStyleGridTemplate& aOther) const {
  1502. return
  1503. mIsSubgrid != aOther.mIsSubgrid ||
  1504. mLineNameLists != aOther.mLineNameLists ||
  1505. mMinTrackSizingFunctions != aOther.mMinTrackSizingFunctions ||
  1506. mMaxTrackSizingFunctions != aOther.mMaxTrackSizingFunctions ||
  1507. mIsAutoFill != aOther.mIsAutoFill ||
  1508. mRepeatAutoIndex != aOther.mRepeatAutoIndex ||
  1509. mRepeatAutoLineNameListBefore != aOther.mRepeatAutoLineNameListBefore ||
  1510. mRepeatAutoLineNameListAfter != aOther.mRepeatAutoLineNameListAfter;
  1511. }
  1512. bool HasRepeatAuto() const {
  1513. return mRepeatAutoIndex != -1;
  1514. }
  1515. bool IsRepeatAutoIndex(uint32_t aIndex) const {
  1516. MOZ_ASSERT(aIndex < uint32_t(2*nsStyleGridLine::kMaxLine));
  1517. return int32_t(aIndex) == mRepeatAutoIndex;
  1518. }
  1519. };
  1520. struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStylePosition
  1521. {
  1522. explicit nsStylePosition(StyleStructContext aContext);
  1523. nsStylePosition(const nsStylePosition& aOther);
  1524. ~nsStylePosition();
  1525. void FinishStyle(nsPresContext* aPresContext) {}
  1526. void* operator new(size_t sz, nsStylePosition* aSelf) { return aSelf; }
  1527. void* operator new(size_t sz, nsPresContext* aContext) {
  1528. return aContext->PresShell()->
  1529. AllocateByObjectID(mozilla::eArenaObjectID_nsStylePosition, sz);
  1530. }
  1531. void Destroy(nsPresContext* aContext) {
  1532. this->~nsStylePosition();
  1533. aContext->PresShell()->
  1534. FreeByObjectID(mozilla::eArenaObjectID_nsStylePosition, this);
  1535. }
  1536. nsChangeHint CalcDifference(const nsStylePosition& aNewData,
  1537. const nsStyleVisibility* aOldStyleVisibility) const;
  1538. static nsChangeHint MaxDifference() {
  1539. return NS_STYLE_HINT_REFLOW |
  1540. nsChangeHint_NeutralChange |
  1541. nsChangeHint_RecomputePosition |
  1542. nsChangeHint_UpdateParentOverflow |
  1543. nsChangeHint_UpdateComputedBSize;
  1544. }
  1545. static nsChangeHint DifferenceAlwaysHandledForDescendants() {
  1546. // CalcDifference can return all of the reflow hints that are
  1547. // sometimes handled for descendants as hints not handled for
  1548. // descendants.
  1549. return nsChangeHint(0);
  1550. }
  1551. /**
  1552. * Return the used value for 'align-self' given our parent StyleContext
  1553. * aParent (or null for the root).
  1554. */
  1555. uint8_t UsedAlignSelf(nsStyleContext* aParent) const;
  1556. /**
  1557. * Return the computed value for 'justify-items' given our parent StyleContext
  1558. * aParent (or null for the root).
  1559. */
  1560. uint8_t ComputedJustifyItems(nsStyleContext* aParent) const;
  1561. /**
  1562. * Return the used value for 'justify-self' given our parent StyleContext
  1563. * aParent (or null for the root).
  1564. */
  1565. uint8_t UsedJustifySelf(nsStyleContext* aParent) const;
  1566. mozilla::Position mObjectPosition; // [reset]
  1567. nsStyleSides mOffset; // [reset] coord, percent, calc, auto
  1568. nsStyleCoord mWidth; // [reset] coord, percent, enum, calc, auto
  1569. nsStyleCoord mMinWidth; // [reset] coord, percent, enum, calc
  1570. nsStyleCoord mMaxWidth; // [reset] coord, percent, enum, calc, none
  1571. nsStyleCoord mHeight; // [reset] coord, percent, calc, auto
  1572. nsStyleCoord mMinHeight; // [reset] coord, percent, calc
  1573. nsStyleCoord mMaxHeight; // [reset] coord, percent, calc, none
  1574. nsStyleCoord mFlexBasis; // [reset] coord, percent, enum, calc, auto
  1575. nsStyleCoord mGridAutoColumnsMin; // [reset] coord, percent, enum, calc, flex
  1576. nsStyleCoord mGridAutoColumnsMax; // [reset] coord, percent, enum, calc, flex
  1577. nsStyleCoord mGridAutoRowsMin; // [reset] coord, percent, enum, calc, flex
  1578. nsStyleCoord mGridAutoRowsMax; // [reset] coord, percent, enum, calc, flex
  1579. float mAspectRatio; // [reset] float
  1580. uint8_t mGridAutoFlow; // [reset] enumerated. See nsStyleConsts.h
  1581. mozilla::StyleBoxSizing mBoxSizing; // [reset] see nsStyleConsts.h
  1582. uint16_t mAlignContent; // [reset] fallback value in the high byte
  1583. uint8_t mAlignItems; // [reset] see nsStyleConsts.h
  1584. uint8_t mAlignSelf; // [reset] see nsStyleConsts.h
  1585. uint16_t mJustifyContent; // [reset] fallback value in the high byte
  1586. private:
  1587. friend class nsRuleNode;
  1588. // mJustifyItems should only be read via ComputedJustifyItems(), which
  1589. // lazily resolves its "auto" value. nsRuleNode needs direct access so
  1590. // it can set mJustifyItems' value when populating this struct.
  1591. uint8_t mJustifyItems; // [reset] see nsStyleConsts.h
  1592. public:
  1593. uint8_t mJustifySelf; // [reset] see nsStyleConsts.h
  1594. uint8_t mFlexDirection; // [reset] see nsStyleConsts.h
  1595. uint8_t mFlexWrap; // [reset] see nsStyleConsts.h
  1596. uint8_t mObjectFit; // [reset] see nsStyleConsts.h
  1597. int32_t mOrder; // [reset] integer
  1598. float mFlexGrow; // [reset] float
  1599. float mFlexShrink; // [reset] float
  1600. nsStyleCoord mZIndex; // [reset] integer, auto
  1601. nsStyleGridTemplate mGridTemplateColumns;
  1602. nsStyleGridTemplate mGridTemplateRows;
  1603. // nullptr for 'none'
  1604. RefPtr<mozilla::css::GridTemplateAreasValue> mGridTemplateAreas;
  1605. nsStyleGridLine mGridColumnStart;
  1606. nsStyleGridLine mGridColumnEnd;
  1607. nsStyleGridLine mGridRowStart;
  1608. nsStyleGridLine mGridRowEnd;
  1609. nsStyleCoord mGridColumnGap; // [reset] coord, percent, calc
  1610. nsStyleCoord mGridRowGap; // [reset] coord, percent, calc
  1611. // FIXME: Logical-coordinate equivalents to these WidthDepends... and
  1612. // HeightDepends... methods have been introduced (see below); we probably
  1613. // want to work towards removing the physical methods, and using the logical
  1614. // ones in all cases.
  1615. bool WidthDependsOnContainer() const
  1616. {
  1617. return mWidth.GetUnit() == eStyleUnit_Auto ||
  1618. WidthCoordDependsOnContainer(mWidth);
  1619. }
  1620. // NOTE: For a flex item, "min-width:auto" is supposed to behave like
  1621. // "min-content", which does depend on the container, so you might think we'd
  1622. // need a special case for "flex item && min-width:auto" here. However,
  1623. // we don't actually need that special-case code, because flex items are
  1624. // explicitly supposed to *ignore* their min-width (i.e. behave like it's 0)
  1625. // until the flex container explicitly considers it. So -- since the flex
  1626. // container doesn't rely on this method, we don't need to worry about
  1627. // special behavior for flex items' "min-width:auto" values here.
  1628. bool MinWidthDependsOnContainer() const
  1629. { return WidthCoordDependsOnContainer(mMinWidth); }
  1630. bool MaxWidthDependsOnContainer() const
  1631. { return WidthCoordDependsOnContainer(mMaxWidth); }
  1632. // Note that these functions count 'auto' as depending on the
  1633. // container since that's the case for absolutely positioned elements.
  1634. // However, some callers do not care about this case and should check
  1635. // for it, since it is the most common case.
  1636. // FIXME: We should probably change the assumption to be the other way
  1637. // around.
  1638. // Consider this as part of moving to the logical-coordinate APIs.
  1639. bool HeightDependsOnContainer() const
  1640. {
  1641. return mHeight.GetUnit() == eStyleUnit_Auto || // CSS 2.1, 10.6.4, item (5)
  1642. HeightCoordDependsOnContainer(mHeight);
  1643. }
  1644. // NOTE: The comment above MinWidthDependsOnContainer about flex items
  1645. // applies here, too.
  1646. bool MinHeightDependsOnContainer() const
  1647. { return HeightCoordDependsOnContainer(mMinHeight); }
  1648. bool MaxHeightDependsOnContainer() const
  1649. { return HeightCoordDependsOnContainer(mMaxHeight); }
  1650. bool OffsetHasPercent(mozilla::css::Side aSide) const
  1651. {
  1652. return mOffset.Get(aSide).HasPercent();
  1653. }
  1654. // Logical-coordinate accessors for width and height properties,
  1655. // given a WritingMode value. The definitions of these methods are
  1656. // found in WritingModes.h (after the WritingMode class is fully
  1657. // declared).
  1658. inline nsStyleCoord& ISize(mozilla::WritingMode aWM);
  1659. inline nsStyleCoord& MinISize(mozilla::WritingMode aWM);
  1660. inline nsStyleCoord& MaxISize(mozilla::WritingMode aWM);
  1661. inline nsStyleCoord& BSize(mozilla::WritingMode aWM);
  1662. inline nsStyleCoord& MinBSize(mozilla::WritingMode aWM);
  1663. inline nsStyleCoord& MaxBSize(mozilla::WritingMode aWM);
  1664. inline const nsStyleCoord& ISize(mozilla::WritingMode aWM) const;
  1665. inline const nsStyleCoord& MinISize(mozilla::WritingMode aWM) const;
  1666. inline const nsStyleCoord& MaxISize(mozilla::WritingMode aWM) const;
  1667. inline const nsStyleCoord& BSize(mozilla::WritingMode aWM) const;
  1668. inline const nsStyleCoord& MinBSize(mozilla::WritingMode aWM) const;
  1669. inline const nsStyleCoord& MaxBSize(mozilla::WritingMode aWM) const;
  1670. inline bool ISizeDependsOnContainer(mozilla::WritingMode aWM) const;
  1671. inline bool MinISizeDependsOnContainer(mozilla::WritingMode aWM) const;
  1672. inline bool MaxISizeDependsOnContainer(mozilla::WritingMode aWM) const;
  1673. inline bool BSizeDependsOnContainer(mozilla::WritingMode aWM) const;
  1674. inline bool MinBSizeDependsOnContainer(mozilla::WritingMode aWM) const;
  1675. inline bool MaxBSizeDependsOnContainer(mozilla::WritingMode aWM) const;
  1676. private:
  1677. static bool WidthCoordDependsOnContainer(const nsStyleCoord &aCoord);
  1678. static bool HeightCoordDependsOnContainer(const nsStyleCoord &aCoord)
  1679. { return aCoord.HasPercent(); }
  1680. };
  1681. struct nsStyleTextOverflowSide
  1682. {
  1683. nsStyleTextOverflowSide() : mType(NS_STYLE_TEXT_OVERFLOW_CLIP) {}
  1684. bool operator==(const nsStyleTextOverflowSide& aOther) const {
  1685. return mType == aOther.mType &&
  1686. (mType != NS_STYLE_TEXT_OVERFLOW_STRING ||
  1687. mString == aOther.mString);
  1688. }
  1689. bool operator!=(const nsStyleTextOverflowSide& aOther) const {
  1690. return !(*this == aOther);
  1691. }
  1692. nsString mString;
  1693. uint8_t mType;
  1694. };
  1695. struct nsStyleTextOverflow
  1696. {
  1697. nsStyleTextOverflow() : mLogicalDirections(true) {}
  1698. bool operator==(const nsStyleTextOverflow& aOther) const {
  1699. return mLeft == aOther.mLeft && mRight == aOther.mRight;
  1700. }
  1701. bool operator!=(const nsStyleTextOverflow& aOther) const {
  1702. return !(*this == aOther);
  1703. }
  1704. // Returns the value to apply on the left side.
  1705. const nsStyleTextOverflowSide& GetLeft(uint8_t aDirection) const {
  1706. NS_ASSERTION(aDirection == NS_STYLE_DIRECTION_LTR ||
  1707. aDirection == NS_STYLE_DIRECTION_RTL, "bad direction");
  1708. return !mLogicalDirections || aDirection == NS_STYLE_DIRECTION_LTR ?
  1709. mLeft : mRight;
  1710. }
  1711. // Returns the value to apply on the right side.
  1712. const nsStyleTextOverflowSide& GetRight(uint8_t aDirection) const {
  1713. NS_ASSERTION(aDirection == NS_STYLE_DIRECTION_LTR ||
  1714. aDirection == NS_STYLE_DIRECTION_RTL, "bad direction");
  1715. return !mLogicalDirections || aDirection == NS_STYLE_DIRECTION_LTR ?
  1716. mRight : mLeft;
  1717. }
  1718. // Returns the first value that was specified.
  1719. const nsStyleTextOverflowSide* GetFirstValue() const {
  1720. return mLogicalDirections ? &mRight : &mLeft;
  1721. }
  1722. // Returns the second value, or null if there was only one value specified.
  1723. const nsStyleTextOverflowSide* GetSecondValue() const {
  1724. return mLogicalDirections ? nullptr : &mRight;
  1725. }
  1726. nsStyleTextOverflowSide mLeft; // start side when mLogicalDirections is true
  1727. nsStyleTextOverflowSide mRight; // end side when mLogicalDirections is true
  1728. bool mLogicalDirections; // true when only one value was specified
  1729. };
  1730. struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleTextReset
  1731. {
  1732. explicit nsStyleTextReset(StyleStructContext aContext);
  1733. nsStyleTextReset(const nsStyleTextReset& aOther);
  1734. ~nsStyleTextReset();
  1735. void FinishStyle(nsPresContext* aPresContext) {}
  1736. void* operator new(size_t sz, nsStyleTextReset* aSelf) { return aSelf; }
  1737. void* operator new(size_t sz, nsPresContext* aContext) {
  1738. return aContext->PresShell()->
  1739. AllocateByObjectID(mozilla::eArenaObjectID_nsStyleTextReset, sz);
  1740. }
  1741. void Destroy(nsPresContext* aContext) {
  1742. this->~nsStyleTextReset();
  1743. aContext->PresShell()->
  1744. FreeByObjectID(mozilla::eArenaObjectID_nsStyleTextReset, this);
  1745. }
  1746. // Note the difference between this and
  1747. // nsStyleContext::HasTextDecorationLines.
  1748. bool HasTextDecorationLines() const {
  1749. return mTextDecorationLine != NS_STYLE_TEXT_DECORATION_LINE_NONE &&
  1750. mTextDecorationLine != NS_STYLE_TEXT_DECORATION_LINE_OVERRIDE_ALL;
  1751. }
  1752. nsChangeHint CalcDifference(const nsStyleTextReset& aNewData) const;
  1753. static nsChangeHint MaxDifference() {
  1754. return nsChangeHint(
  1755. NS_STYLE_HINT_REFLOW |
  1756. nsChangeHint_UpdateSubtreeOverflow);
  1757. }
  1758. static nsChangeHint DifferenceAlwaysHandledForDescendants() {
  1759. // CalcDifference never returns the reflow hints that are sometimes
  1760. // handled for descendants as hints not handled for descendants.
  1761. return nsChangeHint_NeedReflow |
  1762. nsChangeHint_ReflowChangesSizeOrPosition |
  1763. nsChangeHint_ClearAncestorIntrinsics;
  1764. }
  1765. nsStyleTextOverflow mTextOverflow; // [reset] enum, string
  1766. uint8_t mTextDecorationLine; // [reset] see nsStyleConsts.h
  1767. uint8_t mTextDecorationStyle; // [reset] see nsStyleConsts.h
  1768. uint8_t mUnicodeBidi; // [reset] see nsStyleConsts.h
  1769. nscoord mInitialLetterSink; // [reset] 0 means normal
  1770. float mInitialLetterSize; // [reset] 0.0f means normal
  1771. mozilla::StyleComplexColor mTextDecorationColor; // [reset]
  1772. };
  1773. struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleText
  1774. {
  1775. explicit nsStyleText(StyleStructContext aContext);
  1776. nsStyleText(const nsStyleText& aOther);
  1777. ~nsStyleText();
  1778. void FinishStyle(nsPresContext* aPresContext) {}
  1779. void* operator new(size_t sz, nsStyleText* aSelf) { return aSelf; }
  1780. void* operator new(size_t sz, nsPresContext* aContext) {
  1781. return aContext->PresShell()->
  1782. AllocateByObjectID(mozilla::eArenaObjectID_nsStyleText, sz);
  1783. }
  1784. void Destroy(nsPresContext* aContext) {
  1785. this->~nsStyleText();
  1786. aContext->PresShell()->
  1787. FreeByObjectID(mozilla::eArenaObjectID_nsStyleText, this);
  1788. }
  1789. nsChangeHint CalcDifference(const nsStyleText& aNewData) const;
  1790. static nsChangeHint MaxDifference() {
  1791. return nsChangeHint_ReconstructFrame |
  1792. NS_STYLE_HINT_REFLOW |
  1793. nsChangeHint_UpdateSubtreeOverflow |
  1794. nsChangeHint_NeutralChange;
  1795. }
  1796. static nsChangeHint DifferenceAlwaysHandledForDescendants() {
  1797. // CalcDifference never returns the reflow hints that are sometimes
  1798. // handled for descendants as hints not handled for descendants.
  1799. return nsChangeHint_NeedReflow |
  1800. nsChangeHint_ReflowChangesSizeOrPosition |
  1801. nsChangeHint_ClearAncestorIntrinsics;
  1802. }
  1803. uint8_t mTextAlign; // [inherited] see nsStyleConsts.h
  1804. uint8_t mTextAlignLast; // [inherited] see nsStyleConsts.h
  1805. bool mTextAlignTrue : 1; // [inherited] see nsStyleConsts.h
  1806. bool mTextAlignLastTrue : 1; // [inherited] see nsStyleConsts.h
  1807. mozilla::StyleTextJustify mTextJustify; // [inherited]
  1808. uint8_t mTextTransform; // [inherited] see nsStyleConsts.h
  1809. uint8_t mWhiteSpace; // [inherited] see nsStyleConsts.h
  1810. uint8_t mWordBreak; // [inherited] see nsStyleConsts.h
  1811. uint8_t mOverflowWrap; // [inherited] see nsStyleConsts.h
  1812. uint8_t mHyphens; // [inherited] see nsStyleConsts.h
  1813. uint8_t mRubyAlign; // [inherited] see nsStyleConsts.h
  1814. uint8_t mRubyPosition; // [inherited] see nsStyleConsts.h
  1815. uint8_t mTextSizeAdjust; // [inherited] see nsStyleConsts.h
  1816. uint8_t mTextCombineUpright; // [inherited] see nsStyleConsts.h
  1817. uint8_t mControlCharacterVisibility; // [inherited] see nsStyleConsts.h
  1818. uint8_t mTextEmphasisPosition; // [inherited] see nsStyleConsts.h
  1819. uint8_t mTextEmphasisStyle; // [inherited] see nsStyleConsts.h
  1820. uint8_t mTextRendering; // [inherited] see nsStyleConsts.h
  1821. mozilla::StyleComplexColor mTextEmphasisColor; // [inherited]
  1822. mozilla::StyleComplexColor mWebkitTextFillColor; // [inherited]
  1823. mozilla::StyleComplexColor mWebkitTextStrokeColor; // [inherited]
  1824. nsStyleCoord mTabSize; // [inherited] coord, factor, calc
  1825. nsStyleCoord mWordSpacing; // [inherited] coord, percent, calc
  1826. nsStyleCoord mLetterSpacing; // [inherited] coord, normal
  1827. nsStyleCoord mLineHeight; // [inherited] coord, factor, normal
  1828. nsStyleCoord mTextIndent; // [inherited] coord, percent, calc
  1829. nsStyleCoord mWebkitTextStrokeWidth; // [inherited] coord
  1830. RefPtr<nsCSSShadowArray> mTextShadow; // [inherited] nullptr in case of a zero-length
  1831. nsString mTextEmphasisStyleString; // [inherited]
  1832. bool WhiteSpaceIsSignificant() const {
  1833. return mWhiteSpace == NS_STYLE_WHITESPACE_PRE ||
  1834. mWhiteSpace == NS_STYLE_WHITESPACE_PRE_WRAP ||
  1835. mWhiteSpace == NS_STYLE_WHITESPACE_PRE_SPACE;
  1836. }
  1837. bool NewlineIsSignificantStyle() const {
  1838. return mWhiteSpace == NS_STYLE_WHITESPACE_PRE ||
  1839. mWhiteSpace == NS_STYLE_WHITESPACE_PRE_WRAP ||
  1840. mWhiteSpace == NS_STYLE_WHITESPACE_PRE_LINE;
  1841. }
  1842. bool WhiteSpaceOrNewlineIsSignificant() const {
  1843. return mWhiteSpace == NS_STYLE_WHITESPACE_PRE ||
  1844. mWhiteSpace == NS_STYLE_WHITESPACE_PRE_WRAP ||
  1845. mWhiteSpace == NS_STYLE_WHITESPACE_PRE_LINE ||
  1846. mWhiteSpace == NS_STYLE_WHITESPACE_PRE_SPACE;
  1847. }
  1848. bool TabIsSignificant() const {
  1849. return mWhiteSpace == NS_STYLE_WHITESPACE_PRE ||
  1850. mWhiteSpace == NS_STYLE_WHITESPACE_PRE_WRAP;
  1851. }
  1852. bool WhiteSpaceCanWrapStyle() const {
  1853. return mWhiteSpace == NS_STYLE_WHITESPACE_NORMAL ||
  1854. mWhiteSpace == NS_STYLE_WHITESPACE_PRE_WRAP ||
  1855. mWhiteSpace == NS_STYLE_WHITESPACE_PRE_LINE;
  1856. }
  1857. bool WordCanWrapStyle() const {
  1858. if (!WhiteSpaceCanWrapStyle()) {
  1859. return false;
  1860. }
  1861. return (mOverflowWrap == NS_STYLE_OVERFLOWWRAP_BREAK_WORD ||
  1862. mOverflowWrap == NS_STYLE_OVERFLOWWRAP_ANYWHERE);
  1863. }
  1864. bool HasTextEmphasis() const {
  1865. return !mTextEmphasisStyleString.IsEmpty();
  1866. }
  1867. bool HasWebkitTextStroke() const {
  1868. return mWebkitTextStrokeWidth.GetCoordValue() > 0;
  1869. }
  1870. // These are defined in nsStyleStructInlines.h.
  1871. inline bool HasTextShadow() const;
  1872. inline nsCSSShadowArray* GetTextShadow() const;
  1873. // The aContextFrame argument on each of these is the frame this
  1874. // style struct is for. If the frame is for SVG text or inside ruby,
  1875. // the return value will be massaged to be something that makes sense
  1876. // for those cases.
  1877. inline bool NewlineIsSignificant(const nsTextFrame* aContextFrame) const;
  1878. inline bool WhiteSpaceCanWrap(const nsIFrame* aContextFrame) const;
  1879. inline bool WordCanWrap(const nsIFrame* aContextFrame) const;
  1880. mozilla::LogicalSide TextEmphasisSide(mozilla::WritingMode aWM) const;
  1881. };
  1882. struct nsStyleImageOrientation
  1883. {
  1884. static nsStyleImageOrientation CreateAsAngleAndFlip(double aRadians,
  1885. bool aFlip) {
  1886. uint8_t orientation(0);
  1887. // Compute the final angle value, rounding to the closest quarter turn.
  1888. double roundedAngle = fmod(aRadians, 2 * M_PI);
  1889. if (roundedAngle < 0.25 * M_PI) { orientation = ANGLE_0; }
  1890. else if (roundedAngle < 0.75 * M_PI) { orientation = ANGLE_90; }
  1891. else if (roundedAngle < 1.25 * M_PI) { orientation = ANGLE_180;}
  1892. else if (roundedAngle < 1.75 * M_PI) { orientation = ANGLE_270;}
  1893. else { orientation = ANGLE_0; }
  1894. // Add a bit for 'flip' if needed.
  1895. if (aFlip) {
  1896. orientation |= FLIP_MASK;
  1897. }
  1898. return nsStyleImageOrientation(orientation);
  1899. }
  1900. static nsStyleImageOrientation CreateAsFlip() {
  1901. return nsStyleImageOrientation(FLIP_MASK);
  1902. }
  1903. static nsStyleImageOrientation CreateAsFromImage() {
  1904. return nsStyleImageOrientation(FROM_IMAGE_MASK);
  1905. }
  1906. // The default constructor yields 0 degrees of rotation and no flip.
  1907. nsStyleImageOrientation() : mOrientation(0) { }
  1908. bool IsDefault() const { return mOrientation == 0; }
  1909. bool IsFlipped() const { return mOrientation & FLIP_MASK; }
  1910. bool IsFromImage() const { return mOrientation & FROM_IMAGE_MASK; }
  1911. bool SwapsWidthAndHeight() const {
  1912. uint8_t angle = mOrientation & ORIENTATION_MASK;
  1913. return (angle == ANGLE_90) || (angle == ANGLE_270);
  1914. }
  1915. mozilla::image::Angle Angle() const {
  1916. switch (mOrientation & ORIENTATION_MASK) {
  1917. case ANGLE_0: return mozilla::image::Angle::D0;
  1918. case ANGLE_90: return mozilla::image::Angle::D90;
  1919. case ANGLE_180: return mozilla::image::Angle::D180;
  1920. case ANGLE_270: return mozilla::image::Angle::D270;
  1921. default:
  1922. NS_NOTREACHED("Unexpected angle");
  1923. return mozilla::image::Angle::D0;
  1924. }
  1925. }
  1926. nsStyleCoord AngleAsCoord() const {
  1927. switch (mOrientation & ORIENTATION_MASK) {
  1928. case ANGLE_0: return nsStyleCoord(0.0f, eStyleUnit_Degree);
  1929. case ANGLE_90: return nsStyleCoord(90.0f, eStyleUnit_Degree);
  1930. case ANGLE_180: return nsStyleCoord(180.0f, eStyleUnit_Degree);
  1931. case ANGLE_270: return nsStyleCoord(270.0f, eStyleUnit_Degree);
  1932. default:
  1933. NS_NOTREACHED("Unexpected angle");
  1934. return nsStyleCoord();
  1935. }
  1936. }
  1937. bool operator==(const nsStyleImageOrientation& aOther) const {
  1938. return aOther.mOrientation == mOrientation;
  1939. }
  1940. bool operator!=(const nsStyleImageOrientation& aOther) const {
  1941. return !(*this == aOther);
  1942. }
  1943. protected:
  1944. enum Bits {
  1945. ORIENTATION_MASK = 0x1 | 0x2, // The bottom two bits are the angle.
  1946. FLIP_MASK = 0x4, // Whether the image should be flipped.
  1947. FROM_IMAGE_MASK = 0x8, // Whether the image's inherent orientation
  1948. }; // should be used.
  1949. enum Angles {
  1950. ANGLE_0 = 0,
  1951. ANGLE_90 = 1,
  1952. ANGLE_180 = 2,
  1953. ANGLE_270 = 3,
  1954. };
  1955. explicit nsStyleImageOrientation(uint8_t aOrientation)
  1956. : mOrientation(aOrientation)
  1957. { }
  1958. uint8_t mOrientation;
  1959. };
  1960. struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleVisibility
  1961. {
  1962. explicit nsStyleVisibility(StyleStructContext aContext);
  1963. nsStyleVisibility(const nsStyleVisibility& aVisibility);
  1964. ~nsStyleVisibility() {
  1965. MOZ_COUNT_DTOR(nsStyleVisibility);
  1966. }
  1967. void FinishStyle(nsPresContext* aPresContext) {}
  1968. void* operator new(size_t sz, nsStyleVisibility* aSelf) { return aSelf; }
  1969. void* operator new(size_t sz, nsPresContext* aContext) {
  1970. return aContext->PresShell()->
  1971. AllocateByObjectID(mozilla::eArenaObjectID_nsStyleVisibility, sz);
  1972. }
  1973. void Destroy(nsPresContext* aContext) {
  1974. this->~nsStyleVisibility();
  1975. aContext->PresShell()->
  1976. FreeByObjectID(mozilla::eArenaObjectID_nsStyleVisibility, this);
  1977. }
  1978. nsChangeHint CalcDifference(const nsStyleVisibility& aNewData) const;
  1979. static nsChangeHint MaxDifference() {
  1980. return nsChangeHint_ReconstructFrame |
  1981. NS_STYLE_HINT_REFLOW |
  1982. nsChangeHint_NeutralChange;
  1983. }
  1984. static nsChangeHint DifferenceAlwaysHandledForDescendants() {
  1985. // CalcDifference never returns the reflow hints that are sometimes
  1986. // handled for descendants as hints not handled for descendants.
  1987. return nsChangeHint_NeedReflow |
  1988. nsChangeHint_ReflowChangesSizeOrPosition |
  1989. nsChangeHint_ClearAncestorIntrinsics;
  1990. }
  1991. nsStyleImageOrientation mImageOrientation; // [inherited]
  1992. uint8_t mDirection; // [inherited] see nsStyleConsts.h NS_STYLE_DIRECTION_*
  1993. uint8_t mVisible; // [inherited]
  1994. uint8_t mImageRendering; // [inherited] see nsStyleConsts.h
  1995. uint8_t mWritingMode; // [inherited] see nsStyleConsts.h
  1996. uint8_t mTextOrientation; // [inherited] see nsStyleConsts.h
  1997. uint8_t mColorAdjust; // [inherited] see nsStyleConsts.h
  1998. bool IsVisible() const {
  1999. return (mVisible == NS_STYLE_VISIBILITY_VISIBLE);
  2000. }
  2001. bool IsVisibleOrCollapsed() const {
  2002. return ((mVisible == NS_STYLE_VISIBILITY_VISIBLE) ||
  2003. (mVisible == NS_STYLE_VISIBILITY_COLLAPSE));
  2004. }
  2005. };
  2006. struct nsTimingFunction
  2007. {
  2008. enum class Type {
  2009. Ease, // ease
  2010. Linear, // linear
  2011. EaseIn, // ease-in
  2012. EaseOut, // ease-out
  2013. EaseInOut, // ease-in-out
  2014. StepStart, // step-start and steps(..., start)
  2015. StepEnd, // step-end, steps(..., end) and steps(...)
  2016. CubicBezier, // cubic-bezier()
  2017. };
  2018. // Whether the timing function type is represented by a spline,
  2019. // and thus will have mFunc filled in.
  2020. static bool IsSplineType(Type aType)
  2021. {
  2022. return aType != Type::StepStart && aType != Type::StepEnd;
  2023. }
  2024. explicit nsTimingFunction(int32_t aTimingFunctionType
  2025. = NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE)
  2026. {
  2027. AssignFromKeyword(aTimingFunctionType);
  2028. }
  2029. nsTimingFunction(float x1, float y1, float x2, float y2)
  2030. : mType(Type::CubicBezier)
  2031. {
  2032. mFunc.mX1 = x1;
  2033. mFunc.mY1 = y1;
  2034. mFunc.mX2 = x2;
  2035. mFunc.mY2 = y2;
  2036. }
  2037. enum class Keyword { Implicit, Explicit };
  2038. nsTimingFunction(Type aType, uint32_t aSteps)
  2039. : mType(aType)
  2040. {
  2041. MOZ_ASSERT(mType == Type::StepStart || mType == Type::StepEnd,
  2042. "wrong type");
  2043. mSteps = aSteps;
  2044. }
  2045. nsTimingFunction(const nsTimingFunction& aOther)
  2046. {
  2047. *this = aOther;
  2048. }
  2049. Type mType;
  2050. union {
  2051. struct {
  2052. float mX1;
  2053. float mY1;
  2054. float mX2;
  2055. float mY2;
  2056. } mFunc;
  2057. struct {
  2058. uint32_t mSteps;
  2059. };
  2060. };
  2061. nsTimingFunction&
  2062. operator=(const nsTimingFunction& aOther)
  2063. {
  2064. if (&aOther == this) {
  2065. return *this;
  2066. }
  2067. mType = aOther.mType;
  2068. if (HasSpline()) {
  2069. mFunc.mX1 = aOther.mFunc.mX1;
  2070. mFunc.mY1 = aOther.mFunc.mY1;
  2071. mFunc.mX2 = aOther.mFunc.mX2;
  2072. mFunc.mY2 = aOther.mFunc.mY2;
  2073. } else {
  2074. mSteps = aOther.mSteps;
  2075. }
  2076. return *this;
  2077. }
  2078. bool operator==(const nsTimingFunction& aOther) const
  2079. {
  2080. if (mType != aOther.mType) {
  2081. return false;
  2082. }
  2083. if (HasSpline()) {
  2084. return mFunc.mX1 == aOther.mFunc.mX1 && mFunc.mY1 == aOther.mFunc.mY1 &&
  2085. mFunc.mX2 == aOther.mFunc.mX2 && mFunc.mY2 == aOther.mFunc.mY2;
  2086. }
  2087. return mSteps == aOther.mSteps;
  2088. }
  2089. bool operator!=(const nsTimingFunction& aOther) const
  2090. {
  2091. return !(*this == aOther);
  2092. }
  2093. bool HasSpline() const { return IsSplineType(mType); }
  2094. private:
  2095. void AssignFromKeyword(int32_t aTimingFunctionType);
  2096. };
  2097. namespace mozilla {
  2098. struct StyleTransition
  2099. {
  2100. StyleTransition() { /* leaves uninitialized; see also SetInitialValues */ }
  2101. explicit StyleTransition(const StyleTransition& aCopy);
  2102. void SetInitialValues();
  2103. // Delay and Duration are in milliseconds
  2104. const nsTimingFunction& GetTimingFunction() const { return mTimingFunction; }
  2105. float GetDelay() const { return mDelay; }
  2106. float GetDuration() const { return mDuration; }
  2107. nsCSSPropertyID GetProperty() const { return mProperty; }
  2108. nsIAtom* GetUnknownProperty() const { return mUnknownProperty; }
  2109. float GetCombinedDuration() const {
  2110. // http://dev.w3.org/csswg/css-transitions/#combined-duration
  2111. return std::max(mDuration, 0.0f) + mDelay;
  2112. }
  2113. void SetTimingFunction(const nsTimingFunction& aTimingFunction)
  2114. { mTimingFunction = aTimingFunction; }
  2115. void SetDelay(float aDelay) { mDelay = aDelay; }
  2116. void SetDuration(float aDuration) { mDuration = aDuration; }
  2117. void SetProperty(nsCSSPropertyID aProperty)
  2118. {
  2119. NS_ASSERTION(aProperty != eCSSProperty_UNKNOWN &&
  2120. aProperty != eCSSPropertyExtra_variable,
  2121. "invalid property");
  2122. mProperty = aProperty;
  2123. }
  2124. void SetUnknownProperty(nsCSSPropertyID aProperty,
  2125. const nsAString& aPropertyString);
  2126. void CopyPropertyFrom(const StyleTransition& aOther)
  2127. {
  2128. mProperty = aOther.mProperty;
  2129. mUnknownProperty = aOther.mUnknownProperty;
  2130. }
  2131. nsTimingFunction& TimingFunctionSlot() { return mTimingFunction; }
  2132. bool operator==(const StyleTransition& aOther) const;
  2133. bool operator!=(const StyleTransition& aOther) const
  2134. { return !(*this == aOther); }
  2135. private:
  2136. nsTimingFunction mTimingFunction;
  2137. float mDuration;
  2138. float mDelay;
  2139. nsCSSPropertyID mProperty;
  2140. nsCOMPtr<nsIAtom> mUnknownProperty; // used when mProperty is
  2141. // eCSSProperty_UNKNOWN or
  2142. // eCSSPropertyExtra_variable
  2143. };
  2144. struct StyleAnimation
  2145. {
  2146. StyleAnimation() { /* leaves uninitialized; see also SetInitialValues */ }
  2147. explicit StyleAnimation(const StyleAnimation& aCopy);
  2148. void SetInitialValues();
  2149. // Delay and Duration are in milliseconds
  2150. const nsTimingFunction& GetTimingFunction() const { return mTimingFunction; }
  2151. float GetDelay() const { return mDelay; }
  2152. float GetDuration() const { return mDuration; }
  2153. const nsString& GetName() const { return mName; }
  2154. dom::PlaybackDirection GetDirection() const { return mDirection; }
  2155. dom::FillMode GetFillMode() const { return mFillMode; }
  2156. uint8_t GetPlayState() const { return mPlayState; }
  2157. float GetIterationCount() const { return mIterationCount; }
  2158. void SetTimingFunction(const nsTimingFunction& aTimingFunction)
  2159. { mTimingFunction = aTimingFunction; }
  2160. void SetDelay(float aDelay) { mDelay = aDelay; }
  2161. void SetDuration(float aDuration) { mDuration = aDuration; }
  2162. void SetName(const nsSubstring& aName) { mName = aName; }
  2163. void SetDirection(dom::PlaybackDirection aDirection) { mDirection = aDirection; }
  2164. void SetFillMode(dom::FillMode aFillMode) { mFillMode = aFillMode; }
  2165. void SetPlayState(uint8_t aPlayState) { mPlayState = aPlayState; }
  2166. void SetIterationCount(float aIterationCount)
  2167. { mIterationCount = aIterationCount; }
  2168. nsTimingFunction& TimingFunctionSlot() { return mTimingFunction; }
  2169. bool operator==(const StyleAnimation& aOther) const;
  2170. bool operator!=(const StyleAnimation& aOther) const
  2171. { return !(*this == aOther); }
  2172. private:
  2173. nsTimingFunction mTimingFunction;
  2174. float mDuration;
  2175. float mDelay;
  2176. nsString mName; // empty string for 'none'
  2177. dom::PlaybackDirection mDirection;
  2178. dom::FillMode mFillMode;
  2179. uint8_t mPlayState;
  2180. float mIterationCount; // mozilla::PositiveInfinity<float>() means infinite
  2181. };
  2182. class StyleBasicShape final
  2183. {
  2184. public:
  2185. explicit StyleBasicShape(StyleBasicShapeType type)
  2186. : mType(type),
  2187. mFillRule(StyleFillRule::Nonzero)
  2188. {
  2189. mPosition.SetInitialPercentValues(0.5f);
  2190. }
  2191. StyleBasicShapeType GetShapeType() const { return mType; }
  2192. nsCSSKeyword GetShapeTypeName() const;
  2193. StyleFillRule GetFillRule() const { return mFillRule; }
  2194. void SetFillRule(StyleFillRule aFillRule)
  2195. {
  2196. MOZ_ASSERT(mType == StyleBasicShapeType::Polygon, "expected polygon");
  2197. mFillRule = aFillRule;
  2198. }
  2199. Position& GetPosition() {
  2200. MOZ_ASSERT(mType == StyleBasicShapeType::Circle ||
  2201. mType == StyleBasicShapeType::Ellipse,
  2202. "expected circle or ellipse");
  2203. return mPosition;
  2204. }
  2205. const Position& GetPosition() const {
  2206. MOZ_ASSERT(mType == StyleBasicShapeType::Circle ||
  2207. mType == StyleBasicShapeType::Ellipse,
  2208. "expected circle or ellipse");
  2209. return mPosition;
  2210. }
  2211. bool HasRadius() const {
  2212. MOZ_ASSERT(mType == StyleBasicShapeType::Inset, "expected inset");
  2213. nsStyleCoord zero;
  2214. zero.SetCoordValue(0);
  2215. NS_FOR_CSS_HALF_CORNERS(corner) {
  2216. if (mRadius.Get(corner) != zero) {
  2217. return true;
  2218. }
  2219. }
  2220. return false;
  2221. }
  2222. nsStyleCorners& GetRadius() {
  2223. MOZ_ASSERT(mType == StyleBasicShapeType::Inset, "expected inset");
  2224. return mRadius;
  2225. }
  2226. const nsStyleCorners& GetRadius() const {
  2227. MOZ_ASSERT(mType == StyleBasicShapeType::Inset, "expected inset");
  2228. return mRadius;
  2229. }
  2230. // mCoordinates has coordinates for polygon or radii for
  2231. // ellipse and circle.
  2232. nsTArray<nsStyleCoord>& Coordinates()
  2233. {
  2234. return mCoordinates;
  2235. }
  2236. const nsTArray<nsStyleCoord>& Coordinates() const
  2237. {
  2238. return mCoordinates;
  2239. }
  2240. bool operator==(const StyleBasicShape& aOther) const
  2241. {
  2242. return mType == aOther.mType &&
  2243. mFillRule == aOther.mFillRule &&
  2244. mCoordinates == aOther.mCoordinates &&
  2245. mPosition == aOther.mPosition &&
  2246. mRadius == aOther.mRadius;
  2247. }
  2248. bool operator!=(const StyleBasicShape& aOther) const {
  2249. return !(*this == aOther);
  2250. }
  2251. NS_INLINE_DECL_THREADSAFE_REFCOUNTING(StyleBasicShape);
  2252. private:
  2253. ~StyleBasicShape() {}
  2254. StyleBasicShapeType mType;
  2255. StyleFillRule mFillRule;
  2256. // mCoordinates has coordinates for polygon or radii for
  2257. // ellipse and circle.
  2258. // (top, right, bottom, left) for inset
  2259. nsTArray<nsStyleCoord> mCoordinates;
  2260. // position of center for ellipse or circle
  2261. Position mPosition;
  2262. // corner radii for inset (0 if not set)
  2263. nsStyleCorners mRadius;
  2264. };
  2265. template<typename ReferenceBox>
  2266. struct StyleShapeSource
  2267. {
  2268. StyleShapeSource()
  2269. : mURL(nullptr)
  2270. {}
  2271. StyleShapeSource(const StyleShapeSource& aSource)
  2272. : StyleShapeSource()
  2273. {
  2274. if (aSource.mType == StyleShapeSourceType::URL) {
  2275. SetURL(aSource.mURL);
  2276. } else if (aSource.mType == StyleShapeSourceType::Shape) {
  2277. SetBasicShape(aSource.mBasicShape, aSource.mReferenceBox);
  2278. } else if (aSource.mType == StyleShapeSourceType::Box) {
  2279. SetReferenceBox(aSource.mReferenceBox);
  2280. }
  2281. }
  2282. ~StyleShapeSource()
  2283. {
  2284. ReleaseRef();
  2285. }
  2286. StyleShapeSource& operator=(const StyleShapeSource& aOther)
  2287. {
  2288. if (this == &aOther) {
  2289. return *this;
  2290. }
  2291. if (aOther.mType == StyleShapeSourceType::URL) {
  2292. SetURL(aOther.mURL);
  2293. } else if (aOther.mType == StyleShapeSourceType::Shape) {
  2294. SetBasicShape(aOther.mBasicShape, aOther.mReferenceBox);
  2295. } else if (aOther.mType == StyleShapeSourceType::Box) {
  2296. SetReferenceBox(aOther.mReferenceBox);
  2297. } else {
  2298. ReleaseRef();
  2299. mReferenceBox = ReferenceBox::NoBox;
  2300. mType = StyleShapeSourceType::None;
  2301. }
  2302. return *this;
  2303. }
  2304. bool operator==(const StyleShapeSource& aOther) const
  2305. {
  2306. if (mType != aOther.mType) {
  2307. return false;
  2308. }
  2309. if (mType == StyleShapeSourceType::URL) {
  2310. return mURL->Equals(*aOther.mURL);
  2311. } else if (mType == StyleShapeSourceType::Shape) {
  2312. return *mBasicShape == *aOther.mBasicShape &&
  2313. mReferenceBox == aOther.mReferenceBox;
  2314. } else if (mType == StyleShapeSourceType::Box) {
  2315. return mReferenceBox == aOther.mReferenceBox;
  2316. }
  2317. return true;
  2318. }
  2319. bool operator!=(const StyleShapeSource& aOther) const
  2320. {
  2321. return !(*this == aOther);
  2322. }
  2323. StyleShapeSourceType GetType() const
  2324. {
  2325. return mType;
  2326. }
  2327. css::URLValue* GetURL() const
  2328. {
  2329. MOZ_ASSERT(mType == StyleShapeSourceType::URL, "Wrong shape source type!");
  2330. return mURL;
  2331. }
  2332. bool SetURL(css::URLValue* aValue)
  2333. {
  2334. MOZ_ASSERT(aValue);
  2335. ReleaseRef();
  2336. mURL = aValue;
  2337. mURL->AddRef();
  2338. mType = StyleShapeSourceType::URL;
  2339. return true;
  2340. }
  2341. StyleBasicShape* GetBasicShape() const
  2342. {
  2343. MOZ_ASSERT(mType == StyleShapeSourceType::Shape, "Wrong shape source type!");
  2344. return mBasicShape;
  2345. }
  2346. void SetBasicShape(StyleBasicShape* aBasicShape,
  2347. ReferenceBox aReferenceBox)
  2348. {
  2349. NS_ASSERTION(aBasicShape, "expected pointer");
  2350. ReleaseRef();
  2351. mBasicShape = aBasicShape;
  2352. mBasicShape->AddRef();
  2353. mReferenceBox = aReferenceBox;
  2354. mType = StyleShapeSourceType::Shape;
  2355. }
  2356. ReferenceBox GetReferenceBox() const
  2357. {
  2358. MOZ_ASSERT(mType == StyleShapeSourceType::Box ||
  2359. mType == StyleShapeSourceType::Shape,
  2360. "Wrong shape source type!");
  2361. return mReferenceBox;
  2362. }
  2363. void SetReferenceBox(ReferenceBox aReferenceBox)
  2364. {
  2365. ReleaseRef();
  2366. mReferenceBox = aReferenceBox;
  2367. mType = StyleShapeSourceType::Box;
  2368. }
  2369. private:
  2370. void ReleaseRef()
  2371. {
  2372. if (mType == StyleShapeSourceType::Shape) {
  2373. NS_ASSERTION(mBasicShape, "expected pointer");
  2374. mBasicShape->Release();
  2375. } else if (mType == StyleShapeSourceType::URL) {
  2376. NS_ASSERTION(mURL, "expected pointer");
  2377. mURL->Release();
  2378. }
  2379. // Both mBasicShape and mURL are pointers in a union. Nulling one of them
  2380. // nulls both of them.
  2381. mURL = nullptr;
  2382. }
  2383. void* operator new(size_t) = delete;
  2384. union {
  2385. StyleBasicShape* mBasicShape;
  2386. css::URLValue* mURL;
  2387. };
  2388. StyleShapeSourceType mType = StyleShapeSourceType::None;
  2389. ReferenceBox mReferenceBox = ReferenceBox::NoBox;
  2390. };
  2391. using StyleClipPath = StyleShapeSource<StyleGeometryBox>;
  2392. using StyleShapeOutside = StyleShapeSource<StyleShapeOutsideShapeBox>;
  2393. } // namespace mozilla
  2394. struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleDisplay
  2395. {
  2396. explicit nsStyleDisplay(StyleStructContext aContext);
  2397. nsStyleDisplay(const nsStyleDisplay& aOther);
  2398. ~nsStyleDisplay() {
  2399. MOZ_COUNT_DTOR(nsStyleDisplay);
  2400. }
  2401. void FinishStyle(nsPresContext* aPresContext) {}
  2402. void* operator new(size_t sz, nsStyleDisplay* aSelf) { return aSelf; }
  2403. void* operator new(size_t sz, nsPresContext* aContext) {
  2404. return aContext->PresShell()->
  2405. AllocateByObjectID(mozilla::eArenaObjectID_nsStyleDisplay, sz);
  2406. }
  2407. void Destroy(nsPresContext* aContext) {
  2408. this->~nsStyleDisplay();
  2409. aContext->PresShell()->
  2410. FreeByObjectID(mozilla::eArenaObjectID_nsStyleDisplay, this);
  2411. }
  2412. nsChangeHint CalcDifference(const nsStyleDisplay& aNewData) const;
  2413. static nsChangeHint MaxDifference() {
  2414. // All the parts of FRAMECHANGE are present in CalcDifference.
  2415. return nsChangeHint(nsChangeHint_ReconstructFrame |
  2416. NS_STYLE_HINT_REFLOW |
  2417. nsChangeHint_UpdateTransformLayer |
  2418. nsChangeHint_UpdateOverflow |
  2419. nsChangeHint_UpdatePostTransformOverflow |
  2420. nsChangeHint_UpdateContainingBlock |
  2421. nsChangeHint_AddOrRemoveTransform |
  2422. nsChangeHint_NeutralChange);
  2423. }
  2424. static nsChangeHint DifferenceAlwaysHandledForDescendants() {
  2425. // CalcDifference can return all of the reflow hints that are
  2426. // sometimes handled for descendants as hints not handled for
  2427. // descendants.
  2428. return nsChangeHint(0);
  2429. }
  2430. // We guarantee that if mBinding is non-null, so are mBinding->GetURI() and
  2431. // mBinding->mOriginPrincipal.
  2432. RefPtr<mozilla::css::URLValue> mBinding; // [reset]
  2433. mozilla::StyleDisplay mDisplay; // [reset] see nsStyleConsts.h SyleDisplay
  2434. mozilla::StyleDisplay mOriginalDisplay; // [reset] saved mDisplay for
  2435. // position:absolute/fixed
  2436. // and float:left/right;
  2437. // otherwise equal to
  2438. // mDisplay
  2439. uint8_t mContain; // [reset] see nsStyleConsts.h NS_STYLE_CONTAIN_*
  2440. uint8_t mAppearance; // [reset]
  2441. uint8_t mPosition; // [reset] see nsStyleConsts.h
  2442. // [reset] See StyleFloat in nsStyleConsts.h.
  2443. mozilla::StyleFloat mFloat;
  2444. // [reset] Save mFloat for position:absolute/fixed; otherwise equal to mFloat.
  2445. mozilla::StyleFloat mOriginalFloat;
  2446. mozilla::StyleClear mBreakType; // [reset]
  2447. uint8_t mBreakInside; // [reset] NS_STYLE_PAGE_BREAK_AUTO/AVOID
  2448. bool mBreakBefore; // [reset]
  2449. bool mBreakAfter; // [reset]
  2450. uint8_t mOverflowX; // [reset] see nsStyleConsts.h
  2451. uint8_t mOverflowY; // [reset] see nsStyleConsts.h
  2452. uint8_t mOverflowClipBox; // [reset] see nsStyleConsts.h
  2453. uint8_t mResize; // [reset] see nsStyleConsts.h
  2454. mozilla::StyleOrient mOrient; // [reset] see nsStyleConsts.h
  2455. uint8_t mIsolation; // [reset] see nsStyleConsts.h
  2456. uint8_t mTopLayer; // [reset] see nsStyleConsts.h
  2457. uint8_t mWillChangeBitField; // [reset] see nsStyleConsts.h. Stores a
  2458. // bitfield representation of the properties
  2459. // that are frequently queried. This should
  2460. // match mWillChange. Also tracks if any of the
  2461. // properties in the will-change list require
  2462. // a stacking context.
  2463. nsTArray<nsString> mWillChange;
  2464. uint8_t mTouchAction; // [reset] see nsStyleConsts.h
  2465. uint8_t mScrollBehavior; // [reset] see nsStyleConsts.h NS_STYLE_SCROLL_BEHAVIOR_*
  2466. uint8_t mScrollSnapTypeX; // [reset] see nsStyleConsts.h NS_STYLE_SCROLL_SNAP_TYPE_*
  2467. uint8_t mScrollSnapTypeY; // [reset] see nsStyleConsts.h NS_STYLE_SCROLL_SNAP_TYPE_*
  2468. nsStyleCoord mScrollSnapPointsX; // [reset]
  2469. nsStyleCoord mScrollSnapPointsY; // [reset]
  2470. mozilla::Position mScrollSnapDestination; // [reset]
  2471. nsTArray<mozilla::Position> mScrollSnapCoordinate; // [reset]
  2472. // mSpecifiedTransform is the list of transform functions as
  2473. // specified, or null to indicate there is no transform. (inherit or
  2474. // initial are replaced by an actual list of transform functions, or
  2475. // null, as appropriate.)
  2476. uint8_t mBackfaceVisibility;
  2477. uint8_t mTransformStyle;
  2478. uint8_t mTransformBox; // [reset] see nsStyleConsts.h
  2479. RefPtr<nsCSSValueSharedList> mSpecifiedTransform; // [reset]
  2480. nsStyleCoord mTransformOrigin[3]; // [reset] percent, coord, calc, 3rd param is coord, calc only
  2481. nsStyleCoord mChildPerspective; // [reset] none, coord
  2482. nsStyleCoord mPerspectiveOrigin[2]; // [reset] percent, coord, calc
  2483. nsStyleCoord mVerticalAlign; // [reset] coord, percent, calc, enum (see nsStyleConsts.h)
  2484. nsStyleAutoArray<mozilla::StyleTransition> mTransitions; // [reset]
  2485. // The number of elements in mTransitions that are not from repeating
  2486. // a list due to another property being longer.
  2487. uint32_t mTransitionTimingFunctionCount,
  2488. mTransitionDurationCount,
  2489. mTransitionDelayCount,
  2490. mTransitionPropertyCount;
  2491. nsStyleAutoArray<mozilla::StyleAnimation> mAnimations; // [reset]
  2492. // The number of elements in mAnimations that are not from repeating
  2493. // a list due to another property being longer.
  2494. uint32_t mAnimationTimingFunctionCount,
  2495. mAnimationDurationCount,
  2496. mAnimationDelayCount,
  2497. mAnimationNameCount,
  2498. mAnimationDirectionCount,
  2499. mAnimationFillModeCount,
  2500. mAnimationPlayStateCount,
  2501. mAnimationIterationCountCount;
  2502. mozilla::StyleShapeOutside mShapeOutside; // [reset]
  2503. bool IsBlockInsideStyle() const {
  2504. return mozilla::StyleDisplay::Block == mDisplay ||
  2505. mozilla::StyleDisplay::ListItem == mDisplay ||
  2506. mozilla::StyleDisplay::InlineBlock == mDisplay ||
  2507. mozilla::StyleDisplay::TableCaption == mDisplay ||
  2508. mozilla::StyleDisplay::FlowRoot == mDisplay;
  2509. // Should TABLE_CELL be included here? They have
  2510. // block frames nested inside of them.
  2511. // (But please audit all callers before changing.)
  2512. }
  2513. bool IsBlockOutsideStyle() const {
  2514. return mozilla::StyleDisplay::Block == mDisplay ||
  2515. mozilla::StyleDisplay::Flex == mDisplay ||
  2516. mozilla::StyleDisplay::WebkitBox == mDisplay ||
  2517. mozilla::StyleDisplay::Grid == mDisplay ||
  2518. mozilla::StyleDisplay::ListItem == mDisplay ||
  2519. mozilla::StyleDisplay::Table == mDisplay ||
  2520. mozilla::StyleDisplay::FlowRoot == mDisplay;
  2521. }
  2522. static bool IsDisplayTypeInlineOutside(mozilla::StyleDisplay aDisplay) {
  2523. return mozilla::StyleDisplay::Inline == aDisplay ||
  2524. mozilla::StyleDisplay::InlineBlock == aDisplay ||
  2525. mozilla::StyleDisplay::InlineTable == aDisplay ||
  2526. mozilla::StyleDisplay::InlineBox == aDisplay ||
  2527. mozilla::StyleDisplay::InlineFlex == aDisplay ||
  2528. mozilla::StyleDisplay::WebkitInlineBox == aDisplay ||
  2529. mozilla::StyleDisplay::InlineGrid == aDisplay ||
  2530. mozilla::StyleDisplay::InlineXulGrid == aDisplay ||
  2531. mozilla::StyleDisplay::InlineStack == aDisplay ||
  2532. mozilla::StyleDisplay::Ruby == aDisplay ||
  2533. mozilla::StyleDisplay::RubyBase == aDisplay ||
  2534. mozilla::StyleDisplay::RubyBaseContainer == aDisplay ||
  2535. mozilla::StyleDisplay::RubyText == aDisplay ||
  2536. mozilla::StyleDisplay::RubyTextContainer == aDisplay ||
  2537. mozilla::StyleDisplay::Contents == aDisplay;
  2538. }
  2539. bool IsInlineOutsideStyle() const {
  2540. return IsDisplayTypeInlineOutside(mDisplay);
  2541. }
  2542. bool IsOriginalDisplayInlineOutsideStyle() const {
  2543. return IsDisplayTypeInlineOutside(mOriginalDisplay);
  2544. }
  2545. bool IsInnerTableStyle() const {
  2546. return mozilla::StyleDisplay::TableCaption == mDisplay ||
  2547. mozilla::StyleDisplay::TableCell == mDisplay ||
  2548. mozilla::StyleDisplay::TableRow == mDisplay ||
  2549. mozilla::StyleDisplay::TableRowGroup == mDisplay ||
  2550. mozilla::StyleDisplay::TableHeaderGroup == mDisplay ||
  2551. mozilla::StyleDisplay::TableFooterGroup == mDisplay ||
  2552. mozilla::StyleDisplay::TableColumn == mDisplay ||
  2553. mozilla::StyleDisplay::TableColumnGroup == mDisplay;
  2554. }
  2555. bool IsFloatingStyle() const {
  2556. return mozilla::StyleFloat::None != mFloat;
  2557. }
  2558. bool IsAbsolutelyPositionedStyle() const {
  2559. return NS_STYLE_POSITION_ABSOLUTE == mPosition ||
  2560. NS_STYLE_POSITION_FIXED == mPosition;
  2561. }
  2562. bool IsRelativelyPositionedStyle() const {
  2563. return NS_STYLE_POSITION_RELATIVE == mPosition ||
  2564. NS_STYLE_POSITION_STICKY == mPosition;
  2565. }
  2566. bool IsPositionForcingStackingContext() const {
  2567. return NS_STYLE_POSITION_STICKY == mPosition ||
  2568. NS_STYLE_POSITION_FIXED == mPosition;
  2569. }
  2570. static bool IsRubyDisplayType(mozilla::StyleDisplay aDisplay) {
  2571. return mozilla::StyleDisplay::Ruby == aDisplay ||
  2572. mozilla::StyleDisplay::RubyBase == aDisplay ||
  2573. mozilla::StyleDisplay::RubyBaseContainer == aDisplay ||
  2574. mozilla::StyleDisplay::RubyText == aDisplay ||
  2575. mozilla::StyleDisplay::RubyTextContainer == aDisplay;
  2576. }
  2577. bool IsRubyDisplayType() const {
  2578. return IsRubyDisplayType(mDisplay);
  2579. }
  2580. bool IsOutOfFlowStyle() const {
  2581. return (IsAbsolutelyPositionedStyle() || IsFloatingStyle());
  2582. }
  2583. bool IsScrollableOverflow() const {
  2584. // mOverflowX and mOverflowY always match when one of them is
  2585. // NS_STYLE_OVERFLOW_VISIBLE or NS_STYLE_OVERFLOW_CLIP.
  2586. return mOverflowX != NS_STYLE_OVERFLOW_VISIBLE &&
  2587. mOverflowX != NS_STYLE_OVERFLOW_CLIP;
  2588. }
  2589. bool IsContainPaint() const {
  2590. return NS_STYLE_CONTAIN_PAINT & mContain;
  2591. }
  2592. /* Returns whether the element has the -moz-transform property
  2593. * or a related property. */
  2594. bool HasTransformStyle() const {
  2595. return mSpecifiedTransform != nullptr ||
  2596. mTransformStyle == NS_STYLE_TRANSFORM_STYLE_PRESERVE_3D ||
  2597. (mWillChangeBitField & NS_STYLE_WILL_CHANGE_TRANSFORM);
  2598. }
  2599. bool HasPerspectiveStyle() const {
  2600. return mChildPerspective.GetUnit() == eStyleUnit_Coord;
  2601. }
  2602. bool BackfaceIsHidden() const {
  2603. return mBackfaceVisibility == NS_STYLE_BACKFACE_VISIBILITY_HIDDEN;
  2604. }
  2605. // These are defined in nsStyleStructInlines.h.
  2606. // The aContextFrame argument on each of these is the frame this
  2607. // style struct is for. If the frame is for SVG text, the return
  2608. // value will be massaged to be something that makes sense for
  2609. // SVG text.
  2610. inline bool IsBlockInside(const nsIFrame* aContextFrame) const;
  2611. inline bool IsBlockOutside(const nsIFrame* aContextFrame) const;
  2612. inline bool IsInlineOutside(const nsIFrame* aContextFrame) const;
  2613. inline bool IsOriginalDisplayInlineOutside(const nsIFrame* aContextFrame) const;
  2614. inline mozilla::StyleDisplay GetDisplay(const nsIFrame* aContextFrame) const;
  2615. inline bool IsFloating(const nsIFrame* aContextFrame) const;
  2616. inline bool IsRelativelyPositioned(const nsIFrame* aContextFrame) const;
  2617. inline bool IsAbsolutelyPositioned(const nsIFrame* aContextFrame) const;
  2618. // These methods are defined in nsStyleStructInlines.h.
  2619. /**
  2620. * Returns whether the element is a containing block for its
  2621. * absolutely positioned descendants.
  2622. * aContextFrame is the frame for which this is the nsStyleDisplay.
  2623. */
  2624. inline bool IsAbsPosContainingBlock(const nsIFrame* aContextFrame) const;
  2625. /**
  2626. * The same as IsAbsPosContainingBlock, except skipping the tests that
  2627. * are based on the frame rather than the style context (thus
  2628. * potentially returning a false positive).
  2629. */
  2630. template<class StyleContextLike>
  2631. inline bool IsAbsPosContainingBlockForAppropriateFrame(
  2632. StyleContextLike* aStyleContext) const;
  2633. /**
  2634. * Returns true when the element has the transform property
  2635. * or a related property, and supports CSS transforms.
  2636. * aContextFrame is the frame for which this is the nsStyleDisplay.
  2637. */
  2638. inline bool HasTransform(const nsIFrame* aContextFrame) const;
  2639. /**
  2640. * Returns true when the element is a containing block for its fixed-pos
  2641. * descendants.
  2642. * aContextFrame is the frame for which this is the nsStyleDisplay.
  2643. */
  2644. inline bool IsFixedPosContainingBlock(const nsIFrame* aContextFrame) const;
  2645. /**
  2646. * The same as IsFixedPosContainingBlock, except skipping the tests that
  2647. * are based on the frame rather than the style context (thus
  2648. * potentially returning a false positive).
  2649. */
  2650. template<class StyleContextLike>
  2651. inline bool IsFixedPosContainingBlockForAppropriateFrame(
  2652. StyleContextLike* aStyleContext) const;
  2653. private:
  2654. // Helpers for above functions, which do some but not all of the tests
  2655. // for them (since transform must be tested separately for each).
  2656. template<class StyleContextLike>
  2657. inline bool HasAbsPosContainingBlockStyleInternal(
  2658. StyleContextLike* aStyleContext) const;
  2659. template<class StyleContextLike>
  2660. inline bool HasFixedPosContainingBlockStyleInternal(
  2661. StyleContextLike* aStyleContext) const;
  2662. public:
  2663. // Return the 'float' and 'clear' properties, with inline-{start,end} values
  2664. // resolved to {left,right} according to the given writing mode. These are
  2665. // defined in WritingModes.h.
  2666. inline mozilla::StyleFloat PhysicalFloats(mozilla::WritingMode aWM) const;
  2667. inline mozilla::StyleClear PhysicalBreakType(mozilla::WritingMode aWM) const;
  2668. };
  2669. struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleTable
  2670. {
  2671. explicit nsStyleTable(StyleStructContext aContext);
  2672. nsStyleTable(const nsStyleTable& aOther);
  2673. ~nsStyleTable();
  2674. void FinishStyle(nsPresContext* aPresContext) {}
  2675. void* operator new(size_t sz, nsStyleTable* aSelf) { return aSelf; }
  2676. void* operator new(size_t sz, nsPresContext* aContext) {
  2677. return aContext->PresShell()->
  2678. AllocateByObjectID(mozilla::eArenaObjectID_nsStyleTable, sz);
  2679. }
  2680. void Destroy(nsPresContext* aContext) {
  2681. this->~nsStyleTable();
  2682. aContext->PresShell()->
  2683. FreeByObjectID(mozilla::eArenaObjectID_nsStyleTable, this);
  2684. }
  2685. nsChangeHint CalcDifference(const nsStyleTable& aNewData) const;
  2686. static nsChangeHint MaxDifference() {
  2687. return nsChangeHint_ReconstructFrame;
  2688. }
  2689. static nsChangeHint DifferenceAlwaysHandledForDescendants() {
  2690. // CalcDifference never returns the reflow hints that are sometimes
  2691. // handled for descendants as hints not handled for descendants.
  2692. return nsChangeHint(0);
  2693. }
  2694. uint8_t mLayoutStrategy;// [reset] see nsStyleConsts.h NS_STYLE_TABLE_LAYOUT_*
  2695. int32_t mSpan; // [reset] the number of columns spanned by a colgroup or col
  2696. };
  2697. struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleTableBorder
  2698. {
  2699. explicit nsStyleTableBorder(StyleStructContext aContext);
  2700. nsStyleTableBorder(const nsStyleTableBorder& aOther);
  2701. ~nsStyleTableBorder();
  2702. void FinishStyle(nsPresContext* aPresContext) {}
  2703. void* operator new(size_t sz, nsStyleTableBorder* aSelf) { return aSelf; }
  2704. void* operator new(size_t sz, nsPresContext* aContext) {
  2705. return aContext->PresShell()->
  2706. AllocateByObjectID(mozilla::eArenaObjectID_nsStyleTableBorder, sz);
  2707. }
  2708. void Destroy(nsPresContext* aContext) {
  2709. this->~nsStyleTableBorder();
  2710. aContext->PresShell()->
  2711. FreeByObjectID(mozilla::eArenaObjectID_nsStyleTableBorder, this);
  2712. }
  2713. nsChangeHint CalcDifference(const nsStyleTableBorder& aNewData) const;
  2714. static nsChangeHint MaxDifference() {
  2715. return nsChangeHint_ReconstructFrame |
  2716. NS_STYLE_HINT_REFLOW;
  2717. }
  2718. static nsChangeHint DifferenceAlwaysHandledForDescendants() {
  2719. // CalcDifference never returns the reflow hints that are sometimes
  2720. // handled for descendants as hints not handled for descendants.
  2721. return nsChangeHint_NeedReflow |
  2722. nsChangeHint_ReflowChangesSizeOrPosition |
  2723. nsChangeHint_ClearAncestorIntrinsics;
  2724. }
  2725. nscoord mBorderSpacingCol;// [inherited]
  2726. nscoord mBorderSpacingRow;// [inherited]
  2727. uint8_t mBorderCollapse;// [inherited]
  2728. uint8_t mCaptionSide; // [inherited]
  2729. uint8_t mEmptyCells; // [inherited]
  2730. };
  2731. enum nsStyleContentType {
  2732. eStyleContentType_String = 1,
  2733. eStyleContentType_Image = 10,
  2734. eStyleContentType_Attr = 20,
  2735. eStyleContentType_Counter = 30,
  2736. eStyleContentType_Counters = 31,
  2737. eStyleContentType_OpenQuote = 40,
  2738. eStyleContentType_CloseQuote = 41,
  2739. eStyleContentType_NoOpenQuote = 42,
  2740. eStyleContentType_NoCloseQuote = 43,
  2741. eStyleContentType_AltContent = 50,
  2742. eStyleContentType_Uninitialized
  2743. };
  2744. struct nsStyleContentData
  2745. {
  2746. nsStyleContentType mType;
  2747. union {
  2748. char16_t *mString;
  2749. imgRequestProxy *mImage;
  2750. nsCSSValue::Array* mCounters;
  2751. } mContent;
  2752. #ifdef DEBUG
  2753. bool mImageTracked;
  2754. #endif
  2755. nsStyleContentData()
  2756. : mType(eStyleContentType_Uninitialized)
  2757. #ifdef DEBUG
  2758. , mImageTracked(false)
  2759. #endif
  2760. {
  2761. MOZ_COUNT_CTOR(nsStyleContentData);
  2762. mContent.mString = nullptr;
  2763. }
  2764. nsStyleContentData(const nsStyleContentData&);
  2765. ~nsStyleContentData();
  2766. nsStyleContentData& operator=(const nsStyleContentData& aOther);
  2767. bool operator==(const nsStyleContentData& aOther) const;
  2768. bool operator!=(const nsStyleContentData& aOther) const {
  2769. return !(*this == aOther);
  2770. }
  2771. void TrackImage(mozilla::dom::ImageTracker* aImageTracker);
  2772. void UntrackImage(mozilla::dom::ImageTracker* aImageTracker);
  2773. void SetImage(imgRequestProxy* aRequest)
  2774. {
  2775. MOZ_ASSERT(!mImageTracked,
  2776. "Setting a new image without untracking the old one!");
  2777. MOZ_ASSERT(mType == eStyleContentType_Image, "Wrong type!");
  2778. NS_IF_ADDREF(mContent.mImage = aRequest);
  2779. }
  2780. };
  2781. struct nsStyleCounterData
  2782. {
  2783. nsString mCounter;
  2784. int32_t mValue;
  2785. bool operator==(const nsStyleCounterData& aOther) const {
  2786. return mValue == aOther.mValue && mCounter == aOther.mCounter;
  2787. }
  2788. bool operator!=(const nsStyleCounterData& aOther) const {
  2789. return !(*this == aOther);
  2790. }
  2791. };
  2792. struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleContent
  2793. {
  2794. explicit nsStyleContent(StyleStructContext aContext);
  2795. nsStyleContent(const nsStyleContent& aContent);
  2796. ~nsStyleContent();
  2797. void FinishStyle(nsPresContext* aPresContext) {}
  2798. void* operator new(size_t sz, nsStyleContent* aSelf) { return aSelf; }
  2799. void* operator new(size_t sz, nsPresContext* aContext) {
  2800. return aContext->PresShell()->
  2801. AllocateByObjectID(mozilla::eArenaObjectID_nsStyleContent, sz);
  2802. }
  2803. void Destroy(nsPresContext* aContext);
  2804. nsChangeHint CalcDifference(const nsStyleContent& aNewData) const;
  2805. static nsChangeHint MaxDifference() {
  2806. return nsChangeHint_ReconstructFrame |
  2807. NS_STYLE_HINT_REFLOW;
  2808. }
  2809. static nsChangeHint DifferenceAlwaysHandledForDescendants() {
  2810. // CalcDifference never returns the reflow hints that are sometimes
  2811. // handled for descendants as hints not handled for descendants.
  2812. return nsChangeHint_NeedReflow |
  2813. nsChangeHint_ReflowChangesSizeOrPosition |
  2814. nsChangeHint_ClearAncestorIntrinsics;
  2815. }
  2816. uint32_t ContentCount() const { return mContents.Length(); } // [reset]
  2817. const nsStyleContentData& ContentAt(uint32_t aIndex) const {
  2818. return mContents[aIndex];
  2819. }
  2820. nsStyleContentData& ContentAt(uint32_t aIndex) { return mContents[aIndex]; }
  2821. void AllocateContents(uint32_t aCount) {
  2822. // We need to run the destructors of the elements of mContents, so we
  2823. // delete and reallocate even if aCount == mContentCount. (If
  2824. // nsStyleContentData had its members private and managed their
  2825. // ownership on setting, we wouldn't need this, but that seems
  2826. // unnecessary at this point.)
  2827. mContents.Clear();
  2828. mContents.SetLength(aCount);
  2829. }
  2830. uint32_t CounterIncrementCount() const { return mIncrements.Length(); } // [reset]
  2831. const nsStyleCounterData& CounterIncrementAt(uint32_t aIndex) const {
  2832. return mIncrements[aIndex];
  2833. }
  2834. void AllocateCounterIncrements(uint32_t aCount) {
  2835. mIncrements.Clear();
  2836. mIncrements.SetLength(aCount);
  2837. }
  2838. void SetCounterIncrementAt(uint32_t aIndex, const nsString& aCounter, int32_t aIncrement) {
  2839. mIncrements[aIndex].mCounter = aCounter;
  2840. mIncrements[aIndex].mValue = aIncrement;
  2841. }
  2842. uint32_t CounterResetCount() const { return mResets.Length(); } // [reset]
  2843. const nsStyleCounterData& CounterResetAt(uint32_t aIndex) const {
  2844. return mResets[aIndex];
  2845. }
  2846. void AllocateCounterResets(uint32_t aCount) {
  2847. mResets.Clear();
  2848. mResets.SetLength(aCount);
  2849. }
  2850. void SetCounterResetAt(uint32_t aIndex, const nsString& aCounter, int32_t aValue) {
  2851. mResets[aIndex].mCounter = aCounter;
  2852. mResets[aIndex].mValue = aValue;
  2853. }
  2854. protected:
  2855. nsTArray<nsStyleContentData> mContents;
  2856. nsTArray<nsStyleCounterData> mIncrements;
  2857. nsTArray<nsStyleCounterData> mResets;
  2858. };
  2859. struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleUIReset
  2860. {
  2861. explicit nsStyleUIReset(StyleStructContext aContext);
  2862. nsStyleUIReset(const nsStyleUIReset& aOther);
  2863. ~nsStyleUIReset();
  2864. void FinishStyle(nsPresContext* aPresContext) {}
  2865. void* operator new(size_t sz, nsStyleUIReset* aSelf) { return aSelf; }
  2866. void* operator new(size_t sz, nsPresContext* aContext) {
  2867. return aContext->PresShell()->
  2868. AllocateByObjectID(mozilla::eArenaObjectID_nsStyleUIReset, sz);
  2869. }
  2870. void Destroy(nsPresContext* aContext) {
  2871. this->~nsStyleUIReset();
  2872. aContext->PresShell()->
  2873. FreeByObjectID(mozilla::eArenaObjectID_nsStyleUIReset, this);
  2874. }
  2875. nsChangeHint CalcDifference(const nsStyleUIReset& aNewData) const;
  2876. static nsChangeHint MaxDifference() {
  2877. return nsChangeHint_ReconstructFrame |
  2878. NS_STYLE_HINT_REFLOW;
  2879. }
  2880. static nsChangeHint DifferenceAlwaysHandledForDescendants() {
  2881. // CalcDifference never returns the reflow hints that are sometimes
  2882. // handled for descendants as hints not handled for descendants.
  2883. return nsChangeHint_NeedReflow |
  2884. nsChangeHint_ReflowChangesSizeOrPosition |
  2885. nsChangeHint_ClearAncestorIntrinsics;
  2886. }
  2887. mozilla::StyleUserSelect mUserSelect; // [reset](selection-style)
  2888. uint8_t mForceBrokenImageIcon; // [reset] (0 if not forcing, otherwise forcing)
  2889. uint8_t mIMEMode; // [reset]
  2890. mozilla::StyleWindowDragging mWindowDragging; // [reset]
  2891. uint8_t mWindowShadow; // [reset]
  2892. };
  2893. struct nsCursorImage
  2894. {
  2895. bool mHaveHotspot;
  2896. float mHotspotX, mHotspotY;
  2897. nsCursorImage();
  2898. nsCursorImage(const nsCursorImage& aOther);
  2899. ~nsCursorImage();
  2900. nsCursorImage& operator=(const nsCursorImage& aOther);
  2901. bool operator==(const nsCursorImage& aOther) const;
  2902. bool operator!=(const nsCursorImage& aOther) const
  2903. {
  2904. return !(*this == aOther);
  2905. }
  2906. void SetImage(imgIRequest *aImage) {
  2907. if (mImage) {
  2908. mImage->UnlockImage();
  2909. mImage->RequestDiscard();
  2910. }
  2911. mImage = aImage;
  2912. if (mImage) {
  2913. mImage->LockImage();
  2914. }
  2915. }
  2916. imgIRequest* GetImage() const {
  2917. return mImage;
  2918. }
  2919. private:
  2920. nsCOMPtr<imgIRequest> mImage;
  2921. };
  2922. struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleUserInterface
  2923. {
  2924. explicit nsStyleUserInterface(StyleStructContext aContext);
  2925. nsStyleUserInterface(const nsStyleUserInterface& aOther);
  2926. ~nsStyleUserInterface();
  2927. void FinishStyle(nsPresContext* aPresContext) {}
  2928. void* operator new(size_t sz, nsStyleUserInterface* aSelf) { return aSelf; }
  2929. void* operator new(size_t sz, nsPresContext* aContext) {
  2930. return aContext->PresShell()->
  2931. AllocateByObjectID(mozilla::eArenaObjectID_nsStyleUserInterface, sz);
  2932. }
  2933. void Destroy(nsPresContext* aContext) {
  2934. this->~nsStyleUserInterface();
  2935. aContext->PresShell()->
  2936. FreeByObjectID(mozilla::eArenaObjectID_nsStyleUserInterface, this);
  2937. }
  2938. nsChangeHint CalcDifference(const nsStyleUserInterface& aNewData) const;
  2939. static nsChangeHint MaxDifference() {
  2940. return nsChangeHint_ReconstructFrame |
  2941. nsChangeHint_NeedReflow |
  2942. nsChangeHint_NeedDirtyReflow |
  2943. NS_STYLE_HINT_VISUAL |
  2944. nsChangeHint_UpdateCursor |
  2945. nsChangeHint_NeutralChange;
  2946. }
  2947. static nsChangeHint DifferenceAlwaysHandledForDescendants() {
  2948. // CalcDifference never returns the reflow hints that are sometimes
  2949. // handled for descendants as hints not handled for descendants.
  2950. return nsChangeHint_NeedReflow;
  2951. }
  2952. mozilla::StyleUserInput mUserInput; // [inherited]
  2953. mozilla::StyleUserModify mUserModify; // [inherited] (modify-content)
  2954. mozilla::StyleUserFocus mUserFocus; // [inherited] (auto-select)
  2955. uint8_t mPointerEvents; // [inherited] see nsStyleConsts.h
  2956. uint8_t mCursor; // [inherited] See nsStyleConsts.h
  2957. nsTArray<nsCursorImage> mCursorImages; // [inherited] images and coords
  2958. mozilla::StyleComplexColor mCaretColor; // [inherited]
  2959. mozilla::StyleScrollbarWidth mScrollbarWidth;
  2960. inline uint8_t GetEffectivePointerEvents(nsIFrame* aFrame) const;
  2961. };
  2962. struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleXUL
  2963. {
  2964. explicit nsStyleXUL(StyleStructContext aContext);
  2965. nsStyleXUL(const nsStyleXUL& aSource);
  2966. ~nsStyleXUL();
  2967. void FinishStyle(nsPresContext* aPresContext) {}
  2968. void* operator new(size_t sz, nsStyleXUL* aSelf) { return aSelf; }
  2969. void* operator new(size_t sz, nsPresContext* aContext) {
  2970. return aContext->PresShell()->
  2971. AllocateByObjectID(mozilla::eArenaObjectID_nsStyleXUL, sz);
  2972. }
  2973. void Destroy(nsPresContext* aContext) {
  2974. this->~nsStyleXUL();
  2975. aContext->PresShell()->
  2976. FreeByObjectID(mozilla::eArenaObjectID_nsStyleXUL, this);
  2977. }
  2978. nsChangeHint CalcDifference(const nsStyleXUL& aNewData) const;
  2979. static nsChangeHint MaxDifference() {
  2980. return nsChangeHint_ReconstructFrame |
  2981. NS_STYLE_HINT_REFLOW;
  2982. }
  2983. static nsChangeHint DifferenceAlwaysHandledForDescendants() {
  2984. // CalcDifference never returns the reflow hints that are sometimes
  2985. // handled for descendants as hints not handled for descendants.
  2986. return nsChangeHint_NeedReflow |
  2987. nsChangeHint_ReflowChangesSizeOrPosition |
  2988. nsChangeHint_ClearAncestorIntrinsics;
  2989. }
  2990. float mBoxFlex; // [reset] see nsStyleConsts.h
  2991. uint32_t mBoxOrdinal; // [reset] see nsStyleConsts.h
  2992. mozilla::StyleBoxAlign mBoxAlign; // [reset]
  2993. mozilla::StyleBoxDirection mBoxDirection; // [reset]
  2994. mozilla::StyleBoxOrient mBoxOrient; // [reset]
  2995. mozilla::StyleBoxPack mBoxPack; // [reset]
  2996. bool mStretchStack; // [reset] see nsStyleConsts.h
  2997. };
  2998. struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleColumn
  2999. {
  3000. explicit nsStyleColumn(StyleStructContext aContext);
  3001. nsStyleColumn(const nsStyleColumn& aSource);
  3002. ~nsStyleColumn();
  3003. void FinishStyle(nsPresContext* aPresContext) {}
  3004. void* operator new(size_t sz, nsStyleColumn* aSelf) { return aSelf; }
  3005. void* operator new(size_t sz, nsPresContext* aContext) {
  3006. return aContext->PresShell()->
  3007. AllocateByObjectID(mozilla::eArenaObjectID_nsStyleColumn, sz);
  3008. }
  3009. void Destroy(nsPresContext* aContext) {
  3010. this->~nsStyleColumn();
  3011. aContext->PresShell()->
  3012. FreeByObjectID(mozilla::eArenaObjectID_nsStyleColumn, this);
  3013. }
  3014. nsChangeHint CalcDifference(const nsStyleColumn& aNewData) const;
  3015. static nsChangeHint MaxDifference() {
  3016. return nsChangeHint_ReconstructFrame |
  3017. NS_STYLE_HINT_REFLOW |
  3018. nsChangeHint_NeutralChange;
  3019. }
  3020. static nsChangeHint DifferenceAlwaysHandledForDescendants() {
  3021. // CalcDifference never returns the reflow hints that are sometimes
  3022. // handled for descendants as hints not handled for descendants.
  3023. return nsChangeHint_NeedReflow |
  3024. nsChangeHint_ReflowChangesSizeOrPosition |
  3025. nsChangeHint_ClearAncestorIntrinsics;
  3026. }
  3027. /**
  3028. * This is the maximum number of columns we can process. It's used in both
  3029. * nsColumnSetFrame and nsRuleNode.
  3030. */
  3031. static const uint32_t kMaxColumnCount = 1000;
  3032. uint32_t mColumnCount; // [reset] see nsStyleConsts.h
  3033. nsStyleCoord mColumnWidth; // [reset] coord, auto
  3034. nsStyleCoord mColumnGap; // [reset] <length-percentage> | normal
  3035. mozilla::StyleComplexColor mColumnRuleColor; // [reset]
  3036. uint8_t mColumnRuleStyle; // [reset]
  3037. uint8_t mColumnFill; // [reset] see nsStyleConsts.h
  3038. void SetColumnRuleWidth(nscoord aWidth) {
  3039. mColumnRuleWidth = NS_ROUND_BORDER_TO_PIXELS(aWidth, mTwipsPerPixel);
  3040. }
  3041. nscoord GetComputedColumnRuleWidth() const {
  3042. return (IsVisibleBorderStyle(mColumnRuleStyle) ? mColumnRuleWidth : 0);
  3043. }
  3044. protected:
  3045. nscoord mColumnRuleWidth; // [reset] coord
  3046. nscoord mTwipsPerPixel;
  3047. };
  3048. enum nsStyleSVGPaintType {
  3049. eStyleSVGPaintType_None = 1,
  3050. eStyleSVGPaintType_Color,
  3051. eStyleSVGPaintType_Server,
  3052. eStyleSVGPaintType_ContextFill,
  3053. eStyleSVGPaintType_ContextStroke
  3054. };
  3055. enum nsStyleSVGOpacitySource : uint8_t {
  3056. eStyleSVGOpacitySource_Normal,
  3057. eStyleSVGOpacitySource_ContextFillOpacity,
  3058. eStyleSVGOpacitySource_ContextStrokeOpacity
  3059. };
  3060. class nsStyleSVGPaint
  3061. {
  3062. public:
  3063. explicit nsStyleSVGPaint(nsStyleSVGPaintType aType = nsStyleSVGPaintType(0));
  3064. nsStyleSVGPaint(const nsStyleSVGPaint& aSource);
  3065. ~nsStyleSVGPaint();
  3066. nsStyleSVGPaint& operator=(const nsStyleSVGPaint& aOther);
  3067. nsStyleSVGPaintType Type() const { return mType; }
  3068. void SetNone();
  3069. void SetColor(nscolor aColor);
  3070. void SetPaintServer(mozilla::css::URLValue* aPaintServer,
  3071. nscolor aFallbackColor);
  3072. void SetContextValue(nsStyleSVGPaintType aType,
  3073. nscolor aFallbackColor);
  3074. nscolor GetColor() const {
  3075. MOZ_ASSERT(mType == eStyleSVGPaintType_Color);
  3076. return mPaint.mColor;
  3077. }
  3078. mozilla::css::URLValue* GetPaintServer() const {
  3079. MOZ_ASSERT(mType == eStyleSVGPaintType_Server);
  3080. return mPaint.mPaintServer;
  3081. }
  3082. nscolor GetFallbackColor() const {
  3083. MOZ_ASSERT(mType == eStyleSVGPaintType_Server ||
  3084. mType == eStyleSVGPaintType_ContextFill ||
  3085. mType == eStyleSVGPaintType_ContextStroke);
  3086. return mFallbackColor;
  3087. }
  3088. bool operator==(const nsStyleSVGPaint& aOther) const;
  3089. bool operator!=(const nsStyleSVGPaint& aOther) const {
  3090. return !(*this == aOther);
  3091. }
  3092. private:
  3093. void Reset();
  3094. void Assign(const nsStyleSVGPaint& aOther);
  3095. union {
  3096. nscolor mColor;
  3097. mozilla::css::URLValue* mPaintServer;
  3098. } mPaint;
  3099. nsStyleSVGPaintType mType;
  3100. nscolor mFallbackColor;
  3101. };
  3102. struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleSVG
  3103. {
  3104. explicit nsStyleSVG(StyleStructContext aContext);
  3105. nsStyleSVG(const nsStyleSVG& aSource);
  3106. ~nsStyleSVG();
  3107. void FinishStyle(nsPresContext* aPresContext) {}
  3108. void* operator new(size_t sz, nsStyleSVG* aSelf) { return aSelf; }
  3109. void* operator new(size_t sz, nsPresContext* aContext) {
  3110. return aContext->PresShell()->
  3111. AllocateByObjectID(mozilla::eArenaObjectID_nsStyleSVG, sz);
  3112. }
  3113. void Destroy(nsPresContext* aContext) {
  3114. this->~nsStyleSVG();
  3115. aContext->PresShell()->
  3116. FreeByObjectID(mozilla::eArenaObjectID_nsStyleSVG, this);
  3117. }
  3118. nsChangeHint CalcDifference(const nsStyleSVG& aNewData) const;
  3119. static nsChangeHint MaxDifference() {
  3120. return nsChangeHint_UpdateEffects |
  3121. nsChangeHint_NeedReflow |
  3122. nsChangeHint_NeedDirtyReflow | // XXX remove me: bug 876085
  3123. nsChangeHint_RepaintFrame;
  3124. }
  3125. static nsChangeHint DifferenceAlwaysHandledForDescendants() {
  3126. // CalcDifference never returns nsChangeHint_NeedReflow as a hint
  3127. // not handled for descendants, and never returns
  3128. // nsChangeHint_ClearAncestorIntrinsics at all.
  3129. return nsChangeHint_NeedReflow;
  3130. }
  3131. nsStyleSVGPaint mFill; // [inherited]
  3132. nsStyleSVGPaint mStroke; // [inherited]
  3133. RefPtr<mozilla::css::URLValue> mMarkerEnd; // [inherited]
  3134. RefPtr<mozilla::css::URLValue> mMarkerMid; // [inherited]
  3135. RefPtr<mozilla::css::URLValue> mMarkerStart; // [inherited]
  3136. nsTArray<nsStyleCoord> mStrokeDasharray; // [inherited] coord, percent, factor
  3137. nsStyleCoord mStrokeDashoffset; // [inherited] coord, percent, factor
  3138. nsStyleCoord mStrokeWidth; // [inherited] coord, percent, factor
  3139. float mFillOpacity; // [inherited]
  3140. float mStrokeMiterlimit; // [inherited]
  3141. float mStrokeOpacity; // [inherited]
  3142. mozilla::StyleFillRule mClipRule; // [inherited]
  3143. uint8_t mColorInterpolation; // [inherited] see nsStyleConsts.h
  3144. uint8_t mColorInterpolationFilters; // [inherited] see nsStyleConsts.h
  3145. mozilla::StyleFillRule mFillRule; // [inherited] see nsStyleConsts.h
  3146. uint8_t mPaintOrder; // [inherited] see nsStyleConsts.h
  3147. uint8_t mShapeRendering; // [inherited] see nsStyleConsts.h
  3148. uint8_t mStrokeLinecap; // [inherited] see nsStyleConsts.h
  3149. uint8_t mStrokeLinejoin; // [inherited] see nsStyleConsts.h
  3150. uint8_t mTextAnchor; // [inherited] see nsStyleConsts.h
  3151. nsStyleSVGOpacitySource FillOpacitySource() const {
  3152. uint8_t value = (mContextFlags & FILL_OPACITY_SOURCE_MASK) >>
  3153. FILL_OPACITY_SOURCE_SHIFT;
  3154. return nsStyleSVGOpacitySource(value);
  3155. }
  3156. nsStyleSVGOpacitySource StrokeOpacitySource() const {
  3157. uint8_t value = (mContextFlags & STROKE_OPACITY_SOURCE_MASK) >>
  3158. STROKE_OPACITY_SOURCE_SHIFT;
  3159. return nsStyleSVGOpacitySource(value);
  3160. }
  3161. bool StrokeDasharrayFromObject() const {
  3162. return mContextFlags & STROKE_DASHARRAY_CONTEXT;
  3163. }
  3164. bool StrokeDashoffsetFromObject() const {
  3165. return mContextFlags & STROKE_DASHOFFSET_CONTEXT;
  3166. }
  3167. bool StrokeWidthFromObject() const {
  3168. return mContextFlags & STROKE_WIDTH_CONTEXT;
  3169. }
  3170. void SetFillOpacitySource(nsStyleSVGOpacitySource aValue) {
  3171. mContextFlags = (mContextFlags & ~FILL_OPACITY_SOURCE_MASK) |
  3172. (aValue << FILL_OPACITY_SOURCE_SHIFT);
  3173. }
  3174. void SetStrokeOpacitySource(nsStyleSVGOpacitySource aValue) {
  3175. mContextFlags = (mContextFlags & ~STROKE_OPACITY_SOURCE_MASK) |
  3176. (aValue << STROKE_OPACITY_SOURCE_SHIFT);
  3177. }
  3178. void SetStrokeDasharrayFromObject(bool aValue) {
  3179. mContextFlags = (mContextFlags & ~STROKE_DASHARRAY_CONTEXT) |
  3180. (aValue ? STROKE_DASHARRAY_CONTEXT : 0);
  3181. }
  3182. void SetStrokeDashoffsetFromObject(bool aValue) {
  3183. mContextFlags = (mContextFlags & ~STROKE_DASHOFFSET_CONTEXT) |
  3184. (aValue ? STROKE_DASHOFFSET_CONTEXT : 0);
  3185. }
  3186. void SetStrokeWidthFromObject(bool aValue) {
  3187. mContextFlags = (mContextFlags & ~STROKE_WIDTH_CONTEXT) |
  3188. (aValue ? STROKE_WIDTH_CONTEXT : 0);
  3189. }
  3190. bool HasMarker() const {
  3191. return mMarkerStart || mMarkerMid || mMarkerEnd;
  3192. }
  3193. /**
  3194. * Returns true if the stroke is not "none" and the stroke-opacity is greater
  3195. * than zero. This ignores stroke-widths as that depends on the context.
  3196. */
  3197. bool HasStroke() const {
  3198. return mStroke.Type() != eStyleSVGPaintType_None && mStrokeOpacity > 0;
  3199. }
  3200. /**
  3201. * Returns true if the fill is not "none" and the fill-opacity is greater
  3202. * than zero.
  3203. */
  3204. bool HasFill() const {
  3205. return mFill.Type() != eStyleSVGPaintType_None && mFillOpacity > 0;
  3206. }
  3207. private:
  3208. // Flags to represent the use of context-fill and context-stroke
  3209. // for fill-opacity or stroke-opacity, and context-value for stroke-dasharray,
  3210. // stroke-dashoffset and stroke-width.
  3211. enum {
  3212. FILL_OPACITY_SOURCE_MASK = 0x03, // fill-opacity: context-{fill,stroke}
  3213. STROKE_OPACITY_SOURCE_MASK = 0x0C, // stroke-opacity: context-{fill,stroke}
  3214. STROKE_DASHARRAY_CONTEXT = 0x10, // stroke-dasharray: context-value
  3215. STROKE_DASHOFFSET_CONTEXT = 0x20, // stroke-dashoffset: context-value
  3216. STROKE_WIDTH_CONTEXT = 0x40, // stroke-width: context-value
  3217. FILL_OPACITY_SOURCE_SHIFT = 0,
  3218. STROKE_OPACITY_SOURCE_SHIFT = 2,
  3219. };
  3220. uint8_t mContextFlags; // [inherited]
  3221. };
  3222. struct nsStyleFilter
  3223. {
  3224. nsStyleFilter();
  3225. nsStyleFilter(const nsStyleFilter& aSource);
  3226. ~nsStyleFilter();
  3227. void FinishStyle(nsPresContext* aPresContext) {}
  3228. nsStyleFilter& operator=(const nsStyleFilter& aOther);
  3229. bool operator==(const nsStyleFilter& aOther) const;
  3230. bool operator!=(const nsStyleFilter& aOther) const {
  3231. return !(*this == aOther);
  3232. }
  3233. uint32_t GetType() const {
  3234. return mType;
  3235. }
  3236. const nsStyleCoord& GetFilterParameter() const {
  3237. NS_ASSERTION(mType != NS_STYLE_FILTER_DROP_SHADOW &&
  3238. mType != NS_STYLE_FILTER_URL &&
  3239. mType != NS_STYLE_FILTER_NONE, "wrong filter type");
  3240. return mFilterParameter;
  3241. }
  3242. void SetFilterParameter(const nsStyleCoord& aFilterParameter,
  3243. int32_t aType);
  3244. mozilla::css::URLValue* GetURL() const {
  3245. MOZ_ASSERT(mType == NS_STYLE_FILTER_URL, "wrong filter type");
  3246. return mURL;
  3247. }
  3248. bool SetURL(mozilla::css::URLValue* aValue);
  3249. nsCSSShadowArray* GetDropShadow() const {
  3250. NS_ASSERTION(mType == NS_STYLE_FILTER_DROP_SHADOW, "wrong filter type");
  3251. return mDropShadow;
  3252. }
  3253. void SetDropShadow(nsCSSShadowArray* aDropShadow);
  3254. private:
  3255. void ReleaseRef();
  3256. uint32_t mType; // see NS_STYLE_FILTER_* constants in nsStyleConsts.h
  3257. nsStyleCoord mFilterParameter; // coord, percent, factor, angle
  3258. union {
  3259. mozilla::css::URLValue* mURL;
  3260. nsCSSShadowArray* mDropShadow;
  3261. };
  3262. };
  3263. template<>
  3264. struct nsTArray_CopyChooser<nsStyleFilter>
  3265. {
  3266. typedef nsTArray_CopyWithConstructors<nsStyleFilter> Type;
  3267. };
  3268. struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleSVGReset
  3269. {
  3270. explicit nsStyleSVGReset(StyleStructContext aContext);
  3271. nsStyleSVGReset(const nsStyleSVGReset& aSource);
  3272. ~nsStyleSVGReset();
  3273. // Resolves and tracks the images in mMask. Only called with a Servo-backed
  3274. // style system, where those images must be resolved later than the OMT
  3275. // nsStyleSVGReset constructor call.
  3276. void FinishStyle(nsPresContext* aPresContext);
  3277. void* operator new(size_t sz, nsStyleSVGReset* aSelf) { return aSelf; }
  3278. void* operator new(size_t sz, nsPresContext* aContext) {
  3279. return aContext->PresShell()->
  3280. AllocateByObjectID(mozilla::eArenaObjectID_nsStyleSVGReset, sz);
  3281. }
  3282. void Destroy(nsPresContext* aContext);
  3283. nsChangeHint CalcDifference(const nsStyleSVGReset& aNewData) const;
  3284. static nsChangeHint MaxDifference() {
  3285. return nsChangeHint_UpdateEffects |
  3286. nsChangeHint_UpdateOverflow |
  3287. nsChangeHint_NeutralChange |
  3288. nsChangeHint_RepaintFrame |
  3289. nsChangeHint_UpdateBackgroundPosition |
  3290. NS_STYLE_HINT_REFLOW;
  3291. }
  3292. static nsChangeHint DifferenceAlwaysHandledForDescendants() {
  3293. // CalcDifference never returns the reflow hints that are sometimes
  3294. // handled for descendants as hints not handled for descendants.
  3295. return nsChangeHint_NeedReflow |
  3296. nsChangeHint_ReflowChangesSizeOrPosition |
  3297. nsChangeHint_ClearAncestorIntrinsics;
  3298. }
  3299. bool HasClipPath() const {
  3300. return mClipPath.GetType() != mozilla::StyleShapeSourceType::None;
  3301. }
  3302. bool HasNonScalingStroke() const {
  3303. return mVectorEffect == NS_STYLE_VECTOR_EFFECT_NON_SCALING_STROKE;
  3304. }
  3305. nsStyleImageLayers mMask;
  3306. mozilla::StyleClipPath mClipPath; // [reset]
  3307. nscolor mStopColor; // [reset]
  3308. nscolor mFloodColor; // [reset]
  3309. nscolor mLightingColor; // [reset]
  3310. float mStopOpacity; // [reset]
  3311. float mFloodOpacity; // [reset]
  3312. uint8_t mDominantBaseline; // [reset] see nsStyleConsts.h
  3313. uint8_t mVectorEffect; // [reset] see nsStyleConsts.h
  3314. uint8_t mMaskType; // [reset] see nsStyleConsts.h
  3315. };
  3316. struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleVariables
  3317. {
  3318. explicit nsStyleVariables(StyleStructContext aContext);
  3319. nsStyleVariables(const nsStyleVariables& aSource);
  3320. ~nsStyleVariables();
  3321. void FinishStyle(nsPresContext* aPresContext) {}
  3322. void* operator new(size_t sz, nsStyleVariables* aSelf) { return aSelf; }
  3323. void* operator new(size_t sz, nsPresContext* aContext) {
  3324. return aContext->PresShell()->
  3325. AllocateByObjectID(mozilla::eArenaObjectID_nsStyleVariables, sz);
  3326. }
  3327. void Destroy(nsPresContext* aContext) {
  3328. this->~nsStyleVariables();
  3329. aContext->PresShell()->
  3330. FreeByObjectID(mozilla::eArenaObjectID_nsStyleVariables, this);
  3331. }
  3332. nsChangeHint CalcDifference(const nsStyleVariables& aNewData) const;
  3333. static nsChangeHint MaxDifference() {
  3334. return nsChangeHint(0);
  3335. }
  3336. static nsChangeHint DifferenceAlwaysHandledForDescendants() {
  3337. // CalcDifference never returns nsChangeHint_NeedReflow or
  3338. // nsChangeHint_ClearAncestorIntrinsics at all.
  3339. return nsChangeHint(0);
  3340. }
  3341. mozilla::CSSVariableValues mVariables;
  3342. };
  3343. struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleEffects
  3344. {
  3345. explicit nsStyleEffects(StyleStructContext aContext);
  3346. nsStyleEffects(const nsStyleEffects& aSource);
  3347. ~nsStyleEffects();
  3348. void FinishStyle(nsPresContext* aPresContext) {}
  3349. void* operator new(size_t sz, nsStyleEffects* aSelf) { return aSelf; }
  3350. void* operator new(size_t sz, nsPresContext* aContext) {
  3351. return aContext->PresShell()->
  3352. AllocateByObjectID(mozilla::eArenaObjectID_nsStyleEffects, sz);
  3353. }
  3354. void Destroy(nsPresContext* aContext) {
  3355. this->~nsStyleEffects();
  3356. aContext->PresShell()->
  3357. FreeByObjectID(mozilla::eArenaObjectID_nsStyleEffects, this);
  3358. }
  3359. nsChangeHint CalcDifference(const nsStyleEffects& aNewData) const;
  3360. static nsChangeHint MaxDifference() {
  3361. return nsChangeHint_AllReflowHints |
  3362. nsChangeHint_UpdateOverflow |
  3363. nsChangeHint_SchedulePaint |
  3364. nsChangeHint_RepaintFrame |
  3365. nsChangeHint_UpdateOpacityLayer |
  3366. nsChangeHint_UpdateUsesOpacity |
  3367. nsChangeHint_UpdateContainingBlock |
  3368. nsChangeHint_UpdateEffects |
  3369. nsChangeHint_NeutralChange;
  3370. }
  3371. static nsChangeHint DifferenceAlwaysHandledForDescendants() {
  3372. // CalcDifference never returns the reflow hints that are sometimes
  3373. // handled for descendants as hints not handled for descendants.
  3374. return nsChangeHint_NeedReflow |
  3375. nsChangeHint_ReflowChangesSizeOrPosition |
  3376. nsChangeHint_ClearAncestorIntrinsics;
  3377. }
  3378. bool HasFilters() const {
  3379. return !mFilters.IsEmpty();
  3380. }
  3381. nsTArray<nsStyleFilter> mFilters; // [reset]
  3382. RefPtr<nsCSSShadowArray> mBoxShadow; // [reset] nullptr for 'none'
  3383. nsRect mClip; // [reset] offsets from UL border edge
  3384. float mOpacity; // [reset]
  3385. uint8_t mClipFlags; // [reset] see nsStyleConsts.h
  3386. uint8_t mMixBlendMode; // [reset] see nsStyleConsts.h
  3387. };
  3388. #define STATIC_ASSERT_TYPE_LAYOUTS_MATCH(T1, T2) \
  3389. static_assert(sizeof(T1) == sizeof(T2), \
  3390. "Size mismatch between " #T1 " and " #T2); \
  3391. static_assert(alignof(T1) == alignof(T2), \
  3392. "Align mismatch between " #T1 " and " #T2); \
  3393. #define STATIC_ASSERT_FIELD_OFFSET_MATCHES(T1, T2, field) \
  3394. static_assert(offsetof(T1, field) == offsetof(T2, field), \
  3395. "Field offset mismatch of " #field " between " #T1 " and " #T2); \
  3396. /**
  3397. * These *_Simple types are used to map Gecko types to layout-equivalent but
  3398. * simpler Rust types, to aid Rust binding generation.
  3399. *
  3400. * If something in this types or the assertions below needs to change, ask
  3401. * bholley, heycam or emilio before!
  3402. *
  3403. * <div rustbindgen="true" replaces="nsPoint">
  3404. */
  3405. struct nsPoint_Simple {
  3406. nscoord x, y;
  3407. };
  3408. STATIC_ASSERT_TYPE_LAYOUTS_MATCH(nsPoint, nsPoint_Simple);
  3409. STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsPoint, nsPoint_Simple, x);
  3410. STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsPoint, nsPoint_Simple, y);
  3411. /**
  3412. * <div rustbindgen="true" replaces="nsMargin">
  3413. */
  3414. struct nsMargin_Simple {
  3415. nscoord top, right, bottom, left;
  3416. };
  3417. STATIC_ASSERT_TYPE_LAYOUTS_MATCH(nsMargin, nsMargin_Simple);
  3418. STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsMargin, nsMargin_Simple, top);
  3419. STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsMargin, nsMargin_Simple, right);
  3420. STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsMargin, nsMargin_Simple, bottom);
  3421. STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsMargin, nsMargin_Simple, left);
  3422. /**
  3423. * <div rustbindgen="true" replaces="nsRect">
  3424. */
  3425. struct nsRect_Simple {
  3426. nscoord x, y, width, height;
  3427. };
  3428. STATIC_ASSERT_TYPE_LAYOUTS_MATCH(nsRect, nsRect_Simple);
  3429. STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsRect, nsRect_Simple, x);
  3430. STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsRect, nsRect_Simple, y);
  3431. STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsRect, nsRect_Simple, width);
  3432. STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsRect, nsRect_Simple, height);
  3433. /**
  3434. * <div rustbindgen="true" replaces="nsSize">
  3435. */
  3436. struct nsSize_Simple {
  3437. nscoord width, height;
  3438. };
  3439. STATIC_ASSERT_TYPE_LAYOUTS_MATCH(nsSize, nsSize_Simple);
  3440. STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsSize, nsSize_Simple, width);
  3441. STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsSize, nsSize_Simple, height);
  3442. /**
  3443. * <div rustbindgen="true" replaces="UniquePtr">
  3444. *
  3445. * TODO(Emilio): This is a workaround and we should be able to get rid of this
  3446. * one.
  3447. */
  3448. template<typename T, typename Deleter = mozilla::DefaultDelete<T>>
  3449. struct UniquePtr_Simple {
  3450. T* mPtr;
  3451. };
  3452. STATIC_ASSERT_TYPE_LAYOUTS_MATCH(mozilla::UniquePtr<int>, UniquePtr_Simple<int>);
  3453. /**
  3454. * <div rustbindgen replaces="nsTArray"></div>
  3455. */
  3456. template<typename T>
  3457. class nsTArray_Simple {
  3458. T* mBuffer;
  3459. public:
  3460. // The existence of a destructor here prevents bindgen from deriving the Clone
  3461. // trait via a simple memory copy.
  3462. ~nsTArray_Simple() {};
  3463. };
  3464. STATIC_ASSERT_TYPE_LAYOUTS_MATCH(nsTArray<nsStyleImageLayers::Layer>,
  3465. nsTArray_Simple<nsStyleImageLayers::Layer>);
  3466. STATIC_ASSERT_TYPE_LAYOUTS_MATCH(nsTArray<mozilla::StyleTransition>,
  3467. nsTArray_Simple<mozilla::StyleTransition>);
  3468. STATIC_ASSERT_TYPE_LAYOUTS_MATCH(nsTArray<mozilla::StyleAnimation>,
  3469. nsTArray_Simple<mozilla::StyleAnimation>);
  3470. #endif /* nsStyleStruct_h___ */