From c6714e12790347d694cecfc4993bedad4d7e5773 Mon Sep 17 00:00:00 2001 From: adeshkp Date: Tue, 24 Sep 2019 13:51:29 -0400 Subject: [PATCH 1/8] Issue #1231 - Stop using ICC profiles on Linux. General consensus seems to be that color management on Linux desktops is not mature enough to enable by default. --- modules/libpref/init/all.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index bd7df5d051..648ef8a566 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -732,12 +732,19 @@ pref("gfx.layerscope.port", 23456); // This should be use to quickly find which slow paths are used by test cases. pref("gfx.perf-warnings.enabled", false); -// 0 = Off, 1 = Full, 2 = Tagged Images Only. +// 0 = Off, 1 = All Images, 2 = Tagged Images Only. // See eCMSMode in gfx/thebes/gfxPlatform.h +#ifdef XP_WIN pref("gfx.color_management.mode", 2); pref("gfx.color_management.display_profile", ""); pref("gfx.color_management.rendering_intent", 0); pref("gfx.color_management.enablev4", true); +#else +pref("gfx.color_management.mode", 0); +pref("gfx.color_management.display_profile", ""); +pref("gfx.color_management.rendering_intent", 0); +pref("gfx.color_management.enablev4", false); +#endif pref("gfx.downloadable_fonts.enabled", true); pref("gfx.downloadable_fonts.fallback_delay", 3000); From f22ad944b74bae5eda26a895d77e28c62cc79fcf Mon Sep 17 00:00:00 2001 From: Gaming4JC Date: Sat, 28 Sep 2019 23:16:55 -0400 Subject: [PATCH 2/8] Issue #1233 - Part 1: Fix grid overflow and rendering issues by improving Layout CSS-Grid API List of relevant patches applied: 1425599 part 1 - [css-grid] Change the track sizing algorithm for spanning items so that it accumulates individual item contributions to the plan by max() rather than incrementing the planned size directly. Also, fix a bug when copying back the planned limits after updating it for the first span group. It should only copy back track sizes that were actaully spanned by those items, other content-sized tracks' limits should remain at "infinity". 1425599 part 2 - [css-grid] Factor out the min-sizing parts of the track sizing for spanned items to a templated method (idempotent change). 1425599 part 3 - [css-grid] Factor out most of the max-sizing parts of the track sizing for spanned items to a templated method (idempotent change). 1425599 part 4 - [css-grid] Factor out the starting base/limit size to a templated method (idempotent change). 1425599 part 5 - [css-grid] Make CollectGrowable a templated method so that it works with either base/limit sizes (idempotent change). 1425599 part 6 - [css-grid] Make the size distribution methods templated with the intent of merging them in a later patch (idempotent change). This patch also introduces an eInfinitelyGrowable bit to help get rid of the 'limits' temporary track sizes in the next patch. 1425599 part 7 - [css-grid] Remove the 'limits' copy of track sizes since they are no longer needed (idempotent change). 1425599 part 8 - [css-grid] Factor out the fit-content clamping function from DistributeToTrackLimits and pass it as a param instead (idempotent change). 1425599 part 9 - [css-grid] Merge DistributeToTrackLimits/Bases (idempotent change). 1425599 part 10 - [css-grid] Make MarkExcludedTracks a static method since it doesn't use 'this' (idempotent change). 1425599 part 11 - [css-grid] Hoist the marking of excluded tracks out from GrowSelectedTracksUnlimited to a separate method (idempotent change). 1425599 part 12 - [css-grid] Merge CopyPlanToBase/Limits into a templated method instead (idempotent change). 1425599 part 13 - [css-grid] Merge Grow[Base|Limits]ForSpanningItems into a templated method instead (idempotent change). 1425599 part 14 - [css-grid] Use iterators instead of an array + start/end index for the item data (idempotent change). 1425599 part 16 - [css-grid] Make SizeContributionForPhase a template. 1425599 - [css-grid] Follow-up bustage fix for stupid compiler warnings. 1378481 - Assign 'roundingError' in the default branch too, to avoid a maybe-uninitialized compiler warning. 1423292 - [css-grid] Add a couple of ItemState bits to Dump(), and make an ItemState assertion stricter (DEBUG-only changes). 1373678 Part 1: Reduce grid line numbers by count of leading implicit lines, minimum 0. 1416350 - Part 1: Correctly account for removed 'auto-fit' tracks also when there are leading implicit tracks. 1416350 - Part 2: Correct logic for Grid API line numbering with leading implicit tracks. 1418727 part 1 - [css-grid] Introduce StateBitsForRange() that collects the union of the state bits for a range of tracks (idempotent change). 1418727 part 2 - [css-grid] Require that an item spans at least one track with an 'auto' min sizing function for Automatic Minimum Size to apply. --- dom/grid/GridLines.cpp | 42 +- layout/generic/nsGridContainerFrame.cpp | 657 ++++++++++++++---------- 2 files changed, 408 insertions(+), 291 deletions(-) diff --git a/dom/grid/GridLines.cpp b/dom/grid/GridLines.cpp index fac645c64b..8988853464 100644 --- a/dom/grid/GridLines.cpp +++ b/dom/grid/GridLines.cpp @@ -90,7 +90,9 @@ GridLines::SetLineInfo(const ComputedGridTrackInfo* aTrackInfo, for (uint32_t i = aTrackInfo->mStartFragmentTrack; i < aTrackInfo->mEndFragmentTrack + 1; i++) { - uint32_t line1Index = i + 1; + // Since line indexes are 1-based, calculate a 1-based value + // for this track to simplify some calculations. + const uint32_t line1Index = i + 1; startOfNextTrack = (i < aTrackInfo->mEndFragmentTrack) ? aTrackInfo->mPositions[i] : @@ -127,7 +129,8 @@ GridLines::SetLineInfo(const ComputedGridTrackInfo* aTrackInfo, } } - if (i >= aTrackInfo->mRepeatFirstTrack && + if (i >= (aTrackInfo->mRepeatFirstTrack + + aTrackInfo->mNumLeadingImplicitTracks) && repeatIndex < numRepeatTracks) { numAddedLines += AppendRemovedAutoFits(aTrackInfo, aLineInfo, @@ -139,23 +142,30 @@ GridLines::SetLineInfo(const ComputedGridTrackInfo* aTrackInfo, RefPtr line = new GridLine(this); mLines.AppendElement(line); + MOZ_ASSERT(line1Index > 0, "line1Index must be positive."); + bool isBeforeFirstExplicit = + (line1Index <= aTrackInfo->mNumLeadingImplicitTracks); + // Calculate an actionable line number for this line, that could be used + // in a css grid property to align a grid item or area at that line. + // For implicit lines that appear before line 1, report a number of 0. + // We can't report negative indexes, because those have a different + // meaning in the css grid spec (negative indexes are negative-1-based + // from the end of the grid decreasing towards the front). + uint32_t lineNumber = isBeforeFirstExplicit ? 0 : + (line1Index - aTrackInfo->mNumLeadingImplicitTracks + numAddedLines); + GridDeclaration lineType = + (isBeforeFirstExplicit || + line1Index > (aTrackInfo->mNumLeadingImplicitTracks + + aTrackInfo->mNumExplicitTracks + 1)) + ? GridDeclaration::Implicit + : GridDeclaration::Explicit; line->SetLineValues( lineNames, nsPresContext::AppUnitsToDoubleCSSPixels(lastTrackEdge), nsPresContext::AppUnitsToDoubleCSSPixels(startOfNextTrack - lastTrackEdge), - line1Index + numAddedLines, - ( - // Implicit if there are no explicit tracks, or if the index - // is before the first explicit track, or after - // a track beyond the last explicit track. - (aTrackInfo->mNumExplicitTracks == 0) || - (i < aTrackInfo->mNumLeadingImplicitTracks) || - (i > aTrackInfo->mNumLeadingImplicitTracks + - aTrackInfo->mNumExplicitTracks) ? - GridDeclaration::Implicit : - GridDeclaration::Explicit - ) + lineNumber, + lineType ); if (i < aTrackInfo->mEndFragmentTrack) { @@ -215,11 +225,13 @@ GridLines::AppendRemovedAutoFits(const ComputedGridTrackInfo* aTrackInfo, RefPtr line = new GridLine(this); mLines.AppendElement(line); + uint32_t lineNumber = aTrackInfo->mRepeatFirstTrack + + aRepeatIndex + 1; line->SetLineValues( aLineNames, nsPresContext::AppUnitsToDoubleCSSPixels(aLastTrackEdge), nsPresContext::AppUnitsToDoubleCSSPixels(0), - aTrackInfo->mRepeatFirstTrack + aRepeatIndex + 1, + lineNumber, GridDeclaration::Explicit ); diff --git a/layout/generic/nsGridContainerFrame.cpp b/layout/generic/nsGridContainerFrame.cpp index 3a2d5ad1de..59f58f268a 100644 --- a/layout/generic/nsGridContainerFrame.cpp +++ b/layout/generic/nsGridContainerFrame.cpp @@ -198,7 +198,7 @@ struct nsGridContainerFrame::TrackSize eMaxContentMinSizing = 0x4, eMinOrMaxContentMinSizing = eMinContentMinSizing | eMaxContentMinSizing, eIntrinsicMinSizing = eMinOrMaxContentMinSizing | eAutoMinSizing, - // 0x8 is unused, feel free to take it! + eModified = 0x8, eAutoMaxSizing = 0x10, eMinContentMaxSizing = 0x20, eMaxContentMaxSizing = 0x40, @@ -211,6 +211,7 @@ struct nsGridContainerFrame::TrackSize eSkipGrowUnlimited = eSkipGrowUnlimited1 | eSkipGrowUnlimited2, eBreakBefore = 0x800, eFitContent = 0x1000, + eInfinitelyGrowable = 0x2000, }; StateBits Initialize(nscoord aPercentageBasis, @@ -856,6 +857,8 @@ struct nsGridContainerFrame::GridItemInfo // Return true if we should apply Automatic Minimum Size to this item. // https://drafts.csswg.org/css-grid/#min-size-auto + // @note the caller should also check that the item spans at least one track + // that has a min track sizing function that is 'auto' before applying it. bool ShouldApplyAutoMinSize(WritingMode aContainerWM, LogicalAxis aContainerAxis, nscoord aPercentageBasis) const @@ -915,6 +918,12 @@ nsGridContainerFrame::GridItemInfo::Dump() const if (state & ItemState::eIsFlexing) { printf("flexing "); } + if (state & ItemState::eApplyAutoMinSize) { + printf("auto-min-size "); + } + if (state & ItemState::eClampMarginBoxMinSize) { + printf("clamp "); + } if (state & ItemState::eFirstBaseline) { printf("first baseline %s-alignment ", (state & ItemState::eSelfBaseline) ? "self" : "content"); @@ -1091,6 +1100,7 @@ private: const nsTArray& mRepeatAutoLineNameListBefore; const nsTArray& mRepeatAutoLineNameListAfter; // The index of the repeat(auto-fill/fit) track, or zero if there is none. + // Relative to mExplicitGridOffset (repeat tracks are explicit by definition). const uint32_t mRepeatAutoStart; // The (hypothetical) index of the last such repeat() track. const uint32_t mRepeatAutoEnd; @@ -1101,6 +1111,7 @@ private: // generates one track (making mRepeatEndDelta == 0). const uint32_t mTemplateLinesEnd; // True if there is a specified repeat(auto-fill/fit) track. + // Indexed relative to mExplicitGridOffset + mRepeatAutoStart. const bool mHasRepeatAuto; }; @@ -1340,15 +1351,9 @@ struct nsGridContainerFrame::Tracks nscoord aContentBoxSize); /** - * Return true if aRange spans at least one track with an intrinsic sizing - * function and does not span any tracks with a max-sizing function. - * @param aRange the span of tracks to check - * @param aState will be set to the union of the state bits of all the spanned - * tracks, unless a flex track is found - then it only contains - * the union of the tracks up to and including the flex track. + * Return the union of the state bits for the tracks in aRange. */ - bool HasIntrinsicButNoFlexSizingInRange(const LineRange& aRange, - TrackSize::StateBits* aState) const; + TrackSize::StateBits StateBitsForRange(const LineRange& aRange) const; // Some data we collect for aligning baseline-aligned items. struct ItemBaselineData @@ -1383,6 +1388,62 @@ struct nsGridContainerFrame::Tracks */ void AlignBaselineSubtree(const GridItemInfo& aGridItem) const; + enum class TrackSizingPhase + { + eIntrinsicMinimums, + eContentBasedMinimums, + eMaxContentMinimums, + eIntrinsicMaximums, + eMaxContentMaximums, + }; + + // Some data we collect on each item for Step 2 of the Track Sizing Algorithm + // in ResolveIntrinsicSize below. + struct Step2ItemData final + { + uint32_t mSpan; + TrackSize::StateBits mState; + LineRange mLineRange; + nscoord mMinSize; + nscoord mMinContentContribution; + nscoord mMaxContentContribution; + nsIFrame* mFrame; + static bool IsSpanLessThan(const Step2ItemData& a, const Step2ItemData& b) + { + return a.mSpan < b.mSpan; + } + + template + nscoord SizeContributionForPhase() const + { + switch (phase) { + case TrackSizingPhase::eIntrinsicMinimums: + case TrackSizingPhase::eIntrinsicMaximums: + return mMinSize; + case TrackSizingPhase::eContentBasedMinimums: + return mMinContentContribution; + case TrackSizingPhase::eMaxContentMinimums: + case TrackSizingPhase::eMaxContentMaximums: + return mMaxContentContribution; + } + MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE("Unexpected phase"); + } + }; + + using FitContentClamper = + function; + + // Helper method for ResolveIntrinsicSize. + template + bool GrowSizeForSpanningItems(nsTArray::iterator aIter, + const nsTArray::iterator aEnd, + nsTArray& aTracks, + nsTArray& aPlan, + nsTArray& aItemPlan, + TrackSize::StateBits aSelector, + const FitContentClamper& aClamper = nullptr, + bool aNeedInfinitelyGrowableFlag = false); + /** * Resolve Intrinsic Track Sizes. * http://dev.w3.org/csswg/css-grid/#algo-content @@ -1405,66 +1466,117 @@ struct nsGridContainerFrame::Tracks SizingConstraint aConstraint, const LineRange& aRange, const GridItemInfo& aGridItem); + + // Helper method that returns the track size to use in §11.5.1.2 + // https://drafts.csswg.org/css-grid/#extra-space + template static + nscoord StartSizeInDistribution(const TrackSize& aSize) + { + switch (phase) { + case TrackSizingPhase::eIntrinsicMinimums: + case TrackSizingPhase::eContentBasedMinimums: + case TrackSizingPhase::eMaxContentMinimums: + return aSize.mBase; + case TrackSizingPhase::eIntrinsicMaximums: + case TrackSizingPhase::eMaxContentMaximums: + if (aSize.mLimit == NS_UNCONSTRAINEDSIZE) { + return aSize.mBase; + } + return aSize.mLimit; + } + MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE("Unexpected phase"); + } + /** * Collect the tracks which are growable (matching aSelector) into * aGrowableTracks, and return the amount of space that can be used - * to grow those tracks. Specifically, we return aAvailableSpace minus - * the sum of mBase's (and corresponding grid gaps) in aPlan (clamped to 0) - * for the tracks in aRange, or zero when there are no growable tracks. - * @note aPlan[*].mBase represents a planned new base or limit. + * to grow those tracks. This method implements CSS Grid §11.5.1.2. + * https://drafts.csswg.org/css-grid/#extra-space */ - nscoord CollectGrowable(nscoord aAvailableSpace, - const nsTArray& aPlan, - const LineRange& aRange, - TrackSize::StateBits aSelector, - nsTArray& aGrowableTracks) const + template + nscoord CollectGrowable(nscoord aAvailableSpace, + const LineRange& aRange, + TrackSize::StateBits aSelector, + nsTArray& aGrowableTracks) const { MOZ_ASSERT(aAvailableSpace > 0, "why call me?"); nscoord space = aAvailableSpace - mGridGap * (aRange.Extent() - 1); const uint32_t start = aRange.mStart; const uint32_t end = aRange.mEnd; for (uint32_t i = start; i < end; ++i) { - const TrackSize& sz = aPlan[i]; - space -= sz.mBase; + const TrackSize& sz = mSizes[i]; + space -= StartSizeInDistribution(sz); if (space <= 0) { return 0; } - if ((sz.mState & aSelector) && !sz.IsFrozen()) { + if (sz.mState & aSelector) { aGrowableTracks.AppendElement(i); } } return aGrowableTracks.IsEmpty() ? 0 : space; } - void SetupGrowthPlan(nsTArray& aPlan, - const nsTArray& aTracks) const + template + void InitializeItemPlan(nsTArray& aItemPlan, + const nsTArray& aTracks) const { for (uint32_t track : aTracks) { - aPlan[track] = mSizes[track]; + auto& plan = aItemPlan[track]; + const TrackSize& sz = mSizes[track]; + plan.mBase = StartSizeInDistribution(sz); + bool unlimited = sz.mState & TrackSize::eInfinitelyGrowable; + plan.mLimit = unlimited ? NS_UNCONSTRAINEDSIZE : sz.mLimit; + plan.mState = sz.mState; } } - void CopyPlanToBase(const nsTArray& aPlan, - const nsTArray& aTracks) + template + void InitializePlan(nsTArray& aPlan) const { - for (uint32_t track : aTracks) { - MOZ_ASSERT(mSizes[track].mBase <= aPlan[track].mBase); - mSizes[track].mBase = aPlan[track].mBase; + for (size_t i = 0, len = aPlan.Length(); i < len; ++i) { + auto& plan = aPlan[i]; + const auto& sz = mSizes[i]; + plan.mBase = StartSizeInDistribution(sz); + MOZ_ASSERT(phase == TrackSizingPhase::eMaxContentMaximums || + !(sz.mState & TrackSize::eInfinitelyGrowable), + "forgot to reset the eInfinitelyGrowable bit?"); + plan.mState = sz.mState; } } - void CopyPlanToLimit(const nsTArray& aPlan, - const nsTArray& aTracks) + template + void CopyPlanToSize(const nsTArray& aPlan, + bool aNeedInfinitelyGrowableFlag = false) { - for (uint32_t track : aTracks) { - MOZ_ASSERT(mSizes[track].mLimit == NS_UNCONSTRAINEDSIZE || - mSizes[track].mLimit <= aPlan[track].mBase); - mSizes[track].mLimit = aPlan[track].mBase; + for (size_t i = 0, len = mSizes.Length(); i < len; ++i) { + const auto& plan = aPlan[i]; + MOZ_ASSERT(plan.mBase >= 0); + auto& sz = mSizes[i]; + switch (phase) { + case TrackSizingPhase::eIntrinsicMinimums: + case TrackSizingPhase::eContentBasedMinimums: + case TrackSizingPhase::eMaxContentMinimums: + sz.mBase = plan.mBase; + break; + case TrackSizingPhase::eIntrinsicMaximums: + if (plan.mState & TrackSize::eModified) { + if (sz.mLimit == NS_UNCONSTRAINEDSIZE && + aNeedInfinitelyGrowableFlag) { + sz.mState |= TrackSize::eInfinitelyGrowable; + } + sz.mLimit = plan.mBase; + } + break; + case TrackSizingPhase::eMaxContentMaximums: + if (plan.mState & TrackSize::eModified) { + sz.mLimit = plan.mBase; + } + sz.mState &= ~TrackSize::eInfinitelyGrowable; + break; + } } } - using FitContentClamper = - function; /** * Grow the planned size for tracks in aGrowableTracks up to their limit * and then freeze them (all aGrowableTracks must be unfrozen on entry). @@ -1524,12 +1636,13 @@ struct nsGridContainerFrame::Tracks * assumed that aPlan have no aSkipFlag set for tracks in aGrowableTracks * on entry to this method. */ - uint32_t MarkExcludedTracks(nsTArray& aPlan, - uint32_t aNumGrowable, - const nsTArray& aGrowableTracks, - TrackSize::StateBits aMinSizingSelector, - TrackSize::StateBits aMaxSizingSelector, - TrackSize::StateBits aSkipFlag) const + static uint32_t + MarkExcludedTracks(nsTArray& aPlan, + uint32_t aNumGrowable, + const nsTArray& aGrowableTracks, + TrackSize::StateBits aMinSizingSelector, + TrackSize::StateBits aMaxSizingSelector, + TrackSize::StateBits aSkipFlag) { bool foundOneSelected = false; bool foundOneGrowable = false; @@ -1559,41 +1672,60 @@ struct nsGridContainerFrame::Tracks } /** - * Increase the planned size for tracks in aGrowableTracks that match - * aSelector (or all tracks if aSelector is zero) beyond their limit. + * Mark all tracks in aGrowableTracks with an eSkipGrowUnlimited bit if + * they *shouldn't* grow unlimited in §11.5.1.2.3 "Distribute space beyond + * growth limits" https://drafts.csswg.org/css-grid/#extra-space + * Return the number of tracks that are still growable. + */ + template + static uint32_t + MarkExcludedTracks(nsTArray& aPlan, + const nsTArray& aGrowableTracks, + TrackSize::StateBits aSelector) + { + uint32_t numGrowable = aGrowableTracks.Length(); + if (phase == TrackSizingPhase::eIntrinsicMaximums || + phase == TrackSizingPhase::eMaxContentMaximums) { + // "when handling any intrinsic growth limit: all affected tracks" + return numGrowable; + } + MOZ_ASSERT(aSelector == (aSelector & TrackSize::eIntrinsicMinSizing) && + (aSelector & TrackSize::eMaxContentMinSizing), + "Should only get here for track sizing steps 2.1 to 2.3"); + // Note that eMaxContentMinSizing is always included. We do those first: + numGrowable = MarkExcludedTracks(aPlan, numGrowable, aGrowableTracks, + TrackSize::eMaxContentMinSizing, + TrackSize::eMaxContentMaxSizing, + TrackSize::eSkipGrowUnlimited1); + // Now mark min-content/auto min-sizing tracks if requested. + auto minOrAutoSelector = aSelector & ~TrackSize::eMaxContentMinSizing; + if (minOrAutoSelector) { + numGrowable = MarkExcludedTracks(aPlan, numGrowable, aGrowableTracks, + minOrAutoSelector, + TrackSize::eIntrinsicMaxSizing, + TrackSize::eSkipGrowUnlimited2); + } + return numGrowable; + } + + /** + * Increase the planned size for tracks in aGrowableTracks that aren't + * marked with a eSkipGrowUnlimited flag beyond their limit. * This implements the "Distribute space beyond growth limits" step in * https://drafts.csswg.org/css-grid/#distribute-extra-space */ void GrowSelectedTracksUnlimited(nscoord aAvailableSpace, nsTArray& aPlan, const nsTArray& aGrowableTracks, - TrackSize::StateBits aSelector, + uint32_t aNumGrowable, FitContentClamper aFitContentClamper) const { - MOZ_ASSERT(aAvailableSpace > 0 && aGrowableTracks.Length() > 0); - uint32_t numGrowable = aGrowableTracks.Length(); - if (aSelector) { - MOZ_ASSERT(aSelector == (aSelector & TrackSize::eIntrinsicMinSizing) && - (aSelector & TrackSize::eMaxContentMinSizing), - "Should only get here for track sizing steps 2.1 to 2.3"); - // Note that eMaxContentMinSizing is always included. We do those first: - numGrowable = MarkExcludedTracks(aPlan, numGrowable, aGrowableTracks, - TrackSize::eMaxContentMinSizing, - TrackSize::eMaxContentMaxSizing, - TrackSize::eSkipGrowUnlimited1); - // Now mark min-content/auto min-sizing tracks if requested. - auto minOrAutoSelector = aSelector & ~TrackSize::eMaxContentMinSizing; - if (minOrAutoSelector) { - numGrowable = MarkExcludedTracks(aPlan, numGrowable, aGrowableTracks, - minOrAutoSelector, - TrackSize::eIntrinsicMaxSizing, - TrackSize::eSkipGrowUnlimited2); - } - } + MOZ_ASSERT(aAvailableSpace > 0 && aGrowableTracks.Length() > 0 && + aNumGrowable <= aGrowableTracks.Length()); nscoord space = aAvailableSpace; DebugOnly didClamp = false; - while (numGrowable) { - nscoord spacePerTrack = std::max(space / numGrowable, 1); + while (aNumGrowable) { + nscoord spacePerTrack = std::max(space / aNumGrowable, 1); for (uint32_t track : aGrowableTracks) { TrackSize& sz = aPlan[track]; if (sz.mState & TrackSize::eSkipGrowUnlimited) { @@ -1609,7 +1741,7 @@ struct nsGridContainerFrame::Tracks delta = newBase - sz.mBase; MOZ_ASSERT(delta >= 0, "track size shouldn't shrink"); sz.mState |= TrackSize::eSkipGrowUnlimited1; - --numGrowable; + --aNumGrowable; } } sz.mBase = newBase; @@ -1628,46 +1760,30 @@ struct nsGridContainerFrame::Tracks * Distribute aAvailableSpace to the planned base size for aGrowableTracks * up to their limits, then distribute the remaining space beyond the limits. */ - void DistributeToTrackBases(nscoord aAvailableSpace, + template + void DistributeToTrackSizes(nscoord aAvailableSpace, nsTArray& aPlan, + nsTArray& aItemPlan, nsTArray& aGrowableTracks, - TrackSize::StateBits aSelector) + TrackSize::StateBits aSelector, + const FitContentClamper& aFitContentClamper) { - SetupGrowthPlan(aPlan, aGrowableTracks); - nscoord space = GrowTracksToLimit(aAvailableSpace, aPlan, aGrowableTracks, nullptr); + InitializeItemPlan(aItemPlan, aGrowableTracks); + nscoord space = GrowTracksToLimit(aAvailableSpace, aItemPlan, aGrowableTracks, + aFitContentClamper); if (space > 0) { - GrowSelectedTracksUnlimited(space, aPlan, aGrowableTracks, aSelector, nullptr); + uint32_t numGrowable = + MarkExcludedTracks(aItemPlan, aGrowableTracks, aSelector); + GrowSelectedTracksUnlimited(space, aItemPlan, aGrowableTracks, + numGrowable, aFitContentClamper); } - CopyPlanToBase(aPlan, aGrowableTracks); - } - - /** - * Distribute aAvailableSpace to the planned limits for aGrowableTracks. - */ - void DistributeToTrackLimits(nscoord aAvailableSpace, - nsTArray& aPlan, - nsTArray& aGrowableTracks, - const TrackSizingFunctions& aFunctions, - nscoord aPercentageBasis) - { - auto fitContentClamper = [&aFunctions, aPercentageBasis] (uint32_t aTrack, - nscoord aMinSize, - nscoord* aSize) { - nscoord fitContentLimit = - ::ResolveToDefiniteSize(aFunctions.MaxSizingFor(aTrack), aPercentageBasis); - if (*aSize > fitContentLimit) { - *aSize = std::max(aMinSize, fitContentLimit); - return true; + for (uint32_t track : aGrowableTracks) { + nscoord& plannedSize = aPlan[track].mBase; + nscoord itemIncurredSize = aItemPlan[track].mBase; + if (plannedSize < itemIncurredSize) { + plannedSize = itemIncurredSize; } - return false; - }; - nscoord space = GrowTracksToLimit(aAvailableSpace, aPlan, aGrowableTracks, - fitContentClamper); - if (space > 0) { - GrowSelectedTracksUnlimited(aAvailableSpace, aPlan, aGrowableTracks, - TrackSize::StateBits(0), fitContentClamper); } - CopyPlanToLimit(aPlan, aGrowableTracks); } /** @@ -3545,19 +3661,27 @@ nsGridContainerFrame::Grid::PlaceGridItems(GridReflowInput& aState, // Count empty 'auto-fit' tracks in the repeat() range. // |colAdjust| will have a count for each line in the grid of how many // tracks were empty between the start of the grid and that line. + + // Since this loop is concerned with just the repeat tracks, we + // iterate from 0..NumRepeatTracks() which is the natural range of + // mRemoveRepeatTracks. This means we have to add + // (mExplicitGridOffset + mRepeatAutoStart) to get a zero-based + // index for arrays like mCellMap and colAdjust. We'll then fill out + // the colAdjust array for all the remaining lines. Maybe> colAdjust; uint32_t numEmptyCols = 0; if (aState.mColFunctions.mHasRepeatAuto && !gridStyle->mGridTemplateColumns.mIsAutoFill && aState.mColFunctions.NumRepeatTracks() > 0) { - for (uint32_t col = aState.mColFunctions.mRepeatAutoStart, - endRepeat = aState.mColFunctions.mRepeatAutoEnd, - numColLines = mGridColEnd + 1; - col < numColLines; ++col) { + const uint32_t repeatStart = (aState.mColFunctions.mExplicitGridOffset + + aState.mColFunctions.mRepeatAutoStart); + const uint32_t numRepeats = aState.mColFunctions.NumRepeatTracks(); + const uint32_t numColLines = mGridColEnd + 1; + for (uint32_t i = 0; i < numRepeats; ++i) { if (numEmptyCols) { - (*colAdjust)[col] = numEmptyCols; + (*colAdjust)[repeatStart + i] = numEmptyCols; } - if (col < endRepeat && mCellMap.IsEmptyCol(col)) { + if (mCellMap.IsEmptyCol(repeatStart + i)) { ++numEmptyCols; if (colAdjust.isNothing()) { colAdjust.emplace(numColLines); @@ -3565,26 +3689,34 @@ nsGridContainerFrame::Grid::PlaceGridItems(GridReflowInput& aState, PodZero(colAdjust->Elements(), colAdjust->Length()); } - uint32_t repeatIndex = col - aState.mColFunctions.mRepeatAutoStart; - MOZ_ASSERT(aState.mColFunctions.mRemovedRepeatTracks.Length() > - repeatIndex); - aState.mColFunctions.mRemovedRepeatTracks[repeatIndex] = true; + aState.mColFunctions.mRemovedRepeatTracks[i] = true; + } + } + // Fill out the colAdjust array for all the columns after the + // repeats. + if (numEmptyCols) { + for (uint32_t col = repeatStart + numRepeats; + col < numColLines; ++col) { + (*colAdjust)[col] = numEmptyCols; } } } + + // Do similar work for the row tracks, with the same logic. Maybe> rowAdjust; uint32_t numEmptyRows = 0; if (aState.mRowFunctions.mHasRepeatAuto && !gridStyle->mGridTemplateRows.mIsAutoFill && aState.mRowFunctions.NumRepeatTracks() > 0) { - for (uint32_t row = aState.mRowFunctions.mRepeatAutoStart, - endRepeat = aState.mRowFunctions.mRepeatAutoEnd, - numRowLines = mGridRowEnd + 1; - row < numRowLines; ++row) { + const uint32_t repeatStart = (aState.mRowFunctions.mExplicitGridOffset + + aState.mRowFunctions.mRepeatAutoStart); + const uint32_t numRepeats = aState.mRowFunctions.NumRepeatTracks(); + const uint32_t numRowLines = mGridRowEnd + 1; + for (uint32_t i = 0; i < numRepeats; ++i) { if (numEmptyRows) { - (*rowAdjust)[row] = numEmptyRows; + (*rowAdjust)[repeatStart + i] = numEmptyRows; } - if (row < endRepeat && mCellMap.IsEmptyRow(row)) { + if (mCellMap.IsEmptyRow(repeatStart + i)) { ++numEmptyRows; if (rowAdjust.isNothing()) { rowAdjust.emplace(numRowLines); @@ -3592,10 +3724,13 @@ nsGridContainerFrame::Grid::PlaceGridItems(GridReflowInput& aState, PodZero(rowAdjust->Elements(), rowAdjust->Length()); } - uint32_t repeatIndex = row - aState.mRowFunctions.mRepeatAutoStart; - MOZ_ASSERT(aState.mRowFunctions.mRemovedRepeatTracks.Length() > - repeatIndex); - aState.mRowFunctions.mRemovedRepeatTracks[repeatIndex] = true; + aState.mRowFunctions.mRemovedRepeatTracks[i] = true; + } + } + if (numEmptyRows) { + for (uint32_t row = repeatStart + numRepeats; + row < numRowLines; ++row) { + (*rowAdjust)[row] = numEmptyRows; } } } @@ -3974,28 +4109,16 @@ nsGridContainerFrame::Tracks::CalculateSizes( } } -bool -nsGridContainerFrame::Tracks::HasIntrinsicButNoFlexSizingInRange( - const LineRange& aRange, - TrackSize::StateBits* aState) const +TrackSize::StateBits +nsGridContainerFrame::Tracks::StateBitsForRange(const LineRange& aRange) const { - MOZ_ASSERT(!aRange.IsAuto(), "must have a definite range"); + TrackSize::StateBits state = TrackSize::StateBits(0); const uint32_t start = aRange.mStart; const uint32_t end = aRange.mEnd; - const TrackSize::StateBits selector = - TrackSize::eIntrinsicMinSizing | TrackSize::eIntrinsicMaxSizing; - bool foundIntrinsic = false; for (uint32_t i = start; i < end; ++i) { - TrackSize::StateBits state = mSizes[i].mState; - *aState |= state; - if (state & TrackSize::eFlexMaxSizing) { - return false; - } - if (state & selector) { - foundIntrinsic = true; - } + state |= mSizes[i].mState; } - return foundIntrinsic; + return state; } bool @@ -4010,6 +4133,13 @@ nsGridContainerFrame::Tracks::ResolveIntrinsicSizeStep1( CachedIntrinsicSizes cache; TrackSize& sz = mSizes[aRange.mStart]; WritingMode wm = aState.mWM; + + // Check if we need to apply "Automatic Minimum Size" and cache it. + if ((sz.mState & TrackSize::eAutoMinSizing) && + aGridItem.ShouldApplyAutoMinSize(wm, mAxis, aPercentageBasis)) { + aGridItem.mState[mAxis] |= ItemState::eApplyAutoMinSize; + } + // Calculate data for "Automatic Minimum Size" clamping, if needed. bool needed = ((sz.mState & TrackSize::eIntrinsicMinSizing) || aConstraint == SizingConstraint::eNoConstraint) && @@ -4370,6 +4500,55 @@ nsGridContainerFrame::Tracks::AlignBaselineSubtree( } } +template +bool +nsGridContainerFrame::Tracks::GrowSizeForSpanningItems( + nsTArray::iterator aIter, + const nsTArray::iterator aIterEnd, + nsTArray& aTracks, + nsTArray& aPlan, + nsTArray& aItemPlan, + TrackSize::StateBits aSelector, + const FitContentClamper& aFitContentClamper, + bool aNeedInfinitelyGrowableFlag) +{ + constexpr bool isMaxSizingPhase = + phase == TrackSizingPhase::eIntrinsicMaximums || + phase == TrackSizingPhase::eMaxContentMaximums; + bool needToUpdateSizes = false; + InitializePlan(aPlan); + for (; aIter != aIterEnd; ++aIter) { + const Step2ItemData& item = *aIter; + if (!(item.mState & aSelector)) { + continue; + } + if (isMaxSizingPhase) { + for (auto j = item.mLineRange.mStart, end = item.mLineRange.mEnd; j < end; ++j) { + aPlan[j].mState |= TrackSize::eModified; + } + } + nscoord space = item.SizeContributionForPhase(); + if (space <= 0) { + continue; + } + aTracks.ClearAndRetainStorage(); + space = CollectGrowable(space, item.mLineRange, aSelector, + aTracks); + if (space > 0) { + DistributeToTrackSizes(space, aPlan, aItemPlan, aTracks, aSelector, + aFitContentClamper); + needToUpdateSizes = true; + } + } + if (isMaxSizingPhase) { + needToUpdateSizes = true; + } + if (needToUpdateSizes) { + CopyPlanToSize(aPlan, aNeedInfinitelyGrowableFlag); + } + return needToUpdateSizes; +} + void nsGridContainerFrame::Tracks::ResolveIntrinsicSize( GridReflowInput& aState, @@ -4379,21 +4558,6 @@ nsGridContainerFrame::Tracks::ResolveIntrinsicSize( nscoord aPercentageBasis, SizingConstraint aConstraint) { - // Some data we collect on each item for Step 2 of the algorithm below. - struct Step2ItemData - { - uint32_t mSpan; - TrackSize::StateBits mState; - LineRange mLineRange; - nscoord mMinSize; - nscoord mMinContentContribution; - nscoord mMaxContentContribution; - nsIFrame* mFrame; - static bool IsSpanLessThan(const Step2ItemData& a, const Step2ItemData& b) - { - return a.mSpan < b.mSpan; - } - }; // Resolve Intrinsic Track Sizes // http://dev.w3.org/csswg/css-grid/#algo-content @@ -4418,12 +4582,10 @@ nsGridContainerFrame::Tracks::ResolveIntrinsicSize( for (; !iter.AtEnd(); iter.Next()) { auto& gridItem = aGridItems[iter.GridItemIndex()]; - // Check if we need to apply "Automatic Minimum Size" and cache it. - MOZ_ASSERT(!(gridItem.mState[mAxis] & ItemState::eApplyAutoMinSize), - "Why is eApplyAutoMinSize set already?"); - if (gridItem.ShouldApplyAutoMinSize(wm, mAxis, aPercentageBasis)) { - gridItem.mState[mAxis] |= ItemState::eApplyAutoMinSize; - } + MOZ_ASSERT(!(gridItem.mState[mAxis] & + (ItemState::eApplyAutoMinSize | ItemState::eIsFlexing | + ItemState::eClampMarginBoxMinSize)), + "Why are any of these bits set already?"); const GridArea& area = gridItem.mArea; const LineRange& lineRange = area.*aRange; @@ -4435,8 +4597,17 @@ nsGridContainerFrame::Tracks::ResolveIntrinsicSize( gridItem.mState[mAxis] |= ItemState::eIsFlexing; } } else { - TrackSize::StateBits state = TrackSize::StateBits(0); - if (HasIntrinsicButNoFlexSizingInRange(lineRange, &state)) { + TrackSize::StateBits state = StateBitsForRange(lineRange); + + // Check if we need to apply "Automatic Minimum Size" and cache it. + if ((state & TrackSize::eAutoMinSizing) && + gridItem.ShouldApplyAutoMinSize(wm, mAxis, aPercentageBasis)) { + gridItem.mState[mAxis] |= ItemState::eApplyAutoMinSize; + } + + if ((state & (TrackSize::eIntrinsicMinSizing | + TrackSize::eIntrinsicMaxSizing)) && + !(state & TrackSize::eFlexMaxSizing)) { // Collect data for Step 2. maxSpan = std::max(maxSpan, span); if (span >= stateBitsPerSpan.Length()) { @@ -4500,6 +4671,18 @@ nsGridContainerFrame::Tracks::ResolveIntrinsicSize( // Step 2. if (maxSpan) { + auto fitContentClamper = [&aFunctions, aPercentageBasis] (uint32_t aTrack, + nscoord aMinSize, + nscoord* aSize) + { + nscoord fitContentLimit = + ::ResolveToDefiniteSize(aFunctions.MaxSizingFor(aTrack), aPercentageBasis); + if (*aSize > fitContentLimit) { + *aSize = std::max(aMinSize, fitContentLimit); + return true; + } + return false; + }; // Sort the collected items on span length, shortest first. std::stable_sort(step2Items.begin(), step2Items.end(), Step2ItemData::IsSpanLessThan); @@ -4507,85 +4690,44 @@ nsGridContainerFrame::Tracks::ResolveIntrinsicSize( nsTArray tracks(maxSpan); nsTArray plan(mSizes.Length()); plan.SetLength(mSizes.Length()); - for (uint32_t i = 0, len = step2Items.Length(); i < len; ) { - // Start / end index for items of the same span length: - const uint32_t spanGroupStartIndex = i; - uint32_t spanGroupEndIndex = len; - const uint32_t span = step2Items[i].mSpan; - for (++i; i < len; ++i) { - if (step2Items[i].mSpan != span) { - spanGroupEndIndex = i; - break; - } + nsTArray itemPlan(mSizes.Length()); + itemPlan.SetLength(mSizes.Length()); + // Start / end iterator for items of the same span length: + auto spanGroupStart = step2Items.begin(); + auto spanGroupEnd = spanGroupStart; + const auto end = step2Items.end(); + for (; spanGroupStart != end; spanGroupStart = spanGroupEnd) { + while (spanGroupEnd != end && + !Step2ItemData::IsSpanLessThan(*spanGroupStart, *spanGroupEnd)) { + ++spanGroupEnd; } + const uint32_t span = spanGroupStart->mSpan; bool updatedBase = false; // Did we update any mBase in step 2.1 - 2.3? TrackSize::StateBits selector(TrackSize::eIntrinsicMinSizing); if (stateBitsPerSpan[span] & selector) { // Step 2.1 MinSize to intrinsic min-sizing. - for (i = spanGroupStartIndex; i < spanGroupEndIndex; ++i) { - Step2ItemData& item = step2Items[i]; - if (!(item.mState & selector)) { - continue; - } - nscoord space = item.mMinSize; - if (space <= 0) { - continue; - } - tracks.ClearAndRetainStorage(); - space = CollectGrowable(space, mSizes, item.mLineRange, selector, - tracks); - if (space > 0) { - DistributeToTrackBases(space, plan, tracks, selector); - updatedBase = true; - } - } + updatedBase = + GrowSizeForSpanningItems( + spanGroupStart, spanGroupEnd, tracks, plan, itemPlan, selector); } selector = contentBasedMinSelector; if (stateBitsPerSpan[span] & selector) { // Step 2.2 MinContentContribution to min-/max-content (and 'auto' when // sizing under a min-content constraint) min-sizing. - for (i = spanGroupStartIndex; i < spanGroupEndIndex; ++i) { - Step2ItemData& item = step2Items[i]; - if (!(item.mState & selector)) { - continue; - } - nscoord space = item.mMinContentContribution; - if (space <= 0) { - continue; - } - tracks.ClearAndRetainStorage(); - space = CollectGrowable(space, mSizes, item.mLineRange, selector, - tracks); - if (space > 0) { - DistributeToTrackBases(space, plan, tracks, selector); - updatedBase = true; - } - } + updatedBase |= + GrowSizeForSpanningItems( + spanGroupStart, spanGroupEnd, tracks, plan, itemPlan, selector); } selector = maxContentMinSelector; if (stateBitsPerSpan[span] & selector) { // Step 2.3 MaxContentContribution to max-content (and 'auto' when // sizing under a max-content constraint) min-sizing. - for (i = spanGroupStartIndex; i < spanGroupEndIndex; ++i) { - Step2ItemData& item = step2Items[i]; - if (!(item.mState & selector)) { - continue; - } - nscoord space = item.mMaxContentContribution; - if (space <= 0) { - continue; - } - tracks.ClearAndRetainStorage(); - space = CollectGrowable(space, mSizes, item.mLineRange, selector, - tracks); - if (space > 0) { - DistributeToTrackBases(space, plan, tracks, selector); - updatedBase = true; - } - } + updatedBase |= + GrowSizeForSpanningItems( + spanGroupStart, spanGroupEnd, tracks, plan, itemPlan, selector); } if (updatedBase) { @@ -4596,63 +4738,22 @@ nsGridContainerFrame::Tracks::ResolveIntrinsicSize( } } } - if (stateBitsPerSpan[span] & TrackSize::eIntrinsicMaxSizing) { - plan = mSizes; - for (TrackSize& sz : plan) { - if (sz.mLimit == NS_UNCONSTRAINEDSIZE) { - // use mBase as the planned limit - } else { - sz.mBase = sz.mLimit; - } - } + selector = TrackSize::eIntrinsicMaxSizing; + if (stateBitsPerSpan[span] & selector) { + const bool willRunStep2_6 = + stateBitsPerSpan[span] & TrackSize::eAutoOrMaxContentMaxSizing; // Step 2.5 MinSize to intrinsic max-sizing. - for (i = spanGroupStartIndex; i < spanGroupEndIndex; ++i) { - Step2ItemData& item = step2Items[i]; - if (!(item.mState & TrackSize::eIntrinsicMaxSizing)) { - continue; - } - nscoord space = item.mMinSize; - if (space <= 0) { - continue; - } - tracks.ClearAndRetainStorage(); - space = CollectGrowable(space, plan, item.mLineRange, - TrackSize::eIntrinsicMaxSizing, - tracks); - if (space > 0) { - DistributeToTrackLimits(space, plan, tracks, aFunctions, - aPercentageBasis); - } - } - for (size_t j = 0, len = mSizes.Length(); j < len; ++j) { - TrackSize& sz = plan[j]; - sz.mState &= ~(TrackSize::eFrozen | TrackSize::eSkipGrowUnlimited); - if (sz.mLimit != NS_UNCONSTRAINEDSIZE) { - sz.mLimit = sz.mBase; // collect the results from 2.5 - } - } + GrowSizeForSpanningItems( + spanGroupStart, spanGroupEnd, tracks, plan, itemPlan, selector, + fitContentClamper, willRunStep2_6); - if (stateBitsPerSpan[span] & TrackSize::eAutoOrMaxContentMaxSizing) { + if (willRunStep2_6) { // Step 2.6 MaxContentContribution to max-content max-sizing. - for (i = spanGroupStartIndex; i < spanGroupEndIndex; ++i) { - Step2ItemData& item = step2Items[i]; - if (!(item.mState & TrackSize::eAutoOrMaxContentMaxSizing)) { - continue; - } - nscoord space = item.mMaxContentContribution; - if (space <= 0) { - continue; - } - tracks.ClearAndRetainStorage(); - space = CollectGrowable(space, plan, item.mLineRange, - TrackSize::eAutoOrMaxContentMaxSizing, - tracks); - if (space > 0) { - DistributeToTrackLimits(space, plan, tracks, aFunctions, - aPercentageBasis); - } - } + selector = TrackSize::eAutoOrMaxContentMaxSizing; + GrowSizeForSpanningItems( + spanGroupStart, spanGroupEnd, tracks, plan, itemPlan, selector, + fitContentClamper); } } } @@ -4984,6 +5085,7 @@ nsGridContainerFrame::Tracks::AlignJustifyContent( default: MOZ_ASSERT_UNREACHABLE("unknown align-/justify-content value"); between = 0; // just to avoid a compiler warning + roundingError = 0; // just to avoid a compiler warning } between += mGridGap; for (TrackSize& sz : mSizes) { @@ -7113,6 +7215,9 @@ nsGridContainerFrame::TrackSize::Dump() const if (mState & eFrozen) { printf("frozen "); } + if (mState & eModified) { + printf("modified "); + } if (mState & eBreakBefore) { printf("break-before "); } From 1f9d16132b26cfd7181d721e8dfd418f58ab5790 Mon Sep 17 00:00:00 2001 From: Gaming4JC Date: Sat, 28 Sep 2019 23:25:06 -0400 Subject: [PATCH 3/8] Issue #1233 - Part 2: Update Reftests List of relevant patches applied: 1425599 part 15 - [css-grid] Test reference fixes + more tests. 1373678 Part 3: Add line number checks to test_grid_implicit.html. 1416350 - Part 3: Add test to verify line numbers of grids with leading implicit tracks. 1416350 - Part 4: Add a reftest of repeat:auto-fit grids with leading implicit tracks. 1417711 - [css-grid] An abs.pos. grid container child that only covers removed 'auto-fit' tracks should not span to the end padding edge. 1416350 - Part 5: Correct the expected results for grids that have leading implicit tracks. 1418727 part 3 - [css-grid] Reftest updates. --- dom/grid/test/chrome.ini | 1 + dom/grid/test/chrome/test_grid_implicit.html | 63 +- .../test/chrome/test_grid_line_numbers.html | 101 + layout/generic/nsGridContainerFrame.cpp | 10 +- layout/generic/test/mochitest.ini | 4 + .../test/test_grid_track_sizing_algo_001.html | 1641 +++++++++++++++++ .../test/test_grid_track_sizing_algo_002.html | 1641 +++++++++++++++++ ...id-col-max-sizing-max-content-001-ref.html | 15 +- ...id-col-max-sizing-max-content-002-ref.html | 15 +- .../grid-flex-min-sizing-002-ref.html | 8 +- .../grid-max-sizing-flex-004-ref.html | 4 +- .../grid-repeat-auto-fill-fit-006-ref.html | 64 +- .../grid-repeat-auto-fill-fit-007-ref.html | 22 +- .../grid-repeat-auto-fill-fit-008-ref.html | 33 +- .../grid-repeat-auto-fill-fit-008.html | 34 +- .../grid-repeat-auto-fill-fit-012-ref.html | 144 ++ .../grid-repeat-auto-fill-fit-012.html | 160 ++ .../grid-repeat-auto-fill-fit-013-ref.html | 116 ++ .../grid-repeat-auto-fill-fit-013.html | 135 ++ .../grid-track-intrinsic-sizing-002-ref.html | 30 +- .../grid-track-intrinsic-sizing-003-ref.html | 48 +- layout/reftests/css-grid/reftest.list | 6 +- 22 files changed, 4150 insertions(+), 145 deletions(-) create mode 100644 dom/grid/test/chrome/test_grid_line_numbers.html create mode 100644 layout/generic/test/test_grid_track_sizing_algo_001.html create mode 100644 layout/generic/test/test_grid_track_sizing_algo_002.html create mode 100644 layout/reftests/css-grid/grid-repeat-auto-fill-fit-012-ref.html create mode 100644 layout/reftests/css-grid/grid-repeat-auto-fill-fit-012.html create mode 100644 layout/reftests/css-grid/grid-repeat-auto-fill-fit-013-ref.html create mode 100644 layout/reftests/css-grid/grid-repeat-auto-fill-fit-013.html diff --git a/dom/grid/test/chrome.ini b/dom/grid/test/chrome.ini index 2241cf9ebb..169fa9b893 100644 --- a/dom/grid/test/chrome.ini +++ b/dom/grid/test/chrome.ini @@ -2,6 +2,7 @@ [chrome/test_grid_fragmentation.html] [chrome/test_grid_implicit.html] [chrome/test_grid_lines.html] +[chrome/test_grid_line_numbers.html] [chrome/test_grid_object.html] [chrome/test_grid_repeats.html] [chrome/test_grid_tracks.html] diff --git a/dom/grid/test/chrome/test_grid_implicit.html b/dom/grid/test/chrome/test_grid_implicit.html index c7782e0e5f..1f71426583 100644 --- a/dom/grid/test/chrome/test_grid_implicit.html +++ b/dom/grid/test/chrome/test_grid_implicit.html @@ -33,6 +33,11 @@ body { grid-template-rows: [areaA-end areaB-start areaC-end] 50px [areaA-start areaB-end areaC-start]; } +.template4 { + grid-template-columns: 100px 50px 100px; + grid-template-rows: 50px; +} + .box { background-color: #444; color: #fff; @@ -50,6 +55,9 @@ body { .d { grid-area: areaD; } +.e { + grid-column: -7 / 5; +} @@ -246,5 +299,9 @@ function runTests() {
C
+
+
E
+
+ diff --git a/dom/grid/test/chrome/test_grid_line_numbers.html b/dom/grid/test/chrome/test_grid_line_numbers.html new file mode 100644 index 0000000000..c8e5226b60 --- /dev/null +++ b/dom/grid/test/chrome/test_grid_line_numbers.html @@ -0,0 +1,101 @@ + + + + + + + + + + + + +
+
A
+
B
+
C
+
+ +
+
A
+
B
+
C
+
D
+
+ + + diff --git a/layout/generic/nsGridContainerFrame.cpp b/layout/generic/nsGridContainerFrame.cpp index 59f58f268a..054f012978 100644 --- a/layout/generic/nsGridContainerFrame.cpp +++ b/layout/generic/nsGridContainerFrame.cpp @@ -725,9 +725,6 @@ struct nsGridContainerFrame::LineRange mEnd > mStart, "invalid line range"); mEnd -= aNumRemovedTracks[mEnd]; } - if (mStart == mEnd) { - mEnd = nsGridContainerFrame::kAutoLine; - } } /** * Return the contribution of this line range for step 2 in @@ -5179,10 +5176,15 @@ nsGridContainerFrame::LineRange::ToPositionAndLengthForAbsPos( : GridLineSide::eBeforeGridGap; nscoord endPos = aTracks.GridLineEdge(mEnd, side); *aLength = std::max(aGridOrigin + endPos, 0); - } else { + } else if (MOZ_LIKELY(mStart != mEnd)) { nscoord pos; ToPositionAndLength(aTracks.mSizes, &pos, aLength); *aPos = aGridOrigin + pos; + } else { + // The grid area only covers removed 'auto-fit' tracks. + nscoord pos = aTracks.GridLineEdge(mStart, GridLineSide::eBeforeGridGap); + *aPos = aGridOrigin + pos; + *aLength = nscoord(0); } } } diff --git a/layout/generic/test/mochitest.ini b/layout/generic/test/mochitest.ini index 934ffc8a44..33dacddabc 100644 --- a/layout/generic/test/mochitest.ini +++ b/layout/generic/test/mochitest.ini @@ -138,3 +138,7 @@ support-files = file_taintedfilters_feDisplacementMap-tainted-1.svg file_tainted support-files = file_scroll_position_restore.html [test_scroll_animation_restore.html] [test_scroll_position_iframe.html] +[test_grid_track_sizing_algo_001.html] +skip-if = debug == true # the test is slow +[test_grid_track_sizing_algo_002.html] +skip-if = debug == true # the test is slow diff --git a/layout/generic/test/test_grid_track_sizing_algo_001.html b/layout/generic/test/test_grid_track_sizing_algo_001.html new file mode 100644 index 0000000000..68956c2df9 --- /dev/null +++ b/layout/generic/test/test_grid_track_sizing_algo_001.html @@ -0,0 +1,1641 @@ + + + + + CSS Grid Test: intrinsic track sizing with spanning items + + + + + + + + + + + + + + + diff --git a/layout/generic/test/test_grid_track_sizing_algo_002.html b/layout/generic/test/test_grid_track_sizing_algo_002.html new file mode 100644 index 0000000000..40f50e20f4 --- /dev/null +++ b/layout/generic/test/test_grid_track_sizing_algo_002.html @@ -0,0 +1,1641 @@ + + + + + CSS Grid Test: intrinsic track sizing with spanning items + + + + + + + + + + + + + + + diff --git a/layout/reftests/css-grid/grid-col-max-sizing-max-content-001-ref.html b/layout/reftests/css-grid/grid-col-max-sizing-max-content-001-ref.html index eda06249b3..da30a8b89b 100644 --- a/layout/reftests/css-grid/grid-col-max-sizing-max-content-001-ref.html +++ b/layout/reftests/css-grid/grid-col-max-sizing-max-content-001-ref.html @@ -17,9 +17,9 @@ body,html { color:black; background:white; font-size:16px; padding:0; margin:0; clear:left; } -.c1 { min-width:40px; margin-bottom: 2px; margin-right: 47px; } +.c1 { width:40px; margin-bottom: 2px; margin-right: 47px; } .r1 { min-width:70px; margin-left: 38px; margin-top: 2px; } -.c3 { min-width:0; margin: 2px 18px 1px 85px; } +.c3 { width:10px; margin: 2px 18px 1px 71px; } span { display: block; @@ -52,21 +52,22 @@ x { display:inline-block; width:10px; height:18px; }     +
-  +     
-  +       
-  +     
@@ -74,13 +75,13 @@ x { display:inline-block; width:10px; height:18px; }
    -  + 
    -  + 
diff --git a/layout/reftests/css-grid/grid-col-max-sizing-max-content-002-ref.html b/layout/reftests/css-grid/grid-col-max-sizing-max-content-002-ref.html index 23ca12e7bf..eeb4e407ff 100644 --- a/layout/reftests/css-grid/grid-col-max-sizing-max-content-002-ref.html +++ b/layout/reftests/css-grid/grid-col-max-sizing-max-content-002-ref.html @@ -21,9 +21,9 @@ body,html { color:black; background:white; font-size:16px; padding:0; margin:0; clear:left; } -.c1 { min-width:40px; margin-bottom: 2px; margin-right: 47px; } +.c1 { width:40px; margin-bottom: 2px; margin-right: 47px; } .r1 { min-width:70px; margin-left: 38px; margin-top: 2px; } -.c3 { min-width:0; margin: 2px 18px 1px 85px; } +.c3 { width:10px; margin: 2px 18px 1px 71px; } span { display: block; @@ -56,21 +56,22 @@ x { display:inline-block; width:10px; height:18px; }     +
-  +     
-  +       
-  +     
@@ -78,13 +79,13 @@ x { display:inline-block; width:10px; height:18px; }
    -  + 
    -  + 
diff --git a/layout/reftests/css-grid/grid-flex-min-sizing-002-ref.html b/layout/reftests/css-grid/grid-flex-min-sizing-002-ref.html index d9af7e43c7..d811447ff8 100644 --- a/layout/reftests/css-grid/grid-flex-min-sizing-002-ref.html +++ b/layout/reftests/css-grid/grid-flex-min-sizing-002-ref.html @@ -127,10 +127,10 @@ body,html { color:black; background:white; font-family:monospace; font-size:16px } .gF { - grid-template-columns: 22px - 1px - 1px - auto; + grid-template-columns: 2px + 20px + 2px + 0; } diff --git a/layout/reftests/css-grid/grid-max-sizing-flex-004-ref.html b/layout/reftests/css-grid/grid-max-sizing-flex-004-ref.html index 6446c0ee64..b0ac02bf5e 100644 --- a/layout/reftests/css-grid/grid-max-sizing-flex-004-ref.html +++ b/layout/reftests/css-grid/grid-max-sizing-flex-004-ref.html @@ -51,8 +51,8 @@ x { display:inline-block; height:10px; width:18px; }
--> -
-
+
+
+ + + Reference: repeat(auto-fit) with removed tracks + + + + + +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ + + diff --git a/layout/reftests/css-grid/grid-repeat-auto-fill-fit-012.html b/layout/reftests/css-grid/grid-repeat-auto-fill-fit-012.html new file mode 100644 index 0000000000..7ed0843af2 --- /dev/null +++ b/layout/reftests/css-grid/grid-repeat-auto-fill-fit-012.html @@ -0,0 +1,160 @@ + + + + + CSS Grid Test: repeat(auto-fit) with removed tracks + + + + + + + +
+
+ + +
+
+ +
+
+ + +
+
+ +
+
+ + +
+
+ +
+
+ + +
+
+ +
+
+ + +
+
+ +
+
+ + +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ + +
+
+ +
+
+ + +
+
+ +
+
+ + +
+
+ +
+
+ + +
+
+ +
+
+ + +
+
+ +
+
+ + +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ + + diff --git a/layout/reftests/css-grid/grid-repeat-auto-fill-fit-013-ref.html b/layout/reftests/css-grid/grid-repeat-auto-fill-fit-013-ref.html new file mode 100644 index 0000000000..9b8267f88d --- /dev/null +++ b/layout/reftests/css-grid/grid-repeat-auto-fill-fit-013-ref.html @@ -0,0 +1,116 @@ + + + + +CSS Grid Test Reference: test auto placement in repeat auto-fit grids with leading implicit tracks + + + + +
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + diff --git a/layout/reftests/css-grid/grid-repeat-auto-fill-fit-013.html b/layout/reftests/css-grid/grid-repeat-auto-fill-fit-013.html new file mode 100644 index 0000000000..5a9c05d734 --- /dev/null +++ b/layout/reftests/css-grid/grid-repeat-auto-fill-fit-013.html @@ -0,0 +1,135 @@ + + + + +CSS Grid Test: test placement in repeat auto-fit grids with leading implicit tracks + + + + + + + +
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + diff --git a/layout/reftests/css-grid/grid-track-intrinsic-sizing-002-ref.html b/layout/reftests/css-grid/grid-track-intrinsic-sizing-002-ref.html index 7fb00f1daf..23dc42b692 100644 --- a/layout/reftests/css-grid/grid-track-intrinsic-sizing-002-ref.html +++ b/layout/reftests/css-grid/grid-track-intrinsic-sizing-002-ref.html @@ -27,34 +27,34 @@ body,html { color:black; background:white; font-family:monospace; font-size:16px background: grey; } .g1 .d1 { - width: 52px; + width: 0px; } .g2 .d1 { - width: 56px; + width: 0px; } .g2f .d1 { - width: 69px; + width: 0px; } .g3 .d1 { - width: 56px; + width: 0px; } .g4 .d1 { - width: 96px; + width: 80px; } .g4f .d1 { - width: 69px; + width: 0px; } .g5 .d1 { - width: 96px; + width: 80px; } .g6 .d1 { - width: 69px; + width: 0px; } .g6f .d1 { - width: 69px; + width: 0px; } .g7 .d1 { - width: 69px; + width: 0px; } .g8 .t { width: 196px; @@ -63,19 +63,19 @@ body,html { color:black; background:white; font-family:monospace; font-size:16px width: 200px; } .g9 .d1 { - width: 69px; + width: 0px; } .gA .d1 { - width: 93px; + width: 80px; } .gB .d1 { - width: 93px; + width: 80px; } .gC .d1 { - width: 93px; + width: 80px; } .gD .d1 { - width: 93px; + width: 80px; } .t { grid-column: span 1; border:2px solid; } diff --git a/layout/reftests/css-grid/grid-track-intrinsic-sizing-003-ref.html b/layout/reftests/css-grid/grid-track-intrinsic-sizing-003-ref.html index bc52f4ca05..01739578ce 100644 --- a/layout/reftests/css-grid/grid-track-intrinsic-sizing-003-ref.html +++ b/layout/reftests/css-grid/grid-track-intrinsic-sizing-003-ref.html @@ -27,34 +27,34 @@ body,html { color:black; background:white; font-family:monospace; font-size:16px background: grey; } .g1 .d1 { - width: 52px; + width: 0px; } .g2 .d1 { - width: 56px; + width: 0px; } .g2f .d1 { width: 69px; } .g3 .d1 { - width: 56px; + width: 0px; } .g4 .d1 { - width: 96px; + width: 80px; } .g4f .d1 { width: 104px; } .g5 .d1 { - width: 96px; + width: 80px; } .g6 .d1 { - width: 69px; + width: 0px; } .g6f .d1 { width: 89px; } .g7 .d1 { - width: 69px; + width: 0px; } .g8 .t { width: 196px; @@ -63,19 +63,19 @@ body,html { color:black; background:white; font-family:monospace; font-size:16px width: 200px; } .g9 .d1 { - width: 69px; + width: 0px; } .gA .d1 { - width: 93px; + width: 80px; } .gB .d1 { - width: 93px; + width: 80px; } .gC .d1 { - width: 93px; + width: 80px; } .gD .d1 { - width: 93px; + width: 80px; } .d2 { position: absolute; @@ -84,10 +84,10 @@ body,html { color:black; background:white; font-family:monospace; font-size:16px background: blue; } .g1 .d2 { - width: 448px; + width: 500px; } .g2 .d2 { - width: 444px; + width: 500px; } .g2f .d2 { right: auto; @@ -95,10 +95,10 @@ body,html { color:black; background:white; font-family:monospace; font-size:16px width: 35px; } .g3 .d2 { - width: 444px; + width: 500px; } .g4 .d2 { - width: 404px; + width: 420px; } .g4f .d2 { right: auto; @@ -106,10 +106,10 @@ body,html { color:black; background:white; font-family:monospace; font-size:16px width: 35px; } .g5 .d2 { - width: 404px; + width: 420px; } .g6 .d2 { - width: 431px; + width: 500px; } .g6f .d2 { right: auto; @@ -117,25 +117,25 @@ body,html { color:black; background:white; font-family:monospace; font-size:16px width: 35px; } .g7 .d2 { - width: 431px; + width: 500px; } .g8 .d2 { width: 300px; } .g9 .d2 { - width: 431px; + width: 500px; } .gA .d2 { - width: 407px; + width: 420px; } .gB .d2 { - width: 407px; + width: 420px; } .gC .d2 { - width: 407px; + width: 420px; } .gD .d2 { - width: 407px; + width: 420px; } .t { grid-column: span 1; border:2px solid; } diff --git a/layout/reftests/css-grid/reftest.list b/layout/reftests/css-grid/reftest.list index 3087ca49b2..7c5e6be514 100644 --- a/layout/reftests/css-grid/reftest.list +++ b/layout/reftests/css-grid/reftest.list @@ -112,9 +112,9 @@ skip-if(Android) == grid-auto-min-sizing-percent-001.html grid-auto-min-sizing-p == grid-item-auto-min-size-clamp-001.html grid-item-auto-min-size-clamp-001-ref.html == grid-item-auto-min-size-clamp-002.html grid-item-auto-min-size-clamp-002-ref.html == grid-item-auto-min-size-clamp-003.html grid-item-auto-min-size-clamp-003-ref.html -== grid-item-auto-min-size-clamp-004.html grid-item-auto-min-size-clamp-004-ref.html +# == grid-item-auto-min-size-clamp-004.html grid-item-auto-min-size-clamp-004-ref.html # bug 1421976 == grid-item-auto-min-size-clamp-005.html grid-item-auto-min-size-clamp-005-ref.html -== grid-item-auto-min-size-clamp-006.html grid-item-auto-min-size-clamp-006-ref.html +# == grid-item-auto-min-size-clamp-006.html grid-item-auto-min-size-clamp-006-ref.html # bug 1421976 == grid-item-auto-min-size-clamp-007.html grid-item-auto-min-size-clamp-007-ref.html == grid-item-overflow-stretch-001.html grid-item-overflow-stretch-001-ref.html == grid-item-overflow-stretch-002.html grid-item-overflow-stretch-002-ref.html @@ -184,6 +184,8 @@ skip-if(Android&&isDebugBuild) == grid-row-gap-004.html grid-row-gap-004-ref.htm == grid-repeat-auto-fill-fit-009.html grid-repeat-auto-fill-fit-009-ref.html == grid-repeat-auto-fill-fit-010.html grid-repeat-auto-fill-fit-010-ref.html == grid-repeat-auto-fill-fit-011.html grid-repeat-auto-fill-fit-010-ref.html +== grid-repeat-auto-fill-fit-012.html grid-repeat-auto-fill-fit-012-ref.html +== grid-repeat-auto-fill-fit-013.html grid-repeat-auto-fill-fit-013-ref.html == grid-item-blockifying-001.html grid-item-blockifying-001-ref.html == grid-fragmentation-001.html grid-fragmentation-001-ref.html == grid-fragmentation-002.html grid-fragmentation-002-ref.html From e4c397f0d90dd1210fa1d461be86955008444bd0 Mon Sep 17 00:00:00 2001 From: Gaming4JC Date: Sat, 28 Sep 2019 23:36:05 -0400 Subject: [PATCH 4/8] Issue #1230 - Part 1: Fix Back-computing percentages for intrinsic sizing in Layout CSS-Grid List of relevant patches applied: 1398537 part 2 - [css-multicol] Implement percentages for 'column-gap' (Gecko part). 1434478 part 1 - [css-grid] Stop back-computing percentage grid gaps when the percentage basis is indefinite. Treat them as zero sized instead. 1434478 part 2 - Stop back-computing percentage padding/margin when the percentage basis is indefinite. Treat them as zero sized instead. 1434478 part 3 - Remove IntrinsicISizeOffsetData::hPctPadding/hPctMargin members since they are now unused. 1434478 part 4 - Factor out constants like NS_UNCONSTRAINEDSIZE so they can be used in headers without needing nsIFrame.h (idempotent patch). 1434478 part 5 - Create nsLayoutUtils::ResolveToLength for resolving CSS (idempotent patch). 1434478 part 6 - Propagate a percentage basis to nsIFrame::IntrinsicISizeOffsets for resolving padding/margin. This is needed only for CSS Grid since in other cases we're only using IntrinsicISizeOffsets in the inline-axis and the percentage basis is always indefinite for *intrinsic sizing*. When calculating the intrinsic size of grid items in the grid container's block axis however, we do have a definite size for the grid area in the inline-axis and it should be used per: https://drafts.csswg.org/css-grid/#algo-overview "2. Next, the track sizing algorithm resolves the sizes of the grid rows, using the grid column sizes calculated in the previous step." (Percentage padding/margin for grid items is always resolved against the grid area's inline-size nowadays.) --- layout/base/LayoutConstants.h | 31 ++++ layout/base/moz.build | 4 + layout/base/nsLayoutUtils.cpp | 76 ++++------ layout/base/nsLayoutUtils.h | 95 +++++++++---- layout/generic/nsColumnSetFrame.cpp | 19 ++- layout/generic/nsFrame.cpp | 89 +++++------- layout/generic/nsFrame.h | 3 +- layout/generic/nsGridContainerFrame.cpp | 180 ++++++------------------ layout/generic/nsIFrame.h | 31 ++-- layout/style/nsCSSPropList.h | 2 +- layout/style/nsStyleStruct.h | 2 +- layout/style/test/property_database.js | 4 +- layout/tables/nsTableCellFrame.cpp | 6 +- layout/tables/nsTableCellFrame.h | 3 +- layout/tables/nsTableFrame.cpp | 7 +- layout/tables/nsTableFrame.h | 3 +- 16 files changed, 238 insertions(+), 317 deletions(-) create mode 100644 layout/base/LayoutConstants.h diff --git a/layout/base/LayoutConstants.h b/layout/base/LayoutConstants.h new file mode 100644 index 0000000000..cd6e1c3f55 --- /dev/null +++ b/layout/base/LayoutConstants.h @@ -0,0 +1,31 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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/. */ + +/* constants used throughout the Layout module */ + +#ifndef LayoutConstants_h___ +#define LayoutConstants_h___ + +#include "nsSize.h" // for NS_MAXSIZE + +/** + * Constant used to indicate an unconstrained size. + */ +#define NS_UNCONSTRAINEDSIZE NS_MAXSIZE + +// NOTE: There are assumptions all over that these have the same value, +// namely NS_UNCONSTRAINEDSIZE. +#define NS_INTRINSICSIZE NS_UNCONSTRAINEDSIZE +#define NS_AUTOHEIGHT NS_UNCONSTRAINEDSIZE +#define NS_AUTOOFFSET NS_UNCONSTRAINEDSIZE + +// +1 is to avoid clamped huge margin values being processed as auto margins +#define NS_AUTOMARGIN (NS_UNCONSTRAINEDSIZE + 1) + +#define NS_INTRINSIC_WIDTH_UNKNOWN nscoord_MIN + + +#endif // LayoutConstants_h___ diff --git a/layout/base/moz.build b/layout/base/moz.build index 4308a6e4d0..afc683665a 100644 --- a/layout/base/moz.build +++ b/layout/base/moz.build @@ -13,6 +13,9 @@ with Files('Display*'): with Files('FrameLayerBuilder.*'): BUG_COMPONENT = ('Core', 'Layout: View Rendering') +with Files('LayoutConstants.*'): + BUG_COMPONENT = ('Core', 'Layout: View Rendering') + with Files('LayerState.*'): BUG_COMPONENT = ('Core', 'Layout: View Rendering') @@ -63,6 +66,7 @@ EXPORTS += [ 'FrameLayerBuilder.h', 'FrameProperties.h', 'LayerState.h', + 'LayoutConstants.h', 'LayoutLogging.h', 'nsArenaMemoryStats.h', 'nsBidi.h', diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index 06690b208b..21d20c69fa 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -4671,8 +4671,6 @@ GetDefiniteSize(const nsStyleCoord& aStyle, nscoord pb = aIsInlineAxis ? aPercentageBasis.value().ISize(wm) : aPercentageBasis.value().BSize(wm); if (pb == NS_UNCONSTRAINEDSIZE) { - // XXXmats given that we're calculating an intrinsic size here, - // maybe we should back-compute the calc-size using AddPercents? return false; } *aResult = std::max(0, calc->mLength + @@ -4916,12 +4914,9 @@ AddIntrinsicSizeOffset(nsRenderingContext* aRenderingContext, nscoord result = aContentSize; nscoord min = aContentMinSize; nscoord coordOutsideSize = 0; - float pctOutsideSize = 0; - float pctTotal = 0.0f; if (!(aFlags & nsLayoutUtils::IGNORE_PADDING)) { coordOutsideSize += aOffsets.hPadding; - pctOutsideSize += aOffsets.hPctPadding; } coordOutsideSize += aOffsets.hBorder; @@ -4929,21 +4924,15 @@ AddIntrinsicSizeOffset(nsRenderingContext* aRenderingContext, if (aBoxSizing == StyleBoxSizing::Border) { min += coordOutsideSize; result = NSCoordSaturatingAdd(result, coordOutsideSize); - pctTotal += pctOutsideSize; coordOutsideSize = 0; - pctOutsideSize = 0.0f; } coordOutsideSize += aOffsets.hMargin; - pctOutsideSize += aOffsets.hPctMargin; min += coordOutsideSize; result = NSCoordSaturatingAdd(result, coordOutsideSize); - pctTotal += pctOutsideSize; - const bool shouldAddPercent = aType == nsLayoutUtils::PREF_ISIZE || - (aFlags & nsLayoutUtils::ADD_PERCENTS); nscoord size; if (aType == nsLayoutUtils::MIN_ISIZE && (((aStyleSize.HasPercent() || aStyleMaxSize.HasPercent()) && @@ -4961,18 +4950,6 @@ AddIntrinsicSizeOffset(nsRenderingContext* aRenderingContext, GetIntrinsicCoord(aStyleSize, aRenderingContext, aFrame, PROP_WIDTH, size)) { result = size + coordOutsideSize; - if (shouldAddPercent) { - result = nsLayoutUtils::AddPercents(result, pctOutsideSize); - } - } else { - // NOTE: We could really do a lot better for percents and for some - // cases of calc() containing percent (certainly including any where - // the coefficient on the percent is positive and there are no max() - // expressions). However, doing better for percents wouldn't be - // backwards compatible. - if (shouldAddPercent) { - result = nsLayoutUtils::AddPercents(result, pctTotal); - } } nscoord maxSize = aFixedMaxSize ? *aFixedMaxSize : 0; @@ -4980,9 +4957,6 @@ AddIntrinsicSizeOffset(nsRenderingContext* aRenderingContext, GetIntrinsicCoord(aStyleMaxSize, aRenderingContext, aFrame, PROP_MAX_WIDTH, maxSize)) { maxSize += coordOutsideSize; - if (shouldAddPercent) { - maxSize = nsLayoutUtils::AddPercents(maxSize, pctOutsideSize); - } if (result > maxSize) { result = maxSize; } @@ -4993,17 +4967,11 @@ AddIntrinsicSizeOffset(nsRenderingContext* aRenderingContext, GetIntrinsicCoord(aStyleMinSize, aRenderingContext, aFrame, PROP_MIN_WIDTH, minSize)) { minSize += coordOutsideSize; - if (shouldAddPercent) { - minSize = nsLayoutUtils::AddPercents(minSize, pctOutsideSize); - } if (result < minSize) { result = minSize; } } - if (shouldAddPercent) { - min = nsLayoutUtils::AddPercents(min, pctTotal); - } if (result < min) { result = min; } @@ -5020,9 +4988,6 @@ AddIntrinsicSizeOffset(nsRenderingContext* aRenderingContext, : devSize.width); // GetMinimumWidgetSize() returns a border-box width. themeSize += aOffsets.hMargin; - if (shouldAddPercent) { - themeSize = nsLayoutUtils::AddPercents(themeSize, aOffsets.hPctMargin); - } if (themeSize > result || !canOverride) { result = themeSize; } @@ -5267,9 +5232,19 @@ nsLayoutUtils::IntrinsicForAxis(PhysicalAxis aAxis, min = aFrame->GetMinISize(aRenderingContext); } + nscoord pmPercentageBasis = NS_UNCONSTRAINEDSIZE; + if (aPercentageBasis.isSome()) { + // The padding/margin percentage basis is the inline-size in the parent's + // writing-mode. + auto childWM = aFrame->GetWritingMode(); + pmPercentageBasis = + aFrame->GetParent()->GetWritingMode().IsOrthogonalTo(childWM) ? + aPercentageBasis->BSize(childWM) : + aPercentageBasis->ISize(childWM); + } nsIFrame::IntrinsicISizeOffsetData offsets = - MOZ_LIKELY(isInlineAxis) ? aFrame->IntrinsicISizeOffsets() - : aFrame->IntrinsicBSizeOffsets(); + MOZ_LIKELY(isInlineAxis) ? aFrame->IntrinsicISizeOffsets(pmPercentageBasis) + : aFrame->IntrinsicBSizeOffsets(pmPercentageBasis); nscoord contentBoxSize = result; result = AddIntrinsicSizeOffset(aRenderingContext, aFrame, offsets, aType, boxSizing, result, min, styleISize, @@ -5310,11 +5285,12 @@ nsLayoutUtils::IntrinsicForContainer(nsRenderingContext* aRenderingContext, } /* static */ nscoord -nsLayoutUtils::MinSizeContributionForAxis(PhysicalAxis aAxis, +nsLayoutUtils::MinSizeContributionForAxis(PhysicalAxis aAxis, nsRenderingContext* aRC, - nsIFrame* aFrame, - IntrinsicISizeType aType, - uint32_t aFlags) + nsIFrame* aFrame, + IntrinsicISizeType aType, + const LogicalSize& aPercentageBasis, + uint32_t aFlags) { MOZ_ASSERT(aFrame); MOZ_ASSERT(aFrame->IsFlexOrGridItem(), @@ -5328,9 +5304,7 @@ nsLayoutUtils::MinSizeContributionForAxis(PhysicalAxis aAxis, aWM.IsVertical() ? "vertical" : "horizontal"); #endif - // Note: this method is only meant for grid/flex items which always - // include percentages in their intrinsic size. - aFlags |= nsLayoutUtils::ADD_PERCENTS; + // Note: this method is only meant for grid/flex items. const nsStylePosition* const stylePos = aFrame->StylePosition(); const nsStyleCoord* style = aAxis == eAxisHorizontal ? &stylePos->mMinWidth : &stylePos->mMinHeight; @@ -5375,11 +5349,17 @@ nsLayoutUtils::MinSizeContributionForAxis(PhysicalAxis aAxis, // wrapping inside of it should not apply font size inflation. AutoMaybeDisableFontInflation an(aFrame); - PhysicalAxis ourInlineAxis = - aFrame->GetWritingMode().PhysicalAxis(eLogicalAxisInline); + // The padding/margin percentage basis is the inline-size in the parent's + // writing-mode. + auto childWM = aFrame->GetWritingMode(); + nscoord pmPercentageBasis = + aFrame->GetParent()->GetWritingMode().IsOrthogonalTo(childWM) ? + aPercentageBasis.BSize(childWM) : + aPercentageBasis.ISize(childWM); + PhysicalAxis ourInlineAxis = childWM.PhysicalAxis(eLogicalAxisInline); nsIFrame::IntrinsicISizeOffsetData offsets = - ourInlineAxis == aAxis ? aFrame->IntrinsicISizeOffsets() - : aFrame->IntrinsicBSizeOffsets(); + ourInlineAxis == aAxis ? aFrame->IntrinsicISizeOffsets(pmPercentageBasis) + : aFrame->IntrinsicBSizeOffsets(pmPercentageBasis); nscoord result = 0; nscoord min = 0; diff --git a/layout/base/nsLayoutUtils.h b/layout/base/nsLayoutUtils.h index 0a82dbf6a5..bba1f32652 100644 --- a/layout/base/nsLayoutUtils.h +++ b/layout/base/nsLayoutUtils.h @@ -6,6 +6,7 @@ #ifndef nsLayoutUtils_h__ #define nsLayoutUtils_h__ +#include "LayoutConstants.h" #include "mozilla/MemoryReporting.h" #include "mozilla/ArrayUtils.h" #include "mozilla/Maybe.h" @@ -154,6 +155,7 @@ public: typedef mozilla::ScreenMargin ScreenMargin; typedef mozilla::LayoutDeviceIntSize LayoutDeviceIntSize; typedef mozilla::StyleGeometryBox StyleGeometryBox; + typedef mozilla::LogicalSize LogicalSize; /** * Finds previously assigned ViewID for the given content element, if any. @@ -1381,7 +1383,8 @@ public: * variations if that's what matches aAxis) and its padding, border and margin * in the corresponding dimension. * @param aPercentageBasis an optional percentage basis (in aFrame's WM). - * Pass NS_UNCONSTRAINEDSIZE if the basis is indefinite in either/both axes. + * If the basis is indefinite in a given axis, pass a size with + * NS_UNCONSTRAINEDSIZE in that component. * If you pass Nothing() a percentage basis will be calculated from aFrame's * ancestors' computed size in the relevant axis, if needed. * @param aMarginBoxMinSizeClamp make the result fit within this margin-box @@ -1395,14 +1398,13 @@ public: IGNORE_PADDING = 0x01, BAIL_IF_REFLOW_NEEDED = 0x02, // returns NS_INTRINSIC_WIDTH_UNKNOWN if so MIN_INTRINSIC_ISIZE = 0x04, // use min-width/height instead of width/height - ADD_PERCENTS = 0x08, // apply AddPercents also for MIN_ISIZE }; static nscoord IntrinsicForAxis(mozilla::PhysicalAxis aAxis, nsRenderingContext* aRenderingContext, nsIFrame* aFrame, IntrinsicISizeType aType, - const mozilla::Maybe& aPercentageBasis = mozilla::Nothing(), + const mozilla::Maybe& aPercentageBasis = mozilla::Nothing(), uint32_t aFlags = 0, nscoord aMarginBoxMinSizeClamp = NS_MAXSIZE); /** @@ -1427,31 +1429,18 @@ public: * calculates the result as if the 'min-' computed value is zero. * Otherwise, return NS_UNCONSTRAINEDSIZE. * + * @param aPercentageBasis the percentage basis (in aFrame's WM). + * Pass NS_UNCONSTRAINEDSIZE if the basis is indefinite in either/both axes. * @note this behavior is specific to Grid/Flexbox (currently) so aFrame * should be a grid/flex item. */ - static nscoord MinSizeContributionForAxis(mozilla::PhysicalAxis aAxis, - nsRenderingContext* aRC, - nsIFrame* aFrame, - IntrinsicISizeType aType, - uint32_t aFlags = 0); - - /** - * This function increases an initial intrinsic size, 'aCurrent', according - * to the given 'aPercent', such that the size-increase makes up exactly - * 'aPercent' percent of the returned value. If 'aPercent' or 'aCurrent' are - * less than or equal to zero the original 'aCurrent' value is returned. - * If 'aPercent' is greater than or equal to 1.0 the value nscoord_MAX is - * returned. - */ - static nscoord AddPercents(nscoord aCurrent, float aPercent) - { - if (aPercent > 0.0f && aCurrent > 0) { - return MOZ_UNLIKELY(aPercent >= 1.0f) ? nscoord_MAX - : NSToCoordRound(float(aCurrent) / (1.0f - aPercent)); - } - return aCurrent; - } + static nscoord + MinSizeContributionForAxis(mozilla::PhysicalAxis aAxis, + nsRenderingContext* aRC, + nsIFrame* aFrame, + IntrinsicISizeType aType, + const LogicalSize& aPercentageBasis, + uint32_t aFlags = 0); /* * Convert nsStyleCoord to nscoord when percentages depend on the @@ -2876,6 +2865,62 @@ public: static nsRect ComputeGeometryBox(nsIFrame* aFrame, StyleGeometryBox aGeometryBox); + /** + * Resolve a CSS value to a definite size. + */ + template + static nscoord ResolveToLength(const nsStyleCoord& aCoord, + nscoord aPercentageBasis) + { + NS_WARNING_ASSERTION(aPercentageBasis >= nscoord(0), "nscoord overflow?"); + + switch (aCoord.GetUnit()) { + case eStyleUnit_Coord: + MOZ_ASSERT(!clampNegativeResultToZero || aCoord.GetCoordValue() >= 0, + "This value should have been rejected by the style system"); + return aCoord.GetCoordValue(); + case eStyleUnit_Percent: + if (aPercentageBasis == NS_UNCONSTRAINEDSIZE) { + return nscoord(0); + } + MOZ_ASSERT(!clampNegativeResultToZero || aCoord.GetPercentValue() >= 0, + "This value should have been rejected by the style system"); + return NSToCoordFloorClamped(aPercentageBasis * + aCoord.GetPercentValue()); + case eStyleUnit_Calc: { + nsStyleCoord::Calc* calc = aCoord.GetCalcValue(); + nscoord result; + if (aPercentageBasis == NS_UNCONSTRAINEDSIZE) { + result = calc->mLength; + } else { + result = calc->mLength + + NSToCoordFloorClamped(aPercentageBasis * calc->mPercent); + } + if (clampNegativeResultToZero && result < 0) { + return nscoord(0); + } + return result; + } + default: + MOZ_ASSERT_UNREACHABLE("Unexpected unit!"); + return nscoord(0); + } + } + + /** + * Resolve a column-gap/row-gap to a definite size. + * @note This method resolves 'normal' to zero. + * Callers who want different behavior should handle 'normal' on their own. + */ + static nscoord ResolveGapToLength(const nsStyleCoord& aGap, + nscoord aPercentageBasis) + { + if (aGap.GetUnit() == eStyleUnit_Normal) { + return nscoord(0); + } + return ResolveToLength(aGap, aPercentageBasis); + } + private: static uint32_t sFontSizeInflationEmPerLine; static uint32_t sFontSizeInflationMinTwips; diff --git a/layout/generic/nsColumnSetFrame.cpp b/layout/generic/nsColumnSetFrame.cpp index ad36ba1a88..6ea15d4d2f 100644 --- a/layout/generic/nsColumnSetFrame.cpp +++ b/layout/generic/nsColumnSetFrame.cpp @@ -183,18 +183,15 @@ nsColumnSetFrame::GetAvailableContentBSize(const ReflowInput& aReflowInput) static nscoord GetColumnGap(nsColumnSetFrame* aFrame, - const nsStyleColumn* aColStyle) + const nsStyleColumn* aColStyle, + nscoord aPercentageBasis) { - if (eStyleUnit_Normal == aColStyle->mColumnGap.GetUnit()) + const auto& columnGap = aColStyle->mColumnGap; + if (columnGap.GetUnit() == eStyleUnit_Normal) { return aFrame->StyleFont()->mFont.size; - if (eStyleUnit_Coord == aColStyle->mColumnGap.GetUnit()) { - nscoord colGap = aColStyle->mColumnGap.GetCoordValue(); - NS_ASSERTION(colGap >= 0, "negative column gap"); - return colGap; } - NS_NOTREACHED("Unknown gap type"); - return 0; + return nsLayoutUtils::ResolveGapToLength(columnGap, aPercentageBasis); } nsColumnSetFrame::ReflowConfig @@ -227,7 +224,7 @@ nsColumnSetFrame::ChooseColumnStrategy(const ReflowInput& aReflowInput, colBSize = std::min(colBSize, aReflowInput.ComputedMaxBSize()); } - nscoord colGap = GetColumnGap(this, colStyle); + nscoord colGap = GetColumnGap(this, colStyle, aReflowInput.ComputedISize()); int32_t numColumns = colStyle->mColumnCount; // If column-fill is set to 'balance', then we want to balance the columns. @@ -403,7 +400,7 @@ nsColumnSetFrame::GetMinISize(nsRenderingContext *aRenderingContext) // include n-1 column gaps. colISize = iSize; iSize *= colStyle->mColumnCount; - nscoord colGap = GetColumnGap(this, colStyle); + nscoord colGap = GetColumnGap(this, colStyle, NS_UNCONSTRAINEDSIZE); iSize += colGap * (colStyle->mColumnCount - 1); // The multiplication above can make 'width' negative (integer overflow), // so use std::max to protect against that. @@ -424,7 +421,7 @@ nsColumnSetFrame::GetPrefISize(nsRenderingContext *aRenderingContext) nscoord result = 0; DISPLAY_PREF_WIDTH(this, result); const nsStyleColumn* colStyle = StyleColumn(); - nscoord colGap = GetColumnGap(this, colStyle); + nscoord colGap = GetColumnGap(this, colStyle, NS_UNCONSTRAINEDSIZE); nscoord colISize; if (colStyle->mColumnWidth.GetUnit() == eStyleUnit_Coord) { diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index bd96f213b0..a531dea07f 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -4515,68 +4515,44 @@ nsIFrame::InlinePrefISizeData::ForceBreak() mSkipWhitespace = true; } -static void -AddCoord(const nsStyleCoord& aStyle, - nsIFrame* aFrame, - nscoord* aCoord, float* aPercent, - bool aClampNegativeToZero) +static nscoord +ResolveMargin(const nsStyleCoord& aStyle, nscoord aPercentageBasis) { - switch (aStyle.GetUnit()) { - case eStyleUnit_Coord: { - NS_ASSERTION(!aClampNegativeToZero || aStyle.GetCoordValue() >= 0, - "unexpected negative value"); - *aCoord += aStyle.GetCoordValue(); - return; - } - case eStyleUnit_Percent: { - NS_ASSERTION(!aClampNegativeToZero || aStyle.GetPercentValue() >= 0.0f, - "unexpected negative value"); - *aPercent += aStyle.GetPercentValue(); - return; - } - case eStyleUnit_Calc: { - const nsStyleCoord::Calc *calc = aStyle.GetCalcValue(); - if (aClampNegativeToZero) { - // This is far from ideal when one is negative and one is positive. - *aCoord += std::max(calc->mLength, 0); - *aPercent += std::max(calc->mPercent, 0.0f); - } else { - *aCoord += calc->mLength; - *aPercent += calc->mPercent; - } - return; - } - default: { - return; - } + if (aStyle.GetUnit() == eStyleUnit_Auto) { + return nscoord(0); } + return nsLayoutUtils::ResolveToLength(aStyle, aPercentageBasis); +} + +static nscoord +ResolvePadding(const nsStyleCoord& aStyle, nscoord aPercentageBasis) +{ + return nsLayoutUtils::ResolveToLength(aStyle, aPercentageBasis); } static nsIFrame::IntrinsicISizeOffsetData -IntrinsicSizeOffsets(nsIFrame* aFrame, bool aForISize) +IntrinsicSizeOffsets(nsIFrame* aFrame, nscoord aPercentageBasis, bool aForISize) { nsIFrame::IntrinsicISizeOffsetData result; WritingMode wm = aFrame->GetWritingMode(); - const nsStyleMargin* styleMargin = aFrame->StyleMargin(); + const auto& margin = aFrame->StyleMargin()->mMargin; bool verticalAxis = aForISize == wm.IsVertical(); - AddCoord(verticalAxis ? styleMargin->mMargin.GetTop() - : styleMargin->mMargin.GetLeft(), - aFrame, &result.hMargin, &result.hPctMargin, - false); - AddCoord(verticalAxis ? styleMargin->mMargin.GetBottom() - : styleMargin->mMargin.GetRight(), - aFrame, &result.hMargin, &result.hPctMargin, - false); + if (verticalAxis) { + result.hMargin += ResolveMargin(margin.GetTop(), aPercentageBasis); + result.hMargin += ResolveMargin(margin.GetBottom(), aPercentageBasis); + } else { + result.hMargin += ResolveMargin(margin.GetLeft(), aPercentageBasis); + result.hMargin += ResolveMargin(margin.GetRight(), aPercentageBasis); + } - const nsStylePadding* stylePadding = aFrame->StylePadding(); - AddCoord(verticalAxis ? stylePadding->mPadding.GetTop() - : stylePadding->mPadding.GetLeft(), - aFrame, &result.hPadding, &result.hPctPadding, - true); - AddCoord(verticalAxis ? stylePadding->mPadding.GetBottom() - : stylePadding->mPadding.GetRight(), - aFrame, &result.hPadding, &result.hPctPadding, - true); + const auto& padding = aFrame->StylePadding()->mPadding; + if (verticalAxis) { + result.hPadding += ResolvePadding(padding.GetTop(), aPercentageBasis); + result.hPadding += ResolvePadding(padding.GetBottom(), aPercentageBasis); + } else { + result.hPadding += ResolvePadding(padding.GetLeft(), aPercentageBasis); + result.hPadding += ResolvePadding(padding.GetRight(), aPercentageBasis); + } const nsStyleBorder* styleBorder = aFrame->StyleBorder(); if (verticalAxis) { @@ -4606,22 +4582,21 @@ IntrinsicSizeOffsets(nsIFrame* aFrame, bool aForISize) result.hPadding = presContext->DevPixelsToAppUnits(verticalAxis ? padding.TopBottom() : padding.LeftRight()); - result.hPctPadding = 0; } } return result; } /* virtual */ nsIFrame::IntrinsicISizeOffsetData -nsFrame::IntrinsicISizeOffsets() +nsFrame::IntrinsicISizeOffsets(nscoord aPercentageBasis) { - return IntrinsicSizeOffsets(this, true); + return IntrinsicSizeOffsets(this, aPercentageBasis, true); } nsIFrame::IntrinsicISizeOffsetData -nsIFrame::IntrinsicBSizeOffsets() +nsIFrame::IntrinsicBSizeOffsets(nscoord aPercentageBasis) { - return IntrinsicSizeOffsets(this, false); + return IntrinsicSizeOffsets(this, aPercentageBasis, false); } /* virtual */ IntrinsicSize diff --git a/layout/generic/nsFrame.h b/layout/generic/nsFrame.h index af1c95ef29..439e398562 100644 --- a/layout/generic/nsFrame.h +++ b/layout/generic/nsFrame.h @@ -261,7 +261,8 @@ public: InlineMinISizeData *aData) override; virtual void AddInlinePrefISize(nsRenderingContext *aRenderingContext, InlinePrefISizeData *aData) override; - virtual IntrinsicISizeOffsetData IntrinsicISizeOffsets() override; + IntrinsicISizeOffsetData + IntrinsicISizeOffsets(nscoord aPercentageBasis = NS_UNCONSTRAINEDSIZE) override; virtual mozilla::IntrinsicSize GetIntrinsicSize() override; virtual nsSize GetIntrinsicRatio() override; diff --git a/layout/generic/nsGridContainerFrame.cpp b/layout/generic/nsGridContainerFrame.cpp index 054f012978..959061e334 100644 --- a/layout/generic/nsGridContainerFrame.cpp +++ b/layout/generic/nsGridContainerFrame.cpp @@ -8,8 +8,8 @@ #include "nsGridContainerFrame.h" -#include // for std::stable_sort #include +#include // for div() #include "mozilla/CSSAlignUtils.h" #include "mozilla/dom/GridBinding.h" #include "mozilla/Function.h" @@ -127,43 +127,6 @@ ResolveToDefiniteSize(const nsStyleCoord& aCoord, nscoord aPercentBasis) nsRuleNode::ComputeCoordPercentCalc(aCoord, aPercentBasis)); } -static bool -GetPercentSizeParts(const nsStyleCoord& aCoord, nscoord* aLength, float* aPercent) -{ - switch (aCoord.GetUnit()) { - case eStyleUnit_Percent: - *aLength = 0; - *aPercent = aCoord.GetPercentValue(); - return true; - case eStyleUnit_Calc: { - nsStyleCoord::Calc* calc = aCoord.GetCalcValue(); - *aLength = calc->mLength; - *aPercent = calc->mPercent; - return true; - } - default: - return false; - } -} - -static void -ResolvePercentSizeParts(const nsStyleCoord& aCoord, nscoord aPercentBasis, - nscoord* aLength, float* aPercent) -{ - MOZ_ASSERT(aCoord.IsCoordPercentCalcUnit()); - if (aPercentBasis != NS_UNCONSTRAINEDSIZE) { - *aLength = std::max(nscoord(0), - nsRuleNode::ComputeCoordPercentCalc(aCoord, - aPercentBasis)); - *aPercent = 0.0f; - return; - } - if (!GetPercentSizeParts(aCoord, aLength, aPercent)) { - *aLength = aCoord.ToLength(); - *aPercent = 0.0f; - } -} - // Synthesize a baseline from a border box. For an alphabetical baseline // this is the end edge of the border box. For a central baseline it's // the center of the border box. @@ -1172,7 +1135,7 @@ struct nsGridContainerFrame::TrackSizingFunctions return 1; } nscoord repeatTrackSize = 0; - // Note that the repeat() track size is included in |sum| in this loop. + // Note that one repeat() track size is included in |sum| in this loop. nscoord sum = 0; const nscoord percentBasis = aSize; for (uint32_t i = 0; i < numTracks; ++i) { @@ -1189,54 +1152,31 @@ struct nsGridContainerFrame::TrackSizingFunctions } nscoord trackSize = ::ResolveToDefiniteSize(*coord, percentBasis); if (i == mRepeatAutoStart) { - if (percentBasis != NS_UNCONSTRAINEDSIZE) { - // Use a minimum 1px for the repeat() track-size. - if (trackSize < AppUnitsPerCSSPixel()) { - trackSize = AppUnitsPerCSSPixel(); - } + // Use a minimum 1px for the repeat() track-size. + if (trackSize < AppUnitsPerCSSPixel()) { + trackSize = AppUnitsPerCSSPixel(); } repeatTrackSize = trackSize; } sum += trackSize; } - nscoord gridGap; - float percentSum = 0.0f; - float gridGapPercent; - ResolvePercentSizeParts(aGridGap, percentBasis, &gridGap, &gridGapPercent); + nscoord gridGap = nsLayoutUtils::ResolveGapToLength(aGridGap, aSize); if (numTracks > 1) { // Add grid-gaps for all the tracks including the repeat() track. sum += gridGap * (numTracks - 1); - percentSum = gridGapPercent * (numTracks - 1); } // Calculate the max number of tracks that fits without overflow. nscoord available = maxFill != NS_UNCONSTRAINEDSIZE ? maxFill : aMinSize; - nscoord size = nsLayoutUtils::AddPercents(sum, percentSum); - if (available - size < 0) { + nscoord spaceToFill = available - sum; + if (spaceToFill <= 0) { // "if any number of repetitions would overflow, then 1 repetition" return 1; } - uint32_t numRepeatTracks = 1; - bool exactFit = false; - while (true) { - sum += gridGap + repeatTrackSize; - percentSum += gridGapPercent; - nscoord newSize = nsLayoutUtils::AddPercents(sum, percentSum); - if (newSize <= size) { - // Adding more repeat-tracks won't make forward progress. - return numRepeatTracks; - } - size = newSize; - nscoord remaining = available - size; - exactFit = remaining == 0; - if (remaining >= 0) { - ++numRepeatTracks; - } - if (remaining <= 0) { - break; - } - } - - if (!exactFit && maxFill == NS_UNCONSTRAINEDSIZE) { + // Calculate the max number of tracks that fits without overflow. + div_t q = div(spaceToFill, repeatTrackSize + gridGap); + // The +1 here is for the one repeat track we already accounted for above. + uint32_t numRepeatTracks = q.quot + 1; + if (q.rem != 0 && maxFill == NS_UNCONSTRAINEDSIZE) { // "Otherwise, if the grid container has a definite min size in // the relevant axis, the number of repetitions is the largest possible // positive integer that fulfills that minimum requirement." @@ -1882,13 +1822,6 @@ struct nsGridContainerFrame::Tracks WritingMode aWM, const LogicalSize& aContainerSize); - /** - * Return the intrinsic size by back-computing percentages as: - * IntrinsicSize = SumOfCoordSizes / (1 - SumOfPercentages). - */ - nscoord BackComputedIntrinsicSize(const TrackSizingFunctions& aFunctions, - const nsStyleCoord& aGridGap) const; - nscoord GridLineEdge(uint32_t aLine, GridLineSide aSide) const { if (MOZ_UNLIKELY(mSizes.IsEmpty())) { @@ -2198,11 +2131,10 @@ struct MOZ_STACK_CLASS nsGridContainerFrame::GridReflowInput } /** - * Calculate our track sizes. If the given aContentBox block-axis size is - * unconstrained, it is assigned to the resulting intrinsic block-axis size. + * Calculate our track sizes. */ void CalculateTrackSizes(const Grid& aGrid, - LogicalSize& aContentBox, + const LogicalSize& aContentBox, SizingConstraint aConstraint); /** @@ -2688,7 +2620,7 @@ struct MOZ_STACK_CLASS nsGridContainerFrame::Grid void nsGridContainerFrame::GridReflowInput::CalculateTrackSizes( const Grid& aGrid, - LogicalSize& aContentBox, + const LogicalSize& aContentBox, SizingConstraint aConstraint) { mCols.Initialize(mColFunctions, mGridStyle->mGridColumnGap, @@ -2706,12 +2638,6 @@ nsGridContainerFrame::GridReflowInput::CalculateTrackSizes( mRows.CalculateSizes(*this, mGridItems, mRowFunctions, aContentBox.BSize(mWM), &GridArea::mRows, aConstraint); - if (aContentBox.BSize(mWM) == NS_AUTOHEIGHT) { - aContentBox.BSize(mWM) = - mRows.BackComputedIntrinsicSize(mRowFunctions, mGridStyle->mGridRowGap); - mRows.mGridGap = - ::ResolveToDefiniteSize(mGridStyle->mGridRowGap, aContentBox.BSize(mWM)); - } } /** @@ -3813,7 +3739,7 @@ nsGridContainerFrame::Tracks::Initialize( aFunctions.MinSizingFor(i), aFunctions.MaxSizingFor(i)); } - mGridGap = ::ResolveToDefiniteSize(aGridGap, aContentBoxSize); + mGridGap = nsLayoutUtils::ResolveGapToLength(aGridGap, aContentBoxSize); mContentBoxSize = aContentBoxSize; } @@ -3894,8 +3820,7 @@ ContentContribution(const GridItemInfo& aGridItem, PhysicalAxis axis(aCBWM.PhysicalAxis(aAxis)); nscoord size = nsLayoutUtils::IntrinsicForAxis(axis, aRC, child, aConstraint, aPercentageBasis, - aFlags | nsLayoutUtils::BAIL_IF_REFLOW_NEEDED | - nsLayoutUtils::ADD_PERCENTS, + aFlags | nsLayoutUtils::BAIL_IF_REFLOW_NEEDED, aMinSizeClamp); if (size == NS_INTRINSIC_WIDTH_UNKNOWN) { // We need to reflow the child to find its BSize contribution. @@ -3932,15 +3857,7 @@ ContentContribution(const GridItemInfo& aGridItem, LogicalSize availableSize(childWM, availISize, availBSize); size = ::MeasuringReflow(child, aState.mReflowInput, aRC, availableSize, cbSize, iMinSizeClamp, bMinSizeClamp); - nsIFrame::IntrinsicISizeOffsetData offsets = child->IntrinsicBSizeOffsets(); - size += offsets.hMargin; - auto percent = offsets.hPctMargin; - if (availBSize == NS_UNCONSTRAINEDSIZE) { - // We always want to add in percent padding too, unless we already did so - // using a resolved column size above. - percent += offsets.hPctPadding; - } - size = nsLayoutUtils::AddPercents(size, percent); + size += child->GetLogicalUsedMargin(childWM).BStartEnd(childWM); nscoord overflow = size - aMinSizeClamp; if (MOZ_UNLIKELY(overflow > 0)) { nscoord contentSize = child->ContentBSize(childWM); @@ -4045,6 +3962,10 @@ MinSize(const GridItemInfo& aGridItem, return s; } + if (aCache->mPercentageBasis.isNothing()) { + aCache->mPercentageBasis.emplace(aState.PercentageBasisFor(aAxis, aGridItem)); + } + // https://drafts.csswg.org/css-grid/#min-size-auto // This calculates the min-content contribution from either a definite // min-width (or min-height depending on aAxis), or the "specified / @@ -4058,7 +3979,8 @@ MinSize(const GridItemInfo& aGridItem, "baseline offset should be zero when not baseline-aligned"); nscoord sz = aGridItem.mBaselineOffset[aAxis] + nsLayoutUtils::MinSizeContributionForAxis(axis, aRC, child, - nsLayoutUtils::MIN_ISIZE); + nsLayoutUtils::MIN_ISIZE, + *aCache->mPercentageBasis); const nsStyleCoord& style = axis == eAxisHorizontal ? stylePos->mMinWidth : stylePos->mMinHeight; auto unit = style.GetUnit(); @@ -4067,9 +3989,6 @@ MinSize(const GridItemInfo& aGridItem, child->StyleDisplay()->mOverflowX == NS_STYLE_OVERFLOW_VISIBLE)) { // Now calculate the "content size" part and return whichever is smaller. MOZ_ASSERT(unit != eStyleUnit_Enumerated || sz == NS_UNCONSTRAINEDSIZE); - if (aCache->mPercentageBasis.isNothing()) { - aCache->mPercentageBasis.emplace(aState.PercentageBasisFor(aAxis, aGridItem)); - } sz = std::min(sz, ContentContribution(aGridItem, aState, aRC, aCBWM, aAxis, aCache->mPercentageBasis, nsLayoutUtils::MIN_ISIZE, @@ -5097,36 +5016,6 @@ nsGridContainerFrame::Tracks::AlignJustifyContent( MOZ_ASSERT(!roundingError, "we didn't distribute all rounding error?"); } -nscoord -nsGridContainerFrame::Tracks::BackComputedIntrinsicSize( - const TrackSizingFunctions& aFunctions, - const nsStyleCoord& aGridGap) const -{ - // Sum up the current sizes (where percentage tracks were treated as 'auto') - // in 'size'. - nscoord size = 0; - for (size_t i = 0, len = mSizes.Length(); i < len; ++i) { - size += mSizes[i].mBase; - } - - // Add grid-gap contributions to 'size' and calculate a 'percent' sum. - float percent = 0.0f; - size_t numTracks = mSizes.Length(); - if (numTracks > 1) { - const size_t gridGapCount = numTracks - 1; - nscoord gridGapLength; - float gridGapPercent; - if (::GetPercentSizeParts(aGridGap, &gridGapLength, &gridGapPercent)) { - percent = gridGapCount * gridGapPercent; - } else { - gridGapLength = aGridGap.ToLength(); - } - size += gridGapCount * gridGapLength; - } - - return std::max(0, nsLayoutUtils::AddPercents(size, percent)); -} - void nsGridContainerFrame::LineRange::ToPositionAndLength( const nsTArray& aTrackSizes, nscoord* aPos, nscoord* aLength) const @@ -6292,7 +6181,7 @@ nsGridContainerFrame::Reflow(nsPresContext* aPresContext, LogicalSize computedSize(wm, computedISize, computedBSize); nscoord consumedBSize = 0; - nscoord bSize; + nscoord bSize = 0; if (!prevInFlow) { Grid grid; grid.PlaceGridItems(gridReflowInput, aReflowInput.ComputedMinSize(), @@ -6300,7 +6189,12 @@ nsGridContainerFrame::Reflow(nsPresContext* aPresContext, gridReflowInput.CalculateTrackSizes(grid, computedSize, SizingConstraint::eNoConstraint); - bSize = computedSize.BSize(wm); + // Note: we can't use GridLineEdge here since we haven't calculated + // the rows' mPosition yet (happens in AlignJustifyContent below). + for (const auto& sz : gridReflowInput.mRows.mSizes) { + bSize += sz.mBase; + } + bSize += gridReflowInput.mRows.SumOfGridGaps(); } else { consumedBSize = GetConsumedBSize(); gridReflowInput.InitializeForContinuation(this, consumedBSize); @@ -6699,8 +6593,14 @@ nsGridContainerFrame::IntrinsicISize(nsRenderingContext* aRenderingContext, state.mCols.CalculateSizes(state, state.mGridItems, state.mColFunctions, NS_UNCONSTRAINEDSIZE, &GridArea::mCols, constraint); - return state.mCols.BackComputedIntrinsicSize(state.mColFunctions, - state.mGridStyle->mGridColumnGap); + state.mCols.mGridGap = + nsLayoutUtils::ResolveGapToLength(state.mGridStyle->mGridColumnGap, + NS_UNCONSTRAINEDSIZE); + nscoord length = 0; + for (const TrackSize& sz : state.mCols.mSizes) { + length += sz.mBase; + } + return length + state.mCols.SumOfGridGaps(); } nscoord diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h index ec35684832..57f5c460c2 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -25,6 +25,7 @@ #include "CaretAssociationHint.h" #include "FrameProperties.h" +#include "LayoutConstants.h" #include "mozilla/layout/FrameChildList.h" #include "mozilla/Maybe.h" #include "mozilla/WritingModes.h" @@ -130,30 +131,12 @@ typedef uint32_t nsSplittableType; #define NS_FRAME_IS_NOT_SPLITTABLE(type)\ (0 == ((type) & NS_FRAME_SPLITTABLE)) -#define NS_INTRINSIC_WIDTH_UNKNOWN nscoord_MIN - //---------------------------------------------------------------------- #define NS_SUBTREE_DIRTY(_frame) \ (((_frame)->GetStateBits() & \ (NS_FRAME_IS_DIRTY | NS_FRAME_HAS_DIRTY_CHILDREN)) != 0) -/** - * Constant used to indicate an unconstrained size. - * - * @see #Reflow() - */ -#define NS_UNCONSTRAINEDSIZE NS_MAXSIZE - -#define NS_INTRINSICSIZE NS_UNCONSTRAINEDSIZE -#define NS_AUTOHEIGHT NS_UNCONSTRAINEDSIZE -// +1 is to avoid clamped huge margin values being processed as auto margins -#define NS_AUTOMARGIN (NS_UNCONSTRAINEDSIZE + 1) -#define NS_AUTOOFFSET NS_UNCONSTRAINEDSIZE -// NOTE: there are assumptions all over that these have the same value, namely NS_UNCONSTRAINEDSIZE -// if any are changed to be a value other than NS_UNCONSTRAINEDSIZE -// at least update AdjustComputedHeight/Width and test ad nauseum - // 1 million CSS pixels less than our max app unit measure. // For reflowing with an "infinite" available inline space per [css-sizing]. // (reflowing with an NS_UNCONSTRAINEDSIZE available inline size isn't allowed @@ -2050,23 +2033,27 @@ public: /** * Return the horizontal components of padding, border, and margin * that contribute to the intrinsic width that applies to the parent. + * @param aPercentageBasis the percentage basis to use for padding/margin - + * i.e. the Containing Block's inline-size */ struct IntrinsicISizeOffsetData { nscoord hPadding, hBorder, hMargin; - float hPctPadding, hPctMargin; IntrinsicISizeOffsetData() : hPadding(0), hBorder(0), hMargin(0) - , hPctPadding(0.0f), hPctMargin(0.0f) {} }; - virtual IntrinsicISizeOffsetData IntrinsicISizeOffsets() = 0; + virtual IntrinsicISizeOffsetData + IntrinsicISizeOffsets(nscoord aPercentageBasis = NS_UNCONSTRAINEDSIZE) = 0; /** * Return the bsize components of padding, border, and margin * that contribute to the intrinsic width that applies to the parent. + * @param aPercentageBasis the percentage basis to use for padding/margin - + * i.e. the Containing Block's inline-size */ - IntrinsicISizeOffsetData IntrinsicBSizeOffsets(); + IntrinsicISizeOffsetData + IntrinsicBSizeOffsets(nscoord aPercentageBasis = NS_UNCONSTRAINEDSIZE); virtual mozilla::IntrinsicSize GetIntrinsicSize() = 0; diff --git a/layout/style/nsCSSPropList.h b/layout/style/nsCSSPropList.h index 2049f70e88..07db6d3ddc 100644 --- a/layout/style/nsCSSPropList.h +++ b/layout/style/nsCSSPropList.h @@ -1499,7 +1499,7 @@ CSS_PROP_COLUMN( CSS_PROPERTY_PARSE_VALUE | CSS_PROPERTY_VALUE_NONNEGATIVE, "", - VARIANT_HL | VARIANT_NORMAL | VARIANT_CALC, + VARIANT_HLP | VARIANT_NORMAL | VARIANT_CALC, nullptr, offsetof(nsStyleColumn, mColumnGap), eStyleAnimType_Coord) diff --git a/layout/style/nsStyleStruct.h b/layout/style/nsStyleStruct.h index c8182b8f14..b257c6bb54 100644 --- a/layout/style/nsStyleStruct.h +++ b/layout/style/nsStyleStruct.h @@ -3495,7 +3495,7 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleColumn uint32_t mColumnCount; // [reset] see nsStyleConsts.h nsStyleCoord mColumnWidth; // [reset] coord, auto - nsStyleCoord mColumnGap; // [reset] coord, normal + nsStyleCoord mColumnGap; // [reset] | normal mozilla::StyleComplexColor mColumnRuleColor; // [reset] uint8_t mColumnRuleStyle; // [reset] diff --git a/layout/style/test/property_database.js b/layout/style/test/property_database.js index 272931c15e..c75f7b498f 100644 --- a/layout/style/test/property_database.js +++ b/layout/style/test/property_database.js @@ -1438,7 +1438,7 @@ var gCSSProperties = { inherited: false, type: CSS_TYPE_LONGHAND, initial_values: [ "normal", "1em", "calc(-2em + 3em)" ], - other_values: [ "2px", "4em", + other_values: [ "2px", "1em", "4em", "3%", "calc(3%)", "calc(1em - 3%)", "calc(2px)", "calc(-2px)", "calc(0px)", @@ -1448,7 +1448,7 @@ var gCSSProperties = { "calc(25px*3)", "calc(3*25px + 5em)", ], - invalid_values: [ "3%", "-1px", "4" ] + invalid_values: [ "-3%", "-1px", "4" ] }, "-moz-column-gap": { domProp: "MozColumnGap", diff --git a/layout/tables/nsTableCellFrame.cpp b/layout/tables/nsTableCellFrame.cpp index 316a966134..dea82ea591 100644 --- a/layout/tables/nsTableCellFrame.cpp +++ b/layout/tables/nsTableCellFrame.cpp @@ -796,12 +796,12 @@ nsTableCellFrame::GetPrefISize(nsRenderingContext *aRenderingContext) } /* virtual */ nsIFrame::IntrinsicISizeOffsetData -nsTableCellFrame::IntrinsicISizeOffsets() +nsTableCellFrame::IntrinsicISizeOffsets(nscoord aPercentageBasis) { - IntrinsicISizeOffsetData result = nsContainerFrame::IntrinsicISizeOffsets(); + IntrinsicISizeOffsetData result = + nsContainerFrame::IntrinsicISizeOffsets(aPercentageBasis); result.hMargin = 0; - result.hPctMargin = 0; WritingMode wm = GetWritingMode(); result.hBorder = GetBorderWidth(wm).IStartEnd(wm); diff --git a/layout/tables/nsTableCellFrame.h b/layout/tables/nsTableCellFrame.h index 6717e1b70d..2408098507 100644 --- a/layout/tables/nsTableCellFrame.h +++ b/layout/tables/nsTableCellFrame.h @@ -118,7 +118,8 @@ public: virtual nscoord GetMinISize(nsRenderingContext *aRenderingContext) override; virtual nscoord GetPrefISize(nsRenderingContext *aRenderingContext) override; - virtual IntrinsicISizeOffsetData IntrinsicISizeOffsets() override; + IntrinsicISizeOffsetData IntrinsicISizeOffsets(nscoord aPercentageBasis = + NS_UNCONSTRAINEDSIZE) override; virtual void Reflow(nsPresContext* aPresContext, ReflowOutput& aDesiredSize, diff --git a/layout/tables/nsTableFrame.cpp b/layout/tables/nsTableFrame.cpp index b9b6ca5fe5..272a77406a 100644 --- a/layout/tables/nsTableFrame.cpp +++ b/layout/tables/nsTableFrame.cpp @@ -1564,16 +1564,15 @@ nsTableFrame::GetPrefISize(nsRenderingContext *aRenderingContext) } /* virtual */ nsIFrame::IntrinsicISizeOffsetData -nsTableFrame::IntrinsicISizeOffsets() +nsTableFrame::IntrinsicISizeOffsets(nscoord aPercentageBasis) { - IntrinsicISizeOffsetData result = nsContainerFrame::IntrinsicISizeOffsets(); + IntrinsicISizeOffsetData result = + nsContainerFrame::IntrinsicISizeOffsets(aPercentageBasis); result.hMargin = 0; - result.hPctMargin = 0; if (IsBorderCollapse()) { result.hPadding = 0; - result.hPctPadding = 0; WritingMode wm = GetWritingMode(); LogicalMargin outerBC = GetIncludedOuterBCBorder(wm); diff --git a/layout/tables/nsTableFrame.h b/layout/tables/nsTableFrame.h index 7e56c28c17..c7b92d387e 100644 --- a/layout/tables/nsTableFrame.h +++ b/layout/tables/nsTableFrame.h @@ -324,7 +324,8 @@ public: // border to the results of these functions. virtual nscoord GetMinISize(nsRenderingContext *aRenderingContext) override; virtual nscoord GetPrefISize(nsRenderingContext *aRenderingContext) override; - virtual IntrinsicISizeOffsetData IntrinsicISizeOffsets() override; + IntrinsicISizeOffsetData IntrinsicISizeOffsets(nscoord aPercentageBasis = + NS_UNCONSTRAINEDSIZE) override; virtual mozilla::LogicalSize ComputeSize(nsRenderingContext* aRenderingContext, From bbb8b6490a0ad05b512c0da6ff9b77aba16128b1 Mon Sep 17 00:00:00 2001 From: Gaming4JC Date: Sat, 28 Sep 2019 23:38:15 -0400 Subject: [PATCH 5/8] Issue #1230 - Part 2: Align devtools to the changes in css-grid Ref: 1398537 part 4 - [css-multicol] Implement percentages for 'column-gap' (automated update of devtools). --- devtools/shared/css/generated/properties-db.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/devtools/shared/css/generated/properties-db.js b/devtools/shared/css/generated/properties-db.js index 0701674967..25d9e2d334 100644 --- a/devtools/shared/css/generated/properties-db.js +++ b/devtools/shared/css/generated/properties-db.js @@ -779,7 +779,8 @@ exports.CSS_PROPERTIES = { "column-gap" ], "supports": [ - 6 + 6, + 8 ], "values": [ "-moz-calc", @@ -5434,7 +5435,8 @@ exports.CSS_PROPERTIES = { "column-gap" ], "supports": [ - 6 + 6, + 8 ], "values": [ "-moz-calc", From 4bc299bb798a048a96b12ef18c800ad068eb4844 Mon Sep 17 00:00:00 2001 From: Gaming4JC Date: Sat, 28 Sep 2019 23:43:36 -0400 Subject: [PATCH 6/8] Issue #1230 - Part 3: Update Reftests Ref: 1434478 part 7 - Update tests and enable some previously temporarily disabled Grid reftests from bug 1427608. --- layout/reftests/bugs/403519-2-ref.html | 2 +- ...grid-auto-min-sizing-definite-001-ref.html | 51 ++++++++---- ...n-sizing-min-content-min-size-002-ref.html | 2 +- ...n-sizing-min-content-min-size-004-ref.html | 2 +- .../grid-auto-min-sizing-percent-001-ref.html | 10 +-- ...o-min-sizing-transferred-size-002-ref.html | 2 +- ...o-min-sizing-transferred-size-004-ref.html | 2 +- .../grid-item-sizing-percent-003-ref.html | 78 +++++++++---------- .../grid-item-sizing-percent-004-ref.html | 78 +++++++++---------- .../grid-percent-grid-gap-001-ref.html | 16 ++-- .../grid-repeat-auto-fill-fit-002-ref.html | 6 +- .../1174450-intrinsic-sizing-ref.html | 16 ++-- 12 files changed, 143 insertions(+), 122 deletions(-) diff --git a/layout/reftests/bugs/403519-2-ref.html b/layout/reftests/bugs/403519-2-ref.html index e00fb5e240..72176a89a6 100644 --- a/layout/reftests/bugs/403519-2-ref.html +++ b/layout/reftests/bugs/403519-2-ref.html @@ -17,7 +17,7 @@ table { - + diff --git a/layout/reftests/css-grid/grid-auto-min-sizing-definite-001-ref.html b/layout/reftests/css-grid/grid-auto-min-sizing-definite-001-ref.html index 8858b4ea8f..f2c76f78b1 100644 --- a/layout/reftests/css-grid/grid-auto-min-sizing-definite-001-ref.html +++ b/layout/reftests/css-grid/grid-auto-min-sizing-definite-001-ref.html @@ -65,32 +65,49 @@ b40 { .h.r { height: 42px; width: 42px; - /* This margin-left is 20% of 98px-wide grid area */ - margin-left: 19.6px; - /* This padding-bottom is 10% of 98px wide grid area */ - /* This padding-left is 30% of 98px wide grid area */ - padding: 1px 3px 9.8px 29.4px; + /* 49px is the percentage basis, i.e. the column size */ + margin-left: calc(0.2 * 49px); + padding: 1px 3px calc(0.1 * 49px) calc(0.3 * 49px); } .v.r { height: 42px; width: 42px; - /* This margin-left is 20% of 54px-wide grid area */ - margin-left: 10.8px; - /* This padding-bottom is 10% of 54px wide grid area */ - /* This padding-left is 30% of 54px wide grid area */ - padding: 1px 3px 5.4px 16.2px; + /* 27px is the percentage basis, i.e. the column size */ + margin-left: calc(0.2 * 27px); + padding: 1px 3px calc(0.1 * 27px) calc(0.3 * 27px); } .r { position:relative; } +.t4 { width: 49px; + height: calc(10px /* item min-height */ + + 7px /* item margin-top */ + + 1px /* item padding-top */ + + 1px /* item border-top */ + + calc(0.5 * 49px) /* item margin-bottom */ + + calc(0.1 * 49px) /* item padding-bottom */); + } + .t6 { width:46px; } -.t8 { width:118px; height: 102.5px; } +.t8 { width: 27px; + height: calc(30px /* item min-height */ + + 7px /* item margin-top */ + + 3px /* item padding-top */ + + 1px /* item border-top */ + + calc(0.5 * 27px) /* item margin-bottom */ + + calc(0.1 * 27px) /* item padding-bottom */); + } xx { display: block; background: lime; - padding:32px 32px 16px 32px; - margin: 0 0 32px 16px; + padding: 32px 32px calc(0.2 * 32px) calc(0.4 * 32px); + margin: 0 0 calc(0.4 * 32px) calc(0.2 * 32px); +} +.t9, .t10 { + position: relative; + z-index: 1; + grid: calc(32px + calc(0.4 * 32px) + calc(0.2 * 32px)) 0 / 32px; } @@ -100,15 +117,15 @@ xx {
-
+

