forked from mirrors/gecko-dev
		
	 680815cd6e
			
		
	
	
		680815cd6e
		
	
	
	
	
		
			
			This patch was generated automatically by the "modeline.py" script, available here: https://github.com/amccreight/moz-source-tools/blob/master/modeline.py For every file that is modified in this patch, the changes are as follows: (1) The patch changes the file to use the exact C++ mode lines from the Mozilla coding style guide, available here: https://developer.mozilla.org/en-US/docs/Mozilla/Developer_guide/Coding_Style#Mode_Line (2) The patch deletes any blank lines between the mode line & the MPL boilerplate comment. (3) If the file previously had the mode lines and MPL boilerplate in a single contiguous C++ comment, then the patch splits them into separate C++ comments, to match the boilerplate in the coding style. MozReview-Commit-ID: EuRsDue63tK --HG-- extra : rebase_source : 3356d4b80ff6213935192e87cdbc9103fec6084c
		
			
				
	
	
		
			161 lines
		
	
	
	
		
			6.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			161 lines
		
	
	
	
		
			6.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /* -*- 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/. */
 | |
| 
 | |
| /* Utility code for performing CSS Box Alignment */
 | |
| 
 | |
| #include "CSSAlignUtils.h"
 | |
| #include "ReflowInput.h"
 | |
| 
 | |
