1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef nsMathMLmtableFrame_h___ 8 #define nsMathMLmtableFrame_h___ 9 10 #include "mozilla/Attributes.h" 11 #include "mozilla/UniquePtr.h" 12 #include "nsMathMLContainerFrame.h" 13 #include "nsBlockFrame.h" 14 #include "nsTableWrapperFrame.h" 15 #include "nsTableRowFrame.h" 16 #include "nsTableCellFrame.h" 17 18 namespace mozilla { 19 class PresShell; 20 } // namespace mozilla 21 22 // 23 // <mtable> -- table or matrix 24 // 25 26 class nsMathMLmtableWrapperFrame final : public nsTableWrapperFrame, 27 public nsMathMLFrame { 28 public: 29 friend nsContainerFrame* NS_NewMathMLmtableOuterFrame( 30 mozilla::PresShell* aPresShell, ComputedStyle* aStyle); 31 32 NS_DECL_QUERYFRAME 33 NS_DECL_FRAMEARENA_HELPERS(nsMathMLmtableWrapperFrame) 34 35 // overloaded nsTableWrapperFrame methods 36 37 virtual void Reflow(nsPresContext* aPresContext, ReflowOutput& aDesiredSize, 38 const ReflowInput& aReflowInput, 39 nsReflowStatus& aStatus) override; 40 41 virtual nsresult AttributeChanged(int32_t aNameSpaceID, nsAtom* aAttribute, 42 int32_t aModType) override; 43 IsFrameOfType(uint32_t aFlags)44 virtual bool IsFrameOfType(uint32_t aFlags) const override { 45 return nsTableWrapperFrame::IsFrameOfType(aFlags & ~(nsIFrame::eMathML)); 46 } 47 48 protected: nsMathMLmtableWrapperFrame(ComputedStyle * aStyle,nsPresContext * aPresContext)49 explicit nsMathMLmtableWrapperFrame(ComputedStyle* aStyle, 50 nsPresContext* aPresContext) 51 : nsTableWrapperFrame(aStyle, aPresContext, kClassID) {} 52 53 virtual ~nsMathMLmtableWrapperFrame(); 54 55 // helper to find the row frame at a given index, positive or negative, e.g., 56 // 1..n means the first row down to the last row, -1..-n means the last row 57 // up to the first row. Used for alignments that are relative to a given row 58 nsIFrame* GetRowFrameAt(int32_t aRowIndex); 59 }; // class nsMathMLmtableWrapperFrame 60 61 // -------------- 62 63 class nsMathMLmtableFrame final : public nsTableFrame { 64 public: 65 NS_DECL_QUERYFRAME 66 NS_DECL_FRAMEARENA_HELPERS(nsMathMLmtableFrame) 67 68 friend nsContainerFrame* NS_NewMathMLmtableFrame( 69 mozilla::PresShell* aPresShell, ComputedStyle* aStyle); 70 71 // Overloaded nsTableFrame methods 72 73 virtual void SetInitialChildList(ChildListID aListID, 74 nsFrameList& aChildList) override; 75 AppendFrames(ChildListID aListID,nsFrameList & aFrameList)76 virtual void AppendFrames(ChildListID aListID, 77 nsFrameList& aFrameList) override { 78 nsTableFrame::AppendFrames(aListID, aFrameList); 79 RestyleTable(); 80 } 81 InsertFrames(ChildListID aListID,nsIFrame * aPrevFrame,const nsLineList::iterator * aPrevFrameLine,nsFrameList & aFrameList)82 virtual void InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame, 83 const nsLineList::iterator* aPrevFrameLine, 84 nsFrameList& aFrameList) override { 85 nsTableFrame::InsertFrames(aListID, aPrevFrame, aPrevFrameLine, aFrameList); 86 RestyleTable(); 87 } 88 RemoveFrame(ChildListID aListID,nsIFrame * aOldFrame)89 virtual void RemoveFrame(ChildListID aListID, nsIFrame* aOldFrame) override { 90 nsTableFrame::RemoveFrame(aListID, aOldFrame); 91 RestyleTable(); 92 } 93 IsFrameOfType(uint32_t aFlags)94 virtual bool IsFrameOfType(uint32_t aFlags) const override { 95 return nsTableFrame::IsFrameOfType(aFlags & ~(nsIFrame::eMathML)); 96 } 97 98 // helper to restyle and reflow the table when a row is changed -- since 99 // MathML attributes are inter-dependent and row/colspan can affect the table, 100 // it is safer (albeit grossly suboptimal) to just relayout the whole thing. 101 void RestyleTable(); 102 103 /** helper to get the column spacing style value */ 104 nscoord GetColSpacing(int32_t aColIndex) override; 105 106 /** Sums the combined cell spacing between the columns aStartColIndex to 107 * aEndColIndex. 108 */ 109 nscoord GetColSpacing(int32_t aStartColIndex, int32_t aEndColIndex) override; 110 111 /** helper to get the row spacing style value */ 112 nscoord GetRowSpacing(int32_t aRowIndex) override; 113 114 /** Sums the combined cell spacing between the rows aStartRowIndex to 115 * aEndRowIndex. 116 */ 117 nscoord GetRowSpacing(int32_t aStartRowIndex, int32_t aEndRowIndex) override; 118 SetColSpacingArray(const nsTArray<nscoord> & aColSpacing)119 void SetColSpacingArray(const nsTArray<nscoord>& aColSpacing) { 120 mColSpacing = aColSpacing.Clone(); 121 } 122 SetRowSpacingArray(const nsTArray<nscoord> & aRowSpacing)123 void SetRowSpacingArray(const nsTArray<nscoord>& aRowSpacing) { 124 mRowSpacing = aRowSpacing.Clone(); 125 } 126 SetFrameSpacing(nscoord aSpacingX,nscoord aSpacingY)127 void SetFrameSpacing(nscoord aSpacingX, nscoord aSpacingY) { 128 mFrameSpacingX = aSpacingX; 129 mFrameSpacingY = aSpacingY; 130 } 131 132 /** Determines whether the placement of table cells is determined by CSS 133 * spacing based on padding and border-spacing, or one based upon the 134 * rowspacing, columnspacing and framespacing attributes. The second 135 * approach is used if the user specifies at least one of those attributes. 136 */ 137 void SetUseCSSSpacing(); GetUseCSSSpacing()138 bool GetUseCSSSpacing() { return mUseCSSSpacing; } 139 140 protected: nsMathMLmtableFrame(ComputedStyle * aStyle,nsPresContext * aPresContext)141 explicit nsMathMLmtableFrame(ComputedStyle* aStyle, 142 nsPresContext* aPresContext) 143 : nsTableFrame(aStyle, aPresContext, kClassID), 144 mFrameSpacingX(0), 145 mFrameSpacingY(0), 146 mUseCSSSpacing(false) {} 147 148 virtual ~nsMathMLmtableFrame(); 149 150 private: 151 nsTArray<nscoord> mColSpacing; 152 nsTArray<nscoord> mRowSpacing; 153 nscoord mFrameSpacingX; 154 nscoord mFrameSpacingY; 155 bool mUseCSSSpacing; 156 }; // class nsMathMLmtableFrame 157 158 // -------------- 159 160 class nsMathMLmtrFrame final : public nsTableRowFrame { 161 public: 162 NS_DECL_FRAMEARENA_HELPERS(nsMathMLmtrFrame) 163 164 friend nsContainerFrame* NS_NewMathMLmtrFrame(mozilla::PresShell* aPresShell, 165 ComputedStyle* aStyle); 166 167 // overloaded nsTableRowFrame methods 168 169 virtual nsresult AttributeChanged(int32_t aNameSpaceID, nsAtom* aAttribute, 170 int32_t aModType) override; 171 AppendFrames(ChildListID aListID,nsFrameList & aFrameList)172 virtual void AppendFrames(ChildListID aListID, 173 nsFrameList& aFrameList) override { 174 nsTableRowFrame::AppendFrames(aListID, aFrameList); 175 RestyleTable(); 176 } 177 InsertFrames(ChildListID aListID,nsIFrame * aPrevFrame,const nsLineList::iterator * aPrevFrameLine,nsFrameList & aFrameList)178 virtual void InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame, 179 const nsLineList::iterator* aPrevFrameLine, 180 nsFrameList& aFrameList) override { 181 nsTableRowFrame::InsertFrames(aListID, aPrevFrame, aPrevFrameLine, 182 aFrameList); 183 RestyleTable(); 184 } 185 RemoveFrame(ChildListID aListID,nsIFrame * aOldFrame)186 virtual void RemoveFrame(ChildListID aListID, nsIFrame* aOldFrame) override { 187 nsTableRowFrame::RemoveFrame(aListID, aOldFrame); 188 RestyleTable(); 189 } 190 IsFrameOfType(uint32_t aFlags)191 virtual bool IsFrameOfType(uint32_t aFlags) const override { 192 return nsTableRowFrame::IsFrameOfType(aFlags & ~(nsIFrame::eMathML)); 193 } 194 195 // helper to restyle and reflow the table -- @see nsMathMLmtableFrame. RestyleTable()196 void RestyleTable() { 197 nsTableFrame* tableFrame = GetTableFrame(); 198 if (tableFrame && tableFrame->IsFrameOfType(nsIFrame::eMathML)) { 199 // relayout the table 200 ((nsMathMLmtableFrame*)tableFrame)->RestyleTable(); 201 } 202 } 203 204 protected: nsMathMLmtrFrame(ComputedStyle * aStyle,nsPresContext * aPresContext)205 explicit nsMathMLmtrFrame(ComputedStyle* aStyle, nsPresContext* aPresContext) 206 : nsTableRowFrame(aStyle, aPresContext, kClassID) {} 207 208 virtual ~nsMathMLmtrFrame(); 209 }; // class nsMathMLmtrFrame 210 211 // -------------- 212 213 class nsMathMLmtdFrame final : public nsTableCellFrame { 214 public: 215 NS_DECL_FRAMEARENA_HELPERS(nsMathMLmtdFrame) 216 217 friend nsContainerFrame* NS_NewMathMLmtdFrame(mozilla::PresShell* aPresShell, 218 ComputedStyle* aStyle, 219 nsTableFrame* aTableFrame); 220 221 // overloaded nsTableCellFrame methods 222 223 virtual void Init(nsIContent* aContent, nsContainerFrame* aParent, 224 nsIFrame* aPrevInFlow) override; 225 226 virtual nsresult AttributeChanged(int32_t aNameSpaceID, nsAtom* aAttribute, 227 int32_t aModType) override; 228 229 virtual mozilla::StyleVerticalAlignKeyword GetVerticalAlign() const override; 230 virtual nsresult ProcessBorders(nsTableFrame* aFrame, 231 nsDisplayListBuilder* aBuilder, 232 const nsDisplayListSet& aLists) override; 233 IsFrameOfType(uint32_t aFlags)234 virtual bool IsFrameOfType(uint32_t aFlags) const override { 235 return nsTableCellFrame::IsFrameOfType(aFlags & ~(nsIFrame::eMathML)); 236 } 237 238 virtual LogicalMargin GetBorderWidth(WritingMode aWM) const override; 239 240 virtual nsMargin GetBorderOverflow() override; 241 242 protected: nsMathMLmtdFrame(ComputedStyle * aStyle,nsTableFrame * aTableFrame)243 nsMathMLmtdFrame(ComputedStyle* aStyle, nsTableFrame* aTableFrame) 244 : nsTableCellFrame(aStyle, aTableFrame, kClassID) {} 245 246 virtual ~nsMathMLmtdFrame(); 247 }; // class nsMathMLmtdFrame 248 249 // -------------- 250 251 class nsMathMLmtdInnerFrame final : public nsBlockFrame, public nsMathMLFrame { 252 public: 253 friend nsContainerFrame* NS_NewMathMLmtdInnerFrame( 254 mozilla::PresShell* aPresShell, ComputedStyle* aStyle); 255 256 NS_DECL_QUERYFRAME NS_DECL_FRAMEARENA_HELPERS(nsMathMLmtdInnerFrame)257 NS_DECL_FRAMEARENA_HELPERS(nsMathMLmtdInnerFrame) 258 259 // Overloaded nsIMathMLFrame methods 260 261 NS_IMETHOD 262 UpdatePresentationDataFromChildAt(int32_t aFirstIndex, int32_t aLastIndex, 263 uint32_t aFlagsValues, 264 uint32_t aFlagsToUpdate) override { 265 nsMathMLContainerFrame::PropagatePresentationDataFromChildAt( 266 this, aFirstIndex, aLastIndex, aFlagsValues, aFlagsToUpdate); 267 return NS_OK; 268 } 269 270 virtual void Reflow(nsPresContext* aPresContext, ReflowOutput& aDesiredSize, 271 const ReflowInput& aReflowInput, 272 nsReflowStatus& aStatus) override; 273 IsFrameOfType(uint32_t aFlags)274 virtual bool IsFrameOfType(uint32_t aFlags) const override { 275 return nsBlockFrame::IsFrameOfType(aFlags & ~nsIFrame::eMathML); 276 } 277 278 virtual const nsStyleText* StyleTextForLineLayout() override; 279 virtual void DidSetComputedStyle(ComputedStyle* aOldComputedStyle) override; 280 IsMrowLike()281 bool IsMrowLike() override { 282 return mFrames.FirstChild() != mFrames.LastChild() || !mFrames.FirstChild(); 283 } 284 285 protected: 286 explicit nsMathMLmtdInnerFrame(ComputedStyle* aStyle, 287 nsPresContext* aPresContext); 288 virtual ~nsMathMLmtdInnerFrame() = default; 289 290 mozilla::UniquePtr<nsStyleText> mUniqueStyleText; 291 292 }; // class nsMathMLmtdInnerFrame 293 294 #endif /* nsMathMLmtableFrame_h___ */ 295