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
		
			
				
	
	
		
			202 lines
		
	
	
	
		
			6.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			202 lines
		
	
	
	
		
			6.8 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/. */
 | |
| 
 | |
| #include "RubyUtils.h"
 | |
| #include "nsRubyFrame.h"
 | |
| #include "nsRubyBaseFrame.h"
 | |
| #include "nsRubyTextFrame.h"
 | |
| #include "nsRubyBaseContainerFrame.h"
 | |
| #include "nsRubyTextContainerFrame.h"
 | |
| 
 | |
| using namespace mozilla;
 | |
| 
 | |
| NS_DECLARE_FRAME_PROPERTY_SMALL_VALUE(ReservedISize, nscoord)
 | |
| 
 | |
| /* static */ void
 | |
| RubyUtils::SetReservedISize(nsIFrame* aFrame, nscoord aISize)
 | |
| {
 | |
|   MOZ_ASSERT(IsExpandableRubyBox(aFrame));
 | |
|   aFrame->SetProperty(ReservedISize(), aISize);
 | |
| }
 | |
| 
 | |
| /* static */ void
 | |
| RubyUtils::ClearReservedISize(nsIFrame* aFrame)
 | |
| {
 | |
|   MOZ_ASSERT(IsExpandableRubyBox(aFrame));
 | |
|   aFrame->RemoveProperty(ReservedISize());
 | |
| }
 | |
| 
 | |
| /* static */ nscoord
 | |
| RubyUtils::GetReservedISize(nsIFrame* aFrame)
 | |
| {
 | |
|   MOZ_ASSERT(IsExpandableRubyBox(aFrame));
 | |
|   return aFrame->GetProperty(ReservedISize());
 | |
| }
 | |
| 
 | |
| AutoRubyTextContainerArray::AutoRubyTextContainerArray(
 | |
|   nsRubyBaseContainerFrame* aBaseContainer)
 | |
| {
 | |
|   for (nsIFrame* frame = aBaseContainer->GetNextSibling();
 | |
|        frame && frame->IsRubyTextContainerFrame();
 | |
|        frame = frame->GetNextSibling()) {
 | |
|     AppendElement(static_cast<nsRubyTextContainerFrame*>(frame));
 | |
|   }
 | |
| }
 | |
| 
 | |
| nsIFrame*
 | |
| RubyColumn::Iterator::operator*() const
 | |
| {
 | |
|   nsIFrame* frame;
 | |
|   if (mIndex == -1) {
 | |
|     frame = mColumn.mBaseFrame;
 | |
|   } else {
 | |
|     frame = mColumn.mTextFrames[mIndex];
 | |
|   }
 | |
|   MOZ_ASSERT(frame, "Frame here cannot be null");
 | |
|   return frame;
 | |
| }
 | |
| 
 | |
| void
 | |
| RubyColumn::Iterator::SkipUntilExistingFrame()
 | |