| namespace mozilla {
 | |
| 
 | |
| static nscoord
 | |
| SpaceToFill(WritingMode aWM, const LogicalSize& aSize, nscoord aMargin,
 | |
|             LogicalAxis aAxis, nscoord aCBSize)
 | |
| {
 | |
|   nscoord size = aAxis == eLogicalAxisBlock ? aSize.BSize(aWM)
 | |
|                                             : aSize.ISize(aWM);
 | |
|   return aCBSize - (size + aMargin);
 | |
| }
 | |
| 
 | |
| nscoord
 | |
| CSSAlignUtils::AlignJustifySelf(uint8_t aAlignment, LogicalAxis aAxis,
 | |
|                                 AlignJustifyFlags aFlags,
 | |
|                                 nscoord aBaselineAdjust, nscoord aCBSize,
 | |
|                                 const ReflowInput& aRI,
 | |
|                                 const LogicalSize& aChildSize)
 | |
| {
 | |
|   MOZ_ASSERT(aAlignment != NS_STYLE_ALIGN_AUTO,
 | |
|              "auto values should have resolved already");
 | |
|   MOZ_ASSERT(aAlignment != NS_STYLE_ALIGN_LEFT &&
 | |
|              aAlignment != NS_STYLE_ALIGN_RIGHT,
 | |
|              "caller should map that to the corresponding START/END");
 | |
| 
 | |
|   // Promote aFlags to convenience bools:
 | |
|   const bool isOverflowSafe = !!(aFlags & AlignJustifyFlags::eOverflowSafe);
 | |
|   const bool isSameSide = !!(aFlags & AlignJustifyFlags::eSameSide);
 | |
| 
 | |
|   // Map some alignment values to 'start' / 'end'.
 | |
|   switch (aAlignment) {
 | |
|     case NS_STYLE_ALIGN_SELF_START: // align/justify-self: self-start
 | |
|       aAlignment = MOZ_LIKELY(isSameSide) ? NS_STYLE_ALIGN_START
 | |
|                                           : NS_STYLE_ALIGN_END;
 | |
|       break;
 | |
|     case NS_STYLE_ALIGN_SELF_END: // align/justify-self: self-end
 | |
|       aAlignment = MOZ_LIKELY(isSameSide) ? NS_STYLE_ALIGN_END
 | |
|                                           : NS_STYLE_ALIGN_START;
 | |
|       break;
 | |
|     // flex-start/flex-end are the same as start/end, in most contexts.
 | |
|     // (They have special behavior in flex containers, so flex containers
 | |
|     // should map them to some other value before calling this method.)
 | |
|     case NS_STYLE_ALIGN_FLEX_START:
 | |
|       aAlignment = NS_STYLE_ALIGN_START;
 | |
|       break;
 | |
|     case NS_STYLE_ALIGN_FLEX_END:
 | |
|       aAlignment = NS_STYLE_ALIGN_END;
 | |
|       break;
 | |
|   }
 | |
| 
 | |
|   // XXX try to condense this code a bit by adding the necessary convenience
 | |
|   // methods? (bug 1209710)
 | |
| 
 | |
|   // Get the item's margin corresponding to the container's start/end side.
 | |
|   const LogicalMargin margin = aRI.ComputedLogicalMargin();
 | |
|   WritingMode wm = aRI.GetWritingMode();
 | |
|   nscoord marginStart, marginEnd;
 | |
|   if (aAxis == eLogicalAxisBlock) {
 | |
|     if (MOZ_LIKELY(isSameSide)) {
 | |
|       marginStart = margin.BStart(wm);
 | |
|       marginEnd = margin.BEnd(wm);
 | |
|     } else {
 | |
|       marginStart = margin.BEnd(wm);
 | |
|       marginEnd = margin.BStart(wm);
 | |
|     }
 | |
|   } else {
 | |
|     if (MOZ_LIKELY(isSameSide)) {
 | |
|       marginStart = margin.IStart(wm);
 | |
|       marginEnd = margin.IEnd(wm);
 | |
|     } else {
 | |
|       marginStart = margin.IEnd(wm);
 | |
|       marginEnd = margin.IStart(wm);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   const auto& styleMargin = aRI.mStyleMargin->mMargin;
 | |
|   bool hasAutoMarginStart;
 | |
|   bool hasAutoMarginEnd;
 | |
|   if (aFlags & AlignJustifyFlags::eIgnoreAutoMargins) {
 | |
|     // (Note: ReflowInput will have treated "auto" margins as 0, so we
 | |
|     // don't need to do anything special to avoid expanding them.)
 | |
|     hasAutoMarginStart = hasAutoMarginEnd = false;
 | |
|   } else if (aAxis == eLogicalAxisBlock) {
 | |
|     hasAutoMarginStart = styleMargin.GetBStartUnit(wm) == eStyleUnit_Auto;
 | |
|     hasAutoMarginEnd = styleMargin.GetBEndUnit(wm) == eStyleUnit_Auto;
 | |
|   } else { /* aAxis == eLogicalAxisInline */
 | |
|     hasAutoMarginStart = styleMargin.GetIStartUnit(wm) == eStyleUnit_Auto;
 | |
|     hasAutoMarginEnd = styleMargin.GetIEndUnit(wm) == eStyleUnit_Auto;
 | |
|   }
 | |
| 
 | |
|   // https://drafts.csswg.org/css-align-3/#overflow-values
 | |
|   // This implements <overflow-position> = 'safe'.
 | |
|   // And auto-margins: https://drafts.csswg.org/css-grid/#auto-margins
 | |
|   if ((MOZ_UNLIKELY(isOverflowSafe) && aAlignment != NS_STYLE_ALIGN_START) ||
 | |
|       hasAutoMarginStart || hasAutoMarginEnd) {
 | |
|     nscoord space = SpaceToFill(wm, aChildSize, marginStart + marginEnd,
 | |
|                                 aAxis, aCBSize);
 | |
|     // XXX we might want to include == 0 here as an optimization -
 | |
|     // I need to see what the baseline/last baseline code looks like first.
 | |
|     if (space < 0) {
 | |
|       // "Overflowing elements ignore their auto margins and overflow
 | |
|       // in the end directions"
 | |
|       aAlignment = NS_STYLE_ALIGN_START;
 | |
|     } else if (hasAutoMarginEnd) {
 | |
|       aAlignment = hasAutoMarginStart ? NS_STYLE_ALIGN_CENTER
 | |
|                                       : (isSameSide ? NS_STYLE_ALIGN_START
 | |
|                                                     : NS_STYLE_ALIGN_END);
 | |
|     } else if (hasAutoMarginStart) {
 | |
|       aAlignment = isSameSide ? NS_STYLE_ALIGN_END : NS_STYLE_ALIGN_START;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   // Determine the offset for the child frame (its border-box) which will
 | |
|   // achieve the requested alignment.
 | |
|   nscoord offset = 0;
 | |
|   switch (aAlignment) {
 | |
|     case NS_STYLE_ALIGN_BASELINE:
 | |
|     case NS_STYLE_ALIGN_LAST_BASELINE:
 | |
|       if (MOZ_LIKELY(isSameSide == (aAlignment == NS_STYLE_ALIGN_BASELINE))) {
 | |
|         offset = marginStart + aBaselineAdjust;
 | |
|       } else {
 | |
|         nscoord size = aAxis == eLogicalAxisBlock ? aChildSize.BSize(wm)
 | |
|                                                   : aChildSize.ISize(wm);
 | |
|         offset = aCBSize - (size + marginEnd) - aBaselineAdjust;
 | |
|       }
 | |
|       break;
 | |
|     case NS_STYLE_ALIGN_STRETCH:
 | |
|       MOZ_FALLTHROUGH; // ComputeSize() deals with it
 | |
|     case NS_STYLE_ALIGN_START:
 | |
|       offset = marginStart;
 | |
|       break;
 | |
|     case NS_STYLE_ALIGN_END: {
 | |
|       nscoord size = aAxis == eLogicalAxisBlock ? aChildSize.BSize(wm)
 | |
|                                                 : aChildSize.ISize(wm);
 | |
|       offset = aCBSize - (size + marginEnd);
 | |
|       break;
 | |
|     }
 | |
|     case NS_STYLE_ALIGN_CENTER: {
 | |
|       nscoord size = aAxis == eLogicalAxisBlock ? aChildSize.BSize(wm)
 | |
|                                                 : aChildSize.ISize(wm);
 | |
|       offset = (aCBSize - size + marginStart - marginEnd) / 2;
 | |
|       break;
 | |
|     }
 | |
|     default:
 | |
|       MOZ_ASSERT_UNREACHABLE("unknown align-/justify-self value");
 | |
|   }
 | |
| 
 | |
|   return offset;
 | |
| }
 | |
| 
 | |
| } // namespace mozilla
 |