michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "nsMathMLSelectedFrame.h" michael@0: #include "nsDisplayList.h" michael@0: michael@0: nsMathMLSelectedFrame::~nsMathMLSelectedFrame() michael@0: { michael@0: } michael@0: michael@0: void michael@0: nsMathMLSelectedFrame::Init(nsIContent* aContent, michael@0: nsIFrame* aParent, michael@0: nsIFrame* aPrevInFlow) michael@0: { michael@0: // Init our local attributes michael@0: mInvalidMarkup = false; michael@0: mSelectedFrame = nullptr; michael@0: michael@0: // Let the base class do the rest michael@0: nsMathMLContainerFrame::Init(aContent, aParent, aPrevInFlow); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsMathMLSelectedFrame::TransmitAutomaticData() michael@0: { michael@0: // Note that to determine space-like and embellished op properties: michael@0: // - behaves the same as michael@0: // - behaves the same as michael@0: michael@0: // The REC defines the following element to be space-like: michael@0: // * an maction element whose selected sub-expression exists and is michael@0: // space-like; michael@0: nsIMathMLFrame* mathMLFrame = do_QueryFrame(mSelectedFrame); michael@0: if (mathMLFrame && mathMLFrame->IsSpaceLike()) { michael@0: mPresentationData.flags |= NS_MATHML_SPACE_LIKE; michael@0: } else { michael@0: mPresentationData.flags &= ~NS_MATHML_SPACE_LIKE; michael@0: } michael@0: michael@0: // The REC defines the following element to be an embellished operator: michael@0: // * an maction element whose selected sub-expression exists and is an michael@0: // embellished operator; michael@0: mPresentationData.baseFrame = mSelectedFrame; michael@0: GetEmbellishDataFrom(mSelectedFrame, mEmbellishData); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: nsresult michael@0: nsMathMLSelectedFrame::ChildListChanged(int32_t aModType) michael@0: { michael@0: GetSelectedFrame(); michael@0: return nsMathMLContainerFrame::ChildListChanged(aModType); michael@0: } michael@0: michael@0: nsresult michael@0: nsMathMLSelectedFrame::SetInitialChildList(ChildListID aListID, michael@0: nsFrameList& aChildList) michael@0: { michael@0: nsresult rv = nsMathMLContainerFrame::SetInitialChildList(aListID, michael@0: aChildList); michael@0: // This very first call to GetSelectedFrame() will cause us to be marked as an michael@0: // embellished operator if the selected child is an embellished operator michael@0: GetSelectedFrame(); michael@0: return rv; michael@0: } michael@0: michael@0: // Only paint the selected child... michael@0: void michael@0: nsMathMLSelectedFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, michael@0: const nsRect& aDirtyRect, michael@0: const nsDisplayListSet& aLists) michael@0: { michael@0: // Report an error if something wrong was found in this frame. michael@0: // We can't call nsDisplayMathMLError from here, michael@0: // so ask nsMathMLContainerFrame to do the work for us. michael@0: if (NS_MATHML_HAS_ERROR(mPresentationData.flags)) { michael@0: nsMathMLContainerFrame::BuildDisplayList(aBuilder, aDirtyRect, aLists); michael@0: return; michael@0: } michael@0: michael@0: DisplayBorderBackgroundOutline(aBuilder, aLists); michael@0: michael@0: nsIFrame* childFrame = GetSelectedFrame(); michael@0: if (childFrame) { michael@0: // Put the child's background directly onto the content list michael@0: nsDisplayListSet set(aLists, aLists.Content()); michael@0: // The children should be in content order michael@0: BuildDisplayListForChild(aBuilder, childFrame, aDirtyRect, set); michael@0: } michael@0: michael@0: #if defined(DEBUG) && defined(SHOW_BOUNDING_BOX) michael@0: // visual debug michael@0: DisplayBoundingMetrics(aBuilder, this, mReference, mBoundingMetrics, aLists); michael@0: #endif michael@0: } michael@0: michael@0: // Only reflow the selected child ... michael@0: nsresult michael@0: nsMathMLSelectedFrame::Reflow(nsPresContext* aPresContext, michael@0: nsHTMLReflowMetrics& aDesiredSize, michael@0: const nsHTMLReflowState& aReflowState, michael@0: nsReflowStatus& aStatus) michael@0: { michael@0: nsresult rv = NS_OK; michael@0: aStatus = NS_FRAME_COMPLETE; michael@0: aDesiredSize.Width() = aDesiredSize.Height() = 0; michael@0: aDesiredSize.SetTopAscent(0); michael@0: mBoundingMetrics = nsBoundingMetrics(); michael@0: nsIFrame* childFrame = GetSelectedFrame(); michael@0: if (childFrame) { michael@0: nsSize availSize(aReflowState.ComputedWidth(), NS_UNCONSTRAINEDSIZE); michael@0: nsHTMLReflowState childReflowState(aPresContext, aReflowState, michael@0: childFrame, availSize); michael@0: rv = ReflowChild(childFrame, aPresContext, aDesiredSize, michael@0: childReflowState, aStatus); michael@0: SaveReflowAndBoundingMetricsFor(childFrame, aDesiredSize, michael@0: aDesiredSize.mBoundingMetrics); michael@0: mBoundingMetrics = aDesiredSize.mBoundingMetrics; michael@0: } michael@0: FinalizeReflow(*aReflowState.rendContext, aDesiredSize); michael@0: NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); michael@0: return rv; michael@0: } michael@0: michael@0: // Only place the selected child ... michael@0: /* virtual */ nsresult michael@0: nsMathMLSelectedFrame::Place(nsRenderingContext& aRenderingContext, michael@0: bool aPlaceOrigin, michael@0: nsHTMLReflowMetrics& aDesiredSize) michael@0: { michael@0: nsIFrame* childFrame = GetSelectedFrame(); michael@0: michael@0: if (mInvalidMarkup) { michael@0: return ReflowError(aRenderingContext, aDesiredSize); michael@0: } michael@0: michael@0: aDesiredSize.Width() = aDesiredSize.Height() = 0; michael@0: aDesiredSize.SetTopAscent(0); michael@0: mBoundingMetrics = nsBoundingMetrics(); michael@0: if (childFrame) { michael@0: GetReflowAndBoundingMetricsFor(childFrame, aDesiredSize, mBoundingMetrics); michael@0: if (aPlaceOrigin) { michael@0: FinishReflowChild(childFrame, PresContext(), aDesiredSize, nullptr, 0, 0, 0); michael@0: } michael@0: mReference.x = 0; michael@0: mReference.y = aDesiredSize.TopAscent(); michael@0: } michael@0: aDesiredSize.mBoundingMetrics = mBoundingMetrics; michael@0: return NS_OK; michael@0: }