mCtlObj = nsnull;
ctlObj = nsnull;
nsTextFrame::PaintUnicodeText(nsIPresContext* aPresContext,                              nsIRenderingContext& aRenderingContext,                              nsStyleContext* aStyleContext,                              TextStyle& aTextStyle,                              nscoord dx, nscoord dy){  nsCOMPtr<nsISelectionController> selCon;  nsCOMPtr<nsIPresShell> shell;  PRBool  displaySelection,canDarkenColor=PR_FALSE;  PRBool  isPaginated;  PRBool  isSelected;  PRInt16 selectionValue;  nsCOMPtr<nsILineBreaker> lb;#ifdef IBMBIDI  PRUint8 level = 0;#endif  if (NS_FAILED(GetTextInfoForPainting(aPresContext,                                        aRenderingContext,                                       getter_AddRefs(shell),                                       getter_AddRefs(selCon),                                       displaySelection,                                       isPaginated,                                       isSelected,                                       selectionValue,                                       getter_AddRefs(lb)))) {     return;  }  if(isPaginated){    canDarkenColor = CanDarken(aPresContext);  }  // Make enough space to transform  nsAutoTextBuffer paintBuffer;  nsAutoIndexBuffer indexBuffer;  if (displaySelection) {    if (NS_FAILED(indexBuffer.GrowTo(mContentLength + 1))) {      return;    }  }  nscoord width = mRect.width;  // Transform text from content into renderable form  // XXX If the text fragment is already Unicode and the text wasn't  // transformed when we formatted it, then there's no need to do all  // this and we should just render the text fragment directly. See  // PaintAsciiText()...  nsTextTransformer tx(lb, nsnull, aPresContext);  PRInt32 textLength;  // no need to worry about justification, that's always on the slow path  PrepareUnicodeText(tx, (displaySelection ? &indexBuffer : nsnull),                     &paintBuffer, &textLength);  PRInt32* ip = indexBuffer.mBuffer;  PRUnichar* text = paintBuffer.mBuffer;  if (0 != textLength)   {#ifdef IBMBIDI    PRBool isRightToLeftOnBidiPlatform = PR_FALSE;    PRBool isBidiSystem = PR_FALSE;    PRBool bidiEnabled;    nsCharType charType = eCharType_LeftToRight;    aPresContext->GetBidiEnabled(&bidiEnabled);    if (bidiEnabled) {      isBidiSystem = aPresContext->IsBidiSystem();      GetBidiProperty(aPresContext, nsLayoutAtoms::embeddingLevel, (void**) &level,sizeof(level));      GetBidiProperty(aPresContext, nsLayoutAtoms::charType, (void**) &charType,sizeof(charType));      isRightToLeftOnBidiPlatform = (isBidiSystem &&                                     (eCharType_RightToLeft == charType ||                                      eCharType_RightToLeftArabic == charType));      if (isRightToLeftOnBidiPlatform) {        // indicate that the platform should use its native        // capabilities to reorder the text with right-to-left        // base direction         aRenderingContext.SetRightToLeftText(PR_TRUE);      }      nsBidiPresUtils* bidiUtils;      aPresContext->GetBidiUtils(&bidiUtils);      if (bidiUtils) {#ifdef DEBUG        PRInt32 rememberTextLength = textLength;#endif        bidiUtils->ReorderUnicodeText(text, textLength,                                      charType, level & 1, isBidiSystem);        NS_ASSERTION(rememberTextLength == textLength, "Bidi formatting changed text length");      }    }#endif // IBMBIDI    if (!displaySelection || !isSelected ) //draw text normally    {       // When there is no selection showing, use the fastest and      // simplest rendering approach      aRenderingContext.SetColor(nsCSSRendering::TransformColor(aTextStyle.mColor->mColor,canDarkenColor));      aRenderingContext.DrawString(text, PRUint32(textLength), dx, dy + mAscent);      PaintTextDecorations(aRenderingContext, aStyleContext, aPresContext,                           aTextStyle, dx, dy, width);    }    else     { //we draw according to selection rules      SelectionDetails *details = nsnull;      nsCOMPtr<nsIFrameSelection> frameSelection;      //get the frameSelection from the selection controller      if (selCon)      {        frameSelection = do_QueryInterface(selCon); //this MAY implement      }      //if that failed get it from the pres shell      nsresult rv = NS_OK;      if (!frameSelection)        rv = shell->GetFrameSelection(getter_AddRefs(frameSelection));      nsCOMPtr<nsIContent> content;      if (NS_SUCCEEDED(rv) && frameSelection){        PRInt32 offset;        PRInt32 length;        rv = GetContentAndOffsetsForSelection(aPresContext,getter_AddRefs(content),&offset,&length);        if (NS_SUCCEEDED(rv) && content){          rv = frameSelection->LookUpSelection(content, mContentOffset,                                 mContentLength , &details, PR_FALSE);        }      }              //where are the selection points "really"      SelectionDetails *sdptr = details;      while (sdptr){        sdptr->mStart = ip[sdptr->mStart] - mContentOffset;        sdptr->mEnd = ip[sdptr->mEnd]  - mContentOffset;#ifdef SUNCTL        static NS_DEFINE_CID(kLECID, NS_ULE_CID);        nsCOMPtr<nsILE> mCtlObj;        mCtlObj = do_CreateInstance(kLECID, &rv);        if (NS_FAILED(rv)) {          NS_WARNING("Cell based cursor movement will not be supported\n");          mCtlObj = nsnull;        }        else {          PRInt32 mStart, mEnd;          if (sdptr->mEnd < textLength) {            mCtlObj->GetRangeOfCluster(text, PRInt32(textLength), sdptr->mEnd, &mStart, &mEnd);            if (sdptr->mStart > sdptr->mEnd) /* Left Edge */              sdptr->mEnd = mStart;            else              sdptr->mEnd = mEnd;          }          /* Always start selection from a Right Edge */          if (sdptr->mStart > 0) {            mCtlObj->GetRangeOfCluster(text, PRInt32(textLength), sdptr->mStart, &mStart, &mEnd);            sdptr->mStart = mEnd;          }        }#endif /* SUNCTL */#ifdef IBMBIDI        AdjustSelectionPointsForBidi(sdptr, textLength, CHARTYPE_IS_RTL(charType), level & 1, isBidiSystem);#endif        sdptr = sdptr->mNext;      }      //while we have substrings...      //PRBool drawn = PR_FALSE;      DrawSelectionIterator iter(content, details,text,(PRUint32)textLength,aTextStyle, selectionValue, aPresContext, mStyleContext);      if (!iter.IsDone() && iter.First())      {        nscoord currentX = dx;        nscoord newWidth;//temp#ifdef IBMBIDI // Simon - display substrings RTL in RTL frame        nscoord FrameWidth = 0;        if (isRightToLeftOnBidiPlatform)          if (NS_SUCCEEDED(aRenderingContext.GetWidth(text, textLength, FrameWidth)))            currentX = dx + FrameWidth;#endif        while (!iter.IsDone())        {          PRUnichar *currenttext  = iter.CurrentTextUnicharPtr();          PRUint32   currentlength= iter.CurrentLength();          //TextStyle &currentStyle = iter.CurrentStyle();          nscolor    currentFGColor = iter.CurrentForeGroundColor();          nscolor    currentBKColor;          PRBool     isCurrentBKColorTransparent;#ifdef IBMBIDI          if (currentlength > 0            && NS_SUCCEEDED(aRenderingContext.GetWidth(currenttext, currentlength,newWidth)))//ADJUST FOR CHAR SPACING          {            if (isRightToLeftOnBidiPlatform)              currentX -= newWidth;#else // not IBMBIDI          if (NS_SUCCEEDED(aRenderingContext.GetWidth(currenttext, currentlength,newWidth)))//ADJUST FOR CHAR SPACING          {#endif            if (iter.CurrentBackGroundColor(currentBKColor, &isCurrentBKColorTransparent) && !isPaginated)            {//DRAW RECT HERE!!!              if (!isCurrentBKColorTransparent) {                aRenderingContext.SetColor(currentBKColor);                aRenderingContext.FillRect(currentX, dy, newWidth, mRect.height);              }              currentFGColor = EnsureDifferentColors(currentFGColor, currentBKColor);            }          }          else            newWidth =0;                    if (isPaginated && !iter.IsBeforeOrAfter()) {            aRenderingContext.SetColor(nsCSSRendering::TransformColor(aTextStyle.mColor->mColor,canDarkenColor));            aRenderingContext.DrawString(currenttext, currentlength, currentX, dy + mAscent);          } else if (!isPaginated) {            aRenderingContext.SetColor(nsCSSRendering::TransformColor(currentFGColor,canDarkenColor));            aRenderingContext.DrawString(currenttext, currentlength, currentX, dy + mAscent);          }#ifdef IBMBIDI          if (!isRightToLeftOnBidiPlatform)#endif          currentX+=newWidth;//increment twips X start          iter.Next();        }      }      else if (!isPaginated)       {        aRenderingContext.SetColor(nsCSSRendering::TransformColor(aTextStyle.mColor->mColor,canDarkenColor));        aRenderingContext.DrawString(text, PRUint32(textLength), dx, dy + mAscent);      }      PaintTextDecorations(aRenderingContext, aStyleContext, aPresContext,                           aTextStyle, dx, dy, width, text, details, 0,                           (PRUint32)textLength);      sdptr = details;      if (details){        while ((sdptr = details->mNext) != nsnull) {          delete details;          details = sdptr;        }        delete details;      }    }#ifdef IBMBIDI    if (isRightToLeftOnBidiPlatform) {      // indicate that future text should not be reordered with      // right-to-left base direction       aRenderingContext.SetRightToLeftText(PR_FALSE);    }#endif // IBMBIDI  }}