forked from mirrors/gecko-dev
		
	This patch is generated by the following script:
function rename() {
find .\
     -type f\
     ! -path "./obj*"\
     ! -path "./.git"\
     ! -path "./.hg"\
     \( -name "*.cpp" -or\
        -name "*.h" \)\
        -exec sed -i -r "s/$1/$2/g" "{}" \;
}
rename "([[:alpha:]]*)([rR])eflowState(s?)" "\1\2eflowInput\3"
MozReview-Commit-ID: ITFO7uMTkSb
--HG--
extra : rebase_source : c91a2e174a0baec60c1b0111ac7636295004ab35
		
	
			
		
			
				
	
	
		
			181 lines
		
	
	
	
		
			5.9 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			181 lines
		
	
	
	
		
			5.9 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 | 
						|
/* vim: set ts=2 et sw=2 tw=80: */
 | 
						|
/* This Source Code is subject to the terms of the Mozilla Public License
 | 
						|
 * version 2.0 (the "License"). You can obtain a copy of the License at
 | 
						|
 * http://mozilla.org/MPL/2.0/. */
 | 
						|
 | 
						|
/* rendering object for CSS "display: ruby-text-container" */
 | 
						|
 | 
						|
#include "nsRubyTextContainerFrame.h"
 | 
						|
 | 
						|
#include "mozilla/UniquePtr.h"
 | 
						|
#include "mozilla/WritingModes.h"
 | 
						|
#include "nsLineLayout.h"
 | 
						|
#include "nsPresContext.h"
 | 
						|
#include "nsStyleContext.h"
 | 
						|
 | 
						|
using namespace mozilla;
 | 
						|
 | 
						|
//----------------------------------------------------------------------
 | 
						|
 | 
						|
// Frame class boilerplate
 | 
						|
// =======================
 | 
						|
 | 
						|
NS_QUERYFRAME_HEAD(nsRubyTextContainerFrame)
 | 
						|
  NS_QUERYFRAME_ENTRY(nsRubyTextContainerFrame)
 | 
						|
NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame)
 | 
						|
 | 
						|
NS_IMPL_FRAMEARENA_HELPERS(nsRubyTextContainerFrame)
 | 
						|
 | 
						|
nsContainerFrame*
 | 
						|
