nsTextFrame::PaintUnicodeText(nsPresContext* aPresContext,
nsTextFrame::PaintUnicodeText(nsIPresContext* aPresContext,
nsTextFrame::PaintUnicodeText(nsPresContext* aPresContext,                              nsIRenderingContext& aRenderingContext,                              nsStyleContext* aStyleContext,                              nsTextPaintStyle& aTextStyle,                              nscoord dx, nscoord dy){  nsCOMPtr<nsISelectionController> selCon;  nsCOMPtr<nsIPresShell> shell;  PRBool  displaySelection,canDarkenColor=PR_FALSE;  PRBool  isPaginated;  PRBool  isSelected;  PRBool hideStandardSelection;  PRInt16 selectionValue;#ifdef IBMBIDI  PRBool  isOddLevel = PR_FALSE;#endif  if (NS_FAILED(GetTextInfoForPainting(aPresContext,                                        aRenderingContext,                                       getter_AddRefs(shell),                                       getter_AddRefs(selCon),                                       displaySelection,                                       isPaginated,                                       isSelected,                                       hideStandardSelection,                                       selectionValue))) {     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(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;    nsCharType charType = eCharType_LeftToRight;    if (aPresContext->BidiEnabled()) {      isBidiSystem = aPresContext->IsBidiSystem();      isOddLevel = NS_GET_EMBEDDING_LEVEL(this) & 1;      charType = (nsCharType)NS_PTR_TO_INT32(aPresContext->PropertyTable()->GetProperty(this, nsLayoutAtoms::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();      if (bidiUtils) {#ifdef DEBUG        PRInt32 rememberTextLength = textLength;#endif        bidiUtils->ReorderUnicodeText(text, textLength,                                      charType, isOddLevel, 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)        frameSelection = shell->FrameSelection();      nsCOMPtr<nsIContent> content;      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        nsCOMPtr<nsILE> ctlObj;        ctlObj = do_CreateInstance(kLECID, &rv);        if (NS_FAILED(rv)) {          NS_WARNING("Cell based cursor movement will not be supported\n");          ctlObj = nsnull;        }        else {          PRInt32 start, end;          PRBool  needsCTL = PR_FALSE;          ctlObj->NeedsCTLFix(text, sdptr->mStart, sdptr->mEnd, &needsCTL);          if (needsCTL && (sdptr->mEnd < textLength)) {            ctlObj->GetRangeOfCluster(text, PRInt32(textLength), sdptr->mEnd,                                      &start, &end);            if (sdptr->mStart > sdptr->mEnd) /* Left Edge */              sdptr->mEnd = start;            else              sdptr->mEnd = end;          }          /* Always start selection from a Right Edge */          if (needsCTL && (sdptr->mStart > 0)) {            ctlObj->GetRangeOfCluster(text, PRInt32(textLength),                                      sdptr->mStart, &start, &end);            sdptr->mStart = end;          }        }#endif /* SUNCTL */#ifdef IBMBIDI        AdjustSelectionPointsForBidi(sdptr, textLength, CHARTYPE_IS_RTL(charType), isOddLevel, isBidiSystem);#endif        sdptr = sdptr->mNext;      }      if (!hideStandardSelection) {      /*       * Text is drawn by drawing the entire string every time, but       * using clip regions to control which part of the text is shown       * (selected or unselected.)  We do this because you can't       * assume that the layout of a part of text will be the same       * when it's drawn apart from the entire string.  This is true       * in languages like arabic, where shaping affects entire words.       * Simply put: length("abcd") != length("ab") + length("cd") in       * some languages.       */      // See if this rendering backend supports getting cluster      // information.      PRUint32 clusterHint = 0;      aRenderingContext.GetHints(clusterHint);      clusterHint &= NS_RENDERING_HINT_TEXT_CLUSTERS;      //while we have substrings...      //PRBool drawn = PR_FALSE;      DrawSelectionIterator iter(details,                                 text,                                 (PRUint32)textLength,                                 aTextStyle);      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();          //nsTextStyle &currentStyle = iter.CurrentStyle();          nscolor    currentFGColor, currentBKColor;          PRBool     isCurrentBKColorTransparent;          PRBool     isSelection = iter.GetSelectionColors(&currentFGColor,                                                           &currentBKColor,                                                           &isCurrentBKColorTransparent);          if (currentlength > 0)          {            if (clusterHint) {              PRUint32 tmpWidth;              rv = aRenderingContext.GetRangeWidth(text, textLength, currenttext - text,                                                   (currenttext - text) + currentlength,                                                   tmpWidth);              newWidth = nscoord(tmpWidth);            }            else {              rv = aRenderingContext.GetWidth(currenttext, currentlength,newWidth); //ADJUST FOR CHAR SPACING            }            if (NS_SUCCEEDED(rv)) {              if (isRightToLeftOnBidiPlatform)                currentX -= newWidth;              if (isSelection && !isPaginated)              {//DRAW RECT HERE!!!                if (!isCurrentBKColorTransparent) {                  aRenderingContext.SetColor(currentBKColor);                  aRenderingContext.FillRect(currentX, dy, newWidth, mRect.height);                }             }            }            else {              newWidth = 0;            }          }          else {            newWidth = 0;          }          aRenderingContext.PushState();          nsRect rect(currentX, dy, newWidth, mRect.height);          aRenderingContext.SetClipRect(rect, nsClipCombine_kIntersect);                                if (isPaginated && !iter.IsBeforeOrAfter()) {            aRenderingContext.SetColor(nsCSSRendering::TransformColor(aTextStyle.mColor->mColor,canDarkenColor));            aRenderingContext.DrawString(text, PRUint32(textLength), dx, dy + mAscent);          } else if (!isPaginated) {            aRenderingContext.SetColor(nsCSSRendering::TransformColor(currentFGColor,canDarkenColor));            aRenderingContext.DrawString(text, PRUint32(textLength), dx, dy + mAscent);          }          aRenderingContext.PopState();#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  }}