Bug 554822 Caret should refer the actual text color instead of the value of CSS color property r=roc

This commit is contained in:
Masayuki Nakano 2010-04-01 11:35:48 +09:00
parent 25005cf067
commit 553922eee1
6 changed files with 73 additions and 7 deletions

View File

@ -497,7 +497,7 @@ nsresult nsCaret::DrawAtPosition(nsIDOMNode* aNode, PRInt32 aOffset)
return rv;
}
nsIFrame * nsCaret::GetCaretFrame()
nsIFrame * nsCaret::GetCaretFrame(PRInt32 *aOffset)
{
// Return null if we're not drawn to prevent anybody from trying to draw us.
if (!mDrawn)
@ -505,14 +505,17 @@ nsIFrame * nsCaret::GetCaretFrame()
// Recompute the frame that we're supposed to draw in to guarantee that
// we're not going to try to draw into a stale (dead) frame.
PRInt32 unused;
PRInt32 offset;
nsIFrame *frame = nsnull;
nsresult rv = GetCaretFrameForNodeOffset(mLastContent, mLastContentOffset,
mLastHint, mLastBidiLevel, &frame,
&unused);
&offset);
if (NS_FAILED(rv))
return nsnull;
if (aOffset) {
*aOffset = offset;
}
return frame;
}
@ -545,7 +548,10 @@ void nsCaret::PaintCaret(nsDisplayListBuilder *aBuilder,
NS_ASSERTION(mDrawn, "The caret shouldn't be drawing");
const nsRect drawCaretRect = mCaretRect + aOffset;
nscolor cssColor = aForFrame->GetStyleColor()->mColor;
PRInt32 contentOffset;
nsIFrame* frame = GetCaretFrame(&contentOffset);
NS_ASSERTION(frame == aForFrame, "We're referring different frame");
nscolor foregroundColor = aForFrame->GetCaretColorAt(contentOffset);
// Only draw the native caret if the foreground color matches that of
// -moz-fieldtext (the color of the text in a textbox). If it doesn't match
@ -559,7 +565,7 @@ void nsCaret::PaintCaret(nsDisplayListBuilder *aBuilder,
nsILookAndFeel* lookAndFeel = presContext->LookAndFeel();
nscolor fieldText;
if (NS_SUCCEEDED(lookAndFeel->GetColor(nsILookAndFeel::eColor__moz_fieldtext, fieldText)) &&
fieldText == cssColor) {
fieldText == foregroundColor) {
theme->DrawWidgetBackground(aCtx, aForFrame, NS_THEME_TEXTFIELD_CARET,
drawCaretRect, drawCaretRect);
return;
@ -567,7 +573,7 @@ void nsCaret::PaintCaret(nsDisplayListBuilder *aBuilder,
}
}
aCtx->SetColor(cssColor);
aCtx->SetColor(foregroundColor);
aCtx->FillRect(drawCaretRect);
if (!GetHookRect().IsEmpty())
aCtx->FillRect(GetHookRect() + aOffset);

View File

@ -136,8 +136,10 @@ class nsCaret : public nsISelectionListener
* Get the current frame that the caret should be drawn in. If the caret is
* not currently visible (i.e., it is between blinks), then this will
* return null.
*
* @param aOffset is result of the caret offset in the content.
*/
nsIFrame* GetCaretFrame();
nsIFrame* GetCaretFrame(PRInt32 *aOffset = nsnull);
/** GetCaretRect
* Get the current caret rect. Only call this when GetCaretFrame returns

View File

@ -973,6 +973,13 @@ nsIFrame::DisplayCaret(nsDisplayListBuilder* aBuilder,
new (aBuilder) nsDisplayCaret(this, aBuilder->GetCaret()));
}
nscolor
nsIFrame::GetCaretColorAt(PRInt32 aOffset)
{
// Use text color.
return GetStyleColor()->mColor;
}
PRBool
nsIFrame::HasBorder() const
{

View File

@ -977,6 +977,13 @@ public:
const nsRect& aDirtyRect,
nsDisplayList* aList);
/**
* Get the preferred caret color at the offset.
*
* @param aOffset is offset of the content.
*/
virtual nscolor GetCaretColorAt(PRInt32 aOffset);
PRBool IsThemed(nsTransparencyMode* aTransparencyMode = nsnull) {
return IsThemed(GetStyleDisplay(), aTransparencyMode);
}

View File

@ -307,6 +307,8 @@ public:
SelectionDetails* aDetails,
SelectionType aSelectionType);
virtual nscolor GetCaretColorAt(PRInt32 aOffset);
PRInt16 GetSelectionStatus(PRInt16* aSelectionFlags);
#ifdef DEBUG

View File

@ -4717,6 +4717,48 @@ nsTextFrame::PaintTextWithSelection(gfxContext* aCtx,
return PR_TRUE;
}
nscolor
nsTextFrame::GetCaretColorAt(PRInt32 aOffset)
{
NS_PRECONDITION(aOffset >= 0, "aOffset must be positive");
gfxSkipCharsIterator iter = EnsureTextRun();
PropertyProvider provider(this, iter);
PRInt32 contentOffset = provider.GetStart().GetOriginalOffset();
PRInt32 contentLength = provider.GetOriginalLength();
NS_PRECONDITION(aOffset >= contentOffset &&
aOffset <= contentOffset + contentLength,
"aOffset must be in the frame's range");
PRInt32 offsetInFrame = aOffset - contentOffset;
if (offsetInFrame < 0 || offsetInFrame >= contentLength) {
return nsFrame::GetCaretColorAt(aOffset);
}
nsTextPaintStyle textPaintStyle(this);
SelectionDetails* details = GetSelectionDetails();
SelectionDetails* sdptr = details;
nscolor result = nsFrame::GetCaretColorAt(aOffset);
SelectionType type = 0;
while (sdptr) {
PRInt32 start = NS_MAX(0, sdptr->mStart - contentOffset);
PRInt32 end = NS_MIN(contentLength, sdptr->mEnd - contentOffset);
if (start <= offsetInFrame && offsetInFrame < end &&
(type == 0 || sdptr->mType < type)) {
nscolor foreground, background;
if (GetSelectionTextColors(sdptr->mType, textPaintStyle,
sdptr->mTextRangeStyle,
&foreground, &background)) {
result = foreground;
type = sdptr->mType;
}
}
sdptr = sdptr->mNext;
}
DestroySelectionDetails(details);
return result;
}
static PRUint32
ComputeTransformedLength(PropertyProvider& aProvider)
{