Logo Search packages:      
Sourcecode: xulrunner-1.9 version File versions

nsIFrame * nsHyperTextAccessible::GetPosAndText ( PRInt32 &  aStartOffset,
PRInt32 &  aEndOffset,
nsAString aText = nsnull,
nsIFrame **  aEndFrame = nsnull,
nsIntRect *  aBoundsRect = nsnull,
nsIAccessible **  aStartAcc = nsnull,
nsIAccessible **  aEndAcc = nsnull 
) [protected, inherited]

Provides information for substring that is defined by the given start and end offsets for this hyper text.

Parameters:
aStartOffset [inout] the start offset into the hyper text. This is also an out parameter used to return the offset into the start frame's rendered text content (start frame is the
Returns:
)
Parameters:
aEndOffset [inout] the end offset into the hyper text. This is also an out parameter used to return the offset into the end frame's rendered text content.
aText [out, optional] return the substring's text
aEndFrame [out, optional] return the end frame for this substring
aBoundsRect [out, optional] return the bounds rectangle for this substring
aStartAcc [out, optional] return the start accessible for this substring
aEndAcc [out, optional] return the end accessible for this substring
Returns:
the start frame for this substring

Definition at line 321 of file nsHyperTextAccessible.cpp.

References gfxSkipCharsIterator::ConvertOriginalToSkipped(), gfxSkipCharsIterator::ConvertSkippedToOriginal(), nsIFrame::GetChildFrameContainingOffset(), gfxSkipChars::GetOriginalCharCount(), gfxSkipCharsIterator::GetOriginalOffset(), nsIFrame::GetRenderedText(), nsIFrame::GetScreenRectExternal(), gfxSkipCharsIterator::GetSkippedOffset(), and nsIFrame::GetType().

{
  PRInt32 startOffset = aStartOffset;
  PRInt32 endOffset = aEndOffset;

  // Clear out parameters and set up loop
  if (aText) {
    aText->Truncate();
  }
  if (endOffset < 0) {
    const PRInt32 kMaxTextLength = 32767;
    endOffset = kMaxTextLength; // Max end offset
  }
  else if (startOffset > endOffset) {
    return nsnull;
  }

  nsIFrame *startFrame = nsnull;
  if (aEndFrame) {
    *aEndFrame = nsnull;
  }
  if (aBoundsRect) {
    aBoundsRect->Empty();
  }
  if (aStartAcc)
    *aStartAcc = nsnull;
  if (aEndAcc)
    *aEndAcc = nsnull;

  nsIntRect unionRect;
  nsCOMPtr<nsIAccessible> accessible;

  gfxSkipChars skipChars;
  gfxSkipCharsIterator iter;

  // Loop through children and collect valid offsets, text and bounds
  // depending on what we need for out parameters
  while (NextChild(accessible)) {
    nsCOMPtr<nsPIAccessNode> accessNode(do_QueryInterface(accessible));
    nsIFrame *frame = accessNode->GetFrame();
    if (!frame) {
      continue;
    }
    nsIFrame *primaryFrame = frame;
    if (IsText(accessible)) {
      // We only need info up to rendered offset -- that is what we're
      // converting to content offset
      PRInt32 substringEndOffset = -1;
      PRUint32 ourRenderedStart = 0;
      PRInt32 ourContentStart = 0;
      if (frame->GetType() == nsAccessibilityAtoms::textFrame) {
        nsresult rv = frame->GetRenderedText(nsnull, &skipChars, &iter);
        if (NS_SUCCEEDED(rv)) {
          ourRenderedStart = iter.GetSkippedOffset();
          ourContentStart = iter.GetOriginalOffset();
          substringEndOffset =
            iter.ConvertOriginalToSkipped(skipChars.GetOriginalCharCount() +
                                          ourContentStart) - ourRenderedStart;
        }
      }
      if (substringEndOffset < 0) {
        // XXX for non-textframe text like list bullets,
        // should go away after list bullet rewrite
        substringEndOffset = TextLength(accessible);
      }
      if (startOffset < substringEndOffset) {
        // Our start is within this substring
        if (startOffset > 0 || endOffset < substringEndOffset) {
          // We don't want the whole string for this accessible
          // Get out the continuing text frame with this offset
          PRInt32 outStartLineUnused;
          PRInt32 contentOffset;
          if (frame->GetType() == nsAccessibilityAtoms::textFrame) {
            contentOffset = iter.ConvertSkippedToOriginal(startOffset) +
                            ourRenderedStart - ourContentStart;
          }
          else {
            contentOffset = startOffset;
          }
          frame->GetChildFrameContainingOffset(contentOffset, PR_TRUE,
                                               &outStartLineUnused, &frame);
          if (aEndFrame) {
            *aEndFrame = frame; // We ended in the current frame
            if (aEndAcc)
              NS_ADDREF(*aEndAcc = accessible);
          }
          if (substringEndOffset > endOffset) {
            // Need to stop before the end of the available text
            substringEndOffset = endOffset;
          }
          aEndOffset = endOffset;
        }
        if (aText) {
          nsCOMPtr<nsPIAccessible> pAcc(do_QueryInterface(accessible));
          pAcc->AppendTextTo(*aText, startOffset,
                             substringEndOffset - startOffset);
        }
        if (aBoundsRect) {    // Caller wants the bounds of the text
          aBoundsRect->UnionRect(*aBoundsRect,
                                 GetBoundsForString(primaryFrame, startOffset,
                                                    substringEndOffset));
        }
        if (!startFrame) {
          startFrame = frame;
          aStartOffset = startOffset;
          if (aStartAcc)
            NS_ADDREF(*aStartAcc = accessible);
        }
        // We already started copying in this accessible's string,
        // for the next accessible we'll start at offset 0
        startOffset = 0;
      }
      else {
        // We have not found the start position yet, get the new startOffset
        // that is relative to next accessible
        startOffset -= substringEndOffset;
      }
      // The endOffset needs to be relative to the new startOffset
      endOffset -= substringEndOffset;
    }
    else {
      // Embedded object, append marker
      // XXX Append \n for <br>'s
      if (startOffset >= 1) {
        -- startOffset;
      }
      else {
        if (endOffset > 0) {
          if (aText) {
            *aText += (frame->GetType() == nsAccessibilityAtoms::brFrame) ?
                      kForcedNewLineChar : kEmbeddedObjectChar;
          }
          if (aBoundsRect) {
            aBoundsRect->UnionRect(*aBoundsRect,
                                   frame->GetScreenRectExternal());
          }
        }
        if (!startFrame) {
          startFrame = frame;
          aStartOffset = 0;
          if (aStartAcc)
            NS_ADDREF(*aStartAcc = accessible);
        }
      }
      -- endOffset;
    }
    if (endOffset <= 0 && startFrame) {
      break; // If we don't have startFrame yet, get that in next loop iteration
    }
  }

  if (aEndFrame && !*aEndFrame) {
    *aEndFrame = startFrame;
    if (aStartAcc && aEndAcc)
      NS_ADDREF(*aEndAcc = *aStartAcc);
  }

  return startFrame;
}


Generated by  Doxygen 1.6.0   Back to index