Back to index

lightning-sunbird  0.9+nobinonly
Classes | Defines | Enumerations | Functions
nsMathMLmtableFrame.cpp File Reference
#include "nsCOMPtr.h"
#include "nsFrame.h"
#include "nsAreaFrame.h"
#include "nsPresContext.h"
#include "nsUnitConversion.h"
#include "nsStyleContext.h"
#include "nsStyleConsts.h"
#include "nsINameSpaceManager.h"
#include "nsIRenderingContext.h"
#include "nsIFontMetrics.h"
#include "nsVoidArray.h"
#include "nsFrameManager.h"
#include "nsStyleChangeList.h"
#include "nsTableOuterFrame.h"
#include "nsTableFrame.h"
#include "nsTableCellFrame.h"
#include "celldata.h"
#include "nsMathMLmtableFrame.h"

Go to the source code of this file.

Classes

struct  nsValueList

Defines

#define DEBUG_VERIFY_THAT_FRAME_IS(_frame, _expected)

Enumerations

enum  eAlign {
  eAlign_top, eAlign_bottom, eAlign_center, eAlign_baseline,
  eAlign_axis
}

Functions

static void SplitString (nsString &aString, nsVoidArray &aOffset)
static void DestroyValueListFunc (void *aFrame, nsIAtom *aPropertyName, void *aPropertyValue, void *aDtorData)
static PRUnicharGetValueAt (nsPresContext *aPresContext, nsIFrame *aTableOrRowFrame, nsIAtom *aAttributeAtom, PRInt32 aRowOrColIndex)
static void MapAttributesInto (nsPresContext *aPresContext, nsIContent *aCellContent, nsIFrame *aCellFrame, nsIFrame *aCellInnerFrame)
static void ParseAlignAttribute (nsString &aValue, eAlign &aAlign, PRInt32 &aRowIndex)
nsresult NS_NewMathMLmtableOuterFrame (nsIPresShell *aPresShell, nsIFrame **aNewFrame)
nsresult NS_NewMathMLmtdFrame (nsIPresShell *aPresShell, nsIFrame **aNewFrame)
nsresult NS_NewMathMLmtdInnerFrame (nsIPresShell *aPresShell, nsIFrame **aNewFrame)

Define Documentation

#define DEBUG_VERIFY_THAT_FRAME_IS (   _frame,
  _expected 
)

Definition at line 168 of file nsMathMLmtableFrame.cpp.


Enumeration Type Documentation

enum eAlign
Enumerator:
eAlign_top 
eAlign_bottom 
eAlign_center 
eAlign_baseline 
eAlign_axis 

Definition at line 314 of file nsMathMLmtableFrame.cpp.


Function Documentation

static void DestroyValueListFunc ( void aFrame,
nsIAtom aPropertyName,
void aPropertyValue,
void aDtorData 
) [static]

Definition at line 120 of file nsMathMLmtableFrame.cpp.

{
  delete NS_STATIC_CAST(nsValueList*, aPropertyValue);
}

Here is the caller graph for this function:

static PRUnichar* GetValueAt ( nsPresContext aPresContext,
nsIFrame aTableOrRowFrame,
nsIAtom aAttributeAtom,
PRInt32  aRowOrColIndex 
) [static]

Definition at line 129 of file nsMathMLmtableFrame.cpp.