| {
 | |
|   if (mIndex == -1) {
 | |
|     if (mColumn.mBaseFrame) {
 | |
|       return;
 | |
|     }
 | |
|     ++mIndex;
 | |
|   }
 | |
|   int32_t numTextFrames = mColumn.mTextFrames.Length();
 | |
|   for (; mIndex < numTextFrames; ++mIndex) {
 | |
|     if (mColumn.mTextFrames[mIndex]) {
 | |
|       break;
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| RubySegmentEnumerator::RubySegmentEnumerator(nsRubyFrame* aRubyFrame)
 | |
| {
 | |
|   nsIFrame* frame = aRubyFrame->PrincipalChildList().FirstChild();
 | |
|   MOZ_ASSERT(!frame || frame->IsRubyBaseContainerFrame());
 | |
|   mBaseContainer = static_cast<nsRubyBaseContainerFrame*>(frame);
 | |
| }
 | |
| 
 | |
| void
 | |
| RubySegmentEnumerator::Next()
 | |
| {
 | |
|   MOZ_ASSERT(mBaseContainer);
 | |
|   nsIFrame* frame = mBaseContainer->GetNextSibling();
 | |
|   while (frame && !frame->IsRubyBaseContainerFrame()) {
 | |
|     frame = frame->GetNextSibling();
 | |
|   }
 | |
|   mBaseContainer = static_cast<nsRubyBaseContainerFrame*>(frame);
 | |
| }
 | |
| 
 | |
| RubyColumnEnumerator::RubyColumnEnumerator(
 | |
|   nsRubyBaseContainerFrame* aBaseContainer,
 | |
|   const AutoRubyTextContainerArray& aTextContainers)
 | |
|   : mAtIntraLevelWhitespace(false)
 | |
| {
 | |
|   const uint32_t rtcCount = aTextContainers.Length();
 | |
|   mFrames.SetCapacity(rtcCount + 1);
 | |
| 
 | |
|   nsIFrame* rbFrame = aBaseContainer->PrincipalChildList().FirstChild();
 | |
|   MOZ_ASSERT(!rbFrame || rbFrame->IsRubyBaseFrame());
 | |
|   mFrames.AppendElement(static_cast<nsRubyContentFrame*>(rbFrame));
 | |
|   for (uint32_t i = 0; i < rtcCount; i++) {
 | |
|     nsRubyTextContainerFrame* container = aTextContainers[i];
 | |
|     // If the container is for span, leave a nullptr here.
 | |
|     // Spans do not take part in pairing.
 | |
|     nsIFrame* rtFrame = !container->IsSpanContainer() ?
 | |
|       container->PrincipalChildList().FirstChild() : nullptr;
 | |
|     MOZ_ASSERT(!rtFrame || rtFrame->IsRubyTextFrame());
 | |
|     mFrames.AppendElement(static_cast<nsRubyContentFrame*>(rtFrame));
 | |
|   }
 | |
| 
 | |
|   // We have to init mAtIntraLevelWhitespace to be correct for the
 | |
|   // first column. There are two ways we could end up with intra-level
 | |
|   // whitespace in our first colum:
 | |
|   // 1. The current segment itself is an inter-segment whitespace;
 | |
|   // 2. If our ruby segment is split across multiple lines, and some
 | |
|   //    intra-level whitespace happens to fall right after a line-break.
 | |
|   //    Each line will get its own nsRubyBaseContainerFrame, and the
 | |
|   //    container right after the line-break will end up with its first
 | |
|   //    column containing that intra-level whitespace.
 | |
|   for (uint32_t i = 0, iend = mFrames.Length(); i < iend; i++) {
 | |
|     nsRubyContentFrame* frame = mFrames[i];
 | |
|     if (frame && frame->IsIntraLevelWhitespace()) {
 | |
|       mAtIntraLevelWhitespace = true;
 | |
|       break;
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| void
 | |
| RubyColumnEnumerator::Next()
 | |
| {
 | |
|   bool advancingToIntraLevelWhitespace = false;
 | |
|   for (uint32_t i = 0, iend = mFrames.Length(); i < iend; i++) {
 | |
|     nsRubyContentFrame* frame = mFrames[i];
 | |
|     // If we've got intra-level whitespace frames at some levels in the
 | |
|     // current ruby column, we "faked" an anonymous box for all other
 | |
|     // levels for this column. So when we advance off this column, we
 | |
|     // don't advance any of the frames in those levels, because we're
 | |
|     // just advancing across the "fake" frames.
 | |
|     if (frame && (!mAtIntraLevelWhitespace ||
 | |
|                   frame->IsIntraLevelWhitespace())) {
 | |
|       nsIFrame* nextSibling = frame->GetNextSibling();
 | |
|       MOZ_ASSERT(!nextSibling || nextSibling->Type() == frame->Type(),
 | |
|                  "Frame type should be identical among a level");
 | |
|       mFrames[i] = frame = static_cast<nsRubyContentFrame*>(nextSibling);
 | |
|       if (!advancingToIntraLevelWhitespace &&
 | |
|           frame && frame->IsIntraLevelWhitespace()) {
 | |
|         advancingToIntraLevelWhitespace = true;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   MOZ_ASSERT(!advancingToIntraLevelWhitespace || !mAtIntraLevelWhitespace,
 | |
|              "Should never have adjacent intra-level whitespace columns");
 | |
|   mAtIntraLevelWhitespace = advancingToIntraLevelWhitespace;
 | |
| }
 | |
| 
 | |
| bool
 | |
| RubyColumnEnumerator::AtEnd() const
 | |
| {
 | |
|   for (uint32_t i = 0, iend = mFrames.Length(); i < iend; i++) {
 | |
|     if (mFrames[i]) {
 | |
|       return false;
 | |
|     }
 | |
|   }
 | |
|   return true;
 | |
| }
 | |
| 
 | |
| nsRubyContentFrame*
 | |
| RubyColumnEnumerator::GetFrameAtLevel(uint32_t aIndex) const
 | |
| {
 | |
|   // If the current ruby column is for intra-level whitespaces, we
 | |
|   // return nullptr for any levels that do not have an actual intra-
 | |
|   // level whitespace frame in this column.  This nullptr represents
 | |
|   // an anonymous empty intra-level whitespace box.  (In this case,
 | |
|   // it's important that we NOT return mFrames[aIndex], because it's
 | |
|   // really part of the next column, not the current one.)
 | |
|   nsRubyContentFrame* frame = mFrames[aIndex];
 | |
|   return !mAtIntraLevelWhitespace ||
 | |
|          (frame && frame->IsIntraLevelWhitespace()) ? frame : nullptr;
 | |
| }
 | |
| 
 | |
| void
 | |
| RubyColumnEnumerator::GetColumn(RubyColumn& aColumn) const
 | |
| {
 | |
|   nsRubyContentFrame* rbFrame = GetFrameAtLevel(0);
 | |
|   MOZ_ASSERT(!rbFrame || rbFrame->IsRubyBaseFrame());
 | |
|   aColumn.mBaseFrame = static_cast<nsRubyBaseFrame*>(rbFrame);
 | |
|   aColumn.mTextFrames.ClearAndRetainStorage();
 | |
|   for (uint32_t i = 1, iend = mFrames.Length(); i < iend; i++) {
 | |
|     nsRubyContentFrame* rtFrame = GetFrameAtLevel(i);
 | |
|     MOZ_ASSERT(!rtFrame || rtFrame->IsRubyTextFrame());
 | |
|     aColumn.mTextFrames.AppendElement(static_cast<nsRubyTextFrame*>(rtFrame));
 | |
|   }
 | |
|   aColumn.mIsIntraLevelWhitespace = mAtIntraLevelWhitespace;
 | |
| }
 |