checkin for carpool for multiple seleciton/ime selection and api changes to nsIDOMselection

This commit is contained in:
mjudge%netscape.com 1999-07-15 18:19:03 +00:00
Родитель e4b8289dc3
Коммит a2f598637e
14 изменённых файлов: 1350 добавлений и 963 удалений

Просмотреть файл

@ -199,21 +199,21 @@ NS_IMETHODIMP nsCaret::GetWindowRelativeCoordinates(nsPoint& outCoordinates, PRB
outCoordinates.y = -1;
outIsCollapsed = PR_FALSE;
err = domSelection->GetIsCollapsed(&outIsCollapsed);
err = domSelection->GetIsCollapsed(SELECTION_NORMAL, &outIsCollapsed);
if (NS_FAILED(err))
return err;
// code in progress
nsCOMPtr<nsIDOMNode> focusNode;
err = domSelection->GetFocusNode(getter_AddRefs(focusNode));
err = domSelection->GetFocusNode(SELECTION_NORMAL, getter_AddRefs(focusNode));
if (NS_FAILED(err))
return err;
if (!focusNode)
return NS_ERROR_FAILURE;
PRInt32 focusOffset;
err = domSelection->GetFocusOffset(&focusOffset);
err = domSelection->GetFocusOffset(SELECTION_NORMAL, &focusOffset);
if (NS_FAILED(err))
return err;
@ -417,14 +417,14 @@ PRBool nsCaret::SetupDrawingFrameAndOffset()
PRBool isCollapsed;
if (domSelection && NS_SUCCEEDED(domSelection->GetIsCollapsed(&isCollapsed)) && isCollapsed)
if (domSelection && NS_SUCCEEDED(domSelection->GetIsCollapsed(SELECTION_NORMAL, &isCollapsed)) && isCollapsed)
{
// start and end parent should be the same since we are collapsed
nsCOMPtr<nsIDOMNode> focusNode;
PRInt32 contentOffset;
if (NS_SUCCEEDED(domSelection->GetFocusNode(getter_AddRefs(focusNode))) && focusNode &&
NS_SUCCEEDED(domSelection->GetFocusOffset(&contentOffset)))
if (NS_SUCCEEDED(domSelection->GetFocusNode(SELECTION_NORMAL, getter_AddRefs(focusNode))) && focusNode &&
NS_SUCCEEDED(domSelection->GetFocusOffset(SELECTION_NORMAL, &contentOffset)))
{
nsCOMPtr<nsIContent>contentNode = do_QueryInterface(focusNode);

Просмотреть файл

@ -275,7 +275,8 @@ nsLeafIterator::Prev()
if (NS_SUCCEEDED(parent->GetParent(&grandParent)) && grandParent &&
NS_SUCCEEDED(grandParent->FirstChild(nsnull,&result))){
nsFrameList list(result);
if (result = list.GetPrevSiblingFor(parent)){
result = list.GetPrevSiblingFor(parent);
if (result){
parent = result;
while(NS_SUCCEEDED(parent->FirstChild(nsnull,&result)) && result){
parent = result;

Просмотреть файл

@ -29,6 +29,7 @@
#include "nsISupports.h"
#include "nsIFrame.h"
#include "nsIFocusTracker.h"
#include "nsIDOMSelection.h"
// IID for the nsIFrameSelection interface
#define NS_IFRAMESELECTION_IID \
@ -39,6 +40,15 @@
//----------------------------------------------------------------------
// Selection interface
struct SelectionDetails
{
PRInt32 mStart;
PRInt32 mEnd;
SelectionType mType;
SelectionDetails *mNext;
};
class nsIFrameSelection : public nsISupports {
public:
static const nsIID& GetIID() { static nsIID iid = NS_IFRAMESELECTION_IID; return iid; }
@ -79,8 +89,11 @@ public:
* @param aContentOffsetEnd is the content offset of the parent aNewFocus and is specified different
* when you need to select to and include both start and end points
* @param aContinueSelection is the flag that tells the selection to keep the old anchor point or not.
* @param aMultipleSelection will tell the frame selector to replace /or not the old selection.
* cannot coexist with aContinueSelection
*/
NS_IMETHOD TakeFocus(nsIContent *aNewFocus, PRUint32 aContentOffset, PRUint32 aContentEndOffset , PRBool aContinueSelection) = 0;
NS_IMETHOD TakeFocus(nsIContent *aNewFocus, PRUint32 aContentOffset, PRUint32 aContentEndOffset ,
PRBool aContinueSelection, PRBool aMultipleSelection) = 0;
/** EnableFrameNotification
* mutch like start batching, except all dirty calls are ignored. no notifications will go
@ -93,13 +106,10 @@ public:
* @param aContent is the content asking
* @param aContentOffset is the starting content boundary
* @param aContentLength is the length of the content piece asking
* @param aStart start return frame indexed value
* @param aEnd end return frame indexed value
* @param aDrawSelected return value if this offset,length has anything in the selected area
* @param aFlag what type of selection not used now
* @param aReturnDetails linkedlist of return values for the selection.
*/
NS_IMETHOD LookUpSelection(nsIContent *aContent, PRInt32 aContentOffset, PRInt32 aContentLength,
PRInt32 *aStart, PRInt32 *aEnd, PRBool *aDrawSelected, PRUint32 aFlag/*not used*/) = 0;
SelectionDetails **aReturnDetails) = 0;
/** SetMouseDownState(PRBool);
* sets the mouse state to aState for resons of drag state.
@ -116,4 +126,5 @@ public:
};
#endif /* nsIFrameSelection_h___ */

Просмотреть файл

@ -29,6 +29,7 @@
#include "nsISupports.h"
#include "nsIFrame.h"
#include "nsIFocusTracker.h"
#include "nsIDOMSelection.h"
// IID for the nsIFrameSelection interface
#define NS_IFRAMESELECTION_IID \
@ -39,6 +40,15 @@
//----------------------------------------------------------------------
// Selection interface
struct SelectionDetails
{
PRInt32 mStart;
PRInt32 mEnd;
SelectionType mType;
SelectionDetails *mNext;
};
class nsIFrameSelection : public nsISupports {
public:
static const nsIID& GetIID() { static nsIID iid = NS_IFRAMESELECTION_IID; return iid; }
@ -79,8 +89,11 @@ public:
* @param aContentOffsetEnd is the content offset of the parent aNewFocus and is specified different
* when you need to select to and include both start and end points
* @param aContinueSelection is the flag that tells the selection to keep the old anchor point or not.
* @param aMultipleSelection will tell the frame selector to replace /or not the old selection.
* cannot coexist with aContinueSelection
*/
NS_IMETHOD TakeFocus(nsIContent *aNewFocus, PRUint32 aContentOffset, PRUint32 aContentEndOffset , PRBool aContinueSelection) = 0;
NS_IMETHOD TakeFocus(nsIContent *aNewFocus, PRUint32 aContentOffset, PRUint32 aContentEndOffset ,
PRBool aContinueSelection, PRBool aMultipleSelection) = 0;
/** EnableFrameNotification
* mutch like start batching, except all dirty calls are ignored. no notifications will go
@ -93,13 +106,10 @@ public:
* @param aContent is the content asking
* @param aContentOffset is the starting content boundary
* @param aContentLength is the length of the content piece asking
* @param aStart start return frame indexed value
* @param aEnd end return frame indexed value
* @param aDrawSelected return value if this offset,length has anything in the selected area
* @param aFlag what type of selection not used now
* @param aReturnDetails linkedlist of return values for the selection.
*/
NS_IMETHOD LookUpSelection(nsIContent *aContent, PRInt32 aContentOffset, PRInt32 aContentLength,
PRInt32 *aStart, PRInt32 *aEnd, PRBool *aDrawSelected, PRUint32 aFlag/*not used*/) = 0;
SelectionDetails **aReturnDetails) = 0;
/** SetMouseDownState(PRBool);
* sets the mouse state to aState for resons of drag state.
@ -116,4 +126,5 @@ public:
};
#endif /* nsIFrameSelection_h___ */

Просмотреть файл

@ -199,21 +199,21 @@ NS_IMETHODIMP nsCaret::GetWindowRelativeCoordinates(nsPoint& outCoordinates, PRB
outCoordinates.y = -1;
outIsCollapsed = PR_FALSE;
err = domSelection->GetIsCollapsed(&outIsCollapsed);
err = domSelection->GetIsCollapsed(SELECTION_NORMAL, &outIsCollapsed);
if (NS_FAILED(err))
return err;
// code in progress
nsCOMPtr<nsIDOMNode> focusNode;
err = domSelection->GetFocusNode(getter_AddRefs(focusNode));
err = domSelection->GetFocusNode(SELECTION_NORMAL, getter_AddRefs(focusNode));
if (NS_FAILED(err))
return err;
if (!focusNode)
return NS_ERROR_FAILURE;
PRInt32 focusOffset;
err = domSelection->GetFocusOffset(&focusOffset);
err = domSelection->GetFocusOffset(SELECTION_NORMAL, &focusOffset);
if (NS_FAILED(err))
return err;
@ -417,14 +417,14 @@ PRBool nsCaret::SetupDrawingFrameAndOffset()
PRBool isCollapsed;
if (domSelection && NS_SUCCEEDED(domSelection->GetIsCollapsed(&isCollapsed)) && isCollapsed)
if (domSelection && NS_SUCCEEDED(domSelection->GetIsCollapsed(SELECTION_NORMAL, &isCollapsed)) && isCollapsed)
{
// start and end parent should be the same since we are collapsed
nsCOMPtr<nsIDOMNode> focusNode;
PRInt32 contentOffset;
if (NS_SUCCEEDED(domSelection->GetFocusNode(getter_AddRefs(focusNode))) && focusNode &&
NS_SUCCEEDED(domSelection->GetFocusOffset(&contentOffset)))
if (NS_SUCCEEDED(domSelection->GetFocusNode(SELECTION_NORMAL, getter_AddRefs(focusNode))) && focusNode &&
NS_SUCCEEDED(domSelection->GetFocusOffset(SELECTION_NORMAL, &contentOffset)))
{
nsCOMPtr<nsIContent>contentNode = do_QueryInterface(focusNode);

Просмотреть файл

@ -275,7 +275,8 @@ nsLeafIterator::Prev()
if (NS_SUCCEEDED(parent->GetParent(&grandParent)) && grandParent &&
NS_SUCCEEDED(grandParent->FirstChild(nsnull,&result))){
nsFrameList list(result);
if (result = list.GetPrevSiblingFor(parent)){
result = list.GetPrevSiblingFor(parent);
if (result){
parent = result;
while(NS_SUCCEEDED(parent->FirstChild(nsnull,&result)) && result){
parent = result;

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -91,6 +91,9 @@ PRInt32 fTrackerAddListMax = 0;
#include "nsILineIterator.h"
// [HACK] Foward Declarations
void ForceDrawFrame(nsFrame * aFrame);
//non Hack prototypes
static void GetLastLeaf(nsIFrame **aFrame);
static void GetFirstLeaf(nsIFrame **aFrame);
#if 0
static void RefreshContentFrames(nsIPresContext& aPresContext, nsIContent * aStartContent, nsIContent * aEndContent);
#endif
@ -704,7 +707,6 @@ nsFrame::Paint(nsIPresContext& aPresContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)
{
PRBool drawSelected(PR_FALSE);
//if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) {
/** GetDocument
*/
@ -746,10 +748,11 @@ nsFrame::Paint(nsIPresContext& aPresContext,
nsCOMPtr<nsIContent> newContent;
result = mContent->GetParent(*getter_AddRefs(newContent));
SelectionDetails *details;
PRInt32 offset;
PRInt32 offsetEnd;
if (NS_SUCCEEDED(result) && newContent){
result = newContent->IndexOf(mContent, offset);
nsresult result = newContent->IndexOf(mContent, offset);
if (NS_FAILED(result))
{
return result;
@ -764,13 +767,12 @@ nsFrame::Paint(nsIPresContext& aPresContext,
result = GetContent(getter_AddRefs(content));
if (NS_SUCCEEDED(result)){
result = frameSelection->LookUpSelection(newContent, offset,
1, &offset, &offsetEnd,
&drawSelected,0);// last param notused
1, &details);// last param notused
}
}
}
//}
if (drawSelected)
if (details)
{
nsRect rect;
GetRect(rect);
@ -781,6 +783,12 @@ nsFrame::Paint(nsIPresContext& aPresContext,
aRenderingContext.SetColor(NS_RGB(0,0,255));
nsRect drawrect(1, 1, rect.width, rect.height);
aRenderingContext.DrawRect(drawrect );
SelectionDetails *deletingDetails = details;
while(deletingDetails = details->mNext){
delete details;
details = deletingDetails;
}
delete details;
//aRenderingContext.DrawLine(rect.x, rect.y, rect.XMost(), rect.YMost());
//aRenderingContext.DrawLine(rect.x, rect.YMost(), rect.XMost(), rect.y);
}
@ -902,7 +910,7 @@ nsFrame::HandlePress(nsIPresContext& aPresContext,
if (frameselection) {
if (NS_SUCCEEDED( rv )){
frameselection->SetMouseDownState(PR_TRUE);//not important if it fails here
frameselection->TakeFocus(newContent, startPos , contentOffsetEnd , inputEvent->isShift);
frameselection->TakeFocus(newContent, startPos , contentOffsetEnd , inputEvent->isShift, inputEvent->isControl);
}
}
}
@ -945,7 +953,7 @@ NS_IMETHODIMP nsFrame::HandleDrag(nsIPresContext& aPresContext,
nsIFrameSelection* frameselection;
if (NS_SUCCEEDED(selection->QueryInterface(kIFrameSelection, (void **)&frameselection))) {
if (NS_SUCCEEDED( rv )){
frameselection->TakeFocus(newContent, startPos, contentOffsetEnd , PR_TRUE); //TRUE IS THE DIFFERENCE
frameselection->TakeFocus(newContent, startPos, contentOffsetEnd , PR_TRUE, PR_FALSE); //TRUE IS THE DIFFERENCE for continue selection
}
NS_RELEASE(frameselection);
}
@ -990,7 +998,7 @@ NS_IMETHODIMP nsFrame::GetPosition(nsIPresContext& aCX,
}
aContentOffsetEnd = aContentOffset +1;
}
return NS_OK;
return result;
}
@ -1640,6 +1648,194 @@ nsFrame::GetChildFrameContainingOffset(PRInt32 inContentOffset, PRInt32* outFram
return NS_OK;
}
NS_IMETHODIMP
nsFrame::GetNextPrevLineFromeBlockFrame(nsIFocusTracker *aTracker,
nsDirection aDirection,
nsIFrame *aBlockFrame,
PRInt32 aLineStart,
nscoord aDesiredX,
nsIContent **aResultContent,
PRInt32 *aContentOffset,
PRInt8 aOutSideLimit
)
{
//magic numbers aLineStart will be -1 for end of block 0 will be start of block
if (!aBlockFrame)
return NS_ERROR_NULL_POINTER;
PRInt32 thisLine = 0;
nsresult result;
nsCOMPtr<nsILineIterator> it;
result = aBlockFrame->QueryInterface(nsILineIterator::GetIID(),getter_AddRefs(it));
if (NS_FAILED(result) || !it)
return result;
PRInt32 searchingLine = aLineStart;
PRInt32 countLines;
result = it->GetNumLines(&countLines);
if (aOutSideLimit > 0) //start at end
searchingLine = countLines;
else if (aOutSideLimit <0)//start at begining
searchingLine = -1;//"next" will be 0
else
if ((aDirection == eDirPrevious && aLineStart == 0) ||
(aDirection == eDirNext && aLineStart >= (countLines -1) )){
//we need to jump to new block frame.
return NS_ERROR_FAILURE;
/* if (aDirection == eDirNext)
return aBlockFrame->PeekOffset(aTracker, aDesiredX, eSelectLine, aDirection, 0, aResultContent,
aContentOffset, PR_FALSE);
else
return aBlockFrame->PeekOffset(aTracker, aDesiredX, eSelectLine, aDirection, -1, aResultContent,
aContentOffset, PR_FALSE);*/
}
PRInt32 lineFrameCount;
nsIFrame *resultFrame = nsnull;
nsIFrame *farStoppingFrame = nsnull; //we keep searching until we find a "this" frame then we go to next line
nsIFrame *nearStoppingFrame = nsnull; //if we are backing up from edge, stop here
nsIFrame *firstFrame;
nsIFrame *lastFrame;
nsRect nonUsedRect;
PRBool isBeforeFirstFrame, isAfterLastFrame;
PRBool found = PR_FALSE;
while (!found)
{
if (aDirection == eDirPrevious)
searchingLine --;
else
searchingLine ++;
result = it->GetLine(searchingLine, &firstFrame, &lineFrameCount,nonUsedRect);
if (NS_SUCCEEDED(result)){
lastFrame = firstFrame;
for (;lineFrameCount > 1;lineFrameCount --){
result = lastFrame->GetNextSibling(&lastFrame);
if (NS_FAILED(result)){
NS_ASSERTION(0,"should not be reached nsFrame\n");
continue;
}
}
GetLastLeaf(&lastFrame);
if (aDirection == eDirNext){
nearStoppingFrame = firstFrame;
farStoppingFrame = lastFrame;
}
else{
nearStoppingFrame = lastFrame;
farStoppingFrame = firstFrame;
}
result = it->FindFrameAt(searchingLine, aDesiredX, &resultFrame, &isBeforeFirstFrame, &isAfterLastFrame);
}
if (NS_SUCCEEDED(result) && resultFrame)
{
nsCOMPtr<nsILineIterator> newIt;
//check to see if this is ANOTHER blockframe inside the other one if so then call into its lines
result = resultFrame->QueryInterface(nsILineIterator::GetIID(),getter_AddRefs(newIt));
if (NS_SUCCEEDED(result) && newIt)
{
if (aDirection == eDirPrevious){
if (NS_SUCCEEDED(GetNextPrevLineFromeBlockFrame(aTracker,
aDirection,
resultFrame,
0,
aDesiredX,
aResultContent,
aContentOffset,
1//start from end
)))
return NS_OK;
}
else {
if (NS_SUCCEEDED(GetNextPrevLineFromeBlockFrame(aTracker,
aDirection,
resultFrame,
0,
aDesiredX,
aResultContent,
aContentOffset,
-1//start from beginning
)))
return NS_OK;
}
}
//resultFrame is not a block frame
nsCOMPtr<nsIBidirectionalEnumerator> frameTraversal;
result = NS_NewFrameTraversal(getter_AddRefs(frameTraversal),LEAF,resultFrame);
if (NS_FAILED(result))
return result;
nsISupports *isupports = nsnull;
nsIFrame *storeOldResultFrame = resultFrame;
while ( !found ){
nsCOMPtr<nsIPresContext> context;
result = aTracker->GetPresContext(getter_AddRefs(context));
result = resultFrame->GetPosition(*(context.get()),aDesiredX,
aResultContent,*aContentOffset, *aContentOffset);
PRBool breakOut = PR_FALSE;
if (NS_SUCCEEDED(result))
found = PR_TRUE;
else {
if (aDirection == eDirPrevious && (resultFrame == farStoppingFrame))
break;
if (aDirection == eDirNext && (resultFrame == nearStoppingFrame))
break;
//always try previous on THAT line if that fails go the other way
result = frameTraversal->Prev();
if (NS_FAILED(result))
break;
result = frameTraversal->CurrentItem(&isupports);
if (NS_FAILED(result) || !isupports)
return result;
//we must CAST here to an nsIFrame. nsIFrame doesnt really follow the rules
resultFrame = (nsIFrame *)isupports;
}
}
if (!found){
resultFrame = storeOldResultFrame;
result = NS_NewFrameTraversal(getter_AddRefs(frameTraversal),LEAF,resultFrame);
}
while ( !found ){
nsCOMPtr<nsIPresContext> context;
result = aTracker->GetPresContext(getter_AddRefs(context));
result = resultFrame->GetPosition(*(context.get()),aDesiredX,
aResultContent,*aContentOffset, *aContentOffset);
PRBool breakOut = PR_FALSE;
if (NS_SUCCEEDED(result))
found = PR_TRUE;
else {
if (aDirection == eDirPrevious && (resultFrame == nearStoppingFrame))
break;
if (aDirection == eDirNext && (resultFrame == farStoppingFrame))
break;
//previous didnt work now we try "next"
result = frameTraversal->Next();
if (NS_FAILED(result))
break;
result = frameTraversal->CurrentItem(&isupports);
if (NS_FAILED(result) || !isupports)
return result;
//we must CAST here to an nsIFrame. nsIFrame doesnt really follow the rules
resultFrame = (nsIFrame *)isupports;
}
}
}
else {
//we need to jump to new block frame.
if (aDirection == eDirNext)
return aBlockFrame->PeekOffset(aTracker, aDesiredX, eSelectLine, aDirection, 0, aResultContent,
aContentOffset, PR_FALSE);
else
return aBlockFrame->PeekOffset(aTracker, aDesiredX, eSelectLine, aDirection, -1, aResultContent,
aContentOffset, PR_FALSE);
}
}
return NS_OK;
}
NS_IMETHODIMP
nsFrame::PeekOffset(nsIFocusTracker *aTracker,
nscoord aDesiredX,
@ -1652,7 +1848,7 @@ nsFrame::PeekOffset(nsIFocusTracker *aTracker,
{
if (!aResultContent || !aContentOffset ||!aTracker)
return NS_ERROR_NULL_POINTER;
nsresult result;
nsresult result = NS_ERROR_FAILURE;
switch (aAmount){
case eSelectLine :
{
@ -1663,8 +1859,11 @@ nsFrame::PeekOffset(nsIFocusTracker *aTracker,
nsCOMPtr<nsILineIterator> it;
nsIFrame *blockFrame = this;
nsIFrame *thisBlock = this;
PRInt32 thisLine;
while (NS_FAILED(result)){
result = blockFrame->GetParent(&blockFrame);
if (NS_FAILED(result)) //if at line 0 then nothing to do
if (NS_FAILED(result) || !blockFrame) //if at line 0 then nothing to do
return result;
result = blockFrame->QueryInterface(nsILineIterator::GetIID(),getter_AddRefs(it));
while (NS_FAILED(result) && blockFrame)
@ -1677,77 +1876,20 @@ nsFrame::PeekOffset(nsIFocusTracker *aTracker,
}
if (NS_FAILED(result) || !it || !blockFrame)
return result;
nsIFrame *resultFrame = nsnull;
PRInt32 thisLine = 0;
result = it->FindLineContaining(thisBlock, &thisLine);
if (NS_FAILED(result)) //if at line 0 then nothing to do
if (NS_FAILED(result))
return result;
PRInt32 searchingLine = thisLine;
PRBool isBeforeFirstFrame, isAfterLastFrame;
result = GetNextPrevLineFromeBlockFrame(aTracker,
aDirection,
blockFrame,
thisLine,
aDesiredX,
aResultContent,
aContentOffset,
0 //start from thisLine
);
thisBlock = blockFrame;
PRBool found = PR_FALSE;
while (!found)
{
if (aDirection == eDirPrevious)
searchingLine --;
else
searchingLine ++;
result = it->FindFrameAt(searchingLine, coord, &resultFrame, &isBeforeFirstFrame, &isAfterLastFrame);
if (NS_SUCCEEDED(result) && resultFrame)
{
nsIFrame *child;
PRBool exhaustedAllSiblings = PR_FALSE;
while ( !found && !exhaustedAllSiblings)
{
while (NS_SUCCEEDED(resultFrame->FirstChild(nsnull, &child)) && child){
resultFrame = child;
if (aDirection == eDirPrevious) //go to last child now.
{
while (NS_SUCCEEDED(result) && child)
{
resultFrame = child;
result = resultFrame->GetNextSibling(&child);
}
}
}
if (!resultFrame)
return NS_ERROR_FAILURE;
//now we need to get the local frame coordinates
coord = PR_MAX(0, coord);
nsCOMPtr<nsIPresContext> context;
result = aTracker->GetPresContext(getter_AddRefs(context));
result = resultFrame->GetPosition(*(context.get()),coord,
aResultContent,*aContentOffset, *aContentOffset);
//if (isAfterLastFrame) //get previous frame.
if (NS_SUCCEEDED(result))
found = PR_TRUE;
else{
if (aDirection == eDirNext)
#if 0
{
result = resultFrame->GetPrevSibling(&child);
}
else
#endif
result = resultFrame->GetNextSibling(&child);
if (NS_FAILED(result) || !child)
exhaustedAllSiblings = PR_TRUE;
else
resultFrame = child;
}
}
}
else {
//we need to jump to new block frame.
if (aDirection == eDirNext)
return blockFrame->PeekOffset(aTracker, aDesiredX, aAmount, aDirection, 0, aResultContent,
aContentOffset, aEatingWS);
else
return blockFrame->PeekOffset(aTracker, aDesiredX, aAmount, aDirection, -1, aResultContent,
aContentOffset, aEatingWS);
}
}
break;
}
@ -1784,7 +1926,7 @@ nsFrame::PeekOffset(nsIFocusTracker *aTracker,
aContentOffset, aEatingWS);
}
}
return NS_OK;
return result;
}
//-----------------------------------------------------------------------------------
@ -1878,7 +2020,42 @@ void ForceDrawFrame(nsFrame * aFrame)//, PRBool)
}
void
GetLastLeaf(nsIFrame **aFrame)
{
if (!aFrame || !*aFrame)
return;
nsIFrame *child = *aFrame;
nsresult result;
nsIFrame *lookahead = nsnull;
while (1){
result = child->FirstChild(nsnull, &lookahead);
if (NS_FAILED(result) || !lookahead)
return;//nothing to do
child = lookahead;
while (NS_SUCCEEDED(child->GetNextSibling(&lookahead)) && lookahead)
child = lookahead;
*aFrame = child;
}
*aFrame = child;
}
void
GetFirstLeaf(nsIFrame **aFrame)
{
if (!aFrame || !*aFrame)
return;
nsIFrame *child = *aFrame;
nsresult result;
nsIFrame *lookahead = nsnull;
while (1){
result = child->FirstChild(nsnull, &lookahead);
if (NS_FAILED(result) || !lookahead)
return;//nothing to do
child = lookahead;
*aFrame = child;
}
}
#ifdef NS_DEBUG
static void

Просмотреть файл

@ -174,6 +174,16 @@ public:
PRInt32* outFrameContentOffset,
nsIFrame* *outChildFrame);
NS_IMETHOD GetNextPrevLineFromeBlockFrame(nsIFocusTracker *aTracker,
nsDirection aDirection,
nsIFrame *aBlockFrame,
PRInt32 aLineStart,
nscoord aDesiredX,
nsIContent **aResultContent,
PRInt32 *aContentOffset,
PRInt8 aOutSideLimit
);
NS_IMETHOD GetFrameState(nsFrameState* aResult);
NS_IMETHOD SetFrameState(nsFrameState aNewState);

Просмотреть файл

@ -367,7 +367,12 @@ public:
void PaintTextDecorations(nsIRenderingContext& aRenderingContext,
nsIStyleContext* aStyleContext,
TextStyle& aStyle,
nscoord aX, nscoord aY, nscoord aWidth);
nscoord aX, nscoord aY, nscoord aWidth,
PRUnichar* aText = nsnull,
SelectionDetails *aDetails = nsnull,
PRUint32 aIndex = 0,
PRUint32 aLength = 0,
const nscoord* aSpacing = nsnull);
void PaintTextSlowly(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
@ -380,7 +385,8 @@ public:
TextStyle& aStyle,
PRUnichar* aBuffer, PRInt32 aLength,
nscoord aX, nscoord aY,
nscoord aWidth);
nscoord aWidth,
SelectionDetails *aDetails = nsnull);
void MeasureSmallCapsText(const nsHTMLReflowState& aReflowState,
TextStyle& aStyle,
@ -756,7 +762,13 @@ void
nsTextFrame::PaintTextDecorations(nsIRenderingContext& aRenderingContext,
nsIStyleContext* aStyleContext,
TextStyle& aTextStyle,
nscoord aX, nscoord aY, nscoord aWidth)
nscoord aX, nscoord aY, nscoord aWidth,
PRUnichar *aText, /*=nsnull*/
SelectionDetails *aDetails,/*= nsnull*/
PRUint32 aIndex, /*= 0*/
PRUint32 aLength, /*= 0*/
const nscoord* aSpacing /* = nsnull*/ )
{
nscolor overColor;
nscolor underColor;
@ -813,6 +825,70 @@ nsTextFrame::PaintTextDecorations(nsIRenderingContext& aRenderingContext,
aRenderingContext.SetColor(strikeColor);
aRenderingContext.FillRect(aX, aY + baseline - offset, aWidth, size);
}
if (aDetails){
nsRect rect;
GetRect(rect);
PRInt32 startOffset = 0;
PRInt32 textWidth = 0;
while(aDetails){
PRInt32 start = PR_MAX(0,(aDetails->mStart - (PRInt32)aIndex));
PRInt32 end = PR_MIN((PRInt32)aLength,(aDetails->mEnd - (PRInt32)aIndex));
PRInt32 i;
if (start < end && (aLength - start) > 0)
{
//aDetails allready processed to have offsets from frame start not content offsets
if (start < end){
if (aLength == 1)
textWidth = aWidth;
else {
if (aDetails->mStart > 0){
if (aSpacing)
{
for (i = 0; i < start;i ++){
startOffset += *aSpacing ++;
}
}
else
aRenderingContext.GetWidth(aText, start, startOffset);
}
if (aSpacing){
for (i = start; i < end;i ++){
textWidth += *aSpacing ++;
}
}
else
aRenderingContext.GetWidth(aText + start,
PRUint32(end - start), textWidth);
}
switch (aDetails->mType)
{
case SELECTION_NORMAL:{
aRenderingContext.SetColor(NS_RGB(0,0,0));
aRenderingContext.DrawRect(aX + startOffset, aY, textWidth, rect.height);
}break;
case SELECTION_SPELLCHECK:{
aTextStyle.mNormalFont->GetUnderline(offset, size);
aRenderingContext.SetColor(NS_RGB(255,0,0));
aRenderingContext.FillRect(aX, aY + baseline - offset, aWidth, size);
}break;
case SELECTION_IME_SOLID:{
aTextStyle.mNormalFont->GetUnderline(offset, size);
aRenderingContext.SetColor(NS_RGB(0,0,255));
aRenderingContext.FillRect(aX, aY + baseline - offset, aWidth, size);
}break;
case SELECTION_IME_DASHED:{
aTextStyle.mNormalFont->GetUnderline(offset, size);
aRenderingContext.SetColor(NS_RGB(128,0,255));
aRenderingContext.FillRect(aX, aY + baseline - offset, aWidth, size);
}break;
}
}
}
aDetails = aDetails->mNext;
}
}
}
void
@ -869,10 +945,7 @@ nsTextFrame::PaintUnicodeText(nsIPresContext* aPresContext,
//must set up last one for selection beyond edge if in boundary
ip[mContentLength]++;
}
PRInt32 textWidth;
PRInt32 selectionStartOffset = 0;//frame coordinates
PRInt32 selectionEndOffset = 0;//frame coordinates
SelectionDetails *details = nsnull;
nsCOMPtr<nsIPresShell> shell;
nsCOMPtr<nsIDOMSelection> selection;
nsCOMPtr<nsIFrameSelection> frameSelection;
@ -887,82 +960,34 @@ nsTextFrame::PaintUnicodeText(nsIPresContext* aPresContext,
rv = GetContent(getter_AddRefs(content));
if (NS_SUCCEEDED(rv)){
rv = frameSelection->LookUpSelection(content, mContentOffset,
mContentLength , &selectionStartOffset, &selectionEndOffset,
&drawSelected,0);// last param notused
mContentLength , &details);// last param notused
}
}
}
if (frameSelection ){
//where are the selection points "really"
if (drawSelected){
selectionStartOffset = ip[selectionStartOffset] - mContentOffset;
selectionEndOffset = ip[selectionEndOffset] - mContentOffset;
SelectionDetails *sdptr = details;
while (sdptr){
sdptr->mStart = ip[sdptr->mStart] - mContentOffset;
sdptr->mEnd = ip[sdptr->mEnd] - mContentOffset;
sdptr = sdptr->mNext;
}
if (!drawSelected || (selectionStartOffset == selectionEndOffset)) {
aRenderingContext.SetColor(aTextStyle.mColor->mColor);
aRenderingContext.DrawString(text, PRUint32(textLength), dx, dy);
PaintTextDecorations(aRenderingContext, aStyleContext,
aTextStyle, dx, dy, width);
#ifdef SHOW_SELECTION_CURSOR
aRenderingContext.GetWidth(text, PRUint32(selectionStartOffset), textWidth);
aTextStyle, dx, dy, width, text, details,0,(PRUint32)textLength);
sdptr = details;
if (details){
while(sdptr = details->mNext){
delete details;
details = sdptr;
}
delete details;
}
}
}
RenderSelectionCursor(aRenderingContext,
dx + textWidth, dy, mRect.height,
CURSOR_COLOR);
#endif
}
else {
nscoord x = dx;
if (selectionStartOffset) {
// Render first (unselected) section
aRenderingContext.GetWidth(text, PRUint32(selectionStartOffset),//si.mStartOffset),
textWidth);
aRenderingContext.SetColor(aTextStyle.mColor->mColor);
aRenderingContext.DrawString(text, PRUint32(selectionStartOffset),
x, dy);
PaintTextDecorations(aRenderingContext, aStyleContext, aTextStyle,
x, dy, textWidth);
x += textWidth;
}
PRInt32 secondLen = selectionEndOffset - selectionStartOffset;
if (0 != secondLen) {
// Get the width of the second (selected) section
aRenderingContext.GetWidth(text + selectionStartOffset,
PRUint32(secondLen), textWidth);
// Render second (selected) section
aRenderingContext.SetColor(aTextStyle.mSelectionBGColor);
aRenderingContext.FillRect(x, dy, textWidth, mRect.height);
aRenderingContext.SetColor(aTextStyle.mSelectionTextColor);
aRenderingContext.DrawString(text + selectionStartOffset,
PRUint32(secondLen), x, dy);
PaintTextDecorations(aRenderingContext, aStyleContext, aTextStyle,
x, dy, textWidth);
x += textWidth;
}
if (textLength != selectionEndOffset) {
PRInt32 thirdLen = textLength - selectionEndOffset;
if (thirdLen > 0) //Text length is not negative or zero
{
// Render third (unselected) section
aRenderingContext.GetWidth(text + selectionEndOffset, PRUint32(thirdLen),
textWidth);
aRenderingContext.SetColor(aTextStyle.mColor->mColor);
aRenderingContext.DrawString(text + selectionEndOffset,
PRUint32(thirdLen), x, dy);
PaintTextDecorations(aRenderingContext, aStyleContext, aTextStyle,
x, dy, textWidth);
}
}
}
}
}
}
// Cleanup
if (paintBuf != paintBufMem) {
delete [] paintBuf;
@ -1106,7 +1131,8 @@ nsTextFrame::RenderString(nsIRenderingContext& aRenderingContext,
TextStyle& aTextStyle,
PRUnichar* aBuffer, PRInt32 aLength,
nscoord aX, nscoord aY,
nscoord aWidth)
nscoord aWidth,
SelectionDetails *aDetails /*=nsnull*/)
{
PRUnichar buf[TEXT_BUF_SIZE];
PRUnichar* bp0 = buf;
@ -1142,6 +1168,7 @@ nsTextFrame::RenderString(nsIRenderingContext& aRenderingContext,
PRInt32 pendingCount;
PRUnichar* runStart = bp;
nscoord charWidth, width = 0;
PRInt32 countSoFar = 0;
for (; --aLength >= 0; aBuffer++) {
nsIFontMetrics* nextFont;
nscoord nextY, glyphWidth;
@ -1195,8 +1222,8 @@ nsTextFrame::RenderString(nsIRenderingContext& aRenderingContext,
// Note: use aY not small-y so that decorations are drawn with
// respect to the normal-font not the current font.
PaintTextDecorations(aRenderingContext, aStyleContext, aTextStyle,
aX, aY, width);
aX, aY, width, runStart, aDetails,countSoFar,pendingCount, spacing ? sp0 : nsnull);
countSoFar += pendingCount;
aWidth -= width;
aX += width;
runStart = bp = bp0;
@ -1221,7 +1248,8 @@ nsTextFrame::RenderString(nsIRenderingContext& aRenderingContext,
// Note: use aY not small-y so that decorations are drawn with
// respect to the normal-font not the current font.
PaintTextDecorations(aRenderingContext, aStyleContext, aTextStyle,
aX, aY, aWidth);
aX, aY, aWidth, runStart, aDetails,countSoFar,pendingCount,
spacing ? sp0 : nsnull);
}
aTextStyle.mLastFont = lastFont;
@ -1368,6 +1396,7 @@ nsTextFrame::PaintTextSlowly(nsIPresContext* aPresContext,
text, textLength, dx, dy, width);
}
else {
SelectionDetails *details = nsnull;
ip[mContentLength] = ip[mContentLength-1];
if ((ip[mContentLength]-mContentOffset) < textLength) {
//must set up last one for selection beyond edge if in boundary
@ -1375,7 +1404,6 @@ nsTextFrame::PaintTextSlowly(nsIPresContext* aPresContext,
}
PRInt32 selectionStartOffset = 0;//frame coordinates
PRInt32 selectionEndOffset = 0;//frame coordinates
PRInt32 textWidth;
nsCOMPtr<nsIPresShell> shell;
nsCOMPtr<nsIDOMSelection> selection;
nsCOMPtr<nsIFrameSelection> frameSelection;
@ -1389,76 +1417,28 @@ nsTextFrame::PaintTextSlowly(nsIPresContext* aPresContext,
rv = GetContent(getter_AddRefs(content));
if (NS_SUCCEEDED(rv)){
rv = frameSelection->LookUpSelection(content, mContentOffset,
mContentLength , &selectionStartOffset, &selectionEndOffset,
&drawSelected, 0);// last param notused
mContentLength , &details);// last param notused
}
}
}
if (frameSelection){
//where are the selection points "really"
if (drawSelected) {
selectionStartOffset = ip[selectionStartOffset] - mContentOffset;
selectionEndOffset = ip[selectionEndOffset] - mContentOffset;
SelectionDetails *sdptr = details;
while (sdptr){
sdptr->mStart = ip[sdptr->mStart] - mContentOffset;
sdptr->mEnd = ip[sdptr->mEnd] - mContentOffset;
sdptr = sdptr->mNext;
}
if (!drawSelected || (selectionStartOffset == selectionEndOffset)){
RenderString(aRenderingContext, aStyleContext, aTextStyle,
text, textLength, dx, dy, width);
#ifdef SHOW_SELECTION_CURSOR
GetWidth(aRenderingContext, aTextStyle,
text, PRUint32(selectionStartOffset), &textWidth);
RenderSelectionCursor(aRenderingContext,
dx + textWidth, dy, mRect.height,
CURSOR_COLOR);
#endif
}
else {
nscoord x = dx;
if (selectionStartOffset) {
// Render first (unselected) section
GetWidth(aRenderingContext, aTextStyle,
text, PRUint32(selectionStartOffset),
&textWidth);
RenderString(aRenderingContext, aStyleContext, aTextStyle,
text, selectionStartOffset,
x, dy, textWidth);
x += textWidth;
}
PRInt32 secondLen = selectionEndOffset - selectionStartOffset;
if (0 != secondLen) {
// Get the width of the second (selected) section
GetWidth(aRenderingContext, aTextStyle,
text + selectionStartOffset,
PRUint32(secondLen), &textWidth);
// Render second (selected) section
aRenderingContext.SetColor(aTextStyle.mSelectionBGColor);
aRenderingContext.FillRect(x, dy, textWidth, mRect.height);
aRenderingContext.SetColor(aTextStyle.mSelectionTextColor);
RenderString(aRenderingContext, aStyleContext, aTextStyle,
text + selectionStartOffset, secondLen,
x, dy, textWidth);
aRenderingContext.SetColor(aTextStyle.mColor->mColor);
x += textWidth;
}
if (textLength != selectionEndOffset) {
PRInt32 thirdLen = textLength - selectionEndOffset;
// Render third (unselected) section
if (thirdLen > 0) //Text length is not negative or zero
{
GetWidth(aRenderingContext, aTextStyle,
text + selectionStartOffset, PRUint32(thirdLen),
&textWidth);
RenderString(aRenderingContext, aStyleContext, aTextStyle,
text + selectionEndOffset,
thirdLen, x, dy, textWidth);
}
}
RenderString(aRenderingContext,aStyleContext, aTextStyle, text,
PRUint32(textLength), dx, dy, width, details);
sdptr = details;
if (details){
while(sdptr = details->mNext){
delete details;
details = sdptr;
}
delete details;
}
}
}
@ -1532,6 +1512,7 @@ nsTextFrame::PaintAsciiText(nsIPresContext* aPresContext,
dx, dy, width);
}
else {
SelectionDetails *details;
ip[mContentLength] = ip[mContentLength-1];
if ((ip[mContentLength]-mContentOffset) < textLength) {
//must set up last one for selection beyond edge if in boundary
@ -1539,7 +1520,6 @@ nsTextFrame::PaintAsciiText(nsIPresContext* aPresContext,
}
PRInt32 selectionStartOffset = 0;//frame coordinates
PRInt32 selectionEndOffset = 0;//frame coordinates
PRInt32 textWidth;
nsCOMPtr<nsIPresShell> shell;
nsCOMPtr<nsIDOMSelection> selection;
nsCOMPtr<nsIFrameSelection> frameSelection;
@ -1553,81 +1533,30 @@ nsTextFrame::PaintAsciiText(nsIPresContext* aPresContext,
rv = GetContent(getter_AddRefs(content));
if (NS_SUCCEEDED(rv)){
rv = frameSelection->LookUpSelection(content, mContentOffset,
mContentLength , &selectionStartOffset, &selectionEndOffset,
&drawSelected, 0);// last param notused
mContentLength , &details);// last param notused
}
}
}
if (frameSelection){
//where are the selection points "really"
if (drawSelected) {
selectionStartOffset = ip[selectionStartOffset] - mContentOffset;
selectionEndOffset = ip[selectionEndOffset] - mContentOffset;
SelectionDetails *sdptr = details;
while (sdptr){
sdptr->mStart = ip[sdptr->mStart] - mContentOffset;
sdptr->mEnd = ip[sdptr->mEnd] - mContentOffset;
sdptr = sdptr->mNext;
}
if (!drawSelected || (selectionStartOffset == selectionEndOffset)){
aRenderingContext.SetColor(aTextStyle.mColor->mColor);
aRenderingContext.DrawString(text, PRUint32(textLength), dx, dy);
PaintTextDecorations(aRenderingContext, aStyleContext,
aTextStyle, dx, dy, width);
//shell->RefreshCaret();
#ifdef SHOW_SELECTION_CURSOR
aRenderingContext.GetWidth(text, PRUint32(selectionStartOffset), textWidth);
RenderSelectionCursor(aRenderingContext,
dx + textWidth, dy, mRect.height,
CURSOR_COLOR);
#endif
}
else {
nscoord x = dx;
if (selectionStartOffset) {
// Render first (unselected) section
aRenderingContext.GetWidth(text, PRUint32(selectionStartOffset),//si.mStartOffset),
textWidth);
aRenderingContext.SetColor(aTextStyle.mColor->mColor);
aRenderingContext.DrawString(text, PRUint32(selectionStartOffset),
x, dy);
PaintTextDecorations(aRenderingContext, aStyleContext, aTextStyle,
x, dy, textWidth);
x += textWidth;
}
PRInt32 secondLen = selectionEndOffset - selectionStartOffset;
if (0 != secondLen) {
// Get the width of the second (selected) section
aRenderingContext.GetWidth(text + selectionStartOffset,
PRUint32(secondLen), textWidth);
// Render second (selected) section
aRenderingContext.SetColor(aTextStyle.mSelectionBGColor);
aRenderingContext.FillRect(x, dy, textWidth, mRect.height);
aRenderingContext.SetColor(aTextStyle.mSelectionTextColor);
aRenderingContext.DrawString(text + selectionStartOffset,
PRUint32(secondLen), x, dy);
PaintTextDecorations(aRenderingContext, aStyleContext, aTextStyle,
x, dy, textWidth);
x += textWidth;
}
if (textLength != selectionEndOffset) {
PRInt32 thirdLen = textLength - selectionEndOffset;
if (thirdLen > 0) //Text length is not negative or zero
{
// Render third (unselected) section
aRenderingContext.GetWidth(text + selectionEndOffset, PRUint32(thirdLen),
textWidth);
aRenderingContext.SetColor(aTextStyle.mColor->mColor);
aRenderingContext.DrawString(text + selectionEndOffset,
PRUint32(thirdLen), x, dy);
PaintTextDecorations(aRenderingContext, aStyleContext, aTextStyle,
x, dy, textWidth);
}
}
aTextStyle, dx, dy, width, (PRUnichar *)text, details,0,textLength);
sdptr = details;
if (details){
while(sdptr = details->mNext){
delete details;
details = sdptr;
}
delete details;
}
}
}
@ -1999,7 +1928,7 @@ nsTextFrame::GetChildFrameContainingOffset(PRInt32 inContentOffset,
{
if (nsnull == outChildFrame)
return NS_ERROR_NULL_POINTER;
nsresult result;
PRInt32 contentOffset = inContentOffset;
if (contentOffset != -1) //-1 signified the end of the current content
@ -2015,6 +1944,15 @@ nsTextFrame::GetChildFrameContainingOffset(PRInt32 inContentOffset,
else
return NS_ERROR_FAILURE;
}
else if (inContentOffset < mContentOffset) //could happen with floaters!
{
result = GetPrevInFlow(outChildFrame);
if (NS_SUCCEEDED(result))
return (*outChildFrame)->GetChildFrameContainingOffset(inContentOffset,
outFrameContentOffset,outChildFrame);
else
return result;
}
*outFrameContentOffset = contentOffset;
*outChildFrame = this;
@ -2033,7 +1971,7 @@ nsTextFrame::PeekOffset(nsIFocusTracker *aTracker,
PRBool aEatingWS)
{
if (!aResultContent || !aContentOffset)
if (!aResultContent || !aContentOffset || !mContent)
return NS_ERROR_NULL_POINTER;
if (aStartOffset < 0)
aStartOffset = mContentLength + mContentOffset;
@ -2065,9 +2003,11 @@ nsTextFrame::PeekOffset(nsIFocusTracker *aTracker,
PRInt32 textLength;
// Transform text from content into renderable form
nsresult result(NS_OK);
nsIDocument* doc;
mContent->GetDocument(doc);
result = mContent->GetDocument(doc);
if (NS_FAILED(result) || !doc)
return result;
nsCOMPtr<nsILineBreaker> lb;
doc->GetLineBreaker(getter_AddRefs(lb));
nsCOMPtr<nsIWordBreaker> wb;
@ -2075,7 +2015,6 @@ nsTextFrame::PeekOffset(nsIFocusTracker *aTracker,
NS_RELEASE(doc);
nsTextTransformer tx(wordBufMem, WORD_BUF_SIZE,lb,wb);
nsresult result(NS_OK);
switch (aAmount){
case eSelectNoAmount : {
@ -2316,10 +2255,10 @@ nsTextFrame::HandleMultiplePress(nsIPresContext& aPresContext,
nsCOMPtr<nsIDOMSelection> selection;
if (NS_SUCCEEDED(shell->GetSelection(getter_AddRefs(selection)))){
rv = selection->Collapse(startNode,startOffset);
rv = selection->Collapse(startNode,startOffset, SELECTION_NORMAL);
if (NS_FAILED(rv))
return rv;
rv = selection->Extend(endNode,endOffset);
rv = selection->Extend(endNode,endOffset, SELECTION_NORMAL);
if (NS_FAILED(rv))
return rv;
}

Просмотреть файл

@ -91,6 +91,9 @@ PRInt32 fTrackerAddListMax = 0;
#include "nsILineIterator.h"
// [HACK] Foward Declarations
void ForceDrawFrame(nsFrame * aFrame);
//non Hack prototypes
static void GetLastLeaf(nsIFrame **aFrame);
static void GetFirstLeaf(nsIFrame **aFrame);
#if 0
static void RefreshContentFrames(nsIPresContext& aPresContext, nsIContent * aStartContent, nsIContent * aEndContent);
#endif
@ -704,7 +707,6 @@ nsFrame::Paint(nsIPresContext& aPresContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)
{
PRBool drawSelected(PR_FALSE);
//if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) {
/** GetDocument
*/
@ -746,10 +748,11 @@ nsFrame::Paint(nsIPresContext& aPresContext,
nsCOMPtr<nsIContent> newContent;
result = mContent->GetParent(*getter_AddRefs(newContent));
SelectionDetails *details;
PRInt32 offset;
PRInt32 offsetEnd;
if (NS_SUCCEEDED(result) && newContent){
result = newContent->IndexOf(mContent, offset);
nsresult result = newContent->IndexOf(mContent, offset);
if (NS_FAILED(result))
{
return result;
@ -764,13 +767,12 @@ nsFrame::Paint(nsIPresContext& aPresContext,
result = GetContent(getter_AddRefs(content));
if (NS_SUCCEEDED(result)){
result = frameSelection->LookUpSelection(newContent, offset,
1, &offset, &offsetEnd,
&drawSelected,0);// last param notused
1, &details);// last param notused
}
}
}
//}
if (drawSelected)
if (details)
{
nsRect rect;
GetRect(rect);
@ -781,6 +783,12 @@ nsFrame::Paint(nsIPresContext& aPresContext,
aRenderingContext.SetColor(NS_RGB(0,0,255));
nsRect drawrect(1, 1, rect.width, rect.height);
aRenderingContext.DrawRect(drawrect );
SelectionDetails *deletingDetails = details;
while(deletingDetails = details->mNext){
delete details;
details = deletingDetails;
}
delete details;
//aRenderingContext.DrawLine(rect.x, rect.y, rect.XMost(), rect.YMost());
//aRenderingContext.DrawLine(rect.x, rect.YMost(), rect.XMost(), rect.y);
}
@ -902,7 +910,7 @@ nsFrame::HandlePress(nsIPresContext& aPresContext,
if (frameselection) {
if (NS_SUCCEEDED( rv )){
frameselection->SetMouseDownState(PR_TRUE);//not important if it fails here
frameselection->TakeFocus(newContent, startPos , contentOffsetEnd , inputEvent->isShift);
frameselection->TakeFocus(newContent, startPos , contentOffsetEnd , inputEvent->isShift, inputEvent->isControl);
}
}
}
@ -945,7 +953,7 @@ NS_IMETHODIMP nsFrame::HandleDrag(nsIPresContext& aPresContext,
nsIFrameSelection* frameselection;
if (NS_SUCCEEDED(selection->QueryInterface(kIFrameSelection, (void **)&frameselection))) {
if (NS_SUCCEEDED( rv )){
frameselection->TakeFocus(newContent, startPos, contentOffsetEnd , PR_TRUE); //TRUE IS THE DIFFERENCE
frameselection->TakeFocus(newContent, startPos, contentOffsetEnd , PR_TRUE, PR_FALSE); //TRUE IS THE DIFFERENCE for continue selection
}
NS_RELEASE(frameselection);
}
@ -990,7 +998,7 @@ NS_IMETHODIMP nsFrame::GetPosition(nsIPresContext& aCX,
}
aContentOffsetEnd = aContentOffset +1;
}
return NS_OK;
return result;
}
@ -1640,6 +1648,194 @@ nsFrame::GetChildFrameContainingOffset(PRInt32 inContentOffset, PRInt32* outFram
return NS_OK;
}
NS_IMETHODIMP
nsFrame::GetNextPrevLineFromeBlockFrame(nsIFocusTracker *aTracker,
nsDirection aDirection,
nsIFrame *aBlockFrame,
PRInt32 aLineStart,
nscoord aDesiredX,
nsIContent **aResultContent,
PRInt32 *aContentOffset,
PRInt8 aOutSideLimit
)
{
//magic numbers aLineStart will be -1 for end of block 0 will be start of block
if (!aBlockFrame)
return NS_ERROR_NULL_POINTER;
PRInt32 thisLine = 0;
nsresult result;
nsCOMPtr<nsILineIterator> it;
result = aBlockFrame->QueryInterface(nsILineIterator::GetIID(),getter_AddRefs(it));
if (NS_FAILED(result) || !it)
return result;
PRInt32 searchingLine = aLineStart;
PRInt32 countLines;
result = it->GetNumLines(&countLines);
if (aOutSideLimit > 0) //start at end
searchingLine = countLines;
else if (aOutSideLimit <0)//start at begining
searchingLine = -1;//"next" will be 0
else
if ((aDirection == eDirPrevious && aLineStart == 0) ||
(aDirection == eDirNext && aLineStart >= (countLines -1) )){
//we need to jump to new block frame.
return NS_ERROR_FAILURE;
/* if (aDirection == eDirNext)
return aBlockFrame->PeekOffset(aTracker, aDesiredX, eSelectLine, aDirection, 0, aResultContent,
aContentOffset, PR_FALSE);
else
return aBlockFrame->PeekOffset(aTracker, aDesiredX, eSelectLine, aDirection, -1, aResultContent,
aContentOffset, PR_FALSE);*/
}
PRInt32 lineFrameCount;
nsIFrame *resultFrame = nsnull;
nsIFrame *farStoppingFrame = nsnull; //we keep searching until we find a "this" frame then we go to next line
nsIFrame *nearStoppingFrame = nsnull; //if we are backing up from edge, stop here
nsIFrame *firstFrame;
nsIFrame *lastFrame;
nsRect nonUsedRect;
PRBool isBeforeFirstFrame, isAfterLastFrame;
PRBool found = PR_FALSE;
while (!found)
{
if (aDirection == eDirPrevious)
searchingLine --;
else
searchingLine ++;
result = it->GetLine(searchingLine, &firstFrame, &lineFrameCount,nonUsedRect);
if (NS_SUCCEEDED(result)){
lastFrame = firstFrame;
for (;lineFrameCount > 1;lineFrameCount --){
result = lastFrame->GetNextSibling(&lastFrame);
if (NS_FAILED(result)){
NS_ASSERTION(0,"should not be reached nsFrame\n");
continue;
}
}
GetLastLeaf(&lastFrame);
if (aDirection == eDirNext){
nearStoppingFrame = firstFrame;
farStoppingFrame = lastFrame;
}
else{
nearStoppingFrame = lastFrame;
farStoppingFrame = firstFrame;
}
result = it->FindFrameAt(searchingLine, aDesiredX, &resultFrame, &isBeforeFirstFrame, &isAfterLastFrame);
}
if (NS_SUCCEEDED(result) && resultFrame)
{
nsCOMPtr<nsILineIterator> newIt;
//check to see if this is ANOTHER blockframe inside the other one if so then call into its lines
result = resultFrame->QueryInterface(nsILineIterator::GetIID(),getter_AddRefs(newIt));
if (NS_SUCCEEDED(result) && newIt)
{
if (aDirection == eDirPrevious){
if (NS_SUCCEEDED(GetNextPrevLineFromeBlockFrame(aTracker,
aDirection,
resultFrame,
0,
aDesiredX,
aResultContent,
aContentOffset,
1//start from end
)))
return NS_OK;
}
else {
if (NS_SUCCEEDED(GetNextPrevLineFromeBlockFrame(aTracker,
aDirection,
resultFrame,
0,
aDesiredX,
aResultContent,
aContentOffset,
-1//start from beginning
)))
return NS_OK;
}
}
//resultFrame is not a block frame
nsCOMPtr<nsIBidirectionalEnumerator> frameTraversal;
result = NS_NewFrameTraversal(getter_AddRefs(frameTraversal),LEAF,resultFrame);
if (NS_FAILED(result))
return result;
nsISupports *isupports = nsnull;
nsIFrame *storeOldResultFrame = resultFrame;
while ( !found ){
nsCOMPtr<nsIPresContext> context;
result = aTracker->GetPresContext(getter_AddRefs(context));
result = resultFrame->GetPosition(*(context.get()),aDesiredX,
aResultContent,*aContentOffset, *aContentOffset);
PRBool breakOut = PR_FALSE;
if (NS_SUCCEEDED(result))
found = PR_TRUE;
else {
if (aDirection == eDirPrevious && (resultFrame == farStoppingFrame))
break;
if (aDirection == eDirNext && (resultFrame == nearStoppingFrame))
break;
//always try previous on THAT line if that fails go the other way
result = frameTraversal->Prev();
if (NS_FAILED(result))
break;
result = frameTraversal->CurrentItem(&isupports);
if (NS_FAILED(result) || !isupports)
return result;
//we must CAST here to an nsIFrame. nsIFrame doesnt really follow the rules
resultFrame = (nsIFrame *)isupports;
}
}
if (!found){
resultFrame = storeOldResultFrame;
result = NS_NewFrameTraversal(getter_AddRefs(frameTraversal),LEAF,resultFrame);
}
while ( !found ){
nsCOMPtr<nsIPresContext> context;
result = aTracker->GetPresContext(getter_AddRefs(context));
result = resultFrame->GetPosition(*(context.get()),aDesiredX,
aResultContent,*aContentOffset, *aContentOffset);
PRBool breakOut = PR_FALSE;
if (NS_SUCCEEDED(result))
found = PR_TRUE;
else {
if (aDirection == eDirPrevious && (resultFrame == nearStoppingFrame))
break;
if (aDirection == eDirNext && (resultFrame == farStoppingFrame))
break;
//previous didnt work now we try "next"
result = frameTraversal->Next();
if (NS_FAILED(result))
break;
result = frameTraversal->CurrentItem(&isupports);
if (NS_FAILED(result) || !isupports)
return result;
//we must CAST here to an nsIFrame. nsIFrame doesnt really follow the rules
resultFrame = (nsIFrame *)isupports;
}
}
}
else {
//we need to jump to new block frame.
if (aDirection == eDirNext)
return aBlockFrame->PeekOffset(aTracker, aDesiredX, eSelectLine, aDirection, 0, aResultContent,
aContentOffset, PR_FALSE);
else
return aBlockFrame->PeekOffset(aTracker, aDesiredX, eSelectLine, aDirection, -1, aResultContent,
aContentOffset, PR_FALSE);
}
}
return NS_OK;
}
NS_IMETHODIMP
nsFrame::PeekOffset(nsIFocusTracker *aTracker,
nscoord aDesiredX,
@ -1652,7 +1848,7 @@ nsFrame::PeekOffset(nsIFocusTracker *aTracker,
{
if (!aResultContent || !aContentOffset ||!aTracker)
return NS_ERROR_NULL_POINTER;
nsresult result;
nsresult result = NS_ERROR_FAILURE;
switch (aAmount){
case eSelectLine :
{
@ -1663,8 +1859,11 @@ nsFrame::PeekOffset(nsIFocusTracker *aTracker,
nsCOMPtr<nsILineIterator> it;
nsIFrame *blockFrame = this;
nsIFrame *thisBlock = this;
PRInt32 thisLine;
while (NS_FAILED(result)){
result = blockFrame->GetParent(&blockFrame);
if (NS_FAILED(result)) //if at line 0 then nothing to do
if (NS_FAILED(result) || !blockFrame) //if at line 0 then nothing to do
return result;
result = blockFrame->QueryInterface(nsILineIterator::GetIID(),getter_AddRefs(it));
while (NS_FAILED(result) && blockFrame)
@ -1677,77 +1876,20 @@ nsFrame::PeekOffset(nsIFocusTracker *aTracker,
}
if (NS_FAILED(result) || !it || !blockFrame)
return result;
nsIFrame *resultFrame = nsnull;
PRInt32 thisLine = 0;
result = it->FindLineContaining(thisBlock, &thisLine);
if (NS_FAILED(result)) //if at line 0 then nothing to do
if (NS_FAILED(result))
return result;
PRInt32 searchingLine = thisLine;
PRBool isBeforeFirstFrame, isAfterLastFrame;
result = GetNextPrevLineFromeBlockFrame(aTracker,
aDirection,
blockFrame,
thisLine,
aDesiredX,
aResultContent,
aContentOffset,
0 //start from thisLine
);
thisBlock = blockFrame;
PRBool found = PR_FALSE;
while (!found)
{
if (aDirection == eDirPrevious)
searchingLine --;
else
searchingLine ++;
result = it->FindFrameAt(searchingLine, coord, &resultFrame, &isBeforeFirstFrame, &isAfterLastFrame);
if (NS_SUCCEEDED(result) && resultFrame)
{
nsIFrame *child;
PRBool exhaustedAllSiblings = PR_FALSE;
while ( !found && !exhaustedAllSiblings)
{
while (NS_SUCCEEDED(resultFrame->FirstChild(nsnull, &child)) && child){
resultFrame = child;
if (aDirection == eDirPrevious) //go to last child now.
{
while (NS_SUCCEEDED(result) && child)
{
resultFrame = child;
result = resultFrame->GetNextSibling(&child);
}
}
}
if (!resultFrame)
return NS_ERROR_FAILURE;
//now we need to get the local frame coordinates
coord = PR_MAX(0, coord);
nsCOMPtr<nsIPresContext> context;
result = aTracker->GetPresContext(getter_AddRefs(context));
result = resultFrame->GetPosition(*(context.get()),coord,
aResultContent,*aContentOffset, *aContentOffset);
//if (isAfterLastFrame) //get previous frame.
if (NS_SUCCEEDED(result))
found = PR_TRUE;
else{
if (aDirection == eDirNext)
#if 0
{
result = resultFrame->GetPrevSibling(&child);
}
else
#endif
result = resultFrame->GetNextSibling(&child);
if (NS_FAILED(result) || !child)
exhaustedAllSiblings = PR_TRUE;
else
resultFrame = child;
}
}
}
else {
//we need to jump to new block frame.
if (aDirection == eDirNext)
return blockFrame->PeekOffset(aTracker, aDesiredX, aAmount, aDirection, 0, aResultContent,
aContentOffset, aEatingWS);
else
return blockFrame->PeekOffset(aTracker, aDesiredX, aAmount, aDirection, -1, aResultContent,
aContentOffset, aEatingWS);
}
}
break;
}
@ -1784,7 +1926,7 @@ nsFrame::PeekOffset(nsIFocusTracker *aTracker,
aContentOffset, aEatingWS);
}
}
return NS_OK;
return result;
}
//-----------------------------------------------------------------------------------
@ -1878,7 +2020,42 @@ void ForceDrawFrame(nsFrame * aFrame)//, PRBool)
}
void
GetLastLeaf(nsIFrame **aFrame)
{
if (!aFrame || !*aFrame)
return;
nsIFrame *child = *aFrame;
nsresult result;
nsIFrame *lookahead = nsnull;
while (1){
result = child->FirstChild(nsnull, &lookahead);
if (NS_FAILED(result) || !lookahead)
return;//nothing to do
child = lookahead;
while (NS_SUCCEEDED(child->GetNextSibling(&lookahead)) && lookahead)
child = lookahead;
*aFrame = child;
}
*aFrame = child;
}
void
GetFirstLeaf(nsIFrame **aFrame)
{
if (!aFrame || !*aFrame)
return;
nsIFrame *child = *aFrame;
nsresult result;
nsIFrame *lookahead = nsnull;
while (1){
result = child->FirstChild(nsnull, &lookahead);
if (NS_FAILED(result) || !lookahead)
return;//nothing to do
child = lookahead;
*aFrame = child;
}
}
#ifdef NS_DEBUG
static void

Просмотреть файл

@ -174,6 +174,16 @@ public:
PRInt32* outFrameContentOffset,
nsIFrame* *outChildFrame);
NS_IMETHOD GetNextPrevLineFromeBlockFrame(nsIFocusTracker *aTracker,
nsDirection aDirection,
nsIFrame *aBlockFrame,
PRInt32 aLineStart,
nscoord aDesiredX,
nsIContent **aResultContent,
PRInt32 *aContentOffset,
PRInt8 aOutSideLimit
);
NS_IMETHOD GetFrameState(nsFrameState* aResult);
NS_IMETHOD SetFrameState(nsFrameState aNewState);

Просмотреть файл

@ -367,7 +367,12 @@ public:
void PaintTextDecorations(nsIRenderingContext& aRenderingContext,
nsIStyleContext* aStyleContext,
TextStyle& aStyle,
nscoord aX, nscoord aY, nscoord aWidth);
nscoord aX, nscoord aY, nscoord aWidth,
PRUnichar* aText = nsnull,
SelectionDetails *aDetails = nsnull,
PRUint32 aIndex = 0,
PRUint32 aLength = 0,
const nscoord* aSpacing = nsnull);
void PaintTextSlowly(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
@ -380,7 +385,8 @@ public:
TextStyle& aStyle,
PRUnichar* aBuffer, PRInt32 aLength,
nscoord aX, nscoord aY,
nscoord aWidth);
nscoord aWidth,
SelectionDetails *aDetails = nsnull);
void MeasureSmallCapsText(const nsHTMLReflowState& aReflowState,
TextStyle& aStyle,
@ -756,7 +762,13 @@ void
nsTextFrame::PaintTextDecorations(nsIRenderingContext& aRenderingContext,
nsIStyleContext* aStyleContext,
TextStyle& aTextStyle,
nscoord aX, nscoord aY, nscoord aWidth)
nscoord aX, nscoord aY, nscoord aWidth,
PRUnichar *aText, /*=nsnull*/
SelectionDetails *aDetails,/*= nsnull*/
PRUint32 aIndex, /*= 0*/
PRUint32 aLength, /*= 0*/
const nscoord* aSpacing /* = nsnull*/ )
{
nscolor overColor;
nscolor underColor;
@ -813,6 +825,70 @@ nsTextFrame::PaintTextDecorations(nsIRenderingContext& aRenderingContext,
aRenderingContext.SetColor(strikeColor);
aRenderingContext.FillRect(aX, aY + baseline - offset, aWidth, size);
}
if (aDetails){
nsRect rect;
GetRect(rect);
PRInt32 startOffset = 0;
PRInt32 textWidth = 0;
while(aDetails){
PRInt32 start = PR_MAX(0,(aDetails->mStart - (PRInt32)aIndex));
PRInt32 end = PR_MIN((PRInt32)aLength,(aDetails->mEnd - (PRInt32)aIndex));
PRInt32 i;
if (start < end && (aLength - start) > 0)
{
//aDetails allready processed to have offsets from frame start not content offsets
if (start < end){
if (aLength == 1)
textWidth = aWidth;
else {
if (aDetails->mStart > 0){
if (aSpacing)
{
for (i = 0; i < start;i ++){
startOffset += *aSpacing ++;
}
}
else
aRenderingContext.GetWidth(aText, start, startOffset);
}
if (aSpacing){
for (i = start; i < end;i ++){
textWidth += *aSpacing ++;
}
}
else
aRenderingContext.GetWidth(aText + start,
PRUint32(end - start), textWidth);
}
switch (aDetails->mType)
{
case SELECTION_NORMAL:{
aRenderingContext.SetColor(NS_RGB(0,0,0));
aRenderingContext.DrawRect(aX + startOffset, aY, textWidth, rect.height);
}break;
case SELECTION_SPELLCHECK:{
aTextStyle.mNormalFont->GetUnderline(offset, size);
aRenderingContext.SetColor(NS_RGB(255,0,0));
aRenderingContext.FillRect(aX, aY + baseline - offset, aWidth, size);
}break;
case SELECTION_IME_SOLID:{
aTextStyle.mNormalFont->GetUnderline(offset, size);
aRenderingContext.SetColor(NS_RGB(0,0,255));
aRenderingContext.FillRect(aX, aY + baseline - offset, aWidth, size);
}break;
case SELECTION_IME_DASHED:{
aTextStyle.mNormalFont->GetUnderline(offset, size);
aRenderingContext.SetColor(NS_RGB(128,0,255));
aRenderingContext.FillRect(aX, aY + baseline - offset, aWidth, size);
}break;
}
}
}
aDetails = aDetails->mNext;
}
}
}
void
@ -869,10 +945,7 @@ nsTextFrame::PaintUnicodeText(nsIPresContext* aPresContext,
//must set up last one for selection beyond edge if in boundary
ip[mContentLength]++;
}
PRInt32 textWidth;
PRInt32 selectionStartOffset = 0;//frame coordinates
PRInt32 selectionEndOffset = 0;//frame coordinates
SelectionDetails *details = nsnull;
nsCOMPtr<nsIPresShell> shell;
nsCOMPtr<nsIDOMSelection> selection;
nsCOMPtr<nsIFrameSelection> frameSelection;
@ -887,82 +960,34 @@ nsTextFrame::PaintUnicodeText(nsIPresContext* aPresContext,
rv = GetContent(getter_AddRefs(content));
if (NS_SUCCEEDED(rv)){
rv = frameSelection->LookUpSelection(content, mContentOffset,
mContentLength , &selectionStartOffset, &selectionEndOffset,
&drawSelected,0);// last param notused
mContentLength , &details);// last param notused
}
}
}
if (frameSelection ){
//where are the selection points "really"
if (drawSelected){
selectionStartOffset = ip[selectionStartOffset] - mContentOffset;
selectionEndOffset = ip[selectionEndOffset] - mContentOffset;
SelectionDetails *sdptr = details;
while (sdptr){
sdptr->mStart = ip[sdptr->mStart] - mContentOffset;
sdptr->mEnd = ip[sdptr->mEnd] - mContentOffset;
sdptr = sdptr->mNext;
}
if (!drawSelected || (selectionStartOffset == selectionEndOffset)) {
aRenderingContext.SetColor(aTextStyle.mColor->mColor);
aRenderingContext.DrawString(text, PRUint32(textLength), dx, dy);
PaintTextDecorations(aRenderingContext, aStyleContext,
aTextStyle, dx, dy, width);
#ifdef SHOW_SELECTION_CURSOR
aRenderingContext.GetWidth(text, PRUint32(selectionStartOffset), textWidth);
aTextStyle, dx, dy, width, text, details,0,(PRUint32)textLength);
sdptr = details;
if (details){
while(sdptr = details->mNext){
delete details;
details = sdptr;
}
delete details;
}
}
}
RenderSelectionCursor(aRenderingContext,
dx + textWidth, dy, mRect.height,
CURSOR_COLOR);
#endif
}
else {
nscoord x = dx;
if (selectionStartOffset) {
// Render first (unselected) section
aRenderingContext.GetWidth(text, PRUint32(selectionStartOffset),//si.mStartOffset),
textWidth);
aRenderingContext.SetColor(aTextStyle.mColor->mColor);
aRenderingContext.DrawString(text, PRUint32(selectionStartOffset),
x, dy);
PaintTextDecorations(aRenderingContext, aStyleContext, aTextStyle,
x, dy, textWidth);
x += textWidth;
}
PRInt32 secondLen = selectionEndOffset - selectionStartOffset;
if (0 != secondLen) {
// Get the width of the second (selected) section
aRenderingContext.GetWidth(text + selectionStartOffset,
PRUint32(secondLen), textWidth);
// Render second (selected) section
aRenderingContext.SetColor(aTextStyle.mSelectionBGColor);
aRenderingContext.FillRect(x, dy, textWidth, mRect.height);
aRenderingContext.SetColor(aTextStyle.mSelectionTextColor);
aRenderingContext.DrawString(text + selectionStartOffset,
PRUint32(secondLen), x, dy);
PaintTextDecorations(aRenderingContext, aStyleContext, aTextStyle,
x, dy, textWidth);
x += textWidth;
}
if (textLength != selectionEndOffset) {
PRInt32 thirdLen = textLength - selectionEndOffset;
if (thirdLen > 0) //Text length is not negative or zero
{
// Render third (unselected) section
aRenderingContext.GetWidth(text + selectionEndOffset, PRUint32(thirdLen),
textWidth);
aRenderingContext.SetColor(aTextStyle.mColor->mColor);
aRenderingContext.DrawString(text + selectionEndOffset,
PRUint32(thirdLen), x, dy);
PaintTextDecorations(aRenderingContext, aStyleContext, aTextStyle,
x, dy, textWidth);
}
}
}
}
}
}
// Cleanup
if (paintBuf != paintBufMem) {
delete [] paintBuf;
@ -1106,7 +1131,8 @@ nsTextFrame::RenderString(nsIRenderingContext& aRenderingContext,
TextStyle& aTextStyle,
PRUnichar* aBuffer, PRInt32 aLength,
nscoord aX, nscoord aY,
nscoord aWidth)
nscoord aWidth,
SelectionDetails *aDetails /*=nsnull*/)
{
PRUnichar buf[TEXT_BUF_SIZE];
PRUnichar* bp0 = buf;
@ -1142,6 +1168,7 @@ nsTextFrame::RenderString(nsIRenderingContext& aRenderingContext,
PRInt32 pendingCount;
PRUnichar* runStart = bp;
nscoord charWidth, width = 0;
PRInt32 countSoFar = 0;
for (; --aLength >= 0; aBuffer++) {
nsIFontMetrics* nextFont;
nscoord nextY, glyphWidth;
@ -1195,8 +1222,8 @@ nsTextFrame::RenderString(nsIRenderingContext& aRenderingContext,
// Note: use aY not small-y so that decorations are drawn with
// respect to the normal-font not the current font.
PaintTextDecorations(aRenderingContext, aStyleContext, aTextStyle,
aX, aY, width);
aX, aY, width, runStart, aDetails,countSoFar,pendingCount, spacing ? sp0 : nsnull);
countSoFar += pendingCount;
aWidth -= width;
aX += width;
runStart = bp = bp0;
@ -1221,7 +1248,8 @@ nsTextFrame::RenderString(nsIRenderingContext& aRenderingContext,
// Note: use aY not small-y so that decorations are drawn with
// respect to the normal-font not the current font.
PaintTextDecorations(aRenderingContext, aStyleContext, aTextStyle,
aX, aY, aWidth);
aX, aY, aWidth, runStart, aDetails,countSoFar,pendingCount,
spacing ? sp0 : nsnull);
}
aTextStyle.mLastFont = lastFont;
@ -1368,6 +1396,7 @@ nsTextFrame::PaintTextSlowly(nsIPresContext* aPresContext,
text, textLength, dx, dy, width);
}
else {
SelectionDetails *details = nsnull;
ip[mContentLength] = ip[mContentLength-1];
if ((ip[mContentLength]-mContentOffset) < textLength) {
//must set up last one for selection beyond edge if in boundary
@ -1375,7 +1404,6 @@ nsTextFrame::PaintTextSlowly(nsIPresContext* aPresContext,
}
PRInt32 selectionStartOffset = 0;//frame coordinates
PRInt32 selectionEndOffset = 0;//frame coordinates
PRInt32 textWidth;
nsCOMPtr<nsIPresShell> shell;
nsCOMPtr<nsIDOMSelection> selection;
nsCOMPtr<nsIFrameSelection> frameSelection;
@ -1389,76 +1417,28 @@ nsTextFrame::PaintTextSlowly(nsIPresContext* aPresContext,
rv = GetContent(getter_AddRefs(content));
if (NS_SUCCEEDED(rv)){
rv = frameSelection->LookUpSelection(content, mContentOffset,
mContentLength , &selectionStartOffset, &selectionEndOffset,
&drawSelected, 0);// last param notused
mContentLength , &details);// last param notused
}
}
}
if (frameSelection){
//where are the selection points "really"
if (drawSelected) {
selectionStartOffset = ip[selectionStartOffset] - mContentOffset;
selectionEndOffset = ip[selectionEndOffset] - mContentOffset;
SelectionDetails *sdptr = details;
while (sdptr){
sdptr->mStart = ip[sdptr->mStart] - mContentOffset;
sdptr->mEnd = ip[sdptr->mEnd] - mContentOffset;
sdptr = sdptr->mNext;
}
if (!drawSelected || (selectionStartOffset == selectionEndOffset)){
RenderString(aRenderingContext, aStyleContext, aTextStyle,
text, textLength, dx, dy, width);
#ifdef SHOW_SELECTION_CURSOR
GetWidth(aRenderingContext, aTextStyle,
text, PRUint32(selectionStartOffset), &textWidth);
RenderSelectionCursor(aRenderingContext,
dx + textWidth, dy, mRect.height,
CURSOR_COLOR);
#endif
}
else {
nscoord x = dx;
if (selectionStartOffset) {
// Render first (unselected) section
GetWidth(aRenderingContext, aTextStyle,
text, PRUint32(selectionStartOffset),
&textWidth);
RenderString(aRenderingContext, aStyleContext, aTextStyle,
text, selectionStartOffset,
x, dy, textWidth);
x += textWidth;
}
PRInt32 secondLen = selectionEndOffset - selectionStartOffset;
if (0 != secondLen) {
// Get the width of the second (selected) section
GetWidth(aRenderingContext, aTextStyle,
text + selectionStartOffset,
PRUint32(secondLen), &textWidth);
// Render second (selected) section
aRenderingContext.SetColor(aTextStyle.mSelectionBGColor);
aRenderingContext.FillRect(x, dy, textWidth, mRect.height);
aRenderingContext.SetColor(aTextStyle.mSelectionTextColor);
RenderString(aRenderingContext, aStyleContext, aTextStyle,
text + selectionStartOffset, secondLen,
x, dy, textWidth);
aRenderingContext.SetColor(aTextStyle.mColor->mColor);
x += textWidth;
}
if (textLength != selectionEndOffset) {
PRInt32 thirdLen = textLength - selectionEndOffset;
// Render third (unselected) section
if (thirdLen > 0) //Text length is not negative or zero
{
GetWidth(aRenderingContext, aTextStyle,
text + selectionStartOffset, PRUint32(thirdLen),
&textWidth);
RenderString(aRenderingContext, aStyleContext, aTextStyle,
text + selectionEndOffset,
thirdLen, x, dy, textWidth);
}
}
RenderString(aRenderingContext,aStyleContext, aTextStyle, text,
PRUint32(textLength), dx, dy, width, details);
sdptr = details;
if (details){
while(sdptr = details->mNext){
delete details;
details = sdptr;
}
delete details;
}
}
}
@ -1532,6 +1512,7 @@ nsTextFrame::PaintAsciiText(nsIPresContext* aPresContext,
dx, dy, width);
}
else {
SelectionDetails *details;
ip[mContentLength] = ip[mContentLength-1];
if ((ip[mContentLength]-mContentOffset) < textLength) {
//must set up last one for selection beyond edge if in boundary
@ -1539,7 +1520,6 @@ nsTextFrame::PaintAsciiText(nsIPresContext* aPresContext,
}
PRInt32 selectionStartOffset = 0;//frame coordinates
PRInt32 selectionEndOffset = 0;//frame coordinates
PRInt32 textWidth;
nsCOMPtr<nsIPresShell> shell;
nsCOMPtr<nsIDOMSelection> selection;
nsCOMPtr<nsIFrameSelection> frameSelection;
@ -1553,81 +1533,30 @@ nsTextFrame::PaintAsciiText(nsIPresContext* aPresContext,
rv = GetContent(getter_AddRefs(content));
if (NS_SUCCEEDED(rv)){
rv = frameSelection->LookUpSelection(content, mContentOffset,
mContentLength , &selectionStartOffset, &selectionEndOffset,
&drawSelected, 0);// last param notused
mContentLength , &details);// last param notused
}
}
}
if (frameSelection){
//where are the selection points "really"
if (drawSelected) {
selectionStartOffset = ip[selectionStartOffset] - mContentOffset;
selectionEndOffset = ip[selectionEndOffset] - mContentOffset;
SelectionDetails *sdptr = details;
while (sdptr){
sdptr->mStart = ip[sdptr->mStart] - mContentOffset;
sdptr->mEnd = ip[sdptr->mEnd] - mContentOffset;
sdptr = sdptr->mNext;
}
if (!drawSelected || (selectionStartOffset == selectionEndOffset)){
aRenderingContext.SetColor(aTextStyle.mColor->mColor);
aRenderingContext.DrawString(text, PRUint32(textLength), dx, dy);
PaintTextDecorations(aRenderingContext, aStyleContext,
aTextStyle, dx, dy, width);
//shell->RefreshCaret();
#ifdef SHOW_SELECTION_CURSOR
aRenderingContext.GetWidth(text, PRUint32(selectionStartOffset), textWidth);
RenderSelectionCursor(aRenderingContext,
dx + textWidth, dy, mRect.height,
CURSOR_COLOR);
#endif
}
else {
nscoord x = dx;
if (selectionStartOffset) {
// Render first (unselected) section
aRenderingContext.GetWidth(text, PRUint32(selectionStartOffset),//si.mStartOffset),
textWidth);
aRenderingContext.SetColor(aTextStyle.mColor->mColor);
aRenderingContext.DrawString(text, PRUint32(selectionStartOffset),
x, dy);
PaintTextDecorations(aRenderingContext, aStyleContext, aTextStyle,
x, dy, textWidth);
x += textWidth;
}
PRInt32 secondLen = selectionEndOffset - selectionStartOffset;
if (0 != secondLen) {
// Get the width of the second (selected) section
aRenderingContext.GetWidth(text + selectionStartOffset,
PRUint32(secondLen), textWidth);
// Render second (selected) section
aRenderingContext.SetColor(aTextStyle.mSelectionBGColor);
aRenderingContext.FillRect(x, dy, textWidth, mRect.height);
aRenderingContext.SetColor(aTextStyle.mSelectionTextColor);
aRenderingContext.DrawString(text + selectionStartOffset,
PRUint32(secondLen), x, dy);
PaintTextDecorations(aRenderingContext, aStyleContext, aTextStyle,
x, dy, textWidth);
x += textWidth;
}
if (textLength != selectionEndOffset) {
PRInt32 thirdLen = textLength - selectionEndOffset;
if (thirdLen > 0) //Text length is not negative or zero
{
// Render third (unselected) section
aRenderingContext.GetWidth(text + selectionEndOffset, PRUint32(thirdLen),
textWidth);
aRenderingContext.SetColor(aTextStyle.mColor->mColor);
aRenderingContext.DrawString(text + selectionEndOffset,
PRUint32(thirdLen), x, dy);
PaintTextDecorations(aRenderingContext, aStyleContext, aTextStyle,
x, dy, textWidth);
}
}
aTextStyle, dx, dy, width, (PRUnichar *)text, details,0,textLength);
sdptr = details;
if (details){
while(sdptr = details->mNext){
delete details;
details = sdptr;
}
delete details;
}
}
}
@ -1999,7 +1928,7 @@ nsTextFrame::GetChildFrameContainingOffset(PRInt32 inContentOffset,
{
if (nsnull == outChildFrame)
return NS_ERROR_NULL_POINTER;
nsresult result;
PRInt32 contentOffset = inContentOffset;
if (contentOffset != -1) //-1 signified the end of the current content
@ -2015,6 +1944,15 @@ nsTextFrame::GetChildFrameContainingOffset(PRInt32 inContentOffset,
else
return NS_ERROR_FAILURE;
}
else if (inContentOffset < mContentOffset) //could happen with floaters!
{
result = GetPrevInFlow(outChildFrame);
if (NS_SUCCEEDED(result))
return (*outChildFrame)->GetChildFrameContainingOffset(inContentOffset,
outFrameContentOffset,outChildFrame);
else
return result;
}
*outFrameContentOffset = contentOffset;
*outChildFrame = this;
@ -2033,7 +1971,7 @@ nsTextFrame::PeekOffset(nsIFocusTracker *aTracker,
PRBool aEatingWS)
{
if (!aResultContent || !aContentOffset)
if (!aResultContent || !aContentOffset || !mContent)
return NS_ERROR_NULL_POINTER;
if (aStartOffset < 0)
aStartOffset = mContentLength + mContentOffset;
@ -2065,9 +2003,11 @@ nsTextFrame::PeekOffset(nsIFocusTracker *aTracker,
PRInt32 textLength;
// Transform text from content into renderable form
nsresult result(NS_OK);
nsIDocument* doc;
mContent->GetDocument(doc);
result = mContent->GetDocument(doc);
if (NS_FAILED(result) || !doc)
return result;
nsCOMPtr<nsILineBreaker> lb;
doc->GetLineBreaker(getter_AddRefs(lb));
nsCOMPtr<nsIWordBreaker> wb;
@ -2075,7 +2015,6 @@ nsTextFrame::PeekOffset(nsIFocusTracker *aTracker,
NS_RELEASE(doc);
nsTextTransformer tx(wordBufMem, WORD_BUF_SIZE,lb,wb);
nsresult result(NS_OK);
switch (aAmount){
case eSelectNoAmount : {
@ -2316,10 +2255,10 @@ nsTextFrame::HandleMultiplePress(nsIPresContext& aPresContext,
nsCOMPtr<nsIDOMSelection> selection;
if (NS_SUCCEEDED(shell->GetSelection(getter_AddRefs(selection)))){
rv = selection->Collapse(startNode,startOffset);
rv = selection->Collapse(startNode,startOffset, SELECTION_NORMAL);
if (NS_FAILED(rv))
return rv;
rv = selection->Extend(endNode,endOffset);
rv = selection->Extend(endNode,endOffset, SELECTION_NORMAL);
if (NS_FAILED(rv))
return rv;
}

Просмотреть файл

@ -913,13 +913,13 @@ nsGfxTextControlFrame::SelectAllTextContent(nsIDOMNode *aBodyNode, nsIDOMSelecti
result = aBodyNode->GetLastChild(getter_AddRefs(lastChild));
if ((NS_SUCCEEDED(result)) && lastChild)
{
aSelection->Collapse(firstChild, 0);
aSelection->Collapse(firstChild, 0, SELECTION_NORMAL);
nsCOMPtr<nsIDOMCharacterData>text = do_QueryInterface(lastChild);
if (text)
{
PRUint32 length;
text->GetLength(&length);
aSelection->Extend(lastChild, length);
aSelection->Extend(lastChild, length, SELECTION_NORMAL);
}
}
}
@ -1220,7 +1220,7 @@ nsGfxTextControlFrame::InitializeTextControl(nsIPresShell *aPresShell, nsIDOMDoc
result = mEditor->InsertText(value);
result = SelectAllTextContent(bodyNode, selection);
}
selection->ClearSelection();
selection->ClearSelection(SELECTION_NORMAL);
}
}
}