NS_NewRubyTextContainerFrame(nsIPresShell* aPresShell,
 | 
						|
                             nsStyleContext* aContext)
 | 
						|
{
 | 
						|
  return new (aPresShell) nsRubyTextContainerFrame(aContext);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
//----------------------------------------------------------------------
 | 
						|
 | 
						|
// nsRubyTextContainerFrame Method Implementations
 | 
						|
// ===============================================
 | 
						|
 | 
						|
nsIAtom*
 | 
						|
nsRubyTextContainerFrame::GetType() const
 | 
						|
{
 | 
						|
  return nsGkAtoms::rubyTextContainerFrame;
 | 
						|
}
 | 
						|
 | 
						|
#ifdef DEBUG_FRAME_DUMP
 | 
						|
nsresult
 | 
						|
nsRubyTextContainerFrame::GetFrameName(nsAString& aResult) const
 | 
						|
{
 | 
						|
  return MakeFrameName(NS_LITERAL_STRING("RubyTextContainer"), aResult);
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
/* virtual */ bool
 | 
						|
nsRubyTextContainerFrame::IsFrameOfType(uint32_t aFlags) const
 | 
						|
{
 | 
						|
  if (aFlags & eSupportsCSSTransforms) {
 | 
						|
    return false;
 | 
						|
  }
 | 
						|
  return nsContainerFrame::IsFrameOfType(aFlags);
 | 
						|
}
 | 
						|
 | 
						|
/* virtual */ void
 | 
						|
nsRubyTextContainerFrame::SetInitialChildList(ChildListID aListID,
 | 
						|
                                              nsFrameList& aChildList)
 | 
						|
{
 | 
						|
  nsContainerFrame::SetInitialChildList(aListID, aChildList);
 | 
						|
  if (aListID == kPrincipalList) {
 | 
						|
    UpdateSpanFlag();
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
/* virtual */ void
 | 
						|
nsRubyTextContainerFrame::AppendFrames(ChildListID aListID,
 | 
						|
                                       nsFrameList& aFrameList)
 | 
						|
{
 | 
						|
  nsContainerFrame::AppendFrames(aListID, aFrameList);
 | 
						|
  UpdateSpanFlag();
 | 
						|
}
 | 
						|
 | 
						|
/* virtual */ void
 | 
						|
nsRubyTextContainerFrame::InsertFrames(ChildListID aListID,
 | 
						|
                                       nsIFrame* aPrevFrame,
 | 
						|
                                       nsFrameList& aFrameList)
 | 
						|
{
 | 
						|
  nsContainerFrame::InsertFrames(aListID, aPrevFrame, aFrameList);
 | 
						|
  UpdateSpanFlag();
 | 
						|
}
 | 
						|
 | 
						|
/* virtual */ void
 | 
						|
nsRubyTextContainerFrame::RemoveFrame(ChildListID aListID,
 | 
						|
                                      nsIFrame* aOldFrame)
 | 
						|
{
 | 
						|
  nsContainerFrame::RemoveFrame(aListID, aOldFrame);
 | 
						|
  UpdateSpanFlag();
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
nsRubyTextContainerFrame::UpdateSpanFlag()
 | 
						|
{
 | 
						|
  bool isSpan = false;
 | 
						|
  // The continuation checks are safe here because spans never break.
 | 
						|
  if (!GetPrevContinuation() && !GetNextContinuation()) {
 | 
						|
    nsIFrame* onlyChild = mFrames.OnlyChild();
 | 
						|
    if (onlyChild && onlyChild->IsPseudoFrame(GetContent())) {
 | 
						|
      // Per CSS Ruby spec, if the only child of an rtc frame is
 | 
						|
      // a pseudo rt frame, it spans all bases in the segment.
 | 
						|
      isSpan = true;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (isSpan) {
 | 
						|
    AddStateBits(NS_RUBY_TEXT_CONTAINER_IS_SPAN);
 | 
						|
  } else {
 | 
						|
    RemoveStateBits(NS_RUBY_TEXT_CONTAINER_IS_SPAN);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
/* virtual */ void
 | 
						|
nsRubyTextContainerFrame::Reflow(nsPresContext* aPresContext,
 | 
						|
                                 ReflowOutput& aDesiredSize,
 | 
						|
                                 const ReflowInput& aReflowInput,
 | 
						|
                                 nsReflowStatus& aStatus)
 | 
						|
{
 | 
						|
  MarkInReflow();
 | 
						|
  DO_GLOBAL_REFLOW_COUNT("nsRubyTextContainerFrame");
 | 
						|
  DISPLAY_REFLOW(aPresContext, this, aReflowInput, aDesiredSize, aStatus);
 | 
						|
 | 
						|
  // Although a ruby text container may have continuations, returning
 | 
						|
  // NS_FRAME_COMPLETE here is still safe, since its parent, ruby frame,
 | 
						|
  // ignores the status, and continuations of the ruby base container
 | 
						|
  // will take care of our continuations.
 | 
						|
  aStatus = NS_FRAME_COMPLETE;
 | 
						|
  WritingMode lineWM = aReflowInput.mLineLayout->GetWritingMode();
 | 
						|
 | 
						|
  nscoord minBCoord = nscoord_MAX;
 | 
						|
  nscoord maxBCoord = nscoord_MIN;
 | 
						|
  // The container size is not yet known, so we use a dummy (0, 0) size.
 | 
						|
  // The block-dir position will be corrected below after containerSize
 | 
						|
  // is finalized.
 | 
						|
  const nsSize dummyContainerSize;
 | 
						|
  for (nsFrameList::Enumerator e(mFrames); !e.AtEnd(); e.Next()) {
 | 
						|
    nsIFrame* child = e.get();
 | 
						|
    MOZ_ASSERT(child->GetType() == nsGkAtoms::rubyTextFrame);
 | 
						|
    LogicalRect rect = child->GetLogicalRect(lineWM, dummyContainerSize);
 | 
						|
    LogicalMargin margin = child->GetLogicalUsedMargin(lineWM);
 | 
						|
    nscoord blockStart = rect.BStart(lineWM) - margin.BStart(lineWM);
 | 
						|
    minBCoord = std::min(minBCoord, blockStart);
 | 
						|
    nscoord blockEnd = rect.BEnd(lineWM) + margin.BEnd(lineWM);
 | 
						|
    maxBCoord = std::max(maxBCoord, blockEnd);
 | 
						|
  }
 | 
						|
 | 
						|
  LogicalSize size(lineWM, mISize, 0);
 | 
						|
  if (!mFrames.IsEmpty()) {
 | 
						|
    if (MOZ_UNLIKELY(minBCoord > maxBCoord)) {
 | 
						|
      // XXX When bug 765861 gets fixed, this warning should be upgraded.
 | 
						|
      NS_WARNING("bad block coord");
 | 
						|
      minBCoord = maxBCoord = 0;
 | 
						|
    }
 | 
						|
    size.BSize(lineWM) = maxBCoord - minBCoord;
 | 
						|
    nsSize containerSize = size.GetPhysicalSize(lineWM);
 | 
						|
    for (nsFrameList::Enumerator e(mFrames); !e.AtEnd(); e.Next()) {
 | 
						|
      nsIFrame* child = e.get();
 | 
						|
      // We reflowed the child with a dummy container size, as the true size
 | 
						|
      // was not yet known at that time.
 | 
						|
      LogicalPoint pos = child->GetLogicalPosition(lineWM, dummyContainerSize);
 | 
						|
      // Adjust block position to account for minBCoord,
 | 
						|
      // then reposition child based on the true container width.
 | 
						|
      pos.B(lineWM) -= minBCoord;
 | 
						|
      // Relative positioning hasn't happened yet.
 | 
						|
      // So MovePositionBy should not be used here.
 | 
						|
      child->SetPosition(lineWM, pos, containerSize);
 | 
						|
      nsContainerFrame::PlaceFrameView(child);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  aDesiredSize.SetSize(lineWM, size);
 | 
						|
}
 |