1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276 |
- /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
- /* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
- /*
- * structs that contain the data provided by nsStyleContext, the
- * internal API for computed style data for an element
- */
- #include "nsStyleStruct.h"
- #include "nsStyleStructInlines.h"
- #include "nsStyleConsts.h"
- #include "nsThemeConstants.h"
- #include "nsString.h"
- #include "nsPresContext.h"
- #include "nsIAppShellService.h"
- #include "nsIWidget.h"
- #include "nsCRTGlue.h"
- #include "nsCSSParser.h"
- #include "nsCSSProps.h"
- #include "nsDeviceContext.h"
- #include "nsStyleUtil.h"
- #include "nsCOMPtr.h"
- #include "nsBidiUtils.h"
- #include "nsLayoutUtils.h"
- #include "imgIRequest.h"
- #include "imgIContainer.h"
- #include "CounterStyleManager.h"
- #include "mozilla/dom/AnimationEffectReadOnlyBinding.h" // for PlaybackDirection
- #include "mozilla/dom/ImageTracker.h"
- #include "mozilla/Likely.h"
- #include "nsIURI.h"
- #include "nsIDocument.h"
- #include <algorithm>
- using namespace mozilla;
- using namespace mozilla::dom;
- static_assert((((1 << nsStyleStructID_Length) - 1) &
- ~(NS_STYLE_INHERIT_MASK)) == 0,
- "Not enough bits in NS_STYLE_INHERIT_MASK");
- /* static */ const int32_t nsStyleGridLine::kMinLine;
- /* static */ const int32_t nsStyleGridLine::kMaxLine;
- static bool
- EqualURIs(nsIURI *aURI1, nsIURI *aURI2)
- {
- bool eq;
- return aURI1 == aURI2 || // handle null==null, and optimize
- (aURI1 && aURI2 &&
- NS_SUCCEEDED(aURI1->Equals(aURI2, &eq)) && // not equal on fail
- eq);
- }
- static bool
- DefinitelyEqualURIs(css::URLValueData* aURI1,
- css::URLValueData* aURI2)
- {
- return aURI1 == aURI2 ||
- (aURI1 && aURI2 && aURI1->DefinitelyEqualURIs(*aURI2));
- }
- static bool
- DefinitelyEqualURIsAndPrincipal(css::URLValueData* aURI1,
- css::URLValueData* aURI2)
- {
- return aURI1 == aURI2 ||
- (aURI1 && aURI2 && aURI1->DefinitelyEqualURIsAndPrincipal(*aURI2));
- }
- static bool
- EqualImages(imgIRequest *aImage1, imgIRequest* aImage2)
- {
- if (aImage1 == aImage2) {
- return true;
- }
- if (!aImage1 || !aImage2) {
- return false;
- }
- nsCOMPtr<nsIURI> uri1, uri2;
- aImage1->GetURI(getter_AddRefs(uri1));
- aImage2->GetURI(getter_AddRefs(uri2));
- return EqualURIs(uri1, uri2);
- }
- static bool
- DefinitelyEqualImages(nsStyleImageRequest* aRequest1,
- nsStyleImageRequest* aRequest2)
- {
- if (aRequest1 == aRequest2) {
- return true;
- }
- if (!aRequest1 || !aRequest2) {
- return false;
- }
- return aRequest1->DefinitelyEquals(*aRequest2);
- }
- // A nullsafe wrapper for strcmp. We depend on null-safety.
- static int
- safe_strcmp(const char16_t* a, const char16_t* b)
- {
- if (!a || !b) {
- return (int)(a - b);
- }
- return NS_strcmp(a, b);
- }
- int32_t
- StyleStructContext::AppUnitsPerDevPixel()
- {
- return DeviceContext()->AppUnitsPerDevPixel();
- }
- nsDeviceContext*
- StyleStructContext::HackilyFindSomeDeviceContext()
- {
- nsCOMPtr<nsIAppShellService> appShell(do_GetService("@mozilla.org/appshell/appShellService;1"));
- MOZ_ASSERT(appShell);
- nsCOMPtr<mozIDOMWindowProxy> win;
- appShell->GetHiddenDOMWindow(getter_AddRefs(win));
- return nsLayoutUtils::GetDeviceContextForScreenInfo(static_cast<nsPIDOMWindowOuter*>(win.get()));
- }
- static bool AreShadowArraysEqual(nsCSSShadowArray* lhs, nsCSSShadowArray* rhs);
- // --------------------
- // nsStyleFont
- //
- nsStyleFont::nsStyleFont(const nsFont& aFont, StyleStructContext aContext)
- : mFont(aFont)
- , mSize(nsStyleFont::ZoomText(aContext, mFont.size))
- , mGenericID(kGenericFont_NONE)
- , mScriptLevel(0)
- , mMathVariant(NS_MATHML_MATHVARIANT_NONE)
- , mMathDisplay(NS_MATHML_DISPLAYSTYLE_INLINE)
- , mMinFontSizeRatio(100) // 100%
- , mExplicitLanguage(false)
- , mAllowZoom(true)
- , mScriptUnconstrainedSize(mSize)
- , mScriptMinSize(nsPresContext::CSSTwipsToAppUnits(
- NS_POINTS_TO_TWIPS(NS_MATHML_DEFAULT_SCRIPT_MIN_SIZE_PT)))
- , mScriptSizeMultiplier(NS_MATHML_DEFAULT_SCRIPT_SIZE_MULTIPLIER)
- , mLanguage(GetLanguage(aContext))
- {
- MOZ_COUNT_CTOR(nsStyleFont);
- mFont.size = mSize;
- }
- nsStyleFont::nsStyleFont(const nsStyleFont& aSrc)
- : mFont(aSrc.mFont)
- , mSize(aSrc.mSize)
- , mGenericID(aSrc.mGenericID)
- , mScriptLevel(aSrc.mScriptLevel)
- , mMathVariant(aSrc.mMathVariant)
- , mMathDisplay(aSrc.mMathDisplay)
- , mMinFontSizeRatio(aSrc.mMinFontSizeRatio)
- , mExplicitLanguage(aSrc.mExplicitLanguage)
- , mAllowZoom(aSrc.mAllowZoom)
- , mScriptUnconstrainedSize(aSrc.mScriptUnconstrainedSize)
- , mScriptMinSize(aSrc.mScriptMinSize)
- , mScriptSizeMultiplier(aSrc.mScriptSizeMultiplier)
- , mLanguage(aSrc.mLanguage)
- {
- MOZ_COUNT_CTOR(nsStyleFont);
- }
- nsStyleFont::nsStyleFont(StyleStructContext aContext)
- : nsStyleFont(*aContext.GetDefaultFont(kPresContext_DefaultVariableFont_ID),
- aContext)
- {
- }
- void
- nsStyleFont::Destroy(nsPresContext* aContext) {
- this->~nsStyleFont();
- aContext->PresShell()->
- FreeByObjectID(eArenaObjectID_nsStyleFont, this);
- }
- void
- nsStyleFont::EnableZoom(nsPresContext* aContext, bool aEnable)
- {
- if (mAllowZoom == aEnable) {
- return;
- }
- mAllowZoom = aEnable;
- if (mAllowZoom) {
- mSize = nsStyleFont::ZoomText(aContext, mSize);
- mFont.size = nsStyleFont::ZoomText(aContext, mFont.size);
- mScriptUnconstrainedSize =
- nsStyleFont::ZoomText(aContext, mScriptUnconstrainedSize);
- } else {
- mSize = nsStyleFont::UnZoomText(aContext, mSize);
- mFont.size = nsStyleFont::UnZoomText(aContext, mFont.size);
- mScriptUnconstrainedSize =
- nsStyleFont::UnZoomText(aContext, mScriptUnconstrainedSize);
- }
- }
- nsChangeHint
- nsStyleFont::CalcDifference(const nsStyleFont& aNewData) const
- {
- MOZ_ASSERT(mAllowZoom == aNewData.mAllowZoom,
- "expected mAllowZoom to be the same on both nsStyleFonts");
- if (mSize != aNewData.mSize ||
- mFont != aNewData.mFont ||
- mLanguage != aNewData.mLanguage ||
- mExplicitLanguage != aNewData.mExplicitLanguage ||
- mMathVariant != aNewData.mMathVariant ||
- mMathDisplay != aNewData.mMathDisplay ||
- mMinFontSizeRatio != aNewData.mMinFontSizeRatio) {
- return NS_STYLE_HINT_REFLOW;
- }
- // XXX Should any of these cause a non-nsChangeHint_NeutralChange change?
- if (mGenericID != aNewData.mGenericID ||
- mScriptLevel != aNewData.mScriptLevel ||
- mScriptUnconstrainedSize != aNewData.mScriptUnconstrainedSize ||
- mScriptMinSize != aNewData.mScriptMinSize ||
- mScriptSizeMultiplier != aNewData.mScriptSizeMultiplier) {
- return nsChangeHint_NeutralChange;
- }
- return nsChangeHint(0);
- }
- /* static */ nscoord
- nsStyleFont::ZoomText(StyleStructContext aContext, nscoord aSize)
- {
- // aSize can be negative (e.g.: calc(-1px)) so we can't assert that here.
- // The caller is expected deal with that.
- return NSToCoordTruncClamped(float(aSize) * aContext.TextZoom());
- }
- /* static */ nscoord
- nsStyleFont::UnZoomText(nsPresContext *aPresContext, nscoord aSize)
- {
- // aSize can be negative (e.g.: calc(-1px)) so we can't assert that here.
- // The caller is expected deal with that.
- return NSToCoordTruncClamped(float(aSize) / aPresContext->TextZoom());
- }
- /* static */ already_AddRefed<nsIAtom>
- nsStyleFont::GetLanguage(StyleStructContext aContext)
- {
- RefPtr<nsIAtom> language = aContext.GetContentLanguage();
- if (!language) {
- // we didn't find a (usable) Content-Language, so we fall back
- // to whatever the presContext guessed from the charset
- // NOTE this should not be used elsewhere, because we want websites
- // to use UTF-8 with proper language tag, instead of relying on
- // deriving language from charset. See bug 1040668 comment 67.
- language = aContext.GetLanguageFromCharset();
- }
- return language.forget();
- }
- static nscoord
- CalcCoord(const nsStyleCoord& aCoord, const nscoord* aEnumTable, int32_t aNumEnums)
- {
- if (aCoord.GetUnit() == eStyleUnit_Enumerated) {
- MOZ_ASSERT(aEnumTable, "must have enum table");
- int32_t value = aCoord.GetIntValue();
- if (0 <= value && value < aNumEnums) {
- return aEnumTable[aCoord.GetIntValue()];
- }
- NS_NOTREACHED("unexpected enum value");
- return 0;
- }
- MOZ_ASSERT(aCoord.ConvertsToLength(), "unexpected unit");
- return nsRuleNode::ComputeCoordPercentCalc(aCoord, 0);
- }
- nsStyleMargin::nsStyleMargin(StyleStructContext aContext)
- {
- MOZ_COUNT_CTOR(nsStyleMargin);
- nsStyleCoord zero(0, nsStyleCoord::CoordConstructor);
- NS_FOR_CSS_SIDES(side) {
- mMargin.Set(side, zero);
- }
- }
- nsStyleMargin::nsStyleMargin(const nsStyleMargin& aSrc)
- : mMargin(aSrc.mMargin)
- {
- MOZ_COUNT_CTOR(nsStyleMargin);
- }
- void
- nsStyleMargin::Destroy(nsPresContext* aContext) {
- this->~nsStyleMargin();
- aContext->PresShell()->
- FreeByObjectID(eArenaObjectID_nsStyleMargin, this);
- }
- nsChangeHint
- nsStyleMargin::CalcDifference(const nsStyleMargin& aNewData) const
- {
- if (mMargin == aNewData.mMargin) {
- return nsChangeHint(0);
- }
- // Margin differences can't affect descendant intrinsic sizes and
- // don't need to force children to reflow.
- return nsChangeHint_NeedReflow |
- nsChangeHint_ReflowChangesSizeOrPosition |
- nsChangeHint_ClearAncestorIntrinsics;
- }
- nsStylePadding::nsStylePadding(StyleStructContext aContext)
- {
- MOZ_COUNT_CTOR(nsStylePadding);
- nsStyleCoord zero(0, nsStyleCoord::CoordConstructor);
- NS_FOR_CSS_SIDES(side) {
- mPadding.Set(side, zero);
- }
- }
- nsStylePadding::nsStylePadding(const nsStylePadding& aSrc)
- : mPadding(aSrc.mPadding)
- {
- MOZ_COUNT_CTOR(nsStylePadding);
- }
- void
- nsStylePadding::Destroy(nsPresContext* aContext) {
- this->~nsStylePadding();
- aContext->PresShell()->
- FreeByObjectID(eArenaObjectID_nsStylePadding, this);
- }
- nsChangeHint
- nsStylePadding::CalcDifference(const nsStylePadding& aNewData) const
- {
- if (mPadding == aNewData.mPadding) {
- return nsChangeHint(0);
- }
- // Padding differences can't affect descendant intrinsic sizes, but do need
- // to force children to reflow so that we can reposition them, since their
- // offsets are from our frame bounds but our content rect's position within
- // those bounds is moving.
- // FIXME: It would be good to return a weaker hint here that doesn't
- // force reflow of all descendants, but the hint would need to force
- // reflow of the frame's children (see how
- // ReflowInput::InitResizeFlags initializes the inline-resize flag).
- return NS_STYLE_HINT_REFLOW & ~nsChangeHint_ClearDescendantIntrinsics;
- }
- nsStyleBorder::nsStyleBorder(StyleStructContext aContext)
- : mBorderColors(nullptr)
- , mBorderImageFill(NS_STYLE_BORDER_IMAGE_SLICE_NOFILL)
- , mBorderImageRepeatH(NS_STYLE_BORDER_IMAGE_REPEAT_STRETCH)
- , mBorderImageRepeatV(NS_STYLE_BORDER_IMAGE_REPEAT_STRETCH)
- , mFloatEdge(StyleFloatEdge::ContentBox)
- , mBoxDecorationBreak(StyleBoxDecorationBreak::Slice)
- , mComputedBorder(0, 0, 0, 0)
- {
- MOZ_COUNT_CTOR(nsStyleBorder);
- NS_FOR_CSS_HALF_CORNERS (corner) {
- mBorderRadius.Set(corner, nsStyleCoord(0, nsStyleCoord::CoordConstructor));
- }
- nscoord medium =
- (StaticPresData::Get()->GetBorderWidthTable())[NS_STYLE_BORDER_WIDTH_MEDIUM];
- NS_FOR_CSS_SIDES(side) {
- mBorderImageSlice.Set(side, nsStyleCoord(1.0f, eStyleUnit_Percent));
- mBorderImageWidth.Set(side, nsStyleCoord(1.0f, eStyleUnit_Factor));
- mBorderImageOutset.Set(side, nsStyleCoord(0.0f, eStyleUnit_Factor));
- mBorder.Side(side) = medium;
- mBorderStyle[side] = NS_STYLE_BORDER_STYLE_NONE;
- mBorderColor[side] = StyleComplexColor::CurrentColor();
- }
- mTwipsPerPixel = aContext.DevPixelsToAppUnits(1);
- }
- nsBorderColors::~nsBorderColors()
- {
- NS_CSS_DELETE_LIST_MEMBER(nsBorderColors, this, mNext);
- }
- nsBorderColors*
- nsBorderColors::Clone(bool aDeep) const
- {
- nsBorderColors* result = new nsBorderColors(mColor);
- if (MOZ_UNLIKELY(!result)) {
- return result;
- }
- if (aDeep) {
- NS_CSS_CLONE_LIST_MEMBER(nsBorderColors, this, mNext, result, (false));
- }
- return result;
- }
- nsStyleBorder::nsStyleBorder(const nsStyleBorder& aSrc)
- : mBorderColors(nullptr)
- , mBorderRadius(aSrc.mBorderRadius)
- , mBorderImageSource(aSrc.mBorderImageSource)
- , mBorderImageSlice(aSrc.mBorderImageSlice)
- , mBorderImageWidth(aSrc.mBorderImageWidth)
- , mBorderImageOutset(aSrc.mBorderImageOutset)
- , mBorderImageFill(aSrc.mBorderImageFill)
- , mBorderImageRepeatH(aSrc.mBorderImageRepeatH)
- , mBorderImageRepeatV(aSrc.mBorderImageRepeatV)
- , mFloatEdge(aSrc.mFloatEdge)
- , mBoxDecorationBreak(aSrc.mBoxDecorationBreak)
- , mComputedBorder(aSrc.mComputedBorder)
- , mBorder(aSrc.mBorder)
- , mTwipsPerPixel(aSrc.mTwipsPerPixel)
- {
- MOZ_COUNT_CTOR(nsStyleBorder);
- if (aSrc.mBorderColors) {
- EnsureBorderColors();
- for (int32_t i = 0; i < 4; i++) {
- if (aSrc.mBorderColors[i]) {
- mBorderColors[i] = aSrc.mBorderColors[i]->Clone();
- } else {
- mBorderColors[i] = nullptr;
- }
- }
- }
- NS_FOR_CSS_SIDES(side) {
- mBorderStyle[side] = aSrc.mBorderStyle[side];
- mBorderColor[side] = aSrc.mBorderColor[side];
- }
- }
- nsStyleBorder::~nsStyleBorder()
- {
- MOZ_COUNT_DTOR(nsStyleBorder);
- if (mBorderColors) {
- for (int32_t i = 0; i < 4; i++) {
- delete mBorderColors[i];
- }
- delete [] mBorderColors;
- }
- }
- void
- nsStyleBorder::FinishStyle(nsPresContext* aPresContext)
- {
- MOZ_ASSERT(NS_IsMainThread());
- MOZ_ASSERT(aPresContext->StyleSet()->IsServo());
- mBorderImageSource.ResolveImage(aPresContext);
- }
- nsMargin
- nsStyleBorder::GetImageOutset() const
- {
- // We don't check whether there is a border-image (which is OK since
- // the initial values yields 0 outset) so that we don't have to
- // reflow to update overflow areas when an image loads.
- nsMargin outset;
- NS_FOR_CSS_SIDES(s) {
- nsStyleCoord coord = mBorderImageOutset.Get(s);
- nscoord value;
- switch (coord.GetUnit()) {
- case eStyleUnit_Coord:
- value = coord.GetCoordValue();
- break;
- case eStyleUnit_Factor:
- value = coord.GetFactorValue() * mComputedBorder.Side(s);
- break;
- default:
- NS_NOTREACHED("unexpected CSS unit for image outset");
- value = 0;
- break;
- }
- outset.Side(s) = value;
- }
- return outset;
- }
- void
- nsStyleBorder::Destroy(nsPresContext* aContext)
- {
- this->~nsStyleBorder();
- aContext->PresShell()->
- FreeByObjectID(eArenaObjectID_nsStyleBorder, this);
- }
- nsChangeHint
- nsStyleBorder::CalcDifference(const nsStyleBorder& aNewData) const
- {
- // FIXME: XXXbz: As in nsStylePadding::CalcDifference, many of these
- // differences should not need to clear descendant intrinsics.
- // FIXME: It would be good to return a weaker hint for the
- // GetComputedBorder() differences (and perhaps others) that doesn't
- // force reflow of all descendants, but the hint would need to force
- // reflow of the frame's children (see how
- // ReflowInput::InitResizeFlags initializes the inline-resize flag).
- if (mTwipsPerPixel != aNewData.mTwipsPerPixel ||
- GetComputedBorder() != aNewData.GetComputedBorder() ||
- mFloatEdge != aNewData.mFloatEdge ||
- mBorderImageOutset != aNewData.mBorderImageOutset ||
- mBoxDecorationBreak != aNewData.mBoxDecorationBreak) {
- return NS_STYLE_HINT_REFLOW;
- }
- NS_FOR_CSS_SIDES(ix) {
- // See the explanation in nsChangeHint.h of
- // nsChangeHint_BorderStyleNoneChange .
- // Furthermore, even though we know *this* side is 0 width, just
- // assume a repaint hint for some other change rather than bother
- // tracking this result through the rest of the function.
- if (HasVisibleStyle(ix) != aNewData.HasVisibleStyle(ix)) {
- return nsChangeHint_RepaintFrame |
- nsChangeHint_BorderStyleNoneChange;
- }
- }
- // Note that mBorderStyle stores not only the border style but also
- // color-related flags. Given that we've already done an mComputedBorder
- // comparison, border-style differences can only lead to a repaint hint. So
- // it's OK to just compare the values directly -- if either the actual
- // style or the color flags differ we want to repaint.
- NS_FOR_CSS_SIDES(ix) {
- if (mBorderStyle[ix] != aNewData.mBorderStyle[ix] ||
- mBorderColor[ix] != aNewData.mBorderColor[ix]) {
- return nsChangeHint_RepaintFrame;
- }
- }
- if (mBorderRadius != aNewData.mBorderRadius ||
- !mBorderColors != !aNewData.mBorderColors) {
- return nsChangeHint_RepaintFrame;
- }
- if (IsBorderImageLoaded() || aNewData.IsBorderImageLoaded()) {
- if (mBorderImageSource != aNewData.mBorderImageSource ||
- mBorderImageRepeatH != aNewData.mBorderImageRepeatH ||
- mBorderImageRepeatV != aNewData.mBorderImageRepeatV ||
- mBorderImageSlice != aNewData.mBorderImageSlice ||
- mBorderImageFill != aNewData.mBorderImageFill ||
- mBorderImageWidth != aNewData.mBorderImageWidth ||
- mBorderImageOutset != aNewData.mBorderImageOutset) {
- return nsChangeHint_RepaintFrame;
- }
- }
- // Note that at this point if mBorderColors is non-null so is
- // aNewData.mBorderColors
- if (mBorderColors) {
- NS_FOR_CSS_SIDES(ix) {
- if (!nsBorderColors::Equal(mBorderColors[ix],
- aNewData.mBorderColors[ix])) {
- return nsChangeHint_RepaintFrame;
- }
- }
- }
- // mBorder is the specified border value. Changes to this don't
- // need any change processing, since we operate on the computed
- // border values instead.
- if (mBorder != aNewData.mBorder) {
- return nsChangeHint_NeutralChange;
- }
- return nsChangeHint(0);
- }
- nsStyleOutline::nsStyleOutline(StyleStructContext aContext)
- : mOutlineWidth(NS_STYLE_BORDER_WIDTH_MEDIUM, eStyleUnit_Enumerated)
- , mOutlineOffset(0)
- , mOutlineColor(StyleComplexColor::CurrentColor())
- , mOutlineStyle(NS_STYLE_BORDER_STYLE_NONE)
- , mActualOutlineWidth(0)
- , mTwipsPerPixel(aContext.DevPixelsToAppUnits(1))
- {
- MOZ_COUNT_CTOR(nsStyleOutline);
- // spacing values not inherited
- nsStyleCoord zero(0, nsStyleCoord::CoordConstructor);
- NS_FOR_CSS_HALF_CORNERS(corner) {
- mOutlineRadius.Set(corner, zero);
- }
- }
- nsStyleOutline::nsStyleOutline(const nsStyleOutline& aSrc)
- : mOutlineRadius(aSrc.mOutlineRadius)
- , mOutlineWidth(aSrc.mOutlineWidth)
- , mOutlineOffset(aSrc.mOutlineOffset)
- , mOutlineColor(aSrc.mOutlineColor)
- , mOutlineStyle(aSrc.mOutlineStyle)
- , mActualOutlineWidth(aSrc.mActualOutlineWidth)
- , mTwipsPerPixel(aSrc.mTwipsPerPixel)
- {
- MOZ_COUNT_CTOR(nsStyleOutline);
- }
- void
- nsStyleOutline::RecalcData()
- {
- if (NS_STYLE_BORDER_STYLE_NONE == mOutlineStyle) {
- mActualOutlineWidth = 0;
- } else {
- MOZ_ASSERT(mOutlineWidth.ConvertsToLength() ||
- mOutlineWidth.GetUnit() == eStyleUnit_Enumerated);
- // Clamp negative calc() to 0.
- mActualOutlineWidth =
- std::max(CalcCoord(mOutlineWidth,
- StaticPresData::Get()->GetBorderWidthTable(), 3), 0);
- mActualOutlineWidth =
- NS_ROUND_BORDER_TO_PIXELS(mActualOutlineWidth, mTwipsPerPixel);
- }
- }
- nsChangeHint
- nsStyleOutline::CalcDifference(const nsStyleOutline& aNewData) const
- {
- if (mActualOutlineWidth != aNewData.mActualOutlineWidth ||
- (mActualOutlineWidth > 0 &&
- mOutlineOffset != aNewData.mOutlineOffset)) {
- return nsChangeHint_UpdateOverflow |
- nsChangeHint_SchedulePaint;
- }
- if (mOutlineStyle != aNewData.mOutlineStyle ||
- mOutlineColor != aNewData.mOutlineColor ||
- mOutlineRadius != aNewData.mOutlineRadius) {
- if (mActualOutlineWidth > 0) {
- return nsChangeHint_RepaintFrame;
- }
- return nsChangeHint_NeutralChange;
- }
- if (mOutlineWidth != aNewData.mOutlineWidth ||
- mOutlineOffset != aNewData.mOutlineOffset ||
- mTwipsPerPixel != aNewData.mTwipsPerPixel) {
- return nsChangeHint_NeutralChange;
- }
- return nsChangeHint(0);
- }
- // --------------------
- // nsStyleList
- //
- nsStyleList::nsStyleList(StyleStructContext aContext)
- : mListStylePosition(NS_STYLE_LIST_STYLE_POSITION_OUTSIDE)
- , mCounterStyle(aContext.BuildCounterStyle(NS_LITERAL_STRING("disc")))
- {
- MOZ_COUNT_CTOR(nsStyleList);
- SetQuotesInitial();
- }
- nsStyleList::~nsStyleList()
- {
- MOZ_COUNT_DTOR(nsStyleList);
- }
- nsStyleList::nsStyleList(const nsStyleList& aSource)
- : mListStylePosition(aSource.mListStylePosition)
- , mListStyleImage(aSource.mListStyleImage)
- , mCounterStyle(aSource.mCounterStyle)
- , mQuotes(aSource.mQuotes)
- , mImageRegion(aSource.mImageRegion)
- {
- MOZ_COUNT_CTOR(nsStyleList);
- }
- void
- nsStyleList::FinishStyle(nsPresContext* aPresContext)
- {
- MOZ_ASSERT(NS_IsMainThread());
- MOZ_ASSERT(aPresContext->StyleSet()->IsServo());
- if (mListStyleImage && !mListStyleImage->IsResolved()) {
- mListStyleImage->Resolve(aPresContext);
- }
- }
- void
- nsStyleList::SetQuotesInherit(const nsStyleList* aOther)
- {
- mQuotes = aOther->mQuotes;
- }
- void
- nsStyleList::SetQuotesInitial()
- {
- if (!sInitialQuotes) {
- // The initial value for quotes is the en-US typographic convention:
- // outermost are LEFT and RIGHT DOUBLE QUOTATION MARK, alternating
- // with LEFT and RIGHT SINGLE QUOTATION MARK.
- static const char16_t initialQuotes[8] = {
- 0x201C, 0, 0x201D, 0, 0x2018, 0, 0x2019, 0
- };
- sInitialQuotes = new nsStyleQuoteValues;
- sInitialQuotes->mQuotePairs.AppendElement(
- std::make_pair(nsDependentString(&initialQuotes[0], 1),
- nsDependentString(&initialQuotes[2], 1)));
- sInitialQuotes->mQuotePairs.AppendElement(
- std::make_pair(nsDependentString(&initialQuotes[4], 1),
- nsDependentString(&initialQuotes[6], 1)));
- }
- mQuotes = sInitialQuotes;
- }
- void
- nsStyleList::SetQuotesNone()
- {
- if (!sNoneQuotes) {
- sNoneQuotes = new nsStyleQuoteValues;
- }
- mQuotes = sNoneQuotes;
- }
- void
- nsStyleList::SetQuotes(nsStyleQuoteValues::QuotePairArray&& aValues)
- {
- mQuotes = new nsStyleQuoteValues;
- mQuotes->mQuotePairs = Move(aValues);
- }
- const nsStyleQuoteValues::QuotePairArray&
- nsStyleList::GetQuotePairs() const
- {
- return mQuotes->mQuotePairs;
- }
- nsChangeHint
- nsStyleList::CalcDifference(const nsStyleList& aNewData) const
- {
- // If the quotes implementation is ever going to change we might not need
- // a framechange here and a reflow should be sufficient. See bug 35768.
- if (mQuotes != aNewData.mQuotes &&
- (mQuotes || aNewData.mQuotes) &&
- GetQuotePairs() != aNewData.GetQuotePairs()) {
- return nsChangeHint_ReconstructFrame;
- }
- if (mListStylePosition != aNewData.mListStylePosition) {
- return nsChangeHint_ReconstructFrame;
- }
- if (DefinitelyEqualImages(mListStyleImage, aNewData.mListStyleImage) &&
- mCounterStyle == aNewData.mCounterStyle) {
- if (mImageRegion.IsEqualInterior(aNewData.mImageRegion)) {
- return nsChangeHint(0);
- }
- if (mImageRegion.width == aNewData.mImageRegion.width &&
- mImageRegion.height == aNewData.mImageRegion.height) {
- return NS_STYLE_HINT_VISUAL;
- }
- }
- return NS_STYLE_HINT_REFLOW;
- }
- StaticRefPtr<nsStyleQuoteValues>
- nsStyleList::sInitialQuotes;
- StaticRefPtr<nsStyleQuoteValues>
- nsStyleList::sNoneQuotes;
- // --------------------
- // nsStyleXUL
- //
- nsStyleXUL::nsStyleXUL(StyleStructContext aContext)
- : mBoxFlex(0.0f)
- , mBoxOrdinal(1)
- , mBoxAlign(StyleBoxAlign::Stretch)
- , mBoxDirection(StyleBoxDirection::Normal)
- , mBoxOrient(StyleBoxOrient::Horizontal)
- , mBoxPack(StyleBoxPack::Start)
- , mStretchStack(true)
- {
- MOZ_COUNT_CTOR(nsStyleXUL);
- }
- nsStyleXUL::~nsStyleXUL()
- {
- MOZ_COUNT_DTOR(nsStyleXUL);
- }
- nsStyleXUL::nsStyleXUL(const nsStyleXUL& aSource)
- : mBoxFlex(aSource.mBoxFlex)
- , mBoxOrdinal(aSource.mBoxOrdinal)
- , mBoxAlign(aSource.mBoxAlign)
- , mBoxDirection(aSource.mBoxDirection)
- , mBoxOrient(aSource.mBoxOrient)
- , mBoxPack(aSource.mBoxPack)
- , mStretchStack(aSource.mStretchStack)
- {
- MOZ_COUNT_CTOR(nsStyleXUL);
- }
- nsChangeHint
- nsStyleXUL::CalcDifference(const nsStyleXUL& aNewData) const
- {
- if (mBoxAlign == aNewData.mBoxAlign &&
- mBoxDirection == aNewData.mBoxDirection &&
- mBoxFlex == aNewData.mBoxFlex &&
- mBoxOrient == aNewData.mBoxOrient &&
- mBoxPack == aNewData.mBoxPack &&
- mBoxOrdinal == aNewData.mBoxOrdinal &&
- mStretchStack == aNewData.mStretchStack) {
- return nsChangeHint(0);
- }
- if (mBoxOrdinal != aNewData.mBoxOrdinal) {
- return nsChangeHint_ReconstructFrame;
- }
- return NS_STYLE_HINT_REFLOW;
- }
- // --------------------
- // nsStyleColumn
- //
- /* static */ const uint32_t nsStyleColumn::kMaxColumnCount;
- nsStyleColumn::nsStyleColumn(StyleStructContext aContext)
- : mColumnCount(NS_STYLE_COLUMN_COUNT_AUTO)
- , mColumnWidth(eStyleUnit_Auto)
- , mColumnGap(eStyleUnit_Normal)
- , mColumnRuleColor(StyleComplexColor::CurrentColor())
- , mColumnRuleStyle(NS_STYLE_BORDER_STYLE_NONE)
- , mColumnFill(NS_STYLE_COLUMN_FILL_BALANCE)
- , mColumnRuleWidth((StaticPresData::Get()
- ->GetBorderWidthTable())[NS_STYLE_BORDER_WIDTH_MEDIUM])
- , mTwipsPerPixel(aContext.AppUnitsPerDevPixel())
- {
- MOZ_COUNT_CTOR(nsStyleColumn);
- }
- nsStyleColumn::~nsStyleColumn()
- {
- MOZ_COUNT_DTOR(nsStyleColumn);
- }
- nsStyleColumn::nsStyleColumn(const nsStyleColumn& aSource)
- : mColumnCount(aSource.mColumnCount)
- , mColumnWidth(aSource.mColumnWidth)
- , mColumnGap(aSource.mColumnGap)
- , mColumnRuleColor(aSource.mColumnRuleColor)
- , mColumnRuleStyle(aSource.mColumnRuleStyle)
- , mColumnFill(aSource.mColumnFill)
- , mColumnRuleWidth(aSource.mColumnRuleWidth)
- , mTwipsPerPixel(aSource.mTwipsPerPixel)
- {
- MOZ_COUNT_CTOR(nsStyleColumn);
- }
- nsChangeHint
- nsStyleColumn::CalcDifference(const nsStyleColumn& aNewData) const
- {
- if ((mColumnWidth.GetUnit() == eStyleUnit_Auto)
- != (aNewData.mColumnWidth.GetUnit() == eStyleUnit_Auto) ||
- mColumnCount != aNewData.mColumnCount) {
- // We force column count changes to do a reframe, because it's tricky to handle
- // some edge cases where the column count gets smaller and content overflows.
- // XXX not ideal
- return nsChangeHint_ReconstructFrame;
- }
- if (mColumnWidth != aNewData.mColumnWidth ||
- mColumnGap != aNewData.mColumnGap ||
- mColumnFill != aNewData.mColumnFill) {
- return NS_STYLE_HINT_REFLOW;
- }
- if (GetComputedColumnRuleWidth() != aNewData.GetComputedColumnRuleWidth() ||
- mColumnRuleStyle != aNewData.mColumnRuleStyle ||
- mColumnRuleColor != aNewData.mColumnRuleColor) {
- return NS_STYLE_HINT_VISUAL;
- }
- // XXX Is it right that we never check mTwipsPerPixel to return a
- // non-nsChangeHint_NeutralChange hint?
- if (mColumnRuleWidth != aNewData.mColumnRuleWidth ||
- mTwipsPerPixel != aNewData.mTwipsPerPixel) {
- return nsChangeHint_NeutralChange;
- }
- return nsChangeHint(0);
- }
- // --------------------
- // nsStyleSVG
- //
- nsStyleSVG::nsStyleSVG(StyleStructContext aContext)
- : mFill(eStyleSVGPaintType_Color) // Will be initialized to NS_RGB(0, 0, 0)
- , mStroke(eStyleSVGPaintType_None)
- , mStrokeDashoffset(0, nsStyleCoord::CoordConstructor)
- , mStrokeWidth(nsPresContext::CSSPixelsToAppUnits(1), nsStyleCoord::CoordConstructor)
- , mFillOpacity(1.0f)
- , mStrokeMiterlimit(4.0f)
- , mStrokeOpacity(1.0f)
- , mClipRule(StyleFillRule::Nonzero)
- , mColorInterpolation(NS_STYLE_COLOR_INTERPOLATION_SRGB)
- , mColorInterpolationFilters(NS_STYLE_COLOR_INTERPOLATION_LINEARRGB)
- , mFillRule(StyleFillRule::Nonzero)
- , mPaintOrder(NS_STYLE_PAINT_ORDER_NORMAL)
- , mShapeRendering(NS_STYLE_SHAPE_RENDERING_AUTO)
- , mStrokeLinecap(NS_STYLE_STROKE_LINECAP_BUTT)
- , mStrokeLinejoin(NS_STYLE_STROKE_LINEJOIN_MITER)
- , mTextAnchor(NS_STYLE_TEXT_ANCHOR_START)
- , mContextFlags((eStyleSVGOpacitySource_Normal << FILL_OPACITY_SOURCE_SHIFT) |
- (eStyleSVGOpacitySource_Normal << STROKE_OPACITY_SOURCE_SHIFT))
- {
- MOZ_COUNT_CTOR(nsStyleSVG);
- }
- nsStyleSVG::~nsStyleSVG()
- {
- MOZ_COUNT_DTOR(nsStyleSVG);
- }
- nsStyleSVG::nsStyleSVG(const nsStyleSVG& aSource)
- : mFill(aSource.mFill)
- , mStroke(aSource.mStroke)
- , mMarkerEnd(aSource.mMarkerEnd)
- , mMarkerMid(aSource.mMarkerMid)
- , mMarkerStart(aSource.mMarkerStart)
- , mStrokeDasharray(aSource.mStrokeDasharray)
- , mStrokeDashoffset(aSource.mStrokeDashoffset)
- , mStrokeWidth(aSource.mStrokeWidth)
- , mFillOpacity(aSource.mFillOpacity)
- , mStrokeMiterlimit(aSource.mStrokeMiterlimit)
- , mStrokeOpacity(aSource.mStrokeOpacity)
- , mClipRule(aSource.mClipRule)
- , mColorInterpolation(aSource.mColorInterpolation)
- , mColorInterpolationFilters(aSource.mColorInterpolationFilters)
- , mFillRule(aSource.mFillRule)
- , mPaintOrder(aSource.mPaintOrder)
- , mShapeRendering(aSource.mShapeRendering)
- , mStrokeLinecap(aSource.mStrokeLinecap)
- , mStrokeLinejoin(aSource.mStrokeLinejoin)
- , mTextAnchor(aSource.mTextAnchor)
- , mContextFlags(aSource.mContextFlags)
- {
- MOZ_COUNT_CTOR(nsStyleSVG);
- }
- static bool
- PaintURIChanged(const nsStyleSVGPaint& aPaint1, const nsStyleSVGPaint& aPaint2)
- {
- if (aPaint1.Type() != aPaint2.Type()) {
- return aPaint1.Type() == eStyleSVGPaintType_Server ||
- aPaint2.Type() == eStyleSVGPaintType_Server;
- }
- return aPaint1.Type() == eStyleSVGPaintType_Server &&
- !DefinitelyEqualURIs(aPaint1.GetPaintServer(),
- aPaint2.GetPaintServer());
- }
- nsChangeHint
- nsStyleSVG::CalcDifference(const nsStyleSVG& aNewData) const
- {
- nsChangeHint hint = nsChangeHint(0);
- if (!DefinitelyEqualURIs(mMarkerEnd, aNewData.mMarkerEnd) ||
- !DefinitelyEqualURIs(mMarkerMid, aNewData.mMarkerMid) ||
- !DefinitelyEqualURIs(mMarkerStart, aNewData.mMarkerStart)) {
- // Markers currently contribute to nsSVGPathGeometryFrame::mRect,
- // so we need a reflow as well as a repaint. No intrinsic sizes need
- // to change, so nsChangeHint_NeedReflow is sufficient.
- return nsChangeHint_UpdateEffects |
- nsChangeHint_NeedReflow |
- nsChangeHint_NeedDirtyReflow | // XXX remove me: bug 876085
- nsChangeHint_RepaintFrame;
- }
- if (mFill != aNewData.mFill ||
- mStroke != aNewData.mStroke ||
- mFillOpacity != aNewData.mFillOpacity ||
- mStrokeOpacity != aNewData.mStrokeOpacity) {
- hint |= nsChangeHint_RepaintFrame;
- if (HasStroke() != aNewData.HasStroke() ||
- (!HasStroke() && HasFill() != aNewData.HasFill())) {
- // Frame bounds and overflow rects depend on whether we "have" fill or
- // stroke. Whether we have stroke or not just changed, or else we have no
- // stroke (in which case whether we have fill or not is significant to frame
- // bounds) and whether we have fill or not just changed. In either case we
- // need to reflow so the frame rect is updated.
- // XXXperf this is a waste on non nsSVGPathGeometryFrames.
- hint |= nsChangeHint_NeedReflow |
- nsChangeHint_NeedDirtyReflow; // XXX remove me: bug 876085
- }
- if (PaintURIChanged(mFill, aNewData.mFill) ||
- PaintURIChanged(mStroke, aNewData.mStroke)) {
- hint |= nsChangeHint_UpdateEffects;
- }
- }
- // Stroke currently contributes to nsSVGPathGeometryFrame::mRect, so
- // we need a reflow here. No intrinsic sizes need to change, so
- // nsChangeHint_NeedReflow is sufficient.
- // Note that stroke-dashoffset does not affect nsSVGPathGeometryFrame::mRect.
- // text-anchor changes also require a reflow since it changes frames' rects.
- if (mStrokeWidth != aNewData.mStrokeWidth ||
- mStrokeMiterlimit != aNewData.mStrokeMiterlimit ||
- mStrokeLinecap != aNewData.mStrokeLinecap ||
- mStrokeLinejoin != aNewData.mStrokeLinejoin ||
- mTextAnchor != aNewData.mTextAnchor) {
- return hint |
- nsChangeHint_NeedReflow |
- nsChangeHint_NeedDirtyReflow | // XXX remove me: bug 876085
- nsChangeHint_RepaintFrame;
- }
- if (hint & nsChangeHint_RepaintFrame) {
- return hint; // we don't add anything else below
- }
- if ( mStrokeDashoffset != aNewData.mStrokeDashoffset ||
- mClipRule != aNewData.mClipRule ||
- mColorInterpolation != aNewData.mColorInterpolation ||
- mColorInterpolationFilters != aNewData.mColorInterpolationFilters ||
- mFillRule != aNewData.mFillRule ||
- mPaintOrder != aNewData.mPaintOrder ||
- mShapeRendering != aNewData.mShapeRendering ||
- mStrokeDasharray != aNewData.mStrokeDasharray ||
- mContextFlags != aNewData.mContextFlags) {
- return hint | nsChangeHint_RepaintFrame;
- }
- return hint;
- }
- // --------------------
- // StyleBasicShape
- nsCSSKeyword
- StyleBasicShape::GetShapeTypeName() const
- {
- switch (mType) {
- case StyleBasicShapeType::Polygon:
- return eCSSKeyword_polygon;
- case StyleBasicShapeType::Circle:
- return eCSSKeyword_circle;
- case StyleBasicShapeType::Ellipse:
- return eCSSKeyword_ellipse;
- case StyleBasicShapeType::Inset:
- return eCSSKeyword_inset;
- }
- NS_NOTREACHED("unexpected type");
- return eCSSKeyword_UNKNOWN;
- }
- // --------------------
- // nsStyleFilter
- //
- nsStyleFilter::nsStyleFilter()
- : mType(NS_STYLE_FILTER_NONE)
- , mDropShadow(nullptr)
- {
- MOZ_COUNT_CTOR(nsStyleFilter);
- }
- nsStyleFilter::nsStyleFilter(const nsStyleFilter& aSource)
- : mType(NS_STYLE_FILTER_NONE)
- , mDropShadow(nullptr)
- {
- MOZ_COUNT_CTOR(nsStyleFilter);
- if (aSource.mType == NS_STYLE_FILTER_URL) {
- SetURL(aSource.mURL);
- } else if (aSource.mType == NS_STYLE_FILTER_DROP_SHADOW) {
- SetDropShadow(aSource.mDropShadow);
- } else if (aSource.mType != NS_STYLE_FILTER_NONE) {
- SetFilterParameter(aSource.mFilterParameter, aSource.mType);
- }
- }
- nsStyleFilter::~nsStyleFilter()
- {
- ReleaseRef();
- MOZ_COUNT_DTOR(nsStyleFilter);
- }
- nsStyleFilter&
- nsStyleFilter::operator=(const nsStyleFilter& aOther)
- {
- if (this == &aOther) {
- return *this;
- }
- if (aOther.mType == NS_STYLE_FILTER_URL) {
- SetURL(aOther.mURL);
- } else if (aOther.mType == NS_STYLE_FILTER_DROP_SHADOW) {
- SetDropShadow(aOther.mDropShadow);
- } else if (aOther.mType != NS_STYLE_FILTER_NONE) {
- SetFilterParameter(aOther.mFilterParameter, aOther.mType);
- } else {
- ReleaseRef();
- mType = NS_STYLE_FILTER_NONE;
- }
- return *this;
- }
- bool
- nsStyleFilter::operator==(const nsStyleFilter& aOther) const
- {
- if (mType != aOther.mType) {
- return false;
- }
- if (mType == NS_STYLE_FILTER_URL) {
- return DefinitelyEqualURIs(mURL, aOther.mURL);
- } else if (mType == NS_STYLE_FILTER_DROP_SHADOW) {
- return *mDropShadow == *aOther.mDropShadow;
- } else if (mType != NS_STYLE_FILTER_NONE) {
- return mFilterParameter == aOther.mFilterParameter;
- }
- return true;
- }
- void
- nsStyleFilter::ReleaseRef()
- {
- if (mType == NS_STYLE_FILTER_DROP_SHADOW) {
- NS_ASSERTION(mDropShadow, "expected pointer");
- mDropShadow->Release();
- } else if (mType == NS_STYLE_FILTER_URL) {
- NS_ASSERTION(mURL, "expected pointer");
- mURL->Release();
- }
- mURL = nullptr;
- }
- void
- nsStyleFilter::SetFilterParameter(const nsStyleCoord& aFilterParameter,
- int32_t aType)
- {
- ReleaseRef();
- mFilterParameter = aFilterParameter;
- mType = aType;
- }
- bool
- nsStyleFilter::SetURL(css::URLValue* aURL)
- {
- ReleaseRef();
- mURL = aURL;
- mURL->AddRef();
- mType = NS_STYLE_FILTER_URL;
- return true;
- }
- void
- nsStyleFilter::SetDropShadow(nsCSSShadowArray* aDropShadow)
- {
- NS_ASSERTION(aDropShadow, "expected pointer");
- ReleaseRef();
- mDropShadow = aDropShadow;
- mDropShadow->AddRef();
- mType = NS_STYLE_FILTER_DROP_SHADOW;
- }
- // --------------------
- // nsStyleSVGReset
- //
- nsStyleSVGReset::nsStyleSVGReset(StyleStructContext aContext)
- : mMask(nsStyleImageLayers::LayerType::Mask)
- , mStopColor(NS_RGB(0, 0, 0))
- , mFloodColor(NS_RGB(0, 0, 0))
- , mLightingColor(NS_RGB(255, 255, 255))
- , mStopOpacity(1.0f)
- , mFloodOpacity(1.0f)
- , mDominantBaseline(NS_STYLE_DOMINANT_BASELINE_AUTO)
- , mVectorEffect(NS_STYLE_VECTOR_EFFECT_NONE)
- , mMaskType(NS_STYLE_MASK_TYPE_LUMINANCE)
- {
- MOZ_COUNT_CTOR(nsStyleSVGReset);
- }
- nsStyleSVGReset::~nsStyleSVGReset()
- {
- MOZ_COUNT_DTOR(nsStyleSVGReset);
- }
- nsStyleSVGReset::nsStyleSVGReset(const nsStyleSVGReset& aSource)
- : mMask(aSource.mMask)
- , mClipPath(aSource.mClipPath)
- , mStopColor(aSource.mStopColor)
- , mFloodColor(aSource.mFloodColor)
- , mLightingColor(aSource.mLightingColor)
- , mStopOpacity(aSource.mStopOpacity)
- , mFloodOpacity(aSource.mFloodOpacity)
- , mDominantBaseline(aSource.mDominantBaseline)
- , mVectorEffect(aSource.mVectorEffect)
- , mMaskType(aSource.mMaskType)
- {
- MOZ_COUNT_CTOR(nsStyleSVGReset);
- }
- void
- nsStyleSVGReset::Destroy(nsPresContext* aContext)
- {
- this->~nsStyleSVGReset();
- aContext->PresShell()->
- FreeByObjectID(mozilla::eArenaObjectID_nsStyleSVGReset, this);
- }
- void
- nsStyleSVGReset::FinishStyle(nsPresContext* aPresContext)
- {
- MOZ_ASSERT(NS_IsMainThread());
- MOZ_ASSERT(aPresContext->StyleSet()->IsServo());
- mMask.ResolveImages(aPresContext);
- }
- nsChangeHint
- nsStyleSVGReset::CalcDifference(const nsStyleSVGReset& aNewData) const
- {
- nsChangeHint hint = nsChangeHint(0);
- if (mClipPath != aNewData.mClipPath) {
- hint |= nsChangeHint_UpdateEffects |
- nsChangeHint_RepaintFrame;
- // clip-path changes require that we update the PreEffectsBBoxProperty,
- // which is done during overflow computation.
- hint |= nsChangeHint_UpdateOverflow;
- }
- if (mDominantBaseline != aNewData.mDominantBaseline) {
- // XXXjwatt: why NS_STYLE_HINT_REFLOW? Isn't that excessive?
- hint |= NS_STYLE_HINT_REFLOW;
- } else if (mVectorEffect != aNewData.mVectorEffect) {
- // Stroke currently affects nsSVGPathGeometryFrame::mRect, and
- // vector-effect affect stroke. As a result we need to reflow if
- // vector-effect changes in order to have nsSVGPathGeometryFrame::
- // ReflowSVG called to update its mRect. No intrinsic sizes need
- // to change so nsChangeHint_NeedReflow is sufficient.
- hint |= nsChangeHint_NeedReflow |
- nsChangeHint_NeedDirtyReflow | // XXX remove me: bug 876085
- nsChangeHint_RepaintFrame;
- } else if (mStopColor != aNewData.mStopColor ||
- mFloodColor != aNewData.mFloodColor ||
- mLightingColor != aNewData.mLightingColor ||
- mStopOpacity != aNewData.mStopOpacity ||
- mFloodOpacity != aNewData.mFloodOpacity ||
- mMaskType != aNewData.mMaskType) {
- hint |= nsChangeHint_RepaintFrame;
- }
- hint |= mMask.CalcDifference(aNewData.mMask,
- nsStyleImageLayers::LayerType::Mask);
- return hint;
- }
- // nsStyleSVGPaint implementation
- nsStyleSVGPaint::nsStyleSVGPaint(nsStyleSVGPaintType aType)
- : mType(aType)
- , mFallbackColor(NS_RGB(0, 0, 0))
- {
- MOZ_ASSERT(aType == nsStyleSVGPaintType(0) ||
- aType == eStyleSVGPaintType_None ||
- aType == eStyleSVGPaintType_Color);
- mPaint.mColor = NS_RGB(0, 0, 0);
- }
- nsStyleSVGPaint::nsStyleSVGPaint(const nsStyleSVGPaint& aSource)
- : nsStyleSVGPaint(nsStyleSVGPaintType(0))
- {
- Assign(aSource);
- }
- nsStyleSVGPaint::~nsStyleSVGPaint()
- {
- Reset();
- }
- void
- nsStyleSVGPaint::Reset()
- {
- switch (mType) {
- case eStyleSVGPaintType_None:
- break;
- case eStyleSVGPaintType_Color:
- mPaint.mColor = NS_RGB(0, 0, 0);
- break;
- case eStyleSVGPaintType_Server:
- mPaint.mPaintServer->Release();
- mPaint.mPaintServer = nullptr;
- MOZ_FALLTHROUGH;
- case eStyleSVGPaintType_ContextFill:
- case eStyleSVGPaintType_ContextStroke:
- mFallbackColor = NS_RGB(0, 0, 0);
- break;
- }
- mType = nsStyleSVGPaintType(0);
- }
- nsStyleSVGPaint&
- nsStyleSVGPaint::operator=(const nsStyleSVGPaint& aOther)
- {
- if (this != &aOther) {
- Assign(aOther);
- }
- return *this;
- }
- void
- nsStyleSVGPaint::Assign(const nsStyleSVGPaint& aOther)
- {
- MOZ_ASSERT(aOther.mType != nsStyleSVGPaintType(0),
- "shouldn't copy uninitialized nsStyleSVGPaint");
- switch (aOther.mType) {
- case eStyleSVGPaintType_None:
- SetNone();
- break;
- case eStyleSVGPaintType_Color:
- SetColor(aOther.mPaint.mColor);
- break;
- case eStyleSVGPaintType_Server:
- SetPaintServer(aOther.mPaint.mPaintServer,
- aOther.mFallbackColor);
- break;
- case eStyleSVGPaintType_ContextFill:
- case eStyleSVGPaintType_ContextStroke:
- SetContextValue(aOther.mType, aOther.mFallbackColor);
- break;
- }
- }
- void
- nsStyleSVGPaint::SetNone()
- {
- Reset();
- mType = eStyleSVGPaintType_None;
- }
- void
- nsStyleSVGPaint::SetContextValue(nsStyleSVGPaintType aType,
- nscolor aFallbackColor)
- {
- MOZ_ASSERT(aType == eStyleSVGPaintType_ContextFill ||
- aType == eStyleSVGPaintType_ContextStroke);
- Reset();
- mType = aType;
- mFallbackColor = aFallbackColor;
- }
- void
- nsStyleSVGPaint::SetColor(nscolor aColor)
- {
- Reset();
- mType = eStyleSVGPaintType_Color;
- mPaint.mColor = aColor;
- }
- void
- nsStyleSVGPaint::SetPaintServer(css::URLValue* aPaintServer,
- nscolor aFallbackColor)
- {
- MOZ_ASSERT(aPaintServer);
- Reset();
- mType = eStyleSVGPaintType_Server;
- mPaint.mPaintServer = aPaintServer;
- mPaint.mPaintServer->AddRef();
- mFallbackColor = aFallbackColor;
- }
- bool nsStyleSVGPaint::operator==(const nsStyleSVGPaint& aOther) const
- {
- if (mType != aOther.mType) {
- return false;
- }
- switch (mType) {
- case eStyleSVGPaintType_Color:
- return mPaint.mColor == aOther.mPaint.mColor;
- case eStyleSVGPaintType_Server:
- return DefinitelyEqualURIs(mPaint.mPaintServer,
- aOther.mPaint.mPaintServer) &&
- mFallbackColor == aOther.mFallbackColor;
- case eStyleSVGPaintType_ContextFill:
- case eStyleSVGPaintType_ContextStroke:
- return mFallbackColor == aOther.mFallbackColor;
- default:
- MOZ_ASSERT(mType == eStyleSVGPaintType_None,
- "Unexpected SVG paint type");
- return true;
- }
- }
- // --------------------
- // nsStylePosition
- //
- nsStylePosition::nsStylePosition(StyleStructContext aContext)
- : mWidth(eStyleUnit_Auto)
- , mMinWidth(eStyleUnit_Auto)
- , mMaxWidth(eStyleUnit_None)
- , mHeight(eStyleUnit_Auto)
- , mMinHeight(eStyleUnit_Auto)
- , mMaxHeight(eStyleUnit_None)
- , mFlexBasis(eStyleUnit_Auto)
- , mGridAutoColumnsMin(eStyleUnit_Auto)
- , mGridAutoColumnsMax(eStyleUnit_Auto)
- , mGridAutoRowsMin(eStyleUnit_Auto)
- , mGridAutoRowsMax(eStyleUnit_Auto)
- , mAspectRatio(0.0f)
- , mGridAutoFlow(NS_STYLE_GRID_AUTO_FLOW_ROW)
- , mBoxSizing(StyleBoxSizing::Content)
- , mAlignContent(NS_STYLE_ALIGN_NORMAL)
- , mAlignItems(NS_STYLE_ALIGN_NORMAL)
- , mAlignSelf(NS_STYLE_ALIGN_AUTO)
- , mJustifyContent(NS_STYLE_JUSTIFY_NORMAL)
- , mJustifyItems(NS_STYLE_JUSTIFY_AUTO)
- , mJustifySelf(NS_STYLE_JUSTIFY_AUTO)
- , mFlexDirection(NS_STYLE_FLEX_DIRECTION_ROW)
- , mFlexWrap(NS_STYLE_FLEX_WRAP_NOWRAP)
- , mObjectFit(NS_STYLE_OBJECT_FIT_FILL)
- , mOrder(NS_STYLE_ORDER_INITIAL)
- , mFlexGrow(0.0f)
- , mFlexShrink(1.0f)
- , mZIndex(eStyleUnit_Auto)
- , mGridColumnGap(nscoord(0), nsStyleCoord::CoordConstructor)
- , mGridRowGap(nscoord(0), nsStyleCoord::CoordConstructor)
- {
- MOZ_COUNT_CTOR(nsStylePosition);
- // positioning values not inherited
- mObjectPosition.SetInitialPercentValues(0.5f);
- nsStyleCoord autoCoord(eStyleUnit_Auto);
- NS_FOR_CSS_SIDES(side) {
- mOffset.Set(side, autoCoord);
- }
- // The initial value of grid-auto-columns and grid-auto-rows is 'auto',
- // which computes to 'minmax(auto, auto)'.
- // Other members get their default constructors
- // which initialize them to representations of their respective initial value.
- // mGridTemplateAreas: nullptr for 'none'
- // mGridTemplate{Rows,Columns}: false and empty arrays for 'none'
- // mGrid{Column,Row}{Start,End}: false/0/empty values for 'auto'
- }
- nsStylePosition::~nsStylePosition()
- {
- MOZ_COUNT_DTOR(nsStylePosition);
- }
- nsStylePosition::nsStylePosition(const nsStylePosition& aSource)
- : mObjectPosition(aSource.mObjectPosition)
- , mOffset(aSource.mOffset)
- , mWidth(aSource.mWidth)
- , mMinWidth(aSource.mMinWidth)
- , mMaxWidth(aSource.mMaxWidth)
- , mHeight(aSource.mHeight)
- , mMinHeight(aSource.mMinHeight)
- , mMaxHeight(aSource.mMaxHeight)
- , mFlexBasis(aSource.mFlexBasis)
- , mGridAutoColumnsMin(aSource.mGridAutoColumnsMin)
- , mGridAutoColumnsMax(aSource.mGridAutoColumnsMax)
- , mGridAutoRowsMin(aSource.mGridAutoRowsMin)
- , mGridAutoRowsMax(aSource.mGridAutoRowsMax)
- , mAspectRatio(aSource.mAspectRatio)
- , mGridAutoFlow(aSource.mGridAutoFlow)
- , mBoxSizing(aSource.mBoxSizing)
- , mAlignContent(aSource.mAlignContent)
- , mAlignItems(aSource.mAlignItems)
- , mAlignSelf(aSource.mAlignSelf)
- , mJustifyContent(aSource.mJustifyContent)
- , mJustifyItems(aSource.mJustifyItems)
- , mJustifySelf(aSource.mJustifySelf)
- , mFlexDirection(aSource.mFlexDirection)
- , mFlexWrap(aSource.mFlexWrap)
- , mObjectFit(aSource.mObjectFit)
- , mOrder(aSource.mOrder)
- , mFlexGrow(aSource.mFlexGrow)
- , mFlexShrink(aSource.mFlexShrink)
- , mZIndex(aSource.mZIndex)
- , mGridTemplateColumns(aSource.mGridTemplateColumns)
- , mGridTemplateRows(aSource.mGridTemplateRows)
- , mGridTemplateAreas(aSource.mGridTemplateAreas)
- , mGridColumnStart(aSource.mGridColumnStart)
- , mGridColumnEnd(aSource.mGridColumnEnd)
- , mGridRowStart(aSource.mGridRowStart)
- , mGridRowEnd(aSource.mGridRowEnd)
- , mGridColumnGap(aSource.mGridColumnGap)
- , mGridRowGap(aSource.mGridRowGap)
- {
- MOZ_COUNT_CTOR(nsStylePosition);
- }
- static bool
- IsAutonessEqual(const nsStyleSides& aSides1, const nsStyleSides& aSides2)
- {
- NS_FOR_CSS_SIDES(side) {
- if ((aSides1.GetUnit(side) == eStyleUnit_Auto) !=
- (aSides2.GetUnit(side) == eStyleUnit_Auto)) {
- return false;
- }
- }
- return true;
- }
- nsChangeHint
- nsStylePosition::CalcDifference(const nsStylePosition& aNewData,
- const nsStyleVisibility* aOldStyleVisibility) const
- {
- nsChangeHint hint = nsChangeHint(0);
- // Changes to "z-index" require a repaint.
- if (mZIndex != aNewData.mZIndex) {
- hint |= nsChangeHint_RepaintFrame;
- }
- // Changes to "object-fit" & "object-position" require a repaint. They
- // may also require a reflow, if we have a nsSubDocumentFrame, so that we
- // can adjust the size & position of the subdocument.
- if (mObjectFit != aNewData.mObjectFit ||
- mObjectPosition != aNewData.mObjectPosition) {
- hint |= nsChangeHint_RepaintFrame |
- nsChangeHint_NeedReflow;
- }
- if (mOrder != aNewData.mOrder) {
- // "order" impacts both layout order and stacking order, so we need both a
- // reflow and a repaint when it changes. (Technically, we only need a
- // reflow if we're in a multi-line flexbox (which we can't be sure about,
- // since that's determined by styling on our parent) -- there, "order" can
- // affect which flex line we end up on, & hence can affect our sizing by
- // changing the group of flex items we're competing with for space.)
- return hint |
- nsChangeHint_RepaintFrame |
- nsChangeHint_AllReflowHints;
- }
- if (mBoxSizing != aNewData.mBoxSizing) {
- // Can affect both widths and heights; just a bad scene.
- return hint |
- nsChangeHint_AllReflowHints;
- }
- // Properties that apply to flex items:
- // XXXdholbert These should probably be more targeted (bug 819536)
- if (mAlignSelf != aNewData.mAlignSelf ||
- mFlexBasis != aNewData.mFlexBasis ||
- mFlexGrow != aNewData.mFlexGrow ||
- mFlexShrink != aNewData.mFlexShrink) {
- return hint |
- nsChangeHint_AllReflowHints;
- }
- // Properties that apply to flex containers:
- // - flex-direction can swap a flex container between vertical & horizontal.
- // - align-items can change the sizing of a flex container & the positioning
- // of its children.
- // - flex-wrap changes whether a flex container's children are wrapped, which
- // impacts their sizing/positioning and hence impacts the container's size.
- if (mAlignItems != aNewData.mAlignItems ||
- mFlexDirection != aNewData.mFlexDirection ||
- mFlexWrap != aNewData.mFlexWrap) {
- return hint |
- nsChangeHint_AllReflowHints;
- }
- // Properties that apply to grid containers:
- // FIXME: only for grid containers
- // (ie. 'display: grid' or 'display: inline-grid')
- if (mGridTemplateColumns != aNewData.mGridTemplateColumns ||
- mGridTemplateRows != aNewData.mGridTemplateRows ||
- mGridTemplateAreas != aNewData.mGridTemplateAreas ||
- mGridAutoColumnsMin != aNewData.mGridAutoColumnsMin ||
- mGridAutoColumnsMax != aNewData.mGridAutoColumnsMax ||
- mGridAutoRowsMin != aNewData.mGridAutoRowsMin ||
- mGridAutoRowsMax != aNewData.mGridAutoRowsMax ||
- mGridAutoFlow != aNewData.mGridAutoFlow) {
- return hint |
- nsChangeHint_AllReflowHints;
- }
- // Properties that apply to grid items:
- // FIXME: only for grid items
- // (ie. parent frame is 'display: grid' or 'display: inline-grid')
- if (mGridColumnStart != aNewData.mGridColumnStart ||
- mGridColumnEnd != aNewData.mGridColumnEnd ||
- mGridRowStart != aNewData.mGridRowStart ||
- mGridRowEnd != aNewData.mGridRowEnd ||
- mGridColumnGap != aNewData.mGridColumnGap ||
- mGridRowGap != aNewData.mGridRowGap) {
- return hint |
- nsChangeHint_AllReflowHints;
- }
- // Changing 'justify-content/items/self' might affect the positioning,
- // but it won't affect any sizing.
- if (mJustifyContent != aNewData.mJustifyContent ||
- mJustifyItems != aNewData.mJustifyItems ||
- mJustifySelf != aNewData.mJustifySelf) {
- hint |= nsChangeHint_NeedReflow;
- }
- // 'align-content' doesn't apply to a single-line flexbox but we don't know
- // if we're a flex container at this point so we can't optimize for that.
- if (mAlignContent != aNewData.mAlignContent) {
- hint |= nsChangeHint_NeedReflow;
- }
- bool widthChanged = mWidth != aNewData.mWidth ||
- mMinWidth != aNewData.mMinWidth ||
- mMaxWidth != aNewData.mMaxWidth;
- bool heightChanged = mHeight != aNewData.mHeight ||
- mMinHeight != aNewData.mMinHeight ||
- mMaxHeight != aNewData.mMaxHeight;
- // If aOldStyleVisibility is null, we don't need to bother with any of
- // these tests, since we know that the element never had its
- // nsStyleVisibility accessed, which means it couldn't have done
- // layout.
- // Note that we pass an nsStyleVisibility here because we don't want
- // to cause a new struct to be computed during
- // nsStyleContext::CalcStyleDifference, which can lead to incorrect
- // style data.
- // It doesn't matter whether we're looking at the old or new
- // visibility struct, since a change between vertical and horizontal
- // writing-mode will cause a reframe, and it's easier to pass the old.
- if (aOldStyleVisibility) {
- bool isVertical = WritingMode(aOldStyleVisibility).IsVertical();
- if (isVertical ? widthChanged : heightChanged) {
- hint |= nsChangeHint_ReflowHintsForBSizeChange;
- }
- if (isVertical ? heightChanged : widthChanged) {
- hint |= nsChangeHint_ReflowHintsForISizeChange;
- }
- if (mAspectRatio != aNewData.mAspectRatio) {
- hint |= nsChangeHint_ReflowHintsForISizeChange |
- nsChangeHint_ReflowHintsForBSizeChange;
- }
- } else {
- if (widthChanged || heightChanged) {
- hint |= nsChangeHint_NeutralChange;
- }
- }
- // If any of the offsets have changed, then return the respective hints
- // so that we would hopefully be able to avoid reflowing.
- // Note that it is possible that we'll need to reflow when processing
- // restyles, but we don't have enough information to make a good decision
- // right now.
- // Don't try to handle changes between "auto" and non-auto efficiently;
- // that's tricky to do and will hardly ever be able to avoid a reflow.
- if (mOffset != aNewData.mOffset) {
- if (IsAutonessEqual(mOffset, aNewData.mOffset)) {
- hint |= nsChangeHint_RecomputePosition |
- nsChangeHint_UpdateParentOverflow;
- } else {
- hint |= nsChangeHint_AllReflowHints;
- }
- }
- return hint;
- }
- /* static */ bool
- nsStylePosition::WidthCoordDependsOnContainer(const nsStyleCoord &aCoord)
- {
- return aCoord.HasPercent() ||
- (aCoord.GetUnit() == eStyleUnit_Enumerated &&
- (aCoord.GetIntValue() == NS_STYLE_WIDTH_FIT_CONTENT ||
- aCoord.GetIntValue() == NS_STYLE_WIDTH_AVAILABLE));
- }
- uint8_t
- nsStylePosition::UsedAlignSelf(nsStyleContext* aParent) const
- {
- if (mAlignSelf != NS_STYLE_ALIGN_AUTO) {
- return mAlignSelf;
- }
- if (MOZ_LIKELY(aParent)) {
- auto parentAlignItems = aParent->StylePosition()->mAlignItems;
- MOZ_ASSERT(!(parentAlignItems & NS_STYLE_ALIGN_LEGACY),
- "align-items can't have 'legacy'");
- return parentAlignItems;
- }
- return NS_STYLE_ALIGN_NORMAL;
- }
- uint8_t
- nsStylePosition::ComputedJustifyItems(nsStyleContext* aParent) const
- {
- if (mJustifyItems != NS_STYLE_JUSTIFY_AUTO) {
- return mJustifyItems;
- }
- if (MOZ_LIKELY(aParent)) {
- auto inheritedJustifyItems =
- aParent->StylePosition()->ComputedJustifyItems(aParent->GetParent());
- // "If the inherited value of justify-items includes the 'legacy' keyword,
- // 'auto' computes to the inherited value." Otherwise, 'normal'.
- if (inheritedJustifyItems & NS_STYLE_JUSTIFY_LEGACY) {
- return inheritedJustifyItems;
- }
- }
- return NS_STYLE_JUSTIFY_NORMAL;
- }
- uint8_t
- nsStylePosition::UsedJustifySelf(nsStyleContext* aParent) const
- {
- if (mJustifySelf != NS_STYLE_JUSTIFY_AUTO) {
- return mJustifySelf;
- }
- if (MOZ_LIKELY(aParent)) {
- auto inheritedJustifyItems = aParent->StylePosition()->
- ComputedJustifyItems(aParent->GetParent());
- return inheritedJustifyItems & ~NS_STYLE_JUSTIFY_LEGACY;
- }
- return NS_STYLE_JUSTIFY_NORMAL;
- }
- // --------------------
- // nsStyleTable
- //
- nsStyleTable::nsStyleTable(StyleStructContext aContext)
- : mLayoutStrategy(NS_STYLE_TABLE_LAYOUT_AUTO)
- , mSpan(1)
- {
- MOZ_COUNT_CTOR(nsStyleTable);
- }
- nsStyleTable::~nsStyleTable()
- {
- MOZ_COUNT_DTOR(nsStyleTable);
- }
- nsStyleTable::nsStyleTable(const nsStyleTable& aSource)
- : mLayoutStrategy(aSource.mLayoutStrategy)
- , mSpan(aSource.mSpan)
- {
- MOZ_COUNT_CTOR(nsStyleTable);
- }
- nsChangeHint
- nsStyleTable::CalcDifference(const nsStyleTable& aNewData) const
- {
- if (mSpan != aNewData.mSpan ||
- mLayoutStrategy != aNewData.mLayoutStrategy) {
- return nsChangeHint_ReconstructFrame;
- }
- return nsChangeHint(0);
- }
- // -----------------------
- // nsStyleTableBorder
- nsStyleTableBorder::nsStyleTableBorder(StyleStructContext aContext)
- : mBorderSpacingCol(0)
- , mBorderSpacingRow(0)
- , mBorderCollapse(NS_STYLE_BORDER_SEPARATE)
- , mCaptionSide(NS_STYLE_CAPTION_SIDE_TOP)
- , mEmptyCells(NS_STYLE_TABLE_EMPTY_CELLS_SHOW)
- {
- MOZ_COUNT_CTOR(nsStyleTableBorder);
- }
- nsStyleTableBorder::~nsStyleTableBorder()
- {
- MOZ_COUNT_DTOR(nsStyleTableBorder);
- }
- nsStyleTableBorder::nsStyleTableBorder(const nsStyleTableBorder& aSource)
- : mBorderSpacingCol(aSource.mBorderSpacingCol)
- , mBorderSpacingRow(aSource.mBorderSpacingRow)
- , mBorderCollapse(aSource.mBorderCollapse)
- , mCaptionSide(aSource.mCaptionSide)
- , mEmptyCells(aSource.mEmptyCells)
- {
- MOZ_COUNT_CTOR(nsStyleTableBorder);
- }
- nsChangeHint
- nsStyleTableBorder::CalcDifference(const nsStyleTableBorder& aNewData) const
- {
- // Border-collapse changes need a reframe, because we use a different frame
- // class for table cells in the collapsed border model. This is used to
- // conserve memory when using the separated border model (collapsed borders
- // require extra state to be stored).
- if (mBorderCollapse != aNewData.mBorderCollapse) {
- return nsChangeHint_ReconstructFrame;
- }
- if ((mCaptionSide == aNewData.mCaptionSide) &&
- (mBorderSpacingCol == aNewData.mBorderSpacingCol) &&
- (mBorderSpacingRow == aNewData.mBorderSpacingRow)) {
- if (mEmptyCells == aNewData.mEmptyCells) {
- return nsChangeHint(0);
- }
- return NS_STYLE_HINT_VISUAL;
- } else {
- return NS_STYLE_HINT_REFLOW;
- }
- }
- // --------------------
- // nsStyleColor
- //
- nsStyleColor::nsStyleColor(StyleStructContext aContext)
- : mColor(aContext.DefaultColor())
- {
- MOZ_COUNT_CTOR(nsStyleColor);
- }
- nsStyleColor::nsStyleColor(const nsStyleColor& aSource)
- : mColor(aSource.mColor)
- {
- MOZ_COUNT_CTOR(nsStyleColor);
- }
- nsChangeHint
- nsStyleColor::CalcDifference(const nsStyleColor& aNewData) const
- {
- if (mColor == aNewData.mColor) {
- return nsChangeHint(0);
- }
- return nsChangeHint_RepaintFrame;
- }
- // --------------------
- // nsStyleGradient
- //
- bool
- nsStyleGradient::operator==(const nsStyleGradient& aOther) const
- {
- MOZ_ASSERT(mSize == NS_STYLE_GRADIENT_SIZE_FARTHEST_CORNER ||
- mShape != NS_STYLE_GRADIENT_SHAPE_LINEAR,
- "incorrect combination of shape and size");
- MOZ_ASSERT(aOther.mSize == NS_STYLE_GRADIENT_SIZE_FARTHEST_CORNER ||
- aOther.mShape != NS_STYLE_GRADIENT_SHAPE_LINEAR,
- "incorrect combination of shape and size");
- if (mShape != aOther.mShape ||
- mSize != aOther.mSize ||
- mRepeating != aOther.mRepeating ||
- mLegacySyntax != aOther.mLegacySyntax ||
- mBgPosX != aOther.mBgPosX ||
- mBgPosY != aOther.mBgPosY ||
- mAngle != aOther.mAngle ||
- mRadiusX != aOther.mRadiusX ||
- mRadiusY != aOther.mRadiusY) {
- return false;
- }
- if (mStops.Length() != aOther.mStops.Length()) {
- return false;
- }
- for (uint32_t i = 0; i < mStops.Length(); i++) {
- const auto& stop1 = mStops[i];
- const auto& stop2 = aOther.mStops[i];
- if (stop1.mLocation != stop2.mLocation ||
- stop1.mIsInterpolationHint != stop2.mIsInterpolationHint ||
- (!stop1.mIsInterpolationHint && stop1.mColor != stop2.mColor)) {
- return false;
- }
- }
- return true;
- }
- nsStyleGradient::nsStyleGradient()
- : mShape(NS_STYLE_GRADIENT_SHAPE_LINEAR)
- , mSize(NS_STYLE_GRADIENT_SIZE_FARTHEST_CORNER)
- , mRepeating(false)
- , mLegacySyntax(false)
- {
- }
- bool
- nsStyleGradient::IsOpaque()
- {
- for (uint32_t i = 0; i < mStops.Length(); i++) {
- if (NS_GET_A(mStops[i].mColor) < 255) {
- return false;
- }
- }
- return true;
- }
- bool
- nsStyleGradient::HasCalc()
- {
- for (uint32_t i = 0; i < mStops.Length(); i++) {
- if (mStops[i].mLocation.IsCalcUnit()) {
- return true;
- }
- }
- return mBgPosX.IsCalcUnit() || mBgPosY.IsCalcUnit() || mAngle.IsCalcUnit() ||
- mRadiusX.IsCalcUnit() || mRadiusY.IsCalcUnit();
- }
- // --------------------
- // nsStyleImageRequest
- /**
- * Runnable to release the nsStyleImageRequest's mRequestProxy,
- * mImageValue and mImageValue on the main thread, and to perform
- * any necessary unlocking and untracking of the image.
- */
- class StyleImageRequestCleanupTask : public mozilla::Runnable
- {
- public:
- typedef nsStyleImageRequest::Mode Mode;
- StyleImageRequestCleanupTask(Mode aModeFlags,
- already_AddRefed<imgRequestProxy> aRequestProxy,
- already_AddRefed<css::ImageValue> aImageValue,
- already_AddRefed<ImageTracker> aImageTracker)
- : mModeFlags(aModeFlags)
- , mRequestProxy(aRequestProxy)
- , mImageValue(aImageValue)
- , mImageTracker(aImageTracker)
- {
- }
- NS_IMETHOD Run() final
- {
- MOZ_ASSERT(NS_IsMainThread());
- if (!mRequestProxy) {
- return NS_OK;
- }
- if (mModeFlags & Mode::Track) {
- MOZ_ASSERT(mImageTracker);
- mImageTracker->Remove(mRequestProxy);
- } else {
- mRequestProxy->UnlockImage();
- }
- if (mModeFlags & Mode::Discard) {
- mRequestProxy->RequestDiscard();
- }
- return NS_OK;
- }
- protected:
- virtual ~StyleImageRequestCleanupTask() { MOZ_ASSERT(NS_IsMainThread()); }
- private:
- Mode mModeFlags;
- // Since we always dispatch this runnable to the main thread, these will be
- // released on the main thread when the runnable itself is released.
- RefPtr<imgRequestProxy> mRequestProxy;
- RefPtr<css::ImageValue> mImageValue;
- RefPtr<ImageTracker> mImageTracker;
- };
- nsStyleImageRequest::nsStyleImageRequest(Mode aModeFlags,
- imgRequestProxy* aRequestProxy,
- css::ImageValue* aImageValue,
- ImageTracker* aImageTracker)
- : mRequestProxy(aRequestProxy)
- , mImageValue(aImageValue)
- , mImageTracker(aImageTracker)
- , mModeFlags(aModeFlags)
- , mResolved(true)
- {
- MOZ_ASSERT(NS_IsMainThread());
- MOZ_ASSERT(aRequestProxy);
- MOZ_ASSERT(aImageValue);
- MOZ_ASSERT(!!(aModeFlags & Mode::Track) == !!aImageTracker);
- MaybeTrackAndLock();
- }
- nsStyleImageRequest::nsStyleImageRequest(
- Mode aModeFlags,
- nsStringBuffer* aURLBuffer,
- already_AddRefed<PtrHolder<nsIURI>> aBaseURI,
- already_AddRefed<PtrHolder<nsIURI>> aReferrer,
- already_AddRefed<PtrHolder<nsIPrincipal>> aPrincipal)
- : mModeFlags(aModeFlags)
- , mResolved(false)
- {
- mImageValue = new css::ImageValue(aURLBuffer, Move(aBaseURI),
- Move(aReferrer), Move(aPrincipal));
- }
- nsStyleImageRequest::~nsStyleImageRequest()
- {
- // We may or may not be being destroyed on the main thread. To clean
- // up, we must untrack and unlock the image (depending on mModeFlags),
- // and release mRequestProxy and mImageValue, all on the main thread.
- {
- RefPtr<StyleImageRequestCleanupTask> task =
- new StyleImageRequestCleanupTask(mModeFlags,
- mRequestProxy.forget(),
- mImageValue.forget(),
- mImageTracker.forget());
- if (NS_IsMainThread()) {
- task->Run();
- } else {
- NS_DispatchToMainThread(task.forget());
- }
- }
- MOZ_ASSERT(!mRequestProxy);
- MOZ_ASSERT(!mImageValue);
- MOZ_ASSERT(!mImageTracker);
- }
- bool
- nsStyleImageRequest::Resolve(nsPresContext* aPresContext)
- {
- MOZ_ASSERT(NS_IsMainThread());
- MOZ_ASSERT(!IsResolved(), "already resolved");
- mResolved = true;
- // For now, just have unique nsCSSValue/ImageValue objects. We should
- // really store the ImageValue on the Servo specified value, so that we can
- // share imgRequestProxys that come from the same rule in the same
- // document.
- mImageValue->Initialize(aPresContext->Document());
- nsCSSValue value;
- value.SetImageValue(mImageValue);
- mRequestProxy = value.GetPossiblyStaticImageValue(aPresContext->Document(),
- aPresContext);
- if (!mRequestProxy) {
- // The URL resolution or image load failed.
- return false;
- }
- if (mModeFlags & Mode::Track) {
- mImageTracker = aPresContext->Document()->ImageTracker();
- }
- MaybeTrackAndLock();
- return true;
- }
- void
- nsStyleImageRequest::MaybeTrackAndLock()
- {
- MOZ_ASSERT(NS_IsMainThread());
- MOZ_ASSERT(IsResolved());
- MOZ_ASSERT(mRequestProxy);
- if (mModeFlags & Mode::Track) {
- MOZ_ASSERT(mImageTracker);
- mImageTracker->Add(mRequestProxy);
- } else {
- MOZ_ASSERT(!mImageTracker);
- mRequestProxy->LockImage();
- }
- }
- bool
- nsStyleImageRequest::DefinitelyEquals(const nsStyleImageRequest& aOther) const
- {
- return DefinitelyEqualURIs(mImageValue, aOther.mImageValue);
- }
- // --------------------
- // CachedBorderImageData
- //
- void
- CachedBorderImageData::SetCachedSVGViewportSize(
- const mozilla::Maybe<nsSize>& aSVGViewportSize)
- {
- mCachedSVGViewportSize = aSVGViewportSize;
- }
- const mozilla::Maybe<nsSize>&
- CachedBorderImageData::GetCachedSVGViewportSize()
- {
- return mCachedSVGViewportSize;
- }
- void
- CachedBorderImageData::PurgeCachedImages()
- {
- mSubImages.Clear();
- }
- void
- CachedBorderImageData::SetSubImage(uint8_t aIndex, imgIContainer* aSubImage)
- {
- mSubImages.ReplaceObjectAt(aSubImage, aIndex);
- }
- imgIContainer*
- CachedBorderImageData::GetSubImage(uint8_t aIndex)
- {
- imgIContainer* subImage = nullptr;
- if (aIndex < mSubImages.Count())
- subImage = mSubImages[aIndex];
- return subImage;
- }
- // --------------------
- // nsStyleImage
- //
- nsStyleImage::nsStyleImage()
- : mType(eStyleImageType_Null)
- , mCropRect(nullptr)
- {
- MOZ_COUNT_CTOR(nsStyleImage);
- }
- nsStyleImage::~nsStyleImage()
- {
- MOZ_COUNT_DTOR(nsStyleImage);
- if (mType != eStyleImageType_Null) {
- SetNull();
- }
- }
- nsStyleImage::nsStyleImage(const nsStyleImage& aOther)
- : mType(eStyleImageType_Null)
- , mCropRect(nullptr)
- {
- // We need our own copy constructor because we don't want
- // to copy the reference count
- MOZ_COUNT_CTOR(nsStyleImage);
- DoCopy(aOther);
- }
- nsStyleImage&
- nsStyleImage::operator=(const nsStyleImage& aOther)
- {
- if (this != &aOther) {
- DoCopy(aOther);
- }
- return *this;
- }
- void
- nsStyleImage::DoCopy(const nsStyleImage& aOther)
- {
- SetNull();
- if (aOther.mType == eStyleImageType_Image) {
- SetImageRequest(do_AddRef(aOther.mImage));
- } else if (aOther.mType == eStyleImageType_Gradient) {
- SetGradientData(aOther.mGradient);
- } else if (aOther.mType == eStyleImageType_Element) {
- SetElementId(aOther.mElementId);
- }
- UniquePtr<nsStyleSides> cropRectCopy;
- if (aOther.mCropRect) {
- cropRectCopy = MakeUnique<nsStyleSides>(*aOther.mCropRect.get());
- }
- SetCropRect(Move(cropRectCopy));
- }
- void
- nsStyleImage::SetNull()
- {
- if (mType == eStyleImageType_Gradient) {
- mGradient->Release();
- } else if (mType == eStyleImageType_Image) {
- NS_RELEASE(mImage);
- } else if (mType == eStyleImageType_Element) {
- free(mElementId);
- }
- mType = eStyleImageType_Null;
- mCropRect = nullptr;
- }
- void
- nsStyleImage::SetImageRequest(already_AddRefed<nsStyleImageRequest> aImage)
- {
- RefPtr<nsStyleImageRequest> image = aImage;
- if (mType != eStyleImageType_Null) {
- SetNull();
- }
- if (image) {
- mImage = image.forget().take();
- mType = eStyleImageType_Image;
- }
- if (mCachedBIData) {
- mCachedBIData->PurgeCachedImages();
- }
- }
- void
- nsStyleImage::SetGradientData(nsStyleGradient* aGradient)
- {
- if (aGradient) {
- aGradient->AddRef();
- }
- if (mType != eStyleImageType_Null) {
- SetNull();
- }
- if (aGradient) {
- mGradient = aGradient;
- mType = eStyleImageType_Gradient;
- }
- }
- void
- nsStyleImage::SetElementId(const char16_t* aElementId)
- {
- if (mType != eStyleImageType_Null) {
- SetNull();
- }
- if (aElementId) {
- mElementId = NS_strdup(aElementId);
- mType = eStyleImageType_Element;
- }
- }
- void
- nsStyleImage::SetCropRect(UniquePtr<nsStyleSides> aCropRect)
- {
- mCropRect = Move(aCropRect);
- }
- static int32_t
- ConvertToPixelCoord(const nsStyleCoord& aCoord, int32_t aPercentScale)
- {
- double pixelValue;
- switch (aCoord.GetUnit()) {
- case eStyleUnit_Percent:
- pixelValue = aCoord.GetPercentValue() * aPercentScale;
- break;
- case eStyleUnit_Factor:
- pixelValue = aCoord.GetFactorValue();
- break;
- default:
- NS_NOTREACHED("unexpected unit for image crop rect");
- return 0;
- }
- MOZ_ASSERT(pixelValue >= 0, "we ensured non-negative while parsing");
- pixelValue = std::min(pixelValue, double(INT32_MAX)); // avoid overflow
- return NS_lround(pixelValue);
- }
- bool
- nsStyleImage::ComputeActualCropRect(nsIntRect& aActualCropRect,
- bool* aIsEntireImage) const
- {
- if (mType != eStyleImageType_Image) {
- return false;
- }
- imgRequestProxy* req = GetImageData();
- if (!req) {
- return false;
- }
- nsCOMPtr<imgIContainer> imageContainer;
- req->GetImage(getter_AddRefs(imageContainer));
- if (!imageContainer) {
- return false;
- }
- nsIntSize imageSize;
- imageContainer->GetWidth(&imageSize.width);
- imageContainer->GetHeight(&imageSize.height);
- if (imageSize.width <= 0 || imageSize.height <= 0) {
- return false;
- }
- int32_t left = ConvertToPixelCoord(mCropRect->GetLeft(), imageSize.width);
- int32_t top = ConvertToPixelCoord(mCropRect->GetTop(), imageSize.height);
- int32_t right = ConvertToPixelCoord(mCropRect->GetRight(), imageSize.width);
- int32_t bottom = ConvertToPixelCoord(mCropRect->GetBottom(), imageSize.height);
- // IntersectRect() returns an empty rect if we get negative width or height
- nsIntRect cropRect(left, top, right - left, bottom - top);
- nsIntRect imageRect(nsIntPoint(0, 0), imageSize);
- aActualCropRect.IntersectRect(imageRect, cropRect);
- if (aIsEntireImage) {
- *aIsEntireImage = aActualCropRect.IsEqualInterior(imageRect);
- }
- return true;
- }
- nsresult
- nsStyleImage::StartDecoding() const
- {
- if (mType == eStyleImageType_Image) {
- imgRequestProxy* req = GetImageData();
- if (!req) {
- return NS_ERROR_FAILURE;
- }
- return req->StartDecoding();
- }
- return NS_OK;
- }
- bool
- nsStyleImage::IsOpaque() const
- {
- if (!IsComplete()) {
- return false;
- }
- if (mType == eStyleImageType_Gradient) {
- return mGradient->IsOpaque();
- }
- if (mType == eStyleImageType_Element) {
- return false;
- }
- MOZ_ASSERT(mType == eStyleImageType_Image, "unexpected image type");
- MOZ_ASSERT(GetImageData(), "should've returned earlier above");
- nsCOMPtr<imgIContainer> imageContainer;
- GetImageData()->GetImage(getter_AddRefs(imageContainer));
- MOZ_ASSERT(imageContainer, "IsComplete() said image container is ready");
- // Check if the crop region of the image is opaque.
- if (imageContainer->WillDrawOpaqueNow()) {
- if (!mCropRect) {
- return true;
- }
- // Must make sure if mCropRect contains at least a pixel.
- // XXX Is this optimization worth it? Maybe I should just return false.
- nsIntRect actualCropRect;
- bool rv = ComputeActualCropRect(actualCropRect);
- NS_ASSERTION(rv, "ComputeActualCropRect() can not fail here");
- return rv && !actualCropRect.IsEmpty();
- }
- return false;
- }
- bool
- nsStyleImage::IsComplete() const
- {
- switch (mType) {
- case eStyleImageType_Null:
- return false;
- case eStyleImageType_Gradient:
- case eStyleImageType_Element:
- return true;
- case eStyleImageType_Image: {
- imgRequestProxy* req = GetImageData();
- if (!req) {
- return false;
- }
- uint32_t status = imgIRequest::STATUS_ERROR;
- return NS_SUCCEEDED(req->GetImageStatus(&status)) &&
- (status & imgIRequest::STATUS_SIZE_AVAILABLE) &&
- (status & imgIRequest::STATUS_FRAME_COMPLETE);
- }
- default:
- NS_NOTREACHED("unexpected image type");
- return false;
- }
- }
- bool
- nsStyleImage::IsLoaded() const
- {
- switch (mType) {
- case eStyleImageType_Null:
- return false;
- case eStyleImageType_Gradient:
- case eStyleImageType_Element:
- return true;
- case eStyleImageType_Image: {
- imgRequestProxy* req = GetImageData();
- if (!req) {
- return false;
- }
- uint32_t status = imgIRequest::STATUS_ERROR;
- return NS_SUCCEEDED(req->GetImageStatus(&status)) &&
- !(status & imgIRequest::STATUS_ERROR) &&
- (status & imgIRequest::STATUS_LOAD_COMPLETE);
- }
- default:
- NS_NOTREACHED("unexpected image type");
- return false;
- }
- }
- static inline bool
- EqualRects(const UniquePtr<nsStyleSides>& aRect1, const UniquePtr<nsStyleSides>& aRect2)
- {
- return aRect1 == aRect2 || /* handles null== null, and optimize */
- (aRect1 && aRect2 && *aRect1 == *aRect2);
- }
- bool
- nsStyleImage::operator==(const nsStyleImage& aOther) const
- {
- if (mType != aOther.mType) {
- return false;
- }
- if (!EqualRects(mCropRect, aOther.mCropRect)) {
- return false;
- }
- if (mType == eStyleImageType_Image) {
- return DefinitelyEqualImages(mImage, aOther.mImage);
- }
- if (mType == eStyleImageType_Gradient) {
- return *mGradient == *aOther.mGradient;
- }
- if (mType == eStyleImageType_Element) {
- return NS_strcmp(mElementId, aOther.mElementId) == 0;
- }
- return true;
- }
- void
- nsStyleImage::PurgeCacheForViewportChange(
- const mozilla::Maybe<nsSize>& aSVGViewportSize,
- const bool aHasIntrinsicRatio) const
- {
- EnsureCachedBIData();
- // If we're redrawing with a different viewport-size than we used for our
- // cached subimages, then we can't trust that our subimages are valid;
- // any percent sizes/positions in our SVG doc may be different now. Purge!
- // (We don't have to purge if the SVG document has an intrinsic ratio,
- // though, because the actual size of elements in SVG documant's coordinate
- // axis are fixed in this case.)
- if (aSVGViewportSize != mCachedBIData->GetCachedSVGViewportSize() &&
- !aHasIntrinsicRatio) {
- mCachedBIData->PurgeCachedImages();
- mCachedBIData->SetCachedSVGViewportSize(aSVGViewportSize);
- }
- }
- // --------------------
- // nsStyleImageLayers
- //
- const nsCSSPropertyID nsStyleImageLayers::kBackgroundLayerTable[] = {
- eCSSProperty_background, // shorthand
- eCSSProperty_background_color, // color
- eCSSProperty_background_image, // image
- eCSSProperty_background_repeat, // repeat
- eCSSProperty_background_position_x, // positionX
- eCSSProperty_background_position_y, // positionY
- eCSSProperty_background_clip, // clip
- eCSSProperty_background_origin, // origin
- eCSSProperty_background_size, // size
- eCSSProperty_background_attachment, // attachment
- eCSSProperty_UNKNOWN, // maskMode
- eCSSProperty_UNKNOWN // composite
- };
- const nsCSSPropertyID nsStyleImageLayers::kMaskLayerTable[] = {
- eCSSProperty_mask, // shorthand
- eCSSProperty_UNKNOWN, // color
- eCSSProperty_mask_image, // image
- eCSSProperty_mask_repeat, // repeat
- eCSSProperty_mask_position_x, // positionX
- eCSSProperty_mask_position_y, // positionY
- eCSSProperty_mask_clip, // clip
- eCSSProperty_mask_origin, // origin
- eCSSProperty_mask_size, // size
- eCSSProperty_UNKNOWN, // attachment
- eCSSProperty_mask_mode, // maskMode
- eCSSProperty_mask_composite // composite
- };
- nsStyleImageLayers::nsStyleImageLayers(nsStyleImageLayers::LayerType aType)
- : mAttachmentCount(1)
- , mClipCount(1)
- , mOriginCount(1)
- , mRepeatCount(1)
- , mPositionXCount(1)
- , mPositionYCount(1)
- , mImageCount(1)
- , mSizeCount(1)
- , mMaskModeCount(1)
- , mBlendModeCount(1)
- , mCompositeCount(1)
- , mLayers(nsStyleAutoArray<Layer>::WITH_SINGLE_INITIAL_ELEMENT)
- {
- MOZ_COUNT_CTOR(nsStyleImageLayers);
- // Ensure first layer is initialized as specified layer type
- mLayers[0].Initialize(aType);
- }
- nsStyleImageLayers::nsStyleImageLayers(const nsStyleImageLayers &aSource)
- : mAttachmentCount(aSource.mAttachmentCount)
- , mClipCount(aSource.mClipCount)
- , mOriginCount(aSource.mOriginCount)
- , mRepeatCount(aSource.mRepeatCount)
- , mPositionXCount(aSource.mPositionXCount)
- , mPositionYCount(aSource.mPositionYCount)
- , mImageCount(aSource.mImageCount)
- , mSizeCount(aSource.mSizeCount)
- , mMaskModeCount(aSource.mMaskModeCount)
- , mBlendModeCount(aSource.mBlendModeCount)
- , mCompositeCount(aSource.mCompositeCount)
- , mLayers(aSource.mLayers) // deep copy
- {
- MOZ_COUNT_CTOR(nsStyleImageLayers);
- // If the deep copy of mLayers failed, truncate the counts.
- uint32_t count = mLayers.Length();
- if (count != aSource.mLayers.Length()) {
- NS_WARNING("truncating counts due to out-of-memory");
- mAttachmentCount = std::max(mAttachmentCount, count);
- mClipCount = std::max(mClipCount, count);
- mOriginCount = std::max(mOriginCount, count);
- mRepeatCount = std::max(mRepeatCount, count);
- mPositionXCount = std::max(mPositionXCount, count);
- mPositionYCount = std::max(mPositionYCount, count);
- mImageCount = std::max(mImageCount, count);
- mSizeCount = std::max(mSizeCount, count);
- mMaskModeCount = std::max(mMaskModeCount, count);
- mBlendModeCount = std::max(mBlendModeCount, count);
- mCompositeCount = std::max(mCompositeCount, count);
- }
- }
- nsChangeHint
- nsStyleImageLayers::CalcDifference(const nsStyleImageLayers& aNewLayers,
- nsStyleImageLayers::LayerType aType) const
- {
- nsChangeHint hint = nsChangeHint(0);
- const nsStyleImageLayers& moreLayers =
- mImageCount > aNewLayers.mImageCount ?
- *this : aNewLayers;
- const nsStyleImageLayers& lessLayers =
- mImageCount > aNewLayers.mImageCount ?
- aNewLayers : *this;
- NS_FOR_VISIBLE_IMAGE_LAYERS_BACK_TO_FRONT(i, moreLayers) {
- if (i < lessLayers.mImageCount) {
- nsChangeHint layerDifference =
- moreLayers.mLayers[i].CalcDifference(lessLayers.mLayers[i]);
- hint |= layerDifference;
- if (layerDifference &&
- ((moreLayers.mLayers[i].mImage.GetType() == eStyleImageType_Element) ||
- (lessLayers.mLayers[i].mImage.GetType() == eStyleImageType_Element))) {
- hint |= nsChangeHint_UpdateEffects | nsChangeHint_RepaintFrame;
- }
- } else {
- hint |= nsChangeHint_RepaintFrame;
- if (moreLayers.mLayers[i].mImage.GetType() == eStyleImageType_Element) {
- hint |= nsChangeHint_UpdateEffects | nsChangeHint_RepaintFrame;
- }
- }
- }
- if (aType == nsStyleImageLayers::LayerType::Mask &&
- mImageCount != aNewLayers.mImageCount) {
- hint |= nsChangeHint_UpdateEffects;
- }
- if (hint) {
- return hint;
- }
- if (mAttachmentCount != aNewLayers.mAttachmentCount ||
- mBlendModeCount != aNewLayers.mBlendModeCount ||
- mClipCount != aNewLayers.mClipCount ||
- mCompositeCount != aNewLayers.mCompositeCount ||
- mMaskModeCount != aNewLayers.mMaskModeCount ||
- mOriginCount != aNewLayers.mOriginCount ||
- mRepeatCount != aNewLayers.mRepeatCount ||
- mPositionXCount != aNewLayers.mPositionXCount ||
- mPositionYCount != aNewLayers.mPositionYCount ||
- mSizeCount != aNewLayers.mSizeCount) {
- hint |= nsChangeHint_NeutralChange;
- }
- return hint;
- }
- bool
- nsStyleImageLayers::HasLayerWithImage() const
- {
- for (uint32_t i = 0; i < mImageCount; i++) {
- // mLayers[i].mSourceURI can be nullptr if mask-image prop value is
- // <element-reference> or <gradient>
- // mLayers[i].mImage can be empty if mask-image prop value is a reference
- // to SVG mask element.
- // So we need to test both mSourceURI and mImage.
- if ((mLayers[i].mSourceURI && mLayers[i].mSourceURI->GetURI()) ||
- !mLayers[i].mImage.IsEmpty()) {
- return true;
- }
- }
- return false;
- }
- nsStyleImageLayers&
- nsStyleImageLayers::operator=(const nsStyleImageLayers& aOther)
- {
- mAttachmentCount = aOther.mAttachmentCount;
- mClipCount = aOther.mClipCount;
- mOriginCount = aOther.mOriginCount;
- mRepeatCount = aOther.mRepeatCount;
- mPositionXCount = aOther.mPositionXCount;
- mPositionYCount = aOther.mPositionYCount;
- mImageCount = aOther.mImageCount;
- mSizeCount = aOther.mSizeCount;
- mMaskModeCount = aOther.mMaskModeCount;
- mBlendModeCount = aOther.mBlendModeCount;
- mCompositeCount = aOther.mCompositeCount;
- mLayers = aOther.mLayers;
- uint32_t count = mLayers.Length();
- if (count != aOther.mLayers.Length()) {
- NS_WARNING("truncating counts due to out-of-memory");
- mAttachmentCount = std::max(mAttachmentCount, count);
- mClipCount = std::max(mClipCount, count);
- mOriginCount = std::max(mOriginCount, count);
- mRepeatCount = std::max(mRepeatCount, count);
- mPositionXCount = std::max(mPositionXCount, count);
- mPositionYCount = std::max(mPositionYCount, count);
- mImageCount = std::max(mImageCount, count);
- mSizeCount = std::max(mSizeCount, count);
- mMaskModeCount = std::max(mMaskModeCount, count);
- mBlendModeCount = std::max(mBlendModeCount, count);
- mCompositeCount = std::max(mCompositeCount, count);
- }
- return *this;
- }
- bool
- nsStyleImageLayers::IsInitialPositionForLayerType(Position aPosition, LayerType aType)
- {
- if (aPosition.mXPosition.mPercent == 0.0f &&
- aPosition.mXPosition.mLength == 0 &&
- aPosition.mXPosition.mHasPercent &&
- aPosition.mYPosition.mPercent == 0.0f &&
- aPosition.mYPosition.mLength == 0 &&
- aPosition.mYPosition.mHasPercent) {
- return true;
- }
- return false;
- }
- void
- Position::SetInitialPercentValues(float aPercentVal)
- {
- mXPosition.mPercent = aPercentVal;
- mXPosition.mLength = 0;
- mXPosition.mHasPercent = true;
- mYPosition.mPercent = aPercentVal;
- mYPosition.mLength = 0;
- mYPosition.mHasPercent = true;
- }
- void
- Position::SetInitialZeroValues()
- {
- mXPosition.mPercent = 0;
- mXPosition.mLength = 0;
- mXPosition.mHasPercent = false;
- mYPosition.mPercent = 0;
- mYPosition.mLength = 0;
- mYPosition.mHasPercent = false;
- }
- bool
- nsStyleImageLayers::Size::DependsOnPositioningAreaSize(const nsStyleImage& aImage) const
- {
- MOZ_ASSERT(aImage.GetType() != eStyleImageType_Null,
- "caller should have handled this");
- // If either dimension contains a non-zero percentage, rendering for that
- // dimension straightforwardly depends on frame size.
- if ((mWidthType == eLengthPercentage && mWidth.mPercent != 0.0f) ||
- (mHeightType == eLengthPercentage && mHeight.mPercent != 0.0f)) {
- return true;
- }
- // So too for contain and cover.
- if (mWidthType == eContain || mWidthType == eCover) {
- return true;
- }
- // If both dimensions are fixed lengths, there's no dependency.
- if (mWidthType == eLengthPercentage && mHeightType == eLengthPercentage) {
- return false;
- }
- MOZ_ASSERT((mWidthType == eLengthPercentage && mHeightType == eAuto) ||
- (mWidthType == eAuto && mHeightType == eLengthPercentage) ||
- (mWidthType == eAuto && mHeightType == eAuto),
- "logic error");
- nsStyleImageType type = aImage.GetType();
- // Gradient rendering depends on frame size when auto is involved because
- // gradients have no intrinsic ratio or dimensions, and therefore the relevant
- // dimension is "treat[ed] as 100%".
- if (type == eStyleImageType_Gradient) {
- return true;
- }
- // XXX Element rendering for auto or fixed length doesn't depend on frame size
- // according to the spec. However, we don't implement the spec yet, so
- // for now we bail and say element() plus auto affects ultimate size.
- if (type == eStyleImageType_Element) {
- return true;
- }
- if (type == eStyleImageType_Image) {
- nsCOMPtr<imgIContainer> imgContainer;
- if (imgRequestProxy* req = aImage.GetImageData()) {
- req->GetImage(getter_AddRefs(imgContainer));
- }
- if (imgContainer) {
- CSSIntSize imageSize;
- AspectRatio imageRatio;
- bool hasWidth, hasHeight;
- nsLayoutUtils::ComputeSizeForDrawing(imgContainer, imageSize, imageRatio,
- hasWidth, hasHeight);
- // If the image has a fixed width and height, rendering never depends on
- // the frame size.
- if (hasWidth && hasHeight) {
- return false;
- }
- // If the image has an intrinsic ratio, rendering will depend on frame
- // size when background-size is all auto.
- if (imageRatio) {
- return mWidthType == mHeightType;
- }
- // Otherwise, rendering depends on frame size when the image dimensions
- // and background-size don't complement each other.
- return !(hasWidth && mHeightType == eLengthPercentage) &&
- !(hasHeight && mWidthType == eLengthPercentage);
- }
- } else {
- NS_NOTREACHED("missed an enum value");
- }
- // Passed the gauntlet: no dependency.
- return false;
- }
- void
- nsStyleImageLayers::Size::SetInitialValues()
- {
- mWidthType = mHeightType = eAuto;
- }
- bool
- nsStyleImageLayers::Size::operator==(const Size& aOther) const
- {
- MOZ_ASSERT(mWidthType < eDimensionType_COUNT,
- "bad mWidthType for this");
- MOZ_ASSERT(mHeightType < eDimensionType_COUNT,
- "bad mHeightType for this");
- MOZ_ASSERT(aOther.mWidthType < eDimensionType_COUNT,
- "bad mWidthType for aOther");
- MOZ_ASSERT(aOther.mHeightType < eDimensionType_COUNT,
- "bad mHeightType for aOther");
- return mWidthType == aOther.mWidthType &&
- mHeightType == aOther.mHeightType &&
- (mWidthType != eLengthPercentage || mWidth == aOther.mWidth) &&
- (mHeightType != eLengthPercentage || mHeight == aOther.mHeight);
- }
- nsStyleImageLayers::Layer::Layer()
- : mClip(StyleGeometryBox::Border)
- , mAttachment(NS_STYLE_IMAGELAYER_ATTACHMENT_SCROLL)
- , mBlendMode(NS_STYLE_BLEND_NORMAL)
- , mComposite(NS_STYLE_MASK_COMPOSITE_ADD)
- , mMaskMode(NS_STYLE_MASK_MODE_MATCH_SOURCE)
- {
- mImage.SetNull();
- mSize.SetInitialValues();
- }
- nsStyleImageLayers::Layer::~Layer()
- {
- }
- void
- nsStyleImageLayers::Layer::Initialize(nsStyleImageLayers::LayerType aType)
- {
- mRepeat.SetInitialValues();
- mPosition.SetInitialPercentValues(0.0f);
- if (aType == LayerType::Background) {
- mOrigin = StyleGeometryBox::Padding;
- } else {
- MOZ_ASSERT(aType == LayerType::Mask, "unsupported layer type.");
- mOrigin = StyleGeometryBox::Border;
- }
- }
- bool
- nsStyleImageLayers::Layer::RenderingMightDependOnPositioningAreaSizeChange() const
- {
- // Do we even have an image?
- if (mImage.IsEmpty()) {
- return false;
- }
- return mPosition.DependsOnPositioningAreaSize() ||
- mSize.DependsOnPositioningAreaSize(mImage) ||
- mRepeat.DependsOnPositioningAreaSize();
- }
- bool
- nsStyleImageLayers::Layer::operator==(const Layer& aOther) const
- {
- return mAttachment == aOther.mAttachment &&
- mClip == aOther.mClip &&
- mOrigin == aOther.mOrigin &&
- mRepeat == aOther.mRepeat &&
- mBlendMode == aOther.mBlendMode &&
- mPosition == aOther.mPosition &&
- mSize == aOther.mSize &&
- mImage == aOther.mImage &&
- mMaskMode == aOther.mMaskMode &&
- mComposite == aOther.mComposite &&
- DefinitelyEqualURIs(mSourceURI, aOther.mSourceURI);
- }
- nsChangeHint
- nsStyleImageLayers::Layer::CalcDifference(const nsStyleImageLayers::Layer& aNewLayer) const
- {
- nsChangeHint hint = nsChangeHint(0);
- if (!DefinitelyEqualURIs(mSourceURI, aNewLayer.mSourceURI)) {
- hint |= nsChangeHint_RepaintFrame | nsChangeHint_UpdateEffects;
- // If Layer::mSourceURI links to a SVG mask, it has a fragment. Not vice
- // versa. Here are examples of URI contains a fragment, two of them link
- // to a SVG mask:
- // mask:url(a.svg#maskID); // The fragment of this URI is an ID of a mask
- // // element in a.svg.
- // mask:url(#localMaskID); // The fragment of this URI is an ID of a mask
- // // element in local document.
- // mask:url(b.svg#viewBoxID); // The fragment of this URI is an ID of a
- // // viewbox defined in b.svg.
- // That is, if mSourceURI has a fragment, it may link to a SVG mask; If
- // not, it "must" not link to a SVG mask.
- bool maybeSVGMask = false;
- if (mSourceURI) {
- if (mSourceURI->IsLocalRef()) {
- maybeSVGMask = true;
- } else if (mSourceURI->GetURI()) {
- mSourceURI->GetURI()->GetHasRef(&maybeSVGMask);
- }
- }
- if (!maybeSVGMask) {
- if (aNewLayer.mSourceURI) {
- if (aNewLayer.mSourceURI->IsLocalRef()) {
- maybeSVGMask = true;
- } else if (aNewLayer.mSourceURI->GetURI()) {
- aNewLayer.mSourceURI->GetURI()->GetHasRef(&maybeSVGMask);
- }
- }
- }
- // Return nsChangeHint_UpdateOverflow if either URI might link to an SVG
- // mask.
- if (maybeSVGMask) {
- // Mask changes require that we update the PreEffectsBBoxProperty,
- // which is done during overflow computation.
- hint |= nsChangeHint_UpdateOverflow;
- }
- } else if (mAttachment != aNewLayer.mAttachment ||
- mClip != aNewLayer.mClip ||
- mOrigin != aNewLayer.mOrigin ||
- mRepeat != aNewLayer.mRepeat ||
- mBlendMode != aNewLayer.mBlendMode ||
- mSize != aNewLayer.mSize ||
- mImage != aNewLayer.mImage ||
- mMaskMode != aNewLayer.mMaskMode ||
- mComposite != aNewLayer.mComposite) {
- hint |= nsChangeHint_RepaintFrame;
- }
- if (mPosition != aNewLayer.mPosition) {
- hint |= nsChangeHint_UpdateBackgroundPosition;
- }
- return hint;
- }
- // --------------------
- // nsStyleBackground
- //
- nsStyleBackground::nsStyleBackground(StyleStructContext aContext)
- : mImage(nsStyleImageLayers::LayerType::Background)
- , mBackgroundColor(NS_RGBA(0, 0, 0, 0))
- {
- MOZ_COUNT_CTOR(nsStyleBackground);
- }
- nsStyleBackground::nsStyleBackground(const nsStyleBackground& aSource)
- : mImage(aSource.mImage)
- , mBackgroundColor(aSource.mBackgroundColor)
- {
- MOZ_COUNT_CTOR(nsStyleBackground);
- }
- nsStyleBackground::~nsStyleBackground()
- {
- MOZ_COUNT_DTOR(nsStyleBackground);
- }
- void
- nsStyleBackground::Destroy(nsPresContext* aContext)
- {
- this->~nsStyleBackground();
- aContext->PresShell()->
- FreeByObjectID(eArenaObjectID_nsStyleBackground, this);
- }
- void
- nsStyleBackground::FinishStyle(nsPresContext* aPresContext)
- {
- MOZ_ASSERT(NS_IsMainThread());
- MOZ_ASSERT(aPresContext->StyleSet()->IsServo());
- mImage.ResolveImages(aPresContext);
- }
- nsChangeHint
- nsStyleBackground::CalcDifference(const nsStyleBackground& aNewData) const
- {
- nsChangeHint hint = nsChangeHint(0);
- if (mBackgroundColor != aNewData.mBackgroundColor) {
- hint |= nsChangeHint_RepaintFrame;
- }
- hint |= mImage.CalcDifference(aNewData.mImage,
- nsStyleImageLayers::LayerType::Background);
- return hint;
- }
- bool
- nsStyleBackground::HasFixedBackground(nsIFrame* aFrame) const
- {
- NS_FOR_VISIBLE_IMAGE_LAYERS_BACK_TO_FRONT(i, mImage) {
- const nsStyleImageLayers::Layer &layer = mImage.mLayers[i];
- if (layer.mAttachment == NS_STYLE_IMAGELAYER_ATTACHMENT_FIXED &&
- !layer.mImage.IsEmpty() &&
- !nsLayoutUtils::IsTransformed(aFrame)) {
- return true;
- }
- }
- return false;
- }
- bool
- nsStyleBackground::IsTransparent() const
- {
- return BottomLayer().mImage.IsEmpty() &&
- mImage.mImageCount == 1 &&
- NS_GET_A(mBackgroundColor) == 0;
- }
- void
- nsTimingFunction::AssignFromKeyword(int32_t aTimingFunctionType)
- {
- switch (aTimingFunctionType) {
- case NS_STYLE_TRANSITION_TIMING_FUNCTION_STEP_START:
- mType = Type::StepStart;
- mSteps = 1;
- return;
- default:
- MOZ_FALLTHROUGH_ASSERT("aTimingFunctionType must be a keyword value");
- case NS_STYLE_TRANSITION_TIMING_FUNCTION_STEP_END:
- mType = Type::StepEnd;
- mSteps = 1;
- return;
- case NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE:
- case NS_STYLE_TRANSITION_TIMING_FUNCTION_LINEAR:
- case NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE_IN:
- case NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE_OUT:
- case NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE_IN_OUT:
- mType = static_cast<Type>(aTimingFunctionType);
- break;
- }
- static_assert(NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE == 0 &&
- NS_STYLE_TRANSITION_TIMING_FUNCTION_LINEAR == 1 &&
- NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE_IN == 2 &&
- NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE_OUT == 3 &&
- NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE_IN_OUT == 4,
- "transition timing function constants not as expected");
- static const float timingFunctionValues[5][4] = {
- { 0.25f, 0.10f, 0.25f, 1.00f }, // ease
- { 0.00f, 0.00f, 1.00f, 1.00f }, // linear
- { 0.42f, 0.00f, 1.00f, 1.00f }, // ease-in
- { 0.00f, 0.00f, 0.58f, 1.00f }, // ease-out
- { 0.42f, 0.00f, 0.58f, 1.00f } // ease-in-out
- };
- MOZ_ASSERT(0 <= aTimingFunctionType && aTimingFunctionType < 5,
- "keyword out of range");
- mFunc.mX1 = timingFunctionValues[aTimingFunctionType][0];
- mFunc.mY1 = timingFunctionValues[aTimingFunctionType][1];
- mFunc.mX2 = timingFunctionValues[aTimingFunctionType][2];
- mFunc.mY2 = timingFunctionValues[aTimingFunctionType][3];
- }
- StyleTransition::StyleTransition(const StyleTransition& aCopy)
- : mTimingFunction(aCopy.mTimingFunction)
- , mDuration(aCopy.mDuration)
- , mDelay(aCopy.mDelay)
- , mProperty(aCopy.mProperty)
- , mUnknownProperty(aCopy.mUnknownProperty)
- {
- }
- void
- StyleTransition::SetInitialValues()
- {
- mTimingFunction = nsTimingFunction(NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE);
- mDuration = 0.0;
- mDelay = 0.0;
- mProperty = eCSSPropertyExtra_all_properties;
- }
- void
- StyleTransition::SetUnknownProperty(nsCSSPropertyID aProperty,
- const nsAString& aPropertyString)
- {
- MOZ_ASSERT(nsCSSProps::LookupProperty(aPropertyString,
- CSSEnabledState::eForAllContent) ==
- aProperty,
- "property and property string should match");
- MOZ_ASSERT(aProperty == eCSSProperty_UNKNOWN ||
- aProperty == eCSSPropertyExtra_variable,
- "should be either unknown or custom property");
- mProperty = aProperty;
- mUnknownProperty = NS_Atomize(aPropertyString);
- }
- bool
- StyleTransition::operator==(const StyleTransition& aOther) const
- {
- return mTimingFunction == aOther.mTimingFunction &&
- mDuration == aOther.mDuration &&
- mDelay == aOther.mDelay &&
- mProperty == aOther.mProperty &&
- (mProperty != eCSSProperty_UNKNOWN ||
- mUnknownProperty == aOther.mUnknownProperty);
- }
- StyleAnimation::StyleAnimation(const StyleAnimation& aCopy)
- : mTimingFunction(aCopy.mTimingFunction)
- , mDuration(aCopy.mDuration)
- , mDelay(aCopy.mDelay)
- , mName(aCopy.mName)
- , mDirection(aCopy.mDirection)
- , mFillMode(aCopy.mFillMode)
- , mPlayState(aCopy.mPlayState)
- , mIterationCount(aCopy.mIterationCount)
- {
- }
- void
- StyleAnimation::SetInitialValues()
- {
- mTimingFunction = nsTimingFunction(NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE);
- mDuration = 0.0;
- mDelay = 0.0;
- mName = EmptyString();
- mDirection = dom::PlaybackDirection::Normal;
- mFillMode = dom::FillMode::None;
- mPlayState = NS_STYLE_ANIMATION_PLAY_STATE_RUNNING;
- mIterationCount = 1.0f;
- }
- bool
- StyleAnimation::operator==(const StyleAnimation& aOther) const
- {
- return mTimingFunction == aOther.mTimingFunction &&
- mDuration == aOther.mDuration &&
- mDelay == aOther.mDelay &&
- mName == aOther.mName &&
- mDirection == aOther.mDirection &&
- mFillMode == aOther.mFillMode &&
- mPlayState == aOther.mPlayState &&
- mIterationCount == aOther.mIterationCount;
- }
- // --------------------
- // nsStyleDisplay
- //
- nsStyleDisplay::nsStyleDisplay(StyleStructContext aContext)
- : mDisplay(StyleDisplay::Inline)
- , mOriginalDisplay(StyleDisplay::Inline)
- , mContain(NS_STYLE_CONTAIN_NONE)
- , mAppearance(NS_THEME_NONE)
- , mPosition(NS_STYLE_POSITION_STATIC)
- , mFloat(StyleFloat::None)
- , mOriginalFloat(StyleFloat::None)
- , mBreakType(StyleClear::None)
- , mBreakInside(NS_STYLE_PAGE_BREAK_AUTO)
- , mBreakBefore(false)
- , mBreakAfter(false)
- , mOverflowX(NS_STYLE_OVERFLOW_VISIBLE)
- , mOverflowY(NS_STYLE_OVERFLOW_VISIBLE)
- , mOverflowClipBox(NS_STYLE_OVERFLOW_CLIP_BOX_PADDING_BOX)
- , mResize(NS_STYLE_RESIZE_NONE)
- , mOrient(StyleOrient::Inline)
- , mIsolation(NS_STYLE_ISOLATION_AUTO)
- , mTopLayer(NS_STYLE_TOP_LAYER_NONE)
- , mWillChangeBitField(0)
- , mTouchAction(NS_STYLE_TOUCH_ACTION_AUTO)
- , mScrollBehavior(NS_STYLE_SCROLL_BEHAVIOR_AUTO)
- , mScrollSnapTypeX(NS_STYLE_SCROLL_SNAP_TYPE_NONE)
- , mScrollSnapTypeY(NS_STYLE_SCROLL_SNAP_TYPE_NONE)
- , mScrollSnapPointsX(eStyleUnit_None)
- , mScrollSnapPointsY(eStyleUnit_None)
- , mBackfaceVisibility(NS_STYLE_BACKFACE_VISIBILITY_VISIBLE)
- , mTransformStyle(NS_STYLE_TRANSFORM_STYLE_FLAT)
- , mTransformBox(NS_STYLE_TRANSFORM_BOX_BORDER_BOX)
- , mSpecifiedTransform(nullptr)
- , mTransformOrigin{ {0.5f, eStyleUnit_Percent}, // Transform is centered on origin
- {0.5f, eStyleUnit_Percent},
- {0, nsStyleCoord::CoordConstructor} }
- , mChildPerspective(eStyleUnit_None)
- , mPerspectiveOrigin{ {0.5f, eStyleUnit_Percent},
- {0.5f, eStyleUnit_Percent} }
- , mVerticalAlign(NS_STYLE_VERTICAL_ALIGN_BASELINE, eStyleUnit_Enumerated)
- , mTransitions(nsStyleAutoArray<StyleTransition>::WITH_SINGLE_INITIAL_ELEMENT)
- , mTransitionTimingFunctionCount(1)
- , mTransitionDurationCount(1)
- , mTransitionDelayCount(1)
- , mTransitionPropertyCount(1)
- , mAnimations(nsStyleAutoArray<StyleAnimation>::WITH_SINGLE_INITIAL_ELEMENT)
- , mAnimationTimingFunctionCount(1)
- , mAnimationDurationCount(1)
- , mAnimationDelayCount(1)
- , mAnimationNameCount(1)
- , mAnimationDirectionCount(1)
- , mAnimationFillModeCount(1)
- , mAnimationPlayStateCount(1)
- , mAnimationIterationCountCount(1)
- {
- MOZ_COUNT_CTOR(nsStyleDisplay);
- // Initial value for mScrollSnapDestination is "0px 0px"
- mScrollSnapDestination.SetInitialZeroValues();
- mTransitions[0].SetInitialValues();
- mAnimations[0].SetInitialValues();
- }
- nsStyleDisplay::nsStyleDisplay(const nsStyleDisplay& aSource)
- : mBinding(aSource.mBinding)
- , mDisplay(aSource.mDisplay)
- , mOriginalDisplay(aSource.mOriginalDisplay)
- , mContain(aSource.mContain)
- , mAppearance(aSource.mAppearance)
- , mPosition(aSource.mPosition)
- , mFloat(aSource.mFloat)
- , mOriginalFloat(aSource.mOriginalFloat)
- , mBreakType(aSource.mBreakType)
- , mBreakInside(aSource.mBreakInside)
- , mBreakBefore(aSource.mBreakBefore)
- , mBreakAfter(aSource.mBreakAfter)
- , mOverflowX(aSource.mOverflowX)
- , mOverflowY(aSource.mOverflowY)
- , mOverflowClipBox(aSource.mOverflowClipBox)
- , mResize(aSource.mResize)
- , mOrient(aSource.mOrient)
- , mIsolation(aSource.mIsolation)
- , mTopLayer(aSource.mTopLayer)
- , mWillChangeBitField(aSource.mWillChangeBitField)
- , mWillChange(aSource.mWillChange)
- , mTouchAction(aSource.mTouchAction)
- , mScrollBehavior(aSource.mScrollBehavior)
- , mScrollSnapTypeX(aSource.mScrollSnapTypeX)
- , mScrollSnapTypeY(aSource.mScrollSnapTypeY)
- , mScrollSnapPointsX(aSource.mScrollSnapPointsX)
- , mScrollSnapPointsY(aSource.mScrollSnapPointsY)
- , mScrollSnapDestination(aSource.mScrollSnapDestination)
- , mScrollSnapCoordinate(aSource.mScrollSnapCoordinate)
- , mBackfaceVisibility(aSource.mBackfaceVisibility)
- , mTransformStyle(aSource.mTransformStyle)
- , mTransformBox(aSource.mTransformBox)
- , mSpecifiedTransform(aSource.mSpecifiedTransform)
- , mTransformOrigin{ aSource.mTransformOrigin[0],
- aSource.mTransformOrigin[1],
- aSource.mTransformOrigin[2] }
- , mChildPerspective(aSource.mChildPerspective)
- , mPerspectiveOrigin{ aSource.mPerspectiveOrigin[0],
- aSource.mPerspectiveOrigin[1] }
- , mVerticalAlign(aSource.mVerticalAlign)
- , mTransitions(aSource.mTransitions)
- , mTransitionTimingFunctionCount(aSource.mTransitionTimingFunctionCount)
- , mTransitionDurationCount(aSource.mTransitionDurationCount)
- , mTransitionDelayCount(aSource.mTransitionDelayCount)
- , mTransitionPropertyCount(aSource.mTransitionPropertyCount)
- , mAnimations(aSource.mAnimations)
- , mAnimationTimingFunctionCount(aSource.mAnimationTimingFunctionCount)
- , mAnimationDurationCount(aSource.mAnimationDurationCount)
- , mAnimationDelayCount(aSource.mAnimationDelayCount)
- , mAnimationNameCount(aSource.mAnimationNameCount)
- , mAnimationDirectionCount(aSource.mAnimationDirectionCount)
- , mAnimationFillModeCount(aSource.mAnimationFillModeCount)
- , mAnimationPlayStateCount(aSource.mAnimationPlayStateCount)
- , mAnimationIterationCountCount(aSource.mAnimationIterationCountCount)
- , mShapeOutside(aSource.mShapeOutside)
- {
- MOZ_COUNT_CTOR(nsStyleDisplay);
- }
- nsChangeHint
- nsStyleDisplay::CalcDifference(const nsStyleDisplay& aNewData) const
- {
- nsChangeHint hint = nsChangeHint(0);
- if (!DefinitelyEqualURIsAndPrincipal(mBinding, aNewData.mBinding)
- || mPosition != aNewData.mPosition
- || mDisplay != aNewData.mDisplay
- || mContain != aNewData.mContain
- || (mFloat == StyleFloat::None) != (aNewData.mFloat == StyleFloat::None)
- || mScrollBehavior != aNewData.mScrollBehavior
- || mScrollSnapTypeX != aNewData.mScrollSnapTypeX
- || mScrollSnapTypeY != aNewData.mScrollSnapTypeY
- || mScrollSnapPointsX != aNewData.mScrollSnapPointsX
- || mScrollSnapPointsY != aNewData.mScrollSnapPointsY
- || mScrollSnapDestination != aNewData.mScrollSnapDestination
- || mTopLayer != aNewData.mTopLayer
- || mResize != aNewData.mResize) {
- hint |= nsChangeHint_ReconstructFrame;
- }
- if (mOverflowX != aNewData.mOverflowX
- || mOverflowY != aNewData.mOverflowY) {
- hint |= nsChangeHint_ScrollbarChange;
- }
- /* Note: When mScrollBehavior, mScrollSnapTypeX, mScrollSnapTypeY,
- * mScrollSnapPointsX, mScrollSnapPointsY, or mScrollSnapDestination are
- * changed, nsChangeHint_NeutralChange is not sufficient to enter
- * nsCSSFrameConstructor::PropagateScrollToViewport. By using the same hint
- * as used when the overflow css property changes,
- * nsChangeHint_ReconstructFrame, PropagateScrollToViewport will be called.
- *
- * The scroll-behavior css property is not expected to change often (the
- * CSSOM-View DOM methods are likely to be used in those cases); however,
- * if this does become common perhaps a faster-path might be worth while.
- */
- if ((mAppearance == NS_THEME_TEXTFIELD &&
- aNewData.mAppearance != NS_THEME_TEXTFIELD) ||
- (mAppearance != NS_THEME_TEXTFIELD &&
- aNewData.mAppearance == NS_THEME_TEXTFIELD)) {
- // This is for <input type=number> where we allow authors to specify a
- // |-moz-appearance:textfield| to get a control without a spinner. (The
- // spinner is present for |-moz-appearance:number-input| but also other
- // values such as 'none'.) We need to reframe since we want to use
- // nsTextControlFrame instead of nsNumberControlFrame if the author
- // specifies 'textfield'.
- return nsChangeHint_ReconstructFrame;
- }
- if (mFloat != aNewData.mFloat) {
- // Changing which side we float on doesn't affect descendants directly
- hint |= nsChangeHint_AllReflowHints &
- ~(nsChangeHint_ClearDescendantIntrinsics |
- nsChangeHint_NeedDirtyReflow);
- }
- if (mVerticalAlign != aNewData.mVerticalAlign) {
- // XXX Can this just be AllReflowHints + RepaintFrame, and be included in
- // the block below?
- hint |= NS_STYLE_HINT_REFLOW;
- }
- // XXX the following is conservative, for now: changing float breaking shouldn't
- // necessarily require a repaint, reflow should suffice.
- if (mBreakType != aNewData.mBreakType
- || mBreakInside != aNewData.mBreakInside
- || mBreakBefore != aNewData.mBreakBefore
- || mBreakAfter != aNewData.mBreakAfter
- || mAppearance != aNewData.mAppearance
- || mOrient != aNewData.mOrient
- || mOverflowClipBox != aNewData.mOverflowClipBox) {
- hint |= nsChangeHint_AllReflowHints |
- nsChangeHint_RepaintFrame;
- }
- if (mIsolation != aNewData.mIsolation) {
- hint |= nsChangeHint_RepaintFrame;
- }
- /* If we've added or removed the transform property, we need to reconstruct the frame to add
- * or remove the view object, and also to handle abs-pos and fixed-pos containers.
- */
- if (HasTransformStyle() != aNewData.HasTransformStyle()) {
- // We do not need to apply nsChangeHint_UpdateTransformLayer since
- // nsChangeHint_RepaintFrame will forcibly invalidate the frame area and
- // ensure layers are rebuilt (or removed).
- hint |= nsChangeHint_UpdateContainingBlock |
- nsChangeHint_AddOrRemoveTransform |
- nsChangeHint_UpdateOverflow |
- nsChangeHint_RepaintFrame;
- } else {
- /* Otherwise, if we've kept the property lying around and we already had a
- * transform, we need to see whether or not we've changed the transform.
- * If so, we need to recompute its overflow rect (which probably changed
- * if the transform changed) and to redraw within the bounds of that new
- * overflow rect.
- *
- * If the property isn't present in either style struct, we still do the
- * comparisons but turn all the resulting change hints into
- * nsChangeHint_NeutralChange.
- */
- nsChangeHint transformHint = nsChangeHint(0);
- if (!mSpecifiedTransform != !aNewData.mSpecifiedTransform ||
- (mSpecifiedTransform &&
- *mSpecifiedTransform != *aNewData.mSpecifiedTransform)) {
- transformHint |= nsChangeHint_UpdateTransformLayer;
- if (mSpecifiedTransform &&
- aNewData.mSpecifiedTransform) {
- transformHint |= nsChangeHint_UpdatePostTransformOverflow;
- } else {
- transformHint |= nsChangeHint_UpdateOverflow;
- }
- }
- const nsChangeHint kUpdateOverflowAndRepaintHint =
- nsChangeHint_UpdateOverflow | nsChangeHint_RepaintFrame;
- for (uint8_t index = 0; index < 3; ++index) {
- if (mTransformOrigin[index] != aNewData.mTransformOrigin[index]) {
- transformHint |= nsChangeHint_UpdateTransformLayer |
- nsChangeHint_UpdatePostTransformOverflow;
- break;
- }
- }
- for (uint8_t index = 0; index < 2; ++index) {
- if (mPerspectiveOrigin[index] != aNewData.mPerspectiveOrigin[index]) {
- transformHint |= kUpdateOverflowAndRepaintHint;
- break;
- }
- }
- if (HasPerspectiveStyle() != aNewData.HasPerspectiveStyle()) {
- // A change from/to being a containing block for position:fixed.
- hint |= nsChangeHint_UpdateContainingBlock;
- }
- if (mChildPerspective != aNewData.mChildPerspective ||
- mTransformStyle != aNewData.mTransformStyle ||
- mTransformBox != aNewData.mTransformBox) {
- transformHint |= kUpdateOverflowAndRepaintHint;
- }
- if (mBackfaceVisibility != aNewData.mBackfaceVisibility) {
- transformHint |= nsChangeHint_RepaintFrame;
- }
- if (transformHint) {
- if (HasTransformStyle()) {
- hint |= transformHint;
- } else {
- hint |= nsChangeHint_NeutralChange;
- }
- }
- }
- // Note that the HasTransformStyle() != aNewData.HasTransformStyle()
- // test above handles relevant changes in the
- // NS_STYLE_WILL_CHANGE_TRANSFORM bit, which in turn handles frame
- // reconstruction for changes in the containing block of
- // fixed-positioned elements.
- uint8_t willChangeBitsChanged =
- mWillChangeBitField ^ aNewData.mWillChangeBitField;
- if (willChangeBitsChanged & (NS_STYLE_WILL_CHANGE_STACKING_CONTEXT |
- NS_STYLE_WILL_CHANGE_SCROLL |
- NS_STYLE_WILL_CHANGE_OPACITY)) {
- hint |= nsChangeHint_RepaintFrame;
- }
- if (willChangeBitsChanged & NS_STYLE_WILL_CHANGE_FIXPOS_CB) {
- hint |= nsChangeHint_UpdateContainingBlock;
- }
- // If touch-action is changed, we need to regenerate the event regions on
- // the layers and send it over to the compositor for APZ to handle.
- if (mTouchAction != aNewData.mTouchAction) {
- hint |= nsChangeHint_RepaintFrame;
- }
- // Note: Our current behavior for handling changes to the
- // transition-duration, transition-delay, and transition-timing-function
- // properties is to do nothing. In other words, the transition
- // property that matters is what it is when the transition begins, and
- // we don't stop a transition later because the transition property
- // changed.
- // We do handle changes to transition-property, but we don't need to
- // bother with anything here, since the transition manager is notified
- // of any style context change anyway.
- // Note: Likewise, for animation-*, the animation manager gets
- // notified about every new style context constructed, and it uses
- // that opportunity to handle dynamic changes appropriately.
- // But we still need to return nsChangeHint_NeutralChange for these
- // properties, since some data did change in the style struct.
- if (!hint &&
- (mOriginalDisplay != aNewData.mOriginalDisplay ||
- mOriginalFloat != aNewData.mOriginalFloat ||
- mTransitions != aNewData.mTransitions ||
- mTransitionTimingFunctionCount !=
- aNewData.mTransitionTimingFunctionCount ||
- mTransitionDurationCount != aNewData.mTransitionDurationCount ||
- mTransitionDelayCount != aNewData.mTransitionDelayCount ||
- mTransitionPropertyCount != aNewData.mTransitionPropertyCount ||
- mAnimations != aNewData.mAnimations ||
- mAnimationTimingFunctionCount != aNewData.mAnimationTimingFunctionCount ||
- mAnimationDurationCount != aNewData.mAnimationDurationCount ||
- mAnimationDelayCount != aNewData.mAnimationDelayCount ||
- mAnimationNameCount != aNewData.mAnimationNameCount ||
- mAnimationDirectionCount != aNewData.mAnimationDirectionCount ||
- mAnimationFillModeCount != aNewData.mAnimationFillModeCount ||
- mAnimationPlayStateCount != aNewData.mAnimationPlayStateCount ||
- mAnimationIterationCountCount != aNewData.mAnimationIterationCountCount ||
- mScrollSnapCoordinate != aNewData.mScrollSnapCoordinate ||
- mShapeOutside != aNewData.mShapeOutside)) {
- hint |= nsChangeHint_NeutralChange;
- }
- return hint;
- }
- // --------------------
- // nsStyleVisibility
- //
- nsStyleVisibility::nsStyleVisibility(StyleStructContext aContext)
- : mDirection(aContext.GetBidi() == IBMBIDI_TEXTDIRECTION_RTL
- ? NS_STYLE_DIRECTION_RTL
- : NS_STYLE_DIRECTION_LTR)
- , mVisible(NS_STYLE_VISIBILITY_VISIBLE)
- , mImageRendering(NS_STYLE_IMAGE_RENDERING_AUTO)
- , mWritingMode(NS_STYLE_WRITING_MODE_HORIZONTAL_TB)
- , mTextOrientation(NS_STYLE_TEXT_ORIENTATION_MIXED)
- , mColorAdjust(NS_STYLE_COLOR_ADJUST_ECONOMY)
- {
- MOZ_COUNT_CTOR(nsStyleVisibility);
- }
- nsStyleVisibility::nsStyleVisibility(const nsStyleVisibility& aSource)
- : mImageOrientation(aSource.mImageOrientation)
- , mDirection(aSource.mDirection)
- , mVisible(aSource.mVisible)
- , mImageRendering(aSource.mImageRendering)
- , mWritingMode(aSource.mWritingMode)
- , mTextOrientation(aSource.mTextOrientation)
- , mColorAdjust(aSource.mColorAdjust)
- {
- MOZ_COUNT_CTOR(nsStyleVisibility);
- }
- nsChangeHint
- nsStyleVisibility::CalcDifference(const nsStyleVisibility& aNewData) const
- {
- nsChangeHint hint = nsChangeHint(0);
- if (mDirection != aNewData.mDirection || mWritingMode != aNewData.mWritingMode) {
- // It's important that a change in mWritingMode results in frame
- // reconstruction, because it may affect intrinsic size (see
- // nsSubDocumentFrame::GetIntrinsicISize/BSize).
- hint |= nsChangeHint_ReconstructFrame;
- } else {
- if ((mImageOrientation != aNewData.mImageOrientation)) {
- hint |= nsChangeHint_AllReflowHints |
- nsChangeHint_RepaintFrame;
- }
- if (mVisible != aNewData.mVisible) {
- if ((NS_STYLE_VISIBILITY_COLLAPSE == mVisible) ||
- (NS_STYLE_VISIBILITY_COLLAPSE == aNewData.mVisible)) {
- hint |= NS_STYLE_HINT_REFLOW;
- } else {
- hint |= NS_STYLE_HINT_VISUAL;
- }
- }
- if (mTextOrientation != aNewData.mTextOrientation) {
- hint |= NS_STYLE_HINT_REFLOW;
- }
- if (mImageRendering != aNewData.mImageRendering) {
- hint |= nsChangeHint_RepaintFrame;
- }
- if (mColorAdjust != aNewData.mColorAdjust) {
- // color-adjust only affects media where dynamic changes can't happen.
- hint |= nsChangeHint_NeutralChange;
- }
- }
- return hint;
- }
- nsStyleContentData::~nsStyleContentData()
- {
- MOZ_COUNT_DTOR(nsStyleContentData);
- MOZ_ASSERT(!mImageTracked,
- "nsStyleContentData being destroyed while still tracking image!");
- if (mType == eStyleContentType_Image) {
- NS_IF_RELEASE(mContent.mImage);
- } else if (mType == eStyleContentType_Counter ||
- mType == eStyleContentType_Counters) {
- mContent.mCounters->Release();
- } else if (mContent.mString) {
- free(mContent.mString);
- }
- }
- nsStyleContentData::nsStyleContentData(const nsStyleContentData& aOther)
- : mType(aOther.mType)
- #ifdef DEBUG
- , mImageTracked(false)
- #endif
- {
- MOZ_COUNT_CTOR(nsStyleContentData);
- if (mType == eStyleContentType_Image) {
- mContent.mImage = aOther.mContent.mImage;
- NS_IF_ADDREF(mContent.mImage);
- } else if (mType == eStyleContentType_Counter ||
- mType == eStyleContentType_Counters) {
- mContent.mCounters = aOther.mContent.mCounters;
- mContent.mCounters->AddRef();
- } else if (aOther.mContent.mString) {
- mContent.mString = NS_strdup(aOther.mContent.mString);
- } else {
- mContent.mString = nullptr;
- }
- }
- nsStyleContentData&
- nsStyleContentData::operator=(const nsStyleContentData& aOther)
- {
- if (this == &aOther) {
- return *this;
- }
- this->~nsStyleContentData();
- new (this) nsStyleContentData(aOther);
- return *this;
- }
- bool
- nsStyleContentData::operator==(const nsStyleContentData& aOther) const
- {
- if (mType != aOther.mType) {
- return false;
- }
- if (mType == eStyleContentType_Image) {
- if (!mContent.mImage || !aOther.mContent.mImage) {
- return mContent.mImage == aOther.mContent.mImage;
- }
- bool eq;
- nsCOMPtr<nsIURI> thisURI, otherURI;
- mContent.mImage->GetURI(getter_AddRefs(thisURI));
- aOther.mContent.mImage->GetURI(getter_AddRefs(otherURI));
- return thisURI == otherURI || // handles null==null
- (thisURI && otherURI &&
- NS_SUCCEEDED(thisURI->Equals(otherURI, &eq)) &&
- eq);
- }
- if (mType == eStyleContentType_Counter ||
- mType == eStyleContentType_Counters) {
- return *mContent.mCounters == *aOther.mContent.mCounters;
- }
- return safe_strcmp(mContent.mString, aOther.mContent.mString) == 0;
- }
- void
- nsStyleContentData::TrackImage(ImageTracker* aImageTracker)
- {
- // Sanity
- MOZ_ASSERT(!mImageTracked, "Already tracking image!");
- MOZ_ASSERT(mType == eStyleContentType_Image,
- "Trying to do image tracking on non-image!");
- MOZ_ASSERT(mContent.mImage,
- "Can't track image when there isn't one!");
- aImageTracker->Add(mContent.mImage);
- // Mark state
- #ifdef DEBUG
- mImageTracked = true;
- #endif
- }
- void
- nsStyleContentData::UntrackImage(ImageTracker* aImageTracker)
- {
- // Sanity
- MOZ_ASSERT(mImageTracked, "Image not tracked!");
- MOZ_ASSERT(mType == eStyleContentType_Image,
- "Trying to do image tracking on non-image!");
- MOZ_ASSERT(mContent.mImage,
- "Can't untrack image when there isn't one!");
- aImageTracker->Remove(mContent.mImage);
- // Mark state
- #ifdef DEBUG
- mImageTracked = false;
- #endif
- }
- //-----------------------
- // nsStyleContent
- //
- nsStyleContent::nsStyleContent(StyleStructContext aContext)
- {
- MOZ_COUNT_CTOR(nsStyleContent);
- }
- nsStyleContent::~nsStyleContent()
- {
- MOZ_COUNT_DTOR(nsStyleContent);
- }
- void
- nsStyleContent::Destroy(nsPresContext* aContext)
- {
- // Unregister any images we might have with the document.
- for (auto& content : mContents) {
- if (content.mType == eStyleContentType_Image && content.mContent.mImage) {
- content.UntrackImage(aContext->Document()->ImageTracker());
- }
- }
- this->~nsStyleContent();
- aContext->PresShell()->FreeByObjectID(eArenaObjectID_nsStyleContent, this);
- }
- nsStyleContent::nsStyleContent(const nsStyleContent& aSource)
- : mContents(aSource.mContents)
- , mIncrements(aSource.mIncrements)
- , mResets(aSource.mResets)
- {
- MOZ_COUNT_CTOR(nsStyleContent);
- }
- nsChangeHint
- nsStyleContent::CalcDifference(const nsStyleContent& aNewData) const
- {
- // In ElementRestyler::Restyle we assume that if there's no existing
- // ::before or ::after and we don't have to restyle children of the
- // node then we can't end up with a ::before or ::after due to the
- // restyle of the node itself. That's not quite true, but the only
- // exception to the above is when the 'content' property of the node
- // changes and the pseudo-element inherits the changed value. Since
- // the code here triggers a frame change on the node in that case,
- // the optimization in ElementRestyler::Restyle is ok. But if we ever
- // change this code to not reconstruct frames on changes to the
- // 'content' property, then we will need to revisit the optimization
- // in ElementRestyler::Restyle.
- // Unfortunately we need to reframe even if the content lengths are the same;
- // a simple reflow will not pick up different text or different image URLs,
- // since we set all that up in the CSSFrameConstructor
- if (mContents != aNewData.mContents ||
- mIncrements != aNewData.mIncrements ||
- mResets != aNewData.mResets) {
- return nsChangeHint_ReconstructFrame;
- }
- return nsChangeHint(0);
- }
- // --------------------
- // nsStyleTextReset
- //
- nsStyleTextReset::nsStyleTextReset(StyleStructContext aContext)
- : mTextDecorationLine(NS_STYLE_TEXT_DECORATION_LINE_NONE)
- , mTextDecorationStyle(NS_STYLE_TEXT_DECORATION_STYLE_SOLID)
- , mUnicodeBidi(NS_STYLE_UNICODE_BIDI_NORMAL)
- , mInitialLetterSink(0)
- , mInitialLetterSize(0.0f)
- , mTextDecorationColor(StyleComplexColor::CurrentColor())
- {
- MOZ_COUNT_CTOR(nsStyleTextReset);
- }
- nsStyleTextReset::nsStyleTextReset(const nsStyleTextReset& aSource)
- {
- MOZ_COUNT_CTOR(nsStyleTextReset);
- *this = aSource;
- }
- nsStyleTextReset::~nsStyleTextReset()
- {
- MOZ_COUNT_DTOR(nsStyleTextReset);
- }
- nsChangeHint
- nsStyleTextReset::CalcDifference(const nsStyleTextReset& aNewData) const
- {
- if (mUnicodeBidi != aNewData.mUnicodeBidi ||
- mInitialLetterSink != aNewData.mInitialLetterSink ||
- mInitialLetterSize != aNewData.mInitialLetterSize) {
- return NS_STYLE_HINT_REFLOW;
- }
- if (mTextDecorationLine != aNewData.mTextDecorationLine ||
- mTextDecorationStyle != aNewData.mTextDecorationStyle) {
- // Changes to our text-decoration line can impact our overflow area &
- // also our descendants' overflow areas (particularly for text-frame
- // descendants). So, we update those areas & trigger a repaint.
- return nsChangeHint_RepaintFrame |
- nsChangeHint_UpdateSubtreeOverflow |
- nsChangeHint_SchedulePaint;
- }
- // Repaint for decoration color changes
- if (mTextDecorationColor != aNewData.mTextDecorationColor) {
- return nsChangeHint_RepaintFrame;
- }
- if (mTextOverflow != aNewData.mTextOverflow) {
- return nsChangeHint_RepaintFrame;
- }
- return nsChangeHint(0);
- }
- // Returns true if the given shadow-arrays are equal.
- static bool
- AreShadowArraysEqual(nsCSSShadowArray* lhs,
- nsCSSShadowArray* rhs)
- {
- if (lhs == rhs) {
- return true;
- }
- if (!lhs || !rhs || lhs->Length() != rhs->Length()) {
- return false;
- }
- for (uint32_t i = 0; i < lhs->Length(); ++i) {
- if (*lhs->ShadowAt(i) != *rhs->ShadowAt(i)) {
- return false;
- }
- }
- return true;
- }
- // --------------------
- // nsStyleText
- //
- nsStyleText::nsStyleText(StyleStructContext aContext)
- : mTextAlign(NS_STYLE_TEXT_ALIGN_START)
- , mTextAlignLast(NS_STYLE_TEXT_ALIGN_AUTO)
- , mTextAlignTrue(false)
- , mTextAlignLastTrue(false)
- , mTextJustify(StyleTextJustify::Auto)
- , mTextTransform(NS_STYLE_TEXT_TRANSFORM_NONE)
- , mWhiteSpace(NS_STYLE_WHITESPACE_NORMAL)
- , mWordBreak(NS_STYLE_WORDBREAK_NORMAL)
- , mOverflowWrap(NS_STYLE_OVERFLOWWRAP_NORMAL)
- , mHyphens(NS_STYLE_HYPHENS_MANUAL)
- , mRubyAlign(NS_STYLE_RUBY_ALIGN_SPACE_AROUND)
- , mRubyPosition(NS_STYLE_RUBY_POSITION_OVER)
- , mTextSizeAdjust(NS_STYLE_TEXT_SIZE_ADJUST_AUTO)
- , mTextCombineUpright(NS_STYLE_TEXT_COMBINE_UPRIGHT_NONE)
- , mControlCharacterVisibility(nsCSSParser::ControlCharVisibilityDefault())
- , mTextEmphasisStyle(NS_STYLE_TEXT_EMPHASIS_STYLE_NONE)
- , mTextRendering(NS_STYLE_TEXT_RENDERING_AUTO)
- , mTextEmphasisColor(StyleComplexColor::CurrentColor())
- , mWebkitTextFillColor(StyleComplexColor::CurrentColor())
- , mWebkitTextStrokeColor(StyleComplexColor::CurrentColor())
- , mTabSize(float(NS_STYLE_TABSIZE_INITIAL), eStyleUnit_Factor)
- , mWordSpacing(0, nsStyleCoord::CoordConstructor)
- , mLetterSpacing(eStyleUnit_Normal)
- , mLineHeight(eStyleUnit_Normal)
- , mTextIndent(0, nsStyleCoord::CoordConstructor)
- , mWebkitTextStrokeWidth(0, nsStyleCoord::CoordConstructor)
- , mTextShadow(nullptr)
- {
- MOZ_COUNT_CTOR(nsStyleText);
- nsCOMPtr<nsIAtom> language = aContext.GetContentLanguage();
- mTextEmphasisPosition = language &&
- nsStyleUtil::MatchesLanguagePrefix(language, u"zh") ?
- NS_STYLE_TEXT_EMPHASIS_POSITION_DEFAULT_ZH :
- NS_STYLE_TEXT_EMPHASIS_POSITION_DEFAULT;
- }
- nsStyleText::nsStyleText(const nsStyleText& aSource)
- : mTextAlign(aSource.mTextAlign)
- , mTextAlignLast(aSource.mTextAlignLast)
- , mTextAlignTrue(false)
- , mTextAlignLastTrue(false)
- , mTextJustify(aSource.mTextJustify)
- , mTextTransform(aSource.mTextTransform)
- , mWhiteSpace(aSource.mWhiteSpace)
- , mWordBreak(aSource.mWordBreak)
- , mOverflowWrap(aSource.mOverflowWrap)
- , mHyphens(aSource.mHyphens)
- , mRubyAlign(aSource.mRubyAlign)
- , mRubyPosition(aSource.mRubyPosition)
- , mTextSizeAdjust(aSource.mTextSizeAdjust)
- , mTextCombineUpright(aSource.mTextCombineUpright)
- , mControlCharacterVisibility(aSource.mControlCharacterVisibility)
- , mTextEmphasisPosition(aSource.mTextEmphasisPosition)
- , mTextEmphasisStyle(aSource.mTextEmphasisStyle)
- , mTextRendering(aSource.mTextRendering)
- , mTextEmphasisColor(aSource.mTextEmphasisColor)
- , mWebkitTextFillColor(aSource.mWebkitTextFillColor)
- , mWebkitTextStrokeColor(aSource.mWebkitTextStrokeColor)
- , mTabSize(aSource.mTabSize)
- , mWordSpacing(aSource.mWordSpacing)
- , mLetterSpacing(aSource.mLetterSpacing)
- , mLineHeight(aSource.mLineHeight)
- , mTextIndent(aSource.mTextIndent)
- , mWebkitTextStrokeWidth(aSource.mWebkitTextStrokeWidth)
- , mTextShadow(aSource.mTextShadow)
- , mTextEmphasisStyleString(aSource.mTextEmphasisStyleString)
- {
- MOZ_COUNT_CTOR(nsStyleText);
- }
- nsStyleText::~nsStyleText()
- {
- MOZ_COUNT_DTOR(nsStyleText);
- }
- nsChangeHint
- nsStyleText::CalcDifference(const nsStyleText& aNewData) const
- {
- if (WhiteSpaceOrNewlineIsSignificant() !=
- aNewData.WhiteSpaceOrNewlineIsSignificant()) {
- // This may require construction of suppressed text frames
- return nsChangeHint_ReconstructFrame;
- }
- if (mTextCombineUpright != aNewData.mTextCombineUpright ||
- mControlCharacterVisibility != aNewData.mControlCharacterVisibility) {
- return nsChangeHint_ReconstructFrame;
- }
- if ((mTextAlign != aNewData.mTextAlign) ||
- (mTextAlignLast != aNewData.mTextAlignLast) ||
- (mTextAlignTrue != aNewData.mTextAlignTrue) ||
- (mTextAlignLastTrue != aNewData.mTextAlignLastTrue) ||
- (mTextTransform != aNewData.mTextTransform) ||
- (mWhiteSpace != aNewData.mWhiteSpace) ||
- (mWordBreak != aNewData.mWordBreak) ||
- (mOverflowWrap != aNewData.mOverflowWrap) ||
- (mHyphens != aNewData.mHyphens) ||
- (mRubyAlign != aNewData.mRubyAlign) ||
- (mRubyPosition != aNewData.mRubyPosition) ||
- (mTextSizeAdjust != aNewData.mTextSizeAdjust) ||
- (mLetterSpacing != aNewData.mLetterSpacing) ||
- (mLineHeight != aNewData.mLineHeight) ||
- (mTextJustify != aNewData.mTextJustify) ||
- (mTextIndent != aNewData.mTextIndent) ||
- (mWordSpacing != aNewData.mWordSpacing) ||
- (mTabSize != aNewData.mTabSize)) {
- return NS_STYLE_HINT_REFLOW;
- }
- if (HasTextEmphasis() != aNewData.HasTextEmphasis() ||
- (HasTextEmphasis() &&
- mTextEmphasisPosition != aNewData.mTextEmphasisPosition)) {
- // Text emphasis position change could affect line height calculation.
- return nsChangeHint_AllReflowHints |
- nsChangeHint_RepaintFrame;
- }
- nsChangeHint hint = nsChangeHint(0);
- // text-rendering changes require a reflow since they change SVG
- // frames' rects.
- if (mTextRendering != aNewData.mTextRendering) {
- hint |= nsChangeHint_NeedReflow |
- nsChangeHint_NeedDirtyReflow | // XXX remove me: bug 876085
- nsChangeHint_RepaintFrame;
- }
- if (!AreShadowArraysEqual(mTextShadow, aNewData.mTextShadow) ||
- mTextEmphasisStyle != aNewData.mTextEmphasisStyle ||
- mTextEmphasisStyleString != aNewData.mTextEmphasisStyleString ||
- mWebkitTextStrokeWidth != aNewData.mWebkitTextStrokeWidth) {
- hint |= nsChangeHint_UpdateSubtreeOverflow |
- nsChangeHint_SchedulePaint |
- nsChangeHint_RepaintFrame;
- // We don't add any other hints below.
- return hint;
- }
- if (mTextEmphasisColor != aNewData.mTextEmphasisColor ||
- mWebkitTextFillColor != aNewData.mWebkitTextFillColor ||
- mWebkitTextStrokeColor != aNewData.mWebkitTextStrokeColor) {
- hint |= nsChangeHint_SchedulePaint |
- nsChangeHint_RepaintFrame;
- }
- if (hint) {
- return hint;
- }
- if (mTextEmphasisPosition != aNewData.mTextEmphasisPosition) {
- return nsChangeHint_NeutralChange;
- }
- return nsChangeHint(0);
- }
- LogicalSide
- nsStyleText::TextEmphasisSide(WritingMode aWM) const
- {
- MOZ_ASSERT(
- (!(mTextEmphasisPosition & NS_STYLE_TEXT_EMPHASIS_POSITION_LEFT) !=
- !(mTextEmphasisPosition & NS_STYLE_TEXT_EMPHASIS_POSITION_RIGHT)) &&
- (!(mTextEmphasisPosition & NS_STYLE_TEXT_EMPHASIS_POSITION_OVER) !=
- !(mTextEmphasisPosition & NS_STYLE_TEXT_EMPHASIS_POSITION_UNDER)));
- mozilla::Side side = aWM.IsVertical() ?
- (mTextEmphasisPosition & NS_STYLE_TEXT_EMPHASIS_POSITION_LEFT
- ? eSideLeft : eSideRight) :
- (mTextEmphasisPosition & NS_STYLE_TEXT_EMPHASIS_POSITION_OVER
- ? eSideTop : eSideBottom);
- LogicalSide result = aWM.LogicalSideForPhysicalSide(side);
- MOZ_ASSERT(IsBlock(result));
- return result;
- }
- //-----------------------
- // nsStyleUserInterface
- //
- nsCursorImage::nsCursorImage()
- : mHaveHotspot(false)
- , mHotspotX(0.0f)
- , mHotspotY(0.0f)
- {
- }
- nsCursorImage::nsCursorImage(const nsCursorImage& aOther)
- : mHaveHotspot(aOther.mHaveHotspot)
- , mHotspotX(aOther.mHotspotX)
- , mHotspotY(aOther.mHotspotY)
- {
- SetImage(aOther.GetImage());
- }
- nsCursorImage::~nsCursorImage()
- {
- SetImage(nullptr);
- }
- nsCursorImage&
- nsCursorImage::operator=(const nsCursorImage& aOther)
- {
- if (this != &aOther) {
- mHaveHotspot = aOther.mHaveHotspot;
- mHotspotX = aOther.mHotspotX;
- mHotspotY = aOther.mHotspotY;
- SetImage(aOther.GetImage());
- }
- return *this;
- }
- bool
- nsCursorImage::operator==(const nsCursorImage& aOther) const
- {
- NS_ASSERTION(mHaveHotspot ||
- (mHotspotX == 0 && mHotspotY == 0),
- "expected mHotspot{X,Y} to be 0 when mHaveHotspot is false");
- NS_ASSERTION(aOther.mHaveHotspot ||
- (aOther.mHotspotX == 0 && aOther.mHotspotY == 0),
- "expected mHotspot{X,Y} to be 0 when mHaveHotspot is false");
- return mHaveHotspot == aOther.mHaveHotspot &&
- mHotspotX == aOther.mHotspotX &&
- mHotspotY == aOther.mHotspotY &&
- EqualImages(mImage, aOther.mImage);
- }
- nsStyleUserInterface::nsStyleUserInterface(StyleStructContext aContext)
- : mUserInput(StyleUserInput::Auto)
- , mUserModify(StyleUserModify::ReadOnly)
- , mUserFocus(StyleUserFocus::None)
- , mPointerEvents(NS_STYLE_POINTER_EVENTS_AUTO)
- , mCursor(NS_STYLE_CURSOR_AUTO)
- , mCaretColor(StyleComplexColor::Auto())
- , mScrollbarWidth(StyleScrollbarWidth::Auto)
- {
- MOZ_COUNT_CTOR(nsStyleUserInterface);
- }
- nsStyleUserInterface::nsStyleUserInterface(const nsStyleUserInterface& aSource)
- : mUserInput(aSource.mUserInput)
- , mUserModify(aSource.mUserModify)
- , mUserFocus(aSource.mUserFocus)
- , mPointerEvents(aSource.mPointerEvents)
- , mCursor(aSource.mCursor)
- , mCursorImages(aSource.mCursorImages)
- , mCaretColor(aSource.mCaretColor)
- , mScrollbarWidth(aSource.mScrollbarWidth)
- {
- MOZ_COUNT_CTOR(nsStyleUserInterface);
- }
- nsStyleUserInterface::~nsStyleUserInterface()
- {
- MOZ_COUNT_DTOR(nsStyleUserInterface);
- }
- nsChangeHint
- nsStyleUserInterface::CalcDifference(const nsStyleUserInterface& aNewData) const
- {
- nsChangeHint hint = nsChangeHint(0);
- if (mCursor != aNewData.mCursor) {
- hint |= nsChangeHint_UpdateCursor;
- }
- // We could do better. But it wouldn't be worth it, URL-specified cursors are
- // rare.
- if (mCursorImages != aNewData.mCursorImages) {
- hint |= nsChangeHint_UpdateCursor;
- }
- if (mPointerEvents != aNewData.mPointerEvents) {
- // nsSVGPathGeometryFrame's mRect depends on stroke _and_ on the value
- // of pointer-events. See nsSVGPathGeometryFrame::ReflowSVG's use of
- // GetHitTestFlags. (Only a reflow, no visual change.)
- hint |= nsChangeHint_NeedReflow |
- nsChangeHint_NeedDirtyReflow; // XXX remove me: bug 876085
- }
- if (mUserModify != aNewData.mUserModify) {
- hint |= NS_STYLE_HINT_VISUAL;
- }
- if (mUserInput != aNewData.mUserInput) {
- if (StyleUserInput::None == mUserInput ||
- StyleUserInput::None == aNewData.mUserInput) {
- hint |= nsChangeHint_ReconstructFrame;
- } else {
- hint |= nsChangeHint_NeutralChange;
- }
- }
- if (mUserFocus != aNewData.mUserFocus) {
- hint |= nsChangeHint_NeutralChange;
- }
- if (mCaretColor != aNewData.mCaretColor) {
- hint |= nsChangeHint_RepaintFrame;
- }
-
- if (mScrollbarWidth != aNewData.mScrollbarWidth) {
- // For scrollbar-width change, we need some special handling similar
- // to overflow properties. Specifically, we may need to reconstruct
- // the scrollbar or force reflow of the viewport scrollbar.
- hint |= nsChangeHint_ScrollbarChange;
- }
- return hint;
- }
- //-----------------------
- // nsStyleUIReset
- //
- nsStyleUIReset::nsStyleUIReset(StyleStructContext aContext)
- : mUserSelect(StyleUserSelect::Auto)
- , mForceBrokenImageIcon(0)
- , mIMEMode(NS_STYLE_IME_MODE_AUTO)
- , mWindowDragging(StyleWindowDragging::Default)
- , mWindowShadow(NS_STYLE_WINDOW_SHADOW_DEFAULT)
- {
- MOZ_COUNT_CTOR(nsStyleUIReset);
- }
- nsStyleUIReset::nsStyleUIReset(const nsStyleUIReset& aSource)
- : mUserSelect(aSource.mUserSelect)
- , mForceBrokenImageIcon(aSource.mForceBrokenImageIcon)
- , mIMEMode(aSource.mIMEMode)
- , mWindowDragging(aSource.mWindowDragging)
- , mWindowShadow(aSource.mWindowShadow)
- {
- MOZ_COUNT_CTOR(nsStyleUIReset);
- }
- nsStyleUIReset::~nsStyleUIReset()
- {
- MOZ_COUNT_DTOR(nsStyleUIReset);
- }
- nsChangeHint
- nsStyleUIReset::CalcDifference(const nsStyleUIReset& aNewData) const
- {
- // ignore mIMEMode
- if (mForceBrokenImageIcon != aNewData.mForceBrokenImageIcon) {
- return nsChangeHint_ReconstructFrame;
- }
- if (mWindowShadow != aNewData.mWindowShadow) {
- // We really need just an nsChangeHint_SyncFrameView, except
- // on an ancestor of the frame, so we get that by doing a
- // reflow.
- return NS_STYLE_HINT_REFLOW;
- }
- if (mUserSelect != aNewData.mUserSelect) {
- return NS_STYLE_HINT_VISUAL;
- }
- if (mWindowDragging != aNewData.mWindowDragging) {
- return nsChangeHint_SchedulePaint;
- }
- return nsChangeHint(0);
- }
- //-----------------------
- // nsStyleVariables
- //
- nsStyleVariables::nsStyleVariables(StyleStructContext aContext)
- {
- MOZ_COUNT_CTOR(nsStyleVariables);
- }
- nsStyleVariables::nsStyleVariables(const nsStyleVariables& aSource)
- : mVariables(aSource.mVariables)
- {
- MOZ_COUNT_CTOR(nsStyleVariables);
- }
- nsStyleVariables::~nsStyleVariables()
- {
- MOZ_COUNT_DTOR(nsStyleVariables);
- }
- nsChangeHint
- nsStyleVariables::CalcDifference(const nsStyleVariables& aNewData) const
- {
- return nsChangeHint(0);
- }
- //-----------------------
- // nsStyleEffects
- //
- nsStyleEffects::nsStyleEffects(StyleStructContext aContext)
- : mBoxShadow(nullptr)
- , mClip(0, 0, 0, 0)
- , mOpacity(1.0f)
- , mClipFlags(NS_STYLE_CLIP_AUTO)
- , mMixBlendMode(NS_STYLE_BLEND_NORMAL)
- {
- MOZ_COUNT_CTOR(nsStyleEffects);
- }
- nsStyleEffects::nsStyleEffects(const nsStyleEffects& aSource)
- : mFilters(aSource.mFilters)
- , mBoxShadow(aSource.mBoxShadow)
- , mClip(aSource.mClip)
- , mOpacity(aSource.mOpacity)
- , mClipFlags(aSource.mClipFlags)
- , mMixBlendMode(aSource.mMixBlendMode)
- {
- MOZ_COUNT_CTOR(nsStyleEffects);
- }
- nsStyleEffects::~nsStyleEffects()
- {
- MOZ_COUNT_DTOR(nsStyleEffects);
- }
- nsChangeHint
- nsStyleEffects::CalcDifference(const nsStyleEffects& aNewData) const
- {
- nsChangeHint hint = nsChangeHint(0);
- if (!AreShadowArraysEqual(mBoxShadow, aNewData.mBoxShadow)) {
- // Update overflow regions & trigger DLBI to be sure it's noticed.
- // Also request a repaint, since it's possible that only the color
- // of the shadow is changing (and UpdateOverflow/SchedulePaint won't
- // repaint for that, since they won't know what needs invalidating.)
- hint |= nsChangeHint_UpdateOverflow |
- nsChangeHint_SchedulePaint |
- nsChangeHint_RepaintFrame;
- }
- if (mClipFlags != aNewData.mClipFlags) {
- hint |= nsChangeHint_AllReflowHints |
- nsChangeHint_RepaintFrame;
- }
- if (!mClip.IsEqualInterior(aNewData.mClip)) {
- // If the clip has changed, we just need to update overflow areas. DLBI
- // will handle the invalidation.
- hint |= nsChangeHint_UpdateOverflow |
- nsChangeHint_SchedulePaint;
- }
- if (mOpacity != aNewData.mOpacity) {
- // If we're going from the optimized >=0.99 opacity value to 1.0 or back, then
- // repaint the frame because DLBI will not catch the invalidation. Otherwise,
- // just update the opacity layer.
- if ((mOpacity >= 0.99f && mOpacity < 1.0f && aNewData.mOpacity == 1.0f) ||
- (aNewData.mOpacity >= 0.99f && aNewData.mOpacity < 1.0f && mOpacity == 1.0f)) {
- hint |= nsChangeHint_RepaintFrame;
- } else {
- hint |= nsChangeHint_UpdateOpacityLayer;
- if ((mOpacity == 1.0f) != (aNewData.mOpacity == 1.0f)) {
- hint |= nsChangeHint_UpdateUsesOpacity;
- }
- }
- }
- if (HasFilters() != aNewData.HasFilters()) {
- // A change from/to being a containing block for position:fixed.
- hint |= nsChangeHint_UpdateContainingBlock;
- }
- if (mFilters != aNewData.mFilters) {
- hint |= nsChangeHint_UpdateEffects |
- nsChangeHint_RepaintFrame |
- nsChangeHint_UpdateOverflow;
- }
- if (mMixBlendMode != aNewData.mMixBlendMode) {
- hint |= nsChangeHint_RepaintFrame;
- }
- if (!hint &&
- !mClip.IsEqualEdges(aNewData.mClip)) {
- hint |= nsChangeHint_NeutralChange;
- }
- return hint;
- }
|