-
+
-
-
+
+
diff --git a/layout/reftests/css-grid/grid-auto-min-sizing-min-content-min-size-002-ref.html b/layout/reftests/css-grid/grid-auto-min-sizing-min-content-min-size-002-ref.html index 35f596928b..183f00e24f 100644 --- a/layout/reftests/css-grid/grid-auto-min-sizing-min-content-min-size-002-ref.html +++ b/layout/reftests/css-grid/grid-auto-min-sizing-min-content-min-size-002-ref.html @@ -36,7 +36,7 @@ var coltest = [ "min-height:40%", "min-height:40%; max-width:30px" ]; var results = [ -"360px", "360px", "360px", "24px", "24px", "360px", "80px", "24px", "24px", "24px", +"24px", "24px", "24px", "24px", "24px", "24px", "80px", "24px", "24px", "24px", "24px", "24px", "24px" ]; var item_width = [ diff --git a/layout/reftests/css-grid/grid-auto-min-sizing-min-content-min-size-004-ref.html b/layout/reftests/css-grid/grid-auto-min-sizing-min-content-min-size-004-ref.html index caef8b0314..6533c97b67 100644 --- a/layout/reftests/css-grid/grid-auto-min-sizing-min-content-min-size-004-ref.html +++ b/layout/reftests/css-grid/grid-auto-min-sizing-min-content-min-size-004-ref.html @@ -36,7 +36,7 @@ var rowtest = [ "min-width:80%; max-height:20px", "min-width:50%", "margin-left: 50px; width:50%" ]; var results = [ -"0/2px", "0/2px", "0/4px", "0/2px", "0/2px", "0/2px", "12px/2px", "20px/2px", "20px/2px", "24px/2px", "24px/52px" +"0/2px", "0/2px", "0/4px", "0/2px", "0/2px", "0/2px", "12px/2px", "20px/2px", "20px/2px", "24px/2px", "312px/52px" ]; var item_height = [ "0", "0", "0", "0", "0", "0", "12px", "20px", "20px", "24px", "312px" diff --git a/layout/reftests/css-grid/grid-auto-min-sizing-percent-001-ref.html b/layout/reftests/css-grid/grid-auto-min-sizing-percent-001-ref.html index fd2302add0..d435f8f3e1 100644 --- a/layout/reftests/css-grid/grid-auto-min-sizing-percent-001-ref.html +++ b/layout/reftests/css-grid/grid-auto-min-sizing-percent-001-ref.html @@ -54,9 +54,9 @@ br { clear:both; } .c10 { grid-template-columns: minmax(10px,0) 1fr; } #px-border .c10 { grid-template-columns: minmax(30px,0) 1fr; } -#percent-border .c100 { grid-template-columns: 111px 0; } -#percent-border .c100calc100 { grid-template-columns: 100px 11px; } -#percent-border .c10 { grid-template-columns: minmax(11px,0) 0; } +#percent-border .c100 { grid-template-columns: 100px 0; } +#percent-border .c100calc100 { grid-template-columns: 100px 10px; } +#percent-border .c10 { grid-template-columns: minmax(10px,0) 0; } #percent-border .c100100 { grid-template-columns: minmax(100px,0) 150px; } #percent-border .c200 { grid-template-columns: 250px; } @@ -99,7 +99,7 @@ var grids = [ "grid c100", "grid c100", "grid", -"grid c200", +"grid c100", "grid c10", "grid c100", "grid c100", @@ -110,7 +110,7 @@ var grids = [ "grid c100", "grid c100", "grid", -"grid c200", +"grid c100", "grid c10", "grid c100", "grid c100", diff --git a/layout/reftests/css-grid/grid-auto-min-sizing-transferred-size-002-ref.html b/layout/reftests/css-grid/grid-auto-min-sizing-transferred-size-002-ref.html index 8dcdd563bb..528d63bc72 100644 --- a/layout/reftests/css-grid/grid-auto-min-sizing-transferred-size-002-ref.html +++ b/layout/reftests/css-grid/grid-auto-min-sizing-transferred-size-002-ref.html @@ -36,7 +36,7 @@ var coltest = [ "min-height:40%", "min-height:40%; max-width:30px" ]; var results = [ -"360px", "360px", "360px", "24px", "24px", "360px", "80px", "24px", "20px", "24px", +"360px", "0px", "0px", "0px", "24px", "360px", "80px", "24px", "20px", "24px", "6px", "24px", "24px" ]; var item_width = [ diff --git a/layout/reftests/css-grid/grid-auto-min-sizing-transferred-size-004-ref.html b/layout/reftests/css-grid/grid-auto-min-sizing-transferred-size-004-ref.html index 36a2d4920a..4eb623b7d4 100644 --- a/layout/reftests/css-grid/grid-auto-min-sizing-transferred-size-004-ref.html +++ b/layout/reftests/css-grid/grid-auto-min-sizing-transferred-size-004-ref.html @@ -36,7 +36,7 @@ var rowtest = [ "min-width:80%; max-height:20px", "min-width:50%", "margin-left: 50px; width:50%" ]; var results = [ -"0/2px", "0/2px", "0/4px", "0/2px", "0/2px", "0/2px", "12px/2px", "20px/2px", "20px/2px", "24px/2px", "24px/52px" +"0/2px", "0/2px", "0/4px", "0/2px", "0/2px", "0/2px", "12px/2px", "20px/2px", "20px/2px", "24px/2px", "312px/52px" ]; var item_height = [ "0", "0", "0", "0", "0", "0", "12px", "20px", "20px", "24px", "312px" diff --git a/layout/reftests/css-grid/grid-item-sizing-percent-003-ref.html b/layout/reftests/css-grid/grid-item-sizing-percent-003-ref.html index fb4d15ff83..a55dcc989e 100644 --- a/layout/reftests/css-grid/grid-item-sizing-percent-003-ref.html +++ b/layout/reftests/css-grid/grid-item-sizing-percent-003-ref.html @@ -69,67 +69,67 @@ a {
-
-
-
-
+
+
+
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+

-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
diff --git a/layout/reftests/css-grid/grid-item-sizing-percent-004-ref.html b/layout/reftests/css-grid/grid-item-sizing-percent-004-ref.html index 51f71e6628..96365b468a 100644 --- a/layout/reftests/css-grid/grid-item-sizing-percent-004-ref.html +++ b/layout/reftests/css-grid/grid-item-sizing-percent-004-ref.html @@ -62,71 +62,71 @@ a {
-
-
-
-
+
+
+
+
-
-
-
+
+
+

-
-
-
-
+
+
+
+
-
-
-
+
+
+

-
-
-
-
+
+
+
+
-
-
-
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+

-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
diff --git a/layout/reftests/css-grid/grid-percent-grid-gap-001-ref.html b/layout/reftests/css-grid/grid-percent-grid-gap-001-ref.html index 945b43b525..7ad85e1e58 100644 --- a/layout/reftests/css-grid/grid-percent-grid-gap-001-ref.html +++ b/layout/reftests/css-grid/grid-percent-grid-gap-001-ref.html @@ -65,7 +65,7 @@ br { clear: both; }
-
+
@@ -74,7 +74,7 @@ br { clear: both; }
-
+
@@ -141,12 +141,12 @@ br { clear: both; }
-
-
- - - - +
+
+ + + +
diff --git a/layout/reftests/css-grid/grid-repeat-auto-fill-fit-002-ref.html b/layout/reftests/css-grid/grid-repeat-auto-fill-fit-002-ref.html index a404a09058..682e0ca38e 100644 --- a/layout/reftests/css-grid/grid-repeat-auto-fill-fit-002-ref.html +++ b/layout/reftests/css-grid/grid-repeat-auto-fill-fit-002-ref.html @@ -83,12 +83,16 @@ fill,fit { .zero-progress { grid-row-gap: calc(10px - 1%); - grid-template-rows: [a] 10px repeat(4, [b] minmax(0,auto) [c]) [d]; + grid-template-rows: [a] 10px repeat(3, [b] 0 [c]) [d]; } .w50.zero-progress { grid-row-gap: calc(10px - 1%); grid-template-rows: [a] 10px repeat(3, [b] 0 [c]) [d]; } +.mw50.zero-progress { + grid-row-gap: calc(10px - 1%); + grid-template-rows: [a] 10px repeat(4, [b] 0 [c]) [d]; +} diff --git a/layout/reftests/writing-mode/1174450-intrinsic-sizing-ref.html b/layout/reftests/writing-mode/1174450-intrinsic-sizing-ref.html index 629c0a917c..3645fa0066 100644 --- a/layout/reftests/writing-mode/1174450-intrinsic-sizing-ref.html +++ b/layout/reftests/writing-mode/1174450-intrinsic-sizing-ref.html @@ -13,20 +13,20 @@ div.v, div.h { display: block; position: relative; border: 1px dashed silver; - width:92px; - height:60px; + width:74px; + height:24px; } div.h { - width:124px; - height:98px; + width:62px; + height:61.2px; } .h span { - margin: 7px 13px 62px 25px; - padding: 1px 3px 12px 37px; + margin: 7px 13px 32px 12px; + padding: 1px 3px 6px 19px; } .v span { - margin: 7px 13px 30px 12px; - padding: 1px 3px 6px 18px; + margin: 7px 13px 30px 5px; + padding: 1px 3px 2px 7px; } span { From 9d42392ea88ac690ed305fc5eac84366de847c7e Mon Sep 17 00:00:00 2001 From: Dmitry Grigoryev Date: Sat, 28 Sep 2019 10:00:36 +0200 Subject: [PATCH 7/8] Added missing libwebp NEON files --- media/libwebp/dsp/alpha_processing_neon.c | 191 +++++++++++++ media/libwebp/dsp/filters_neon.c | 329 ++++++++++++++++++++++ media/libwebp/dsp/moz.build | 6 + media/libwebp/dsp/yuv_neon.c | 288 +++++++++++++++++++ 4 files changed, 814 insertions(+) create mode 100644 media/libwebp/dsp/alpha_processing_neon.c create mode 100644 media/libwebp/dsp/filters_neon.c create mode 100644 media/libwebp/dsp/yuv_neon.c diff --git a/media/libwebp/dsp/alpha_processing_neon.c b/media/libwebp/dsp/alpha_processing_neon.c new file mode 100644 index 0000000000..53dfce2b36 --- /dev/null +++ b/media/libwebp/dsp/alpha_processing_neon.c @@ -0,0 +1,191 @@ +// Copyright 2017 Google Inc. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the COPYING file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. +// ----------------------------------------------------------------------------- +// +// Utilities for processing transparent channel, NEON version. +// +// Author: Skal (pascal.massimino@gmail.com) + +#include "../dsp/dsp.h" + +#if defined(WEBP_USE_NEON) + +#include "../dsp/neon.h" + +//------------------------------------------------------------------------------ + +#define MULTIPLIER(a) ((a) * 0x8081) +#define PREMULTIPLY(x, m) (((x) * (m)) >> 23) + +#define MULTIPLY_BY_ALPHA(V, ALPHA, OTHER) do { \ + const uint8x8_t alpha = (V).val[(ALPHA)]; \ + const uint16x8_t r1 = vmull_u8((V).val[1], alpha); \ + const uint16x8_t g1 = vmull_u8((V).val[2], alpha); \ + const uint16x8_t b1 = vmull_u8((V).val[(OTHER)], alpha); \ + /* we use: v / 255 = (v + 1 + (v >> 8)) >> 8 */ \ + const uint16x8_t r2 = vsraq_n_u16(r1, r1, 8); \ + const uint16x8_t g2 = vsraq_n_u16(g1, g1, 8); \ + const uint16x8_t b2 = vsraq_n_u16(b1, b1, 8); \ + const uint16x8_t r3 = vaddq_u16(r2, kOne); \ + const uint16x8_t g3 = vaddq_u16(g2, kOne); \ + const uint16x8_t b3 = vaddq_u16(b2, kOne); \ + (V).val[1] = vshrn_n_u16(r3, 8); \ + (V).val[2] = vshrn_n_u16(g3, 8); \ + (V).val[(OTHER)] = vshrn_n_u16(b3, 8); \ +} while (0) + +static void ApplyAlphaMultiply_NEON(uint8_t* rgba, int alpha_first, + int w, int h, int stride) { + const uint16x8_t kOne = vdupq_n_u16(1u); + while (h-- > 0) { + uint32_t* const rgbx = (uint32_t*)rgba; + int i = 0; + if (alpha_first) { + for (; i + 8 <= w; i += 8) { + // load aaaa...|rrrr...|gggg...|bbbb... + uint8x8x4_t RGBX = vld4_u8((const uint8_t*)(rgbx + i)); + MULTIPLY_BY_ALPHA(RGBX, 0, 3); + vst4_u8((uint8_t*)(rgbx + i), RGBX); + } + } else { + for (; i + 8 <= w; i += 8) { + uint8x8x4_t RGBX = vld4_u8((const uint8_t*)(rgbx + i)); + MULTIPLY_BY_ALPHA(RGBX, 3, 0); + vst4_u8((uint8_t*)(rgbx + i), RGBX); + } + } + // Finish with left-overs. + for (; i < w; ++i) { + uint8_t* const rgb = rgba + (alpha_first ? 1 : 0); + const uint8_t* const alpha = rgba + (alpha_first ? 0 : 3); + const uint32_t a = alpha[4 * i]; + if (a != 0xff) { + const uint32_t mult = MULTIPLIER(a); + rgb[4 * i + 0] = PREMULTIPLY(rgb[4 * i + 0], mult); + rgb[4 * i + 1] = PREMULTIPLY(rgb[4 * i + 1], mult); + rgb[4 * i + 2] = PREMULTIPLY(rgb[4 * i + 2], mult); + } + } + rgba += stride; + } +} +#undef MULTIPLY_BY_ALPHA +#undef MULTIPLIER +#undef PREMULTIPLY + +//------------------------------------------------------------------------------ + +static int DispatchAlpha_NEON(const uint8_t* alpha, int alpha_stride, + int width, int height, + uint8_t* dst, int dst_stride) { + uint32_t alpha_mask = 0xffffffffu; + uint8x8_t mask8 = vdup_n_u8(0xff); + uint32_t tmp[2]; + int i, j; + for (j = 0; j < height; ++j) { + // We don't know if alpha is first or last in dst[] (depending on rgbA/Argb + // mode). So we must be sure dst[4*i + 8 - 1] is writable for the store. + // Hence the test with 'width - 1' instead of just 'width'. + for (i = 0; i + 8 <= width - 1; i += 8) { + uint8x8x4_t rgbX = vld4_u8((const uint8_t*)(dst + 4 * i)); + const uint8x8_t alphas = vld1_u8(alpha + i); + rgbX.val[0] = alphas; + vst4_u8((uint8_t*)(dst + 4 * i), rgbX); + mask8 = vand_u8(mask8, alphas); + } + for (; i < width; ++i) { + const uint32_t alpha_value = alpha[i]; + dst[4 * i] = alpha_value; + alpha_mask &= alpha_value; + } + alpha += alpha_stride; + dst += dst_stride; + } + vst1_u8((uint8_t*)tmp, mask8); + alpha_mask &= tmp[0]; + alpha_mask &= tmp[1]; + return (alpha_mask != 0xffffffffu); +} + +static void DispatchAlphaToGreen_NEON(const uint8_t* alpha, int alpha_stride, + int width, int height, + uint32_t* dst, int dst_stride) { + int i, j; + uint8x8x4_t greens; // leave A/R/B channels zero'd. + greens.val[0] = vdup_n_u8(0); + greens.val[2] = vdup_n_u8(0); + greens.val[3] = vdup_n_u8(0); + for (j = 0; j < height; ++j) { + for (i = 0; i + 8 <= width; i += 8) { + greens.val[1] = vld1_u8(alpha + i); + vst4_u8((uint8_t*)(dst + i), greens); + } + for (; i < width; ++i) dst[i] = alpha[i] << 8; + alpha += alpha_stride; + dst += dst_stride; + } +} + +static int ExtractAlpha_NEON(const uint8_t* argb, int argb_stride, + int width, int height, + uint8_t* alpha, int alpha_stride) { + uint32_t alpha_mask = 0xffffffffu; + uint8x8_t mask8 = vdup_n_u8(0xff); + uint32_t tmp[2]; + int i, j; + for (j = 0; j < height; ++j) { + // We don't know if alpha is first or last in dst[] (depending on rgbA/Argb + // mode). So we must be sure dst[4*i + 8 - 1] is writable for the store. + // Hence the test with 'width - 1' instead of just 'width'. + for (i = 0; i + 8 <= width - 1; i += 8) { + const uint8x8x4_t rgbX = vld4_u8((const uint8_t*)(argb + 4 * i)); + const uint8x8_t alphas = rgbX.val[0]; + vst1_u8((uint8_t*)(alpha + i), alphas); + mask8 = vand_u8(mask8, alphas); + } + for (; i < width; ++i) { + alpha[i] = argb[4 * i]; + alpha_mask &= alpha[i]; + } + argb += argb_stride; + alpha += alpha_stride; + } + vst1_u8((uint8_t*)tmp, mask8); + alpha_mask &= tmp[0]; + alpha_mask &= tmp[1]; + return (alpha_mask == 0xffffffffu); +} + +static void ExtractGreen_NEON(const uint32_t* argb, + uint8_t* alpha, int size) { + int i; + for (i = 0; i + 16 <= size; i += 16) { + const uint8x16x4_t rgbX = vld4q_u8((const uint8_t*)(argb + i)); + const uint8x16_t greens = rgbX.val[1]; + vst1q_u8(alpha + i, greens); + } + for (; i < size; ++i) alpha[i] = (argb[i] >> 8) & 0xff; +} + +//------------------------------------------------------------------------------ + +extern void WebPInitAlphaProcessingNEON(void); + +WEBP_TSAN_IGNORE_FUNCTION void WebPInitAlphaProcessingNEON(void) { + WebPApplyAlphaMultiply = ApplyAlphaMultiply_NEON; + WebPDispatchAlpha = DispatchAlpha_NEON; + WebPDispatchAlphaToGreen = DispatchAlphaToGreen_NEON; + WebPExtractAlpha = ExtractAlpha_NEON; + WebPExtractGreen = ExtractGreen_NEON; +} + +#else // !WEBP_USE_NEON + +WEBP_DSP_INIT_STUB(WebPInitAlphaProcessingNEON) + +#endif // WEBP_USE_NEON diff --git a/media/libwebp/dsp/filters_neon.c b/media/libwebp/dsp/filters_neon.c new file mode 100644 index 0000000000..4788118c91 --- /dev/null +++ b/media/libwebp/dsp/filters_neon.c @@ -0,0 +1,329 @@ +// Copyright 2017 Google Inc. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the COPYING file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. +// ----------------------------------------------------------------------------- +// +// NEON variant of alpha filters +// +// Author: Skal (pascal.massimino@gmail.com) + +#include "../dsp/dsp.h" + +#if defined(WEBP_USE_NEON) + +#include +#include "../dsp/neon.h" + +//------------------------------------------------------------------------------ +// Helpful macros. + +# define SANITY_CHECK(in, out) \ + assert(in != NULL); \ + assert(out != NULL); \ + assert(width > 0); \ + assert(height > 0); \ + assert(stride >= width); \ + assert(row >= 0 && num_rows > 0 && row + num_rows <= height); \ + (void)height; // Silence unused warning. + +// load eight u8 and widen to s16 +#define U8_TO_S16(A) vreinterpretq_s16_u16(vmovl_u8(A)) +#define LOAD_U8_TO_S16(A) U8_TO_S16(vld1_u8(A)) + +// shift left or right by N byte, inserting zeros +#define SHIFT_RIGHT_N_Q(A, N) vextq_u8((A), zero, (N)) +#define SHIFT_LEFT_N_Q(A, N) vextq_u8(zero, (A), (16 - (N)) % 16) + +// rotate left by N bytes +#define ROTATE_LEFT_N(A, N) vext_u8((A), (A), (N)) +// rotate right by N bytes +#define ROTATE_RIGHT_N(A, N) vext_u8((A), (A), (8 - (N)) % 8) + +static void PredictLine_NEON(const uint8_t* src, const uint8_t* pred, + uint8_t* dst, int length) { + int i; + assert(length >= 0); + for (i = 0; i + 16 <= length; i += 16) { + const uint8x16_t A = vld1q_u8(&src[i]); + const uint8x16_t B = vld1q_u8(&pred[i]); + const uint8x16_t C = vsubq_u8(A, B); + vst1q_u8(&dst[i], C); + } + for (; i < length; ++i) dst[i] = src[i] - pred[i]; +} + +// Special case for left-based prediction (when preds==dst-1 or preds==src-1). +static void PredictLineLeft_NEON(const uint8_t* src, uint8_t* dst, int length) { + PredictLine_NEON(src, src - 1, dst, length); +} + +//------------------------------------------------------------------------------ +// Horizontal filter. + +static WEBP_INLINE void DoHorizontalFilter_NEON(const uint8_t* in, + int width, int height, + int stride, + int row, int num_rows, + uint8_t* out) { + const size_t start_offset = row * stride; + const int last_row = row + num_rows; + SANITY_CHECK(in, out); + in += start_offset; + out += start_offset; + + if (row == 0) { + // Leftmost pixel is the same as input for topmost scanline. + out[0] = in[0]; + PredictLineLeft_NEON(in + 1, out + 1, width - 1); + row = 1; + in += stride; + out += stride; + } + + // Filter line-by-line. + while (row < last_row) { + // Leftmost pixel is predicted from above. + out[0] = in[0] - in[-stride]; + PredictLineLeft_NEON(in + 1, out + 1, width - 1); + ++row; + in += stride; + out += stride; + } +} + +static void HorizontalFilter_NEON(const uint8_t* data, int width, int height, + int stride, uint8_t* filtered_data) { + DoHorizontalFilter_NEON(data, width, height, stride, 0, height, + filtered_data); +} + +//------------------------------------------------------------------------------ +// Vertical filter. + +static WEBP_INLINE void DoVerticalFilter_NEON(const uint8_t* in, + int width, int height, int stride, + int row, int num_rows, + uint8_t* out) { + const size_t start_offset = row * stride; + const int last_row = row + num_rows; + SANITY_CHECK(in, out); + in += start_offset; + out += start_offset; + + if (row == 0) { + // Very first top-left pixel is copied. + out[0] = in[0]; + // Rest of top scan-line is left-predicted. + PredictLineLeft_NEON(in + 1, out + 1, width - 1); + row = 1; + in += stride; + out += stride; + } + + // Filter line-by-line. + while (row < last_row) { + PredictLine_NEON(in, in - stride, out, width); + ++row; + in += stride; + out += stride; + } +} + +static void VerticalFilter_NEON(const uint8_t* data, int width, int height, + int stride, uint8_t* filtered_data) { + DoVerticalFilter_NEON(data, width, height, stride, 0, height, + filtered_data); +} + +//------------------------------------------------------------------------------ +// Gradient filter. + +static WEBP_INLINE int GradientPredictor_C(uint8_t a, uint8_t b, uint8_t c) { + const int g = a + b - c; + return ((g & ~0xff) == 0) ? g : (g < 0) ? 0 : 255; // clip to 8bit +} + +static void GradientPredictDirect_NEON(const uint8_t* const row, + const uint8_t* const top, + uint8_t* const out, int length) { + int i; + for (i = 0; i + 8 <= length; i += 8) { + const uint8x8_t A = vld1_u8(&row[i - 1]); + const uint8x8_t B = vld1_u8(&top[i + 0]); + const int16x8_t C = vreinterpretq_s16_u16(vaddl_u8(A, B)); + const int16x8_t D = LOAD_U8_TO_S16(&top[i - 1]); + const uint8x8_t E = vqmovun_s16(vsubq_s16(C, D)); + const uint8x8_t F = vld1_u8(&row[i + 0]); + vst1_u8(&out[i], vsub_u8(F, E)); + } + for (; i < length; ++i) { + out[i] = row[i] - GradientPredictor_C(row[i - 1], top[i], top[i - 1]); + } +} + +static WEBP_INLINE void DoGradientFilter_NEON(const uint8_t* in, + int width, int height, + int stride, + int row, int num_rows, + uint8_t* out) { + const size_t start_offset = row * stride; + const int last_row = row + num_rows; + SANITY_CHECK(in, out); + in += start_offset; + out += start_offset; + + // left prediction for top scan-line + if (row == 0) { + out[0] = in[0]; + PredictLineLeft_NEON(in + 1, out + 1, width - 1); + row = 1; + in += stride; + out += stride; + } + + // Filter line-by-line. + while (row < last_row) { + out[0] = in[0] - in[-stride]; + GradientPredictDirect_NEON(in + 1, in + 1 - stride, out + 1, width - 1); + ++row; + in += stride; + out += stride; + } +} + +static void GradientFilter_NEON(const uint8_t* data, int width, int height, + int stride, uint8_t* filtered_data) { + DoGradientFilter_NEON(data, width, height, stride, 0, height, + filtered_data); +} + +#undef SANITY_CHECK + +//------------------------------------------------------------------------------ +// Inverse transforms + +static void HorizontalUnfilter_NEON(const uint8_t* prev, const uint8_t* in, + uint8_t* out, int width) { + int i; + const uint8x16_t zero = vdupq_n_u8(0); + uint8x16_t last; + out[0] = in[0] + (prev == NULL ? 0 : prev[0]); + if (width <= 1) return; + last = vsetq_lane_u8(out[0], zero, 0); + for (i = 1; i + 16 <= width; i += 16) { + const uint8x16_t A0 = vld1q_u8(&in[i]); + const uint8x16_t A1 = vaddq_u8(A0, last); + const uint8x16_t A2 = SHIFT_LEFT_N_Q(A1, 1); + const uint8x16_t A3 = vaddq_u8(A1, A2); + const uint8x16_t A4 = SHIFT_LEFT_N_Q(A3, 2); + const uint8x16_t A5 = vaddq_u8(A3, A4); + const uint8x16_t A6 = SHIFT_LEFT_N_Q(A5, 4); + const uint8x16_t A7 = vaddq_u8(A5, A6); + const uint8x16_t A8 = SHIFT_LEFT_N_Q(A7, 8); + const uint8x16_t A9 = vaddq_u8(A7, A8); + vst1q_u8(&out[i], A9); + last = SHIFT_RIGHT_N_Q(A9, 15); + } + for (; i < width; ++i) out[i] = in[i] + out[i - 1]; +} + +static void VerticalUnfilter_NEON(const uint8_t* prev, const uint8_t* in, + uint8_t* out, int width) { + if (prev == NULL) { + HorizontalUnfilter_NEON(NULL, in, out, width); + } else { + int i; + assert(width >= 0); + for (i = 0; i + 16 <= width; i += 16) { + const uint8x16_t A = vld1q_u8(&in[i]); + const uint8x16_t B = vld1q_u8(&prev[i]); + const uint8x16_t C = vaddq_u8(A, B); + vst1q_u8(&out[i], C); + } + for (; i < width; ++i) out[i] = in[i] + prev[i]; + } +} + +// GradientUnfilter_NEON is correct but slower than the C-version, +// at least on ARM64. For armv7, it's a wash. +// So best is to disable it for now, but keep the idea around... +#if !defined(USE_GRADIENT_UNFILTER) +#define USE_GRADIENT_UNFILTER 0 // ALTERNATE_CODE +#endif + +#if (USE_GRADIENT_UNFILTER == 1) +#define GRAD_PROCESS_LANE(L) do { \ + const uint8x8_t tmp1 = ROTATE_RIGHT_N(pred, 1); /* rotate predictor in */ \ + const int16x8_t tmp2 = vaddq_s16(BC, U8_TO_S16(tmp1)); \ + const uint8x8_t delta = vqmovun_s16(tmp2); \ + pred = vadd_u8(D, delta); \ + out = vext_u8(out, ROTATE_LEFT_N(pred, (L)), 1); \ +} while (0) + +static void GradientPredictInverse_NEON(const uint8_t* const in, + const uint8_t* const top, + uint8_t* const row, int length) { + if (length > 0) { + int i; + uint8x8_t pred = vdup_n_u8(row[-1]); // left sample + uint8x8_t out = vdup_n_u8(0); + for (i = 0; i + 8 <= length; i += 8) { + const int16x8_t B = LOAD_U8_TO_S16(&top[i + 0]); + const int16x8_t C = LOAD_U8_TO_S16(&top[i - 1]); + const int16x8_t BC = vsubq_s16(B, C); // unclipped gradient basis B - C + const uint8x8_t D = vld1_u8(&in[i]); // base input + GRAD_PROCESS_LANE(0); + GRAD_PROCESS_LANE(1); + GRAD_PROCESS_LANE(2); + GRAD_PROCESS_LANE(3); + GRAD_PROCESS_LANE(4); + GRAD_PROCESS_LANE(5); + GRAD_PROCESS_LANE(6); + GRAD_PROCESS_LANE(7); + vst1_u8(&row[i], out); + } + for (; i < length; ++i) { + row[i] = in[i] + GradientPredictor_C(row[i - 1], top[i], top[i - 1]); + } + } +} +#undef GRAD_PROCESS_LANE + +static void GradientUnfilter_NEON(const uint8_t* prev, const uint8_t* in, + uint8_t* out, int width) { + if (prev == NULL) { + HorizontalUnfilter_NEON(NULL, in, out, width); + } else { + out[0] = in[0] + prev[0]; // predict from above + GradientPredictInverse_NEON(in + 1, prev + 1, out + 1, width - 1); + } +} + +#endif // USE_GRADIENT_UNFILTER + +//------------------------------------------------------------------------------ +// Entry point + +extern void VP8FiltersInitNEON(void); + +WEBP_TSAN_IGNORE_FUNCTION void VP8FiltersInitNEON(void) { + WebPUnfilters[WEBP_FILTER_HORIZONTAL] = HorizontalUnfilter_NEON; + WebPUnfilters[WEBP_FILTER_VERTICAL] = VerticalUnfilter_NEON; +#if (USE_GRADIENT_UNFILTER == 1) + WebPUnfilters[WEBP_FILTER_GRADIENT] = GradientUnfilter_NEON; +#endif + + WebPFilters[WEBP_FILTER_HORIZONTAL] = HorizontalFilter_NEON; + WebPFilters[WEBP_FILTER_VERTICAL] = VerticalFilter_NEON; + WebPFilters[WEBP_FILTER_GRADIENT] = GradientFilter_NEON; +} + +#else // !WEBP_USE_NEON + +WEBP_DSP_INIT_STUB(VP8FiltersInitNEON) + +#endif // WEBP_USE_NEON diff --git a/media/libwebp/dsp/moz.build b/media/libwebp/dsp/moz.build index fa6df9e9ed..f3c2bdd0b9 100644 --- a/media/libwebp/dsp/moz.build +++ b/media/libwebp/dsp/moz.build @@ -9,6 +9,7 @@ with Files('**'): SOURCES += [ 'alpha_processing.c', + 'alpha_processing_neon.c', 'alpha_processing_sse2.c', 'alpha_processing_sse41.c', 'dec.c', @@ -17,6 +18,7 @@ SOURCES += [ 'dec_sse2.c', 'dec_sse41.c', 'filters.c', + 'filters_neon.c', 'filters_sse2.c', 'lossless.c', 'lossless_neon.c', @@ -29,15 +31,19 @@ SOURCES += [ 'upsampling_sse2.c', 'upsampling_sse41.c', 'yuv.c', + 'yuv_neon.c', 'yuv_sse2.c', 'yuv_sse41.c', ] if CONFIG['CPU_ARCH'] == 'arm' and CONFIG['BUILD_ARM_NEON']: + SOURCES['alpha_processing_neon.c'].flags += CONFIG['NEON_FLAGS'] SOURCES['dec_neon.c'].flags += CONFIG['NEON_FLAGS'] + SOURCES['filters_neon.c'].flags += CONFIG['NEON_FLAGS'] SOURCES['lossless_neon.c'].flags += CONFIG['NEON_FLAGS'] SOURCES['rescaler_neon.c'].flags += CONFIG['NEON_FLAGS'] SOURCES['upsampling_neon.c'].flags += CONFIG['NEON_FLAGS'] + SOURCES['yuv_neon.c'].flags += CONFIG['NEON_FLAGS'] elif CONFIG['INTEL_ARCHITECTURE']: SOURCES['alpha_processing_sse2.c'].flags += CONFIG['SSE2_FLAGS'] SOURCES['alpha_processing_sse41.c'].flags += CONFIG['SSE2_FLAGS'] diff --git a/media/libwebp/dsp/yuv_neon.c b/media/libwebp/dsp/yuv_neon.c new file mode 100644 index 0000000000..81f00fe5a8 --- /dev/null +++ b/media/libwebp/dsp/yuv_neon.c @@ -0,0 +1,288 @@ +// Copyright 2017 Google Inc. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the COPYING file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. +// ----------------------------------------------------------------------------- +// +// YUV->RGB conversion functions +// +// Author: Skal (pascal.massimino@gmail.com) + +#include "../dsp/yuv.h" + +#if defined(WEBP_USE_NEON) + +#include +#include + +#include "../dsp/neon.h" + +//----------------------------------------------------------------------------- + +static uint8x8_t ConvertRGBToY_NEON(const uint8x8_t R, + const uint8x8_t G, + const uint8x8_t B) { + const uint16x8_t r = vmovl_u8(R); + const uint16x8_t g = vmovl_u8(G); + const uint16x8_t b = vmovl_u8(B); + const uint16x4_t r_lo = vget_low_u16(r); + const uint16x4_t r_hi = vget_high_u16(r); + const uint16x4_t g_lo = vget_low_u16(g); + const uint16x4_t g_hi = vget_high_u16(g); + const uint16x4_t b_lo = vget_low_u16(b); + const uint16x4_t b_hi = vget_high_u16(b); + const uint32x4_t tmp0_lo = vmull_n_u16( r_lo, 16839u); + const uint32x4_t tmp0_hi = vmull_n_u16( r_hi, 16839u); + const uint32x4_t tmp1_lo = vmlal_n_u16(tmp0_lo, g_lo, 33059u); + const uint32x4_t tmp1_hi = vmlal_n_u16(tmp0_hi, g_hi, 33059u); + const uint32x4_t tmp2_lo = vmlal_n_u16(tmp1_lo, b_lo, 6420u); + const uint32x4_t tmp2_hi = vmlal_n_u16(tmp1_hi, b_hi, 6420u); + const uint16x8_t Y1 = vcombine_u16(vrshrn_n_u32(tmp2_lo, 16), + vrshrn_n_u32(tmp2_hi, 16)); + const uint16x8_t Y2 = vaddq_u16(Y1, vdupq_n_u16(16)); + return vqmovn_u16(Y2); +} + +static void ConvertRGB24ToY_NEON(const uint8_t* rgb, uint8_t* y, int width) { + int i; + for (i = 0; i + 8 <= width; i += 8, rgb += 3 * 8) { + const uint8x8x3_t RGB = vld3_u8(rgb); + const uint8x8_t Y = ConvertRGBToY_NEON(RGB.val[0], RGB.val[1], RGB.val[2]); + vst1_u8(y + i, Y); + } + for (; i < width; ++i, rgb += 3) { // left-over + y[i] = VP8RGBToY(rgb[0], rgb[1], rgb[2], YUV_HALF); + } +} + +static void ConvertBGR24ToY_NEON(const uint8_t* bgr, uint8_t* y, int width) { + int i; + for (i = 0; i + 8 <= width; i += 8, bgr += 3 * 8) { + const uint8x8x3_t BGR = vld3_u8(bgr); + const uint8x8_t Y = ConvertRGBToY_NEON(BGR.val[2], BGR.val[1], BGR.val[0]); + vst1_u8(y + i, Y); + } + for (; i < width; ++i, bgr += 3) { // left-over + y[i] = VP8RGBToY(bgr[2], bgr[1], bgr[0], YUV_HALF); + } +} + +static void ConvertARGBToY_NEON(const uint32_t* argb, uint8_t* y, int width) { + int i; + for (i = 0; i + 8 <= width; i += 8) { + const uint8x8x4_t RGB = vld4_u8((const uint8_t*)&argb[i]); + const uint8x8_t Y = ConvertRGBToY_NEON(RGB.val[2], RGB.val[1], RGB.val[0]); + vst1_u8(y + i, Y); + } + for (; i < width; ++i) { // left-over + const uint32_t p = argb[i]; + y[i] = VP8RGBToY((p >> 16) & 0xff, (p >> 8) & 0xff, (p >> 0) & 0xff, + YUV_HALF); + } +} + +//----------------------------------------------------------------------------- + +// computes: DST_s16 = [(C0 * r + C1 * g + C2 * b) >> 16] + CST +#define MULTIPLY_16b_PREAMBLE(r, g, b) \ + const int16x4_t r_lo = vreinterpret_s16_u16(vget_low_u16(r)); \ + const int16x4_t r_hi = vreinterpret_s16_u16(vget_high_u16(r)); \ + const int16x4_t g_lo = vreinterpret_s16_u16(vget_low_u16(g)); \ + const int16x4_t g_hi = vreinterpret_s16_u16(vget_high_u16(g)); \ + const int16x4_t b_lo = vreinterpret_s16_u16(vget_low_u16(b)); \ + const int16x4_t b_hi = vreinterpret_s16_u16(vget_high_u16(b)) + +#define MULTIPLY_16b(C0, C1, C2, CST, DST_s16) do { \ + const int32x4_t tmp0_lo = vmull_n_s16( r_lo, C0); \ + const int32x4_t tmp0_hi = vmull_n_s16( r_hi, C0); \ + const int32x4_t tmp1_lo = vmlal_n_s16(tmp0_lo, g_lo, C1); \ + const int32x4_t tmp1_hi = vmlal_n_s16(tmp0_hi, g_hi, C1); \ + const int32x4_t tmp2_lo = vmlal_n_s16(tmp1_lo, b_lo, C2); \ + const int32x4_t tmp2_hi = vmlal_n_s16(tmp1_hi, b_hi, C2); \ + const int16x8_t tmp3 = vcombine_s16(vshrn_n_s32(tmp2_lo, 16), \ + vshrn_n_s32(tmp2_hi, 16)); \ + DST_s16 = vaddq_s16(tmp3, vdupq_n_s16(CST)); \ +} while (0) + +// This needs to be a macro, since (128 << SHIFT) needs to be an immediate. +#define CONVERT_RGB_TO_UV(r, g, b, SHIFT, U_DST, V_DST) do { \ + MULTIPLY_16b_PREAMBLE(r, g, b); \ + MULTIPLY_16b(-9719, -19081, 28800, 128 << SHIFT, U_DST); \ + MULTIPLY_16b(28800, -24116, -4684, 128 << SHIFT, V_DST); \ +} while (0) + +static void ConvertRGBA32ToUV_NEON(const uint16_t* rgb, + uint8_t* u, uint8_t* v, int width) { + int i; + for (i = 0; i + 8 <= width; i += 8, rgb += 4 * 8) { + const uint16x8x4_t RGB = vld4q_u16((const uint16_t*)rgb); + int16x8_t U, V; + CONVERT_RGB_TO_UV(RGB.val[0], RGB.val[1], RGB.val[2], 2, U, V); + vst1_u8(u + i, vqrshrun_n_s16(U, 2)); + vst1_u8(v + i, vqrshrun_n_s16(V, 2)); + } + for (; i < width; i += 1, rgb += 4) { + const int r = rgb[0], g = rgb[1], b = rgb[2]; + u[i] = VP8RGBToU(r, g, b, YUV_HALF << 2); + v[i] = VP8RGBToV(r, g, b, YUV_HALF << 2); + } +} + +static void ConvertARGBToUV_NEON(const uint32_t* argb, uint8_t* u, uint8_t* v, + int src_width, int do_store) { + int i; + for (i = 0; i + 16 <= src_width; i += 16, u += 8, v += 8) { + const uint8x16x4_t RGB = vld4q_u8((const uint8_t*)&argb[i]); + const uint16x8_t R = vpaddlq_u8(RGB.val[2]); // pair-wise adds + const uint16x8_t G = vpaddlq_u8(RGB.val[1]); + const uint16x8_t B = vpaddlq_u8(RGB.val[0]); + int16x8_t U_tmp, V_tmp; + CONVERT_RGB_TO_UV(R, G, B, 1, U_tmp, V_tmp); + { + const uint8x8_t U = vqrshrun_n_s16(U_tmp, 1); + const uint8x8_t V = vqrshrun_n_s16(V_tmp, 1); + if (do_store) { + vst1_u8(u, U); + vst1_u8(v, V); + } else { + const uint8x8_t prev_u = vld1_u8(u); + const uint8x8_t prev_v = vld1_u8(v); + vst1_u8(u, vrhadd_u8(U, prev_u)); + vst1_u8(v, vrhadd_u8(V, prev_v)); + } + } + } + if (i < src_width) { // left-over + WebPConvertARGBToUV_C(argb + i, u, v, src_width - i, do_store); + } +} + + +//------------------------------------------------------------------------------ + +extern void WebPInitConvertARGBToYUVNEON(void); + +WEBP_TSAN_IGNORE_FUNCTION void WebPInitConvertARGBToYUVNEON(void) { + WebPConvertRGB24ToY = ConvertRGB24ToY_NEON; + WebPConvertBGR24ToY = ConvertBGR24ToY_NEON; + WebPConvertARGBToY = ConvertARGBToY_NEON; + WebPConvertARGBToUV = ConvertARGBToUV_NEON; + WebPConvertRGBA32ToUV = ConvertRGBA32ToUV_NEON; +} + +//------------------------------------------------------------------------------ + +#define MAX_Y ((1 << 10) - 1) // 10b precision over 16b-arithmetic +static uint16_t clip_y_NEON(int v) { + return (v < 0) ? 0 : (v > MAX_Y) ? MAX_Y : (uint16_t)v; +} + +static uint64_t SharpYUVUpdateY_NEON(const uint16_t* ref, const uint16_t* src, + uint16_t* dst, int len) { + int i; + const int16x8_t zero = vdupq_n_s16(0); + const int16x8_t max = vdupq_n_s16(MAX_Y); + uint64x2_t sum = vdupq_n_u64(0); + uint64_t diff; + + for (i = 0; i + 8 <= len; i += 8) { + const int16x8_t A = vreinterpretq_s16_u16(vld1q_u16(ref + i)); + const int16x8_t B = vreinterpretq_s16_u16(vld1q_u16(src + i)); + const int16x8_t C = vreinterpretq_s16_u16(vld1q_u16(dst + i)); + const int16x8_t D = vsubq_s16(A, B); // diff_y + const int16x8_t F = vaddq_s16(C, D); // new_y + const uint16x8_t H = + vreinterpretq_u16_s16(vmaxq_s16(vminq_s16(F, max), zero)); + const int16x8_t I = vabsq_s16(D); // abs(diff_y) + vst1q_u16(dst + i, H); + sum = vpadalq_u32(sum, vpaddlq_u16(vreinterpretq_u16_s16(I))); + } + diff = vgetq_lane_u64(sum, 0) + vgetq_lane_u64(sum, 1); + for (; i < len; ++i) { + const int diff_y = ref[i] - src[i]; + const int new_y = (int)(dst[i]) + diff_y; + dst[i] = clip_y_NEON(new_y); + diff += (uint64_t)(abs(diff_y)); + } + return diff; +} + +static void SharpYUVUpdateRGB_NEON(const int16_t* ref, const int16_t* src, + int16_t* dst, int len) { + int i; + for (i = 0; i + 8 <= len; i += 8) { + const int16x8_t A = vld1q_s16(ref + i); + const int16x8_t B = vld1q_s16(src + i); + const int16x8_t C = vld1q_s16(dst + i); + const int16x8_t D = vsubq_s16(A, B); // diff_uv + const int16x8_t E = vaddq_s16(C, D); // new_uv + vst1q_s16(dst + i, E); + } + for (; i < len; ++i) { + const int diff_uv = ref[i] - src[i]; + dst[i] += diff_uv; + } +} + +static void SharpYUVFilterRow_NEON(const int16_t* A, const int16_t* B, int len, + const uint16_t* best_y, uint16_t* out) { + int i; + const int16x8_t max = vdupq_n_s16(MAX_Y); + const int16x8_t zero = vdupq_n_s16(0); + for (i = 0; i + 8 <= len; i += 8) { + const int16x8_t a0 = vld1q_s16(A + i + 0); + const int16x8_t a1 = vld1q_s16(A + i + 1); + const int16x8_t b0 = vld1q_s16(B + i + 0); + const int16x8_t b1 = vld1q_s16(B + i + 1); + const int16x8_t a0b1 = vaddq_s16(a0, b1); + const int16x8_t a1b0 = vaddq_s16(a1, b0); + const int16x8_t a0a1b0b1 = vaddq_s16(a0b1, a1b0); // A0+A1+B0+B1 + const int16x8_t a0b1_2 = vaddq_s16(a0b1, a0b1); // 2*(A0+B1) + const int16x8_t a1b0_2 = vaddq_s16(a1b0, a1b0); // 2*(A1+B0) + const int16x8_t c0 = vshrq_n_s16(vaddq_s16(a0b1_2, a0a1b0b1), 3); + const int16x8_t c1 = vshrq_n_s16(vaddq_s16(a1b0_2, a0a1b0b1), 3); + const int16x8_t d0 = vaddq_s16(c1, a0); + const int16x8_t d1 = vaddq_s16(c0, a1); + const int16x8_t e0 = vrshrq_n_s16(d0, 1); + const int16x8_t e1 = vrshrq_n_s16(d1, 1); + const int16x8x2_t f = vzipq_s16(e0, e1); + const int16x8_t g0 = vreinterpretq_s16_u16(vld1q_u16(best_y + 2 * i + 0)); + const int16x8_t g1 = vreinterpretq_s16_u16(vld1q_u16(best_y + 2 * i + 8)); + const int16x8_t h0 = vaddq_s16(g0, f.val[0]); + const int16x8_t h1 = vaddq_s16(g1, f.val[1]); + const int16x8_t i0 = vmaxq_s16(vminq_s16(h0, max), zero); + const int16x8_t i1 = vmaxq_s16(vminq_s16(h1, max), zero); + vst1q_u16(out + 2 * i + 0, vreinterpretq_u16_s16(i0)); + vst1q_u16(out + 2 * i + 8, vreinterpretq_u16_s16(i1)); + } + for (; i < len; ++i) { + const int a0b1 = A[i + 0] + B[i + 1]; + const int a1b0 = A[i + 1] + B[i + 0]; + const int a0a1b0b1 = a0b1 + a1b0 + 8; + const int v0 = (8 * A[i + 0] + 2 * a1b0 + a0a1b0b1) >> 4; + const int v1 = (8 * A[i + 1] + 2 * a0b1 + a0a1b0b1) >> 4; + out[2 * i + 0] = clip_y_NEON(best_y[2 * i + 0] + v0); + out[2 * i + 1] = clip_y_NEON(best_y[2 * i + 1] + v1); + } +} +#undef MAX_Y + +//------------------------------------------------------------------------------ + +extern void WebPInitSharpYUVNEON(void); + +WEBP_TSAN_IGNORE_FUNCTION void WebPInitSharpYUVNEON(void) { + WebPSharpYUVUpdateY = SharpYUVUpdateY_NEON; + WebPSharpYUVUpdateRGB = SharpYUVUpdateRGB_NEON; + WebPSharpYUVFilterRow = SharpYUVFilterRow_NEON; +} + +#else // !WEBP_USE_NEON + +WEBP_DSP_INIT_STUB(WebPInitConvertARGBToYUVNEON) +WEBP_DSP_INIT_STUB(WebPInitSharpYUVNEON) + +#endif // WEBP_USE_NEON From bca314ad0229924ede1994b05c8e9f9e9c652526 Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Wed, 2 Oct 2019 14:00:30 +0200 Subject: [PATCH 8/8] No issue - Update TZ data to 2019c --- config/external/icu/data/icudt58l.dat | Bin 11695584 -> 11696784 bytes intl/tzdata/GIT-INFO | 8 +- intl/tzdata/VERSION | 2 +- intl/tzdata/source/be/metaZones.res | Bin 41488 -> 41488 bytes intl/tzdata/source/be/windowsZones.res | Bin 22496 -> 22528 bytes intl/tzdata/source/be/zoneinfo64.res | Bin 154224 -> 155392 bytes intl/tzdata/source/ee/metaZones.res | Bin 41488 -> 41488 bytes intl/tzdata/source/ee/windowsZones.res | Bin 22496 -> 22528 bytes intl/tzdata/source/ee/zoneinfo64.res | Bin 154224 -> 155392 bytes intl/tzdata/source/le/metaZones.res | Bin 41488 -> 41488 bytes intl/tzdata/source/le/windowsZones.res | Bin 22496 -> 22528 bytes intl/tzdata/source/le/zoneinfo64.res | Bin 154224 -> 155392 bytes intl/tzdata/source/metaZones.txt | 4 +- intl/tzdata/source/windowsZones.txt | 25 ++- intl/tzdata/source/zoneinfo64.txt | 160 ++++++++---------- js/src/builtin/IntlTimeZoneData.h | 2 +- .../DateTimeFormat/timeZone_backward_links.js | 2 +- .../Intl/DateTimeFormat/timeZone_backzone.js | 2 +- .../DateTimeFormat/timeZone_backzone_links.js | 2 +- .../timeZone_notbackward_links.js | 2 +- 20 files changed, 103 insertions(+), 106 deletions(-) diff --git a/config/external/icu/data/icudt58l.dat b/config/external/icu/data/icudt58l.dat index 528ff5ebec57fa30fcec919ece257d6893bd37f4..0bded3ec6448c32e6462bbb7d8bb39f6586157d8 100644 GIT binary patch delta 25737 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 delta 24451 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 diff --git a/intl/tzdata/GIT-INFO b/intl/tzdata/GIT-INFO index 9c6206b1b8..80b232e89c 100644 --- a/intl/tzdata/GIT-INFO +++ b/intl/tzdata/GIT-INFO @@ -1,5 +1,5 @@ -commit a1dd3c5661404aa93924e737aeb86acf130b8889 -Author: yumaoka -Date: Tue Mar 26 19:02:10 2019 -0400 +commit 4d027901ef4d3288b2ca264ba1f532cf826190ac +Author: Yoshito Umaoka +Date: Fri Sep 13 18:23:18 2019 -0400 - ICU-20522 tzdata2019a updates + ICU-20823 ICU time zone data updates for 2019c diff --git a/intl/tzdata/VERSION b/intl/tzdata/VERSION index 149d790c3d..db18f8311d 100644 --- a/intl/tzdata/VERSION +++ b/intl/tzdata/VERSION @@ -1 +1 @@ -2019a +2019c diff --git a/intl/tzdata/source/be/metaZones.res b/intl/tzdata/source/be/metaZones.res index 3df8225d6d33c3de81acdbf109c71db2de89b477..bc6b490a3f5e4984c267394d262b8916d0e9dd06 100644 GIT binary patch delta 24 gcmbPmglWPNrVZQOISm-h7<3to7%Vm)a1V$A0BSr3#Q*>R delta 24 gcmbPmglWPNrVZQOISm;M7<3s78B8`Ga1V$A0BPa}y8r+H diff --git a/intl/tzdata/source/be/windowsZones.res b/intl/tzdata/source/be/windowsZones.res index e6bb5af0fc01e64711e03214f04cd8f192edfff0..9e84b8f227928c822349270e7dbbb01e28e46a8c 100644 GIT binary patch delta 2956 zcmYk;c~lff8UXOBu0E@~dU|d^SZ8p(q7hUiMhuq+CK?$;-8H&KTwJ`tK{u;UGX#&t z=Mj>Qx=$mE&m$2HqG)`p33v;*M%SzwqGmB0yb=wriHR}m?$9#$%tPWRpN%$TiBq2l&BINxc3ax}P3~~3pnfZ!8Z{ebavx~!p1%dqe1#=4v!i9mc zGv-XIe_MG%l<~#0i;9cF1%>r*uvEkJX1nWmC(NT}dq%K6zQ^Ch`bT}b@#e7pN6hUh zJxn2`w*E>=3vcepNHMQGKRBrr%|Hbx35|yD-=ks_Jr1C(r%@6b4(I29BD4UNnnr@Z zzU!c|yt%HY$1w&jn2)BTX($X80%k*>?&kJqT;{6uW%hS*Mmp|o)@4no7cy%w&Ndrz zI@iCL-H$V`r1L`Mq5zME9b2U*P@>A zPas-=Pbo({qH@GsJgR4;)Lm+y56e^hTdeckY)oA>t{Sw^D(6;^ab#SyE!T@N6OjUC zC%DsG3wM?~&wa{W!qkx<{oq_>Y;YvF6V-t02HFC*G>2>Du5$n4zU105he<8kgeg5A_lo1+@w;F} z!Ei{e>!-LKc65#gXaG52-ngse2D#1e=6B1*=DwGo8@HW?_^+H}#2>{Y?w6Rx3GU5O ztNa;iemW16Vg^_dznmh9tO#FoBsr4ovg6WbX|t68-;Tpp0xTqFciI}y%=FRm-JGIR zL^8?|dJ9QHKVg6{P)HNfxh48MUX^#L9da|bE@q!uHaa+scm96SFxDln`_-* zp;9n~_1X?^l}I&v6ha*tK}OgqEKsVIYV*?QU`DL-PttC(UeKi$A>J8FtNH&pR=QGY z3E9dyt-4~+v){8Hi4diU>0*|Zrgq0TtaQ;YYj@1l+`go@v$r`jHzAVY%)l+yHE5)( z!PQ_#&2X>!SP_5RJ=s0kZZX}F<;b#flx9kEq!O)3Ym#qrA6Vz4HTWXFXh%DZHlxj2 zWYRI|r2dFb(I5TtUdg|XbEqNjArx!XCbf>nLciOt{zS$kjqggLd!SicrY*Co$ODxU zrNoYM`AWXhUcas6oYv~gXQ?;q~ z9X2G>ivN@qDdS0y*kwwImZ@c0Wn8;dB9&N!P_`)Bgc-_vq*y&~ zyx<*0ilaRk4~z%VNPgYxi$;7C-(=;AnuT;RP3(O8?h!57R)`5gaH4Ox`)$j4{{ibpwgGA*Emw2026 zb7+ZuT`Bz|T}T(x2rZ|}X$4(H*V4D>J9GoxNH^1J8rcfX4WUO^g77};dGm z-qE*t%hfV@4R@EDhVEM#Inzo?tkDs_vxO??lZ3FX>j zTIP67SWPp9*M;HIEmyfPRTzjG?Y@o?iAZ+Ts)UpQAv^5g%lUFE(qw!W-?bum3ah?z zRs_3Tb*R?1p^e&T7|B?3_n3r8#F6jFw`(@zI2>nRy_Xu)u%mm%S>vpIc9Z*l?22D5 zccm_Nlyk3Ahjv+O0iMegIo(&)I&0WshxViPSbHL7F^nl*qV)6CidXeh`~)QnFR@mt z*uhjdQxP$iYXMwgFWzg+3ytKcnVvI{I5f&S!*QN|3*}iyVmcg6)RNIeD-D*+`ioi6 zM3J$R&yXMDA}dW6VyAs;>}Zx!rj*&KH?z-txzR{Fs2#MUkxHA=h8!r8!>+I|)Hm66 z_7%Iy?y$S8gFRpm*(3HdtbDIn)G;Th?$W13JRY~)VSI#P!YAScSv{d%09 zpa=9WdN;kN-dj)7`{@JpfqI&ru4m~(#TfZru|nMD{Z7y2w(v1Vu9!`p=+AO1b<>?{ z6h!1hcD5nZAO5YMr&g|AU#KtEBYL^M98=+ELyB3Z8TtX?f^fon8C|pL>($%F+B6B}18@lq#!~8l^$GptLKGX#yQa zchFDhH!4x%)D-n4b*@^Yo>Z@@4>VOv)COt4(PnAo+Pm6*l&gKJ-PP_hp6M)xC9<9@ zmF2U!tb$du!|Z>0PDC%zEA*}Ui4gkLAHXb70v3QpAOe>Bv{KM?WA9{>OV delta 2908 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 P;&B#NrQ#y8qV@j*W*7F? delta 17041 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 kg4Ybh0)N2QV?vdZ!Q0GY%83jhEB diff --git a/intl/tzdata/source/ee/metaZones.res b/intl/tzdata/source/ee/metaZones.res index e495c2aa90c2b6db3e383db8b8a842d04477718c..bb2226702e56a938b603c8c4ff0d286363454288 100644 GIT binary patch delta 24 gcmbPmglWPNrVZQOISm-h7<3to7%Vm)a1V$A0BSr3#Q*>R delta 24 gcmbPmglWPNrVZQOISm;M7<3s78B8`Ga1V$A0BPa}y8r+H diff --git a/intl/tzdata/source/ee/windowsZones.res b/intl/tzdata/source/ee/windowsZones.res index 2a6500de33326ef1457f1aef6002f16df79b142c..c2ec2db8a8aedd27053c94ad8cc6ee36a205d057 100644 GIT binary patch delta 2956 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 Q9Pv1Vt5Q)RS=su30oRlNEC2ui delta 17041 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 F{{b*l#C8Ax delta 2874 zcmYk;c~BKc8UXO_Ip1_o&%3#=M-)+aH5@7i6+sad74V9dyIJwp)#C6@)aR{4P|O%L zi@G7Y>Uy9AS4GPx!PR{fiNUNy0&H|6A;x1ttBgq??l%K}EkUr*21-}Ki#u>LH* zcLoEUF?0BFj1zTn_;l!K3=QW}n)KqdFuh|SsfbO9=Ja{}9Qx7J z*Y%FnQCxbH-WDHKkvr0XD^f-kijiB@ttyAoP&(>hcl?dkMwEyXvC%3)Mb^)Q^tSZO z*Efvo z?Oo+utO<^^00sK4b2qsf?lbNS?n|y7 zMt5r8%WLfgwoa{=(@wu~lp+~MHE>PbH{5@@78nuAQClAOvGf&>-K}QaW-M7o_*=X% zuqPkQ_vQQXF?>8fh`+DAExje(S7vGDbhs936Jf-3{tx`0_*s0t&`$SCi=}$Om>?Z( z;DQ>IZ7$`4R--3o#PDJEFg+(D)Ei@uvDcV8G98_9 zoN;tLMn9;cv4tAAYGJnXC+lo;YYme;R*$*Ri{vG8u6$fQuHLnrHfJo7@8COToWIMr zZMSX4-Ji<;lpC}x(xCmej&94Kpk#W)9cV1$0#wHT)!ON24F6TemPEd%kZ3-x4=q=h zn@f;j$yTz>>SS1og<_#Av0Hql>ULC`Bl7Vab&lCOXz>sa>3Rqk@9K`Umqq9~nZbXY zq)t+eebQCWM~>QnhyYJ_HM8hhb1zI)JiN!eFIS0CV^kyc0;Nz{DDF~n_$u1pmgUar zj@x2uv31RrV+q#VGu__YfVsA=Gt-PalvfHz2;QJXI~D|g%{D0ivu{EK;x)th4kI<3 zhx8!5NFNyEC(rjE;PR8pt(g8Or&zA=`%nms97V>EaU_FGBvZ&VV%#@_yhXCf95SCQ zB1=dvSxQ!r)npCvl8t1Gmux3HAlwMKoOG(kMU54?M#$&wIPikAj)b$7uKT3e-ouj2 zCNdB8*_-T6XSyrf#W}L+9cvLXUJ4D|5ps;2Ag9S$QUS4^aLd?cZM!>b)gk)j ziJ{*4YMeFBJor8ogoDg`K2R~i=4Pr_uiCDfr7l4)oMnN(-Or`UpuofSQsrd#OPOFh zy6-Hd#%rKWx~G1tey1i&4^@KK;@6b@eofL*ZMqPvti{GwY?GeDmF-@<(q>n;n_bPg z6S~q+4E@5DW(JiR!CB~ET9)~3m_+al}nk$+i^fSDtAF+)^#kImvd?0#%ub5?CCH>)wDZ+!$?~mZ445 zrf39rh^^MVK&-y6-4?HlRqkf9^10do?y#%ttZm|VYP+>K`1@4kY;}zjVg*qta-K6+ z!iU=Vf$nYkmB~BsC;FHv!QNF`gp#C8SC%U8DMyt{%4f>Aib#G>c9Qet-{cYDXb6p^ zQ|Wv3G`&t6>2pfdNHq!G9gEb>>H#$aT~_a?4eDd{g^Czqb{57G*;JOxcCcH_UyISE zX-l;|+B;z=b3NDs-UYkBo-pLi`~Vt9!5MH4RDw^yO;8K!z+KP`9)O47DR>Tk2Csk+ zjxzm06zB_vfHW`_WP^F&&tMr?4c37Y@L{+YW&RBsC%_qS30wu&fe(BQz5&m`F91cL zOcC?|y}>|`2!?}HFcxHh$zVE|3Fd-DAP=knUa%PyfMVlI3HT5k1E)YaI1jFXPr*%4 z3+g~UXax7bL+}(l2QLBdL75i7fCB`AXfPD400m$t(7}Fi5O_a=ALXDH)PZ`?2=0Lv z@B{b}bO0QQG9^HP4Y)xB=mio$G8hZ8z%(!$EC5SDK3EO*gUjF=_%ad&X5NKHE5IlM MdElSq6WyQx157En4FCWD diff --git a/intl/tzdata/source/le/zoneinfo64.res b/intl/tzdata/source/le/zoneinfo64.res index 7e0afd40558838bbecb49c027053754ae4d1ccfe..2dd90caaa8146b7363f28d98834071eb3d5f19dd 100644 GIT binary patch delta 18155 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 !!! >> THIS IS A MACHINE-GENERATED FILE << !!! << // >> !!! >>> DO NOT EDIT <<< !!! << //--------------------------------------------------------- zoneinfo64:table(nofallback) { - TZVersion { "2019a" } + TZVersion { "2019c" } Zones:array { /* ACT */ :int { 355 } //Z#0 /* AET */ :int { 367 } //Z#1 @@ -60,8 +60,9 @@ zoneinfo64:table(nofallback) { } //Z#18 /* Africa/Casablanca */ :table { trans:intvector { -1773012580, -956361600, -950490000, -942019200, -761187600, -617241600, -605149200, -81432000, -71110800, 141264000, 147222000, 199756800, 207702000, 231292800, 244249200, 265507200, 271033200, 448243200, 504918000, 1212278400, 1220223600, 1243814400, 1250809200, 1272758400, 1281222000, 1301788800, 1312066800, 1335664800, 1342749600, 1345428000, 1348970400, 1367114400, 1373162400, 1376100000, 1382839200, 1396144800, 1403920800, 1406944800, 1414288800, 1427594400, 1434247200, 1437271200, 1445738400, 1459044000, 1465092000, 1468116000, 1477792800, 1490493600, 1495332000, 1498960800, 1509242400, 1521943200, 1526176800, 1529200800, 1557021600, 1560045600, 1587261600, 1590285600, 1618106400, 1621130400, 1648346400, 1651975200, 1679191200, 1682215200, 1710036000, 1713060000, 1740276000, 1743904800, 1771120800, 1774144800, 1801965600, 1804989600, 1832205600, 1835229600, 1863050400, 1866074400, 1893290400, 1896919200, 1924135200, 1927159200, 1954980000, 1958004000, 1985220000, 1988848800, 2016064800, 2019088800, 2046304800, 2049933600, 2077149600, 2080173600, 2107994400, 2111018400, 2138234400, 2141863200 } + transPost32:intvector { 0, -2125888096, 0, -2122864096, 0, -2095043296, 0, -2092019296, 0, -2064803296, 0, -2061174496, 0, -2033958496, 0, -2030934496, 0, -2003718496, 0, -2000089696, 0, -1972873696, 0, -1969849696, 0, -1942028896, 0, -1939004896, 0, -1911788896, 0, -1908160096, 0, -1880944096, 0, -1877920096, 0, -1850099296, 0, -1847075296, 0, -1819859296, 0, -1816230496, 0, -1789014496, 0, -1785990496, 0, -1758774496, 0, -1755145696, 0, -1727929696, 0, -1724905696, 0, -1697084896, 0, -1694060896, 0, -1666844896, 0, -1663216096, 0, -1636000096, 0, -1632976096, 0, -1605155296, 0, -1602131296, 0, -1574915296, 0, -1571286496, 0, -1544070496, 0, -1541046496, 0, -1513830496, 0, -1510201696, 0, -1482985696, 0, -1479961696, 0, -1452140896, 0, -1449116896, 0, -1421900896, 0, -1418272096, 0, -1391056096, 0, -1388032096, 0, -1360211296, 0, -1357187296, 0, -1329971296, 0, -1326947296, 0, -1299126496, 0, -1296102496, 0, -1268886496, 0, -1265257696, 0, -1238041696, 0, -1235017696, 0, -1207196896, 0, -1204172896, 0, -1176956896, 0, -1173328096, 0, -1146112096, 0, -1143088096, 0, -1115267296, 0, -1112243296, 0, -1085027296, 0, -1082003296, 0, -1054182496, 0, -1051158496, 0, -1023942496, 0, -1020313696, 0, -993097696, 0, -990073696, 0, -962252896, 0, -959228896, 0, -932012896, 0, -928384096, 0, -901168096, 0, -898144096, 0, -870323296, 0, -867299296, 0, -840083296, 0, -837059296, 0, -809238496, 0, -806214496, 0, -778998496, 0, -775369696, 0, -748153696, 0, -745129696, 0, -717308896, 0, -714284896, 0, -687068896, 0, -683440096, 0, -656224096, 0, -653200096, 0, -625379296, 0, -622355296, 0, -595139296, 0, -592115296 } typeOffsets:intvector { -1820, 0, 0, 0, 0, 3600, 3600, 0 } - typeMap:bin { "01020102010201020102010201020102010301020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102" } + typeMap:bin { "01020102010201020102010201020102010301020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102" } } //Z#19 /* Africa/Ceuta */ :table { transPre32:intvector { -1, 2117514496 } @@ -79,8 +80,9 @@ zoneinfo64:table(nofallback) { /* Africa/Douala */ :int { 36 } //Z#25 /* Africa/El_Aaiun */ :table { trans:intvector { -1136070432, 198291600, 199756800, 207702000, 231292800, 244249200, 265507200, 271033200, 1212278400, 1220223600, 1243814400, 1250809200, 1272758400, 1281222000, 1301788800, 1312066800, 1335664800, 1342749600, 1345428000, 1348970400, 1367114400, 1373162400, 1376100000, 1382839200, 1396144800, 1403920800, 1406944800, 1414288800, 1427594400, 1434247200, 1437271200, 1445738400, 1459044000, 1465092000, 1468116000, 1477792800, 1490493600, 1495332000, 1498960800, 1509242400, 1521943200, 1526176800, 1529200800, 1557021600, 1560045600, 1587261600, 1590285600, 1618106400, 1621130400, 1648346400, 1651975200, 1679191200, 1682215200, 1710036000, 1713060000, 1740276000, 1743904800, 1771120800, 1774144800, 1801965600, 1804989600, 1832205600, 1835229600, 1863050400, 1866074400, 1893290400, 1896919200, 1924135200, 1927159200, 1954980000, 1958004000, 1985220000, 1988848800, 2016064800, 2019088800, 2046304800, 2049933600, 2077149600, 2080173600, 2107994400, 2111018400, 2138234400, 2141863200 } + transPost32:intvector { 0, -2125888096, 0, -2122864096, 0, -2095043296, 0, -2092019296, 0, -2064803296, 0, -2061174496, 0, -2033958496, 0, -2030934496, 0, -2003718496, 0, -2000089696, 0, -1972873696, 0, -1969849696, 0, -1942028896, 0, -1939004896, 0, -1911788896, 0, -1908160096, 0, -1880944096, 0, -1877920096, 0, -1850099296, 0, -1847075296, 0, -1819859296, 0, -1816230496, 0, -1789014496, 0, -1785990496, 0, -1758774496, 0, -1755145696, 0, -1727929696, 0, -1724905696, 0, -1697084896, 0, -1694060896, 0, -1666844896, 0, -1663216096, 0, -1636000096, 0, -1632976096, 0, -1605155296, 0, -1602131296, 0, -1574915296, 0, -1571286496, 0, -1544070496, 0, -1541046496, 0, -1513830496, 0, -1510201696, 0, -1482985696, 0, -1479961696, 0, -1452140896, 0, -1449116896, 0, -1421900896, 0, -1418272096, 0, -1391056096, 0, -1388032096, 0, -1360211296, 0, -1357187296, 0, -1329971296, 0, -1326947296, 0, -1299126496, 0, -1296102496, 0, -1268886496, 0, -1265257696, 0, -1238041696, 0, -1235017696, 0, -1207196896, 0, -1204172896, 0, -1176956896, 0, -1173328096, 0, -1146112096, 0, -1143088096, 0, -1115267296, 0, -1112243296, 0, -1085027296, 0, -1082003296, 0, -1054182496, 0, -1051158496, 0, -1023942496, 0, -1020313696, 0, -993097696, 0, -990073696, 0, -962252896, 0, -959228896, 0, -932012896, 0, -928384096, 0, -901168096, 0, -898144096, 0, -870323296, 0, -867299296, 0, -840083296, 0, -837059296, 0, -809238496, 0, -806214496, 0, -778998496, 0, -775369696, 0, -748153696, 0, -745129696, 0, -717308896, 0, -714284896, 0, -687068896, 0, -683440096, 0, -656224096, 0, -653200096, 0, -625379296, 0, -622355296, 0, -595139296, 0, -592115296 } typeOffsets:intvector { -3168, 0, -3600, 0, 0, 0, 0, 3600 } - typeMap:bin { "0102030203020302030203020302030203020302030203020302030203020302030203020302030203020302030203020302030203020302030203020302030203020302030203020302030203020302030203" } + typeMap:bin { "0102030203020302030203020302030203020302030203020302030203020302030203020302030203020302030203020302030203020302030203020302030203020302030203020302030203020302030203020302030203020302030203020302030203020302030203020302030203020302030203020302030203020302030203020302030203020302030203020302030203020302030203020302030203020302030203020302030203020302030203020302030203" } } //Z#26 /* Africa/Freetown */ :int { 5 } //Z#27 /* Africa/Gaborone */ :int { 43 } //Z#28 @@ -355,13 +357,9 @@ zoneinfo64:table(nofallback) { finalYear:int { 2008 } } //Z#91 /* America/Campo_Grande */ :table { - trans:intvector { -1767212492, -1206954000, -1191358800, -1175371200, -1159822800, -633816000, -622065600, -602280000, -591829200, -570744000, -560206800, -539121600, -531349200, -191361600, -184194000, -155160000, -150066000, -128894400, -121122000, -99950400, -89586000, -68414400, -57963600, 499752000, 511239600, 530596800, 540270000, 562132800, 571201200, 592977600, 602046000, 624427200, 634705200, 656481600, 666759600, 687931200, 697604400, 719985600, 728449200, 750830400, 761713200, 782280000, 793162800, 813729600, 824007600, 844574400, 856062000, 876110400, 888721200, 908078400, 919566000, 938923200, 951620400, 970977600, 982465200, 1003032000, 1013914800, 1036296000, 1045364400, 1066536000, 1076814000, 1099368000, 1108868400, 1129435200, 1140318000, 1162699200, 1172372400, 1192334400, 1203217200, 1224388800, 1234666800, 1255838400, 1266721200, 1287288000, 1298170800, 1318737600, 1330225200, 1350792000, 1361070000, 1382241600, 1392519600, 1413691200, 1424574000, 1445140800, 1456023600, 1476590400, 1487473200, 1508040000, 1518922800, 1541304000, 1550372400, 1572753600, 1581822000, 1604203200, 1613876400, 1636257600, 1645326000, 1667707200, 1677380400, 1699156800, 1708225200, 1730606400, 1739674800, 1762056000, 1771729200, 1793505600, 1803178800, 1825560000, 1834628400, 1857009600, 1866078000, 1888459200, 1897527600, 1919908800, 1928977200, 1951358400, 1960426800, 1983412800, 1992481200, 2014862400, 2024535600, 2046312000, 2055380400, 2077761600, 2086830000, 2109211200, 2118884400, 2140660800 } - transPost32:intvector { 0, -2144633296, 0, -2122252096 } + trans:intvector { -1767212492, -1206954000, -1191358800, -1175371200, -1159822800, -633816000, -622065600, -602280000, -591829200, -570744000, -560206800, -539121600, -531349200, -191361600, -184194000, -155160000, -150066000, -128894400, -121122000, -99950400, -89586000, -68414400, -57963600, 499752000, 511239600, 530596800, 540270000, 562132800, 571201200, 592977600, 602046000, 624427200, 634705200, 656481600, 666759600, 687931200, 697604400, 719985600, 728449200, 750830400, 761713200, 782280000, 793162800, 813729600, 824007600, 844574400, 856062000, 876110400, 888721200, 908078400, 919566000, 938923200, 951620400, 970977600, 982465200, 1003032000, 1013914800, 1036296000, 1045364400, 1066536000, 1076814000, 1099368000, 1108868400, 1129435200, 1140318000, 1162699200, 1172372400, 1192334400, 1203217200, 1224388800, 1234666800, 1255838400, 1266721200, 1287288000, 1298170800, 1318737600, 1330225200, 1350792000, 1361070000, 1382241600, 1392519600, 1413691200, 1424574000, 1445140800, 1456023600, 1476590400, 1487473200, 1508040000, 1518922800, 1541304000, 1550372400 } typeOffsets:intvector { -13108, 0, -14400, 0, -14400, 3600 } - typeMap:bin { "01020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102" } - finalRule { "Brazil" } - finalRaw:int { -14400 } - finalYear:int { 2039 } + typeMap:bin { "01020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201" } } //Z#92 /* America/Cancun */ :table { trans:intvector { -1514743200, 377935200, 828860400, 846396000, 860310000, 877845600, 891759600, 902037600, 909298800, 923212800, 941353200, 954662400, 972802800, 989136000, 1001833200, 1018166400, 1035702000, 1049616000, 1067151600, 1081065600, 1099206000, 1112515200, 1130655600, 1143964800, 1162105200, 1175414400, 1193554800, 1207468800, 1225004400, 1238918400, 1256454000, 1270368000, 1288508400, 1301817600, 1319958000, 1333267200, 1351407600, 1365321600, 1382857200, 1396771200, 1414306800, 1422777600 } @@ -413,13 +411,9 @@ zoneinfo64:table(nofallback) { typeMap:bin { "020102" } } //Z#103 /* America/Cuiaba */ :table { - trans:intvector { -1767212140, -1206954000, -1191358800, -1175371200, -1159822800, -633816000, -622065600, -602280000, -591829200, -570744000, -560206800, -539121600, -531349200, -191361600, -184194000, -155160000, -150066000, -128894400, -121122000, -99950400, -89586000, -68414400, -57963600, 499752000, 511239600, 530596800, 540270000, 562132800, 571201200, 592977600, 602046000, 624427200, 634705200, 656481600, 666759600, 687931200, 697604400, 719985600, 728449200, 750830400, 761713200, 782280000, 793162800, 813729600, 824007600, 844574400, 856062000, 876110400, 888721200, 908078400, 919566000, 938923200, 951620400, 970977600, 982465200, 1003032000, 1013914800, 1036296000, 1045364400, 1099368000, 1108868400, 1129435200, 1140318000, 1162699200, 1172372400, 1192334400, 1203217200, 1224388800, 1234666800, 1255838400, 1266721200, 1287288000, 1298170800, 1318737600, 1330225200, 1350792000, 1361070000, 1382241600, 1392519600, 1413691200, 1424574000, 1445140800, 1456023600, 1476590400, 1487473200, 1508040000, 1518922800, 1541304000, 1550372400, 1572753600, 1581822000, 1604203200, 1613876400, 1636257600, 1645326000, 1667707200, 1677380400, 1699156800, 1708225200, 1730606400, 1739674800, 1762056000, 1771729200, 1793505600, 1803178800, 1825560000, 1834628400, 1857009600, 1866078000, 1888459200, 1897527600, 1919908800, 1928977200, 1951358400, 1960426800, 1983412800, 1992481200, 2014862400, 2024535600, 2046312000, 2055380400, 2077761600, 2086830000, 2109211200, 2118884400, 2140660800 } - transPost32:intvector { 0, -2144633296, 0, -2122252096 } + trans:intvector { -1767212140, -1206954000, -1191358800, -1175371200, -1159822800, -633816000, -622065600, -602280000, -591829200, -570744000, -560206800, -539121600, -531349200, -191361600, -184194000, -155160000, -150066000, -128894400, -121122000, -99950400, -89586000, -68414400, -57963600, 499752000, 511239600, 530596800, 540270000, 562132800, 571201200, 592977600, 602046000, 624427200, 634705200, 656481600, 666759600, 687931200, 697604400, 719985600, 728449200, 750830400, 761713200, 782280000, 793162800, 813729600, 824007600, 844574400, 856062000, 876110400, 888721200, 908078400, 919566000, 938923200, 951620400, 970977600, 982465200, 1003032000, 1013914800, 1036296000, 1045364400, 1099368000, 1108868400, 1129435200, 1140318000, 1162699200, 1172372400, 1192334400, 1203217200, 1224388800, 1234666800, 1255838400, 1266721200, 1287288000, 1298170800, 1318737600, 1330225200, 1350792000, 1361070000, 1382241600, 1392519600, 1413691200, 1424574000, 1445140800, 1456023600, 1476590400, 1487473200, 1508040000, 1518922800, 1541304000, 1550372400 } typeOffsets:intvector { -13460, 0, -14400, 0, -14400, 3600 } - typeMap:bin { "0102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102" } - finalRule { "Brazil" } - finalRaw:int { -14400 } - finalYear:int { 2039 } + typeMap:bin { "0102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201" } } //Z#104 /* America/Curacao */ :table { trans:intvector { -1826738653, -157750200 } @@ -458,9 +452,9 @@ zoneinfo64:table(nofallback) { links:intvector { 109, 204, 544, 624 } } //Z#109 /* America/Detroit */ :table { - trans:intvector { -2051202469, -1724083200, -880218000, -765396000, -684349200, -671047200, 104914800, 120636000, 126687600, 152085600, 167814000, 183535200, 199263600, 215589600, 230713200, 247039200, 262767600, 278488800, 294217200, 309938400, 325666800, 341388000, 357116400, 372837600, 388566000, 404892000, 420015600, 436341600, 452070000, 467791200, 483519600, 499240800, 514969200, 530690400, 544604400, 562140000, 576054000, 594194400, 607503600, 625644000, 638953200, 657093600, 671007600, 688543200, 702457200, 719992800, 733906800, 752047200, 765356400, 783496800, 796806000, 814946400, 828860400, 846396000, 860310000, 877845600, 891759600, 909295200, 923209200, 941349600, 954658800, 972799200, 986108400, 1004248800, 1018162800, 1035698400, 1049612400, 1067148000, 1081062000, 1099202400, 1112511600, 1130652000, 1143961200, 1162101600, 1173596400, 1194156000 } + trans:intvector { -2051202469, -1724083200, -880218000, -765396000, -684349200, -671047200, -80506740, -68666400, -52938000, -37216800, 104914800, 120636000, 126687600, 152085600, 167814000, 183535200, 199263600, 215589600, 230713200, 247039200, 262767600, 278488800, 294217200, 309938400, 325666800, 341388000, 357116400, 372837600, 388566000, 404892000, 420015600, 436341600, 452070000, 467791200, 483519600, 499240800, 514969200, 530690400, 544604400, 562140000, 576054000, 594194400, 607503600, 625644000, 638953200, 657093600, 671007600, 688543200, 702457200, 719992800, 733906800, 752047200, 765356400, 783496800, 796806000, 814946400, 828860400, 846396000, 860310000, 877845600, 891759600, 909295200, 923209200, 941349600, 954658800, 972799200, 986108400, 1004248800, 1018162800, 1035698400, 1049612400, 1067148000, 1081062000, 1099202400, 1112511600, 1130652000, 1143961200, 1162101600, 1173596400, 1194156000 } typeOffsets:intvector { -19931, 0, -21600, 0, -18000, 0, -18000, 3600 } - typeMap:bin { "01020302030203020302030203020302030203020302030203020302030203020302030203020302030203020302030203020302030203020302030203020302030203020302030203020302" } + typeMap:bin { "0102030203020302030203020302030203020302030203020302030203020302030203020302030203020302030203020302030203020302030203020302030203020302030203020302030203020302" } finalRule { "US" } finalRaw:int { -18000 } finalYear:int { 2008 } @@ -468,9 +462,9 @@ zoneinfo64:table(nofallback) { } //Z#110 /* America/Dominica */ :int { 186 } //Z#111 /* America/Edmonton */ :table { - trans:intvector { -1998663968, -1632063600, -1615132800, -1600614000, -1596816000, -1567954800, -1551628800, -1536505200, -1523203200, -1504450800, -1491753600, -1473001200, -1459699200, -880210800, -765388800, -715791600, -702489600, -84380400, -68659200, -21481200, -5760000, 73472400, 89193600, 104922000, 120643200, 136371600, 152092800, 167821200, 183542400, 199270800, 215596800, 230720400, 247046400, 262774800, 278496000, 294224400, 309945600, 325674000, 341395200, 357123600, 372844800, 388573200, 404899200, 420022800, 436348800, 452077200, 467798400, 483526800, 499248000, 514976400, 530697600, 544611600, 562147200, 576061200, 594201600, 607510800, 625651200, 638960400, 657100800, 671014800, 688550400, 702464400, 720000000, 733914000, 752054400, 765363600, 783504000, 796813200, 814953600, 828867600, 846403200, 860317200, 877852800, 891766800, 909302400, 923216400, 941356800, 954666000, 972806400, 986115600, 1004256000, 1018170000, 1035705600, 1049619600, 1067155200, 1081069200, 1099209600, 1112518800, 1130659200, 1143968400, 1162108800, 1173603600, 1194163200 } + trans:intvector { -1998663968, -1632063600, -1615132800, -1600614000, -1596816000, -1567954800, -1551628800, -1536505200, -1523203200, -1504450800, -1491753600, -1473001200, -1459699200, -880210800, -765388800, -715791600, -702489600, 73472400, 89193600, 104922000, 120643200, 136371600, 152092800, 167821200, 183542400, 199270800, 215596800, 230720400, 247046400, 262774800, 278496000, 294224400, 309945600, 325674000, 341395200, 357123600, 372844800, 388573200, 404899200, 420022800, 436348800, 452077200, 467798400, 483526800, 499248000, 514976400, 530697600, 544611600, 562147200, 576061200, 594201600, 607510800, 625651200, 638960400, 657100800, 671014800, 688550400, 702464400, 720000000, 733914000, 752054400, 765363600, 783504000, 796813200, 814953600, 828867600, 846403200, 860317200, 877852800, 891766800, 909302400, 923216400, 941356800, 954666000, 972806400, 986115600, 1004256000, 1018170000, 1035705600, 1049619600, 1067155200, 1081069200, 1099209600, 1112518800, 1130659200, 1143968400, 1162108800, 1173603600, 1194163200 } typeOffsets:intvector { -27232, 0, -25200, 0, -25200, 3600 } - typeMap:bin { "010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201" } + typeMap:bin { "0102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201" } finalRule { "Canada" } finalRaw:int { -25200 } finalYear:int { 2008 } @@ -615,9 +609,9 @@ zoneinfo64:table(nofallback) { } //Z#134 /* America/Indiana/Tell_City */ :table { transPre32:intvector { -1, 1577320096 } - trans:intvector { -1633276800, -1615136400, -1601827200, -1583686800, -880214400, -765392400, -747244800, -733942800, -526492800, -513190800, -495043200, -481741200, -462996000, -450291600, -431539200, -418237200, -400089600, -386787600, -368640000, -355338000, -337190400, -323888400, -305740800, -289414800, -273686400, -260989200, -242236800, -226515600, -210787200, -195066000, -179337600, -21488400, -5767200, 9961200, 25682400, 1143961200, 1162105200, 1173600000, 1194159600 } + trans:intvector { -1633276800, -1615136400, -1601827200, -1583686800, -880214400, -765392400, -462996000, -450291600, -431539200, -418237200, -400089600, -386787600, -368640000, -355338000, -337190400, -323888400, -305740800, -292438800, -273686400, -257965200, -242236800, -226515600, -210787200, -195066000, -179337600, -68662800, -52934400, -37213200, -21484800, -5767200, 9961200, 25682400, 1143961200, 1162105200, 1173600000, 1194159600 } typeOffsets:intvector { -20823, 0, -21600, 0, -21600, 3600, -18000, 0, -18000, 3600 } - typeMap:bin { "01020102010201020102010201020102010201020102010201020102010201030403040302010201" } + typeMap:bin { "01020102010201020102010201020102010201020102010201030102010403040302010201" } finalRule { "US" } finalRaw:int { -21600 } finalYear:int { 2008 } @@ -684,7 +678,7 @@ zoneinfo64:table(nofallback) { } //Z#144 /* America/Kentucky/Louisville */ :table { transPre32:intvector { -1, 1577320096 } - trans:intvector { -1633276800, -1615136400, -1601827200, -1583686800, -1535904000, -1525280400, -905097600, -891795600, -880214400, -765392400, -757360800, -744224400, -715795200, -608144400, -589392000, -576090000, -557942400, -544640400, -526492800, -513190800, -495043200, -481741200, -463593600, -450291600, -431539200, -415818000, -400089600, -384368400, -368640000, -352918800, -337190400, -321469200, -305740800, -289414800, -273686400, -266432400, -52938000, -37216800, -21488400, -5767200, 9961200, 25682400, 41410800, 57736800, 73465200, 89186400, 104914800, 120636000, 126687600, 152089200, 162370800, 183535200, 199263600, 215589600, 230713200, 247039200, 262767600, 278488800, 294217200, 309938400, 325666800, 341388000, 357116400, 372837600, 388566000, 404892000, 420015600, 436341600, 452070000, 467791200, 483519600, 499240800, 514969200, 530690400, 544604400, 562140000, 576054000, 594194400, 607503600, 625644000, 638953200, 657093600, 671007600, 688543200, 702457200, 719992800, 733906800, 752047200, 765356400, 783496800, 796806000, 814946400, 828860400, 846396000, 860310000, 877845600, 891759600, 909295200, 923209200, 941349600, 954658800, 972799200, 986108400, 1004248800, 1018162800, 1035698400, 1049612400, 1067148000, 1081062000, 1099202400, 1112511600, 1130652000, 1143961200, 1162101600, 1173596400, 1194156000 } + trans:intvector { -1633276800, -1615136400, -1601827200, -1583686800, -1535904000, -1525280400, -905097600, -891795600, -880214400, -765392400, -747251940, -744224400, -620841600, -608144400, -589392000, -576090000, -557942400, -544640400, -526492800, -513190800, -495043200, -481741200, -463593600, -450291600, -431539200, -415818000, -400089600, -384368400, -368640000, -352918800, -337190400, -321469200, -305740800, -289414800, -273686400, -266432400, -52938000, -37216800, -21488400, -5767200, 9961200, 25682400, 41410800, 57736800, 73465200, 89186400, 104914800, 120636000, 126687600, 152089200, 162370800, 183535200, 199263600, 215589600, 230713200, 247039200, 262767600, 278488800, 294217200, 309938400, 325666800, 341388000, 357116400, 372837600, 388566000, 404892000, 420015600, 436341600, 452070000, 467791200, 483519600, 499240800, 514969200, 530690400, 544604400, 562140000, 576054000, 594194400, 607503600, 625644000, 638953200, 657093600, 671007600, 688543200, 702457200, 719992800, 733906800, 752047200, 765356400, 783496800, 796806000, 814946400, 828860400, 846396000, 860310000, 877845600, 891759600, 909295200, 923209200, 941349600, 954658800, 972799200, 986108400, 1004248800, 1018162800, 1035698400, 1049612400, 1067148000, 1081062000, 1099202400, 1112511600, 1130652000, 1143961200, 1162101600, 1173596400, 1194156000 } typeOffsets:intvector { -20582, 0, -21600, 0, -21600, 3600, -18000, 0, -18000, 3600 } typeMap:bin { "010201020102010201020102010201020102010201020102010201020102010201020102030403040304030403040304030203040304030403040304030403040304030403040304030403040304030403040304030403040304030403040304030403040304030403040304030403040304030403" } finalRule { "US" } @@ -1037,13 +1031,9 @@ zoneinfo64:table(nofallback) { typeMap:bin { "0401030102010201020102010201050105" } } //Z#201 /* America/Sao_Paulo */ :table { - trans:intvector { -1767214412, -1206957600, -1191362400, -1175374800, -1159826400, -633819600, -622069200, -602283600, -591832800, -570747600, -560210400, -539125200, -531352800, -195426000, -184197600, -155163600, -150069600, -128898000, -121125600, -99954000, -89589600, -68418000, -57967200, 499748400, 511236000, 530593200, 540266400, 562129200, 571197600, 592974000, 602042400, 624423600, 634701600, 656478000, 666756000, 687927600, 697600800, 719982000, 728445600, 750826800, 761709600, 782276400, 793159200, 813726000, 824004000, 844570800, 856058400, 876106800, 888717600, 908074800, 919562400, 938919600, 951616800, 970974000, 982461600, 1003028400, 1013911200, 1036292400, 1045360800, 1066532400, 1076810400, 1099364400, 1108864800, 1129431600, 1140314400, 1162695600, 1172368800, 1192330800, 1203213600, 1224385200, 1234663200, 1255834800, 1266717600, 1287284400, 1298167200, 1318734000, 1330221600, 1350788400, 1361066400, 1382238000, 1392516000, 1413687600, 1424570400, 1445137200, 1456020000, 1476586800, 1487469600, 1508036400, 1518919200, 1541300400, 1550368800, 1572750000, 1581818400, 1604199600, 1613872800, 1636254000, 1645322400, 1667703600, 1677376800, 1699153200, 1708221600, 1730602800, 1739671200, 1762052400, 1771725600, 1793502000, 1803175200, 1825556400, 1834624800, 1857006000, 1866074400, 1888455600, 1897524000, 1919905200, 1928973600, 1951354800, 1960423200, 1983409200, 1992477600, 2014858800, 2024532000, 2046308400, 2055376800, 2077758000, 2086826400, 2109207600, 2118880800, 2140657200 } - transPost32:intvector { 0, -2144636896, 0, -2122255696 } + trans:intvector { -1767214412, -1206957600, -1191362400, -1175374800, -1159826400, -633819600, -622069200, -602283600, -591832800, -570747600, -560210400, -539125200, -531352800, -195426000, -184197600, -155163600, -150069600, -128898000, -121125600, -99954000, -89589600, -68418000, -57967200, 499748400, 511236000, 530593200, 540266400, 562129200, 571197600, 592974000, 602042400, 624423600, 634701600, 656478000, 666756000, 687927600, 697600800, 719982000, 728445600, 750826800, 761709600, 782276400, 793159200, 813726000, 824004000, 844570800, 856058400, 876106800, 888717600, 908074800, 919562400, 938919600, 951616800, 970974000, 982461600, 1003028400, 1013911200, 1036292400, 1045360800, 1066532400, 1076810400, 1099364400, 1108864800, 1129431600, 1140314400, 1162695600, 1172368800, 1192330800, 1203213600, 1224385200, 1234663200, 1255834800, 1266717600, 1287284400, 1298167200, 1318734000, 1330221600, 1350788400, 1361066400, 1382238000, 1392516000, 1413687600, 1424570400, 1445137200, 1456020000, 1476586800, 1487469600, 1508036400, 1518919200, 1541300400, 1550368800 } typeOffsets:intvector { -11188, 0, -10800, 0, -10800, 3600 } - typeMap:bin { "01020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102" } - finalRule { "Brazil" } - finalRaw:int { -10800 } - finalYear:int { 2039 } + typeMap:bin { "01020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201" } links:intvector { 202, 372, 376 } } //Z#202 /* America/Scoresbysund */ :table { @@ -1127,7 +1117,7 @@ zoneinfo64:table(nofallback) { /* America/Tortola */ :int { 186 } //Z#218 /* America/Vancouver */ :table { transPre32:intvector { -1, 1581086444 } - trans:intvector { -1632060000, -1615129200, -880207200, -765385200, -747237600, -732726000, -715788000, -702486000, -684338400, -671036400, -652888800, -639586800, -620834400, -608137200, -589384800, -576082800, -557935200, -544633200, -526485600, -513183600, -495036000, -481734000, -463586400, -450284400, -431532000, -418230000, -400082400, -386780400, -368632800, -355330800, -337183200, -323881200, -305733600, -292431600, -273679200, -260982000, -242229600, -226508400, -210780000, -195058800, -179330400, -163609200, -147880800, -131554800, -116431200, -100105200, -84376800, -68655600, -52927200, -37206000, -21477600, -5756400, 9972000, 25693200, 41421600, 57747600, 73476000, 89197200, 104925600, 120646800, 136375200, 152096400, 167824800, 183546000, 199274400, 215600400, 230724000, 247050000, 262778400, 278499600, 294228000, 309949200, 325677600, 341398800, 357127200, 372848400, 388576800, 404902800, 420026400, 436352400, 452080800, 467802000, 483530400, 499251600, 514980000, 530701200, 544615200, 562150800, 576064800, 594205200, 607514400, 625654800, 638964000, 657104400, 671018400, 688554000, 702468000, 720003600, 733917600, 752058000, 765367200, 783507600, 796816800, 814957200, 828871200, 846406800, 860320800, 877856400, 891770400, 909306000, 923220000, 941360400, 954669600, 972810000, 986119200, 1004259600, 1018173600, 1035709200, 1049623200, 1067158800, 1081072800, 1099213200, 1112522400, 1130662800, 1143972000, 1162112400, 1173607200, 1194166800 } + trans:intvector { -1632060000, -1615129200, -880207200, -765385200, -747237600, -733935600, -715788000, -702486000, -684338400, -671036400, -652888800, -639586800, -620834400, -608137200, -589384800, -576082800, -557935200, -544633200, -526485600, -513183600, -495036000, -481734000, -463586400, -450284400, -431532000, -418230000, -400082400, -386780400, -368632800, -355330800, -337183200, -323881200, -305733600, -292431600, -273679200, -260982000, -242229600, -226508400, -210780000, -195058800, -179330400, -163609200, -147880800, -131554800, -116431200, -100105200, -84376800, -68655600, -52927200, -37206000, -21477600, -5756400, 9972000, 25693200, 41421600, 57747600, 73476000, 89197200, 104925600, 120646800, 136375200, 152096400, 167824800, 183546000, 199274400, 215600400, 230724000, 247050000, 262778400, 278499600, 294228000, 309949200, 325677600, 341398800, 357127200, 372848400, 388576800, 404902800, 420026400, 436352400, 452080800, 467802000, 483530400, 499251600, 514980000, 530701200, 544615200, 562150800, 576064800, 594205200, 607514400, 625654800, 638964000, 657104400, 671018400, 688554000, 702468000, 720003600, 733917600, 752058000, 765367200, 783507600, 796816800, 814957200, 828871200, 846406800, 860320800, 877856400, 891770400, 909306000, 923220000, 941360400, 954669600, 972810000, 986119200, 1004259600, 1018173600, 1035709200, 1049623200, 1067158800, 1081072800, 1099213200, 1112522400, 1130662800, 1143972000, 1162112400, 1173607200, 1194166800 } typeOffsets:intvector { -29548, 0, -28800, 0, -28800, 3600 } typeMap:bin { "010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201" } finalRule { "Canada" } @@ -1374,22 +1364,22 @@ zoneinfo64:table(nofallback) { } //Z#267 /* Asia/Gaza */ :table { transPre32:intvector { -1, 2109557424 } - trans:intvector { -933645600, -857358000, -844300800, -825822000, -812685600, -794199600, -779853600, -762656400, -748310400, -731127600, -399088800, -386650800, -368330400, -355114800, -336790800, -323654400, -305168400, -292032000, -273632400, -260496000, -242096400, -228960000, -210560400, -197424000, -178938000, -165801600, -147402000, -134265600, -115866000, -102643200, -84330000, -81313200, 142380000, 150843600, 167176800, 178664400, 334015200, 337644000, 452556000, 462232800, 482277600, 495579600, 516751200, 526424400, 545436000, 558478800, 576626400, 589323600, 609890400, 620773200, 638316000, 651618000, 669765600, 683672400, 701820000, 715726800, 733701600, 747176400, 765151200, 778021200, 796600800, 810075600, 828655200, 843170400, 860104800, 874620000, 891554400, 906069600, 924213600, 939934800, 956268000, 971989200, 987717600, 1003438800, 1019167200, 1034888400, 1050616800, 1066338000, 1082066400, 1096581600, 1113516000, 1128380400, 1143842400, 1158872400, 1175378400, 1189638000, 1206655200, 1219957200, 1238104800, 1252015200, 1269640860, 1281474000, 1301608860, 1312146000, 1333058400, 1348178400, 1364508000, 1380229200, 1395957600, 1414098000, 1427493600, 1445547600, 1458946800, 1477692000 } + trans:intvector { -933645600, -857358000, -844300800, -825822000, -812685600, -794199600, -779853600, -762656400, -748310400, -731127600, -399088800, -386650800, -368330400, -355114800, -336790800, -323654400, -305168400, -292032000, -273632400, -260496000, -242096400, -228960000, -210560400, -197424000, -178938000, -165801600, -147402000, -134265600, -115866000, -102643200, -84330000, -81313200, 142380000, 150843600, 167176800, 178664400, 334015200, 337644000, 452556000, 462232800, 482277600, 495579600, 516751200, 526424400, 545436000, 558478800, 576626400, 589323600, 609890400, 620773200, 638316000, 651618000, 669765600, 683672400, 701820000, 715726800, 733701600, 747176400, 765151200, 778021200, 796600800, 810075600, 828655200, 843170400, 860104800, 874620000, 891554400, 906069600, 924213600, 939934800, 956268000, 971989200, 987717600, 1003438800, 1019167200, 1034888400, 1050616800, 1066338000, 1082066400, 1096581600, 1113516000, 1128380400, 1143842400, 1158872400, 1175378400, 1189638000, 1206655200, 1219957200, 1238104800, 1252015200, 1269640860, 1281474000, 1301608860, 1312146000, 1333058400, 1348178400, 1364508000, 1380229200, 1395957600, 1414098000, 1427493600, 1445547600, 1458946800, 1477692000, 1490396400, 1509141600, 1521846000, 1540591200, 1553810400, 1572040800 } typeOffsets:intvector { 8272, 0, 7200, 0, 7200, 3600 } - typeMap:bin { "010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201" } + typeMap:bin { "010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201" } finalRule { "Palestine" } finalRaw:int { 7200 } - finalYear:int { 2017 } + finalYear:int { 2020 } } //Z#268 /* Asia/Harbin */ :int { 314 } //Z#269 /* Asia/Hebron */ :table { transPre32:intvector { -1, 2109557273 } - trans:intvector { -933645600, -857358000, -844300800, -825822000, -812685600, -794199600, -779853600, -762656400, -748310400, -731127600, -399088800, -386650800, -368330400, -355114800, -336790800, -323654400, -305168400, -292032000, -273632400, -260496000, -242096400, -228960000, -210560400, -197424000, -178938000, -165801600, -147402000, -134265600, -115866000, -102643200, -84330000, -81313200, 142380000, 150843600, 167176800, 178664400, 334015200, 337644000, 452556000, 462232800, 482277600, 495579600, 516751200, 526424400, 545436000, 558478800, 576626400, 589323600, 609890400, 620773200, 638316000, 651618000, 669765600, 683672400, 701820000, 715726800, 733701600, 747176400, 765151200, 778021200, 796600800, 810075600, 828655200, 843170400, 860104800, 874620000, 891554400, 906069600, 924213600, 939934800, 956268000, 971989200, 987717600, 1003438800, 1019167200, 1034888400, 1050616800, 1066338000, 1082066400, 1096581600, 1113516000, 1128380400, 1143842400, 1158872400, 1175378400, 1189638000, 1206655200, 1220216400, 1238104800, 1252015200, 1269554400, 1281474000, 1301608860, 1312146000, 1314655200, 1317330000, 1333058400, 1348178400, 1364508000, 1380229200, 1395957600, 1414098000, 1427493600, 1445547600, 1458946800, 1477692000 } + trans:intvector { -933645600, -857358000, -844300800, -825822000, -812685600, -794199600, -779853600, -762656400, -748310400, -731127600, -399088800, -386650800, -368330400, -355114800, -336790800, -323654400, -305168400, -292032000, -273632400, -260496000, -242096400, -228960000, -210560400, -197424000, -178938000, -165801600, -147402000, -134265600, -115866000, -102643200, -84330000, -81313200, 142380000, 150843600, 167176800, 178664400, 334015200, 337644000, 452556000, 462232800, 482277600, 495579600, 516751200, 526424400, 545436000, 558478800, 576626400, 589323600, 609890400, 620773200, 638316000, 651618000, 669765600, 683672400, 701820000, 715726800, 733701600, 747176400, 765151200, 778021200, 796600800, 810075600, 828655200, 843170400, 860104800, 874620000, 891554400, 906069600, 924213600, 939934800, 956268000, 971989200, 987717600, 1003438800, 1019167200, 1034888400, 1050616800, 1066338000, 1082066400, 1096581600, 1113516000, 1128380400, 1143842400, 1158872400, 1175378400, 1189638000, 1206655200, 1220216400, 1238104800, 1252015200, 1269554400, 1281474000, 1301608860, 1312146000, 1314655200, 1317330000, 1333058400, 1348178400, 1364508000, 1380229200, 1395957600, 1414098000, 1427493600, 1445547600, 1458946800, 1477692000, 1490396400, 1509141600, 1521846000, 1540591200, 1553810400, 1572040800 } typeOffsets:intvector { 8423, 0, 7200, 0, 7200, 3600 } - typeMap:bin { "0102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201" } + typeMap:bin { "0102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201" } finalRule { "Palestine" } finalRaw:int { 7200 } - finalYear:int { 2017 } + finalYear:int { 2020 } } //Z#270 /* Asia/Ho_Chi_Minh */ :table { trans:intvector { -2004073600, -1851577590, -852105600, -782643600, -767869200, -718095600, -457776000, -315648000, 171820800 } @@ -1398,9 +1388,9 @@ zoneinfo64:table(nofallback) { links:intvector { 271, 310, 630 } } //Z#271 /* Asia/Hong_Kong */ :table { - trans:intvector { -2056690800, -900909000, -891579600, -884248200, -766659600, -747981000, -728544600, -717049800, -694503000, -683785800, -668064600, -654755400, -636615000, -623305800, -605165400, -591856200, -573715800, -559801800, -541661400, -528352200, -510211800, -498112200, -478762200, -466662600, -446707800, -435213000, -415258200, -403158600, -383808600, -371709000, -352359000, -340259400, -320909400, -308809800, -288855000, -277360200, -257405400, -245910600, -225955800, -213856200, -194506200, -182406600, -163056600, -148537800, -132816600, -117088200, -101367000, -85638600, -69312600, -53584200, -37863000, -22134600, -6413400, 9315000, 25036200, 40764600, 56485800, 72214200, 88540200, 104268600, 119989800, 126041400, 151439400, 167167800, 182889000, 198617400, 214338600, 295385400, 309292200 } - typeOffsets:intvector { 27402, 0, 28800, 0, 28800, 3600, 30600, 0, 32400, 0 } - typeMap:bin { "010203040102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201" } + trans:intvector { -2056690800, -900910800, -891579600, -884248200, -761209200, -747907200, -728541000, -717049800, -697091400, -683785800, -668061000, -654755400, -636611400, -623305800, -605161800, -591856200, -573712200, -559801800, -541657800, -528352200, -510211800, -498112200, -478762200, -466662600, -446707800, -435213000, -415258200, -403158600, -383808600, -371709000, -352359000, -340259400, -320909400, -308809800, -288855000, -277360200, -257405400, -245910600, -225955800, -213856200, -194506200, -182406600, -163056600, -148537800, -132816600, -117088200, -101367000, -85638600, -69312600, -53584200, -37863000, -22134600, -6413400, 9315000, 25036200, 40764600, 56485800, 72214200, 88540200, 104268600, 119989800, 126041400, 151439400, 167167800, 182889000, 198617400, 214338600, 295385400, 309292200 } + typeOffsets:intvector { 27402, 0, 28800, 0, 28800, 1800, 28800, 3600, 32400, 0 } + typeMap:bin { "010302040103010301030103010301030103010301030103010301030103010301030103010301030103010301030103010301030103010301030103010301030103010301" } links:intvector { 272, 511 } } //Z#272 /* Asia/Hovd */ :table { @@ -1588,9 +1578,9 @@ zoneinfo64:table(nofallback) { typeMap:bin { "010203040302030203020302030203020302030203020302" } } //Z#312 /* Asia/Seoul */ :table { - trans:intvector { -1948782472, -1830414600, -498128400, -462702600, -451733400, -429784200, -418296600, -399544200, -387451800, -368094600, -356002200, -336645000, -324552600, -305195400, -293103000, -264933000, 547578000, 560883600, 579027600, 592333200 } + trans:intvector { -1948782472, -1830414600, -681210000, -672228000, -654771600, -640864800, -623408400, -609415200, -588848400, -577965600, -498128400, -462702600, -451733400, -429784200, -418296600, -399544200, -387451800, -368094600, -356002200, -336645000, -324552600, -305195400, -293103000, -264933000, 547578000, 560883600, 579027600, 592333200 } typeOffsets:intvector { 30472, 0, 30600, 0, 30600, 3600, 32400, 0, 32400, 3600 } - typeMap:bin { "0103010201020102010201020102010304030403" } + typeMap:bin { "01030403040304030403010201020102010201020102010304030403" } links:intvector { 313, 597 } } //Z#313 /* Asia/Shanghai */ :table { @@ -2093,7 +2083,7 @@ zoneinfo64:table(nofallback) { } //Z#445 /* Europe/Bratislava */ :int { 477 } //Z#446 /* Europe/Brussels */ :table { - transPre32:intvector { -1, 1844014246 } + transPre32:intvector { -1, 1843972096 } trans:intvector { -1740355200, -1693702800, -1680483600, -1663455600, -1650150000, -1632006000, -1618700400, -1613826000, -1604278800, -1585530000, -1574038800, -1552266000, -1539997200, -1520557200, -1507510800, -1490576400, -1473642000, -1459126800, -1444006800, -1427677200, -1411952400, -1396227600, -1379293200, -1364778000, -1348448400, -1333328400, -1316394000, -1301263200, -1284328800, -1269813600, -1253484000, -1238364000, -1221429600, -1206914400, -1191189600, -1175464800, -1160344800, -1143410400, -1127685600, -1111960800, -1096840800, -1080511200, -1063576800, -1049061600, -1033336800, -1017612000, -1002492000, -986162400, -969228000, -950479200, -942012000, -934668000, -857257200, -844556400, -828226800, -812502000, -798073200, -781052400, -766623600, -745455600, -733273200, 228877200, 243997200, 260326800, 276051600, 291776400, 307501200, 323830800, 338950800, 354675600, 370400400, 386125200, 401850000, 417574800, 433299600, 449024400, 465354000, 481078800, 496803600, 512528400, 528253200, 543978000, 559702800, 575427600, 591152400, 606877200, 622602000, 638326800, 654656400, 670381200, 686106000, 701830800, 717555600, 733280400, 749005200, 764730000, 780454800, 796179600, 811904400, 828234000, 846378000 } typeOffsets:intvector { 1050, 0, 0, 0, 0, 3600, 3600, 0, 3600, 3600 } typeMap:bin { "010304030403040301020102010201020102010201020102010201020102010201020102010201020102010201020102010201020403040304030403040304030403040304030403040304030403040304030403040304030403040304030403040304030403" } @@ -2170,17 +2160,17 @@ zoneinfo64:table(nofallback) { /* Europe/Isle_of_Man */ :int { 465 } //Z#457 /* Europe/Istanbul */ :table { transPre32:intvector { -1, 1454819544 } - trans:intvector { -1869875816, -1693706400, -1680490800, -1570413600, -1552186800, -1538359200, -1522551600, -1507514400, -1490583600, -1440208800, -1428030000, -1409709600, -1396494000, -931140000, -922762800, -917834400, -892436400, -875844000, -857358000, -781063200, -764737200, -744343200, -733806000, -716436000, -701924400, -684986400, -670474800, -654141600, -639025200, -621828000, -606970800, -590032800, -575434800, -235620000, -228279600, -177732000, -165726000, 10533600, 23835600, 41983200, 55285200, 74037600, 87339600, 107910000, 121219200, 133920000, 152676000, 165362400, 183502800, 202428000, 215557200, 228866400, 245797200, 260316000, 277246800, 308779200, 323827200, 340228800, 354672000, 371678400, 386121600, 403128000, 428446800, 433886400, 482792400, 496702800, 512521200, 528246000, 543970800, 559695600, 575420400, 591145200, 606870000, 622594800, 638319600, 654649200, 670374000, 686098800, 701823600, 717548400, 733273200, 748998000, 764118000, 780447600, 796172400, 811897200, 828226800, 846370800, 859676400, 877820400, 891126000, 909270000, 922575600, 941324400, 954025200, 972774000, 985474800, 1004223600, 1017529200, 1035673200, 1048978800, 1067122800, 1080428400, 1099177200, 1111878000, 1130626800, 1143327600, 1162076400, 1174784400, 1193533200, 1206838800, 1224982800, 1238288400, 1256432400, 1269738000, 1288486800, 1301274000, 1319936400, 1332637200, 1351386000, 1364691600, 1382835600, 1396227600, 1414285200, 1427590800, 1446944400, 1459040400, 1473195600 } + trans:intvector { -1869875816, -1693706400, -1680490800, -1570413600, -1552186800, -1538359200, -1522551600, -1507514400, -1490583600, -1440208800, -1428030000, -1409709600, -1396494000, -931053600, -922676400, -917834400, -892436400, -875844000, -764737200, -744343200, -733806000, -716436000, -701924400, -684986400, -670474800, -654141600, -639025200, -622087200, -606970800, -590032800, -575521200, -235620000, -194842800, -177732000, -165726000, 107910000, 121215600, 133920000, 152665200, 164678400, 184114800, 196214400, 215564400, 228873600, 245804400, 260323200, 267915600, 428454000, 433893600, 468111600, 482799600, 496710000, 512521200, 528246000, 543970800, 559695600, 575420400, 591145200, 606870000, 622594800, 638319600, 654649200, 670374000, 686098800, 701823600, 717548400, 733273200, 748998000, 764118000, 780447600, 796172400, 811897200, 828226800, 846370800, 859676400, 877820400, 891126000, 909270000, 922575600, 941324400, 954025200, 972774000, 985474800, 1004223600, 1017529200, 1035673200, 1048978800, 1067122800, 1080428400, 1099177200, 1111878000, 1130626800, 1143327600, 1162076400, 1174784400, 1193533200, 1206838800, 1224982800, 1238288400, 1256432400, 1269738000, 1288486800, 1301274000, 1319936400, 1332637200, 1351386000, 1364691600, 1382835600, 1396227600, 1414285200, 1427590800, 1446944400, 1459040400, 1473195600 } typeOffsets:intvector { 6952, 0, 7016, 0, 7200, 0, 7200, 3600, 10800, 0, 10800, 3600 } - typeMap:bin { "010203020302030203020302030203020302030203020302030203020302030203020302030203020302030203020302030203020302030504050405040504050403020302030203020302030203020302030203020302030203020302030203020302030203020302030203020302030203020302030203020302030203020304" } + typeMap:bin { "01020302030203020302030203020302030203020302030203020302030203020302030203020302030203020302030405040203020302030203020302030203020302030203020302030203020302030203020302030203020302030203020302030203020302030203020302030203020304" } links:intvector { 275, 458, 613 } } //Z#458 /* Europe/Jersey */ :int { 465 } //Z#459 /* Europe/Kaliningrad */ :table { transPre32:intvector { -1, 1872911176 } - trans:intvector { -1693706400, -1680483600, -1663455600, -1650150000, -1632006000, -1618700400, -938905200, -857257200, -844556400, -828226800, -812502000, -796777200, -788922000, -778730400, -762663600, -757389600, 354920400, 370728000, 386456400, 402264000, 417992400, 433800000, 449614800, 465346800, 481071600, 496796400, 512521200, 528246000, 543970800, 559695600, 575420400, 591145200, 606870000, 622598400, 638323200, 654652800, 670377600, 686102400, 701827200, 717552000, 733276800, 749001600, 764726400, 780451200, 796176000, 811900800, 828230400, 846374400, 859680000, 877824000, 891129600, 909273600, 922579200, 941328000, 954028800, 972777600, 985478400, 1004227200, 1017532800, 1035676800, 1048982400, 1067126400, 1080432000, 1099180800, 1111881600, 1130630400, 1143331200, 1162080000, 1174780800, 1193529600, 1206835200, 1224979200, 1238284800, 1256428800, 1269734400, 1288483200, 1301184000, 1414278000 } + trans:intvector { -1693706400, -1680483600, -1663455600, -1650150000, -1632006000, -1618700400, -938905200, -857257200, -844556400, -828226800, -812502000, -796777200, -781052400, -780372000, -778730400, -762663600, -749095200, 354920400, 370728000, 386456400, 402264000, 417992400, 433800000, 449614800, 465346800, 481071600, 496796400, 512521200, 528246000, 543970800, 559695600, 575420400, 591145200, 606870000, 622598400, 638323200, 654652800, 670377600, 686102400, 701827200, 717552000, 733276800, 749001600, 764726400, 780451200, 796176000, 811900800, 828230400, 846374400, 859680000, 877824000, 891129600, 909273600, 922579200, 941328000, 954028800, 972777600, 985478400, 1004227200, 1017532800, 1035676800, 1048982400, 1067126400, 1080432000, 1099180800, 1111881600, 1130630400, 1143331200, 1162080000, 1174780800, 1193529600, 1206835200, 1224979200, 1238284800, 1256428800, 1269734400, 1288483200, 1301184000, 1414278000 } typeOffsets:intvector { 4920, 0, 3600, 0, 3600, 3600, 7200, 0, 7200, 3600, 10800, 0, 10800, 3600 } - typeMap:bin { "01020102010201020102010201030403050605060506050605060506050605060504030403040304030403040304030403040304030403040304030403040304030403040304030403040304030503" } + typeMap:bin { "0102010201020102010201020102030403050605060506050605060506050605060504030403040304030403040304030403040304030403040304030403040304030403040304030403040304030503" } } //Z#460 /* Europe/Kiev */ :table { trans:intvector { -1441159324, -1247536800, -892522800, -857257200, -844556400, -828226800, -825382800, 354920400, 370728000, 386456400, 402264000, 417992400, 433800000, 449614800, 465346800, 481071600, 496796400, 512521200, 528246000, 543970800, 559695600, 575420400, 591145200, 606870000, 622594800, 638319600, 646783200, 686102400, 701820000, 717541200, 733269600, 748990800, 764719200, 780440400, 796179600, 811904400, 828234000, 846378000 } @@ -2384,7 +2374,7 @@ zoneinfo64:table(nofallback) { /* Europe/Vatican */ :int { 479 } //Z#494 /* Europe/Vienna */ :table { transPre32:intvector { -1, 1872912175 } - trans:intvector { -1693706400, -1680483600, -1663455600, -1650150000, -1632006000, -1618700400, -1569711600, -1555801200, -938905200, -857257200, -844556400, -828226800, -812502000, -796777200, -781052400, -780188400, -748479600, -733359600, -717634800, -701910000, -684975600, -670460400, 323823600, 338940000, 354675600, 370400400, 386125200, 401850000, 417574800, 433299600, 449024400, 465354000, 481078800, 496803600, 512528400, 528253200, 543978000, 559702800, 575427600, 591152400, 606877200, 622602000, 638326800, 654656400, 670381200, 686106000, 701830800, 717555600, 733280400, 749005200, 764730000, 780454800, 796179600, 811904400, 828234000, 846378000 } + trans:intvector { -1693706400, -1680483600, -1663455600, -1650150000, -1632006000, -1618700400, -1569711600, -1555801200, -938905200, -857257200, -844556400, -828226800, -812502000, -796777200, -781052400, -780188400, -748479600, -733273200, -717634800, -701910000, -684975600, -670460400, 323823600, 338940000, 354675600, 370400400, 386125200, 401850000, 417574800, 433299600, 449024400, 465354000, 481078800, 496803600, 512528400, 528253200, 543978000, 559702800, 575427600, 591152400, 606877200, 622602000, 638326800, 654656400, 670381200, 686106000, 701830800, 717555600, 733280400, 749005200, 764730000, 780454800, 796179600, 811904400, 828234000, 846378000 } typeOffsets:intvector { 3921, 0, 3600, 0, 3600, 3600 } typeMap:bin { "010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201" } finalRule { "EU" } @@ -2612,12 +2602,12 @@ zoneinfo64:table(nofallback) { typeMap:bin { "0102" } } //Z#559 /* Pacific/Fiji */ :table { - trans:intvector { -1709985344, 909842400, 920124000, 941896800, 951573600, 1259416800, 1269698400, 1287842400, 1299333600, 1319292000, 1327154400, 1350741600, 1358604000, 1382796000, 1390050000, 1414850400, 1421503200, 1446300000 } + trans:intvector { -1709985344, 909842400, 920124000, 941896800, 951573600, 1259416800, 1269698400, 1287842400, 1299333600, 1319292000, 1327154400, 1350741600, 1358604000, 1382796000, 1390050000, 1414850400, 1421503200, 1446300000, 1452952800, 1478354400, 1484402400, 1509804000, 1515852000, 1541253600, 1547301600, 1573308000 } typeOffsets:intvector { 42944, 0, 43200, 0, 43200, 3600 } - typeMap:bin { "010201020102010201020102010201020102" } + typeMap:bin { "0102010201020102010201020102010201020102010201020102" } finalRule { "Fiji" } finalRaw:int { 43200 } - finalYear:int { 2016 } + finalYear:int { 2020 } } //Z#560 /* Pacific/Funafuti */ :table { transPre32:intvector { -1, 2117471484 } @@ -2699,9 +2689,12 @@ zoneinfo64:table(nofallback) { } //Z#575 /* Pacific/Norfolk */ :table { transPre32:intvector { -1, 2117474184 } - trans:intvector { -599656320, 152029800, 162912600, 1443882600 } - typeOffsets:intvector { 40312, 0, 39600, 0, 40320, 0, 41400, 0, 41400, 3600 } - typeMap:bin { "0203040301" } + trans:intvector { -599656320, 152029800, 162916200, 1443882600, 1570287600, 1586012400, 1601737200 } + typeOffsets:intvector { 40312, 0, 39600, 0, 39600, 3600, 40320, 0, 41400, 0, 41400, 3600 } + typeMap:bin { "0304050401020102" } + finalRule { "AN" } + finalRaw:int { 39600 } + finalYear:int { 2021 } } //Z#576 /* Pacific/Noumea */ :table { trans:intvector { -1829387148, 250002000, 257342400, 281451600, 288878400, 849366000, 857228400 } @@ -3086,84 +3079,81 @@ zoneinfo64:table(nofallback) { AV:intvector { 9, 1, -1, 7200, 1, 3, 1, -1, 7200, 1, 3600 } //_#3 - Brazil:intvector { - 10, 1, -1, 0, 0, 1, 15, -1, 0, 0, 3600 - } //_#4 C-Eur:intvector { 2, -31, -1, 7200, 1, 9, -31, -1, 7200, 1, 3600 - } //_#5 + } //_#4 Canada:intvector { 2, 8, -1, 7200, 0, 10, 1, -1, 7200, 0, 3600 - } //_#6 + } //_#5 Chatham:intvector { 8, -30, -1, 9900, 1, 3, 1, -1, 9900, 1, 3600 - } //_#7 + } //_#6 Chile:intvector { 8, 2, -1, 14400, 2, 3, 2, -1, 10800, 2, 3600 - } //_#8 + } //_#7 Cuba:intvector { 2, 8, -1, 0, 1, 10, 1, -1, 0, 1, 3600 - } //_#9 + } //_#8 EU:intvector { 2, -31, -1, 3600, 2, 9, -31, -1, 3600, 2, 3600 - } //_#10 + } //_#9 EUAsia:intvector { 2, -31, -1, 3600, 2, 9, -31, -1, 3600, 2, 3600 - } //_#11 + } //_#10 Fiji:intvector { - 10, 1, -1, 7200, 0, 0, 13, -1, 10800, 0, 3600 - } //_#12 + 10, 8, -1, 7200, 0, 0, 12, -1, 10800, 0, 3600 + } //_#11 Haiti:intvector { 2, 8, -1, 7200, 0, 10, 1, -1, 7200, 0, 3600 - } //_#13 + } //_#12 Iran:intvector { 2, 20, 0, 86400, 0, 8, 20, 0, 86400, 0, 3600 - } //_#14 + } //_#13 Jordan:intvector { 2, -31, -5, 86400, 0, 9, -31, -6, 0, 1, 3600 - } //_#15 + } //_#14 LH:intvector { 9, 1, -1, 7200, 0, 3, 1, -1, 7200, 0, 1800 - } //_#16 + } //_#15 Lebanon:intvector { 2, -31, -1, 0, 0, 9, -31, -1, 0, 0, 3600 - } //_#17 + } //_#16 Mexico:intvector { 3, 1, -1, 7200, 0, 9, -31, -1, 7200, 0, 3600 - } //_#18 + } //_#17 Moldova:intvector { 2, -31, -1, 7200, 0, 9, -31, -1, 10800, 0, 3600 - } //_#19 + } //_#18 NZ:intvector { 8, -30, -1, 7200, 1, 3, 1, -1, 7200, 1, 3600 - } //_#20 + } //_#19 Palestine:intvector { - 2, 24, -7, 3600, 0, 9, -31, -7, 3600, 0, 3600 - } //_#21 + 2, -31, -6, 0, 0, 9, -31, -7, 3600, 0, 3600 + } //_#20 Para:intvector { 9, 1, -1, 0, 0, 2, 22, -1, 0, 0, 3600 - } //_#22 + } //_#21 Syria:intvector { 2, -31, -6, 0, 0, 9, -31, -6, 0, 0, 3600 - } //_#23 + } //_#22 SystemV:intvector { 3, -30, -1, 7200, 0, 9, -31, -1, 7200, 0, 3600 - } //_#24 + } //_#23 Thule:intvector { 2, 8, -1, 7200, 0, 10, 1, -1, 7200, 0, 3600 - } //_#25 + } //_#24 Troll:intvector { 2, -31, -1, 3600, 2, 9, -31, -1, 3600, 2, 7200 - } //_#26 + } //_#25 US:intvector { 2, 8, -1, 7200, 0, 10, 1, -1, 7200, 0, 3600 - } //_#27 + } //_#26 WS:intvector { 8, -30, -1, 10800, 0, 3, 1, -1, 14400, 0, 3600 - } //_#28 + } //_#27 Zion:intvector { 2, 23, -6, 7200, 0, 9, -31, -1, 7200, 0, 3600 - } //_#29 + } //_#28 } Regions:array { "AU", //Z#0 ACT diff --git a/js/src/builtin/IntlTimeZoneData.h b/js/src/builtin/IntlTimeZoneData.h index 8f963ffbc9..1612f0f6be 100644 --- a/js/src/builtin/IntlTimeZoneData.h +++ b/js/src/builtin/IntlTimeZoneData.h @@ -1,5 +1,5 @@ // Generated by make_intl_data.py. DO NOT EDIT. -// tzdata version = 2019a +// tzdata version = 2019c #ifndef builtin_IntlTimeZoneData_h #define builtin_IntlTimeZoneData_h diff --git a/js/src/tests/Intl/DateTimeFormat/timeZone_backward_links.js b/js/src/tests/Intl/DateTimeFormat/timeZone_backward_links.js index 8cda44d87d..8bd0512c53 100644 --- a/js/src/tests/Intl/DateTimeFormat/timeZone_backward_links.js +++ b/js/src/tests/Intl/DateTimeFormat/timeZone_backward_links.js @@ -1,7 +1,7 @@ // |reftest| skip-if(!this.hasOwnProperty("Intl")) // Generated by make_intl_data.py. DO NOT EDIT. -// tzdata version = 2019a +// tzdata version = 2019c const tzMapper = [ x => x, diff --git a/js/src/tests/Intl/DateTimeFormat/timeZone_backzone.js b/js/src/tests/Intl/DateTimeFormat/timeZone_backzone.js index a3efe03101..c760fd85e9 100644 --- a/js/src/tests/Intl/DateTimeFormat/timeZone_backzone.js +++ b/js/src/tests/Intl/DateTimeFormat/timeZone_backzone.js @@ -1,7 +1,7 @@ // |reftest| skip-if(!this.hasOwnProperty("Intl")) // Generated by make_intl_data.py. DO NOT EDIT. -// tzdata version = 2019a +// tzdata version = 2019c const tzMapper = [ x => x, diff --git a/js/src/tests/Intl/DateTimeFormat/timeZone_backzone_links.js b/js/src/tests/Intl/DateTimeFormat/timeZone_backzone_links.js index b61593f789..38db5e77dd 100644 --- a/js/src/tests/Intl/DateTimeFormat/timeZone_backzone_links.js +++ b/js/src/tests/Intl/DateTimeFormat/timeZone_backzone_links.js @@ -1,7 +1,7 @@ // |reftest| skip-if(!this.hasOwnProperty("Intl")) // Generated by make_intl_data.py. DO NOT EDIT. -// tzdata version = 2019a +// tzdata version = 2019c const tzMapper = [ x => x, diff --git a/js/src/tests/Intl/DateTimeFormat/timeZone_notbackward_links.js b/js/src/tests/Intl/DateTimeFormat/timeZone_notbackward_links.js index 12b55c214c..64a25c2414 100644 --- a/js/src/tests/Intl/DateTimeFormat/timeZone_notbackward_links.js +++ b/js/src/tests/Intl/DateTimeFormat/timeZone_notbackward_links.js @@ -1,7 +1,7 @@ // |reftest| skip-if(!this.hasOwnProperty("Intl")) // Generated by make_intl_data.py. DO NOT EDIT. -// tzdata version = 2019a +// tzdata version = 2019c const tzMapper = [ x => x,
 
 
b