{
  PRUnichar* result = nsnull;
  nsPropertyTable *propTable = aPresContext->PropertyTable();
  nsValueList* valueList;

  valueList = NS_STATIC_CAST(nsValueList*,
                             propTable->GetProperty(aTableOrRowFrame,
                                                    aAttributeAtom));

  if (!valueList) {
    // The property isn't there yet, so set it
    nsAutoString values;
    if (NS_CONTENT_ATTR_HAS_VALUE ==
        aTableOrRowFrame->GetContent()->GetAttr(kNameSpaceID_None, aAttributeAtom, values)) {
      valueList = new nsValueList(values);
      if (valueList) {
        propTable->SetProperty(aTableOrRowFrame, aAttributeAtom,
                               valueList, DestroyValueListFunc, nsnull);
      }
    }
  }

  if (valueList) {
    PRInt32 count = valueList->mArray.Count();
    result = (aRowOrColIndex < count)
           ? (PRUnichar*)(valueList->mArray[aRowOrColIndex])
           : (PRUnichar*)(valueList->mArray[count-1]);
  }
  return result;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void MapAttributesInto ( nsPresContext aPresContext,
nsIContent aCellContent,
nsIFrame aCellFrame,
nsIFrame aCellInnerFrame 
) [static]

Definition at line 172 of file nsMathMLmtableFrame.cpp.

{
  nsTableCellFrame* cellFrame = NS_STATIC_CAST(nsTableCellFrame*, aCellFrame);
  nsTableCellFrame* sibling;

  PRInt32 rowIndex, colIndex;
  nsresult rv = cellFrame->GetCellIndexes(rowIndex, colIndex);
  NS_ASSERTION(NS_SUCCEEDED(rv), "cannot find the position of the cell frame");
  if (NS_FAILED(rv)) return;

  nsIFrame* rowFrame = cellFrame->GetParent();
  nsIFrame* rowgroupFrame = rowFrame->GetParent();
  nsIFrame* tableFrame = rowgroupFrame->GetParent();
  DEBUG_VERIFY_THAT_FRAME_IS(rowFrame, TABLE_ROW);
  DEBUG_VERIFY_THAT_FRAME_IS(rowgroupFrame, TABLE_ROW_GROUP);
  DEBUG_VERIFY_THAT_FRAME_IS(tableFrame, TABLE);
#ifdef NS_DEBUG
  PRBool originates;
  ((nsTableFrame*)tableFrame)->GetCellInfoAt(rowIndex, colIndex, &originates);
  NS_ASSERTION(originates, "internal error");
#endif

  nsIAtom* atom;
  PRUnichar* attr;
  nsAutoString value;
  PRBool hasChanged = PR_FALSE;
  NS_NAMED_LITERAL_STRING(trueStr, "true");

  // process attributes that depend on the index of the row:
  // rowalign, rowlines

  // see if the rowalign attribute is not already set
  atom = nsMathMLAtoms::rowalign_;
  rv = aCellContent->GetAttr(kNameSpaceID_None, atom, value);
  if (NS_CONTENT_ATTR_NOT_THERE == rv) {
    // see if the rowalign attribute was specified on the row
    attr = GetValueAt(aPresContext, rowFrame, atom, rowIndex);
    if (!attr) {
       // see if the rowalign attribute was specified on the table
      attr = GetValueAt(aPresContext, tableFrame, atom, rowIndex);
    }
    // set the attribute without notifying that we want a reflow
    if (attr) {
      hasChanged = PR_TRUE;
      aCellContent->SetAttr(kNameSpaceID_None, atom, nsDependentString(attr), PR_FALSE);
    }
  }
  // if we are not on the first row, see if |rowlines| was specified on the table.
  // Note that we pass 'rowIndex-1' because the CSS rule in mathml.css is associated
  // to 'border-top', and it is as if we draw the line on behalf of the previous cell.
  // This way of doing so allows us to handle selective lines, [row]\hline[row][row]',
  // and cases of spanning cells without further complications.
  if (rowIndex > 0) {
    attr = GetValueAt(aPresContext, tableFrame, nsMathMLAtoms::rowlines_, rowIndex-1);
    // set the special -moz-math-rowline without notifying that we want a reflow
    if (attr) {
      hasChanged = PR_TRUE;
      aCellContent->SetAttr(kNameSpaceID_None, nsMathMLAtoms::MOZrowline, nsDependentString(attr), PR_FALSE);
    }
  }
  else {
    // set the special -moz-math-firstrow to annotate that we are on the first row
    hasChanged = PR_TRUE;
    aCellContent->SetAttr(kNameSpaceID_None, nsMathMLAtoms::MOZfirstrow, trueStr, PR_FALSE);
  }
  // if we are on the last row, set the special -moz-math-lastrow
  PRInt32 rowSpan = ((nsTableFrame*)tableFrame)->GetEffectiveRowSpan(*cellFrame);
  sibling = ((nsTableFrame*)tableFrame)->GetCellFrameAt(rowIndex+rowSpan, colIndex);
  if (!sibling) {
    hasChanged = PR_TRUE;
    aCellContent->SetAttr(kNameSpaceID_None, nsMathMLAtoms::MOZlastrow, trueStr, PR_FALSE);
  }

  // process attributes that depend on the index of the column:
  // columnalign, columnlines, XXX need columnwidth too

  // see if the columnalign attribute is not already set
  atom = nsMathMLAtoms::columnalign_;
  rv = aCellContent->GetAttr(kNameSpaceID_None, atom, value);
  if (NS_CONTENT_ATTR_NOT_THERE == rv) {
    // see if the columnalign attribute was specified on the row
    attr = GetValueAt(aPresContext, rowFrame, atom, colIndex);
    if (!attr) {
       // see if the columnalign attribute was specified on the table
      attr = GetValueAt(aPresContext, tableFrame, atom, colIndex);
    }
    if (attr) {
      hasChanged = PR_TRUE;
      aCellContent->SetAttr(kNameSpaceID_None, atom, nsDependentString(attr), PR_FALSE);
    }
  }
  // if we are not on the first column, see if |columnlines| was specified on
  // the table. Note that we pass 'colIndex-1' because the CSS rule in mathml.css
  // is associated to 'border-left', and it is as if we draw the line on behalf
  // of the previous cell. This way of doing so allows us to handle selective lines,
  // e.g., 'r|cl', and cases of spanning cells without further complications.
  if (colIndex > 0) {
    attr = GetValueAt(aPresContext, tableFrame, nsMathMLAtoms::columnlines_, colIndex-1);
    // set the special -moz-math-columnline without notifying that we want a reflow
    if (attr) {
      hasChanged = PR_TRUE;
      aCellContent->SetAttr(kNameSpaceID_None, nsMathMLAtoms::MOZcolumnline, nsDependentString(attr), PR_FALSE);
    }
  }
  else {
    // set the special -moz-math-firstcolumn to annotate that we are on the first column
    hasChanged = PR_TRUE;
    aCellContent->SetAttr(kNameSpaceID_None, nsMathMLAtoms::MOZfirstcolumn, trueStr, PR_FALSE);
  }
  // if we are on the last column, set the special -moz-math-lastcolumn
  PRInt32 colSpan = ((nsTableFrame*)tableFrame)->GetEffectiveColSpan(*cellFrame);
  sibling = ((nsTableFrame*)tableFrame)->GetCellFrameAt(rowIndex, colIndex+colSpan);
  if (!sibling) {
    hasChanged = PR_TRUE;
    aCellContent->SetAttr(kNameSpaceID_None, nsMathMLAtoms::MOZlastcolumn, trueStr, PR_FALSE);
  }

  // now, re-resolve the style contexts in our subtree to pick up any changes
  if (hasChanged) {
    nsFrameManager *fm = aPresContext->FrameManager();
    nsStyleChangeList changeList;
    nsChangeHint maxChange = fm->ComputeStyleChangeFor(aCellFrame, &changeList,
                                                       NS_STYLE_HINT_NONE);
#ifdef DEBUG
    // Use the parent frame to make sure we catch in-flows and such
    nsIFrame* parentFrame = aCellFrame->GetParent();
    fm->DebugVerifyStyleTree(parentFrame ? parentFrame : aCellFrame);
#endif
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult NS_NewMathMLmtableOuterFrame ( nsIPresShell aPresShell,
nsIFrame **  aNewFrame 
)

Definition at line 366 of file nsMathMLmtableFrame.cpp.

{
  NS_PRECONDITION(aNewFrame, "null OUT ptr");
  if (nsnull == aNewFrame) {
    return NS_ERROR_NULL_POINTER;
  }
  nsMathMLmtableOuterFrame* it = new (aPresShell) nsMathMLmtableOuterFrame;
  if (!it)
    return NS_ERROR_OUT_OF_MEMORY;

  *aNewFrame = it;
  return NS_OK;
}
nsresult NS_NewMathMLmtdFrame ( nsIPresShell aPresShell,
nsIFrame **  aNewFrame 
)

Definition at line 602 of file nsMathMLmtableFrame.cpp.

{
  NS_PRECONDITION(aNewFrame, "null OUT ptr");
  if (nsnull == aNewFrame) {
    return NS_ERROR_NULL_POINTER;
  }
  nsMathMLmtdFrame* it = new (aPresShell) nsMathMLmtdFrame;
  if (nsnull == it) {
    return NS_ERROR_OUT_OF_MEMORY;
  }
  *aNewFrame = it;
  return NS_OK;
}
nsresult NS_NewMathMLmtdInnerFrame ( nsIPresShell aPresShell,
nsIFrame **  aNewFrame 
)

Definition at line 669 of file nsMathMLmtableFrame.cpp.

{
  NS_PRECONDITION(aNewFrame, "null OUT ptr");
  if (nsnull == aNewFrame) {
    return NS_ERROR_NULL_POINTER;
  }
  nsMathMLmtdInnerFrame* it = new (aPresShell) nsMathMLmtdInnerFrame;
  if (nsnull == it) {
    return NS_ERROR_OUT_OF_MEMORY;
  }
  *aNewFrame = it;
  return NS_OK;
}
static void ParseAlignAttribute ( nsString aValue,
eAlign aAlign,
PRInt32 aRowIndex 
) [static]

Definition at line 323 of file nsMathMLmtableFrame.cpp.

{
  // by default, the table is centered about the axis
  aRowIndex = 0;
  aAlign = eAlign_axis;
  PRInt32 len = 0;
  if (0 == aValue.Find("top")) {
    len = 3; // 3 is the length of 'top'
    aAlign = eAlign_top;
  }
  else if (0 == aValue.Find("bottom")) {
    len = 6; // 6 is the length of 'bottom'
    aAlign = eAlign_bottom;
  }
  else if (0 == aValue.Find("center")) {
    len = 6; // 6 is the length of 'center'
    aAlign = eAlign_center;
  }
  else if (0 == aValue.Find("baseline")) {
    len = 8; // 8 is the length of 'baseline'
    aAlign = eAlign_baseline;
  }
  else if (0 == aValue.Find("axis")) {
    len = 4; // 4 is the length of 'axis'
    aAlign = eAlign_axis;
  }
  if (len) {
    PRInt32 error;
    aValue.Cut(0, len); // aValue is not a const here
    aRowIndex = aValue.ToInteger(&error);
    if (error)
      aRowIndex = 0;
  }
}

Here is the caller graph for this function:

static void SplitString ( nsString aString,
nsVoidArray aOffset 
) [static]

Definition at line 69 of file nsMathMLmtableFrame.cpp.

{
  static const PRUnichar kNullCh = PRUnichar('\0');

  aString.Append(kNullCh);  // put an extra null at the end

  PRUnichar* start = aString.BeginWriting();
  PRUnichar* end   = start;

  while (kNullCh != *start) {
    while ((kNullCh != *start) && nsCRT::IsAsciiSpace(*start)) {  // skip leading space
      start++;
    }
    end = start;

    while ((kNullCh != *end) && (PR_FALSE == nsCRT::IsAsciiSpace(*end))) { // look for space or end
      end++;
    }
    *end = kNullCh; // end string here

    if (start < end) {
      aOffset.AppendElement(start); // record the beginning of this segment
    }

    start = ++end;
  }
}

Here is the caller graph for this function: